Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions cli/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -66,15 +66,15 @@
"@octokit/rest": "^22.0.1",
"clipanion": "^4.0.0-rc.4",
"colorette": "^2.0.20",
"emnapi": "^1.7.1",
"emnapi": "^1.9.1",
"es-toolkit": "^1.41.0",
"js-yaml": "^4.1.0",
"obug": "^2.0.0",
"semver": "^7.7.3",
"typanion": "^3.14.0"
},
"devDependencies": {
"@emnapi/runtime": "^1.7.1",
"@emnapi/runtime": "^1.9.1",
Comment thread
coderabbitai[bot] marked this conversation as resolved.
"@oxc-node/core": "^0.0.35",
"@std/toml": "npm:@jsr/std__toml@^1.0.11",
"@types/inquirer": "^9.0.9",
Expand Down
91 changes: 90 additions & 1 deletion cli/src/api/__tests__/build.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import { fileURLToPath } from 'node:url'

import ava, { type TestFn } from 'ava'

import { generateTypeDef, writeJsBinding } from '../build.js'
import { buildProject, generateTypeDef, writeJsBinding } from '../build.js'
import { getSystemDefaultTarget } from '../../utils/index.js'

const __dirname = dirname(fileURLToPath(import.meta.url))
Expand Down Expand Up @@ -183,3 +183,92 @@ napi-build = { path = "${napiBuildPath}" }
const jsContent = await readFile(jsPath, 'utf-8')
t.regex(jsContent, /module\.exports\.sum = nativeBinding\.sum/)
})

test('should throw on emnapi version mismatch in wasm build', async (t) => {
const { projectDir } = t.context
const crateName = 'wasm_version_check'
const binaryName = 'wasm-version-check'
const packageName = 'wasm-version-check'
const version = '0.1.0'

const napiPath = posixJoin(repoRoot, 'crates', 'napi').replaceAll(
win32Sep,
posixSep,
)
const napiDerivePath = posixJoin(repoRoot, 'crates', 'macro').replaceAll(
win32Sep,
posixSep,
)
const napiBuildPath = posixJoin(repoRoot, 'crates', 'build').replaceAll(
win32Sep,
posixSep,
)

await mkdir(join(projectDir, 'src'), { recursive: true })

const cargoToml = `[package]
name = "${crateName}"
version = "${version}"
edition = "2021"

[lib]
crate-type = ["cdylib"]

[dependencies]
napi = { path = "${napiPath}", features = ["noop"] }
napi-derive = { path = "${napiDerivePath}", features = ["noop"] }

[build-dependencies]
napi-build = { path = "${napiBuildPath}" }
`

await writeFile(join(projectDir, 'Cargo.toml'), cargoToml)
await writeFile(
join(projectDir, 'package.json'),
`${JSON.stringify(
{
name: packageName,
version,
napi: {
binaryName,
targets: ['wasm32-wasi-preview1-threads'],
},
},
null,
2,
)}\n`,
)
await writeFile(
join(projectDir, 'build.rs'),
'fn main() {\n napi_build::setup();\n}\n',
)
await writeFile(
join(projectDir, 'src', 'lib.rs'),
'use napi_derive::napi;\n\n#[napi]\npub fn sum(a: i32, b: i32) -> i32 {\n a + b\n}\n',
)

// Create fake @emnapi/core and @emnapi/runtime with mismatched versions
const fakeVersion = '0.0.0-fake'
for (const pkg of ['@emnapi/core', '@emnapi/runtime']) {
const pkgDir = join(projectDir, 'node_modules', pkg)
await mkdir(pkgDir, { recursive: true })
await writeFile(
join(pkgDir, 'package.json'),
JSON.stringify({ name: pkg, version: fakeVersion, main: 'index.js' }),
)
await writeFile(
join(pkgDir, 'index.js'),
`module.exports = { version: "${fakeVersion}" }`,
)
}

const error = await t.throwsAsync(() =>
buildProject({
target: 'wasm32-wasi-preview1-threads',
cwd: projectDir,
}),
)

t.truthy(error)
t.regex(error!.message, /emnapi version mismatch/)
})
32 changes: 32 additions & 0 deletions cli/src/api/__tests__/create-npm-dirs.spec.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
import { existsSync } from 'node:fs'
import { mkdir, readFile, rm, writeFile } from 'node:fs/promises'
import { createRequire } from 'node:module'
import { tmpdir } from 'node:os'
import { join } from 'node:path'

import ava, { type TestFn } from 'ava'

import { createNpmDirs } from '../create-npm-dirs.js'

const require = createRequire(import.meta.url)

const test = ava as TestFn<{
tmpDir: string
packageJsonPath: string
Expand Down Expand Up @@ -208,3 +211,32 @@ test('should handle WASM targets correctly with publishConfig', async (t) => {
t.truthy(scopedPackageJson.browser)
t.truthy(scopedPackageJson.dependencies)
})

test('should set @emnapi/core and @emnapi/runtime versions to match emnapi for WASM targets', async (t) => {
const { tmpDir, packageJsonPath } = t.context

const packageJson = {
name: 'test-emnapi-versions',
version: '1.0.0',
napi: {
binaryName: 'test-emnapi-versions',
targets: ['wasm32-wasi-preview1-threads'],
},
}

await writeFile(packageJsonPath, JSON.stringify(packageJson, null, 2))

await createNpmDirs({
cwd: tmpDir,
packageJsonPath: 'package.json',
})

const scopedDir = join(tmpDir, 'npm', 'wasm32-wasi')
const scopedPackageJson = JSON.parse(
await readFile(join(scopedDir, 'package.json'), 'utf-8'),
)

const emnapiVersion = require('emnapi/package.json').version
t.is(scopedPackageJson.dependencies['@emnapi/core'], emnapiVersion)
t.is(scopedPackageJson.dependencies['@emnapi/runtime'], emnapiVersion)
})
13 changes: 13 additions & 0 deletions cli/src/api/build.ts
Original file line number Diff line number Diff line change
Expand Up @@ -569,6 +569,19 @@ class Builder {
'wasm32-wasi-threads',
)
this.envs.EMNAPI_LINK_DIR = emnapi
const emnapiVersion = require('emnapi/package.json').version
const projectRequire = createRequire(join(this.options.cwd, 'package.json'))
const emnapiCoreVersion = projectRequire('@emnapi/core').version
const emnapiRuntimeVersion = projectRequire('@emnapi/runtime').version
Comment thread
sapphi-red marked this conversation as resolved.

if (
emnapiVersion !== emnapiCoreVersion ||
emnapiVersion !== emnapiRuntimeVersion
) {
throw new Error(
`emnapi version mismatch: emnapi@${emnapiVersion}, @emnapi/core@${emnapiCoreVersion}, @emnapi/runtime@${emnapiRuntimeVersion}. Please ensure all emnapi packages are the same version.`,
)
}
const { WASI_SDK_PATH } = process.env

if (WASI_SDK_PATH && existsSync(WASI_SDK_PATH)) {
Expand Down
6 changes: 6 additions & 0 deletions cli/src/api/create-npm-dirs.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
import { createRequire } from 'node:module'
import { join, resolve } from 'node:path'

import { parse } from 'semver'

const require = createRequire(import.meta.url)

import {
applyDefaultCreateNpmDirsOptions,
type CreateNpmDirsOptions,
Expand Down Expand Up @@ -122,11 +125,14 @@ export async function createNpmDirs(userOptions: CreateNpmDirsOptions) {
node: '>=14.0.0',
}
}
const emnapiVersion = require('emnapi/package.json').version
const wasmRuntime = await fetch(
`https://registry.npmjs.org/@napi-rs/wasm-runtime`,
).then((res) => res.json() as Promise<PackageMeta>)
scopedPackageJson.dependencies = {
'@napi-rs/wasm-runtime': `^${wasmRuntime['dist-tags'].latest}`,
'@emnapi/core': emnapiVersion,
'@emnapi/runtime': emnapiVersion,
}
}

Expand Down
3 changes: 2 additions & 1 deletion examples/napi/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@
"timeout": "10m"
},
"dependencies": {
"@emnapi/core": "^1.7.0"
"@emnapi/core": "1.9.1",
"@emnapi/runtime": "1.9.1"
}
}
6 changes: 4 additions & 2 deletions wasm-runtime/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,12 @@
"tslib": "^2.8.1"
},
"dependencies": {
"@emnapi/core": "^1.7.1",
"@emnapi/runtime": "^1.7.1",
"@tybys/wasm-util": "^0.10.1"
},
"peerDependencies": {
"@emnapi/core": "^1.7.1",
"@emnapi/runtime": "^1.7.1"
},
"scripts": {
"build": "rollup -c rollup.config.js",
"test": "node --test"
Expand Down
52 changes: 41 additions & 11 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,17 @@ __metadata:
languageName: node
linkType: hard

"@emnapi/core@npm:^1.1.0, @emnapi/core@npm:^1.7.0, @emnapi/core@npm:^1.7.1":
"@emnapi/core@npm:1.9.1":
version: 1.9.1
resolution: "@emnapi/core@npm:1.9.1"
dependencies:
"@emnapi/wasi-threads": "npm:1.2.0"
tslib: "npm:^2.4.0"
checksum: 10c0/00e7a99a2bc3ad908ca8272ba861a934da87dffa8797a41316c4a3b571a1e4d2743e2fa14b1a0f131fa4a3c2018ddb601cd2a8cb7f574fa940af696df3c2fe8d
languageName: node
linkType: hard

"@emnapi/core@npm:^1.1.0":
version: 1.8.1
resolution: "@emnapi/core@npm:1.8.1"
dependencies:
Expand All @@ -122,7 +132,16 @@ __metadata:
languageName: node
linkType: hard

"@emnapi/runtime@npm:^1.1.0, @emnapi/runtime@npm:^1.7.1":
"@emnapi/runtime@npm:1.9.1, @emnapi/runtime@npm:^1.9.1":
version: 1.9.1
resolution: "@emnapi/runtime@npm:1.9.1"
dependencies:
tslib: "npm:^2.4.0"
checksum: 10c0/750edca117e0363ab2de10622f8ee60e57d8690c2f29c49704813da5cd627c641798d7f3cb0d953c62fdc71688e02e333ddbf2c1204f38b47e3e40657332a6f5
languageName: node
linkType: hard

"@emnapi/runtime@npm:^1.1.0":
version: 1.8.1
resolution: "@emnapi/runtime@npm:1.8.1"
dependencies:
Expand All @@ -140,6 +159,15 @@ __metadata:
languageName: node
linkType: hard

"@emnapi/wasi-threads@npm:1.2.0":
version: 1.2.0
resolution: "@emnapi/wasi-threads@npm:1.2.0"
dependencies:
tslib: "npm:^2.4.0"
checksum: 10c0/1e3724b5814b06c14782fda87eee9b9aa68af01576c81ffeaefdf621ddb74386e419d5b3b1027b6a8172397729d95a92f814fc4b8d3c224376428faa07a6a01a
languageName: node
linkType: hard

"@epic-web/invariant@npm:^1.0.0":
version: 1.0.0
resolution: "@epic-web/invariant@npm:1.0.0"
Expand Down Expand Up @@ -343,7 +371,8 @@ __metadata:
version: 0.0.0-use.local
resolution: "@examples/napi@workspace:examples/napi"
dependencies:
"@emnapi/core": "npm:^1.7.0"
"@emnapi/core": "npm:1.9.1"
"@emnapi/runtime": "npm:1.9.1"
"@napi-rs/cli": "workspace:*"
"@napi-rs/triples": "workspace:*"
"@napi-rs/wasm-runtime": "workspace:*"
Expand Down Expand Up @@ -1364,7 +1393,7 @@ __metadata:
version: 0.0.0-use.local
resolution: "@napi-rs/cli@workspace:cli"
dependencies:
"@emnapi/runtime": "npm:^1.7.1"
"@emnapi/runtime": "npm:^1.9.1"
"@inquirer/prompts": "npm:^8.0.0"
"@napi-rs/cross-toolchain": "npm:^1.0.3"
"@napi-rs/wasm-tools": "npm:^1.0.1"
Expand All @@ -1378,7 +1407,7 @@ __metadata:
ava: "npm:^7.0.0"
clipanion: "npm:^4.0.0-rc.4"
colorette: "npm:^2.0.20"
emnapi: "npm:^1.7.1"
emnapi: "npm:^1.9.1"
empathic: "npm:^2.0.0"
env-paths: "npm:^4.0.0"
es-toolkit: "npm:^1.41.0"
Expand Down Expand Up @@ -1823,8 +1852,6 @@ __metadata:
version: 0.0.0-use.local
resolution: "@napi-rs/wasm-runtime@workspace:wasm-runtime"
dependencies:
"@emnapi/core": "npm:^1.7.1"
"@emnapi/runtime": "npm:^1.7.1"
"@rollup/plugin-alias": "npm:^6.0.0"
"@rollup/plugin-commonjs": "npm:^29.0.0"
"@rollup/plugin-inject": "npm:^5.0.5"
Expand All @@ -1842,6 +1869,9 @@ __metadata:
rollup: "npm:^4.53.1"
rollup-plugin-polyfill-node: "npm:^0.13.0"
tslib: "npm:^2.8.1"
peerDependencies:
"@emnapi/core": ^1.7.1
"@emnapi/runtime": ^1.7.1
languageName: unknown
linkType: soft

Expand Down Expand Up @@ -6766,15 +6796,15 @@ __metadata:
languageName: node
linkType: hard

"emnapi@npm:^1.7.1":
version: 1.8.1
resolution: "emnapi@npm:1.8.1"
"emnapi@npm:^1.9.1":
version: 1.9.1
resolution: "emnapi@npm:1.9.1"
peerDependencies:
node-addon-api: ">= 6.1.0"
peerDependenciesMeta:
node-addon-api:
optional: true
checksum: 10c0/a95b167083ee485a84a06202b693f9588bc32080dba82b5752bf805959e97005db1e0cb82ebfe9f35129858b7325f7161c63e97dc78e756a8d6a61443eca79bc
checksum: 10c0/d2dfc4f7ab1999a77147a924776e8d4d852776a2d246a88a1aff2090774c43d087ab1045ec83e22b999acd4bbef80298c519b0705938384945f4842a1df38f40
languageName: node
linkType: hard

Expand Down
Loading