From a781a4f27e19ffaf3e42a470a6d4a990c34c9e3b Mon Sep 17 00:00:00 2001 From: forehal Date: Thu, 6 Apr 2023 11:04:53 +0800 Subject: [PATCH] feat(cli): brand new cli tool with both cli and programmatical usage (#1492) BREAKING CHANGE: requires node >= 16 and some cli options have been renamed --- .eslintignore | 1 + .eslintrc.yml | 2 +- .github/workflows/android-armv7.yml | 5 +- .github/workflows/android.yml | 5 +- .github/workflows/asan.yml | 6 +- .github/workflows/bench.yaml | 3 - .github/workflows/cli-binary.yml | 10 - .github/workflows/linux-aarch64-musl.yaml | 6 +- .github/workflows/linux-aarch64.yaml | 5 +- .github/workflows/linux-armv7.yaml | 5 +- .github/workflows/linux-musl.yaml | 5 +- .github/workflows/memory-test.yml | 3 - .github/workflows/msrv.yml | 3 - .github/workflows/test.yaml | 6 +- .github/workflows/windows-arm.yml | 7 +- .github/workflows/windows-i686.yml | 10 +- .github/workflows/zig.yaml | 18 +- ava.config.mjs | 21 - bench/package.json | 3 +- cli/README.md | 95 +- cli/ava.config.mjs | 10 + cli/cli.mjs | 12 + cli/codegen/commands.ts | 505 ++++++ cli/codegen/index.ts | 279 +++ cli/docs/artifacts.md | 31 + cli/docs/build.md | 50 + cli/docs/create-npm-dirs.md | 31 + cli/docs/new.md | 37 + cli/docs/pre-publish.md | 35 + cli/docs/rename.md | 36 + cli/docs/universalize.md | 30 + cli/docs/version.md | 30 + cli/esbuild.mjs | 11 + cli/package.json | 85 +- cli/src/__test__/parse-triple.spec.ts | 132 -- cli/src/api/artifacts.ts | 93 + cli/src/api/build.ts | 549 ++++++ cli/src/api/create-npm-dirs.ts | 105 ++ cli/src/api/new.ts | 206 +++ cli/src/api/pre-publish.ts | 216 +++ cli/src/api/rename.ts | 51 + .../templates/.gitignore.ts} | 2 +- .../templates/.npmignore.ts} | 2 +- cli/src/api/templates/build.rs.ts | 4 + cli/src/api/templates/cargo.toml.ts | 35 + cli/src/{new => api/templates}/ci-template.ts | 33 +- .../ci-yml.ts => api/templates/ci.yml.ts} | 13 +- cli/src/api/templates/index.ts | 8 + cli/src/api/templates/js-binding.ts | 130 ++ .../lib-rs.ts => api/templates/lib.rs.ts} | 2 +- cli/src/api/templates/package.json.ts | 44 + cli/src/api/universalize.ts | 76 + cli/src/api/version.ts | 26 + cli/src/arm-features.h.ts | 56 - cli/src/artifacts.ts | 89 - cli/src/build.ts | 921 ---------- cli/src/cli.ts | 29 + cli/src/commands/artifacts.ts | 23 + cli/src/commands/build.ts | 42 + cli/src/commands/create-npm-dirs.ts | 8 + cli/src/{ => commands}/help.ts | 0 cli/src/commands/new.ts | 138 ++ cli/src/commands/pre-publish.ts | 9 + cli/src/commands/rename.ts | 8 + cli/src/commands/universalize.ts | 8 + cli/src/commands/version.ts | 8 + cli/src/consts.ts | 40 - cli/src/create-npm-dir.ts | 105 -- cli/src/debug.ts | 3 - cli/src/def/artifacts.ts | 79 + cli/src/def/build.ts | 242 +++ cli/src/def/create-npm-dirs.ts | 79 + cli/src/def/new.ts | 144 ++ cli/src/def/pre-publish.ts | 120 ++ cli/src/def/rename.ts | 122 ++ cli/src/def/universalize.ts | 66 + cli/src/def/version.ts | 65 + cli/src/index.ts | 71 +- cli/src/js-binding-template.ts | 258 --- cli/src/new/cargo-config.ts | 9 - cli/src/new/cargo.ts | 19 - cli/src/new/index.ts | 230 --- cli/src/new/package.ts | 64 - cli/src/pre-publish.ts | 242 --- cli/src/rename.ts | 121 -- cli/src/spawn.ts | 30 - cli/src/universal.ts | 81 - cli/src/update-package.ts | 17 - cli/src/utils.ts | 23 - .../__tests__/__fixtures__/napi_type_def | 201 +++ .../__tests__/__snapshots__/target.spec.ts.md | 110 ++ .../__snapshots__/target.spec.ts.snap | Bin 0 -> 991 bytes .../__snapshots__/typegen.spec.ts.md | 618 +++++++ .../__snapshots__/typegen.spec.ts.snap | Bin 0 -> 3961 bytes .../__snapshots__/version.spec.ts.md | 20 + .../__snapshots__/version.spec.ts.snap | Bin 0 -> 364 bytes cli/src/utils/__tests__/target.spec.ts | 19 + cli/src/utils/__tests__/typegen.spec.ts | 49 + cli/src/utils/__tests__/version.spec.ts | 13 + cli/src/utils/cargo.ts | 35 + cli/src/utils/ci.ts | 102 ++ cli/src/utils/config.ts | 123 ++ cli/src/utils/index.ts | 9 + cli/src/utils/log.ts | 34 + cli/src/utils/metadata.ts | 59 + cli/src/utils/misc.ts | 45 + cli/src/{parse-triple.ts => utils/target.ts} | 111 +- cli/src/utils/typegen.ts | 193 +++ cli/src/utils/version.ts | 76 + cli/src/version.ts | 43 - cli/tsconfig.json | 16 + crates/build/src/lib.rs | 1 + crates/napi/Cargo.toml | 3 + examples/binary/package.json | 10 +- .../__snapshots__}/object.spec.ts.md | 2 +- .../__snapshots__}/object.spec.ts.snap | Bin .../__snapshots__}/string.spec.ts.md | Bin 554 -> 529 bytes .../__snapshots__}/string.spec.ts.snap | Bin .../{__test__ => __tests__}/array.spec.ts | 0 .../arraybuffer.spec.ts | 0 .../{__test__ => __tests__}/buffer.spec.ts | 0 .../{__test__ => __tests__}/class.spec.ts | 0 .../cleanup-env.spec.ts | 0 .../create-external.spec.ts | 0 .../{__test__ => __tests__}/either.spec.ts | 0 .../{__test__ => __tests__}/env.spec.ts | 2 +- .../{__test__ => __tests__}/function.spec.ts | 0 .../get-napi-version.spec.ts | 0 .../{__test__ => __tests__}/global.spec.ts | 0 .../{__test__ => __tests__}/js-value.spec.ts | 0 .../{__test__ => __tests__}/napi-version.ts | 0 .../napi4/deferred.spec.ts | 0 .../{__test__ => __tests__}/napi4/example.txt | 0 .../napi4/threadsafe_function.spec.ts | 0 .../napi4/tokio_readfile.spec.ts | 0 .../napi4/tokio_rt.spec.ts | 0 .../napi4/tsfn-dua-instance.js | 0 .../napi4/tsfn-throw.js | 0 .../napi4/tsfn_error.spec.ts | 0 .../napi5/date.spec.ts | 0 .../napi6/bigint.spec.ts | 0 .../napi6/instance-data.spec.ts | 0 .../napi7/arraybuffer.spec.ts | 0 .../napi8/async-cleanup.spec.ts | 0 .../napi8/object.spec.ts | 0 .../napi8/sub-process-removable.js | 0 .../napi8/sub-process.js | 0 .../{__test__ => __tests__}/object.spec.ts | 0 .../serde/__snapshots__/ser.spec.ts.md | 141 ++ .../serde/__snapshots__}/ser.spec.ts.snap | Bin .../{__test__ => __tests__}/serde/de.spec.ts | 0 .../{__test__ => __tests__}/serde/ser.spec.ts | 0 .../serde/ser.spec.ts.md | 0 .../__tests__/serde/ser.spec.ts.snap | Bin 0 -> 1079 bytes .../serde/serde-json.spec.ts | 0 .../{__test__ => __tests__}/spawn.spec.ts | 0 .../{__test__ => __tests__}/string.spec.ts | 0 .../{__test__ => __tests__}/symbol.spec.ts | 0 .../{__test__ => __tests__}/throw.spec.ts | 0 examples/napi-compat-mode/package.json | 31 +- examples/napi-shared/Cargo.toml | 3 + examples/napi-shared/build.rs | 5 + examples/napi/__test__/values.spec.ts.md | 47 - examples/napi/__test__/values.spec.ts.snap | Bin 633 -> 0 bytes .../__snapshots__}/typegen.spec.ts.md | 772 +++++---- .../__snapshots__/typegen.spec.ts.snap | Bin 0 -> 3952 bytes .../__tests__/__snapshots__/values.spec.ts.md | 17 + .../__snapshots__/values.spec.ts.snap | Bin 0 -> 233 bytes .../{__test__ => __tests__}/error-msg.spec.ts | 0 .../{__test__ => __tests__}/generator.spec.ts | 0 .../object-attr.spec.ts | 0 .../{__test__ => __tests__}/strict.spec.ts | 0 .../{__test__ => __tests__}/tsfn-error.js | 0 .../{__test__ => __tests__}/typegen.spec.ts | 0 .../{__test__ => __tests__}/unload.spec.js | 0 .../{__test__ => __tests__}/values.spec.ts | 6 +- .../worker-thread.spec.ts | 0 .../napi/{__test__ => __tests__}/worker.js | 0 examples/napi/index.d.ts | 770 +++++---- examples/napi/package.json | 30 +- examples/napi/src/class.rs | 3 +- examples/napi/tsconfig.json | 2 +- generate-triple-list.ts | 48 - memory-testing/package.json | 3 +- memory-testing/test-util.mjs | 10 +- package.json | 28 +- rollup.config.mjs | 74 - triples/generate-triple-list.ts | 58 + triples/index.cjs | 393 +++++ triples/index.js | 394 ++++- triples/package.json | 21 + tsconfig.json | 8 +- tsconfig.root-lint.json | 6 +- yarn.lock | 1502 +++++++++++------ 194 files changed, 8805 insertions(+), 4158 deletions(-) delete mode 100644 ava.config.mjs create mode 100644 cli/ava.config.mjs create mode 100755 cli/cli.mjs create mode 100644 cli/codegen/commands.ts create mode 100644 cli/codegen/index.ts create mode 100644 cli/docs/artifacts.md create mode 100644 cli/docs/build.md create mode 100644 cli/docs/create-npm-dirs.md create mode 100644 cli/docs/new.md create mode 100644 cli/docs/pre-publish.md create mode 100644 cli/docs/rename.md create mode 100644 cli/docs/universalize.md create mode 100644 cli/docs/version.md create mode 100644 cli/esbuild.mjs delete mode 100644 cli/src/__test__/parse-triple.spec.ts create mode 100644 cli/src/api/artifacts.ts create mode 100644 cli/src/api/build.ts create mode 100644 cli/src/api/create-npm-dirs.ts create mode 100644 cli/src/api/new.ts create mode 100644 cli/src/api/pre-publish.ts create mode 100644 cli/src/api/rename.ts rename cli/src/{new/gitignore-template.ts => api/templates/.gitignore.ts} (98%) rename cli/src/{new/npmignore.ts => api/templates/.npmignore.ts} (75%) create mode 100644 cli/src/api/templates/build.rs.ts create mode 100644 cli/src/api/templates/cargo.toml.ts rename cli/src/{new => api/templates}/ci-template.ts (94%) rename cli/src/{new/ci-yml.ts => api/templates/ci.yml.ts} (94%) create mode 100644 cli/src/api/templates/index.ts create mode 100644 cli/src/api/templates/js-binding.ts rename cli/src/{new/lib-rs.ts => api/templates/lib.rs.ts} (63%) create mode 100644 cli/src/api/templates/package.json.ts create mode 100644 cli/src/api/universalize.ts create mode 100644 cli/src/api/version.ts delete mode 100644 cli/src/arm-features.h.ts delete mode 100644 cli/src/artifacts.ts delete mode 100644 cli/src/build.ts create mode 100644 cli/src/cli.ts create mode 100644 cli/src/commands/artifacts.ts create mode 100644 cli/src/commands/build.ts create mode 100644 cli/src/commands/create-npm-dirs.ts rename cli/src/{ => commands}/help.ts (100%) create mode 100644 cli/src/commands/new.ts create mode 100644 cli/src/commands/pre-publish.ts create mode 100644 cli/src/commands/rename.ts create mode 100644 cli/src/commands/universalize.ts create mode 100644 cli/src/commands/version.ts delete mode 100644 cli/src/consts.ts delete mode 100644 cli/src/create-npm-dir.ts delete mode 100644 cli/src/debug.ts create mode 100644 cli/src/def/artifacts.ts create mode 100644 cli/src/def/build.ts create mode 100644 cli/src/def/create-npm-dirs.ts create mode 100644 cli/src/def/new.ts create mode 100644 cli/src/def/pre-publish.ts create mode 100644 cli/src/def/rename.ts create mode 100644 cli/src/def/universalize.ts create mode 100644 cli/src/def/version.ts delete mode 100644 cli/src/js-binding-template.ts delete mode 100644 cli/src/new/cargo-config.ts delete mode 100644 cli/src/new/cargo.ts delete mode 100644 cli/src/new/index.ts delete mode 100644 cli/src/new/package.ts delete mode 100644 cli/src/pre-publish.ts delete mode 100644 cli/src/rename.ts delete mode 100644 cli/src/spawn.ts delete mode 100644 cli/src/universal.ts delete mode 100644 cli/src/update-package.ts delete mode 100644 cli/src/utils.ts create mode 100644 cli/src/utils/__tests__/__fixtures__/napi_type_def create mode 100644 cli/src/utils/__tests__/__snapshots__/target.spec.ts.md create mode 100644 cli/src/utils/__tests__/__snapshots__/target.spec.ts.snap create mode 100644 cli/src/utils/__tests__/__snapshots__/typegen.spec.ts.md create mode 100644 cli/src/utils/__tests__/__snapshots__/typegen.spec.ts.snap create mode 100644 cli/src/utils/__tests__/__snapshots__/version.spec.ts.md create mode 100644 cli/src/utils/__tests__/__snapshots__/version.spec.ts.snap create mode 100644 cli/src/utils/__tests__/target.spec.ts create mode 100644 cli/src/utils/__tests__/typegen.spec.ts create mode 100644 cli/src/utils/__tests__/version.spec.ts create mode 100644 cli/src/utils/cargo.ts create mode 100644 cli/src/utils/ci.ts create mode 100644 cli/src/utils/config.ts create mode 100644 cli/src/utils/index.ts create mode 100644 cli/src/utils/log.ts create mode 100644 cli/src/utils/metadata.ts create mode 100644 cli/src/utils/misc.ts rename cli/src/{parse-triple.ts => utils/target.ts} (50%) create mode 100644 cli/src/utils/typegen.ts create mode 100644 cli/src/utils/version.ts delete mode 100644 cli/src/version.ts create mode 100644 cli/tsconfig.json rename examples/napi-compat-mode/{__test__ => __tests__/__snapshots__}/object.spec.ts.md (87%) rename examples/napi-compat-mode/{__test__ => __tests__/__snapshots__}/object.spec.ts.snap (100%) rename examples/napi-compat-mode/{__test__ => __tests__/__snapshots__}/string.spec.ts.md (86%) rename examples/napi-compat-mode/{__test__ => __tests__/__snapshots__}/string.spec.ts.snap (100%) rename examples/napi-compat-mode/{__test__ => __tests__}/array.spec.ts (100%) rename examples/napi-compat-mode/{__test__ => __tests__}/arraybuffer.spec.ts (100%) rename examples/napi-compat-mode/{__test__ => __tests__}/buffer.spec.ts (100%) rename examples/napi-compat-mode/{__test__ => __tests__}/class.spec.ts (100%) rename examples/napi-compat-mode/{__test__ => __tests__}/cleanup-env.spec.ts (100%) rename examples/napi-compat-mode/{__test__ => __tests__}/create-external.spec.ts (100%) rename examples/napi-compat-mode/{__test__ => __tests__}/either.spec.ts (100%) rename examples/napi-compat-mode/{__test__ => __tests__}/env.spec.ts (92%) rename examples/napi-compat-mode/{__test__ => __tests__}/function.spec.ts (100%) rename examples/napi-compat-mode/{__test__ => __tests__}/get-napi-version.spec.ts (100%) rename examples/napi-compat-mode/{__test__ => __tests__}/global.spec.ts (100%) rename examples/napi-compat-mode/{__test__ => __tests__}/js-value.spec.ts (100%) rename examples/napi-compat-mode/{__test__ => __tests__}/napi-version.ts (100%) rename examples/napi-compat-mode/{__test__ => __tests__}/napi4/deferred.spec.ts (100%) rename examples/napi-compat-mode/{__test__ => __tests__}/napi4/example.txt (100%) rename examples/napi-compat-mode/{__test__ => __tests__}/napi4/threadsafe_function.spec.ts (100%) rename examples/napi-compat-mode/{__test__ => __tests__}/napi4/tokio_readfile.spec.ts (100%) rename examples/napi-compat-mode/{__test__ => __tests__}/napi4/tokio_rt.spec.ts (100%) rename examples/napi-compat-mode/{__test__ => __tests__}/napi4/tsfn-dua-instance.js (100%) rename examples/napi-compat-mode/{__test__ => __tests__}/napi4/tsfn-throw.js (100%) rename examples/napi-compat-mode/{__test__ => __tests__}/napi4/tsfn_error.spec.ts (100%) rename examples/napi-compat-mode/{__test__ => __tests__}/napi5/date.spec.ts (100%) rename examples/napi-compat-mode/{__test__ => __tests__}/napi6/bigint.spec.ts (100%) rename examples/napi-compat-mode/{__test__ => __tests__}/napi6/instance-data.spec.ts (100%) rename examples/napi-compat-mode/{__test__ => __tests__}/napi7/arraybuffer.spec.ts (100%) rename examples/napi-compat-mode/{__test__ => __tests__}/napi8/async-cleanup.spec.ts (100%) rename examples/napi-compat-mode/{__test__ => __tests__}/napi8/object.spec.ts (100%) rename examples/napi-compat-mode/{__test__ => __tests__}/napi8/sub-process-removable.js (100%) rename examples/napi-compat-mode/{__test__ => __tests__}/napi8/sub-process.js (100%) rename examples/napi-compat-mode/{__test__ => __tests__}/object.spec.ts (100%) create mode 100644 examples/napi-compat-mode/__tests__/serde/__snapshots__/ser.spec.ts.md rename examples/napi-compat-mode/{__test__/serde => __tests__/serde/__snapshots__}/ser.spec.ts.snap (100%) rename examples/napi-compat-mode/{__test__ => __tests__}/serde/de.spec.ts (100%) rename examples/napi-compat-mode/{__test__ => __tests__}/serde/ser.spec.ts (100%) rename examples/napi-compat-mode/{__test__ => __tests__}/serde/ser.spec.ts.md (100%) create mode 100644 examples/napi-compat-mode/__tests__/serde/ser.spec.ts.snap rename examples/napi-compat-mode/{__test__ => __tests__}/serde/serde-json.spec.ts (100%) rename examples/napi-compat-mode/{__test__ => __tests__}/spawn.spec.ts (100%) rename examples/napi-compat-mode/{__test__ => __tests__}/string.spec.ts (100%) rename examples/napi-compat-mode/{__test__ => __tests__}/symbol.spec.ts (100%) rename examples/napi-compat-mode/{__test__ => __tests__}/throw.spec.ts (100%) create mode 100644 examples/napi-shared/build.rs delete mode 100644 examples/napi/__test__/values.spec.ts.md delete mode 100644 examples/napi/__test__/values.spec.ts.snap rename examples/napi/{__test__ => __tests__/__snapshots__}/typegen.spec.ts.md (91%) create mode 100644 examples/napi/__tests__/__snapshots__/typegen.spec.ts.snap create mode 100644 examples/napi/__tests__/__snapshots__/values.spec.ts.md create mode 100644 examples/napi/__tests__/__snapshots__/values.spec.ts.snap rename examples/napi/{__test__ => __tests__}/error-msg.spec.ts (100%) rename examples/napi/{__test__ => __tests__}/generator.spec.ts (100%) rename examples/napi/{__test__ => __tests__}/object-attr.spec.ts (100%) rename examples/napi/{__test__ => __tests__}/strict.spec.ts (100%) rename examples/napi/{__test__ => __tests__}/tsfn-error.js (100%) rename examples/napi/{__test__ => __tests__}/typegen.spec.ts (100%) rename examples/napi/{__test__ => __tests__}/unload.spec.js (100%) rename examples/napi/{__test__ => __tests__}/values.spec.ts (99%) rename examples/napi/{__test__ => __tests__}/worker-thread.spec.ts (100%) rename examples/napi/{__test__ => __tests__}/worker.js (100%) delete mode 100644 generate-triple-list.ts delete mode 100644 rollup.config.mjs create mode 100644 triples/generate-triple-list.ts create mode 100644 triples/index.cjs diff --git a/.eslintignore b/.eslintignore index cb05ec9a..fab70af3 100644 --- a/.eslintignore +++ b/.eslintignore @@ -14,3 +14,4 @@ target scripts triples/index.js rollup.config.js +crates/cli/index.js \ No newline at end of file diff --git a/.eslintrc.yml b/.eslintrc.yml index 44351830..e6c076d5 100644 --- a/.eslintrc.yml +++ b/.eslintrc.yml @@ -192,7 +192,7 @@ rules: overrides: - files: - - ./cli/**/*.ts + - ./**/*.ts plugins: - '@typescript-eslint' parserOptions: diff --git a/.github/workflows/android-armv7.yml b/.github/workflows/android-armv7.yml index 2f790ab1..3c724c45 100644 --- a/.github/workflows/android-armv7.yml +++ b/.github/workflows/android-armv7.yml @@ -47,13 +47,10 @@ jobs: - name: Install dependencies run: yarn install --immutable --mode=skip-build - - name: 'Build TypeScript' - run: yarn build - - name: Cross build run: | export CARGO_TARGET_ARMV7_LINUX_ANDROIDEABI_LINKER="${ANDROID_NDK_LATEST_HOME}/toolchains/llvm/prebuilt/linux-x86_64/bin/armv7a-linux-androideabi24-clang" - yarn build:test:android:armv7 + yarn build:test -- --target armv7-linux-androideabi du -sh examples/napi/index.node ${ANDROID_NDK_LATEST_HOME}/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-strip examples/napi/index.node du -sh examples/napi/index.node diff --git a/.github/workflows/android.yml b/.github/workflows/android.yml index 6a84b408..53a3499c 100644 --- a/.github/workflows/android.yml +++ b/.github/workflows/android.yml @@ -47,10 +47,7 @@ jobs: - name: Install dependencies run: yarn install --immutable --mode=skip-build - - name: 'Build TypeScript' - run: yarn build - - name: Cross build native tests run: | export CARGO_TARGET_AARCH64_LINUX_ANDROID_LINKER="${ANDROID_NDK_LATEST_HOME}/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android24-clang" - yarn build:test:android + yarn build:test -- --target aarch64-linux-android diff --git a/.github/workflows/asan.yml b/.github/workflows/asan.yml index 0b9f2677..8ec41173 100644 --- a/.github/workflows/asan.yml +++ b/.github/workflows/asan.yml @@ -44,12 +44,10 @@ jobs: - name: 'Install dependencies' run: yarn install --immutable --mode=skip-build - - name: 'Build TypeScript' - run: yarn build - - name: Unit tests with address sanitizer run: | - yarn build:test:asan + yarn workspace @examples/napi build -- -Z build-std + yarn workspace @examples/compat-mode build -- -Z build-std LD_PRELOAD=/usr/lib/gcc/x86_64-linux-gnu/9/libasan.so yarn test env: RUST_TARGET: x86_64-unknown-linux-gnu diff --git a/.github/workflows/bench.yaml b/.github/workflows/bench.yaml index c887be9f..6c5f9476 100644 --- a/.github/workflows/bench.yaml +++ b/.github/workflows/bench.yaml @@ -46,9 +46,6 @@ jobs: - name: 'Install dependencies' run: yarn install --immutable --mode=skip-build - - name: 'Build ts' - run: yarn build - - name: 'Build bench' run: yarn build:bench diff --git a/.github/workflows/cli-binary.yml b/.github/workflows/cli-binary.yml index 6bf9033c..79c2f3bf 100644 --- a/.github/workflows/cli-binary.yml +++ b/.github/workflows/cli-binary.yml @@ -44,9 +44,6 @@ jobs: - name: 'Install dependencies' run: yarn install --mode=skip-build --immutable - - name: 'Build TypeScript' - run: yarn build - - name: Build and run binary run: | yarn workspace binary build @@ -54,13 +51,6 @@ jobs: env: RUST_BACKTRACE: 1 - - name: Pass -p and --cargo-name to build - run: | - node ./cli/scripts/index.js build -p napi-examples-binary --cargo-name napi-examples-binary - ./napi-examples-binary - env: - RUST_BACKTRACE: 1 - - name: Clear the cargo caches run: | cargo install cargo-cache --no-default-features --features ci-autoclean diff --git a/.github/workflows/linux-aarch64-musl.yaml b/.github/workflows/linux-aarch64-musl.yaml index cb195c8e..b0fb8042 100644 --- a/.github/workflows/linux-aarch64-musl.yaml +++ b/.github/workflows/linux-aarch64-musl.yaml @@ -30,9 +30,6 @@ jobs: - name: Install dependencies run: yarn install --immutable --mode=skip-build - - name: 'Build TypeScript' - run: yarn build - - name: Cross build native tests uses: addnab/docker-run-action@v3 with: @@ -40,8 +37,7 @@ jobs: options: -v ${{ github.workspace }}:/napi-rs -w /napi-rs run: | export CARGO_TARGET_AARCH64_UNKNOWN_LINUX_MUSL_LINKER=aarch64-linux-musl-gcc - yarn workspace compat-mode-examples build --target aarch64-unknown-linux-musl - yarn workspace examples build --target aarch64-unknown-linux-musl + yarn build:test -- --target aarch64-unknown-linux-musl - run: docker run --rm --privileged multiarch/qemu-user-static --reset -p yes diff --git a/.github/workflows/linux-aarch64.yaml b/.github/workflows/linux-aarch64.yaml index 8d9ddf48..3f01f3c5 100644 --- a/.github/workflows/linux-aarch64.yaml +++ b/.github/workflows/linux-aarch64.yaml @@ -50,11 +50,8 @@ jobs: - name: Install dependencies run: yarn install --immutable --mode=skip-build - - name: 'Build TypeScript' - run: yarn build - - name: Cross build native tests - run: yarn build:test:aarch64 + run: yarn build:test -- --target aarch64-unknown-linux-gnu --cross-compile - run: docker run --rm --privileged multiarch/qemu-user-static --reset -p yes diff --git a/.github/workflows/linux-armv7.yaml b/.github/workflows/linux-armv7.yaml index 35a61f42..fed78015 100644 --- a/.github/workflows/linux-armv7.yaml +++ b/.github/workflows/linux-armv7.yaml @@ -51,11 +51,8 @@ jobs: - name: Install dependencies run: yarn install --immutable --mode=skip-build - - name: 'Build TypeScript' - run: yarn build - - name: Cross build native tests - run: yarn build:test:armv7 + run: yarn build:test -- --target armv7-unknown-linux-gnueabihf --cross-compile - run: docker run --rm --privileged multiarch/qemu-user-static --reset -p yes diff --git a/.github/workflows/linux-musl.yaml b/.github/workflows/linux-musl.yaml index b417ab4e..6df364fe 100644 --- a/.github/workflows/linux-musl.yaml +++ b/.github/workflows/linux-musl.yaml @@ -30,9 +30,6 @@ jobs: - name: 'Install dependencies' run: yarn install --immutable --mode=skip-build - - name: 'Build TypeScript' - run: yarn build - - name: Setup and run tests uses: addnab/docker-run-action@v3 with: @@ -40,5 +37,5 @@ jobs: options: -v ${{ github.workspace }}:/napi-rs -w /napi-rs run: | cargo check -vvv - yarn build:test + yarn build:test -- --target x86_64-unknown-linux-musl yarn test diff --git a/.github/workflows/memory-test.yml b/.github/workflows/memory-test.yml index afbcb2ec..1883c73e 100644 --- a/.github/workflows/memory-test.yml +++ b/.github/workflows/memory-test.yml @@ -49,9 +49,6 @@ jobs: - name: 'Install dependencies' run: yarn install --immutable - - name: 'Build TypeScript' - run: yarn build - - name: 'Pull docker image' run: docker pull node:lts-slim diff --git a/.github/workflows/msrv.yml b/.github/workflows/msrv.yml index 7814d392..b161ab40 100644 --- a/.github/workflows/msrv.yml +++ b/.github/workflows/msrv.yml @@ -43,9 +43,6 @@ jobs: - name: 'Install dependencies' run: yarn install --mode=skip-build --immutable - - name: 'Build TypeScript' - run: yarn build - - name: Check build uses: actions-rs/cargo@v1 with: diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 6b108579..1b04ae79 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -19,7 +19,7 @@ jobs: strategy: fail-fast: false matrix: - node: ['14', '16', '18'] + node: ['16', '18'] os: [ubuntu-latest, macos-latest, windows-latest] name: stable - ${{ matrix.os }} - node@${{ matrix.node }} @@ -51,9 +51,6 @@ jobs: - name: 'Install dependencies' run: yarn install --mode=skip-build --immutable - - name: 'Build TypeScript' - run: yarn build - - name: Check build uses: actions-rs/cargo@v1 with: @@ -62,6 +59,7 @@ jobs: - name: Unit tests run: | + yarn test:cli yarn build:test yarn test --verbose yarn tsc -p examples/napi/tsconfig.json --noEmit diff --git a/.github/workflows/windows-arm.yml b/.github/workflows/windows-arm.yml index 4dabd4ba..3dd9ec80 100644 --- a/.github/workflows/windows-arm.yml +++ b/.github/workflows/windows-arm.yml @@ -30,9 +30,6 @@ jobs: - name: 'Install dependencies' run: yarn install --mode=skip-build --immutable - - name: 'Build TypeScript' - run: yarn build - - name: Install uses: dtolnay/rust-toolchain@stable with: @@ -55,7 +52,9 @@ jobs: args: --all --bins --examples --tests --target aarch64-pc-windows-msvc -vvv - name: Build release target - run: cargo build --release --target aarch64-pc-windows-msvc + run: | + yarn workspace @examples/napi build --target aarch64-pc-windows-msvc --release + yarn workspace @examples/compat-mode build --target aarch64-pc-windows-msvc --release - name: Clear the cargo caches run: | diff --git a/.github/workflows/windows-i686.yml b/.github/workflows/windows-i686.yml index f3c4b9dd..d4ad4243 100644 --- a/.github/workflows/windows-i686.yml +++ b/.github/workflows/windows-i686.yml @@ -31,9 +31,6 @@ jobs: run: | yarn install --mode=skip-build --immutable - - name: 'Build TypeScript' - run: yarn build - - name: Install uses: dtolnay/rust-toolchain@stable with: @@ -55,6 +52,11 @@ jobs: command: check args: --all --bins --examples --tests --target i686-pc-windows-msvc -vvv + - name: Build + run: | + yarn workspace @examples/napi build --target i686-pc-windows-msvc --release + yarn workspace @examples/compat-mode build --target i686-pc-windows-msvc --release + - name: Setup node uses: actions/setup-node@v3 with: @@ -64,8 +66,6 @@ jobs: - name: Build Tests run: | - yarn workspace compat-mode-examples build-i686 --release - yarn workspace examples build-i686 --release yarn test --verbose node ./node_modules/electron/install.js yarn test:electron diff --git a/.github/workflows/zig.yaml b/.github/workflows/zig.yaml index 7898b0ba..789a8ea5 100644 --- a/.github/workflows/zig.yaml +++ b/.github/workflows/zig.yaml @@ -56,17 +56,15 @@ jobs: version: 0.10.1 - name: Install dependencies run: yarn install --immutable --mode=skip-build - - name: 'Build TypeScript' - run: yarn build - - name: Setup node - uses: actions/setup-node@v3 - with: - # Testing for compatibility with node v12.x - node-version: 12 - - name: Cross build native tests + - name: install MacOS SDK + if: contains(matrix.target, 'apple') run: | - yarn workspace compat-mode-examples build --target ${{ matrix.target }} --zig - yarn workspace examples build --target ${{ matrix.target }} --zig + curl -L "https://github.com/phracker/MacOSX-SDKs/releases/download/11.3/MacOSX11.3.sdk.tar.xz" | tar -J -x -C /opt + - name: Cross build native tests + env: + SDKROOT: /opt/MacOSX11.3.sdk + run: | + yarn build:test -- --target ${{ matrix.target }} --cross-compile - name: Upload artifacts uses: actions/upload-artifact@v3 with: diff --git a/ava.config.mjs b/ava.config.mjs deleted file mode 100644 index 1d1564f3..00000000 --- a/ava.config.mjs +++ /dev/null @@ -1,21 +0,0 @@ -import { cpus } from 'os' - -const configuration = { - extensions: ['ts', 'tsx'], - files: ['cli/**/*.spec.ts', 'examples/**/__test__/**/*.spec.ts'], - require: ['ts-node/register/transpile-only'], - environmentVariables: { - TS_NODE_PROJECT: './examples/tsconfig.json', - }, - timeout: '5m', - workerThreads: true, - concurrency: process.env.CI ? 2 : cpus().length, - failFast: false, - verbose: !!process.env.CI, -} - -if (parseInt(process.versions.napi, 10) < 4) { - configuration.compileEnhancements = false -} - -export default configuration diff --git a/bench/package.json b/bench/package.json index 34873543..0ae2a49a 100644 --- a/bench/package.json +++ b/bench/package.json @@ -3,9 +3,10 @@ "version": "1.0.0", "private": true, "scripts": { - "build": "node ../cli/scripts/index.js build --js false --release" + "build": "napi-raw build --js false --release" }, "devDependencies": { + "@napi-rs/cli": "workspace:*", "benny": "^3.7.1" } } diff --git a/cli/README.md b/cli/README.md index 37190324..f674ecac 100644 --- a/cli/README.md +++ b/cli/README.md @@ -9,88 +9,27 @@ > Cli tools for napi-rs +```sh +# or npm, pnpm +yarn add @napi-rs/cli -D +yarn napi build +``` + ## Commands +| Command | desc | docs | +| --------------- | -------------------------------------------------------------- | --------------------------------------------------- | +| new | create new napi-rs project | [./docs/new.md](./docs/new.md) | +| build | build napi-rs project | [./docs/build.md](./docs/build.md) | +| create-npm-dirs | Create npm package dirs for different platforms | [./docs/create-npm-dirs](./docs/create-npm-dirs.md) | +| artifacts | Copy artifacts from Github Actions into specified dir | [./docs/artifacts.md](./docs/artifacts.md) | +| rename | Rename the napi-rs project | [./docs/rename.md](./docs/rename.md) | +| universalize | Combile built binaries into one universal binary | [./docs/universalize.md](./docs/universalize.md) | +| version | Update version in created npm packages by `create-npm-dirs` | [./docs/version.md](./docs/version.md) | +| pre-publish | Update package.json and copy addons into per platform packages | [./docs/pre-publish.md](./docs/pre-publish.md) | + ### Debug mode ```bash DEBUG="napi:*" napi [command] ``` - -### `napi build` - -> Build command. Build rust codes and copy the dynamic lib binary file to the dist dir. - -#### `--platform` - -> default `false` - -Append `platform-arch-[abi]` name to dist file. eg: `index.darwin-x64.node`. - -#### `--release` - -> default `false` - -Is release build. This flag will be passed to `Cargo` directly. - -#### `--features` - -> default `''` - -Cargo features, passthrough to `cargo build` command. - -#### `--config,-c` - -> default `package.json` - -`napi-rs` config file name. `napi-rs` config example : - -```js -{ - "name": "@native-binding/fib", - "version": "0.1.0", - "napi": { - "name": "fib", // binary name - "triples": { - "defaults": true, // default true, if this value is true, will build `x86_64-pc-windows-msvc`, `x86_64-apple-darwin` and `x86_64-unknown-linux-gnu` - "additional": [ - "x86_64-unknown-linux-musl", - "x86_64-unknown-freebsd", - "aarch64-unknown-linux-gnu" - ] - } - } -} -``` - -#### `--cargo-name` - -> default `undefined` - -If not set, cli will read the `package.name` field in `Cargo.toml` under `process.cwd()`. The `-` in the name will be replaced with `_`. - -#### `--target` - -> default `undefined` - -> Note you should have `rustup` installed if omit the `--target` flag. The `@napi-rs/cli` will try to find the default target on your system via `rustup` if no `--target` specified. - -You can also define this value using the `RUST_TARGET` environment variable. - -This value will be passed to `Cargo build` command directly. eg: `napi build --target x86_64-unknown-linux-musl` - -#### `--cargo-flags` - -> default `undefined` - -Other flags you want pass to `Cargo build`. - -#### `--cargo-cwd` - -> default `undefined` - -This flag can be used to build binaries that are not in the current directory. The path that is passed to this flag should be relative to the current directory. - -### `napi artifacts` - -> Copy artifact files in Github actions. diff --git a/cli/ava.config.mjs b/cli/ava.config.mjs new file mode 100644 index 00000000..8d0514c3 --- /dev/null +++ b/cli/ava.config.mjs @@ -0,0 +1,10 @@ +export default { + extensions: { + ts: 'module', + }, + files: ['**/__tests__/**/*.spec.ts'], + nodeArguments: ['--loader=ts-node/esm/transpile-only'], + environmentVariables: { + TS_NODE_PROJECT: './tsconfig.json', + }, +} diff --git a/cli/cli.mjs b/cli/cli.mjs new file mode 100755 index 00000000..f46856e0 --- /dev/null +++ b/cli/cli.mjs @@ -0,0 +1,12 @@ +import { execSync } from 'child_process' +import { resolve } from 'path' +import { fileURLToPath } from 'url' + +execSync( + `node --loader ts-node/esm/transpile-only ${resolve(fileURLToPath(import.meta.url), '../src/cli.ts')} ${process.argv + .slice(2) + .join(' ')}`, + { + stdio: 'inherit', + }, +) diff --git a/cli/codegen/commands.ts b/cli/codegen/commands.ts new file mode 100644 index 00000000..463296c4 --- /dev/null +++ b/cli/codegen/commands.ts @@ -0,0 +1,505 @@ +export interface ArgSchema { + name: string + type: 'string' + description: string + required?: boolean +} + +export interface OptionSchema { + name: string + type: string + description: string + required?: boolean + default?: any + short?: string + long?: string +} + +export interface CommandSchema { + name: string + description: string + args: ArgSchema[] + options: OptionSchema[] +} + +export type CommandDefineSchema = CommandSchema[] + +const NEW_OPTIONS: CommandSchema = { + name: 'new', + description: 'Create a new project with pre-configured boilerplate', + args: [ + { + name: 'path', + type: 'string', + description: 'The path where the napi-rs project will be created.', + required: true, + }, + ], + options: [ + { + name: 'name', + type: 'string', + description: + 'The name of the project, default to the name of the directory if not provided', + short: 'n', + }, + { + name: 'minNodeApiVersion', + type: 'number', + description: 'The minimum Node-API version to support', + default: 4, + short: 'v', + long: 'min-node-api', + }, + // will support it later + // { + // name: 'packageManager', + // type: 'string', + // description: 'The package manager to use', + // default: "'yarn'", + // }, + { + name: 'license', + type: 'string', + description: 'License for open-sourced project', + short: 'l', + default: "'MIT'", + }, + { + name: 'targets', + type: 'string[]', + description: 'All targets the crate will be compiled for.', + short: 't', + default: '[]', + }, + { + name: 'enableDefaultTargets', + type: 'boolean', + description: 'Whether enable default targets', + default: true, + }, + { + name: 'enableAllTargets', + type: 'boolean', + description: 'Whether enable all targets', + default: false, + }, + { + name: 'enableTypeDef', + type: 'boolean', + description: + 'Whether enable the `type-def` feature for typescript definitions auto-generation', + default: true, + }, + { + name: 'enableGithubActions', + type: 'boolean', + description: 'Whether generate preconfigured GitHub Actions workflow', + default: true, + }, + { + name: 'dryRun', + type: 'boolean', + description: 'Whether to run the command in dry-run mode', + default: false, + }, + ], +} + +const BUILD_OPTIONS: CommandSchema = { + name: 'build', + description: 'Build the napi-rs project', + args: [], + options: [ + { + name: 'target', + type: 'string', + description: + 'Build for the target triple, bypassed to `cargo build --target`', + short: 't', + }, + { + name: 'cwd', + type: 'string', + description: + 'The working directory of where napi command will be executed in, all other paths options are relative to this path', + }, + { + name: 'manifestPath', + type: 'string', + description: 'Path to `Cargo.toml`', + }, + { + name: 'packageJsonPath', + type: 'string', + description: 'Path to `package.json`', + }, + { + name: 'targetDir', + type: 'string', + description: + 'Directory for all crate generated artifacts, see `cargo build --target-dir`', + }, + { + name: 'outputDir', + type: 'string', + description: + 'Path to where all the built files would be put. Default to the crate folder', + short: 'o', + }, + { + name: 'platform', + type: 'boolean', + description: + 'Add platform triple to the generated nodejs binding file, eg: `[name].linux-x64-gnu.node`', + }, + { + name: 'jsPackageName', + type: 'string', + description: + 'Package name in generated js binding file. Only works with `--platform` flag', + }, + { + name: 'jsBinding', + type: 'string', + description: + 'Path and filename of generated JS binding file. Only works with `--platform` flag. Relative to `--output_dir`.', + long: 'js', + }, + { + name: 'noJsBinding', + type: 'boolean', + description: + 'Whether to disable the generation JS binding file. Only works with `--platform` flag.', + long: 'no-js', + }, + { + name: 'dts', + type: 'string', + description: + 'Path and filename of generated type def file. Relative to `--output_dir`', + }, + { + name: 'dtsHeader', + type: 'string', + description: + 'Custom file header for generated type def file. Only works when `typedef` feature enabled.', + }, + { + name: 'noDtsHeader', + type: 'boolean', + description: + 'Whether to disable the default file header for generated type def file. Only works when `typedef` feature enabled.', + }, + { + name: 'strip', + type: 'boolean', + description: 'Whether strip the library to achieve the minimum file size', + short: 's', + }, + { + name: 'release', + type: 'boolean', + description: 'Build in release mode', + short: 'r', + }, + { + name: 'verbose', + type: 'boolean', + description: 'Verbosely log build command trace', + short: 'v', + }, + { + name: 'bin', + type: 'string', + description: 'Build only the specified binary', + }, + { + name: 'package', + type: 'string', + description: 'Build the specified library or the one at cwd', + short: 'p', + }, + { + name: 'crossCompile', + type: 'boolean', + description: + '[experimental] cross-compile for the specified target with `cargo-xwin` on windows and `cargo-zigbuild` on other platform', + short: 'x', + }, + { + name: 'watch', + type: 'boolean', + description: + 'watch the crate changes and build continiously with `cargo-watch` crates', + short: 'w', + }, + { + name: 'features', + type: 'string[]', + description: 'Space-separated list of features to activate', + short: 'F', + }, + { + name: 'allFeatures', + type: 'boolean', + description: 'Activate all available features', + }, + { + name: 'noDefaultFeatures', + type: 'boolean', + description: 'Do not activate the `default` feature', + }, + ], +} + +const ARTIFACTS_OPTIONS: CommandSchema = { + name: 'artifacts', + description: + 'Copy artifacts from Github Actions into npm packages and ready to publish', + args: [], + options: [ + { + name: 'cwd', + type: 'string', + description: + 'The working directory of where napi command will be executed in, all other paths options are relative to this path', + default: 'process.cwd()', + }, + { + name: 'packageJsonPath', + type: 'string', + description: 'Path to `package.json`', + default: "'package.json'", + }, + { + name: 'outputDir', + type: 'string', + description: + 'Path to the folder where all built `.node` files put, same as `--output-dir` of build command', + short: 'o', + default: "'./'", + }, + { + name: 'npmDir', + type: 'string', + description: 'Path to the folder where the npm packages put', + default: "'npm'", + }, + ], +} + +const CREATE_NPM_DIRS_OPTIONS: CommandSchema = { + name: 'createNpmDirs', + description: 'Create npm package dirs for different platforms', + args: [], + options: [ + { + name: 'cwd', + type: 'string', + description: + 'The working directory of where napi command will be executed in, all other paths options are relative to this path', + default: 'process.cwd()', + }, + { + name: 'packageJsonPath', + type: 'string', + description: 'Path to `package.json`', + default: "'package.json'", + }, + { + name: 'npmDir', + type: 'string', + description: 'Path to the folder where the npm packages put', + default: "'npm'", + }, + { + name: 'dryRun', + type: 'boolean', + description: 'Dry run without touching file system', + default: false, + }, + ], +} + +const RENAME_OPTIONS: CommandSchema = { + name: 'rename', + description: 'Rename the napi-rs project', + args: [], + options: [ + { + name: 'cwd', + type: 'string', + description: + 'The working directory of where napi command will be executed in, all other paths options are relative to this path', + default: 'process.cwd()', + }, + { + name: 'packageJsonPath', + type: 'string', + description: 'Path to `package.json`', + default: "'package.json'", + }, + { + name: 'npmDir', + type: 'string', + description: 'Path to the folder where the npm packages put', + default: "'npm'", + }, + { + name: 'name', + type: 'string', + description: 'The new name of the project', + short: 'n', + }, + { + name: 'binaryName', + type: 'string', + description: 'The new binary name *.node files', + short: 'b', + }, + { + name: 'packageName', + type: 'string', + description: 'The new package name of the project', + }, + { + name: 'manifestPath', + type: 'string', + description: 'Path to `Cargo.toml`', + default: "'Cargo.toml'", + }, + { + name: 'repository', + type: 'string', + description: 'The new repository of the project', + }, + { + name: 'description', + type: 'string', + description: 'The new description of the project', + }, + ], +} + +const UNIVERSALIZE_OPTIONS: CommandSchema = { + name: 'universalize', + description: 'Combile built binaries into one universal binary', + args: [], + options: [ + { + name: 'cwd', + type: 'string', + description: + 'The working directory of where napi command will be executed in, all other paths options are relative to this path', + default: 'process.cwd()', + }, + { + name: 'packageJsonPath', + type: 'string', + description: 'Path to `package.json`', + default: "'package.json'", + }, + { + name: 'outputDir', + type: 'string', + description: + 'Path to the folder where all built `.node` files put, same as `--output-dir` of build command', + short: 'o', + default: "'./'", + }, + ], +} + +const VERSION_OPTIONS: CommandSchema = { + name: 'version', + description: 'Update version in created npm packages', + args: [], + options: [ + { + name: 'cwd', + type: 'string', + description: + 'The working directory of where napi command will be executed in, all other paths options are relative to this path', + default: 'process.cwd()', + }, + { + name: 'packageJsonPath', + type: 'string', + description: 'Path to `package.json`', + default: "'package.json'", + }, + { + name: 'npmDir', + type: 'string', + description: 'Path to the folder where the npm packages put', + default: "'npm'", + }, + ], +} + +const PRE_PUBLISH_OPTIONS: CommandSchema = { + name: 'prePublish', + description: 'Update package.json and copy addons into per platform packages', + args: [], + options: [ + { + name: 'cwd', + type: 'string', + description: + 'The working directory of where napi command will be executed in, all other paths options are relative to this path', + default: 'process.cwd()', + }, + { + name: 'packageJsonPath', + type: 'string', + description: 'Path to `package.json`', + default: "'package.json'", + }, + { + name: 'npmDir', + type: 'string', + description: 'Path to the folder where the npm packages put', + default: "'npm'", + }, + { + name: 'tagStyle', + type: "'npm' | 'lerna'", + description: 'git tag style, `npm` or `lerna`', + default: "'lerna'", + }, + { + name: 'ghRelease', + type: 'boolean', + description: 'Whether create GitHub release', + default: true, + }, + { + name: 'ghReleaseName', + type: 'string', + description: 'GitHub release name', + }, + { + name: 'ghReleaseId', + type: 'string', + description: 'Existing GitHub release id', + }, + { + name: 'dryRun', + type: 'boolean', + description: 'Dry run without touching file system', + default: false, + }, + ], +} + +export const commandDefines: CommandDefineSchema = [ + NEW_OPTIONS, + BUILD_OPTIONS, + ARTIFACTS_OPTIONS, + CREATE_NPM_DIRS_OPTIONS, + RENAME_OPTIONS, + UNIVERSALIZE_OPTIONS, + VERSION_OPTIONS, + PRE_PUBLISH_OPTIONS, +] diff --git a/cli/codegen/index.ts b/cli/codegen/index.ts new file mode 100644 index 00000000..55ea0721 --- /dev/null +++ b/cli/codegen/index.ts @@ -0,0 +1,279 @@ +import { execSync } from 'child_process' +import fs from 'fs' +import path from 'path' +import { fileURLToPath } from 'url' + +import { kebabCase, startCase } from 'lodash-es' + +import { commandDefines, CommandSchema, OptionSchema } from './commands.js' + +const __filename = fileURLToPath(import.meta.url) +const defFolder = path.join(__filename, '../../src/def') +const docsTargetFolder = path.join(__filename, '../../docs') + +function PascalCase(str: string) { + return startCase(str).replace(/\s/g, '') +} + +/** + * convert command definition to command options interface + */ +function generateOptionsDef(command: CommandSchema) { + const optionsName = `${PascalCase(command.name)}Options` + + const optLines: string[] = [] + + optLines.push('/**') + optLines.push(` * ${command.description}`) + optLines.push(' */') + optLines.push(`export interface ${optionsName} {`) + command.args.forEach((arg) => { + optLines.push(' /**') + optLines.push(` * ${arg.description}`) + optLines.push(' */') + optLines.push(` ${arg.name}${arg.required ? '' : '?'}: ${arg.type}`) + }) + + command.options.forEach((opt) => { + optLines.push(' /**') + optLines.push(` * ${opt.description}`) + if (typeof opt.default !== 'undefined') { + optLines.push(' *') + optLines.push(` * @default ${opt.default}`) + } + optLines.push(' */') + optLines.push(` ${opt.name}${opt.required ? '' : '?'}: ${opt.type}`) + }) + + optLines.push('}\n') + + if (command.options.some((opt) => typeof opt.default !== 'undefined')) { + optLines.push( + `export function applyDefault${optionsName}(options: ${optionsName}) {`, + ) + optLines.push(` return {`) + command.options.forEach((opt) => { + if (typeof opt.default !== 'undefined') { + optLines.push(` ${opt.name}: ${opt.default},`) + } + }) + optLines.push(' ...options,') + optLines.push(' }') + optLines.push('}\n') + } + + return optLines.join('\n') +} + +function getOptionDescriptor(opt: OptionSchema) { + let desc = `--${opt.long ?? kebabCase(opt.name)}` + if (opt.short) { + desc += `,-${opt.short}` + } + + return desc +} + +function generateCommandDef(command: CommandSchema) { + const commandPath = kebabCase(command.name) + const avoidList = ['path', 'name'] + + const avoidName = (name: string) => { + return avoidList.includes(name) ? '$$' + name : name + } + + const prepare: string[] = [] + const cmdLines: string[] = [] + + cmdLines.push(` +export abstract class Base${PascalCase(command.name)}Command extends Command { + static paths = [['${commandPath}']] + + static usage = Command.Usage({ + description: '${command.description}', + })\n`) + + command.args.forEach((arg) => { + cmdLines.push( + ` ${avoidName(arg.name)} = Option.String({ required: ${ + arg.required ?? false + } })`, + ) + }) + + cmdLines.push('') + + command.options.forEach((opt) => { + const optName = avoidName(opt.name) + let optionType = '' + + switch (opt.type) { + case 'number': + optionType = 'String' + prepare.push("import * as typanion from 'typanion'") + break + case 'boolean': + optionType = 'Boolean' + break + case 'string[]': + optionType = 'Array' + break + case 'string': + default: + optionType = 'String' + } + + const optionDesc = getOptionDescriptor(opt) + + if (opt.required) { + cmdLines.push(` ${optName} = Option.${optionType}('${optionDesc}', {`) + cmdLines.push(' required: true,') + } else if (typeof opt.default !== 'undefined') { + const defaultValue = + typeof opt.default === 'number' + ? `'${opt.default.toString()}'` + : opt.default + cmdLines.push(` ${optName} = Option.${optionType}(`) + cmdLines.push(` '${optionDesc}',`) + cmdLines.push(` ${defaultValue},`) + cmdLines.push(` {`) + } else { + cmdLines.push( + ` ${optName}?: ${opt.type} = Option.${optionType}('${optionDesc}', {`, + ) + } + + if (opt.type === 'number') { + cmdLines.push(' validator: typanion.isNumber(),') + } + + cmdLines.push(` description: '${opt.description}'`) + cmdLines.push(' })\n') + }) + + cmdLines.push(` getOptions() {`) + cmdLines.push(` return {`) + command.args + .map(({ name }) => name) + .concat(command.options.map(({ name }) => name)) + .forEach((name) => { + cmdLines.push(` ${name}: this.${avoidName(name)},`) + }) + cmdLines.push(' }') + cmdLines.push(' }') + + cmdLines.push('}\n') + + return prepare.join('\n') + '\n' + cmdLines.join('\n') +} + +function generateDocs(command: CommandSchema, targetFolder: string): string { + const docsFileName = kebabCase(command.name) + const docsFile = path.join(targetFolder, `${docsFileName}.md`) + + const options: string[] = [] + + command.args.forEach((arg) => { + options.push( + [ + '', + arg.name, + `<${kebabCase(arg.name)}>`, + arg.required ? 'true' : 'false', + arg.type, + '', + arg.description, + '', + ].join('|'), + ) + }) + + command.options.forEach((opt) => { + options.push( + [ + '', + opt.name, + getOptionDescriptor(opt), + opt.type.replace(/\|/g, '\\|'), + opt.required ? 'true' : 'false', + opt.default ?? '', + opt.description, + '', + ].join('|'), + ) + }) + + const content = `# ${startCase(command.name)} + +> This file is generated by cli/codegen. Do not edit this file manually. + +${command.description} + +## Usage + +\`\`\`sh +# CLI +napi ${kebabCase(command.name)}${command.args.reduce( + (h, arg) => h + ` <${arg.name}>`, + '', + )} [--options] +\`\`\` + +\`\`\`typescript +// Programatically +import { NapiCli } from '@napi-rs/cli' + +new NapiCli().${command.name}({ + // options +}) +\`\`\` + +## Options + +| Options | CLI Options | type | required | default | description | +| ------- | ----------- | ---- | -------- | ------- | ----------- | +| | --help,-h | | | | get help | +${options.join('\n')} +` + + // make sure the target folder exists + fs.mkdirSync(targetFolder, { recursive: true }) + // write file + fs.writeFileSync(docsFile, content) + + return docsFile +} + +function generateDef(cmd: CommandSchema, folder: string): string { + const defFileName = kebabCase(cmd.name) + const defFilePath = path.join(folder, `${defFileName}.ts`) + + const def = `// This file is generated by codegen/index.ts +// Do not edit this file manually +import { Command, Option } from 'clipanion' +${generateCommandDef(cmd)} + +${generateOptionsDef(cmd)} +` + + // make sure the target folder exists + fs.mkdirSync(folder, { recursive: true }) + // write file + fs.writeFileSync(defFilePath, def) + + return defFilePath +} + +function codegen() { + const outputs: string[] = [] + commandDefines.forEach((command) => { + outputs.push(generateDef(command, defFolder)) + outputs.push(generateDocs(command, docsTargetFolder)) + }) + + outputs.forEach((output) => { + execSync(`yarn prettier -w ${output}`) + }) +} + +codegen() diff --git a/cli/docs/artifacts.md b/cli/docs/artifacts.md new file mode 100644 index 00000000..bc15c19c --- /dev/null +++ b/cli/docs/artifacts.md @@ -0,0 +1,31 @@ +# Artifacts + +> This file is generated by cli/codegen. Do not edit this file manually. + +Copy artifacts from Github Actions into npm packages and ready to publish + +## Usage + +```sh +# CLI +napi artifacts [--options] +``` + +```typescript +// Programatically +import { NapiCli } from '@napi-rs/cli' + +new NapiCli().artifacts({ + // options +}) +``` + +## Options + +| Options | CLI Options | type | required | default | description | +| --------------- | ------------------- | ------ | -------- | -------------- | ------------------------------------------------------------------------------------------------------------------ | +| | --help,-h | | | | get help | +| cwd | --cwd | string | false | process.cwd() | The working directory of where napi command will be executed in, all other paths options are relative to this path | +| packageJsonPath | --package-json-path | string | false | 'package.json' | Path to `package.json` | +| outputDir | --output-dir,-o | string | false | './' | Path to the folder where all built `.node` files put, same as `--output-dir` of build command | +| npmDir | --npm-dir | string | false | 'npm' | Path to the folder where the npm packages put | diff --git a/cli/docs/build.md b/cli/docs/build.md new file mode 100644 index 00000000..e3939b3a --- /dev/null +++ b/cli/docs/build.md @@ -0,0 +1,50 @@ +# Build + +> This file is generated by cli/codegen. Do not edit this file manually. + +Build the napi-rs project + +## Usage + +```sh +# CLI +napi build [--options] +``` + +```typescript +// Programatically +import { NapiCli } from '@napi-rs/cli' + +new NapiCli().build({ + // options +}) +``` + +## Options + +| Options | CLI Options | type | required | default | description | +| ----------------- | --------------------- | -------- | -------- | ------- | ------------------------------------------------------------------------------------------------------------------------- | +| | --help,-h | | | | get help | +| target | --target,-t | string | false | | Build for the target triple, bypassed to `cargo build --target` | +| cwd | --cwd | string | false | | The working directory of where napi command will be executed in, all other paths options are relative to this path | +| manifestPath | --manifest-path | string | false | | Path to `Cargo.toml` | +| packageJsonPath | --package-json-path | string | false | | Path to `package.json` | +| targetDir | --target-dir | string | false | | Directory for all crate generated artifacts, see `cargo build --target-dir` | +| outputDir | --output-dir,-o | string | false | | Path to where all the built files would be put. Default to the crate folder | +| platform | --platform | boolean | false | | Add platform triple to the generated nodejs binding file, eg: `[name].linux-x64-gnu.node` | +| jsPackageName | --js-package-name | string | false | | Package name in generated js binding file. Only works with `--platform` flag | +| jsBinding | --js | string | false | | Path and filename of generated JS binding file. Only works with `--platform` flag. Relative to `--output_dir`. | +| noJsBinding | --no-js | boolean | false | | Whether to disable the generation JS binding file. Only works with `--platform` flag. | +| dts | --dts | string | false | | Path and filename of generated type def file. Relative to `--output_dir` | +| dtsHeader | --dts-header | string | false | | Custom file header for generated type def file. Only works when `typedef` feature enabled. | +| noDtsHeader | --no-dts-header | boolean | false | | Whether to disable the default file header for generated type def file. Only works when `typedef` feature enabled. | +| strip | --strip,-s | boolean | false | | Whether strip the library to achieve the minimum file size | +| release | --release,-r | boolean | false | | Build in release mode | +| verbose | --verbose,-v | boolean | false | | Verbosely log build command trace | +| bin | --bin | string | false | | Build only the specified binary | +| package | --package,-p | string | false | | Build the specified library or the one at cwd | +| crossCompile | --cross-compile,-x | boolean | false | | [experimental] cross-compile for the specified target with `cargo-xwin` on windows and `cargo-zigbuild` on other platform | +| watch | --watch,-w | boolean | false | | watch the crate changes and build continiously with `cargo-watch` crates | +| features | --features,-F | string[] | false | | Space-separated list of features to activate | +| allFeatures | --all-features | boolean | false | | Activate all available features | +| noDefaultFeatures | --no-default-features | boolean | false | | Do not activate the `default` feature | diff --git a/cli/docs/create-npm-dirs.md b/cli/docs/create-npm-dirs.md new file mode 100644 index 00000000..6279bad8 --- /dev/null +++ b/cli/docs/create-npm-dirs.md @@ -0,0 +1,31 @@ +# Create Npm Dirs + +> This file is generated by cli/codegen. Do not edit this file manually. + +Create npm package dirs for different platforms + +## Usage + +```sh +# CLI +napi create-npm-dirs [--options] +``` + +```typescript +// Programatically +import { NapiCli } from '@napi-rs/cli' + +new NapiCli().createNpmDirs({ + // options +}) +``` + +## Options + +| Options | CLI Options | type | required | default | description | +| --------------- | ------------------- | ------- | -------- | -------------- | ------------------------------------------------------------------------------------------------------------------ | +| | --help,-h | | | | get help | +| cwd | --cwd | string | false | process.cwd() | The working directory of where napi command will be executed in, all other paths options are relative to this path | +| packageJsonPath | --package-json-path | string | false | 'package.json' | Path to `package.json` | +| npmDir | --npm-dir | string | false | 'npm' | Path to the folder where the npm packages put | +| dryRun | --dry-run | boolean | false | false | Dry run without touching file system | diff --git a/cli/docs/new.md b/cli/docs/new.md new file mode 100644 index 00000000..ad17bfdb --- /dev/null +++ b/cli/docs/new.md @@ -0,0 +1,37 @@ +# New + +> This file is generated by cli/codegen. Do not edit this file manually. + +Create a new project with pre-configured boilerplate + +## Usage + +```sh +# CLI +napi new [--options] +``` + +```typescript +// Programatically +import { NapiCli } from '@napi-rs/cli' + +new NapiCli().new({ + // options +}) +``` + +## Options + +| Options | CLI Options | type | required | default | description | +| -------------------- | ------------------------ | -------- | -------- | ------- | -------------------------------------------------------------------------------- | +| | --help,-h | | | | get help | +| path | | true | string | | The path where the napi-rs project will be created. | +| name | --name,-n | string | false | | The name of the project, default to the name of the directory if not provided | +| minNodeApiVersion | --min-node-api,-v | number | false | 4 | The minimum Node-API version to support | +| license | --license,-l | string | false | 'MIT' | License for open-sourced project | +| targets | --targets,-t | string[] | false | [] | All targets the crate will be compiled for. | +| enableDefaultTargets | --enable-default-targets | boolean | false | true | Whether enable default targets | +| enableAllTargets | --enable-all-targets | boolean | false | false | Whether enable all targets | +| enableTypeDef | --enable-type-def | boolean | false | true | Whether enable the `type-def` feature for typescript definitions auto-generation | +| enableGithubActions | --enable-github-actions | boolean | false | true | Whether generate preconfigured GitHub Actions workflow | +| dryRun | --dry-run | boolean | false | false | Whether to run the command in dry-run mode | diff --git a/cli/docs/pre-publish.md b/cli/docs/pre-publish.md new file mode 100644 index 00000000..3b983561 --- /dev/null +++ b/cli/docs/pre-publish.md @@ -0,0 +1,35 @@ +# Pre Publish + +> This file is generated by cli/codegen. Do not edit this file manually. + +Update package.json and copy addons into per platform packages + +## Usage + +```sh +# CLI +napi pre-publish [--options] +``` + +```typescript +// Programatically +import { NapiCli } from '@napi-rs/cli' + +new NapiCli().prePublish({ + // options +}) +``` + +## Options + +| Options | CLI Options | type | required | default | description | +| --------------- | ------------------- | ---------------- | -------- | -------------- | ------------------------------------------------------------------------------------------------------------------ | +| | --help,-h | | | | get help | +| cwd | --cwd | string | false | process.cwd() | The working directory of where napi command will be executed in, all other paths options are relative to this path | +| packageJsonPath | --package-json-path | string | false | 'package.json' | Path to `package.json` | +| npmDir | --npm-dir | string | false | 'npm' | Path to the folder where the npm packages put | +| tagStyle | --tag-style | 'npm' \| 'lerna' | false | 'lerna' | git tag style, `npm` or `lerna` | +| ghRelease | --gh-release | boolean | false | true | Whether create GitHub release | +| ghReleaseName | --gh-release-name | string | false | | GitHub release name | +| ghReleaseId | --gh-release-id | string | false | | Existing GitHub release id | +| dryRun | --dry-run | boolean | false | false | Dry run without touching file system | diff --git a/cli/docs/rename.md b/cli/docs/rename.md new file mode 100644 index 00000000..0ade2270 --- /dev/null +++ b/cli/docs/rename.md @@ -0,0 +1,36 @@ +# Rename + +> This file is generated by cli/codegen. Do not edit this file manually. + +Rename the napi-rs project + +## Usage + +```sh +# CLI +napi rename [--options] +``` + +```typescript +// Programatically +import { NapiCli } from '@napi-rs/cli' + +new NapiCli().rename({ + // options +}) +``` + +## Options + +| Options | CLI Options | type | required | default | description | +| --------------- | ------------------- | ------ | -------- | -------------- | ------------------------------------------------------------------------------------------------------------------ | +| | --help,-h | | | | get help | +| cwd | --cwd | string | false | process.cwd() | The working directory of where napi command will be executed in, all other paths options are relative to this path | +| packageJsonPath | --package-json-path | string | false | 'package.json' | Path to `package.json` | +| npmDir | --npm-dir | string | false | 'npm' | Path to the folder where the npm packages put | +| name | --name,-n | string | false | | The new name of the project | +| binaryName | --binary-name,-b | string | false | | The new binary name \*.node files | +| packageName | --package-name | string | false | | The new package name of the project | +| manifestPath | --manifest-path | string | false | 'Cargo.toml' | Path to `Cargo.toml` | +| repository | --repository | string | false | | The new repository of the project | +| description | --description | string | false | | The new description of the project | diff --git a/cli/docs/universalize.md b/cli/docs/universalize.md new file mode 100644 index 00000000..a5916ea1 --- /dev/null +++ b/cli/docs/universalize.md @@ -0,0 +1,30 @@ +# Universalize + +> This file is generated by cli/codegen. Do not edit this file manually. + +Combile built binaries into one universal binary + +## Usage + +```sh +# CLI +napi universalize [--options] +``` + +```typescript +// Programatically +import { NapiCli } from '@napi-rs/cli' + +new NapiCli().universalize({ + // options +}) +``` + +## Options + +| Options | CLI Options | type | required | default | description | +| --------------- | ------------------- | ------ | -------- | -------------- | ------------------------------------------------------------------------------------------------------------------ | +| | --help,-h | | | | get help | +| cwd | --cwd | string | false | process.cwd() | The working directory of where napi command will be executed in, all other paths options are relative to this path | +| packageJsonPath | --package-json-path | string | false | 'package.json' | Path to `package.json` | +| outputDir | --output-dir,-o | string | false | './' | Path to the folder where all built `.node` files put, same as `--output-dir` of build command | diff --git a/cli/docs/version.md b/cli/docs/version.md new file mode 100644 index 00000000..8cc02c80 --- /dev/null +++ b/cli/docs/version.md @@ -0,0 +1,30 @@ +# Version + +> This file is generated by cli/codegen. Do not edit this file manually. + +Update version in created npm packages + +## Usage + +```sh +# CLI +napi version [--options] +``` + +```typescript +// Programatically +import { NapiCli } from '@napi-rs/cli' + +new NapiCli().version({ + // options +}) +``` + +## Options + +| Options | CLI Options | type | required | default | description | +| --------------- | ------------------- | ------ | -------- | -------------- | ------------------------------------------------------------------------------------------------------------------ | +| | --help,-h | | | | get help | +| cwd | --cwd | string | false | process.cwd() | The working directory of where napi command will be executed in, all other paths options are relative to this path | +| packageJsonPath | --package-json-path | string | false | 'package.json' | Path to `package.json` | +| npmDir | --npm-dir | string | false | 'npm' | Path to the folder where the npm packages put | diff --git a/cli/esbuild.mjs b/cli/esbuild.mjs new file mode 100644 index 00000000..14014aa0 --- /dev/null +++ b/cli/esbuild.mjs @@ -0,0 +1,11 @@ +import * as esbuild from 'esbuild' + +await esbuild.build({ + entryPoints: ['./dist/index.js'], + outfile: './dist/index.cjs', + bundle: true, + platform: 'node', + define: { + 'import.meta.url': '__filename', + }, +}) diff --git a/cli/package.json b/cli/package.json index 927d5261..1dd88201 100644 --- a/cli/package.json +++ b/cli/package.json @@ -2,30 +2,57 @@ "name": "@napi-rs/cli", "version": "2.15.2", "description": "Cli tools for napi-rs", + "author": "LongYinan ", + "homepage": "https://github.com/napi-rs/napi-rs", + "license": "MIT", + "type": "module", + "engines": { + "node": ">= 16" + }, + "bin": { + "napi": "./dist/cli.js", + "napi-raw": "./cli.mjs" + }, + "main": "./dist/index.cjs", + "module": "./dist/index.js", + "exports": { + ".": { + "import": { + "default": "./dist/index.js", + "types": "./dist/index.d.ts" + }, + "require": { + "default": "./dist/index.cjs", + "types": "./dist/index.d.ts" + } + }, + "./package.json": { + "import": "./package.json", + "require": "./package.json" + } + }, + "files": [ + "dist", + "src" + ], "keywords": [ "cli", "rust", "napi", "n-api", + "node-api", + "node-addon", "neon" ], - "author": "LongYinan ", - "homepage": "https://github.com/napi-rs/napi-rs", - "license": "MIT", - "bin": { - "napi": "./scripts/index.js" - }, - "files": [ - "scripts" - ], - "engines": { - "node": ">= 10" - }, "maintainers": [ { "name": "LongYinan", "email": "lynweklm@gmail.com", "homepage": "https://github.com/Brooooooklyn" + }, + { + "name": "forehalo", + "homepage": "https://github.com/forehalo" } ], "repository": { @@ -39,26 +66,34 @@ "bugs": { "url": "https://github.com/napi-rs/napi-rs/issues" }, + "dependencies": { + "@octokit/rest": "^19.0.7", + "clipanion": "^3.2.0", + "colorette": "^2.0.19", + "debug": "^4.3.4", + "inquirer": "^9.1.5", + "js-yaml": "^4.1.0", + "lodash-es": "^4.17.21", + "typanion": "^3.12.1" + }, "devDependencies": { - "@octokit/rest": "^19.0.5", "@types/inquirer": "^9.0.3", "@types/js-yaml": "^4.0.5", "@types/lodash-es": "^4.17.6", - "clipanion": "^3.1.0", - "colorette": "^2.0.19", - "core-js": "^3.27.1", - "debug": "^4.3.4", - "env-paths": "^3.0.0", - "fdir": "^5.3.0", - "inquirer": "^9.1.4", - "js-yaml": "^4.1.0", - "lodash-es": "4.17.21", - "toml": "^3.0.0", - "tslib": "^2.4.1", - "typanion": "^3.12.1" + "ava": "^5.2.0", + "esbuild": "^0.17.14", + "prettier": "^2.8.7", + "ts-node": "^10.9.1", + "typescript": "^4.9.4" }, "funding": { "type": "github", "url": "https://github.com/sponsors/Brooooooklyn" + }, + "scripts": { + "codegen": "node --loader ts-node/esm/transpile-only ./codegen/index.ts", + "build": "tsc && yarn build:cjs", + "build:cjs": "node ./esbuild.mjs", + "test": "ava" } } diff --git a/cli/src/__test__/parse-triple.spec.ts b/cli/src/__test__/parse-triple.spec.ts deleted file mode 100644 index 7d6bca4f..00000000 --- a/cli/src/__test__/parse-triple.spec.ts +++ /dev/null @@ -1,132 +0,0 @@ -import test from 'ava' - -import { parseTriple } from '../parse-triple' - -const triples = [ - { - name: 'x86_64-unknown-linux-musl', - expected: { - abi: 'musl', - arch: 'x64', - platform: 'linux', - platformArchABI: 'linux-x64-musl', - raw: 'x86_64-unknown-linux-musl', - } as const, - }, - { - name: 'x86_64-unknown-linux-gnu', - expected: { - abi: 'gnu', - arch: 'x64', - platform: 'linux', - platformArchABI: 'linux-x64-gnu', - raw: 'x86_64-unknown-linux-gnu', - } as const, - }, - { - name: 'x86_64-pc-windows-msvc', - expected: { - abi: 'msvc', - arch: 'x64', - platform: 'win32', - platformArchABI: 'win32-x64-msvc', - raw: 'x86_64-pc-windows-msvc', - } as const, - }, - { - name: 'x86_64-apple-darwin', - expected: { - abi: null, - arch: 'x64', - platform: 'darwin', - platformArchABI: 'darwin-x64', - raw: 'x86_64-apple-darwin', - } as const, - }, - { - name: 'i686-pc-windows-msvc', - expected: { - abi: 'msvc', - arch: 'ia32', - platform: 'win32', - platformArchABI: 'win32-ia32-msvc', - raw: 'i686-pc-windows-msvc', - } as const, - }, - { - name: 'x86_64-unknown-freebsd', - expected: { - abi: null, - arch: 'x64', - platform: 'freebsd', - platformArchABI: 'freebsd-x64', - raw: 'x86_64-unknown-freebsd', - } as const, - }, - { - name: 'aarch64-unknown-linux-gnu', - expected: { - abi: 'gnu', - arch: 'arm64', - platform: 'linux', - platformArchABI: 'linux-arm64-gnu', - raw: 'aarch64-unknown-linux-gnu', - } as const, - }, - { - name: 'aarch64-pc-windows-msvc', - expected: { - abi: 'msvc', - arch: 'arm64', - platform: 'win32', - platformArchABI: 'win32-arm64-msvc', - raw: 'aarch64-pc-windows-msvc', - } as const, - }, - { - name: 'armv7-unknown-linux-gnueabihf', - expected: { - abi: 'gnueabihf', - arch: 'arm', - platform: 'linux', - platformArchABI: 'linux-arm-gnueabihf', - raw: 'armv7-unknown-linux-gnueabihf', - } as const, - }, - { - name: 'aarch64-linux-android', - expected: { - abi: null, - arch: 'arm64', - platform: 'android', - platformArchABI: 'android-arm64', - raw: 'aarch64-linux-android', - }, - } as const, - { - name: 'armv7-linux-androideabi', - expected: { - abi: 'eabi', - arch: 'arm', - platform: 'android', - platformArchABI: 'android-arm-eabi', - raw: 'armv7-linux-androideabi', - }, - } as const, - { - name: 'universal-apple-darwin', - expected: { - abi: null, - arch: 'universal', - platform: 'darwin', - platformArchABI: 'darwin-universal', - raw: 'universal-apple-darwin', - }, - } as const, -] - -for (const triple of triples) { - test(`should parse ${triple.name}`, (t) => { - t.deepEqual(parseTriple(triple.name), triple.expected) - }) -} diff --git a/cli/src/api/artifacts.ts b/cli/src/api/artifacts.ts new file mode 100644 index 00000000..a314548e --- /dev/null +++ b/cli/src/api/artifacts.ts @@ -0,0 +1,93 @@ +import { join, parse, resolve } from 'path' + +import * as colors from 'colorette' + +import { + applyDefaultArtifactsOptions, + ArtifactsOptions, +} from '../def/artifacts.js' +import { + readNapiConfig, + debugFactory, + readFileAsync, + writeFileAsync, + UniArchsByPlatform, + readdirAsync, +} from '../utils/index.js' + +const debug = debugFactory('artifacts') + +export async function collectArtifacts(userOptions: ArtifactsOptions) { + const options = applyDefaultArtifactsOptions(userOptions) + + const packageJsonPath = resolve(options.cwd, options.packageJsonPath) + const { targets, binaryName } = await readNapiConfig(packageJsonPath) + + const distDirs = targets.map((platform) => + resolve(options.cwd, options.npmDir, platform.platformArchABI), + ) + + const universalSourceBins = new Set( + targets + .filter((platform) => platform.arch === 'universal') + .flatMap((p) => + UniArchsByPlatform[p.platform]?.map((a) => `${p.platform}-${a}`), + ) + .filter(Boolean) as string[], + ) + + await collectNodeBinaries(resolve(options.cwd, options.outputDir)).then( + (output) => + Promise.all( + output.map(async (filePath) => { + debug.info(`Read [${colors.yellowBright(filePath)}]`) + const sourceContent = await readFileAsync(filePath) + const parsedName = parse(filePath) + const [_binaryName, platformArchABI] = parsedName.name.split('.') + if (_binaryName !== binaryName) { + debug.warn( + `[${_binaryName}] is not matched with [${binaryName}], skip`, + ) + return + } + const dir = distDirs.find((dir) => dir.includes(platformArchABI)) + if (!dir && universalSourceBins.has(platformArchABI)) { + debug.warn( + `[${platformArchABI}] has no dist dir but it is source bin for universal arch, skip`, + ) + return + } + if (!dir) { + throw new Error(`No dist dir found for ${filePath}`) + } + + const distFilePath = join(dir, parsedName.base) + debug.info( + `Write file content to [${colors.yellowBright(distFilePath)}]`, + ) + await writeFileAsync(distFilePath, sourceContent) + const distFilePathLocal = join( + parse(packageJsonPath).dir, + parsedName.base, + ) + debug.info( + `Write file content to [${colors.yellowBright(distFilePathLocal)}]`, + ) + await writeFileAsync(distFilePathLocal, sourceContent) + }), + ), + ) +} + +async function collectNodeBinaries(root: string) { + const files = await readdirAsync(root, { withFileTypes: true }) + const nodeBinaries = files + .filter((file) => file.isFile() && file.name.endsWith('.node')) + .map((file) => join(root, file.name)) + + const dirs = files.filter((file) => file.isDirectory()) + for (const dir of dirs) { + nodeBinaries.push(...(await collectNodeBinaries(join(root, dir.name)))) + } + return nodeBinaries +} diff --git a/cli/src/api/build.ts b/cli/src/api/build.ts new file mode 100644 index 00000000..f149cbbf --- /dev/null +++ b/cli/src/api/build.ts @@ -0,0 +1,549 @@ +import { spawn } from 'child_process' +import { createHash } from 'crypto' +import { tmpdir } from 'os' +import { parse, join, resolve } from 'path' + +import * as colors from 'colorette' + +import { BuildOptions as RawBuildOptions } from '../def/build.js' +import { + CLI_VERSION, + copyFileAsync, + Crate, + debugFactory, + DEFAULT_TYPE_DEF_HEADER, + fileExists, + getSystemDefaultTarget, + getTargetLinker, + mkdirAsync, + NapiConfig, + parseMetadata, + parseTriple, + processTypeDef, + readNapiConfig, + Target, + targetToEnvVar, + tryInstallCargoBinary, + unlinkAsync, + writeFileAsync, +} from '../utils/index.js' + +import { createJsBinding } from './templates/index.js' + +const debug = debugFactory('build') + +type OutputKind = 'js' | 'dts' | 'node' | 'exe' +type Output = { + kind: OutputKind + path: string +} + +type BuildOptions = RawBuildOptions & { + cargoOptions?: string[] +} + +export async function buildProject(options: BuildOptions) { + debug('napi build command receive options: %O', options) + + const cwd = options.cwd ?? process.cwd() + + const resolvePath = (...paths: string[]) => resolve(cwd, ...paths) + + const manifestPath = resolvePath(options.manifestPath ?? 'Cargo.toml') + const metadata = parseMetadata(manifestPath) + + const pkg = metadata.packages.find((p) => { + // package with given name + if (options.package) { + return p.name === options.package + } else { + return p.manifest_path === manifestPath + } + }) + + if (!pkg) { + throw new Error( + 'Unable to find crate to build. It seems you are trying to build a crate in a workspace, try using `--package` option to specify the package to build.', + ) + } + + const crateDir = parse(pkg.manifest_path).dir + + const builder = new Builder( + options, + pkg, + cwd, + options.target + ? parseTriple(options.target) + : process.env.CARGO_BUILD_TARGET + ? parseTriple(process.env.CARGO_BUILD_TARGET) + : getSystemDefaultTarget(), + crateDir, + resolvePath(options.outputDir ?? crateDir), + options.targetDir ?? + process.env.CARGO_BUILD_TARGET_DIR ?? + metadata.target_directory, + await readNapiConfig( + resolvePath(options.packageJsonPath ?? 'package.json'), + ), + ) + + return builder.build() +} + +class Builder { + private readonly args: string[] = [] + private readonly envs: Record = {} + private readonly outputs: Output[] = [] + + constructor( + private readonly options: BuildOptions, + private readonly crate: Crate, + private readonly cwd: string, + private readonly target: Target, + private readonly crateDir: string, + private readonly outputDir: string, + private readonly targetDir: string, + private readonly config: NapiConfig, + ) {} + + get cdyLibName() { + return this.crate.targets.find((t) => t.crate_types.includes('cdylib')) + ?.name + } + + get binName() { + return ( + this.options.bin ?? + // only available if not cdylib or bin name specified + (this.cdyLibName + ? null + : this.crate.targets.find((t) => t.crate_types.includes('bin'))?.name) + ) + } + + build() { + if (!this.cdyLibName) { + const warning = + 'Missing `crate-type = ["cdylib"]` in [lib] config. The build result will not be available as node addon.' + + if (this.binName) { + debug.warn(warning) + } else { + throw new Error(warning) + } + } + + return this.pickBinary() + .setPackage() + .setFeatures() + .setTarget() + .setEnvs() + .setBypassArgs() + .exec() + } + + private exec() { + debug(`Start building crate: ${this.crate.name}`) + debug(' %i', `cargo ${this.args.join(' ')}`) + + const controller = new AbortController() + + const buildTask = new Promise((resolve, reject) => { + const buildProcess = spawn('cargo', this.args, { + env: { + ...process.env, + ...this.envs, + }, + stdio: 'inherit', + cwd: this.cwd, + signal: controller.signal, + }) + + buildProcess.once('exit', (code) => { + if (code === 0) { + debug('%i', `Build crate ${this.crate.name} successfully!`) + resolve() + } else { + reject(new Error(`Build failed with exit code ${code}`)) + } + }) + + buildProcess.once('error', (e) => { + reject( + new Error(`Build failed with error: ${e.message}`, { + cause: e, + }), + ) + }) + }) + + return { + task: buildTask.then(() => this.postBuild()), + abort: () => controller.abort(), + } + } + + private pickBinary() { + let set = false + if (this.options.watch) { + if (process.env.CI) { + debug.warn('Watch mode is not supported in CI environment') + } else { + debug('Use %i', 'cargo-watch') + tryInstallCargoBinary('cargo-watch', 'watch') + // yarn napi watch --target x86_64-unknown-linux-gnu [--cross-compile] + // ===> + // cargo watch [...] -- build --target x86_64-unknown-linux-gnu + // cargo watch [...] -- zigbuild --target x86_64-unknown-linux-gnu + this.args.push( + 'watch', + '--why', + '-i', + '*.{js,ts,node}', + '-w', + this.crateDir, + '--', + 'cargo', + ) + set = true + } + } + + if (this.options.crossCompile) { + if (this.target.platform === 'win32') { + if (process.platform === 'win32') { + debug.warn( + 'You are trying to cross compile to win32 platform on win32 platform which is unnecessary.', + ) + } else { + // use cargo-xwin to cross compile to win32 platform + debug('Use %i', 'cargo-xwin') + tryInstallCargoBinary('cargo-xwin', 'xwin') + this.args.push('xwin', 'build') + if (this.target.arch === 'ia32') { + this.envs.XWIN_ARCH = 'x86' + } + set = true + } + } else { + if ( + this.target.platform === 'linux' && + process.platform === 'linux' && + this.target.arch === process.arch && + (function (abi: string | null) { + const glibcVersionRuntime = + // @ts-expect-error + process.report?.getReport()?.header?.glibcVersionRuntime + const libc = glibcVersionRuntime ? 'gnu' : 'musl' + return abi === libc + })(this.target.abi) + ) { + debug.warn( + 'You are trying to cross compile to linux target on linux platform which is unnecessary.', + ) + } else if ( + this.target.platform === 'darwin' && + process.platform === 'darwin' + ) { + debug.warn( + 'You are trying to cross compile to darwin target on darwin platform which is unnecessary.', + ) + } else { + // use cargo-zigbuild to cross compile to other platforms + debug('Use %i', 'cargo-zigbuild') + tryInstallCargoBinary('cargo-zigbuild', 'zigbuild') + this.args.push('zigbuild') + set = true + } + } + } + + if (!set) { + this.args.push('build') + } + return this + } + + private setPackage() { + const args = [] + + if (this.options.package) { + args.push('--package', this.options.package) + } + + if (this.binName) { + args.push('--bin', this.binName) + } + + if (args.length) { + debug('Set package flags: ') + debug(' %O', args) + this.args.push(...args) + } + + return this + } + + private setTarget() { + debug('Set compiling target to: ') + debug(' %i', this.target.triple) + + this.args.push('--target', this.target.triple) + + return this + } + + private setEnvs() { + // type definition intermediate file + this.envs.TYPE_DEF_TMP_PATH = this.getIntermediateTypeFile() + this.envs.CARGO_CFG_NAPI_RS_CLI_VERSION = CLI_VERSION + + // RUSTFLAGS + let rustflags = + process.env.RUSTFLAGS ?? process.env.CARGO_BUILD_RUSTFLAGS ?? '' + + if ( + this.target.abi?.includes('musl') && + !rustflags.includes('target-feature=-crt-static') + ) { + rustflags += ' -C target-feature=-crt-static' + } + + if (this.options.strip && !rustflags.includes('link-arg=-s')) { + rustflags += ' -C link-arg=-s' + } + + if (rustflags.length) { + this.envs.RUSTFLAGS = rustflags + } + // END RUSTFLAGS + + // LINKER + const linker = getTargetLinker(this.target.triple) + if ( + linker && + !process.env.RUSTC_LINKER && + !process.env[`CARGET_TARGET_${targetToEnvVar(this.target.triple)}_LINKER`] + ) { + this.envs.RUSTC_LINKER = linker + } + + if (this.target.platform === 'android') { + const { ANDROID_NDK_LATEST_HOME } = process.env + if (!ANDROID_NDK_LATEST_HOME) { + debug.warn( + `${colors.red( + 'ANDROID_NDK_LATEST_HOME', + )} environment variable is missing`, + ) + } + + const targetArch = this.target.arch === 'arm' ? 'armv7a' : 'aarch64' + const targetPlatform = + this.target.arch === 'arm' ? 'androideabi24' : 'android24' + Object.assign(this.envs, { + CARGO_TARGET_AARCH64_LINUX_ANDROID_LINKER: `${ANDROID_NDK_LATEST_HOME}/toolchains/llvm/prebuilt/linux-x86_64/bin/${targetArch}-linux-android24-clang`, + CARGO_TARGET_ARMV7_LINUX_ANDROIDEABI_LINKER: `${ANDROID_NDK_LATEST_HOME}/toolchains/llvm/prebuilt/linux-x86_64/bin/${targetArch}-linux-androideabi24-clang`, + CC: `${ANDROID_NDK_LATEST_HOME}/toolchains/llvm/prebuilt/linux-x86_64/bin/${targetArch}-linux-${targetPlatform}-clang`, + CXX: `${ANDROID_NDK_LATEST_HOME}/toolchains/llvm/prebuilt/linux-x86_64/bin/${targetArch}-linux-${targetPlatform}-clang++`, + AR: `${ANDROID_NDK_LATEST_HOME}/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-ar`, + ANDROID_NDK: ANDROID_NDK_LATEST_HOME, + PATH: `${ANDROID_NDK_LATEST_HOME}/toolchains/llvm/prebuilt/linux-x86_64/bin:${process.env.PATH}`, + }) + } + // END LINKER + + debug('Set envs: ') + Object.entries(this.envs).forEach(([k, v]) => { + debug(' %i', `${k}=${v}`) + }) + + return this + } + + private setFeatures() { + const args = [] + if (this.options.allFeatures) { + args.push('--all-features') + } else if (this.options.noDefaultFeatures) { + args.push('--no-default-features') + } else if (this.options.features) { + args.push('--features', ...this.options.features) + } + + debug('Set features flags: ') + debug(' %O', args) + this.args.push(...args) + + return this + } + + private setBypassArgs() { + if (this.options.release) { + this.args.push('--release') + } + + if (this.options.verbose) { + this.args.push('--verbose') + } + + if (this.options.targetDir) { + this.args.push('--target-dir', this.options.targetDir) + } + + if (this.options.cargoOptions?.length) { + this.args.push(...this.options.cargoOptions) + } + + return this + } + + private getIntermediateTypeFile() { + return join( + tmpdir(), + `${this.crate.name}-${createHash('sha256') + .update(this.crate.manifest_path) + .update(CLI_VERSION) + .digest('hex') + .substring(0, 8)}.napi_type_def.tmp`, + ) + } + + private async postBuild() { + try { + debug(`Try to create output directory:`) + debug(' %i', this.outputDir) + await mkdirAsync(this.outputDir, { recursive: true }) + debug(`Output directory created`) + } catch (e) { + throw new Error(`Failed to create output directory ${this.outputDir}`, { + cause: e, + }) + } + + await this.copyArtifact() + + // only for cdylib + if (this.cdyLibName) { + await this.generateTypeDef() + await this.writeJsBinding() + } + + return this.outputs + } + + private async copyArtifact() { + const [srcName, destName] = this.getArtifactNames() + if (!srcName || !destName) { + return + } + + const src = join( + this.targetDir, + this.target.triple, + this.options.release ? 'release' : 'debug', + srcName, + ) + const dest = join(this.outputDir, destName) + + try { + if (await fileExists(dest)) { + debug('Old artifact found, remove it first') + await unlinkAsync(dest) + } + debug('Copy artifact to:') + debug(' %i', dest) + await copyFileAsync(src, dest) + this.outputs.push({ + kind: dest.endsWith('.node') ? 'node' : 'exe', + path: dest, + }) + } catch (e) { + throw new Error('Failed to copy artifact', { + cause: e, + }) + } + } + + private getArtifactNames() { + if (this.cdyLibName) { + const cdyLib = this.cdyLibName.replace(/-/g, '_') + + const srcName = + this.target.platform === 'darwin' + ? `lib${cdyLib}.dylib` + : this.target.platform === 'win32' + ? `${cdyLib}.dll` + : `lib${cdyLib}.so` + + let destName = this.config.binaryName + // add platform suffix to binary name + // index[.linux-x64-gnu].node + // ^^^^^^^^^^^^^^ + if (this.options.platform) { + destName += `.${this.target.platformArchABI}` + } + destName += '.node' + + return [srcName, destName] + } else if (this.binName) { + const srcName = + this.target.platform === 'win32' ? `${this.binName}.exe` : this.binName + + return [srcName, srcName] + } + + return [] + } + + private async generateTypeDef() { + if (!(await fileExists(this.envs.TYPE_DEF_TMP_PATH))) { + return + } + + const dest = join(this.outputDir, this.options.dts ?? 'index.d.ts') + + const dts = await processTypeDef( + this.envs.TYPE_DEF_TMP_PATH, + !this.options.noDtsHeader + ? this.options.dtsHeader ?? DEFAULT_TYPE_DEF_HEADER + : '', + ) + + try { + debug('Writing type def to:') + debug(' %i', dest) + await writeFileAsync(dest, dts, 'utf-8') + this.outputs.push({ + kind: 'dts', + path: dest, + }) + } catch (e) { + debug.error('Failed to write type def file') + debug.error(e as Error) + } + } + + private async writeJsBinding() { + if (!this.options.platform || this.options.noJsBinding) { + return + } + + const dest = join(this.outputDir, this.options.jsBinding ?? 'index.js') + + const js = createJsBinding(this.config.binaryName, this.config.packageName) + + try { + debug('Writing js binding to:') + debug(' %i', dest) + await writeFileAsync(dest, js, 'utf-8') + this.outputs.push({ + kind: 'js', + path: dest, + }) + } catch (e) { + throw new Error('Failed to write js binding file', { cause: e }) + } + } +} diff --git a/cli/src/api/create-npm-dirs.ts b/cli/src/api/create-npm-dirs.ts new file mode 100644 index 00000000..e4cbdb08 --- /dev/null +++ b/cli/src/api/create-npm-dirs.ts @@ -0,0 +1,105 @@ +import { join, resolve } from 'path' + +import { + applyDefaultCreateNpmDirsOptions, + CreateNpmDirsOptions, +} from '../def/create-npm-dirs.js' +import { + debugFactory, + readNapiConfig, + mkdirAsync as rawMkdirAsync, + pick, + writeFileAsync as rawWriteFileAsync, + Target, +} from '../utils/index.js' + +const debug = debugFactory('create-npm-dirs') + +export async function createNpmDirs(userOptions: CreateNpmDirsOptions) { + const options = applyDefaultCreateNpmDirsOptions(userOptions) + + async function mkdirAsync(dir: string) { + debug('Try to create dir: %i', dir) + if (options.dryRun) { + return + } + + await rawMkdirAsync(dir, { + recursive: true, + }) + } + + async function writeFileAsync(file: string, content: string) { + debug('Writing file %i', file) + + if (options.dryRun) { + debug(content) + return + } + + await rawWriteFileAsync(file, content) + } + + const packageJsonPath = resolve(options.cwd, options.packageJsonPath) + const npmPath = resolve(options.cwd, options.npmDir) + + debug(`Read content from [${packageJsonPath}]`) + + const { targets, binaryName, packageName, packageJson } = + await readNapiConfig(packageJsonPath) + + for (const target of targets) { + const targetDir = join(npmPath, `${target.platformArchABI}`) + await mkdirAsync(targetDir) + + const binaryFileName = `${binaryName}.${target.platformArchABI}.node` + const scopedPackageJson = { + name: `${packageName}-${target.platformArchABI}`, + version: packageJson.version, + os: [target.platform], + cpu: target.arch !== 'universal' ? [target.arch] : undefined, + main: binaryFileName, + files: [binaryFileName], + ...pick( + packageJson, + 'description', + 'keywords', + 'author', + 'authors', + 'homepage', + 'license', + 'engines', + 'publishConfig', + 'repository', + 'bugs', + ), + } + + // Only works with yarn 3.1+ + // https://github.com/yarnpkg/berry/pull/3981 + if (target.abi === 'gnu') { + // @ts-expect-error + scopedPackageJson.libc = ['glibc'] + } else if (target.abi === 'musl') { + // @ts-expect-error + scopedPackageJson.libc = ['musl'] + } + + const targetPackageJson = join(targetDir, 'package.json') + await writeFileAsync( + targetPackageJson, + JSON.stringify(scopedPackageJson, null, 2), + ) + const targetReadme = join(targetDir, 'README.md') + await writeFileAsync(targetReadme, readme(packageName, target)) + + debug.info(`${packageName}-${target.platformArchABI} created`) + } +} + +function readme(packageName: string, target: Target) { + return `# \`${packageName}-${target.platformArchABI}\` + +This is the **${target.triple}** binary for \`${packageName}\` +` +} diff --git a/cli/src/api/new.ts b/cli/src/api/new.ts new file mode 100644 index 00000000..667226c1 --- /dev/null +++ b/cli/src/api/new.ts @@ -0,0 +1,206 @@ +import path from 'path' + +import { + applyDefaultNewOptions, + NewOptions as RawNewOptions, +} from '../def/new.js' +import { + AVAILABLE_TARGETS, + CLI_VERSION, + debugFactory, + DEFAULT_TARGETS, + mkdirAsync, + writeFileAsync, +} from '../utils/index.js' +import { napiEngineRequirement } from '../utils/version.js' + +import { + createBuildRs, + createCargoToml, + createGithubActionsCIYml, + createLibRs, + createPackageJson, + gitIgnore, + npmIgnore, +} from './templates/index.js' + +const debug = debugFactory('new') + +interface Output { + target: string + content: string +} + +type NewOptions = Required + +function processOptions(options: RawNewOptions) { + debug('Processing options...') + options.path = path.resolve(process.cwd(), options.path) + debug(`Resolved target path to: ${options.path}`) + + if (!options.name) { + options.name = path.parse(options.path).base + debug(`No project name provided, fix it to dir name: ${options.name}`) + } + + if (!options.targets?.length) { + if (options.enableAllTargets) { + options.targets = AVAILABLE_TARGETS.concat() + debug('Enable all targets') + } else if (options.enableDefaultTargets) { + options.targets = DEFAULT_TARGETS.concat() + debug('Enable default targets') + } else { + throw new Error('At least one target must be enabled') + } + } + + return applyDefaultNewOptions(options) as NewOptions +} + +export async function newProject(userOptions: RawNewOptions) { + debug('Will create napi-rs project with given options:') + debug(userOptions) + + const options = processOptions(userOptions) + + debug('Targets to be enabled:') + debug(options.targets) + + const outputs = generateFiles(options) + + try { + debug(`Try to create target directory: ${options.path}`) + if (!options.dryRun) { + await mkdirAsync(options.path, { recursive: true }) + } + } catch (e) { + throw new Error(`Failed to create target directory: ${options.path}`, { + cause: e, + }) + } + + await dumpOutputs(outputs, options.dryRun) + debug(`Project created at: ${options.path}`) +} + +function generateFiles(options: NewOptions): Output[] { + return [ + generateCargoToml, + generateLibRs, + generateBuildRs, + generatePackageJson, + generateGithubWorkflow, + generateIgnoreFiles, + ].flatMap((generator) => { + const output = generator(options) + + if (!output) { + return [] + } + + if (Array.isArray(output)) { + return output.map((o) => ({ + ...o, + target: path.join(options.path, o.target), + })) + } else { + return [{ ...output, target: path.join(options.path, output.target) }] + } + }) +} + +function generateCargoToml(options: NewOptions): Output { + return { + target: './Cargo.toml', + content: createCargoToml({ + name: options.name, + license: options.license, + features: [`napi${options.minNodeApiVersion}`], + deriveFeatures: options.enableTypeDef ? ['type-def'] : [], + }), + } +} + +function generateLibRs(_options: NewOptions): Output { + return { + target: './src/lib.rs', + content: createLibRs(), + } +} + +function generateBuildRs(_options: NewOptions): Output { + return { + target: './build.rs', + content: createBuildRs(), + } +} + +function generatePackageJson(options: NewOptions): Output { + return { + target: './package.json', + content: createPackageJson({ + name: options.name, + binaryName: getBinaryName(options.name), + targets: options.targets, + license: options.license, + engineRequirement: napiEngineRequirement(options.minNodeApiVersion), + cliVersion: CLI_VERSION, + }), + } +} + +function generateGithubWorkflow(options: NewOptions): Output | null { + if (!options.enableGithubActions) { + return null + } + + return { + target: './.github/workflows/ci.yml', + content: createGithubActionsCIYml( + getBinaryName(options.name), + options.targets, + ), + } +} + +function generateIgnoreFiles(_options: NewOptions): Output[] { + return [ + { + target: './.gitignore', + content: gitIgnore, + }, + { + target: './.npmignore', + content: npmIgnore, + }, + ] +} + +async function dumpOutputs(outputs: Output[], dryRun?: boolean) { + for (const output of outputs) { + if (!output) { + continue + } + + debug(`Writing project file: ${output.target}`) + // only output content to logger instead of writing to file system + if (dryRun) { + debug(output.content) + continue + } + + try { + await mkdirAsync(path.dirname(output.target), { recursive: true }) + await writeFileAsync(output.target, output.content, 'utf-8') + } catch (e) { + throw new Error(`Failed to write file: ${output.target}`, { cause: e }) + } + } +} + +function getBinaryName(name: string): string { + return name.split('/').pop()! +} + +export { NewOptions } diff --git a/cli/src/api/pre-publish.ts b/cli/src/api/pre-publish.ts new file mode 100644 index 00000000..55ca5193 --- /dev/null +++ b/cli/src/api/pre-publish.ts @@ -0,0 +1,216 @@ +import { execSync } from 'child_process' +import { existsSync, statSync } from 'fs' +import { join, relative, resolve } from 'path' + +import { Octokit } from '@octokit/rest' + +import { + applyDefaultPrePublishOptions, + PrePublishOptions, +} from '../def/pre-publish.js' +import { + readFileAsync, + readNapiConfig, + debugFactory, + updatePackageJson, +} from '../utils/index.js' + +import { version } from './version.js' + +const debug = debugFactory('pre-publish') + +interface PackageInfo { + name: string + version: string + tag: string +} + +export async function prePublish(userOptions: PrePublishOptions) { + debug('Receive pre-publish options:') + debug(' %O', userOptions) + + const options = applyDefaultPrePublishOptions(userOptions) + + const packageJsonPath = relative(options.cwd, options.packageJsonPath) + + const { packageJson, targets, packageName, binaryName, npmClient } = + await readNapiConfig(packageJsonPath) + + async function createGhRelease(packageName: string, version: string) { + if (!options.ghRelease) { + return { + owner: null, + repo: null, + pkgInfo: { name: null, version: null, tag: null }, + } + } + const { repo, owner, pkgInfo, octokit } = getRepoInfo(packageName, version) + + if (!repo || !owner) { + return { + owner: null, + repo: null, + pkgInfo: { name: null, version: null, tag: null }, + } + } + + if (!options.dryRun) { + try { + await octokit.repos.createRelease({ + owner, + repo, + tag_name: pkgInfo.tag, + name: options.ghReleaseName, + prerelease: + version.includes('alpha') || + version.includes('beta') || + version.includes('rc'), + }) + } catch (e) { + debug( + `Params: ${JSON.stringify( + { owner, repo, tag_name: pkgInfo.tag }, + null, + 2, + )}`, + ) + console.error(e) + } + } + return { owner, repo, pkgInfo, octokit } + } + + function getRepoInfo(packageName: string, version: string) { + const headCommit = execSync('git log -1 --pretty=%B', { + encoding: 'utf-8', + }).trim() + + const { GITHUB_REPOSITORY } = process.env + if (!GITHUB_REPOSITORY) { + return { + owner: null, + repo: null, + pkgInfo: { name: null, version: null, tag: null }, + } + } + debug(`Github repository: ${GITHUB_REPOSITORY}`) + const [owner, repo] = GITHUB_REPOSITORY.split('/') + const octokit = new Octokit({ + auth: process.env.GITHUB_TOKEN, + }) + let pkgInfo: PackageInfo | undefined + if (options.tagStyle === 'lerna') { + const packagesToPublish = headCommit + .split('\n') + .map((line) => line.trim()) + .filter((line, index) => line.length && index) + .map((line) => line.substring(2)) + .map(parseTag) + + pkgInfo = packagesToPublish.find( + (pkgInfo) => pkgInfo.name === packageName, + ) + + if (!pkgInfo) { + throw new TypeError( + `No release commit found with ${packageName}, original commit info: ${headCommit}`, + ) + } + } else { + pkgInfo = { + tag: `v${version}`, + version, + name: packageName, + } + } + return { owner, repo, pkgInfo, octokit } + } + + if (!options.dryRun) { + await version(userOptions) + await updatePackageJson(packageJsonPath, { + optionalDependencies: targets.reduce((deps, target) => { + deps[`${packageName}-${target.platformArchABI}`] = packageJson.version + + return deps + }, {} as Record), + }) + } + + const { owner, repo, pkgInfo, octokit } = options.ghReleaseId + ? getRepoInfo(packageName, packageJson.version) + : await createGhRelease(packageName, packageJson.version) + + for (const target of targets) { + const pkgDir = resolve( + options.cwd, + options.npmDir, + `${target.platformArchABI}`, + ) + const filename = `${binaryName}.${target.platformArchABI}.node` + const dstPath = join(pkgDir, filename) + + if (!options.dryRun) { + if (!existsSync(dstPath)) { + debug.warn(`%s doesn't exist`, dstPath) + continue + } + + execSync(`${npmClient} publish`, { + cwd: pkgDir, + env: process.env, + }) + + if (options.ghRelease && repo && owner) { + debug.info(`Creating GitHub release ${pkgInfo.tag}`) + try { + const releaseId = options.ghReleaseId + ? Number(options.ghReleaseId) + : ( + await octokit!.repos.getReleaseByTag({ + repo: repo, + owner: owner, + tag: pkgInfo.tag, + }) + ).data.id + const dstFileStats = statSync(dstPath) + const assetInfo = await octokit!.repos.uploadReleaseAsset({ + owner: owner, + repo: repo, + name: filename, + release_id: releaseId, + mediaType: { format: 'raw' }, + headers: { + 'content-length': dstFileStats.size, + 'content-type': 'application/octet-stream', + }, + data: await readFileAsync(dstPath, { encoding: 'utf-8' }), + }) + debug.info(`GitHub release created`) + debug.info(`Download URL: %s`, assetInfo.data.browser_download_url) + } catch (e) { + debug.error( + `Param: ${JSON.stringify( + { owner, repo, tag: pkgInfo.tag, filename: dstPath }, + null, + 2, + )}`, + ) + debug.error(e) + } + } + } + } +} + +function parseTag(tag: string) { + const segments = tag.split('@') + const version = segments.pop()! + const name = segments.join('@') + + return { + name, + version, + tag, + } +} diff --git a/cli/src/api/rename.ts b/cli/src/api/rename.ts new file mode 100644 index 00000000..c948b7e0 --- /dev/null +++ b/cli/src/api/rename.ts @@ -0,0 +1,51 @@ +import { resolve } from 'path' + +import { isNil, merge, omitBy, pick } from 'lodash-es' + +import { applyDefaultRenameOptions, RenameOptions } from '../def/rename.js' +import { readFileAsync, writeFileAsync } from '../utils/index.js' + +import { createNpmDirs } from './create-npm-dirs.js' + +export async function renameProject(userOptions: RenameOptions) { + const options = applyDefaultRenameOptions(userOptions) + + const packageJsonPath = resolve(options.cwd, options.packageJsonPath) + const cargoTomlPath = resolve(options.cwd, options.manifestPath) + + const packageJsonContent = await readFileAsync(packageJsonPath, 'utf8') + const packageJsonData = JSON.parse(packageJsonContent) + + merge( + packageJsonData, + omitBy(pick(options, ['name', 'description', 'author', 'license']), isNil), + { + napi: omitBy( + { + binaryName: options.binaryName, + packageName: options.packageName, + }, + isNil, + ), + }, + ) + + await writeFileAsync( + packageJsonPath, + JSON.stringify(packageJsonData, null, 2), + ) + + let tomlContent = await readFileAsync(cargoTomlPath, 'utf8') + tomlContent = tomlContent.replace( + /name\s?=\s?"([\w+])"/, + `name = "${options.binaryName}"`, + ) + await writeFileAsync(cargoTomlPath, tomlContent) + + await createNpmDirs({ + cwd: options.cwd, + packageJsonPath: options.packageJsonPath, + npmDir: options.npmDir, + dryRun: false, + }) +} diff --git a/cli/src/new/gitignore-template.ts b/cli/src/api/templates/.gitignore.ts similarity index 98% rename from cli/src/new/gitignore-template.ts rename to cli/src/api/templates/.gitignore.ts index c64c2f68..635d75c2 100644 --- a/cli/src/new/gitignore-template.ts +++ b/cli/src/api/templates/.gitignore.ts @@ -1,4 +1,4 @@ -export const GitIgnore = `# Created by https://www.toptal.com/developers/gitignore/api/node +export const gitIgnore = `# Created by https://www.toptal.com/developers/gitignore/api/node # Edit at https://www.toptal.com/developers/gitignore?templates=node ### Node ### diff --git a/cli/src/new/npmignore.ts b/cli/src/api/templates/.npmignore.ts similarity index 75% rename from cli/src/new/npmignore.ts rename to cli/src/api/templates/.npmignore.ts index 932c9429..33385d63 100644 --- a/cli/src/new/npmignore.ts +++ b/cli/src/api/templates/.npmignore.ts @@ -1,4 +1,4 @@ -export const NPMIgnoreFiles = `target +export const npmIgnore = `target Cargo.lock .cargo .github diff --git a/cli/src/api/templates/build.rs.ts b/cli/src/api/templates/build.rs.ts new file mode 100644 index 00000000..1deae449 --- /dev/null +++ b/cli/src/api/templates/build.rs.ts @@ -0,0 +1,4 @@ +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 new file mode 100644 index 00000000..b9b4a331 --- /dev/null +++ b/cli/src/api/templates/cargo.toml.ts @@ -0,0 +1,35 @@ +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 +` diff --git a/cli/src/new/ci-template.ts b/cli/src/api/templates/ci-template.ts similarity index 94% rename from cli/src/new/ci-template.ts rename to cli/src/api/templates/ci-template.ts index 4b36c9f6..c7995e98 100644 --- a/cli/src/new/ci-template.ts +++ b/cli/src/api/templates/ci-template.ts @@ -1,9 +1,8 @@ -export const YAML = (app: string) => ` +export const YAML = () => ` name: CI env: DEBUG: 'napi:*' - APP_NAME: '${app}' MACOSX_DEPLOYMENT_TARGET: '10.13' on: @@ -30,14 +29,14 @@ jobs: - host: macos-latest target: 'x86_64-apple-darwin' build: | - yarn build + yarn build --platform strip -x *.node - host: windows-latest - build: yarn build + build: yarn build --platform target: 'x86_64-pc-windows-msvc' - host: windows-latest build: | - yarn build --target i686-pc-windows-msvc + yarn build --platform --target i686-pc-windows-msvc yarn test target: 'i686-pc-windows-msvc' - host: ubuntu-latest @@ -45,26 +44,26 @@ jobs: docker: ghcr.io/napi-rs/napi-rs/nodejs-rust:lts-debian build: >- set -e &&\n - yarn build --target x86_64-unknown-linux-gnu &&\n + yarn build --platform --target x86_64-unknown-linux-gnu &&\n strip *.node - host: ubuntu-latest target: 'x86_64-unknown-linux-musl' docker: ghcr.io/napi-rs/napi-rs/nodejs-rust:lts-alpine build: >- set -e && - yarn build && + yarn build --platform && strip *.node - host: macos-latest target: 'aarch64-apple-darwin' build: | - yarn build --target aarch64-apple-darwin + yarn build --platform --target aarch64-apple-darwin strip -x *.node - host: ubuntu-latest target: 'aarch64-unknown-linux-gnu' docker: ghcr.io/napi-rs/napi-rs/nodejs-rust:lts-debian-aarch64 build: >- set -e &&\n - yarn build --target aarch64-unknown-linux-gnu &&\n + yarn build --platform --target aarch64-unknown-linux-gnu &&\n aarch64-unknown-linux-gnu-strip *.node - host: ubuntu-latest target: 'armv7-unknown-linux-gnueabihf' @@ -72,17 +71,17 @@ jobs: sudo apt-get update sudo apt-get install gcc-arm-linux-gnueabihf -y build: | - yarn build --target armv7-unknown-linux-gnueabihf + yarn build --platform --target armv7-unknown-linux-gnueabihf arm-linux-gnueabihf-strip *.node - host: ubuntu-latest target: 'aarch64-linux-android' build: | - yarn build --target aarch64-linux-android + yarn build --platform --target aarch64-linux-android \${ANDROID_NDK_LATEST_HOME}/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-strip *.node - host: ubuntu-latest target: 'armv7-linux-androideabi' build: | - yarn build --target armv7-linux-androideabi + yarn build --platform --target armv7-linux-androideabi \${ANDROID_NDK_LATEST_HOME}/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-strip *.node - host: ubuntu-latest target: 'aarch64-unknown-linux-musl' @@ -90,11 +89,11 @@ jobs: build: >- set -e &&\n rustup target add aarch64-unknown-linux-musl &&\n - yarn build --target aarch64-unknown-linux-musl &&\n + yarn build --platform --target aarch64-unknown-linux-musl &&\n /aarch64-linux-musl-cross/bin/aarch64-linux-musl-strip *.node - host: windows-latest target: 'aarch64-pc-windows-msvc' - build: yarn build --target aarch64-pc-windows-msvc + build: yarn build --platform --target aarch64-pc-windows-msvc name: stable - \${{ matrix.settings.target }} - node@18 runs-on: \${{ matrix.settings.host }} @@ -172,7 +171,7 @@ jobs: uses: actions/upload-artifact@v3 with: name: bindings-\${{ matrix.settings.target }} - path: \${{ env.APP_NAME }}.*.node + path: "*.node" if-no-files-found: error build-freebsd: @@ -223,7 +222,7 @@ jobs: uses: actions/upload-artifact@v3 with: name: bindings-freebsd - path: \${{ env.APP_NAME }}.*.node + path: "*.node" if-no-files-found: error test-macOS-windows-binding: @@ -508,7 +507,7 @@ jobs: uses: actions/upload-artifact@v3 with: name: bindings-universal-apple-darwin - path: \${{ env.APP_NAME }}.*.node + path: "*.node" if-no-files-found: error publish: diff --git a/cli/src/new/ci-yml.ts b/cli/src/api/templates/ci.yml.ts similarity index 94% rename from cli/src/new/ci-yml.ts rename to cli/src/api/templates/ci.yml.ts index 1f956dd3..ec015f96 100644 --- a/cli/src/new/ci-yml.ts +++ b/cli/src/api/templates/ci.yml.ts @@ -1,8 +1,12 @@ import { load, dump } from 'js-yaml' -import { NodeArchToCpu, UniArchsByPlatform, parseTriple } from '../parse-triple' +import { + NodeArchToCpu, + UniArchsByPlatform, + parseTriple, +} from '../../utils/index.js' -import { YAML } from './ci-template' +import { YAML } from './ci-template.js' const BUILD_FREEBSD = 'build-freebsd' const TEST_MACOS_WINDOWS = 'test-macOS-windows-binding' @@ -29,7 +33,9 @@ export const createGithubActionsCIYml = ( return [t] }), ) - const fullTemplate = load(YAML(binaryName)) as any + + const fullTemplate = load(YAML()) as any + const requiredSteps = [] const enableWindowsX86 = allTargets.has('x86_64-pc-windows-msvc') const enableMacOSX86 = allTargets.has('x86_64-apple-darwin') @@ -40,7 +46,6 @@ export const createGithubActionsCIYml = ( const enableLinuxArm7 = allTargets.has('armv7-unknown-linux-gnueabihf') const enableFreeBSD = allTargets.has('x86_64-unknown-freebsd') const enableMacOSUni = allTargets.has('universal-apple-darwin') - fullTemplate.env.APP_NAME = binaryName fullTemplate.jobs.build.strategy.matrix.settings = fullTemplate.jobs.build.strategy.matrix.settings.filter( ({ target }: { target: string }) => allTargets.has(target), diff --git a/cli/src/api/templates/index.ts b/cli/src/api/templates/index.ts new file mode 100644 index 00000000..b67fa7a0 --- /dev/null +++ b/cli/src/api/templates/index.ts @@ -0,0 +1,8 @@ +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/js-binding.ts b/cli/src/api/templates/js-binding.ts new file mode 100644 index 00000000..fd236c24 --- /dev/null +++ b/cli/src/api/templates/js-binding.ts @@ -0,0 +1,130 @@ +/* eslint-disable @typescript-eslint/switch-exhaustiveness-check */ + +function loadNapiModule(binaryName: string, packageName: string) { + const { existsSync, readFileSync } = require('fs') + const { join } = require('path') + const { platform, arch } = process + + const candidates: string[] = [] + + function isMusl() { + // For Node 10 + if (!process.report || typeof process.report.getReport !== 'function') { + try { + const lddPath = require('child_process') + .execSync('which ldd') + .toString() + .trim() + return readFileSync(lddPath, 'utf8').includes('musl') + } catch (e) { + return true + } + } else { + // @ts-expect-error + const { glibcVersionRuntime } = process.report.getReport().header + return !glibcVersionRuntime + } + } + + switch (platform) { + case 'android': + switch (arch) { + case 'arm64': + candidates.push('android-arm64') + break + case 'arm': + candidates.push('android-arm-eabi') + break + } + break + case 'win32': + switch (arch) { + case 'x64': + candidates.push('win32-x64-msvc') + break + case 'ia32': + candidates.push('win32-ia32-msvc') + break + case 'arm64': + candidates.push('win32-arm64-msvc') + break + } + break + case 'darwin': + candidates.push('darwin-universal') + switch (arch) { + case 'x64': + candidates.push('darwin-x64') + break + case 'arm64': + candidates.push('darwin-arm64') + break + } + break + case 'freebsd': + if (arch === 'x64') { + candidates.push('freebsd-x64') + } + break + case 'linux': + switch (arch) { + case 'x64': + if (isMusl()) { + candidates.push('linux-x64-musl') + } else { + candidates.push('linux-x64-gnu') + } + break + case 'arm64': + if (isMusl()) { + candidates.push('linux-arm64-musl') + } else { + candidates.push('linux-arm64-gnu') + } + break + case 'arm': + candidates.push('linux-arm-gnueabihf') + break + } + break + } + + let nativeBinding: any + let loadError: any + + for (const suffix of candidates) { + const localPath = join(__dirname, `${binaryName}.${suffix}.node`) + const pkgPath = `${packageName}-${suffix}` + + try { + if (existsSync(localPath)) { + nativeBinding = require(localPath) + } else { + nativeBinding = require(pkgPath) + } + } catch (e) { + loadError = e + continue + } + + loadError = null + break + } + + if (!nativeBinding) { + if (loadError) { + throw loadError + } + + throw new Error(`Unsupported OS: ${platform}, architecture: ${arch}`) + } + + return nativeBinding +} + +export function createJsBinding(localName: string, pkgName: string): string { + return `${loadNapiModule.toString()} + +module.exports = loadNapiModule('${localName}', '${pkgName}') +` +} diff --git a/cli/src/new/lib-rs.ts b/cli/src/api/templates/lib.rs.ts similarity index 63% rename from cli/src/new/lib-rs.ts rename to cli/src/api/templates/lib.rs.ts index 6789aa7a..4c01b6a6 100644 --- a/cli/src/new/lib-rs.ts +++ b/cli/src/api/templates/lib.rs.ts @@ -1,4 +1,4 @@ -export const LibRs = `#![deny(clippy::all)] +export const createLibRs = () => `#![deny(clippy::all)] #[macro_use] extern crate napi_derive; diff --git a/cli/src/api/templates/package.json.ts b/cli/src/api/templates/package.json.ts new file mode 100644 index 00000000..67e95709 --- /dev/null +++ b/cli/src/api/templates/package.json.ts @@ -0,0 +1,44 @@ +export const createPackageJson = ({ + name, + binaryName, + targets, + license, + engineRequirement, + cliVersion, +}: { + name: string + binaryName: string + targets: string[] + license: string + engineRequirement: string + cliVersion: string +}) => { + return `{ + "name": "${name}", + "version": "1.0.0", + "main": "index.js", + "types": "index.d.ts", + "license": "${license}", + "engines": { + "node": "${engineRequirement}" + }, + "napi": { + "name": "${binaryName}", + "targets": [ + ${targets.map((t) => `"${t}"`).join(',\n ')} + ] + }, + "scripts": { + "test": "yarn build:debug --platform && node -e \\"assert(require('.').sum(1, 2) === 3)\\"", + "build": "napi build --release --platform --strip", + "build:debug": "napi build", + "prepublishOnly": "napi prepublish -t npm", + "artifacts": "napi artifacts", + "universal": "napi universal", + "version": "napi version" + }, + "devDependencies": { + "@napi-rs/cli": "^${cliVersion}" + } +}` +} diff --git a/cli/src/api/universalize.ts b/cli/src/api/universalize.ts new file mode 100644 index 00000000..53ebd860 --- /dev/null +++ b/cli/src/api/universalize.ts @@ -0,0 +1,76 @@ +import { spawnSync } from 'child_process' +import { join, resolve } from 'path' + +import { + applyDefaultUniversalizeOptions, + UniversalizeOptions, +} from '../def/universalize.js' +import { readNapiConfig } from '../utils/config.js' +import { debugFactory } from '../utils/log.js' +import { fileExists } from '../utils/misc.js' +import { UniArchsByPlatform } from '../utils/target.js' + +const debug = debugFactory('universalize') + +const universalizers: Partial< + Record void> +> = { + darwin: (inputs, output) => { + spawnSync('lipo', ['-create', '-output', output, ...inputs], { + stdio: 'inherit', + }) + }, +} + +export async function universalizeBinaries(userOptions: UniversalizeOptions) { + const options = applyDefaultUniversalizeOptions(userOptions) + + const packageJsonPath = join(options.cwd, options.packageJsonPath) + + const config = await readNapiConfig(packageJsonPath) + + const target = config.targets.find( + (t) => t.platform === process.platform && t.arch === 'universal', + ) + + if (!target) { + throw new Error( + `'universal' arch for platform '${process.platform}' not found in config!`, + ) + } + + const srcFiles = UniArchsByPlatform[process.platform]?.map( + (arch) => `${config.binaryName}.${process.platform}-${arch}.node`, + ) + + if (!srcFiles || !universalizers[process.platform]) { + throw new Error( + `'universal' arch for platform '${process.platform}' not supported.`, + ) + } + + debug(`Looking up source binaries to combine: `) + debug(' %O', srcFiles) + + const srcFileLookup = await Promise.all( + srcFiles.map((f) => fileExists(resolve(options.cwd, options.outputDir, f))), + ) + + const notFoundFiles = srcFiles.filter((_, i) => !srcFileLookup[i]) + + if (notFoundFiles.length) { + throw new Error( + `Some binary files were not found: ${JSON.stringify(notFoundFiles)}`, + ) + } + + const output = resolve( + options.cwd, + options.outputDir, + `${config.binaryName}.${process.platform}-universal.node`, + ) + + universalizers[process.platform]?.(srcFiles, output) + + debug(`Produced universal binary: ${output}`) +} diff --git a/cli/src/api/version.ts b/cli/src/api/version.ts new file mode 100644 index 00000000..fa3e47cc --- /dev/null +++ b/cli/src/api/version.ts @@ -0,0 +1,26 @@ +import { join, resolve } from 'path' + +import { applyDefaultVersionOptions, VersionOptions } from '../def/version.js' +import { + readNapiConfig, + debugFactory, + updatePackageJson, +} from '../utils/index.js' + +const debug = debugFactory('version') + +export async function version(userOptions: VersionOptions) { + const options = applyDefaultVersionOptions(userOptions) + const packageJsonPath = resolve(options.cwd, options.packageJsonPath) + + const config = await readNapiConfig(packageJsonPath) + + for (const target of config.targets) { + const pkgDir = resolve(options.cwd, options.npmDir, target.platformArchABI) + + debug(`Update version to %i in [%i]`, config.packageJson.version, pkgDir) + await updatePackageJson(join(pkgDir, 'package.json'), { + version: config.packageJson.version, + }) + } +} diff --git a/cli/src/arm-features.h.ts b/cli/src/arm-features.h.ts deleted file mode 100644 index 2399f15a..00000000 --- a/cli/src/arm-features.h.ts +++ /dev/null @@ -1,56 +0,0 @@ -export const ARM_FEATURES_H = `/* Macros to test for CPU features on ARM. Generic ARM version. -Copyright (C) 2012-2022 Free Software Foundation, Inc. -This file is part of the GNU C Library. -The GNU C Library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; either -version 2.1 of the License, or (at your option) any later version. -The GNU C Library is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -Lesser General Public License for more details. -You should have received a copy of the GNU Lesser General Public -License along with the GNU C Library. If not, see -. */ - -#ifndef _ARM_ARM_FEATURES_H -#define _ARM_ARM_FEATURES_H 1 - -/* An OS-specific arm-features.h file should define ARM_HAVE_VFP to -an appropriate expression for testing at runtime whether the VFP -hardware is present. We'll then redefine it to a constant if we -know at compile time that we can assume VFP. */ - -#ifndef __SOFTFP__ -/* The compiler is generating VFP instructions, so we're already -assuming the hardware exists. */ -# undef ARM_HAVE_VFP -# define ARM_HAVE_VFP 1 -#endif - -/* An OS-specific arm-features.h file may define ARM_ASSUME_NO_IWMMXT -to indicate at compile time that iWMMXt hardware is never present -at runtime (or that we never care about its state) and so need not -be checked for. */ - -/* A more-specific arm-features.h file may define ARM_ALWAYS_BX to indicate -that instructions using pc as a destination register must never be used, -so a "bx" (or "blx") instruction is always required. */ - -/* The log2 of the minimum alignment required for an address that -is the target of a computed branch (i.e. a "bx" instruction). -A more-specific arm-features.h file may define this to set a more -stringent requirement. -Using this only makes sense for code in ARM mode (where instructions -always have a fixed size of four bytes), or for Thumb-mode code that is -specifically aligning all the related branch targets to match (since -Thumb instructions might be either two or four bytes). */ -#ifndef ARM_BX_ALIGN_LOG2 -# define ARM_BX_ALIGN_LOG2 2 -#endif - -/* An OS-specific arm-features.h file may define ARM_NO_INDEX_REGISTER to -indicate that the two-register addressing modes must never be used. */ - -#endif /* arm-features.h */ -` diff --git a/cli/src/artifacts.ts b/cli/src/artifacts.ts deleted file mode 100644 index b5d1271f..00000000 --- a/cli/src/artifacts.ts +++ /dev/null @@ -1,89 +0,0 @@ -import { join, parse } from 'path' - -import { Command, Option } from 'clipanion' -import * as chalk from 'colorette' -import { fdir } from 'fdir' - -import { getNapiConfig } from './consts' -import { debugFactory } from './debug' -import { UniArchsByPlatform } from './parse-triple' -import { readFileAsync, writeFileAsync } from './utils' - -const debug = debugFactory('artifacts') - -export class ArtifactsCommand extends Command { - static usage = Command.Usage({ - description: 'Copy artifacts from Github Actions into specified dir', - }) - - static paths = [['artifacts']] - - sourceDir = Option.String('-d,--dir', 'artifacts') - - distDir = Option.String('--dist', 'npm') - - configFileName?: string = Option.String('-c,--config') - - async execute() { - const { platforms, binaryName, packageJsonPath } = getNapiConfig( - this.configFileName, - ) - - const packageJsonDir = parse(packageJsonPath).dir - - const sourceApi = new fdir() - .withFullPaths() - .crawl(join(process.cwd(), this.sourceDir)) - - const distDirs = platforms.map((platform) => - join(process.cwd(), this.distDir, platform.platformArchABI), - ) - - const universalSourceBins = new Set( - platforms - .filter((platform) => platform.arch === 'universal') - .flatMap((p) => - UniArchsByPlatform[p.platform].map((a) => `${p.platform}-${a}`), - ), - ) - - await sourceApi.withPromise().then((output) => - Promise.all( - (output as string[]).map(async (filePath) => { - debug(`Read [${chalk.yellowBright(filePath)}]`) - const sourceContent = await readFileAsync(filePath) - const parsedName = parse(filePath) - const [_binaryName, platformArchABI] = parsedName.name.split('.') - if (_binaryName !== binaryName) { - debug( - `[${chalk.yellowBright( - _binaryName, - )}] is not matched with [${chalk.greenBright(binaryName)}], skip`, - ) - return - } - const dir = distDirs.find((dir) => dir.includes(platformArchABI)) - if (!dir && universalSourceBins.has(platformArchABI)) { - debug( - `[${chalk.yellowBright( - platformArchABI, - )}] has no dist dir but it is source bin for universal arch, skip`, - ) - return - } - if (!dir) { - throw new TypeError(`No dist dir found for ${filePath}`) - } - const distFilePath = join(dir, parsedName.base) - debug(`Write file content to [${chalk.yellowBright(distFilePath)}]`) - await writeFileAsync(distFilePath, sourceContent) - const distFilePathLocal = join(packageJsonDir, parsedName.base) - debug( - `Write file content to [${chalk.yellowBright(distFilePathLocal)}]`, - ) - await writeFileAsync(distFilePathLocal, sourceContent) - }), - ), - ) - } -} diff --git a/cli/src/build.ts b/cli/src/build.ts deleted file mode 100644 index d6374cff..00000000 --- a/cli/src/build.ts +++ /dev/null @@ -1,921 +0,0 @@ -import { execSync } from 'child_process' -import { createHash } from 'crypto' -import { existsSync, mkdirSync } from 'fs' -import { tmpdir } from 'os' -import { join, parse, sep } from 'path' - -import { Command, Option } from 'clipanion' -import * as chalk from 'colorette' -import envPaths from 'env-paths' -import { groupBy } from 'lodash-es' - -import { version } from '../package.json' - -import { ARM_FEATURES_H } from './arm-features.h' -import { getNapiConfig } from './consts' -import { debugFactory } from './debug' -import { createJsBinding } from './js-binding-template' -import { getHostTargetTriple, parseTriple } from './parse-triple' -import { - copyFileAsync, - mkdirAsync, - readFileAsync, - unlinkAsync, - writeFileAsync, -} from './utils' - -const debug = debugFactory('build') - -const ZIG_PLATFORM_TARGET_MAP = { - 'x86_64-unknown-linux-musl': 'x86_64-linux-musl', - 'x86_64-unknown-linux-gnu': 'x86_64-linux-gnu', - // Doesn't support Windows MSVC for now - // 'x86_64-pc-windows-gnu': 'x86_64-windows-gnu', - // https://github.com/ziglang/zig/issues/1759 - // 'x86_64-unknown-freebsd': 'x86_64-freebsd', - 'x86_64-apple-darwin': 'x86_64-macos', - 'aarch64-apple-darwin': 'aarch64-macos', - 'aarch64-unknown-linux-gnu': 'aarch64-linux-gnu', - 'aarch64-unknown-linux-musl': 'aarch64-linux-musl', - 'armv7-unknown-linux-gnueabihf': 'arm-linux-gnueabihf', -} - -const DEFAULT_GLIBC_TARGET = process.env.GLIBC_ABI_TARGET ?? '2.17' - -const SHEBANG_NODE = process.platform === 'win32' ? '' : '#!/usr/bin/env node\n' -const SHEBANG_SH = process.platform === 'win32' ? '' : '#!/usr/bin/env sh\n' - -function processZigLinkerArgs(platform: string, args: string[]) { - if (platform.includes('apple')) { - const newArgs = args.filter( - (arg, index) => - !arg.startsWith('-Wl,-exported_symbols_list') && - arg !== '-Wl,-dylib' && - arg !== '-liconv' && - arg !== '-Wl,-dead_strip' && - !(arg === '-framework' && args[index + 1] === 'CoreFoundation') && - !(arg === 'CoreFoundation' && args[index - 1] === '-framework'), - ) - newArgs.push('-Wl,"-undefined=dynamic_lookup"', '-dead_strip', '-lunwind') - return newArgs - } - if (platform.includes('linux')) { - return args - .map((arg) => { - if (arg === '-lgcc_s') { - return '-lunwind' - } - return arg - }) - .filter((arg) => arg !== '-march=armv7-a') - } - return args -} - -export class BuildCommand extends Command { - static usage = Command.Usage({ - description: 'Build and copy native module into specified dir', - }) - - static paths = [['build']] - - appendPlatformToFilename = Option.Boolean(`--platform`, false, { - description: `Add platform triple to the .node file. ${chalk.green( - '[name].linux-x64-gnu.node', - )} for example`, - }) - - isRelease = Option.Boolean(`--release`, false, { - description: `Bypass to ${chalk.green('cargo build --release')}`, - }) - - configFileName?: string = Option.String('--config,-c', { - description: `napi config path, only JSON format accepted. Default to ${chalk.underline( - chalk.green('package.json'), - )}`, - }) - - cargoName?: string = Option.String('--cargo-name', { - description: `Override the ${chalk.green( - 'name', - )} field in ${chalk.underline(chalk.yellowBright('Cargo.toml'))}`, - }) - - targetTripleDir = Option.String( - '--target', - process.env.RUST_TARGET ?? process.env.CARGO_BUILD_TARGET ?? '', - { - description: `Bypass to ${chalk.green('cargo build --target')}`, - }, - ) - - features?: string = Option.String('--features', { - description: `Bypass to ${chalk.green('cargo build --features')}`, - }) - - bin?: string = Option.String('--bin', { - description: `Bypass to ${chalk.green('cargo build --bin')}`, - }) - - dts?: string = Option.String('--dts', 'index.d.ts', { - description: `The filename and path of ${chalk.green( - '.d.ts', - )} file, relative to cwd`, - }) - - constEnum?: boolean = Option.Boolean('--const-enum', true, { - description: `Generate ${chalk.green( - 'const enum', - )} in .d.ts file or not, default is ${chalk.green('true')}`, - }) - - noDtsHeader = Option.Boolean('--no-dts-header', false, { - description: `Don't generate ${chalk.green('.d.ts')} header`, - }) - - project = Option.String('-p', { - description: `Bypass to ${chalk.green('cargo -p')}`, - }) - - cargoFlags = Option.String('--cargo-flags', '', { - description: `All the others flag passed to ${chalk.yellow('cargo build')}`, - }) - - jsBinding = Option.String('--js', 'index.js', { - description: `Path to the JS binding file, pass ${chalk.underline( - chalk.yellow('false'), - )} to disable it. Only affect if ${chalk.green('--target')} is specified.`, - }) - - jsPackageName = Option.String('--js-package-name', { - description: `Package name in generated js binding file, Only affect if ${chalk.green( - '--target', - )} specified and ${chalk.green('--js')} is not false.`, - required: false, - }) - - cargoCwd?: string = Option.String('--cargo-cwd', { - description: `The cwd of ${chalk.underline( - chalk.yellow('Cargo.toml'), - )} file`, - }) - - pipe?: string = Option.String('--pipe', { - description: `Pipe [${chalk.green( - '.js/.ts', - )}] files to this command, eg ${chalk.green('prettier -w')}`, - }) - - // https://github.com/napi-rs/napi-rs/issues/297 - disableWindowsX32Optimize?: boolean = Option.Boolean( - '--disable-windows-x32-optimize', - false, - { - description: `Disable windows x32 ${chalk.green( - 'lto', - )} and increase ${chalk.green( - 'codegen-units', - )}. Disabled by default. See ${chalk.underline( - chalk.blue('https://github.com/napi-rs/napi-rs/issues/297'), - )}`, - }, - ) - - destDir = Option.String({ - required: false, - }) - - useZig = Option.Boolean(`--zig`, false, { - description: `Use ${chalk.green('zig')} as linker ${chalk.yellowBright( - '(Experimental)', - )}`, - }) - - zigABIVersion = Option.String(`--zig-abi-suffix`, { - description: `The suffix of the ${chalk.green( - 'zig --target', - )} ABI version. Eg. ${chalk.cyan( - '--target x86_64-unknown-linux-gnu', - )} ${chalk.green('--zig-abi-suffix=2.17')}`, - }) - - zigLinkOnly = Option.Boolean(`--zig-link-only`, false, { - description: `Only link the library with ${chalk.green('zig')}`, - }) - - isStrip = Option.Boolean(`--strip`, false, { - description: `${chalk.green('Strip')} the library for minimum file size`, - }) - - async execute() { - const cwd = this.cargoCwd - ? join(process.cwd(), this.cargoCwd) - : process.cwd() - const cargoTomlPath = join(cwd, 'Cargo.toml') - - let cargoMetadata: any - - try { - debug('Start parse toml') - cargoMetadata = JSON.parse( - execSync( - `cargo metadata --format-version 1 --manifest-path "${cargoTomlPath}"`, - { - stdio: 'pipe', - maxBuffer: 1024 * 1024 * 10, - }, - ).toString('utf8'), - ) - } catch (e) { - throw new TypeError('Could not parse the Cargo.toml: ' + e) - } - const packages = cargoMetadata.packages - - let cargoPackageName: string - if (this.cargoName) { - cargoPackageName = this.cargoName - } else { - const root = cargoMetadata.resolve.root - if (root) { - const rootPackage = packages.find((p: { id: string }) => p.id === root) - cargoPackageName = rootPackage.name - } else { - throw new TypeError('No package.name field in Cargo.toml') - } - } - - const cargoPackage = packages.find( - (p: { name: string }) => p.name === cargoPackageName, - ) - if ( - !this.bin && - cargoPackage?.targets?.length === 1 && - cargoPackage?.targets[0].kind.length === 1 && - cargoPackage?.targets[0].kind[0] === 'bin' - ) { - this.bin = cargoPackageName - } - const releaseFlag = this.isRelease ? `--release` : '' - - const targetFlag = this.targetTripleDir - ? `--target ${this.targetTripleDir}` - : '' - const featuresFlag = this.features ? `--features ${this.features}` : '' - const binFlag = this.bin ? `--bin ${this.bin}` : '' - const triple = this.targetTripleDir - ? parseTriple(this.targetTripleDir) - : getHostTargetTriple() - debug(`Current triple is: ${chalk.green(triple.raw)}`) - const pFlag = this.project ? `-p ${this.project}` : '' - const externalFlags = [ - releaseFlag, - targetFlag, - featuresFlag, - binFlag, - pFlag, - this.cargoFlags, - ] - .filter((flag) => Boolean(flag)) - .join(' ') - const additionalEnv = {} - const isCrossForWin = - triple.platform === 'win32' && process.platform !== 'win32' - const isCrossForLinux = - triple.platform === 'linux' && - (process.platform !== 'linux' || - triple.arch !== process.arch || - (function () { - const glibcVersionRuntime = - // @ts-expect-error - process.report?.getReport()?.header?.glibcVersionRuntime - const libc = glibcVersionRuntime ? 'gnu' : 'musl' - return triple.abi !== libc - })()) - const isCrossForMacOS = - triple.platform === 'darwin' && process.platform !== 'darwin' - const cargo = process.env.CARGO ?? (isCrossForWin ? 'cargo-xwin' : 'cargo') - if (isCrossForWin && triple.arch === 'ia32') { - additionalEnv['XWIN_ARCH'] = 'x86' - } - const cargoCommand = `${cargo} build ${externalFlags}` - debug(`Run ${chalk.green(cargoCommand)}`) - - const rustflags = process.env.RUSTFLAGS - ? process.env.RUSTFLAGS.split(' ') - : [] - if (triple.raw.includes('musl') && !this.bin) { - if (!rustflags.includes('target-feature=-crt-static')) { - rustflags.push('-C target-feature=-crt-static') - } - } - - if (this.isStrip && !rustflags.includes('-C link-arg=-s')) { - rustflags.push('-C link-arg=-s') - } - - let useZig = false - if (this.useZig || isCrossForLinux || isCrossForMacOS) { - try { - execSync('zig version') - useZig = true - } catch (e) { - if (this.useZig) { - throw new TypeError( - `Could not find ${chalk.green('zig')} on the PATH`, - ) - } else { - debug( - `Could not find ${chalk.green( - 'zig', - )} on the PATH, fallback to normal linker`, - ) - } - } - } - - if (useZig) { - const zigABIVersion = - this.zigABIVersion ?? - (isCrossForLinux && triple.abi === 'gnu' ? DEFAULT_GLIBC_TARGET : null) - const mappedZigTarget = ZIG_PLATFORM_TARGET_MAP[triple.raw] - const zigTarget = `${mappedZigTarget}${ - zigABIVersion ? `.${zigABIVersion}` : '' - }` - debug(`Using Zig with target ${chalk.green(zigTarget)}`) - if (!mappedZigTarget) { - throw new Error(`${triple.raw} can not be cross compiled by zig`) - } - const paths = envPaths('napi-rs') - const shellFileExt = process.platform === 'win32' ? 'cmd' : 'sh' - const linkerWrapperShell = join( - paths.cache, - `zig-linker-${triple.raw}.${shellFileExt}`, - ) - const CCWrapperShell = join( - paths.cache, - `zig-cc-${triple.raw}.${shellFileExt}`, - ) - const CXXWrapperShell = join( - paths.cache, - `zig-cxx-${triple.raw}.${shellFileExt}`, - ) - const linkerWrapper = join(paths.cache, `zig-cc-${triple.raw}.js`) - mkdirSync(paths.cache, { recursive: true }) - const forwardArgs = process.platform === 'win32' ? '"%*"' : '$@' - if (triple.arch === 'arm') { - await patchArmFeaturesHForArmTargets() - } - await writeFileAsync( - linkerWrapperShell, - process.platform === 'win32' - ? `@IF EXIST "%~dp0\\node.exe" ( - "%~dp0\\node.exe" "${linkerWrapper}" %* -) ELSE ( - @SETLOCAL - @SET PATHEXT=%PATHEXT:;.JS;=;% - node "${linkerWrapper}" %* -)` - : `${SHEBANG_SH}node ${linkerWrapper} ${forwardArgs}`, - { - mode: '777', - }, - ) - await writeFileAsync( - CCWrapperShell, - `${SHEBANG_SH}node ${linkerWrapper} cc ${forwardArgs}`, - { - mode: '777', - }, - ) - await writeFileAsync( - CXXWrapperShell, - `${SHEBANG_SH}node ${linkerWrapper} c++ ${forwardArgs}`, - { - mode: '777', - }, - ) - - await writeFileAsync( - linkerWrapper, - `${SHEBANG_NODE}const{writeFileSync} = require('fs')\n${processZigLinkerArgs.toString()}\nconst {status} = require('child_process').spawnSync('zig', [process.argv[2] === "c++" || process.argv[2] === "cc" ? "" : "cc", ...processZigLinkerArgs('${ - triple.raw - }', process.argv.slice(2)), '-target', '${zigTarget}'], { stdio: 'inherit', shell: true })\nwriteFileSync('${linkerWrapper.replaceAll( - '\\', - '/', - )}.args.log', processZigLinkerArgs('${ - triple.raw - }', process.argv.slice(2)).join(' '))\n\nprocess.exit(status || 0)\n`, - { - mode: '777', - }, - ) - const envTarget = triple.raw.replaceAll('-', '_').toUpperCase() - if (!this.zigLinkOnly) { - Object.assign(additionalEnv, { - CC: CCWrapperShell, - CXX: CXXWrapperShell, - TARGET_CC: CCWrapperShell, - TARGET_CXX: CXXWrapperShell, - }) - } - additionalEnv[`CARGO_TARGET_${envTarget}_LINKER`] = linkerWrapperShell - } - debug(`Platform: ${JSON.stringify(triple, null, 2)}`) - if (triple.platform === 'android') { - const { ANDROID_NDK_LATEST_HOME } = process.env - if (!ANDROID_NDK_LATEST_HOME) { - console.info( - `${chalk.yellow( - 'ANDROID_NDK_LATEST_HOME', - )} environment variable is missing`, - ) - } - const targetArch = triple.arch === 'arm' ? 'armv7a' : 'aarch64' - const targetPlatform = - triple.arch === 'arm' ? 'androideabi24' : 'android24' - Object.assign(additionalEnv, { - CARGO_TARGET_AARCH64_LINUX_ANDROID_LINKER: `${ANDROID_NDK_LATEST_HOME}/toolchains/llvm/prebuilt/linux-x86_64/bin/${targetArch}-linux-android24-clang`, - CARGO_TARGET_ARMV7_LINUX_ANDROIDEABI_LINKER: `${ANDROID_NDK_LATEST_HOME}/toolchains/llvm/prebuilt/linux-x86_64/bin/${targetArch}-linux-androideabi24-clang`, - CC: `${ANDROID_NDK_LATEST_HOME}/toolchains/llvm/prebuilt/linux-x86_64/bin/${targetArch}-linux-${targetPlatform}-clang`, - CXX: `${ANDROID_NDK_LATEST_HOME}/toolchains/llvm/prebuilt/linux-x86_64/bin/${targetArch}-linux-${targetPlatform}-clang++`, - AR: `${ANDROID_NDK_LATEST_HOME}/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-ar`, - ANDROID_NDK: ANDROID_NDK_LATEST_HOME, - PATH: `${ANDROID_NDK_LATEST_HOME}/toolchains/llvm/prebuilt/linux-x86_64/bin:${process.env.PATH}`, - }) - } - - const { - binaryName, - packageName, - tsConstEnum: tsConstEnumFromConfig, - } = getNapiConfig(this.configFileName) - const tsConstEnum = this.constEnum ?? tsConstEnumFromConfig - if (triple.platform === 'wasi') { - try { - const emnapiDir = require.resolve('emnapi') - const linkDir = join(emnapiDir, '..', 'lib', 'wasm32-wasi') - additionalEnv['EMNAPI_LINK_DIR'] = linkDir - rustflags.push('-Z wasi-exec-model=reactor') - } catch (e) { - const err = new Error(`Could not find emnapi, please install emnapi`) - err.cause = e - throw err - } - } - if (rustflags.length > 0) { - additionalEnv['RUSTFLAGS'] = rustflags.join(' ') - } - - let cargoArtifactName = this.cargoName - if (!cargoArtifactName) { - if (this.bin) { - cargoArtifactName = cargoPackageName - } else { - cargoArtifactName = cargoPackageName.replace(/-/g, '_') - } - - if ( - !this.bin && - !cargoPackage.targets.some((target: { crate_types: string[] }) => - target.crate_types.includes('cdylib'), - ) - ) { - throw new TypeError( - `Missing ${chalk.green('crate-type = ["cdylib"]')} in ${chalk.green( - '[lib]', - )}`, - ) - } - } - - if (this.bin) { - debug(`Binary name: ${chalk.greenBright(cargoArtifactName)}`) - } else { - debug(`Dylib name: ${chalk.greenBright(cargoArtifactName)}`) - } - const cwdSha = createHash('sha256') - .update(process.cwd()) - .update(version) - .digest('hex') - .substring(0, 8) - const intermediateTypeFile = join( - tmpdir(), - `${cargoArtifactName}-${cwdSha}.napi_type_def.tmp`, - ) - const intermediateWasiRegisterFile = join( - tmpdir(), - `${cargoArtifactName}-${cwdSha}.napi_wasi_register.tmp`, - ) - debug(`intermediate type def file: ${intermediateTypeFile}`) - - const commandEnv = { - ...process.env, - ...additionalEnv, - TYPE_DEF_TMP_PATH: intermediateTypeFile, - WASI_REGISTER_TMP_PATH: intermediateWasiRegisterFile, - CARGO_CFG_NAPI_RS_CLI_VERSION: version, - } - - try { - execSync(cargoCommand, { - env: commandEnv, - stdio: 'inherit', - cwd, - }) - } catch (e) { - if (cargo === 'cargo-xwin') { - console.warn( - `You are cross compiling ${chalk.underline( - triple.raw, - )} target on ${chalk.green(process.platform)} host`, - ) - } else if (isCrossForLinux || isCrossForMacOS) { - console.warn( - `You are cross compiling ${chalk.underline( - triple.raw, - )} on ${chalk.green(process.platform)} host`, - ) - } - throw e - } - - const platform = triple.platform - let libExt = '' - - debug(`Platform: ${chalk.greenBright(platform)}`) - - // Platform based massaging for build commands - if (!this.bin) { - switch (platform) { - case 'darwin': - libExt = '.dylib' - cargoArtifactName = `lib${cargoArtifactName}` - break - case 'win32': - libExt = '.dll' - break - case 'linux': - case 'freebsd': - case 'openbsd': - case 'android': - case 'sunos': - cargoArtifactName = `lib${cargoArtifactName}` - libExt = '.so' - break - default: - throw new TypeError( - 'Operating system not currently supported or recognized by the build script', - ) - } - } - - const targetRootDir = - // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing - process.env.CARGO_TARGET_DIR || - // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing - process.env.CARGO_BUILD_TARGET_DIR || - (await findUp(cwd)) - - if (!targetRootDir) { - throw new TypeError('No target dir found') - } - - const targetDir = join( - this.targetTripleDir, - this.isRelease ? 'release' : 'debug', - ) - - const platformName = this.appendPlatformToFilename - ? `.${triple.platformArchABI}` - : '' - - debug(`Platform name: ${platformName || chalk.green('[Empty]')}`) - const distFileName = this.bin - ? cargoArtifactName! - : `${binaryName}${platformName}.node` - - const distModulePath = join(this.destDir ?? '.', distFileName) - - const parsedDist = parse(distModulePath) - - if (parsedDist.dir && !existsSync(parsedDist.dir)) { - await mkdirAsync(parsedDist.dir, { recursive: true }).catch((e) => { - console.warn( - chalk.bgYellowBright( - `Create dir [${parsedDist.dir}] failed, reason: ${e.message}`, - ), - ) - }) - } - - const sourcePath = join( - targetRootDir, - targetDir, - `${cargoArtifactName}${libExt}`, - ) - - if (existsSync(distModulePath)) { - debug(`remove old binary [${chalk.yellowBright(distModulePath)}]`) - await unlinkAsync(distModulePath) - } - - debug(`Write binary content to [${chalk.yellowBright(distModulePath)}]`) - await copyFileAsync(sourcePath, distModulePath) - - if (!this.bin) { - const dtsFilePath = join( - process.cwd(), - this.destDir ?? '.', - this.dts ?? 'index.d.ts', - ) - - const jsBindingFilePath = - this.jsBinding && - this.jsBinding !== 'false' && - this.appendPlatformToFilename - ? join(process.cwd(), this.destDir ?? '.', this.jsBinding) - : null - const idents = await processIntermediateTypeFile( - intermediateTypeFile, - dtsFilePath, - this.noDtsHeader, - tsConstEnum, - ) - await writeJsBinding( - binaryName, - this.jsPackageName ?? packageName, - jsBindingFilePath, - idents, - ) - if (this.pipe) { - if (jsBindingFilePath) { - const pipeCommand = `${this.pipe} ${jsBindingFilePath}` - console.info(`Run ${chalk.green(pipeCommand)}`) - try { - execSync(pipeCommand, { stdio: 'inherit', env: commandEnv }) - } catch (e) { - console.warn( - chalk.bgYellowBright( - 'Pipe the js binding file to command failed', - ), - e, - ) - } - } - const pipeCommand = `${this.pipe} ${dtsFilePath}` - console.info(`Run ${chalk.green(pipeCommand)}`) - try { - execSync(pipeCommand, { stdio: 'inherit', env: commandEnv }) - } catch (e) { - console.warn( - chalk.bgYellowBright('Pipe the dts file to command failed'), - e, - ) - } - } - } - } -} - -async function findUp(dir = process.cwd()): Promise { - const dist = join(dir, 'target') - if (existsSync(dist)) { - return dist - } - const dirs = dir.split(sep) - if (dirs.length < 2) { - return null - } - dirs.pop() - return findUp(dirs.join(sep)) -} - -interface TypeDef { - kind: 'fn' | 'struct' | 'impl' | 'enum' | 'interface' - name: string - original_name?: string - def: string - js_mod?: string - js_doc: string -} - -async function processIntermediateTypeFile( - source: string, - target: string, - noDtsHeader: boolean, - tsConstEnum: boolean, -): Promise { - const idents: string[] = [] - if (!existsSync(source)) { - debug(`do not find tmp type file. skip type generation`) - return idents - } - - const tmpFile = await readFileAsync(source, 'utf8') - const lines = tmpFile - .split('\n') - .map((line) => line.trim()) - .filter(Boolean) - .map((line) => { - // compatible with old version - if (line.startsWith('{')) { - return line - } else { - const [_crateName, ...rest] = line.split(':') - return rest.join(':') - } - }) - - if (!lines.length) { - return idents - } - - const allDefs = lines.map((line) => JSON.parse(line) as TypeDef) - - function convertDefs(defs: TypeDef[], nested = false): string { - const classes = new Map< - string, - { def: string; js_doc: string; original_name?: string } - >() - const impls = new Map() - let dts = '' - const nest = nested ? 2 : 0 - - defs.forEach((def) => { - switch (def.kind) { - case 'struct': - if (!nested) { - idents.push(def.name) - } - classes.set(def.name, { - original_name: def.original_name, - def: def.def, - js_doc: def.js_doc, - }) - break - case 'impl': - const existed = impls.get(def.name) - impls.set( - def.name, - `${existed ? existed + '\n' : ''}${def.js_doc}${def.def}`, - ) - break - case 'interface': - dts += - indentLines(`${def.js_doc}export interface ${def.name} {`, nest) + - '\n' - dts += indentLines(def.def, nest + 2) + '\n' - dts += indentLines(`}`, nest) + '\n' - break - case 'enum': - if (!nested) { - idents.push(def.name) - } - const enumPrefix = tsConstEnum ? ' const' : '' - dts += - indentLines( - `${def.js_doc}export${enumPrefix} enum ${def.name} {`, - nest, - ) + '\n' - dts += indentLines(def.def, nest + 2) + '\n' - dts += indentLines(`}`, nest) + '\n' - break - default: - if (!nested) { - idents.push(def.name) - } - dts += indentLines(`${def.js_doc}${def.def}`, nest) + '\n' - } - }) - - for (const [name, { js_doc, def, original_name }] of classes.entries()) { - const implDef = impls.get(name) - - if (original_name && name !== original_name) { - dts += indentLines(`export type ${original_name} = ${name}\n`, nest) - } - - dts += indentLines(`${js_doc}export class ${name} {`, nest) - - if (def) { - dts += '\n' + indentLines(def, nest + 2) - } - - if (implDef) { - dts += '\n' + indentLines(implDef, nest + 2) - } - - if (def || implDef) { - dts += '\n' - } else { - dts += ` ` - } - - dts += indentLines(`}`, nest) + '\n' - } - - return dts - } - - const topLevelDef = convertDefs(allDefs.filter((def) => !def.js_mod)) - - const namespaceDefs = Object.entries( - groupBy( - allDefs.filter((def) => def.js_mod), - 'js_mod', - ), - ).reduce((acc, [mod, defs]) => { - idents.push(mod) - return acc + `export namespace ${mod} {\n${convertDefs(defs, true)}}\n` - }, '') - - const dtsHeader = noDtsHeader - ? '' - : `/* tslint:disable */ -/* eslint-disable */ - -/* auto-generated by NAPI-RS */\n -` - - const externalDef = - topLevelDef.indexOf('ExternalObject<') > -1 || - namespaceDefs.indexOf('ExternalObject<') > -1 - ? `export class ExternalObject { - readonly '': { - readonly '': unique symbol - [K: symbol]: T - } -}\n` - : '' - - await writeFileAsync( - target, - dtsHeader + externalDef + topLevelDef + namespaceDefs, - 'utf8', - ) - return idents -} - -function indentLines(input: string, spaces: number) { - return input - .split('\n') - .map( - (line) => - ''.padEnd(spaces, ' ') + - (line.startsWith(' *') ? line.trimEnd() : line.trim()), - ) - .join('\n') -} - -async function writeJsBinding( - localName: string, - packageName: string, - distFileName: string | null, - idents: string[], -) { - if (distFileName && idents.length) { - const template = createJsBinding(localName, packageName) - const declareCodes = `const { ${idents.join(', ')} } = nativeBinding\n` - const exportsCode = idents.reduce( - (acc, cur) => `${acc}\nmodule.exports.${cur} = ${cur}`, - '', - ) - await writeFileAsync( - distFileName, - template + declareCodes + exportsCode + '\n', - 'utf8', - ) - } -} - -async function patchArmFeaturesHForArmTargets() { - let zigExePath: string - let zigLibDir: string | undefined - try { - const zigEnv = JSON.parse(execSync(`zig env`, { encoding: 'utf8' }).trim()) - zigExePath = zigEnv['zig_exe'] - zigLibDir = zigEnv['lib_dir'] - } catch (e) { - throw new Error( - 'Cannot get zig env correctly, please ensure the zig is installed correctly on your system', - ) - } - try { - const p = zigLibDir - ? join(zigLibDir, 'libc/glibc/sysdeps/arm/arm-features.h') - : join(zigExePath, '../lib/libc/glibc/sysdeps/arm/arm-features.h') - if (!existsSync(p)) { - await writeFileAsync(p, ARM_FEATURES_H, { - mode: 0o644, - }) - } - } catch (e) { - console.error( - Error( - `Cannot patch arm-features.h, error: ${ - (e as Error).message || e - }. See: https://github.com/ziglang/zig/issues/3287`, - ), - ) - } -} diff --git a/cli/src/cli.ts b/cli/src/cli.ts new file mode 100644 index 00000000..edde745b --- /dev/null +++ b/cli/src/cli.ts @@ -0,0 +1,29 @@ +import { Cli } from 'clipanion' + +import { ArtifactsCommand } from './commands/artifacts.js' +import { BuildCommand } from './commands/build.js' +import { CreateNpmDirsCommand } from './commands/create-npm-dirs.js' +import { HelpCommand } from './commands/help.js' +import { NewCommand } from './commands/new.js' +import { PrePublishCommand } from './commands/pre-publish.js' +import { RenameCommand } from './commands/rename.js' +import { UniversalizeCommand } from './commands/universalize.js' +import { VersionCommand } from './commands/version.js' +import { CLI_VERSION } from './utils/misc.js' + +const cli = new Cli({ + binaryName: 'napi', + binaryVersion: CLI_VERSION, +}) + +cli.register(NewCommand) +cli.register(BuildCommand) +cli.register(CreateNpmDirsCommand) +cli.register(ArtifactsCommand) +cli.register(UniversalizeCommand) +cli.register(RenameCommand) +cli.register(PrePublishCommand) +cli.register(VersionCommand) +cli.register(HelpCommand) + +void cli.runExit(process.argv.slice(2)) diff --git a/cli/src/commands/artifacts.ts b/cli/src/commands/artifacts.ts new file mode 100644 index 00000000..195db18f --- /dev/null +++ b/cli/src/commands/artifacts.ts @@ -0,0 +1,23 @@ +import { Command } from 'clipanion' + +import { collectArtifacts } from '../api/artifacts.js' +import { BaseArtifactsCommand } from '../def/artifacts.js' + +export class ArtifactsCommand extends BaseArtifactsCommand { + static usage = Command.Usage({ + description: 'Copy artifacts from Github Actions into specified dir', + examples: [ + [ + '$0 artifacts --dir . --dist ./npm', + `Copy [binaryName].[platform].node under current dir(.) into packages under npm dir. +e.g: index.linux-x64-gnu.node --> ./npm/linux-x64-gnu/index.node`, + ], + ], + }) + + static paths = [['artifacts']] + + async execute() { + await collectArtifacts(this.getOptions()) + } +} diff --git a/cli/src/commands/build.ts b/cli/src/commands/build.ts new file mode 100644 index 00000000..384f3b0c --- /dev/null +++ b/cli/src/commands/build.ts @@ -0,0 +1,42 @@ +import { execSync } from 'child_process' + +import { Option } from 'clipanion' + +import { buildProject } from '../api/build.js' +import { BaseBuildCommand } from '../def/build.js' +import { debugFactory } from '../utils/index.js' + +const debug = debugFactory('build') + +export class BuildCommand extends BaseBuildCommand { + pipe = Option.String('--pipe', { + description: + 'Pipe all outputs file to given command. e.g. `napi build --pipe "npx prettier --write"`', + }) + + cargoOptions = Option.Rest() + + async execute() { + const { task } = await buildProject({ + ...this.getOptions(), + cargoOptions: this.cargoOptions, + }) + + const outputs = await task + + if (this.pipe) { + for (const output of outputs) { + debug('Piping output file to command: %s', this.pipe) + try { + execSync(`${this.pipe} ${output.path}`, { + stdio: 'inherit', + cwd: this.cwd, + }) + } catch (e) { + debug.error(`Failed to pipe output file ${output.path} to command`) + debug.error(e) + } + } + } + } +} diff --git a/cli/src/commands/create-npm-dirs.ts b/cli/src/commands/create-npm-dirs.ts new file mode 100644 index 00000000..5bed874d --- /dev/null +++ b/cli/src/commands/create-npm-dirs.ts @@ -0,0 +1,8 @@ +import { createNpmDirs } from '../api/create-npm-dirs.js' +import { BaseCreateNpmDirsCommand } from '../def/create-npm-dirs.js' + +export class CreateNpmDirsCommand extends BaseCreateNpmDirsCommand { + async execute() { + await createNpmDirs(this.getOptions()) + } +} diff --git a/cli/src/help.ts b/cli/src/commands/help.ts similarity index 100% rename from cli/src/help.ts rename to cli/src/commands/help.ts diff --git a/cli/src/commands/new.ts b/cli/src/commands/new.ts new file mode 100644 index 00000000..13c9cf4a --- /dev/null +++ b/cli/src/commands/new.ts @@ -0,0 +1,138 @@ +import path from 'path' + +import { Option } from 'clipanion' +import inquirer from 'inquirer' + +import { newProject } from '../api/new.js' +import { BaseNewCommand } from '../def/new.js' +import { + AVAILABLE_TARGETS, + debugFactory, + DEFAULT_TARGETS, + TargetTriple, +} from '../utils/index.js' +import { napiEngineRequirement } from '../utils/version.js' + +const debug = debugFactory('new') + +export class NewCommand extends BaseNewCommand { + interactive = Option.Boolean('--interactive,-i', false, { + description: + 'Ask project basic information interactively without just using the default.', + }) + + async execute() { + try { + const options = await this.fetchOptions() + await newProject(options) + return 0 + } catch (e) { + debug('Failed to create new project') + debug.error(e) + return 1 + } + } + + private async fetchOptions() { + const cmdOptions = super.getOptions() + + if (this.interactive) { + return { + ...cmdOptions, + name: await this.fetchName(path.parse(cmdOptions.path).base), + minNodeApiVersion: await this.fetchNapiVersion(), + targets: await this.fetchTargets(), + license: await this.fetchLicense(), + enableTypeDef: await this.fetchTypeDef(), + enableGithubActions: await this.fetchGithubActions(), + } + } + + return cmdOptions + } + + private async fetchName(defaultName: string): Promise { + return ( + this.$$name ?? + (await inquirer + .prompt({ + type: 'input', + name: 'name', + message: 'Package name (the name field in your package.json file)', + default: defaultName, + }) + .then(({ name }) => name)) + ) + } + + private async fetchLicense(): Promise { + return inquirer + .prompt({ + type: 'input', + name: 'license', + message: 'License for open-sourced project', + default: this.license, + }) + .then(({ license }) => license) + } + + private async fetchNapiVersion(): Promise { + return inquirer + .prompt({ + type: 'list', + name: 'minNodeApiVersion', + message: 'Minimum node-api version (with node version requirement)', + loop: false, + choices: new Array(8).fill(0).map((_, i) => ({ + name: `napi${i + 1} (${napiEngineRequirement(i + 1)})`, + value: i + 1, + })), + // choice index + default: this.minNodeApiVersion - 1, + }) + .then(({ minNodeApiVersion }) => minNodeApiVersion) + } + + private async fetchTargets(): Promise { + if (this.enableDefaultTargets) { + return DEFAULT_TARGETS.concat() + } + + if (this.enableAllTargets) { + return AVAILABLE_TARGETS.concat() + } + + const { targets } = await inquirer.prompt({ + name: 'targets', + type: 'checkbox', + loop: false, + message: 'Choose target(s) your crate will be compiled to', + default: DEFAULT_TARGETS, + choices: AVAILABLE_TARGETS, + }) + + return targets + } + + private async fetchTypeDef(): Promise { + const { enableTypeDef } = await inquirer.prompt({ + name: 'enableTypeDef', + type: 'confirm', + message: 'Enable type definition auto-generation', + default: this.enableTypeDef, + }) + + return enableTypeDef + } + + private async fetchGithubActions(): Promise { + const { enableGithubActions } = await inquirer.prompt({ + name: 'enableGithubActions', + type: 'confirm', + message: 'Enable Github Actions CI', + default: this.enableGithubActions, + }) + + return enableGithubActions + } +} diff --git a/cli/src/commands/pre-publish.ts b/cli/src/commands/pre-publish.ts new file mode 100644 index 00000000..c860aa7d --- /dev/null +++ b/cli/src/commands/pre-publish.ts @@ -0,0 +1,9 @@ +import { prePublish } from '../api/pre-publish.js' +import { BasePrePublishCommand } from '../def/pre-publish.js' + +export class PrePublishCommand extends BasePrePublishCommand { + async execute() { + // @ts-expect-error const 'npm' | 'lerna' to string + await prePublish(this.getOptions()) + } +} diff --git a/cli/src/commands/rename.ts b/cli/src/commands/rename.ts new file mode 100644 index 00000000..26a6409d --- /dev/null +++ b/cli/src/commands/rename.ts @@ -0,0 +1,8 @@ +import { renameProject } from '../api/rename.js' +import { BaseRenameCommand } from '../def/rename.js' + +export class RenameCommand extends BaseRenameCommand { + async execute() { + await renameProject(this.getOptions()) + } +} diff --git a/cli/src/commands/universalize.ts b/cli/src/commands/universalize.ts new file mode 100644 index 00000000..3a6d13c7 --- /dev/null +++ b/cli/src/commands/universalize.ts @@ -0,0 +1,8 @@ +import { universalizeBinaries } from '../api/universalize.js' +import { BaseUniversalizeCommand } from '../def/universalize.js' + +export class UniversalizeCommand extends BaseUniversalizeCommand { + async execute() { + await universalizeBinaries(this.getOptions()) + } +} diff --git a/cli/src/commands/version.ts b/cli/src/commands/version.ts new file mode 100644 index 00000000..e90899b2 --- /dev/null +++ b/cli/src/commands/version.ts @@ -0,0 +1,8 @@ +import { version } from '../api/version.js' +import { BaseVersionCommand } from '../def/version.js' + +export class VersionCommand extends BaseVersionCommand { + async execute() { + await version(this.getOptions()) + } +} diff --git a/cli/src/consts.ts b/cli/src/consts.ts deleted file mode 100644 index c4d03303..00000000 --- a/cli/src/consts.ts +++ /dev/null @@ -1,40 +0,0 @@ -import { join } from 'path' - -import { DefaultPlatforms, PlatformDetail, parseTriple } from './parse-triple' - -export function getNapiConfig( - packageJson = 'package.json', - cwd = process.cwd(), -) { - const packageJsonPath = join(cwd, packageJson) - - const pkgJson = require(packageJsonPath) - const { version: packageVersion, napi, name } = pkgJson - const additionPlatforms: PlatformDetail[] = ( - napi?.triples?.additional ?? [] - ).map(parseTriple) - const defaultPlatforms = - napi?.triples?.defaults === false ? [] : [...DefaultPlatforms] - const tsConstEnum: boolean = napi?.ts?.constEnum ?? true - const platforms = [...defaultPlatforms, ...additionPlatforms] - const releaseVersion = process.env.RELEASE_VERSION - const releaseVersionWithoutPrefix = releaseVersion?.startsWith('v') - ? releaseVersion.substring(1) - : releaseVersion - const version = releaseVersionWithoutPrefix ?? packageVersion - const packageName = napi?.package?.name ?? name - const npmClient: string = napi?.npmClient ?? 'npm' - - const binaryName: string = napi?.name ?? 'index' - - return { - platforms, - version, - packageName, - binaryName, - packageJsonPath, - content: pkgJson, - npmClient, - tsConstEnum, - } -} diff --git a/cli/src/create-npm-dir.ts b/cli/src/create-npm-dir.ts deleted file mode 100644 index 9b2cfbd6..00000000 --- a/cli/src/create-npm-dir.ts +++ /dev/null @@ -1,105 +0,0 @@ -import { mkdirSync } from 'fs' -import { join } from 'path' - -import { Command, Option } from 'clipanion' -import * as chalk from 'colorette' - -import { getNapiConfig } from './consts' -import { debugFactory } from './debug' -import { PlatformDetail } from './parse-triple' -import { writeFileAsync, pick } from './utils' - -const debug = debugFactory('create-npm-dir') - -export class CreateNpmDirCommand extends Command { - static usage = Command.Usage({ - description: 'Create npm packages dir for platforms', - }) - - static paths = [['create-npm-dir']] - - static create = async ( - config: string, - targetDirPath: string, - cwd: string, - ) => { - const pkgJsonDir = config - debug(`Read content from [${chalk.yellowBright(pkgJsonDir)}]`) - const { platforms, packageName, version, binaryName, content } = - getNapiConfig(pkgJsonDir, cwd) - - for (const platformDetail of platforms) { - const targetDir = join( - targetDirPath, - 'npm', - `${platformDetail.platformArchABI}`, - ) - mkdirSync(targetDir, { - recursive: true, - }) - const binaryFileName = `${binaryName}.${platformDetail.platformArchABI}.node` - const targetPackageJson = join(targetDir, 'package.json') - debug(`Write file [${chalk.yellowBright(targetPackageJson)}]`) - const packageJson: { - name: string - libc?: string[] - } = { - name: `${packageName}-${platformDetail.platformArchABI}`, - version, - os: [platformDetail.platform], - cpu: - platformDetail.arch !== 'universal' - ? [platformDetail.arch] - : undefined, - main: binaryFileName, - files: [binaryFileName], - ...pick( - content, - 'description', - 'keywords', - 'author', - 'authors', - 'homepage', - 'license', - 'engines', - 'publishConfig', - 'repository', - 'bugs', - ), - } - // Only works with yarn 3.1+ - // https://github.com/yarnpkg/berry/pull/3981 - if (platformDetail.abi === 'gnu') { - packageJson.libc = ['glibc'] - } else if (platformDetail.abi === 'musl') { - packageJson.libc = ['musl'] - } - await writeFileAsync( - targetPackageJson, - JSON.stringify(packageJson, null, 2), - ) - const targetReadme = join(targetDir, 'README.md') - debug(`Write target README.md [${chalk.yellowBright(targetReadme)}]`) - await writeFileAsync(targetReadme, readme(packageName, platformDetail)) - } - } - - targetDir: string = Option.String('-t,--target')! - - config = Option.String('-c,--config', 'package.json') - - async execute() { - await CreateNpmDirCommand.create( - this.config, - join(process.cwd(), this.targetDir), - process.cwd(), - ) - } -} - -function readme(packageName: string, platformDetail: PlatformDetail) { - return `# \`${packageName}-${platformDetail.platformArchABI}\` - -This is the **${platformDetail.raw}** binary for \`${packageName}\` -` -} diff --git a/cli/src/debug.ts b/cli/src/debug.ts deleted file mode 100644 index d15de10e..00000000 --- a/cli/src/debug.ts +++ /dev/null @@ -1,3 +0,0 @@ -import debug from 'debug' - -export const debugFactory = (namespace: string) => debug(`napi:${namespace}`) diff --git a/cli/src/def/artifacts.ts b/cli/src/def/artifacts.ts new file mode 100644 index 00000000..d1de0c83 --- /dev/null +++ b/cli/src/def/artifacts.ts @@ -0,0 +1,79 @@ +// This file is generated by codegen/index.ts +// Do not edit this file manually +import { Command, Option } from 'clipanion' + +export abstract class BaseArtifactsCommand extends Command { + static paths = [['artifacts']] + + static usage = Command.Usage({ + description: + 'Copy artifacts from Github Actions into npm packages and ready to publish', + }) + + cwd = Option.String('--cwd', process.cwd(), { + description: + 'The working directory of where napi command will be executed in, all other paths options are relative to this path', + }) + + packageJsonPath = Option.String('--package-json-path', 'package.json', { + description: 'Path to `package.json`', + }) + + outputDir = Option.String('--output-dir,-o', './', { + description: + 'Path to the folder where all built `.node` files put, same as `--output-dir` of build command', + }) + + npmDir = Option.String('--npm-dir', 'npm', { + description: 'Path to the folder where the npm packages put', + }) + + getOptions() { + return { + cwd: this.cwd, + packageJsonPath: this.packageJsonPath, + outputDir: this.outputDir, + npmDir: this.npmDir, + } + } +} + +/** + * Copy artifacts from Github Actions into npm packages and ready to publish + */ +export interface ArtifactsOptions { + /** + * The working directory of where napi command will be executed in, all other paths options are relative to this path + * + * @default process.cwd() + */ + cwd?: string + /** + * Path to `package.json` + * + * @default 'package.json' + */ + packageJsonPath?: string + /** + * Path to the folder where all built `.node` files put, same as `--output-dir` of build command + * + * @default './' + */ + outputDir?: string + /** + * Path to the folder where the npm packages put + * + * @default 'npm' + */ + npmDir?: string +} + +export function applyDefaultArtifactsOptions(options: ArtifactsOptions) { + return { + cwd: process.cwd(), + packageJsonPath: 'package.json', + outputDir: './', + npmDir: 'npm', + ...options, + } +} diff --git a/cli/src/def/build.ts b/cli/src/def/build.ts new file mode 100644 index 00000000..7e045e0d --- /dev/null +++ b/cli/src/def/build.ts @@ -0,0 +1,242 @@ +// This file is generated by codegen/index.ts +// Do not edit this file manually +import { Command, Option } from 'clipanion' + +export abstract class BaseBuildCommand extends Command { + static paths = [['build']] + + static usage = Command.Usage({ + description: 'Build the napi-rs project', + }) + + target?: string = Option.String('--target,-t', { + description: + 'Build for the target triple, bypassed to `cargo build --target`', + }) + + cwd?: string = Option.String('--cwd', { + description: + 'The working directory of where napi command will be executed in, all other paths options are relative to this path', + }) + + manifestPath?: string = Option.String('--manifest-path', { + description: 'Path to `Cargo.toml`', + }) + + packageJsonPath?: string = Option.String('--package-json-path', { + description: 'Path to `package.json`', + }) + + targetDir?: string = Option.String('--target-dir', { + description: + 'Directory for all crate generated artifacts, see `cargo build --target-dir`', + }) + + outputDir?: string = Option.String('--output-dir,-o', { + description: + 'Path to where all the built files would be put. Default to the crate folder', + }) + + platform?: boolean = Option.Boolean('--platform', { + description: + 'Add platform triple to the generated nodejs binding file, eg: `[name].linux-x64-gnu.node`', + }) + + jsPackageName?: string = Option.String('--js-package-name', { + description: + 'Package name in generated js binding file. Only works with `--platform` flag', + }) + + jsBinding?: string = Option.String('--js', { + description: + 'Path and filename of generated JS binding file. Only works with `--platform` flag. Relative to `--output_dir`.', + }) + + noJsBinding?: boolean = Option.Boolean('--no-js', { + description: + 'Whether to disable the generation JS binding file. Only works with `--platform` flag.', + }) + + dts?: string = Option.String('--dts', { + description: + 'Path and filename of generated type def file. Relative to `--output_dir`', + }) + + dtsHeader?: string = Option.String('--dts-header', { + description: + 'Custom file header for generated type def file. Only works when `typedef` feature enabled.', + }) + + noDtsHeader?: boolean = Option.Boolean('--no-dts-header', { + description: + 'Whether to disable the default file header for generated type def file. Only works when `typedef` feature enabled.', + }) + + strip?: boolean = Option.Boolean('--strip,-s', { + description: 'Whether strip the library to achieve the minimum file size', + }) + + release?: boolean = Option.Boolean('--release,-r', { + description: 'Build in release mode', + }) + + verbose?: boolean = Option.Boolean('--verbose,-v', { + description: 'Verbosely log build command trace', + }) + + bin?: string = Option.String('--bin', { + description: 'Build only the specified binary', + }) + + package?: string = Option.String('--package,-p', { + description: 'Build the specified library or the one at cwd', + }) + + crossCompile?: boolean = Option.Boolean('--cross-compile,-x', { + description: + '[experimental] cross-compile for the specified target with `cargo-xwin` on windows and `cargo-zigbuild` on other platform', + }) + + watch?: boolean = Option.Boolean('--watch,-w', { + description: + 'watch the crate changes and build continiously with `cargo-watch` crates', + }) + + features?: string[] = Option.Array('--features,-F', { + description: 'Space-separated list of features to activate', + }) + + allFeatures?: boolean = Option.Boolean('--all-features', { + description: 'Activate all available features', + }) + + noDefaultFeatures?: boolean = Option.Boolean('--no-default-features', { + description: 'Do not activate the `default` feature', + }) + + getOptions() { + return { + target: this.target, + cwd: this.cwd, + manifestPath: this.manifestPath, + packageJsonPath: this.packageJsonPath, + targetDir: this.targetDir, + outputDir: this.outputDir, + platform: this.platform, + jsPackageName: this.jsPackageName, + jsBinding: this.jsBinding, + noJsBinding: this.noJsBinding, + dts: this.dts, + dtsHeader: this.dtsHeader, + noDtsHeader: this.noDtsHeader, + strip: this.strip, + release: this.release, + verbose: this.verbose, + bin: this.bin, + package: this.package, + crossCompile: this.crossCompile, + watch: this.watch, + features: this.features, + allFeatures: this.allFeatures, + noDefaultFeatures: this.noDefaultFeatures, + } + } +} + +/** + * Build the napi-rs project + */ +export interface BuildOptions { + /** + * Build for the target triple, bypassed to `cargo build --target` + */ + target?: string + /** + * The working directory of where napi command will be executed in, all other paths options are relative to this path + */ + cwd?: string + /** + * Path to `Cargo.toml` + */ + manifestPath?: string + /** + * Path to `package.json` + */ + packageJsonPath?: string + /** + * Directory for all crate generated artifacts, see `cargo build --target-dir` + */ + targetDir?: string + /** + * Path to where all the built files would be put. Default to the crate folder + */ + outputDir?: string + /** + * Add platform triple to the generated nodejs binding file, eg: `[name].linux-x64-gnu.node` + */ + platform?: boolean + /** + * Package name in generated js binding file. Only works with `--platform` flag + */ + jsPackageName?: string + /** + * Path and filename of generated JS binding file. Only works with `--platform` flag. Relative to `--output_dir`. + */ + jsBinding?: string + /** + * Whether to disable the generation JS binding file. Only works with `--platform` flag. + */ + noJsBinding?: boolean + /** + * Path and filename of generated type def file. Relative to `--output_dir` + */ + dts?: string + /** + * Custom file header for generated type def file. Only works when `typedef` feature enabled. + */ + dtsHeader?: string + /** + * Whether to disable the default file header for generated type def file. Only works when `typedef` feature enabled. + */ + noDtsHeader?: boolean + /** + * Whether strip the library to achieve the minimum file size + */ + strip?: boolean + /** + * Build in release mode + */ + release?: boolean + /** + * Verbosely log build command trace + */ + verbose?: boolean + /** + * Build only the specified binary + */ + bin?: string + /** + * Build the specified library or the one at cwd + */ + package?: string + /** + * [experimental] cross-compile for the specified target with `cargo-xwin` on windows and `cargo-zigbuild` on other platform + */ + crossCompile?: boolean + /** + * watch the crate changes and build continiously with `cargo-watch` crates + */ + watch?: boolean + /** + * Space-separated list of features to activate + */ + features?: string[] + /** + * Activate all available features + */ + allFeatures?: boolean + /** + * Do not activate the `default` feature + */ + noDefaultFeatures?: boolean +} diff --git a/cli/src/def/create-npm-dirs.ts b/cli/src/def/create-npm-dirs.ts new file mode 100644 index 00000000..d44bd630 --- /dev/null +++ b/cli/src/def/create-npm-dirs.ts @@ -0,0 +1,79 @@ +// This file is generated by codegen/index.ts +// Do not edit this file manually +import { Command, Option } from 'clipanion' + +export abstract class BaseCreateNpmDirsCommand extends Command { + static paths = [['create-npm-dirs']] + + static usage = Command.Usage({ + description: 'Create npm package dirs for different platforms', + }) + + cwd = Option.String('--cwd', process.cwd(), { + description: + 'The working directory of where napi command will be executed in, all other paths options are relative to this path', + }) + + packageJsonPath = Option.String('--package-json-path', 'package.json', { + description: 'Path to `package.json`', + }) + + npmDir = Option.String('--npm-dir', 'npm', { + description: 'Path to the folder where the npm packages put', + }) + + dryRun = Option.Boolean('--dry-run', false, { + description: 'Dry run without touching file system', + }) + + getOptions() { + return { + cwd: this.cwd, + packageJsonPath: this.packageJsonPath, + npmDir: this.npmDir, + dryRun: this.dryRun, + } + } +} + +/** + * Create npm package dirs for different platforms + */ +export interface CreateNpmDirsOptions { + /** + * The working directory of where napi command will be executed in, all other paths options are relative to this path + * + * @default process.cwd() + */ + cwd?: string + /** + * Path to `package.json` + * + * @default 'package.json' + */ + packageJsonPath?: string + /** + * Path to the folder where the npm packages put + * + * @default 'npm' + */ + npmDir?: string + /** + * Dry run without touching file system + * + * @default false + */ + dryRun?: boolean +} + +export function applyDefaultCreateNpmDirsOptions( + options: CreateNpmDirsOptions, +) { + return { + cwd: process.cwd(), + packageJsonPath: 'package.json', + npmDir: 'npm', + dryRun: false, + ...options, + } +} diff --git a/cli/src/def/new.ts b/cli/src/def/new.ts new file mode 100644 index 00000000..387eb050 --- /dev/null +++ b/cli/src/def/new.ts @@ -0,0 +1,144 @@ +// This file is generated by codegen/index.ts +// Do not edit this file manually +import { Command, Option } from 'clipanion' +import * as typanion from 'typanion' + +export abstract class BaseNewCommand extends Command { + static paths = [['new']] + + static usage = Command.Usage({ + description: 'Create a new project with pre-configured boilerplate', + }) + + $$path = Option.String({ required: true }) + + $$name?: string = Option.String('--name,-n', { + description: + 'The name of the project, default to the name of the directory if not provided', + }) + + minNodeApiVersion = Option.String('--min-node-api,-v', '4', { + validator: typanion.isNumber(), + description: 'The minimum Node-API version to support', + }) + + license = Option.String('--license,-l', 'MIT', { + description: 'License for open-sourced project', + }) + + targets = Option.Array('--targets,-t', [], { + description: 'All targets the crate will be compiled for.', + }) + + enableDefaultTargets = Option.Boolean('--enable-default-targets', true, { + description: 'Whether enable default targets', + }) + + enableAllTargets = Option.Boolean('--enable-all-targets', false, { + description: 'Whether enable all targets', + }) + + enableTypeDef = Option.Boolean('--enable-type-def', true, { + description: + 'Whether enable the `type-def` feature for typescript definitions auto-generation', + }) + + enableGithubActions = Option.Boolean('--enable-github-actions', true, { + description: 'Whether generate preconfigured GitHub Actions workflow', + }) + + dryRun = Option.Boolean('--dry-run', false, { + description: 'Whether to run the command in dry-run mode', + }) + + getOptions() { + return { + path: this.$$path, + name: this.$$name, + minNodeApiVersion: this.minNodeApiVersion, + license: this.license, + targets: this.targets, + enableDefaultTargets: this.enableDefaultTargets, + enableAllTargets: this.enableAllTargets, + enableTypeDef: this.enableTypeDef, + enableGithubActions: this.enableGithubActions, + dryRun: this.dryRun, + } + } +} + +/** + * Create a new project with pre-configured boilerplate + */ +export interface NewOptions { + /** + * The path where the napi-rs project will be created. + */ + path: string + /** + * The name of the project, default to the name of the directory if not provided + */ + name?: string + /** + * The minimum Node-API version to support + * + * @default 4 + */ + minNodeApiVersion?: number + /** + * License for open-sourced project + * + * @default 'MIT' + */ + license?: string + /** + * All targets the crate will be compiled for. + * + * @default [] + */ + targets?: string[] + /** + * Whether enable default targets + * + * @default true + */ + enableDefaultTargets?: boolean + /** + * Whether enable all targets + * + * @default false + */ + enableAllTargets?: boolean + /** + * Whether enable the `type-def` feature for typescript definitions auto-generation + * + * @default true + */ + enableTypeDef?: boolean + /** + * Whether generate preconfigured GitHub Actions workflow + * + * @default true + */ + enableGithubActions?: boolean + /** + * Whether to run the command in dry-run mode + * + * @default false + */ + dryRun?: boolean +} + +export function applyDefaultNewOptions(options: NewOptions) { + return { + minNodeApiVersion: 4, + license: 'MIT', + targets: [], + enableDefaultTargets: true, + enableAllTargets: false, + enableTypeDef: true, + enableGithubActions: true, + dryRun: false, + ...options, + } +} diff --git a/cli/src/def/pre-publish.ts b/cli/src/def/pre-publish.ts new file mode 100644 index 00000000..12e7b9f3 --- /dev/null +++ b/cli/src/def/pre-publish.ts @@ -0,0 +1,120 @@ +// This file is generated by codegen/index.ts +// Do not edit this file manually +import { Command, Option } from 'clipanion' + +export abstract class BasePrePublishCommand extends Command { + static paths = [['pre-publish']] + + static usage = Command.Usage({ + description: + 'Update package.json and copy addons into per platform packages', + }) + + cwd = Option.String('--cwd', process.cwd(), { + description: + 'The working directory of where napi command will be executed in, all other paths options are relative to this path', + }) + + packageJsonPath = Option.String('--package-json-path', 'package.json', { + description: 'Path to `package.json`', + }) + + npmDir = Option.String('--npm-dir', 'npm', { + description: 'Path to the folder where the npm packages put', + }) + + tagStyle = Option.String('--tag-style', 'lerna', { + description: 'git tag style, `npm` or `lerna`', + }) + + ghRelease = Option.Boolean('--gh-release', true, { + description: 'Whether create GitHub release', + }) + + ghReleaseName?: string = Option.String('--gh-release-name', { + description: 'GitHub release name', + }) + + ghReleaseId?: string = Option.String('--gh-release-id', { + description: 'Existing GitHub release id', + }) + + dryRun = Option.Boolean('--dry-run', false, { + description: 'Dry run without touching file system', + }) + + getOptions() { + return { + cwd: this.cwd, + packageJsonPath: this.packageJsonPath, + npmDir: this.npmDir, + tagStyle: this.tagStyle, + ghRelease: this.ghRelease, + ghReleaseName: this.ghReleaseName, + ghReleaseId: this.ghReleaseId, + dryRun: this.dryRun, + } + } +} + +/** + * Update package.json and copy addons into per platform packages + */ +export interface PrePublishOptions { + /** + * The working directory of where napi command will be executed in, all other paths options are relative to this path + * + * @default process.cwd() + */ + cwd?: string + /** + * Path to `package.json` + * + * @default 'package.json' + */ + packageJsonPath?: string + /** + * Path to the folder where the npm packages put + * + * @default 'npm' + */ + npmDir?: string + /** + * git tag style, `npm` or `lerna` + * + * @default 'lerna' + */ + tagStyle?: 'npm' | 'lerna' + /** + * Whether create GitHub release + * + * @default true + */ + ghRelease?: boolean + /** + * GitHub release name + */ + ghReleaseName?: string + /** + * Existing GitHub release id + */ + ghReleaseId?: string + /** + * Dry run without touching file system + * + * @default false + */ + dryRun?: boolean +} + +export function applyDefaultPrePublishOptions(options: PrePublishOptions) { + return { + cwd: process.cwd(), + packageJsonPath: 'package.json', + npmDir: 'npm', + tagStyle: 'lerna', + ghRelease: true, + dryRun: false, + ...options, + } +} diff --git a/cli/src/def/rename.ts b/cli/src/def/rename.ts new file mode 100644 index 00000000..ac54454d --- /dev/null +++ b/cli/src/def/rename.ts @@ -0,0 +1,122 @@ +// This file is generated by codegen/index.ts +// Do not edit this file manually +import { Command, Option } from 'clipanion' + +export abstract class BaseRenameCommand extends Command { + static paths = [['rename']] + + static usage = Command.Usage({ + description: 'Rename the napi-rs project', + }) + + cwd = Option.String('--cwd', process.cwd(), { + description: + 'The working directory of where napi command will be executed in, all other paths options are relative to this path', + }) + + packageJsonPath = Option.String('--package-json-path', 'package.json', { + description: 'Path to `package.json`', + }) + + npmDir = Option.String('--npm-dir', 'npm', { + description: 'Path to the folder where the npm packages put', + }) + + $$name?: string = Option.String('--name,-n', { + description: 'The new name of the project', + }) + + binaryName?: string = Option.String('--binary-name,-b', { + description: 'The new binary name *.node files', + }) + + packageName?: string = Option.String('--package-name', { + description: 'The new package name of the project', + }) + + manifestPath = Option.String('--manifest-path', 'Cargo.toml', { + description: 'Path to `Cargo.toml`', + }) + + repository?: string = Option.String('--repository', { + description: 'The new repository of the project', + }) + + description?: string = Option.String('--description', { + description: 'The new description of the project', + }) + + getOptions() { + return { + cwd: this.cwd, + packageJsonPath: this.packageJsonPath, + npmDir: this.npmDir, + name: this.$$name, + binaryName: this.binaryName, + packageName: this.packageName, + manifestPath: this.manifestPath, + repository: this.repository, + description: this.description, + } + } +} + +/** + * Rename the napi-rs project + */ +export interface RenameOptions { + /** + * The working directory of where napi command will be executed in, all other paths options are relative to this path + * + * @default process.cwd() + */ + cwd?: string + /** + * Path to `package.json` + * + * @default 'package.json' + */ + packageJsonPath?: string + /** + * Path to the folder where the npm packages put + * + * @default 'npm' + */ + npmDir?: string + /** + * The new name of the project + */ + name?: string + /** + * The new binary name *.node files + */ + binaryName?: string + /** + * The new package name of the project + */ + packageName?: string + /** + * Path to `Cargo.toml` + * + * @default 'Cargo.toml' + */ + manifestPath?: string + /** + * The new repository of the project + */ + repository?: string + /** + * The new description of the project + */ + description?: string +} + +export function applyDefaultRenameOptions(options: RenameOptions) { + return { + cwd: process.cwd(), + packageJsonPath: 'package.json', + npmDir: 'npm', + manifestPath: 'Cargo.toml', + ...options, + } +} diff --git a/cli/src/def/universalize.ts b/cli/src/def/universalize.ts new file mode 100644 index 00000000..099bb851 --- /dev/null +++ b/cli/src/def/universalize.ts @@ -0,0 +1,66 @@ +// This file is generated by codegen/index.ts +// Do not edit this file manually +import { Command, Option } from 'clipanion' + +export abstract class BaseUniversalizeCommand extends Command { + static paths = [['universalize']] + + static usage = Command.Usage({ + description: 'Combile built binaries into one universal binary', + }) + + cwd = Option.String('--cwd', process.cwd(), { + description: + 'The working directory of where napi command will be executed in, all other paths options are relative to this path', + }) + + packageJsonPath = Option.String('--package-json-path', 'package.json', { + description: 'Path to `package.json`', + }) + + outputDir = Option.String('--output-dir,-o', './', { + description: + 'Path to the folder where all built `.node` files put, same as `--output-dir` of build command', + }) + + getOptions() { + return { + cwd: this.cwd, + packageJsonPath: this.packageJsonPath, + outputDir: this.outputDir, + } + } +} + +/** + * Combile built binaries into one universal binary + */ +export interface UniversalizeOptions { + /** + * The working directory of where napi command will be executed in, all other paths options are relative to this path + * + * @default process.cwd() + */ + cwd?: string + /** + * Path to `package.json` + * + * @default 'package.json' + */ + packageJsonPath?: string + /** + * Path to the folder where all built `.node` files put, same as `--output-dir` of build command + * + * @default './' + */ + outputDir?: string +} + +export function applyDefaultUniversalizeOptions(options: UniversalizeOptions) { + return { + cwd: process.cwd(), + packageJsonPath: 'package.json', + outputDir: './', + ...options, + } +} diff --git a/cli/src/def/version.ts b/cli/src/def/version.ts new file mode 100644 index 00000000..c1fe0c2f --- /dev/null +++ b/cli/src/def/version.ts @@ -0,0 +1,65 @@ +// This file is generated by codegen/index.ts +// Do not edit this file manually +import { Command, Option } from 'clipanion' + +export abstract class BaseVersionCommand extends Command { + static paths = [['version']] + + static usage = Command.Usage({ + description: 'Update version in created npm packages', + }) + + cwd = Option.String('--cwd', process.cwd(), { + description: + 'The working directory of where napi command will be executed in, all other paths options are relative to this path', + }) + + packageJsonPath = Option.String('--package-json-path', 'package.json', { + description: 'Path to `package.json`', + }) + + npmDir = Option.String('--npm-dir', 'npm', { + description: 'Path to the folder where the npm packages put', + }) + + getOptions() { + return { + cwd: this.cwd, + packageJsonPath: this.packageJsonPath, + npmDir: this.npmDir, + } + } +} + +/** + * Update version in created npm packages + */ +export interface VersionOptions { + /** + * The working directory of where napi command will be executed in, all other paths options are relative to this path + * + * @default process.cwd() + */ + cwd?: string + /** + * Path to `package.json` + * + * @default 'package.json' + */ + packageJsonPath?: string + /** + * Path to the folder where the npm packages put + * + * @default 'npm' + */ + npmDir?: string +} + +export function applyDefaultVersionOptions(options: VersionOptions) { + return { + cwd: process.cwd(), + packageJsonPath: 'package.json', + npmDir: 'npm', + ...options, + } +} diff --git a/cli/src/index.ts b/cli/src/index.ts index c6d4fc7c..f27e478d 100644 --- a/cli/src/index.ts +++ b/cli/src/index.ts @@ -1,42 +1,31 @@ -import 'core-js/es/string/replace-all' +import { collectArtifacts } from './api/artifacts.js' +import { buildProject } from './api/build.js' +import { createNpmDirs } from './api/create-npm-dirs.js' +import { newProject } from './api/new.js' +import { prePublish } from './api/pre-publish.js' +import { renameProject } from './api/rename.js' +import { universalizeBinaries } from './api/universalize.js' +import { version } from './api/version.js' -import { Cli } from 'clipanion' - -import { version } from '../package.json' - -import { ArtifactsCommand } from './artifacts' -import { BuildCommand } from './build' -import { CreateNpmDirCommand } from './create-npm-dir' -import { HelpCommand } from './help' -import { NewProjectCommand } from './new' -import { PrePublishCommand } from './pre-publish' -import { RenameCommand } from './rename' -import { UniversalCommand } from './universal' -import { VersionCommand } from './version' - -const cli = new Cli({ - binaryName: 'napi', - binaryVersion: version, -}) - -cli.register(ArtifactsCommand) -cli.register(BuildCommand) -cli.register(CreateNpmDirCommand) -cli.register(PrePublishCommand) -cli.register(VersionCommand) -cli.register(UniversalCommand) -cli.register(NewProjectCommand) -cli.register(RenameCommand) -cli.register(HelpCommand) - -cli - .run(process.argv.slice(2), { - ...Cli.defaultContext, - }) - .then((status) => { - process.exit(status) - }) - .catch((e) => { - console.error(e) - process.exit(1) - }) +/** + * + * @usage + * + * ```ts + * const cli = new NapiCli() + * + * cli.build({ + * cwd: '/path/to/your/project', + * }) + * ``` + */ +export class NapiCli { + artifacts = collectArtifacts + new = newProject + build = buildProject + createNpmDirs = createNpmDirs + prePublish = prePublish + rename = renameProject + universalize = universalizeBinaries + version = version +} diff --git a/cli/src/js-binding-template.ts b/cli/src/js-binding-template.ts deleted file mode 100644 index d467104e..00000000 --- a/cli/src/js-binding-template.ts +++ /dev/null @@ -1,258 +0,0 @@ -export const createJsBinding = ( - localName: string, - pkgName: string, -) => `/* tslint:disable */ -/* eslint-disable */ -/* prettier-ignore */ - -/* auto-generated by NAPI-RS */ - -const { existsSync, readFileSync } = require('fs') -const { join } = require('path') - -const { platform, arch } = process - -let nativeBinding = null -let localFileExisted = false -let loadError = null - -function isMusl() { - // For Node 10 - if (!process.report || typeof process.report.getReport !== 'function') { - try { - const lddPath = require('child_process').execSync('which ldd').toString().trim() - return readFileSync(lddPath, 'utf8').includes('musl') - } catch (e) { - return true - } - } else { - const { glibcVersionRuntime } = process.report.getReport().header - return !glibcVersionRuntime - } -} - -switch (platform) { - case 'android': - switch (arch) { - case 'arm64': - localFileExisted = existsSync(join(__dirname, '${localName}.android-arm64.node')) - try { - if (localFileExisted) { - nativeBinding = require('./${localName}.android-arm64.node') - } else { - nativeBinding = require('${pkgName}-android-arm64') - } - } catch (e) { - loadError = e - } - break - case 'arm': - localFileExisted = existsSync(join(__dirname, '${localName}.android-arm-eabi.node')) - try { - if (localFileExisted) { - nativeBinding = require('./${localName}.android-arm-eabi.node') - } else { - nativeBinding = require('${pkgName}-android-arm-eabi') - } - } catch (e) { - loadError = e - } - break - default: - throw new Error(\`Unsupported architecture on Android \${arch}\`) - } - break - case 'win32': - switch (arch) { - case 'x64': - localFileExisted = existsSync( - join(__dirname, '${localName}.win32-x64-msvc.node') - ) - try { - if (localFileExisted) { - nativeBinding = require('./${localName}.win32-x64-msvc.node') - } else { - nativeBinding = require('${pkgName}-win32-x64-msvc') - } - } catch (e) { - loadError = e - } - break - case 'ia32': - localFileExisted = existsSync( - join(__dirname, '${localName}.win32-ia32-msvc.node') - ) - try { - if (localFileExisted) { - nativeBinding = require('./${localName}.win32-ia32-msvc.node') - } else { - nativeBinding = require('${pkgName}-win32-ia32-msvc') - } - } catch (e) { - loadError = e - } - break - case 'arm64': - localFileExisted = existsSync( - join(__dirname, '${localName}.win32-arm64-msvc.node') - ) - try { - if (localFileExisted) { - nativeBinding = require('./${localName}.win32-arm64-msvc.node') - } else { - nativeBinding = require('${pkgName}-win32-arm64-msvc') - } - } catch (e) { - loadError = e - } - break - default: - throw new Error(\`Unsupported architecture on Windows: \${arch}\`) - } - break - case 'darwin': - localFileExisted = existsSync(join(__dirname, '${localName}.darwin-universal.node')) - try { - if (localFileExisted) { - nativeBinding = require('./${localName}.darwin-universal.node') - } else { - nativeBinding = require('${pkgName}-darwin-universal') - } - break - } catch {} - switch (arch) { - case 'x64': - localFileExisted = existsSync(join(__dirname, '${localName}.darwin-x64.node')) - try { - if (localFileExisted) { - nativeBinding = require('./${localName}.darwin-x64.node') - } else { - nativeBinding = require('${pkgName}-darwin-x64') - } - } catch (e) { - loadError = e - } - break - case 'arm64': - localFileExisted = existsSync( - join(__dirname, '${localName}.darwin-arm64.node') - ) - try { - if (localFileExisted) { - nativeBinding = require('./${localName}.darwin-arm64.node') - } else { - nativeBinding = require('${pkgName}-darwin-arm64') - } - } catch (e) { - loadError = e - } - break - default: - throw new Error(\`Unsupported architecture on macOS: \${arch}\`) - } - break - case 'freebsd': - if (arch !== 'x64') { - throw new Error(\`Unsupported architecture on FreeBSD: \${arch}\`) - } - localFileExisted = existsSync(join(__dirname, '${localName}.freebsd-x64.node')) - try { - if (localFileExisted) { - nativeBinding = require('./${localName}.freebsd-x64.node') - } else { - nativeBinding = require('${pkgName}-freebsd-x64') - } - } catch (e) { - loadError = e - } - break - case 'linux': - switch (arch) { - case 'x64': - if (isMusl()) { - localFileExisted = existsSync( - join(__dirname, '${localName}.linux-x64-musl.node') - ) - try { - if (localFileExisted) { - nativeBinding = require('./${localName}.linux-x64-musl.node') - } else { - nativeBinding = require('${pkgName}-linux-x64-musl') - } - } catch (e) { - loadError = e - } - } else { - localFileExisted = existsSync( - join(__dirname, '${localName}.linux-x64-gnu.node') - ) - try { - if (localFileExisted) { - nativeBinding = require('./${localName}.linux-x64-gnu.node') - } else { - nativeBinding = require('${pkgName}-linux-x64-gnu') - } - } catch (e) { - loadError = e - } - } - break - case 'arm64': - if (isMusl()) { - localFileExisted = existsSync( - join(__dirname, '${localName}.linux-arm64-musl.node') - ) - try { - if (localFileExisted) { - nativeBinding = require('./${localName}.linux-arm64-musl.node') - } else { - nativeBinding = require('${pkgName}-linux-arm64-musl') - } - } catch (e) { - loadError = e - } - } else { - localFileExisted = existsSync( - join(__dirname, '${localName}.linux-arm64-gnu.node') - ) - try { - if (localFileExisted) { - nativeBinding = require('./${localName}.linux-arm64-gnu.node') - } else { - nativeBinding = require('${pkgName}-linux-arm64-gnu') - } - } catch (e) { - loadError = e - } - } - break - case 'arm': - localFileExisted = existsSync( - join(__dirname, '${localName}.linux-arm-gnueabihf.node') - ) - try { - if (localFileExisted) { - nativeBinding = require('./${localName}.linux-arm-gnueabihf.node') - } else { - nativeBinding = require('${pkgName}-linux-arm-gnueabihf') - } - } catch (e) { - loadError = e - } - break - default: - throw new Error(\`Unsupported architecture on Linux: \${arch}\`) - } - break - default: - throw new Error(\`Unsupported OS: \${platform}, architecture: \${arch}\`) -} - -if (!nativeBinding) { - if (loadError) { - throw loadError - } - throw new Error(\`Failed to load native binding\`) -} - -` diff --git a/cli/src/new/cargo-config.ts b/cli/src/new/cargo-config.ts deleted file mode 100644 index 6224eb16..00000000 --- a/cli/src/new/cargo-config.ts +++ /dev/null @@ -1,9 +0,0 @@ -export const createCargoConfig = (enableLinuxArm8Musl: boolean) => { - const result: string[] = [] - if (enableLinuxArm8Musl) { - result.push(`[target.aarch64-unknown-linux-musl] -linker = "aarch64-linux-musl-gcc" -rustflags = ["-C", "target-feature=-crt-static"]`) - } - return result.join('\n') -} diff --git a/cli/src/new/cargo.ts b/cli/src/new/cargo.ts deleted file mode 100644 index b125e2d4..00000000 --- a/cli/src/new/cargo.ts +++ /dev/null @@ -1,19 +0,0 @@ -export const createCargoContent = (name: string) => `[package] -edition = "2021" -name = "${name.replace('@', '').replace('/', '_').toLowerCase()}" -version = "0.0.0" - -[lib] -crate-type = ["cdylib"] - -[dependencies] -# Default enable napi4 feature, see https://nodejs.org/api/n-api.html#node-api-version-matrix -napi = { version = "NAPI_VERSION", default-features = false, features = ["napi4"] } -napi-derive = "NAPI_DERIVE_VERSION" - -[build-dependencies] -napi-build = "NAPI_BUILD_VERSION" - -[profile.release] -lto = true -` diff --git a/cli/src/new/index.ts b/cli/src/new/index.ts deleted file mode 100644 index 669e6f8f..00000000 --- a/cli/src/new/index.ts +++ /dev/null @@ -1,230 +0,0 @@ -import { writeFileSync, mkdirSync } from 'fs' -import { join } from 'path' - -import { Command, Option } from 'clipanion' -import * as chalk from 'colorette' -import inquirer from 'inquirer' - -import { CreateNpmDirCommand } from '../create-npm-dir' -import { debugFactory } from '../debug' -import { DefaultPlatforms } from '../parse-triple' -import { spawn } from '../spawn' - -import { createCargoContent } from './cargo' -import { createCargoConfig } from './cargo-config' -import { createGithubActionsCIYml } from './ci-yml' -import { GitIgnore } from './gitignore-template' -import { LibRs } from './lib-rs' -import { NPMIgnoreFiles } from './npmignore' -import { createPackageJson } from './package' - -const NAME_PROMOTE_NAME = 'Package name' -const DIR_PROMOTE_NAME = 'Dir name' -const ENABLE_GITHUB_ACTIONS_PROMOTE_NAME = 'Enable github actions' - -const debug = debugFactory('create') - -const BUILD_RS = `extern crate napi_build; - -fn main() { - napi_build::setup(); -} -` - -const SupportedPlatforms: string[] = [ - 'aarch64-apple-darwin', - 'aarch64-linux-android', - 'aarch64-unknown-linux-gnu', - 'aarch64-unknown-linux-musl', - 'aarch64-pc-windows-msvc', - 'armv7-unknown-linux-gnueabihf', - 'x86_64-apple-darwin', - 'x86_64-pc-windows-msvc', - 'x86_64-unknown-linux-gnu', - 'x86_64-unknown-linux-musl', - 'x86_64-unknown-freebsd', - 'i686-pc-windows-msvc', - 'armv7-linux-androideabi', - 'universal-apple-darwin', -] - -export class NewProjectCommand extends Command { - static usage = Command.Usage({ - description: 'Create a new project from scratch', - }) - - static paths = [['new']] - - name?: string = Option.String({ - name: '-n,--name', - required: false, - }) - - dirname?: string = Option.String({ - name: '-d,--dirname', - required: false, - }) - - targets?: string[] = Option.Array('--targets,-t') - - dryRun = Option.Boolean(`--dry-run`, false) - - enableGithubActions?: boolean = Option.Boolean(`--enable-github-actions`) - - async execute() { - await this.getName() - if (!this.dirname) { - const [scope, name] = this.name?.split('/') ?? [] - const defaultProjectDir = name ?? scope - const dirAnswer = await inquirer.prompt({ - type: 'input', - name: DIR_PROMOTE_NAME, - default: defaultProjectDir, - }) - - this.dirname = dirAnswer[DIR_PROMOTE_NAME] - } - - if (!this.targets) { - const { targets } = await inquirer.prompt([ - { - type: 'checkbox', - name: 'targets', - message: 'Choose targets you want to support', - default: DefaultPlatforms.map((p) => p.raw), - choices: SupportedPlatforms, - }, - ]) - - if (!targets.length) { - throw new TypeError('At least choose one target') - } - - this.targets = targets - } - - if (this.enableGithubActions === undefined) { - const answer = await inquirer.prompt([ - { - type: 'confirm', - name: ENABLE_GITHUB_ACTIONS_PROMOTE_NAME, - message: 'Enable github actions?', - default: true, - choices: SupportedPlatforms, - }, - ]) - this.enableGithubActions = answer[ENABLE_GITHUB_ACTIONS_PROMOTE_NAME] - } - - debug(`Running command: ${chalk.green('[${command}]')}`) - if (!this.dryRun) { - mkdirSync(join(process.cwd(), this.dirname!), { - recursive: true, - }) - mkdirSync(join(process.cwd(), this.dirname!, 'src'), { - recursive: true, - }) - } - - const [s, pkgName] = this.name!.split('/') - const binaryName = pkgName ?? s - - this.writeFile('Cargo.toml', createCargoContent(this.name!)) - this.writeFile('.npmignore', NPMIgnoreFiles) - this.writeFile('build.rs', BUILD_RS) - this.writeFile( - 'package.json', - JSON.stringify( - createPackageJson(this.name!, binaryName, this.targets!), - null, - 2, - ), - ) - this.writeFile('src/lib.rs', LibRs) - - mkdirSync(join(process.cwd(), this.dirname!, '__test__'), { - recursive: true, - }) - this.writeFile( - '__test__/index.spec.mjs', - `import test from 'ava' - -import { sum } from '../index.js' - -test('sum from native', (t) => { - t.is(sum(1, 2), 3) -}) -`, - ) - - if (this.enableGithubActions) { - const githubDir = join(process.cwd(), this.dirname!, '.github') - const workflowsDir = join(githubDir, 'workflows') - if (!this.dryRun) { - mkdirSync(githubDir, { recursive: true }) - mkdirSync(workflowsDir, { recursive: true }) - } - this.writeFile( - join('.github', 'workflows', 'CI.yml'), - createGithubActionsCIYml(binaryName, this.targets!), - ) - } - - await CreateNpmDirCommand.create( - 'package.json', - join(process.cwd(), this.dirname!), - join(process.cwd(), this.dirname!), - ) - - const enableLinuxArm8Musl = this.targets!.includes( - 'aarch64-unknown-linux-musl', - ) - const cargoConfig = createCargoConfig(enableLinuxArm8Musl) - if (cargoConfig.length) { - const configDir = join(process.cwd(), this.dirname!, '.cargo') - if (!this.dryRun) { - mkdirSync(configDir, { recursive: true }) - this.writeFile(join('.cargo', 'config.toml'), cargoConfig) - } - } - this.writeFile( - 'rustfmt.toml', - `tab_spaces = 2 -edition = "2021" -`, - ) - this.writeFile('.gitignore', GitIgnore) - this.writeFile('.yarnrc.yml', 'nodeLinker: node-modules') - await spawn(`yarn set version stable`, { - cwd: join(process.cwd(), this.dirname!), - }) - await spawn(`yarn install`, { - cwd: join(process.cwd(), this.dirname!), - }) - } - - private writeFile(path: string, content: string) { - const distDir = join(process.cwd(), this.dirname!) - this.context.stdout.write(chalk.green(`Writing ${chalk.blue(path)}\n`)) - if (!this.dryRun) { - writeFileSync(join(distDir, path), content) - } - } - - private async getName() { - if (!this.name) { - const nameAnswer = await inquirer.prompt({ - type: 'input', - name: NAME_PROMOTE_NAME, - suffix: ' (The name filed in your package.json)', - }) - - const name = nameAnswer[NAME_PROMOTE_NAME] - if (!name) { - await this.getName() - } else { - this.name = name - } - } - } -} diff --git a/cli/src/new/package.ts b/cli/src/new/package.ts deleted file mode 100644 index 49347b28..00000000 --- a/cli/src/new/package.ts +++ /dev/null @@ -1,64 +0,0 @@ -import { version } from '../../package.json' -import { DefaultPlatforms } from '../parse-triple' - -export const createPackageJson = ( - name: string, - binaryName: string, - targets: string[], -) => { - const pkgContent = { - name, - version: '0.0.0', - main: 'index.js', - types: 'index.d.ts', - napi: { - name: binaryName, - }, - license: 'MIT', - devDependencies: { - '@napi-rs/cli': `^${version}`, - ava: '^5.1.1', - }, - ava: { - timeout: '3m', - }, - engines: { - node: '>= 10', - }, - scripts: { - artifacts: 'napi artifacts', - build: 'napi build --platform --release', - 'build:debug': 'napi build --platform', - prepublishOnly: 'napi prepublish -t npm', - test: 'ava', - universal: 'napi universal', - version: 'napi version', - }, - } - - const triples: any = {} - - const defaultTargetsSupported = DefaultPlatforms.every((p) => - targets!.includes(p.raw), - ) - - const isOnlyDefaultTargets = - targets.length === 3 && - DefaultPlatforms.every((p) => targets.includes(p.raw)) - - if (!isOnlyDefaultTargets) { - if (!defaultTargetsSupported) { - triples.defaults = false - triples.additional = targets - } else { - triples.additional = targets.filter( - (t) => !DefaultPlatforms.map((p) => p.raw).includes(t), - ) - } - } - - // @ts-expect-error - pkgContent.napi.triples = triples - - return pkgContent -} diff --git a/cli/src/pre-publish.ts b/cli/src/pre-publish.ts deleted file mode 100644 index 4e99568c..00000000 --- a/cli/src/pre-publish.ts +++ /dev/null @@ -1,242 +0,0 @@ -import { existsSync, statSync } from 'fs' -import { join } from 'path' - -import { Octokit } from '@octokit/rest' -import { Command, Option } from 'clipanion' -import * as chalk from 'colorette' - -import { getNapiConfig } from './consts' -import { debugFactory } from './debug' -import { spawn } from './spawn' -import { updatePackageJson } from './update-package' -import { readFileAsync } from './utils' -import { VersionCommand } from './version' - -const debug = debugFactory('prepublish') - -interface PackageInfo { - name: string - version: string - tag: string -} - -export class PrePublishCommand extends Command { - static usage = Command.Usage({ - description: - 'Update package.json and copy addons into per platform packages', - }) - - static paths = [['prepublish']] - - prefix = Option.String(`-p,--prefix`, 'npm') - - tagStyle: 'npm' | 'lerna' = Option.String('--tagstyle,-t', 'lerna') - - configFileName?: string = Option.String('-c,--config') - - isDryRun = Option.Boolean('--dry-run', false) - - skipGHRelease = Option.Boolean('--skip-gh-release', false) - - ghReleaseName?: string = Option.String('--gh-release-name') - - existingReleaseId?: string = Option.String('--gh-release-id') - - async execute() { - const { - packageJsonPath, - platforms, - version, - packageName, - binaryName, - npmClient, - } = getNapiConfig(this.configFileName) - debug(`Update optionalDependencies in [${packageJsonPath}]`) - if (!this.isDryRun) { - await VersionCommand.updatePackageJson(this.prefix, this.configFileName) - await updatePackageJson(packageJsonPath, { - optionalDependencies: platforms.reduce( - (acc: Record, cur) => { - acc[`${packageName}-${cur.platformArchABI}`] = `${version}` - return acc - }, - {}, - ), - }) - } - - const { owner, repo, pkgInfo, octokit } = this.existingReleaseId - ? await this.getRepoInfo(packageName, version) - : await this.createGhRelease(packageName, version) - - for (const platformDetail of platforms) { - const pkgDir = join( - process.cwd(), - this.prefix, - `${platformDetail.platformArchABI}`, - ) - const filename = `${binaryName}.${platformDetail.platformArchABI}.node` - const dstPath = join(pkgDir, filename) - - if (!this.isDryRun) { - if (!existsSync(dstPath)) { - console.warn(`[${chalk.yellowBright(dstPath)}] doesn't exist`) - continue - } - await spawn(`${npmClient} publish`, { - cwd: pkgDir, - env: process.env, - }) - if (!this.skipGHRelease && repo && owner) { - debug( - `Start upload [${chalk.greenBright( - dstPath, - )}] to Github release, [${chalk.greenBright(pkgInfo.tag)}]`, - ) - try { - const releaseId = this.existingReleaseId - ? Number(this.existingReleaseId) - : ( - await octokit!.repos.getReleaseByTag({ - repo: repo, - owner: owner, - tag: pkgInfo.tag, - }) - ).data.id - const dstFileStats = statSync(dstPath) - const assetInfo = await octokit!.repos.uploadReleaseAsset({ - owner: owner, - repo: repo, - name: filename, - release_id: releaseId, - mediaType: { format: 'raw' }, - headers: { - 'content-length': dstFileStats.size, - 'content-type': 'application/octet-stream', - }, - // @ts-expect-error - data: await readFileAsync(dstPath), - }) - console.info(`${chalk.green(dstPath)} upload success`) - console.info( - `Download url: ${chalk.blueBright( - assetInfo.data.browser_download_url, - )}`, - ) - } catch (e) { - debug( - `Param: ${JSON.stringify( - { owner, repo, tag: pkgInfo.tag, filename: dstPath }, - null, - 2, - )}`, - ) - console.error(e) - } - } - } - } - } - - private async createGhRelease(packageName: string, version: string) { - if (this.skipGHRelease) { - return { - owner: null, - repo: null, - pkgInfo: { name: null, version: null, tag: null }, - } - } - const { repo, owner, pkgInfo, octokit } = await this.getRepoInfo( - packageName, - version, - ) - - if (!repo || !owner) { - return { - owner: null, - repo: null, - pkgInfo: { name: null, version: null, tag: null }, - } - } - - if (!this.isDryRun) { - try { - await octokit.repos.createRelease({ - owner, - repo, - tag_name: pkgInfo.tag, - name: this.ghReleaseName, - prerelease: - version.includes('alpha') || - version.includes('beta') || - version.includes('rc'), - }) - } catch (e) { - debug( - `Params: ${JSON.stringify( - { owner, repo, tag_name: pkgInfo.tag }, - null, - 2, - )}`, - ) - console.error(e) - } - } - return { owner, repo, pkgInfo, octokit } - } - - private async getRepoInfo(packageName: string, version: string) { - const headCommit = (await spawn('git log -1 --pretty=%B')) - .toString('utf8') - .trim() - const { GITHUB_REPOSITORY } = process.env - if (!GITHUB_REPOSITORY) { - return { - owner: null, - repo: null, - pkgInfo: { name: null, version: null, tag: null }, - } - } - debug(`Github repository: ${GITHUB_REPOSITORY}`) - const [owner, repo] = GITHUB_REPOSITORY.split('/') - const octokit = new Octokit({ - auth: process.env.GITHUB_TOKEN, - }) - let pkgInfo: PackageInfo | undefined - if (this.tagStyle === 'lerna') { - const packagesToPublish = headCommit - .split('\n') - .map((line) => line.trim()) - .filter((line, index) => line.length && index) - .map((line) => line.substring(2)) - .map(this.parseTag) - pkgInfo = packagesToPublish.find( - (pkgInfo) => pkgInfo.name === packageName, - ) - if (!pkgInfo) { - throw new TypeError( - `No release commit found with ${packageName}, original commit info: ${headCommit}`, - ) - } - } else { - pkgInfo = { - tag: `v${version}`, - version, - name: packageName, - } - } - return { owner, repo, pkgInfo, octokit } - } - - private parseTag(tag: string) { - const segments = tag.split('@') - const version = segments.pop()! - const name = segments.join('@') - - return { - name, - version, - tag, - } - } -} diff --git a/cli/src/rename.ts b/cli/src/rename.ts deleted file mode 100644 index 6c253550..00000000 --- a/cli/src/rename.ts +++ /dev/null @@ -1,121 +0,0 @@ -import { join } from 'path' - -import { Command, Option } from 'clipanion' -import * as chalk from 'colorette' -import inquirer from 'inquirer' -import { load, dump } from 'js-yaml' - -import { debugFactory } from './debug' -import { spawn } from './spawn' -import { readFileAsync, writeFileAsync } from './utils' - -const debug = debugFactory('rename') - -export class RenameCommand extends Command { - static paths = [['rename']] - - name = Option.String('-n', { - required: false, - description: 'The new name of the project', - }) - - napiName = Option.String('--napi-name', { - required: false, - description: 'The new napi addon name', - }) - - repository = Option.String('--repository', { - required: false, - description: 'The repository of the package', - }) - - description = Option.String('-d,--description', { - required: false, - description: 'The description of the package', - }) - - cwd = Option.String({ - required: false, - description: 'The working directory, default is [process.cwd()]', - }) - - async execute() { - const cwd = this.cwd ?? process.cwd() - const packageJson = await readFileAsync(join(cwd, 'package.json'), 'utf8') - const packageJsonData = JSON.parse(packageJson) - const name = - this.name ?? - ( - await inquirer.prompt({ - name: 'name', - type: 'input', - suffix: chalk.dim(' name field in package.json'), - }) - ).name - const napiName = - this.napiName ?? - ( - await inquirer.prompt({ - name: 'napi name', - type: 'input', - default: name.split('/')[1], - }) - )['napi name'] - debug('name: %s, napi name: %s', name, napiName) - packageJsonData.name = name - packageJsonData.napi.name = napiName - const repository = - this.repository ?? - ( - await inquirer.prompt({ - name: 'repository', - type: 'input', - suffix: chalk.dim(' Leave empty to skip'), - }) - ).repository - if (repository) { - packageJsonData.repository = repository - } - const description = - this.description ?? - ( - await inquirer.prompt({ - name: 'description', - type: 'input', - suffix: chalk.dim(' Leave empty to skip'), - }) - ).description - - if (description) { - packageJsonData.description = description - } - - await writeFileAsync( - join(cwd, 'package.json'), - JSON.stringify(packageJsonData, null, 2), - ) - - const CI = await readFileAsync( - join(cwd, '.github', 'workflows', 'CI.yml'), - 'utf8', - ) - const CIObject = load(CI) as any - CIObject.env.APP_NAME = napiName - - await writeFileAsync( - join(cwd, '.github', 'workflows', 'CI.yml'), - dump(CIObject, { - lineWidth: 1000, - }), - ) - - let tomlContent = await readFileAsync(join(cwd, 'Cargo.toml'), 'utf8') - tomlContent = tomlContent.replace( - 'name = "napi-package-template"', - `name = "${napiName}"`, - ) - await writeFileAsync(join(cwd, 'Cargo.toml'), tomlContent) - - await spawn('napi create-npm-dir -t .') - } -} diff --git a/cli/src/spawn.ts b/cli/src/spawn.ts deleted file mode 100644 index 1e21b597..00000000 --- a/cli/src/spawn.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { spawn as _spawn, SpawnOptionsWithoutStdio } from 'child_process' - -import { debugFactory } from './debug' - -const debug = debugFactory('spawn') - -export function spawn( - command: string, - options: SpawnOptionsWithoutStdio = {}, -): Promise { - const [cmd, ...args] = command.split(' ').map((s) => s.trim()) - debug(`execute ${cmd} ${args.join(' ')}`) - return new Promise((resolve, reject) => { - const spawnStream = _spawn(cmd, args, { ...options, shell: true }) - const chunks: Buffer[] = [] - process.stdin.pipe(spawnStream.stdin) - spawnStream.stdout?.on('data', (chunk) => { - chunks.push(chunk) - }) - spawnStream.stdout.pipe(process.stdout) - spawnStream.stderr.pipe(process.stderr) - spawnStream.on('close', (code) => { - if (code !== 0) { - reject() - } else { - resolve(Buffer.concat(chunks)) - } - }) - }) -} diff --git a/cli/src/universal.ts b/cli/src/universal.ts deleted file mode 100644 index c20493ff..00000000 --- a/cli/src/universal.ts +++ /dev/null @@ -1,81 +0,0 @@ -import { spawnSync } from 'child_process' -import { join } from 'path' - -import { Command, Option } from 'clipanion' -import * as chalk from 'colorette' - -import { getNapiConfig } from './consts' -import { debugFactory } from './debug' -import { UniArchsByPlatform } from './parse-triple' -import { fileExists } from './utils' - -const debug = debugFactory('universal') - -export class UniversalCommand extends Command { - static usage = Command.Usage({ - description: 'Combine built binaries to universal binaries', - }) - - static paths = [['universal']] - - sourceDir = Option.String('-d,--dir', 'artifacts') - - distDir = Option.String('--dist', '.') - - configFileName?: string = Option.String('-c,--config') - - buildUniversal: Record< - keyof typeof UniArchsByPlatform, - (binName: string, srcFiles: string[]) => string - > = { - darwin: (binName, srcFiles) => { - const outPath = join( - this.distDir, - `${binName}.${process.platform}-universal.node`, - ) - const srcPaths = srcFiles.map((f) => join(this.sourceDir, f)) - spawnSync('lipo', ['-create', '-output', outPath, ...srcPaths]) - return outPath - }, - } - - async execute() { - const { platforms, binaryName } = getNapiConfig(this.configFileName) - - const targetPlatform = platforms.find( - (p) => p.platform === process.platform && p.arch === 'universal', - ) - if (!targetPlatform) { - throw new TypeError( - `'universal' arch for platform '${process.platform}' not found in config!`, - ) - } - - const srcFiles = UniArchsByPlatform[process.platform]?.map( - (a) => `${binaryName}.${process.platform}-${a}.node`, - ) - if (!srcFiles) { - throw new TypeError( - `'universal' arch for platform '${process.platform}' not supported.`, - ) - } - - debug( - `Looking up source binaries to combine: ${chalk.yellowBright( - srcFiles.join(', '), - )}`, - ) - const srcFileLookup = await Promise.all( - srcFiles.map((f) => fileExists(join(this.sourceDir, f))), - ) - const notFoundFiles = srcFiles.filter((_f, i) => !srcFileLookup[i]) - if (notFoundFiles.length > 0) { - throw new TypeError( - `Some binary files were not found: ${JSON.stringify(notFoundFiles)}`, - ) - } - - const outPath = this.buildUniversal[process.platform](binaryName, srcFiles) - debug(`Produced universal binary: ${outPath}`) - } -} diff --git a/cli/src/update-package.ts b/cli/src/update-package.ts deleted file mode 100644 index 7498bdf7..00000000 --- a/cli/src/update-package.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { debugFactory } from './debug' -import { writeFileAsync, fileExists } from './utils' - -const debug = debugFactory('update-package') - -export async function updatePackageJson( - path: string, - partial: Record, -) { - const exists = await fileExists(path) - if (!exists) { - debug(`File not exists ${path}`) - return - } - const old = require(path) - await writeFileAsync(path, JSON.stringify({ ...old, ...partial }, null, 2)) -} diff --git a/cli/src/utils.ts b/cli/src/utils.ts deleted file mode 100644 index ccd00378..00000000 --- a/cli/src/utils.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { readFile, writeFile, copyFile, mkdir, unlink, stat } from 'fs' -import { promisify } from 'util' - -export const readFileAsync = promisify(readFile) -export const writeFileAsync = promisify(writeFile) -export const unlinkAsync = promisify(unlink) -export const copyFileAsync = promisify(copyFile) -export const mkdirAsync = promisify(mkdir) -export const statAsync = promisify(stat) - -export async function fileExists(path: string) { - const exists = await statAsync(path) - .then(() => true) - .catch(() => false) - return exists -} - -export function pick(o: O, ...keys: K[]): Pick { - return keys.reduce((acc, key) => { - acc[key] = o[key] - return acc - }, {} as O) -} diff --git a/cli/src/utils/__tests__/__fixtures__/napi_type_def b/cli/src/utils/__tests__/__fixtures__/napi_type_def new file mode 100644 index 00000000..c0f50a3a --- /dev/null +++ b/cli/src/utils/__tests__/__fixtures__/napi_type_def @@ -0,0 +1,201 @@ +{"kind": "const", "name": "DEFAULT_COST", "js_doc": "/** This is a const */\n", "def": "export const DEFAULT_COST: number", "original_name": "DEFAULT_COST"} +{"kind": "fn", "name": "getWords", "js_doc": "", "def": "export function getWords(): Array"} +{"kind": "fn", "name": "getNums", "js_doc": "/** Gets some numbers */\n", "def": "export function getNums(): Array"} +{"kind": "fn", "name": "sumNums", "js_doc": "", "def": "export function sumNums(nums: Array): number"} +{"kind": "fn", "name": "toJsObj", "js_doc": "", "def": "export function toJsObj(): object"} +{"kind": "fn", "name": "getNumArr", "js_doc": "", "def": "export function getNumArr(): number[]"} +{"kind": "fn", "name": "getNestedNumArr", "js_doc": "", "def": "export function getNestedNumArr(): number[][][]"} +{"kind": "fn", "name": "readFileAsync", "js_doc": "", "def": "export function readFileAsync(path: string): Promise"} +{"kind": "fn", "name": "asyncMultiTwo", "js_doc": "", "def": "export function asyncMultiTwo(arg: number): Promise"} +{"kind": "fn", "name": "bigintAdd", "js_doc": "", "def": "export function bigintAdd(a: bigint, b: bigint): bigint"} +{"kind": "fn", "name": "createBigInt", "js_doc": "", "def": "export function createBigInt(): bigint"} +{"kind": "fn", "name": "createBigIntI64", "js_doc": "", "def": "export function createBigIntI64(): bigint"} +{"kind": "fn", "name": "bigintGetU64AsString", "js_doc": "", "def": "export function bigintGetU64AsString(bi: bigint): string"} +{"kind": "fn", "name": "bigintFromI64", "js_doc": "", "def": "export function bigintFromI64(): bigint"} +{"kind": "fn", "name": "bigintFromI128", "js_doc": "", "def": "export function bigintFromI128(): bigint"} +{"kind": "fn", "name": "getCwd", "js_doc": "", "def": "export function getCwd(callback: (arg0: string) => void): void"} +{"kind": "fn", "name": "optionEnd", "js_doc": "", "def": "export function optionEnd(callback: (arg0: string, arg1?: string | undefined | null) => void): void"} +{"kind": "fn", "name": "optionStart", "js_doc": "", "def": "export function optionStart(callback: (arg0: string | undefined | null, arg1: string) => void): void"} +{"kind": "fn", "name": "optionStartEnd", "js_doc": "", "def": "export function optionStartEnd(callback: (arg0: string | undefined | null, arg1: string, arg2?: string | undefined | null) => void): void"} +{"kind": "fn", "name": "optionOnly", "js_doc": "", "def": "export function optionOnly(callback: (arg0?: string | undefined | null) => void): void"} +{"kind": "fn", "name": "readFile", "js_doc": "/** napi = { version = 2, features = [\"serde-json\"] } */\n", "def": "export function readFile(callback: (arg0: Error | undefined, arg1?: string | undefined | null) => void): void"} +{"kind": "fn", "name": "returnJsFunction", "js_doc": "", "def": "export function returnJsFunction(): (...args: any[]) => any"} +{"kind": "fn", "name": "callbackReturnPromise", "js_doc": "", "def": "export function callbackReturnPromise(functionInput: () => T | Promise, callback: (err: Error | null, result: T) => void): T | Promise"} +{"kind": "fn", "name": "captureErrorInCallback", "js_doc": "", "def": "export function captureErrorInCallback(cb1: () => void, cb2: (arg0: Error) => void): void"} +{"kind": "struct", "name": "Animal", "js_doc": "/**\n * `constructor` option for `struct` requires all fields to be public,\n * otherwise tag impl fn as constructor\n * #[napi(constructor)]\n */\n", "def": "/** Kind of animal */\nreadonly kind: Kind", "original_name": "Animal"} +{"kind": "impl", "name": "Animal", "js_doc": "", "def": "/** This is the constructor */\n constructor(kind: Kind, name: string)\n/** This is a factory method */\nstatic withKind(kind: Kind): Animal\nget name(): string\nset name(name: string)\nget type(): Kind\nset type(kind: Kind)\n/**\n * This is a\n * multi-line comment\n * with an emoji \uD83D\uDE80\n */\n whoami(): string\n/** This is static... */\nstatic getDogKind(): Kind\n/**\n * Here are some characters and character sequences\n * that should be escaped correctly:\n * \\[]{}/\\:\"\"{\n * }\n */\n returnOtherClass(): Dog\n returnOtherClassWithCustomConstructor(): Bird\n overrideIndividualArgOnMethod(normalTy: string, overriddenTy: {n: string}): Bird"} +{"kind": "struct", "name": "Dog", "js_doc": "", "def": "name: string\nconstructor(name: string)", "original_name": "Dog"} +{"kind": "struct", "name": "Bird", "js_doc": "", "def": "name: string", "original_name": "Bird"} +{"kind": "impl", "name": "Bird", "js_doc": "", "def": " constructor(name: string)\n getCount(): number\n getNameAsync(): Promise"} +{"kind": "struct", "name": "Blake2BHasher", "js_doc": "/** Smoking test for type generation */\n", "def": "", "original_name": "Blake2bHasher"} +{"kind": "impl", "name": "Blake2BHasher", "js_doc": "", "def": "static withKey(key: Blake2bKey): Blake2BHasher"} +{"kind": "impl", "name": "Blake2BHasher", "js_doc": "", "def": " update(data: Buffer): void"} +{"kind": "struct", "name": "Blake2BKey", "js_doc": "", "def": "", "original_name": "Blake2bKey"} +{"kind": "struct", "name": "Context", "js_doc": "", "def": "maybeNeed?: boolean\nbuffer: Uint8Array", "original_name": "Context"} +{"kind": "impl", "name": "Context", "js_doc": "", "def": " constructor()\nstatic withData(data: string): Context\nstatic withBuffer(buf: Uint8Array): Context\n method(): string"} +{"kind": "struct", "name": "AnimalWithDefaultConstructor", "js_doc": "", "def": "name: string\nkind: number\nconstructor(name: string, kind: number)", "original_name": "AnimalWithDefaultConstructor"} +{"kind": "struct", "name": "NinjaTurtle", "js_doc": "", "def": "name: string", "original_name": "NinjaTurtle"} +{"kind": "impl", "name": "NinjaTurtle", "js_doc": "", "def": "static isInstanceOf(value: unknown): boolean\n/** Create your ninja turtle! \uD83D\uDC22 */\nstatic newRaph(): NinjaTurtle\n getMaskColor(): string\n getName(): string\n returnThis(this: this): this"} +{"kind": "struct", "name": "Assets", "js_doc": "", "def": "", "original_name": "JsAssets"} +{"kind": "impl", "name": "Assets", "js_doc": "", "def": " constructor()\n get(id: number): JsAsset | null"} +{"kind": "struct", "name": "Asset", "js_doc": "", "def": "", "original_name": "JsAsset"} +{"kind": "impl", "name": "Asset", "js_doc": "", "def": " constructor()\nget filePath(): number"} +{"kind": "struct", "name": "Optional", "js_doc": "", "def": "", "original_name": "Optional"} +{"kind": "impl", "name": "Optional", "js_doc": "", "def": "static optionEnd(required: string, optional?: string | undefined | null): string\nstatic optionStart(optional: string | undefined | null, required: string): string\nstatic optionStartEnd(optional1: string | undefined | null, required: string, optional2?: string | undefined | null): string\nstatic optionOnly(optional?: string | undefined | null): string"} +{"kind": "interface", "name": "ObjectFieldClassInstance", "js_doc": "", "def": "bird: Bird", "original_name": "ObjectFieldClassInstance"} +{"kind": "fn", "name": "createObjectWithClassField", "js_doc": "", "def": "export function createObjectWithClassField(): ObjectFieldClassInstance"} +{"kind": "fn", "name": "receiveObjectWithClassField", "js_doc": "", "def": "export function receiveObjectWithClassField(object: ObjectFieldClassInstance): Bird"} +{"kind": "struct", "name": "NotWritableClass", "js_doc": "", "def": "name: string\nconstructor(name: string)", "original_name": "NotWritableClass"} +{"kind": "impl", "name": "NotWritableClass", "js_doc": "", "def": " setName(name: string): void"} +{"kind": "struct", "name": "CustomFinalize", "js_doc": "", "def": "", "original_name": "CustomFinalize"} +{"kind": "impl", "name": "CustomFinalize", "js_doc": "", "def": " constructor(width: number, height: number)"} +{"kind": "struct", "name": "Width", "js_doc": "", "def": "value: number\nconstructor(value: number)", "original_name": "Width"} +{"kind": "fn", "name": "plusOne", "js_doc": "", "def": "export function plusOne(this: Width): number"} +{"kind": "struct", "name": "ClassWithFactory", "js_doc": "", "def": "name: string", "original_name": "ClassWithFactory"} +{"kind": "impl", "name": "ClassWithFactory", "js_doc": "", "def": "static withName(name: string): ClassWithFactory\n setName(name: string): this"} +{"kind": "fn", "name": "dateToNumber", "js_doc": "", "def": "export function dateToNumber(input: Date): number"} +{"kind": "fn", "name": "chronoDateToMillis", "js_doc": "", "def": "export function chronoDateToMillis(input: Date): number"} +{"kind": "fn", "name": "chronoDateAdd1Minute", "js_doc": "", "def": "export function chronoDateAdd1Minute(input: Date): Date"} +{"kind": "interface", "name": "Dates", "js_doc": "", "def": "start: Date\nend?: Date", "original_name": "Dates"} +{"kind": "fn", "name": "eitherStringOrNumber", "js_doc": "", "def": "export function eitherStringOrNumber(input: string | number): number"} +{"kind": "fn", "name": "returnEither", "js_doc": "", "def": "export function returnEither(input: number): string | number"} +{"kind": "fn", "name": "either3", "js_doc": "", "def": "export function either3(input: string | number | boolean): number"} +{"kind": "interface", "name": "Obj", "js_doc": "", "def": "v: string | number", "original_name": "Obj"} +{"kind": "fn", "name": "either4", "js_doc": "", "def": "export function either4(input: string | number | boolean | Obj): number"} +{"kind": "struct", "name": "JsClassForEither", "js_doc": "", "def": "", "original_name": "JsClassForEither"} +{"kind": "impl", "name": "JsClassForEither", "js_doc": "", "def": " constructor()"} +{"kind": "struct", "name": "AnotherClassForEither", "js_doc": "", "def": "", "original_name": "AnotherClassForEither"} +{"kind": "impl", "name": "AnotherClassForEither", "js_doc": "", "def": " constructor()"} +{"kind": "fn", "name": "receiveClassOrNumber", "js_doc": "", "def": "export function receiveClassOrNumber(either: number | JsClassForEither): number"} +{"kind": "fn", "name": "receiveMutClassOrNumber", "js_doc": "", "def": "export function receiveMutClassOrNumber(either: number | JsClassForEither): number"} +{"kind": "fn", "name": "receiveDifferentClass", "js_doc": "", "def": "export function receiveDifferentClass(either: JsClassForEither | AnotherClassForEither): number"} +{"kind": "fn", "name": "returnEitherClass", "js_doc": "", "def": "export function returnEitherClass(input: number): number | JsClassForEither"} +{"kind": "fn", "name": "eitherFromOption", "js_doc": "", "def": "export function eitherFromOption(): JsClassForEither | undefined"} +{"kind": "interface", "name": "A", "js_doc": "", "def": "foo: number", "original_name": "A"} +{"kind": "interface", "name": "B", "js_doc": "", "def": "bar: number", "original_name": "B"} +{"kind": "interface", "name": "C", "js_doc": "", "def": "baz: number", "original_name": "C"} +{"kind": "fn", "name": "eitherFromObjects", "js_doc": "", "def": "export function eitherFromObjects(input: A | B | C): string"} +{"kind": "fn", "name": "eitherBoolOrFunction", "js_doc": "", "def": "export function eitherBoolOrFunction(input: boolean | ((...args: any[]) => any)): void"} +{"kind": "fn", "name": "promiseInEither", "js_doc": "", "def": "export function promiseInEither(input: number | Promise): Promise"} +{"kind": "enum", "name": "Kind", "js_doc": "/** default enum values are continuos i32s start from 0 */\n", "def": "/** Barks */\nDog = 0,\n /** Kills birds */\nCat = 1,\n /** Tasty */\nDuck = 2", "original_name": "Kind"} +{"kind": "enum", "name": "Empty", "js_doc": "", "def": "", "original_name": "Empty"} +{"kind": "enum", "name": "CustomNumEnum", "js_doc": "/** You could break the step and for an new continuous value. */\n", "def": "One = 1,\n Two = 2,\n Three = 3,\n Four = 4,\n Six = 6,\n Eight = 8,\n Nine = 9,\n Ten = 10", "original_name": "CustomNumEnum"} +{"kind": "fn", "name": "enumToI32", "js_doc": "", "def": "export function enumToI32(e: CustomNumEnum): number"} +{"kind": "fn", "name": "throwError", "js_doc": "", "def": "export function throwError(): void"} +{"kind": "fn", "name": "panic", "js_doc": "", "def": "export function panic(): void"} +{"kind": "fn", "name": "receiveString", "js_doc": "", "def": "export function receiveString(s: string): string"} +{"kind": "fn", "name": "customStatusCode", "js_doc": "", "def": "export function customStatusCode(): void"} +{"kind": "fn", "name": "createExternal", "js_doc": "", "def": "export function createExternal(size: number): ExternalObject"} +{"kind": "fn", "name": "createExternalString", "js_doc": "", "def": "export function createExternalString(content: string): ExternalObject"} +{"kind": "fn", "name": "getExternal", "js_doc": "", "def": "export function getExternal(external: ExternalObject): number"} +{"kind": "fn", "name": "mutateExternal", "js_doc": "", "def": "export function mutateExternal(external: ExternalObject, newVal: number): void"} +{"kind": "fn", "name": "validateArray", "js_doc": "", "def": "export function validateArray(arr: Array): number"} +{"kind": "fn", "name": "validateBuffer", "js_doc": "", "def": "export function validateBuffer(b: Buffer): number"} +{"kind": "fn", "name": "validateTypedArray", "js_doc": "", "def": "export function validateTypedArray(input: Uint8Array): number"} +{"kind": "fn", "name": "validateBigint", "js_doc": "", "def": "export function validateBigint(input: bigint): bigint"} +{"kind": "fn", "name": "validateBoolean", "js_doc": "", "def": "export function validateBoolean(i: boolean): boolean"} +{"kind": "fn", "name": "validateDate", "js_doc": "", "def": "export function validateDate(d: Date): number"} +{"kind": "fn", "name": "validateDateTime", "js_doc": "", "def": "export function validateDateTime(d: Date): number"} +{"kind": "fn", "name": "validateExternal", "js_doc": "", "def": "export function validateExternal(e: ExternalObject): number"} +{"kind": "fn", "name": "validateFunction", "js_doc": "", "def": "export function validateFunction(cb: () => number): number"} +{"kind": "fn", "name": "validateHashMap", "js_doc": "", "def": "export function validateHashMap(input: Record): number"} +{"kind": "fn", "name": "validateNull", "js_doc": "", "def": "export function validateNull(i: null): boolean"} +{"kind": "fn", "name": "validateUndefined", "js_doc": "", "def": "export function validateUndefined(i: undefined): boolean"} +{"kind": "fn", "name": "validateNumber", "js_doc": "", "def": "export function validateNumber(i: number): number"} +{"kind": "fn", "name": "validatePromise", "js_doc": "", "def": "export function validatePromise(p: Promise): Promise"} +{"kind": "fn", "name": "validateString", "js_doc": "", "def": "export function validateString(s: string): string"} +{"kind": "fn", "name": "validateSymbol", "js_doc": "", "def": "export function validateSymbol(s: symbol): boolean"} +{"kind": "fn", "name": "validateOptional", "js_doc": "", "def": "export function validateOptional(input1?: string | undefined | null, input2?: boolean | undefined | null): boolean"} +{"kind": "fn", "name": "returnUndefinedIfInvalid", "js_doc": "", "def": "export function returnUndefinedIfInvalid(input: boolean): boolean"} +{"kind": "fn", "name": "returnUndefinedIfInvalidPromise", "js_doc": "", "def": "export function returnUndefinedIfInvalidPromise(input: Promise): Promise"} +{"kind": "fn", "name": "tsRename", "js_doc": "", "def": "export function tsRename(a: { foo: number }): string[]"} +{"kind": "fn", "name": "overrideIndividualArgOnFunction", "js_doc": "", "def": "export function overrideIndividualArgOnFunction(notOverridden: string, f: () => string, notOverridden2: number): string"} +{"kind": "fn", "name": "overrideIndividualArgOnFunctionWithCbArg", "js_doc": "", "def": "export function overrideIndividualArgOnFunctionWithCbArg(callback: (town: string, name?: string | undefined | null) => string, notOverridden: number): object"} +{"kind": "struct", "name": "Fib", "js_doc": "", "def": "", "original_name": "Fib"} +{"kind": "impl", "name": "Fib", "js_doc": "", "def": "[Symbol.iterator](): Iterator"} +{"kind": "impl", "name": "Fib", "js_doc": "", "def": " constructor()"} +{"kind": "struct", "name": "Fib2", "js_doc": "", "def": "", "original_name": "Fib2"} +{"kind": "impl", "name": "Fib2", "js_doc": "", "def": "[Symbol.iterator](): Iterator"} +{"kind": "impl", "name": "Fib2", "js_doc": "", "def": "static create(seed: number): Fib2"} +{"kind": "struct", "name": "Fib3", "js_doc": "", "def": "current: number\nnext: number\nconstructor(current: number, next: number)", "original_name": "Fib3"} +{"kind": "impl", "name": "Fib3", "js_doc": "", "def": "[Symbol.iterator](): Iterator"} +{"kind": "const", "name": "ALIGNMENT", "js_doc": "", "def": "export const ALIGNMENT: number", "original_name": "ALIGNMENT", "js_mod": "xxh3"} +{"kind": "fn", "name": "xxh3_64", "js_doc": "", "def": "export function xxh3_64(input: Buffer): bigint", "js_mod": "xxh3"} +{"kind": "fn", "name": "xxh128", "js_doc": "/** xxh128 function */\n", "def": "export function xxh128(input: Buffer): bigint", "js_mod": "xxh3"} +{"kind": "struct", "name": "Xxh3", "js_doc": "/** Xxh3 class */\n", "def": "", "original_name": "Xxh3", "js_mod": "xxh3"} +{"kind": "impl", "name": "Xxh3", "js_doc": "", "def": " constructor()\n/** update */\n update(input: Buffer): void\n digest(): bigint", "js_mod": "xxh3"} +{"kind": "fn", "name": "xxh2Plus", "js_doc": "", "def": "export function xxh2Plus(a: number, b: number): number", "js_mod": "xxh2"} +{"kind": "fn", "name": "xxh3Xxh64Alias", "js_doc": "", "def": "export function xxh3Xxh64Alias(input: Buffer): bigint", "js_mod": "xxh2"} +{"kind": "fn", "name": "xxh64Alias", "js_doc": "", "def": "export function xxh64Alias(input: Buffer): bigint"} +{"kind": "fn", "name": "getMapping", "js_doc": "", "def": "export function getMapping(): Record"} +{"kind": "fn", "name": "sumMapping", "js_doc": "", "def": "export function sumMapping(nums: Record): number"} +{"kind": "fn", "name": "mapOption", "js_doc": "", "def": "export function mapOption(val?: number | undefined | null): number | null"} +{"kind": "fn", "name": "returnNull", "js_doc": "", "def": "export function returnNull(): null"} +{"kind": "fn", "name": "returnUndefined", "js_doc": "", "def": "export function returnUndefined(): void"} +{"kind": "fn", "name": "add", "js_doc": "", "def": "export function add(a: number, b: number): number"} +{"kind": "fn", "name": "fibonacci", "js_doc": "", "def": "export function fibonacci(n: number): number"} +{"kind": "fn", "name": "listObjKeys", "js_doc": "", "def": "export function listObjKeys(obj: object): Array"} +{"kind": "fn", "name": "createObj", "js_doc": "", "def": "export function createObj(): object"} +{"kind": "fn", "name": "getGlobal", "js_doc": "", "def": "export function getGlobal(): typeof global"} +{"kind": "fn", "name": "getUndefined", "js_doc": "", "def": "export function getUndefined(): void"} +{"kind": "fn", "name": "getNull", "js_doc": "", "def": "export function getNull(): null"} +{"kind": "interface", "name": "AllOptionalObject", "js_doc": "", "def": "name?: string\nage?: number", "original_name": "AllOptionalObject"} +{"kind": "fn", "name": "receiveAllOptionalObject", "js_doc": "", "def": "export function receiveAllOptionalObject(obj?: AllOptionalObject | undefined | null): void"} +{"kind": "enum", "name": "ALIAS", "js_doc": "", "def": "A = 0,\n B = 1", "original_name": "AliasedEnum"} +{"kind": "interface", "name": "AliasedStruct", "js_doc": "", "def": "a: ALIAS\nb: number", "original_name": "StructContainsAliasedEnum"} +{"kind": "fn", "name": "fnReceivedAliased", "js_doc": "", "def": "export function fnReceivedAliased(s: AliasedStruct, e: ALIAS): void"} +{"kind": "interface", "name": "StrictObject", "js_doc": "", "def": "name: string", "original_name": "StrictObject"} +{"kind": "fn", "name": "receiveStrictObject", "js_doc": "", "def": "export function receiveStrictObject(strictObject: StrictObject): void"} +{"kind": "fn", "name": "getStrFromObject", "js_doc": "", "def": "export function getStrFromObject(): void"} +{"kind": "interface", "name": "TsTypeChanged", "js_doc": "", "def": "typeOverride: object\ntypeOverrideOptional?: object", "original_name": "TsTypeChanged"} +{"kind": "fn", "name": "createObjWithProperty", "js_doc": "", "def": "export function createObjWithProperty(): { value: ArrayBuffer, get getter(): number }"} +{"kind": "fn", "name": "getterFromObj", "js_doc": "", "def": "export function getterFromObj(): number"} +{"kind": "interface", "name": "ObjectOnlyFromJs", "js_doc": "", "def": "count: number\ncallback: (err: Error | null, value: number) => any", "original_name": "ObjectOnlyFromJs"} +{"kind": "fn", "name": "receiveObjectOnlyFromJs", "js_doc": "", "def": "export function receiveObjectOnlyFromJs(obj: { count: number, callback: (err: Error | null, count: number) => void }): void"} +{"kind": "fn", "name": "asyncPlus100", "js_doc": "", "def": "export function asyncPlus100(p: Promise): Promise"} +{"kind": "struct", "name": "JsRepo", "js_doc": "", "def": "", "original_name": "JsRepo"} +{"kind": "impl", "name": "JsRepo", "js_doc": "", "def": " constructor(dir: string)\n remote(): JsRemote"} +{"kind": "struct", "name": "JsRemote", "js_doc": "", "def": "", "original_name": "JsRemote"} +{"kind": "impl", "name": "JsRemote", "js_doc": "", "def": " name(): string"} +{"kind": "struct", "name": "CssRuleList", "js_doc": "", "def": "", "original_name": "CSSRuleList"} +{"kind": "impl", "name": "CssRuleList", "js_doc": "", "def": " getRules(): Array\nget parentStyleSheet(): CSSStyleSheet\nget name(): string | null"} +{"kind": "struct", "name": "CssStyleSheet", "js_doc": "", "def": "", "original_name": "CSSStyleSheet"} +{"kind": "struct", "name": "AnotherCssStyleSheet", "js_doc": "", "def": "", "original_name": "AnotherCSSStyleSheet"} +{"kind": "impl", "name": "AnotherCssStyleSheet", "js_doc": "", "def": "get rules(): CssRuleList"} +{"kind": "impl", "name": "CssStyleSheet", "js_doc": "", "def": " constructor(name: string, rules: Array)\nget rules(): CssRuleList\n anotherCssStyleSheet(): AnotherCssStyleSheet"} +{"kind": "interface", "name": "PackageJson", "js_doc": "/** This is an interface for package.json */\n", "def": "name: string\n/** The version of the package */\nversion: string\ndependencies?: Record\ndevDependencies?: Record", "original_name": "PackageJson"} +{"kind": "fn", "name": "readPackageJson", "js_doc": "", "def": "export function readPackageJson(): PackageJson"} +{"kind": "fn", "name": "getPackageJsonName", "js_doc": "", "def": "export function getPackageJsonName(packageJson: PackageJson): string"} +{"kind": "fn", "name": "testSerdeRoundtrip", "js_doc": "", "def": "export function testSerdeRoundtrip(data: any): any"} +{"kind": "fn", "name": "contains", "js_doc": "", "def": "export function contains(source: string, target: string): boolean"} +{"kind": "fn", "name": "concatStr", "js_doc": "", "def": "export function concatStr(s: string): string"} +{"kind": "fn", "name": "concatUtf16", "js_doc": "", "def": "export function concatUtf16(s: string): string"} +{"kind": "fn", "name": "concatLatin1", "js_doc": "", "def": "export function concatLatin1(s: string): string"} +{"kind": "fn", "name": "roundtripStr", "js_doc": "", "def": "export function roundtripStr(s: string): string"} +{"kind": "fn", "name": "setSymbolInObj", "js_doc": "", "def": "export function setSymbolInObj(symbol: symbol): object"} +{"kind": "fn", "name": "createSymbol", "js_doc": "", "def": "export function createSymbol(): symbol"} +{"kind": "impl", "name": "DelaySum", "js_doc": "", "def": ""} +{"kind": "fn", "name": "withoutAbortController", "js_doc": "", "def": "export function withoutAbortController(a: number, b: number): Promise"} +{"kind": "fn", "name": "withAbortController", "js_doc": "", "def": "export function withAbortController(a: number, b: number, signal: AbortSignal): Promise"} +{"kind": "fn", "name": "callThreadsafeFunction", "js_doc": "", "def": "export function callThreadsafeFunction(callback: (...args: any[]) => any): void"} +{"kind": "fn", "name": "threadsafeFunctionThrowError", "js_doc": "", "def": "export function threadsafeFunctionThrowError(cb: (...args: any[]) => any): void"} +{"kind": "fn", "name": "threadsafeFunctionFatalMode", "js_doc": "", "def": "export function threadsafeFunctionFatalMode(cb: (...args: any[]) => any): void"} +{"kind": "fn", "name": "threadsafeFunctionFatalModeError", "js_doc": "", "def": "export function threadsafeFunctionFatalModeError(cb: (...args: any[]) => any): void"} +{"kind": "fn", "name": "threadsafeFunctionClosureCapture", "js_doc": "", "def": "export function threadsafeFunctionClosureCapture(func: (...args: any[]) => any): void"} +{"kind": "fn", "name": "tsfnCallWithCallback", "js_doc": "", "def": "export function tsfnCallWithCallback(func: (...args: any[]) => any): void"} +{"kind": "fn", "name": "tsfnAsyncCall", "js_doc": "", "def": "export function tsfnAsyncCall(func: (...args: any[]) => any): Promise"} +{"kind": "fn", "name": "acceptThreadsafeFunction", "js_doc": "", "def": "export function acceptThreadsafeFunction(func: (err: Error | null, value: number) => any): void"} +{"kind": "fn", "name": "acceptThreadsafeFunctionFatal", "js_doc": "", "def": "export function acceptThreadsafeFunctionFatal(func: (value: number) => any): void"} +{"kind": "fn", "name": "acceptThreadsafeFunctionTupleArgs", "js_doc": "", "def": "export function acceptThreadsafeFunctionTupleArgs(func: (err: Error | null, arg0: number, arg1: boolean, arg2: string) => any): void"} +{"kind": "fn", "name": "getBuffer", "js_doc": "", "def": "export function getBuffer(): Buffer"} +{"kind": "fn", "name": "appendBuffer", "js_doc": "", "def": "export function appendBuffer(buf: Buffer): Buffer"} +{"kind": "fn", "name": "getEmptyBuffer", "js_doc": "", "def": "export function getEmptyBuffer(): Buffer"} +{"kind": "fn", "name": "convertU32Array", "js_doc": "", "def": "export function convertU32Array(input: Uint32Array): Array"} +{"kind": "fn", "name": "createExternalTypedArray", "js_doc": "", "def": "export function createExternalTypedArray(): Uint32Array"} +{"kind": "fn", "name": "mutateTypedArray", "js_doc": "", "def": "export function mutateTypedArray(input: Float32Array): void"} +{"kind": "fn", "name": "derefUint8Array", "js_doc": "", "def": "export function derefUint8Array(a: Uint8Array, b: Uint8ClampedArray): number"} +{"kind": "fn", "name": "bufferPassThrough", "js_doc": "", "def": "export function bufferPassThrough(buf: Buffer): Promise"} +{"kind": "fn", "name": "arrayBufferPassThrough", "js_doc": "", "def": "export function arrayBufferPassThrough(buf: Uint8Array): Promise"} +{"kind": "impl", "name": "AsyncBuffer", "js_doc": "", "def": ""} +{"kind": "fn", "name": "asyncReduceBuffer", "js_doc": "", "def": "export function asyncReduceBuffer(buf: Buffer): Promise"} +{"kind": "fn", "name": "runScript", "js_doc": "", "def": "export function runScript(script: string): unknown"} diff --git a/cli/src/utils/__tests__/__snapshots__/target.spec.ts.md b/cli/src/utils/__tests__/__snapshots__/target.spec.ts.md new file mode 100644 index 00000000..8cd87f38 --- /dev/null +++ b/cli/src/utils/__tests__/__snapshots__/target.spec.ts.md @@ -0,0 +1,110 @@ +# Snapshot report for `src/utils/__tests__/target.spec.ts` + +The actual snapshot is saved in `target.spec.ts.snap`. + +Generated by [AVA](https://avajs.dev). + +## should parse triple correctly + +> Snapshot 1 + + [ + { + abi: null, + arch: 'arm64', + platform: 'darwin', + platformArchABI: 'darwin-arm64', + triple: 'aarch64-apple-darwin', + }, + { + abi: null, + arch: 'arm64', + platform: 'android', + platformArchABI: 'android-arm64', + triple: 'aarch64-linux-android', + }, + { + abi: 'gnu', + arch: 'arm64', + platform: 'linux', + platformArchABI: 'linux-arm64-gnu', + triple: 'aarch64-unknown-linux-gnu', + }, + { + abi: 'musl', + arch: 'arm64', + platform: 'linux', + platformArchABI: 'linux-arm64-musl', + triple: 'aarch64-unknown-linux-musl', + }, + { + abi: 'msvc', + arch: 'arm64', + platform: 'win32', + platformArchABI: 'win32-arm64-msvc', + triple: 'aarch64-pc-windows-msvc', + }, + { + abi: null, + arch: 'x64', + platform: 'darwin', + platformArchABI: 'darwin-x64', + triple: 'x86_64-apple-darwin', + }, + { + abi: 'msvc', + arch: 'x64', + platform: 'win32', + platformArchABI: 'win32-x64-msvc', + triple: 'x86_64-pc-windows-msvc', + }, + { + abi: 'gnu', + arch: 'x64', + platform: 'linux', + platformArchABI: 'linux-x64-gnu', + triple: 'x86_64-unknown-linux-gnu', + }, + { + abi: 'musl', + arch: 'x64', + platform: 'linux', + platformArchABI: 'linux-x64-musl', + triple: 'x86_64-unknown-linux-musl', + }, + { + abi: null, + arch: 'x64', + platform: 'freebsd', + platformArchABI: 'freebsd-x64', + triple: 'x86_64-unknown-freebsd', + }, + { + abi: 'msvc', + arch: 'ia32', + platform: 'win32', + platformArchABI: 'win32-ia32-msvc', + triple: 'i686-pc-windows-msvc', + }, + { + abi: 'gnueabihf', + arch: 'arm', + platform: 'linux', + platformArchABI: 'linux-arm-gnueabihf', + triple: 'armv7-unknown-linux-gnueabihf', + }, + { + abi: 'eabi', + arch: 'arm', + platform: 'android', + platformArchABI: 'android-arm-eabi', + triple: 'armv7-linux-androideabi', + }, + { + abi: null, + arch: 'universal', + platform: 'darwin', + platformArchABI: 'darwin-universal', + triple: 'universal-apple-darwin', + }, + ] diff --git a/cli/src/utils/__tests__/__snapshots__/target.spec.ts.snap b/cli/src/utils/__tests__/__snapshots__/target.spec.ts.snap new file mode 100644 index 0000000000000000000000000000000000000000..19ac3f83b2f1221924aa36f68b3db8b8f1c4e947 GIT binary patch literal 991 zcmV<510eiCRzVV zW4BE=VK-@0iqL}gA_$^KDOA*o2M;0$f+sIkQ4j?|Q4mie6a*3UQr}E=V>^>Jo2Iq! zBX861&FstUH?wou!CXE)Vol%Dih41pl{>AWd?}adDyXKVbrns$kkh)-dDGO=#oUB$ z8EOF)MQeI4lTnN68Re~)1PJ|;f|4?T&nzf_NiYMhftz3+JOod{0(c8PgKyv`XqDs^ z$=_$1>VzaYN>LOdg^3g=QbdxLDicAaBz#Itj#BAi@-~%TCO=Z?V{(fJ($C}xDrF|8 zs0=Xqn93lNi&Tb~+~Xx|YRGd`Mwq-#Wt7PmRK{p-88eXp*a?n-VKD2nGs&k0hwFD-WCvSa)^*9*bhzu6Wj}NwxD49gp#ko z6DDLAI1Vm`Ia^4uJwnM7@B#b*T@gY~M>tzpuw6yT4e$WG2EV|*C})cZw(}^-fJ@*G zcnLf)&K4DHhfvZB2EY`!3%>BSm|*LS6S5l|18HytJd1O-xM2H@k|ofg5OM@$!K}jB zl$Ev^>n{a0o;KQlc!<2}pw6^6#{I{qn&~0u!mpa6scx1oohP6g88feETn38SANpX5ESBI0UWQ-X3al_8Xe08$!4_9M;F5QmW=_p*CU9*zjEOf4S=K7acW&)!#0fZ>d1m)U-j%?a>vn%j-8)I~S=sPqTgH(^a8m znrkej(pYp{7oF9nr+QKi_f-f_sfO#J?3ycv9e6{Z!q)1!m0axxxOknY9Xl+xnB%Rt ze6+6Fhz-6^C6>KUC2PztoL(&9iWjPiYyGVjDjE8iW?CxW=uMts3HuCNZFs)vs&y+4 Nv%e3&F((!f008I0++Y9z literal 0 HcmV?d00001 diff --git a/cli/src/utils/__tests__/__snapshots__/typegen.spec.ts.md b/cli/src/utils/__tests__/__snapshots__/typegen.spec.ts.md new file mode 100644 index 00000000..5c1c2032 --- /dev/null +++ b/cli/src/utils/__tests__/__snapshots__/typegen.spec.ts.md @@ -0,0 +1,618 @@ +# Snapshot report for `src/utils/__tests__/typegen.spec.ts` + +The actual snapshot is saved in `typegen.spec.ts.snap`. + +Generated by [AVA](https://avajs.dev). + +## should ident string correctly + +> original ident is 0 + + `␊ + /**␊ + * should keep␊ + * class A {␊ + * foo = () => {}␊ + * bar = () => {}␊ + * }␊ + */␊ + class A {␊ + foo() {␊ + a = b␊ + }␊ + ␊ + bar = () => {␊ + ␊ + }␊ + boz = 1␊ + }␊ + ␊ + namespace B {␊ + namespace C {␊ + type D = A␊ + }␊ + }␊ + ` + +> original ident is 2 + + `␊ + /**␊ + * should keep␊ + * class A {␊ + * foo = () => {}␊ + * bar = () => {}␊ + * }␊ + */␊ + class A {␊ + foo() {␊ + a = b␊ + }␊ + ␊ + bar = () => {␊ + ␊ + }␊ + boz = 1␊ + }␊ + ␊ + namespace B {␊ + namespace C {␊ + type D = A␊ + }␊ + }␊ + ` + +## should process type def correctly + +> Snapshot 1 + + `␊ + export class ExternalObject {␊ + readonly '': {␊ + readonly '': unique symbol␊ + [K: symbol]: T␊ + }␊ + }␊ + /**␊ + * \`constructor\` option for \`struct\` requires all fields to be public,␊ + * otherwise tag impl fn as constructor␊ + * #[napi(constructor)]␊ + */␊ + export class Animal {␊ + /** Kind of animal */␊ + readonly kind: Kind␊ + /** This is the constructor */␊ + constructor(kind: Kind, name: string)␊ + /** This is a factory method */␊ + static withKind(kind: Kind): Animal␊ + get name(): string␊ + set name(name: string)␊ + get type(): Kind␊ + set type(kind: Kind)␊ + /**␊ + * This is a␊ + * multi-line comment␊ + * with an emoji 🚀␊ + */␊ + whoami(): string␊ + /** This is static... */␊ + static getDogKind(): Kind␊ + /**␊ + * Here are some characters and character sequences␊ + * that should be escaped correctly:␊ + * \\[]{}/\\:""{␊ + * }␊ + */␊ + returnOtherClass(): Dog␊ + returnOtherClassWithCustomConstructor(): Bird␊ + overrideIndividualArgOnMethod(normalTy: string, overriddenTy: {n: string}): Bird␊ + }␊ + ␊ + export class AnimalWithDefaultConstructor {␊ + name: string␊ + kind: number␊ + constructor(name: string, kind: number)␊ + }␊ + ␊ + export class AnotherClassForEither {␊ + constructor()␊ + }␊ + ␊ + export class AnotherCssStyleSheet {␊ + get rules(): CssRuleList␊ + }␊ + export type AnotherCSSStyleSheet = AnotherCssStyleSheet␊ + ␊ + export class Asset {␊ + constructor()␊ + get filePath(): number␊ + }␊ + export type JsAsset = Asset␊ + ␊ + export class Assets {␊ + constructor()␊ + get(id: number): JsAsset | null␊ + }␊ + export type JsAssets = Assets␊ + ␊ + export class Bird {␊ + name: string␊ + constructor(name: string)␊ + getCount(): number␊ + getNameAsync(): Promise␊ + }␊ + ␊ + /** Smoking test for type generation */␊ + export class Blake2BHasher {␊ + static withKey(key: Blake2bKey): Blake2BHasher␊ + update(data: Buffer): void␊ + }␊ + export type Blake2bHasher = Blake2BHasher␊ + ␊ + export class Blake2BKey {␊ + ␊ + }␊ + export type Blake2bKey = Blake2BKey␊ + ␊ + export class ClassWithFactory {␊ + name: string␊ + static withName(name: string): ClassWithFactory␊ + setName(name: string): this␊ + }␊ + ␊ + export class Context {␊ + maybeNeed?: boolean␊ + buffer: Uint8Array␊ + constructor()␊ + static withData(data: string): Context␊ + static withBuffer(buf: Uint8Array): Context␊ + method(): string␊ + }␊ + ␊ + export class CssRuleList {␊ + getRules(): Array␊ + get parentStyleSheet(): CSSStyleSheet␊ + get name(): string | null␊ + }␊ + export type CSSRuleList = CssRuleList␊ + ␊ + export class CssStyleSheet {␊ + constructor(name: string, rules: Array)␊ + get rules(): CssRuleList␊ + anotherCssStyleSheet(): AnotherCssStyleSheet␊ + }␊ + export type CSSStyleSheet = CssStyleSheet␊ + ␊ + export class CustomFinalize {␊ + constructor(width: number, height: number)␊ + }␊ + ␊ + export class Dog {␊ + name: string␊ + constructor(name: string)␊ + }␊ + ␊ + export class Fib {␊ + [Symbol.iterator](): Iterator␊ + constructor()␊ + }␊ + ␊ + export class Fib2 {␊ + [Symbol.iterator](): Iterator␊ + static create(seed: number): Fib2␊ + }␊ + ␊ + export class Fib3 {␊ + current: number␊ + next: number␊ + constructor(current: number, next: number)␊ + [Symbol.iterator](): Iterator␊ + }␊ + ␊ + export class JsClassForEither {␊ + constructor()␊ + }␊ + ␊ + export class JsRemote {␊ + name(): string␊ + }␊ + ␊ + export class JsRepo {␊ + constructor(dir: string)␊ + remote(): JsRemote␊ + }␊ + ␊ + export class NinjaTurtle {␊ + name: string␊ + static isInstanceOf(value: unknown): boolean␊ + /** Create your ninja turtle! 🐢 */␊ + static newRaph(): NinjaTurtle␊ + getMaskColor(): string␊ + getName(): string␊ + returnThis(this: this): this␊ + }␊ + ␊ + export class NotWritableClass {␊ + name: string␊ + constructor(name: string)␊ + setName(name: string): void␊ + }␊ + ␊ + export class Optional {␊ + static optionEnd(required: string, optional?: string | undefined | null): string␊ + static optionStart(optional: string | undefined | null, required: string): string␊ + static optionStartEnd(optional1: string | undefined | null, required: string, optional2?: string | undefined | null): string␊ + static optionOnly(optional?: string | undefined | null): string␊ + }␊ + ␊ + export class Width {␊ + value: number␊ + constructor(value: number)␊ + }␊ + ␊ + export interface A {␊ + foo: number␊ + }␊ + ␊ + export function acceptThreadsafeFunction(func: (err: Error | null, value: number) => any): void␊ + ␊ + export function acceptThreadsafeFunctionFatal(func: (value: number) => any): void␊ + ␊ + export function acceptThreadsafeFunctionTupleArgs(func: (err: Error | null, arg0: number, arg1: boolean, arg2: string) => any): void␊ + ␊ + export function add(a: number, b: number): number␊ + ␊ + export const enum ALIAS {␊ + A = 0,␊ + B = 1␊ + }␊ + ␊ + export interface AliasedStruct {␊ + a: ALIAS␊ + b: number␊ + }␊ + ␊ + export interface AllOptionalObject {␊ + name?: string␊ + age?: number␊ + }␊ + ␊ + export function appendBuffer(buf: Buffer): Buffer␊ + ␊ + export function arrayBufferPassThrough(buf: Uint8Array): Promise␊ + ␊ + export function asyncMultiTwo(arg: number): Promise␊ + ␊ + export function asyncPlus100(p: Promise): Promise␊ + ␊ + export function asyncReduceBuffer(buf: Buffer): Promise␊ + ␊ + export interface B {␊ + bar: number␊ + }␊ + ␊ + export function bigintAdd(a: bigint, b: bigint): bigint␊ + ␊ + export function bigintFromI128(): bigint␊ + ␊ + export function bigintFromI64(): bigint␊ + ␊ + export function bigintGetU64AsString(bi: bigint): string␊ + ␊ + export function bufferPassThrough(buf: Buffer): Promise␊ + ␊ + export interface C {␊ + baz: number␊ + }␊ + ␊ + export function callbackReturnPromise(functionInput: () => T | Promise, callback: (err: Error | null, result: T) => void): T | Promise␊ + ␊ + export function callThreadsafeFunction(callback: (...args: any[]) => any): void␊ + ␊ + export function captureErrorInCallback(cb1: () => void, cb2: (arg0: Error) => void): void␊ + ␊ + export function chronoDateAdd1Minute(input: Date): Date␊ + ␊ + export function chronoDateToMillis(input: Date): number␊ + ␊ + export function concatLatin1(s: string): string␊ + ␊ + export function concatStr(s: string): string␊ + ␊ + export function concatUtf16(s: string): string␊ + ␊ + export function contains(source: string, target: string): boolean␊ + ␊ + export function convertU32Array(input: Uint32Array): Array␊ + ␊ + export function createBigInt(): bigint␊ + ␊ + export function createBigIntI64(): bigint␊ + ␊ + export function createExternal(size: number): ExternalObject␊ + ␊ + export function createExternalString(content: string): ExternalObject␊ + ␊ + export function createExternalTypedArray(): Uint32Array␊ + ␊ + export function createObj(): object␊ + ␊ + export function createObjectWithClassField(): ObjectFieldClassInstance␊ + ␊ + export function createObjWithProperty(): { value: ArrayBuffer, get getter(): number }␊ + ␊ + export function createSymbol(): symbol␊ + ␊ + /** You could break the step and for an new continuous value. */␊ + export const enum CustomNumEnum {␊ + One = 1,␊ + Two = 2,␊ + Three = 3,␊ + Four = 4,␊ + Six = 6,␊ + Eight = 8,␊ + Nine = 9,␊ + Ten = 10␊ + }␊ + ␊ + export function customStatusCode(): void␊ + ␊ + export interface Dates {␊ + start: Date␊ + end?: Date␊ + }␊ + ␊ + export function dateToNumber(input: Date): number␊ + ␊ + /** This is a const */␊ + export const DEFAULT_COST: number␊ + ␊ + export function derefUint8Array(a: Uint8Array, b: Uint8ClampedArray): number␊ + ␊ + export function either3(input: string | number | boolean): number␊ + ␊ + export function either4(input: string | number | boolean | Obj): number␊ + ␊ + export function eitherBoolOrFunction(input: boolean | ((...args: any[]) => any)): void␊ + ␊ + export function eitherFromObjects(input: A | B | C): string␊ + ␊ + export function eitherFromOption(): JsClassForEither | undefined␊ + ␊ + export function eitherStringOrNumber(input: string | number): number␊ + ␊ + export const enum Empty {␊ + ␊ + }␊ + ␊ + export function enumToI32(e: CustomNumEnum): number␊ + ␊ + export function fibonacci(n: number): number␊ + ␊ + export function fnReceivedAliased(s: AliasedStruct, e: ALIAS): void␊ + ␊ + export function getBuffer(): Buffer␊ + ␊ + export function getCwd(callback: (arg0: string) => void): void␊ + ␊ + export function getEmptyBuffer(): Buffer␊ + ␊ + export function getExternal(external: ExternalObject): number␊ + ␊ + export function getGlobal(): typeof global␊ + ␊ + export function getMapping(): Record␊ + ␊ + export function getNestedNumArr(): number[][][]␊ + ␊ + export function getNull(): null␊ + ␊ + export function getNumArr(): number[]␊ + ␊ + /** Gets some numbers */␊ + export function getNums(): Array␊ + ␊ + export function getPackageJsonName(packageJson: PackageJson): string␊ + ␊ + export function getStrFromObject(): void␊ + ␊ + export function getterFromObj(): number␊ + ␊ + export function getUndefined(): void␊ + ␊ + export function getWords(): Array␊ + ␊ + /** default enum values are continuos i32s start from 0 */␊ + export const enum Kind {␊ + /** Barks */␊ + Dog = 0,␊ + /** Kills birds */␊ + Cat = 1,␊ + /** Tasty */␊ + Duck = 2␊ + }␊ + ␊ + export function listObjKeys(obj: object): Array␊ + ␊ + export function mapOption(val?: number | undefined | null): number | null␊ + ␊ + export function mutateExternal(external: ExternalObject, newVal: number): void␊ + ␊ + export function mutateTypedArray(input: Float32Array): void␊ + ␊ + export interface Obj {␊ + v: string | number␊ + }␊ + ␊ + export interface ObjectFieldClassInstance {␊ + bird: Bird␊ + }␊ + ␊ + export interface ObjectOnlyFromJs {␊ + count: number␊ + callback: (err: Error | null, value: number) => any␊ + }␊ + ␊ + export function optionEnd(callback: (arg0: string, arg1?: string | undefined | null) => void): void␊ + ␊ + export function optionOnly(callback: (arg0?: string | undefined | null) => void): void␊ + ␊ + export function optionStart(callback: (arg0: string | undefined | null, arg1: string) => void): void␊ + ␊ + export function optionStartEnd(callback: (arg0: string | undefined | null, arg1: string, arg2?: string | undefined | null) => void): void␊ + ␊ + export function overrideIndividualArgOnFunction(notOverridden: string, f: () => string, notOverridden2: number): string␊ + ␊ + export function overrideIndividualArgOnFunctionWithCbArg(callback: (town: string, name?: string | undefined | null) => string, notOverridden: number): object␊ + ␊ + /** This is an interface for package.json */␊ + export interface PackageJson {␊ + name: string␊ + /** The version of the package */␊ + version: string␊ + dependencies?: Record␊ + devDependencies?: Record␊ + }␊ + ␊ + export function panic(): void␊ + ␊ + export function plusOne(this: Width): number␊ + ␊ + export function promiseInEither(input: number | Promise): Promise␊ + ␊ + /** napi = { version = 2, features = ["serde-json"] } */␊ + export function readFile(callback: (arg0: Error | undefined, arg1?: string | undefined | null) => void): void␊ + ␊ + export function readFileAsync(path: string): Promise␊ + ␊ + export function readPackageJson(): PackageJson␊ + ␊ + export function receiveAllOptionalObject(obj?: AllOptionalObject | undefined | null): void␊ + ␊ + export function receiveClassOrNumber(either: number | JsClassForEither): number␊ + ␊ + export function receiveDifferentClass(either: JsClassForEither | AnotherClassForEither): number␊ + ␊ + export function receiveMutClassOrNumber(either: number | JsClassForEither): number␊ + ␊ + export function receiveObjectOnlyFromJs(obj: { count: number, callback: (err: Error | null, count: number) => void }): void␊ + ␊ + export function receiveObjectWithClassField(object: ObjectFieldClassInstance): Bird␊ + ␊ + export function receiveStrictObject(strictObject: StrictObject): void␊ + ␊ + export function receiveString(s: string): string␊ + ␊ + export function returnEither(input: number): string | number␊ + ␊ + export function returnEitherClass(input: number): number | JsClassForEither␊ + ␊ + export function returnJsFunction(): (...args: any[]) => any␊ + ␊ + export function returnNull(): null␊ + ␊ + export function returnUndefined(): void␊ + ␊ + export function returnUndefinedIfInvalid(input: boolean): boolean␊ + ␊ + export function returnUndefinedIfInvalidPromise(input: Promise): Promise␊ + ␊ + export function roundtripStr(s: string): string␊ + ␊ + export function runScript(script: string): unknown␊ + ␊ + export function setSymbolInObj(symbol: symbol): object␊ + ␊ + export interface StrictObject {␊ + name: string␊ + }␊ + ␊ + export function sumMapping(nums: Record): number␊ + ␊ + export function sumNums(nums: Array): number␊ + ␊ + export function testSerdeRoundtrip(data: any): any␊ + ␊ + export function threadsafeFunctionClosureCapture(func: (...args: any[]) => any): void␊ + ␊ + export function threadsafeFunctionFatalMode(cb: (...args: any[]) => any): void␊ + ␊ + export function threadsafeFunctionFatalModeError(cb: (...args: any[]) => any): void␊ + ␊ + export function threadsafeFunctionThrowError(cb: (...args: any[]) => any): void␊ + ␊ + export function throwError(): void␊ + ␊ + export function toJsObj(): object␊ + ␊ + export function tsfnAsyncCall(func: (...args: any[]) => any): Promise␊ + ␊ + export function tsfnCallWithCallback(func: (...args: any[]) => any): void␊ + ␊ + export function tsRename(a: { foo: number }): string[]␊ + ␊ + export interface TsTypeChanged {␊ + typeOverride: object␊ + typeOverrideOptional?: object␊ + }␊ + ␊ + export function validateArray(arr: Array): number␊ + ␊ + export function validateBigint(input: bigint): bigint␊ + ␊ + export function validateBoolean(i: boolean): boolean␊ + ␊ + export function validateBuffer(b: Buffer): number␊ + ␊ + export function validateDate(d: Date): number␊ + ␊ + export function validateDateTime(d: Date): number␊ + ␊ + export function validateExternal(e: ExternalObject): number␊ + ␊ + export function validateFunction(cb: () => number): number␊ + ␊ + export function validateHashMap(input: Record): number␊ + ␊ + export function validateNull(i: null): boolean␊ + ␊ + export function validateNumber(i: number): number␊ + ␊ + export function validateOptional(input1?: string | undefined | null, input2?: boolean | undefined | null): boolean␊ + ␊ + export function validatePromise(p: Promise): Promise␊ + ␊ + export function validateString(s: string): string␊ + ␊ + export function validateSymbol(s: symbol): boolean␊ + ␊ + export function validateTypedArray(input: Uint8Array): number␊ + ␊ + export function validateUndefined(i: undefined): boolean␊ + ␊ + export function withAbortController(a: number, b: number, signal: AbortSignal): Promise␊ + ␊ + export function withoutAbortController(a: number, b: number): Promise␊ + ␊ + export function xxh64Alias(input: Buffer): bigint␊ + ␊ + export namespace xxh2 {␊ + export function xxh2Plus(a: number, b: number): number␊ + export function xxh3Xxh64Alias(input: Buffer): bigint␊ + }␊ + ␊ + export namespace xxh3 {␊ + /** Xxh3 class */␊ + export class Xxh3 {␊ + constructor()␊ + /** update */␊ + update(input: Buffer): void␊ + digest(): bigint␊ + }␊ + export const ALIGNMENT: number␊ + /** xxh128 function */␊ + export function xxh128(input: Buffer): bigint␊ + export function xxh3_64(input: Buffer): bigint␊ + }␊ + ␊ + ` diff --git a/cli/src/utils/__tests__/__snapshots__/typegen.spec.ts.snap b/cli/src/utils/__tests__/__snapshots__/typegen.spec.ts.snap new file mode 100644 index 0000000000000000000000000000000000000000..7425cbeddc5f53b2ef2260ecff89d9ed09bba201 GIT binary patch literal 3961 zcmV-<4~FnTRzVrB&rEU|vv+?Gvowz*!XuVQB4oysDGAdoW1);MxJc*%C?qgM5ta1i ze|~f8cen7LU;Xyh?|=QTTPt6D_Sp*gj2JPej4kjnjHwW0KrZoNlBQ&f1U<6#kX&Bj z2q9yd)yDAuzF2V>kq-#)7akRYb)Ur7?^-JOxS`}re+*1slz}U)|EanW>{ot$Ut``CSntxJN@-1 zWz}!K{BOmq|Ne4?y<4Q2G|S(8Cs_uw9gW|DfCr<8O2>@RC{5xE^6962qjY5`Px$va zBjRE{PGj}@)z^LV__|L{LduQa09(@DCzt4Hb1fg+E zCY;3)EG{KuMi%)v=HV)eN#%@X=Ugx%>6GyK0!R}=1#!e9-5+0p4S3*;_FgN`uPl6! z@HrUyQhOQsnkNxSCxq%@kr?XH47LUS1&!R$6t!0c0Nn#oL3ZdSFhK(wzgJT zHfXw&PSwJDuJ!e7U$Kl43V%d82SsKy0|T-Qw1kZ;9${_Zs0o}F%_V14S}+0cVj`pq z7M16xugSiB_4@Mai*Nh4Z(r6?BV#hpk|XrRAvzN325NfVya0O)b0O3D(D4W$-{u)E zB|T$V28VnZjR^fIw;uB=D^Adicq8ar%4 zVb>fz3eW6wuaZo@cStj5`&5spn%ZwpPV@STVApCnT0S@RW;O8Pk79pQ8~lejd7|IKM`8M zmKNj_F509AytHJ$kn|%A#j$@HVdoLGiO>gp+uF8|MuTCRC(>D)8axELfw)LQeDN$x z=K#A8G}}YmI6S>4^Yj#R8OelHaIUnRvV>(+L3|x@w_|$BHnzW_!a9TtaO@&DW#HJF zY7Ec4ew76n@&yDn7GPw9m-%F(%yyRYsAeo9#mu!;6XewkX2j6$m4olL9KxD};=Jz} z6!&a{v)01~F!viGG%ounC7@>G@W9cQ?45SvIlUOOL&l;8BZ>V3MYJ235?TJ_73g^>jaskMn z$nrodWN;6@H!k|m74Q{vZ&mQ6p<@l0+7VL0RZaC?7nDKD>A@+rd>?)_R#1VwF09iL zX%90@{sU_)`n&dP|&y${uc^IaKYX8VZnr9?I=|n2=pFoQG_n#{nXTr{p=|Tm1 zM-P2$52!dDrm@c83Vlqdtc>YA5OdoAp;`lW8*U$_@ts^)BVAT+Lr+Y z;XAAFW7{^&nj08%Dp+))_FOT+d`bf5YMxznSz~*Yb=#%@jYp2_(kVW6ILBhalE_Wo zihNrC@UUPyqhCG)Z-z}u^Xbf!`Pqu09DL}JhV{h(HWNnYX#m^f7}*N2;mptcEY8LH zojbvz!EkL6$1KW2=CwkbfN~>ri*HP`E<2C0ohJv{q4a}tDE+f%f3z{~ffoDg8~20j zQQo_|obWM|&+pwGK#qv65{$W{jB%ePr+?QQ#?k{mV-1b5e&{k*NaJ`+!_#9GL#@!! z!@yGPCyN}CBi)D{!O1UaRts)FI%G_Mv-QbH@#47$y{jVp3V8t3nQ3ip4SW~EJmATz z*GrKlqzhOYQ>yJJLn9{$$Ln@gI*|*0%tE2Rx1;bE&e`Ft21xlaR`%5F?ZIKs4ib3j;Xb4XB^X$@;zP(o4z{5eP{3 zLZ=*qya6&bM}kceeIm|SCZBI^DA=-gKp-AQWmsEP6*~NZHI+Rv;zKGWR##>!{nvLP zsx$UYnu8;$9y3s#s%ruv*+TWEu~SA9tTmLs!YNI2p;cLPTV`cmp-c9|e7=iMh@wXc z!^8qJ42YfZb3^?EoWk)WVo!z~` z^QWWlhDRr(cF>Ag#wKNEf?>IQQlVKrf?Lh4M|VIVQ|0ug)!Jz^DbM-QLd{YUcbAHQ zU*N_|1#JWMQC5U1Bej$fw1uqJz@p`1exZ+D5grC0ZX5m#J3!fCR!OTa|7+a{r-o{i zpyBE$t9nVzSe^O#?tCFli?=xk5RB6O&5Zy6p>p6l>^DPVv*3NC3aG)wO0Sf)X=7+Tu}% zX+X^5I2}`kq}b9-CuFJyytD^UyI|-7VlZi%MGtJCZw-Ces9}J?5$q})=@Q#ty~h9f z86a)cgt1?brYwz9kMWj9-An3m;UHCw-|297>HZA15em8|B284gXHh;w?p;1~oI{WT zURECB28g?qvN-NR_qIK^$F@`43)mx1FJBoe(sz^kh^jCs)V;0^j)3@^8$yQ@G6AK? z9eGE@LcXwE!5#o+1#3`mkC znCEMDAp%HYY#!5GW1VqM7X}E=R2Qj0c~2Lqc;|P)c`n_oaM=OG&hq)6@qK|+{vFeD zorKPS?OvQxCk<{%0bo+y;cB3>x0}(H$?0+twyANuUFXHV9D3^$d&`#2$B?UgvMuU+Td2B+cHOv9>(ajOM7me^feZG3Tv232 zNh*(u?#Ig!P8F`E}tB;-syYD922eGe7U z+0Jr0&oN!lgoo|HXc6ZEswZZH%pt`kt1zH(s`_M9EgsrKlftQQ_=my(Z~!3nOrc zuy`3g~B9?U5rI;itvf~ZZ(hac33#ap(Efj`w6tLSHt@qqiam>`W zMihgR^L>K~F50`Dc1?MLMgr^A;fy9zrrQA6M>4rFD-2N`J}N)vFz-D_O+gS|s_AYq zM#Jl#7R$P=u5}6|Tz2zYuxT_4__ffp;4+ul&h6|n{dUwxwM(!2T=Eg0--M-XQoKid z&SH8FnXJQ%|e ze$t$!aSS`^`#fls2tHLEI7NM;9_H^xOeYn_wK5z1#6%J3Tl{B{_Qm2 z(O=7Ygl*uLHcLK;@-l9|T&l^HUzg3ImHQGO^yhP`qhLF~YUHJ*Y<|nGx%J-|(458J zAE>LMViCTN_!JTx=O$kN<-AI>dGK`q@!`Sl;mBD!&IC%YZ`?1J?<(us1V83!v4!7; T-`%_0VZ8qX6t`>QaXJ71&SIRo literal 0 HcmV?d00001 diff --git a/cli/src/utils/__tests__/__snapshots__/version.spec.ts.md b/cli/src/utils/__tests__/__snapshots__/version.spec.ts.md new file mode 100644 index 00000000..23bf153b --- /dev/null +++ b/cli/src/utils/__tests__/__snapshots__/version.spec.ts.md @@ -0,0 +1,20 @@ +# Snapshot report for `src/utils/__tests__/version.spec.ts` + +The actual snapshot is saved in `version.spec.ts.snap`. + +Generated by [AVA](https://avajs.dev). + +## should generate correct napi engine requirement + +> Snapshot 1 + + [ + '>= 8.6.0', + '>= 8.10.0 && < 9 || >= 9.3.0', + '>= 6.14.2 && < 7 || >= 8.11.2 && < 9 || >= 9.11.0', + '>= 10.16.0 && < 11 || >= 11.8.0', + '>= 10.17.0 && < 11 || >= 12.11.0', + '>= 10.20.0 && < 11 || >= 12.17.0 && < 13 || >= 14.0.0', + '>= 10.23.0 && < 11 || >= 12.19.0 && < 13 || >= 14.12.0', + '>= 12.22.0 && < 13 || >= 14.17.0 && < 15 || >= 15.12.0', + ] diff --git a/cli/src/utils/__tests__/__snapshots__/version.spec.ts.snap b/cli/src/utils/__tests__/__snapshots__/version.spec.ts.snap new file mode 100644 index 0000000000000000000000000000000000000000..8e7feceb5ef11294941f2b33697fd4102fb1760e GIT binary patch literal 364 zcmV-y0h9hgRzV}GiKoo}Ofb?QaNY$l@v+8nWhC)lcB<@_fcZo0}5kZG( zqDeRP9ejZLI6i@oANQ$y2@jk~-Igd^@Wjt9g;qOqNo`TGFIa zN+z0?@k>r+ndPOVO1{o>C7)%f^BM!(=z6(I(^$uM)}c-MMkstyKIDV7^?}C9sbS0teWz$T8RioDmGJF6oSg%xeMwlboy*?lF&! z$Mk|mbg`i5Ma*y8mT7ZLLdGXdY}(VNjRbDImVn+CVH?CLMtF{g<|60K0PC}MuxAFe z8BG5V#LfxFEP~BKc%6%u;~RIvycW|ln6Sb4otUT#gTa>5-{A-*MCYRYoxr%kn)3^X K+`?dI0ssI;Jg>a~ literal 0 HcmV?d00001 diff --git a/cli/src/utils/__tests__/target.spec.ts b/cli/src/utils/__tests__/target.spec.ts new file mode 100644 index 00000000..a788cfc1 --- /dev/null +++ b/cli/src/utils/__tests__/target.spec.ts @@ -0,0 +1,19 @@ +import os from 'os' + +import test from 'ava' + +import { + parseTriple, + getSystemDefaultTarget, + AVAILABLE_TARGETS, +} from '../target.js' + +test('should parse triple correctly', (t) => { + t.snapshot(AVAILABLE_TARGETS.map(parseTriple)) +}) + +test('should get system default target correctly', (t) => { + const target = getSystemDefaultTarget() + + t.is(target.platform, os.platform()) +}) diff --git a/cli/src/utils/__tests__/typegen.spec.ts b/cli/src/utils/__tests__/typegen.spec.ts new file mode 100644 index 00000000..0b6516a7 --- /dev/null +++ b/cli/src/utils/__tests__/typegen.spec.ts @@ -0,0 +1,49 @@ +import { join } from 'path' +import { fileURLToPath } from 'url' + +import test from 'ava' + +import { correctStringIdent, processTypeDef } from '../typegen.js' + +test('should ident string correctly', (t) => { + const input = ` + /** + * should keep + * class A { + * foo = () => {} + * bar = () => {} + * } + */ + class A { + foo() { + a = b + } + + bar = () => { + + } + boz = 1 + } + + namespace B { + namespace C { + type D = A + } + } +` + t.snapshot(correctStringIdent(input, 0), 'original ident is 0') + t.snapshot(correctStringIdent(input, 2), 'original ident is 2') +}) + +test('should process type def correctly', async (t) => { + const dts = await processTypeDef( + join( + fileURLToPath(import.meta.url), + '../', + '__fixtures__', + 'napi_type_def', + ), + ) + + t.snapshot(dts) +}) diff --git a/cli/src/utils/__tests__/version.spec.ts b/cli/src/utils/__tests__/version.spec.ts new file mode 100644 index 00000000..d198b15b --- /dev/null +++ b/cli/src/utils/__tests__/version.spec.ts @@ -0,0 +1,13 @@ +import test from 'ava' + +import { napiEngineRequirement, NapiVersion } from '../version.js' + +test('should generate correct napi engine requirement', (t) => { + t.snapshot( + ( + Object.values(NapiVersion).filter( + (v) => typeof v === 'number', + ) as NapiVersion[] + ).map(napiEngineRequirement), + ) +}) diff --git a/cli/src/utils/cargo.ts b/cli/src/utils/cargo.ts new file mode 100644 index 00000000..d538184a --- /dev/null +++ b/cli/src/utils/cargo.ts @@ -0,0 +1,35 @@ +import { execSync } from 'child_process' + +import { debug } from './log.js' + +export function tryInstallCargoBinary(name: string, bin: string) { + if (detectCargoBinary(bin)) { + debug('Cargo binary already installed: %s', name) + return + } + + try { + debug('Installing cargo binary: %s', name) + execSync(`cargo install ${name}`, { + stdio: 'inherit', + }) + } catch (e) { + throw new Error(`Failed to install cargo binary: ${name}`, { + cause: e, + }) + } +} + +function detectCargoBinary(bin: string) { + debug('Detecting cargo binary: %s', bin) + try { + execSync(`cargo help ${bin}`, { + stdio: 'ignore', + }) + debug('Cargo binary detected: %s', bin) + return true + } catch (e) { + debug('Cargo binary not detected: %s', bin) + return false + } +} diff --git a/cli/src/utils/ci.ts b/cli/src/utils/ci.ts new file mode 100644 index 00000000..3084bb38 --- /dev/null +++ b/cli/src/utils/ci.ts @@ -0,0 +1,102 @@ +import { TargetTriple } from './target.js' + +export const CIConfig: Partial< + Record< + TargetTriple, + { + host: string + build_image?: string + build_setup?: string[] + test?: boolean + test_image?: string + test_setup?: string[] + yarn_cpu?: string + yarn_libc?: string + } + > +> = { + 'x86_64-apple-darwin': { + host: 'macos-latest', + }, + 'x86_64-pc-windows-msvc': { + host: 'windows-latest', + }, + 'i686-pc-windows-msvc': { + host: 'windows-latest', + test: false, + }, + 'x86_64-unknown-linux-gnu': { + host: 'ubuntu-latest', + build_image: 'ghcr.io/napi-rs/napi-rs/nodejs-rust:lts-debian', + }, + 'x86_64-unknown-linux-musl': { + host: 'ubuntu-latest', + build_image: 'ghcr.io/napi-rs/napi-rs/nodejs-rust:lts-alpine', + test_image: 'node:${{ matrix.node }}-alpine', + yarn_libc: 'musl', + }, + 'aarch64-apple-darwin': { + host: 'macos-latest', + build_setup: [ + 'sudo rm -Rf /Library/Developer/CommandLineTools/SDKs/*', + 'export CC=$(xcrun -f clang)', + 'export CXX=$(xcrun -f clang++)', + 'export SDK_ROOT=$(xcrun --sdk macosx --show-sdk-path)', + 'export CFLAGS="-isysroot $SDK_ROOT -isystem $SDK_ROOT"', + ], + test: false, + }, + 'aarch64-unknown-linux-gnu': { + host: 'ubuntu-latest', + build_image: 'ghcr.io/napi-rs/napi-rs/nodejs-rust:lts-debian-aarch64', + build_setup: [ + 'sudo apt-get update', + 'sudo apt-get install g++-aarch64-linux-gnu gcc-aarch64-linux-gnu -y', + 'export CARGO_BUILD_TARGET=x86_64-unknown-linux-gnu', + ], + test_image: 'ghcr.io/napi-rs/napi-rs/nodejs:aarch64-${{ matrix.node }}', + yarn_cpu: 'arm64', + }, + 'aarch64-unknown-linux-musl': { + host: 'ubuntu-latest', + build_image: 'ghcr.io/napi-rs/napi-rs/nodejs-rust:lts-alpine', + build_setup: ['rustup target add aarch64-unknown-linux-musl'], + test_image: 'multiarch/alpine:aarch64-latest-stable', + test_setup: ['apk add nodejs npm yarn'], + yarn_cpu: 'arm64', + yarn_libc: 'musl', + }, + 'aarch64-pc-windows-msvc': { + host: 'windows-latest', + test: false, + }, + 'armv7-unknown-linux-gnueabihf': { + host: 'ubuntu-latest', + build_setup: [ + 'sudo apt-get update', + 'sudo apt-get install gcc-arm-linux-gnueabihf g++-arm-linux-gnueabihf -y', + ], + yarn_cpu: 'arm', + test_image: 'ghcr.io/napi-rs/napi-rs/nodejs:armhf-${{ matrix.node }}', + }, + 'aarch64-linux-android': { + host: 'ubuntu-latest', + build_setup: [ + 'export CARGO_TARGET_AARCH64_LINUX_ANDROID_LINKER="${ANDROID_NDK_HOME}/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android24-clang"', + 'export CC="${ANDROID_NDK_HOME}/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android24-clang"', + 'export CXX="${ANDROID_NDK_HOME}/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android24-clang++"', + 'export PATH="${ANDROID_NDK_HOME}/toolchains/llvm/prebuilt/linux-x86_64/bin:${PATH}"', + ], + test: false, + }, + 'armv7-linux-androideabi': { + host: 'ubuntu-latest', + build_setup: [ + 'export CARGO_TARGET_ARMV7_LINUX_ANDROIDEABI_LINKER="${ANDROID_NDK_HOME}/toolchains/llvm/prebuilt/linux-x86_64/bin/armv7a-linux-androideabi24-clang"', + 'export CC="${ANDROID_NDK_HOME}/toolchains/llvm/prebuilt/linux-x86_64/bin/armv7a-linux-androideabi24-clang"', + 'export CXX="${ANDROID_NDK_HOME}/toolchains/llvm/prebuilt/linux-x86_64/bin/armv7a-linux-androideabi24-clang++"', + 'export PATH="${ANDROID_NDK_HOME}/toolchains/llvm/prebuilt/linux-x86_64/bin:${PATH}"', + ], + test: false, + }, +} diff --git a/cli/src/utils/config.ts b/cli/src/utils/config.ts new file mode 100644 index 00000000..2ad2f02e --- /dev/null +++ b/cli/src/utils/config.ts @@ -0,0 +1,123 @@ +import { merge, omit } from 'lodash-es' + +import { fileExists, readFileAsync } from './misc.js' +import { DEFAULT_TARGETS, parseTriple, Target } from './target.js' + +interface UserNapiConfig { + /** + * Name of the binary to be generated, default to `index` + */ + binaryName?: string + /** + * Name of the npm package, default to the name of root package.json name + * + * Always given `@scope/pkg` and arch suffix will be appended like `@scope/pkg-linux-gnu-x64` + */ + packageName?: string + /** + * All targets the crate will be compiled for + */ + targets?: string[] + + /** + * The npm client project uses. + */ + npmClient?: string + + /** + * @deprecated binaryName instead + */ + name?: string + /** + * @deprecated use packageName instead + */ + package?: { + name?: string + } + /** + * @deprecated use targets instead + */ + triples?: { + /** + * Whether enable default targets + */ + default: boolean + /** + * Additional targets to be compiled for + */ + additional?: string[] + } +} + +interface CommonPackageJsonFields { + name: string + version: string + description?: string + keywords?: string[] + author?: string + authors?: string[] + license?: string + repository?: any + homepage?: any + engines?: Record + publishConfig?: any + bugs?: any + // eslint-disable-next-line no-use-before-define + napi?: UserNapiConfig +} + +export type NapiConfig = Required< + Pick +> & { + targets: Target[] + packageJson: CommonPackageJsonFields +} + +export async function readNapiConfig(path: string): Promise { + if (!(await fileExists(path))) { + throw new Error(`napi-rs config not found at ${path}`) + } + // May support multiple config sources later on. + const content = await readFileAsync(path, 'utf8') + let pkgJson + try { + pkgJson = JSON.parse(content) as CommonPackageJsonFields + } catch (e) { + throw new Error('Failed to parse napi-rs config', { + cause: e, + }) + } + + const userNapiConfig = pkgJson.napi ?? {} + const napiConfig: NapiConfig = merge( + { + binaryName: 'index', + packageName: pkgJson.name, + targets: [], + packageJson: pkgJson, + npmClient: 'npm', + }, + omit(userNapiConfig, 'targets'), + ) + + let targets: string[] = userNapiConfig.targets ?? [] + + // compatible with old config + if (userNapiConfig.package?.name) { + napiConfig.packageName = userNapiConfig.package.name + } + + if (!targets.length) { + if (userNapiConfig.triples?.default) { + targets = targets.concat(DEFAULT_TARGETS) + } + + if (userNapiConfig.triples?.additional?.length) { + targets = targets.concat(userNapiConfig.triples.additional) + } + } + + napiConfig.targets = targets.map(parseTriple) + + return napiConfig +} diff --git a/cli/src/utils/index.ts b/cli/src/utils/index.ts new file mode 100644 index 00000000..14b584a1 --- /dev/null +++ b/cli/src/utils/index.ts @@ -0,0 +1,9 @@ +export * from './ci.js' +export * from './log.js' +export * from './misc.js' +export * from './target.js' +export * from './version.js' +export * from './metadata.js' +export * from './config.js' +export * from './cargo.js' +export * from './typegen.js' diff --git a/cli/src/utils/log.ts b/cli/src/utils/log.ts new file mode 100644 index 00000000..f55629a3 --- /dev/null +++ b/cli/src/utils/log.ts @@ -0,0 +1,34 @@ +import * as colors from 'colorette' +import rawDebug from 'debug' + +// debug('%i', 'This is an info') +rawDebug.formatters.i = (v) => { + return colors.green(v) +} + +declare module 'debug' { + interface Debugger { + info: typeof console.error + warn: typeof console.error + error: typeof console.error + } +} + +export const debugFactory = (namespace: string) => { + const debug = rawDebug(`napi:${namespace}`) + + debug.info = (...args: any[]) => + console.error(colors.black(colors.bgGreen(' INFO ')), ...args) + debug.warn = (...args: any[]) => + console.error(colors.black(colors.bgYellow(' WARNING ')), ...args) + debug.error = (...args: any[]) => + console.error( + colors.white(colors.bgRed(' ERROR ')), + ...args.map((arg) => + arg instanceof Error ? arg.stack ?? arg.message : arg, + ), + ) + + return debug +} +export const debug = debugFactory('utils') diff --git a/cli/src/utils/metadata.ts b/cli/src/utils/metadata.ts new file mode 100644 index 00000000..935943e6 --- /dev/null +++ b/cli/src/utils/metadata.ts @@ -0,0 +1,59 @@ +import { execSync } from 'child_process' +import fs from 'fs' + +export type CrateTargetKind = + | 'bin' + | 'example' + | 'test' + | 'bench' + | 'lib' + | 'rlib' + | 'cdylib' + | 'custom-build' + +export interface CrateTarget { + name: string + kind: CrateTargetKind[] + crate_types: CrateTargetKind[] +} + +export interface Crate { + id: string + name: string + src_path: string + version: string + edition: string + targets: CrateTarget[] + features: Record + manifest_path: string +} + +export interface CargoWorkspaceMetadata { + version: number + packages: Crate[] + workspace_members: string[] + target_directory: string + workspace_root: string +} + +export function parseMetadata(manifestPath: string) { + if (!fs.existsSync(manifestPath)) { + throw new Error(`No crate found in manifest: ${manifestPath}`) + } + + const cmd = `cargo metadata --manifest-path ${manifestPath} --format-version 1 --no-deps` + + try { + const output = execSync(cmd, { + encoding: 'utf-8', + }) + return JSON.parse(output) as CargoWorkspaceMetadata + } catch (e) { + throw new Error( + `Failed to parse cargo metadata output by command: ${cmd}`, + { + cause: e, + }, + ) + } +} diff --git a/cli/src/utils/misc.ts b/cli/src/utils/misc.ts new file mode 100644 index 00000000..885224e1 --- /dev/null +++ b/cli/src/utils/misc.ts @@ -0,0 +1,45 @@ +import { readFile, writeFile, copyFile, mkdir, unlink, stat, readdir } from 'fs' +import { createRequire } from 'module' +import { promisify } from 'util' + +import { debug } from './log.js' + +const require = createRequire(import.meta.url) +const pkgJson = require('../../package.json') + +export const readFileAsync = promisify(readFile) +export const writeFileAsync = promisify(writeFile) +export const unlinkAsync = promisify(unlink) +export const copyFileAsync = promisify(copyFile) +export const mkdirAsync = promisify(mkdir) +export const statAsync = promisify(stat) +export const readdirAsync = promisify(readdir) + +export async function fileExists(path: string) { + const exists = await statAsync(path) + .then(() => true) + .catch(() => false) + return exists +} + +export function pick(o: O, ...keys: K[]): Pick { + return keys.reduce((acc, key) => { + acc[key] = o[key] + return acc + }, {} as O) +} + +export async function updatePackageJson( + path: string, + partial: Record, +) { + const exists = await fileExists(path) + if (!exists) { + debug(`File not exists ${path}`) + return + } + const old = require(path) + await writeFileAsync(path, JSON.stringify({ ...old, ...partial }, null, 2)) +} + +export const CLI_VERSION = pkgJson.version diff --git a/cli/src/parse-triple.ts b/cli/src/utils/target.ts similarity index 50% rename from cli/src/parse-triple.ts rename to cli/src/utils/target.ts index 987b9867..16aa18e5 100644 --- a/cli/src/parse-triple.ts +++ b/cli/src/utils/target.ts @@ -1,5 +1,36 @@ import { execSync } from 'child_process' +export const AVAILABLE_TARGETS = [ + 'aarch64-apple-darwin', + 'aarch64-linux-android', + 'aarch64-unknown-linux-gnu', + 'aarch64-unknown-linux-musl', + 'aarch64-pc-windows-msvc', + 'x86_64-apple-darwin', + 'x86_64-pc-windows-msvc', + 'x86_64-unknown-linux-gnu', + 'x86_64-unknown-linux-musl', + 'x86_64-unknown-freebsd', + 'i686-pc-windows-msvc', + 'armv7-unknown-linux-gnueabihf', + 'armv7-linux-androideabi', + 'universal-apple-darwin', +] as const + +export type TargetTriple = (typeof AVAILABLE_TARGETS)[number] + +export const DEFAULT_TARGETS = [ + 'x86_64-apple-darwin', + 'x86_64-pc-windows-msvc', + 'x86_64-unknown-linux-gnu', +] as const + +export const TARGET_LINKER: Record = { + 'aarch64-unknown-linux-gnu': 'aarch64-linux-gnu-gcc', + 'armv7-unknown-linux-gnueabihf': 'arm-linux-gnueabihf-gcc', + 'aarch64-unknown-linux-musl': 'aarch64-linux-musl-gcc', +} + // https://nodejs.org/api/process.html#process_process_arch type NodeJSArch = | 'arm' @@ -14,65 +45,42 @@ type NodeJSArch = | 'x32' | 'x64' | 'universal' - | 'wasm32' -const CpuToNodeArch: { [index: string]: NodeJSArch } = { +const CpuToNodeArch: Record = { x86_64: 'x64', aarch64: 'arm64', i686: 'ia32', armv7: 'arm', } -export const NodeArchToCpu: { [index: string]: string } = { +export const NodeArchToCpu: Record = { x64: 'x86_64', arm64: 'aarch64', ia32: 'i686', arm: 'armv7', } -const SysToNodePlatform: { [index: string]: NodeJS.Platform } = { +const SysToNodePlatform: Record = { linux: 'linux', freebsd: 'freebsd', darwin: 'darwin', windows: 'win32', } -export const UniArchsByPlatform: Record = { +export const UniArchsByPlatform: Partial< + Record +> = { darwin: ['x64', 'arm64'], } -export interface PlatformDetail { - platform: NodeJS.Platform | 'wasi' +export interface Target { + triple: string platformArchABI: string + platform: NodeJS.Platform arch: NodeJSArch - raw: string abi: string | null } -export const DefaultPlatforms: PlatformDetail[] = [ - { - platform: 'win32', - arch: 'x64', - abi: 'msvc', - platformArchABI: 'win32-x64-msvc', - raw: 'x86_64-pc-windows-msvc', - }, - { - platform: 'darwin', - arch: 'x64', - abi: null, - platformArchABI: 'darwin-x64', - raw: 'x86_64-apple-darwin', - }, - { - platform: 'linux', - arch: 'x64', - abi: 'gnu', - platformArchABI: 'linux-x64-gnu', - raw: 'x86_64-unknown-linux-gnu', - }, -] - /** * A triple is a specific format for specifying a target architecture. * Triples may be referred to as a target triple which is the architecture for the artifact produced, and the host triple which is the architecture that the compiler is running on. @@ -83,7 +91,7 @@ export const DefaultPlatforms: PlatformDetail[] = [ * - `sys` = The system name, for example `linux`, `windows`, `darwin`, etc. none is typically used for bare-metal without an OS. * - `abi` = The ABI, for example `gnu`, `android`, `eabi`, etc. */ -export function parseTriple(rawTriple: string): PlatformDetail { +export function parseTriple(rawTriple: string): Target { const triple = rawTriple.endsWith('eabi') ? `${rawTriple.slice(0, -4)}-eabi` : rawTriple @@ -91,27 +99,30 @@ export function parseTriple(rawTriple: string): PlatformDetail { let cpu: string let sys: string let abi: string | null = null - if (triples.length === 4) { - ;[cpu, , sys, abi = null] = triples - } else if (triples.length === 3) { - ;[cpu, , sys] = triples - } else { + if (triples.length === 2) { + // aarch64-fuchsia + // ^ cpu ^ sys ;[cpu, sys] = triples + } else { + // aarch64-unknown-linux-musl + // ^ cpu ^ sys ^ abi + // aarch64-apple-darwin + // ^ cpu ^ sys (abi is None) + ;[cpu, , sys, abi = null] = triples } - const platformName = SysToNodePlatform[sys] ?? sys - const arch = CpuToNodeArch[cpu] ?? cpu + + const platform = SysToNodePlatform[sys] ?? (sys as NodeJS.Platform) + const arch = CpuToNodeArch[cpu] ?? (cpu as NodeJSArch) return { - platform: platformName, + triple: rawTriple, + platformArchABI: abi ? `${platform}-${arch}-${abi}` : `${platform}-${arch}`, + platform, arch, abi, - platformArchABI: abi - ? `${platformName}-${arch}-${abi}` - : `${platformName}-${arch}`, - raw: rawTriple, } } -export function getHostTargetTriple(): PlatformDetail { +export function getSystemDefaultTarget(): Target { const host = execSync(`rustc -vV`, { env: process.env, }) @@ -124,3 +135,11 @@ export function getHostTargetTriple(): PlatformDetail { } return parseTriple(triple) } + +export function getTargetLinker(target: string): string | undefined { + return TARGET_LINKER[target] +} + +export function targetToEnvVar(target: string): string { + return target.replace(/-/g, '_').toUpperCase() +} diff --git a/cli/src/utils/typegen.ts b/cli/src/utils/typegen.ts new file mode 100644 index 00000000..a42ed318 --- /dev/null +++ b/cli/src/utils/typegen.ts @@ -0,0 +1,193 @@ +import { sortBy } from 'lodash-es' + +import { readFileAsync } from './misc.js' + +const TOP_LEVEL_NAMESPACE = '__TOP_LEVEL_MODULE__' +export const DEFAULT_TYPE_DEF_HEADER = `/* auto-generated by NAPI-RS */ +/* eslint-disable */ +` + +enum TypeDefKind { + Const = 'const', + Enum = 'enum', + Interface = 'interface', + Fn = 'fn', + Struct = 'struct', + Impl = 'impl', +} + +interface TypeDefLine { + kind: TypeDefKind + name: string + original_name?: string + def: string + js_doc?: string + js_mod?: string +} + +function prettyPrint(line: TypeDefLine, ident: number): string { + let s = line.js_doc ?? '' + switch (line.kind) { + case TypeDefKind.Interface: + s += `export interface ${line.name} {\n${line.def}\n}` + break + + case TypeDefKind.Enum: + s += `export const enum ${line.name} {\n${line.def}\n}` + break + + case TypeDefKind.Struct: + s += `export class ${line.name} {\n${line.def}\n}` + if (line.original_name && line.original_name !== line.name) { + s += `\nexport type ${line.original_name} = ${line.name}` + } + break + + default: + s += line.def + } + + return correctStringIdent(s, ident) +} + +export async function processTypeDef( + intermediateTypeFile: string, + header?: string, +) { + const defs = await readIntermediateTypeFile(intermediateTypeFile) + const groupedDefs = preprocessTypeDef(defs) + + header = header ? header + '\n' : '' + let dts = '' + + sortBy(Array.from(groupedDefs), ([namespace]) => namespace).forEach( + ([namespace, defs]) => { + if (namespace === TOP_LEVEL_NAMESPACE) { + for (const def of defs) { + dts += prettyPrint(def, 0) + '\n\n' + } + } else { + dts += `export namespace ${namespace} {\n` + for (const def of defs) { + dts += prettyPrint(def, 2) + '\n' + } + dts += '}\n\n' + } + }, + ) + + if (dts.indexOf('ExternalObject<') > -1) { + header += ` +export class ExternalObject { + readonly '': { + readonly '': unique symbol + [K: symbol]: T + } +} +` + } + + return header + dts +} + +async function readIntermediateTypeFile(file: string) { + const content = await readFileAsync(file, 'utf8') + const defs = content + .split('\n') + .filter(Boolean) + .map((line) => { + line = line.trim() + if (!line.startsWith('{')) { + // crateName:{ "def": "", ... } + const start = line.indexOf(':') + 1 + line = line.slice(start) + } + return JSON.parse(line) as TypeDefLine + }) + + // move all `struct` def to the very top + // and order the rest alphabetically. + return defs.sort((a, b) => { + if (a.kind === TypeDefKind.Struct) { + if (b.kind === TypeDefKind.Struct) { + return a.name.localeCompare(b.name) + } + return -1 + } else if (b.kind === TypeDefKind.Struct) { + return 1 + } else { + return a.name.localeCompare(b.name) + } + }) +} + +function preprocessTypeDef(defs: TypeDefLine[]): Map { + const namespaceGrouped = new Map() + const classDefs = new Map() + + for (const def of defs) { + const namespace = def.js_mod ?? TOP_LEVEL_NAMESPACE + if (!namespaceGrouped.has(namespace)) { + namespaceGrouped.set(namespace, []) + } + + const group = namespaceGrouped.get(namespace)! + + if (def.kind === TypeDefKind.Struct) { + group.push(def) + classDefs.set(def.name, def) + } else if (def.kind === TypeDefKind.Impl) { + // merge `impl` into class definition + const classDef = classDefs.get(def.name) + if (classDef) { + if (classDef.def) { + classDef.def += '\n' + } + + classDef.def += def.def + } + } else { + group.push(def) + } + } + + return namespaceGrouped +} + +export function correctStringIdent(src: string, ident: number): string { + let bracketDepth = 0 + const result = src + .split('\n') + .map((line) => { + line = line.trim() + if (line === '') { + return '' + } + + const isInMultilineComment = line.startsWith('*') + const isClosingBracket = line.endsWith('}') + const isOpeningBracket = line.endsWith('{') + + let rightIndent = ident + if (isOpeningBracket && !isInMultilineComment) { + bracketDepth += 1 + rightIndent += (bracketDepth - 1) * 2 + } else { + if (isClosingBracket && bracketDepth > 0 && !isInMultilineComment) { + bracketDepth -= 1 + } + rightIndent += bracketDepth * 2 + } + + if (isInMultilineComment) { + rightIndent += 1 + } + + const s = `${' '.repeat(rightIndent)}${line}` + + return s + }) + .join('\n') + + return result +} diff --git a/cli/src/utils/version.ts b/cli/src/utils/version.ts new file mode 100644 index 00000000..b5226f95 --- /dev/null +++ b/cli/src/utils/version.ts @@ -0,0 +1,76 @@ +export enum NapiVersion { + Napi1 = 1, + Napi2, + Napi3, + Napi4, + Napi5, + Napi6, + Napi7, + Napi8, +} + +/// because node support new napi version in some minor version updates, so we might meet such situation: +/// `node v10.20.0` supports `napi5` and `napi6`, but `node v12.0.0` only support `napi4`, +/// by which, we can not tell directly napi version supportness from node version directly. +const NAPI_VERSION_MATRIX = new Map([ + [NapiVersion.Napi1, '8.6.0'], + [NapiVersion.Napi2, '8.10.0 | 9.3.0'], + [NapiVersion.Napi3, '6.14.2 | 8.11.2 | 9.11.0'], + [NapiVersion.Napi4, '10.16.0 | 11.8.0'], + [NapiVersion.Napi5, '10.17.0 | 12.11.0'], + [NapiVersion.Napi6, '10.20.0 | 12.17.0 | 14.0.0'], + [NapiVersion.Napi7, '10.23.0 | 12.19.0 | 14.12.0'], + [NapiVersion.Napi8, '12.22.0 | 14.17.0 | 15.12.0'], +]) + +interface NodeVersion { + major: number + minor: number + patch: number +} + +function parseNodeVersion(v: string): NodeVersion { + const matches = v.match(/v?([0-9]+)\.([0-9]+)\.([0-9]+)/i) + + if (!matches) { + throw new Error('Unknown node version number: ' + v) + } + + const [, major, minor, patch] = matches + + return { + major: parseInt(major), + minor: parseInt(minor), + patch: parseInt(patch), + } +} + +function requiredNodeVersions(napiVersion: NapiVersion): NodeVersion[] { + const requirement = NAPI_VERSION_MATRIX.get(napiVersion) + + if (!requirement) { + return [parseNodeVersion('10.0.0')] + } + + return requirement.split('|').map(parseNodeVersion) +} + +function toEngineRequirement(versions: NodeVersion[]): string { + const requirements: string[] = [] + versions.forEach((v, i) => { + let req = '' + if (i !== 0) { + const lastVersion = versions[i - 1] + req += `< ${lastVersion.major + 1}` + } + + req += `${i === 0 ? '' : ' || '}>= ${v.major}.${v.minor}.${v.patch}` + requirements.push(req) + }) + + return requirements.join(' && ') +} + +export function napiEngineRequirement(napiVersion: NapiVersion): string { + return toEngineRequirement(requiredNodeVersions(napiVersion)) +} diff --git a/cli/src/version.ts b/cli/src/version.ts deleted file mode 100644 index 3130a6f6..00000000 --- a/cli/src/version.ts +++ /dev/null @@ -1,43 +0,0 @@ -import { join } from 'path' - -import { Command, Option } from 'clipanion' -import * as chalk from 'colorette' - -import { getNapiConfig } from './consts' -import { debugFactory } from './debug' -import { spawn } from './spawn' -import { updatePackageJson } from './update-package' - -const debug = debugFactory('version') - -export class VersionCommand extends Command { - static usage = Command.Usage({ - description: 'Update versions in created npm dir', - }) - - static paths = [['version']] - - static async updatePackageJson(prefix: string, configFileName?: string) { - const { version, platforms } = getNapiConfig(configFileName) - for (const platformDetail of platforms) { - const pkgDir = join(process.cwd(), prefix, platformDetail.platformArchABI) - debug( - `Update version to ${chalk.greenBright( - version, - )} in [${chalk.yellowBright(pkgDir)}]`, - ) - await updatePackageJson(join(pkgDir, 'package.json'), { - version, - }) - } - } - - prefix = Option.String(`-p,--prefix`, 'npm') - - configFileName?: string = Option.String('-c,--config') - - async execute() { - await VersionCommand.updatePackageJson(this.prefix, this.configFileName) - await spawn('git add .') - } -} diff --git a/cli/tsconfig.json b/cli/tsconfig.json new file mode 100644 index 00000000..0aeb7a5b --- /dev/null +++ b/cli/tsconfig.json @@ -0,0 +1,16 @@ +{ + "compilerOptions": { + "strict": true, + "target": "ES2022", + "module": "NodeNext", + "moduleResolution": "nodenext", + "resolveJsonModule": true, + "allowSyntheticDefaultImports": true, + "declaration": true, + "rootDir": "./src", + "baseUrl": ".", + "outDir": "dist", + "allowJs": false + }, + "include": ["./src"] +} diff --git a/crates/build/src/lib.rs b/crates/build/src/lib.rs index 3dd6bf16..7c8aceb7 100644 --- a/crates/build/src/lib.rs +++ b/crates/build/src/lib.rs @@ -3,6 +3,7 @@ mod macos; pub fn setup() { println!("cargo:rerun-if-env-changed=DEBUG_GENERATED_CODE"); + println!("cargo:rerun-if-env-changed=TYPE_DEF_TMP_PATH"); match std::env::var("CARGO_CFG_TARGET_OS").as_deref() { Ok("macos") => { macos::setup(); diff --git a/crates/napi/Cargo.toml b/crates/napi/Cargo.toml index 5b2e5fde..9635d641 100644 --- a/crates/napi/Cargo.toml +++ b/crates/napi/Cargo.toml @@ -10,6 +10,9 @@ repository = "https://github.com/napi-rs/napi-rs" rust-version = "1.57" version = "2.12.2" +[lib] +doctest = false + [package.metadata.docs.rs] all-features = true diff --git a/examples/binary/package.json b/examples/binary/package.json index 0f03a2c9..8b8f5ee6 100644 --- a/examples/binary/package.json +++ b/examples/binary/package.json @@ -4,11 +4,9 @@ "version": "0.0.0", "bin": "napi-examples-binary", "scripts": { - "build": "node ../../cli/scripts/index.js build --js false", - "build-aarch64": "node ../../cli/scripts/index.js build --js false --target aarch64-unknown-linux-gnu", - "build-armv7": "node ../../cli/scripts/index.js build --js false --target armv7-unknown-linux-gnueabihf", - "build-i686": "node ../../cli/scripts/index.js build --js false --target i686-pc-windows-msvc", - "build-i686-release": "node ../../cli/scripts/index.js build --js false --release --target i686-pc-windows-msvc", - "build-release": "node ../../cli/scripts/index.js build --js false --release" + "build": "napi-raw build" + }, + "devDependencies": { + "@napi-rs/cli": "workspace:*" } } diff --git a/examples/napi-compat-mode/__test__/object.spec.ts.md b/examples/napi-compat-mode/__tests__/__snapshots__/object.spec.ts.md similarity index 87% rename from examples/napi-compat-mode/__test__/object.spec.ts.md rename to examples/napi-compat-mode/__tests__/__snapshots__/object.spec.ts.md index 991ad250..3023f566 100644 --- a/examples/napi-compat-mode/__test__/object.spec.ts.md +++ b/examples/napi-compat-mode/__tests__/__snapshots__/object.spec.ts.md @@ -1,4 +1,4 @@ -# Snapshot report for `examples/napi-compat-mode/__test__/object.spec.ts` +# Snapshot report for `__tests__/object.spec.ts` The actual snapshot is saved in `object.spec.ts.snap`. diff --git a/examples/napi-compat-mode/__test__/object.spec.ts.snap b/examples/napi-compat-mode/__tests__/__snapshots__/object.spec.ts.snap similarity index 100% rename from examples/napi-compat-mode/__test__/object.spec.ts.snap rename to examples/napi-compat-mode/__tests__/__snapshots__/object.spec.ts.snap diff --git a/examples/napi-compat-mode/__test__/string.spec.ts.md b/examples/napi-compat-mode/__tests__/__snapshots__/string.spec.ts.md similarity index 86% rename from examples/napi-compat-mode/__test__/string.spec.ts.md rename to examples/napi-compat-mode/__tests__/__snapshots__/string.spec.ts.md index c3baff297a3da4e891c894966520892a270b4711..be7f6f2d0156cde8284ffb27685d3432588376a7 100644 GIT binary patch delta 18 ZcmZ3*GLdD1ID342NosLP@kaB{i~u`m2EPCR delta 43 ycmbQpvWjJbxI$`0Vs1fBYO#J^VnL>Ea(-?>Vu@~UeoCr-e0)i2amhxx&x`<9bPzNE diff --git a/examples/napi-compat-mode/__test__/string.spec.ts.snap b/examples/napi-compat-mode/__tests__/__snapshots__/string.spec.ts.snap similarity index 100% rename from examples/napi-compat-mode/__test__/string.spec.ts.snap rename to examples/napi-compat-mode/__tests__/__snapshots__/string.spec.ts.snap diff --git a/examples/napi-compat-mode/__test__/array.spec.ts b/examples/napi-compat-mode/__tests__/array.spec.ts similarity index 100% rename from examples/napi-compat-mode/__test__/array.spec.ts rename to examples/napi-compat-mode/__tests__/array.spec.ts diff --git a/examples/napi-compat-mode/__test__/arraybuffer.spec.ts b/examples/napi-compat-mode/__tests__/arraybuffer.spec.ts similarity index 100% rename from examples/napi-compat-mode/__test__/arraybuffer.spec.ts rename to examples/napi-compat-mode/__tests__/arraybuffer.spec.ts diff --git a/examples/napi-compat-mode/__test__/buffer.spec.ts b/examples/napi-compat-mode/__tests__/buffer.spec.ts similarity index 100% rename from examples/napi-compat-mode/__test__/buffer.spec.ts rename to examples/napi-compat-mode/__tests__/buffer.spec.ts diff --git a/examples/napi-compat-mode/__test__/class.spec.ts b/examples/napi-compat-mode/__tests__/class.spec.ts similarity index 100% rename from examples/napi-compat-mode/__test__/class.spec.ts rename to examples/napi-compat-mode/__tests__/class.spec.ts diff --git a/examples/napi-compat-mode/__test__/cleanup-env.spec.ts b/examples/napi-compat-mode/__tests__/cleanup-env.spec.ts similarity index 100% rename from examples/napi-compat-mode/__test__/cleanup-env.spec.ts rename to examples/napi-compat-mode/__tests__/cleanup-env.spec.ts diff --git a/examples/napi-compat-mode/__test__/create-external.spec.ts b/examples/napi-compat-mode/__tests__/create-external.spec.ts similarity index 100% rename from examples/napi-compat-mode/__test__/create-external.spec.ts rename to examples/napi-compat-mode/__tests__/create-external.spec.ts diff --git a/examples/napi-compat-mode/__test__/either.spec.ts b/examples/napi-compat-mode/__tests__/either.spec.ts similarity index 100% rename from examples/napi-compat-mode/__test__/either.spec.ts rename to examples/napi-compat-mode/__tests__/either.spec.ts diff --git a/examples/napi-compat-mode/__test__/env.spec.ts b/examples/napi-compat-mode/__tests__/env.spec.ts similarity index 92% rename from examples/napi-compat-mode/__test__/env.spec.ts rename to examples/napi-compat-mode/__tests__/env.spec.ts index 1cf61182..239460e9 100644 --- a/examples/napi-compat-mode/__test__/env.spec.ts +++ b/examples/napi-compat-mode/__tests__/env.spec.ts @@ -3,7 +3,7 @@ import test from 'ava' const bindings = require('../index.node') test('should be able to access env variable from native', (t) => { - t.is(bindings.getEnvVariable(), 'napi-rs') + t.is(bindings.getEnvVariable(), '@examples/compat-mode') }) test('should be able to throw syntax error', (t) => { diff --git a/examples/napi-compat-mode/__test__/function.spec.ts b/examples/napi-compat-mode/__tests__/function.spec.ts similarity index 100% rename from examples/napi-compat-mode/__test__/function.spec.ts rename to examples/napi-compat-mode/__tests__/function.spec.ts diff --git a/examples/napi-compat-mode/__test__/get-napi-version.spec.ts b/examples/napi-compat-mode/__tests__/get-napi-version.spec.ts similarity index 100% rename from examples/napi-compat-mode/__test__/get-napi-version.spec.ts rename to examples/napi-compat-mode/__tests__/get-napi-version.spec.ts diff --git a/examples/napi-compat-mode/__test__/global.spec.ts b/examples/napi-compat-mode/__tests__/global.spec.ts similarity index 100% rename from examples/napi-compat-mode/__test__/global.spec.ts rename to examples/napi-compat-mode/__tests__/global.spec.ts diff --git a/examples/napi-compat-mode/__test__/js-value.spec.ts b/examples/napi-compat-mode/__tests__/js-value.spec.ts similarity index 100% rename from examples/napi-compat-mode/__test__/js-value.spec.ts rename to examples/napi-compat-mode/__tests__/js-value.spec.ts diff --git a/examples/napi-compat-mode/__test__/napi-version.ts b/examples/napi-compat-mode/__tests__/napi-version.ts similarity index 100% rename from examples/napi-compat-mode/__test__/napi-version.ts rename to examples/napi-compat-mode/__tests__/napi-version.ts diff --git a/examples/napi-compat-mode/__test__/napi4/deferred.spec.ts b/examples/napi-compat-mode/__tests__/napi4/deferred.spec.ts similarity index 100% rename from examples/napi-compat-mode/__test__/napi4/deferred.spec.ts rename to examples/napi-compat-mode/__tests__/napi4/deferred.spec.ts diff --git a/examples/napi-compat-mode/__test__/napi4/example.txt b/examples/napi-compat-mode/__tests__/napi4/example.txt similarity index 100% rename from examples/napi-compat-mode/__test__/napi4/example.txt rename to examples/napi-compat-mode/__tests__/napi4/example.txt diff --git a/examples/napi-compat-mode/__test__/napi4/threadsafe_function.spec.ts b/examples/napi-compat-mode/__tests__/napi4/threadsafe_function.spec.ts similarity index 100% rename from examples/napi-compat-mode/__test__/napi4/threadsafe_function.spec.ts rename to examples/napi-compat-mode/__tests__/napi4/threadsafe_function.spec.ts diff --git a/examples/napi-compat-mode/__test__/napi4/tokio_readfile.spec.ts b/examples/napi-compat-mode/__tests__/napi4/tokio_readfile.spec.ts similarity index 100% rename from examples/napi-compat-mode/__test__/napi4/tokio_readfile.spec.ts rename to examples/napi-compat-mode/__tests__/napi4/tokio_readfile.spec.ts diff --git a/examples/napi-compat-mode/__test__/napi4/tokio_rt.spec.ts b/examples/napi-compat-mode/__tests__/napi4/tokio_rt.spec.ts similarity index 100% rename from examples/napi-compat-mode/__test__/napi4/tokio_rt.spec.ts rename to examples/napi-compat-mode/__tests__/napi4/tokio_rt.spec.ts diff --git a/examples/napi-compat-mode/__test__/napi4/tsfn-dua-instance.js b/examples/napi-compat-mode/__tests__/napi4/tsfn-dua-instance.js similarity index 100% rename from examples/napi-compat-mode/__test__/napi4/tsfn-dua-instance.js rename to examples/napi-compat-mode/__tests__/napi4/tsfn-dua-instance.js diff --git a/examples/napi-compat-mode/__test__/napi4/tsfn-throw.js b/examples/napi-compat-mode/__tests__/napi4/tsfn-throw.js similarity index 100% rename from examples/napi-compat-mode/__test__/napi4/tsfn-throw.js rename to examples/napi-compat-mode/__tests__/napi4/tsfn-throw.js diff --git a/examples/napi-compat-mode/__test__/napi4/tsfn_error.spec.ts b/examples/napi-compat-mode/__tests__/napi4/tsfn_error.spec.ts similarity index 100% rename from examples/napi-compat-mode/__test__/napi4/tsfn_error.spec.ts rename to examples/napi-compat-mode/__tests__/napi4/tsfn_error.spec.ts diff --git a/examples/napi-compat-mode/__test__/napi5/date.spec.ts b/examples/napi-compat-mode/__tests__/napi5/date.spec.ts similarity index 100% rename from examples/napi-compat-mode/__test__/napi5/date.spec.ts rename to examples/napi-compat-mode/__tests__/napi5/date.spec.ts diff --git a/examples/napi-compat-mode/__test__/napi6/bigint.spec.ts b/examples/napi-compat-mode/__tests__/napi6/bigint.spec.ts similarity index 100% rename from examples/napi-compat-mode/__test__/napi6/bigint.spec.ts rename to examples/napi-compat-mode/__tests__/napi6/bigint.spec.ts diff --git a/examples/napi-compat-mode/__test__/napi6/instance-data.spec.ts b/examples/napi-compat-mode/__tests__/napi6/instance-data.spec.ts similarity index 100% rename from examples/napi-compat-mode/__test__/napi6/instance-data.spec.ts rename to examples/napi-compat-mode/__tests__/napi6/instance-data.spec.ts diff --git a/examples/napi-compat-mode/__test__/napi7/arraybuffer.spec.ts b/examples/napi-compat-mode/__tests__/napi7/arraybuffer.spec.ts similarity index 100% rename from examples/napi-compat-mode/__test__/napi7/arraybuffer.spec.ts rename to examples/napi-compat-mode/__tests__/napi7/arraybuffer.spec.ts diff --git a/examples/napi-compat-mode/__test__/napi8/async-cleanup.spec.ts b/examples/napi-compat-mode/__tests__/napi8/async-cleanup.spec.ts similarity index 100% rename from examples/napi-compat-mode/__test__/napi8/async-cleanup.spec.ts rename to examples/napi-compat-mode/__tests__/napi8/async-cleanup.spec.ts diff --git a/examples/napi-compat-mode/__test__/napi8/object.spec.ts b/examples/napi-compat-mode/__tests__/napi8/object.spec.ts similarity index 100% rename from examples/napi-compat-mode/__test__/napi8/object.spec.ts rename to examples/napi-compat-mode/__tests__/napi8/object.spec.ts diff --git a/examples/napi-compat-mode/__test__/napi8/sub-process-removable.js b/examples/napi-compat-mode/__tests__/napi8/sub-process-removable.js similarity index 100% rename from examples/napi-compat-mode/__test__/napi8/sub-process-removable.js rename to examples/napi-compat-mode/__tests__/napi8/sub-process-removable.js diff --git a/examples/napi-compat-mode/__test__/napi8/sub-process.js b/examples/napi-compat-mode/__tests__/napi8/sub-process.js similarity index 100% rename from examples/napi-compat-mode/__test__/napi8/sub-process.js rename to examples/napi-compat-mode/__tests__/napi8/sub-process.js diff --git a/examples/napi-compat-mode/__test__/object.spec.ts b/examples/napi-compat-mode/__tests__/object.spec.ts similarity index 100% rename from examples/napi-compat-mode/__test__/object.spec.ts rename to examples/napi-compat-mode/__tests__/object.spec.ts diff --git a/examples/napi-compat-mode/__tests__/serde/__snapshots__/ser.spec.ts.md b/examples/napi-compat-mode/__tests__/serde/__snapshots__/ser.spec.ts.md new file mode 100644 index 00000000..6a92e2ec --- /dev/null +++ b/examples/napi-compat-mode/__tests__/serde/__snapshots__/ser.spec.ts.md @@ -0,0 +1,141 @@ +# Snapshot report for `__tests__/serde/ser.spec.ts` + +The actual snapshot is saved in `ser.spec.ts.snap`. + +Generated by [AVA](https://avajs.dev). + +## serialize make_num_77 from bindings + +> Snapshot 1 + + 77 + +## serialize make_num_32 from bindings + +> Snapshot 1 + + 32 + +## serialize make_str_hello from bindings + +> Snapshot 1 + + 'Hello World' + +## serialize make_num_array from bindings + +> Snapshot 1 + + [ + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + ] + +## serialize make_buff from bindings + +> Snapshot 1 + + Buffer @Uint8Array [ + fffefd + ] + +## serialize make_obj from bindings + +> Snapshot 1 + + { + a: 1, + b: [ + 0.1, + 1.1, + 2.2, + 3.3, + ], + c: 'Hi', + } + +## serialize make_map from bindings + +> Snapshot 1 + + { + a: 1, + b: 2, + c: 3, + } + +## serialize make_bytes_struct from bindings + +> Snapshot 1 + + { + code: Buffer @Uint8Array [ + 00010203 + ], + map: 'source map', + } + +## serialize make_object from bindings + +> Snapshot 1 + + { + a: 1, + b: [ + 1, + 2, + ], + c: 'abc', + d: false, + e: null, + f: null, + g: [ + 9, + false, + 'efg', + ], + h: '🤷', + i: 'Empty', + j: [ + 27, + 'hij', + ], + k: { + a: 128, + b: [ + 9, + 8, + 7, + ], + }, + l: 'jkl', + m: [ + 0, + 1, + 2, + 3, + 4, + ], + o: { + Value: [ + 'z', + 'y', + 'x', + ], + }, + p: [ + 1, + 2, + 3.5, + ], + q: 9998881288248882845242411222333n, + r: -340282363588614574563373375108745990111n, + } diff --git a/examples/napi-compat-mode/__test__/serde/ser.spec.ts.snap b/examples/napi-compat-mode/__tests__/serde/__snapshots__/ser.spec.ts.snap similarity index 100% rename from examples/napi-compat-mode/__test__/serde/ser.spec.ts.snap rename to examples/napi-compat-mode/__tests__/serde/__snapshots__/ser.spec.ts.snap diff --git a/examples/napi-compat-mode/__test__/serde/de.spec.ts b/examples/napi-compat-mode/__tests__/serde/de.spec.ts similarity index 100% rename from examples/napi-compat-mode/__test__/serde/de.spec.ts rename to examples/napi-compat-mode/__tests__/serde/de.spec.ts diff --git a/examples/napi-compat-mode/__test__/serde/ser.spec.ts b/examples/napi-compat-mode/__tests__/serde/ser.spec.ts similarity index 100% rename from examples/napi-compat-mode/__test__/serde/ser.spec.ts rename to examples/napi-compat-mode/__tests__/serde/ser.spec.ts diff --git a/examples/napi-compat-mode/__test__/serde/ser.spec.ts.md b/examples/napi-compat-mode/__tests__/serde/ser.spec.ts.md similarity index 100% rename from examples/napi-compat-mode/__test__/serde/ser.spec.ts.md rename to examples/napi-compat-mode/__tests__/serde/ser.spec.ts.md diff --git a/examples/napi-compat-mode/__tests__/serde/ser.spec.ts.snap b/examples/napi-compat-mode/__tests__/serde/ser.spec.ts.snap new file mode 100644 index 0000000000000000000000000000000000000000..85e3135bd528be9af2055bcb3e063ba5d2a8aed7 GIT binary patch literal 1079 zcmV-71jzeARzVDC7om8B0p3JZeTDuO6|vItfMpH~nc>{DL^!6!jq6d$a9_ik<` zxt-lqbeNCad^z{rbH8)WO)mBvKj>^m7cRN67yItHdm=aVY~MTY)`#|{yFQu>*H>5T zy)YQo9dFe2MjMeAjqGvM58~*xi`}jr+ou$%EYTlPC35N@SEliAT-CX&dj(ff9Ip3W z-wz7By>MshPLmeNp%ZM*nIQDL`?;o3+F@vK6}i5Vx~`Bz&)|9*aDlVHHn0PH4159X z0@s0GfZIrEk!X+6H3;FOg@px)RM~$X7P53ZQK$yVEg^gNgm6Mm2$>T~LMWV26GG*L zmJk{zN(oWoL^&bKoTwy3g%fiLF~{}0ThPy$^m;|o^;7AN5~YRfqrekfn$qKN;f7S3 z>Y6u-tv!Ki5a^h+M3ld8{3VgY5|v_s#>67hVC-zg?n!sF5%;+iJjl8bWZ(=6VtkPt z$>dk1K|Tzu0sS=4r=5Y@iD{t8uvV+F&=eswVo%d|gpfDjA${bCwjDl_Pk3~3?F!7V z0^b2Y0e=cbB#T9)=8LFIl$B*&s3eg3l$2A_ST=-;0%xN;NrYTMg`NaDkG8-#~Wtc6q zX<043(OhjbTc){+e^XzvaMy0H=(^5Y>lH-vCh)d$&{>D`C^1A})(-xblfdIcs| zfnDIb;Ik^8`f~o%pMEOvZwHx~DT3Kt-i(%g_MJcr$?a{-T;Z<#RBGDy2K>C6*`4yM z605e~)O>qZrS!Ap|NZpYJO8laQEj@ScG~tQ?o2smsV2T7&E+Ob&y#TZEMNnnmQPPf xEY#OwZ~=G+xGWgYiMcFDQs#q Snapshot 1 - - [ - '@rollup/plugin-alias', - '@rollup/plugin-commonjs', - '@rollup/plugin-json', - '@rollup/plugin-node-resolve', - '@rollup/plugin-replace', - '@taplo/cli', - '@types/debug', - '@types/lodash-es', - '@types/node', - '@types/sinon', - '@typescript-eslint/eslint-plugin', - '@typescript-eslint/parser', - 'ava', - 'benny', - 'c8', - 'colorette', - 'cross-env', - 'electron', - 'esbuild', - 'eslint', - 'eslint-config-prettier', - 'eslint-plugin-import', - 'eslint-plugin-prettier', - 'husky', - 'lerna', - 'lint-staged', - 'npm-run-all', - 'prettier', - 'rollup', - 'shx', - 'sinon', - 'source-map-support', - 'ts-node', - 'tslib', - 'typescript', - ] diff --git a/examples/napi/__test__/values.spec.ts.snap b/examples/napi/__test__/values.spec.ts.snap deleted file mode 100644 index c4f5bde58d14689866cded23502ec62b5acf18e7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 633 zcmV-<0*3uTRzV)TW~wKzwABmY&=k8E+CTx6)!hXYwk zI@sll#UG0Z00000000ARlfQ0LF%-t_{BIga)1)n-KwDt7GQt=p2A%+fgq(Zb#HnLj zwr@nnA~Ep*Y)I{n#DEwOBN8(+5)7<701^u)ocmsR_ zz5{=NeuCxCcA~UIK4{&%ig}H?UJ7WB@z_o&p|t4ZH)s z09{(^(CP!{_<~aW*KW57Z4!Ei&=w?0q({qyRy(vebVjMn4y?+?QZue3_j!m?Ozjm? ziJ8rep2lDagWW=KIY11RF|=O@X#=Bn!W%Ug7_MM=w-9#1DxSn#6?4sD;8vMIq9l4X z^jgEPu)+^gG0Mj1*3sR{U1d`4Crrey8kpG36U&35xlt_crC#^iME7vzCQjM_rIplS zuzIjnL-@ufzR~~B8_zuR?AbxYI|`)lgyvQ30;e_5>Cf?_T%OMtLXzDi`dxpXlgrSE?aeEjE zsNxB3#CfcC8ugp;LjB}9inrpqE^XEU%G=&#E)i_TE%TYZIFZA6A;GhYOM4V+1{l={ T<=gQiTCd(;S}-lB5(NMN-X|#g diff --git a/examples/napi/__test__/typegen.spec.ts.md b/examples/napi/__tests__/__snapshots__/typegen.spec.ts.md similarity index 91% rename from examples/napi/__test__/typegen.spec.ts.md rename to examples/napi/__tests__/__snapshots__/typegen.spec.ts.md index e978724c..499a98b4 100644 --- a/examples/napi/__test__/typegen.spec.ts.md +++ b/examples/napi/__tests__/__snapshots__/typegen.spec.ts.md @@ -1,4 +1,4 @@ -# Snapshot report for `examples/napi/__test__/typegen.spec.ts` +# Snapshot report for `__tests__/typegen.spec.ts` The actual snapshot is saved in `typegen.spec.ts.snap`. @@ -8,10 +8,9 @@ Generated by [AVA](https://avajs.dev). > Snapshot 1 - `/* tslint:disable */␊ + `/* auto-generated by NAPI-RS */␊ /* eslint-disable */␊ ␊ - /* auto-generated by NAPI-RS */␊ ␊ export class ExternalObject {␊ readonly '': {␊ @@ -19,222 +18,6 @@ Generated by [AVA](https://avajs.dev). [K: symbol]: T␊ }␊ }␊ - export interface Shared {␊ - value: number␊ - }␊ - /** This is a const */␊ - export const DEFAULT_COST: number␊ - export function getWords(): Array␊ - /** Gets some numbers */␊ - export function getNums(): Array␊ - export function sumNums(nums: Array): number␊ - export function toJsObj(): object␊ - export function getNumArr(): number[]␊ - export function getNestedNumArr(): number[][][]␊ - export function readFileAsync(path: string): Promise␊ - export function asyncMultiTwo(arg: number): Promise␊ - export function bigintAdd(a: bigint, b: bigint): bigint␊ - export function createBigInt(): bigint␊ - export function createBigIntI64(): bigint␊ - export function bigintGetU64AsString(bi: bigint): string␊ - export function bigintFromI64(): bigint␊ - export function bigintFromI128(): bigint␊ - export function getCwd(callback: (arg0: string) => void): void␊ - export function optionEnd(callback: (arg0: string, arg1?: string | undefined | null) => void): void␊ - export function optionStart(callback: (arg0: string | undefined | null, arg1: string) => void): void␊ - export function optionStartEnd(callback: (arg0: string | undefined | null, arg1: string, arg2?: string | undefined | null) => void): void␊ - export function optionOnly(callback: (arg0?: string | undefined | null) => void): void␊ - /** napi = { version = 2, features = ["serde-json"] } */␊ - export function readFile(callback: (arg0: Error | undefined, arg1?: string | undefined | null) => void): void␊ - export function returnJsFunction(): (...args: any[]) => any␊ - export function callbackReturnPromise(functionInput: () => T | Promise, callback: (err: Error | null, result: T) => void): T | Promise␊ - export function captureErrorInCallback(cb1: () => void, cb2: (arg0: Error) => void): void␊ - export interface ObjectFieldClassInstance {␊ - bird: Bird␊ - }␊ - export function createObjectWithClassField(): ObjectFieldClassInstance␊ - export function receiveObjectWithClassField(object: ObjectFieldClassInstance): Bird␊ - export function plusOne(this: Width): number␊ - export function dateToNumber(input: Date): number␊ - export function chronoDateToMillis(input: Date): number␊ - export function chronoDateAdd1Minute(input: Date): Date␊ - export interface Dates {␊ - start: Date␊ - end?: Date␊ - }␊ - export function eitherStringOrNumber(input: string | number): number␊ - export function returnEither(input: number): string | number␊ - export function either3(input: string | number | boolean): number␊ - export interface Obj {␊ - v: string | number␊ - }␊ - export function either4(input: string | number | boolean | Obj): number␊ - export function receiveClassOrNumber(either: number | JsClassForEither): number␊ - export function receiveMutClassOrNumber(either: number | JsClassForEither): number␊ - export function receiveDifferentClass(either: JsClassForEither | AnotherClassForEither): number␊ - export function returnEitherClass(input: number): number | JsClassForEither␊ - export function eitherFromOption(): JsClassForEither | undefined␊ - export interface A {␊ - foo: number␊ - }␊ - export interface B {␊ - bar: number␊ - }␊ - export interface C {␊ - baz: number␊ - }␊ - export function eitherFromObjects(input: A | B | C): string␊ - export function eitherBoolOrFunction(input: boolean | ((...args: any[]) => any)): void␊ - export function promiseInEither(input: number | Promise): Promise␊ - /** default enum values are continuos i32s start from 0 */␊ - export const enum Kind {␊ - /** Barks */␊ - Dog = 0,␊ - /** Kills birds */␊ - Cat = 1,␊ - /** Tasty */␊ - Duck = 2␊ - }␊ - export const enum Empty {␊ - ␊ - }␊ - export const enum Status {␊ - Pristine = 'Pristine',␊ - Loading = 'Loading',␊ - Ready = 'Ready'␊ - }␊ - /** You could break the step and for an new continuous value. */␊ - export const enum CustomNumEnum {␊ - One = 1,␊ - Two = 2,␊ - Three = 3,␊ - Four = 4,␊ - Six = 6,␊ - Eight = 8,␊ - Nine = 9,␊ - Ten = 10␊ - }␊ - export function enumToI32(e: CustomNumEnum): number␊ - export function throwError(): void␊ - export function panic(): void␊ - export function receiveString(s: string): string␊ - export function customStatusCode(): void␊ - export function createExternal(size: number): ExternalObject␊ - export function createExternalString(content: string): ExternalObject␊ - export function getExternal(external: ExternalObject): number␊ - export function mutateExternal(external: ExternalObject, newVal: number): void␊ - export function validateArray(arr: Array): number␊ - export function validateBuffer(b: Buffer): number␊ - export function validateTypedArray(input: Uint8Array): number␊ - export function validateBigint(input: bigint): bigint␊ - export function validateBoolean(i: boolean): boolean␊ - export function validateDate(d: Date): number␊ - export function validateDateTime(d: Date): number␊ - export function validateExternal(e: ExternalObject): number␊ - export function validateFunction(cb: () => number): number␊ - export function validateHashMap(input: Record): number␊ - export function validateNull(i: null): boolean␊ - export function validateUndefined(i: undefined): boolean␊ - export function validateNumber(i: number): number␊ - export function validatePromise(p: Promise): Promise␊ - export function validateString(s: string): string␊ - export function validateSymbol(s: symbol): boolean␊ - export function validateOptional(input1?: string | undefined | null, input2?: boolean | undefined | null): boolean␊ - export function returnUndefinedIfInvalid(input: boolean): boolean␊ - export function returnUndefinedIfInvalidPromise(input: Promise): Promise␊ - export function tsRename(a: { foo: number }): string[]␊ - export function overrideIndividualArgOnFunction(notOverridden: string, f: () => string, notOverridden2: number): string␊ - export function overrideIndividualArgOnFunctionWithCbArg(callback: (town: string, name?: string | undefined | null) => string, notOverridden: number): object␊ - export function xxh64Alias(input: Buffer): bigint␊ - export function getMapping(): Record␊ - export function sumMapping(nums: Record): number␊ - export function mapOption(val?: number | undefined | null): number | null␊ - export function returnNull(): null␊ - export function returnUndefined(): void␊ - export function add(a: number, b: number): number␊ - export function fibonacci(n: number): number␊ - export function listObjKeys(obj: object): Array␊ - export function createObj(): object␊ - export function getGlobal(): typeof global␊ - export function getUndefined(): void␊ - export function getNull(): null␊ - export interface AllOptionalObject {␊ - name?: string␊ - age?: number␊ - }␊ - export function receiveAllOptionalObject(obj?: AllOptionalObject | undefined | null): void␊ - export const enum ALIAS {␊ - A = 0,␊ - B = 1␊ - }␊ - export interface AliasedStruct {␊ - a: ALIAS␊ - b: number␊ - }␊ - export function fnReceivedAliased(s: AliasedStruct, e: ALIAS): void␊ - export interface StrictObject {␊ - name: string␊ - }␊ - export function receiveStrictObject(strictObject: StrictObject): void␊ - export function getStrFromObject(): void␊ - export interface TsTypeChanged {␊ - typeOverride: object␊ - typeOverrideOptional?: object␊ - }␊ - export function createObjWithProperty(): { value: ArrayBuffer, get getter(): number }␊ - export function getterFromObj(): number␊ - export interface ObjectOnlyFromJs {␊ - count: number␊ - callback: (err: Error | null, value: number) => any␊ - }␊ - export function receiveObjectOnlyFromJs(obj: { count: number, callback: (err: Error | null, count: number) => void }): void␊ - export function asyncPlus100(p: Promise): Promise␊ - /** This is an interface for package.json */␊ - export interface PackageJson {␊ - name: string␊ - /** The version of the package */␊ - version: string␊ - dependencies?: Record␊ - devDependencies?: Record␊ - }␊ - export function readPackageJson(): PackageJson␊ - export function getPackageJsonName(packageJson: PackageJson): string␊ - export function testSerdeRoundtrip(data: any): any␊ - export function testSerdeBigNumberPrecision(number: string): any␊ - export function returnFromSharedCrate(): Shared␊ - export function contains(source: string, target: string): boolean␊ - export function concatStr(s: string): string␊ - export function concatUtf16(s: string): string␊ - export function concatLatin1(s: string): string␊ - export function roundtripStr(s: string): string␊ - export function setSymbolInObj(symbol: symbol): object␊ - export function createSymbol(): symbol␊ - export function withoutAbortController(a: number, b: number): Promise␊ - export function withAbortController(a: number, b: number, signal: AbortSignal): Promise␊ - export function callThreadsafeFunction(callback: (...args: any[]) => any): void␊ - export function callLongThreadsafeFunction(callback: (...args: any[]) => any): void␊ - export function threadsafeFunctionThrowError(cb: (...args: any[]) => any): void␊ - export function threadsafeFunctionFatalMode(cb: (...args: any[]) => any): void␊ - export function threadsafeFunctionFatalModeError(cb: (...args: any[]) => any): void␊ - export function threadsafeFunctionClosureCapture(func: (...args: any[]) => any): void␊ - export function tsfnCallWithCallback(func: (...args: any[]) => any): void␊ - export function tsfnAsyncCall(func: (...args: any[]) => any): Promise␊ - export function acceptThreadsafeFunction(func: (err: Error | null, value: number) => any): void␊ - export function acceptThreadsafeFunctionFatal(func: (value: number) => any): void␊ - export function acceptThreadsafeFunctionTupleArgs(func: (err: Error | null, arg0: number, arg1: boolean, arg2: string) => any): void␊ - export function tsfnReturnPromise(func: (err: Error | null, value: number) => any): Promise␊ - export function tsfnReturnPromiseTimeout(func: (err: Error | null, value: number) => any): Promise␊ - export function getBuffer(): Buffer␊ - export function appendBuffer(buf: Buffer): Buffer␊ - export function getEmptyBuffer(): Buffer␊ - export function convertU32Array(input: Uint32Array): Array␊ - export function createExternalTypedArray(): Uint32Array␊ - export function mutateTypedArray(input: Float32Array): void␊ - export function derefUint8Array(a: Uint8Array, b: Uint8ClampedArray): number␊ - export function bufferPassThrough(buf: Buffer): Promise␊ - export function arrayBufferPassThrough(buf: Uint8Array): Promise␊ - export function asyncReduceBuffer(buf: Buffer): Promise␊ - export function runScript(script: string): unknown␊ /**␊ * \`constructor\` option for \`struct\` requires all fields to be public,␊ * otherwise tag impl fn as constructor␊ @@ -262,30 +45,66 @@ Generated by [AVA](https://avajs.dev). /**␊ * Here are some characters and character sequences␊ * that should be escaped correctly:␊ - * \\[]{}/\\:""␊ + * \\[]{}/\\:""{␊ + * }␊ */␊ returnOtherClass(): Dog␊ returnOtherClassWithCustomConstructor(): Bird␊ overrideIndividualArgOnMethod(normalTy: string, overriddenTy: {n: string}): Bird␊ }␊ - export class Dog {␊ + ␊ + export class AnimalWithDefaultConstructor {␊ name: string␊ - constructor(name: string)␊ + kind: number␊ + constructor(name: string, kind: number)␊ }␊ + ␊ + export class AnotherClassForEither {␊ + constructor()␊ + }␊ + ␊ + export class AnotherCssStyleSheet {␊ + get rules(): CssRuleList␊ + }␊ + export type AnotherCSSStyleSheet = AnotherCssStyleSheet␊ + ␊ + export class Asset {␊ + constructor()␊ + get filePath(): number␊ + }␊ + export type JsAsset = Asset␊ + ␊ + export class Assets {␊ + constructor()␊ + get(id: number): JsAsset | null␊ + }␊ + export type JsAssets = Assets␊ + ␊ export class Bird {␊ name: string␊ constructor(name: string)␊ getCount(): number␊ getNameAsync(): Promise␊ }␊ - export type Blake2bHasher = Blake2BHasher␊ + ␊ /** Smoking test for type generation */␊ export class Blake2BHasher {␊ static withKey(key: Blake2bKey): Blake2BHasher␊ update(data: Buffer): void␊ }␊ + export type Blake2bHasher = Blake2BHasher␊ + ␊ + export class Blake2BKey {␊ + ␊ + }␊ export type Blake2bKey = Blake2BKey␊ - export class Blake2BKey { }␊ + ␊ + export class ClassWithFactory {␊ + name: string␊ + static withName(name: string): ClassWithFactory␊ + setName(name: string): this␊ + }␊ + ␊ export class Context {␊ maybeNeed?: boolean␊ buffer: Uint8Array␊ @@ -294,11 +113,64 @@ Generated by [AVA](https://avajs.dev). static withBuffer(buf: Uint8Array): Context␊ method(): string␊ }␊ - export class AnimalWithDefaultConstructor {␊ - name: string␊ - kind: number␊ - constructor(name: string, kind: number)␊ + ␊ + export class CssRuleList {␊ + getRules(): Array␊ + get parentStyleSheet(): CSSStyleSheet␊ + get name(): string | null␊ }␊ + export type CSSRuleList = CssRuleList␊ + ␊ + export class CssStyleSheet {␊ + constructor(name: string, rules: Array)␊ + get rules(): CssRuleList␊ + anotherCssStyleSheet(): AnotherCssStyleSheet␊ + }␊ + export type CSSStyleSheet = CssStyleSheet␊ + ␊ + export class CustomFinalize {␊ + constructor(width: number, height: number)␊ + }␊ + ␊ + export class Dog {␊ + name: string␊ + constructor(name: string)␊ + }␊ + ␊ + export class Fib {␊ + [Symbol.iterator](): Iterator␊ + constructor()␊ + }␊ + ␊ + export class Fib2 {␊ + [Symbol.iterator](): Iterator␊ + static create(seed: number): Fib2␊ + }␊ + ␊ + export class Fib3 {␊ + current: number␊ + next: number␊ + constructor(current: number, next: number)␊ + [Symbol.iterator](): Iterator␊ + }␊ + ␊ + export class GetterSetterWithClosures {␊ + constructor()␊ + }␊ + ␊ + export class JsClassForEither {␊ + constructor()␊ + }␊ + ␊ + export class JsRemote {␊ + name(): string␊ + }␊ + ␊ + export class JsRepo {␊ + constructor(dir: string)␊ + remote(): JsRemote␊ + }␊ + ␊ export class NinjaTurtle {␊ name: string␊ static isInstanceOf(value: unknown): boolean␊ @@ -308,90 +180,397 @@ Generated by [AVA](https://avajs.dev). getName(): string␊ returnThis(this: this): this␊ }␊ - export type JsAssets = Assets␊ - export class Assets {␊ - constructor()␊ - get(id: number): JsAsset | null␊ - }␊ - export type JsAsset = Asset␊ - export class Asset {␊ - constructor()␊ - get filePath(): number␊ + ␊ + export class NotWritableClass {␊ + name: string␊ + constructor(name: string)␊ + setName(name: string): void␊ }␊ + ␊ export class Optional {␊ static optionEnd(required: string, optional?: string | undefined | null): string␊ static optionStart(optional: string | undefined | null, required: string): string␊ static optionStartEnd(optional1: string | undefined | null, required: string, optional2?: string | undefined | null): string␊ static optionOnly(optional?: string | undefined | null): string␊ }␊ - export class NotWritableClass {␊ - name: string␊ - constructor(name: string)␊ - setName(name: string): void␊ - }␊ - export class CustomFinalize {␊ - constructor(width: number, height: number)␊ - }␊ + ␊ export class Width {␊ value: number␊ constructor(value: number)␊ }␊ - export class GetterSetterWithClosures {␊ - constructor()␊ + ␊ + export interface A {␊ + foo: number␊ }␊ - export class ClassWithFactory {␊ + ␊ + export function acceptThreadsafeFunction(func: (err: Error | null, value: number) => any): void␊ + ␊ + export function acceptThreadsafeFunctionFatal(func: (value: number) => any): void␊ + ␊ + export function acceptThreadsafeFunctionTupleArgs(func: (err: Error | null, arg0: number, arg1: boolean, arg2: string) => any): void␊ + ␊ + export function add(a: number, b: number): number␊ + ␊ + export const enum ALIAS {␊ + A = 0,␊ + B = 1␊ + }␊ + ␊ + export interface AliasedStruct {␊ + a: ALIAS␊ + b: number␊ + }␊ + ␊ + export interface AllOptionalObject {␊ + name?: string␊ + age?: number␊ + }␊ + ␊ + export function appendBuffer(buf: Buffer): Buffer␊ + ␊ + export function arrayBufferPassThrough(buf: Uint8Array): Promise␊ + ␊ + export function asyncMultiTwo(arg: number): Promise␊ + ␊ + export function asyncPlus100(p: Promise): Promise␊ + ␊ + export function asyncReduceBuffer(buf: Buffer): Promise␊ + ␊ + export interface B {␊ + bar: number␊ + }␊ + ␊ + export function bigintAdd(a: bigint, b: bigint): bigint␊ + ␊ + export function bigintFromI128(): bigint␊ + ␊ + export function bigintFromI64(): bigint␊ + ␊ + export function bigintGetU64AsString(bi: bigint): string␊ + ␊ + export function bufferPassThrough(buf: Buffer): Promise␊ + ␊ + export interface C {␊ + baz: number␊ + }␊ + ␊ + export function callbackReturnPromise(functionInput: () => T | Promise, callback: (err: Error | null, result: T) => void): T | Promise␊ + ␊ + export function callLongThreadsafeFunction(callback: (...args: any[]) => any): void␊ + ␊ + export function callThreadsafeFunction(callback: (...args: any[]) => any): void␊ + ␊ + export function captureErrorInCallback(cb1: () => void, cb2: (arg0: Error) => void): void␊ + ␊ + export function chronoDateAdd1Minute(input: Date): Date␊ + ␊ + export function chronoDateToMillis(input: Date): number␊ + ␊ + export function concatLatin1(s: string): string␊ + ␊ + export function concatStr(s: string): string␊ + ␊ + export function concatUtf16(s: string): string␊ + ␊ + export function contains(source: string, target: string): boolean␊ + ␊ + export function convertU32Array(input: Uint32Array): Array␊ + ␊ + export function createBigInt(): bigint␊ + ␊ + export function createBigIntI64(): bigint␊ + ␊ + export function createExternal(size: number): ExternalObject␊ + ␊ + export function createExternalString(content: string): ExternalObject␊ + ␊ + export function createExternalTypedArray(): Uint32Array␊ + ␊ + export function createObj(): object␊ + ␊ + export function createObjectWithClassField(): ObjectFieldClassInstance␊ + ␊ + export function createObjWithProperty(): { value: ArrayBuffer, get getter(): number }␊ + ␊ + export function createSymbol(): symbol␊ + ␊ + /** You could break the step and for an new continuous value. */␊ + export const enum CustomNumEnum {␊ + One = 1,␊ + Two = 2,␊ + Three = 3,␊ + Four = 4,␊ + Six = 6,␊ + Eight = 8,␊ + Nine = 9,␊ + Ten = 10␊ + }␊ + ␊ + export function customStatusCode(): void␊ + ␊ + export interface Dates {␊ + start: Date␊ + end?: Date␊ + }␊ + ␊ + export function dateToNumber(input: Date): number␊ + ␊ + /** This is a const */␊ + export const DEFAULT_COST: number␊ + ␊ + export function derefUint8Array(a: Uint8Array, b: Uint8ClampedArray): number␊ + ␊ + export function either3(input: string | number | boolean): number␊ + ␊ + export function either4(input: string | number | boolean | Obj): number␊ + ␊ + export function eitherBoolOrFunction(input: boolean | ((...args: any[]) => any)): void␊ + ␊ + export function eitherFromObjects(input: A | B | C): string␊ + ␊ + export function eitherFromOption(): JsClassForEither | undefined␊ + ␊ + export function eitherStringOrNumber(input: string | number): number␊ + ␊ + export const enum Empty {␊ + ␊ + }␊ + ␊ + export function enumToI32(e: CustomNumEnum): number␊ + ␊ + export function fibonacci(n: number): number␊ + ␊ + export function fnReceivedAliased(s: AliasedStruct, e: ALIAS): void␊ + ␊ + export function getBuffer(): Buffer␊ + ␊ + export function getCwd(callback: (arg0: string) => void): void␊ + ␊ + export function getEmptyBuffer(): Buffer␊ + ␊ + export function getExternal(external: ExternalObject): number␊ + ␊ + export function getGlobal(): typeof global␊ + ␊ + export function getMapping(): Record␊ + ␊ + export function getNestedNumArr(): number[][][]␊ + ␊ + export function getNull(): null␊ + ␊ + export function getNumArr(): number[]␊ + ␊ + /** Gets some numbers */␊ + export function getNums(): Array␊ + ␊ + export function getPackageJsonName(packageJson: PackageJson): string␊ + ␊ + export function getStrFromObject(): void␊ + ␊ + export function getterFromObj(): number␊ + ␊ + export function getUndefined(): void␊ + ␊ + export function getWords(): Array␊ + ␊ + /** default enum values are continuos i32s start from 0 */␊ + export const enum Kind {␊ + /** Barks */␊ + Dog = 0,␊ + /** Kills birds */␊ + Cat = 1,␊ + /** Tasty */␊ + Duck = 2␊ + }␊ + ␊ + export function listObjKeys(obj: object): Array␊ + ␊ + export function mapOption(val?: number | undefined | null): number | null␊ + ␊ + export function mutateExternal(external: ExternalObject, newVal: number): void␊ + ␊ + export function mutateTypedArray(input: Float32Array): void␊ + ␊ + export interface Obj {␊ + v: string | number␊ + }␊ + ␊ + export interface ObjectFieldClassInstance {␊ + bird: Bird␊ + }␊ + ␊ + export interface ObjectOnlyFromJs {␊ + count: number␊ + callback: (err: Error | null, value: number) => any␊ + }␊ + ␊ + export function optionEnd(callback: (arg0: string, arg1?: string | undefined | null) => void): void␊ + ␊ + export function optionOnly(callback: (arg0?: string | undefined | null) => void): void␊ + ␊ + export function optionStart(callback: (arg0: string | undefined | null, arg1: string) => void): void␊ + ␊ + export function optionStartEnd(callback: (arg0: string | undefined | null, arg1: string, arg2?: string | undefined | null) => void): void␊ + ␊ + export function overrideIndividualArgOnFunction(notOverridden: string, f: () => string, notOverridden2: number): string␊ + ␊ + export function overrideIndividualArgOnFunctionWithCbArg(callback: (town: string, name?: string | undefined | null) => string, notOverridden: number): object␊ + ␊ + /** This is an interface for package.json */␊ + export interface PackageJson {␊ name: string␊ - static withName(name: string): ClassWithFactory␊ - setName(name: string): this␊ + /** The version of the package */␊ + version: string␊ + dependencies?: Record␊ + devDependencies?: Record␊ }␊ - export class JsClassForEither {␊ - constructor()␊ + ␊ + export function panic(): void␊ + ␊ + export function plusOne(this: Width): number␊ + ␊ + export function promiseInEither(input: number | Promise): Promise␊ + ␊ + /** napi = { version = 2, features = ["serde-json"] } */␊ + export function readFile(callback: (arg0: Error | undefined, arg1?: string | undefined | null) => void): void␊ + ␊ + export function readFileAsync(path: string): Promise␊ + ␊ + export function readPackageJson(): PackageJson␊ + ␊ + export function receiveAllOptionalObject(obj?: AllOptionalObject | undefined | null): void␊ + ␊ + export function receiveClassOrNumber(either: number | JsClassForEither): number␊ + ␊ + export function receiveDifferentClass(either: JsClassForEither | AnotherClassForEither): number␊ + ␊ + export function receiveMutClassOrNumber(either: number | JsClassForEither): number␊ + ␊ + export function receiveObjectOnlyFromJs(obj: { count: number, callback: (err: Error | null, count: number) => void }): void␊ + ␊ + export function receiveObjectWithClassField(object: ObjectFieldClassInstance): Bird␊ + ␊ + export function receiveStrictObject(strictObject: StrictObject): void␊ + ␊ + export function receiveString(s: string): string␊ + ␊ + export function returnEither(input: number): string | number␊ + ␊ + export function returnEitherClass(input: number): number | JsClassForEither␊ + ␊ + export function returnFromSharedCrate(): Shared␊ + ␊ + export function returnJsFunction(): (...args: any[]) => any␊ + ␊ + export function returnNull(): null␊ + ␊ + export function returnUndefined(): void␊ + ␊ + export function returnUndefinedIfInvalid(input: boolean): boolean␊ + ␊ + export function returnUndefinedIfInvalidPromise(input: Promise): Promise␊ + ␊ + export function roundtripStr(s: string): string␊ + ␊ + export function runScript(script: string): unknown␊ + ␊ + export function setSymbolInObj(symbol: symbol): object␊ + ␊ + export interface Shared {␊ + value: number␊ }␊ - export class AnotherClassForEither {␊ - constructor()␊ + ␊ + export const enum Status {␊ + Pristine = 'Pristine',␊ + Loading = 'Loading',␊ + Ready = 'Ready'␊ }␊ - export class Fib {␊ - [Symbol.iterator](): Iterator␊ - constructor()␊ + ␊ + export interface StrictObject {␊ + name: string␊ }␊ - export class Fib2 {␊ - [Symbol.iterator](): Iterator␊ - static create(seed: number): Fib2␊ + ␊ + export function sumMapping(nums: Record): number␊ + ␊ + export function sumNums(nums: Array): number␊ + ␊ + export function testSerdeBigNumberPrecision(number: string): any␊ + ␊ + export function testSerdeRoundtrip(data: any): any␊ + ␊ + export function threadsafeFunctionClosureCapture(func: (...args: any[]) => any): void␊ + ␊ + export function threadsafeFunctionFatalMode(cb: (...args: any[]) => any): void␊ + ␊ + export function threadsafeFunctionFatalModeError(cb: (...args: any[]) => any): void␊ + ␊ + export function threadsafeFunctionThrowError(cb: (...args: any[]) => any): void␊ + ␊ + export function throwError(): void␊ + ␊ + export function toJsObj(): object␊ + ␊ + export function tsfnAsyncCall(func: (...args: any[]) => any): Promise␊ + ␊ + export function tsfnCallWithCallback(func: (...args: any[]) => any): void␊ + ␊ + export function tsfnReturnPromise(func: (err: Error | null, value: number) => any): Promise␊ + ␊ + export function tsfnReturnPromiseTimeout(func: (err: Error | null, value: number) => any): Promise␊ + ␊ + export function tsRename(a: { foo: number }): string[]␊ + ␊ + export interface TsTypeChanged {␊ + typeOverride: object␊ + typeOverrideOptional?: object␊ }␊ - export class Fib3 {␊ - current: number␊ - next: number␊ - constructor(current: number, next: number)␊ - [Symbol.iterator](): Iterator␊ - }␊ - export class JsRepo {␊ - constructor(dir: string)␊ - remote(): JsRemote␊ - }␊ - export class JsRemote {␊ - name(): string␊ - }␊ - export type CSSRuleList = CssRuleList␊ - export class CssRuleList {␊ - getRules(): Array␊ - get parentStyleSheet(): CSSStyleSheet␊ - get name(): string | null␊ - }␊ - export type CSSStyleSheet = CssStyleSheet␊ - export class CssStyleSheet {␊ - constructor(name: string, rules: Array)␊ - get rules(): CssRuleList␊ - anotherCssStyleSheet(): AnotherCssStyleSheet␊ - }␊ - export type AnotherCSSStyleSheet = AnotherCssStyleSheet␊ - export class AnotherCssStyleSheet {␊ - get rules(): CssRuleList␊ + ␊ + export function validateArray(arr: Array): number␊ + ␊ + export function validateBigint(input: bigint): bigint␊ + ␊ + export function validateBoolean(i: boolean): boolean␊ + ␊ + export function validateBuffer(b: Buffer): number␊ + ␊ + export function validateDate(d: Date): number␊ + ␊ + export function validateDateTime(d: Date): number␊ + ␊ + export function validateExternal(e: ExternalObject): number␊ + ␊ + export function validateFunction(cb: () => number): number␊ + ␊ + export function validateHashMap(input: Record): number␊ + ␊ + export function validateNull(i: null): boolean␊ + ␊ + export function validateNumber(i: number): number␊ + ␊ + export function validateOptional(input1?: string | undefined | null, input2?: boolean | undefined | null): boolean␊ + ␊ + export function validatePromise(p: Promise): Promise␊ + ␊ + export function validateString(s: string): string␊ + ␊ + export function validateSymbol(s: symbol): boolean␊ + ␊ + export function validateTypedArray(input: Uint8Array): number␊ + ␊ + export function validateUndefined(i: undefined): boolean␊ + ␊ + export function withAbortController(a: number, b: number, signal: AbortSignal): Promise␊ + ␊ + export function withoutAbortController(a: number, b: number): Promise␊ + ␊ + export function xxh64Alias(input: Buffer): bigint␊ + ␊ + export namespace xxh2 {␊ + export function xxh2Plus(a: number, b: number): number␊ + export function xxh3Xxh64Alias(input: Buffer): bigint␊ }␊ + ␊ export namespace xxh3 {␊ - export const ALIGNMENT: number␊ - export function xxh3_64(input: Buffer): bigint␊ - /** xxh128 function */␊ - export function xxh128(input: Buffer): bigint␊ /** Xxh3 class */␊ export class Xxh3 {␊ constructor()␊ @@ -399,9 +578,10 @@ Generated by [AVA](https://avajs.dev). update(input: Buffer): void␊ digest(): bigint␊ }␊ + export const ALIGNMENT: number␊ + /** xxh128 function */␊ + export function xxh128(input: Buffer): bigint␊ + export function xxh3_64(input: Buffer): bigint␊ }␊ - export namespace xxh2 {␊ - export function xxh2Plus(a: number, b: number): number␊ - export function xxh3Xxh64Alias(input: Buffer): bigint␊ - }␊ + ␊ ` diff --git a/examples/napi/__tests__/__snapshots__/typegen.spec.ts.snap b/examples/napi/__tests__/__snapshots__/typegen.spec.ts.snap new file mode 100644 index 0000000000000000000000000000000000000000..27a610deccc883cea3475db33eb48f344c7f87dc GIT binary patch literal 3952 zcmV-$50CIcRzVEC<^#r-+)a~L=!mP*bahp5GSx5JL_zGfoIa} zA{%Tp5@&|7Mw}HXJ6^AW?i=)X{}j7V*hlC&yhxNpNp?2PRie&0JR}dlb0Pi9bdvDs zO#J*Sl}sk|eVPDR2}c|T?%oFo(* zS61l9CC?;@l28b;_fgU;4U^-^2T3ZcF6u7rS?veKqPle3#Nb>AG;Y-PQN~Sy`?{({Y5dK5XGAc-z zBrtlK#DYjpCX_7mNy4I46vO45W*1CQBEuPBizSezBoxFEk92>13p2+8r*-gd1&3Z4 z_;$(`VWI{HYLc&68WTPxp>76hXUJ#pai~ZP^?1$%fj^*;+q-6S8iJB@m89W0hKAH; zM8Y;X^0j`rw2qScb&)5M-3PnEu`d=hmAW0(g!vjiB zN3X}ZwzgIoHfZ{s&(y#N?(FN{zM>f=A^a750gBAS3?`6fpd~D1@d{%DLro(pG?$!* zl9>Gm)-(6jQ`Q7l&oh#jNT?{3oGSAXuw8dRCB-9Pm^n7^( z^Rb%?$rrnhMF9B@%Wx?CoMst|=|LK^a~9`evYpM2(?ewdLCP~&-tncKvQ^TZ=x9#CF0YKqW_d!@T*K#6cz(r%1PMlfLQcy+8ae!1Ua|F_g)m)JHPl@r z8lQx6j=h`7sdoHQXaQSVkWaX1lOC{gCWnQjpP(s8{M`uKkEnHoHsD*^{+KPjTUJ_l_1E3}Hqj6;i>u($Y91g!nq-?j+$E-Prjm z6xJYIfTNee83n`ER1-I^Xk7MDNGSv`5-!5c9DgX=4}{ES7VN1*>FE*=#P`u^v3%?I5QvV4qEtfVU$R zJgzZ`=)tphIP?Sa^2Dlx8-3L%^R(BYfb5OmAl#UE1YsaRj)48-AT`SNb-1Z#G|$jJ z9ZXGOBeeL|8u4m{cJPVn*HwE#B`}QCzbY_ExX3Z$?)S?t#jRcWOK}QOprnOubZmX3 zUGj#|m}Rb`%9Ol7`A99hA?S#uAHs2-L5|gdzf2rJCn1D{$J5|EOmd3p%vs7W(t!(? z=;3zN(vwS`XCy`GL@M!rf#~*MzgB|PlwO>MOBEwHdgvX07>cu9p6KAO(8qY$N}CQL zF)R)c?FsXcVHzqh{nn98Yak3IJ<=hEpE!8wnBNe-aQAC$=JjWbZgj2e2J_JZH zBmtx%L$a4;5cb(Qt9DJco`Orev<7wK4)!79NNg{kN8~tPCKPfj(V={p%^s8p3~%cN z7^v5c!oqsBh~pqEMNJ&1VWzuSS6nwjp_OdEI@lhmb=e00{a_UycHm*%zkmq~1&v2) z%@q^$rzBvQ=UG*kHL+V+S9}W4c;=XHIK$Tt<5(_f8oO~{5sK>v4+};@`r`>$Gb|F% zXLC=`Xp@by@u^1|rY472hZtY*0G7v@WGldWLO=6Kl8f~R4}xWb;l?6PX`DyYI}2?B z%7xfb6F&*Fu6drY8E|ZCgVHa`p!DOwKD06JgBAzt8;^sVQ9gRuPY7Ye>qif_A-qIW z2`0=@#+Xl&)4%GC$2kA10xGGRPcnmwg zq**Pv{pbLJ5*XW%j1@2Ld(gWo!mrRPp3XcV>h!j@wg&bKt{yPu?YmxdLC()Ca0&B8 z)p!rmT_Y!mChK;pbYK}x00ILIlZx1#iWbqZ+$o1Vl7b1ZAF?!u2#)Dhz}A8OuZwZa z4_T5xI8URLt&wv2Si8HRAk7lXr(il9X31Ag`T!8?$Y(3fhM(w2Z4Z8(t+UG zp+b*hmfBznPMS)Gipi;ovz34zabw7gV?Aku%7nEsf_S9ls+SHT_^LA~Op5TV0=aa% zdQ~56lF=atg#dmmVR@B`S2lv$E`8;ysu;{v+E&)+h!6ghSe+@VoI;0YliVB{K*DZxFvcGcTSFVg)@%YO-6Pr+Rv$XQw_}&-eDXU%wiEzk56y zw}VzpGdeB99rX3(oAUSS70ha3ExH2&smjqet=3NAOIglO7HWD$JnR(#PhiHqf_8xV zI4fM0ky^?K+FVwvW6^RkXwloQa1YxcZU_GEc7U?OtRi7uQ>c|VoW!h6f`+T(tZF5- z$?6RH_ZCZOO3uwbfMCoIHa7wQgvy5NnC~f@Kx7|9EJ)k4j*>b(r4eQ4U{gAwK%Z90 zEmjFNiAC#D05q8hxFh(-Q-+J!4N`O*;bc^ufdufYxw=tLg;S#Dq0Jw4Obv*6k?={V zkQ7U-d`f1j!ApAx2@$$3AciUBS^UI0`c~J6)gKBN9K))@mM*dV?K}MKXMk8#6DEE= znzA%by}(l=bxx|=g@aTzey8HzrTYmiBV>s$1y5BCX<5EQKwrLe>_dZEvnq0Q0L6nIRfHuZV2s8$P|7@uD zgt2iM~Ymv9T9o2$~57&@o{)T4jjoP&EpyuBl67SsE<5_jH_YhS>CMW}t2(B{6fh*nt2=YS&HoxYZ`4Dpz{C=s;P5G&k{ z^{8tt<*Scgg~p9~Ir`RTLr)#u>o40zqGT)YQsfUhsc_b^o|AN#g%S9i;oxa1^~E$R z(UaVGuW0pmaG1-_u5{gH>fq(7>NWf7vlZgPl*o185_qdQ8mih$I`+C)iW1dcKZ8>!jt;^dc43}~=hp0K;#f!?!i=XlyV#x7GMUAj}$CmAFz zy6$(^KHtUM=M@iQG+bymkE;0;fE@4Q-Bk~Fy{-|{4>DOR23A7X(vntWDy3jIHmP&|~p_)P*Wdpiw(DSA#9q?o2EvcVI$-UYB| zf!%qa0)?R*<=E_r-X|`qz%rq8qWTFJKzfhU8=Z{Vg7RGcfBHJ5>PA|KQHFC1MnwyH zvpMy*5>&12cQx$!!wo9_mc?47*0nP)TP2ESY-)wJ;O zX%}v+lv@PF1&cls6;2e>t8BB>Sh=IrH@{`D$%f@*b#;vQ=(i`(gm>mMo+PlMzDs1Q zM6j7EsVeG`db!C2Vh4bzH|gUh;y!+yKYFOnitGdxP*B4h#9FaL00ka>9or*p1Mg$? zT$}SUZhq6N$+cgX&7wB{4Zi40ma0T#<5ku2jiqeAMevjD< zA~xr01yMg+Rtb@}Umd(SI@~)NJ445wKh;h)3rA3f}ty#E1D KFN5d7IsgDKxQVy` literal 0 HcmV?d00001 diff --git a/examples/napi/__tests__/__snapshots__/values.spec.ts.md b/examples/napi/__tests__/__snapshots__/values.spec.ts.md new file mode 100644 index 00000000..b45716d5 --- /dev/null +++ b/examples/napi/__tests__/__snapshots__/values.spec.ts.md @@ -0,0 +1,17 @@ +# Snapshot report for `__tests__/values.spec.ts` + +The actual snapshot is saved in `values.spec.ts.snap`. + +Generated by [AVA](https://avajs.dev). + +## serde-json + +> Snapshot 1 + + [ + '@napi-rs/cli', + '@types/lodash', + 'ava', + 'lodash', + 'sinon', + ] diff --git a/examples/napi/__tests__/__snapshots__/values.spec.ts.snap b/examples/napi/__tests__/__snapshots__/values.spec.ts.snap new file mode 100644 index 0000000000000000000000000000000000000000..8f5900f62cba8fbcef6fad16998027e1c7635d51 GIT binary patch literal 233 zcmV!!$L486wK1$>yE!Z)dFWu2uRO%e7Y>IdRP+=&PAA~ui~knFt|13;YeJZG?CkTA&TV#c<>X)7SB>4`2qR*lg=2@vhN4nwc7 jGENF?qn<_0#ZAPJ$1wdrp2s{vZJqr9tTxaX@Bjb+$;@Uw literal 0 HcmV?d00001 diff --git a/examples/napi/__test__/error-msg.spec.ts b/examples/napi/__tests__/error-msg.spec.ts similarity index 100% rename from examples/napi/__test__/error-msg.spec.ts rename to examples/napi/__tests__/error-msg.spec.ts diff --git a/examples/napi/__test__/generator.spec.ts b/examples/napi/__tests__/generator.spec.ts similarity index 100% rename from examples/napi/__test__/generator.spec.ts rename to examples/napi/__tests__/generator.spec.ts diff --git a/examples/napi/__test__/object-attr.spec.ts b/examples/napi/__tests__/object-attr.spec.ts similarity index 100% rename from examples/napi/__test__/object-attr.spec.ts rename to examples/napi/__tests__/object-attr.spec.ts diff --git a/examples/napi/__test__/strict.spec.ts b/examples/napi/__tests__/strict.spec.ts similarity index 100% rename from examples/napi/__test__/strict.spec.ts rename to examples/napi/__tests__/strict.spec.ts diff --git a/examples/napi/__test__/tsfn-error.js b/examples/napi/__tests__/tsfn-error.js similarity index 100% rename from examples/napi/__test__/tsfn-error.js rename to examples/napi/__tests__/tsfn-error.js diff --git a/examples/napi/__test__/typegen.spec.ts b/examples/napi/__tests__/typegen.spec.ts similarity index 100% rename from examples/napi/__test__/typegen.spec.ts rename to examples/napi/__tests__/typegen.spec.ts diff --git a/examples/napi/__test__/unload.spec.js b/examples/napi/__tests__/unload.spec.js similarity index 100% rename from examples/napi/__test__/unload.spec.js rename to examples/napi/__tests__/unload.spec.js diff --git a/examples/napi/__test__/values.spec.ts b/examples/napi/__tests__/values.spec.ts similarity index 99% rename from examples/napi/__test__/values.spec.ts rename to examples/napi/__tests__/values.spec.ts index 2a87c012..2c373e53 100644 --- a/examples/napi/__test__/values.spec.ts +++ b/examples/napi/__tests__/values.spec.ts @@ -460,12 +460,12 @@ test('aliased rust struct and enum', (t) => { test('serde-json', (t) => { const packageJson = readPackageJson() - t.is(packageJson.name, 'napi-rs') + t.is(packageJson.name, '@examples/napi') t.is(packageJson.version, '0.0.0') t.is(packageJson.dependencies, undefined) t.snapshot(Object.keys(packageJson.devDependencies!).sort()) - t.is(getPackageJsonName(packageJson), 'napi-rs') + t.is(getPackageJsonName(packageJson), '@examples/napi') }) test('serde-roundtrip', (t) => { @@ -562,7 +562,7 @@ test('async', async (t) => { await t.notThrowsAsync(bufPromise) const buf = await bufPromise const { name } = JSON.parse(buf.toString()) - t.is(name, 'examples') + t.is(name, '@examples/napi') await t.throwsAsync(() => readFileAsync('some_nonexist_path.file')) }) diff --git a/examples/napi/__test__/worker-thread.spec.ts b/examples/napi/__tests__/worker-thread.spec.ts similarity index 100% rename from examples/napi/__test__/worker-thread.spec.ts rename to examples/napi/__tests__/worker-thread.spec.ts diff --git a/examples/napi/__test__/worker.js b/examples/napi/__tests__/worker.js similarity index 100% rename from examples/napi/__test__/worker.js rename to examples/napi/__tests__/worker.js diff --git a/examples/napi/index.d.ts b/examples/napi/index.d.ts index aba4722f..9dc42e10 100644 --- a/examples/napi/index.d.ts +++ b/examples/napi/index.d.ts @@ -1,7 +1,6 @@ -/* tslint:disable */ +/* auto-generated by NAPI-RS */ /* eslint-disable */ -/* auto-generated by NAPI-RS */ export class ExternalObject { readonly '': { @@ -9,222 +8,6 @@ export class ExternalObject { [K: symbol]: T } } -export interface Shared { - value: number -} -/** This is a const */ -export const DEFAULT_COST: number -export function getWords(): Array -/** Gets some numbers */ -export function getNums(): Array -export function sumNums(nums: Array): number -export function toJsObj(): object -export function getNumArr(): number[] -export function getNestedNumArr(): number[][][] -export function readFileAsync(path: string): Promise -export function asyncMultiTwo(arg: number): Promise -export function bigintAdd(a: bigint, b: bigint): bigint -export function createBigInt(): bigint -export function createBigIntI64(): bigint -export function bigintGetU64AsString(bi: bigint): string -export function bigintFromI64(): bigint -export function bigintFromI128(): bigint -export function getCwd(callback: (arg0: string) => void): void -export function optionEnd(callback: (arg0: string, arg1?: string | undefined | null) => void): void -export function optionStart(callback: (arg0: string | undefined | null, arg1: string) => void): void -export function optionStartEnd(callback: (arg0: string | undefined | null, arg1: string, arg2?: string | undefined | null) => void): void -export function optionOnly(callback: (arg0?: string | undefined | null) => void): void -/** napi = { version = 2, features = ["serde-json"] } */ -export function readFile(callback: (arg0: Error | undefined, arg1?: string | undefined | null) => void): void -export function returnJsFunction(): (...args: any[]) => any -export function callbackReturnPromise(functionInput: () => T | Promise, callback: (err: Error | null, result: T) => void): T | Promise -export function captureErrorInCallback(cb1: () => void, cb2: (arg0: Error) => void): void -export interface ObjectFieldClassInstance { - bird: Bird -} -export function createObjectWithClassField(): ObjectFieldClassInstance -export function receiveObjectWithClassField(object: ObjectFieldClassInstance): Bird -export function plusOne(this: Width): number -export function dateToNumber(input: Date): number -export function chronoDateToMillis(input: Date): number -export function chronoDateAdd1Minute(input: Date): Date -export interface Dates { - start: Date - end?: Date -} -export function eitherStringOrNumber(input: string | number): number -export function returnEither(input: number): string | number -export function either3(input: string | number | boolean): number -export interface Obj { - v: string | number -} -export function either4(input: string | number | boolean | Obj): number -export function receiveClassOrNumber(either: number | JsClassForEither): number -export function receiveMutClassOrNumber(either: number | JsClassForEither): number -export function receiveDifferentClass(either: JsClassForEither | AnotherClassForEither): number -export function returnEitherClass(input: number): number | JsClassForEither -export function eitherFromOption(): JsClassForEither | undefined -export interface A { - foo: number -} -export interface B { - bar: number -} -export interface C { - baz: number -} -export function eitherFromObjects(input: A | B | C): string -export function eitherBoolOrFunction(input: boolean | ((...args: any[]) => any)): void -export function promiseInEither(input: number | Promise): Promise -/** default enum values are continuos i32s start from 0 */ -export const enum Kind { - /** Barks */ - Dog = 0, - /** Kills birds */ - Cat = 1, - /** Tasty */ - Duck = 2 -} -export const enum Empty { - -} -export const enum Status { - Pristine = 'Pristine', - Loading = 'Loading', - Ready = 'Ready' -} -/** You could break the step and for an new continuous value. */ -export const enum CustomNumEnum { - One = 1, - Two = 2, - Three = 3, - Four = 4, - Six = 6, - Eight = 8, - Nine = 9, - Ten = 10 -} -export function enumToI32(e: CustomNumEnum): number -export function throwError(): void -export function panic(): void -export function receiveString(s: string): string -export function customStatusCode(): void -export function createExternal(size: number): ExternalObject -export function createExternalString(content: string): ExternalObject -export function getExternal(external: ExternalObject): number -export function mutateExternal(external: ExternalObject, newVal: number): void -export function validateArray(arr: Array): number -export function validateBuffer(b: Buffer): number -export function validateTypedArray(input: Uint8Array): number -export function validateBigint(input: bigint): bigint -export function validateBoolean(i: boolean): boolean -export function validateDate(d: Date): number -export function validateDateTime(d: Date): number -export function validateExternal(e: ExternalObject): number -export function validateFunction(cb: () => number): number -export function validateHashMap(input: Record): number -export function validateNull(i: null): boolean -export function validateUndefined(i: undefined): boolean -export function validateNumber(i: number): number -export function validatePromise(p: Promise): Promise -export function validateString(s: string): string -export function validateSymbol(s: symbol): boolean -export function validateOptional(input1?: string | undefined | null, input2?: boolean | undefined | null): boolean -export function returnUndefinedIfInvalid(input: boolean): boolean -export function returnUndefinedIfInvalidPromise(input: Promise): Promise -export function tsRename(a: { foo: number }): string[] -export function overrideIndividualArgOnFunction(notOverridden: string, f: () => string, notOverridden2: number): string -export function overrideIndividualArgOnFunctionWithCbArg(callback: (town: string, name?: string | undefined | null) => string, notOverridden: number): object -export function xxh64Alias(input: Buffer): bigint -export function getMapping(): Record -export function sumMapping(nums: Record): number -export function mapOption(val?: number | undefined | null): number | null -export function returnNull(): null -export function returnUndefined(): void -export function add(a: number, b: number): number -export function fibonacci(n: number): number -export function listObjKeys(obj: object): Array -export function createObj(): object -export function getGlobal(): typeof global -export function getUndefined(): void -export function getNull(): null -export interface AllOptionalObject { - name?: string - age?: number -} -export function receiveAllOptionalObject(obj?: AllOptionalObject | undefined | null): void -export const enum ALIAS { - A = 0, - B = 1 -} -export interface AliasedStruct { - a: ALIAS - b: number -} -export function fnReceivedAliased(s: AliasedStruct, e: ALIAS): void -export interface StrictObject { - name: string -} -export function receiveStrictObject(strictObject: StrictObject): void -export function getStrFromObject(): void -export interface TsTypeChanged { - typeOverride: object - typeOverrideOptional?: object -} -export function createObjWithProperty(): { value: ArrayBuffer, get getter(): number } -export function getterFromObj(): number -export interface ObjectOnlyFromJs { - count: number - callback: (err: Error | null, value: number) => any -} -export function receiveObjectOnlyFromJs(obj: { count: number, callback: (err: Error | null, count: number) => void }): void -export function asyncPlus100(p: Promise): Promise -/** This is an interface for package.json */ -export interface PackageJson { - name: string - /** The version of the package */ - version: string - dependencies?: Record - devDependencies?: Record -} -export function readPackageJson(): PackageJson -export function getPackageJsonName(packageJson: PackageJson): string -export function testSerdeRoundtrip(data: any): any -export function testSerdeBigNumberPrecision(number: string): any -export function returnFromSharedCrate(): Shared -export function contains(source: string, target: string): boolean -export function concatStr(s: string): string -export function concatUtf16(s: string): string -export function concatLatin1(s: string): string -export function roundtripStr(s: string): string -export function setSymbolInObj(symbol: symbol): object -export function createSymbol(): symbol -export function withoutAbortController(a: number, b: number): Promise -export function withAbortController(a: number, b: number, signal: AbortSignal): Promise -export function callThreadsafeFunction(callback: (...args: any[]) => any): void -export function callLongThreadsafeFunction(callback: (...args: any[]) => any): void -export function threadsafeFunctionThrowError(cb: (...args: any[]) => any): void -export function threadsafeFunctionFatalMode(cb: (...args: any[]) => any): void -export function threadsafeFunctionFatalModeError(cb: (...args: any[]) => any): void -export function threadsafeFunctionClosureCapture(func: (...args: any[]) => any): void -export function tsfnCallWithCallback(func: (...args: any[]) => any): void -export function tsfnAsyncCall(func: (...args: any[]) => any): Promise -export function acceptThreadsafeFunction(func: (err: Error | null, value: number) => any): void -export function acceptThreadsafeFunctionFatal(func: (value: number) => any): void -export function acceptThreadsafeFunctionTupleArgs(func: (err: Error | null, arg0: number, arg1: boolean, arg2: string) => any): void -export function tsfnReturnPromise(func: (err: Error | null, value: number) => any): Promise -export function tsfnReturnPromiseTimeout(func: (err: Error | null, value: number) => any): Promise -export function getBuffer(): Buffer -export function appendBuffer(buf: Buffer): Buffer -export function getEmptyBuffer(): Buffer -export function convertU32Array(input: Uint32Array): Array -export function createExternalTypedArray(): Uint32Array -export function mutateTypedArray(input: Float32Array): void -export function derefUint8Array(a: Uint8Array, b: Uint8ClampedArray): number -export function bufferPassThrough(buf: Buffer): Promise -export function arrayBufferPassThrough(buf: Uint8Array): Promise -export function asyncReduceBuffer(buf: Buffer): Promise -export function runScript(script: string): unknown /** * `constructor` option for `struct` requires all fields to be public, * otherwise tag impl fn as constructor @@ -252,30 +35,66 @@ export class Animal { /** * Here are some characters and character sequences * that should be escaped correctly: - * \[]{}/\:"" + * \[]{}/\:""{ + * } */ returnOtherClass(): Dog returnOtherClassWithCustomConstructor(): Bird overrideIndividualArgOnMethod(normalTy: string, overriddenTy: {n: string}): Bird } -export class Dog { + +export class AnimalWithDefaultConstructor { name: string - constructor(name: string) + kind: number + constructor(name: string, kind: number) } + +export class AnotherClassForEither { + constructor() +} + +export class AnotherCssStyleSheet { + get rules(): CssRuleList +} +export type AnotherCSSStyleSheet = AnotherCssStyleSheet + +export class Asset { + constructor() + get filePath(): number +} +export type JsAsset = Asset + +export class Assets { + constructor() + get(id: number): JsAsset | null +} +export type JsAssets = Assets + export class Bird { name: string constructor(name: string) getCount(): number getNameAsync(): Promise } -export type Blake2bHasher = Blake2BHasher + /** Smoking test for type generation */ export class Blake2BHasher { static withKey(key: Blake2bKey): Blake2BHasher update(data: Buffer): void +} +export type Blake2bHasher = Blake2BHasher + +export class Blake2BKey { + } export type Blake2bKey = Blake2BKey -export class Blake2BKey { } + +export class ClassWithFactory { + name: string + static withName(name: string): ClassWithFactory + setName(name: string): this +} + export class Context { maybeNeed?: boolean buffer: Uint8Array @@ -284,11 +103,64 @@ export class Context { static withBuffer(buf: Uint8Array): Context method(): string } -export class AnimalWithDefaultConstructor { - name: string - kind: number - constructor(name: string, kind: number) + +export class CssRuleList { + getRules(): Array + get parentStyleSheet(): CSSStyleSheet + get name(): string | null } +export type CSSRuleList = CssRuleList + +export class CssStyleSheet { + constructor(name: string, rules: Array) + get rules(): CssRuleList + anotherCssStyleSheet(): AnotherCssStyleSheet +} +export type CSSStyleSheet = CssStyleSheet + +export class CustomFinalize { + constructor(width: number, height: number) +} + +export class Dog { + name: string + constructor(name: string) +} + +export class Fib { + [Symbol.iterator](): Iterator + constructor() +} + +export class Fib2 { + [Symbol.iterator](): Iterator + static create(seed: number): Fib2 +} + +export class Fib3 { + current: number + next: number + constructor(current: number, next: number) + [Symbol.iterator](): Iterator +} + +export class GetterSetterWithClosures { + constructor() +} + +export class JsClassForEither { + constructor() +} + +export class JsRemote { + name(): string +} + +export class JsRepo { + constructor(dir: string) + remote(): JsRemote +} + export class NinjaTurtle { name: string static isInstanceOf(value: unknown): boolean @@ -298,90 +170,397 @@ export class NinjaTurtle { getName(): string returnThis(this: this): this } -export type JsAssets = Assets -export class Assets { - constructor() - get(id: number): JsAsset | null -} -export type JsAsset = Asset -export class Asset { - constructor() - get filePath(): number + +export class NotWritableClass { + name: string + constructor(name: string) + setName(name: string): void } + export class Optional { static optionEnd(required: string, optional?: string | undefined | null): string static optionStart(optional: string | undefined | null, required: string): string static optionStartEnd(optional1: string | undefined | null, required: string, optional2?: string | undefined | null): string static optionOnly(optional?: string | undefined | null): string } -export class NotWritableClass { - name: string - constructor(name: string) - setName(name: string): void -} -export class CustomFinalize { - constructor(width: number, height: number) -} + export class Width { value: number constructor(value: number) } -export class GetterSetterWithClosures { - constructor() + +export interface A { + foo: number } -export class ClassWithFactory { + +export function acceptThreadsafeFunction(func: (err: Error | null, value: number) => any): void + +export function acceptThreadsafeFunctionFatal(func: (value: number) => any): void + +export function acceptThreadsafeFunctionTupleArgs(func: (err: Error | null, arg0: number, arg1: boolean, arg2: string) => any): void + +export function add(a: number, b: number): number + +export const enum ALIAS { + A = 0, + B = 1 +} + +export interface AliasedStruct { + a: ALIAS + b: number +} + +export interface AllOptionalObject { + name?: string + age?: number +} + +export function appendBuffer(buf: Buffer): Buffer + +export function arrayBufferPassThrough(buf: Uint8Array): Promise + +export function asyncMultiTwo(arg: number): Promise + +export function asyncPlus100(p: Promise): Promise + +export function asyncReduceBuffer(buf: Buffer): Promise + +export interface B { + bar: number +} + +export function bigintAdd(a: bigint, b: bigint): bigint + +export function bigintFromI128(): bigint + +export function bigintFromI64(): bigint + +export function bigintGetU64AsString(bi: bigint): string + +export function bufferPassThrough(buf: Buffer): Promise + +export interface C { + baz: number +} + +export function callbackReturnPromise(functionInput: () => T | Promise, callback: (err: Error | null, result: T) => void): T | Promise + +export function callLongThreadsafeFunction(callback: (...args: any[]) => any): void + +export function callThreadsafeFunction(callback: (...args: any[]) => any): void + +export function captureErrorInCallback(cb1: () => void, cb2: (arg0: Error) => void): void + +export function chronoDateAdd1Minute(input: Date): Date + +export function chronoDateToMillis(input: Date): number + +export function concatLatin1(s: string): string + +export function concatStr(s: string): string + +export function concatUtf16(s: string): string + +export function contains(source: string, target: string): boolean + +export function convertU32Array(input: Uint32Array): Array + +export function createBigInt(): bigint + +export function createBigIntI64(): bigint + +export function createExternal(size: number): ExternalObject + +export function createExternalString(content: string): ExternalObject + +export function createExternalTypedArray(): Uint32Array + +export function createObj(): object + +export function createObjectWithClassField(): ObjectFieldClassInstance + +export function createObjWithProperty(): { value: ArrayBuffer, get getter(): number } + +export function createSymbol(): symbol + +/** You could break the step and for an new continuous value. */ +export const enum CustomNumEnum { + One = 1, + Two = 2, + Three = 3, + Four = 4, + Six = 6, + Eight = 8, + Nine = 9, + Ten = 10 +} + +export function customStatusCode(): void + +export interface Dates { + start: Date + end?: Date +} + +export function dateToNumber(input: Date): number + +/** This is a const */ +export const DEFAULT_COST: number + +export function derefUint8Array(a: Uint8Array, b: Uint8ClampedArray): number + +export function either3(input: string | number | boolean): number + +export function either4(input: string | number | boolean | Obj): number + +export function eitherBoolOrFunction(input: boolean | ((...args: any[]) => any)): void + +export function eitherFromObjects(input: A | B | C): string + +export function eitherFromOption(): JsClassForEither | undefined + +export function eitherStringOrNumber(input: string | number): number + +export const enum Empty { + +} + +export function enumToI32(e: CustomNumEnum): number + +export function fibonacci(n: number): number + +export function fnReceivedAliased(s: AliasedStruct, e: ALIAS): void + +export function getBuffer(): Buffer + +export function getCwd(callback: (arg0: string) => void): void + +export function getEmptyBuffer(): Buffer + +export function getExternal(external: ExternalObject): number + +export function getGlobal(): typeof global + +export function getMapping(): Record + +export function getNestedNumArr(): number[][][] + +export function getNull(): null + +export function getNumArr(): number[] + +/** Gets some numbers */ +export function getNums(): Array + +export function getPackageJsonName(packageJson: PackageJson): string + +export function getStrFromObject(): void + +export function getterFromObj(): number + +export function getUndefined(): void + +export function getWords(): Array + +/** default enum values are continuos i32s start from 0 */ +export const enum Kind { + /** Barks */ + Dog = 0, + /** Kills birds */ + Cat = 1, + /** Tasty */ + Duck = 2 +} + +export function listObjKeys(obj: object): Array + +export function mapOption(val?: number | undefined | null): number | null + +export function mutateExternal(external: ExternalObject, newVal: number): void + +export function mutateTypedArray(input: Float32Array): void + +export interface Obj { + v: string | number +} + +export interface ObjectFieldClassInstance { + bird: Bird +} + +export interface ObjectOnlyFromJs { + count: number + callback: (err: Error | null, value: number) => any +} + +export function optionEnd(callback: (arg0: string, arg1?: string | undefined | null) => void): void + +export function optionOnly(callback: (arg0?: string | undefined | null) => void): void + +export function optionStart(callback: (arg0: string | undefined | null, arg1: string) => void): void + +export function optionStartEnd(callback: (arg0: string | undefined | null, arg1: string, arg2?: string | undefined | null) => void): void + +export function overrideIndividualArgOnFunction(notOverridden: string, f: () => string, notOverridden2: number): string + +export function overrideIndividualArgOnFunctionWithCbArg(callback: (town: string, name?: string | undefined | null) => string, notOverridden: number): object + +/** This is an interface for package.json */ +export interface PackageJson { name: string - static withName(name: string): ClassWithFactory - setName(name: string): this + /** The version of the package */ + version: string + dependencies?: Record + devDependencies?: Record } -export class JsClassForEither { - constructor() + +export function panic(): void + +export function plusOne(this: Width): number + +export function promiseInEither(input: number | Promise): Promise + +/** napi = { version = 2, features = ["serde-json"] } */ +export function readFile(callback: (arg0: Error | undefined, arg1?: string | undefined | null) => void): void + +export function readFileAsync(path: string): Promise + +export function readPackageJson(): PackageJson + +export function receiveAllOptionalObject(obj?: AllOptionalObject | undefined | null): void + +export function receiveClassOrNumber(either: number | JsClassForEither): number + +export function receiveDifferentClass(either: JsClassForEither | AnotherClassForEither): number + +export function receiveMutClassOrNumber(either: number | JsClassForEither): number + +export function receiveObjectOnlyFromJs(obj: { count: number, callback: (err: Error | null, count: number) => void }): void + +export function receiveObjectWithClassField(object: ObjectFieldClassInstance): Bird + +export function receiveStrictObject(strictObject: StrictObject): void + +export function receiveString(s: string): string + +export function returnEither(input: number): string | number + +export function returnEitherClass(input: number): number | JsClassForEither + +export function returnFromSharedCrate(): Shared + +export function returnJsFunction(): (...args: any[]) => any + +export function returnNull(): null + +export function returnUndefined(): void + +export function returnUndefinedIfInvalid(input: boolean): boolean + +export function returnUndefinedIfInvalidPromise(input: Promise): Promise + +export function roundtripStr(s: string): string + +export function runScript(script: string): unknown + +export function setSymbolInObj(symbol: symbol): object + +export interface Shared { + value: number } -export class AnotherClassForEither { - constructor() + +export const enum Status { + Pristine = 'Pristine', + Loading = 'Loading', + Ready = 'Ready' } -export class Fib { - [Symbol.iterator](): Iterator - constructor() + +export interface StrictObject { + name: string } -export class Fib2 { - [Symbol.iterator](): Iterator - static create(seed: number): Fib2 + +export function sumMapping(nums: Record): number + +export function sumNums(nums: Array): number + +export function testSerdeBigNumberPrecision(number: string): any + +export function testSerdeRoundtrip(data: any): any + +export function threadsafeFunctionClosureCapture(func: (...args: any[]) => any): void + +export function threadsafeFunctionFatalMode(cb: (...args: any[]) => any): void + +export function threadsafeFunctionFatalModeError(cb: (...args: any[]) => any): void + +export function threadsafeFunctionThrowError(cb: (...args: any[]) => any): void + +export function throwError(): void + +export function toJsObj(): object + +export function tsfnAsyncCall(func: (...args: any[]) => any): Promise + +export function tsfnCallWithCallback(func: (...args: any[]) => any): void + +export function tsfnReturnPromise(func: (err: Error | null, value: number) => any): Promise + +export function tsfnReturnPromiseTimeout(func: (err: Error | null, value: number) => any): Promise + +export function tsRename(a: { foo: number }): string[] + +export interface TsTypeChanged { + typeOverride: object + typeOverrideOptional?: object } -export class Fib3 { - current: number - next: number - constructor(current: number, next: number) - [Symbol.iterator](): Iterator -} -export class JsRepo { - constructor(dir: string) - remote(): JsRemote -} -export class JsRemote { - name(): string -} -export type CSSRuleList = CssRuleList -export class CssRuleList { - getRules(): Array - get parentStyleSheet(): CSSStyleSheet - get name(): string | null -} -export type CSSStyleSheet = CssStyleSheet -export class CssStyleSheet { - constructor(name: string, rules: Array) - get rules(): CssRuleList - anotherCssStyleSheet(): AnotherCssStyleSheet -} -export type AnotherCSSStyleSheet = AnotherCssStyleSheet -export class AnotherCssStyleSheet { - get rules(): CssRuleList + +export function validateArray(arr: Array): number + +export function validateBigint(input: bigint): bigint + +export function validateBoolean(i: boolean): boolean + +export function validateBuffer(b: Buffer): number + +export function validateDate(d: Date): number + +export function validateDateTime(d: Date): number + +export function validateExternal(e: ExternalObject): number + +export function validateFunction(cb: () => number): number + +export function validateHashMap(input: Record): number + +export function validateNull(i: null): boolean + +export function validateNumber(i: number): number + +export function validateOptional(input1?: string | undefined | null, input2?: boolean | undefined | null): boolean + +export function validatePromise(p: Promise): Promise + +export function validateString(s: string): string + +export function validateSymbol(s: symbol): boolean + +export function validateTypedArray(input: Uint8Array): number + +export function validateUndefined(i: undefined): boolean + +export function withAbortController(a: number, b: number, signal: AbortSignal): Promise + +export function withoutAbortController(a: number, b: number): Promise + +export function xxh64Alias(input: Buffer): bigint + +export namespace xxh2 { + export function xxh2Plus(a: number, b: number): number + export function xxh3Xxh64Alias(input: Buffer): bigint } + export namespace xxh3 { - export const ALIGNMENT: number - export function xxh3_64(input: Buffer): bigint - /** xxh128 function */ - export function xxh128(input: Buffer): bigint /** Xxh3 class */ export class Xxh3 { constructor() @@ -389,8 +568,9 @@ export namespace xxh3 { update(input: Buffer): void digest(): bigint } + export const ALIGNMENT: number + /** xxh128 function */ + export function xxh128(input: Buffer): bigint + export function xxh3_64(input: Buffer): bigint } -export namespace xxh2 { - export function xxh2Plus(a: number, b: number): number - export function xxh3Xxh64Alias(input: Buffer): bigint -} + diff --git a/examples/napi/package.json b/examples/napi/package.json index 9dba677c..7d15eddc 100644 --- a/examples/napi/package.json +++ b/examples/napi/package.json @@ -1,20 +1,34 @@ { - "name": "examples", + "name": "@examples/napi", "private": true, "version": "0.0.0", "main": "./index.node", "types": "./index.d.ts", "scripts": { - "build": "node ../../cli/scripts/index.js build --js false", - "build-aarch64": "node ../../cli/scripts/index.js build --js false --target aarch64-unknown-linux-gnu", - "build-armv7": "node ../../cli/scripts/index.js build --js false --target armv7-unknown-linux-gnueabihf", - "build-i686": "node ../../cli/scripts/index.js build --js false --target i686-pc-windows-msvc", - "build-i686-release": "node ../../cli/scripts/index.js build --js false --release --target i686-pc-windows-msvc", - "build-release": "node ../../cli/scripts/index.js build --js false --release" + "build": "napi-raw build --no-js", + "test": "ava" }, - "dependencies": { + "devDependencies": { + "@napi-rs/cli": "workspace:*", "@types/lodash": "^4.14.191", + "ava": "^5.2.0", "lodash": "^4.17.21", "sinon": "^15.0.1" + }, + "ava": { + "extensions": [ + "ts", + "tsx" + ], + "require": [ + "ts-node/register/transpile-only" + ], + "files": [ + "__tests__/**/*.spec.ts" + ], + "environmentVariables": { + "TS_NODE_PROJECT": "../tsconfig.json" + }, + "timeout": "5m" } } diff --git a/examples/napi/src/class.rs b/examples/napi/src/class.rs index 230fcdcb..8045dd12 100644 --- a/examples/napi/src/class.rs +++ b/examples/napi/src/class.rs @@ -77,7 +77,8 @@ impl Animal { #[napi] /// Here are some characters and character sequences /// that should be escaped correctly: - /// \[]{}/\:"" + /// \[]{}/\:""{ + /// } pub fn return_other_class(&self) -> Dog { Dog { name: "Doge".to_owned(), diff --git a/examples/napi/tsconfig.json b/examples/napi/tsconfig.json index 6e513db0..67e53d4a 100644 --- a/examples/napi/tsconfig.json +++ b/examples/napi/tsconfig.json @@ -3,7 +3,7 @@ "include": ["."], "compilerOptions": { "outDir": "./dist", - "rootDir": "__test__", + "rootDir": "__tests__", "target": "ES2018", "skipLibCheck": false }, diff --git a/generate-triple-list.ts b/generate-triple-list.ts deleted file mode 100644 index 4121c592..00000000 --- a/generate-triple-list.ts +++ /dev/null @@ -1,48 +0,0 @@ -import { readFileSync, writeFileSync } from 'fs' -import { join } from 'path' - -import * as esbuild from 'esbuild' -import { groupBy, mapValues } from 'lodash' - -import { parseTriple } from './cli/src/parse-triple' - -const RAW_LIST = readFileSync(join(__dirname, 'triples', 'target-list'), 'utf8') - -const SUPPORTED_PLATFORM = new Set([ - 'darwin', - 'ios', - 'android', - 'win32', - 'linux', - 'freebsd', -]) - -const tripleLists: { [key: string]: { platform?: string } } = RAW_LIST.trim() - .split('\n') - .filter((line) => !line.startsWith('wasm') && line.trim().length) - .map(parseTriple) - .reduce((acc, cur) => { - acc[cur.raw] = cur - return acc - }, {}) - -const platformArchTriples = mapValues( - groupBy( - Object.values(tripleLists).filter((k) => - SUPPORTED_PLATFORM.has(k.platform!), - ), - 'platform', - ), - (v) => groupBy(v, 'arch'), -) - -const fileContent = ` -module.exports.platformArchTriples = ${JSON.stringify(platformArchTriples)} -` - -writeFileSync( - join(__dirname, 'triples', 'index.js'), - esbuild.transformSync(fileContent, { - minify: true, - }).code, -) diff --git a/memory-testing/package.json b/memory-testing/package.json index c288463f..30840d32 100644 --- a/memory-testing/package.json +++ b/memory-testing/package.json @@ -3,7 +3,7 @@ "version": "1.0.0", "private": true, "scripts": { - "build": "node ../cli/scripts/index.js build --release --js false" + "build": "napi-raw build --release --no-js" }, "dependencies": { "colorette": "^2.0.19", @@ -12,6 +12,7 @@ "table": "^6.8.1" }, "devDependencies": { + "@napi-rs/cli": "workspace:*", "@types/dockerode": "^3.3.14" } } diff --git a/memory-testing/test-util.mjs b/memory-testing/test-util.mjs index 1e442c4e..dbda13c6 100644 --- a/memory-testing/test-util.mjs +++ b/memory-testing/test-util.mjs @@ -1,7 +1,7 @@ import { setTimeout } from 'timers' import { promisify } from 'util' -import * as chalk from 'colorette' +import * as colors from 'colorette' import Dockerode from 'dockerode' import prettyBytes from 'pretty-bytes' @@ -10,7 +10,7 @@ const sleep = promisify(setTimeout) const client = new Dockerode() export async function createSuite(testFile, maxMemoryUsage) { - console.info(chalk.cyanBright(`Create container to test ${testFile}`)) + console.info(colors.cyanBright(`Create container to test ${testFile}`)) const container = await client.createContainer({ Image: 'node:lts-slim', @@ -26,7 +26,7 @@ export async function createSuite(testFile, maxMemoryUsage) { }, }) - console.info(chalk.cyanBright('Container created, starting ...')) + console.info(colors.cyanBright('Container created, starting ...')) await container.start() @@ -58,7 +58,7 @@ export async function createSuite(testFile, maxMemoryUsage) { const memoryGrowth = memory_stats.usage - initialMemoryUsage if (memoryGrowth > (maxMemoryUsage ?? initialMemoryUsage)) { console.info( - chalk.redBright( + colors.redBright( `Potential memory leak, memory growth: ${prettyBytes( memoryGrowth, )}`, @@ -72,7 +72,7 @@ export async function createSuite(testFile, maxMemoryUsage) { }) console.info( - chalk.red(`Initial memory usage: ${prettyBytes(initialMemoryUsage)}`), + colors.red(`Initial memory usage: ${prettyBytes(initialMemoryUsage ?? 0)}`), ) await sleep(60000) diff --git a/package.json b/package.json index bf9f5a30..b2c0439a 100644 --- a/package.json +++ b/package.json @@ -9,7 +9,8 @@ "memory-testing", "examples/napi", "examples/napi-compat-mode", - "examples/binary" + "examples/binary", + "crates/cli" ], "repository": { "type": "git", @@ -18,27 +19,22 @@ "license": "MIT", "scripts": { "bench": "cross-env TS_NODE_PROJECT='./bench/tsconfig.json' node -r ts-node/register/transpile-only bench/bench.ts", - "build": "tsc -p tsconfig.json -m esnext && yarn bundle && shx chmod 777 cli/scripts/index.js && node -r ts-node/register/transpile-only ./generate-triple-list.ts", + "build": "lerna run build --scope '@napi-rs/*'", "build:bench": "yarn workspace bench build", "build:memory": "yarn workspace memory-testing build", - "build:test": "yarn workspace compat-mode-examples build && yarn workspace examples build", - "build:test:asan": "yarn workspace compat-mode-examples build --cargo-flags='-Zbuild-std' && yarn workspace examples build --cargo-flags='-Zbuild-std'", - "build:test:aarch64": "yarn workspace compat-mode-examples build-aarch64 && yarn workspace examples build-aarch64", - "build:test:android": "yarn workspace compat-mode-examples build --target aarch64-linux-android && yarn workspace examples build --target aarch64-linux-android", - "build:test:android:armv7": "yarn workspace compat-mode-examples build --target armv7-linux-androideabi && yarn workspace examples build --target armv7-linux-androideabi", - "build:test:armv7": "yarn workspace compat-mode-examples build-armv7 && yarn workspace examples build-armv7", - "bundle": "rollup -c rollup.config.mjs", + "build:test": "lerna run build --scope '@examples/*'", "format": "run-p format:prettier format:rs format:toml", "format:prettier": "prettier . -w", "format:rs": "cargo fmt", "format:toml": "taplo format", "lint": "eslint -c .eslintrc.yml .", - "prepublishOnly": "npm run build && pinst --disable", - "test": "ava \"./examples/napi/**/*.ts\" && ava --no-worker-threads \"./examples/napi-compat-mode/**/*.ts\" && ava \"./cli/**/*.ts\"", + "test": "lerna run test --ignore @napi-rs/cli", + "test:cli": "yarn workspace @napi-rs/cli test", "test:electron": "electron examples/napi/electron.js", "test:macro": "cargo test -p napi-examples", "test:memory": "node memory-testing/index.mjs", "postinstall": "husky install", + "prepublishOnly": "yarn build && pinst --disable", "postpublish": "pinst --enable" }, "bugs": { @@ -72,6 +68,7 @@ } }, "devDependencies": { + "@napi-rs/cli": "workspace:*", "@rollup/plugin-alias": "^4.0.2", "@rollup/plugin-commonjs": "^24.0.0", "@rollup/plugin-json": "^6.0.0", @@ -85,9 +82,7 @@ "@typescript-eslint/eslint-plugin": "^5.48.2", "@typescript-eslint/parser": "^5.48.2", "ava": "^5.1.1", - "benny": "^3.7.1", "c8": "^7.12.0", - "colorette": "^2.0.19", "cross-env": "^7.0.3", "electron": "22.0.3", "esbuild": "^0.17.2", @@ -95,12 +90,11 @@ "eslint-config-prettier": "^8.6.0", "eslint-plugin-import": "^2.27.5", "eslint-plugin-prettier": "^4.2.1", - "husky": "^8.0.3", - "lerna": "^6.4.1", - "lint-staged": "^13.1.0", + "husky": "^8.0.1", + "lerna": "^5.1.6", + "lint-staged": "^13.0.3", "npm-run-all": "^4.1.5", "prettier": "^2.8.3", - "rollup": "^3.10.0", "shx": "^0.3.4", "sinon": "^15.0.1", "source-map-support": "^0.5.21", diff --git a/rollup.config.mjs b/rollup.config.mjs deleted file mode 100644 index 01e45e05..00000000 --- a/rollup.config.mjs +++ /dev/null @@ -1,74 +0,0 @@ -import { readFileSync } from 'fs' -import { join } from 'path' -import { fileURLToPath } from 'url' - -import alias from '@rollup/plugin-alias' -import commonjs from '@rollup/plugin-commonjs' -import json from '@rollup/plugin-json' -import nodeResolve from '@rollup/plugin-node-resolve' -import replace from '@rollup/plugin-replace' -import toml from 'toml' - -const __dirname = join(fileURLToPath(import.meta.url), '..') - -const NAPI_CARGO_TOML = readFileSync( - join(__dirname, 'crates', 'napi', 'Cargo.toml'), - 'utf8', -) -const NAPI_DERIVE_CARGO_TOML = readFileSync( - join(__dirname, 'crates', 'macro', 'Cargo.toml'), - 'utf8', -) -const NAPI_BUILD_CARGO_TOML = readFileSync( - join(__dirname, 'crates', 'build', 'Cargo.toml'), - 'utf8', -) - -const { - package: { version: NAPI_VERSION }, -} = toml.parse(NAPI_CARGO_TOML) -const { - package: { version: NAPI_DERIVE_VERSION }, -} = toml.parse(NAPI_DERIVE_CARGO_TOML) -const { - package: { version: NAPI_BUILD_VERSION }, -} = toml.parse(NAPI_BUILD_CARGO_TOML) - -console.info('napi version: ', NAPI_VERSION) -console.info('napi-derive version: ', NAPI_DERIVE_VERSION) -console.info('napi-build version: ', NAPI_BUILD_VERSION) - -export default { - input: './scripts/cli/src/index.js', - output: { - banner: '#!/usr/bin/env node', - file: './cli/scripts/index.js', - format: 'cjs', - sourcemap: 'inline', - inlineDynamicImports: true, - }, - plugins: [ - replace({ - NAPI_VERSION, - NAPI_DERIVE_VERSION, - NAPI_BUILD_VERSION, - // Do not external `node:xx` because we need to replace it with `xx` to compatible with `node@12` - 'node:path': 'path', - 'node:os': 'os', - 'node:process': 'process', - 'node:tty': 'tty', - 'node:assert': 'assert', - 'node:readline': 'readline', - preventAssignment: true, - }), - alias({ - entries: [{ find: 'readable-stream', replacement: 'stream' }], - }), - nodeResolve({ - preferBuiltins: true, - exportConditions: ['node', 'default', 'module', 'export'], - }), - commonjs(), - json(), - ], -} diff --git a/triples/generate-triple-list.ts b/triples/generate-triple-list.ts new file mode 100644 index 00000000..6a3f313d --- /dev/null +++ b/triples/generate-triple-list.ts @@ -0,0 +1,58 @@ +import { readFileSync, writeFileSync } from 'fs' +import { join, resolve } from 'path' +import { fileURLToPath } from 'url' + +import { groupBy, mapValues } from 'lodash-es' + +import { parseTriple } from '../cli/src/utils/target.js' + +const __dirname = resolve(fileURLToPath(import.meta.url), '..') + +const RAW_LIST = readFileSync(join(__dirname, 'target-list'), 'utf8') + +const SUPPORTED_PLATFORM = new Set([ + 'darwin', + 'ios', + 'android', + 'win32', + 'linux', + 'freebsd', +]) + +const tripleLists: { [key: string]: { platform?: string } } = RAW_LIST.trim() + .split('\n') + .filter((line) => !line.startsWith('wasm') && line.trim().length) + .map(parseTriple) + .reduce((acc, cur) => { + acc[cur.triple] = cur + return acc + }, {}) + +const platformArchTriples = mapValues( + groupBy( + Object.values(tripleLists).filter((k) => + SUPPORTED_PLATFORM.has(k.platform!), + ), + 'platform', + ), + (v) => groupBy(v, 'arch'), +) + +const mjsContent = ` +export const platformArchTriples = ${JSON.stringify( + platformArchTriples, + null, + 2, +)} +` +const cjsContent = ` +module.exports.platformArchTriples = ${JSON.stringify( + platformArchTriples, + null, + 2, +)} +` + +writeFileSync(join(__dirname, 'index.js'), mjsContent) + +writeFileSync(join(__dirname, 'index.cjs'), cjsContent) diff --git a/triples/index.cjs b/triples/index.cjs new file mode 100644 index 00000000..4f5f6657 --- /dev/null +++ b/triples/index.cjs @@ -0,0 +1,393 @@ + +module.exports.platformArchTriples = { + "darwin": { + "arm64": [ + { + "triple": "aarch64-apple-darwin", + "platformArchABI": "darwin-arm64", + "platform": "darwin", + "arch": "arm64", + "abi": null + } + ], + "x64": [ + { + "triple": "x86_64-apple-darwin", + "platformArchABI": "darwin-x64", + "platform": "darwin", + "arch": "x64", + "abi": null + } + ] + }, + "ios": { + "arm64": [ + { + "triple": "aarch64-apple-ios", + "platformArchABI": "ios-arm64", + "platform": "ios", + "arch": "arm64", + "abi": null + } + ], + "x64": [ + { + "triple": "x86_64-apple-ios", + "platformArchABI": "ios-x64", + "platform": "ios", + "arch": "x64", + "abi": null + } + ] + }, + "android": { + "arm64": [ + { + "triple": "aarch64-linux-android", + "platformArchABI": "android-arm64", + "platform": "android", + "arch": "arm64", + "abi": null + } + ], + "arm": [ + { + "triple": "armv7-linux-android-eabi", + "platformArchABI": "android-arm-eabi", + "platform": "android", + "arch": "arm", + "abi": "eabi" + } + ], + "ia32": [ + { + "triple": "i686-linux-android", + "platformArchABI": "android-ia32", + "platform": "android", + "arch": "ia32", + "abi": null + } + ], + "x64": [ + { + "triple": "x86_64-linux-android", + "platformArchABI": "android-x64", + "platform": "android", + "arch": "x64", + "abi": null + } + ] + }, + "win32": { + "arm64": [ + { + "triple": "aarch64-pc-windows-msvc", + "platformArchABI": "win32-arm64-msvc", + "platform": "win32", + "arch": "arm64", + "abi": "msvc" + } + ], + "ia32": [ + { + "triple": "i686-pc-windows-gnu", + "platformArchABI": "win32-ia32-gnu", + "platform": "win32", + "arch": "ia32", + "abi": "gnu" + }, + { + "triple": "i686-pc-windows-msvc", + "platformArchABI": "win32-ia32-msvc", + "platform": "win32", + "arch": "ia32", + "abi": "msvc" + } + ], + "x64": [ + { + "triple": "x86_64-pc-windows-gnu", + "platformArchABI": "win32-x64-gnu", + "platform": "win32", + "arch": "x64", + "abi": "gnu" + }, + { + "triple": "x86_64-pc-windows-msvc", + "platformArchABI": "win32-x64-msvc", + "platform": "win32", + "arch": "x64", + "abi": "msvc" + } + ] + }, + "linux": { + "arm64": [ + { + "triple": "aarch64-unknown-linux-gnu", + "platformArchABI": "linux-arm64-gnu", + "platform": "linux", + "arch": "arm64", + "abi": "gnu" + }, + { + "triple": "aarch64-unknown-linux-musl", + "platformArchABI": "linux-arm64-musl", + "platform": "linux", + "arch": "arm64", + "abi": "musl" + } + ], + "arm": [ + { + "triple": "arm-unknown-linux-gnu-eabi", + "platformArchABI": "linux-arm-gnu", + "platform": "linux", + "arch": "arm", + "abi": "gnu" + }, + { + "triple": "arm-unknown-linux-gnueabihf", + "platformArchABI": "linux-arm-gnueabihf", + "platform": "linux", + "arch": "arm", + "abi": "gnueabihf" + }, + { + "triple": "arm-unknown-linux-musl-eabi", + "platformArchABI": "linux-arm-musl", + "platform": "linux", + "arch": "arm", + "abi": "musl" + }, + { + "triple": "arm-unknown-linux-musleabihf", + "platformArchABI": "linux-arm-musleabihf", + "platform": "linux", + "arch": "arm", + "abi": "musleabihf" + }, + { + "triple": "armv7-unknown-linux-gnu-eabi", + "platformArchABI": "linux-arm-gnu", + "platform": "linux", + "arch": "arm", + "abi": "gnu" + }, + { + "triple": "armv7-unknown-linux-gnueabihf", + "platformArchABI": "linux-arm-gnueabihf", + "platform": "linux", + "arch": "arm", + "abi": "gnueabihf" + }, + { + "triple": "armv7-unknown-linux-musl-eabi", + "platformArchABI": "linux-arm-musl", + "platform": "linux", + "arch": "arm", + "abi": "musl" + }, + { + "triple": "armv7-unknown-linux-musleabihf", + "platformArchABI": "linux-arm-musleabihf", + "platform": "linux", + "arch": "arm", + "abi": "musleabihf" + } + ], + "armv5te": [ + { + "triple": "armv5te-unknown-linux-gnu-eabi", + "platformArchABI": "linux-armv5te-gnu", + "platform": "linux", + "arch": "armv5te", + "abi": "gnu" + }, + { + "triple": "armv5te-unknown-linux-musl-eabi", + "platformArchABI": "linux-armv5te-musl", + "platform": "linux", + "arch": "armv5te", + "abi": "musl" + } + ], + "ia32": [ + { + "triple": "i686-unknown-linux-gnu", + "platformArchABI": "linux-ia32-gnu", + "platform": "linux", + "arch": "ia32", + "abi": "gnu" + }, + { + "triple": "i686-unknown-linux-musl", + "platformArchABI": "linux-ia32-musl", + "platform": "linux", + "arch": "ia32", + "abi": "musl" + } + ], + "mips": [ + { + "triple": "mips-unknown-linux-gnu", + "platformArchABI": "linux-mips-gnu", + "platform": "linux", + "arch": "mips", + "abi": "gnu" + }, + { + "triple": "mips-unknown-linux-musl", + "platformArchABI": "linux-mips-musl", + "platform": "linux", + "arch": "mips", + "abi": "musl" + } + ], + "mips64": [ + { + "triple": "mips64-unknown-linux-gnuabi64", + "platformArchABI": "linux-mips64-gnuabi64", + "platform": "linux", + "arch": "mips64", + "abi": "gnuabi64" + }, + { + "triple": "mips64-unknown-linux-muslabi64", + "platformArchABI": "linux-mips64-muslabi64", + "platform": "linux", + "arch": "mips64", + "abi": "muslabi64" + } + ], + "mips64el": [ + { + "triple": "mips64el-unknown-linux-gnuabi64", + "platformArchABI": "linux-mips64el-gnuabi64", + "platform": "linux", + "arch": "mips64el", + "abi": "gnuabi64" + }, + { + "triple": "mips64el-unknown-linux-muslabi64", + "platformArchABI": "linux-mips64el-muslabi64", + "platform": "linux", + "arch": "mips64el", + "abi": "muslabi64" + } + ], + "mipsel": [ + { + "triple": "mipsel-unknown-linux-gnu", + "platformArchABI": "linux-mipsel-gnu", + "platform": "linux", + "arch": "mipsel", + "abi": "gnu" + }, + { + "triple": "mipsel-unknown-linux-musl", + "platformArchABI": "linux-mipsel-musl", + "platform": "linux", + "arch": "mipsel", + "abi": "musl" + } + ], + "powerpc": [ + { + "triple": "powerpc-unknown-linux-gnu", + "platformArchABI": "linux-powerpc-gnu", + "platform": "linux", + "arch": "powerpc", + "abi": "gnu" + } + ], + "powerpc64": [ + { + "triple": "powerpc64-unknown-linux-gnu", + "platformArchABI": "linux-powerpc64-gnu", + "platform": "linux", + "arch": "powerpc64", + "abi": "gnu" + } + ], + "powerpc64le": [ + { + "triple": "powerpc64le-unknown-linux-gnu", + "platformArchABI": "linux-powerpc64le-gnu", + "platform": "linux", + "arch": "powerpc64le", + "abi": "gnu" + } + ], + "riscv64gc": [ + { + "triple": "riscv64gc-unknown-linux-gnu", + "platformArchABI": "linux-riscv64gc-gnu", + "platform": "linux", + "arch": "riscv64gc", + "abi": "gnu" + } + ], + "s390x": [ + { + "triple": "s390x-unknown-linux-gnu", + "platformArchABI": "linux-s390x-gnu", + "platform": "linux", + "arch": "s390x", + "abi": "gnu" + } + ], + "sparc64": [ + { + "triple": "sparc64-unknown-linux-gnu", + "platformArchABI": "linux-sparc64-gnu", + "platform": "linux", + "arch": "sparc64", + "abi": "gnu" + } + ], + "x64": [ + { + "triple": "x86_64-unknown-linux-gnu", + "platformArchABI": "linux-x64-gnu", + "platform": "linux", + "arch": "x64", + "abi": "gnu" + }, + { + "triple": "x86_64-unknown-linux-gnux32", + "platformArchABI": "linux-x64-gnux32", + "platform": "linux", + "arch": "x64", + "abi": "gnux32" + }, + { + "triple": "x86_64-unknown-linux-musl", + "platformArchABI": "linux-x64-musl", + "platform": "linux", + "arch": "x64", + "abi": "musl" + } + ] + }, + "freebsd": { + "ia32": [ + { + "triple": "i686-unknown-freebsd", + "platformArchABI": "freebsd-ia32", + "platform": "freebsd", + "arch": "ia32", + "abi": null + } + ], + "x64": [ + { + "triple": "x86_64-unknown-freebsd", + "platformArchABI": "freebsd-x64", + "platform": "freebsd", + "arch": "x64", + "abi": null + } + ] + } +} diff --git a/triples/index.js b/triples/index.js index 51079877..3b846599 100644 --- a/triples/index.js +++ b/triples/index.js @@ -1 +1,393 @@ -module.exports.platformArchTriples={darwin:{arm64:[{platform:"darwin",arch:"arm64",abi:null,platformArchABI:"darwin-arm64",raw:"aarch64-apple-darwin"}],x64:[{platform:"darwin",arch:"x64",abi:null,platformArchABI:"darwin-x64",raw:"x86_64-apple-darwin"}]},ios:{arm64:[{platform:"ios",arch:"arm64",abi:null,platformArchABI:"ios-arm64",raw:"aarch64-apple-ios"}],x64:[{platform:"ios",arch:"x64",abi:null,platformArchABI:"ios-x64",raw:"x86_64-apple-ios"}]},android:{arm64:[{platform:"android",arch:"arm64",abi:null,platformArchABI:"android-arm64",raw:"aarch64-linux-android"}],arm:[{platform:"android",arch:"arm",abi:"eabi",platformArchABI:"android-arm-eabi",raw:"armv7-linux-androideabi"}],ia32:[{platform:"android",arch:"ia32",abi:null,platformArchABI:"android-ia32",raw:"i686-linux-android"}],x64:[{platform:"android",arch:"x64",abi:null,platformArchABI:"android-x64",raw:"x86_64-linux-android"}]},win32:{arm64:[{platform:"win32",arch:"arm64",abi:"msvc",platformArchABI:"win32-arm64-msvc",raw:"aarch64-pc-windows-msvc"}],ia32:[{platform:"win32",arch:"ia32",abi:"gnu",platformArchABI:"win32-ia32-gnu",raw:"i686-pc-windows-gnu"},{platform:"win32",arch:"ia32",abi:"msvc",platformArchABI:"win32-ia32-msvc",raw:"i686-pc-windows-msvc"}],x64:[{platform:"win32",arch:"x64",abi:"gnu",platformArchABI:"win32-x64-gnu",raw:"x86_64-pc-windows-gnu"},{platform:"win32",arch:"x64",abi:"msvc",platformArchABI:"win32-x64-msvc",raw:"x86_64-pc-windows-msvc"}]},linux:{arm64:[{platform:"linux",arch:"arm64",abi:"gnu",platformArchABI:"linux-arm64-gnu",raw:"aarch64-unknown-linux-gnu"},{platform:"linux",arch:"arm64",abi:"musl",platformArchABI:"linux-arm64-musl",raw:"aarch64-unknown-linux-musl"}],arm:[{platform:"linux",arch:"arm",abi:"gnueabihf",platformArchABI:"linux-arm-gnueabihf",raw:"arm-unknown-linux-gnueabihf"},{platform:"linux",arch:"arm",abi:"musleabihf",platformArchABI:"linux-arm-musleabihf",raw:"arm-unknown-linux-musleabihf"},{platform:"linux",arch:"arm",abi:"gnueabihf",platformArchABI:"linux-arm-gnueabihf",raw:"armv7-unknown-linux-gnueabihf"},{platform:"linux",arch:"arm",abi:"musleabihf",platformArchABI:"linux-arm-musleabihf",raw:"armv7-unknown-linux-musleabihf"}],ia32:[{platform:"linux",arch:"ia32",abi:"gnu",platformArchABI:"linux-ia32-gnu",raw:"i686-unknown-linux-gnu"},{platform:"linux",arch:"ia32",abi:"musl",platformArchABI:"linux-ia32-musl",raw:"i686-unknown-linux-musl"}],mips:[{platform:"linux",arch:"mips",abi:"gnu",platformArchABI:"linux-mips-gnu",raw:"mips-unknown-linux-gnu"},{platform:"linux",arch:"mips",abi:"musl",platformArchABI:"linux-mips-musl",raw:"mips-unknown-linux-musl"}],mips64:[{platform:"linux",arch:"mips64",abi:"gnuabi64",platformArchABI:"linux-mips64-gnuabi64",raw:"mips64-unknown-linux-gnuabi64"},{platform:"linux",arch:"mips64",abi:"muslabi64",platformArchABI:"linux-mips64-muslabi64",raw:"mips64-unknown-linux-muslabi64"}],mips64el:[{platform:"linux",arch:"mips64el",abi:"gnuabi64",platformArchABI:"linux-mips64el-gnuabi64",raw:"mips64el-unknown-linux-gnuabi64"},{platform:"linux",arch:"mips64el",abi:"muslabi64",platformArchABI:"linux-mips64el-muslabi64",raw:"mips64el-unknown-linux-muslabi64"}],mipsel:[{platform:"linux",arch:"mipsel",abi:"gnu",platformArchABI:"linux-mipsel-gnu",raw:"mipsel-unknown-linux-gnu"},{platform:"linux",arch:"mipsel",abi:"musl",platformArchABI:"linux-mipsel-musl",raw:"mipsel-unknown-linux-musl"}],powerpc:[{platform:"linux",arch:"powerpc",abi:"gnu",platformArchABI:"linux-powerpc-gnu",raw:"powerpc-unknown-linux-gnu"}],powerpc64:[{platform:"linux",arch:"powerpc64",abi:"gnu",platformArchABI:"linux-powerpc64-gnu",raw:"powerpc64-unknown-linux-gnu"}],powerpc64le:[{platform:"linux",arch:"powerpc64le",abi:"gnu",platformArchABI:"linux-powerpc64le-gnu",raw:"powerpc64le-unknown-linux-gnu"}],riscv64gc:[{platform:"linux",arch:"riscv64gc",abi:"gnu",platformArchABI:"linux-riscv64gc-gnu",raw:"riscv64gc-unknown-linux-gnu"}],s390x:[{platform:"linux",arch:"s390x",abi:"gnu",platformArchABI:"linux-s390x-gnu",raw:"s390x-unknown-linux-gnu"}],sparc64:[{platform:"linux",arch:"sparc64",abi:"gnu",platformArchABI:"linux-sparc64-gnu",raw:"sparc64-unknown-linux-gnu"}],x64:[{platform:"linux",arch:"x64",abi:"gnu",platformArchABI:"linux-x64-gnu",raw:"x86_64-unknown-linux-gnu"},{platform:"linux",arch:"x64",abi:"gnux32",platformArchABI:"linux-x64-gnux32",raw:"x86_64-unknown-linux-gnux32"},{platform:"linux",arch:"x64",abi:"musl",platformArchABI:"linux-x64-musl",raw:"x86_64-unknown-linux-musl"}]},freebsd:{ia32:[{platform:"freebsd",arch:"ia32",abi:null,platformArchABI:"freebsd-ia32",raw:"i686-unknown-freebsd"}],x64:[{platform:"freebsd",arch:"x64",abi:null,platformArchABI:"freebsd-x64",raw:"x86_64-unknown-freebsd"}]}}; + +export const platformArchTriples = { + "darwin": { + "arm64": [ + { + "triple": "aarch64-apple-darwin", + "platformArchABI": "darwin-arm64", + "platform": "darwin", + "arch": "arm64", + "abi": null + } + ], + "x64": [ + { + "triple": "x86_64-apple-darwin", + "platformArchABI": "darwin-x64", + "platform": "darwin", + "arch": "x64", + "abi": null + } + ] + }, + "ios": { + "arm64": [ + { + "triple": "aarch64-apple-ios", + "platformArchABI": "ios-arm64", + "platform": "ios", + "arch": "arm64", + "abi": null + } + ], + "x64": [ + { + "triple": "x86_64-apple-ios", + "platformArchABI": "ios-x64", + "platform": "ios", + "arch": "x64", + "abi": null + } + ] + }, + "android": { + "arm64": [ + { + "triple": "aarch64-linux-android", + "platformArchABI": "android-arm64", + "platform": "android", + "arch": "arm64", + "abi": null + } + ], + "arm": [ + { + "triple": "armv7-linux-android-eabi", + "platformArchABI": "android-arm-eabi", + "platform": "android", + "arch": "arm", + "abi": "eabi" + } + ], + "ia32": [ + { + "triple": "i686-linux-android", + "platformArchABI": "android-ia32", + "platform": "android", + "arch": "ia32", + "abi": null + } + ], + "x64": [ + { + "triple": "x86_64-linux-android", + "platformArchABI": "android-x64", + "platform": "android", + "arch": "x64", + "abi": null + } + ] + }, + "win32": { + "arm64": [ + { + "triple": "aarch64-pc-windows-msvc", + "platformArchABI": "win32-arm64-msvc", + "platform": "win32", + "arch": "arm64", + "abi": "msvc" + } + ], + "ia32": [ + { + "triple": "i686-pc-windows-gnu", + "platformArchABI": "win32-ia32-gnu", + "platform": "win32", + "arch": "ia32", + "abi": "gnu" + }, + { + "triple": "i686-pc-windows-msvc", + "platformArchABI": "win32-ia32-msvc", + "platform": "win32", + "arch": "ia32", + "abi": "msvc" + } + ], + "x64": [ + { + "triple": "x86_64-pc-windows-gnu", + "platformArchABI": "win32-x64-gnu", + "platform": "win32", + "arch": "x64", + "abi": "gnu" + }, + { + "triple": "x86_64-pc-windows-msvc", + "platformArchABI": "win32-x64-msvc", + "platform": "win32", + "arch": "x64", + "abi": "msvc" + } + ] + }, + "linux": { + "arm64": [ + { + "triple": "aarch64-unknown-linux-gnu", + "platformArchABI": "linux-arm64-gnu", + "platform": "linux", + "arch": "arm64", + "abi": "gnu" + }, + { + "triple": "aarch64-unknown-linux-musl", + "platformArchABI": "linux-arm64-musl", + "platform": "linux", + "arch": "arm64", + "abi": "musl" + } + ], + "arm": [ + { + "triple": "arm-unknown-linux-gnu-eabi", + "platformArchABI": "linux-arm-gnu", + "platform": "linux", + "arch": "arm", + "abi": "gnu" + }, + { + "triple": "arm-unknown-linux-gnueabihf", + "platformArchABI": "linux-arm-gnueabihf", + "platform": "linux", + "arch": "arm", + "abi": "gnueabihf" + }, + { + "triple": "arm-unknown-linux-musl-eabi", + "platformArchABI": "linux-arm-musl", + "platform": "linux", + "arch": "arm", + "abi": "musl" + }, + { + "triple": "arm-unknown-linux-musleabihf", + "platformArchABI": "linux-arm-musleabihf", + "platform": "linux", + "arch": "arm", + "abi": "musleabihf" + }, + { + "triple": "armv7-unknown-linux-gnu-eabi", + "platformArchABI": "linux-arm-gnu", + "platform": "linux", + "arch": "arm", + "abi": "gnu" + }, + { + "triple": "armv7-unknown-linux-gnueabihf", + "platformArchABI": "linux-arm-gnueabihf", + "platform": "linux", + "arch": "arm", + "abi": "gnueabihf" + }, + { + "triple": "armv7-unknown-linux-musl-eabi", + "platformArchABI": "linux-arm-musl", + "platform": "linux", + "arch": "arm", + "abi": "musl" + }, + { + "triple": "armv7-unknown-linux-musleabihf", + "platformArchABI": "linux-arm-musleabihf", + "platform": "linux", + "arch": "arm", + "abi": "musleabihf" + } + ], + "armv5te": [ + { + "triple": "armv5te-unknown-linux-gnu-eabi", + "platformArchABI": "linux-armv5te-gnu", + "platform": "linux", + "arch": "armv5te", + "abi": "gnu" + }, + { + "triple": "armv5te-unknown-linux-musl-eabi", + "platformArchABI": "linux-armv5te-musl", + "platform": "linux", + "arch": "armv5te", + "abi": "musl" + } + ], + "ia32": [ + { + "triple": "i686-unknown-linux-gnu", + "platformArchABI": "linux-ia32-gnu", + "platform": "linux", + "arch": "ia32", + "abi": "gnu" + }, + { + "triple": "i686-unknown-linux-musl", + "platformArchABI": "linux-ia32-musl", + "platform": "linux", + "arch": "ia32", + "abi": "musl" + } + ], + "mips": [ + { + "triple": "mips-unknown-linux-gnu", + "platformArchABI": "linux-mips-gnu", + "platform": "linux", + "arch": "mips", + "abi": "gnu" + }, + { + "triple": "mips-unknown-linux-musl", + "platformArchABI": "linux-mips-musl", + "platform": "linux", + "arch": "mips", + "abi": "musl" + } + ], + "mips64": [ + { + "triple": "mips64-unknown-linux-gnuabi64", + "platformArchABI": "linux-mips64-gnuabi64", + "platform": "linux", + "arch": "mips64", + "abi": "gnuabi64" + }, + { + "triple": "mips64-unknown-linux-muslabi64", + "platformArchABI": "linux-mips64-muslabi64", + "platform": "linux", + "arch": "mips64", + "abi": "muslabi64" + } + ], + "mips64el": [ + { + "triple": "mips64el-unknown-linux-gnuabi64", + "platformArchABI": "linux-mips64el-gnuabi64", + "platform": "linux", + "arch": "mips64el", + "abi": "gnuabi64" + }, + { + "triple": "mips64el-unknown-linux-muslabi64", + "platformArchABI": "linux-mips64el-muslabi64", + "platform": "linux", + "arch": "mips64el", + "abi": "muslabi64" + } + ], + "mipsel": [ + { + "triple": "mipsel-unknown-linux-gnu", + "platformArchABI": "linux-mipsel-gnu", + "platform": "linux", + "arch": "mipsel", + "abi": "gnu" + }, + { + "triple": "mipsel-unknown-linux-musl", + "platformArchABI": "linux-mipsel-musl", + "platform": "linux", + "arch": "mipsel", + "abi": "musl" + } + ], + "powerpc": [ + { + "triple": "powerpc-unknown-linux-gnu", + "platformArchABI": "linux-powerpc-gnu", + "platform": "linux", + "arch": "powerpc", + "abi": "gnu" + } + ], + "powerpc64": [ + { + "triple": "powerpc64-unknown-linux-gnu", + "platformArchABI": "linux-powerpc64-gnu", + "platform": "linux", + "arch": "powerpc64", + "abi": "gnu" + } + ], + "powerpc64le": [ + { + "triple": "powerpc64le-unknown-linux-gnu", + "platformArchABI": "linux-powerpc64le-gnu", + "platform": "linux", + "arch": "powerpc64le", + "abi": "gnu" + } + ], + "riscv64gc": [ + { + "triple": "riscv64gc-unknown-linux-gnu", + "platformArchABI": "linux-riscv64gc-gnu", + "platform": "linux", + "arch": "riscv64gc", + "abi": "gnu" + } + ], + "s390x": [ + { + "triple": "s390x-unknown-linux-gnu", + "platformArchABI": "linux-s390x-gnu", + "platform": "linux", + "arch": "s390x", + "abi": "gnu" + } + ], + "sparc64": [ + { + "triple": "sparc64-unknown-linux-gnu", + "platformArchABI": "linux-sparc64-gnu", + "platform": "linux", + "arch": "sparc64", + "abi": "gnu" + } + ], + "x64": [ + { + "triple": "x86_64-unknown-linux-gnu", + "platformArchABI": "linux-x64-gnu", + "platform": "linux", + "arch": "x64", + "abi": "gnu" + }, + { + "triple": "x86_64-unknown-linux-gnux32", + "platformArchABI": "linux-x64-gnux32", + "platform": "linux", + "arch": "x64", + "abi": "gnux32" + }, + { + "triple": "x86_64-unknown-linux-musl", + "platformArchABI": "linux-x64-musl", + "platform": "linux", + "arch": "x64", + "abi": "musl" + } + ] + }, + "freebsd": { + "ia32": [ + { + "triple": "i686-unknown-freebsd", + "platformArchABI": "freebsd-ia32", + "platform": "freebsd", + "arch": "ia32", + "abi": null + } + ], + "x64": [ + { + "triple": "x86_64-unknown-freebsd", + "platformArchABI": "freebsd-x64", + "platform": "freebsd", + "arch": "x64", + "abi": null + } + ] + } +} diff --git a/triples/package.json b/triples/package.json index 42f8ba97..0f340724 100644 --- a/triples/package.json +++ b/triples/package.json @@ -13,8 +13,21 @@ "author": "LongYinan ", "homepage": "https://github.com/napi-rs/napi-rs/tree/main/triples#readme", "license": "MIT", + "type": "module", "main": "./index.js", "types": "./index.d.ts", + "exports": { + ".": { + "import": { + "default": "./index.js", + "types": "./index.d.ts" + }, + "require": { + "default": "./index.cjs", + "types": "./index.d.ts" + } + } + }, "publishConfig": { "registry": "https://registry.npmjs.org/", "access": "public" @@ -29,5 +42,13 @@ }, "bugs": { "url": "https://github.com/napi-rs/napi-rs/issues" + }, + "scripts": { + "build": "node --loader ts-node/esm/transpile-only ./generate-triple-list.ts" + }, + "devDependencies": { + "lodash-es": "^4.17.21", + "ts-node": "^10.9.1", + "typescript": "^4.9.4" } } diff --git a/tsconfig.json b/tsconfig.json index a765e7af..d02b0536 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -5,8 +5,8 @@ "downlevelIteration": true, "importHelpers": true, "allowJs": true, - "module": "CommonJS", - "moduleResolution": "node", + "module": "NodeNext", + "moduleResolution": "nodenext", "newLine": "LF", "noEmitHelpers": true, "noUnusedLocals": true, @@ -17,14 +17,14 @@ "suppressExcessPropertyErrors": true, "forceConsistentCasingInFileNames": true, "preserveSymlinks": true, - "target": "ES2015", + "target": "ES2022", "sourceMap": true, "esModuleInterop": true, "stripInternal": true, "resolveJsonModule": true, "importsNotUsedAsValues": "remove", "outDir": "scripts", - "lib": ["dom", "DOM.Iterable", "ES2019", "ES2020", "esnext"] + "lib": ["ES2022"] }, "include": ["."], "exclude": ["node_modules", "bench", "cli/scripts", "scripts", "target"] diff --git a/tsconfig.root-lint.json b/tsconfig.root-lint.json index 77829e5b..79782f3b 100644 --- a/tsconfig.root-lint.json +++ b/tsconfig.root-lint.json @@ -1,10 +1,10 @@ { "extends": "./tsconfig.json", "include": [ - "./ava.config.js", - "./generate-triplelist.js", + "./ava.config.mjs", "./triples/index.js", "./memory-testing/*.js", - "./memory-testing/*.mjs" + "./memory-testing/*.mjs", + "./crates/cli/index.js" ] } diff --git a/yarn.lock b/yarn.lock index 3350e124..21bee56e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -118,6 +118,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/android-arm64@npm:0.17.14": + version: 0.17.14 + resolution: "@esbuild/android-arm64@npm:0.17.14" + conditions: os=android & cpu=arm64 + languageName: node + linkType: hard + "@esbuild/android-arm64@npm:0.17.2": version: 0.17.2 resolution: "@esbuild/android-arm64@npm:0.17.2" @@ -125,6 +132,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/android-arm@npm:0.17.14": + version: 0.17.14 + resolution: "@esbuild/android-arm@npm:0.17.14" + conditions: os=android & cpu=arm + languageName: node + linkType: hard + "@esbuild/android-arm@npm:0.17.2": version: 0.17.2 resolution: "@esbuild/android-arm@npm:0.17.2" @@ -132,6 +146,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/android-x64@npm:0.17.14": + version: 0.17.14 + resolution: "@esbuild/android-x64@npm:0.17.14" + conditions: os=android & cpu=x64 + languageName: node + linkType: hard + "@esbuild/android-x64@npm:0.17.2": version: 0.17.2 resolution: "@esbuild/android-x64@npm:0.17.2" @@ -139,6 +160,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/darwin-arm64@npm:0.17.14": + version: 0.17.14 + resolution: "@esbuild/darwin-arm64@npm:0.17.14" + conditions: os=darwin & cpu=arm64 + languageName: node + linkType: hard + "@esbuild/darwin-arm64@npm:0.17.2": version: 0.17.2 resolution: "@esbuild/darwin-arm64@npm:0.17.2" @@ -146,6 +174,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/darwin-x64@npm:0.17.14": + version: 0.17.14 + resolution: "@esbuild/darwin-x64@npm:0.17.14" + conditions: os=darwin & cpu=x64 + languageName: node + linkType: hard + "@esbuild/darwin-x64@npm:0.17.2": version: 0.17.2 resolution: "@esbuild/darwin-x64@npm:0.17.2" @@ -153,6 +188,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/freebsd-arm64@npm:0.17.14": + version: 0.17.14 + resolution: "@esbuild/freebsd-arm64@npm:0.17.14" + conditions: os=freebsd & cpu=arm64 + languageName: node + linkType: hard + "@esbuild/freebsd-arm64@npm:0.17.2": version: 0.17.2 resolution: "@esbuild/freebsd-arm64@npm:0.17.2" @@ -160,6 +202,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/freebsd-x64@npm:0.17.14": + version: 0.17.14 + resolution: "@esbuild/freebsd-x64@npm:0.17.14" + conditions: os=freebsd & cpu=x64 + languageName: node + linkType: hard + "@esbuild/freebsd-x64@npm:0.17.2": version: 0.17.2 resolution: "@esbuild/freebsd-x64@npm:0.17.2" @@ -167,6 +216,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/linux-arm64@npm:0.17.14": + version: 0.17.14 + resolution: "@esbuild/linux-arm64@npm:0.17.14" + conditions: os=linux & cpu=arm64 + languageName: node + linkType: hard + "@esbuild/linux-arm64@npm:0.17.2": version: 0.17.2 resolution: "@esbuild/linux-arm64@npm:0.17.2" @@ -174,6 +230,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/linux-arm@npm:0.17.14": + version: 0.17.14 + resolution: "@esbuild/linux-arm@npm:0.17.14" + conditions: os=linux & cpu=arm + languageName: node + linkType: hard + "@esbuild/linux-arm@npm:0.17.2": version: 0.17.2 resolution: "@esbuild/linux-arm@npm:0.17.2" @@ -181,6 +244,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/linux-ia32@npm:0.17.14": + version: 0.17.14 + resolution: "@esbuild/linux-ia32@npm:0.17.14" + conditions: os=linux & cpu=ia32 + languageName: node + linkType: hard + "@esbuild/linux-ia32@npm:0.17.2": version: 0.17.2 resolution: "@esbuild/linux-ia32@npm:0.17.2" @@ -188,6 +258,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/linux-loong64@npm:0.17.14": + version: 0.17.14 + resolution: "@esbuild/linux-loong64@npm:0.17.14" + conditions: os=linux & cpu=loong64 + languageName: node + linkType: hard + "@esbuild/linux-loong64@npm:0.17.2": version: 0.17.2 resolution: "@esbuild/linux-loong64@npm:0.17.2" @@ -195,6 +272,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/linux-mips64el@npm:0.17.14": + version: 0.17.14 + resolution: "@esbuild/linux-mips64el@npm:0.17.14" + conditions: os=linux & cpu=mips64el + languageName: node + linkType: hard + "@esbuild/linux-mips64el@npm:0.17.2": version: 0.17.2 resolution: "@esbuild/linux-mips64el@npm:0.17.2" @@ -202,6 +286,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/linux-ppc64@npm:0.17.14": + version: 0.17.14 + resolution: "@esbuild/linux-ppc64@npm:0.17.14" + conditions: os=linux & cpu=ppc64 + languageName: node + linkType: hard + "@esbuild/linux-ppc64@npm:0.17.2": version: 0.17.2 resolution: "@esbuild/linux-ppc64@npm:0.17.2" @@ -209,6 +300,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/linux-riscv64@npm:0.17.14": + version: 0.17.14 + resolution: "@esbuild/linux-riscv64@npm:0.17.14" + conditions: os=linux & cpu=riscv64 + languageName: node + linkType: hard + "@esbuild/linux-riscv64@npm:0.17.2": version: 0.17.2 resolution: "@esbuild/linux-riscv64@npm:0.17.2" @@ -216,6 +314,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/linux-s390x@npm:0.17.14": + version: 0.17.14 + resolution: "@esbuild/linux-s390x@npm:0.17.14" + conditions: os=linux & cpu=s390x + languageName: node + linkType: hard + "@esbuild/linux-s390x@npm:0.17.2": version: 0.17.2 resolution: "@esbuild/linux-s390x@npm:0.17.2" @@ -223,6 +328,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/linux-x64@npm:0.17.14": + version: 0.17.14 + resolution: "@esbuild/linux-x64@npm:0.17.14" + conditions: os=linux & cpu=x64 + languageName: node + linkType: hard + "@esbuild/linux-x64@npm:0.17.2": version: 0.17.2 resolution: "@esbuild/linux-x64@npm:0.17.2" @@ -230,6 +342,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/netbsd-x64@npm:0.17.14": + version: 0.17.14 + resolution: "@esbuild/netbsd-x64@npm:0.17.14" + conditions: os=netbsd & cpu=x64 + languageName: node + linkType: hard + "@esbuild/netbsd-x64@npm:0.17.2": version: 0.17.2 resolution: "@esbuild/netbsd-x64@npm:0.17.2" @@ -237,6 +356,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/openbsd-x64@npm:0.17.14": + version: 0.17.14 + resolution: "@esbuild/openbsd-x64@npm:0.17.14" + conditions: os=openbsd & cpu=x64 + languageName: node + linkType: hard + "@esbuild/openbsd-x64@npm:0.17.2": version: 0.17.2 resolution: "@esbuild/openbsd-x64@npm:0.17.2" @@ -244,6 +370,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/sunos-x64@npm:0.17.14": + version: 0.17.14 + resolution: "@esbuild/sunos-x64@npm:0.17.14" + conditions: os=sunos & cpu=x64 + languageName: node + linkType: hard + "@esbuild/sunos-x64@npm:0.17.2": version: 0.17.2 resolution: "@esbuild/sunos-x64@npm:0.17.2" @@ -251,6 +384,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/win32-arm64@npm:0.17.14": + version: 0.17.14 + resolution: "@esbuild/win32-arm64@npm:0.17.14" + conditions: os=win32 & cpu=arm64 + languageName: node + linkType: hard + "@esbuild/win32-arm64@npm:0.17.2": version: 0.17.2 resolution: "@esbuild/win32-arm64@npm:0.17.2" @@ -258,6 +398,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/win32-ia32@npm:0.17.14": + version: 0.17.14 + resolution: "@esbuild/win32-ia32@npm:0.17.14" + conditions: os=win32 & cpu=ia32 + languageName: node + linkType: hard + "@esbuild/win32-ia32@npm:0.17.2": version: 0.17.2 resolution: "@esbuild/win32-ia32@npm:0.17.2" @@ -265,6 +412,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/win32-x64@npm:0.17.14": + version: 0.17.14 + resolution: "@esbuild/win32-x64@npm:0.17.14" + conditions: os=win32 & cpu=x64 + languageName: node + linkType: hard + "@esbuild/win32-x64@npm:0.17.2": version: 0.17.2 resolution: "@esbuild/win32-x64@npm:0.17.2" @@ -289,6 +443,28 @@ __metadata: languageName: node linkType: hard +"@examples/compat-mode@workspace:examples/napi-compat-mode": + version: 0.0.0-use.local + resolution: "@examples/compat-mode@workspace:examples/napi-compat-mode" + dependencies: + "@napi-rs/cli": "workspace:*" + ava: ^5.2.0 + sinon: ^15.0.1 + languageName: unknown + linkType: soft + +"@examples/napi@workspace:examples/napi": + version: 0.0.0-use.local + resolution: "@examples/napi@workspace:examples/napi" + dependencies: + "@napi-rs/cli": "workspace:*" + "@types/lodash": ^4.14.191 + ava: ^5.2.0 + lodash: ^4.17.21 + sinon: ^15.0.1 + languageName: unknown + linkType: soft + "@gar/promisify@npm:^1.1.3": version: 1.1.3 resolution: "@gar/promisify@npm:1.1.3" @@ -376,40 +552,40 @@ __metadata: languageName: node linkType: hard -"@lerna/add@npm:6.4.1": - version: 6.4.1 - resolution: "@lerna/add@npm:6.4.1" +"@lerna/add@npm:5.6.2": + version: 5.6.2 + resolution: "@lerna/add@npm:5.6.2" dependencies: - "@lerna/bootstrap": 6.4.1 - "@lerna/command": 6.4.1 - "@lerna/filter-options": 6.4.1 - "@lerna/npm-conf": 6.4.1 - "@lerna/validation-error": 6.4.1 + "@lerna/bootstrap": 5.6.2 + "@lerna/command": 5.6.2 + "@lerna/filter-options": 5.6.2 + "@lerna/npm-conf": 5.6.2 + "@lerna/validation-error": 5.6.2 dedent: ^0.7.0 npm-package-arg: 8.1.1 p-map: ^4.0.0 pacote: ^13.6.1 semver: ^7.3.4 - checksum: 7d9772e4d1149a30f8f050a3d6c3bd0d01dc51ed8fbf781be799b6b69ee97ae2976398336ec3564c670b4625889b37481924e1eabd2427b3df3c1a7d60b4af0f + checksum: a6e9a6270f3145cb24da1b90a312cbbe0f3a0c556943c7e7b8cf4bfbb0912db4de7e7dc248321dd26955b3b8dbf8ede8c9481e2a0f3107c8a5cd917bfe187976 languageName: node linkType: hard -"@lerna/bootstrap@npm:6.4.1": - version: 6.4.1 - resolution: "@lerna/bootstrap@npm:6.4.1" +"@lerna/bootstrap@npm:5.6.2": + version: 5.6.2 + resolution: "@lerna/bootstrap@npm:5.6.2" dependencies: - "@lerna/command": 6.4.1 - "@lerna/filter-options": 6.4.1 - "@lerna/has-npm-version": 6.4.1 - "@lerna/npm-install": 6.4.1 - "@lerna/package-graph": 6.4.1 - "@lerna/pulse-till-done": 6.4.1 - "@lerna/rimraf-dir": 6.4.1 - "@lerna/run-lifecycle": 6.4.1 - "@lerna/run-topologically": 6.4.1 - "@lerna/symlink-binary": 6.4.1 - "@lerna/symlink-dependencies": 6.4.1 - "@lerna/validation-error": 6.4.1 + "@lerna/command": 5.6.2 + "@lerna/filter-options": 5.6.2 + "@lerna/has-npm-version": 5.6.2 + "@lerna/npm-install": 5.6.2 + "@lerna/package-graph": 5.6.2 + "@lerna/pulse-till-done": 5.6.2 + "@lerna/rimraf-dir": 5.6.2 + "@lerna/run-lifecycle": 5.6.2 + "@lerna/run-topologically": 5.6.2 + "@lerna/symlink-binary": 5.6.2 + "@lerna/symlink-dependencies": 5.6.2 + "@lerna/validation-error": 5.6.2 "@npmcli/arborist": 5.3.0 dedent: ^0.7.0 get-port: ^5.1.1 @@ -420,119 +596,119 @@ __metadata: p-map-series: ^2.1.0 p-waterfall: ^2.1.1 semver: ^7.3.4 - checksum: 777d1c95af102f0ed66c812c51628813c976ae8e2c5f32ff2b8e3b927c6daaf7efac43776e4e8f4c988c52460dc9752a6f3f6a9617453c7cef84e015ebfa26f2 + checksum: 5b416f2276077348a72c4079d96b35729502a8bc3f91144cf3109b1ea5966245c809769304414a9b038de0980e783ed2a8da898fd05802879e8186e35a8a14cf languageName: node linkType: hard -"@lerna/changed@npm:6.4.1": - version: 6.4.1 - resolution: "@lerna/changed@npm:6.4.1" +"@lerna/changed@npm:5.6.2": + version: 5.6.2 + resolution: "@lerna/changed@npm:5.6.2" dependencies: - "@lerna/collect-updates": 6.4.1 - "@lerna/command": 6.4.1 - "@lerna/listable": 6.4.1 - "@lerna/output": 6.4.1 - checksum: 1e69313731ef6cef526ce2e1a9a3294ae9c645695253d8dc26f4bf3c92fa938ff85dab73244b17f4a017fb2e0073883944756df994d360875d5989054420047b + "@lerna/collect-updates": 5.6.2 + "@lerna/command": 5.6.2 + "@lerna/listable": 5.6.2 + "@lerna/output": 5.6.2 + checksum: 69a86cf3b3124553dee5de03988e7e7ecbf3f9084685ff13da1a1c9dfd4dcc3991145db4937cc0a72dde029da6cd37b3614bd21b7b461f8d5724a2f38b6c56d7 languageName: node linkType: hard -"@lerna/check-working-tree@npm:6.4.1": - version: 6.4.1 - resolution: "@lerna/check-working-tree@npm:6.4.1" +"@lerna/check-working-tree@npm:5.6.2": + version: 5.6.2 + resolution: "@lerna/check-working-tree@npm:5.6.2" dependencies: - "@lerna/collect-uncommitted": 6.4.1 - "@lerna/describe-ref": 6.4.1 - "@lerna/validation-error": 6.4.1 - checksum: aeeea4bccbabfe77b2f834e0e7ed044ab43ca5059090dead5cc5a49140d2f35427dba357bf2be0647908249543f5cd44414777ceb593501450a7bdfa632f24bd + "@lerna/collect-uncommitted": 5.6.2 + "@lerna/describe-ref": 5.6.2 + "@lerna/validation-error": 5.6.2 + checksum: 46a30143ab3f73f8e70c76bdffa66d521b787251c986800f60335188a62375186a380c0d772439b0fa9cf057da2f028780674744d684636e84e6974b9a4193e5 languageName: node linkType: hard -"@lerna/child-process@npm:6.4.1": - version: 6.4.1 - resolution: "@lerna/child-process@npm:6.4.1" +"@lerna/child-process@npm:5.6.2": + version: 5.6.2 + resolution: "@lerna/child-process@npm:5.6.2" dependencies: chalk: ^4.1.0 execa: ^5.0.0 strong-log-transformer: ^2.1.0 - checksum: 30b5cec078f3c8e52232e9fd6756f3951f1c11c1e262170da4331291da0548982a32def221f567e7301d7561e1224af760d7b07c572c72820c9dfb1ae13aae28 + checksum: 94e9c03119b3177cb41e210ac8a4bf04386857192e3a99c8bdd3d2ae913eda1538f813138de03693681ee360644cab9a0584658df9e2acbd04eb52a2e3a761cf languageName: node linkType: hard -"@lerna/clean@npm:6.4.1": - version: 6.4.1 - resolution: "@lerna/clean@npm:6.4.1" +"@lerna/clean@npm:5.6.2": + version: 5.6.2 + resolution: "@lerna/clean@npm:5.6.2" dependencies: - "@lerna/command": 6.4.1 - "@lerna/filter-options": 6.4.1 - "@lerna/prompt": 6.4.1 - "@lerna/pulse-till-done": 6.4.1 - "@lerna/rimraf-dir": 6.4.1 + "@lerna/command": 5.6.2 + "@lerna/filter-options": 5.6.2 + "@lerna/prompt": 5.6.2 + "@lerna/pulse-till-done": 5.6.2 + "@lerna/rimraf-dir": 5.6.2 p-map: ^4.0.0 p-map-series: ^2.1.0 p-waterfall: ^2.1.1 - checksum: 0c369d4c4a6b8468753681308434478aad85f41f92bc445ce692334ed7339b65d3ed5681ed5a171672821d9f5a4bf3e56bf2d631c9538ecd7b19b3b011f47a88 + checksum: b20aa2d5c0ace554dcb2ce37915b6a172627e1d26f54a6be33ae8b59d2b31ac1c4c70fa99ca5bffefc9a725ef798059b3b83f751728f6471e9edee1cb901d8b9 languageName: node linkType: hard -"@lerna/cli@npm:6.4.1": - version: 6.4.1 - resolution: "@lerna/cli@npm:6.4.1" +"@lerna/cli@npm:5.6.2": + version: 5.6.2 + resolution: "@lerna/cli@npm:5.6.2" dependencies: - "@lerna/global-options": 6.4.1 + "@lerna/global-options": 5.6.2 dedent: ^0.7.0 npmlog: ^6.0.2 yargs: ^16.2.0 - checksum: c8e36e039a5741d991e53f2569c9cd69f71c98f6a8e7da9de186bafeae082a7621013b2d668ac60b3e9a13afc573afd3d2a02f61171c9d05af17847308ec368d + checksum: e0b853feafe6d572056ea61a18fed4acb0ad62bcd99c3b5d753a8b8e8b69e5275f5eb7e102e7d09340d8f8e0e73a038b203acb4c77437d7edcf835470917b296 languageName: node linkType: hard -"@lerna/collect-uncommitted@npm:6.4.1": - version: 6.4.1 - resolution: "@lerna/collect-uncommitted@npm:6.4.1" +"@lerna/collect-uncommitted@npm:5.6.2": + version: 5.6.2 + resolution: "@lerna/collect-uncommitted@npm:5.6.2" dependencies: - "@lerna/child-process": 6.4.1 + "@lerna/child-process": 5.6.2 chalk: ^4.1.0 npmlog: ^6.0.2 - checksum: cb7e6773e9f0c578a6e2c6c079e4fc8d91b316e6eee50db8b762101f5974f09db1131cc3a8c3f040f52b15bcea442ce9d739eb05e195c89bcfc2afabd30e753b + checksum: 9c9298bc447629819634dc5fa697caa6a4b33c4e9fd61ae7ad4108a42d916ef9193ea4cb72d6cf766fc6863e350211ab9b1fcde6a8fb75b75f43aa5e4a1afeb4 languageName: node linkType: hard -"@lerna/collect-updates@npm:6.4.1": - version: 6.4.1 - resolution: "@lerna/collect-updates@npm:6.4.1" +"@lerna/collect-updates@npm:5.6.2": + version: 5.6.2 + resolution: "@lerna/collect-updates@npm:5.6.2" dependencies: - "@lerna/child-process": 6.4.1 - "@lerna/describe-ref": 6.4.1 + "@lerna/child-process": 5.6.2 + "@lerna/describe-ref": 5.6.2 minimatch: ^3.0.4 npmlog: ^6.0.2 slash: ^3.0.0 - checksum: 1b500a32e1ec4561facc8e2530904d701ba64da5b1e1b0fbe936f9893a44c689359a53506723fb0cb221f11a315b01aa6278a9b35b12afbfa5be3907e2ba8308 + checksum: 44149466c60e63f495bb09a3a8fd6c1d91f55de9dfcaac3adcefaf27c690adb6ac2c2a9b6bf5c9f8e430cb41db7c6994c9506b28945f5bb46a47e78f2829425d languageName: node linkType: hard -"@lerna/command@npm:6.4.1": - version: 6.4.1 - resolution: "@lerna/command@npm:6.4.1" +"@lerna/command@npm:5.6.2": + version: 5.6.2 + resolution: "@lerna/command@npm:5.6.2" dependencies: - "@lerna/child-process": 6.4.1 - "@lerna/package-graph": 6.4.1 - "@lerna/project": 6.4.1 - "@lerna/validation-error": 6.4.1 - "@lerna/write-log-file": 6.4.1 + "@lerna/child-process": 5.6.2 + "@lerna/package-graph": 5.6.2 + "@lerna/project": 5.6.2 + "@lerna/validation-error": 5.6.2 + "@lerna/write-log-file": 5.6.2 clone-deep: ^4.0.1 dedent: ^0.7.0 execa: ^5.0.0 is-ci: ^2.0.0 npmlog: ^6.0.2 - checksum: 900f91749411eea606bef637bc508ecae5fdf947452768b9befe47780034cd132d1c9a00e592fe8eed0e76aa47060a34367c15a7e54e0408e21fd088703be6ce + checksum: 6a3bdef20658b474476a3750862e2d4753284d0023faf755b39d403a7dc71f6c5c46bc68f79ba27af1a12eb8add391f3afb82aee08b93e02141aa44f939cd668 languageName: node linkType: hard -"@lerna/conventional-commits@npm:6.4.1": - version: 6.4.1 - resolution: "@lerna/conventional-commits@npm:6.4.1" +"@lerna/conventional-commits@npm:5.6.2": + version: 5.6.2 + resolution: "@lerna/conventional-commits@npm:5.6.2" dependencies: - "@lerna/validation-error": 6.4.1 + "@lerna/validation-error": 5.6.2 conventional-changelog-angular: ^5.0.12 conventional-changelog-core: ^4.2.4 conventional-recommended-bump: ^6.1.0 @@ -542,29 +718,29 @@ __metadata: npmlog: ^6.0.2 pify: ^5.0.0 semver: ^7.3.4 - checksum: 4a82da8d6b8b9afb71c558db7245d494315dbab3f676f836aa00ba079dd97842d75b3ee689c4a2c572d1ad0c203c6271790cd55e64aa5a744d59650fee4a113a + checksum: a8dbcd4bbb697aebb6c1b045f8597f019b754cf42b5abaf6a77da7379e212107bb46e8c9747a7bc1b41de640109036f71bc97df0b1066ca6c719172dd5d8b563 languageName: node linkType: hard -"@lerna/create-symlink@npm:6.4.1": - version: 6.4.1 - resolution: "@lerna/create-symlink@npm:6.4.1" +"@lerna/create-symlink@npm:5.6.2": + version: 5.6.2 + resolution: "@lerna/create-symlink@npm:5.6.2" dependencies: cmd-shim: ^5.0.0 fs-extra: ^9.1.0 npmlog: ^6.0.2 - checksum: 7906832ce5765335964a0439f3b2327f8a9b338276b635ad18ae71ed869a6ef8a2b249e16f5167fa1b7c42b38408ea6ad13d7a77c5db31ecfc04aa76211dc87e + checksum: 1848bd60d5f3227cf66103571779d8c12c363c54ade93aaddcb10b7bba00adaf263faccee15fd05ac87ee5514feecd0e20e42b79b798a457609af1e77e734762 languageName: node linkType: hard -"@lerna/create@npm:6.4.1": - version: 6.4.1 - resolution: "@lerna/create@npm:6.4.1" +"@lerna/create@npm:5.6.2": + version: 5.6.2 + resolution: "@lerna/create@npm:5.6.2" dependencies: - "@lerna/child-process": 6.4.1 - "@lerna/command": 6.4.1 - "@lerna/npm-conf": 6.4.1 - "@lerna/validation-error": 6.4.1 + "@lerna/child-process": 5.6.2 + "@lerna/command": 5.6.2 + "@lerna/npm-conf": 5.6.2 + "@lerna/validation-error": 5.6.2 dedent: ^0.7.0 fs-extra: ^9.1.0 init-package-json: ^3.0.2 @@ -577,367 +753,367 @@ __metadata: validate-npm-package-license: ^3.0.4 validate-npm-package-name: ^4.0.0 yargs-parser: 20.2.4 - checksum: bb2d79c4fe28fd7fffd334e0fb48dd378bd329b0b727c62ea8e4ac5266bfd6387d2538d31c92d234d410ad8d07dc2c319afec3fe7a9a959e36478320bfb3a6d1 + checksum: 94706188839a8cd0b8c20fb593a0cb4375bd350e2b6587a29933786bdd8c83417a1d651e5f53fb69e0939bad4f97dd013f5a4c901557e3c20fc360bbd0590806 languageName: node linkType: hard -"@lerna/describe-ref@npm:6.4.1": - version: 6.4.1 - resolution: "@lerna/describe-ref@npm:6.4.1" +"@lerna/describe-ref@npm:5.6.2": + version: 5.6.2 + resolution: "@lerna/describe-ref@npm:5.6.2" dependencies: - "@lerna/child-process": 6.4.1 + "@lerna/child-process": 5.6.2 npmlog: ^6.0.2 - checksum: 1aaefd272f08afb8d917cb570eae4ee18f2f335162686c0c84e9e126aebcd7845a5ed42cc567e6c6c40ac6a090ebdf21c40c80049dbe2072556dfd911a4e84b4 + checksum: 510814bd0004859475cf62917a3145b010b33b519be3b80f30170b98500e176285d8f4b0aa9e5928b80798be90bc65f1591d6c72e26fee70d46e0f006996d69e languageName: node linkType: hard -"@lerna/diff@npm:6.4.1": - version: 6.4.1 - resolution: "@lerna/diff@npm:6.4.1" +"@lerna/diff@npm:5.6.2": + version: 5.6.2 + resolution: "@lerna/diff@npm:5.6.2" dependencies: - "@lerna/child-process": 6.4.1 - "@lerna/command": 6.4.1 - "@lerna/validation-error": 6.4.1 + "@lerna/child-process": 5.6.2 + "@lerna/command": 5.6.2 + "@lerna/validation-error": 5.6.2 npmlog: ^6.0.2 - checksum: f0f918c8acb6ca83c73e474601112687de2fd817ab52d30bdc022a8c0713b468dda4234a4c2001f8639e12780de03b02bd037a9c50c9bb3507b6a434e1b02ba5 + checksum: 0731f5819da8c7bb2a210a9514541e7f7cdde8ddf1802e3ec5e40bd689f3c546d6fba12b9c72cd48aa97d179ff767c658bdfe26bf9590056307ee738b5b44052 languageName: node linkType: hard -"@lerna/exec@npm:6.4.1": - version: 6.4.1 - resolution: "@lerna/exec@npm:6.4.1" +"@lerna/exec@npm:5.6.2": + version: 5.6.2 + resolution: "@lerna/exec@npm:5.6.2" dependencies: - "@lerna/child-process": 6.4.1 - "@lerna/command": 6.4.1 - "@lerna/filter-options": 6.4.1 - "@lerna/profiler": 6.4.1 - "@lerna/run-topologically": 6.4.1 - "@lerna/validation-error": 6.4.1 + "@lerna/child-process": 5.6.2 + "@lerna/command": 5.6.2 + "@lerna/filter-options": 5.6.2 + "@lerna/profiler": 5.6.2 + "@lerna/run-topologically": 5.6.2 + "@lerna/validation-error": 5.6.2 p-map: ^4.0.0 - checksum: ec4e7074ec7b5c14838fad663c3de4985d5c46bf86409d5d2259597483c3cb71168c4e09f2b5fee519b2852b782fe91daa359830671ca4db29b9f9714a9241df + checksum: 30255cffbb67bc6a89290c1755e0e832fe9be1de0a98a2a6553a0baf0e1f509e0268318eeb3da4441bad2aa5517268b522f57dc3aefc49d122b301dd06ff6086 languageName: node linkType: hard -"@lerna/filter-options@npm:6.4.1": - version: 6.4.1 - resolution: "@lerna/filter-options@npm:6.4.1" +"@lerna/filter-options@npm:5.6.2": + version: 5.6.2 + resolution: "@lerna/filter-options@npm:5.6.2" dependencies: - "@lerna/collect-updates": 6.4.1 - "@lerna/filter-packages": 6.4.1 + "@lerna/collect-updates": 5.6.2 + "@lerna/filter-packages": 5.6.2 dedent: ^0.7.0 npmlog: ^6.0.2 - checksum: 98c715980beb7a527bb393c687a6e911abdb31e4bd566ee1b0cdb1450d6dc5670f1c93ea4b530227d0129af93b75cc7dbae48773b54f55cfef465bddc2926ae5 + checksum: c1b4ce4973bd8fff66a1632891f69ce4c20858d304cc02502df1576235b879cb4d3dd04b4be4b1835058f445c44d572554b206cf35ec4c1a3b76de396949bff1 languageName: node linkType: hard -"@lerna/filter-packages@npm:6.4.1": - version: 6.4.1 - resolution: "@lerna/filter-packages@npm:6.4.1" +"@lerna/filter-packages@npm:5.6.2": + version: 5.6.2 + resolution: "@lerna/filter-packages@npm:5.6.2" dependencies: - "@lerna/validation-error": 6.4.1 + "@lerna/validation-error": 5.6.2 multimatch: ^5.0.0 npmlog: ^6.0.2 - checksum: 39339e156fb7c9215362fd505a440f7ac3d62096d56aa6dfbe360231bb05ecbd5d605f1885c062ee038d360f32fbf29028863b54c98d7dce2feff58c19a4fb2b + checksum: b5b4c3b1d1ae6d889802ead0e682aecb8a12c1cbb3738a95e68013e9c7fd04cc0e495e249ef69eb52e65c69bca760d357d265642b1e066857c898ff1415978bd languageName: node linkType: hard -"@lerna/get-npm-exec-opts@npm:6.4.1": - version: 6.4.1 - resolution: "@lerna/get-npm-exec-opts@npm:6.4.1" +"@lerna/get-npm-exec-opts@npm:5.6.2": + version: 5.6.2 + resolution: "@lerna/get-npm-exec-opts@npm:5.6.2" dependencies: npmlog: ^6.0.2 - checksum: 81d95ec6b2082d9fafc268357f44c45f93b8c536cf5fde8adbcc8f5eb6e839fabba4ef539f8a2317f86d6f79735a32263b9a9823d81b66c8af7d46564d519f33 + checksum: 3430e602db853e075490e6b080d46340940acf354fb5513da19af2a8ad60c8fa397de7cbcbe0bda8a4266e9d995bc7cba1698d092933c5feaef134585eef9f08 languageName: node linkType: hard -"@lerna/get-packed@npm:6.4.1": - version: 6.4.1 - resolution: "@lerna/get-packed@npm:6.4.1" +"@lerna/get-packed@npm:5.6.2": + version: 5.6.2 + resolution: "@lerna/get-packed@npm:5.6.2" dependencies: fs-extra: ^9.1.0 ssri: ^9.0.1 tar: ^6.1.0 - checksum: 452c865960216a0b1b1d9e983ab3699a382192cbe7e1ce02882f250ee9b1de23576f777aefe89a0cd75eb25c10afbeeb18bc7889c19836ccd53f734b424ebec5 + checksum: 12637d74cf654214fb6adfe444370d90d66f5aa2fdbcfc6bedd4168e24a8e91346ad22f1386630b635452b3a0089c91cd3ea141f6cddfd8d111ba7b94dbbaac8 languageName: node linkType: hard -"@lerna/github-client@npm:6.4.1": - version: 6.4.1 - resolution: "@lerna/github-client@npm:6.4.1" +"@lerna/github-client@npm:5.6.2": + version: 5.6.2 + resolution: "@lerna/github-client@npm:5.6.2" dependencies: - "@lerna/child-process": 6.4.1 + "@lerna/child-process": 5.6.2 "@octokit/plugin-enterprise-rest": ^6.0.1 "@octokit/rest": ^19.0.3 git-url-parse: ^13.1.0 npmlog: ^6.0.2 - checksum: 8adbc11d9154e3558f4f457e62248a103bdeb01febbc8dc973baf7249a46f7b3357765c4188dd0ac9c0a1d07960240b85d97fcb4403aaf947c8af905f5f0589a + checksum: 08a7386af70bacec5b1c2ec7ba09a0cae407e54c65d33c89444b4460df48dc325772fe77b38ce7c5355295e24ba64d0d64e53ae3ca76ddd4b930af1f5b38507c languageName: node linkType: hard -"@lerna/gitlab-client@npm:6.4.1": - version: 6.4.1 - resolution: "@lerna/gitlab-client@npm:6.4.1" +"@lerna/gitlab-client@npm:5.6.2": + version: 5.6.2 + resolution: "@lerna/gitlab-client@npm:5.6.2" dependencies: node-fetch: ^2.6.1 npmlog: ^6.0.2 - checksum: 03b960d8887936ac0e6fb2a6e3431ed22c047b805bcd53efd2345023dee17f28d8c9a31f9f44aae3fb76a9edad5bd5f1549c85676a99073f80310b9f096b9f97 + checksum: ad9e45621b727858f4ea87a5d624da41cd6784e616d247b86275fb08fbfb4c9974c5f698f59ac0272ec1d0a848bba5f04ef2fbc32c62ca3a77ecd3b0415bd298 languageName: node linkType: hard -"@lerna/global-options@npm:6.4.1": - version: 6.4.1 - resolution: "@lerna/global-options@npm:6.4.1" - checksum: 69c5e5fe10ab80d16c3c3c3aea6f33e836daf071857888874844a1ff2ace5fd0cd5f2c71d2fc28b35fb385c8c7d4c26d47280b32c4afc9454f0b743c0b73dab7 +"@lerna/global-options@npm:5.6.2": + version: 5.6.2 + resolution: "@lerna/global-options@npm:5.6.2" + checksum: 7cb542edef4f06c98dc5a1f797a442e4a1f8bde444046bc5258b0908ecd888ac7fe75902c90c20898feb90e685dee2e3518dc5c85a8155504373ec3f4634f3db languageName: node linkType: hard -"@lerna/has-npm-version@npm:6.4.1": - version: 6.4.1 - resolution: "@lerna/has-npm-version@npm:6.4.1" +"@lerna/has-npm-version@npm:5.6.2": + version: 5.6.2 + resolution: "@lerna/has-npm-version@npm:5.6.2" dependencies: - "@lerna/child-process": 6.4.1 + "@lerna/child-process": 5.6.2 semver: ^7.3.4 - checksum: e209bd35744ca1c838886c055d962a4ef733927fccd5f5f9b832c8863cfd6340c961fa788aafb61b213a0008a9dc811e69aa3498c5161f4a952ca4eef1df5171 + checksum: 98ca1161618a84e0509b9c988f3dd2e147225564d31820ea7b94332388afb7650b510ad902919c5ec9a0ec95b27aab81b4c3067769d106c801426620018a7aa4 languageName: node linkType: hard -"@lerna/import@npm:6.4.1": - version: 6.4.1 - resolution: "@lerna/import@npm:6.4.1" +"@lerna/import@npm:5.6.2": + version: 5.6.2 + resolution: "@lerna/import@npm:5.6.2" dependencies: - "@lerna/child-process": 6.4.1 - "@lerna/command": 6.4.1 - "@lerna/prompt": 6.4.1 - "@lerna/pulse-till-done": 6.4.1 - "@lerna/validation-error": 6.4.1 + "@lerna/child-process": 5.6.2 + "@lerna/command": 5.6.2 + "@lerna/prompt": 5.6.2 + "@lerna/pulse-till-done": 5.6.2 + "@lerna/validation-error": 5.6.2 dedent: ^0.7.0 fs-extra: ^9.1.0 p-map-series: ^2.1.0 - checksum: 40763687862c424e72d654871b22bee875465c161ced9e97976eb5a8cf2db10025d6aff6b5d7e9232caf14e4cf24c9e3065b6ba789e95f6659fba6c186af9605 + checksum: fdcecfd29de36488f78d51776d0edaf4e789bcedad57fe72818ab2e8416578396cfdf142f57095490eefcdd0d3d63a55b23a5e03cf42e5b97878a997025b6b86 languageName: node linkType: hard -"@lerna/info@npm:6.4.1": - version: 6.4.1 - resolution: "@lerna/info@npm:6.4.1" +"@lerna/info@npm:5.6.2": + version: 5.6.2 + resolution: "@lerna/info@npm:5.6.2" dependencies: - "@lerna/command": 6.4.1 - "@lerna/output": 6.4.1 + "@lerna/command": 5.6.2 + "@lerna/output": 5.6.2 envinfo: ^7.7.4 - checksum: 069c5461fa24e788f0cb164f2f51b42722bb8b7432c07bdbc5f569e5c1358c23a71583af04a1abb487ce31f6cb466d02ff73e49993f36080666e58383c38a401 + checksum: 0124b7b1fe75e9bee4f4d4e13216a61869ad918ac9dfbad79aa49e3dd4657a67945aceae6632452b08580d1370823af0ce15ac6fd7134b9042f69624c531be57 languageName: node linkType: hard -"@lerna/init@npm:6.4.1": - version: 6.4.1 - resolution: "@lerna/init@npm:6.4.1" +"@lerna/init@npm:5.6.2": + version: 5.6.2 + resolution: "@lerna/init@npm:5.6.2" dependencies: - "@lerna/child-process": 6.4.1 - "@lerna/command": 6.4.1 - "@lerna/project": 6.4.1 + "@lerna/child-process": 5.6.2 + "@lerna/command": 5.6.2 + "@lerna/project": 5.6.2 fs-extra: ^9.1.0 p-map: ^4.0.0 write-json-file: ^4.3.0 - checksum: 63a3177541aaf5c889947a0db4945646866ebaec4b9325b015245adf23fe18c7d297a81344ac736b4c947ab6e5d89b6514bfa5e265e41fe482a201d555790f4a + checksum: 15e9cfee4ec7c0a09ed0426a38c4cdd2d85b1b005bc5c499f69464e7fe4f5dc4ec1dab0e0fae260508f100f68a84ae54d1b8ab556bdd17938f3db8862290eec9 languageName: node linkType: hard -"@lerna/link@npm:6.4.1": - version: 6.4.1 - resolution: "@lerna/link@npm:6.4.1" +"@lerna/link@npm:5.6.2": + version: 5.6.2 + resolution: "@lerna/link@npm:5.6.2" dependencies: - "@lerna/command": 6.4.1 - "@lerna/package-graph": 6.4.1 - "@lerna/symlink-dependencies": 6.4.1 - "@lerna/validation-error": 6.4.1 + "@lerna/command": 5.6.2 + "@lerna/package-graph": 5.6.2 + "@lerna/symlink-dependencies": 5.6.2 + "@lerna/validation-error": 5.6.2 p-map: ^4.0.0 slash: ^3.0.0 - checksum: e033ca9572ef8a9994f3365e9bcfdb6f09a0953e1b17d2021f9a54f1104c49f31e26c43ae4a7c29dd5fdc58280dbba2d86c22ef0bb97678ee1ada0218dbf6cb1 + checksum: 5d4d3cf7cd90e30797cd0961d835984f5f4f01de508c89cd4870462bd64b65f6a2cf01a2f0df738ce612f45154d3ba4fbfbe73d24f21c0b0015d8c3263b93a80 languageName: node linkType: hard -"@lerna/list@npm:6.4.1": - version: 6.4.1 - resolution: "@lerna/list@npm:6.4.1" +"@lerna/list@npm:5.6.2": + version: 5.6.2 + resolution: "@lerna/list@npm:5.6.2" dependencies: - "@lerna/command": 6.4.1 - "@lerna/filter-options": 6.4.1 - "@lerna/listable": 6.4.1 - "@lerna/output": 6.4.1 - checksum: 9b6f70aef86dd603e1643db8ad301515c07941829b85b19a82a4c0106de2aa122d5ffe155f24b16b55ea83b77e4db838a509c59b9930df9c1a989b775593eb31 + "@lerna/command": 5.6.2 + "@lerna/filter-options": 5.6.2 + "@lerna/listable": 5.6.2 + "@lerna/output": 5.6.2 + checksum: 969b4a458e26bb12533549577fc3c95b62f7a982e04c77bf0755b99a1280d51a0b6288d9a42f1cb05d2f84e852c0fac6a388a5ab735daf1eaa478d9a5e4244f3 languageName: node linkType: hard -"@lerna/listable@npm:6.4.1": - version: 6.4.1 - resolution: "@lerna/listable@npm:6.4.1" +"@lerna/listable@npm:5.6.2": + version: 5.6.2 + resolution: "@lerna/listable@npm:5.6.2" dependencies: - "@lerna/query-graph": 6.4.1 + "@lerna/query-graph": 5.6.2 chalk: ^4.1.0 columnify: ^1.6.0 - checksum: 623205f60000245a5a1de09994686ca385a24d02c7a1cb7e91d25a5e18439c9d6184aec3d6aa6ac014d9dbc5b3e052ba7b93c7f0556c6befa00bb6cc17ed1cc1 + checksum: 3c94647582cd976117c636799e10cea486d171b9c7c20554ffc68c0dd5e33f0d847667264c19a40fbf44a697902dc11e55ca01e74d12f536fb67e338c124381e languageName: node linkType: hard -"@lerna/log-packed@npm:6.4.1": - version: 6.4.1 - resolution: "@lerna/log-packed@npm:6.4.1" +"@lerna/log-packed@npm:5.6.2": + version: 5.6.2 + resolution: "@lerna/log-packed@npm:5.6.2" dependencies: byte-size: ^7.0.0 columnify: ^1.6.0 has-unicode: ^2.0.1 npmlog: ^6.0.2 - checksum: 386f6c9976273f86245304342592779d337ca7f1c27353f5bbb3ec11e826e41c00539723b8d4f6f30d5ecec21cd4048f9dc3d0482e02eab387c8fff1f0bcb7ae + checksum: bbb43bd521bd431298048556a0ca1b83819d6352a06c4792a121403ab5cc2a467c7e89848cec72c7e348af12d3eac1e65e95d1372bedad2ef4a68aaa5d624e5a languageName: node linkType: hard -"@lerna/npm-conf@npm:6.4.1": - version: 6.4.1 - resolution: "@lerna/npm-conf@npm:6.4.1" +"@lerna/npm-conf@npm:5.6.2": + version: 5.6.2 + resolution: "@lerna/npm-conf@npm:5.6.2" dependencies: config-chain: ^1.1.12 pify: ^5.0.0 - checksum: d56212097cdad5704650529f917860c465766d78e03ff7a5885a22ffaa51b4dabf50863b406f7d33fbbda54c731d75cad013f357c159087dae7eaeec6b8b1943 + checksum: ee79c50b57859c918e597b48f44483c00c47fc84e61440c21d756981e8ff0d2721ff068e9539fabc50c073710d5c8fee469aa9e6620c0ecbf4dfce9db4979f94 languageName: node linkType: hard -"@lerna/npm-dist-tag@npm:6.4.1": - version: 6.4.1 - resolution: "@lerna/npm-dist-tag@npm:6.4.1" +"@lerna/npm-dist-tag@npm:5.6.2": + version: 5.6.2 + resolution: "@lerna/npm-dist-tag@npm:5.6.2" dependencies: - "@lerna/otplease": 6.4.1 + "@lerna/otplease": 5.6.2 npm-package-arg: 8.1.1 npm-registry-fetch: ^13.3.0 npmlog: ^6.0.2 - checksum: 860cd4d272176622898f1b5fff2d2f502096916986d9c24ab559c91882522aae20263b72065b0789e55c257814c9e36bb26d623ecef10f7261b85443f47a10d1 + checksum: f50f8b090d197b773b467853d54f2993dd99721cfd8dc17f4af587bc0f53a6c1d879175673f34471d2778b114bc97fcb86bfade1d1aafa349ade92f78878dbf5 languageName: node linkType: hard -"@lerna/npm-install@npm:6.4.1": - version: 6.4.1 - resolution: "@lerna/npm-install@npm:6.4.1" +"@lerna/npm-install@npm:5.6.2": + version: 5.6.2 + resolution: "@lerna/npm-install@npm:5.6.2" dependencies: - "@lerna/child-process": 6.4.1 - "@lerna/get-npm-exec-opts": 6.4.1 + "@lerna/child-process": 5.6.2 + "@lerna/get-npm-exec-opts": 5.6.2 fs-extra: ^9.1.0 npm-package-arg: 8.1.1 npmlog: ^6.0.2 signal-exit: ^3.0.3 write-pkg: ^4.0.0 - checksum: 3d956bbb818c59cb7683341e8580953f28b7322e9fd58b5eb56f11b8867932f5efdfeb6d7ddde7d316b1ae321216c8d8afe75466828f7512e4eb15965605f7b0 + checksum: 6878ee7420edb0353ae8b755b10ae33100980b108cbeaa5848f4b5d2c19c836dbe2d93b401365fe05baf080808c8ad259a05bb78d52b177fc21d6c24bdf41b27 languageName: node linkType: hard -"@lerna/npm-publish@npm:6.4.1": - version: 6.4.1 - resolution: "@lerna/npm-publish@npm:6.4.1" +"@lerna/npm-publish@npm:5.6.2": + version: 5.6.2 + resolution: "@lerna/npm-publish@npm:5.6.2" dependencies: - "@lerna/otplease": 6.4.1 - "@lerna/run-lifecycle": 6.4.1 + "@lerna/otplease": 5.6.2 + "@lerna/run-lifecycle": 5.6.2 fs-extra: ^9.1.0 libnpmpublish: ^6.0.4 npm-package-arg: 8.1.1 npmlog: ^6.0.2 pify: ^5.0.0 read-package-json: ^5.0.1 - checksum: 327264027606c4138eaead609f8b08d879f04fbc5bf05758e66cbd8ed7ee9eb486c15d0868dbd7a73b188dd7128e012da66e9fb99f484e14b1453504dae5d32f + checksum: 87ec165e2c5976fd04e41bbed0cf796317813d4ef50cc42a1c96c25d96f761333d34fa575702f2979b3c828ea7df87d21064521fc4137da9d16f67803192c902 languageName: node linkType: hard -"@lerna/npm-run-script@npm:6.4.1": - version: 6.4.1 - resolution: "@lerna/npm-run-script@npm:6.4.1" +"@lerna/npm-run-script@npm:5.6.2": + version: 5.6.2 + resolution: "@lerna/npm-run-script@npm:5.6.2" dependencies: - "@lerna/child-process": 6.4.1 - "@lerna/get-npm-exec-opts": 6.4.1 + "@lerna/child-process": 5.6.2 + "@lerna/get-npm-exec-opts": 5.6.2 npmlog: ^6.0.2 - checksum: a566e840a09c4bc358ca5837f3ddeee93af3930f8cab2c06cf9fd57922c4921c7e586f6e71b34bff656085f429d2446653ccba2eafa60067a6c949499be2b938 + checksum: b8319fe926484afd28f7fa68d92cca438a6429841bec06c843ca673bff044da15380c0077530bc7dd11b10c413a7404c6f7597f0ec15a33137ff5dbb1b9f98f2 languageName: node linkType: hard -"@lerna/otplease@npm:6.4.1": - version: 6.4.1 - resolution: "@lerna/otplease@npm:6.4.1" +"@lerna/otplease@npm:5.6.2": + version: 5.6.2 + resolution: "@lerna/otplease@npm:5.6.2" dependencies: - "@lerna/prompt": 6.4.1 - checksum: 37a1352badfb40a084333c61ea3d43c1c7be2be736c48022d75eb85e23c9e14e49d657e5de9ac0eebd4e1aeda45d0dadbf4261586388f9c1e72e6346b90a481c + "@lerna/prompt": 5.6.2 + checksum: a8eaf9a3104d2d869dac773001e7b82b5825ae1753e1ed5ec953f11930bfc61ec7131a3e802a735cf88e6d61c945ac7bf52a5ae3a3937c40be11ef34b0f85a06 languageName: node linkType: hard -"@lerna/output@npm:6.4.1": - version: 6.4.1 - resolution: "@lerna/output@npm:6.4.1" +"@lerna/output@npm:5.6.2": + version: 5.6.2 + resolution: "@lerna/output@npm:5.6.2" dependencies: npmlog: ^6.0.2 - checksum: f7b8272f7a1f8c70e345fa39dade9c7c802bd0e42b111ce85de45882ece5786c4c77b96f529980bf36070d1d45879163b65ea1ebf9b5e15e917fe741cdddddd1 + checksum: 34494135cf13cf024bb325c85f91e33f1d295df941afa659bdab3896862a9b69165ad6afdefc30945576577960f83c8e2374d2d5feb79e9a34b757ccffce2d9f languageName: node linkType: hard -"@lerna/pack-directory@npm:6.4.1": - version: 6.4.1 - resolution: "@lerna/pack-directory@npm:6.4.1" +"@lerna/pack-directory@npm:5.6.2": + version: 5.6.2 + resolution: "@lerna/pack-directory@npm:5.6.2" dependencies: - "@lerna/get-packed": 6.4.1 - "@lerna/package": 6.4.1 - "@lerna/run-lifecycle": 6.4.1 - "@lerna/temp-write": 6.4.1 + "@lerna/get-packed": 5.6.2 + "@lerna/package": 5.6.2 + "@lerna/run-lifecycle": 5.6.2 + "@lerna/temp-write": 5.6.2 npm-packlist: ^5.1.1 npmlog: ^6.0.2 tar: ^6.1.0 - checksum: 8642a74f6e9e7a965f2637130fc35fec293110b7637f3833fcc92e1661d99315e83a236963557c3e68b5ce7a08344f2f93404e274a9063805c24cdc0ee22c40a + checksum: 1231c9d0d1573267616364a50ef736be6edfdcf82600aee0d89ba8ddae891a32ad8d6d041af92ea685dee95ab7d4662098d62c61201d071a8ec9b4e19dd28e80 languageName: node linkType: hard -"@lerna/package-graph@npm:6.4.1": - version: 6.4.1 - resolution: "@lerna/package-graph@npm:6.4.1" +"@lerna/package-graph@npm:5.6.2": + version: 5.6.2 + resolution: "@lerna/package-graph@npm:5.6.2" dependencies: - "@lerna/prerelease-id-from-version": 6.4.1 - "@lerna/validation-error": 6.4.1 + "@lerna/prerelease-id-from-version": 5.6.2 + "@lerna/validation-error": 5.6.2 npm-package-arg: 8.1.1 npmlog: ^6.0.2 semver: ^7.3.4 - checksum: 8352fee329ea771c06316c5445799b604a29eb29d594ca1fcce62756b866bc2143f0aea1f159482474f1df7e3b6c7f06ee450df30bf9b340bab2b06166c3a00d + checksum: 1627c2de7bad648f6579ebf5cfdeedf3d4eb1931d8dfde10f9ee60663f38b9286b29292b135337f9c4976c4c444b27d341b4ced408f8a067ba97d66ac1efe203 languageName: node linkType: hard -"@lerna/package@npm:6.4.1": - version: 6.4.1 - resolution: "@lerna/package@npm:6.4.1" +"@lerna/package@npm:5.6.2": + version: 5.6.2 + resolution: "@lerna/package@npm:5.6.2" dependencies: load-json-file: ^6.2.0 npm-package-arg: 8.1.1 write-pkg: ^4.0.0 - checksum: 43eb93868633ffb232d093e55747138a3d5453af97d718e3e3e388d06b4efb1b8eedcaaeb0db8c5cbaa6dd5e1297f2adc82f4c5affc9bfa8b1e8c3e776251d18 + checksum: 7f0d32cf4a74c76d932633a06ace58eca7ea46a2624ef304101b6b882ebe4ec1c683c6836784b790132d29e68e396f6490703db3070af3cff02ef32260f0fb52 languageName: node linkType: hard -"@lerna/prerelease-id-from-version@npm:6.4.1": - version: 6.4.1 - resolution: "@lerna/prerelease-id-from-version@npm:6.4.1" +"@lerna/prerelease-id-from-version@npm:5.6.2": + version: 5.6.2 + resolution: "@lerna/prerelease-id-from-version@npm:5.6.2" dependencies: semver: ^7.3.4 - checksum: 30a631680a70be1b429d22e66cc104931c05c70211f6273476ec75cb55b0591f9c01d967c81efddb0b285a14a22cce79c3b93fef5b2e31200a560720eb58463d + checksum: 0b48944fc17941061036d7ed93829ca9555897b5073177cb6435cda852da433095df4a76c0b37842788ea5a4536a5300adec2bc23d55daeb8a0b0ca53de16268 languageName: node linkType: hard -"@lerna/profiler@npm:6.4.1": - version: 6.4.1 - resolution: "@lerna/profiler@npm:6.4.1" +"@lerna/profiler@npm:5.6.2": + version: 5.6.2 + resolution: "@lerna/profiler@npm:5.6.2" dependencies: fs-extra: ^9.1.0 npmlog: ^6.0.2 upath: ^2.0.1 - checksum: b12ec9029b8ca6c5bfe5404da0ea5b6dda98c39f5b598ed97615bd6fcc60d64108700a305c89aa862ef5bfa66ef7507dceaca5312b14a006319367e45e24e04d + checksum: a66e0c763b1b0477cdfb0d8c06da0693bf142aaa4cd694022e35a9f7b016126780b685494c862cc3f3a175b14f31f1fc9902f924aa48d1243ad3e41088a661f1 languageName: node linkType: hard -"@lerna/project@npm:6.4.1": - version: 6.4.1 - resolution: "@lerna/project@npm:6.4.1" +"@lerna/project@npm:5.6.2": + version: 5.6.2 + resolution: "@lerna/project@npm:5.6.2" dependencies: - "@lerna/package": 6.4.1 - "@lerna/validation-error": 6.4.1 + "@lerna/package": 5.6.2 + "@lerna/validation-error": 5.6.2 cosmiconfig: ^7.0.0 dedent: ^0.7.0 dot-prop: ^6.0.1 @@ -949,43 +1125,43 @@ __metadata: p-map: ^4.0.0 resolve-from: ^5.0.0 write-json-file: ^4.3.0 - checksum: 4fdeffdcc68dfcc464a73264ead18f4177762d062ce2a166d54dcfb3622516e0c4e1987c859629fc42928ead2d8d2b86e0cf7d876a92fb16b2c528fdcac1624d + checksum: 26ba2daa219bc033fe06770f3f539ca801c96993a7e2e95d0a2ad72646f43746d5efe67e8a407306b2de6ebfa8220c6682b8a6fd72ec4402ce3af21cdec54f20 languageName: node linkType: hard -"@lerna/prompt@npm:6.4.1": - version: 6.4.1 - resolution: "@lerna/prompt@npm:6.4.1" +"@lerna/prompt@npm:5.6.2": + version: 5.6.2 + resolution: "@lerna/prompt@npm:5.6.2" dependencies: inquirer: ^8.2.4 npmlog: ^6.0.2 - checksum: 54728019855b67cb2188cf7ac4fde4231ec0377015acd364786d13380d394f914cfe01466c3146f9d29e316a1aa7aae275aafc56e13c090e76317d005e5c80d8 + checksum: a6f9352f223493d2eeb975f0eeb8981184a6981e2166a49bed792cebd811bf896234bf818b6e8260a6cf2cb2e5e0e26bf3c25475a159dc9b044f3708252b52b8 languageName: node linkType: hard -"@lerna/publish@npm:6.4.1": - version: 6.4.1 - resolution: "@lerna/publish@npm:6.4.1" +"@lerna/publish@npm:5.6.2": + version: 5.6.2 + resolution: "@lerna/publish@npm:5.6.2" dependencies: - "@lerna/check-working-tree": 6.4.1 - "@lerna/child-process": 6.4.1 - "@lerna/collect-updates": 6.4.1 - "@lerna/command": 6.4.1 - "@lerna/describe-ref": 6.4.1 - "@lerna/log-packed": 6.4.1 - "@lerna/npm-conf": 6.4.1 - "@lerna/npm-dist-tag": 6.4.1 - "@lerna/npm-publish": 6.4.1 - "@lerna/otplease": 6.4.1 - "@lerna/output": 6.4.1 - "@lerna/pack-directory": 6.4.1 - "@lerna/prerelease-id-from-version": 6.4.1 - "@lerna/prompt": 6.4.1 - "@lerna/pulse-till-done": 6.4.1 - "@lerna/run-lifecycle": 6.4.1 - "@lerna/run-topologically": 6.4.1 - "@lerna/validation-error": 6.4.1 - "@lerna/version": 6.4.1 + "@lerna/check-working-tree": 5.6.2 + "@lerna/child-process": 5.6.2 + "@lerna/collect-updates": 5.6.2 + "@lerna/command": 5.6.2 + "@lerna/describe-ref": 5.6.2 + "@lerna/log-packed": 5.6.2 + "@lerna/npm-conf": 5.6.2 + "@lerna/npm-dist-tag": 5.6.2 + "@lerna/npm-publish": 5.6.2 + "@lerna/otplease": 5.6.2 + "@lerna/output": 5.6.2 + "@lerna/pack-directory": 5.6.2 + "@lerna/prerelease-id-from-version": 5.6.2 + "@lerna/prompt": 5.6.2 + "@lerna/pulse-till-done": 5.6.2 + "@lerna/run-lifecycle": 5.6.2 + "@lerna/run-topologically": 5.6.2 + "@lerna/validation-error": 5.6.2 + "@lerna/version": 5.6.2 fs-extra: ^9.1.0 libnpmaccess: ^6.0.3 npm-package-arg: 8.1.1 @@ -995,166 +1171,165 @@ __metadata: p-pipe: ^3.1.0 pacote: ^13.6.1 semver: ^7.3.4 - checksum: 69fec3c4e410714ee949b05b4aad496d2386d19a8c0ccb4af3330725b421bb387aa7ca0c6d5a021e3a8a24146ac63c010b9a071301043176088c991ea9a3cd7f + checksum: dce481b6e6ec168e75bc9c08bd075169b299fdf345abebf14029fa717029ddf2fc1464c65653234830807fb881ef0999a0af0f094a143c38865dd9d0dfb74ffd languageName: node linkType: hard -"@lerna/pulse-till-done@npm:6.4.1": - version: 6.4.1 - resolution: "@lerna/pulse-till-done@npm:6.4.1" +"@lerna/pulse-till-done@npm:5.6.2": + version: 5.6.2 + resolution: "@lerna/pulse-till-done@npm:5.6.2" dependencies: npmlog: ^6.0.2 - checksum: 58c0ab4d313e2d2189a9655176f8d5cff4934dc2cfbed71eb0f8e52540f78bcecaa4976356ba59a2ce9293b2b33c72ab0e5338a1c4d168074faf77b059edbde9 + checksum: 923995424e6399947fa752d0eb7b33852e6f77d0c17280c2fef43e757f47f28e07227708bc2ce1d8dc81c8afee2e1509cee1d7c3d08ab8f615498770974f8f0d languageName: node linkType: hard -"@lerna/query-graph@npm:6.4.1": - version: 6.4.1 - resolution: "@lerna/query-graph@npm:6.4.1" +"@lerna/query-graph@npm:5.6.2": + version: 5.6.2 + resolution: "@lerna/query-graph@npm:5.6.2" dependencies: - "@lerna/package-graph": 6.4.1 - checksum: 5b80f0a14f15c222aac91c5c22756e042e9a6395dc5883cb7a6af5924aacbd2b255f93569c5c0cbc1fe3527024b9ab680ec9f32370dde5f23441d219217923cb + "@lerna/package-graph": 5.6.2 + checksum: a582795283760828417e3554ec015c68c815690bb7b29d7cf368a3a9d82f5150b8e6dbf02356cf4e4539b581d9879609876577ec87f3e4cc7a4caf605b2a042d languageName: node linkType: hard -"@lerna/resolve-symlink@npm:6.4.1": - version: 6.4.1 - resolution: "@lerna/resolve-symlink@npm:6.4.1" +"@lerna/resolve-symlink@npm:5.6.2": + version: 5.6.2 + resolution: "@lerna/resolve-symlink@npm:5.6.2" dependencies: fs-extra: ^9.1.0 npmlog: ^6.0.2 read-cmd-shim: ^3.0.0 - checksum: a59eb10fe0a46769d78c0d64f7c0c892f03642a6e6f15a1f2810f93243b0c2ab395c80c536712ad570cb566f25d72dc54c5ea264a17bed1407d12ffda6a87b31 + checksum: 19a95bb295ff9154f3661d36b54abfd5e415c0fb85a669a2fc7b600a180de13877b310d230c7782d8d5441324c5527c311f7a4afef57d6b8be04cbce5cd94927 languageName: node linkType: hard -"@lerna/rimraf-dir@npm:6.4.1": - version: 6.4.1 - resolution: "@lerna/rimraf-dir@npm:6.4.1" +"@lerna/rimraf-dir@npm:5.6.2": + version: 5.6.2 + resolution: "@lerna/rimraf-dir@npm:5.6.2" dependencies: - "@lerna/child-process": 6.4.1 + "@lerna/child-process": 5.6.2 npmlog: ^6.0.2 path-exists: ^4.0.0 rimraf: ^3.0.2 - checksum: d640c51c8d7aae29f847cb05bfe0f106fad538ba0121e04e5e771f6977e5a90608a34d93d0f798a42dd0d91e3a665b00f3aab070bb3088f37c346ad1595368fa + checksum: b0ec7dc69e3caa4c4eae88b8feedf248feff603e50d082a5f363fc0a1f604fc7b76d2067d69c79fdaa20675e3d5a87b59baaab6225c73dc1322b8705ce58030b languageName: node linkType: hard -"@lerna/run-lifecycle@npm:6.4.1": - version: 6.4.1 - resolution: "@lerna/run-lifecycle@npm:6.4.1" +"@lerna/run-lifecycle@npm:5.6.2": + version: 5.6.2 + resolution: "@lerna/run-lifecycle@npm:5.6.2" dependencies: - "@lerna/npm-conf": 6.4.1 + "@lerna/npm-conf": 5.6.2 "@npmcli/run-script": ^4.1.7 npmlog: ^6.0.2 p-queue: ^6.6.2 - checksum: da4fd9e74642310ff6beb35905728cbf00c0ab092561739462af8c1b7c1c0277533c38e01fc23ff5abe43adec016d5b8f559dc05679efcc926543a360c2a6105 + checksum: 3c05af8ddd442a2fba007a41daeac3157dbfe845c3123f106b738843e2615e2a7350c8381622a6b4a793e675340c5671baabef95e6c63398c39b2fcedcafe6fb languageName: node linkType: hard -"@lerna/run-topologically@npm:6.4.1": - version: 6.4.1 - resolution: "@lerna/run-topologically@npm:6.4.1" +"@lerna/run-topologically@npm:5.6.2": + version: 5.6.2 + resolution: "@lerna/run-topologically@npm:5.6.2" dependencies: - "@lerna/query-graph": 6.4.1 + "@lerna/query-graph": 5.6.2 p-queue: ^6.6.2 - checksum: 49a6af44add8962c559e127e3e043f106d356ffeb08259fa08730ee4b22e994c1d7bbf6a20abceda6ba65eee6a3aba0322ca34b4ec19fbd3161d533802800e7f + checksum: d10b59ddff43c0f8387bcd7f9618d135ae6f33ba23d74d9d2fa16cece4209759f8ada46e1050cff07ad82388eda4774a7f0a1690bac4b36ce8f3a23c2718d0d3 languageName: node linkType: hard -"@lerna/run@npm:6.4.1": - version: 6.4.1 - resolution: "@lerna/run@npm:6.4.1" +"@lerna/run@npm:5.6.2": + version: 5.6.2 + resolution: "@lerna/run@npm:5.6.2" dependencies: - "@lerna/command": 6.4.1 - "@lerna/filter-options": 6.4.1 - "@lerna/npm-run-script": 6.4.1 - "@lerna/output": 6.4.1 - "@lerna/profiler": 6.4.1 - "@lerna/run-topologically": 6.4.1 - "@lerna/timer": 6.4.1 - "@lerna/validation-error": 6.4.1 - fs-extra: ^9.1.0 - nx: ">=15.4.2 < 16" - p-map: ^4.0.0 - checksum: e75f9e7c3cae51880590215a9322179688780403dcbf8ba82f381abcd8260fe5072b24abf17bd18cc17156942fdb4f3c4498c865481c5aaeebf7a8b94d8f6175 - languageName: node - linkType: hard - -"@lerna/symlink-binary@npm:6.4.1": - version: 6.4.1 - resolution: "@lerna/symlink-binary@npm:6.4.1" - dependencies: - "@lerna/create-symlink": 6.4.1 - "@lerna/package": 6.4.1 + "@lerna/command": 5.6.2 + "@lerna/filter-options": 5.6.2 + "@lerna/npm-run-script": 5.6.2 + "@lerna/output": 5.6.2 + "@lerna/profiler": 5.6.2 + "@lerna/run-topologically": 5.6.2 + "@lerna/timer": 5.6.2 + "@lerna/validation-error": 5.6.2 fs-extra: ^9.1.0 p-map: ^4.0.0 - checksum: 5154213c2648971ea621af248a2184270ad4652641b6a7e2e5586cd4d5520db4c710ba395a62a22f5aaf381d73764dc141410183188676a305cb938750c8fd36 + checksum: a3ed53fea86b2b80d0c95aa2a9f007e524cde35422ebad312e21adaeae8564475f3d2a5ab40612ab8be1bfe8e935b61115808833e3e281ab93240f1b38b7d69a languageName: node linkType: hard -"@lerna/symlink-dependencies@npm:6.4.1": - version: 6.4.1 - resolution: "@lerna/symlink-dependencies@npm:6.4.1" +"@lerna/symlink-binary@npm:5.6.2": + version: 5.6.2 + resolution: "@lerna/symlink-binary@npm:5.6.2" dependencies: - "@lerna/create-symlink": 6.4.1 - "@lerna/resolve-symlink": 6.4.1 - "@lerna/symlink-binary": 6.4.1 + "@lerna/create-symlink": 5.6.2 + "@lerna/package": 5.6.2 + fs-extra: ^9.1.0 + p-map: ^4.0.0 + checksum: f4d633677cde5b27e580c064ffca60b46be6808afcab5bd327e3c4e4d0cb7a924d79d5022f87f1e2209014687c75cb7c59d8514cab3911f4e14a5b5bbbf96fec + languageName: node + linkType: hard + +"@lerna/symlink-dependencies@npm:5.6.2": + version: 5.6.2 + resolution: "@lerna/symlink-dependencies@npm:5.6.2" + dependencies: + "@lerna/create-symlink": 5.6.2 + "@lerna/resolve-symlink": 5.6.2 + "@lerna/symlink-binary": 5.6.2 fs-extra: ^9.1.0 p-map: ^4.0.0 p-map-series: ^2.1.0 - checksum: 49e66aaa38627744364c7b40a89306e2bf9cd6ca995835a85f8cf03f92d3f95057c3bf9d7b83c6651dcf7508238bf25780af4b6eba1cea11ec84adfe0bcb1ff5 + checksum: f1de8b38288f42647a0c663b8d6c701bf80acadaaf566830f736d3aae4b9f6dc0bac2fb3a771a266c62bcc72dd3b02b9ab5c2b4ccba40ad9e91894c08a168df8 languageName: node linkType: hard -"@lerna/temp-write@npm:6.4.1": - version: 6.4.1 - resolution: "@lerna/temp-write@npm:6.4.1" +"@lerna/temp-write@npm:5.6.2": + version: 5.6.2 + resolution: "@lerna/temp-write@npm:5.6.2" dependencies: graceful-fs: ^4.1.15 is-stream: ^2.0.0 make-dir: ^3.0.0 temp-dir: ^1.0.0 uuid: ^8.3.2 - checksum: 03ae6ea14fd821e5559c05f54a53daed1e9d8732d067f916b2f0998b85e5dcab924995f4441becc9c3acd0b107381b963d868ac5f1b64bb2da9a4f17a03c04b8 + checksum: 9a3ef13e08230a88de046aaaba0efdc2b5e27f16abd97af03b395bc2cf40ec52d8b6850d25a913b955046f52013c4a99b3e75a48397356d0a9a86b0f97afa905 languageName: node linkType: hard -"@lerna/timer@npm:6.4.1": - version: 6.4.1 - resolution: "@lerna/timer@npm:6.4.1" - checksum: 6be5c7796db819b21dfc9f697304013185d38ad6e516be872176ae1b398358334fb1fb414fe027459f4b90a88a1ef052dec624b7f5acc732fea652ea0646f265 +"@lerna/timer@npm:5.6.2": + version: 5.6.2 + resolution: "@lerna/timer@npm:5.6.2" + checksum: 3eb43f371f5e357a42ec0a69722b13feff3967c88057334562366ffae40ce5ee7750718a498037e1f0ab9d438274357c4033561f068a76b1a6f98861a5eeae0c languageName: node linkType: hard -"@lerna/validation-error@npm:6.4.1": - version: 6.4.1 - resolution: "@lerna/validation-error@npm:6.4.1" +"@lerna/validation-error@npm:5.6.2": + version: 5.6.2 + resolution: "@lerna/validation-error@npm:5.6.2" dependencies: npmlog: ^6.0.2 - checksum: 1cc0000599ba69ffa32825e7cb28ea719ea5f0de61daf8e9fac7724f7bc0d9b7766ae8ba634f7864b757c26eef3e1b8f2f63633fb9a68ec938440e3ece146e3e + checksum: 3871cbacc7668ab2b0498f3d394ea65fa721257402cffa89efb97f6bed89d11504f554d25007d079e679181bcbbf773432745733654f8415e901c7d08a6ae06b languageName: node linkType: hard -"@lerna/version@npm:6.4.1": - version: 6.4.1 - resolution: "@lerna/version@npm:6.4.1" +"@lerna/version@npm:5.6.2": + version: 5.6.2 + resolution: "@lerna/version@npm:5.6.2" dependencies: - "@lerna/check-working-tree": 6.4.1 - "@lerna/child-process": 6.4.1 - "@lerna/collect-updates": 6.4.1 - "@lerna/command": 6.4.1 - "@lerna/conventional-commits": 6.4.1 - "@lerna/github-client": 6.4.1 - "@lerna/gitlab-client": 6.4.1 - "@lerna/output": 6.4.1 - "@lerna/prerelease-id-from-version": 6.4.1 - "@lerna/prompt": 6.4.1 - "@lerna/run-lifecycle": 6.4.1 - "@lerna/run-topologically": 6.4.1 - "@lerna/temp-write": 6.4.1 - "@lerna/validation-error": 6.4.1 - "@nrwl/devkit": ">=15.4.2 < 16" + "@lerna/check-working-tree": 5.6.2 + "@lerna/child-process": 5.6.2 + "@lerna/collect-updates": 5.6.2 + "@lerna/command": 5.6.2 + "@lerna/conventional-commits": 5.6.2 + "@lerna/github-client": 5.6.2 + "@lerna/gitlab-client": 5.6.2 + "@lerna/output": 5.6.2 + "@lerna/prerelease-id-from-version": 5.6.2 + "@lerna/prompt": 5.6.2 + "@lerna/run-lifecycle": 5.6.2 + "@lerna/run-topologically": 5.6.2 + "@lerna/temp-write": 5.6.2 + "@lerna/validation-error": 5.6.2 + "@nrwl/devkit": ">=14.8.1 < 16" chalk: ^4.1.0 dedent: ^0.7.0 load-json-file: ^6.2.0 @@ -1167,48 +1342,53 @@ __metadata: semver: ^7.3.4 slash: ^3.0.0 write-json-file: ^4.3.0 - checksum: c560e8ca018f808f1ac81a0c361afae9d7f4fbd86a0816284bb2bb9bd52af08b20d12918c0dc93cb04abf4945b632ca66a7cae4b4137c0717f434922121b987d + checksum: da0e0b822af685b0553dac95aa1355b5bfb9abde208d1afcc1a0e38134c49e7d3dc1430d0c951ffad236032bba5c242025754494dd6ceb5ad913f3cc8b9113b3 languageName: node linkType: hard -"@lerna/write-log-file@npm:6.4.1": - version: 6.4.1 - resolution: "@lerna/write-log-file@npm:6.4.1" +"@lerna/write-log-file@npm:5.6.2": + version: 5.6.2 + resolution: "@lerna/write-log-file@npm:5.6.2" dependencies: npmlog: ^6.0.2 write-file-atomic: ^4.0.1 - checksum: 27c934ad5bf5fa030dfcd4b85ab464954609913e55be8ac2a026a295352fbab65c3ef9855d6f963c16e344a8befc9fa2cca54272a471626030c0f4888c0c2f7b + checksum: 814e9cf20ac28be49b22720be7bef8f708b28c344d54a0664cb8c44bbcb11387c4f89abf1050cfc81b41fa770099c748ac97fdb99d8a016c9e2c3ca801f27a30 languageName: node linkType: hard -"@napi-rs/cli@workspace:cli": +"@napi-rs/cli@workspace:*, @napi-rs/cli@workspace:cli": version: 0.0.0-use.local resolution: "@napi-rs/cli@workspace:cli" dependencies: - "@octokit/rest": ^19.0.5 + "@octokit/rest": ^19.0.7 "@types/inquirer": ^9.0.3 "@types/js-yaml": ^4.0.5 "@types/lodash-es": ^4.17.6 - clipanion: ^3.1.0 + ava: ^5.2.0 + clipanion: ^3.2.0 colorette: ^2.0.19 - core-js: ^3.27.1 debug: ^4.3.4 - env-paths: ^3.0.0 - fdir: ^5.3.0 - inquirer: ^9.1.4 + esbuild: ^0.17.14 + inquirer: ^9.1.5 js-yaml: ^4.1.0 - lodash-es: 4.17.21 - toml: ^3.0.0 - tslib: ^2.4.1 + lodash-es: ^4.17.21 + prettier: ^2.8.7 + ts-node: ^10.9.1 typanion: ^3.12.1 + typescript: ^4.9.4 bin: - napi: ./scripts/index.js + napi: ./dist/cli.js + napi-raw: ./cli.mjs languageName: unknown linkType: soft "@napi-rs/triples@workspace:triples": version: 0.0.0-use.local resolution: "@napi-rs/triples@workspace:triples" + dependencies: + lodash-es: ^4.17.21 + ts-node: ^10.9.1 + typescript: ^4.9.4 languageName: unknown linkType: soft @@ -1401,18 +1581,18 @@ __metadata: languageName: node linkType: hard -"@nrwl/cli@npm:15.5.2": - version: 15.5.2 - resolution: "@nrwl/cli@npm:15.5.2" +"@nrwl/cli@npm:15.7.2": + version: 15.7.2 + resolution: "@nrwl/cli@npm:15.7.2" dependencies: - nx: 15.5.2 - checksum: 6a7b86fe2ea58d67b0a5ee545ccd05e1df9d251293aa55736690696b82496e45033f8c93c7ccb822c028f70e35ef661f5492522fc7ef88968886cf3bab6a6ab0 + nx: 15.7.2 + checksum: c59130679458e1572181d8b49ff3a755bba4e07f8fe9a4c0b20330a16105548381467c557a4f3dd09051cf6ae8bcea15c3f2ccd2dba9ad6d0dfec79de0b61b49 languageName: node linkType: hard -"@nrwl/devkit@npm:>=15.4.2 < 16": - version: 15.5.2 - resolution: "@nrwl/devkit@npm:15.5.2" +"@nrwl/devkit@npm:>=14.8.1 < 16": + version: 15.7.2 + resolution: "@nrwl/devkit@npm:15.7.2" dependencies: "@phenomnomnominal/tsquery": 4.1.1 ejs: ^3.1.7 @@ -1420,19 +1600,82 @@ __metadata: semver: 7.3.4 tslib: ^2.3.0 peerDependencies: - nx: ">= 14 <= 16" - checksum: 56daaaae7384ede0b1b04d32aa27acbe5ee74ad8f343ede8131c95bb9551470b0a208cb8da2125b2ae9d52656cc9907492ea31defad8a9ccfd3a87f6057d9241 + nx: ">= 14.1 <= 16" + checksum: a6f78a1374e91c183a71fb3cb81bfc8fe0d21e18d2bd7b20d01777fd31d155c16dce5944ed2146514761a3960683842f137fc5a22975403d515c32fc753c0a1f languageName: node linkType: hard -"@nrwl/tao@npm:15.5.2": - version: 15.5.2 - resolution: "@nrwl/tao@npm:15.5.2" +"@nrwl/nx-darwin-arm64@npm:15.7.2": + version: 15.7.2 + resolution: "@nrwl/nx-darwin-arm64@npm:15.7.2" + conditions: os=darwin & cpu=arm64 + languageName: node + linkType: hard + +"@nrwl/nx-darwin-x64@npm:15.7.2": + version: 15.7.2 + resolution: "@nrwl/nx-darwin-x64@npm:15.7.2" + conditions: os=darwin & cpu=x64 + languageName: node + linkType: hard + +"@nrwl/nx-linux-arm-gnueabihf@npm:15.7.2": + version: 15.7.2 + resolution: "@nrwl/nx-linux-arm-gnueabihf@npm:15.7.2" + conditions: os=linux & cpu=arm + languageName: node + linkType: hard + +"@nrwl/nx-linux-arm64-gnu@npm:15.7.2": + version: 15.7.2 + resolution: "@nrwl/nx-linux-arm64-gnu@npm:15.7.2" + conditions: os=linux & cpu=arm64 & libc=glibc + languageName: node + linkType: hard + +"@nrwl/nx-linux-arm64-musl@npm:15.7.2": + version: 15.7.2 + resolution: "@nrwl/nx-linux-arm64-musl@npm:15.7.2" + conditions: os=linux & cpu=arm64 & libc=musl + languageName: node + linkType: hard + +"@nrwl/nx-linux-x64-gnu@npm:15.7.2": + version: 15.7.2 + resolution: "@nrwl/nx-linux-x64-gnu@npm:15.7.2" + conditions: os=linux & cpu=x64 & libc=glibc + languageName: node + linkType: hard + +"@nrwl/nx-linux-x64-musl@npm:15.7.2": + version: 15.7.2 + resolution: "@nrwl/nx-linux-x64-musl@npm:15.7.2" + conditions: os=linux & cpu=x64 & libc=musl + languageName: node + linkType: hard + +"@nrwl/nx-win32-arm64-msvc@npm:15.7.2": + version: 15.7.2 + resolution: "@nrwl/nx-win32-arm64-msvc@npm:15.7.2" + conditions: os=win32 & cpu=arm64 + languageName: node + linkType: hard + +"@nrwl/nx-win32-x64-msvc@npm:15.7.2": + version: 15.7.2 + resolution: "@nrwl/nx-win32-x64-msvc@npm:15.7.2" + conditions: os=win32 & cpu=x64 + languageName: node + linkType: hard + +"@nrwl/tao@npm:15.7.2": + version: 15.7.2 + resolution: "@nrwl/tao@npm:15.7.2" dependencies: - nx: 15.5.2 + nx: 15.7.2 bin: tao: index.js - checksum: df9b47e961b90278fdce9f2bbdd6cd232120fc1f2325308ae0404de4f3fa60ea0d02fe1d05e4cc84fb277fa5c5ee77d2f71767409fc31e29b4b8d342027092ed + checksum: cbf76f385bffb1bf1bde52d4ad950a8abd1ba9865f47afb67a58bb5dc5d7be0d21c5021a3332d2ab665d99b36ec1f08ee260c1289bb7e69783e69712145d2709 languageName: node linkType: hard @@ -1489,6 +1732,13 @@ __metadata: languageName: node linkType: hard +"@octokit/openapi-types@npm:^16.0.0": + version: 16.0.0 + resolution: "@octokit/openapi-types@npm:16.0.0" + checksum: 844f30a545da380d63c712e0eb733366bc567d1aab34529c79fdfbec3d73810e81d83f06fdab13058a5cbc7dae786db1a9b90b5b61b1e606854ee45d5ec5f194 + languageName: node + linkType: hard + "@octokit/plugin-enterprise-rest@npm:^6.0.1": version: 6.0.1 resolution: "@octokit/plugin-enterprise-rest@npm:6.0.1" @@ -1507,6 +1757,17 @@ __metadata: languageName: node linkType: hard +"@octokit/plugin-paginate-rest@npm:^6.0.0": + version: 6.0.0 + resolution: "@octokit/plugin-paginate-rest@npm:6.0.0" + dependencies: + "@octokit/types": ^9.0.0 + peerDependencies: + "@octokit/core": ">=4" + checksum: 4ad89568d883373898b733837cada7d849d51eef32157c11d4a81cef5ce8e509720d79b46918cada3c132f9b29847e383f17b7cd5c39ede7c93cdcd2f850b47f + languageName: node + linkType: hard + "@octokit/plugin-request-log@npm:^1.0.4": version: 1.0.4 resolution: "@octokit/plugin-request-log@npm:1.0.4" @@ -1528,6 +1789,18 @@ __metadata: languageName: node linkType: hard +"@octokit/plugin-rest-endpoint-methods@npm:^7.0.0": + version: 7.0.1 + resolution: "@octokit/plugin-rest-endpoint-methods@npm:7.0.1" + dependencies: + "@octokit/types": ^9.0.0 + deprecation: ^2.3.1 + peerDependencies: + "@octokit/core": ">=3" + checksum: cdb8734ec960f75acc2405284920c58efac9a71b1c3b2a71662b9100ffbc22dac597150acff017a93459c57e9a492d9e1c27872b068387dbb90597de75065fcf + languageName: node + linkType: hard + "@octokit/request-error@npm:^3.0.0": version: 3.0.2 resolution: "@octokit/request-error@npm:3.0.2" @@ -1553,7 +1826,7 @@ __metadata: languageName: node linkType: hard -"@octokit/rest@npm:^19.0.3, @octokit/rest@npm:^19.0.5": +"@octokit/rest@npm:^19.0.3": version: 19.0.5 resolution: "@octokit/rest@npm:19.0.5" dependencies: @@ -1565,6 +1838,18 @@ __metadata: languageName: node linkType: hard +"@octokit/rest@npm:^19.0.7": + version: 19.0.7 + resolution: "@octokit/rest@npm:19.0.7" + dependencies: + "@octokit/core": ^4.1.0 + "@octokit/plugin-paginate-rest": ^6.0.0 + "@octokit/plugin-request-log": ^1.0.4 + "@octokit/plugin-rest-endpoint-methods": ^7.0.0 + checksum: 1f970c4de2cf3d1691d3cf5dd4bfa5ac205629e76417b5c51561e1beb5b4a7e6c65ba647f368727e67e5243418e06ca9cdafd9e733173e1529385d4f4d053d3d + languageName: node + linkType: hard + "@octokit/types@npm:^8.0.0": version: 8.1.1 resolution: "@octokit/types@npm:8.1.1" @@ -1574,6 +1859,15 @@ __metadata: languageName: node linkType: hard +"@octokit/types@npm:^9.0.0": + version: 9.0.0 + resolution: "@octokit/types@npm:9.0.0" + dependencies: + "@octokit/openapi-types": ^16.0.0 + checksum: 5c7f5cca8f00f7c4daa0d00f4fe991c1598ec47cd6ced50b1c5fbe9721bb9dee0adc2acdee265a3a715bb984e53ef3dc7f1cfb7326f712c6d809d59fc5c6648d + languageName: node + linkType: hard + "@parcel/watcher@npm:2.0.4": version: 2.0.4 resolution: "@parcel/watcher@npm:2.0.4" @@ -2596,6 +2890,66 @@ __metadata: languageName: node linkType: hard +"ava@npm:^5.2.0": + version: 5.2.0 + resolution: "ava@npm:5.2.0" + dependencies: + acorn: ^8.8.1 + acorn-walk: ^8.2.0 + ansi-styles: ^6.2.1 + arrgv: ^1.0.2 + arrify: ^3.0.0 + callsites: ^4.0.0 + cbor: ^8.1.0 + chalk: ^5.2.0 + chokidar: ^3.5.3 + chunkd: ^2.0.1 + ci-info: ^3.7.1 + ci-parallel-vars: ^1.0.1 + clean-yaml-object: ^0.1.0 + cli-truncate: ^3.1.0 + code-excerpt: ^4.0.0 + common-path-prefix: ^3.0.0 + concordance: ^5.0.4 + currently-unhandled: ^0.4.1 + debug: ^4.3.4 + del: ^7.0.0 + emittery: ^1.0.1 + figures: ^5.0.0 + globby: ^13.1.3 + ignore-by-default: ^2.1.0 + indent-string: ^5.0.0 + is-error: ^2.2.2 + is-plain-object: ^5.0.0 + is-promise: ^4.0.0 + matcher: ^5.0.0 + mem: ^9.0.2 + ms: ^2.1.3 + p-event: ^5.0.1 + p-map: ^5.5.0 + picomatch: ^2.3.1 + pkg-conf: ^4.0.0 + plur: ^5.1.0 + pretty-ms: ^8.0.0 + resolve-cwd: ^3.0.0 + slash: ^3.0.0 + stack-utils: ^2.0.6 + strip-ansi: ^7.0.1 + supertap: ^3.0.1 + temp-dir: ^3.0.0 + write-file-atomic: ^5.0.0 + yargs: ^17.6.2 + peerDependencies: + "@ava/typescript": "*" + peerDependenciesMeta: + "@ava/typescript": + optional: true + bin: + ava: entrypoints/cli.mjs + checksum: d5991f1f3d7ca0e63e0df185c5c025a9c80614dd42537336a9b96ea29e8a8d5ad680c1e775dacabb55f3b1b2d63764e468f201d52a44166c8a88d4e9309cde61 + languageName: node + linkType: hard + "available-typed-arrays@npm:^1.0.5": version: 1.0.5 resolution: "available-typed-arrays@npm:1.0.5" @@ -2648,6 +3002,7 @@ __metadata: version: 0.0.0-use.local resolution: "bench@workspace:bench" dependencies: + "@napi-rs/cli": "workspace:*" benny: ^3.7.1 languageName: unknown linkType: soft @@ -2703,6 +3058,8 @@ __metadata: "binary@workspace:examples/binary": version: 0.0.0-use.local resolution: "binary@workspace:examples/binary" + dependencies: + "@napi-rs/cli": "workspace:*" bin: binary: napi-examples-binary languageName: unknown @@ -2985,7 +3342,7 @@ __metadata: languageName: node linkType: hard -"chalk@npm:^5.0.0, chalk@npm:^5.1.2, chalk@npm:^5.2.0": +"chalk@npm:^5.0.0, chalk@npm:^5.2.0": version: 5.2.0 resolution: "chalk@npm:5.2.0" checksum: 03d8060277de6cf2fd567dc25fcf770593eb5bb85f460ce443e49255a30ff1242edd0c90a06a03803b0466ff0687a939b41db1757bec987113e83de89a003caa @@ -3149,14 +3506,14 @@ __metadata: languageName: node linkType: hard -"clipanion@npm:^3.1.0": - version: 3.1.0 - resolution: "clipanion@npm:3.1.0" +"clipanion@npm:^3.2.0": + version: 3.2.0 + resolution: "clipanion@npm:3.2.0" dependencies: - typanion: ^3.3.1 + typanion: ^3.8.0 peerDependencies: typanion: "*" - checksum: bf350082e8953c697cfe35262845700012bdeb1cc490f81cd17de2fe985c8861750164509795ad95d3ee6a2b3742a1d5c6394cdf0f3ff4c4d24173a9fec3418e + checksum: e28e6f0d48aecff86097823c604aa486082d76d2a5d3abc71069a0d9f3338af769fd7c6634b2f444c5b1aac0743b503325cc0b30552c094c01ebc602631b273d languageName: node linkType: hard @@ -3346,14 +3703,6 @@ __metadata: languageName: node linkType: hard -"compat-mode-examples@workspace:examples/napi-compat-mode": - version: 0.0.0-use.local - resolution: "compat-mode-examples@workspace:examples/napi-compat-mode" - dependencies: - sinon: ^15.0.1 - languageName: unknown - linkType: soft - "concat-map@npm:0.0.1": version: 0.0.1 resolution: "concat-map@npm:0.0.1" @@ -3522,13 +3871,6 @@ __metadata: languageName: node linkType: hard -"core-js@npm:^3.27.1": - version: 3.27.1 - resolution: "core-js@npm:3.27.1" - checksum: d50b5f88aea4302512ad9446c18e90f4d35dea1e6d8d3f87337690677061565ff11a670f1e0c87de57aa6074375fbb25ed5784076c040d3c4de8b4bce7d2ebeb - languageName: node - linkType: hard - "core-util-is@npm:~1.0.0": version: 1.0.3 resolution: "core-util-is@npm:1.0.3" @@ -4000,13 +4342,6 @@ __metadata: languageName: node linkType: hard -"env-paths@npm:^3.0.0": - version: 3.0.0 - resolution: "env-paths@npm:3.0.0" - checksum: b2b0a0d0d9931a13d279c22ed94d78648a1cc5f408f05d47ff3e0c1616f0aa0c38fb33deec5e5be50497225d500607d57f9c8652c4d39c2f2b7608cd45768128 - languageName: node - linkType: hard - "envinfo@npm:^7.7.4": version: 7.8.1 resolution: "envinfo@npm:7.8.1" @@ -4111,6 +4446,83 @@ __metadata: languageName: node linkType: hard +"esbuild@npm:^0.17.14": + version: 0.17.14 + resolution: "esbuild@npm:0.17.14" + dependencies: + "@esbuild/android-arm": 0.17.14 + "@esbuild/android-arm64": 0.17.14 + "@esbuild/android-x64": 0.17.14 + "@esbuild/darwin-arm64": 0.17.14 + "@esbuild/darwin-x64": 0.17.14 + "@esbuild/freebsd-arm64": 0.17.14 + "@esbuild/freebsd-x64": 0.17.14 + "@esbuild/linux-arm": 0.17.14 + "@esbuild/linux-arm64": 0.17.14 + "@esbuild/linux-ia32": 0.17.14 + "@esbuild/linux-loong64": 0.17.14 + "@esbuild/linux-mips64el": 0.17.14 + "@esbuild/linux-ppc64": 0.17.14 + "@esbuild/linux-riscv64": 0.17.14 + "@esbuild/linux-s390x": 0.17.14 + "@esbuild/linux-x64": 0.17.14 + "@esbuild/netbsd-x64": 0.17.14 + "@esbuild/openbsd-x64": 0.17.14 + "@esbuild/sunos-x64": 0.17.14 + "@esbuild/win32-arm64": 0.17.14 + "@esbuild/win32-ia32": 0.17.14 + "@esbuild/win32-x64": 0.17.14 + dependenciesMeta: + "@esbuild/android-arm": + optional: true + "@esbuild/android-arm64": + optional: true + "@esbuild/android-x64": + optional: true + "@esbuild/darwin-arm64": + optional: true + "@esbuild/darwin-x64": + optional: true + "@esbuild/freebsd-arm64": + optional: true + "@esbuild/freebsd-x64": + optional: true + "@esbuild/linux-arm": + optional: true + "@esbuild/linux-arm64": + optional: true + "@esbuild/linux-ia32": + optional: true + "@esbuild/linux-loong64": + optional: true + "@esbuild/linux-mips64el": + optional: true + "@esbuild/linux-ppc64": + optional: true + "@esbuild/linux-riscv64": + optional: true + "@esbuild/linux-s390x": + optional: true + "@esbuild/linux-x64": + optional: true + "@esbuild/netbsd-x64": + optional: true + "@esbuild/openbsd-x64": + optional: true + "@esbuild/sunos-x64": + optional: true + "@esbuild/win32-arm64": + optional: true + "@esbuild/win32-ia32": + optional: true + "@esbuild/win32-x64": + optional: true + bin: + esbuild: bin/esbuild + checksum: 8f4c05f5d3da04f05c48d65f60f3c6422253f406cd56a7ab7a898f0971b0366c454635a6340172874950771dc005a9928dd999b732a6d4caa504b537bfcbf2ff + languageName: node + linkType: hard + "esbuild@npm:^0.17.2": version: 0.17.2 resolution: "esbuild@npm:0.17.2" @@ -4465,16 +4877,6 @@ __metadata: languageName: node linkType: hard -"examples@workspace:examples/napi": - version: 0.0.0-use.local - resolution: "examples@workspace:examples/napi" - dependencies: - "@types/lodash": ^4.14.191 - lodash: ^4.17.21 - sinon: ^15.0.1 - languageName: unknown - linkType: soft - "execa@npm:^5.0.0": version: 5.1.1 resolution: "execa@npm:5.1.1" @@ -4609,18 +5011,6 @@ __metadata: languageName: node linkType: hard -"fdir@npm:^5.3.0": - version: 5.3.0 - resolution: "fdir@npm:5.3.0" - peerDependencies: - picomatch: 2.x - peerDependenciesMeta: - picomatch: - optional: true - checksum: decf21f93c8a32d5b1f2cabc197ff9e97da75d3b9b3d2bc2afaae0aa693c99c42592789a37168010ea720e43590e984deee46397632f457ac459cbb7149a1245 - languageName: node - linkType: hard - "figures@npm:3.2.0, figures@npm:^3.0.0": version: 3.2.0 resolution: "figures@npm:3.2.0" @@ -5387,7 +5777,7 @@ __metadata: languageName: node linkType: hard -"husky@npm:^8.0.3": +"husky@npm:^8.0.1": version: 8.0.3 resolution: "husky@npm:8.0.3" bin: @@ -5556,26 +5946,26 @@ __metadata: languageName: node linkType: hard -"inquirer@npm:^9.1.4": - version: 9.1.4 - resolution: "inquirer@npm:9.1.4" +"inquirer@npm:^9.1.5": + version: 9.1.5 + resolution: "inquirer@npm:9.1.5" dependencies: ansi-escapes: ^6.0.0 - chalk: ^5.1.2 + chalk: ^5.2.0 cli-cursor: ^4.0.0 cli-width: ^4.0.0 external-editor: ^3.0.3 figures: ^5.0.0 lodash: ^4.17.21 - mute-stream: 0.0.8 + mute-stream: 1.0.0 ora: ^6.1.2 run-async: ^2.4.0 - rxjs: ^7.5.7 + rxjs: ^7.8.0 string-width: ^5.1.2 strip-ansi: ^7.0.1 through: ^2.3.6 - wrap-ansi: ^8.0.1 - checksum: b9acb56dfc01fdc3aac5997260b9c88b84893e270254cb67a8bef8d074d2deeea500963e69247510f1790a6b656b0a11e981441d084ce6d906e7e2a7c5441aa2 + wrap-ansi: ^8.1.0 + checksum: 8491fad532c781041abca63605505ddb4bfeaf6547c8a68aa3e9f5a72dec627e1f222d3dbb082dc741cbb031394c6ae3ca0c3d7d0ffde5087f235939996e63e5 languageName: node linkType: hard @@ -6280,38 +6670,36 @@ __metadata: languageName: node linkType: hard -"lerna@npm:^6.4.1": - version: 6.4.1 - resolution: "lerna@npm:6.4.1" +"lerna@npm:^5.1.6": + version: 5.6.2 + resolution: "lerna@npm:5.6.2" dependencies: - "@lerna/add": 6.4.1 - "@lerna/bootstrap": 6.4.1 - "@lerna/changed": 6.4.1 - "@lerna/clean": 6.4.1 - "@lerna/cli": 6.4.1 - "@lerna/command": 6.4.1 - "@lerna/create": 6.4.1 - "@lerna/diff": 6.4.1 - "@lerna/exec": 6.4.1 - "@lerna/filter-options": 6.4.1 - "@lerna/import": 6.4.1 - "@lerna/info": 6.4.1 - "@lerna/init": 6.4.1 - "@lerna/link": 6.4.1 - "@lerna/list": 6.4.1 - "@lerna/publish": 6.4.1 - "@lerna/run": 6.4.1 - "@lerna/validation-error": 6.4.1 - "@lerna/version": 6.4.1 - "@nrwl/devkit": ">=15.4.2 < 16" + "@lerna/add": 5.6.2 + "@lerna/bootstrap": 5.6.2 + "@lerna/changed": 5.6.2 + "@lerna/clean": 5.6.2 + "@lerna/cli": 5.6.2 + "@lerna/command": 5.6.2 + "@lerna/create": 5.6.2 + "@lerna/diff": 5.6.2 + "@lerna/exec": 5.6.2 + "@lerna/import": 5.6.2 + "@lerna/info": 5.6.2 + "@lerna/init": 5.6.2 + "@lerna/link": 5.6.2 + "@lerna/list": 5.6.2 + "@lerna/publish": 5.6.2 + "@lerna/run": 5.6.2 + "@lerna/version": 5.6.2 + "@nrwl/devkit": ">=14.8.1 < 16" import-local: ^3.0.2 inquirer: ^8.2.4 npmlog: ^6.0.2 - nx: ">=15.4.2 < 16" + nx: ">=14.8.1 < 16" typescript: ^3 || ^4 bin: lerna: cli.js - checksum: 30773a9413f4cac596350a184e183bdce8011637695fcdaf2b5312dbe6f461394df5854cf331dc14fe5d635fc039000ac79690d06fdf58103bfce1bdb1d634f9 + checksum: 5e06ac9f1e47e414231aa9d9e6a74f6ea7eef62e0110941b1ac1a73635cfaaae3802047e16c33c9682f5932e72653b959b2895cc49da334afbae51ff718baca3 languageName: node linkType: hard @@ -6371,9 +6759,9 @@ __metadata: languageName: node linkType: hard -"lint-staged@npm:^13.1.0": - version: 13.1.0 - resolution: "lint-staged@npm:13.1.0" +"lint-staged@npm:^13.0.3": + version: 13.1.2 + resolution: "lint-staged@npm:13.1.2" dependencies: cli-truncate: ^3.1.0 colorette: ^2.0.19 @@ -6390,7 +6778,7 @@ __metadata: yaml: ^2.1.3 bin: lint-staged: bin/lint-staged.js - checksum: adf20c4ca9285c4a93b06598b970d71b04cfe58a1a4c9006f753b83e02c1c622d1866c32a4f1e7e29a98091c501eac3345f7678af247b4f97d5be88b3d8727c1 + checksum: f854ad5c88542b8f06e27f3b4046927a4f3d4a451a04e079526559d819a325762268f65bd2df7156bcc0cb5f531f621c42cdb824b403f537c78305adc9e56a54 languageName: node linkType: hard @@ -6483,7 +6871,7 @@ __metadata: languageName: node linkType: hard -"lodash-es@npm:4.17.21": +"lodash-es@npm:^4.17.21": version: 4.17.21 resolution: "lodash-es@npm:4.17.21" checksum: 05cbffad6e2adbb331a4e16fbd826e7faee403a1a04873b82b42c0f22090f280839f85b95393f487c1303c8a3d2a010048bf06151a6cbe03eee4d388fb0a12d2 @@ -6703,6 +7091,7 @@ __metadata: version: 0.0.0-use.local resolution: "memory-testing@workspace:memory-testing" dependencies: + "@napi-rs/cli": "workspace:*" "@types/dockerode": ^3.3.14 colorette: ^2.0.19 dockerode: ^3.3.4 @@ -7014,6 +7403,13 @@ __metadata: languageName: node linkType: hard +"mute-stream@npm:1.0.0": + version: 1.0.0 + resolution: "mute-stream@npm:1.0.0" + checksum: 36fc968b0e9c9c63029d4f9dc63911950a3bdf55c9a87f58d3a266289b67180201cade911e7699f8b2fa596b34c9db43dad37649e3f7fdd13c3bb9edb0017ee7 + languageName: node + linkType: hard + "nan@npm:^2.15.0, nan@npm:^2.16.0": version: 2.17.0 resolution: "nan@npm:2.17.0" @@ -7027,6 +7423,7 @@ __metadata: version: 0.0.0-use.local resolution: "napi-rs@workspace:." dependencies: + "@napi-rs/cli": "workspace:*" "@rollup/plugin-alias": ^4.0.2 "@rollup/plugin-commonjs": ^24.0.0 "@rollup/plugin-json": ^6.0.0 @@ -7040,9 +7437,7 @@ __metadata: "@typescript-eslint/eslint-plugin": ^5.48.2 "@typescript-eslint/parser": ^5.48.2 ava: ^5.1.1 - benny: ^3.7.1 c8: ^7.12.0 - colorette: ^2.0.19 cross-env: ^7.0.3 electron: 22.0.3 esbuild: ^0.17.2 @@ -7050,12 +7445,11 @@ __metadata: eslint-config-prettier: ^8.6.0 eslint-plugin-import: ^2.27.5 eslint-plugin-prettier: ^4.2.1 - husky: ^8.0.3 - lerna: ^6.4.1 - lint-staged: ^13.1.0 + husky: ^8.0.1 + lerna: ^5.1.6 + lint-staged: ^13.0.3 npm-run-all: ^4.1.5 prettier: ^2.8.3 - rollup: ^3.10.0 shx: ^0.3.4 sinon: ^15.0.1 source-map-support: ^0.5.21 @@ -7402,12 +7796,21 @@ __metadata: languageName: node linkType: hard -"nx@npm:15.5.2, nx@npm:>=15.4.2 < 16": - version: 15.5.2 - resolution: "nx@npm:15.5.2" +"nx@npm:15.7.2, nx@npm:>=14.8.1 < 16": + version: 15.7.2 + resolution: "nx@npm:15.7.2" dependencies: - "@nrwl/cli": 15.5.2 - "@nrwl/tao": 15.5.2 + "@nrwl/cli": 15.7.2 + "@nrwl/nx-darwin-arm64": 15.7.2 + "@nrwl/nx-darwin-x64": 15.7.2 + "@nrwl/nx-linux-arm-gnueabihf": 15.7.2 + "@nrwl/nx-linux-arm64-gnu": 15.7.2 + "@nrwl/nx-linux-arm64-musl": 15.7.2 + "@nrwl/nx-linux-x64-gnu": 15.7.2 + "@nrwl/nx-linux-x64-musl": 15.7.2 + "@nrwl/nx-win32-arm64-msvc": 15.7.2 + "@nrwl/nx-win32-x64-msvc": 15.7.2 + "@nrwl/tao": 15.7.2 "@parcel/watcher": 2.0.4 "@yarnpkg/lockfile": ^1.1.0 "@yarnpkg/parsers": ^3.0.0-rc.18 @@ -7444,6 +7847,25 @@ __metadata: peerDependencies: "@swc-node/register": ^1.4.2 "@swc/core": ^1.2.173 + dependenciesMeta: + "@nrwl/nx-darwin-arm64": + optional: true + "@nrwl/nx-darwin-x64": + optional: true + "@nrwl/nx-linux-arm-gnueabihf": + optional: true + "@nrwl/nx-linux-arm64-gnu": + optional: true + "@nrwl/nx-linux-arm64-musl": + optional: true + "@nrwl/nx-linux-x64-gnu": + optional: true + "@nrwl/nx-linux-x64-musl": + optional: true + "@nrwl/nx-win32-arm64-msvc": + optional: true + "@nrwl/nx-win32-x64-msvc": + optional: true peerDependenciesMeta: "@swc-node/register": optional: true @@ -7451,7 +7873,7 @@ __metadata: optional: true bin: nx: bin/nx.js - checksum: 0cd65ef3aea508c1d14cf9ec4ae22ba63ba408561a27e7cf36630c470e151f055516fe10d7772b56b0114aff40d26f25b40b60bdd040729222f71ed825265719 + checksum: c5765575146bb94f54c1da3d6dec600e6414c0cc64c198821a3de10a72583933f1a752a61452b74f02492e3518f4ead3c287416173b1bb3bbc15ce82bd8d2bb4 languageName: node linkType: hard @@ -8074,6 +8496,15 @@ __metadata: languageName: node linkType: hard +"prettier@npm:^2.8.7": + version: 2.8.7 + resolution: "prettier@npm:2.8.7" + bin: + prettier: bin-prettier.js + checksum: fdc8f2616f099f5f0d685907f4449a70595a0fc1d081a88919604375989e0d5e9168d6121d8cc6861f21990b31665828e00472544d785d5940ea08a17660c3a6 + languageName: node + linkType: hard + "pretty-bytes@npm:^6.0.0": version: 6.0.0 resolution: "pretty-bytes@npm:6.0.0" @@ -8528,20 +8959,6 @@ __metadata: languageName: node linkType: hard -"rollup@npm:^3.10.0": - version: 3.10.0 - resolution: "rollup@npm:3.10.0" - dependencies: - fsevents: ~2.3.2 - dependenciesMeta: - fsevents: - optional: true - bin: - rollup: dist/bin/rollup - checksum: 31a882689c58d084ac36362aeaf2422dc4b80d671bd88c856693c37d63a26ddac9b9819dfba7f79c2d50d5207868b0e3d75f728fe551bbc347cf5dedf8ece18e - languageName: node - linkType: hard - "run-async@npm:^2.4.0": version: 2.4.1 resolution: "run-async@npm:2.4.1" @@ -8558,7 +8975,7 @@ __metadata: languageName: node linkType: hard -"rxjs@npm:^7.2.0, rxjs@npm:^7.5.5, rxjs@npm:^7.5.7": +"rxjs@npm:^7.2.0, rxjs@npm:^7.5.5, rxjs@npm:^7.5.7, rxjs@npm:^7.8.0": version: 7.8.0 resolution: "rxjs@npm:7.8.0" dependencies: @@ -9336,13 +9753,6 @@ __metadata: languageName: node linkType: hard -"toml@npm:^3.0.0": - version: 3.0.0 - resolution: "toml@npm:3.0.0" - checksum: 5d7f1d8413ad7780e9bdecce8ea4c3f5130dd53b0a4f2e90b93340979a137739879d7b9ce2ce05c938b8cc828897fe9e95085197342a1377dd8850bf5125f15f - languageName: node - linkType: hard - "tr46@npm:~0.0.3": version: 0.0.3 resolution: "tr46@npm:0.0.3" @@ -9457,7 +9867,7 @@ __metadata: languageName: node linkType: hard -"typanion@npm:^3.12.1, typanion@npm:^3.3.1": +"typanion@npm:^3.12.1, typanion@npm:^3.8.0": version: 3.12.1 resolution: "typanion@npm:3.12.1" checksum: a2e26fa216f8a1dbd2ffbaacb75b1e2dc042a0356e9702fba05a968cad95d9f661b24e37f6c6d8c3adad2c8582c99fca4826ff26a2d07cd2ae617ea87e6187eb @@ -9862,14 +10272,14 @@ __metadata: languageName: node linkType: hard -"wrap-ansi@npm:^8.0.1": - version: 8.0.1 - resolution: "wrap-ansi@npm:8.0.1" +"wrap-ansi@npm:^8.1.0": + version: 8.1.0 + resolution: "wrap-ansi@npm:8.1.0" dependencies: ansi-styles: ^6.1.0 string-width: ^5.0.1 strip-ansi: ^7.0.1 - checksum: 5d7816e64f75544e466d58a736cb96ca47abad4ad57f48765b9735ba5601221013a37f436662340ca159208b011121e4e030de5a17180c76202e35157195a71e + checksum: 371733296dc2d616900ce15a0049dca0ef67597d6394c57347ba334393599e800bab03c41d4d45221b6bc967b8c453ec3ae4749eff3894202d16800fdfe0e238 languageName: node linkType: hard