diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 79834d3..9e522a8 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -7,6 +7,7 @@ on: permissions: id-token: write + contents: write jobs: publish: @@ -35,4 +36,40 @@ jobs: run: npm run build && npm run build:wasm - name: Publish - run: npm publish --access public \ No newline at end of file + run: npm publish --access public + + - name: Extract changelog entry + run: | + VERSION="${GITHUB_REF_NAME#v}" + awk -v ver="$VERSION" ' + /^## \[/ { + if (capture) exit + if ($0 ~ "^## \\[" ver "\\]") { capture=1; next } + next + } + capture { print } + ' CHANGELOG.md > /tmp/release-notes.md + + if [ ! -s /tmp/release-notes.md ]; then + echo "error: no CHANGELOG.md entry found for version ${VERSION}" >&2 + exit 1 + fi + + - name: Attach WASM artifacts to GitHub release + env: + GH_TOKEN: ${{ github.token }} + run: | + ASSETS=( + wasm/dist/cld.node.js + wasm/dist/cld.node.wasm + wasm/dist/cld.web.mjs + wasm/dist/cld.web.wasm + ) + if gh release view "${GITHUB_REF_NAME}" >/dev/null 2>&1; then + gh release upload "${GITHUB_REF_NAME}" "${ASSETS[@]}" --clobber + else + gh release create "${GITHUB_REF_NAME}" \ + --title "${GITHUB_REF_NAME}" \ + --notes-file /tmp/release-notes.md \ + "${ASSETS[@]}" + fi \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index a037e66..00721ed 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,16 @@ This fork ([`cld-universal`](https://github.com/figulusproject/cld-universal)) d [`dachev/node-cld`](https://github.com/dachev/node-cld) at `2.10.1`. Entries below start from that point. +## [2.11.2] - 2026-08-03 + +### Changed + +- Publish workflow (`publish.yml`) now attaches the built WASM artifacts (`cld.node.js`, `cld.node.wasm`, `cld.web.mjs`, `cld.web.wasm`) to the pushed tag's GitHub release, using the matching version's entry from this changelog as the release notes. + +### Fixed + +- Browser entry point renamed from `wasm/browser-entry.js` to `wasm/browser-entry.mjs`. Node 20 lacks the fallback that reparses typeless .js files as ESM, so import() hit them through the CJS loader and errored on the `import` statement. Renaming it to use an MJS extension avoids the ambiguity. + ## [2.11.1] - 2026-08-03 ### Added diff --git a/README.md b/README.md index 0eb6e73..551c733 100644 --- a/README.md +++ b/README.md @@ -2,11 +2,7 @@ [![CI](https://github.com/figulusproject/cld-universal/actions/workflows/ci.yml/badge.svg)](https://github.com/figulusproject/cld-universal/actions/workflows/ci.yml) [![NPM version](https://badge.fury.io/js/cld-universal.svg)](http://badge.fury.io/js/cld-universal) -[![Stand With Palestine](https://raw.githubusercontent.com/standforhumanity/stand-with-palestine/main/Banners/Banner1.svg)](https://stand-with-palestine.vercel.app/) - -[![Stand With Ukraine](https://raw.githubusercontent.com/vshymanskyy/StandWithUkraine/main/banner2-direct.svg)](https://stand-with-ukraine.pp.ua) - -*Fork developed on stolen Wurundjeri Land. We pay our respects to Elders past, present, and emerging, and with all peoples resisting occupation.* +*Everyone has the right to resist occupation.* > **This is a fork of [dachev/node-cld](https://github.com/dachev/node-cld).** The original project has had no maintainer activity in over a year, and has outdated dependencies causing 3 high severity security issues. > diff --git a/index.d.ts b/index.d.ts index 6ba6160..172a064 100644 --- a/index.d.ts +++ b/index.d.ts @@ -29,7 +29,7 @@ export const LANGUAGES: {[name: string]: string}; export const DETECTED_LANGUAGES: string[]; export const ENCODINGS: string[]; -// Browser entry point only (./wasm/browser-entry.js). Overrides where the +// Browser entry point only (./wasm/browser-entry.mjs). Overrides where the // WASM backend fetches cld.web.wasm from -- has no effect on the native // backend. Must be called before the first detect() call. export declare function setWasmModuleOptions(options: { locateFile?: (path: string, scriptDirectory: string) => string }): void; diff --git a/lib/detect-shape.js b/lib/detect-shape.js index c997efe..5f5567e 100644 --- a/lib/detect-shape.js +++ b/lib/detect-shape.js @@ -1,5 +1,5 @@ // Shared detect() implementation used by both index.js (Node, native-first -// with WASM fallback) and wasm/browser-entry.js (bundler/browser, WASM +// with WASM fallback) and wasm/browser-entry.mjs (bundler/browser, WASM // only) -- the validation/defaults/error-mapping logic is identical for // both, only how the backend is loaded differs. diff --git a/lib/wasm-wrap.js b/lib/wasm-wrap.js index e699382..28b00ac 100644 --- a/lib/wasm-wrap.js +++ b/lib/wasm-wrap.js @@ -1,7 +1,7 @@ // Wraps an instantiated Emscripten module (Node or browser target -- both // expose the same ccall/UTF8ToString shape) into the {detectAsync(...)} // interface shared with the native backend. Deliberately has no other -// requires: wasm/browser-entry.js imports this directly (not through +// requires: wasm/browser-entry.mjs imports this directly (not through // lib/backend.js) so bundlers never see lib/backend.js's // require('../build/Release/cld') at all. diff --git a/package-lock.json b/package-lock.json index 05ddf14..d24858a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "cld-universal", - "version": "2.11.1", + "version": "2.11.2", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "cld-universal", - "version": "2.11.1", + "version": "2.11.2", "hasInstallScript": true, "dependencies": { "glob": "^12", diff --git a/package.json b/package.json index 41f0a58..4383ca9 100644 --- a/package.json +++ b/package.json @@ -10,13 +10,13 @@ "wasm", "webassembly" ], - "version": "2.11.1", + "version": "2.11.2", "main": "./index.js", "types": "./index.d.ts", "exports": { ".": { "types": "./index.d.ts", - "browser": "./wasm/browser-entry.js", + "browser": "./wasm/browser-entry.mjs", "default": "./index.js" } }, @@ -25,7 +25,7 @@ "index.d.ts", "lib", "wasm/dist", - "wasm/browser-entry.js", + "wasm/browser-entry.mjs", "src", "deps/cld/public", "deps/cld/internal", diff --git a/test/runner-wasm-browser.js b/test/runner-wasm-browser.js index 168a932..5c01fc2 100644 --- a/test/runner-wasm-browser.js +++ b/test/runner-wasm-browser.js @@ -1,14 +1,14 @@ #!/usr/bin/env node -// Proves wasm/browser-entry.js's setWasmModuleOptions({ locateFile }) hook +// Proves wasm/browser-entry.mjs's setWasmModuleOptions({ locateFile }) hook // actually controls where the WASM backend fetches cld.web.wasm from -- // not just that the option is accepted, but that redirecting it to a // custom URL is what makes detection succeed. // -// Each case runs in its own child process: browser-entry.js caches +// Each case runs in its own child process: browser-entry.mjs caches // moduleOptions/modulePromise at module scope on first use, so "no // override" and "with override" can't share one process/import. // -// With no override, browser-entry.js's default WASM URL resolves against +// With no override, browser-entry.mjs's default WASM URL resolves against // import.meta.url, which is a file:// URL here -- and Node's fetch() // doesn't support file://, so detect() is expected to reject. That's not a // Node quirk being worked around, it's exactly the gap the override exists @@ -39,7 +39,7 @@ function runChild(script) { (async () => { const withoutOverride = ` - import('../wasm/browser-entry.js') + import('../wasm/browser-entry.mjs') .then(m => m.detect(${JSON.stringify(SAMPLE.sample)})) .then(() => { console.log('UNEXPECTED_SUCCESS'); process.exit(0); }) .catch(() => { console.log('EXPECTED_FAILURE'); process.exit(0); }); @@ -58,7 +58,7 @@ function runChild(script) { try { const withOverride = ` - import('../wasm/browser-entry.js').then(async m => { + import('../wasm/browser-entry.mjs').then(async m => { m.setWasmModuleOptions({ locateFile: () => 'http://127.0.0.1:${port}/custom-path/cld.web.wasm' }); const result = await m.detect(${JSON.stringify(SAMPLE.sample)}); console.log(JSON.stringify(result.languages[0])); diff --git a/wasm/browser-entry.js b/wasm/browser-entry.mjs similarity index 100% rename from wasm/browser-entry.js rename to wasm/browser-entry.mjs