@brust/core 2.0.0-alpha.11 → 2.0.0-alpha.13

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.
package/native/index.js CHANGED
@@ -89,8 +89,8 @@ function requireNative() {
89
89
  try {
90
90
  const binding = require('@brust/native-android-arm64')
91
91
  const bindingPackageVersion = require('@brust/native-android-arm64/package.json').version
92
- if (bindingPackageVersion !== '2.0.0-alpha.11' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
93
- throw new Error(`Native binding package version mismatch, expected 2.0.0-alpha.11 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
92
+ if (bindingPackageVersion !== '2.0.0-alpha.13' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
93
+ throw new Error(`Native binding package version mismatch, expected 2.0.0-alpha.13 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
94
94
  }
95
95
  return binding
96
96
  } catch (e) {
@@ -105,8 +105,8 @@ function requireNative() {
105
105
  try {
106
106
  const binding = require('@brust/native-android-arm-eabi')
107
107
  const bindingPackageVersion = require('@brust/native-android-arm-eabi/package.json').version
108
- if (bindingPackageVersion !== '2.0.0-alpha.11' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
109
- throw new Error(`Native binding package version mismatch, expected 2.0.0-alpha.11 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
108
+ if (bindingPackageVersion !== '2.0.0-alpha.13' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
109
+ throw new Error(`Native binding package version mismatch, expected 2.0.0-alpha.13 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
110
110
  }
111
111
  return binding
112
112
  } catch (e) {
@@ -126,8 +126,8 @@ function requireNative() {
126
126
  try {
127
127
  const binding = require('@brust/native-win32-x64-gnu')
128
128
  const bindingPackageVersion = require('@brust/native-win32-x64-gnu/package.json').version
129
- if (bindingPackageVersion !== '2.0.0-alpha.11' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
130
- throw new Error(`Native binding package version mismatch, expected 2.0.0-alpha.11 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
129
+ if (bindingPackageVersion !== '2.0.0-alpha.13' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
130
+ throw new Error(`Native binding package version mismatch, expected 2.0.0-alpha.13 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
131
131
  }
132
132
  return binding
133
133
  } catch (e) {
@@ -142,8 +142,8 @@ function requireNative() {
142
142
  try {
143
143
  const binding = require('@brust/native-win32-x64-msvc')
144
144
  const bindingPackageVersion = require('@brust/native-win32-x64-msvc/package.json').version
145
- if (bindingPackageVersion !== '2.0.0-alpha.11' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
146
- throw new Error(`Native binding package version mismatch, expected 2.0.0-alpha.11 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
145
+ if (bindingPackageVersion !== '2.0.0-alpha.13' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
146
+ throw new Error(`Native binding package version mismatch, expected 2.0.0-alpha.13 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
147
147
  }
148
148
  return binding
149
149
  } catch (e) {
@@ -159,8 +159,8 @@ function requireNative() {
159
159
  try {
160
160
  const binding = require('@brust/native-win32-ia32-msvc')
161
161
  const bindingPackageVersion = require('@brust/native-win32-ia32-msvc/package.json').version
162
- if (bindingPackageVersion !== '2.0.0-alpha.11' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
163
- throw new Error(`Native binding package version mismatch, expected 2.0.0-alpha.11 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
162
+ if (bindingPackageVersion !== '2.0.0-alpha.13' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
163
+ throw new Error(`Native binding package version mismatch, expected 2.0.0-alpha.13 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
164
164
  }
165
165
  return binding
166
166
  } catch (e) {
@@ -175,8 +175,8 @@ function requireNative() {
175
175
  try {
176
176
  const binding = require('@brust/native-win32-arm64-msvc')
177
177
  const bindingPackageVersion = require('@brust/native-win32-arm64-msvc/package.json').version
178
- if (bindingPackageVersion !== '2.0.0-alpha.11' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
179
- throw new Error(`Native binding package version mismatch, expected 2.0.0-alpha.11 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
178
+ if (bindingPackageVersion !== '2.0.0-alpha.13' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
179
+ throw new Error(`Native binding package version mismatch, expected 2.0.0-alpha.13 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
180
180
  }
181
181
  return binding
182
182
  } catch (e) {
@@ -194,8 +194,8 @@ function requireNative() {
194
194
  try {
195
195
  const binding = require('@brust/native-darwin-universal')
196
196
  const bindingPackageVersion = require('@brust/native-darwin-universal/package.json').version
197
- if (bindingPackageVersion !== '2.0.0-alpha.11' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
198
- throw new Error(`Native binding package version mismatch, expected 2.0.0-alpha.11 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
197
+ if (bindingPackageVersion !== '2.0.0-alpha.13' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
198
+ throw new Error(`Native binding package version mismatch, expected 2.0.0-alpha.13 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
199
199
  }
200
200
  return binding
201
201
  } catch (e) {
@@ -210,8 +210,8 @@ function requireNative() {
210
210
  try {
211
211
  const binding = require('@brust/native-darwin-x64')
212
212
  const bindingPackageVersion = require('@brust/native-darwin-x64/package.json').version
213
- if (bindingPackageVersion !== '2.0.0-alpha.11' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
214
- throw new Error(`Native binding package version mismatch, expected 2.0.0-alpha.11 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
213
+ if (bindingPackageVersion !== '2.0.0-alpha.13' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
214
+ throw new Error(`Native binding package version mismatch, expected 2.0.0-alpha.13 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
215
215
  }
216
216
  return binding
217
217
  } catch (e) {
@@ -226,8 +226,8 @@ function requireNative() {
226
226
  try {
227
227
  const binding = require('@brust/native-darwin-arm64')
228
228
  const bindingPackageVersion = require('@brust/native-darwin-arm64/package.json').version
229
- if (bindingPackageVersion !== '2.0.0-alpha.11' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
230
- throw new Error(`Native binding package version mismatch, expected 2.0.0-alpha.11 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
229
+ if (bindingPackageVersion !== '2.0.0-alpha.13' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
230
+ throw new Error(`Native binding package version mismatch, expected 2.0.0-alpha.13 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
231
231
  }
232
232
  return binding
233
233
  } catch (e) {
@@ -246,8 +246,8 @@ function requireNative() {
246
246
  try {
247
247
  const binding = require('@brust/native-freebsd-x64')
248
248
  const bindingPackageVersion = require('@brust/native-freebsd-x64/package.json').version
249
- if (bindingPackageVersion !== '2.0.0-alpha.11' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
250
- throw new Error(`Native binding package version mismatch, expected 2.0.0-alpha.11 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
249
+ if (bindingPackageVersion !== '2.0.0-alpha.13' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
250
+ throw new Error(`Native binding package version mismatch, expected 2.0.0-alpha.13 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
251
251
  }
252
252
  return binding
253
253
  } catch (e) {
@@ -262,8 +262,8 @@ function requireNative() {
262
262
  try {
263
263
  const binding = require('@brust/native-freebsd-arm64')
264
264
  const bindingPackageVersion = require('@brust/native-freebsd-arm64/package.json').version
265
- if (bindingPackageVersion !== '2.0.0-alpha.11' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
266
- throw new Error(`Native binding package version mismatch, expected 2.0.0-alpha.11 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
265
+ if (bindingPackageVersion !== '2.0.0-alpha.13' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
266
+ throw new Error(`Native binding package version mismatch, expected 2.0.0-alpha.13 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
267
267
  }
268
268
  return binding
269
269
  } catch (e) {
@@ -283,8 +283,8 @@ function requireNative() {
283
283
  try {
284
284
  const binding = require('@brust/native-linux-x64-musl')
285
285
  const bindingPackageVersion = require('@brust/native-linux-x64-musl/package.json').version
286
- if (bindingPackageVersion !== '2.0.0-alpha.11' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
287
- throw new Error(`Native binding package version mismatch, expected 2.0.0-alpha.11 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
286
+ if (bindingPackageVersion !== '2.0.0-alpha.13' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
287
+ throw new Error(`Native binding package version mismatch, expected 2.0.0-alpha.13 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
288
288
  }
289
289
  return binding
290
290
  } catch (e) {
@@ -299,8 +299,8 @@ function requireNative() {
299
299
  try {
300
300
  const binding = require('@brust/native-linux-x64-gnu')
301
301
  const bindingPackageVersion = require('@brust/native-linux-x64-gnu/package.json').version
302
- if (bindingPackageVersion !== '2.0.0-alpha.11' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
303
- throw new Error(`Native binding package version mismatch, expected 2.0.0-alpha.11 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
302
+ if (bindingPackageVersion !== '2.0.0-alpha.13' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
303
+ throw new Error(`Native binding package version mismatch, expected 2.0.0-alpha.13 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
304
304
  }
305
305
  return binding
306
306
  } catch (e) {
@@ -317,8 +317,8 @@ function requireNative() {
317
317
  try {
318
318
  const binding = require('@brust/native-linux-arm64-musl')
319
319
  const bindingPackageVersion = require('@brust/native-linux-arm64-musl/package.json').version
320
- if (bindingPackageVersion !== '2.0.0-alpha.11' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
321
- throw new Error(`Native binding package version mismatch, expected 2.0.0-alpha.11 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
320
+ if (bindingPackageVersion !== '2.0.0-alpha.13' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
321
+ throw new Error(`Native binding package version mismatch, expected 2.0.0-alpha.13 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
322
322
  }
323
323
  return binding
324
324
  } catch (e) {
@@ -333,8 +333,8 @@ function requireNative() {
333
333
  try {
334
334
  const binding = require('@brust/native-linux-arm64-gnu')
335
335
  const bindingPackageVersion = require('@brust/native-linux-arm64-gnu/package.json').version
336
- if (bindingPackageVersion !== '2.0.0-alpha.11' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
337
- throw new Error(`Native binding package version mismatch, expected 2.0.0-alpha.11 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
336
+ if (bindingPackageVersion !== '2.0.0-alpha.13' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
337
+ throw new Error(`Native binding package version mismatch, expected 2.0.0-alpha.13 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
338
338
  }
339
339
  return binding
340
340
  } catch (e) {
@@ -351,8 +351,8 @@ function requireNative() {
351
351
  try {
352
352
  const binding = require('@brust/native-linux-arm-musleabihf')
353
353
  const bindingPackageVersion = require('@brust/native-linux-arm-musleabihf/package.json').version
354
- if (bindingPackageVersion !== '2.0.0-alpha.11' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
355
- throw new Error(`Native binding package version mismatch, expected 2.0.0-alpha.11 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
354
+ if (bindingPackageVersion !== '2.0.0-alpha.13' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
355
+ throw new Error(`Native binding package version mismatch, expected 2.0.0-alpha.13 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
356
356
  }
357
357
  return binding
358
358
  } catch (e) {
@@ -367,8 +367,8 @@ function requireNative() {
367
367
  try {
368
368
  const binding = require('@brust/native-linux-arm-gnueabihf')
369
369
  const bindingPackageVersion = require('@brust/native-linux-arm-gnueabihf/package.json').version
370
- if (bindingPackageVersion !== '2.0.0-alpha.11' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
371
- throw new Error(`Native binding package version mismatch, expected 2.0.0-alpha.11 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
370
+ if (bindingPackageVersion !== '2.0.0-alpha.13' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
371
+ throw new Error(`Native binding package version mismatch, expected 2.0.0-alpha.13 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
372
372
  }
373
373
  return binding
374
374
  } catch (e) {
@@ -385,8 +385,8 @@ function requireNative() {
385
385
  try {
386
386
  const binding = require('@brust/native-linux-loong64-musl')
387
387
  const bindingPackageVersion = require('@brust/native-linux-loong64-musl/package.json').version
388
- if (bindingPackageVersion !== '2.0.0-alpha.11' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
389
- throw new Error(`Native binding package version mismatch, expected 2.0.0-alpha.11 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
388
+ if (bindingPackageVersion !== '2.0.0-alpha.13' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
389
+ throw new Error(`Native binding package version mismatch, expected 2.0.0-alpha.13 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
390
390
  }
391
391
  return binding
392
392
  } catch (e) {
@@ -401,8 +401,8 @@ function requireNative() {
401
401
  try {
402
402
  const binding = require('@brust/native-linux-loong64-gnu')
403
403
  const bindingPackageVersion = require('@brust/native-linux-loong64-gnu/package.json').version
404
- if (bindingPackageVersion !== '2.0.0-alpha.11' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
405
- throw new Error(`Native binding package version mismatch, expected 2.0.0-alpha.11 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
404
+ if (bindingPackageVersion !== '2.0.0-alpha.13' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
405
+ throw new Error(`Native binding package version mismatch, expected 2.0.0-alpha.13 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
406
406
  }
407
407
  return binding
408
408
  } catch (e) {
@@ -419,8 +419,8 @@ function requireNative() {
419
419
  try {
420
420
  const binding = require('@brust/native-linux-riscv64-musl')
421
421
  const bindingPackageVersion = require('@brust/native-linux-riscv64-musl/package.json').version
422
- if (bindingPackageVersion !== '2.0.0-alpha.11' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
423
- throw new Error(`Native binding package version mismatch, expected 2.0.0-alpha.11 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
422
+ if (bindingPackageVersion !== '2.0.0-alpha.13' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
423
+ throw new Error(`Native binding package version mismatch, expected 2.0.0-alpha.13 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
424
424
  }
425
425
  return binding
426
426
  } catch (e) {
@@ -435,8 +435,8 @@ function requireNative() {
435
435
  try {
436
436
  const binding = require('@brust/native-linux-riscv64-gnu')
437
437
  const bindingPackageVersion = require('@brust/native-linux-riscv64-gnu/package.json').version
438
- if (bindingPackageVersion !== '2.0.0-alpha.11' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
439
- throw new Error(`Native binding package version mismatch, expected 2.0.0-alpha.11 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
438
+ if (bindingPackageVersion !== '2.0.0-alpha.13' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
439
+ throw new Error(`Native binding package version mismatch, expected 2.0.0-alpha.13 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
440
440
  }
441
441
  return binding
442
442
  } catch (e) {
@@ -452,8 +452,8 @@ function requireNative() {
452
452
  try {
453
453
  const binding = require('@brust/native-linux-ppc64-gnu')
454
454
  const bindingPackageVersion = require('@brust/native-linux-ppc64-gnu/package.json').version
455
- if (bindingPackageVersion !== '2.0.0-alpha.11' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
456
- throw new Error(`Native binding package version mismatch, expected 2.0.0-alpha.11 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
455
+ if (bindingPackageVersion !== '2.0.0-alpha.13' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
456
+ throw new Error(`Native binding package version mismatch, expected 2.0.0-alpha.13 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
457
457
  }
458
458
  return binding
459
459
  } catch (e) {
@@ -468,8 +468,8 @@ function requireNative() {
468
468
  try {
469
469
  const binding = require('@brust/native-linux-s390x-gnu')
470
470
  const bindingPackageVersion = require('@brust/native-linux-s390x-gnu/package.json').version
471
- if (bindingPackageVersion !== '2.0.0-alpha.11' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
472
- throw new Error(`Native binding package version mismatch, expected 2.0.0-alpha.11 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
471
+ if (bindingPackageVersion !== '2.0.0-alpha.13' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
472
+ throw new Error(`Native binding package version mismatch, expected 2.0.0-alpha.13 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
473
473
  }
474
474
  return binding
475
475
  } catch (e) {
@@ -488,8 +488,8 @@ function requireNative() {
488
488
  try {
489
489
  const binding = require('@brust/native-openharmony-arm64')
490
490
  const bindingPackageVersion = require('@brust/native-openharmony-arm64/package.json').version
491
- if (bindingPackageVersion !== '2.0.0-alpha.11' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
492
- throw new Error(`Native binding package version mismatch, expected 2.0.0-alpha.11 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
491
+ if (bindingPackageVersion !== '2.0.0-alpha.13' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
492
+ throw new Error(`Native binding package version mismatch, expected 2.0.0-alpha.13 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
493
493
  }
494
494
  return binding
495
495
  } catch (e) {
@@ -504,8 +504,8 @@ function requireNative() {
504
504
  try {
505
505
  const binding = require('@brust/native-openharmony-x64')
506
506
  const bindingPackageVersion = require('@brust/native-openharmony-x64/package.json').version
507
- if (bindingPackageVersion !== '2.0.0-alpha.11' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
508
- throw new Error(`Native binding package version mismatch, expected 2.0.0-alpha.11 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
507
+ if (bindingPackageVersion !== '2.0.0-alpha.13' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
508
+ throw new Error(`Native binding package version mismatch, expected 2.0.0-alpha.13 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
509
509
  }
510
510
  return binding
511
511
  } catch (e) {
@@ -520,8 +520,8 @@ function requireNative() {
520
520
  try {
521
521
  const binding = require('@brust/native-openharmony-arm')
522
522
  const bindingPackageVersion = require('@brust/native-openharmony-arm/package.json').version
523
- if (bindingPackageVersion !== '2.0.0-alpha.11' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
524
- throw new Error(`Native binding package version mismatch, expected 2.0.0-alpha.11 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
523
+ if (bindingPackageVersion !== '2.0.0-alpha.13' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
524
+ throw new Error(`Native binding package version mismatch, expected 2.0.0-alpha.13 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
525
525
  }
526
526
  return binding
527
527
  } catch (e) {
@@ -661,8 +661,8 @@ if (!nativeBinding || forceWasi) {
661
661
  if (!candidateFailed) {
662
662
  if (process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
663
663
  const bindingPackageVersion = require('@brust/native-wasm32-wasi/package.json').version
664
- if (bindingPackageVersion !== '2.0.0-alpha.11') {
665
- throw new Error(`WASI binding package version mismatch, expected 2.0.0-alpha.11 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
664
+ if (bindingPackageVersion !== '2.0.0-alpha.13') {
665
+ throw new Error(`WASI binding package version mismatch, expected 2.0.0-alpha.13 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
666
666
  }
667
667
  }
668
668
  wasiBinding = require('@brust/native-wasm32-wasi')
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@brust/core",
3
- "version": "2.0.0-alpha.11",
3
+ "version": "2.0.0-alpha.13",
4
4
  "description": "brust v2 — React components compiled to Rust-rendered templates",
5
5
  "license": "MIT",
6
6
  "homepage": "https://brust.dev",
@@ -55,7 +55,7 @@
55
55
  ]
56
56
  },
57
57
  "dependencies": {
58
- "@brust/runtime-dom": "2.0.0-alpha.11"
58
+ "@brust/runtime-dom": "2.0.0-alpha.13"
59
59
  },
60
60
  "peerDependencies": {
61
61
  "react": "^19.0.0",
@@ -93,12 +93,12 @@
93
93
  "access": "public"
94
94
  },
95
95
  "optionalDependencies": {
96
- "@brust/native-darwin-x64": "2.0.0-alpha.11",
97
- "@brust/native-darwin-arm64": "2.0.0-alpha.11",
98
- "@brust/native-linux-x64-gnu": "2.0.0-alpha.11",
99
- "@brust/native-linux-arm64-gnu": "2.0.0-alpha.11",
100
- "@brust/native-linux-x64-musl": "2.0.0-alpha.11",
101
- "@brust/native-linux-arm64-musl": "2.0.0-alpha.11",
102
- "@brust/core-cf": "2.0.0-alpha.11"
96
+ "@brust/native-darwin-x64": "2.0.0-alpha.13",
97
+ "@brust/native-darwin-arm64": "2.0.0-alpha.13",
98
+ "@brust/native-linux-x64-gnu": "2.0.0-alpha.13",
99
+ "@brust/native-linux-arm64-gnu": "2.0.0-alpha.13",
100
+ "@brust/native-linux-x64-musl": "2.0.0-alpha.13",
101
+ "@brust/native-linux-arm64-musl": "2.0.0-alpha.13",
102
+ "@brust/core-cf": "2.0.0-alpha.13"
103
103
  }
104
104
  }
@@ -249,6 +249,7 @@ async function evaluateInstances(
249
249
  const imports: string[] = []
250
250
  /** Component id -> its staged job module; written once, with the stubs its own imports are served by. */
251
251
  const staged = new Map<string, string>()
252
+ const jobFiles = new Set<string>() // the only importers of `brust-job:` (F186)
252
253
  const stageJob = (c: Compiled, served: { source: string; code: string }[]) => {
253
254
  if (staged.has(c.id)) return
254
255
  const file = join(dist, '.stage', 'eval', `${c.id}.job.ts`)
@@ -266,6 +267,7 @@ async function evaluateInstances(
266
267
  stubs.set(realpathSync(file), map)
267
268
  }
268
269
  staged.set(c.id, file)
270
+ jobFiles.add(file).add(realpathSync(file))
269
271
  }
270
272
  for (const c of compiled.values()) {
271
273
  for (const inst of c.ir.build_eval_instances ?? []) {
@@ -296,7 +298,7 @@ async function evaluateInstances(
296
298
  target: 'bun',
297
299
  format: 'esm',
298
300
  define: PRODUCTION,
299
- plugins: [jobImportPlugin((id) => staged.get(id)), stubPlugin(stubs), sourceDirPlugin(sourceOf, appRoot)],
301
+ plugins: [jobImportPlugin((id) => staged.get(id), (importer) => jobFiles.has(importer)), stubPlugin(stubs), sourceDirPlugin(sourceOf, appRoot)],
300
302
  })
301
303
  if (!res.success) {
302
304
  log(`warning build-eval the instance jobs could not be bundled for build evaluation, they stay per-request jobs: ${res.logs.map(String).join(' | ').split('\n')[0]}`)
@@ -76,6 +76,9 @@ export function sourceDirPlugin(sourceOf: SourceOf, appRoot: string, external: s
76
76
  return src === undefined ? undefined : { path: Bun.resolveSync(a.path, dirname(src)) }
77
77
  })
78
78
  b.onResolve({ filter: /^[^./]/ }, (a) => {
79
+ // A package source imported as itself (a React component revived from it): its bare imports are the package's.
80
+ const own = sourceOf.has(a.importer) ? undefined : packageDirOf(a.importer)
81
+ if (own !== undefined && !matchesExternal(a.path, external)) return { path: Bun.resolveSync(a.path, own) }
79
82
  if (!sourceOf.has(a.importer) || matchesExternal(a.path, external)) return undefined
80
83
  // F153c: an artifact compiled from a package's source imports what that package sees.
81
84
  const pkg = packageDirOf(sourceOf.get(a.importer)!)
@@ -600,12 +603,14 @@ export async function buildCacheAdapter(dist: string, entry: string, cssMaps: Ma
600
603
  }
601
604
 
602
605
  /** R34.96: a parent's job calls the job of each child fused into it through `brust-job:<component id>`, resolved here to
603
- * that child's staged job module (`fileOf`). Only a compiled component's id resolves: anything else fails the bundle. */
604
- export function jobImportPlugin(fileOf: (id: string) => string | undefined): BunPlugin {
606
+ * that child's staged job module (`fileOf`). Only a compiled component's id resolves, and only for a staged job file
607
+ * (`isJobFile`, F186): any other importer (app or package source) fails the bundle, as does an unknown id. */
608
+ export function jobImportPlugin(fileOf: (id: string) => string | undefined, isJobFile: (importer: string) => boolean): BunPlugin {
605
609
  return {
606
610
  name: 'brust-job-import',
607
611
  setup(b) {
608
612
  b.onResolve({ filter: /^brust-job:/ }, (a) => {
613
+ if (!isJobFile(a.importer)) throw new BuildError('bundle', `${a.importer}: brust-job: is for generated job modules only`)
609
614
  const id = a.path.slice('brust-job:'.length)
610
615
  const file = /^[A-Za-z0-9_$-]+$/.test(id) ? fileOf(id) : undefined
611
616
  if (file === undefined) throw new BuildError('bundle', `${a.importer}: no job module for ${JSON.stringify(id)}`)
@@ -625,6 +630,8 @@ export async function buildJobs(
625
630
  stores: string[] = [],
626
631
  cssMaps: Map<string, Record<string, string>> = new Map(),
627
632
  routeRoots?: ReadonlySet<string>,
633
+ /** F183 (`reachedJobs`): only these entries are written; every one when absent. */
634
+ reached?: { planned: ReadonlySet<string>; ssr: ReadonlySet<string> },
628
635
  ): Promise<void> {
629
636
  const imports: string[] = ["import { createElement } from 'react'", "import { renderToString } from 'react-dom/server'"]
630
637
  const entries: string[] = []
@@ -644,17 +651,22 @@ export async function buildJobs(
644
651
  imports.push(reviveSource(`{ ${revived.map((r, i) => `${JSON.stringify(r.id)}: N${i}`).join(', ')} }`))
645
652
  }
646
653
  const hosts = new Set(reviving.map((c) => c.id))
654
+ const jobFiles = new Set<string>() // the staged job modules: the only importers of `brust-job:` (F186)
647
655
  let n = 0
648
656
  for (const c of compiled.values()) {
649
657
  const fns: string[] = []
650
658
  if (c.serverTs !== undefined) {
659
+ // Staged even when unreached: a parent's fused job imports it (`brust-job:<id>`, R34.96).
651
660
  const file = join(dist, 'jobs', `${c.id}.server.ts`)
652
661
  write(file, c.serverTs)
653
662
  stage(sourceOf, file, c)
654
- imports.push(`import * as j${n} from ${JSON.stringify(file)}`)
655
- fns.push(`precompute: j${n}.precompute`)
663
+ jobFiles.add(file).add(realpathSync(file))
664
+ if (reached === undefined || reached.planned.has(c.id)) {
665
+ imports.push(`import * as j${n} from ${JSON.stringify(file)}`)
666
+ fns.push(`precompute: j${n}.precompute`)
667
+ }
656
668
  }
657
- if (isReact(c) && !c.ir.tier.React.client_only) {
669
+ if (isReact(c) && !c.ir.tier.React.client_only && (reached === undefined || reached.ssr.has(c.id))) {
658
670
  imports.push(componentImport(c, `C${n}`))
659
671
  // Ruling 2bf3775a (R1): the island's component id prefixes React's useId on BOTH sides
660
672
  // (the shim's hydrateRoot passes the same prefix), so ids differ across islands.
@@ -672,7 +684,10 @@ export async function buildJobs(
672
684
  define: PRODUCTION,
673
685
  external: JOBS_EXTERNALS,
674
686
  plugins: [
675
- jobImportPlugin((id) => (compiled.get(id)?.serverTs !== undefined ? join(dist, 'jobs', `${id}.server.ts`) : undefined)),
687
+ jobImportPlugin(
688
+ (id) => (compiled.get(id)?.serverTs !== undefined ? join(dist, 'jobs', `${id}.server.ts`) : undefined),
689
+ (importer) => jobFiles.has(importer),
690
+ ),
676
691
  serverOnlyEmptyPlugin(),
677
692
  cssPlugin(cssMaps),
678
693
  workerStorePlugin,
@@ -19,7 +19,7 @@ import { buildCss, CssGraph, directCss, resolveGlobals, routeCssSources } from '
19
19
  import { type ActionsBuildConfig, type CacheBuildConfig, loadBuildConfig } from './config'
20
20
  import { BuildError } from './errors'
21
21
  import { importsStore } from './features'
22
- import { type CacheRecord, type ManifestJson, needsWorkers, tierOf, writeManifest } from './manifest'
22
+ import { type CacheRecord, type ManifestJson, needsWorkers, reachedJobs, tierOf, writeManifest } from './manifest'
23
23
  import { scanRoutes } from './scan'
24
24
  import { type ExprReads, prepareStatic, writeStatic } from './static'
25
25
  import { writeStaticWorker } from './static-worker'
@@ -289,7 +289,7 @@ async function buildInto(
289
289
  const files = [...new Set((routeCss.get(r.id) ?? []).flatMap((s) => (css.file.has(s) ? [css.file.get(s)!] : [])))]
290
290
  if (files.length > 0) r.css = files
291
291
  }
292
- await buildJobs(out, compiled, ctx.sourceOf, appRoot, storeModules(manifest), css.maps, routeRoots)
292
+ await buildJobs(out, compiled, ctx.sourceOf, appRoot, storeModules(manifest), css.maps, routeRoots, reachedJobs(manifest))
293
293
  manifest.actions =
294
294
  o.actions && o.actionsEntry
295
295
  ? { entry: await buildActions(out, o.actionsEntry, css.maps), prefix: o.actions.prefix, maxBodyBytes: o.actions.maxBodyBytes, maxResponseBytes: o.actions.maxResponseBytes, crossSite: o.actions.crossSite }
@@ -95,9 +95,26 @@ export interface ManifestJson {
95
95
 
96
96
  /** F165 (R40.1): whether any request can call a worker. Workers answer four kinds of call
97
97
  * (worker.ts): `loader`, `jobs` (precompute and SSR), `fetch` (the local actions app) and `cache`
98
- * (the adapter). Every component's jobs count, reached by a route or not (F166 prunes those later). */
98
+ * (the adapter). Only the jobs a request can plan count (`reachedJobs`, F183). */
99
99
  export function needsWorkers(m: Pick<ManifestJson, 'routes' | 'components' | 'actions' | 'cache'>): boolean {
100
- return Object.values(m.components).some((c) => c.jobs.length > 0) || m.routes.some((r) => r.loaders.length > 0) || m.actions !== null || m.cache !== undefined
100
+ const planned = [...reachedJobs(m).planned].some((id) => (m.components[id]?.jobs.length ?? 0) > 0)
101
+ return planned || m.routes.some((r) => r.loaders.length > 0) || m.actions !== null || m.cache !== undefined
102
+ }
103
+
104
+ /** F183: the jobs a request can call, as brust-core plans them (`collect_jobs`, pipeline.rs): every job of each
105
+ * route chain component and of each of its direct `children[]` records (`planned`; nothing deeper has a job,
106
+ * `linkNativeChunks`), and the `ssr` of each component one of those jobs targets (`ssr`; the worker runs the
107
+ * target's, handlers.ts). `jobs.js` leaves out every other entry: no request reaches it. */
108
+ export function reachedJobs(m: Pick<ManifestJson, 'routes' | 'components'>): { planned: Set<string>; ssr: Set<string> } {
109
+ const planned = new Set<string>()
110
+ for (const r of m.routes)
111
+ for (const id of r.chain) {
112
+ planned.add(id)
113
+ for (const ch of m.components[id]?.children ?? []) planned.add(ch.id)
114
+ }
115
+ const ssr = new Set<string>()
116
+ for (const id of planned) for (const j of m.components[id]?.jobs ?? []) if (j.kind === 'ssr' && j.target !== undefined) ssr.add(j.target)
117
+ return { planned, ssr }
101
118
  }
102
119
 
103
120
  /** `manifest.cache` / `CONFIG.cache`: the adapter the runtime loads (`cache-adapter/load.ts`). */
@@ -356,6 +373,8 @@ function linkNativeChunks(routes: RouteRecord[], compiled: Map<string, Compiled>
356
373
  const chainIds = new Set(routes.flatMap((r) => r.chain))
357
374
  for (const root of chainIds) {
358
375
  const rec = components[root]!
376
+ // A React root renders its whole subtree itself: whatever native chunks its IR lists are not served.
377
+ if (rec.tier === 'react') continue
359
378
  const linked = new Set(rec.children.map((ch) => ch.id))
360
379
  const seen = new Set([root])
361
380
  const walk = (id: string) => {
@@ -209,11 +209,13 @@ const transpile = (code: string, loader: 'tsx' | 'ts' | 'js') =>
209
209
 
210
210
  /** What of `sources` is not in `published`; empty = the sources are what the published file was built from. */
211
211
  export function integrityGaps(sources: { path: string; text: string }[], published: string): string[] {
212
- const pub = skeleton(transpile(published, 'js'))
212
+ const pubJs = transpile(published, 'js')
213
+ const pub = skeleton(pubJs)
214
+ const pubPairs = exportPairs(pubJs)
213
215
  const gaps: string[] = []
214
216
  for (const s of sources) {
215
217
  const loader = s.path.endsWith('.tsx') ? 'tsx' : 'ts'
216
- const sk = skeleton(transpile(s.text, loader))
218
+ const sk = skeleton(withoutUnstableAliases(transpile(s.text, loader), pub.names, pubPairs))
217
219
  // Import specifiers are module names, which bundling replaces; they are checked as imports instead.
218
220
  for (const im of new Bun.Transpiler({ loader }).scanImports(s.text)) sk.strings.delete(im.path)
219
221
  for (const v of sk.strings) if (!pub.strings.has(v)) gaps.push(`${s.path}: literal ${JSON.stringify(v.startsWith('#') ? v.slice(1) : v).slice(0, 60)}`)
@@ -222,6 +224,82 @@ export function integrityGaps(sources: { path: string; text: string }[], publish
222
224
  return gaps
223
225
  }
224
226
 
227
+
228
+ /** The `local as exported` pairs of the `export { … }` clauses of transpiled JS (`x` alone is `x as x`). */
229
+ function exportPairs(js: string): Set<string> {
230
+ const out = new Set<string>()
231
+ for (const m of js.matchAll(/\bexport\s*\{([^}]*)\}/g)) {
232
+ for (const item of m[1]!.split(',')) {
233
+ const parts = item.trim().split(/\s+as\s+/)
234
+ if (parts[0] && /^[A-Za-z_$][\w$]*$/.test(parts[0])) out.add(`${parts[0]} as ${parts[1] ?? parts[0]}`)
235
+ }
236
+ }
237
+ return out
238
+ }
239
+
240
+ /** P2 (wave A step 0): a source export clause `export { Local as Alias }` whose alias the published file spells
241
+ * `unstable_Alias` (the Radix convention) names the same binding under another export name; an export name carries no
242
+ * behaviour. The alias is dropped from the source text before the name check ONLY when the published file exports the
243
+ * IDENTICAL local binding as EXACTLY `unstable_` + the alias. Any other alias that the published file does not have stays
244
+ * a name difference (a refusal). */
245
+ function withoutUnstableAliases(js: string, pubNames: Set<string>, pubPairs: Set<string>): string {
246
+ return js.replace(/\bexport\s*\{([^}]*)\}/g, (all, body: string) => {
247
+ const items = body.split(',').map((item) => {
248
+ const parts = item.trim().split(/\s+as\s+/)
249
+ const [local, alias] = [parts[0] ?? '', parts[1]]
250
+ if (alias === undefined || pubNames.has(alias)) return item.trim()
251
+ return pubPairs.has(`${local} as unstable_${alias}`) ? local : item.trim()
252
+ })
253
+ return `export { ${items.join(', ')} }`
254
+ })
255
+ }
256
+
257
+ /** P1 (wave A step 0): a published file bundled from SEVERAL sources, none of which is the entry (the `index.ts` is not in
258
+ * the ESM map). Provable only when the published file's one `export { a, b }` clause lists plain names (no alias, no
259
+ * `export *`, no default) and EACH of them is declared by `export function|const|let|class` in exactly one source and
260
+ * EVERY source declares at least one of them: the entry is then a barrel the build writes from those names (identifiers
261
+ * only), never one of the sources chosen by eye. Every source still goes through the integrity check. */
262
+ function barrelOf(files: { path: string; text: string }[], published: string): { path: string; text: string } | undefined {
263
+ let js: string
264
+ try {
265
+ js = transpile(published, 'js')
266
+ } catch {
267
+ return undefined
268
+ }
269
+ if (/\bexport\s+(?:(?:default|function|const|let|var|class)\b|\*)/.test(js)) return undefined
270
+ const clauses = [...js.matchAll(/\bexport\s*\{([^}]*)\}/g)]
271
+ if (clauses.length !== 1) return undefined
272
+ const names: string[] = []
273
+ for (const item of clauses[0]![1]!.split(',')) {
274
+ const n = item.trim()
275
+ if (n === '') continue
276
+ if (!/^[A-Za-z_$][\w$]*$/.test(n)) return undefined // an alias (`a as b`) or anything else
277
+ names.push(n)
278
+ }
279
+ if (names.length === 0 || new Set(names).size !== names.length) return undefined
280
+ const owner = new Map<string, string>()
281
+ const used = new Set<string>()
282
+ for (const name of names) {
283
+ const owners = files.filter((f) => new RegExp(`^export\\s+(?:async\\s+)?(?:function\\*?|const|let|class)\\s+${name.replace(/\$/g, '\\$')}\\b`, 'm').test(f.text))
284
+ if (owners.length !== 1) return undefined
285
+ owner.set(name, owners[0]!.path)
286
+ used.add(owners[0]!.path)
287
+ }
288
+ if (files.some((f) => !used.has(f.path))) return undefined
289
+ // The barrel's specifiers are source-map paths (package-controlled text): only plain path characters, no `..` segment,
290
+ // never absolute; and each is printed as a JSON string, so nothing in it can end the string or the statement.
291
+ const plainPath = (p: string) => /^[A-Za-z0-9_@./-]+$/.test(p) && !p.startsWith('/') && !p.split('/').some((seg) => seg === '..' || seg === '')
292
+ if (files.some((f) => !plainPath(f.path))) return undefined
293
+ const dir = posix.dirname(files[0]!.path)
294
+ const path = posix.join(dir, 'index.ts')
295
+ if (files.some((f) => f.path === path)) return undefined
296
+ const lines = [...used].map((src) => {
297
+ const rel = posix.relative(dir, src).replace(/\.tsx?$/, '')
298
+ return `export { ${names.filter((n) => owner.get(n) === src).join(', ')} } from ${JSON.stringify(rel.startsWith('.') ? rel : `./${rel}`)}`
299
+ })
300
+ return { path, text: `${lines.join('\n')}\n` }
301
+ }
302
+
225
303
  // ---------------------------------------------------------------------------------------------------------------
226
304
 
227
305
  /** Reads one package (real directory `dir`), checks it, and writes its sources under `outRoot`. */
@@ -247,7 +325,11 @@ function writePackage(appRoot: string, dir: string, budget: { bytes: number }):
247
325
  const text = contents[k]
248
326
  if (typeof s !== 'string' || typeof text !== 'string') continue
249
327
  const abs = posix.normalize(posix.join(relative(dir, dirname(mapFile)).split(sep).join('/'), s))
250
- if (abs.startsWith('..') || posix.isAbsolute(abs) || /^[a-z]+:/i.test(s)) return { ok: false, reason: `the source ${s} lies outside the package` }
328
+ if (abs.startsWith('..') || posix.isAbsolute(abs) || posix.isAbsolute(s) || /^[a-z]+:/i.test(s)) return { ok: false, reason: `the source ${s} lies outside the package` }
329
+ // Map paths are package-controlled text and become file names, the entry path and import specifiers the compiler
330
+ // prints: only plain path characters, no `//`, no `..` segment left after normalizing (Mellow, wave A step 0).
331
+ if (!/^[A-Za-z0-9_@./-]+$/.test(s) || s.includes('//') || !/^[A-Za-z0-9_@][A-Za-z0-9_@./-]*$/.test(abs) || abs.split('/').includes('..'))
332
+ return { ok: false, reason: `the source path ${JSON.stringify(s).slice(0, 80)} has characters other than letters, digits and _ @ . / -` }
251
333
  if (!/\.tsx?$/.test(abs)) continue
252
334
  files.push({ path: abs, text })
253
335
  }
@@ -284,7 +366,8 @@ function writePackage(appRoot: string, dir: string, budget: { bytes: number }):
284
366
  const declared = typeof pj.source === 'string' ? posix.normalize(pj.source.replace(/^\.\//, '')) : null
285
367
  const roots = files.filter((f) => !imported.has(f.path))
286
368
  const entrySrc = files.find((f) => f.path === declared) ?? (roots.length === 1 ? roots[0] : undefined)
287
- if (!entrySrc) return { ok: false, reason: `the source map has ${files.length} sources and none is the entry (no \`source\` field, ${roots.length} unimported)` }
369
+ const barrel = entrySrc ? undefined : barrelOf(files, readFileSync(entry, 'utf8'))
370
+ if (!entrySrc && !barrel) return { ok: false, reason: `the source map has ${files.length} sources and none is the entry (no \`source\` field, ${roots.length} unimported)` }
288
371
  // R34.62: the published file must be what these sources were built into.
289
372
  let gaps: string[]
290
373
  try {
@@ -300,7 +383,8 @@ function writePackage(appRoot: string, dir: string, budget: { bytes: number }):
300
383
  const hash = createHash('sha256').update(relative(appRoot, dir).split(sep).join('/')).digest('hex').slice(0, 16)
301
384
  const outRel = posix.join(PKG_SRC_DIR, `p-${hash}`)
302
385
  const own = resolve(appRoot, PKG_SRC_DIR) + sep
303
- const targets = files.map((f) => ({ f, target: resolve(appRoot, outRel, f.path) }))
386
+ const written = barrel ? [...files, barrel] : files
387
+ const targets = written.map((f) => ({ f, target: resolve(appRoot, outRel, f.path) }))
304
388
  const escaped = targets.find((t) => !t.target.startsWith(own))
305
389
  if (escaped) return { ok: false, reason: `the source ${escaped.f.path} would be written outside ${PKG_SRC_DIR}` }
306
390
  for (const { f, target } of targets) {
@@ -311,7 +395,7 @@ function writePackage(appRoot: string, dir: string, budget: { bytes: number }):
311
395
  writeFileSync(target, f.text)
312
396
  }
313
397
  budget.bytes += bytes
314
- return { ok: true, dir: outRel, entry: posix.join(outRel, entrySrc.path), imports: [...bare].sort() }
398
+ return { ok: true, dir: outRel, entry: posix.join(outRel, (entrySrc ?? barrel)!.path), imports: [...bare].sort() }
315
399
  }
316
400
 
317
401
  /**
@@ -2,15 +2,25 @@
2
2
  // shadcn's own `init` does not detect brust, so this writes what `add` needs (components.json, the `@/*` path),
3
3
  // installs the four packages the components import, and runs ONE pinned shadcn CLI for the theme and the components.
4
4
  // Every child process is spawned from an argv array, never through a shell; the runner is injected for tests.
5
- import { existsSync, readFileSync, writeFileSync } from 'node:fs'
5
+ import { existsSync, lstatSync, readFileSync, writeFileSync } from 'node:fs'
6
6
  import { isAbsolute, join, relative, resolve } from 'node:path'
7
7
  import { type ObjectNode, raw, readObject } from './jsonc'
8
8
 
9
9
  /** The shadcn CLI version this command runs (R41.6). A release that moves it re-runs the transcript. */
10
10
  export const SHADCN_VERSION = '4.21.4'
11
11
 
12
- /** The packages the components import (R41.5). */
13
- export const SHADCN_DEPS = ['radix-ui', 'lucide-react', 'class-variance-authority', 'tw-animate-css'] as const
12
+ /**
13
+ * The packages the components import (R41.5), each pinned to the exact version the transcript ran
14
+ * (`docs/transcripts/shadcn-init-guide.md`, F181). They move together with `SHADCN_VERSION`: a release that moves one
15
+ * re-runs the transcript. A package the project already depends on, at any version, is left alone.
16
+ */
17
+ export const SHADCN_DEP_PINS = {
18
+ 'radix-ui': '1.8.1',
19
+ 'lucide-react': '1.57.0',
20
+ 'class-variance-authority': '0.7.1',
21
+ 'tw-animate-css': '1.4.0',
22
+ } as const
23
+ export const SHADCN_DEPS = Object.keys(SHADCN_DEP_PINS) as (keyof typeof SHADCN_DEP_PINS)[]
14
24
 
15
25
  /** Runs `argv` in `cwd` with the terminal attached; resolves to the exit code. Never a shell string. */
16
26
  export type Runner = (argv: string[], cwd: string) => Promise<number>
@@ -32,6 +42,25 @@ const REGISTRY_URL = /^https:\/\/[^\s]+$/
32
42
  const VERSION = /^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?$/
33
43
  const COLOR = /^[a-z]+$/
34
44
 
45
+ /** True for a symlink, also a dangling one (`existsSync` follows links and says false for those). */
46
+ function isLink(path: string): boolean {
47
+ try {
48
+ return lstatSync(path).isSymbolicLink()
49
+ } catch {
50
+ return false
51
+ }
52
+ }
53
+
54
+ /** The name a registry URL installs: its last path segment without `.json`; undefined when it is not a plain name. */
55
+ function urlItemName(url: string): string | undefined {
56
+ try {
57
+ const seg = new URL(url).pathname.split('/').filter(Boolean).pop()?.replace(/\.json$/, '')
58
+ return seg !== undefined && COMPONENT.test(seg) ? seg : undefined
59
+ } catch {
60
+ return undefined
61
+ }
62
+ }
63
+
35
64
  /** The `components.json` of the tested fixture (`tests/fixtures/shadcn/components.json`), for `css` and `baseColor` (R41.2). */
36
65
  export function componentsJson(css: string, baseColor: string): string {
37
66
  return `{
@@ -142,6 +171,12 @@ export async function shadcnInit(o: InitOptions): Promise<number> {
142
171
  if (!COLOR.test(baseColor)) return fail2(`--base-color ${JSON.stringify(baseColor)} must be a lowercase colour name`)
143
172
  const entry = tailwindEntry(root, o.css)
144
173
  if ('error' in entry) return fail2(entry.error)
174
+ // F181: never write through a symlink (the target may be outside the project, e.g. a shared tsconfig). Fail-safe:
175
+ // refuse before the first write, even with --force; the reader edits the real file by hand.
176
+ const cj = join(root, 'components.json')
177
+ const tsPath = join(root, 'tsconfig.json')
178
+ if (isLink(tsPath)) return fail2('tsconfig.json is a symbolic link; refusing to write through it. Add "@/*": ["./*"] to compilerOptions.paths of the real file yourself, then run again')
179
+ if (isLink(cj) && (!existsSync(cj) || o.force)) return fail2('components.json is a symbolic link; refusing to write through it. Replace it with a real file or remove the link, then run again')
145
180
 
146
181
  const report = (name: string, step: Step, why = ''): void => out(`${step === 'done' ? '✓' : step === 'skipped' ? '-' : '✗'} ${name}: ${step}${why ? ` (${why})` : ''}`)
147
182
  const stop = (name: string, code: number): number => {
@@ -151,14 +186,12 @@ export async function shadcnInit(o: InitOptions): Promise<number> {
151
186
  }
152
187
 
153
188
  // R41.2: components.json.
154
- const cj = join(root, 'components.json')
155
189
  if (!existsSync(cj) || o.force) {
156
190
  writeFileSync(cj, componentsJson(entry.css, baseColor))
157
191
  report('components.json', 'done', entry.css)
158
192
  } else report('components.json', 'skipped', 'exists; --force replaces it')
159
193
 
160
194
  // R41.4: the `@/*` path.
161
- const tsPath = join(root, 'tsconfig.json')
162
195
  if (!existsSync(tsPath)) {
163
196
  report('tsconfig.json', 'skipped', `no tsconfig.json; add ${JSON.stringify({ compilerOptions: { paths: { '@/*': ['./*'] } } })}`)
164
197
  } else {
@@ -176,9 +209,10 @@ export async function shadcnInit(o: InitOptions): Promise<number> {
176
209
  const missing = SHADCN_DEPS.filter((d) => !have[d])
177
210
  if (missing.length === 0) report('dependencies', 'skipped', 'all four are installed')
178
211
  else {
179
- const code = await o.run(['bun', 'add', ...missing], root)
212
+ const specs = missing.map((d) => `${d}@${SHADCN_DEP_PINS[d]}`)
213
+ const code = await o.run(['bun', 'add', ...specs], root)
180
214
  if (code !== 0) return stop('bun add', code)
181
- report('dependencies', 'done', missing.join(' '))
215
+ report('dependencies', 'done', specs.join(' '))
182
216
  }
183
217
 
184
218
  // R41.6 / R41.7: the pinned shadcn CLI. `bun x` is `bunx`; argv only.
@@ -190,9 +224,16 @@ export async function shadcnInit(o: InitOptions): Promise<number> {
190
224
  if (code !== 0) return stop('shadcn add index', code)
191
225
  report('theme', 'done', `shadcn@${version} add index`)
192
226
  }
193
- // A component whose file is already in components/ui is not added again (idempotent); a URL always is.
194
- const todo = o.components.filter((c) => o.force || REGISTRY_URL.test(c) || !existsSync(join(root, 'components/ui', `${c}.tsx`)))
195
- for (const c of o.components) if (!todo.includes(c)) report(c, 'skipped', 'components/ui already has it')
227
+ // A component whose file is already in components/ui is not added again (idempotent). A registry URL is judged by
228
+ // the item name in its path (`.../acme-card.json` → `acme-card`), looked up in components/ui and components.
229
+ const present = (c: string): boolean => {
230
+ const name = REGISTRY_URL.test(c) ? urlItemName(c) : c
231
+ if (name === undefined) return false
232
+ return existsSync(join(root, 'components/ui', `${name}.tsx`)) || (name !== c && existsSync(join(root, 'components', `${name}.tsx`)))
233
+ }
234
+ const todo = o.components.filter((c) => o.force || !present(c))
235
+ for (const c of o.components) if (!todo.includes(c)) report(c, 'skipped', REGISTRY_URL.test(c) ? 'its item is already in components; --force adds it again' : 'components/ui already has it')
236
+ for (const c of todo) if (REGISTRY_URL.test(c)) out(`warning shadcn-init ${c} is third-party code: it is written into your project and runs in your build and in the browser. Read it before you ship`)
196
237
  if (todo.length > 0) {
197
238
  const code = await o.run(shadcn('add', ...todo, '-y'), root)
198
239
  if (code !== 0) return stop(`shadcn add ${todo.join(' ')}`, code)