@napi-rs/cli 3.0.0-alpha.94 → 3.0.0-alpha.95

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -95,6 +95,10 @@ export interface CommonPackageJsonFields {
95
95
  author?: string;
96
96
  authors?: string[];
97
97
  license?: string;
98
+ cpu?: string[];
99
+ os?: string[];
100
+ libc?: string[];
101
+ files?: string[];
98
102
  repository?: any;
99
103
  homepage?: any;
100
104
  engines?: Record<string, string>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@napi-rs/cli",
3
- "version": "3.0.0-alpha.94",
3
+ "version": "3.0.0-alpha.95",
4
4
  "description": "Cli tools for napi-rs",
5
5
  "author": "LongYinan <lynweklm@gmail.com>",
6
6
  "homepage": "https://github.com/napi-rs/napi-rs",
@@ -132,5 +132,5 @@
132
132
  "e2e/**/*.spec.ts"
133
133
  ]
134
134
  },
135
- "gitHead": "08c364f5a76fa5f3b887b3050ffd175d33206a30"
135
+ "gitHead": "0aa36c39a6cb6b73ce969a33cf4ec04301a1d77a"
136
136
  }
@@ -0,0 +1,210 @@
1
+ import { existsSync } from 'node:fs'
2
+ import { mkdir, readFile, rm, writeFile } from 'node:fs/promises'
3
+ import { tmpdir } from 'node:os'
4
+ import { join } from 'node:path'
5
+
6
+ import ava, { TestFn } from 'ava'
7
+
8
+ import { createNpmDirs } from '../create-npm-dirs.js'
9
+
10
+ const test = ava as TestFn<{
11
+ tmpDir: string
12
+ packageJsonPath: string
13
+ }>
14
+
15
+ test.beforeEach(async (t) => {
16
+ // Create a unique temp directory for tests
17
+ const timestamp = Date.now()
18
+ const random = Math.random().toString(36).substring(7)
19
+ const tmpDir = join(
20
+ tmpdir(),
21
+ 'napi-rs-test',
22
+ `create-npm-dirs-${timestamp}-${random}`,
23
+ )
24
+ const packageJsonPath = join(tmpDir, 'package.json')
25
+
26
+ // Create the directory
27
+ await mkdir(tmpDir, { recursive: true })
28
+
29
+ t.context = { tmpDir, packageJsonPath }
30
+ })
31
+
32
+ test.afterEach.always(async (t) => {
33
+ // Clean up any created directories
34
+ if (existsSync(t.context.tmpDir)) {
35
+ await rm(t.context.tmpDir, { recursive: true, force: true })
36
+ }
37
+ })
38
+
39
+ test('should omit exports fields from publishConfig in scoped packages', async (t) => {
40
+ const { tmpDir, packageJsonPath } = t.context
41
+
42
+ // Create a package.json with publishConfig that includes exports field
43
+ const packageJson = {
44
+ name: 'test-package',
45
+ version: '1.0.0',
46
+ publishConfig: {
47
+ registry: 'https://custom-registry.com',
48
+ access: 'public',
49
+ exports: {
50
+ '.': './dist/index.js',
51
+ './package.json': './package.json',
52
+ },
53
+ tag: 'beta',
54
+ },
55
+ napi: {
56
+ binaryName: 'test-package',
57
+ targets: ['x86_64-unknown-linux-gnu'],
58
+ },
59
+ }
60
+
61
+ await writeFile(packageJsonPath, JSON.stringify(packageJson, null, 2))
62
+
63
+ await createNpmDirs({
64
+ cwd: tmpDir,
65
+ packageJsonPath: 'package.json',
66
+ })
67
+
68
+ // Check that the scoped package directory was created
69
+ const scopedDir = join(tmpDir, 'npm', 'linux-x64-gnu')
70
+ t.true(existsSync(scopedDir))
71
+
72
+ // Read the generated package.json for the scoped package
73
+ const scopedPackageJsonPath = join(scopedDir, 'package.json')
74
+ t.true(existsSync(scopedPackageJsonPath))
75
+
76
+ const scopedPackageJson = JSON.parse(
77
+ await readFile(scopedPackageJsonPath, 'utf-8'),
78
+ )
79
+
80
+ // Verify that publishConfig only contains registry and access, not exports
81
+ t.truthy(scopedPackageJson.publishConfig)
82
+ t.is(scopedPackageJson.publishConfig.registry, 'https://custom-registry.com')
83
+ t.is(scopedPackageJson.publishConfig.access, 'public')
84
+ t.is(scopedPackageJson.publishConfig.exports, undefined)
85
+ t.is(scopedPackageJson.publishConfig.tag, undefined)
86
+ })
87
+
88
+ test('should handle package without publishConfig', async (t) => {
89
+ const { tmpDir, packageJsonPath } = t.context
90
+
91
+ // Create a package.json without publishConfig
92
+ const packageJson = {
93
+ name: 'test-package-no-config',
94
+ version: '1.0.0',
95
+ napi: {
96
+ binaryName: 'test-package-no-config',
97
+ targets: ['x86_64-unknown-linux-gnu'],
98
+ },
99
+ }
100
+
101
+ await writeFile(packageJsonPath, JSON.stringify(packageJson, null, 2))
102
+
103
+ await createNpmDirs({
104
+ cwd: tmpDir,
105
+ packageJsonPath: 'package.json',
106
+ })
107
+
108
+ // Check that the scoped package directory was created
109
+ const scopedDir = join(tmpDir, 'npm', 'linux-x64-gnu')
110
+ t.true(existsSync(scopedDir))
111
+
112
+ // Read the generated package.json for the scoped package
113
+ const scopedPackageJsonPath = join(scopedDir, 'package.json')
114
+ const scopedPackageJson = JSON.parse(
115
+ await readFile(scopedPackageJsonPath, 'utf-8'),
116
+ )
117
+
118
+ // Verify that publishConfig is not present when not in source
119
+ t.is(scopedPackageJson.publishConfig, undefined)
120
+ })
121
+
122
+ test('should preserve only registry and access in publishConfig', async (t) => {
123
+ const { tmpDir, packageJsonPath } = t.context
124
+
125
+ // Create a package.json with minimal publishConfig
126
+ const packageJson = {
127
+ name: 'test-package-minimal',
128
+ version: '1.0.0',
129
+ publishConfig: {
130
+ registry: 'https://npm.company.com',
131
+ access: 'restricted',
132
+ },
133
+ napi: {
134
+ binaryName: 'test-package-minimal',
135
+ targets: ['aarch64-apple-darwin'],
136
+ },
137
+ }
138
+
139
+ await writeFile(packageJsonPath, JSON.stringify(packageJson, null, 2))
140
+
141
+ await createNpmDirs({
142
+ cwd: tmpDir,
143
+ packageJsonPath: 'package.json',
144
+ })
145
+
146
+ // Check that the scoped package directory was created
147
+ const scopedDir = join(tmpDir, 'npm', 'darwin-arm64')
148
+ t.true(existsSync(scopedDir))
149
+
150
+ // Read the generated package.json for the scoped package
151
+ const scopedPackageJsonPath = join(scopedDir, 'package.json')
152
+ const scopedPackageJson = JSON.parse(
153
+ await readFile(scopedPackageJsonPath, 'utf-8'),
154
+ )
155
+
156
+ // Verify that publishConfig contains exactly registry and access
157
+ t.truthy(scopedPackageJson.publishConfig)
158
+ t.is(scopedPackageJson.publishConfig.registry, 'https://npm.company.com')
159
+ t.is(scopedPackageJson.publishConfig.access, 'restricted')
160
+ t.is(Object.keys(scopedPackageJson.publishConfig).length, 2)
161
+ })
162
+
163
+ test('should handle WASM targets correctly with publishConfig', async (t) => {
164
+ const { tmpDir, packageJsonPath } = t.context
165
+
166
+ // Create a package.json for WASM target
167
+ const packageJson = {
168
+ name: 'test-wasm-package',
169
+ version: '1.0.0',
170
+ publishConfig: {
171
+ registry: 'https://wasm-registry.com',
172
+ access: 'public',
173
+ exports: './wasm.js',
174
+ browser: './browser.js',
175
+ },
176
+ napi: {
177
+ binaryName: 'test-wasm-package',
178
+ targets: ['wasm32-wasi-preview1-threads'],
179
+ },
180
+ }
181
+
182
+ await writeFile(packageJsonPath, JSON.stringify(packageJson, null, 2))
183
+
184
+ await createNpmDirs({
185
+ cwd: tmpDir,
186
+ packageJsonPath: 'package.json',
187
+ })
188
+
189
+ // Check that the scoped package directory was created
190
+ const scopedDir = join(tmpDir, 'npm', 'wasm32-wasi')
191
+ t.true(existsSync(scopedDir))
192
+
193
+ // Read the generated package.json for the scoped package
194
+ const scopedPackageJsonPath = join(scopedDir, 'package.json')
195
+ const scopedPackageJson = JSON.parse(
196
+ await readFile(scopedPackageJsonPath, 'utf-8'),
197
+ )
198
+
199
+ // Verify that publishConfig is correctly filtered for WASM too
200
+ t.truthy(scopedPackageJson.publishConfig)
201
+ t.is(scopedPackageJson.publishConfig.registry, 'https://wasm-registry.com')
202
+ t.is(scopedPackageJson.publishConfig.access, 'public')
203
+ t.is(scopedPackageJson.publishConfig.exports, undefined)
204
+ t.is(scopedPackageJson.publishConfig.browser, undefined)
205
+
206
+ // Verify WASM-specific fields are set correctly
207
+ t.truthy(scopedPackageJson.main)
208
+ t.truthy(scopedPackageJson.browser)
209
+ t.truthy(scopedPackageJson.dependencies)
210
+ })
@@ -13,6 +13,7 @@ import {
13
13
  pick,
14
14
  writeFileAsync as rawWriteFileAsync,
15
15
  Target,
16
+ type CommonPackageJsonFields,
16
17
  } from '../utils/index.js'
17
18
 
18
19
  const debug = debugFactory('create-npm-dirs')
@@ -65,7 +66,7 @@ export async function createNpmDirs(userOptions: CreateNpmDirsOptions) {
65
66
  target.arch === 'wasm32'
66
67
  ? `${binaryName}.${target.platformArchABI}.wasm`
67
68
  : `${binaryName}.${target.platformArchABI}.node`
68
- const scopedPackageJson = {
69
+ const scopedPackageJson: CommonPackageJsonFields = {
69
70
  name: `${packageName}-${target.platformArchABI}`,
70
71
  version: packageJson.version,
71
72
  cpu: target.arch !== 'universal' ? [target.arch] : undefined,
@@ -80,22 +81,25 @@ export async function createNpmDirs(userOptions: CreateNpmDirsOptions) {
80
81
  'homepage',
81
82
  'license',
82
83
  'engines',
83
- 'publishConfig',
84
84
  'repository',
85
85
  'bugs',
86
86
  ),
87
87
  }
88
+ if (packageJson.publishConfig) {
89
+ scopedPackageJson.publishConfig = pick(
90
+ packageJson.publishConfig,
91
+ 'registry',
92
+ 'access',
93
+ )
94
+ }
88
95
  if (target.arch !== 'wasm32') {
89
- // @ts-expect-error
90
96
  scopedPackageJson.os = [target.platform]
91
97
  } else {
92
98
  const entry = `${binaryName}.wasi.cjs`
93
99
  scopedPackageJson.main = entry
94
- // @ts-expect-error
95
100
  scopedPackageJson.browser = `${binaryName}.wasi-browser.js`
96
- scopedPackageJson.files.push(
101
+ scopedPackageJson.files?.push(
97
102
  entry,
98
- // @ts-expect-error
99
103
  scopedPackageJson.browser,
100
104
  `wasi-worker.mjs`,
101
105
  `wasi-worker-browser.mjs`,
@@ -121,17 +125,14 @@ export async function createNpmDirs(userOptions: CreateNpmDirsOptions) {
121
125
  const wasmRuntime = await fetch(
122
126
  `https://registry.npmjs.org/@napi-rs/wasm-runtime`,
123
127
  ).then((res) => res.json() as Promise<PackageMeta>)
124
- // @ts-expect-error
125
128
  scopedPackageJson.dependencies = {
126
129
  '@napi-rs/wasm-runtime': `^${wasmRuntime['dist-tags'].latest}`,
127
130
  }
128
131
  }
129
132
 
130
133
  if (target.abi === 'gnu') {
131
- // @ts-expect-error
132
134
  scopedPackageJson.libc = ['glibc']
133
135
  } else if (target.abi === 'musl') {
134
- // @ts-expect-error
135
136
  scopedPackageJson.libc = ['musl']
136
137
  }
137
138
 
@@ -115,6 +115,10 @@ export interface CommonPackageJsonFields {
115
115
  author?: string
116
116
  authors?: string[]
117
117
  license?: string
118
+ cpu?: string[]
119
+ os?: string[]
120
+ libc?: string[]
121
+ files?: string[]
118
122
  repository?: any
119
123
  homepage?: any
120
124
  engines?: Record<string, string>