@helpers4/license 3.1.8 → 3.1.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -1
- package/lib/index.js +4 -8
- package/lib/index.js.map +1 -1
- package/llms.txt +1 -1
- package/meta/api.json +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -41,6 +41,7 @@ A set of helpers for working with URLs.
|
|
|
41
41
|
- [number](../number)
|
|
42
42
|
- [object](../object)
|
|
43
43
|
- [observable](../observable)
|
|
44
|
+
- [package](../package)
|
|
44
45
|
- [promise](../promise)
|
|
45
46
|
- [set](../set)
|
|
46
47
|
- [string](../string)
|
|
@@ -57,7 +58,7 @@ A set of helpers for working with URLs.
|
|
|
57
58
|
|------|---------|-------------|-------------|
|
|
58
59
|
| animation | [@helpers4/animation](https://www.npmjs.com/package/@helpers4/animation) | [Source](https://github.com/helpers4/helpers4/tree/main/helpers/animation) | Timing and interpolation for animations |
|
|
59
60
|
| array | [@helpers4/array](https://www.npmjs.com/package/@helpers4/array) | [Source](https://github.com/helpers4/helpers4/tree/main/helpers/array) | Array manipulation utilities |
|
|
60
|
-
| binary | [@helpers4/binary](https://www.npmjs.com/package/@helpers4/binary) | [Source](https://github.com/helpers4/helpers4/tree/main/helpers/binary) | Read and
|
|
61
|
+
| binary | [@helpers4/binary](https://www.npmjs.com/package/@helpers4/binary) | [Source](https://github.com/helpers4/helpers4/tree/main/helpers/binary) | Read, write and identify binary formats |
|
|
61
62
|
| browser | [@helpers4/browser](https://www.npmjs.com/package/@helpers4/browser) | [Source](https://github.com/helpers4/helpers4/tree/main/helpers/browser) | Browser-specific utilities |
|
|
62
63
|
| ci | [@helpers4/ci](https://www.npmjs.com/package/@helpers4/ci) | [Source](https://github.com/helpers4/helpers4/tree/main/helpers/ci) | CI/CD workflow status utilities |
|
|
63
64
|
| color | [@helpers4/color](https://www.npmjs.com/package/@helpers4/color) | [Source](https://github.com/helpers4/helpers4/tree/main/helpers/color) | Color conversion and validation utilities |
|
|
@@ -77,6 +78,7 @@ A set of helpers for working with URLs.
|
|
|
77
78
|
| number | [@helpers4/number](https://www.npmjs.com/package/@helpers4/number) | [Source](https://github.com/helpers4/helpers4/tree/main/helpers/number) | Number utility functions and validation |
|
|
78
79
|
| object | [@helpers4/object](https://www.npmjs.com/package/@helpers4/object) | [Source](https://github.com/helpers4/helpers4/tree/main/helpers/object) | Object manipulation utilities |
|
|
79
80
|
| observable | [@helpers4/observable](https://www.npmjs.com/package/@helpers4/observable) | [Source](https://github.com/helpers4/helpers4/tree/main/helpers/observable) | Observable utilities and combinators |
|
|
81
|
+
| package | [@helpers4/package](https://www.npmjs.com/package/@helpers4/package) | [Source](https://github.com/helpers4/helpers4/tree/main/helpers/package) | Package metadata parsers |
|
|
80
82
|
| promise | [@helpers4/promise](https://www.npmjs.com/package/@helpers4/promise) | [Source](https://github.com/helpers4/helpers4/tree/main/helpers/promise) | Promise utilities and error handling |
|
|
81
83
|
| set | [@helpers4/set](https://www.npmjs.com/package/@helpers4/set) | [Source](https://github.com/helpers4/helpers4/tree/main/helpers/set) | Native Set manipulation utilities |
|
|
82
84
|
| string | [@helpers4/string](https://www.npmjs.com/package/@helpers4/string) | [Source](https://github.com/helpers4/helpers4/tree/main/helpers/string) | String manipulation and formatting utilities |
|
package/lib/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
// helpers/license/_unknownFamily.ts
|
|
2
2
|
/**
|
|
3
3
|
* This file is part of helpers4.
|
|
4
4
|
* Copyright (C) 2025 baxyz
|
|
@@ -15,8 +15,7 @@
|
|
|
15
15
|
* @ignore
|
|
16
16
|
*/
|
|
17
17
|
var UNKNOWN_FAMILY = "unknown";
|
|
18
|
-
|
|
19
|
-
//#region helpers/license/families.ts
|
|
18
|
+
// helpers/license/families.ts
|
|
20
19
|
/**
|
|
21
20
|
* This file is part of helpers4.
|
|
22
21
|
* Copyright (C) 2025 baxyz
|
|
@@ -170,8 +169,7 @@ function families(raw) {
|
|
|
170
169
|
}
|
|
171
170
|
return result;
|
|
172
171
|
}
|
|
173
|
-
|
|
174
|
-
//#region helpers/license/agree.ts
|
|
172
|
+
// helpers/license/agree.ts
|
|
175
173
|
/**
|
|
176
174
|
* This file is part of helpers4.
|
|
177
175
|
* Copyright (C) 2025 baxyz
|
|
@@ -203,8 +201,7 @@ function agree(a, b) {
|
|
|
203
201
|
for (const family of knownA) if (knownB.has(family)) return true;
|
|
204
202
|
return false;
|
|
205
203
|
}
|
|
206
|
-
|
|
207
|
-
//#region helpers/license/isKnown.ts
|
|
204
|
+
// helpers/license/isKnown.ts
|
|
208
205
|
/**
|
|
209
206
|
* This file is part of helpers4.
|
|
210
207
|
* Copyright (C) 2025 baxyz
|
|
@@ -228,7 +225,6 @@ function isKnown(raw) {
|
|
|
228
225
|
for (const family of families(raw)) if (family !== "unknown") return true;
|
|
229
226
|
return false;
|
|
230
227
|
}
|
|
231
|
-
//#endregion
|
|
232
228
|
export { agree, families, isKnown };
|
|
233
229
|
|
|
234
230
|
//# sourceMappingURL=index.js.map
|
package/lib/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../../../helpers/license/_unknownFamily.ts","../../../helpers/license/families.ts","../../../helpers/license/agree.ts","../../../helpers/license/isKnown.ts"],"sourcesContent":["/**\n * This file is part of helpers4.\n * Copyright (C) 2025 baxyz\n * SPDX-License-Identifier: LGPL-3.0-or-later\n */\n\n/**\n * Sentinel family for a license token that carries no comparable content — `custom`, a bare\n * vendor name inside `custom:<...>`/`LicenseRef-<...>`, or an explicit \"we don't know\". Two\n * unknown tokens are never treated as either agreeing or conflicting with each other, since\n * neither is a real claim to compare against the other.\n *\n * Not exported from the package — `families()`, `agree()` and `isKnown()` already fully\n * encapsulate this concept; a consumer never needs the sentinel's actual value.\n * @ignore\n */\nexport const UNKNOWN_FAMILY = 'unknown';\n","/**\n * This file is part of helpers4.\n * Copyright (C) 2025 baxyz\n * SPDX-License-Identifier: LGPL-3.0-or-later\n */\n\nimport { UNKNOWN_FAMILY } from './_unknownFamily';\n\n// Longest/most specific alias keys first within a family so a substring match never lets a\n// shorter, less specific alias shadow a longer one that also matches the same input.\nconst FAMILY_ALIASES: Record<string, readonly string[]> = {\n mit: ['mit-0', 'mit'],\n gpl: [\n 'gpl-3.0-or-later', 'gpl-3.0-only', 'gpl-2.0-or-later', 'gpl-2.0-only',\n 'gpl-1.0-or-later', 'gpl-3.0+', 'gpl-2.0+', 'gpl-3.0', 'gpl-2.0',\n 'gplv3', 'gplv2', 'gpl3+', 'gpl3', 'gpl2', 'gpl-3', 'gpl-2', 'gpl',\n ],\n lgpl: [\n 'lgpl-3.0-or-later', 'lgpl-3.0-only', 'lgpl-2.1-or-later', 'lgpl-2.1-only',\n 'lgpl-2.0-or-later', 'lgpl-2.0-only', 'lgpl-3.0+', 'lgpl-2.1+', 'lgpl-3.0', 'lgpl-2.1',\n 'lgplv3', 'lgplv2.1', 'lgpl3', 'lgpl2.1', 'lgpl2', 'lgpl',\n ],\n agpl: ['agpl-3.0-or-later', 'agpl-3.0-only', 'agpl-3.0', 'agplv3', 'agpl3', 'agpl'],\n bsd: [\n 'bsd-3-clause', 'bsd-2-clause', '0bsd', 'bsd3', 'bsd 3-clause',\n 'bsd 2-clause', 'bsd-3', 'bsd',\n ],\n apache: ['apache-2.0', 'apache license 2.0', 'apache license, version 2.0', 'apache2', 'apache 2.0', 'apache'],\n mpl: ['mpl-2.0', 'mpl2', 'mpl'],\n artistic: ['artistic-2.0', 'artistic2.0', 'perlartistic', 'artistic'],\n isc: ['isc'],\n unlicense: ['unlicense'],\n zlib: ['zlib'],\n wtfpl: ['wtfpl'],\n php: ['php'],\n epl: ['epl'],\n cc: ['cc0-1.0', 'cc0', 'cc-by-sa-4.0', 'cc-by-nc-sa-4.0', 'cc-by-sa', 'ccpl'],\n 'public-domain': ['public domain'],\n boost: ['bsl-1.0', 'boost'],\n eupl: ['eupl-1.2', 'eupl'],\n postgresql: ['postgresql'],\n psf: ['psf-2.0', 'psf'],\n gfdl: ['gfdl-1.3', 'gfdl'],\n sspl: ['sspl-1.0', 'sspl'],\n busl: ['busl-1.1', 'busl'],\n};\n\n// Non-informative tokens — a real license claim was made, but it carries no comparable content\n// (\"custom\", a bare vendor name inside `custom:<...>`/`LicenseRef-<...>`, or an explicit \"we\n// don't know\"). Checked first, before the alias table, so e.g. \"custom:MIT\" reads as\n// UNKNOWN_FAMILY rather than incorrectly matching MIT's alias substring — a `custom:<...>`\n// convention names the *vendor's own license text*, not necessarily the SPDX license the name\n// resembles.\nconst UNKNOWN_PATTERNS = [/^custom\\b/, /^licenseref-/, /unknown/, /^none$/, /^various$/, /^unknow$/];\n\nfunction matchAlias(normalized: string): string | undefined {\n for (const [family, aliases] of Object.entries(FAMILY_ALIASES)) {\n if (aliases.includes(normalized)) return family;\n }\n return undefined;\n}\n\n// Splits an SPDX-ish compound expression (\"GPL-3.0+ AND LGPL-3.0+\", or a lowercase \"GPL-2.0+ and\n// GFDL-1.3\") into its individual license tokens. `WITH` exceptions (\"Apache-2.0 WITH\n// LLVM-exception\") are dropped entirely — the exception clause never itself resembles a distinct\n// license family, so it would otherwise either land in UNKNOWN_FAMILY for no reason or dilute the\n// comparison with a token that isn't really a separate license claim.\nfunction splitTokens(raw: string): string[] {\n // Trimmed first: otherwise a padded bare operator (\" or \") would split into empty tokens\n // while the unpadded one (\"or\") stays a single token.\n return raw\n .trim()\n .split(/\\s+(?:and|or)\\s+/i)\n .map((token) => token.split(/\\s+with\\s+/i)[0].trim())\n .filter((token) => token.length > 0);\n}\n\n/**\n * Groups a raw, possibly compound license string into its coarse family set — e.g.\n * `\"GPL-3.0-or-later AND LGPL-3.0-or-later\"` yields `{\"gpl\", \"lgpl\"}`. Two sources reporting the\n * same real license under different notation (`\"GPL3\"` vs `\"GPL-3.0-or-later\"`, `\"GPL\"` vs\n * `\"GPL2\"`) yield the same family, so they read as agreeing rather than conflicting.\n *\n * Proprietary/custom/unknown tokens all collapse to a single shared unknown-family sentinel\n * rather than each becoming their own one-off family, so a batch of otherwise-identical\n * `\"custom:<vendor>\"` strings don't look like dozens of distinct disagreeing licenses. Use\n * {@link isKnown} to check whether any real (non-sentinel) family was found.\n * @param raw - A raw license string, single (`\"MIT\"`) or compound (`\"GPL-3.0+ AND LGPL-3.0+\"`)\n * @returns The set of families found; empty only when `raw` has no tokens at all (e.g. an empty string)\n * @example\n * families('GPL3')\n * // => Set(1) { 'gpl' }\n * @example\n * families('GPL-3.0-or-later AND LGPL-3.0-or-later')\n * // => Set(2) { 'gpl', 'lgpl' }\n * @example\n * families('custom:Acme End User License')\n * // => Set(1) { 'unknown' }\n * @since 3.1.2\n */\nexport function families(raw: string): Set<string> {\n const result = new Set<string>();\n for (const token of splitTokens(raw)) {\n const normalized = token.toLowerCase();\n if (UNKNOWN_PATTERNS.some((pattern) => pattern.test(normalized))) {\n result.add(UNKNOWN_FAMILY);\n continue;\n }\n result.add(matchAlias(normalized) ?? UNKNOWN_FAMILY);\n }\n return result;\n}\n","/**\n * This file is part of helpers4.\n * Copyright (C) 2025 baxyz\n * SPDX-License-Identifier: LGPL-3.0-or-later\n */\n\nimport { UNKNOWN_FAMILY } from './_unknownFamily';\nimport { families } from './families';\n\n/**\n * Whether two raw license strings agree closely enough to count as \"no real conflict\" — true\n * when their family sets share at least one real (known) family, or when either side is entirely\n * unknown (e.g. `\"custom\"`/`\"unknown\"`) — a vague claim is never itself evidence of disagreement.\n * Only two *different*, both-known family sets (e.g. `bsd` vs `apache`) count as a real conflict.\n * @param a - The first raw license string\n * @param b - The second raw license string\n * @returns `true` when the two strings can be treated as the same license (or too vague to tell), `false` on a real family conflict\n * @example\n * agree('GPL3', 'GPL-3.0-or-later')\n * // => true\n * @example\n * agree('BSD-2-Clause', 'Apache-2.0')\n * // => false\n * @example\n * agree('custom', 'MIT')\n * // => true (a vague claim is never itself a conflict)\n * @since 3.1.2\n */\nexport function agree(a: string, b: string): boolean {\n const knownA = new Set([...families(a)].filter((f) => f !== UNKNOWN_FAMILY));\n const knownB = new Set([...families(b)].filter((f) => f !== UNKNOWN_FAMILY));\n\n if (knownA.size === 0 || knownB.size === 0) return true;\n for (const family of knownA) if (knownB.has(family)) return true;\n return false;\n}\n","/**\n * This file is part of helpers4.\n * Copyright (C) 2025 baxyz\n * SPDX-License-Identifier: LGPL-3.0-or-later\n */\n\nimport { UNKNOWN_FAMILY } from './_unknownFamily';\nimport { families } from './families';\n\n/**\n * Whether a raw license string resolves to at least one recognized family — `false` for an\n * empty string, a purely non-informative claim (`\"custom\"`, `\"unknown\"`, `\"LicenseRef-EULA\"`,\n * ...), or a compound expression where every token is non-informative.\n * @param raw - The raw license string to check\n * @returns `true` if at least one token in `raw` resolves to a real family\n * @example\n * isKnown('GPL-3.0-or-later')\n * // => true\n * @example\n * isKnown('custom:Acme End User License')\n * // => false\n * @since 3.1.2\n */\nexport function isKnown(raw: string): boolean {\n for (const family of families(raw)) {\n if (family !== UNKNOWN_FAMILY) return true;\n }\n return false;\n}\n"],"mappings":";;;;;;;;;;;;;;;;AAgBA,IAAa,iBAAiB;;;;;;;;ACN9B,IAAM,iBAAoD;CACxD,KAAK,CAAC,SAAS,KAAK;CACpB,KAAK;EACH;EAAoB;EAAgB;EAAoB;EACxD;EAAoB;EAAY;EAAY;EAAW;EACvD;EAAS;EAAS;EAAS;EAAQ;EAAQ;EAAS;EAAS;CAC/D;CACA,MAAM;EACJ;EAAqB;EAAiB;EAAqB;EAC3D;EAAqB;EAAiB;EAAa;EAAa;EAAY;EAC5E;EAAU;EAAY;EAAS;EAAW;EAAS;CACrD;CACA,MAAM;EAAC;EAAqB;EAAiB;EAAY;EAAU;EAAS;CAAM;CAClF,KAAK;EACH;EAAgB;EAAgB;EAAQ;EAAQ;EAChD;EAAgB;EAAS;CAC3B;CACA,QAAQ;EAAC;EAAc;EAAsB;EAA+B;EAAW;EAAc;CAAQ;CAC7G,KAAK;EAAC;EAAW;EAAQ;CAAK;CAC9B,UAAU;EAAC;EAAgB;EAAe;EAAgB;CAAU;CACpE,KAAK,CAAC,KAAK;CACX,WAAW,CAAC,WAAW;CACvB,MAAM,CAAC,MAAM;CACb,OAAO,CAAC,OAAO;CACf,KAAK,CAAC,KAAK;CACX,KAAK,CAAC,KAAK;CACX,IAAI;EAAC;EAAW;EAAO;EAAgB;EAAmB;EAAY;CAAM;CAC5E,iBAAiB,CAAC,eAAe;CACjC,OAAO,CAAC,WAAW,OAAO;CAC1B,MAAM,CAAC,YAAY,MAAM;CACzB,YAAY,CAAC,YAAY;CACzB,KAAK,CAAC,WAAW,KAAK;CACtB,MAAM,CAAC,YAAY,MAAM;CACzB,MAAM,CAAC,YAAY,MAAM;CACzB,MAAM,CAAC,YAAY,MAAM;AAC3B;AAQA,IAAM,mBAAmB;CAAC;CAAa;CAAgB;CAAW;CAAU;CAAa;AAAU;AAEnG,SAAS,WAAW,YAAwC;CAC1D,KAAK,MAAM,CAAC,QAAQ,YAAY,OAAO,QAAQ,cAAc,GAC3D,IAAI,QAAQ,SAAS,UAAU,GAAG,OAAO;AAG7C;AAOA,SAAS,YAAY,KAAuB;CAG1C,OAAO,IACJ,KAAK,CAAC,CACN,MAAM,mBAAmB,CAAC,CAC1B,KAAK,UAAU,MAAM,MAAM,aAAa,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CACpD,QAAQ,UAAU,MAAM,SAAS,CAAC;AACvC;;;;;;;;;;;;;;;;;;;;;;;;AAyBA,SAAgB,SAAS,KAA0B;CACjD,MAAM,yBAAS,IAAI,IAAY;CAC/B,KAAK,MAAM,SAAS,YAAY,GAAG,GAAG;EACpC,MAAM,aAAa,MAAM,YAAY;EACrC,IAAI,iBAAiB,MAAM,YAAY,QAAQ,KAAK,UAAU,CAAC,GAAG;GAChE,OAAO,IAAI,cAAc;GACzB;EACF;EACA,OAAO,IAAI,WAAW,UAAU,KAAA,SAAmB;CACrD;CACA,OAAO;AACT;;;;;;;;;;;;;;;;;;;;;;;;;;;ACnFA,SAAgB,MAAM,GAAW,GAAoB;CACnD,MAAM,SAAS,IAAI,IAAI,CAAC,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC,QAAQ,MAAM,MAAM,cAAc,CAAC;CAC3E,MAAM,SAAS,IAAI,IAAI,CAAC,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC,QAAQ,MAAM,MAAM,cAAc,CAAC;CAE3E,IAAI,OAAO,SAAS,KAAK,OAAO,SAAS,GAAG,OAAO;CACnD,KAAK,MAAM,UAAU,QAAQ,IAAI,OAAO,IAAI,MAAM,GAAG,OAAO;CAC5D,OAAO;AACT;;;;;;;;;;;;;;;;;;;;;;ACZA,SAAgB,QAAQ,KAAsB;CAC5C,KAAK,MAAM,UAAU,SAAS,GAAG,GAC/B,IAAI,WAAA,WAA2B,OAAO;CAExC,OAAO;AACT"}
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../../helpers/license/_unknownFamily.ts","../../../helpers/license/families.ts","../../../helpers/license/agree.ts","../../../helpers/license/isKnown.ts"],"sourcesContent":["/**\n * This file is part of helpers4.\n * Copyright (C) 2025 baxyz\n * SPDX-License-Identifier: LGPL-3.0-or-later\n */\n\n/**\n * Sentinel family for a license token that carries no comparable content — `custom`, a bare\n * vendor name inside `custom:<...>`/`LicenseRef-<...>`, or an explicit \"we don't know\". Two\n * unknown tokens are never treated as either agreeing or conflicting with each other, since\n * neither is a real claim to compare against the other.\n *\n * Not exported from the package — `families()`, `agree()` and `isKnown()` already fully\n * encapsulate this concept; a consumer never needs the sentinel's actual value.\n * @ignore\n */\nexport const UNKNOWN_FAMILY = 'unknown';\n","/**\n * This file is part of helpers4.\n * Copyright (C) 2025 baxyz\n * SPDX-License-Identifier: LGPL-3.0-or-later\n */\n\nimport { UNKNOWN_FAMILY } from './_unknownFamily';\n\n// Longest/most specific alias keys first within a family so a substring match never lets a\n// shorter, less specific alias shadow a longer one that also matches the same input.\nconst FAMILY_ALIASES: Record<string, readonly string[]> = {\n mit: ['mit-0', 'mit'],\n gpl: [\n 'gpl-3.0-or-later', 'gpl-3.0-only', 'gpl-2.0-or-later', 'gpl-2.0-only',\n 'gpl-1.0-or-later', 'gpl-3.0+', 'gpl-2.0+', 'gpl-3.0', 'gpl-2.0',\n 'gplv3', 'gplv2', 'gpl3+', 'gpl3', 'gpl2', 'gpl-3', 'gpl-2', 'gpl',\n ],\n lgpl: [\n 'lgpl-3.0-or-later', 'lgpl-3.0-only', 'lgpl-2.1-or-later', 'lgpl-2.1-only',\n 'lgpl-2.0-or-later', 'lgpl-2.0-only', 'lgpl-3.0+', 'lgpl-2.1+', 'lgpl-3.0', 'lgpl-2.1',\n 'lgplv3', 'lgplv2.1', 'lgpl3', 'lgpl2.1', 'lgpl2', 'lgpl',\n ],\n agpl: ['agpl-3.0-or-later', 'agpl-3.0-only', 'agpl-3.0', 'agplv3', 'agpl3', 'agpl'],\n bsd: [\n 'bsd-3-clause', 'bsd-2-clause', '0bsd', 'bsd3', 'bsd 3-clause',\n 'bsd 2-clause', 'bsd-3', 'bsd',\n ],\n apache: ['apache-2.0', 'apache license 2.0', 'apache license, version 2.0', 'apache2', 'apache 2.0', 'apache'],\n mpl: ['mpl-2.0', 'mpl2', 'mpl'],\n artistic: ['artistic-2.0', 'artistic2.0', 'perlartistic', 'artistic'],\n isc: ['isc'],\n unlicense: ['unlicense'],\n zlib: ['zlib'],\n wtfpl: ['wtfpl'],\n php: ['php'],\n epl: ['epl'],\n cc: ['cc0-1.0', 'cc0', 'cc-by-sa-4.0', 'cc-by-nc-sa-4.0', 'cc-by-sa', 'ccpl'],\n 'public-domain': ['public domain'],\n boost: ['bsl-1.0', 'boost'],\n eupl: ['eupl-1.2', 'eupl'],\n postgresql: ['postgresql'],\n psf: ['psf-2.0', 'psf'],\n gfdl: ['gfdl-1.3', 'gfdl'],\n sspl: ['sspl-1.0', 'sspl'],\n busl: ['busl-1.1', 'busl'],\n};\n\n// Non-informative tokens — a real license claim was made, but it carries no comparable content\n// (\"custom\", a bare vendor name inside `custom:<...>`/`LicenseRef-<...>`, or an explicit \"we\n// don't know\"). Checked first, before the alias table, so e.g. \"custom:MIT\" reads as\n// UNKNOWN_FAMILY rather than incorrectly matching MIT's alias substring — a `custom:<...>`\n// convention names the *vendor's own license text*, not necessarily the SPDX license the name\n// resembles.\nconst UNKNOWN_PATTERNS = [/^custom\\b/, /^licenseref-/, /unknown/, /^none$/, /^various$/, /^unknow$/];\n\nfunction matchAlias(normalized: string): string | undefined {\n for (const [family, aliases] of Object.entries(FAMILY_ALIASES)) {\n if (aliases.includes(normalized)) return family;\n }\n return undefined;\n}\n\n// Splits an SPDX-ish compound expression (\"GPL-3.0+ AND LGPL-3.0+\", or a lowercase \"GPL-2.0+ and\n// GFDL-1.3\") into its individual license tokens. `WITH` exceptions (\"Apache-2.0 WITH\n// LLVM-exception\") are dropped entirely — the exception clause never itself resembles a distinct\n// license family, so it would otherwise either land in UNKNOWN_FAMILY for no reason or dilute the\n// comparison with a token that isn't really a separate license claim.\nfunction splitTokens(raw: string): string[] {\n // Trimmed first: otherwise a padded bare operator (\" or \") would split into empty tokens\n // while the unpadded one (\"or\") stays a single token.\n return raw\n .trim()\n .split(/\\s+(?:and|or)\\s+/i)\n .map((token) => token.split(/\\s+with\\s+/i)[0].trim())\n .filter((token) => token.length > 0);\n}\n\n/**\n * Groups a raw, possibly compound license string into its coarse family set — e.g.\n * `\"GPL-3.0-or-later AND LGPL-3.0-or-later\"` yields `{\"gpl\", \"lgpl\"}`. Two sources reporting the\n * same real license under different notation (`\"GPL3\"` vs `\"GPL-3.0-or-later\"`, `\"GPL\"` vs\n * `\"GPL2\"`) yield the same family, so they read as agreeing rather than conflicting.\n *\n * Proprietary/custom/unknown tokens all collapse to a single shared unknown-family sentinel\n * rather than each becoming their own one-off family, so a batch of otherwise-identical\n * `\"custom:<vendor>\"` strings don't look like dozens of distinct disagreeing licenses. Use\n * {@link isKnown} to check whether any real (non-sentinel) family was found.\n * @param raw - A raw license string, single (`\"MIT\"`) or compound (`\"GPL-3.0+ AND LGPL-3.0+\"`)\n * @returns The set of families found; empty only when `raw` has no tokens at all (e.g. an empty string)\n * @example\n * families('GPL3')\n * // => Set(1) { 'gpl' }\n * @example\n * families('GPL-3.0-or-later AND LGPL-3.0-or-later')\n * // => Set(2) { 'gpl', 'lgpl' }\n * @example\n * families('custom:Acme End User License')\n * // => Set(1) { 'unknown' }\n * @since 3.1.2\n */\nexport function families(raw: string): Set<string> {\n const result = new Set<string>();\n for (const token of splitTokens(raw)) {\n const normalized = token.toLowerCase();\n if (UNKNOWN_PATTERNS.some((pattern) => pattern.test(normalized))) {\n result.add(UNKNOWN_FAMILY);\n continue;\n }\n result.add(matchAlias(normalized) ?? UNKNOWN_FAMILY);\n }\n return result;\n}\n","/**\n * This file is part of helpers4.\n * Copyright (C) 2025 baxyz\n * SPDX-License-Identifier: LGPL-3.0-or-later\n */\n\nimport { UNKNOWN_FAMILY } from './_unknownFamily';\nimport { families } from './families';\n\n/**\n * Whether two raw license strings agree closely enough to count as \"no real conflict\" — true\n * when their family sets share at least one real (known) family, or when either side is entirely\n * unknown (e.g. `\"custom\"`/`\"unknown\"`) — a vague claim is never itself evidence of disagreement.\n * Only two *different*, both-known family sets (e.g. `bsd` vs `apache`) count as a real conflict.\n * @param a - The first raw license string\n * @param b - The second raw license string\n * @returns `true` when the two strings can be treated as the same license (or too vague to tell), `false` on a real family conflict\n * @example\n * agree('GPL3', 'GPL-3.0-or-later')\n * // => true\n * @example\n * agree('BSD-2-Clause', 'Apache-2.0')\n * // => false\n * @example\n * agree('custom', 'MIT')\n * // => true (a vague claim is never itself a conflict)\n * @since 3.1.2\n */\nexport function agree(a: string, b: string): boolean {\n const knownA = new Set([...families(a)].filter((f) => f !== UNKNOWN_FAMILY));\n const knownB = new Set([...families(b)].filter((f) => f !== UNKNOWN_FAMILY));\n\n if (knownA.size === 0 || knownB.size === 0) return true;\n for (const family of knownA) if (knownB.has(family)) return true;\n return false;\n}\n","/**\n * This file is part of helpers4.\n * Copyright (C) 2025 baxyz\n * SPDX-License-Identifier: LGPL-3.0-or-later\n */\n\nimport { UNKNOWN_FAMILY } from './_unknownFamily';\nimport { families } from './families';\n\n/**\n * Whether a raw license string resolves to at least one recognized family — `false` for an\n * empty string, a purely non-informative claim (`\"custom\"`, `\"unknown\"`, `\"LicenseRef-EULA\"`,\n * ...), or a compound expression where every token is non-informative.\n * @param raw - The raw license string to check\n * @returns `true` if at least one token in `raw` resolves to a real family\n * @example\n * isKnown('GPL-3.0-or-later')\n * // => true\n * @example\n * isKnown('custom:Acme End User License')\n * // => false\n * @since 3.1.2\n */\nexport function isKnown(raw: string): boolean {\n for (const family of families(raw)) {\n if (family !== UNKNOWN_FAMILY) return true;\n }\n return false;\n}\n"],"mappings":";;;;;;;;;;;;;;;;AAgBA,IAAa,iBAAiB;;;;;;;ACN9B,IAAM,iBAAoD;CACxD,KAAK,CAAC,SAAS,KAAK;CACpB,KAAK;EACH;EAAoB;EAAgB;EAAoB;EACxD;EAAoB;EAAY;EAAY;EAAW;EACvD;EAAS;EAAS;EAAS;EAAQ;EAAQ;EAAS;EAAS;CAC/D;CACA,MAAM;EACJ;EAAqB;EAAiB;EAAqB;EAC3D;EAAqB;EAAiB;EAAa;EAAa;EAAY;EAC5E;EAAU;EAAY;EAAS;EAAW;EAAS;CACrD;CACA,MAAM;EAAC;EAAqB;EAAiB;EAAY;EAAU;EAAS;CAAM;CAClF,KAAK;EACH;EAAgB;EAAgB;EAAQ;EAAQ;EAChD;EAAgB;EAAS;CAC3B;CACA,QAAQ;EAAC;EAAc;EAAsB;EAA+B;EAAW;EAAc;CAAQ;CAC7G,KAAK;EAAC;EAAW;EAAQ;CAAK;CAC9B,UAAU;EAAC;EAAgB;EAAe;EAAgB;CAAU;CACpE,KAAK,CAAC,KAAK;CACX,WAAW,CAAC,WAAW;CACvB,MAAM,CAAC,MAAM;CACb,OAAO,CAAC,OAAO;CACf,KAAK,CAAC,KAAK;CACX,KAAK,CAAC,KAAK;CACX,IAAI;EAAC;EAAW;EAAO;EAAgB;EAAmB;EAAY;CAAM;CAC5E,iBAAiB,CAAC,eAAe;CACjC,OAAO,CAAC,WAAW,OAAO;CAC1B,MAAM,CAAC,YAAY,MAAM;CACzB,YAAY,CAAC,YAAY;CACzB,KAAK,CAAC,WAAW,KAAK;CACtB,MAAM,CAAC,YAAY,MAAM;CACzB,MAAM,CAAC,YAAY,MAAM;CACzB,MAAM,CAAC,YAAY,MAAM;AAC3B;AAQA,IAAM,mBAAmB;CAAC;CAAa;CAAgB;CAAW;CAAU;CAAa;AAAU;AAEnG,SAAS,WAAW,YAAwC;CAC1D,KAAK,MAAM,CAAC,QAAQ,YAAY,OAAO,QAAQ,cAAc,GAC3D,IAAI,QAAQ,SAAS,UAAU,GAAG,OAAO;AAG7C;AAOA,SAAS,YAAY,KAAuB;CAG1C,OAAO,IACJ,KAAK,CAAC,CACN,MAAM,mBAAmB,CAAC,CAC1B,KAAK,UAAU,MAAM,MAAM,aAAa,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CACpD,QAAQ,UAAU,MAAM,SAAS,CAAC;AACvC;;;;;;;;;;;;;;;;;;;;;;;;AAyBA,SAAgB,SAAS,KAA0B;CACjD,MAAM,yBAAS,IAAI,IAAY;CAC/B,KAAK,MAAM,SAAS,YAAY,GAAG,GAAG;EACpC,MAAM,aAAa,MAAM,YAAY;EACrC,IAAI,iBAAiB,MAAM,YAAY,QAAQ,KAAK,UAAU,CAAC,GAAG;GAChE,OAAO,IAAI,cAAc;GACzB;EACF;EACA,OAAO,IAAI,WAAW,UAAU,KAAA,SAAmB;CACrD;CACA,OAAO;AACT;;;;;;;;;;;;;;;;;;;;;;;;;;ACnFA,SAAgB,MAAM,GAAW,GAAoB;CACnD,MAAM,SAAS,IAAI,IAAI,CAAC,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC,QAAQ,MAAM,MAAM,cAAc,CAAC;CAC3E,MAAM,SAAS,IAAI,IAAI,CAAC,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC,QAAQ,MAAM,MAAM,cAAc,CAAC;CAE3E,IAAI,OAAO,SAAS,KAAK,OAAO,SAAS,GAAG,OAAO;CACnD,KAAK,MAAM,UAAU,QAAQ,IAAI,OAAO,IAAI,MAAM,GAAG,OAAO;CAC5D,OAAO;AACT;;;;;;;;;;;;;;;;;;;;;ACZA,SAAgB,QAAQ,KAAsB;CAC5C,KAAK,MAAM,UAAU,SAAS,GAAG,GAC/B,IAAI,WAAA,WAA2B,OAAO;CAExC,OAAO;AACT"}
|
package/llms.txt
CHANGED
package/meta/api.json
CHANGED
package/package.json
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@helpers4/license",
|
|
3
|
-
"version": "3.1.
|
|
3
|
+
"version": "3.1.10",
|
|
4
4
|
"description": "A set of helpers in TS/JS, compatible with tree-shaking, for license.",
|
|
5
5
|
"author": "baxyz <craft@baxyz.dev>",
|
|
6
|
-
"license": "LGPL-3.0",
|
|
6
|
+
"license": "LGPL-3.0-or-later",
|
|
7
7
|
"homepage": "https://helpers4.dev/typescript/categories/license/",
|
|
8
8
|
"repository": {
|
|
9
9
|
"type": "git",
|