@ms-cloudpack/esbuild-node-helpers 0.1.5 → 0.1.7
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/lib/bundleNode.d.ts.map +1 -1
- package/lib/bundleNode.js +9 -8
- package/lib/bundleNode.js.map +1 -1
- package/lib/license/analyzeLicenses.js +1 -1
- package/lib/license/analyzeLicenses.js.map +1 -1
- package/lib/license/writeNotice.d.ts.map +1 -1
- package/lib/license/writeNotice.js +3 -1
- package/lib/license/writeNotice.js.map +1 -1
- package/package.json +1 -1
package/lib/bundleNode.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bundleNode.d.ts","sourceRoot":"","sources":["../src/bundleNode.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,OAAO,MAAM,SAAS,CAAC;AAInC,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAK/D,OAAO,EAAqB,KAAK,wBAAwB,EAAE,MAAM,8BAA8B,CAAC;AAEhG,MAAM,WAAW,iBACf,SAAQ,wBAAwB,EAAE,IAAI,CAAC,oBAAoB,EAAE,yBAAyB,GAAG,mBAAmB,CAAC;IAC7G,2FAA2F;IAC3F,GAAG,EAAE,MAAM,CAAC;IAEZ,8FAA8F;IAC9F,KAAK,CAAC,EAAE,OAAO,CAAC;IAEhB,gCAAgC;IAChC,cAAc,CAAC,EAAE,IAAI,CACnB,OAAO,CAAC,YAAY,EACpB,eAAe,GAAG,QAAQ,GAAG,aAAa,GAAG,UAAU,GAAG,QAAQ,GAAG,UAAU,CAChF,CAAC;IAEF,0EAA0E;IAC1E,iBAAiB,CAAC,EAAE,MAAM,EAAE,CAAC;IAE7B,wFAAwF;IACxF,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;
|
|
1
|
+
{"version":3,"file":"bundleNode.d.ts","sourceRoot":"","sources":["../src/bundleNode.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,OAAO,MAAM,SAAS,CAAC;AAInC,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAK/D,OAAO,EAAqB,KAAK,wBAAwB,EAAE,MAAM,8BAA8B,CAAC;AAEhG,MAAM,WAAW,iBACf,SAAQ,wBAAwB,EAAE,IAAI,CAAC,oBAAoB,EAAE,yBAAyB,GAAG,mBAAmB,CAAC;IAC7G,2FAA2F;IAC3F,GAAG,EAAE,MAAM,CAAC;IAEZ,8FAA8F;IAC9F,KAAK,CAAC,EAAE,OAAO,CAAC;IAEhB,gCAAgC;IAChC,cAAc,CAAC,EAAE,IAAI,CACnB,OAAO,CAAC,YAAY,EACpB,eAAe,GAAG,QAAQ,GAAG,aAAa,GAAG,UAAU,GAAG,QAAQ,GAAG,UAAU,CAChF,CAAC;IAEF,0EAA0E;IAC1E,iBAAiB,CAAC,EAAE,MAAM,EAAE,CAAC;IAE7B,wFAAwF;IACxF,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAkBD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAsB,UAAU,CAAC,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC,CA2G1E"}
|
package/lib/bundleNode.js
CHANGED
|
@@ -12,15 +12,16 @@ import { verifyPackageJson } from "./utils/verifyPackageJson.js";
|
|
|
12
12
|
* We need `require()` for bundled CJS that loads Node internals or native packages.
|
|
13
13
|
* The bundled CJS deps also use `__filename` and `__dirname` in a couple places.
|
|
14
14
|
* https://github.com/evanw/esbuild/issues/946#issuecomment-814703190
|
|
15
|
+
*
|
|
16
|
+
* `var` is used instead of `const` to avoid re-declaration issues if a bundled package applies the
|
|
17
|
+
* same workaround. The odd `createRequire` import name is for similar reasons.
|
|
15
18
|
*/
|
|
16
|
-
const
|
|
19
|
+
const cjsGlobalsHeader = `// @ts-nocheck
|
|
17
20
|
/* eslint-disable */
|
|
18
|
-
import { createRequire as
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
const __filename = topLevelUrl.fileURLToPath(import.meta.url);
|
|
23
|
-
const __dirname = topLevelPath.dirname(__filename);`;
|
|
21
|
+
import { createRequire as esbuildNodeHelpersCreateRequire } from 'node:module';
|
|
22
|
+
var require = esbuildNodeHelpersCreateRequire(import.meta.url);
|
|
23
|
+
var __filename = import.meta.filename;
|
|
24
|
+
var __dirname = import.meta.dirname;`;
|
|
24
25
|
/**
|
|
25
26
|
* Bundle a node package with esbuild. By default it creates an ESM bundle for Node 22+.
|
|
26
27
|
* `dependencies` will be externalized, but all other referenced deps will be bundled.
|
|
@@ -53,7 +54,7 @@ export async function bundleNode(options) {
|
|
|
53
54
|
}
|
|
54
55
|
// The header defining require() is needed with ESM output, but not if the user changed the format
|
|
55
56
|
const format = esbuildOptions?.format ?? 'esm';
|
|
56
|
-
const jsBanner = format === 'esm' ?
|
|
57
|
+
const jsBanner = format === 'esm' ? cjsGlobalsHeader : undefined;
|
|
57
58
|
let result;
|
|
58
59
|
try {
|
|
59
60
|
result = await esbuild.build({
|
package/lib/bundleNode.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bundleNode.js","sourceRoot":"","sources":["../src/bundleNode.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,OAAO,MAAM,SAAS,CAAC;AACnC,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAE3D,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AACrD,OAAO,EAAE,qBAAqB,EAAE,MAAM,kCAAkC,CAAC;AACzE,OAAO,EAAE,mBAAmB,EAAE,MAAM,gCAAgC,CAAC;AACrE,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAE,iBAAiB,EAAiC,MAAM,8BAA8B,CAAC;AAuBhG;;;;;GAKG;AACH,MAAM,aAAa,GAAG;;;;;;;oDAO8B,CAAC;AAErD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,OAA0B;IACzD,MAAM,EAAE,GAAG,EAAE,WAAW,EAAE,MAAM,EAAE,SAAS,EAAE,iBAAiB,EAAE,cAAc,EAAE,KAAK,GAAG,IAAI,EAAE,GAAG,OAAO,CAAC;IAEzG,OAAO,CAAC,GAAG,EAAE,CAAC;IACd,OAAO,CAAC,GAAG,CAAC,oCAAoC,CAAC,CAAC;IAElD,MAAM,EAAE,WAAW,EAAE,WAAW,EAAE,GAAG,mBAAmB,CAAC,GAAG,CAAC,CAAC;IAE9D,iBAAiB,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC;IAExC,IAAI,KAAK,EAAE,CAAC;QACV,kFAAkF;QAClF,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,MAAM,CAAC,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC9E,CAAC;IAED,kGAAkG;IAClG,MAAM,MAAM,GAAG,cAAc,EAAE,MAAM,IAAI,KAAK,CAAC;IAC/C,MAAM,QAAQ,GAAG,MAAM,KAAK,KAAK,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,SAAS,CAAC;IAE9D,IAAI,MAAsE,CAAC;IAC3E,IAAI,CAAC;QACH,MAAM,GAAG,MAAM,OAAO,CAAC,KAAK,CAAC;YAC3B,SAAS,EAAE,MAAM,KAAK,KAAK;YAC3B,WAAW,EAAE,IAAI;YACjB,MAAM,EAAE,CAAC,QAAQ,CAAC;YAClB,4DAA4D;YAC5D,SAAS,EAAE,IAAI;YACf,6EAA6E;YAC7E,QAAQ,EAAE,MAAM;YAChB,2DAA2D;YAC3D,mBAAmB;YAEnB,GAAG,cAAc;YAEjB,mBAAmB;YACnB,aAAa,EAAE,WAAW;YAC1B,WAAW,EAAE,WAAW;YACxB,MAAM,EAAE,MAAM;YACd,QAAQ,EAAE,MAAM;YAChB,MAAM,EAAE,IAAI;YACZ,MAAM;YACN,yFAAyF;YACzF,oFAAoF;YACpF,oFAAoF;YACpF,QAAQ,EAAE;gBACR,GAAG,MAAM,CAAC,IAAI,CAAC;oBACb,GAAG,WAAW,CAAC,YAAY;oBAC3B,GAAG,WAAW,CAAC,gBAAgB;oBAC/B,GAAG,WAAW,CAAC,oBAAoB;iBACpC,CAAC;gBACF,GAAG,CAAC,cAAc,EAAE,QAAQ,IAAI,EAAE,CAAC;aACpC;YACD,OAAO,EAAE;gBACP,aAAa,CAAC;oBACZ,WAAW,EAAE,WAAW,CAAC,IAAI;oBAC7B,WAAW;oBACX,SAAS,EAAE,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC,WAAW;oBACtE,uBAAuB,EAAE,OAAO,CAAC,uBAAuB;oBACxD,iBAAiB,EAAE,OAAO,CAAC,iBAAiB;iBAC7C,CAAC;gBACF,GAAG,CAAC,cAAc,EAAE,OAAO,IAAI,EAAE,CAAC;aACnC;YACD,MAAM,EAAE;gBACN,GAAG,cAAc,EAAE,MAAM;gBACzB,EAAE,EAAE,CAAC,cAAc,EAAE,MAAM,EAAE,EAAE,EAAE,QAAQ,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;aACtE;YACD,QAAQ,EAAE,IAAI;SACf,CAAC,CAAC;IACL,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,OAAO,GAAG,GAA2B,CAAC;QAC5C,IAAI,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,mBAAmB,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC;YAC5G,OAAO,CAAC,GAAG,CACT,KAAK,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,+DAA+D;gBAClG,uEAAuE;gBACvE,wCAAwC,MAAM,CAAC,IAAI,CAAC,8BAA8B,CAAC,MAAM;gBACzF,yFAAyF,CAC5F,CAAC;QACJ,CAAC;QACD,MAAM,GAAG,GAAG,wBAAwB,OAAO,CAAC,MAAM,CAAC,MAAM,YAAY,CAAC;QACtE,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;QAC9C,MAAM,IAAI,WAAW,CAAC,GAAG,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,CAAC;IAClE,CAAC;IAED,IAAI,OAAO,CAAC,aAAa,EAAE,CAAC;QAC1B,0DAA0D;QAC1D,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;QAC9C,EAAE,CAAC,SAAS,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,0BAA0B;QACrE,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,uBAAuB,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;QACvG,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,eAAe,CAAC,MAAM,CAAC,QAAQ,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;QACnF,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,+BAA+B,CAAC,EAAE,QAAQ,CAAC,CAAC;IACjF,CAAC;IAED,kDAAkD;IAClD,MAAM,EAAE,aAAa,EAAE,YAAY,EAAE,gBAAgB,EAAE,GAAG,qBAAqB,CAC7E,WAAW,EACX,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,EACnC,iBAAiB,CAClB,CAAC;IACF,IAAI,aAAa,CAAC,MAAM,IAAI,gBAAgB,CAAC,MAAM,EAAE,CAAC;QACpD,MAAM,IAAI,WAAW,CAAC,6CAA6C,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;IAChG,CAAC;IACD,MAAM,eAAe,GAAG,CAAC,CAAC,YAAY,CAAC,MAAM,CAAC;IAE9C,MAAM,WAAW,GAAG,eAAe,IAAI,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC;IAChE,MAAM,KAAK,GAAG,WAAW,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC;IAC/C,sEAAsE;IACtE,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,qBAAqB,WAAW,CAAC,CAAC,CAAC,4BAA4B,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;AACrH,CAAC","sourcesContent":["import * as esbuild from 'esbuild';\nimport fs from 'fs';\nimport path from 'path';\nimport { licensePlugin } from './license/licensePlugin.ts';\nimport type { LicensePluginOptions } from './license/types.ts';\nimport { BundleError } from './utils/BundleError.ts';\nimport { checkForDuplicateDeps } from './utils/checkForDuplicateDeps.ts';\nimport { findRealPackageJson } from './utils/findRealPackageJson.ts';\nimport { colors, logError } from './utils/logHelpers.ts';\nimport { verifyPackageJson, type VerifyPackageJsonOptions } from './utils/verifyPackageJson.ts';\n\nexport interface BundleNodeOptions\n extends VerifyPackageJsonOptions, Pick<LicensePluginOptions, 'unacceptableLicenseTest' | 'excludeFromNotice'> {\n /** Working directory, usually the package root (it will find the actual root from here) */\n cwd: string;\n\n /** Clean output before building (highly recommended due to hashed filenames) @default true */\n clean?: boolean;\n\n /** Extra options for esbuild */\n esbuildOptions?: Omit<\n esbuild.BuildOptions,\n 'absWorkingDir' | 'bundle' | 'entryPoints' | 'metafile' | 'outdir' | 'platform'\n >;\n\n /** Error if there are duplicate packages matching any of these regexps */\n errorDupePackages?: RegExp[];\n\n /** If true, write esbuild's metafile and analysis to disk under `<packageRoot>/temp` */\n writeMetafile?: boolean;\n}\n\n/**\n * This is added at the top of every file and makes CJS globals work in esbuild output.\n * We need `require()` for bundled CJS that loads Node internals or native packages.\n * The bundled CJS deps also use `__filename` and `__dirname` in a couple places.\n * https://github.com/evanw/esbuild/issues/946#issuecomment-814703190\n */\nconst requireHeader = `// @ts-nocheck\n/* eslint-disable */\nimport { createRequire as topLevelCreateRequire } from 'node:module';\nimport topLevelPath from 'node:path';\nimport topLevelUrl from 'node:url';\nconst require = topLevelCreateRequire(import.meta.url);\nconst __filename = topLevelUrl.fileURLToPath(import.meta.url);\nconst __dirname = topLevelPath.dirname(__filename);`;\n\n/**\n * Bundle a node package with esbuild. By default it creates an ESM bundle for Node 22+.\n * `dependencies` will be externalized, but all other referenced deps will be bundled.\n *\n * It also writes a `NOTICE.txt` file at the package root with license information for dependencies\n * from outside the current repo, and if `options.unacceptableLicenseTest` is provided, errors if\n * any packages have disallowed licenses. It also errors if a package is missing license info.\n *\n * Before bundling, it checks for proper configuration of `package.json`:\n * - `NOTICE.txt` and the output directory are included in `files`\n * - If `verifyExportPaths` is set, `exports` are correctly mapped\n * - If `verifyTypesInFiles` is true, `lib/** /*.d.ts` is included in `files`\n *\n * After bundling, it checks for duplicate dependencies:\n * - Always error if there are multiple copies of the same version of a dependency\n * - Optionally error if any dependencies match the regexps provided in `errorDupePackages`\n *\n * (Some of the current logic and messages assume the consuming repo is using yarn v4, likely\n * with `nodeLinker: 'pnpm'`, but it can be updated as needed for other linkers and/or managers.)\n */\nexport async function bundleNode(options: BundleNodeOptions): Promise<void> {\n const { cwd, entryPoints, outDir, noticeDir, errorDupePackages, esbuildOptions, clean = true } = options;\n\n console.log();\n console.log('Bundling package with esbuild...\\n');\n\n const { packageJson, packageRoot } = findRealPackageJson(cwd);\n\n verifyPackageJson(options, packageJson);\n\n if (clean) {\n // Remove old output. This is more important with esbuild due to hashed filenames.\n fs.rmSync(path.join(packageRoot, outDir), { force: true, recursive: true });\n }\n\n // The header defining require() is needed with ESM output, but not if the user changed the format\n const format = esbuildOptions?.format ?? 'esm';\n const jsBanner = format === 'esm' ? requireHeader : undefined;\n\n let result: esbuild.BuildResult<esbuild.BuildOptions & { metafile: true }>;\n try {\n result = await esbuild.build({\n splitting: format === 'esm',\n treeShaking: true,\n target: ['node22'],\n // some packages rely on specific names in instanceof checks\n keepNames: true,\n // log errors, warnings, and a summary (which includes the output file sizes)\n logLevel: 'info',\n // less important if not minifying, and bloats package size\n // sourcemap: true,\n\n ...esbuildOptions,\n\n // Critical options\n absWorkingDir: packageRoot,\n entryPoints: entryPoints,\n outdir: outDir,\n platform: 'node',\n bundle: true,\n format,\n // Exclude non-dev dependencies from the bundle. In a bundled package, generally the only\n // dependencies should be other internal packages and anything with native binaries.\n // (It appears node built-ins are automatically externalized with platform: 'node'.)\n external: [\n ...Object.keys({\n ...packageJson.dependencies,\n ...packageJson.peerDependencies,\n ...packageJson.optionalDependencies,\n }),\n ...(esbuildOptions?.external || []),\n ],\n plugins: [\n licensePlugin({\n packageName: packageJson.name,\n packageRoot,\n absOutDir: noticeDir ? path.join(packageRoot, noticeDir) : packageRoot,\n unacceptableLicenseTest: options.unacceptableLicenseTest,\n excludeFromNotice: options.excludeFromNotice,\n }),\n ...(esbuildOptions?.plugins || []),\n ],\n banner: {\n ...esbuildOptions?.banner,\n js: [esbuildOptions?.banner?.js, jsBanner].filter(Boolean).join('\\n'),\n },\n metafile: true,\n });\n } catch (err) {\n const failure = err as esbuild.BuildFailure;\n if (failure.errors.some((e) => e.text.includes('Could not resolve') && e.location?.file.includes('.store'))) {\n console.log(\n `\\n${colors.red(colors.bold('NOTE:'))} Packages that could not be found are usually missing peers, ` +\n `which may not be specified properly for strict installation layouts. ` +\n `You can work around this by updating ${colors.bold('yarnrc.yml packageExtensions')} to ` +\n `include the missing package as a dependency or peerDependency of the importing package.`,\n );\n }\n const msg = `Bundling failed with ${failure.errors.length} error(s)!`;\n logError(colors.red(colors.bold(msg + '\\n')));\n throw new BundleError(msg, { alreadyLogged: true, cause: err });\n }\n\n if (options.writeMetafile) {\n // Write the metafile and analysis to disk for inspection.\n const tmpDir = path.join(packageRoot, 'temp');\n fs.mkdirSync(tmpDir, { recursive: true }); // do nothing if it exists\n fs.writeFileSync(path.join(tmpDir, 'esbuild-metafile.json'), JSON.stringify(result.metafile, null, 2));\n const analysis = await esbuild.analyzeMetafile(result.metafile, { verbose: true });\n fs.writeFileSync(path.join(tmpDir, 'esbuild-metafile-analysis.txt'), analysis);\n }\n\n // Check for duplicate dependencies in the bundle.\n const { errorDupeDeps, warnDupeDeps, sameVersionDupes } = checkForDuplicateDeps(\n packageRoot,\n Object.keys(result.metafile.inputs),\n errorDupePackages,\n );\n if (errorDupeDeps.length || sameVersionDupes.length) {\n throw new BundleError('Duplicate dependencies detected (see above)', { alreadyLogged: true });\n }\n const hasDupeWarnings = !!warnDupeDeps.length;\n\n const hasWarnings = hasDupeWarnings || !!result.warnings.length;\n const color = hasWarnings ? 'yellow' : 'green';\n // With logLevel set to 'info', esbuild will handle the basic logging.\n console.log(colors[color](colors.bold(`Bundling completed${hasWarnings ? ' with warnings (see above)' : '!'}\\n`)));\n}\n"]}
|
|
1
|
+
{"version":3,"file":"bundleNode.js","sourceRoot":"","sources":["../src/bundleNode.ts"],"names":[],"mappings":"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","sourcesContent":["import * as esbuild from 'esbuild';\nimport fs from 'fs';\nimport path from 'path';\nimport { licensePlugin } from './license/licensePlugin.ts';\nimport type { LicensePluginOptions } from './license/types.ts';\nimport { BundleError } from './utils/BundleError.ts';\nimport { checkForDuplicateDeps } from './utils/checkForDuplicateDeps.ts';\nimport { findRealPackageJson } from './utils/findRealPackageJson.ts';\nimport { colors, logError } from './utils/logHelpers.ts';\nimport { verifyPackageJson, type VerifyPackageJsonOptions } from './utils/verifyPackageJson.ts';\n\nexport interface BundleNodeOptions\n extends VerifyPackageJsonOptions, Pick<LicensePluginOptions, 'unacceptableLicenseTest' | 'excludeFromNotice'> {\n /** Working directory, usually the package root (it will find the actual root from here) */\n cwd: string;\n\n /** Clean output before building (highly recommended due to hashed filenames) @default true */\n clean?: boolean;\n\n /** Extra options for esbuild */\n esbuildOptions?: Omit<\n esbuild.BuildOptions,\n 'absWorkingDir' | 'bundle' | 'entryPoints' | 'metafile' | 'outdir' | 'platform'\n >;\n\n /** Error if there are duplicate packages matching any of these regexps */\n errorDupePackages?: RegExp[];\n\n /** If true, write esbuild's metafile and analysis to disk under `<packageRoot>/temp` */\n writeMetafile?: boolean;\n}\n\n/**\n * This is added at the top of every file and makes CJS globals work in esbuild output.\n * We need `require()` for bundled CJS that loads Node internals or native packages.\n * The bundled CJS deps also use `__filename` and `__dirname` in a couple places.\n * https://github.com/evanw/esbuild/issues/946#issuecomment-814703190\n *\n * `var` is used instead of `const` to avoid re-declaration issues if a bundled package applies the\n * same workaround. The odd `createRequire` import name is for similar reasons.\n */\nconst cjsGlobalsHeader: string = `// @ts-nocheck\n/* eslint-disable */\nimport { createRequire as esbuildNodeHelpersCreateRequire } from 'node:module';\nvar require = esbuildNodeHelpersCreateRequire(import.meta.url);\nvar __filename = import.meta.filename;\nvar __dirname = import.meta.dirname;`;\n\n/**\n * Bundle a node package with esbuild. By default it creates an ESM bundle for Node 22+.\n * `dependencies` will be externalized, but all other referenced deps will be bundled.\n *\n * It also writes a `NOTICE.txt` file at the package root with license information for dependencies\n * from outside the current repo, and if `options.unacceptableLicenseTest` is provided, errors if\n * any packages have disallowed licenses. It also errors if a package is missing license info.\n *\n * Before bundling, it checks for proper configuration of `package.json`:\n * - `NOTICE.txt` and the output directory are included in `files`\n * - If `verifyExportPaths` is set, `exports` are correctly mapped\n * - If `verifyTypesInFiles` is true, `lib/** /*.d.ts` is included in `files`\n *\n * After bundling, it checks for duplicate dependencies:\n * - Always error if there are multiple copies of the same version of a dependency\n * - Optionally error if any dependencies match the regexps provided in `errorDupePackages`\n *\n * (Some of the current logic and messages assume the consuming repo is using yarn v4, likely\n * with `nodeLinker: 'pnpm'`, but it can be updated as needed for other linkers and/or managers.)\n */\nexport async function bundleNode(options: BundleNodeOptions): Promise<void> {\n const { cwd, entryPoints, outDir, noticeDir, errorDupePackages, esbuildOptions, clean = true } = options;\n\n console.log();\n console.log('Bundling package with esbuild...\\n');\n\n const { packageJson, packageRoot } = findRealPackageJson(cwd);\n\n verifyPackageJson(options, packageJson);\n\n if (clean) {\n // Remove old output. This is more important with esbuild due to hashed filenames.\n fs.rmSync(path.join(packageRoot, outDir), { force: true, recursive: true });\n }\n\n // The header defining require() is needed with ESM output, but not if the user changed the format\n const format = esbuildOptions?.format ?? 'esm';\n const jsBanner = format === 'esm' ? cjsGlobalsHeader : undefined;\n\n let result: esbuild.BuildResult<esbuild.BuildOptions & { metafile: true }>;\n try {\n result = await esbuild.build({\n splitting: format === 'esm',\n treeShaking: true,\n target: ['node22'],\n // some packages rely on specific names in instanceof checks\n keepNames: true,\n // log errors, warnings, and a summary (which includes the output file sizes)\n logLevel: 'info',\n // less important if not minifying, and bloats package size\n // sourcemap: true,\n\n ...esbuildOptions,\n\n // Critical options\n absWorkingDir: packageRoot,\n entryPoints: entryPoints,\n outdir: outDir,\n platform: 'node',\n bundle: true,\n format,\n // Exclude non-dev dependencies from the bundle. In a bundled package, generally the only\n // dependencies should be other internal packages and anything with native binaries.\n // (It appears node built-ins are automatically externalized with platform: 'node'.)\n external: [\n ...Object.keys({\n ...packageJson.dependencies,\n ...packageJson.peerDependencies,\n ...packageJson.optionalDependencies,\n }),\n ...(esbuildOptions?.external || []),\n ],\n plugins: [\n licensePlugin({\n packageName: packageJson.name,\n packageRoot,\n absOutDir: noticeDir ? path.join(packageRoot, noticeDir) : packageRoot,\n unacceptableLicenseTest: options.unacceptableLicenseTest,\n excludeFromNotice: options.excludeFromNotice,\n }),\n ...(esbuildOptions?.plugins || []),\n ],\n banner: {\n ...esbuildOptions?.banner,\n js: [esbuildOptions?.banner?.js, jsBanner].filter(Boolean).join('\\n'),\n },\n metafile: true,\n });\n } catch (err) {\n const failure = err as esbuild.BuildFailure;\n if (failure.errors.some((e) => e.text.includes('Could not resolve') && e.location?.file.includes('.store'))) {\n console.log(\n `\\n${colors.red(colors.bold('NOTE:'))} Packages that could not be found are usually missing peers, ` +\n `which may not be specified properly for strict installation layouts. ` +\n `You can work around this by updating ${colors.bold('yarnrc.yml packageExtensions')} to ` +\n `include the missing package as a dependency or peerDependency of the importing package.`,\n );\n }\n const msg = `Bundling failed with ${failure.errors.length} error(s)!`;\n logError(colors.red(colors.bold(msg + '\\n')));\n throw new BundleError(msg, { alreadyLogged: true, cause: err });\n }\n\n if (options.writeMetafile) {\n // Write the metafile and analysis to disk for inspection.\n const tmpDir = path.join(packageRoot, 'temp');\n fs.mkdirSync(tmpDir, { recursive: true }); // do nothing if it exists\n fs.writeFileSync(path.join(tmpDir, 'esbuild-metafile.json'), JSON.stringify(result.metafile, null, 2));\n const analysis = await esbuild.analyzeMetafile(result.metafile, { verbose: true });\n fs.writeFileSync(path.join(tmpDir, 'esbuild-metafile-analysis.txt'), analysis);\n }\n\n // Check for duplicate dependencies in the bundle.\n const { errorDupeDeps, warnDupeDeps, sameVersionDupes } = checkForDuplicateDeps(\n packageRoot,\n Object.keys(result.metafile.inputs),\n errorDupePackages,\n );\n if (errorDupeDeps.length || sameVersionDupes.length) {\n throw new BundleError('Duplicate dependencies detected (see above)', { alreadyLogged: true });\n }\n const hasDupeWarnings = !!warnDupeDeps.length;\n\n const hasWarnings = hasDupeWarnings || !!result.warnings.length;\n const color = hasWarnings ? 'yellow' : 'green';\n // With logLevel set to 'info', esbuild will handle the basic logging.\n console.log(colors[color](colors.bold(`Bundling completed${hasWarnings ? ' with warnings (see above)' : '!'}\\n`)));\n}\n"]}
|
|
@@ -36,7 +36,7 @@ export function analyzeLicenses(includedPackages, options) {
|
|
|
36
36
|
function readAndValidateLicenses(includedPackages, options) {
|
|
37
37
|
const dependencies = [];
|
|
38
38
|
const errorDependencies = [];
|
|
39
|
-
const sortedEntries = Object.entries(includedPackages).sort((a, b) => a[1].name.localeCompare(b[1].name));
|
|
39
|
+
const sortedEntries = Object.entries(includedPackages).sort((a, b) => a[1].name.localeCompare(b[1].name) || a[1].version.localeCompare(b[1].version));
|
|
40
40
|
for (const [depPkgRoot, depPkgJson] of sortedEntries) {
|
|
41
41
|
const pkgMeta = {
|
|
42
42
|
name: depPkgJson.name,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"analyzeLicenses.js","sourceRoot":"","sources":["../../src/license/analyzeLicenses.ts"],"names":[],"mappings":"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","sourcesContent":["import fs from 'fs';\nimport hostedGitInfo from 'hosted-git-info';\nimport path from 'path';\nimport validateLicense from 'validate-npm-package-license';\nimport type { PackageJson, PackageJsonPerson } from '../types.ts';\nimport { BundleError } from '../utils/BundleError.ts';\nimport { bulletedList, colors, logError } from '../utils/logHelpers.ts';\nimport type { Dependency, ErrorDependency, LicensePluginOptions } from './types.ts';\n\n/**\n * Analyze licenses for all included packages.\n * @param includedPackages Mapping from package root to package.json for all packages in the bundle\n */\nexport function analyzeLicenses(\n includedPackages: Record<string, PackageJson>,\n options: Pick<LicensePluginOptions, 'packageRoot' | 'unacceptableLicenseTest'>,\n): { dependencies: Dependency[] } | { error: string } {\n let dependencies: Dependency[];\n let errorDependencies: ErrorDependency[];\n try {\n ({ dependencies, errorDependencies } = readAndValidateLicenses(includedPackages, options));\n } catch (err) {\n // this would be due to some issue reading a file (the function isn't intended to throw)\n // but we need to catch it for clear error reporting in the esbuild onEnd context\n logError(`Unexpected error during license analysis: ${(err as Error).stack || err}`);\n throw new BundleError('Unexpected error during license analysis', { alreadyLogged: true, cause: err });\n }\n\n if (errorDependencies.length) {\n // Return the formatted string from the function to verify the output formatting\n // (it's hard to test this via the esbuild plugin)\n const errors = errorDependencies.map((dep) => [`${dep.name}@${dep.version} (${dep.path})`, dep.issues]).flat(1);\n return {\n error: colors.red(`${colors.bold('ERROR:')} Found dependencies with license issues:\\n${bulletedList(errors)}`),\n };\n }\n\n return { dependencies };\n}\n\n/**\n * Check the license specified in package.json, and if it's valid, read the license and notice text.\n */\nfunction readAndValidateLicenses(\n includedPackages: Record<string, PackageJson>,\n options: Pick<LicensePluginOptions, 'packageRoot' | 'unacceptableLicenseTest'>,\n): { dependencies: Dependency[]; errorDependencies: ErrorDependency[] } {\n const dependencies: Dependency[] = [];\n const errorDependencies: ErrorDependency[] = [];\n\n const sortedEntries = Object.entries(includedPackages).sort((a, b) => a[1].name.localeCompare(b[1].name));\n for (const [depPkgRoot, depPkgJson] of sortedEntries) {\n const pkgMeta = {\n name: depPkgJson.name,\n version: depPkgJson.version,\n path: path.relative(options.packageRoot, depPkgRoot).replace(/\\\\/g, '/'),\n };\n const license = depPkgJson.license;\n if (!license || typeof license !== 'string') {\n errorDependencies.push({\n ...pkgMeta,\n issues: [license ? `Unexpected \"license\" format ${JSON.stringify(license)}` : 'Missing \"license\"'],\n });\n continue;\n }\n\n const licenseResult = validateLicense(license);\n if (!licenseResult.validForNewPackages) {\n errorDependencies.push({\n ...pkgMeta,\n issues: [`Invalid \"license\" value ${JSON.stringify(license)}`, ...(licenseResult.warnings || [])],\n });\n continue;\n }\n const licenseInFilePath = licenseResult.inFile && path.join(depPkgRoot, licenseResult.inFile);\n if (licenseInFilePath && !fs.existsSync(licenseInFilePath)) {\n errorDependencies.push({\n ...pkgMeta,\n issues: [`License file \"${licenseResult.inFile}\" (specified by \"SEE LICENSE IN\") not found`],\n });\n continue;\n }\n\n if (options.unacceptableLicenseTest?.(license)) {\n errorDependencies.push({\n ...pkgMeta,\n issues: [\n `License ${JSON.stringify(license)} is not allowed (if incorrect, update the unacceptableLicenseTest setting)`,\n ],\n });\n continue;\n }\n\n const files = fs.readdirSync(depPkgRoot);\n // Read the license from either \"SEE LICENSE IN ___\" or a file named LICENSE*\n let licenseText: string | undefined;\n if (licenseInFilePath) {\n licenseText = fs.readFileSync(licenseInFilePath, 'utf8');\n } else {\n licenseText = findFile(/^license/i, files, depPkgRoot) || findFile(/^copying/i, files, depPkgRoot);\n }\n // Just look for a \"notice\" file at the root for notices\n const noticeText = findFile(/^notice/i, files, depPkgRoot);\n\n // Get author from package.json and/or \"authors\" file\n let author = personToString(depPkgJson.author);\n const authorsText = findFile(/^authors/i, files, depPkgRoot);\n if (authorsText) {\n author = (author ? author + '\\n' : '') + authorsText;\n }\n\n // Same with contributors\n let contributors = depPkgJson.contributors?.map(personToString).filter(Boolean).join('\\n');\n const contributorsText = findFile(/^contributors?/i, files, depPkgRoot);\n if (contributorsText) {\n contributors = (contributors ? contributors + '\\n' : '') + contributorsText;\n }\n\n const maintainers = depPkgJson.maintainers?.map(personToString).join('\\n');\n\n // Following CG, use \"homepage\" by default, followed by \"repository\"\n let url = depPkgJson.homepage;\n const repository = depPkgJson.repository;\n if (!url && repository) {\n url = typeof repository === 'string' ? repository : repository.url;\n const gitInfo = hostedGitInfo.fromUrl(url);\n if (gitInfo) {\n url = gitInfo.browse();\n }\n }\n\n dependencies.push({\n name: pkgMeta.name,\n version: pkgMeta.version,\n author,\n contributors,\n maintainers,\n url,\n license,\n licenseText,\n noticeText,\n });\n }\n\n return { dependencies, errorDependencies };\n}\n\n/**\n * Convert a person field to a string\n */\nfunction personToString(person: PackageJsonPerson | undefined): string | undefined {\n if (!person || typeof person === 'string') {\n return person;\n }\n const { name, email, url } = person;\n return `${name}${email ? ` <${email}>` : ''}${url ? ` (${url})` : ''}`;\n}\n\n/**\n * Find and read a file in a directory that matches a specific pattern.\n * @param isMatch - The function or regexp to match the file name.\n * @param files - The list of files to search.\n * @param dir - The parent directory path.\n * @returns The file contents if found (whitespace trimmed), otherwise undefined.\n */\nfunction findFile(isMatch: RegExp | ((file: string) => boolean), files: string[], dir: string): string | undefined {\n const match = files.find(typeof isMatch === 'function' ? isMatch : (file) => isMatch.test(file));\n return match && fs.readFileSync(path.join(dir, match), 'utf8').trim();\n}\n"]}
|
|
1
|
+
{"version":3,"file":"analyzeLicenses.js","sourceRoot":"","sources":["../../src/license/analyzeLicenses.ts"],"names":[],"mappings":"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","sourcesContent":["import fs from 'fs';\nimport hostedGitInfo from 'hosted-git-info';\nimport path from 'path';\nimport validateLicense from 'validate-npm-package-license';\nimport type { PackageJson, PackageJsonPerson } from '../types.ts';\nimport { BundleError } from '../utils/BundleError.ts';\nimport { bulletedList, colors, logError } from '../utils/logHelpers.ts';\nimport type { Dependency, ErrorDependency, LicensePluginOptions } from './types.ts';\n\n/**\n * Analyze licenses for all included packages.\n * @param includedPackages Mapping from package root to package.json for all packages in the bundle\n */\nexport function analyzeLicenses(\n includedPackages: Record<string, PackageJson>,\n options: Pick<LicensePluginOptions, 'packageRoot' | 'unacceptableLicenseTest'>,\n): { dependencies: Dependency[] } | { error: string } {\n let dependencies: Dependency[];\n let errorDependencies: ErrorDependency[];\n try {\n ({ dependencies, errorDependencies } = readAndValidateLicenses(includedPackages, options));\n } catch (err) {\n // this would be due to some issue reading a file (the function isn't intended to throw)\n // but we need to catch it for clear error reporting in the esbuild onEnd context\n logError(`Unexpected error during license analysis: ${(err as Error).stack || err}`);\n throw new BundleError('Unexpected error during license analysis', { alreadyLogged: true, cause: err });\n }\n\n if (errorDependencies.length) {\n // Return the formatted string from the function to verify the output formatting\n // (it's hard to test this via the esbuild plugin)\n const errors = errorDependencies.map((dep) => [`${dep.name}@${dep.version} (${dep.path})`, dep.issues]).flat(1);\n return {\n error: colors.red(`${colors.bold('ERROR:')} Found dependencies with license issues:\\n${bulletedList(errors)}`),\n };\n }\n\n return { dependencies };\n}\n\n/**\n * Check the license specified in package.json, and if it's valid, read the license and notice text.\n */\nfunction readAndValidateLicenses(\n includedPackages: Record<string, PackageJson>,\n options: Pick<LicensePluginOptions, 'packageRoot' | 'unacceptableLicenseTest'>,\n): { dependencies: Dependency[]; errorDependencies: ErrorDependency[] } {\n const dependencies: Dependency[] = [];\n const errorDependencies: ErrorDependency[] = [];\n\n const sortedEntries = Object.entries(includedPackages).sort(\n (a, b) => a[1].name.localeCompare(b[1].name) || a[1].version.localeCompare(b[1].version),\n );\n for (const [depPkgRoot, depPkgJson] of sortedEntries) {\n const pkgMeta = {\n name: depPkgJson.name,\n version: depPkgJson.version,\n path: path.relative(options.packageRoot, depPkgRoot).replace(/\\\\/g, '/'),\n };\n const license = depPkgJson.license;\n if (!license || typeof license !== 'string') {\n errorDependencies.push({\n ...pkgMeta,\n issues: [license ? `Unexpected \"license\" format ${JSON.stringify(license)}` : 'Missing \"license\"'],\n });\n continue;\n }\n\n const licenseResult = validateLicense(license);\n if (!licenseResult.validForNewPackages) {\n errorDependencies.push({\n ...pkgMeta,\n issues: [`Invalid \"license\" value ${JSON.stringify(license)}`, ...(licenseResult.warnings || [])],\n });\n continue;\n }\n const licenseInFilePath = licenseResult.inFile && path.join(depPkgRoot, licenseResult.inFile);\n if (licenseInFilePath && !fs.existsSync(licenseInFilePath)) {\n errorDependencies.push({\n ...pkgMeta,\n issues: [`License file \"${licenseResult.inFile}\" (specified by \"SEE LICENSE IN\") not found`],\n });\n continue;\n }\n\n if (options.unacceptableLicenseTest?.(license)) {\n errorDependencies.push({\n ...pkgMeta,\n issues: [\n `License ${JSON.stringify(license)} is not allowed (if incorrect, update the unacceptableLicenseTest setting)`,\n ],\n });\n continue;\n }\n\n const files = fs.readdirSync(depPkgRoot);\n // Read the license from either \"SEE LICENSE IN ___\" or a file named LICENSE*\n let licenseText: string | undefined;\n if (licenseInFilePath) {\n licenseText = fs.readFileSync(licenseInFilePath, 'utf8');\n } else {\n licenseText = findFile(/^license/i, files, depPkgRoot) || findFile(/^copying/i, files, depPkgRoot);\n }\n // Just look for a \"notice\" file at the root for notices\n const noticeText = findFile(/^notice/i, files, depPkgRoot);\n\n // Get author from package.json and/or \"authors\" file\n let author = personToString(depPkgJson.author);\n const authorsText = findFile(/^authors/i, files, depPkgRoot);\n if (authorsText) {\n author = (author ? author + '\\n' : '') + authorsText;\n }\n\n // Same with contributors\n let contributors = depPkgJson.contributors?.map(personToString).filter(Boolean).join('\\n');\n const contributorsText = findFile(/^contributors?/i, files, depPkgRoot);\n if (contributorsText) {\n contributors = (contributors ? contributors + '\\n' : '') + contributorsText;\n }\n\n const maintainers = depPkgJson.maintainers?.map(personToString).join('\\n');\n\n // Following CG, use \"homepage\" by default, followed by \"repository\"\n let url = depPkgJson.homepage;\n const repository = depPkgJson.repository;\n if (!url && repository) {\n url = typeof repository === 'string' ? repository : repository.url;\n const gitInfo = hostedGitInfo.fromUrl(url);\n if (gitInfo) {\n url = gitInfo.browse();\n }\n }\n\n dependencies.push({\n name: pkgMeta.name,\n version: pkgMeta.version,\n author,\n contributors,\n maintainers,\n url,\n license,\n licenseText,\n noticeText,\n });\n }\n\n return { dependencies, errorDependencies };\n}\n\n/**\n * Convert a person field to a string\n */\nfunction personToString(person: PackageJsonPerson | undefined): string | undefined {\n if (!person || typeof person === 'string') {\n return person;\n }\n const { name, email, url } = person;\n return `${name}${email ? ` <${email}>` : ''}${url ? ` (${url})` : ''}`;\n}\n\n/**\n * Find and read a file in a directory that matches a specific pattern.\n * @param isMatch - The function or regexp to match the file name.\n * @param files - The list of files to search.\n * @param dir - The parent directory path.\n * @returns The file contents if found (whitespace trimmed), otherwise undefined.\n */\nfunction findFile(isMatch: RegExp | ((file: string) => boolean), files: string[], dir: string): string | undefined {\n const match = files.find(typeof isMatch === 'function' ? isMatch : (file) => isMatch.test(file));\n return match && fs.readFileSync(path.join(dir, match), 'utf8').trim();\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"writeNotice.d.ts","sourceRoot":"","sources":["../../src/license/writeNotice.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAE7C,eAAO,MAAM,cAAc,eAAe,CAAC;AAE3C;;GAEG;AACH,wBAAgB,WAAW,CACzB,YAAY,EAAE,UAAU,EAAE,EAC1B,SAAS,EAAE,MAAM,EACjB,iBAAiB,CAAC,EAAE,CAAC,UAAU,EAAE,UAAU,KAAK,OAAO,GACtD,IAAI,
|
|
1
|
+
{"version":3,"file":"writeNotice.d.ts","sourceRoot":"","sources":["../../src/license/writeNotice.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAE7C,eAAO,MAAM,cAAc,eAAe,CAAC;AAE3C;;GAEG;AACH,wBAAgB,WAAW,CACzB,YAAY,EAAE,UAAU,EAAE,EAC1B,SAAS,EAAE,MAAM,EACjB,iBAAiB,CAAC,EAAE,CAAC,UAAU,EAAE,UAAU,KAAK,OAAO,GACtD,IAAI,CAgCN"}
|
|
@@ -12,7 +12,9 @@ export function writeNotice(dependencies, absOutDir, excludeFromNotice) {
|
|
|
12
12
|
return;
|
|
13
13
|
const noticeText = [
|
|
14
14
|
`NOTICES\n\nThis package incorporates material as listed below or described in the code.`,
|
|
15
|
-
...filteredDependencies
|
|
15
|
+
...filteredDependencies
|
|
16
|
+
.sort((a, b) => a.name.localeCompare(b.name) || a.version.localeCompare(b.version))
|
|
17
|
+
.map((dep) => {
|
|
16
18
|
const shortLicense = dep.license ? (/^see license/i.test(dep.license) ? '' : dep.license) : 'unknown license';
|
|
17
19
|
return [
|
|
18
20
|
`${dep.name} ${dep.version}${shortLicense ? ` - ${shortLicense}` : ''}${dep.url ? `\n${dep.url}` : ''}`,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"writeNotice.js","sourceRoot":"","sources":["../../src/license/writeNotice.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,IAAI,MAAM,MAAM,CAAC;AAGxB,MAAM,CAAC,MAAM,cAAc,GAAG,YAAY,CAAC;AAE3C;;GAEG;AACH,MAAM,UAAU,WAAW,CACzB,YAA0B,EAC1B,SAAiB,EACjB,iBAAuD;IAEvD,IAAI,CAAC,YAAY,CAAC,MAAM;QAAE,OAAO;IAEjC,MAAM,oBAAoB,GAAG,iBAAiB,CAAC,CAAC,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,iBAAiB,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC;IACtH,IAAI,CAAC,oBAAoB,CAAC,MAAM;QAAE,OAAO;IAEzC,MAAM,UAAU,GAAG;QACjB,yFAAyF;QACzF,GAAG,oBAAoB,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE;
|
|
1
|
+
{"version":3,"file":"writeNotice.js","sourceRoot":"","sources":["../../src/license/writeNotice.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,IAAI,MAAM,MAAM,CAAC;AAGxB,MAAM,CAAC,MAAM,cAAc,GAAG,YAAY,CAAC;AAE3C;;GAEG;AACH,MAAM,UAAU,WAAW,CACzB,YAA0B,EAC1B,SAAiB,EACjB,iBAAuD;IAEvD,IAAI,CAAC,YAAY,CAAC,MAAM;QAAE,OAAO;IAEjC,MAAM,oBAAoB,GAAG,iBAAiB,CAAC,CAAC,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,iBAAiB,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC;IACtH,IAAI,CAAC,oBAAoB,CAAC,MAAM;QAAE,OAAO;IAEzC,MAAM,UAAU,GAAG;QACjB,yFAAyF;QACzF,GAAG,oBAAoB;aACpB,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;aAClF,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE;YACX,MAAM,YAAY,GAAG,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,eAAe,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,iBAAiB,CAAC;YAC9G,OAAO;gBACL,GAAG,GAAG,CAAC,IAAI,IAAI,GAAG,CAAC,OAAO,GAAG,YAAY,CAAC,CAAC,CAAC,MAAM,YAAY,EAAE,CAAC,CAAC,CAAC,EAAE,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE;gBACvG,uFAAuF;gBACvF,GAAG,CAAC,MAAM,IAAI,WAAW,GAAG,CAAC,MAAM,EAAE;gBACrC,GAAG,CAAC,WAAW,IAAI,iBAAiB,GAAG,CAAC,WAAW,EAAE;gBACrD,GAAG,CAAC,YAAY,IAAI,kBAAkB,GAAG,CAAC,YAAY,EAAE;gBACxD,oEAAoE;gBACpE,GAAG,CAAC,WAAW;gBACf,+DAA+D;gBAC/D,GAAG,CAAC,UAAU,IAAI,eAAe,GAAG,CAAC,UAAU,EAAE;aAClD;iBACE,MAAM,CAAC,OAAO,CAAC;iBACf,IAAI,CAAC,MAAM,CAAC,CAAC;QAClB,CAAC,CAAC;KACL,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;IAEvB,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,cAAc,CAAC,CAAC;IACrD,EAAE,CAAC,SAAS,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC7C,EAAE,CAAC,aAAa,CAAC,OAAO,EAAE,UAAU,EAAE,MAAM,CAAC,CAAC;IAC9C,OAAO,CAAC,GAAG,CAAC,4BAA4B,OAAO,IAAI,CAAC,CAAC;AACvD,CAAC","sourcesContent":["import fs from 'fs';\nimport path from 'path';\nimport type { Dependency } from './types.ts';\n\nexport const noticeFilename = 'NOTICE.txt';\n\n/**\n * Write NOTICE.txt with license and author info for the given dependencies.\n */\nexport function writeNotice(\n dependencies: Dependency[],\n absOutDir: string,\n excludeFromNotice?: (dependency: Dependency) => boolean,\n): void {\n if (!dependencies.length) return;\n\n const filteredDependencies = excludeFromNotice ? dependencies.filter((dep) => !excludeFromNotice(dep)) : dependencies;\n if (!filteredDependencies.length) return;\n\n const noticeText = [\n `NOTICES\\n\\nThis package incorporates material as listed below or described in the code.`,\n ...filteredDependencies\n .sort((a, b) => a.name.localeCompare(b.name) || a.version.localeCompare(b.version))\n .map((dep) => {\n const shortLicense = dep.license ? (/^see license/i.test(dep.license) ? '' : dep.license) : 'unknown license';\n return [\n `${dep.name} ${dep.version}${shortLicense ? ` - ${shortLicense}` : ''}${dep.url ? `\\n${dep.url}` : ''}`,\n // Unclear which author/maintainer/contributor info is required, so include all of them\n dep.author && `Author: ${dep.author}`,\n dep.maintainers && `Maintainers:\\n${dep.maintainers}`,\n dep.contributors && `Contributors:\\n${dep.contributors}`,\n // The license text typically includes the official copyright notice\n dep.licenseText,\n // As of writing we don't use any packages that publish NOTICES\n dep.noticeText && `NOTICES:\\n\\n${dep.noticeText}`,\n ]\n .filter(Boolean)\n .join('\\n\\n');\n }),\n ].join('\\n\\n----\\n\\n');\n\n const outFile = path.join(absOutDir, noticeFilename);\n fs.mkdirSync(absOutDir, { recursive: true });\n fs.writeFileSync(outFile, noticeText, 'utf8');\n console.log(`Wrote license notices to ${outFile}\\n`);\n}\n"]}
|