License UI redesign + composition API (#3225)
* refactor(frontend): revamp license page - Add more understandable UI - Field titles - Field description - Use more semantically correct elements - Make paragraph not a label - Rephrase some parts - Fields no longer jump around - Split SPDX-identifier and license name into two seperate fields, for readability - Sort imports - fmt * feat(frontend): encourage license URL on custom license * refactor(frontend): license page to composition + ts - Move to Vue composition API - Move to TypeScript - Move away from vue-multiselect to the dropdown component - Use `formatProjectType` function for typesafety - Remove unused form error highlighting code - Creating typings for built-in licenses - Move standard licenses to licenses.ts util - There are other license-related utils I want to move there eventually - Fix typo in Project license type definition * chore(frontend): fmt * chore(frontend): fmt * feat(frontend): require URL and name for custom license * refactor(frontend): give license or-later checkbox own row * chore(frontend): fmt
This commit is contained in:
parent
a75538c093
commit
affeec82f0
@ -1,61 +1,128 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<section class="universal-card">
|
<section class="universal-card">
|
||||||
|
<h2 class="label__title size-card-header">License</h2>
|
||||||
|
<p class="label__description">
|
||||||
|
It is important to choose a proper license for your
|
||||||
|
{{ formatProjectType(project.project_type).toLowerCase() }}. You may choose one from our
|
||||||
|
list or provide a custom license. You may also provide a custom URL to your chosen license;
|
||||||
|
otherwise, the license text will be displayed. See our
|
||||||
|
<a
|
||||||
|
href="https://blog.modrinth.com/licensing-guide/"
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener"
|
||||||
|
class="text-link"
|
||||||
|
>
|
||||||
|
licensing guide
|
||||||
|
</a>
|
||||||
|
for more information.
|
||||||
|
</p>
|
||||||
|
|
||||||
<div class="adjacent-input">
|
<div class="adjacent-input">
|
||||||
<label for="license-multiselect">
|
<label for="license-multiselect">
|
||||||
<span class="label__title size-card-header">License</span>
|
<span class="label__title">Select a license</span>
|
||||||
<span class="label__description">
|
<span class="label__description">
|
||||||
It is very important to choose a proper license for your
|
How users are and aren't allowed to use your project.
|
||||||
{{ $formatProjectType(project.project_type).toLowerCase() }}. You may choose one from
|
|
||||||
our list or provide a custom license. You may also provide a custom URL to your chosen
|
|
||||||
license; otherwise, the license text will be displayed.
|
|
||||||
<span v-if="license && license.friendly === 'Custom'" class="label__subdescription">
|
|
||||||
Enter a valid
|
|
||||||
<a href="https://spdx.org/licenses/" target="_blank" rel="noopener" class="text-link">
|
|
||||||
SPDX license identifier</a
|
|
||||||
>
|
|
||||||
in the marked area. If your license does not have a SPDX identifier (for example, if
|
|
||||||
you created the license yourself or if the license is Minecraft-specific), simply
|
|
||||||
check the box and enter the name of the license instead.
|
|
||||||
</span>
|
|
||||||
<span class="label__subdescription">
|
|
||||||
Confused? See our
|
|
||||||
<a
|
|
||||||
href="https://blog.modrinth.com/licensing-guide/"
|
|
||||||
target="_blank"
|
|
||||||
rel="noopener"
|
|
||||||
class="text-link"
|
|
||||||
>
|
|
||||||
licensing guide</a
|
|
||||||
>
|
|
||||||
for more information.
|
|
||||||
</span>
|
|
||||||
</span>
|
</span>
|
||||||
</label>
|
</label>
|
||||||
<div class="input-stack">
|
|
||||||
<Multiselect
|
<div class="w-1/2">
|
||||||
id="license-multiselect"
|
<DropdownSelect
|
||||||
v-model="license"
|
v-model="license"
|
||||||
|
name="License selector"
|
||||||
|
:options="builtinLicenses"
|
||||||
|
:display-name="(chosen: BuiltinLicense) => chosen.friendly"
|
||||||
placeholder="Select license..."
|
placeholder="Select license..."
|
||||||
track-by="short"
|
/>
|
||||||
label="friendly"
|
</div>
|
||||||
:options="defaultLicenses"
|
</div>
|
||||||
:searchable="true"
|
|
||||||
:close-on-select="true"
|
<div class="adjacent-input" v-if="license.requiresOnlyOrLater">
|
||||||
:show-labels="false"
|
<label for="or-later-checkbox">
|
||||||
:class="{
|
<span class="label__title">Later editions</span>
|
||||||
'known-error': license?.short === '' && showKnownErrors,
|
<span class="label__description">
|
||||||
}"
|
The license you selected has an "or later" clause. If you check this box, users may use
|
||||||
|
your project under later editions of the license.
|
||||||
|
</span>
|
||||||
|
</label>
|
||||||
|
|
||||||
|
<Checkbox
|
||||||
|
id="or-later-checkbox"
|
||||||
|
v-model="allowOrLater"
|
||||||
|
:disabled="!hasPermission"
|
||||||
|
description="Allow later editions"
|
||||||
|
class="w-1/2"
|
||||||
|
>
|
||||||
|
Allow later editions
|
||||||
|
</Checkbox>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="adjacent-input">
|
||||||
|
<label for="license-url">
|
||||||
|
<span class="label__title">License URL</span>
|
||||||
|
<span class="label__description" v-if="license?.friendly !== 'Custom'">
|
||||||
|
The web location of the full license text. If you don't provide a link, the license text
|
||||||
|
will be displayed instead.
|
||||||
|
</span>
|
||||||
|
<span class="label__description" v-else>
|
||||||
|
The web location of the full license text. You have to provide a link since this is a
|
||||||
|
custom license.
|
||||||
|
</span>
|
||||||
|
</label>
|
||||||
|
|
||||||
|
<div class="w-1/2">
|
||||||
|
<input
|
||||||
|
id="license-url"
|
||||||
|
v-model="licenseUrl"
|
||||||
|
type="url"
|
||||||
|
maxlength="2048"
|
||||||
|
:placeholder="license?.friendly !== 'Custom' ? `License URL (optional)` : `License URL`"
|
||||||
|
:disabled="!hasPermission || licenseId === 'LicenseRef-Unknown'"
|
||||||
|
class="w-full"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="adjacent-input" v-if="license?.friendly === 'Custom'">
|
||||||
|
<label for="license-spdx" v-if="!nonSpdxLicense">
|
||||||
|
<span class="label__title">SPDX identifier</span>
|
||||||
|
<span class="label__description">
|
||||||
|
If your license does not have an offical
|
||||||
|
<a href="https://spdx.org/licenses/" target="_blank" rel="noopener" class="text-link">
|
||||||
|
SPDX license identifier</a
|
||||||
|
>, check the box and enter the name of the license instead.
|
||||||
|
</span>
|
||||||
|
</label>
|
||||||
|
<label for="license-name" v-else>
|
||||||
|
<span class="label__title">License name</span>
|
||||||
|
<span class="label__description"
|
||||||
|
>The full name of the license. If the license has a SPDX identifier, please uncheck the
|
||||||
|
checkbox and use the identifier instead.</span
|
||||||
|
>
|
||||||
|
</label>
|
||||||
|
|
||||||
|
<div class="input-stack w-1/2">
|
||||||
|
<input
|
||||||
|
v-if="!nonSpdxLicense"
|
||||||
|
v-model="license.short"
|
||||||
|
id="license-spdx"
|
||||||
|
class="w-full"
|
||||||
|
type="text"
|
||||||
|
maxlength="128"
|
||||||
|
placeholder="SPDX identifier"
|
||||||
:disabled="!hasPermission"
|
:disabled="!hasPermission"
|
||||||
/>
|
/>
|
||||||
<Checkbox
|
<input
|
||||||
v-if="license?.requiresOnlyOrLater"
|
v-else
|
||||||
v-model="allowOrLater"
|
v-model="license.short"
|
||||||
|
id="license-name"
|
||||||
|
class="w-full"
|
||||||
|
type="text"
|
||||||
|
maxlength="128"
|
||||||
|
placeholder="License name"
|
||||||
:disabled="!hasPermission"
|
:disabled="!hasPermission"
|
||||||
description="Allow later editions of this license"
|
/>
|
||||||
>
|
|
||||||
Allow later editions of this license
|
|
||||||
</Checkbox>
|
|
||||||
<Checkbox
|
<Checkbox
|
||||||
v-if="license?.friendly === 'Custom'"
|
v-if="license?.friendly === 'Custom'"
|
||||||
v-model="nonSpdxLicense"
|
v-model="nonSpdxLicense"
|
||||||
@ -64,31 +131,18 @@
|
|||||||
>
|
>
|
||||||
License does not have a SPDX identifier
|
License does not have a SPDX identifier
|
||||||
</Checkbox>
|
</Checkbox>
|
||||||
<input
|
|
||||||
v-if="license?.friendly === 'Custom'"
|
|
||||||
v-model="license.short"
|
|
||||||
type="text"
|
|
||||||
maxlength="2048"
|
|
||||||
:placeholder="nonSpdxLicense ? 'License name' : 'SPDX identifier'"
|
|
||||||
:class="{
|
|
||||||
'known-error': license.short === '' && showKnownErrors,
|
|
||||||
}"
|
|
||||||
:disabled="!hasPermission"
|
|
||||||
/>
|
|
||||||
<input
|
|
||||||
v-model="licenseUrl"
|
|
||||||
type="url"
|
|
||||||
maxlength="2048"
|
|
||||||
placeholder="License URL (optional)"
|
|
||||||
:disabled="!hasPermission || licenseId === 'LicenseRef-Unknown'"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="input-stack">
|
<div class="input-stack">
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
class="iconified-button brand-button"
|
class="iconified-button brand-button"
|
||||||
:disabled="!hasChanges || license === null"
|
:disabled="
|
||||||
|
!hasChanges ||
|
||||||
|
!hasPermission ||
|
||||||
|
(license.friendly === 'Custom' && (license.short === '' || licenseUrl === ''))
|
||||||
|
"
|
||||||
@click="saveChanges()"
|
@click="saveChanges()"
|
||||||
>
|
>
|
||||||
<SaveIcon />
|
<SaveIcon />
|
||||||
@ -99,199 +153,109 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script setup lang="ts">
|
||||||
import Multiselect from "vue-multiselect";
|
import { Checkbox, DropdownSelect } from "@modrinth/ui";
|
||||||
import Checkbox from "~/components/ui/Checkbox";
|
import {
|
||||||
|
TeamMemberPermission,
|
||||||
|
builtinLicenses,
|
||||||
|
formatProjectType,
|
||||||
|
type BuiltinLicense,
|
||||||
|
type Project,
|
||||||
|
type TeamMember,
|
||||||
|
} from "@modrinth/utils";
|
||||||
|
import { computed, ref, type Ref } from "vue";
|
||||||
import SaveIcon from "~/assets/images/utils/save.svg?component";
|
import SaveIcon from "~/assets/images/utils/save.svg?component";
|
||||||
|
|
||||||
export default defineNuxtComponent({
|
const props = defineProps<{
|
||||||
components: {
|
project: Project;
|
||||||
Multiselect,
|
currentMember: TeamMember | undefined;
|
||||||
Checkbox,
|
patchProject: (payload: Object, quiet?: boolean) => Object;
|
||||||
SaveIcon,
|
}>();
|
||||||
},
|
|
||||||
props: {
|
|
||||||
project: {
|
|
||||||
type: Object,
|
|
||||||
default() {
|
|
||||||
return {};
|
|
||||||
},
|
|
||||||
},
|
|
||||||
currentMember: {
|
|
||||||
type: Object,
|
|
||||||
default() {
|
|
||||||
return null;
|
|
||||||
},
|
|
||||||
},
|
|
||||||
patchProject: {
|
|
||||||
type: Function,
|
|
||||||
default() {
|
|
||||||
return () => {
|
|
||||||
this.$notify({
|
|
||||||
group: "main",
|
|
||||||
title: "An error occurred",
|
|
||||||
text: "Patch project function not found",
|
|
||||||
type: "error",
|
|
||||||
});
|
|
||||||
};
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
licenseUrl: "",
|
|
||||||
license: { friendly: "", short: "", requiresOnlyOrLater: false },
|
|
||||||
allowOrLater: this.project.license.id.includes("-or-later"),
|
|
||||||
nonSpdxLicense: this.project.license.id.includes("LicenseRef-"),
|
|
||||||
showKnownErrors: false,
|
|
||||||
};
|
|
||||||
},
|
|
||||||
async setup(props) {
|
|
||||||
const defaultLicenses = shallowRef([
|
|
||||||
{ friendly: "Custom", short: "" },
|
|
||||||
{
|
|
||||||
friendly: "All Rights Reserved/No License",
|
|
||||||
short: "All-Rights-Reserved",
|
|
||||||
},
|
|
||||||
{ friendly: "Apache License 2.0", short: "Apache-2.0" },
|
|
||||||
{
|
|
||||||
friendly: 'BSD 2-Clause "Simplified" License',
|
|
||||||
short: "BSD-2-Clause",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
friendly: 'BSD 3-Clause "New" or "Revised" License',
|
|
||||||
short: "BSD-3-Clause",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
friendly: "CC Zero (Public Domain equivalent)",
|
|
||||||
short: "CC0-1.0",
|
|
||||||
},
|
|
||||||
{ friendly: "CC-BY 4.0", short: "CC-BY-4.0" },
|
|
||||||
{
|
|
||||||
friendly: "CC-BY-SA 4.0",
|
|
||||||
short: "CC-BY-SA-4.0",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
friendly: "CC-BY-NC 4.0",
|
|
||||||
short: "CC-BY-NC-4.0",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
friendly: "CC-BY-NC-SA 4.0",
|
|
||||||
short: "CC-BY-NC-SA-4.0",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
friendly: "CC-BY-ND 4.0",
|
|
||||||
short: "CC-BY-ND-4.0",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
friendly: "CC-BY-NC-ND 4.0",
|
|
||||||
short: "CC-BY-NC-ND-4.0",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
friendly: "GNU Affero General Public License v3",
|
|
||||||
short: "AGPL-3.0",
|
|
||||||
requiresOnlyOrLater: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
friendly: "GNU Lesser General Public License v2.1",
|
|
||||||
short: "LGPL-2.1",
|
|
||||||
requiresOnlyOrLater: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
friendly: "GNU Lesser General Public License v3",
|
|
||||||
short: "LGPL-3.0",
|
|
||||||
requiresOnlyOrLater: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
friendly: "GNU General Public License v2",
|
|
||||||
short: "GPL-2.0",
|
|
||||||
requiresOnlyOrLater: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
friendly: "GNU General Public License v3",
|
|
||||||
short: "GPL-3.0",
|
|
||||||
requiresOnlyOrLater: true,
|
|
||||||
},
|
|
||||||
{ friendly: "ISC License", short: "ISC" },
|
|
||||||
{ friendly: "MIT License", short: "MIT" },
|
|
||||||
{ friendly: "Mozilla Public License 2.0", short: "MPL-2.0" },
|
|
||||||
{ friendly: "zlib License", short: "Zlib" },
|
|
||||||
]);
|
|
||||||
|
|
||||||
const licenseUrl = ref(props.project.license.url);
|
const licenseUrl = ref(props.project.license.url);
|
||||||
|
const license: Ref<{
|
||||||
const licenseId = props.project.license.id;
|
friendly: string;
|
||||||
const trimmedLicenseId = licenseId
|
short: string;
|
||||||
.replaceAll("-only", "")
|
requiresOnlyOrLater?: boolean;
|
||||||
.replaceAll("-or-later", "")
|
}> = ref({
|
||||||
.replaceAll("LicenseRef-", "");
|
friendly: "",
|
||||||
|
short: "",
|
||||||
const license = ref(
|
requiresOnlyOrLater: false,
|
||||||
defaultLicenses.value.find((x) => x.short === trimmedLicenseId) ?? {
|
|
||||||
friendly: "Custom",
|
|
||||||
short: licenseId.replaceAll("LicenseRef-", ""),
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
if (licenseId === "LicenseRef-Unknown") {
|
|
||||||
license.value = {
|
|
||||||
friendly: "Unknown",
|
|
||||||
short: licenseId.replaceAll("LicenseRef-", ""),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
defaultLicenses,
|
|
||||||
licenseUrl,
|
|
||||||
license,
|
|
||||||
};
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
hasPermission() {
|
|
||||||
const EDIT_DETAILS = 1 << 2;
|
|
||||||
return (this.currentMember.permissions & EDIT_DETAILS) === EDIT_DETAILS;
|
|
||||||
},
|
|
||||||
licenseId() {
|
|
||||||
let id = "";
|
|
||||||
if (this.license === null) return id;
|
|
||||||
if (
|
|
||||||
(this.nonSpdxLicense && this.license.friendly === "Custom") ||
|
|
||||||
this.license.short === "All-Rights-Reserved" ||
|
|
||||||
this.license.short === "Unknown"
|
|
||||||
) {
|
|
||||||
id += "LicenseRef-";
|
|
||||||
}
|
|
||||||
id += this.license.short;
|
|
||||||
if (this.license.requiresOnlyOrLater) {
|
|
||||||
id += this.allowOrLater ? "-or-later" : "-only";
|
|
||||||
}
|
|
||||||
if (this.nonSpdxLicense && this.license.friendly === "Custom") {
|
|
||||||
id = id.replaceAll(" ", "-");
|
|
||||||
}
|
|
||||||
return id;
|
|
||||||
},
|
|
||||||
patchData() {
|
|
||||||
const data = {};
|
|
||||||
|
|
||||||
if (this.licenseId !== this.project.license.id) {
|
|
||||||
data.license_id = this.licenseId;
|
|
||||||
data.license_url = this.licenseUrl ? this.licenseUrl : null;
|
|
||||||
} else if (this.licenseUrl !== this.project.license.url) {
|
|
||||||
data.license_url = this.licenseUrl ? this.licenseUrl : null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return data;
|
|
||||||
},
|
|
||||||
hasChanges() {
|
|
||||||
return Object.keys(this.patchData).length > 0;
|
|
||||||
},
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
saveChanges() {
|
|
||||||
if (this.hasChanges) {
|
|
||||||
this.patchProject(this.patchData);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const allowOrLater = ref(props.project.license.id.includes("-or-later"));
|
||||||
|
const nonSpdxLicense = ref(props.project.license.id.includes("LicenseRef-"));
|
||||||
|
|
||||||
|
const oldLicenseId = props.project.license.id;
|
||||||
|
const trimmedLicenseId = oldLicenseId
|
||||||
|
.replaceAll("-only", "")
|
||||||
|
.replaceAll("-or-later", "")
|
||||||
|
.replaceAll("LicenseRef-", "");
|
||||||
|
|
||||||
|
license.value = builtinLicenses.find((x) => x.short === trimmedLicenseId) ?? {
|
||||||
|
friendly: "Custom",
|
||||||
|
short: oldLicenseId.replaceAll("LicenseRef-", ""),
|
||||||
|
requiresOnlyOrLater: oldLicenseId.includes("-or-later"),
|
||||||
|
};
|
||||||
|
|
||||||
|
if (oldLicenseId === "LicenseRef-Unknown") {
|
||||||
|
// Mark it as not having a license, forcing the user to select one
|
||||||
|
license.value = {
|
||||||
|
friendly: "",
|
||||||
|
short: oldLicenseId.replaceAll("LicenseRef-", ""),
|
||||||
|
requiresOnlyOrLater: false,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const hasPermission = computed(() => {
|
||||||
|
return (props.currentMember?.permissions ?? 0) & TeamMemberPermission.EDIT_DETAILS;
|
||||||
|
});
|
||||||
|
|
||||||
|
const licenseId = computed(() => {
|
||||||
|
let id = "";
|
||||||
|
|
||||||
|
if (
|
||||||
|
(nonSpdxLicense && license.value.friendly === "Custom") ||
|
||||||
|
license.value.short === "All-Rights-Reserved" ||
|
||||||
|
license.value.short === "Unknown"
|
||||||
|
) {
|
||||||
|
id += "LicenseRef-";
|
||||||
|
}
|
||||||
|
|
||||||
|
id += license.value.short;
|
||||||
|
if (license.value.requiresOnlyOrLater) {
|
||||||
|
id += allowOrLater.value ? "-or-later" : "-only";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nonSpdxLicense && license.value.friendly === "Custom") {
|
||||||
|
id = id.replaceAll(" ", "-");
|
||||||
|
}
|
||||||
|
|
||||||
|
return id;
|
||||||
|
});
|
||||||
|
|
||||||
|
const patchRequestPayload = computed(() => {
|
||||||
|
const payload: {
|
||||||
|
license_id?: string;
|
||||||
|
license_url?: string | null; // null = remove url
|
||||||
|
} = {};
|
||||||
|
|
||||||
|
if (licenseId.value !== props.project.license.id) {
|
||||||
|
payload.license_id = licenseId.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (licenseUrl.value !== props.project.license.url) {
|
||||||
|
payload.license_url = licenseUrl.value ? licenseUrl.value : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return payload;
|
||||||
|
});
|
||||||
|
|
||||||
|
const hasChanges = computed(() => {
|
||||||
|
return Object.keys(patchRequestPayload.value).length > 0;
|
||||||
|
});
|
||||||
|
|
||||||
|
function saveChanges() {
|
||||||
|
props.patchProject(patchRequestPayload.value);
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@ -1,8 +1,8 @@
|
|||||||
|
export * from './billing'
|
||||||
export * from './highlight'
|
export * from './highlight'
|
||||||
|
export * from './licenses'
|
||||||
export * from './parse'
|
export * from './parse'
|
||||||
export * from './projects'
|
export * from './projects'
|
||||||
|
export * from './types'
|
||||||
export * from './users'
|
export * from './users'
|
||||||
export * from './utils'
|
export * from './utils'
|
||||||
export * from './billing'
|
|
||||||
|
|
||||||
export * from './types'
|
|
||||||
|
|||||||
76
packages/utils/licenses.ts
Normal file
76
packages/utils/licenses.ts
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
export interface BuiltinLicense {
|
||||||
|
friendly: string
|
||||||
|
short: string
|
||||||
|
requiresOnlyOrLater?: boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
export const builtinLicenses: BuiltinLicense[] = [
|
||||||
|
{ friendly: 'Custom', short: '' },
|
||||||
|
{
|
||||||
|
friendly: 'All Rights Reserved/No License',
|
||||||
|
short: 'All-Rights-Reserved',
|
||||||
|
},
|
||||||
|
{ friendly: 'Apache License 2.0', short: 'Apache-2.0' },
|
||||||
|
{
|
||||||
|
friendly: 'BSD 2-Clause "Simplified" License',
|
||||||
|
short: 'BSD-2-Clause',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
friendly: 'BSD 3-Clause "New" or "Revised" License',
|
||||||
|
short: 'BSD-3-Clause',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
friendly: 'CC Zero (Public Domain equivalent)',
|
||||||
|
short: 'CC0-1.0',
|
||||||
|
},
|
||||||
|
{ friendly: 'CC-BY 4.0', short: 'CC-BY-4.0' },
|
||||||
|
{
|
||||||
|
friendly: 'CC-BY-SA 4.0',
|
||||||
|
short: 'CC-BY-SA-4.0',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
friendly: 'CC-BY-NC 4.0',
|
||||||
|
short: 'CC-BY-NC-4.0',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
friendly: 'CC-BY-NC-SA 4.0',
|
||||||
|
short: 'CC-BY-NC-SA-4.0',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
friendly: 'CC-BY-ND 4.0',
|
||||||
|
short: 'CC-BY-ND-4.0',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
friendly: 'CC-BY-NC-ND 4.0',
|
||||||
|
short: 'CC-BY-NC-ND-4.0',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
friendly: 'GNU Affero General Public License v3',
|
||||||
|
short: 'AGPL-3.0',
|
||||||
|
requiresOnlyOrLater: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
friendly: 'GNU Lesser General Public License v2.1',
|
||||||
|
short: 'LGPL-2.1',
|
||||||
|
requiresOnlyOrLater: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
friendly: 'GNU Lesser General Public License v3',
|
||||||
|
short: 'LGPL-3.0',
|
||||||
|
requiresOnlyOrLater: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
friendly: 'GNU General Public License v2',
|
||||||
|
short: 'GPL-2.0',
|
||||||
|
requiresOnlyOrLater: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
friendly: 'GNU General Public License v3',
|
||||||
|
short: 'GPL-3.0',
|
||||||
|
requiresOnlyOrLater: true,
|
||||||
|
},
|
||||||
|
{ friendly: 'ISC License', short: 'ISC' },
|
||||||
|
{ friendly: 'MIT License', short: 'MIT' },
|
||||||
|
{ friendly: 'Mozilla Public License 2.0', short: 'MPL-2.0' },
|
||||||
|
{ friendly: 'zlib License', short: 'Zlib' },
|
||||||
|
] as const
|
||||||
@ -87,8 +87,7 @@ export interface Project {
|
|||||||
|
|
||||||
license: {
|
license: {
|
||||||
id: string
|
id: string
|
||||||
name
|
name: string
|
||||||
string
|
|
||||||
url?: string
|
url?: string
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user