From bde0439e5f11c93f998b95d56c4766babc3c6a58 Mon Sep 17 00:00:00 2001 From: KCM Date: Sun, 15 Mar 2026 09:42:46 -0500 Subject: [PATCH 1/6] chore: prettier. --- .github/workflows/ci.yml | 2 +- .oxlintrc.json | 12 +- package.json | 6 + src/app.js | 639 +++++++++++++++++++-------------------- src/index.html | 5 +- src/styles.css | 22 +- 6 files changed, 341 insertions(+), 345 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 57b860f..718b7ab 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -32,4 +32,4 @@ jobs: path: npm-debug.log - name: Lint - run: npm run lint \ No newline at end of file + run: npm run lint diff --git a/.oxlintrc.json b/.oxlintrc.json index deee81b..9e897bf 100644 --- a/.oxlintrc.json +++ b/.oxlintrc.json @@ -10,7 +10,13 @@ "rules": { "no-console": "error", "no-unused-vars": "error", - "no-shadow": "error", + "no-shadow": "error" }, - "ignorePatterns": ["dist/**", "coverage/**", "vendor/**", "test/snapshots/**", "node_modules/**"] -} \ No newline at end of file + "ignorePatterns": [ + "dist/**", + "coverage/**", + "vendor/**", + "test/snapshots/**", + "node_modules/**" + ] +} diff --git a/package.json b/package.json index 0ea9f12..8c81237 100644 --- a/package.json +++ b/package.json @@ -27,5 +27,11 @@ "http-server": "^14.1.1", "oxlint": "^1.55.0", "prettier": "^3.8.1" + }, + "prettier": { + "arrowParens": "avoid", + "printWidth": 90, + "semi": false, + "singleQuote": true } } diff --git a/src/app.js b/src/app.js index 9c0e20e..80a127e 100644 --- a/src/app.js +++ b/src/app.js @@ -1,33 +1,33 @@ -import { cssFromSource } from "https://esm.sh/@knighted/css/browser"; -import { jsx } from "@knighted/jsx"; -import { transpileJsxSource } from "@knighted/jsx/transpile"; - -const statusNode = document.getElementById("status"); -const renderMode = document.getElementById("render-mode"); -const autoRenderToggle = document.getElementById("auto-render"); -const renderButton = document.getElementById("render-button"); -const styleMode = document.getElementById("style-mode"); -const shadowToggle = document.getElementById("shadow-toggle"); -const jsxEditor = document.getElementById("jsx-editor"); -const cssEditor = document.getElementById("css-editor"); -const previewHost = document.getElementById("preview-host"); -const styleWarning = document.getElementById("style-warning"); -const cdnLoading = document.getElementById("cdn-loading"); +import { cssFromSource } from '@knighted/css/browser' +import { jsx } from '@knighted/jsx' +import { transpileJsxSource } from '@knighted/jsx/transpile' + +const statusNode = document.getElementById('status') +const renderMode = document.getElementById('render-mode') +const autoRenderToggle = document.getElementById('auto-render') +const renderButton = document.getElementById('render-button') +const styleMode = document.getElementById('style-mode') +const shadowToggle = document.getElementById('shadow-toggle') +const jsxEditor = document.getElementById('jsx-editor') +const cssEditor = document.getElementById('css-editor') +const previewHost = document.getElementById('preview-host') +const styleWarning = document.getElementById('style-warning') +const cdnLoading = document.getElementById('cdn-loading') const defaultJsx = [ - "const Button = ({ onClick }) => {", - " return ", - "}", - "", - "const App = () => {", - " const onClick = () => {", + 'const Button = ({ onClick }) => {', + ' return ', + '}', + '', + 'const App = () => {', + ' const onClick = () => {', " alert('clicked!')", - " }", - "", - " return + @@ -100,6 +98,7 @@

Preview

- + From 847d4f7216d466e1bed6ae4b2b2e779c8c5aa4ef Mon Sep 17 00:00:00 2001 From: KCM Date: Sun, 15 Mar 2026 13:08:32 -0500 Subject: [PATCH 3/6] build: sass fallbacks. --- .github/workflows/ci.yml | 3 + .github/workflows/deploy.yml | 16 +- .gitignore | 3 +- .oxlintrc.json | 8 +- docs/build-and-deploy.md | 103 +++ package-lock.json | 1209 +--------------------------------- package.json | 15 +- scripts/build-importmap.js | 39 ++ scripts/build-prepare.js | 86 +++ src/bootstrap.js | 7 +- src/cdn.js | 68 +- 11 files changed, 329 insertions(+), 1228 deletions(-) create mode 100644 docs/build-and-deploy.md create mode 100644 scripts/build-importmap.js create mode 100644 scripts/build-prepare.js diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 718b7ab..aaa658f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -33,3 +33,6 @@ jobs: - name: Lint run: npm run lint + + - name: Build + run: npm run build diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 9046c53..be01b3b 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -26,10 +26,16 @@ jobs: - name: Checkout uses: actions/checkout@v6.0.1 - - name: Package static site - run: | - mkdir -p build - cp -r src/* build/ + - name: Setup Node + uses: actions/setup-node@v6.2.0 + with: + node-version: '24.14.0' + + - name: Install Dependencies + run: npm ci + + - name: Build Production Site + run: npm run build:esm - name: Setup Pages uses: actions/configure-pages@v5.0.0 @@ -37,7 +43,7 @@ jobs: - name: Upload Pages artifact uses: actions/upload-pages-artifact@v3.0.1 with: - path: build + path: dist - name: Deploy to GitHub Pages id: deployment diff --git a/.gitignore b/.gitignore index b512c09..76add87 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ -node_modules \ No newline at end of file +node_modules +dist \ No newline at end of file diff --git a/.oxlintrc.json b/.oxlintrc.json index 9e897bf..cfd91fb 100644 --- a/.oxlintrc.json +++ b/.oxlintrc.json @@ -1,5 +1,6 @@ { "$schema": "./node_modules/oxlint/configuration_schema.json", + "plugins": ["import"], "categories": { "correctness": "error", "suspicious": "warn", @@ -10,10 +11,15 @@ "rules": { "no-console": "error", "no-unused-vars": "error", - "no-shadow": "error" + "no-shadow": "error", + "import/no-cycle": "error", + "import/no-duplicates": "error", + "import/no-self-import": "error", + "import/no-unresolved": "error" }, "ignorePatterns": [ "dist/**", + ".tmp-jspm-sass/**", "coverage/**", "vendor/**", "test/snapshots/**", diff --git a/docs/build-and-deploy.md b/docs/build-and-deploy.md new file mode 100644 index 0000000..ef74370 --- /dev/null +++ b/docs/build-and-deploy.md @@ -0,0 +1,103 @@ +# Build And Deploy + +This project uses two runtime modes: + +- Local development mode: dynamic CDN resolution from `src/cdn.js` with esm.sh as default. +- Production mode: JSPM-generated import map injected into `dist/index.html` and hosted on GitHub Pages. + +## Local Development + +Install dependencies and start the local server: + +```sh +npm ci +npm run dev +``` + +The app loads from `src/index.html` and keeps the dynamic CDN fallback behavior for fast iteration and debugging. + +## Production Build + +Create a production-ready `dist` folder: + +```sh +npm run build +``` + +Select a different production primary CDN at build time: + +```sh +KNIGHTED_PRIMARY_CDN=esm npm run build +KNIGHTED_PRIMARY_CDN=jspmGa npm run build +``` + +Convenience scripts are also available: + +```sh +npm run build:esm +npm run build:jspm +npm run build:importmap-mode +``` + +### Build Mode Matrix + + +| Mode | Resolver | Import map step | JSPM index needed | Typical use | +| --- | --- | --- | --- | --- | +| `importMap` | Import map in `dist/index.html` | Yes | Yes | Default production mode | +| `esm` | `src/cdn.js` (`esm.sh` primary) | No | No | Stable fallback mode | +| `jspmGa` | `src/cdn.js` (`ga.jspm.io` primary) | No | No | Direct ga.jspm.io testing | + + +Mode notes: + +- `importMap`: Preferred production mode when JSPM has indexed the required graph. +- `esm`: Stable fallback mode while waiting on JSPM indexing. +- `jspmGa`: Direct ga.jspm.io URL mode without import-map generation. + +This runs two steps: + +1. `npm run build:prepare` + +- Copies `src` to `dist` +- Injects `window.__KNIGHTED_PRIMARY_CDN__` into `dist/index.html` + +2. `npm run build:importmap` + +- Runs only when `KNIGHTED_PRIMARY_CDN=importMap` +- Runs `jspm link` with `--provider jspm.io` +- Injects an inline import map into `dist/index.html` +- Adds integrity metadata and modulepreload links +- Pins the following packages through resolution overrides: + - `sass=1.93.2` + - `less=4.4.2` +- Traces generated `dist/prod-imports.js` +- Import specifiers come from `importMap` entries in `src/cdn.js` (`cdnImportSpecs`) + +Preview the built site locally: + +```sh +npm run preview +``` + +## CI And Deployment + +- CI workflow (`.github/workflows/ci.yml`) installs dependencies, runs lint, and runs `npm run build`. +- Deploy workflow (`.github/workflows/deploy.yml`) builds the production site and publishes `dist` to GitHub Pages. + +## Notes + +- Runtime resolution is import-map first in production (`window.__KNIGHTED_PRIMARY_CDN__ = "importMap"`). +- If a specifier is missing from the generated map, runtime falls back through the CDN + provider chain configured in `src/cdn.js`. + +### Sass Loading Gotchas + +- Symptom: switching to Sass mode shows `Unable to load Sass compiler for browser usage: Dynamic require of "url" is not supported`. +- Cause: some `esm.sh` Sass outputs currently include runtime paths that are not browser-safe for this app. +- Current mitigation: `src/cdn.js` keeps `esm.sh` first, then falls back to `unpkg` for Sass via `sass@1.93.2/sass.default.js?module`. +- Important context: this can appear even if the Sass URL has not changed in this repo, because CDN-transformed module output can change upstream. +- If this regresses again: + - Verify Sass import candidates in `src/cdn.js`. + - Reproduce directly in browser devtools with `await import('')`. + - Keep at least one known browser-safe fallback provider in the Sass candidate list. diff --git a/package-lock.json b/package-lock.json index 27e3e70..89e44fd 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,10 +8,6 @@ "name": "@knighted/develop", "version": "0.1.0", "license": "MIT", - "dependencies": { - "@knighted/css": "^1.2.0", - "@knighted/jsx": "^1.8.0" - }, "devDependencies": { "http-server": "^14.1.1", "jspm": "^4.4.0", @@ -468,46 +464,6 @@ "node": ">=6.9.0" } }, - "node_modules/@emnapi/core": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.8.1.tgz", - "integrity": "sha512-AvT9QFpxK0Zd8J0jopedNm+w/2fIzvtPKPjqyw9jwvBaReTTqPBk9Hixaz7KbjimP+QNz605/XnjFcDAL2pqBg==", - "license": "MIT", - "dependencies": { - "@emnapi/wasi-threads": "1.1.0", - "tslib": "^2.4.0" - } - }, - "node_modules/@emnapi/runtime": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.8.1.tgz", - "integrity": "sha512-mehfKSMWjjNol8659Z8KxEMrdSJDDot5SXMq00dM8BN4o+CLNXQ0xH2V7EchNHV4RmbZLmmPdEaXZc5H2FXmDg==", - "license": "MIT", - "dependencies": { - "tslib": "^2.4.0" - } - }, - "node_modules/@emnapi/wasi-threads": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.1.0.tgz", - "integrity": "sha512-WI0DdZ8xFSbgMjR1sFsKABJ/C5OnRrjT06JXbZKexJGrDuPTzZdDYfFlsgcCXCyf+suG5QU2e/y1Wo2V/OapLQ==", - "license": "MIT", - "dependencies": { - "tslib": "^2.4.0" - } - }, - "node_modules/@isaacs/fs-minipass": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@isaacs/fs-minipass/-/fs-minipass-4.0.1.tgz", - "integrity": "sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==", - "license": "ISC", - "dependencies": { - "minipass": "^7.0.4" - }, - "engines": { - "node": ">=18.0.0" - } - }, "node_modules/@jridgewell/gen-mapping": { "version": "0.3.13", "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", @@ -555,6 +511,7 @@ "version": "1.5.5", "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", + "dev": true, "license": "MIT" }, "node_modules/@jridgewell/trace-mapping": { @@ -625,99 +582,6 @@ "terser": "^5.31.3" } }, - "node_modules/@knighted/css": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@knighted/css/-/css-1.2.0.tgz", - "integrity": "sha512-4ZMoDjO4a81H1ak69sd3bcKiFibqZtegShS225Yb3o76lK1ObvXoK9PmZPbpj6zcnZnFt2AsmRaXHqTc1ODi+A==", - "license": "MIT", - "dependencies": { - "es-module-lexer": "^2.0.0", - "get-tsconfig": "^4.13.0", - "lightningcss": "^1.30.1", - "node-module-type": "^1.0.1", - "oxc-parser": "^0.116.0", - "oxc-resolver": "^11.19.1", - "tsconfig-paths": "^4.2.0" - }, - "bin": { - "knighted-css-generate-types": "bin/generate-types.js" - }, - "peerDependencies": { - "@vanilla-extract/integration": "^8.0.0", - "less": "^4.2.0", - "sass": "^1.80.0" - }, - "peerDependenciesMeta": { - "@vanilla-extract/integration": { - "optional": true - }, - "less": { - "optional": true - }, - "sass": { - "optional": true - } - } - }, - "node_modules/@knighted/jsx": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/@knighted/jsx/-/jsx-1.8.0.tgz", - "integrity": "sha512-bKU/1kZksgCJm5mAapGWRk+2uYJqd6z1c/mkRwKk0et9rfgcvz3bogpvXccLA2VE3rYitUFPGob5kestEOSEoA==", - "license": "MIT", - "dependencies": { - "@napi-rs/wasm-runtime": "^1.1.1", - "magic-string": "^0.30.21", - "oxc-parser": "^0.116.0", - "property-information": "^7.1.0", - "tar": "^7.5.11" - }, - "bin": { - "jsx": "dist/cli/init.js" - }, - "engines": { - "node": ">=22.21.1" - }, - "optionalDependencies": { - "@oxc-parser/binding-darwin-arm64": "^0.116.0", - "@oxc-parser/binding-linux-x64-gnu": "^0.116.0", - "@oxc-parser/binding-wasm32-wasi": "^0.116.0" - }, - "peerDependencies": { - "@types/react": ">=18", - "jsdom": "*", - "linkedom": "*", - "react": ">=18" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "jsdom": { - "optional": true - }, - "linkedom": { - "optional": true - }, - "react": { - "optional": true - } - } - }, - "node_modules/@napi-rs/wasm-runtime": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.1.1.tgz", - "integrity": "sha512-p64ah1M1ld8xjWv3qbvFwHiFVWrq1yFvV4f7w+mzaqiR4IlSgkqhcRdHwsGgomwzBH51sRY4NEowLxnaBjcW/A==", - "license": "MIT", - "dependencies": { - "@emnapi/core": "^1.7.1", - "@emnapi/runtime": "^1.7.1", - "@tybys/wasm-util": "^0.10.1" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/Brooooooklyn" - } - }, "node_modules/@npmcli/fs": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-5.0.0.tgz", @@ -740,601 +604,9 @@ "bin": { "semver": "bin/semver.js" }, - "engines": { - "node": ">=10" - } - }, - "node_modules/@oxc-parser/binding-android-arm-eabi": { - "version": "0.116.0", - "resolved": "https://registry.npmjs.org/@oxc-parser/binding-android-arm-eabi/-/binding-android-arm-eabi-0.116.0.tgz", - "integrity": "sha512-AOET7YIOU3+ANO/3xQeRVGN5Xx6+JGXaIwlqkcHSfxJ/zzw2B6jb0YaLhX45SeRluKVTU8rka4N/tHtNoJjoCg==", - "cpu": [ - "arm" - ], - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@oxc-parser/binding-android-arm64": { - "version": "0.116.0", - "resolved": "https://registry.npmjs.org/@oxc-parser/binding-android-arm64/-/binding-android-arm64-0.116.0.tgz", - "integrity": "sha512-yh0Zvth5cQ6XZkP3QF9MDrXf695zr5XxXq/wBQqpZb0uAgI9wpr98/Hx2RZITMfnNjkIq2VcyU44o3A0bdEmlQ==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@oxc-parser/binding-darwin-arm64": { - "version": "0.116.0", - "resolved": "https://registry.npmjs.org/@oxc-parser/binding-darwin-arm64/-/binding-darwin-arm64-0.116.0.tgz", - "integrity": "sha512-plcTd/Jska55dToZz6XdRBPRVsj+asjD8QCpQFvt3Wj8pY+10D1pE53Mei3POAS/wSRSy7HiQ2twrm7H2A0CjA==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@oxc-parser/binding-darwin-x64": { - "version": "0.116.0", - "resolved": "https://registry.npmjs.org/@oxc-parser/binding-darwin-x64/-/binding-darwin-x64-0.116.0.tgz", - "integrity": "sha512-ahqcF3e3x5Z2ZepzXpZ8ugREdmxvBL+g1nQ0SxO11pIZfck6UtbOtwtdAAxnQXBHHtidu7lPcrBq1SEx26t1PQ==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@oxc-parser/binding-freebsd-x64": { - "version": "0.116.0", - "resolved": "https://registry.npmjs.org/@oxc-parser/binding-freebsd-x64/-/binding-freebsd-x64-0.116.0.tgz", - "integrity": "sha512-yo2/LaSXtlzKBurvNbwun/sN/RJwW3XhbMr069FwNVtft7GBnaLLdPIz/sf47icxw/BPViEX6wFvzeD12mtrAg==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@oxc-parser/binding-linux-arm-gnueabihf": { - "version": "0.116.0", - "resolved": "https://registry.npmjs.org/@oxc-parser/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-0.116.0.tgz", - "integrity": "sha512-EiZeliIPPdFsuaPx8PzDMVijD/4YaUxO46/eYPk5raRocJqjjxOG6GAacQ8UrG3fbrgYjaEChfYL1e8DyE445A==", - "cpu": [ - "arm" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@oxc-parser/binding-linux-arm-musleabihf": { - "version": "0.116.0", - "resolved": "https://registry.npmjs.org/@oxc-parser/binding-linux-arm-musleabihf/-/binding-linux-arm-musleabihf-0.116.0.tgz", - "integrity": "sha512-Nf7hnKRYRSIgglQcLAqE2St4b/Yr6dh+Z7in8mxol065Knevw71XZAiV1fmPSojq6uKPLV9eoH/wFrgr4TnZXw==", - "cpu": [ - "arm" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@oxc-parser/binding-linux-arm64-gnu": { - "version": "0.116.0", - "resolved": "https://registry.npmjs.org/@oxc-parser/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-0.116.0.tgz", - "integrity": "sha512-9SJI0S4Qggn3QHpT8Y1jtZceA0m4BlpvO3ne2Wxd33UdTHMmelAnrXryjWutHWQtjCzOwSnFBEoQAdNNyt1u3A==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@oxc-parser/binding-linux-arm64-musl": { - "version": "0.116.0", - "resolved": "https://registry.npmjs.org/@oxc-parser/binding-linux-arm64-musl/-/binding-linux-arm64-musl-0.116.0.tgz", - "integrity": "sha512-wMZ6//GI+q1JwO7G2OR51+eA5P8Gr3BobU8RAzCGJptvyGMkWb7KQ1E8s8naVZRr6bSGWAL2p3mCzKOxmEPmrA==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@oxc-parser/binding-linux-ppc64-gnu": { - "version": "0.116.0", - "resolved": "https://registry.npmjs.org/@oxc-parser/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-0.116.0.tgz", - "integrity": "sha512-5BO0KCzTG2HZTnp3r6SCAOeCs/GwFBQJ1WAOG/ROfDf1fVVEy6hrtLKTLCuUMaamH38v+1+RVEmzRkzBj+rMDQ==", - "cpu": [ - "ppc64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@oxc-parser/binding-linux-riscv64-gnu": { - "version": "0.116.0", - "resolved": "https://registry.npmjs.org/@oxc-parser/binding-linux-riscv64-gnu/-/binding-linux-riscv64-gnu-0.116.0.tgz", - "integrity": "sha512-M24gYb/ocVMnLwnH2wY5sLt4sRBkAUHDmfiYtyUYdKTkfPOKtpopd5otsL/BPLnIhpMD8zby4uXVvw7BU0UIlw==", - "cpu": [ - "riscv64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@oxc-parser/binding-linux-riscv64-musl": { - "version": "0.116.0", - "resolved": "https://registry.npmjs.org/@oxc-parser/binding-linux-riscv64-musl/-/binding-linux-riscv64-musl-0.116.0.tgz", - "integrity": "sha512-LHLXTHCH0bdvGjlitwr1ngeh32GAgq9HYzQ5VAgt0k0UT84AS8AkXj9Spoa9l20fXkVgSvAKcCEkydi4Ol23Dw==", - "cpu": [ - "riscv64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@oxc-parser/binding-linux-s390x-gnu": { - "version": "0.116.0", - "resolved": "https://registry.npmjs.org/@oxc-parser/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-0.116.0.tgz", - "integrity": "sha512-VE+XsztuE5jdHvLIDIQMuyDpz5NJGq1Vx/8EXYF0sS/gehlv9GhDpGVWU0SCZ/LjzIy4io/Z0W84UudqufvP3g==", - "cpu": [ - "s390x" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@oxc-parser/binding-linux-x64-gnu": { - "version": "0.116.0", - "resolved": "https://registry.npmjs.org/@oxc-parser/binding-linux-x64-gnu/-/binding-linux-x64-gnu-0.116.0.tgz", - "integrity": "sha512-rxUkauyjjCmgA7BoR63ogRGEtgubROnCm8AXE9ydg+p42jCGLLqG05mFcS2eC+FYyAU58ZFJNXXeqFW1iCyTGQ==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@oxc-parser/binding-linux-x64-musl": { - "version": "0.116.0", - "resolved": "https://registry.npmjs.org/@oxc-parser/binding-linux-x64-musl/-/binding-linux-x64-musl-0.116.0.tgz", - "integrity": "sha512-0zoZlk9MmXe6oTgSh5lT1D51SDC1bfwC96JmE1amMFAPdEbJk5MFRisfTN9TFBpBigQua65842tjaxqMiorAYw==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@oxc-parser/binding-openharmony-arm64": { - "version": "0.116.0", - "resolved": "https://registry.npmjs.org/@oxc-parser/binding-openharmony-arm64/-/binding-openharmony-arm64-0.116.0.tgz", - "integrity": "sha512-PGS7Xqik77U9WMyW626gAD5A2rSN629UvyYJKAl/tgpT+KqZI4+56pJfExhv8IW/PpSHjYHwjmakwobLikz8ww==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "openharmony" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@oxc-parser/binding-wasm32-wasi": { - "version": "0.116.0", - "resolved": "https://registry.npmjs.org/@oxc-parser/binding-wasm32-wasi/-/binding-wasm32-wasi-0.116.0.tgz", - "integrity": "sha512-lGNf/9PU8XxB4Gt1Gr1AKwSrjxGYa6os0PlrT4bpoQsfE3gaZonQTKwJyKhiQdgy7pBCI+ed1LB1NNib1FYULw==", - "cpu": [ - "wasm32" - ], - "license": "MIT", - "optional": true, - "dependencies": { - "@napi-rs/wasm-runtime": "^1.1.1" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@oxc-parser/binding-win32-arm64-msvc": { - "version": "0.116.0", - "resolved": "https://registry.npmjs.org/@oxc-parser/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-0.116.0.tgz", - "integrity": "sha512-tcsOHE31duBSRQXZ7NfdtjmMKZwQYlS00PwAMJ4w5oXs3iPCvisUuIXP7Ko4FzeOBTRvkd64btxtQ6cRM0Kwlw==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@oxc-parser/binding-win32-ia32-msvc": { - "version": "0.116.0", - "resolved": "https://registry.npmjs.org/@oxc-parser/binding-win32-ia32-msvc/-/binding-win32-ia32-msvc-0.116.0.tgz", - "integrity": "sha512-higCz/x+dOQ264YEk22hnu4RDqvjhfehjFORpxoh42QyUxsP6eIembYesBUu5ilALWo0HvRD+m89az2BSTwqpQ==", - "cpu": [ - "ia32" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@oxc-parser/binding-win32-x64-msvc": { - "version": "0.116.0", - "resolved": "https://registry.npmjs.org/@oxc-parser/binding-win32-x64-msvc/-/binding-win32-x64-msvc-0.116.0.tgz", - "integrity": "sha512-Lg2SRmVHpGG85knDVLbv44r1bYn0OpIV0vg9jVmoEIpDj3Q4kwXuQ6MWVtuslwHR8o2CSiqdBeEn1n1URrs6Eg==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, - "node_modules/@oxc-project/types": { - "version": "0.116.0", - "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.116.0.tgz", - "integrity": "sha512-uOT8S1tlPmDckNxMNtIudN/yXpLdnhlJMX2oLS7cxCd7L0sUF09A/EbSVMWT3Y/iT44IwXCJSJfgfSxXAqWf9Q==", - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/Boshen" - } - }, - "node_modules/@oxc-resolver/binding-android-arm-eabi": { - "version": "11.19.1", - "resolved": "https://registry.npmjs.org/@oxc-resolver/binding-android-arm-eabi/-/binding-android-arm-eabi-11.19.1.tgz", - "integrity": "sha512-aUs47y+xyXHUKlbhqHUjBABjvycq6YSD7bpxSW7vplUmdzAlJ93yXY6ZR0c1o1x5A/QKbENCvs3+NlY8IpIVzg==", - "cpu": [ - "arm" - ], - "license": "MIT", - "optional": true, - "os": [ - "android" - ] - }, - "node_modules/@oxc-resolver/binding-android-arm64": { - "version": "11.19.1", - "resolved": "https://registry.npmjs.org/@oxc-resolver/binding-android-arm64/-/binding-android-arm64-11.19.1.tgz", - "integrity": "sha512-oolbkRX+m7Pq2LNjr/kKgYeC7bRDMVTWPgxBGMjSpZi/+UskVo4jsMU3MLheZV55jL6c3rNelPl4oD60ggYmqA==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "android" - ] - }, - "node_modules/@oxc-resolver/binding-darwin-arm64": { - "version": "11.19.1", - "resolved": "https://registry.npmjs.org/@oxc-resolver/binding-darwin-arm64/-/binding-darwin-arm64-11.19.1.tgz", - "integrity": "sha512-nUC6d2i3R5B12sUW4O646qD5cnMXf2oBGPLIIeaRfU9doJRORAbE2SGv4eW6rMqhD+G7nf2Y8TTJTLiiO3Q/dQ==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@oxc-resolver/binding-darwin-x64": { - "version": "11.19.1", - "resolved": "https://registry.npmjs.org/@oxc-resolver/binding-darwin-x64/-/binding-darwin-x64-11.19.1.tgz", - "integrity": "sha512-cV50vE5+uAgNcFa3QY1JOeKDSkM/9ReIcc/9wn4TavhW/itkDGrXhw9jaKnkQnGbjJ198Yh5nbX/Gr2mr4Z5jQ==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@oxc-resolver/binding-freebsd-x64": { - "version": "11.19.1", - "resolved": "https://registry.npmjs.org/@oxc-resolver/binding-freebsd-x64/-/binding-freebsd-x64-11.19.1.tgz", - "integrity": "sha512-xZOQiYGFxtk48PBKff+Zwoym7ScPAIVp4c14lfLxizO2LTTTJe5sx9vQNGrBymrf/vatSPNMD4FgsaaRigPkqw==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ] - }, - "node_modules/@oxc-resolver/binding-linux-arm-gnueabihf": { - "version": "11.19.1", - "resolved": "https://registry.npmjs.org/@oxc-resolver/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-11.19.1.tgz", - "integrity": "sha512-lXZYWAC6kaGe/ky2su94e9jN9t6M0/6c+GrSlCqL//XO1cxi5lpAhnJYdyrKfm0ZEr/c7RNyAx3P7FSBcBd5+A==", - "cpu": [ - "arm" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@oxc-resolver/binding-linux-arm-musleabihf": { - "version": "11.19.1", - "resolved": "https://registry.npmjs.org/@oxc-resolver/binding-linux-arm-musleabihf/-/binding-linux-arm-musleabihf-11.19.1.tgz", - "integrity": "sha512-veG1kKsuK5+t2IsO9q0DErYVSw2azvCVvWHnfTOS73WE0STdLLB7Q1bB9WR+yHPQM76ASkFyRbogWo1GR1+WbQ==", - "cpu": [ - "arm" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@oxc-resolver/binding-linux-arm64-gnu": { - "version": "11.19.1", - "resolved": "https://registry.npmjs.org/@oxc-resolver/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-11.19.1.tgz", - "integrity": "sha512-heV2+jmXyYnUrpUXSPugqWDRpnsQcDm2AX4wzTuvgdlZfoNYO0O3W2AVpJYaDn9AG4JdM6Kxom8+foE7/BcSig==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@oxc-resolver/binding-linux-arm64-musl": { - "version": "11.19.1", - "resolved": "https://registry.npmjs.org/@oxc-resolver/binding-linux-arm64-musl/-/binding-linux-arm64-musl-11.19.1.tgz", - "integrity": "sha512-jvo2Pjs1c9KPxMuMPIeQsgu0mOJF9rEb3y3TdpsrqwxRM+AN6/nDDwv45n5ZrUnQMsdBy5gIabioMKnQfWo9ew==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@oxc-resolver/binding-linux-ppc64-gnu": { - "version": "11.19.1", - "resolved": "https://registry.npmjs.org/@oxc-resolver/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-11.19.1.tgz", - "integrity": "sha512-vLmdNxWCdN7Uo5suays6A/+ywBby2PWBBPXctWPg5V0+eVuzsJxgAn6MMB4mPlshskYbppjpN2Zg83ArHze9gQ==", - "cpu": [ - "ppc64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@oxc-resolver/binding-linux-riscv64-gnu": { - "version": "11.19.1", - "resolved": "https://registry.npmjs.org/@oxc-resolver/binding-linux-riscv64-gnu/-/binding-linux-riscv64-gnu-11.19.1.tgz", - "integrity": "sha512-/b+WgR+VTSBxzgOhDO7TlMXC1ufPIMR6Vj1zN+/x+MnyXGW7prTLzU9eW85Aj7Th7CCEG9ArCbTeqxCzFWdg2w==", - "cpu": [ - "riscv64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@oxc-resolver/binding-linux-riscv64-musl": { - "version": "11.19.1", - "resolved": "https://registry.npmjs.org/@oxc-resolver/binding-linux-riscv64-musl/-/binding-linux-riscv64-musl-11.19.1.tgz", - "integrity": "sha512-YlRdeWb9j42p29ROh+h4eg/OQ3dTJlpHSa+84pUM9+p6i3djtPz1q55yLJhgW9XfDch7FN1pQ/Vd6YP+xfRIuw==", - "cpu": [ - "riscv64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@oxc-resolver/binding-linux-s390x-gnu": { - "version": "11.19.1", - "resolved": "https://registry.npmjs.org/@oxc-resolver/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-11.19.1.tgz", - "integrity": "sha512-EDpafVOQWF8/MJynsjOGFThcqhRHy417sRyLfQmeiamJ8qVhSKAn2Dn2VVKUGCjVB9C46VGjhNo7nOPUi1x6uA==", - "cpu": [ - "s390x" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@oxc-resolver/binding-linux-x64-gnu": { - "version": "11.19.1", - "resolved": "https://registry.npmjs.org/@oxc-resolver/binding-linux-x64-gnu/-/binding-linux-x64-gnu-11.19.1.tgz", - "integrity": "sha512-NxjZe+rqWhr+RT8/Ik+5ptA3oz7tUw361Wa5RWQXKnfqwSSHdHyrw6IdcTfYuml9dM856AlKWZIUXDmA9kkiBQ==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@oxc-resolver/binding-linux-x64-musl": { - "version": "11.19.1", - "resolved": "https://registry.npmjs.org/@oxc-resolver/binding-linux-x64-musl/-/binding-linux-x64-musl-11.19.1.tgz", - "integrity": "sha512-cM/hQwsO3ReJg5kR+SpI69DMfvNCp+A/eVR4b4YClE5bVZwz8rh2Nh05InhwI5HR/9cArbEkzMjcKgTHS6UaNw==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@oxc-resolver/binding-openharmony-arm64": { - "version": "11.19.1", - "resolved": "https://registry.npmjs.org/@oxc-resolver/binding-openharmony-arm64/-/binding-openharmony-arm64-11.19.1.tgz", - "integrity": "sha512-QF080IowFB0+9Rh6RcD19bdgh49BpQHUW5TajG1qvWHvmrQznTZZjYlgE2ltLXyKY+qs4F/v5xuX1XS7Is+3qA==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "openharmony" - ] - }, - "node_modules/@oxc-resolver/binding-wasm32-wasi": { - "version": "11.19.1", - "resolved": "https://registry.npmjs.org/@oxc-resolver/binding-wasm32-wasi/-/binding-wasm32-wasi-11.19.1.tgz", - "integrity": "sha512-w8UCKhX826cP/ZLokXDS6+milN8y4X7zidsAttEdWlVoamTNf6lhBJldaWr3ukTDiye7s4HRcuPEPOXNC432Vg==", - "cpu": [ - "wasm32" - ], - "license": "MIT", - "optional": true, - "dependencies": { - "@napi-rs/wasm-runtime": "^1.1.1" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@oxc-resolver/binding-win32-arm64-msvc": { - "version": "11.19.1", - "resolved": "https://registry.npmjs.org/@oxc-resolver/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-11.19.1.tgz", - "integrity": "sha512-nJ4AsUVZrVKwnU/QRdzPCCrO0TrabBqgJ8pJhXITdZGYOV28TIYystV1VFLbQ7DtAcaBHpocT5/ZJnF78YJPtQ==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@oxc-resolver/binding-win32-ia32-msvc": { - "version": "11.19.1", - "resolved": "https://registry.npmjs.org/@oxc-resolver/binding-win32-ia32-msvc/-/binding-win32-ia32-msvc-11.19.1.tgz", - "integrity": "sha512-EW+ND5q2Tl+a3pH81l1QbfgbF3HmqgwLfDfVithRFheac8OTcnbXt/JxqD2GbDkb7xYEqy1zNaVFRr3oeG8npA==", - "cpu": [ - "ia32" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@oxc-resolver/binding-win32-x64-msvc": { - "version": "11.19.1", - "resolved": "https://registry.npmjs.org/@oxc-resolver/binding-win32-x64-msvc/-/binding-win32-x64-msvc-11.19.1.tgz", - "integrity": "sha512-6hIU3RQu45B+VNTY4Ru8ppFwjVS/S5qwYyGhBotmjxfEKk41I2DlGtRfGJndZ5+6lneE2pwloqunlOyZuX/XAw==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ] + "engines": { + "node": ">=10" + } }, "node_modules/@oxlint/binding-android-arm-eabi": { "version": "1.55.0", @@ -1659,15 +931,6 @@ "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/@tybys/wasm-util": { - "version": "0.10.1", - "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.1.tgz", - "integrity": "sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg==", - "license": "MIT", - "dependencies": { - "tslib": "^2.4.0" - } - }, "node_modules/acorn": { "version": "8.16.0", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.16.0.tgz", @@ -2017,15 +1280,6 @@ "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/chownr": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-3.0.0.tgz", - "integrity": "sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==", - "license": "BlueOak-1.0.0", - "engines": { - "node": ">=18" - } - }, "node_modules/cjs-module-lexer": { "version": "1.4.3", "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.4.3.tgz", @@ -2134,15 +1388,6 @@ } } }, - "node_modules/detect-libc": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", - "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", - "license": "Apache-2.0", - "engines": { - "node": ">=8" - } - }, "node_modules/dunder-proto": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", @@ -2192,12 +1437,6 @@ "node": ">= 0.4" } }, - "node_modules/es-module-lexer": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-2.0.0.tgz", - "integrity": "sha512-5POEcUuZybH7IdmGsD8wlf0AI55wMecM9rVBTI/qEAy2c1kTOm3DjFYjrBdI2K3BaJjJYfYFeRtM0t9ssnRuxw==", - "license": "MIT" - }, "node_modules/es-object-atoms": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", @@ -2398,18 +1637,6 @@ "node": ">= 0.4" } }, - "node_modules/get-tsconfig": { - "version": "4.13.1", - "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.13.1.tgz", - "integrity": "sha512-EoY1N2xCn44xU6750Sx7OjOIT59FkmstNc3X6y5xpz7D5cBtZRe/3pSlTkDJgqsOk3WwZPkWfonhhUJfttQo3w==", - "license": "MIT", - "dependencies": { - "resolve-pkg-maps": "^1.0.0" - }, - "funding": { - "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1" - } - }, "node_modules/glob": { "version": "13.0.6", "resolved": "https://registry.npmjs.org/glob/-/glob-13.0.6.tgz", @@ -2616,6 +1843,7 @@ "version": "2.2.3", "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "dev": true, "license": "MIT", "bin": { "json5": "lib/cli.js" @@ -2641,255 +1869,6 @@ "jspm": "dist/jspm.js" } }, - "node_modules/lightningcss": { - "version": "1.31.1", - "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.31.1.tgz", - "integrity": "sha512-l51N2r93WmGUye3WuFoN5k10zyvrVs0qfKBhyC5ogUQ6Ew6JUSswh78mbSO+IU3nTWsyOArqPCcShdQSadghBQ==", - "license": "MPL-2.0", - "dependencies": { - "detect-libc": "^2.0.3" - }, - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - }, - "optionalDependencies": { - "lightningcss-android-arm64": "1.31.1", - "lightningcss-darwin-arm64": "1.31.1", - "lightningcss-darwin-x64": "1.31.1", - "lightningcss-freebsd-x64": "1.31.1", - "lightningcss-linux-arm-gnueabihf": "1.31.1", - "lightningcss-linux-arm64-gnu": "1.31.1", - "lightningcss-linux-arm64-musl": "1.31.1", - "lightningcss-linux-x64-gnu": "1.31.1", - "lightningcss-linux-x64-musl": "1.31.1", - "lightningcss-win32-arm64-msvc": "1.31.1", - "lightningcss-win32-x64-msvc": "1.31.1" - } - }, - "node_modules/lightningcss-android-arm64": { - "version": "1.31.1", - "resolved": "https://registry.npmjs.org/lightningcss-android-arm64/-/lightningcss-android-arm64-1.31.1.tgz", - "integrity": "sha512-HXJF3x8w9nQ4jbXRiNppBCqeZPIAfUo8zE/kOEGbW5NZvGc/K7nMxbhIr+YlFlHW5mpbg/YFPdbnCh1wAXCKFg==", - "cpu": [ - "arm64" - ], - "license": "MPL-2.0", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-darwin-arm64": { - "version": "1.31.1", - "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.31.1.tgz", - "integrity": "sha512-02uTEqf3vIfNMq3h/z2cJfcOXnQ0GRwQrkmPafhueLb2h7mqEidiCzkE4gBMEH65abHRiQvhdcQ+aP0D0g67sg==", - "cpu": [ - "arm64" - ], - "license": "MPL-2.0", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-darwin-x64": { - "version": "1.31.1", - "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.31.1.tgz", - "integrity": "sha512-1ObhyoCY+tGxtsz1lSx5NXCj3nirk0Y0kB/g8B8DT+sSx4G9djitg9ejFnjb3gJNWo7qXH4DIy2SUHvpoFwfTA==", - "cpu": [ - "x64" - ], - "license": "MPL-2.0", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-freebsd-x64": { - "version": "1.31.1", - "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.31.1.tgz", - "integrity": "sha512-1RINmQKAItO6ISxYgPwszQE1BrsVU5aB45ho6O42mu96UiZBxEXsuQ7cJW4zs4CEodPUioj/QrXW1r9pLUM74A==", - "cpu": [ - "x64" - ], - "license": "MPL-2.0", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-linux-arm-gnueabihf": { - "version": "1.31.1", - "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.31.1.tgz", - "integrity": "sha512-OOCm2//MZJ87CdDK62rZIu+aw9gBv4azMJuA8/KB74wmfS3lnC4yoPHm0uXZ/dvNNHmnZnB8XLAZzObeG0nS1g==", - "cpu": [ - "arm" - ], - "license": "MPL-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-linux-arm64-gnu": { - "version": "1.31.1", - "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.31.1.tgz", - "integrity": "sha512-WKyLWztD71rTnou4xAD5kQT+982wvca7E6QoLpoawZ1gP9JM0GJj4Tp5jMUh9B3AitHbRZ2/H3W5xQmdEOUlLg==", - "cpu": [ - "arm64" - ], - "license": "MPL-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-linux-arm64-musl": { - "version": "1.31.1", - "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.31.1.tgz", - "integrity": "sha512-mVZ7Pg2zIbe3XlNbZJdjs86YViQFoJSpc41CbVmKBPiGmC4YrfeOyz65ms2qpAobVd7WQsbW4PdsSJEMymyIMg==", - "cpu": [ - "arm64" - ], - "license": "MPL-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-linux-x64-gnu": { - "version": "1.31.1", - "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.31.1.tgz", - "integrity": "sha512-xGlFWRMl+0KvUhgySdIaReQdB4FNudfUTARn7q0hh/V67PVGCs3ADFjw+6++kG1RNd0zdGRlEKa+T13/tQjPMA==", - "cpu": [ - "x64" - ], - "license": "MPL-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-linux-x64-musl": { - "version": "1.31.1", - "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.31.1.tgz", - "integrity": "sha512-eowF8PrKHw9LpoZii5tdZwnBcYDxRw2rRCyvAXLi34iyeYfqCQNA9rmUM0ce62NlPhCvof1+9ivRaTY6pSKDaA==", - "cpu": [ - "x64" - ], - "license": "MPL-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-win32-arm64-msvc": { - "version": "1.31.1", - "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.31.1.tgz", - "integrity": "sha512-aJReEbSEQzx1uBlQizAOBSjcmr9dCdL3XuC/6HLXAxmtErsj2ICo5yYggg1qOODQMtnjNQv2UHb9NpOuFtYe4w==", - "cpu": [ - "arm64" - ], - "license": "MPL-2.0", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-win32-x64-msvc": { - "version": "1.31.1", - "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.31.1.tgz", - "integrity": "sha512-I9aiFrbd7oYHwlnQDqr1Roz+fTz61oDDJX7n9tYF9FJymH1cIN1DtKw3iYt6b8WZgEjoNwVSncwF4wx/ZedMhw==", - "cpu": [ - "x64" - ], - "license": "MPL-2.0", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, "node_modules/locko": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/locko/-/locko-1.1.0.tgz", @@ -2957,15 +1936,6 @@ "dev": true, "license": "ISC" }, - "node_modules/magic-string": { - "version": "0.30.21", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz", - "integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==", - "license": "MIT", - "dependencies": { - "@jridgewell/sourcemap-codec": "^1.5.5" - } - }, "node_modules/math-intrinsics": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", @@ -3022,6 +1992,7 @@ "version": "1.2.8", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "dev": true, "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" @@ -3031,6 +2002,7 @@ "version": "7.1.3", "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.3.tgz", "integrity": "sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==", + "dev": true, "license": "BlueOak-1.0.0", "engines": { "node": ">=16 || 14 >=14.17" @@ -3115,18 +2087,6 @@ "dev": true, "license": "ISC" }, - "node_modules/minizlib": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-3.1.0.tgz", - "integrity": "sha512-KZxYo1BUkWD2TVFLr0MQoM8vUUigWD3LlD83a/75BqC+4qE0Hb1Vo5v1FgcfaNXvfXzr+5EhQ6ing/CaBijTlw==", - "license": "MIT", - "dependencies": { - "minipass": "^7.1.2" - }, - "engines": { - "node": ">= 18" - } - }, "node_modules/ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", @@ -3190,20 +2150,6 @@ "node": ">=18.19.0" } }, - "node_modules/node-module-type": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/node-module-type/-/node-module-type-1.0.4.tgz", - "integrity": "sha512-jJEWdpQFDFhjA87debF8AgaBXPkHyFCw/6atsRwOGu/bpVwje1ZAl8/0WuwxrYNRUdWQ5YNUOT0ARSZeqjFlGA==", - "license": "MIT", - "workspaces": [ - "test/ambiguous", - "test/cjslib", - "test/esmlib" - ], - "engines": { - "node": ">=20.19.0" - } - }, "node_modules/node-releases": { "version": "2.0.36", "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.36.tgz", @@ -3287,74 +2233,6 @@ "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/oxc-parser": { - "version": "0.116.0", - "resolved": "https://registry.npmjs.org/oxc-parser/-/oxc-parser-0.116.0.tgz", - "integrity": "sha512-ugEo6wwqaqCGcpi7GsLCwSkoD7gIXzvtdaTxE+mbrXFYazU5Q9YdpZdAj9z2b79i/xlv+uW2aAvyzGAlpUzhKQ==", - "license": "MIT", - "dependencies": { - "@oxc-project/types": "^0.116.0" - }, - "engines": { - "node": "^20.19.0 || >=22.12.0" - }, - "funding": { - "url": "https://github.com/sponsors/Boshen" - }, - "optionalDependencies": { - "@oxc-parser/binding-android-arm-eabi": "0.116.0", - "@oxc-parser/binding-android-arm64": "0.116.0", - "@oxc-parser/binding-darwin-arm64": "0.116.0", - "@oxc-parser/binding-darwin-x64": "0.116.0", - "@oxc-parser/binding-freebsd-x64": "0.116.0", - "@oxc-parser/binding-linux-arm-gnueabihf": "0.116.0", - "@oxc-parser/binding-linux-arm-musleabihf": "0.116.0", - "@oxc-parser/binding-linux-arm64-gnu": "0.116.0", - "@oxc-parser/binding-linux-arm64-musl": "0.116.0", - "@oxc-parser/binding-linux-ppc64-gnu": "0.116.0", - "@oxc-parser/binding-linux-riscv64-gnu": "0.116.0", - "@oxc-parser/binding-linux-riscv64-musl": "0.116.0", - "@oxc-parser/binding-linux-s390x-gnu": "0.116.0", - "@oxc-parser/binding-linux-x64-gnu": "0.116.0", - "@oxc-parser/binding-linux-x64-musl": "0.116.0", - "@oxc-parser/binding-openharmony-arm64": "0.116.0", - "@oxc-parser/binding-wasm32-wasi": "0.116.0", - "@oxc-parser/binding-win32-arm64-msvc": "0.116.0", - "@oxc-parser/binding-win32-ia32-msvc": "0.116.0", - "@oxc-parser/binding-win32-x64-msvc": "0.116.0" - } - }, - "node_modules/oxc-resolver": { - "version": "11.19.1", - "resolved": "https://registry.npmjs.org/oxc-resolver/-/oxc-resolver-11.19.1.tgz", - "integrity": "sha512-qE/CIg/spwrTBFt5aKmwe3ifeDdLfA2NESN30E42X/lII5ClF8V7Wt6WIJhcGZjp0/Q+nQ+9vgxGk//xZNX2hg==", - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/Boshen" - }, - "optionalDependencies": { - "@oxc-resolver/binding-android-arm-eabi": "11.19.1", - "@oxc-resolver/binding-android-arm64": "11.19.1", - "@oxc-resolver/binding-darwin-arm64": "11.19.1", - "@oxc-resolver/binding-darwin-x64": "11.19.1", - "@oxc-resolver/binding-freebsd-x64": "11.19.1", - "@oxc-resolver/binding-linux-arm-gnueabihf": "11.19.1", - "@oxc-resolver/binding-linux-arm-musleabihf": "11.19.1", - "@oxc-resolver/binding-linux-arm64-gnu": "11.19.1", - "@oxc-resolver/binding-linux-arm64-musl": "11.19.1", - "@oxc-resolver/binding-linux-ppc64-gnu": "11.19.1", - "@oxc-resolver/binding-linux-riscv64-gnu": "11.19.1", - "@oxc-resolver/binding-linux-riscv64-musl": "11.19.1", - "@oxc-resolver/binding-linux-s390x-gnu": "11.19.1", - "@oxc-resolver/binding-linux-x64-gnu": "11.19.1", - "@oxc-resolver/binding-linux-x64-musl": "11.19.1", - "@oxc-resolver/binding-openharmony-arm64": "11.19.1", - "@oxc-resolver/binding-wasm32-wasi": "11.19.1", - "@oxc-resolver/binding-win32-arm64-msvc": "11.19.1", - "@oxc-resolver/binding-win32-ia32-msvc": "11.19.1", - "@oxc-resolver/binding-win32-x64-msvc": "11.19.1" - } - }, "node_modules/oxlint": { "version": "1.55.0", "resolved": "https://registry.npmjs.org/oxlint/-/oxlint-1.55.0.tgz", @@ -3484,16 +2362,6 @@ "url": "https://github.com/prettier/prettier?sponsor=1" } }, - "node_modules/property-information": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/property-information/-/property-information-7.1.0.tgz", - "integrity": "sha512-TwEZ+X+yCJmYfL7TPUOcvBZ4QfoT5YenQiJuX//0th53DE6w0xxLEtfK3iyryQFddXuvkIk51EEgrJQ0WJkOmQ==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, "node_modules/qs": { "version": "6.14.1", "resolved": "https://registry.npmjs.org/qs/-/qs-6.14.1.tgz", @@ -3517,15 +2385,6 @@ "dev": true, "license": "MIT" }, - "node_modules/resolve-pkg-maps": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", - "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==", - "license": "MIT", - "funding": { - "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" - } - }, "node_modules/restore-cursor": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-5.1.0.tgz", @@ -3756,15 +2615,6 @@ "url": "https://github.com/chalk/strip-ansi?sponsor=1" } }, - "node_modules/strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", - "license": "MIT", - "engines": { - "node": ">=4" - } - }, "node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -3785,22 +2635,6 @@ "dev": true, "license": "MIT" }, - "node_modules/tar": { - "version": "7.5.11", - "resolved": "https://registry.npmjs.org/tar/-/tar-7.5.11.tgz", - "integrity": "sha512-ChjMH33/KetonMTAtpYdgUFr0tbz69Fp2v7zWxQfYZX4g5ZN2nOBXm1R2xyA+lMIKrLKIoKAwFj93jE/avX9cQ==", - "license": "BlueOak-1.0.0", - "dependencies": { - "@isaacs/fs-minipass": "^4.0.0", - "chownr": "^3.0.0", - "minipass": "^7.1.2", - "minizlib": "^3.1.0", - "yallist": "^5.0.0" - }, - "engines": { - "node": ">=18" - } - }, "node_modules/tar-stream": { "version": "3.1.8", "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-3.1.8.tgz", @@ -3853,26 +2687,6 @@ "b4a": "^1.6.4" } }, - "node_modules/tsconfig-paths": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-4.2.0.tgz", - "integrity": "sha512-NoZ4roiN7LnbKn9QqE1amc9DJfzvZXxF4xDavcOWt1BPkdx+m+0gJuPM+S0vCe7zTJMYUP0R8pO2XMr+Y8oLIg==", - "license": "MIT", - "dependencies": { - "json5": "^2.2.2", - "minimist": "^1.2.6", - "strip-bom": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/tslib": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", - "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", - "license": "0BSD" - }, "node_modules/union": { "version": "0.5.0", "resolved": "https://registry.npmjs.org/union/-/union-0.5.0.tgz", @@ -3972,15 +2786,6 @@ "engines": { "node": ">=12" } - }, - "node_modules/yallist": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-5.0.0.tgz", - "integrity": "sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==", - "license": "BlueOak-1.0.0", - "engines": { - "node": ">=18" - } } } } diff --git a/package.json b/package.json index 835f622..bc509c5 100644 --- a/package.json +++ b/package.json @@ -14,14 +14,17 @@ "type": "module", "main": "index.js", "scripts": { - "dev": "http-server . -c-1 -o src/index.html", + "dev": "http-server . -a localhost -c-1 -o src/index.html", + "build:prepare": "node scripts/build-prepare.js", + "build:importmap": "node scripts/build-importmap.js", + "build": "npm run build:prepare && npm run build:importmap", + "build:esm": "KNIGHTED_PRIMARY_CDN=esm npm run build", + "build:jspm": "KNIGHTED_PRIMARY_CDN=jspmGa npm run build", + "build:importmap-mode": "KNIGHTED_PRIMARY_CDN=importMap npm run build", + "preview": "http-server dist -a localhost -c-1 -o index.html", "test": "echo \"Error: no test specified\" && exit 1", "prettier": "prettier --write .", - "lint": "oxlint" - }, - "dependencies": { - "@knighted/css": "^1.2.0", - "@knighted/jsx": "^1.8.0" + "lint": "oxlint src scripts" }, "devDependencies": { "http-server": "^14.1.1", diff --git a/scripts/build-importmap.js b/scripts/build-importmap.js new file mode 100644 index 0000000..8f11fd4 --- /dev/null +++ b/scripts/build-importmap.js @@ -0,0 +1,39 @@ +import { spawnSync } from 'node:child_process' + +const npxCommand = process.platform === 'win32' ? 'npx.cmd' : 'npx' +const primaryCdn = process.env.KNIGHTED_PRIMARY_CDN ?? 'importMap' + +if (primaryCdn !== 'importMap') { + process.stderr.write( + `[build-importmap] Skipping import-map generation for primary CDN: ${primaryCdn}.\n`, + ) + process.exit(0) +} + +const commonArgs = [ + 'jspm', + 'link', + '--map', + './dist/index.html', + '--out', + './dist/index.html', + '--provider', + 'jspm.io', + '--release', + '--integrity', + '--preload=static', + '--resolution', + 'sass=1.93.2,less=4.4.2', + './dist/prod-imports.js', +] + +const linkResult = spawnSync(npxCommand, commonArgs, { + stdio: 'inherit', + encoding: 'utf8', +}) + +if (linkResult.status === 0) { + process.exit(0) +} + +process.exit(linkResult.status ?? 1) diff --git a/scripts/build-prepare.js b/scripts/build-prepare.js new file mode 100644 index 0000000..f2f3680 --- /dev/null +++ b/scripts/build-prepare.js @@ -0,0 +1,86 @@ +import { cp, mkdir, readFile, rm, writeFile } from 'node:fs/promises' +import { dirname, resolve } from 'node:path' +import { fileURLToPath } from 'node:url' +import { cdnImportSpecs } from '../src/cdn.js' + +const validPrimaryCdns = new Set(['importMap', 'esm', 'jspmGa']) + +const parsePrimaryCdnFromArgs = argv => { + for (const arg of argv) { + if (!arg.startsWith('--primary-cdn=')) continue + const value = arg.slice('--primary-cdn='.length) + return value || null + } + return null +} + +const resolvePrimaryCdn = () => { + const fromArgs = parsePrimaryCdnFromArgs(process.argv.slice(2)) + const fromEnv = process.env.KNIGHTED_PRIMARY_CDN + const selected = fromArgs ?? fromEnv ?? 'importMap' + + if (!validPrimaryCdns.has(selected)) { + throw new Error( + `Invalid primary CDN: ${selected}. Expected one of importMap, esm, jspmGa.`, + ) + } + + return selected +} + +const __dirname = dirname(fileURLToPath(import.meta.url)) +const projectRoot = resolve(__dirname, '..') +const srcDir = resolve(projectRoot, 'src') +const distDir = resolve(projectRoot, 'dist') +const distIndexHtml = resolve(distDir, 'index.html') +const distProdImportsFile = resolve(distDir, 'prod-imports.js') + +const primaryCdn = resolvePrimaryCdn() + +const productionRuntimeScript = `` + +const createProdImportsModule = async () => { + const specifiers = [ + ...new Set( + Object.values(cdnImportSpecs) + .map(spec => spec?.importMap) + .filter(specifier => typeof specifier === 'string' && specifier.length > 0), + ), + ] + + if (specifiers.length === 0) { + throw new Error('No importMap specifiers found in src/cdn.js (cdnImportSpecs).') + } + + const lines = [ + '/*', + ' * Generated by scripts/build-prepare.js from src/cdn.js (cdnImportSpecs).', + ' * JSPM links this module to trace top-level production imports.', + ' */', + ...specifiers.map(specifier => `import '${specifier}'`), + '', + ] + + await writeFile(distProdImportsFile, lines.join('\n')) +} + +await rm(distDir, { recursive: true, force: true }) +await mkdir(distDir, { recursive: true }) +await cp(srcDir, distDir, { recursive: true }) +await createProdImportsModule() + +const html = await readFile(distIndexHtml, 'utf8') + +if (!html.includes(productionRuntimeScript)) { + const moduleScriptTag = '' + const updatedHtml = html.replace( + moduleScriptTag, + `${productionRuntimeScript}\n ${moduleScriptTag}`, + ) + + if (updatedHtml === html) { + throw new Error('Could not locate bootstrap module script tag in dist/index.html.') + } + + await writeFile(distIndexHtml, updatedHtml) +} diff --git a/src/bootstrap.js b/src/bootstrap.js index 3246b5b..21fb4ec 100644 --- a/src/bootstrap.js +++ b/src/bootstrap.js @@ -15,6 +15,9 @@ const preloadImportKeys = [ 'reactDomClient', ] +const isImportMapPrimary = + typeof globalThis !== 'undefined' && globalThis.__KNIGHTED_PRIMARY_CDN__ === 'importMap' + const ensureModulePreloadLinks = hrefs => { for (const href of hrefs) { const existing = document.head.querySelector( @@ -33,6 +36,8 @@ const ensureModulePreloadLinks = hrefs => { } } -ensureModulePreloadLinks(getPrimaryCdnImportUrls(preloadImportKeys)) +if (!isImportMapPrimary) { + ensureModulePreloadLinks(getPrimaryCdnImportUrls(preloadImportKeys)) +} await import('./app.js') diff --git a/src/cdn.js b/src/cdn.js index 246e116..c45f3e7 100644 --- a/src/cdn.js +++ b/src/cdn.js @@ -1,8 +1,16 @@ const cdnProviders = { + importMap: { + label: 'import map', + host: '', + }, esm: { label: 'esm.sh', host: 'https://esm.sh', }, + unpkg: { + label: 'unpkg', + host: 'https://unpkg.com', + }, jspmGa: { label: 'ga.jspm.io', host: 'https://ga.jspm.io', @@ -10,44 +18,72 @@ const cdnProviders = { } /* - * Toggle this between 'esm' and 'jspmGa' to swap the preferred CDN strategy. - * The alternate provider is used as fallback automatically. + * Local dev defaults to esm.sh. + * Production can set window.__KNIGHTED_PRIMARY_CDN__ = 'importMap'. */ -const primaryCdnProvider = 'esm' - -const secondaryCdnProvider = primaryCdnProvider === 'esm' ? 'jspmGa' : 'esm' +const defaultPrimaryCdnProvider = 'esm' + +const configuredPrimaryCdnProvider = + typeof globalThis !== 'undefined' && + typeof globalThis.__KNIGHTED_PRIMARY_CDN__ === 'string' + ? globalThis.__KNIGHTED_PRIMARY_CDN__ + : defaultPrimaryCdnProvider + +const primaryCdnProvider = + configuredPrimaryCdnProvider in cdnProviders + ? configuredPrimaryCdnProvider + : defaultPrimaryCdnProvider + +const fallbackCdnProvidersByPrimary = { + importMap: ['esm', 'unpkg', 'jspmGa'], + esm: ['unpkg', 'jspmGa'], + unpkg: ['esm', 'jspmGa'], + jspmGa: ['unpkg', 'esm'], +} -const fallbackCdnProviders = [secondaryCdnProvider] +const fallbackCdnProviders = fallbackCdnProvidersByPrimary[primaryCdnProvider] ?? [] -const cdnImportSpecs = { +export const cdnImportSpecs = { cssBrowser: { + importMap: '@knighted/css/browser', esm: '@knighted/css/browser', }, jsxDom: { + importMap: '@knighted/jsx', esm: '@knighted/jsx', }, jsxTranspile: { + importMap: '@knighted/jsx/transpile', esm: '@knighted/jsx/transpile', }, jsxReact: { + importMap: '@knighted/jsx/react', esm: '@knighted/jsx/react', }, react: { + importMap: 'react', esm: 'react@19.2.4', jspmGa: 'npm:react@19.2.4/index.js', }, reactDomClient: { + importMap: 'react-dom/client', esm: 'react-dom@19.2.4/client', jspmGa: 'npm:react-dom@19.2.4/client.js', }, sass: { - esm: 'sass@1.93.2?conditions=browser', - jspmGa: 'npm:sass@1.93.2/sass.default.js', + importMap: 'sass', + esm: [ + 'sass@1.93.2?conditions=browser', + 'sass@1.93.2/sass.default?conditions=browser', + ], + unpkg: 'sass@1.93.2/sass.default.js?module', }, less: { + importMap: 'less', esm: 'less', }, lightningCssWasm: { + importMap: '@parcel/css-wasm', esm: '@parcel/css-wasm', }, } @@ -66,9 +102,14 @@ const getCdnImportCandidates = importKey => { const candidates = [] for (const provider of getProviderPriority()) { - const specifier = specs[provider] - if (!specifier) continue - candidates.push({ provider, specifier }) + const configured = specs[provider] + if (!configured) continue + + const specifiers = Array.isArray(configured) ? configured : [configured] + for (const specifier of specifiers) { + if (typeof specifier !== 'string' || specifier.length === 0) continue + candidates.push({ provider, specifier }) + } } if (candidates.length === 0) { @@ -90,6 +131,9 @@ export const getCdnImportUrl = ({ provider, specifier }) => { if (!config) { throw new Error(`Unknown CDN provider: ${String(provider)}`) } + if (provider === 'importMap') { + return specifier + } return `${config.host}/${specifier}` } From 5dc19c6a53e3c99d143732bd06d5be77dc9ecf35 Mon Sep 17 00:00:00 2001 From: KCM Date: Sun, 15 Mar 2026 13:10:57 -0500 Subject: [PATCH 4/6] ci: run build esm instead. --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index aaa658f..95c34ee 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -35,4 +35,4 @@ jobs: run: npm run lint - name: Build - run: npm run build + run: npm run build:esm From de9b305a24d6e00bf79e2014203b3d1f3557f738 Mon Sep 17 00:00:00 2001 From: KCM Date: Sun, 15 Mar 2026 13:18:04 -0500 Subject: [PATCH 5/6] docs: update wording around build usage. Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- docs/build-and-deploy.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/docs/build-and-deploy.md b/docs/build-and-deploy.md index ef74370..316acef 100644 --- a/docs/build-and-deploy.md +++ b/docs/build-and-deploy.md @@ -87,9 +87,10 @@ npm run preview ## Notes -- Runtime resolution is import-map first in production (`window.__KNIGHTED_PRIMARY_CDN__ = "importMap"`). -- If a specifier is missing from the generated map, runtime falls back through the CDN +- In production, the preferred/default mode is import-map-based resolution (`window.__KNIGHTED_PRIMARY_CDN__ = "importMap"`). +- In `importMap` mode, runtime resolution is import-map first; if a specifier is missing from the generated map, runtime falls back through the CDN provider chain configured in `src/cdn.js`. +- In `esm` and `jspmGa` modes, runtime resolution is handled entirely by the CDN provider chain configured in `src/cdn.js` without an import map. ### Sass Loading Gotchas From cdc828bcbb6b6c920f605be7ca81f73a18d3e5ba Mon Sep 17 00:00:00 2001 From: KCM Date: Sun, 15 Mar 2026 13:30:40 -0500 Subject: [PATCH 6/6] build: jspmga targets, strengthen matching. --- scripts/build-prepare.js | 7 ++++--- src/cdn.js | 7 +++++++ 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/scripts/build-prepare.js b/scripts/build-prepare.js index f2f3680..4179319 100644 --- a/scripts/build-prepare.js +++ b/scripts/build-prepare.js @@ -72,10 +72,11 @@ await createProdImportsModule() const html = await readFile(distIndexHtml, 'utf8') if (!html.includes(productionRuntimeScript)) { - const moduleScriptTag = '' + const bootstrapModuleScriptRegex = + /]*\btype=(['"])module\1)(?=[^>]*\bsrc=(['"])bootstrap\.js\2)[^>]*>\s*<\/script>/i const updatedHtml = html.replace( - moduleScriptTag, - `${productionRuntimeScript}\n ${moduleScriptTag}`, + bootstrapModuleScriptRegex, + match => `${productionRuntimeScript}\n ${match}`, ) if (updatedHtml === html) { diff --git a/src/cdn.js b/src/cdn.js index c45f3e7..f79525f 100644 --- a/src/cdn.js +++ b/src/cdn.js @@ -47,18 +47,22 @@ export const cdnImportSpecs = { cssBrowser: { importMap: '@knighted/css/browser', esm: '@knighted/css/browser', + jspmGa: 'npm:@knighted/css/browser', }, jsxDom: { importMap: '@knighted/jsx', esm: '@knighted/jsx', + jspmGa: 'npm:@knighted/jsx', }, jsxTranspile: { importMap: '@knighted/jsx/transpile', esm: '@knighted/jsx/transpile', + jspmGa: 'npm:@knighted/jsx/transpile', }, jsxReact: { importMap: '@knighted/jsx/react', esm: '@knighted/jsx/react', + jspmGa: 'npm:@knighted/jsx/react', }, react: { importMap: 'react', @@ -77,14 +81,17 @@ export const cdnImportSpecs = { 'sass@1.93.2/sass.default?conditions=browser', ], unpkg: 'sass@1.93.2/sass.default.js?module', + jspmGa: 'npm:sass@1.93.2/sass.default.js', }, less: { importMap: 'less', esm: 'less', + jspmGa: 'npm:less', }, lightningCssWasm: { importMap: '@parcel/css-wasm', esm: '@parcel/css-wasm', + jspmGa: 'npm:@parcel/css-wasm', }, }