diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 444b80ba..d75baccf 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -157,9 +157,7 @@ jobs: env: NODE_AUTH_TOKEN: '${{ secrets.NPM_TOKEN }}' run: | - for pkg in linux-arm linux-arm64 linux-ia32 linux-x64 darwin-arm64 darwin-x64 win32-ia32 win32-x64; do - npx ts-node ./tool/prepare-optional-release.ts --package=$pkg && npm publish ./npm/$pkg - done + find ./npm -mindepth 1 -maxdepth 1 -print0 | xargs -0 -n 1 -- sh -xc 'npx ts-node ./tool/prepare-optional-release.ts --package=$(basename $1) && npm publish $1' -- - run: npm publish env: diff --git a/CHANGELOG.md b/CHANGELOG.md index 3ff3e06f..a7884687 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,30 @@ +## 1.69.7 + +### Embedded Sass + +* In the JS Embedded Host, properly install the x64 Dart Sass executable on + ARM64 Windows. + +## 1.69.6 + +* Produce better output for numbers with complex units in `meta.inspect()` and + debugging messages. + +* Escape U+007F DELETE when serializing strings. + +* When generating CSS error messages to display in-browser, escape all code + points that aren't in the US-ASCII region. Previously only code points U+0100 + LATIN CAPITAL LETTER A WITH MACRON were escaped. + +* Provide official releases for musl LibC and for Android. + +* Don't crash when running `meta.apply()` in asynchronous mode. + +### JS API + +* Fix a bug where certain exceptions could produce `SourceSpan`s that didn't + follow the documented `SourceSpan` API. + ## 1.69.5 ### JS API diff --git a/lib/src/compiler-path.ts b/lib/src/compiler-path.ts index 0e193c95..c71494dc 100644 --- a/lib/src/compiler-path.ts +++ b/lib/src/compiler-path.ts @@ -6,14 +6,35 @@ import * as fs from 'fs'; import * as p from 'path'; import {isErrnoException} from './utils'; +/** + * Detect if the current running node binary is linked with musl libc by + * checking if the binary contains a string like "/.../ld-musl-$ARCH.so" + */ +const isLinuxMusl = function () { + return fs.readFileSync(process.execPath).includes('/ld-musl-'); +}; + /** The full command for the embedded compiler executable. */ export const compilerCommand = (() => { + const platform = + process.platform === 'linux' && isLinuxMusl() + ? 'linux-musl' + : (process.platform as string); + + // https://github.com/sass/embedded-host-node/issues/263 + // Use windows-x64 emulation on windows-arm64 + // + // TODO: Make sure to remove "arm64" from "npm/win32-x64/package.json" when + // this logic is removed once we have true windows-arm64 support. + const arch = + platform === 'win32' && process.arch === 'arm64' ? 'x64' : process.arch; + // find for development for (const path of ['vendor', '../../../lib/src/vendor']) { const executable = p.resolve( __dirname, path, - `dart-sass/sass${process.platform === 'win32' ? '.bat' : ''}` + `dart-sass/sass${platform === 'win32' ? '.bat' : ''}` ); if (fs.existsSync(executable)) return [executable]; @@ -22,13 +43,11 @@ export const compilerCommand = (() => { try { return [ require.resolve( - `sass-embedded-${process.platform}-${process.arch}/` + - 'dart-sass/src/dart' + - (process.platform === 'win32' ? '.exe' : '') + `sass-embedded-${platform}-${arch}/dart-sass/src/dart` + + (platform === 'win32' ? '.exe' : '') ), require.resolve( - `sass-embedded-${process.platform}-${process.arch}/` + - 'dart-sass/src/sass.snapshot' + `sass-embedded-${platform}-${arch}/dart-sass/src/sass.snapshot` ), ]; } catch (ignored) { @@ -38,9 +57,8 @@ export const compilerCommand = (() => { try { return [ require.resolve( - `sass-embedded-${process.platform}-${process.arch}/` + - 'dart-sass/sass' + - (process.platform === 'win32' ? '.bat' : '') + `sass-embedded-${platform}-${arch}/dart-sass/sass` + + (platform === 'win32' ? '.bat' : '') ), ]; } catch (e: unknown) { @@ -52,7 +70,7 @@ export const compilerCommand = (() => { throw new Error( "Embedded Dart Sass couldn't find the embedded compiler executable. " + 'Please make sure the optional dependency ' + - `sass-embedded-${process.platform}-${process.arch} is installed in ` + + `sass-embedded-${platform}-${arch} is installed in ` + 'node_modules.' ); })(); diff --git a/npm/android-arm/README.md b/npm/android-arm/README.md new file mode 100644 index 00000000..c3538822 --- /dev/null +++ b/npm/android-arm/README.md @@ -0,0 +1,3 @@ +# `sass-embedded-android-arm` + +This is the **android-arm** binary for [`sass-embedded`](https://www.npmjs.com/package/sass-embedded) diff --git a/npm/android-arm/package.json b/npm/android-arm/package.json new file mode 100644 index 00000000..8d3b6796 --- /dev/null +++ b/npm/android-arm/package.json @@ -0,0 +1,23 @@ +{ + "name": "sass-embedded-android-arm", + "version": "1.69.7", + "description": "The android-arm binary for sass-embedded", + "repository": "sass/embedded-host-node", + "author": "Google Inc.", + "license": "MIT", + "files": [ + "dart-sass/**/*" + ], + "engines": { + "node": ">=14.0.0" + }, + "bin": { + "sass": "./dart-sass/sass" + }, + "os": [ + "android" + ], + "cpu": [ + "arm" + ] +} diff --git a/npm/android-arm64/README.md b/npm/android-arm64/README.md new file mode 100644 index 00000000..1398e4a3 --- /dev/null +++ b/npm/android-arm64/README.md @@ -0,0 +1,3 @@ +# `sass-embedded-android-arm64` + +This is the **android-arm64** binary for [`sass-embedded`](https://www.npmjs.com/package/sass-embedded) diff --git a/npm/android-arm64/package.json b/npm/android-arm64/package.json new file mode 100644 index 00000000..d14c273a --- /dev/null +++ b/npm/android-arm64/package.json @@ -0,0 +1,23 @@ +{ + "name": "sass-embedded-android-arm64", + "version": "1.69.7", + "description": "The android-arm64 binary for sass-embedded", + "repository": "sass/embedded-host-node", + "author": "Google Inc.", + "license": "MIT", + "files": [ + "dart-sass/**/*" + ], + "engines": { + "node": ">=14.0.0" + }, + "bin": { + "sass": "./dart-sass/sass" + }, + "os": [ + "android" + ], + "cpu": [ + "arm64" + ] +} diff --git a/npm/android-ia32/README.md b/npm/android-ia32/README.md new file mode 100644 index 00000000..2146454b --- /dev/null +++ b/npm/android-ia32/README.md @@ -0,0 +1,3 @@ +# `sass-embedded-android-ia32` + +This is the **android-ia32** binary for [`sass-embedded`](https://www.npmjs.com/package/sass-embedded) diff --git a/npm/android-ia32/package.json b/npm/android-ia32/package.json new file mode 100644 index 00000000..d8f62e72 --- /dev/null +++ b/npm/android-ia32/package.json @@ -0,0 +1,23 @@ +{ + "name": "sass-embedded-android-ia32", + "version": "1.69.7", + "description": "The android-ia32 binary for sass-embedded", + "repository": "sass/embedded-host-node", + "author": "Google Inc.", + "license": "MIT", + "files": [ + "dart-sass/**/*" + ], + "engines": { + "node": ">=14.0.0" + }, + "bin": { + "sass": "./dart-sass/sass" + }, + "os": [ + "android" + ], + "cpu": [ + "ia32" + ] +} diff --git a/npm/android-x64/README.md b/npm/android-x64/README.md new file mode 100644 index 00000000..873ab4d7 --- /dev/null +++ b/npm/android-x64/README.md @@ -0,0 +1,3 @@ +# `sass-embedded-android-x64` + +This is the **android-x64** binary for [`sass-embedded`](https://www.npmjs.com/package/sass-embedded) diff --git a/npm/android-x64/package.json b/npm/android-x64/package.json new file mode 100644 index 00000000..8b86c117 --- /dev/null +++ b/npm/android-x64/package.json @@ -0,0 +1,23 @@ +{ + "name": "sass-embedded-android-x64", + "version": "1.69.7", + "description": "The android-x64 binary for sass-embedded", + "repository": "sass/embedded-host-node", + "author": "Google Inc.", + "license": "MIT", + "files": [ + "dart-sass/**/*" + ], + "engines": { + "node": ">=14.0.0" + }, + "bin": { + "sass": "./dart-sass/sass" + }, + "os": [ + "android" + ], + "cpu": [ + "x64" + ] +} diff --git a/npm/darwin-arm64/package.json b/npm/darwin-arm64/package.json index bffd3b3a..8a70304b 100644 --- a/npm/darwin-arm64/package.json +++ b/npm/darwin-arm64/package.json @@ -1,6 +1,6 @@ { "name": "sass-embedded-darwin-arm64", - "version": "1.69.5", + "version": "1.69.7", "description": "The darwin-arm64 binary for sass-embedded", "repository": "sass/embedded-host-node", "author": "Google Inc.", diff --git a/npm/darwin-x64/package.json b/npm/darwin-x64/package.json index a18878d4..bc3a13b7 100644 --- a/npm/darwin-x64/package.json +++ b/npm/darwin-x64/package.json @@ -1,6 +1,6 @@ { "name": "sass-embedded-darwin-x64", - "version": "1.69.5", + "version": "1.69.7", "description": "The darwin-x64 binary for sass-embedded", "repository": "sass/embedded-host-node", "author": "Google Inc.", diff --git a/npm/linux-arm/package.json b/npm/linux-arm/package.json index f66dbc1a..7d2f929a 100644 --- a/npm/linux-arm/package.json +++ b/npm/linux-arm/package.json @@ -1,6 +1,6 @@ { "name": "sass-embedded-linux-arm", - "version": "1.69.5", + "version": "1.69.7", "description": "The linux-arm binary for sass-embedded", "repository": "sass/embedded-host-node", "author": "Google Inc.", diff --git a/npm/linux-arm64/package.json b/npm/linux-arm64/package.json index d319078e..84a3addf 100644 --- a/npm/linux-arm64/package.json +++ b/npm/linux-arm64/package.json @@ -1,6 +1,6 @@ { "name": "sass-embedded-linux-arm64", - "version": "1.69.5", + "version": "1.69.7", "description": "The linux-arm64 binary for sass-embedded", "repository": "sass/embedded-host-node", "author": "Google Inc.", diff --git a/npm/linux-ia32/package.json b/npm/linux-ia32/package.json index b7181eb6..75b1a336 100644 --- a/npm/linux-ia32/package.json +++ b/npm/linux-ia32/package.json @@ -1,6 +1,6 @@ { "name": "sass-embedded-linux-ia32", - "version": "1.69.5", + "version": "1.69.7", "description": "The linux-ia32 binary for sass-embedded", "repository": "sass/embedded-host-node", "author": "Google Inc.", diff --git a/npm/linux-musl-arm/README.md b/npm/linux-musl-arm/README.md new file mode 100644 index 00000000..df594f68 --- /dev/null +++ b/npm/linux-musl-arm/README.md @@ -0,0 +1,3 @@ +# `sass-embedded-linux-musl-arm` + +This is the **linux-musl-arm** binary for [`sass-embedded`](https://www.npmjs.com/package/sass-embedded) diff --git a/npm/linux-musl-arm/package.json b/npm/linux-musl-arm/package.json new file mode 100644 index 00000000..f0edbb63 --- /dev/null +++ b/npm/linux-musl-arm/package.json @@ -0,0 +1,20 @@ +{ + "name": "sass-embedded-linux-musl-arm", + "version": "1.69.7", + "description": "The linux-musl-arm binary for sass-embedded", + "repository": "sass/embedded-host-node", + "author": "Google Inc.", + "license": "MIT", + "files": [ + "dart-sass/**/*" + ], + "engines": { + "node": ">=14.0.0" + }, + "os": [ + "linux" + ], + "cpu": [ + "arm" + ] +} diff --git a/npm/linux-musl-arm64/README.md b/npm/linux-musl-arm64/README.md new file mode 100644 index 00000000..a1f1c6df --- /dev/null +++ b/npm/linux-musl-arm64/README.md @@ -0,0 +1,3 @@ +# `sass-embedded-linux-musl-arm64` + +This is the **linux-musl-arm64** binary for [`sass-embedded`](https://www.npmjs.com/package/sass-embedded) diff --git a/npm/linux-musl-arm64/package.json b/npm/linux-musl-arm64/package.json new file mode 100644 index 00000000..7dddd3f6 --- /dev/null +++ b/npm/linux-musl-arm64/package.json @@ -0,0 +1,20 @@ +{ + "name": "sass-embedded-linux-musl-arm64", + "version": "1.69.7", + "description": "The linux-musl-arm64 binary for sass-embedded", + "repository": "sass/embedded-host-node", + "author": "Google Inc.", + "license": "MIT", + "files": [ + "dart-sass/**/*" + ], + "engines": { + "node": ">=14.0.0" + }, + "os": [ + "linux" + ], + "cpu": [ + "arm64" + ] +} diff --git a/npm/linux-musl-ia32/README.md b/npm/linux-musl-ia32/README.md new file mode 100644 index 00000000..918fff76 --- /dev/null +++ b/npm/linux-musl-ia32/README.md @@ -0,0 +1,3 @@ +# `sass-embedded-linux-musl-ia32` + +This is the **linux-musl-ia32** binary for [`sass-embedded`](https://www.npmjs.com/package/sass-embedded) diff --git a/npm/linux-musl-ia32/package.json b/npm/linux-musl-ia32/package.json new file mode 100644 index 00000000..e77d20af --- /dev/null +++ b/npm/linux-musl-ia32/package.json @@ -0,0 +1,20 @@ +{ + "name": "sass-embedded-linux-musl-ia32", + "version": "1.69.7", + "description": "The linux-musl-ia32 binary for sass-embedded", + "repository": "sass/embedded-host-node", + "author": "Google Inc.", + "license": "MIT", + "files": [ + "dart-sass/**/*" + ], + "engines": { + "node": ">=14.0.0" + }, + "os": [ + "linux" + ], + "cpu": [ + "ia32" + ] +} diff --git a/npm/linux-musl-x64/README.md b/npm/linux-musl-x64/README.md new file mode 100644 index 00000000..476f09ec --- /dev/null +++ b/npm/linux-musl-x64/README.md @@ -0,0 +1,3 @@ +# `sass-embedded-linux-musl-x64` + +This is the **linux-musl-x64** binary for [`sass-embedded`](https://www.npmjs.com/package/sass-embedded) diff --git a/npm/linux-musl-x64/package.json b/npm/linux-musl-x64/package.json new file mode 100644 index 00000000..27e9e088 --- /dev/null +++ b/npm/linux-musl-x64/package.json @@ -0,0 +1,20 @@ +{ + "name": "sass-embedded-linux-musl-x64", + "version": "1.69.7", + "description": "The linux-musl-x64 binary for sass-embedded", + "repository": "sass/embedded-host-node", + "author": "Google Inc.", + "license": "MIT", + "files": [ + "dart-sass/**/*" + ], + "engines": { + "node": ">=14.0.0" + }, + "os": [ + "linux" + ], + "cpu": [ + "x64" + ] +} diff --git a/npm/linux-x64/package.json b/npm/linux-x64/package.json index 5896693e..dabe83d3 100644 --- a/npm/linux-x64/package.json +++ b/npm/linux-x64/package.json @@ -1,6 +1,6 @@ { "name": "sass-embedded-linux-x64", - "version": "1.69.5", + "version": "1.69.7", "description": "The linux-x64 binary for sass-embedded", "repository": "sass/embedded-host-node", "author": "Google Inc.", diff --git a/npm/win32-ia32/package.json b/npm/win32-ia32/package.json index 5bfdf49a..c50754cb 100644 --- a/npm/win32-ia32/package.json +++ b/npm/win32-ia32/package.json @@ -1,6 +1,6 @@ { "name": "sass-embedded-win32-ia32", - "version": "1.69.5", + "version": "1.69.7", "description": "The win32-ia32 binary for sass-embedded", "repository": "sass/embedded-host-node", "author": "Google Inc.", diff --git a/npm/win32-x64/package.json b/npm/win32-x64/package.json index 67fbe37c..6d3af30d 100644 --- a/npm/win32-x64/package.json +++ b/npm/win32-x64/package.json @@ -1,6 +1,6 @@ { "name": "sass-embedded-win32-x64", - "version": "1.69.5", + "version": "1.69.7", "description": "The win32-x64 binary for sass-embedded", "repository": "sass/embedded-host-node", "author": "Google Inc.", @@ -18,6 +18,7 @@ "win32" ], "cpu": [ + "arm64", "x64" ] } diff --git a/package.json b/package.json index d4134105..65cb0e17 100644 --- a/package.json +++ b/package.json @@ -1,8 +1,8 @@ { "name": "sass-embedded", - "version": "1.69.5", + "version": "1.69.7", "protocol-version": "3.0.0-dev", - "compiler-version": "1.69.5", + "compiler-version": "1.69.7", "description": "Node.js library that communicates with Embedded Dart Sass using the Embedded Sass protocol", "repository": "sass/embedded-host-node", "author": "Google Inc.", @@ -35,14 +35,22 @@ "test": "jest" }, "optionalDependencies": { - "sass-embedded-darwin-arm64": "1.69.5", - "sass-embedded-darwin-x64": "1.69.5", - "sass-embedded-linux-arm": "1.69.5", - "sass-embedded-linux-arm64": "1.69.5", - "sass-embedded-linux-ia32": "1.69.5", - "sass-embedded-linux-x64": "1.69.5", - "sass-embedded-win32-ia32": "1.69.5", - "sass-embedded-win32-x64": "1.69.5" + "sass-embedded-android-arm": "1.69.7", + "sass-embedded-android-arm64": "1.69.7", + "sass-embedded-android-ia32": "1.69.7", + "sass-embedded-android-x64": "1.69.7", + "sass-embedded-darwin-arm64": "1.69.7", + "sass-embedded-darwin-x64": "1.69.7", + "sass-embedded-linux-arm": "1.69.7", + "sass-embedded-linux-arm64": "1.69.7", + "sass-embedded-linux-ia32": "1.69.7", + "sass-embedded-linux-x64": "1.69.7", + "sass-embedded-linux-musl-arm": "1.69.7", + "sass-embedded-linux-musl-arm64": "1.69.7", + "sass-embedded-linux-musl-ia32": "1.69.7", + "sass-embedded-linux-musl-x64": "1.69.7", + "sass-embedded-win32-ia32": "1.69.7", + "sass-embedded-win32-x64": "1.69.7" }, "dependencies": { "@bufbuild/protobuf": "^1.0.0", diff --git a/tool/prepare-optional-release.ts b/tool/prepare-optional-release.ts index 36a42ba7..f1bcb314 100644 --- a/tool/prepare-optional-release.ts +++ b/tool/prepare-optional-release.ts @@ -7,7 +7,12 @@ import yargs from 'yargs'; import * as pkg from '../package.json'; import * as utils from './utils'; -export type DartPlatform = 'linux' | 'macos' | 'windows'; +export type DartPlatform = + | 'android' + | 'linux' + | 'linux-musl' + | 'macos' + | 'windows'; export type DartArch = 'ia32' | 'x64' | 'arm' | 'arm64'; const argv = yargs(process.argv.slice(2)) @@ -27,8 +32,12 @@ const argv = yargs(process.argv.slice(2)) // Dart Sass Embedded. export function nodePlatformToDartPlatform(platform: string): DartPlatform { switch (platform) { + case 'android': + return 'android'; case 'linux': return 'linux'; + case 'linux-musl': + return 'linux-musl'; case 'darwin': return 'macos'; case 'win32': @@ -104,6 +113,47 @@ async function downloadRelease(options: { await fs.unlink(zippedAssetPath); } +// Patch the launcher script if needed. +// +// For linux both `-linux-` and `-linux-musl-` packages will be installed +// because npm doesn't know how to select packages based on LibC. To avoid +// conflicts, only the `-linux-` packages have "bin" scripts defined in +// package.json, which we patch to detect which LibC is available and launch the +// correct binary. +async function patchLauncherScript( + path: string, + dartPlatform: DartPlatform, + dartArch: DartArch +) { + if (dartPlatform !== 'linux') return; + + const scriptPath = p.join(path, 'dart-sass', 'sass'); + console.log(`Patching ${scriptPath} script.`); + + const shebang = Buffer.from('#!/bin/sh\n'); + const buffer = await fs.readFile(scriptPath); + if (!buffer.subarray(0, shebang.length).equals(shebang)) { + throw new Error(`${scriptPath} is not a shell script!`); + } + + const lines = buffer.toString('utf-8').split('\n'); + const index = lines.findIndex(line => line.startsWith('path=')); + if (index < 0) { + throw new Error(`The format of ${scriptPath} has changed!`); + } + + lines.splice( + index + 1, + 0, + '# Detect linux-musl', + 'if grep -qm 1 /ld-musl- /proc/self/exe; then', + ` path="$path/../../sass-embedded-linux-musl-${dartArch}/dart-sass"`, + 'fi' + ); + + await fs.writeFile(scriptPath, lines.join('\n')); +} + void (async () => { try { const version = pkg['compiler-version'] as string; @@ -113,7 +163,9 @@ void (async () => { ); } - const [nodePlatform, nodeArch] = argv.package.split('-'); + const index = argv.package.lastIndexOf('-'); + const nodePlatform = argv.package.substring(0, index); + const nodeArch = argv.package.substring(index + 1); const dartPlatform = nodePlatformToDartPlatform(nodePlatform); const dartArch = nodeArchToDartArch(nodeArch); const outPath = p.join('npm', argv.package); @@ -125,6 +177,7 @@ void (async () => { `${dartPlatform}-${dartArch}${getArchiveExtension(dartPlatform)}`, outPath, }); + await patchLauncherScript(outPath, dartPlatform, dartArch); } catch (error) { console.error(error); process.exitCode = 1;