diff --git a/cli/package.json b/cli/package.json index 3bec39f6..a5af10ea 100644 --- a/cli/package.json +++ b/cli/package.json @@ -96,7 +96,7 @@ "ava": "^6.2.0", "env-paths": "^3.0.0", "prettier": "^3.5.3", - "rolldown": "^1.0.0-beta.19", + "rolldown": "^1.0.0-beta.23", "tslib": "^2.8.1", "typescript": "^5.8.2" }, diff --git a/cli/src/api/build.ts b/cli/src/api/build.ts index fcd64633..d367c3a3 100644 --- a/cli/src/api/build.ts +++ b/cli/src/api/build.ts @@ -905,6 +905,12 @@ export declare class ExternalObject { ` } + if (dts.indexOf('TypedArray') > -1) { + header += ` +export type TypedArray = Int8Array | Uint8Array | Uint8ClampedArray | Int16Array | Uint16Array | Int32Array | Uint32Array | Float32Array | Float64Array | BigInt64Array | BigUint64Array +` + } + dts = header + dts try { diff --git a/cli/src/api/create-npm-dirs.ts b/cli/src/api/create-npm-dirs.ts index 7d937e51..e8712cb4 100644 --- a/cli/src/api/create-npm-dirs.ts +++ b/cli/src/api/create-npm-dirs.ts @@ -15,10 +15,12 @@ import { Target, } from '../utils/index.js' -import type { PackageMeta } from './templates/package.json.js' - const debug = debugFactory('create-npm-dirs') +export interface PackageMeta { + 'dist-tags': { [index: string]: string } +} + export async function createNpmDirs(userOptions: CreateNpmDirsOptions) { const options = applyDefaultCreateNpmDirsOptions(userOptions) diff --git a/cli/src/api/templates/.gitignore.ts b/cli/src/api/templates/.gitignore.ts deleted file mode 100644 index 709c3be1..00000000 --- a/cli/src/api/templates/.gitignore.ts +++ /dev/null @@ -1,199 +0,0 @@ -export const gitIgnore = `# Created by https://www.toptal.com/developers/gitignore/api/node -# Edit at https://www.toptal.com/developers/gitignore?templates=node - -### Node ### -# Logs -logs -*.log -npm-debug.log* -yarn-debug.log* -yarn-error.log* -lerna-debug.log* - -# Diagnostic reports (https://nodejs.org/api/report.html) -report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json - -# Runtime data -pids -*.pid -*.seed -*.pid.lock - -# Directory for instrumented libs generated by jscoverage/JSCover -lib-cov - -# Coverage directory used by tools like istanbul -coverage -*.lcov - -# nyc test coverage -.nyc_output - -# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) -.grunt - -# Bower dependency directory (https://bower.io/) -bower_components - -# node-waf configuration -.lock-wscript - -# Compiled binary addons (https://nodejs.org/api/addons.html) -build/Release - -# Dependency directories -node_modules/ -jspm_packages/ - -# TypeScript v1 declaration files -typings/ - -# TypeScript cache -*.tsbuildinfo - -# Optional npm cache directory -.npm - -# Optional eslint cache -.eslintcache - -# Microbundle cache -.rpt2_cache/ -.rts2_cache_cjs/ -.rts2_cache_es/ -.rts2_cache_umd/ - -# Optional REPL history -.node_repl_history - -# Output of 'npm pack' -*.tgz - -# Yarn Integrity file -.yarn-integrity - -# dotenv environment variables file -.env -.env.test - -# parcel-bundler cache (https://parceljs.org/) -.cache - -# Next.js build output -.next - -# Nuxt.js build / generate output -.nuxt -dist - -# Gatsby files -.cache/ -# Comment in the public line in if your project uses Gatsby and not Next.js -# https://nextjs.org/blog/next-9-1#public-directory-support -# public - -# vuepress build output -.vuepress/dist - -# Serverless directories -.serverless/ - -# FuseBox cache -.fusebox/ - -# DynamoDB Local files -.dynamodb/ - -# TernJS port file -.tern-port - -# Stores VSCode versions used for testing VSCode extensions -.vscode-test - -# End of https://www.toptal.com/developers/gitignore/api/node - -# Created by https://www.toptal.com/developers/gitignore/api/macos -# Edit at https://www.toptal.com/developers/gitignore?templates=macos - -### macOS ### -# General -.DS_Store -.AppleDouble -.LSOverride - -# Icon must end with two \r -Icon - - -# Thumbnails -._* - -# Files that might appear in the root of a volume -.DocumentRevisions-V100 -.fseventsd -.Spotlight-V100 -.TemporaryItems -.Trashes -.VolumeIcon.icns -.com.apple.timemachine.donotpresent - -# Directories potentially created on remote AFP share -.AppleDB -.AppleDesktop -Network Trash Folder -Temporary Items -.apdisk - -### macOS Patch ### -# iCloud generated files -*.icloud - -# End of https://www.toptal.com/developers/gitignore/api/macos - -# Created by https://www.toptal.com/developers/gitignore/api/windows -# Edit at https://www.toptal.com/developers/gitignore?templates=windows - -### Windows ### -# Windows thumbnail cache files -Thumbs.db -Thumbs.db:encryptable -ehthumbs.db -ehthumbs_vista.db - -# Dump file -*.stackdump - -# Folder config file -[Dd]esktop.ini - -# Recycle Bin used on file shares -$RECYCLE.BIN/ - -# Windows Installer files -*.cab -*.msi -*.msix -*.msm -*.msp - -# Windows shortcuts -*.lnk - -# End of https://www.toptal.com/developers/gitignore/api/windows - -#Added by cargo - -/target -Cargo.lock - -.pnp.* -.yarn/* -!.yarn/patches -!.yarn/plugins -!.yarn/releases -!.yarn/sdks -!.yarn/versions - -*.node -*.wasm -` diff --git a/cli/src/api/templates/.npmignore.ts b/cli/src/api/templates/.npmignore.ts deleted file mode 100644 index 33385d63..00000000 --- a/cli/src/api/templates/.npmignore.ts +++ /dev/null @@ -1,14 +0,0 @@ -export const npmIgnore = `target -Cargo.lock -.cargo -.github -npm -.eslintrc -.prettierignore -rustfmt.toml -yarn.lock -*.node -.yarn -__test__ -renovate.json -` diff --git a/cli/src/api/templates/build.rs.ts b/cli/src/api/templates/build.rs.ts deleted file mode 100644 index 1deae449..00000000 --- a/cli/src/api/templates/build.rs.ts +++ /dev/null @@ -1,4 +0,0 @@ -export const createBuildRs = () => `fn main() { - napi_build::setup(); -} -` diff --git a/cli/src/api/templates/cargo.toml.ts b/cli/src/api/templates/cargo.toml.ts deleted file mode 100644 index 019c2690..00000000 --- a/cli/src/api/templates/cargo.toml.ts +++ /dev/null @@ -1,36 +0,0 @@ -export const createCargoToml = ({ - name, - license, - features, - deriveFeatures, -}: { - name: string - license: string - features: string[] - deriveFeatures: string[] -}) => `[package] -name = "${name.replace('@', '').replace('/', '_').toLowerCase()}" -version = "1.0.0" -edition = "2021" -license = "${license}" - -[lib] -crate-type = ["cdylib"] - -[dependencies.napi] -version = "2" -default-features = false -# see https://nodejs.org/api/n-api.html#node-api-version-matrix -features = ${JSON.stringify(features)} - -[dependencies.napi-derive] -version = "2" -features = ${JSON.stringify(deriveFeatures)} - -[build-dependencies] -napi-build = "2" - -[profile.release] -lto = true -strip = "symbols" -` diff --git a/cli/src/api/templates/ci-template.ts b/cli/src/api/templates/ci-template.ts deleted file mode 100644 index 8095cdce..00000000 --- a/cli/src/api/templates/ci-template.ts +++ /dev/null @@ -1,602 +0,0 @@ -import type { SupportedPackageManager } from '../../utils/config.js' - -export type WasiTargetName = - | 'wasm32-wasi-preview1-threads' - | 'wasm32-wasip1-threads' - | 'wasm32-wasip2' - -export const YAML = ( - packageManager: SupportedPackageManager, - wasiTargetName: WasiTargetName, -) => ` -name: CI - -env: - DEBUG: 'napi:*' - MACOSX_DEPLOYMENT_TARGET: '10.13' - -permissions: - contents: write - id-token: write - -on: - push: - branches: - - main - tags-ignore: - - '**' - paths-ignore: - - '**/*.md' - - 'LICENSE' - - '**/*.gitignore' - - '.editorconfig' - - 'docs/**' - pull_request: - -jobs: - build: - - strategy: - fail-fast: false - matrix: - settings: - - host: macos-latest - target: 'x86_64-apple-darwin' - build: ${packageManager} build --platform --target x86_64-apple-darwin - - host: windows-latest - build: ${packageManager} build --platform - target: 'x86_64-pc-windows-msvc' - - host: windows-latest - build: | - ${packageManager} build --platform --target i686-pc-windows-msvc - ${packageManager} test - target: 'i686-pc-windows-msvc' - - host: ubuntu-latest - target: 'x86_64-unknown-linux-gnu' - build: ${packageManager} build --platform --target x86_64-unknown-linux-gnu --use-napi-cross - - host: ubuntu-latest - target: 'x86_64-unknown-linux-musl' - build: ${packageManager} build --platform --target x86_64-unknown-linux-musl -x - - host: macos-latest - target: 'aarch64-apple-darwin' - build: ${packageManager} build --platform --target aarch64-apple-darwin - - host: ubuntu-latest - target: 'aarch64-unknown-linux-gnu' - build: ${packageManager} build --platform --target aarch64-unknown-linux-gnu --use-napi-cross - - host: ubuntu-latest - target: 'armv7-unknown-linux-gnueabihf' - build: ${packageManager} build --platform --target armv7-unknown-linux-gnueabihf --use-napi-cross - - host: ubuntu-latest - target: 'armv7-unknown-linux-musleabihf' - build: ${packageManager} build --platform --target armv7-unknown-linux-musleabihf -x - - host: ubuntu-latest - target: 'aarch64-linux-android' - build: ${packageManager} build --platform --target aarch64-linux-android - - host: ubuntu-latest - target: 'armv7-linux-androideabi' - build: ${packageManager} build --platform --target armv7-linux-androideabi - - host: ubuntu-latest - target: 'aarch64-unknown-linux-musl' - build: ${packageManager} build --platform --target aarch64-unknown-linux-musl -x - - host: windows-latest - target: 'aarch64-pc-windows-msvc' - build: ${packageManager} build --platform --target aarch64-pc-windows-msvc - - host: ubuntu-latest - target: 'riscv64gc-unknown-linux-gnu' - setup: | - sudo apt-get update - sudo apt-get install gcc-riscv64-linux-gnu -y - build: ${packageManager} build --platform --target riscv64gc-unknown-linux-gnu - - host: ubuntu-latest - target: 'powerpc64le-unknown-linux-gnu' - setup: | - sudo apt-get update - sudo apt-get install gcc-powerpc64le-linux-gnu -y - build: ${packageManager} build --platform --target powerpc64le-unknown-linux-gnu - - host: ubuntu-latest - target: 's390x-unknown-linux-gnu' - setup: | - sudo apt-get update - sudo apt-get install gcc-s390x-linux-gnu -y - build: ${packageManager} build --platform --target s390x-unknown-linux-gnu - - host: ubuntu-latest - target: '${wasiTargetName}' - build: ${packageManager} build --platform --target ${wasiTargetName} - - name: stable - \${{ matrix.settings.target }} - node@20 - runs-on: \${{ matrix.settings.host }} - - steps: - - uses: actions/checkout@v4 - - - name: Setup node - uses: actions/setup-node@v4 - with: - node-version: 20 - cache: ${packageManager} - - - name: Install - uses: dtolnay/rust-toolchain@stable - with: - toolchain: stable - targets: \${{ matrix.settings.target }} - - - name: Cache cargo - uses: actions/cache@v4 - with: - path: | - ~/.cargo/registry/index/ - ~/.cargo/registry/cache/ - ~/.cargo/git/db/ - ~/.napi-rs - .cargo-cache - target/ - key: \${{ matrix.settings.target }}-cargo-\${{ matrix.settings.host }} - - - uses: goto-bus-stop/setup-zig@v2 - if: \${{ contains(matrix.settings.target, 'musl') }} - with: - version: 0.13.0 - - - name: Install cargo-zigbuild - uses: taiki-e/install-action@v2 - if: \${{ contains(matrix.settings.target, 'musl') }} - env: - GITHUB_TOKEN: \${{ github.token }} - with: - tool: cargo-zigbuild - - - name: Setup toolchain - run: \${{ matrix.settings.setup }} - if: \${{ matrix.settings.setup }} - shell: bash - - - name: Setup node x86 - if: matrix.settings.target == 'i686-pc-windows-msvc' - run: yarn config set supportedArchitectures.cpu "ia32" - shell: bash - - - name: 'Install dependencies' - run: ${packageManager} install - - - name: Setup node x86 - uses: actions/setup-node@v4 - if: matrix.settings.target == 'i686-pc-windows-msvc' - with: - node-version: 20 - architecture: x86 - - - name: 'Build' - run: \${{ matrix.settings.build }} - shell: bash - - - name: Upload artifact - uses: actions/upload-artifact@v4 - if: matrix.settings.target != '${wasiTargetName}' - with: - name: bindings-\${{ matrix.settings.target }} - path: "*.node" - if-no-files-found: error - - - name: Upload artifact - uses: actions/upload-artifact@v4 - if: matrix.settings.target == '${wasiTargetName}' - with: - name: bindings-\${{ matrix.settings.target }} - path: "*.wasm" - if-no-files-found: error - - build-freebsd: - runs-on: ubuntu-latest - name: Build FreeBSD - steps: - - uses: actions/checkout@v4 - - name: Build - id: build - uses: cross-platform-actions/action@v0.25.0 - env: - DEBUG: 'napi:*' - RUSTUP_IO_THREADS: 1 - with: - operating_system: freebsd - version: '14.1' - memory: 8G - cpu_count: 3 - environment_variables: 'DEBUG RUSTUP_IO_THREADS' - shell: bash - run: | - sudo pkg install -y -f curl node libnghttp2 npm - sudo npm install -g ${packageManager} --ignore-scripts - curl https://sh.rustup.rs -sSf --output rustup.sh - sh rustup.sh -y --profile minimal --default-toolchain stable - source "$HOME/.cargo/env" - echo "~~~~ rustc --version ~~~~" - rustc --version - echo "~~~~ node -v ~~~~" - node -v - echo "~~~~ yarn --version ~~~~" - yarn --version - pwd - ls -lah - whoami - env - freebsd-version - ${packageManager} install - ${packageManager} build - strip -x *.node - yarn test - rm -rf node_modules - rm -rf target - rm -rf .yarn/cache - - name: Upload artifact - uses: actions/upload-artifact@v4 - with: - name: bindings-freebsd - path: "*.node" - if-no-files-found: error - - test-macOS-windows-binding: - name: Test bindings on \${{ matrix.settings.target }} - node@\${{ matrix.node }} - needs: - - build - strategy: - fail-fast: false - matrix: - settings: - - host: macos-latest - target: 'x86_64-apple-darwin' - architecture: x64 - - host: macos-latest - target: 'aarch64-apple-darwin' - architecture: arm64 - - host: windows-latest - target: 'x86_64-pc-windows-msvc' - architecture: x64 - node: ['18', '20'] - runs-on: \${{ matrix.settings.host }} - - steps: - - uses: actions/checkout@v4 - - - name: Setup node - uses: actions/setup-node@v4 - with: - node-version: \${{ matrix.node }} - cache: '${packageManager}' - architecture: \${{ matrix.settings.architecture }} - - - name: 'Install dependencies' - run: ${packageManager} install - - - name: Download artifacts - uses: actions/download-artifact@v4 - with: - name: bindings-\${{ matrix.settings.target }} - path: . - - - name: List packages - run: ls -R . - shell: bash - - - name: Test bindings - run: ${packageManager} run test - - test-linux-x64-gnu-binding: - name: Test bindings on Linux-x64-gnu - node@\${{ matrix.node }} - needs: - - build - strategy: - fail-fast: false - matrix: - node: ['18', '20'] - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v4 - - - name: Setup node - uses: actions/setup-node@v4 - with: - node-version: \${{ matrix.node }} - cache: '${packageManager}' - - - name: 'Install dependencies' - run: ${packageManager} install - - - name: Download artifacts - uses: actions/download-artifact@v4 - with: - name: bindings-x86_64-unknown-linux-gnu - path: . - - - name: List packages - run: ls -R . - shell: bash - - - name: Test bindings - run: docker run --rm -v $(pwd):/build -w /build node:\${{ matrix.node }}-slim ${packageManager} run test - - test-linux-x64-musl-binding: - name: Test bindings on x86_64-unknown-linux-musl - node@\${{ matrix.node }} - needs: - - build - strategy: - fail-fast: false - matrix: - node: ['18', '20'] - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v4 - - - name: Setup node - uses: actions/setup-node@v4 - with: - node-version: \${{ matrix.node }} - cache: '${packageManager}' - - - name: 'Install dependencies' - run: | - yarn config set supportedArchitectures.libc "musl" - ${packageManager} install - - - name: Download artifacts - uses: actions/download-artifact@v4 - with: - name: bindings-x86_64-unknown-linux-musl - path: . - - - name: List packages - run: ls -R . - shell: bash - - - name: Test bindings - run: docker run --rm -v $(pwd):/build -w /build node:\${{ matrix.node }}-alpine ${packageManager} run test - - test-linux-aarch64-gnu-binding: - name: Test bindings on aarch64-unknown-linux-gnu - node@\${{ matrix.node }} - needs: - - build - strategy: - fail-fast: false - matrix: - node: ['20'] - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v4 - - - name: Download artifacts - uses: actions/download-artifact@v4 - with: - name: bindings-aarch64-unknown-linux-gnu - path: . - - - name: List packages - run: ls -R . - shell: bash - - - name: Install dependencies - run: | - yarn config set supportedArchitectures.cpu "arm64" - yarn config set supportedArchitectures.libc "glibc" - ${packageManager} install - - - name: Set up QEMU - uses: docker/setup-qemu-action@v3 - with: - platforms: arm64 - - run: docker run --rm --privileged multiarch/qemu-user-static --reset -p yes - - - name: Setup and run tests - uses: addnab/docker-run-action@v3 - with: - image: node:\${{ matrix.node }}-slim - options: --platform linux/arm64 -v \${{ github.workspace }}:/build -w /build - run: ${packageManager} run test - - test-linux-aarch64-musl-binding: - name: Test bindings on aarch64-unknown-linux-musl - node@\${{ matrix.node }} - needs: - - build - strategy: - fail-fast: false - matrix: - node: ['18', '20'] - - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v4 - - - name: Download artifacts - uses: actions/download-artifact@v4 - with: - name: bindings-aarch64-unknown-linux-musl - path: . - - - name: List packages - run: ls -R . - shell: bash - - - name: Install dependencies - run: | - yarn config set supportedArchitectures.cpu "arm64" - yarn config set supportedArchitectures.libc "musl" - ${packageManager} install - - - name: Set up QEMU - uses: docker/setup-qemu-action@v3 - with: - platforms: arm64 - - run: docker run --rm --privileged multiarch/qemu-user-static --reset -p yes - - - name: Setup and run tests - uses: addnab/docker-run-action@v3 - with: - image: node:\${{ matrix.node }}-alpine - options: --platform linux/arm64 -v \${{ github.workspace }}:/build -w /build - run: ${packageManager} run test - - test-linux-arm-gnueabihf-binding: - name: Test bindings on armv7-unknown-linux-gnueabihf - node@\${{ matrix.node }} - needs: - - build - strategy: - fail-fast: false - matrix: - node: ['18', '20'] - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v4 - - - name: Download artifacts - uses: actions/download-artifact@v4 - with: - name: bindings-armv7-unknown-linux-gnueabihf - path: . - - - name: List packages - run: ls -R . - shell: bash - - - name: Install dependencies - run: | - yarn config set supportedArchitectures.cpu "arm" - ${packageManager} install - - - name: Set up QEMU - uses: docker/setup-qemu-action@v3 - with: - platforms: arm - - run: docker run --rm --privileged multiarch/qemu-user-static --reset -p yes - - - name: Setup and run tests - uses: addnab/docker-run-action@v3 - with: - image: node:\${{ matrix.node }}-bullseye-slim - options: --platform linux/arm/v7 -v \${{ github.workspace }}:/build -w /build - run: ${packageManager} test - - universal-macOS: - name: Build universal macOS binary - needs: - - build - runs-on: macos-latest - - steps: - - uses: actions/checkout@v4 - - - name: Setup node - uses: actions/setup-node@v4 - with: - node-version: 20 - cache: ${packageManager} - - - name: 'Install dependencies' - run: ${packageManager} install - - - name: Download macOS x64 artifact - uses: actions/download-artifact@v4 - with: - name: bindings-x86_64-apple-darwin - path: . - - name: Download macOS arm64 artifact - uses: actions/download-artifact@v4 - with: - name: bindings-aarch64-apple-darwin - path: . - - - name: Combine binaries - run: ${packageManager} napi universalize - - - name: Upload artifact - uses: actions/upload-artifact@v4 - with: - name: bindings-universal-apple-darwin - path: "*.node" - if-no-files-found: error - - test-wasi-nodejs: - name: Test bindings on wasi - node@\${{ matrix.node }} - needs: - - build - strategy: - fail-fast: false - matrix: - node: ['18', '20'] - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - name: Download artifacts - uses: actions/download-artifact@v4 - with: - name: bindings-${wasiTargetName} - path: . - - name: List packages - run: ls -R . - - uses: actions/setup-node@v4 - with: - node-version: \${{ matrix.node }} - cache: ${packageManager} - - name: 'Install dependencies' - run: ${packageManager} install - - name: Test - run: ${packageManager} test - env: - NAPI_RS_FORCE_WASI: true - - publish: - name: Publish - runs-on: ubuntu-latest - needs: - - test-linux-x64-gnu-binding - - test-linux-x64-musl-binding - - test-linux-aarch64-gnu-binding - - test-linux-arm-gnueabihf-binding - - test-macOS-windows-binding - - test-linux-aarch64-musl-binding - - test-wasi-nodejs - - build-freebsd - - steps: - - uses: actions/checkout@v4 - - - name: Setup node - uses: actions/setup-node@v4 - with: - node-version: 20 - cache: '${packageManager}' - registry-url: 'https://registry.npmjs.org' - - - name: 'Install dependencies' - run: ${packageManager} install - - - name: Download all artifacts - uses: actions/download-artifact@v4 - with: - path: artifacts - - - name: Move artifacts - run: ${packageManager} artifacts - - - name: List packages - run: ls -R ./npm - shell: bash - - - name: Publish - run: | - if git log -1 --pretty=%B | grep "^[0-9]\\+\\.[0-9]\\+\\.[0-9]\\+$"; - then - npm publish --access public --provenance - elif git log -1 --pretty=%B | grep "^[0-9]\\+\\.[0-9]\\+\\.[0-9]\\+"; - then - npm publish --tag next --access public --provenance - else - echo "Not a release, skipping publish" - fi - env: - GITHUB_TOKEN: \${{ secrets.GITHUB_TOKEN }} - NODE_AUTH_TOKEN: \${{ secrets.NPM_TOKEN }} -` diff --git a/cli/src/api/templates/ci.yml.ts b/cli/src/api/templates/ci.yml.ts deleted file mode 100644 index 7d3fa16c..00000000 --- a/cli/src/api/templates/ci.yml.ts +++ /dev/null @@ -1,140 +0,0 @@ -import { load, dump } from 'js-yaml' - -import { - NodeArchToCpu, - type SupportedPackageManager, - UniArchsByPlatform, - parseTriple, -} from '../../utils/index.js' - -import { type WasiTargetName, YAML } from './ci-template.js' - -const BUILD_FREEBSD = 'build-freebsd' -const TEST_MACOS_WINDOWS = 'test-macOS-windows-binding' -const TEST_LINUX_X64_GNU = 'test-linux-x64-gnu-binding' -const TEST_LINUX_X64_MUSL = 'test-linux-x64-musl-binding' -const TEST_LINUX_AARCH64_GNU = 'test-linux-aarch64-gnu-binding' -const TEST_LINUX_AARCH64_MUSL = 'test-linux-aarch64-musl-binding' -const TEST_LINUX_ARM_GNUEABIHF = 'test-linux-arm-gnueabihf-binding' -const TEST_WASI = 'test-wasi-nodejs' -const UNIVERSAL_MACOS = 'universal-macOS' - -export const createGithubActionsCIYml = ( - targets: string[], - packageManager: SupportedPackageManager, - wasiTargetName: WasiTargetName, -) => { - const allTargets = new Set( - targets.flatMap((t) => { - const platform = parseTriple(t) - if (platform.arch === 'universal') { - const srcTriples = UniArchsByPlatform[platform.platform]?.map((arch) => - t.replace('universal', NodeArchToCpu[arch]), - ) - return [t, ...(srcTriples ?? [])] - } - return [t] - }), - ) - - const fullTemplate = load(YAML(packageManager, wasiTargetName)) as any - - const requiredSteps = [] - const enableWindowsX86 = allTargets.has('x86_64-pc-windows-msvc') - const enableMacOSX86 = allTargets.has('x86_64-apple-darwin') - const enableLinuxX86Gnu = allTargets.has('x86_64-unknown-linux-gnu') - const enableLinuxX86Musl = allTargets.has('x86_64-unknown-linux-musl') - const enableLinuxArm8Gnu = allTargets.has('aarch64-unknown-linux-gnu') - const enableLinuxArm8Musl = allTargets.has('aarch64-unknown-linux-musl') - const enableLinuxArm7 = allTargets.has('armv7-unknown-linux-gnueabihf') - const enableFreeBSD = allTargets.has('x86_64-unknown-freebsd') - const enableMacOSUni = allTargets.has('universal-apple-darwin') - const enableWasi = - allTargets.has('wasm32-wasi-preview1-threads') || - allTargets.has('wasm32-wasip1-threads') || - allTargets.has('wasm32-wasip2') - fullTemplate.jobs.build.strategy.matrix.settings = - fullTemplate.jobs.build.strategy.matrix.settings.filter( - ({ target }: { target: string }) => allTargets.has(target), - ) - if (!fullTemplate.jobs.build.strategy.matrix.settings.length) { - delete fullTemplate.jobs.build.strategy.matrix - } - - if (!enableFreeBSD) { - delete fullTemplate.jobs[BUILD_FREEBSD] - } else { - requiredSteps.push(BUILD_FREEBSD) - } - - if (!enableWindowsX86 && !enableMacOSX86) { - delete fullTemplate.jobs[TEST_MACOS_WINDOWS] - } else { - const filterTargets = new Set() - if (enableWindowsX86) { - filterTargets.add('windows-latest') - } - if (enableMacOSUni || enableMacOSX86) { - filterTargets.add('macos-latest') - } - fullTemplate.jobs[TEST_MACOS_WINDOWS].strategy.matrix.settings = - fullTemplate.jobs[TEST_MACOS_WINDOWS].strategy.matrix.settings.filter( - ({ host }: { host: string; target: string }) => filterTargets.has(host), - ) - - requiredSteps.push(TEST_MACOS_WINDOWS) - } - - if (!enableLinuxX86Gnu) { - delete fullTemplate.jobs[TEST_LINUX_X64_GNU] - } else { - requiredSteps.push(TEST_LINUX_X64_GNU) - } - - if (!enableLinuxX86Musl) { - delete fullTemplate.jobs[TEST_LINUX_X64_MUSL] - } else { - requiredSteps.push(TEST_LINUX_X64_MUSL) - } - - if (!enableLinuxArm8Gnu) { - delete fullTemplate.jobs[TEST_LINUX_AARCH64_GNU] - } else { - requiredSteps.push(TEST_LINUX_AARCH64_GNU) - } - - if (!enableLinuxArm8Musl) { - delete fullTemplate.jobs[TEST_LINUX_AARCH64_MUSL] - } else { - requiredSteps.push(TEST_LINUX_AARCH64_MUSL) - } - - if (!enableLinuxArm7) { - delete fullTemplate.jobs[TEST_LINUX_ARM_GNUEABIHF] - } else { - requiredSteps.push(TEST_LINUX_ARM_GNUEABIHF) - } - - if (!enableMacOSUni) { - delete fullTemplate.jobs[UNIVERSAL_MACOS] - } else { - requiredSteps.push(UNIVERSAL_MACOS) - } - - if (!enableWasi) { - delete fullTemplate.jobs[TEST_WASI] - } else { - requiredSteps.push(TEST_WASI) - } - - fullTemplate.jobs.publish.needs = requiredSteps - - try { - return dump(fullTemplate, { - lineWidth: 1000, - }) - } catch (err) { - console.info(fullTemplate) - throw err - } -} diff --git a/cli/src/api/templates/index.ts b/cli/src/api/templates/index.ts index b67fa7a0..ebc997d7 100644 --- a/cli/src/api/templates/index.ts +++ b/cli/src/api/templates/index.ts @@ -1,8 +1 @@ -export * from './.gitignore.js' -export * from './.npmignore.js' -export * from './build.rs.js' -export * from './cargo.toml.js' -export * from './ci.yml.js' -export * from './lib.rs.js' -export * from './package.json.js' export * from './js-binding.js' diff --git a/cli/src/api/templates/lib.rs.ts b/cli/src/api/templates/lib.rs.ts deleted file mode 100644 index b73f2964..00000000 --- a/cli/src/api/templates/lib.rs.ts +++ /dev/null @@ -1,7 +0,0 @@ -export const createLibRs = () => `use napi_derive::napi; - -#[napi] -pub fn sum(a: i32, b: i32) -> i32 { - a + b -} -` diff --git a/cli/src/api/templates/package.json.ts b/cli/src/api/templates/package.json.ts deleted file mode 100644 index 45e0a0f1..00000000 --- a/cli/src/api/templates/package.json.ts +++ /dev/null @@ -1,90 +0,0 @@ -import type { - CommonPackageJsonFields, - SupportedTestFramework, -} from '../../utils/config.js' -import { UNIVERSAL_TARGETS } from '../../utils/target.js' - -export interface PackageMeta { - 'dist-tags': { [index: string]: string } -} - -export const createPackageJson = async ({ - name, - binaryName, - targets, - license, - engineRequirement, - cliVersion, - testFramework, -}: { - name: string - binaryName: string - targets: string[] - license: string - engineRequirement: string - cliVersion: string - testFramework: SupportedTestFramework -}) => { - const hasWasmTarget = targets.some((t) => t.includes('wasm')) - const universalTargets = targets.filter( - (t) => t in UNIVERSAL_TARGETS, - ) as (keyof typeof UNIVERSAL_TARGETS)[] - const unifiedtargets = universalTargets.length - ? targets.filter( - (target) => - !universalTargets.some((t) => { - // @ts-expect-error - return UNIVERSAL_TARGETS[t].includes(target) - }), - ) - : targets - const content: CommonPackageJsonFields = { - name, - version: '0.0.0', - license, - engines: { - node: engineRequirement, - }, - type: 'commonjs', - main: 'index.js', - types: 'index.d.ts', - browser: 'browser.js', - module: undefined, - exports: undefined, - napi: { - binaryName, - targets: unifiedtargets, - }, - scripts: { - test: testFramework, - build: 'napi build --release --platform --strip', - 'build:debug': 'napi build', - prepublishOnly: 'napi prepublish -t npm', - artifacts: 'napi artifacts', - version: 'napi version', - }, - devDependencies: { - '@napi-rs/cli': `^${cliVersion}`, - }, - } - - if (testFramework === 'ava') { - const avaMeta = await fetch(`https://registry.npmjs.org/ava`).then( - (res) => res.json() as Promise, - ) - content.devDependencies!['ava'] = `^${avaMeta['dist-tags'].latest}` - content.ava = { - timeout: '1m', - } - } - - if (hasWasmTarget) { - const wasmRuntime = await fetch( - `https://registry.npmjs.org/@napi-rs/wasm-runtime`, - ).then((res) => res.json() as Promise) - const latest = wasmRuntime['dist-tags'].latest - content.devDependencies!['@napi-rs/wasm-runtime'] = `^${latest}` - } - - return JSON.stringify(content, null, 2) -} diff --git a/crates/napi/src/bindgen_runtime/js_values/arraybuffer.rs b/crates/napi/src/bindgen_runtime/js_values/arraybuffer.rs index ea7feb8d..78870c39 100644 --- a/crates/napi/src/bindgen_runtime/js_values/arraybuffer.rs +++ b/crates/napi/src/bindgen_runtime/js_values/arraybuffer.rs @@ -325,6 +325,96 @@ impl<'env> ArrayBuffer<'env> { } } +#[derive(Clone, Copy)] +/// Represents a JavaScript ArrayBuffer +pub struct TypedArray<'env> { + pub(crate) value: Value, + pub typed_array_type: TypedArrayType, + pub arraybuffer: ArrayBuffer<'env>, + pub byte_offset: usize, +} + +impl TypeName for TypedArray<'_> { + fn type_name() -> &'static str { + "TypedArray" + } + + fn value_type() -> ValueType { + ValueType::Object + } +} + +impl ValidateNapiValue for TypedArray<'_> { + unsafe fn validate(env: sys::napi_env, napi_val: sys::napi_value) -> Result { + let mut is_typedarray = false; + check_status!( + unsafe { sys::napi_is_typedarray(env, napi_val, &mut is_typedarray) }, + "Failed to validate TypedArray" + )?; + if !is_typedarray { + return Err(Error::new( + Status::InvalidArg, + "Value is not a TypedArray".to_owned(), + )); + } + Ok(ptr::null_mut()) + } +} + +impl<'env> JsValue<'env> for TypedArray<'env> { + fn value(&self) -> Value { + self.value + } +} + +impl<'env> JsObjectValue<'env> for TypedArray<'env> {} + +impl FromNapiValue for TypedArray<'_> { + unsafe fn from_napi_value(env: sys::napi_env, napi_val: sys::napi_value) -> Result { + let value = Value { + env, + value: napi_val, + value_type: ValueType::Object, + }; + let mut typed_array_type = 0; + let mut data = ptr::null_mut(); + let mut length = 0; + let mut arraybuffer = ptr::null_mut(); + let mut byte_offset = 0; + check_status!( + unsafe { + sys::napi_get_typedarray_info( + env, + napi_val, + &mut typed_array_type, + &mut length, + &mut data, + &mut arraybuffer, + &mut byte_offset, + ) + }, + "Failed to get typedarray info" + )?; + Ok(Self { + value: Value { + env, + value: napi_val, + value_type: ValueType::Object, + }, + typed_array_type: typed_array_type.into(), + byte_offset, + arraybuffer: ArrayBuffer { + value, + data: if data.is_null() { + &[] + } else { + unsafe { std::slice::from_raw_parts(data as *const u8, length) } + }, + }, + }) + } +} + trait Finalizer { type RustType; @@ -575,7 +665,7 @@ macro_rules! impl_typed_array { let mut ref_ = ptr::null_mut(); check_status!( unsafe { sys::napi_create_reference(env, napi_val, 1, &mut ref_) }, - "Failed to create reference from Buffer" + "Failed to create reference from TypedArray" )?; check_status!( unsafe { diff --git a/examples/napi/__tests__/__snapshots__/values.spec.ts.md b/examples/napi/__tests__/__snapshots__/values.spec.ts.md index a29f4d2b..2c63c527 100644 --- a/examples/napi/__tests__/__snapshots__/values.spec.ts.md +++ b/examples/napi/__tests__/__snapshots__/values.spec.ts.md @@ -49,6 +49,8 @@ Generated by [AVA](https://avajs.dev). [K: symbol]: T␊ }␊ }␊ + ␊ + export type TypedArray = Int8Array | Uint8Array | Uint8ClampedArray | Int16Array | Uint16Array | Int32Array | Uint32Array | Float32Array | Float64Array | BigInt64Array | BigUint64Array␊ /**␊ * \`constructor\` option for \`struct\` requires all fields to be public,␊ * otherwise tag impl fn as constructor␊ @@ -346,6 +348,8 @@ Generated by [AVA](https://avajs.dev). ␊ export declare function acceptUint8ClampedSliceAndBufferSlice(a: Buffer, b: Uint8ClampedArray): bigint␊ ␊ + export declare function acceptUntypedTypedArray(input: TypedArray): bigint␊ + ␊ export declare function add(a: number, b: number): number␊ ␊ export declare const enum ALIAS {␊ diff --git a/examples/napi/__tests__/__snapshots__/values.spec.ts.snap b/examples/napi/__tests__/__snapshots__/values.spec.ts.snap index e43ff56b..4e9b2858 100644 Binary files a/examples/napi/__tests__/__snapshots__/values.spec.ts.snap and b/examples/napi/__tests__/__snapshots__/values.spec.ts.snap differ diff --git a/examples/napi/__tests__/values.spec.ts b/examples/napi/__tests__/values.spec.ts index 5dcca221..75dc2efd 100644 --- a/examples/napi/__tests__/values.spec.ts +++ b/examples/napi/__tests__/values.spec.ts @@ -261,6 +261,7 @@ import { spawnFutureLifetime, promiseRawReturnClassInstance, ClassReturnInPromise, + acceptUntypedTypedArray, } from '../index.cjs' // import other stuff in `#[napi(module_exports)]` import nativeAddon from '../index.cjs' @@ -1141,6 +1142,10 @@ test('deref uint8 array', (t) => { ) }) +test('accept untyped typed array', (t) => { + t.is(acceptUntypedTypedArray(new Uint8Array([1, 2, 3])), 3n) +}) + test('async', async (t) => { if (process.env.WASI_TEST) { t.pass() diff --git a/examples/napi/example.wasi-browser.js b/examples/napi/example.wasi-browser.js index 0d7da677..eea1c018 100644 --- a/examples/napi/example.wasi-browser.js +++ b/examples/napi/example.wasi-browser.js @@ -120,6 +120,7 @@ export const acceptThreadsafeFunctionFatal = __napiModule.exports.acceptThreadsa export const acceptThreadsafeFunctionTupleArgs = __napiModule.exports.acceptThreadsafeFunctionTupleArgs export const acceptUint8ClampedSlice = __napiModule.exports.acceptUint8ClampedSlice export const acceptUint8ClampedSliceAndBufferSlice = __napiModule.exports.acceptUint8ClampedSliceAndBufferSlice +export const acceptUntypedTypedArray = __napiModule.exports.acceptUntypedTypedArray export const add = __napiModule.exports.add export const ALIAS = __napiModule.exports.ALIAS export const AliasedEnum = __napiModule.exports.AliasedEnum diff --git a/examples/napi/example.wasi.cjs b/examples/napi/example.wasi.cjs index 0f9b7945..f572dc17 100644 --- a/examples/napi/example.wasi.cjs +++ b/examples/napi/example.wasi.cjs @@ -144,6 +144,7 @@ module.exports.acceptThreadsafeFunctionFatal = __napiModule.exports.acceptThread module.exports.acceptThreadsafeFunctionTupleArgs = __napiModule.exports.acceptThreadsafeFunctionTupleArgs module.exports.acceptUint8ClampedSlice = __napiModule.exports.acceptUint8ClampedSlice module.exports.acceptUint8ClampedSliceAndBufferSlice = __napiModule.exports.acceptUint8ClampedSliceAndBufferSlice +module.exports.acceptUntypedTypedArray = __napiModule.exports.acceptUntypedTypedArray module.exports.add = __napiModule.exports.add module.exports.ALIAS = __napiModule.exports.ALIAS module.exports.AliasedEnum = __napiModule.exports.AliasedEnum diff --git a/examples/napi/index.cjs b/examples/napi/index.cjs index f85bacd9..044f4c79 100644 --- a/examples/napi/index.cjs +++ b/examples/napi/index.cjs @@ -435,6 +435,7 @@ module.exports.acceptThreadsafeFunctionFatal = nativeBinding.acceptThreadsafeFun module.exports.acceptThreadsafeFunctionTupleArgs = nativeBinding.acceptThreadsafeFunctionTupleArgs module.exports.acceptUint8ClampedSlice = nativeBinding.acceptUint8ClampedSlice module.exports.acceptUint8ClampedSliceAndBufferSlice = nativeBinding.acceptUint8ClampedSliceAndBufferSlice +module.exports.acceptUntypedTypedArray = nativeBinding.acceptUntypedTypedArray module.exports.add = nativeBinding.add module.exports.ALIAS = nativeBinding.ALIAS module.exports.AliasedEnum = nativeBinding.AliasedEnum diff --git a/examples/napi/index.d.cts b/examples/napi/index.d.cts index 3cea6d69..ff4186a4 100644 --- a/examples/napi/index.d.cts +++ b/examples/napi/index.d.cts @@ -11,6 +11,8 @@ export declare class ExternalObject { [K: symbol]: T } } + +export type TypedArray = Int8Array | Uint8Array | Uint8ClampedArray | Int16Array | Uint16Array | Int32Array | Uint32Array | Float32Array | Float64Array | BigInt64Array | BigUint64Array /** * `constructor` option for `struct` requires all fields to be public, * otherwise tag impl fn as constructor @@ -308,6 +310,8 @@ export declare function acceptUint8ClampedSlice(input: Uint8ClampedArray): bigin export declare function acceptUint8ClampedSliceAndBufferSlice(a: Buffer, b: Uint8ClampedArray): bigint +export declare function acceptUntypedTypedArray(input: TypedArray): bigint + export declare function add(a: number, b: number): number export declare const enum ALIAS { diff --git a/examples/napi/src/typed_array.rs b/examples/napi/src/typed_array.rs index bfe4c698..e191e6e9 100644 --- a/examples/napi/src/typed_array.rs +++ b/examples/napi/src/typed_array.rs @@ -278,3 +278,8 @@ pub fn uint8_array_from_external(env: &Env) -> Result> { }) } } + +#[napi] +pub fn accept_untyped_typed_array(input: TypedArray) -> usize { + input.arraybuffer.len() +} diff --git a/yarn.lock b/yarn.lock index d2d1b2c4..f0d51faf 100644 --- a/yarn.lock +++ b/yarn.lock @@ -819,7 +819,7 @@ __metadata: js-yaml: "npm:^4.1.0" lodash-es: "npm:^4.17.21" prettier: "npm:^3.5.3" - rolldown: "npm:^1.0.0-beta.19" + rolldown: "npm:^1.0.0-beta.23" semver: "npm:^7.7.1" tslib: "npm:^2.8.1" typanion: "npm:^3.14.0" @@ -10823,7 +10823,7 @@ __metadata: languageName: node linkType: hard -"rolldown@npm:^1.0.0-beta.19": +"rolldown@npm:^1.0.0-beta.23": version: 1.0.0-beta.9-commit.d91dfb5 resolution: "rolldown@npm:1.0.0-beta.9-commit.d91dfb5" dependencies: