diff --git a/package-lock.json b/package-lock.json index 426838d..fa49b4a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4,6 +4,7 @@ "requires": true, "packages": { "": { + "name": "ejs", "dependencies": { "astring": "1.9.0", "meriyah": "6.1.4" @@ -15,7 +16,9 @@ "@types/bun": "1.2.21", "@types/deno": "2.3.0", "@types/node": "24.3.0", - "rollup": "4.50.0" + "prettier": "^3.6.2", + "rollup": "4.50.0", + "rollup-plugin-license": "^3.6.0" } }, "node_modules/@isaacs/cliui": { @@ -582,6 +585,16 @@ "dev": true, "license": "MIT" }, + "node_modules/array-find-index": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz", + "integrity": "sha512-M1HQyIXcBGtVywBt8WVdim+lrNaK7VHp99Qt5pSNziXznKHViIBbXWtfRTpEFpF/c4FdfxNAsCCwPp5phBYJtw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/astring": { "version": "1.9.0", "resolved": "https://registry.npmjs.org/astring/-/astring-1.9.0.tgz", @@ -658,6 +671,13 @@ "node": ">= 6" } }, + "node_modules/commenting": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/commenting/-/commenting-1.1.0.tgz", + "integrity": "sha512-YeNK4tavZwtH7jEgK1ZINXzLKm6DZdEMfsaaieOsCAN0S8vsY7UeuO3Q7d/M018EFgE+IeUAuBOKkFccBZsUZA==", + "dev": true, + "license": "MIT" + }, "node_modules/cross-spawn": { "version": "7.0.6", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", @@ -712,6 +732,24 @@ "dev": true, "license": "MIT" }, + "node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, "node_modules/foreground-child": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz", @@ -851,6 +889,13 @@ "dev": true, "license": "MIT" }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "dev": true, + "license": "MIT" + }, "node_modules/lru-cache": { "version": "10.4.3", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", @@ -858,6 +903,16 @@ "dev": true, "license": "ISC" }, + "node_modules/magic-string": { + "version": "0.30.19", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.19.tgz", + "integrity": "sha512-2N21sPY9Ws53PZvsEpVtNuSW+ScYbQdp4b9qUaL+9QkHUrGFKo56Lg9Emg5s9V/qrtNBmiR01sYhUOwu3H+VOw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.5" + } + }, "node_modules/meriyah": { "version": "6.1.4", "resolved": "https://registry.npmjs.org/meriyah/-/meriyah-6.1.4.tgz", @@ -893,6 +948,16 @@ "node": ">=16 || 14 >=14.17" } }, + "node_modules/moment": { + "version": "2.30.1", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.30.1.tgz", + "integrity": "sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how==", + "dev": true, + "license": "MIT", + "engines": { + "node": "*" + } + }, "node_modules/mz": { "version": "2.7.0", "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", @@ -922,6 +987,19 @@ "dev": true, "license": "BlueOak-1.0.0" }, + "node_modules/package-name-regex": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/package-name-regex/-/package-name-regex-2.0.6.tgz", + "integrity": "sha512-gFL35q7kbE/zBaPA3UKhp2vSzcPYx2ecbYuwv1ucE9Il6IIgBDweBlH8D68UFGZic2MkllKa2KHCfC1IQBQUYA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/dword-design" + } + }, "node_modules/path-key": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", @@ -979,6 +1057,22 @@ "node": ">= 6" } }, + "node_modules/prettier": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.6.2.tgz", + "integrity": "sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ==", + "dev": true, + "license": "MIT", + "bin": { + "prettier": "bin/prettier.cjs" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, "node_modules/randombytes": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", @@ -1051,6 +1145,29 @@ "fsevents": "~2.3.2" } }, + "node_modules/rollup-plugin-license": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/rollup-plugin-license/-/rollup-plugin-license-3.6.0.tgz", + "integrity": "sha512-1ieLxTCaigI5xokIfszVDRoy6c/Wmlot1fDEnea7Q/WXSR8AqOjYljHDLObAx7nFxHC2mbxT3QnTSPhaic2IYw==", + "dev": true, + "license": "MIT", + "dependencies": { + "commenting": "~1.1.0", + "fdir": "^6.4.3", + "lodash": "~4.17.21", + "magic-string": "~0.30.0", + "moment": "~2.30.1", + "package-name-regex": "~2.0.6", + "spdx-expression-validate": "~2.0.0", + "spdx-satisfies": "~5.0.1" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "rollup": "^1.0.0 || ^2.0.0 || ^3.0.0 || ^4.0.0" + } + }, "node_modules/safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", @@ -1146,6 +1263,72 @@ "source-map": "^0.6.0" } }, + "node_modules/spdx-compare": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/spdx-compare/-/spdx-compare-1.0.0.tgz", + "integrity": "sha512-C1mDZOX0hnu0ep9dfmuoi03+eOdDoz2yvK79RxbcrVEG1NO1Ph35yW102DHWKN4pk80nwCgeMmSY5L25VE4D9A==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-find-index": "^1.0.2", + "spdx-expression-parse": "^3.0.0", + "spdx-ranges": "^2.0.0" + } + }, + "node_modules/spdx-exceptions": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz", + "integrity": "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==", + "dev": true, + "license": "CC-BY-3.0" + }, + "node_modules/spdx-expression-parse": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", + "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-expression-validate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/spdx-expression-validate/-/spdx-expression-validate-2.0.0.tgz", + "integrity": "sha512-b3wydZLM+Tc6CFvaRDBOF9d76oGIHNCLYFeHbftFXUWjnfZWganmDmvtM5sm1cRwJc/VDBMLyGGrsLFd1vOxbg==", + "dev": true, + "license": "(MIT AND CC-BY-3.0)", + "dependencies": { + "spdx-expression-parse": "^3.0.0" + } + }, + "node_modules/spdx-license-ids": { + "version": "3.0.22", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.22.tgz", + "integrity": "sha512-4PRT4nh1EImPbt2jASOKHX7PB7I+e4IWNLvkKFDxNhJlfjbYlleYQh285Z/3mPTHSAK/AvdMmw5BNNuYH8ShgQ==", + "dev": true, + "license": "CC0-1.0" + }, + "node_modules/spdx-ranges": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/spdx-ranges/-/spdx-ranges-2.1.1.tgz", + "integrity": "sha512-mcdpQFV7UDAgLpXEE/jOMqvK4LBoO0uTQg0uvXUewmEFhpiZx5yJSZITHB8w1ZahKdhfZqP5GPEOKLyEq5p8XA==", + "dev": true, + "license": "(MIT AND CC-BY-3.0)" + }, + "node_modules/spdx-satisfies": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/spdx-satisfies/-/spdx-satisfies-5.0.1.tgz", + "integrity": "sha512-Nwor6W6gzFp8XX4neaKQ7ChV4wmpSh2sSDemMFSzHxpTw460jxFYeOn+jq4ybnSSw/5sc3pjka9MQPouksQNpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "spdx-compare": "^1.0.0", + "spdx-expression-parse": "^3.0.0", + "spdx-ranges": "^2.0.0" + } + }, "node_modules/string-width": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", diff --git a/package.json b/package.json index beeba8e..163600a 100644 --- a/package.json +++ b/package.json @@ -1,4 +1,5 @@ { + "name": "ejs", "type": "module", "scripts": { "bundle": "rollup -c" @@ -15,6 +16,7 @@ "@types/bun": "1.2.21", "@types/deno": "2.3.0", "@types/node": "24.3.0", - "rollup": "4.50.0" + "rollup": "4.50.0", + "prettier": "^3.6.2" } } diff --git a/rollup.config.js b/rollup.config.js index 0e96647..3cb32a9 100644 --- a/rollup.config.js +++ b/rollup.config.js @@ -1,10 +1,14 @@ -import { defineConfig } from "rollup"; +import {defineConfig} from "rollup"; import nodeResolve from "@rollup/plugin-node-resolve"; import sucrase from "@rollup/plugin-sucrase"; import terser from "@rollup/plugin-terser"; -import { createHash } from "node:crypto"; -import { Buffer } from "node:buffer"; -import license from 'rollup-plugin-license'; +import {createHash} from "node:crypto"; +import {Buffer} from "node:buffer"; +import license from 'rollup-plugin-license'; +import {readFileSync} from "node:fs"; +import prettier from "prettier"; + +const pkg = JSON.parse(readFileSync('./package.json')); const LICENSE_BANNER = "SPDX-License-Identifier: Unlicense\n" + @@ -12,146 +16,246 @@ const LICENSE_BANNER = "<% if (dependencies && dependencies.length) { %>" + "\n\nBundled Dependencies:" + "<% _.forEach(dependencies, function (dependency) { if (!dependency.private) { %>" + - "\n\n---\nName: <%= dependency.name %>" + - "<% if (dependency.version) { %>\nVersion: <%= dependency.version %><% } %>" + - "\nLicense: <%= dependency.license %>" + - "<% if (dependency.repository && dependency.repository.url) { %>\nRepository: <%= dependency.repository.url %><% } %>" + - "<% if (dependency.homepage && dependency.homepage.url) { %>\nHomepage: <%= dependency.homepage.url %><% } %>" + - "<% if (dependency.author) { %>\nAuthor: <%= dependency.author.text() %><% } %>" + - "<% if (dependency.licenseText) { %>\n\n<%= dependency.licenseText %><% } %>" + - "\n---<% } }) %>\n<% } %>" + "\n\n---\nName: <%= dependency.name %>" + + "<% if (dependency.version) { %>\nVersion: <%= dependency.version %><% } %>" + + "\nLicense: <%= dependency.license %>" + + "<% if (dependency.repository && dependency.repository.url) { %>\nRepository: <%= dependency.repository.url %><% } %>" + + "<% if (dependency.homepage && dependency.homepage.url) { %>\nHomepage: <%= dependency.homepage.url %><% } %>" + + "<% if (dependency.author) { %>\nAuthor: <%= dependency.author.text() %><% } %>" + + "<% if (dependency.licenseText) { %>\n\n<%= dependency.licenseText %><% } %>" + + "\n---<% } }) %>\n<% } %>" const ALLOWED_COMMENTS_RE = /SPDX-License-Identifier:/ function printHash() { - return { - name: "hash-output-plugin", - writeBundle(_options, bundle) { - for (const [fileName, assetInfo] of Object.entries(bundle)) { - if (assetInfo.code) { - try { - const data = Buffer.from(assetInfo.code) - const hash = createHash("sha3-512").update(data).digest("hex"); - console.log(`SHA3-512 for ${assetInfo.fileName}: ${hash}`); - } catch (err) { - console.error(`Error hashing ${fileName}:`, err.message); + return { + name: "hash-output-plugin", + writeBundle(_options, bundle) { + for (const [fileName, assetInfo] of Object.entries(bundle)) { + if (assetInfo.code) { + try { + const data = Buffer.from(assetInfo.code) + const hash = createHash("sha3-512").update(data).digest("hex"); + console.log(`SHA3-512 for ${assetInfo.fileName}: ${hash}`); + } catch (err) { + console.error(`Error hashing ${fileName}:`, err.message); + } + } } - } - } - }, - }; + }, + }; } +function dynamicImportRewrite({format = "deno"} = {}) { + return { + name: "dynamic-import-rewrite-plugin", + resolveId(source) { + if (pkg.dependencies[source]) { + if (format === "deno") { + return {id: `npm:${source}@${pkg.dependencies[source]}`, external: true}; + } else if (format === "bun") { + return {id: `${source}@${pkg.dependencies[source]}`, external: true}; + } + return null + } + return null; + }, + renderDynamicImport() { + return null; + } + }; +} + +function prettifyOutput() { + return { + name: 'prettify-output', + renderChunk(code) { + return prettier.format(code, {parser: 'babel', singleQuote: true}); + } + } +} + + export default defineConfig([ - { - input: "src/main.ts", - output: { - name: "jsc", - globals: { - astring: "astring", - input: "input", - meriyah: "meriyah", - }, - file: "dist/yt.solver.core.js", - format: "iife", - }, - external: ["astring", "meriyah"], - plugins: [ - nodeResolve(), - sucrase({ - exclude: ["node_modules/**"], - transforms: ["typescript"], - }), - license({ - banner: { - content: LICENSE_BANNER + { + input: "src/main.ts", + output: { + name: "jsc", + globals: { + astring: "astring", + input: "input", + meriyah: "meriyah", + }, + file: "dist/yt.solver.core.js", + format: "iife", }, - }), - printHash(), - ], - }, - { - input: "src/main.ts", - output: { - name: "jsc", - globals: { - astring: "astring", - input: "input", - meriyah: "meriyah", - }, - file: "dist/yt.solver.core.min.js", - compact: true, - format: "iife", - minifyInternalExports: true, + external: ["astring", "meriyah"], + plugins: [ + nodeResolve(), + sucrase({ + exclude: ["node_modules/**"], + transforms: ["typescript"], + }), + license({ + banner: { + content: LICENSE_BANNER + }, + }), + // Use terser to remove comments but do not minify + terser({ + format: { + comments: ALLOWED_COMMENTS_RE + }, + compress: false, + mangle: false, + }), + prettifyOutput(), + printHash(), + ], }, - external: ["astring", "meriyah"], - plugins: [ - nodeResolve(), - sucrase({ - exclude: ["node_modules/**"], - transforms: ["typescript"], - }), - terser({ - format: { - comments: ALLOWED_COMMENTS_RE - } - }), - license({ - banner: { - content: LICENSE_BANNER + { + input: "src/main.ts", + output: { + name: "jsc", + globals: { + astring: "astring", + input: "input", + meriyah: "meriyah", + }, + file: "dist/yt.solver.core.min.js", + compact: true, + format: "iife", + minifyInternalExports: true, }, - }), - printHash(), - ], - }, - { - input: "src/lib.ts", - output: { - name: "lib", - file: "dist/yt.solver.lib.js", - format: "iife", - exports: "named", + external: ["astring", "meriyah"], + plugins: [ + nodeResolve(), + sucrase({ + exclude: ["node_modules/**"], + transforms: ["typescript"], + }), + terser({ + format: { + comments: ALLOWED_COMMENTS_RE + } + }), + license({ + banner: { + content: LICENSE_BANNER + }, + }), + printHash(), + ], }, - plugins: [ - nodeResolve(), - sucrase({ - exclude: ["node_modules/**"], - transforms: ["typescript"], - }), - license({ - banner: { - content: LICENSE_BANNER + { + input: "src/lib.ts", + output: { + name: "lib", + file: "dist/yt.solver.lib.js", + format: "iife", + exports: "named", }, - }), - printHash(), - ], - }, - { - input: "src/lib.ts", - output: { - name: "lib", - file: "dist/yt.solver.lib.min.js", - compact: true, - format: "iife", - minifyInternalExports: true, + plugins: [ + nodeResolve(), + sucrase({ + exclude: ["node_modules/**"], + transforms: ["typescript"], + }), + license({ + banner: { + content: LICENSE_BANNER + }, + }), + // Use terser to remove comments but do not minify + terser({ + format: { + comments: ALLOWED_COMMENTS_RE + }, + compress: false, + mangle: false, + }), + prettifyOutput(), + printHash(), + ], }, - plugins: [ - nodeResolve(), - sucrase({ - exclude: ["node_modules/**"], - transforms: ["typescript"], - }), - terser({ - format: { - comments: ALLOWED_COMMENTS_RE - } - }), - license({ - banner: { - content: LICENSE_BANNER + { + input: "src/lib.ts", + output: { + name: "lib", + file: "dist/yt.solver.lib.min.js", + compact: true, + format: "iife", + minifyInternalExports: true, }, - }), - printHash(), - ], - }, + plugins: [ + nodeResolve(), + sucrase({ + exclude: ["node_modules/**"], + transforms: ["typescript"], + }), + terser({ + format: { + comments: ALLOWED_COMMENTS_RE + } + }), + license({ + banner: { + content: LICENSE_BANNER + }, + }), + printHash(), + ], + }, + { + input: "src/dynamic.lib.ts", + output: { + name: "lib", + file: "dist/yt.solver.deno.lib.js", + format: "es", + }, + plugins: [ + dynamicImportRewrite({format: "deno"}), + license({ + banner: { + content: LICENSE_BANNER + }, + }), + // Use terser to remove comments but do not minify + terser({ + format: { + comments: ALLOWED_COMMENTS_RE + }, + compress: false, + mangle: false, + }), + prettifyOutput(), + printHash(), + ], + }, + { + input: "src/dynamic.lib.ts", + output: { + name: "lib", + file: "dist/yt.solver.bun.lib.js", + format: "es", + }, + plugins: [ + dynamicImportRewrite({format: "bun"}), + license({ + banner: { + content: LICENSE_BANNER + }, + }), + // Use terser to remove comments but do not minify + terser({ + format: { + comments: ALLOWED_COMMENTS_RE + }, + compress: false, + mangle: false, + }), + prettifyOutput(), + printHash(), + ], + }, ]); diff --git a/src/dynamic.lib.ts b/src/dynamic.lib.ts new file mode 100644 index 0000000..7613b64 --- /dev/null +++ b/src/dynamic.lib.ts @@ -0,0 +1,5 @@ +// Used for generating deno/bun auto-imports +export const lib = { + meriyah: (await import('meriyah')), + astring: (await import('astring')) +}; \ No newline at end of file