@nudojs/env 0.4.0 → 0.4.2-beta.0

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.
@@ -30,11 +30,32 @@ function undef() {
30
30
  return makeAbs({ k: "unknown" }, termLit(void 0), void 0, "exact");
31
31
  }
32
32
  function nullLit() {
33
- return makeAbs({ k: "unknown" }, termLit(null), void 0, "exact");
33
+ return makeAbs(
34
+ { k: "brand", name: "null", shape: makeAbs({ k: "unknown" }, termLit(null), void 0, "exact") },
35
+ termLit(null),
36
+ void 0,
37
+ "exact"
38
+ );
34
39
  }
35
40
  function anyAbs() {
36
41
  return makeAbs({ k: "any" }, void 0, void 0, "path");
37
42
  }
43
+ function dateAbs() {
44
+ return brandOf("Date", objAbs({
45
+ getTime: envFn([], num()),
46
+ valueOf: envFn([], num()),
47
+ toISOString: envFn([], str())
48
+ }));
49
+ }
50
+ function openObjBrand(name, index, entries = {}) {
51
+ const shape = {
52
+ k: "obj",
53
+ slots: slotsOf(entries),
54
+ open: true,
55
+ index
56
+ };
57
+ return makeAbs({ k: "brand", name, shape: makeAbs(shape, void 0, void 0, "exact") }, void 0, void 0, "path");
58
+ }
38
59
  function arrOf(element) {
39
60
  return makeAbs({ k: "arr", element }, void 0, void 0, "exact");
40
61
  }
@@ -403,6 +424,8 @@ function defineEnv() {
403
424
  export {
404
425
  undef,
405
426
  nullLit,
427
+ dateAbs,
428
+ openObjBrand,
406
429
  arrOf,
407
430
  tupleOf,
408
431
  unionOf,
package/dist/es.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  defineEnv
3
- } from "./chunk-6RZUMVN5.js";
3
+ } from "./chunk-KRMQSDG3.js";
4
4
  export {
5
5
  defineEnv
6
6
  };
package/dist/node.js CHANGED
@@ -1,17 +1,19 @@
1
1
  import {
2
2
  arrOf,
3
3
  brandOf,
4
+ dateAbs,
4
5
  defineEnv,
5
6
  envFn,
6
7
  envFnVariadic,
7
8
  nullLit,
8
9
  objAbs,
10
+ openObjBrand,
9
11
  prim,
10
12
  promiseOf,
11
13
  tupleOf,
12
14
  undef,
13
15
  unionOf
14
- } from "./chunk-6RZUMVN5.js";
16
+ } from "./chunk-KRMQSDG3.js";
15
17
 
16
18
  // src/node.ts
17
19
  import {
@@ -39,7 +41,9 @@ function defineEnv2() {
39
41
  const BufferInstance = brandOf(
40
42
  "Buffer",
41
43
  objAbs({
42
- toString: envFn([prim.str()], prim.str()),
44
+ toString: envFn([prim.str(), prim.num(), prim.num()], prim.str(), void 0, {
45
+ params: ["encoding?", "start?", "end?"]
46
+ }),
43
47
  toJSON: envFn(
44
48
  [],
45
49
  objAbs({ type: prim.str(), data: arrOf(prim.num()) })
@@ -47,7 +51,7 @@ function defineEnv2() {
47
51
  length: prim.num(),
48
52
  slice: envFn([prim.num(), prim.num()], brandOf("Buffer")),
49
53
  copy: envFn(
50
- [prim.unknown, prim.num(), prim.num(), prim.num()],
54
+ [brandOf("Buffer"), prim.num(), prim.num(), prim.num()],
51
55
  prim.num()
52
56
  ),
53
57
  write: envFn(
@@ -73,10 +77,138 @@ function defineEnv2() {
73
77
  })
74
78
  );
75
79
  const bufferBrand = BufferInstance;
80
+ const errOrNull = unionOf(brandOf("Error"), nullLit());
81
+ const dateOr = dateAbs();
82
+ const encodingOptions = objAbs({
83
+ encoding: { value: prim.str(), optional: true },
84
+ flag: { value: prim.str(), optional: true }
85
+ });
86
+ const encodingOptionsArg = unionOf(prim.str(), encodingOptions);
87
+ const statOptions = objAbs({
88
+ bigint: { value: prim.bool(), optional: true },
89
+ throwIfNoEntry: { value: prim.bool(), optional: true }
90
+ });
91
+ const mkdirOptions = objAbs({
92
+ recursive: { value: prim.bool(), optional: true },
93
+ mode: { value: prim.num(), optional: true }
94
+ });
95
+ const rmOptions = objAbs({
96
+ recursive: { value: prim.bool(), optional: true },
97
+ force: { value: prim.bool(), optional: true },
98
+ maxRetries: { value: prim.num(), optional: true },
99
+ retryDelay: { value: prim.num(), optional: true }
100
+ });
101
+ const readdirOptions = objAbs({
102
+ encoding: { value: prim.str(), optional: true },
103
+ withFileTypes: { value: prim.bool(), optional: true },
104
+ recursive: { value: prim.bool(), optional: true }
105
+ });
106
+ const inspectOptions = objAbs({
107
+ showHidden: { value: prim.bool(), optional: true },
108
+ depth: { value: prim.num(), optional: true },
109
+ colors: { value: prim.bool(), optional: true },
110
+ customInspect: { value: prim.bool(), optional: true },
111
+ maxArrayLength: { value: prim.num(), optional: true },
112
+ breakLength: { value: prim.num(), optional: true },
113
+ compact: { value: prim.bool(), optional: true },
114
+ sorted: { value: prim.bool(), optional: true }
115
+ });
116
+ const querystringOptions = objAbs({
117
+ maxKeys: { value: prim.num(), optional: true }
118
+ });
119
+ const anyParam = prim.any();
120
+ const callbackFnBrand = brandOf(
121
+ "CallbackFn",
122
+ envFnVariadic(anyParam, undef(), { restName: "...args" })
123
+ );
124
+ const streamOptions = objAbs({
125
+ highWaterMark: { value: prim.num(), optional: true },
126
+ objectMode: { value: prim.bool(), optional: true },
127
+ encoding: { value: prim.str(), optional: true },
128
+ autoDestroy: { value: prim.bool(), optional: true },
129
+ emitClose: { value: prim.bool(), optional: true }
130
+ });
131
+ const streamIoMethods = {
132
+ on: envFn([prim.str(), callbackFnBrand], brandOf("Stream")),
133
+ once: envFn([prim.str(), callbackFnBrand], brandOf("Stream")),
134
+ off: envFn([prim.str(), callbackFnBrand], brandOf("Stream")),
135
+ emit: envFn([prim.str(), anyParam], prim.bool(), void 0, {
136
+ params: ["event", "...args"]
137
+ }),
138
+ pipe: envFn([brandOf("Writable")], brandOf("Writable")),
139
+ destroy: envFn([errOrNull], undef(), void 0, { params: ["error?"] }),
140
+ read: envFn([prim.num()], unionOf(prim.str(), bufferBrand, nullLit())),
141
+ write: envFn([unionOf(prim.str(), bufferBrand)], prim.bool()),
142
+ end: envFn([unionOf(prim.str(), bufferBrand), callbackFnBrand], undef(), void 0, {
143
+ params: ["chunk?", "callback?"]
144
+ }),
145
+ pause: envFn([], brandOf("Stream")),
146
+ resume: envFn([], brandOf("Stream")),
147
+ setEncoding: envFn([prim.str()], brandOf("Stream"))
148
+ };
149
+ const chunk = unionOf(prim.str(), bufferBrand);
150
+ const streamCallback = envFn([errOrNull], undef(), void 0, { params: ["error?"] });
151
+ const transformHook = envFn(
152
+ [chunk, prim.str(), envFn([errOrNull, chunk], undef(), void 0, { params: ["error?", "data?"] })],
153
+ undef(),
154
+ void 0,
155
+ { params: ["chunk", "encoding", "callback"] }
156
+ );
157
+ const writeHook = envFn(
158
+ [chunk, prim.str(), envFn([errOrNull], undef(), void 0, { params: ["error?"] })],
159
+ undef(),
160
+ void 0,
161
+ { params: ["chunk", "encoding", "callback"] }
162
+ );
163
+ const readHook = envFn([prim.num()], undef(), void 0, { params: ["size"] });
164
+ const finalHook = envFn([streamCallback], undef(), void 0, { params: ["callback"] });
165
+ const flushHook = envFn([streamCallback], undef(), void 0, { params: ["callback"] });
166
+ const streamBaseSlots = {
167
+ highWaterMark: { value: prim.num(), optional: true },
168
+ objectMode: { value: prim.bool(), optional: true },
169
+ encoding: { value: prim.str(), optional: true },
170
+ autoDestroy: { value: prim.bool(), optional: true },
171
+ emitClose: { value: prim.bool(), optional: true }
172
+ };
173
+ const streamHooks = {
174
+ transform: { value: transformHook, optional: true },
175
+ flush: { value: flushHook, optional: true },
176
+ read: { value: readHook, optional: true },
177
+ write: { value: writeHook, optional: true },
178
+ final: { value: finalHook, optional: true },
179
+ construct: { value: streamCallback, optional: true },
180
+ destroy: { value: envFn([errOrNull, streamCallback], undef(), void 0, { params: ["error", "callback"] }), optional: true }
181
+ };
182
+ const eventEmitterOptions = objAbs({
183
+ captureRejections: { value: prim.bool(), optional: true }
184
+ });
185
+ const promiseFnBrand = brandOf(
186
+ "PromiseFn",
187
+ envFnVariadic(anyParam, promiseOf(anyParam), { restName: "...args" })
188
+ );
189
+ const anyValueBrand = brandOf("Value");
190
+ const platformPathMethods = () => ({
191
+ join: envFnVariadic(prim.str(), prim.str(), {
192
+ restName: "...paths"
193
+ }),
194
+ resolve: envFnVariadic(prim.str(), prim.str(), {
195
+ restName: "...paths"
196
+ }),
197
+ dirname: envFn([prim.str()], prim.str()),
198
+ basename: envFn([prim.str(), prim.str()], prim.str(), void 0, {
199
+ params: ["path", "ext?"]
200
+ }),
201
+ extname: envFn([prim.str()], prim.str()),
202
+ normalize: envFn([prim.str()], prim.str()),
203
+ isAbsolute: envFn([prim.str()], prim.bool()),
204
+ relative: envFn([prim.str(), prim.str()], prim.str()),
205
+ sep: prim.str(),
206
+ delimiter: prim.str()
207
+ });
76
208
  const fsModule = {
77
209
  // encoding 字面量 → string;否则 string|Buffer(TS 重载近似)
78
210
  readFileSync: envFn(
79
- [prim.str(), unionOf(prim.str(), objAbs({}))],
211
+ [prim.str(), encodingOptionsArg],
80
212
  unionOf(prim.str(), bufferBrand),
81
213
  (args) => {
82
214
  const enc = args[1];
@@ -88,42 +220,81 @@ function defineEnv2() {
88
220
  return prim.str();
89
221
  }
90
222
  return unionOf(prim.str(), bufferBrand);
91
- }
223
+ },
224
+ { params: ["path", "options?"] }
92
225
  ),
93
226
  writeFileSync: envFn(
94
- [prim.str(), unionOf(prim.str(), bufferBrand)],
95
- undef()
227
+ [prim.str(), unionOf(prim.str(), bufferBrand), encodingOptionsArg],
228
+ undef(),
229
+ void 0,
230
+ { params: ["path", "data", "options?"] }
96
231
  ),
97
232
  appendFileSync: envFn(
98
- [prim.str(), unionOf(prim.str(), bufferBrand)],
99
- undef()
233
+ [prim.str(), unionOf(prim.str(), bufferBrand), encodingOptionsArg],
234
+ undef(),
235
+ void 0,
236
+ { params: ["path", "data", "options?"] }
100
237
  ),
101
238
  existsSync: envFn([prim.str()], prim.bool()),
102
- mkdirSync: envFn([prim.str(), prim.unknown], unionOf(prim.str(), undef())),
239
+ mkdirSync: envFn(
240
+ [prim.str(), mkdirOptions],
241
+ unionOf(prim.str(), undef()),
242
+ void 0,
243
+ { params: ["path", "options?"] }
244
+ ),
103
245
  rmdirSync: envFn([prim.str()], undef()),
104
- rmSync: envFn([prim.str(), prim.unknown], undef()),
246
+ rmSync: envFn(
247
+ [prim.str(), rmOptions],
248
+ undef(),
249
+ void 0,
250
+ { params: ["path", "options?"] }
251
+ ),
105
252
  unlinkSync: envFn([prim.str()], undef()),
106
253
  renameSync: envFn([prim.str(), prim.str()], undef()),
107
254
  copyFileSync: envFn([prim.str(), prim.str()], undef()),
108
255
  statSync: envFn(
109
- [prim.str()],
256
+ [prim.str(), statOptions],
110
257
  objAbs({
111
258
  isFile: envFn([], prim.bool()),
112
259
  isDirectory: envFn([], prim.bool()),
113
260
  isSymbolicLink: envFn([], prim.bool()),
261
+ isBlockDevice: envFn([], prim.bool()),
262
+ isCharacterDevice: envFn([], prim.bool()),
263
+ isFIFO: envFn([], prim.bool()),
264
+ isSocket: envFn([], prim.bool()),
114
265
  size: prim.num(),
115
- mtime: prim.unknown,
116
- ctime: prim.unknown,
117
- atime: prim.unknown,
118
- birthtime: prim.unknown,
266
+ mtime: dateOr,
267
+ ctime: dateOr,
268
+ atime: dateOr,
269
+ birthtime: dateOr,
270
+ mtimeMs: prim.num(),
271
+ ctimeMs: prim.num(),
272
+ atimeMs: prim.num(),
273
+ birthtimeMs: prim.num(),
119
274
  mode: prim.num(),
120
275
  uid: prim.num(),
121
- gid: prim.num()
122
- })
276
+ gid: prim.num(),
277
+ ino: prim.num(),
278
+ dev: prim.num(),
279
+ nlink: prim.num()
280
+ }),
281
+ void 0,
282
+ { params: ["path", "options?"] }
123
283
  ),
124
284
  readdirSync: envFn(
125
- [prim.str(), prim.unknown],
126
- arrOf(unionOf(prim.str(), prim.unknown))
285
+ [prim.str(), readdirOptions],
286
+ // brand 名避免 `string | Dirent[]` 的结合歧义(真实是 (string|Dirent)[])
287
+ brandOf(
288
+ "Array<string | Dirent>",
289
+ arrOf(unionOf(prim.str(), brandOf("Dirent", objAbs({
290
+ name: prim.str(),
291
+ isFile: envFn([], prim.bool()),
292
+ isDirectory: envFn([], prim.bool()),
293
+ isSymbolicLink: envFn([], prim.bool())
294
+ }))))
295
+ ),
296
+ void 0,
297
+ { params: ["path", "options?"] }
127
298
  ),
128
299
  realpathSync: envFn([prim.str()], prim.str()),
129
300
  readlinkSync: envFn([prim.str()], prim.str()),
@@ -134,97 +305,97 @@ function defineEnv2() {
134
305
  // Callback-style async on `fs` / `node:fs` (Node actual API).
135
306
  // Promise APIs live only under fs.promises / node:fs/promises.
136
307
  readFile: envFn(
137
- [prim.str(), prim.unknown, prim.unknown],
308
+ [prim.str(), encodingOptionsArg, callbackFnBrand],
138
309
  undef(),
139
310
  void 0,
140
311
  { params: ["path", "options?", "callback"] }
141
312
  ),
142
313
  writeFile: envFn(
143
- [prim.str(), unionOf(prim.str(), bufferBrand), prim.unknown],
314
+ [prim.str(), unionOf(prim.str(), bufferBrand), encodingOptionsArg, callbackFnBrand],
144
315
  undef(),
145
316
  void 0,
146
- { params: ["path", "data", "callback"] }
317
+ { params: ["path", "data", "options?", "callback"] }
147
318
  ),
148
319
  mkdir: envFn(
149
- [prim.str(), prim.unknown, prim.unknown],
320
+ [prim.str(), mkdirOptions, callbackFnBrand],
150
321
  undef(),
151
322
  void 0,
152
323
  { params: ["path", "options?", "callback"] }
153
324
  ),
154
325
  rm: envFn(
155
- [prim.str(), prim.unknown, prim.unknown],
326
+ [prim.str(), rmOptions, callbackFnBrand],
156
327
  undef(),
157
328
  void 0,
158
329
  { params: ["path", "options?", "callback"] }
159
330
  ),
160
331
  stat: envFn(
161
- [prim.str(), prim.unknown, prim.unknown],
332
+ [prim.str(), statOptions, callbackFnBrand],
162
333
  undef(),
163
334
  void 0,
164
335
  { params: ["path", "options?", "callback"] }
165
336
  ),
166
337
  readdir: envFn(
167
- [prim.str(), prim.unknown, prim.unknown],
338
+ [prim.str(), readdirOptions, callbackFnBrand],
168
339
  undef(),
169
340
  void 0,
170
341
  { params: ["path", "options?", "callback"] }
171
342
  ),
172
343
  access: envFn(
173
- [prim.str(), prim.unknown, prim.unknown],
344
+ [prim.str(), prim.num(), callbackFnBrand],
174
345
  undef(),
175
346
  void 0,
176
347
  { params: ["path", "mode?", "callback"] }
177
348
  ),
178
349
  appendFile: envFn(
179
- [prim.str(), unionOf(prim.str(), bufferBrand), prim.unknown],
350
+ [prim.str(), unionOf(prim.str(), bufferBrand), encodingOptionsArg, callbackFnBrand],
180
351
  undef(),
181
352
  void 0,
182
- { params: ["path", "data", "callback"] }
353
+ { params: ["path", "data", "options?", "callback"] }
183
354
  ),
184
355
  unlink: envFn(
185
- [prim.str(), prim.unknown, prim.unknown],
356
+ [prim.str(), callbackFnBrand],
186
357
  undef(),
187
358
  void 0,
188
- { params: ["path", "options?", "callback"] }
359
+ { params: ["path", "callback"] }
189
360
  ),
190
361
  rename: envFn(
191
- [prim.str(), prim.str(), prim.unknown],
362
+ [prim.str(), prim.str(), callbackFnBrand],
192
363
  undef(),
193
364
  void 0,
194
365
  { params: ["oldPath", "newPath", "callback"] }
195
366
  ),
196
367
  copyFile: envFn(
197
- [prim.str(), prim.str(), prim.unknown],
368
+ [prim.str(), prim.str(), callbackFnBrand],
198
369
  undef(),
199
370
  void 0,
200
371
  { params: ["src", "dest", "callback"] }
201
372
  ),
202
373
  realpath: envFn(
203
- [prim.str(), prim.unknown, prim.unknown],
374
+ [prim.str(), encodingOptionsArg, callbackFnBrand],
204
375
  undef(),
205
376
  void 0,
206
377
  { params: ["path", "options?", "callback"] }
207
378
  ),
208
379
  readlink: envFn(
209
- [prim.str(), prim.unknown, prim.unknown],
380
+ [prim.str(), encodingOptionsArg, callbackFnBrand],
210
381
  undef(),
211
382
  void 0,
212
383
  { params: ["path", "options?", "callback"] }
213
384
  ),
214
385
  symlink: envFn(
215
- [prim.str(), prim.str(), prim.unknown, prim.unknown],
386
+ [prim.str(), prim.str(), prim.str(), callbackFnBrand],
216
387
  undef(),
217
388
  void 0,
218
389
  { params: ["target", "path", "type?", "callback"] }
219
390
  ),
220
391
  chmod: envFn(
221
- [prim.str(), prim.num(), prim.unknown],
392
+ [prim.str(), prim.num(), callbackFnBrand],
222
393
  undef(),
223
394
  void 0,
224
395
  { params: ["path", "mode", "callback"] }
225
396
  ),
226
397
  open: envFn(
227
- [prim.str(), prim.unknown, prim.unknown],
398
+ [prim.str(), unionOf(prim.str(), prim.num()), callbackFnBrand],
228
399
  undef(),
229
400
  void 0,
230
401
  { params: ["path", "flags?", "callback"] }
@@ -232,36 +403,77 @@ function defineEnv2() {
232
403
  };
233
404
  const fsPromisesModule = {
234
405
  readFile: envFn(
235
- [prim.str(), prim.unknown],
236
- promiseOf(unionOf(prim.str(), bufferBrand))
406
+ [prim.str(), encodingOptionsArg],
407
+ promiseOf(unionOf(prim.str(), bufferBrand)),
408
+ void 0,
409
+ { params: ["path", "options?"] }
237
410
  ),
238
411
  writeFile: envFn(
239
- [prim.str(), unionOf(prim.str(), bufferBrand)],
240
- promiseOf(undef())
412
+ [prim.str(), unionOf(prim.str(), bufferBrand), encodingOptionsArg],
413
+ promiseOf(undef()),
414
+ void 0,
415
+ { params: ["path", "data", "options?"] }
241
416
  ),
242
417
  mkdir: envFn(
243
- [prim.str(), prim.unknown],
244
- promiseOf(unionOf(prim.str(), undef()))
418
+ [prim.str(), mkdirOptions],
419
+ promiseOf(unionOf(prim.str(), undef())),
420
+ void 0,
421
+ { params: ["path", "options?"] }
422
+ ),
423
+ rm: envFn(
424
+ [prim.str(), rmOptions],
425
+ promiseOf(undef()),
426
+ void 0,
427
+ { params: ["path", "options?"] }
428
+ ),
429
+ stat: envFn(
430
+ [prim.str(), statOptions],
431
+ promiseOf(objAbs({
432
+ isFile: envFn([], prim.bool()),
433
+ isDirectory: envFn([], prim.bool()),
434
+ isSymbolicLink: envFn([], prim.bool()),
435
+ size: prim.num(),
436
+ mtime: dateOr,
437
+ ctime: dateOr,
438
+ atime: dateOr,
439
+ birthtime: dateOr,
440
+ mode: prim.num(),
441
+ uid: prim.num(),
442
+ gid: prim.num()
443
+ })),
444
+ void 0,
445
+ { params: ["path", "options?"] }
245
446
  ),
246
- rm: envFn([prim.str(), prim.unknown], promiseOf(undef())),
247
- stat: envFn([prim.str()], promiseOf(prim.unknown)),
248
447
  readdir: envFn(
249
- [prim.str(), prim.unknown],
250
- promiseOf(arrOf(prim.unknown))
448
+ [prim.str(), readdirOptions],
449
+ promiseOf(brandOf(
450
+ "Array<string | Dirent>",
451
+ arrOf(unionOf(prim.str(), brandOf("Dirent")))
452
+ )),
453
+ void 0,
454
+ { params: ["path", "options?"] }
251
455
  ),
252
456
  access: envFn([prim.str(), prim.num()], promiseOf(undef())),
253
457
  appendFile: envFn(
254
- [prim.str(), unionOf(prim.str(), bufferBrand)],
255
- promiseOf(undef())
458
+ [prim.str(), unionOf(prim.str(), bufferBrand), encodingOptionsArg],
459
+ promiseOf(undef()),
460
+ void 0,
461
+ { params: ["path", "data", "options?"] }
256
462
  ),
257
463
  unlink: envFn([prim.str()], promiseOf(undef())),
258
464
  rename: envFn([prim.str(), prim.str()], promiseOf(undef())),
259
465
  copyFile: envFn([prim.str(), prim.str()], promiseOf(undef())),
260
- realpath: envFn([prim.str()], promiseOf(prim.str())),
261
- readlink: envFn([prim.str()], promiseOf(prim.str())),
262
- symlink: envFn([prim.str(), prim.str()], promiseOf(undef())),
466
+ realpath: envFn([prim.str(), encodingOptionsArg], promiseOf(prim.str()), void 0, {
467
+ params: ["path", "options?"]
468
+ }),
469
+ readlink: envFn([prim.str(), encodingOptionsArg], promiseOf(prim.str()), void 0, {
470
+ params: ["path", "options?"]
471
+ }),
472
+ symlink: envFn([prim.str(), prim.str(), prim.str()], promiseOf(undef()), void 0, {
473
+ params: ["target", "path", "type?"]
474
+ }),
263
475
  chmod: envFn([prim.str(), prim.num()], promiseOf(undef())),
264
- open: envFn([prim.str(), prim.str()], promiseOf(prim.unknown))
476
+ open: envFn([prim.str(), prim.str()], promiseOf(brandOf("FileHandle")))
265
477
  };
266
478
  const strImpl1Abs = (fn) => (args) => {
267
479
  const a = absStr(args[0]);
@@ -332,11 +544,21 @@ function defineEnv2() {
332
544
  });
333
545
  }
334
546
  ),
335
- format: envFn([objAbs({})], prim.str()),
547
+ format: envFn(
548
+ [objAbs({
549
+ root: { value: prim.str(), optional: true },
550
+ dir: { value: prim.str(), optional: true },
551
+ base: { value: prim.str(), optional: true },
552
+ name: { value: prim.str(), optional: true },
553
+ ext: { value: prim.str(), optional: true }
554
+ })],
555
+ prim.str()
556
+ ),
557
+ // 常量:平台相关字面量在 defineEnv 时可具体化
336
558
  sep: prim.str(),
337
559
  delimiter: prim.str(),
338
- posix: prim.unknown,
339
- win32: prim.unknown
560
+ posix: brandOf("path.PlatformPath", objAbs(platformPathMethods())),
561
+ win32: brandOf("path.PlatformPath", objAbs(platformPathMethods()))
340
562
  };
341
563
  const osModule = {
342
564
  platform: envFn([], prim.str()),
@@ -354,7 +576,20 @@ function defineEnv2() {
354
576
  freemem: envFn([], prim.num()),
355
577
  uptime: envFn([], prim.num()),
356
578
  loadavg: envFn([], tupleOf([prim.num(), prim.num(), prim.num()])),
357
- networkInterfaces: envFn([], prim.unknown),
579
+ networkInterfaces: envFn(
580
+ [],
581
+ openObjBrand(
582
+ "Record<string, NetworkInterfaceInfo[]>",
583
+ { key: prim.str(), value: arrOf(objAbs({
584
+ address: prim.str(),
585
+ netmask: prim.str(),
586
+ family: prim.str(),
587
+ mac: prim.str(),
588
+ internal: prim.bool(),
589
+ cidr: unionOf(prim.str(), nullLit())
590
+ })) }
591
+ )
592
+ ),
358
593
  userInfo: envFn(
359
594
  [],
360
595
  objAbs({
@@ -415,15 +650,23 @@ function defineEnv2() {
415
650
  { params: ["href", "base?"] }
416
651
  ),
417
652
  URLSearchParams: envFn(
418
- [prim.unknown],
653
+ [unionOf(
654
+ prim.str(),
655
+ openObjBrand("Record<string, string>", { key: prim.str(), value: prim.str() }),
656
+ arrOf(arrOf(prim.str()))
657
+ )],
419
658
  objAbs({
420
659
  get: envFn([prim.str()], unionOf(prim.str(), nullLit())),
660
+ getAll: envFn([prim.str()], arrOf(prim.str())),
421
661
  has: envFn([prim.str()], prim.bool()),
422
662
  set: envFn([prim.str(), prim.str()], undef()),
423
663
  append: envFn([prim.str(), prim.str()], undef()),
424
664
  delete: envFn([prim.str()], undef()),
425
- toString: envFn([], prim.str())
426
- })
665
+ toString: envFn([], prim.str()),
666
+ size: prim.num()
667
+ }),
668
+ void 0,
669
+ { params: ["init?"] }
427
670
  ),
428
671
  fileURLToPath: envFn([prim.str()], prim.str(), strImpl1Abs((s) => {
429
672
  try {
@@ -446,39 +689,58 @@ function defineEnv2() {
446
689
  }
447
690
  }
448
691
  ),
449
- format: envFn([prim.unknown], prim.str())
692
+ format: envFn(
693
+ [objAbs({
694
+ auth: { value: unionOf(prim.str(), nullLit()), optional: true },
695
+ hash: { value: unionOf(prim.str(), nullLit()), optional: true },
696
+ host: { value: unionOf(prim.str(), nullLit()), optional: true },
697
+ hostname: { value: unionOf(prim.str(), nullLit()), optional: true },
698
+ href: { value: unionOf(prim.str(), nullLit()), optional: true },
699
+ pathname: { value: unionOf(prim.str(), nullLit()), optional: true },
700
+ protocol: { value: unionOf(prim.str(), nullLit()), optional: true },
701
+ search: { value: unionOf(prim.str(), nullLit()), optional: true },
702
+ port: { value: unionOf(prim.str(), prim.num(), nullLit()), optional: true }
703
+ })],
704
+ prim.str()
705
+ )
450
706
  };
451
707
  const cryptoModule = {
452
708
  randomBytes: envFn([prim.num()], bufferBrand),
453
709
  randomUUID: envFn([], prim.str()),
454
710
  randomInt: envFn([prim.num(), prim.num()], prim.num()),
711
+ // Hash/HMAC 实例:update 链式返回自身 brand(不是 unknown)
455
712
  createHash: envFn(
456
713
  [prim.str()],
457
- objAbs({
458
- update: envFn([unionOf(prim.str(), bufferBrand)], prim.unknown),
714
+ brandOf("Hash", objAbs({
715
+ update: envFn([unionOf(prim.str(), bufferBrand)], brandOf("Hash")),
459
716
  digest: envFn(
460
717
  [prim.str()],
461
- unionOf(prim.str(), bufferBrand)
462
- )
463
- })
718
+ unionOf(prim.str(), bufferBrand),
719
+ void 0,
720
+ { params: ["encoding?"] }
721
+ ),
722
+ copy: envFn([], brandOf("Hash"))
723
+ }))
464
724
  ),
465
725
  createHmac: envFn(
466
726
  [prim.str(), unionOf(prim.str(), bufferBrand)],
467
- objAbs({
468
- update: envFn([unionOf(prim.str(), bufferBrand)], prim.unknown),
727
+ brandOf("Hmac", objAbs({
728
+ update: envFn([unionOf(prim.str(), bufferBrand)], brandOf("Hmac")),
469
729
  digest: envFn(
470
730
  [prim.str()],
471
- unionOf(prim.str(), bufferBrand)
731
+ unionOf(prim.str(), bufferBrand),
732
+ void 0,
733
+ { params: ["encoding?"] }
472
734
  )
473
- })
735
+ }))
474
736
  ),
475
737
  createCipheriv: envFn(
476
- [prim.str(), prim.unknown, prim.unknown],
477
- prim.unknown
738
+ [prim.str(), unionOf(prim.str(), bufferBrand), unionOf(prim.str(), bufferBrand)],
739
+ brandOf("Cipher")
478
740
  ),
479
741
  createDecipheriv: envFn(
480
- [prim.str(), prim.unknown, prim.unknown],
481
- prim.unknown
742
+ [prim.str(), unionOf(prim.str(), bufferBrand), unionOf(prim.str(), bufferBrand)],
743
+ brandOf("Decipher")
482
744
  ),
483
745
  pbkdf2Sync: envFn(
484
746
  [prim.str(), prim.str(), prim.num(), prim.num(), prim.str()],
@@ -487,126 +749,230 @@ function defineEnv2() {
487
749
  scryptSync: envFn([prim.str(), prim.str(), prim.num()], bufferBrand),
488
750
  timingSafeEqual: envFn([bufferBrand, bufferBrand], prim.bool())
489
751
  };
752
+ const spawnOptions = objAbs({
753
+ cwd: { value: prim.str(), optional: true },
754
+ env: { value: openObjBrand("Record<string, string | undefined>", { key: prim.str(), value: unionOf(prim.str(), undef()) }), optional: true },
755
+ stdio: { value: unionOf(prim.str(), arrOf(prim.str())), optional: true },
756
+ shell: { value: unionOf(prim.bool(), prim.str()), optional: true },
757
+ timeout: { value: prim.num(), optional: true },
758
+ killSignal: { value: unionOf(prim.str(), prim.num()), optional: true }
759
+ });
760
+ const childProcessInstance = brandOf(
761
+ "ChildProcess",
762
+ objAbs({
763
+ pid: prim.num(),
764
+ connected: prim.bool(),
765
+ killed: prim.bool(),
766
+ exitCode: unionOf(prim.num(), nullLit()),
767
+ signalCode: unionOf(prim.str(), nullLit()),
768
+ stdin: brandOf("Writable", objAbs(streamIoMethods)),
769
+ stdout: brandOf("Readable", objAbs(streamIoMethods)),
770
+ stderr: brandOf("Readable", objAbs(streamIoMethods)),
771
+ on: envFn([prim.str(), callbackFnBrand], brandOf("ChildProcess")),
772
+ once: envFn([prim.str(), callbackFnBrand], brandOf("ChildProcess")),
773
+ off: envFn([prim.str(), callbackFnBrand], brandOf("ChildProcess")),
774
+ kill: envFn([unionOf(prim.str(), prim.num())], prim.bool(), void 0, {
775
+ params: ["signal?"]
776
+ }),
777
+ ref: envFn([], brandOf("ChildProcess")),
778
+ unref: envFn([], brandOf("ChildProcess"))
779
+ })
780
+ );
490
781
  const childProcessModule = {
491
782
  execSync: envFn(
492
- [prim.str(), prim.unknown],
493
- unionOf(prim.str(), bufferBrand)
783
+ [prim.str(), objAbs({
784
+ encoding: { value: prim.str(), optional: true },
785
+ timeout: { value: prim.num(), optional: true },
786
+ maxBuffer: { value: prim.num(), optional: true },
787
+ cwd: { value: prim.str(), optional: true }
788
+ })],
789
+ unionOf(prim.str(), bufferBrand),
790
+ void 0,
791
+ { params: ["command", "options?"] }
494
792
  ),
495
793
  execFileSync: envFn(
496
- [prim.str(), arrOf(prim.str()), prim.unknown],
497
- unionOf(prim.str(), bufferBrand)
794
+ [prim.str(), arrOf(prim.str()), objAbs({
795
+ encoding: { value: prim.str(), optional: true },
796
+ timeout: { value: prim.num(), optional: true },
797
+ maxBuffer: { value: prim.num(), optional: true },
798
+ cwd: { value: prim.str(), optional: true }
799
+ })],
800
+ unionOf(prim.str(), bufferBrand),
801
+ void 0,
802
+ { params: ["file", "args", "options?"] }
498
803
  ),
499
804
  spawnSync: envFn(
500
- [prim.str(), arrOf(prim.str()), prim.unknown],
805
+ [prim.str(), arrOf(prim.str()), objAbs({
806
+ encoding: { value: prim.str(), optional: true },
807
+ timeout: { value: prim.num(), optional: true },
808
+ maxBuffer: { value: prim.num(), optional: true },
809
+ cwd: { value: prim.str(), optional: true }
810
+ })],
501
811
  objAbs({
502
812
  status: unionOf(prim.num(), nullLit()),
503
813
  stdout: unionOf(prim.str(), bufferBrand),
504
814
  stderr: unionOf(prim.str(), bufferBrand),
505
815
  error: unionOf(brandOf("Error"), undef())
506
- })
816
+ }),
817
+ void 0,
818
+ { params: ["command", "args", "options?"] }
507
819
  ),
508
- exec: envFn([prim.str(), prim.unknown], prim.unknown),
509
- spawn: envFn([prim.str(), arrOf(prim.str()), prim.unknown], prim.unknown),
510
- fork: envFn([prim.str(), arrOf(prim.str()), prim.unknown], prim.unknown)
820
+ exec: envFn([prim.str(), callbackFnBrand], childProcessInstance, void 0, {
821
+ params: ["command", "callback?"]
822
+ }),
823
+ execFile: envFn([prim.str(), arrOf(prim.str()), callbackFnBrand], childProcessInstance, void 0, {
824
+ params: ["file", "args?", "callback?"]
825
+ }),
826
+ spawn: envFn([prim.str(), arrOf(prim.str()), spawnOptions], childProcessInstance, void 0, {
827
+ params: ["command", "args", "options?"]
828
+ }),
829
+ fork: envFn([prim.str(), arrOf(prim.str()), spawnOptions], childProcessInstance, void 0, {
830
+ params: ["modulePath", "args", "options?"]
831
+ })
511
832
  };
512
833
  const utilModule = {
513
- // Signature-level: promisify preserves fn-ness only as unknown (no generic).
514
- promisify: envFn([prim.unknown], prim.unknown, void 0, { name: "util.promisify" }),
515
- inspect: envFn([prim.unknown, prim.unknown], prim.str()),
516
- format: envFnVariadic(prim.unknown, prim.str(), {
517
- // util.format() with zero args is valid in Node.
834
+ // HOF:callback 风格 fn → promise 风格 fn。真实 arity 由调用点决定,
835
+ // 用角色 brand 表达(format 干净,不假装具体参数表)。
836
+ promisify: envFn([callbackFnBrand], promiseFnBrand, void 0, {
837
+ name: "util.promisify"
838
+ }),
839
+ // value 无约束(产品 any);options 具体化
840
+ inspect: envFn(
841
+ [anyParam, inspectOptions],
842
+ prim.str(),
843
+ void 0,
844
+ { params: ["value", "options?"], name: "util.inspect" }
845
+ ),
846
+ // util.format() with zero args is valid in Node;混参无约束
847
+ format: envFnVariadic(anyParam, prim.str(), {
518
848
  restName: "...args",
519
849
  name: "util.format"
520
850
  }),
521
- callbackify: envFn([prim.unknown], prim.unknown),
522
- deprecate: envFn([prim.unknown, prim.str()], prim.unknown),
523
- inherits: envFn([prim.unknown, prim.unknown], undef()),
524
- isDeepStrictEqual: envFn([prim.unknown, prim.unknown], prim.bool()),
851
+ // HOF 与 promisify 对偶:promise fn → callback fn
852
+ callbackify: envFn([promiseFnBrand], callbackFnBrand),
853
+ deprecate: envFn([anyParam, prim.str()], anyValueBrand),
854
+ inherits: envFn([brandOf("Function"), brandOf("Function")], undef()),
855
+ isDeepStrictEqual: envFn([anyValueBrand, anyValueBrand], prim.bool()),
525
856
  types: objAbs({
526
- isDate: envFn([prim.unknown], prim.bool()),
527
- isRegExp: envFn([prim.unknown], prim.bool()),
528
- isPromise: envFn([prim.unknown], prim.bool()),
529
- isArrayBuffer: envFn([prim.unknown], prim.bool()),
530
- isTypedArray: envFn([prim.unknown], prim.bool()),
531
- isNativeError: envFn([prim.unknown], prim.bool()),
532
- isAsyncFunction: envFn([prim.unknown], prim.bool()),
533
- isGeneratorFunction: envFn([prim.unknown], prim.bool())
857
+ // 谓词收任意值(产品 any);返回精确 bool
858
+ isDate: envFn([anyParam], prim.bool()),
859
+ isRegExp: envFn([anyParam], prim.bool()),
860
+ isPromise: envFn([anyParam], prim.bool()),
861
+ isArrayBuffer: envFn([anyParam], prim.bool()),
862
+ isTypedArray: envFn([anyParam], prim.bool()),
863
+ isNativeError: envFn([anyParam], prim.bool()),
864
+ isAsyncFunction: envFn([anyParam], prim.bool()),
865
+ isGeneratorFunction: envFn([anyParam], prim.bool())
534
866
  }),
535
867
  TextEncoder: envFn(
536
868
  [],
537
- objAbs({ encode: envFn([prim.str()], prim.unknown) })
869
+ objAbs({
870
+ encode: envFn([prim.str()], brandOf("Uint8Array", objAbs({
871
+ length: prim.num(),
872
+ buffer: brandOf("ArrayBuffer")
873
+ }))),
874
+ encoding: prim.str()
875
+ })
538
876
  ),
539
877
  TextDecoder: envFn(
540
878
  [prim.str()],
541
- objAbs({ decode: envFn([prim.unknown], prim.str()) })
879
+ objAbs({
880
+ decode: envFn([brandOf("Uint8Array", objAbs({ length: prim.num() }))], prim.str()),
881
+ encoding: prim.str()
882
+ }),
883
+ void 0,
884
+ { params: ["encoding?"] }
542
885
  )
543
886
  };
544
887
  const eventEmitterShape = objAbs({
545
- on: envFn([prim.str(), prim.unknown], prim.unknown),
546
- once: envFn([prim.str(), prim.unknown], prim.unknown),
547
- off: envFn([prim.str(), prim.unknown], prim.unknown),
548
- emit: envFn([prim.str()], prim.bool()),
549
- addListener: envFn([prim.str(), prim.unknown], prim.unknown),
550
- removeListener: envFn([prim.str(), prim.unknown], prim.unknown),
551
- removeAllListeners: envFn([prim.str()], prim.unknown),
552
- listeners: envFn([prim.str()], arrOf(prim.unknown)),
888
+ on: envFn([prim.str(), callbackFnBrand], brandOf("EventEmitter")),
889
+ once: envFn([prim.str(), callbackFnBrand], brandOf("EventEmitter")),
890
+ off: envFn([prim.str(), callbackFnBrand], brandOf("EventEmitter")),
891
+ emit: envFn([prim.str(), anyParam], prim.bool(), void 0, {
892
+ params: ["event", "...args"]
893
+ }),
894
+ addListener: envFn([prim.str(), callbackFnBrand], brandOf("EventEmitter")),
895
+ removeListener: envFn([prim.str(), callbackFnBrand], brandOf("EventEmitter")),
896
+ removeAllListeners: envFn([prim.str()], brandOf("EventEmitter")),
897
+ listeners: envFn([prim.str()], arrOf(callbackFnBrand)),
553
898
  listenerCount: envFn([prim.str()], prim.num()),
554
899
  eventNames: envFn([], arrOf(prim.str()))
555
900
  });
556
901
  const eventEmitterInstance = brandOf("EventEmitter", eventEmitterShape);
557
- const EventEmitterCtor = envFn([prim.unknown], eventEmitterInstance, void 0, {
902
+ const EventEmitterCtor = envFn([eventEmitterOptions], eventEmitterInstance, void 0, {
558
903
  params: ["options?"]
559
904
  });
560
905
  const eventsModule = {
561
906
  EventEmitter: EventEmitterCtor,
907
+ // 事件实参依赖事件类型 — 用 EventArgs brand 留口,不假装具体元组
562
908
  once: envFn(
563
- [prim.unknown, prim.str()],
564
- promiseOf(arrOf(prim.unknown))
909
+ [eventEmitterInstance, prim.str()],
910
+ promiseOf(brandOf("EventArgs", arrOf(anyParam))),
911
+ void 0,
912
+ { params: ["emitter", "event"] }
565
913
  ),
566
- on: envFn([prim.unknown, prim.str()], prim.unknown),
567
- listenerCount: envFn([prim.unknown, prim.str()], prim.num())
568
- };
569
- const streamIoMethods = {
570
- on: envFn([prim.str(), prim.unknown], prim.unknown),
571
- once: envFn([prim.str(), prim.unknown], prim.unknown),
572
- off: envFn([prim.str(), prim.unknown], prim.unknown),
573
- emit: envFn([prim.str()], prim.bool()),
574
- pipe: envFn([prim.unknown], prim.unknown),
575
- destroy: envFn([prim.unknown], undef()),
576
- read: envFn([prim.num()], prim.unknown),
577
- write: envFn([unionOf(prim.str(), bufferBrand)], prim.bool()),
578
- end: envFn([prim.unknown], undef()),
579
- pause: envFn([], prim.unknown),
580
- resume: envFn([], prim.unknown),
581
- setEncoding: envFn([prim.str()], prim.unknown)
914
+ // AsyncIterator 由事件流驱动(limitations §2 机器回调边界)
915
+ on: envFn(
916
+ [eventEmitterInstance, prim.str()],
917
+ brandOf(
918
+ "AsyncIterator",
919
+ objAbs({
920
+ next: envFn([], promiseOf(objAbs({
921
+ value: arrOf(anyParam),
922
+ done: prim.bool()
923
+ }))),
924
+ return: envFn([], promiseOf(objAbs({
925
+ value: arrOf(anyParam),
926
+ done: prim.bool()
927
+ })))
928
+ })
929
+ ),
930
+ void 0,
931
+ { params: ["emitter", "event"] }
932
+ ),
933
+ listenerCount: envFn([eventEmitterInstance, prim.str()], prim.num())
582
934
  };
583
- const streamCtor = (brandName) => envFn([prim.unknown], brandOf(brandName, objAbs(streamIoMethods)), void 0, {
584
- params: ["options?"]
585
- });
935
+ const streamCtor = (brandName) => envFn(
936
+ [objAbs({ ...streamBaseSlots, ...streamHooks })],
937
+ brandOf(brandName, objAbs(streamIoMethods)),
938
+ void 0,
939
+ { params: ["options?"] }
940
+ );
586
941
  const streamModule = {
587
942
  Readable: streamCtor("Readable"),
588
943
  Writable: streamCtor("Writable"),
589
944
  Duplex: streamCtor("Duplex"),
590
945
  Transform: streamCtor("Transform"),
591
- pipeline: envFnVariadic(prim.unknown, promiseOf(undef()), {
946
+ pipeline: envFnVariadic(brandOf("Stream"), promiseOf(undef()), {
592
947
  restName: "...streams"
593
948
  }),
594
- finished: envFn([prim.unknown], promiseOf(undef()))
949
+ finished: envFn([brandOf("Stream"), callbackFnBrand], promiseOf(undef()), void 0, {
950
+ params: ["stream", "callback?"]
951
+ }),
952
+ promises: objAbs({
953
+ pipeline: envFnVariadic(brandOf("Stream"), promiseOf(undef()), {
954
+ restName: "...streams"
955
+ }),
956
+ finished: envFn([brandOf("Stream")], promiseOf(undef()))
957
+ })
595
958
  };
596
- const parsedQueryString = brandOf(
959
+ const parsedQueryString = openObjBrand(
597
960
  "ParsedQueryString",
598
- objAbs({})
961
+ { key: prim.str(), value: unionOf(prim.str(), arrOf(prim.str())) }
599
962
  );
600
963
  const querystringModule = {
601
- // sep/eq/options optional — required arity 1; labels+types render `sep?: string` etc.
964
+ // sep/eq/options optional — required arity 1; labels+types render typed options
602
965
  parse: envFn(
603
- [prim.str(), prim.str(), prim.str(), prim.unknown],
966
+ [prim.str(), prim.str(), prim.str(), querystringOptions],
604
967
  parsedQueryString,
605
968
  void 0,
606
969
  { params: ["str", "sep?", "eq?", "options?"] }
607
970
  ),
608
971
  stringify: envFn(
609
- [prim.unknown, prim.str(), prim.str(), prim.unknown],
972
+ [openObjBrand(
973
+ "StringifyInput",
974
+ { key: prim.str(), value: unionOf(prim.str(), prim.num(), prim.bool(), arrOf(unionOf(prim.str(), prim.num(), prim.bool()))) }
975
+ ), prim.str(), prim.str(), querystringOptions],
610
976
  prim.str(),
611
977
  void 0,
612
978
  { params: ["obj", "sep?", "eq?", "options?"] }
@@ -614,26 +980,70 @@ function defineEnv2() {
614
980
  escape: envFn([prim.str()], prim.str()),
615
981
  unescape: envFn([prim.str()], prim.str())
616
982
  };
983
+ const assertMessageArg = unionOf(prim.str(), brandOf("Error"));
984
+ const assertModule = {
985
+ ok: envFn(
986
+ [anyParam, assertMessageArg],
987
+ undef(),
988
+ void 0,
989
+ { params: ["value", "message?"] }
990
+ ),
991
+ strictEqual: envFn(
992
+ [anyParam, anyParam, assertMessageArg],
993
+ undef(),
994
+ void 0,
995
+ { params: ["actual", "expected", "message?"] }
996
+ ),
997
+ deepStrictEqual: envFn(
998
+ [anyParam, anyParam, assertMessageArg],
999
+ undef(),
1000
+ void 0,
1001
+ { params: ["actual", "expected", "message?"] }
1002
+ ),
1003
+ notStrictEqual: envFn(
1004
+ [anyParam, anyParam, assertMessageArg],
1005
+ undef(),
1006
+ void 0,
1007
+ { params: ["actual", "expected", "message?"] }
1008
+ ),
1009
+ match: envFn(
1010
+ [prim.str(), brandOf("RegExp"), assertMessageArg],
1011
+ undef(),
1012
+ void 0,
1013
+ { params: ["value", "regexp", "message?"] }
1014
+ ),
1015
+ fail: envFn([assertMessageArg], prim.never, void 0, {
1016
+ params: ["message?"]
1017
+ })
1018
+ };
617
1019
  const nodeGlobals = {
618
1020
  process: objAbs({
619
- env: objAbs({}),
1021
+ // Record<string, string | undefined> 语义:开放键 + string|undefined 值
1022
+ env: openObjBrand(
1023
+ "Record<string, string | undefined>",
1024
+ { key: prim.str(), value: unionOf(prim.str(), undef()) }
1025
+ ),
620
1026
  argv: arrOf(prim.str()),
621
1027
  argv0: prim.str(),
622
1028
  execArgv: arrOf(prim.str()),
623
1029
  execPath: prim.str(),
624
1030
  cwd: envFn([], prim.str()),
625
1031
  chdir: envFn([prim.str()], undef()),
626
- exit: envFn([prim.num()], prim.never),
1032
+ exit: envFn([prim.num()], prim.never, void 0, { params: ["code?"] }),
1033
+ exitCode: unionOf(prim.num(), undef()),
627
1034
  pid: prim.num(),
628
1035
  ppid: prim.num(),
629
1036
  platform: prim.str(),
630
1037
  arch: prim.str(),
631
1038
  version: prim.str(),
632
- versions: objAbs({}),
1039
+ versions: openObjBrand(
1040
+ "Record<string, string>",
1041
+ { key: prim.str(), value: prim.str() }
1042
+ ),
633
1043
  stdout: objAbs({ write: envFn([prim.str()], prim.bool()) }),
634
1044
  stderr: objAbs({ write: envFn([prim.str()], prim.bool()) }),
635
1045
  stdin: objAbs({
636
- on: envFn([prim.str(), prim.unknown], prim.unknown)
1046
+ on: envFn([prim.str(), callbackFnBrand], brandOf("EventEmitter"))
637
1047
  }),
638
1048
  hrtime: objAbs({ bigint: envFn([], brandOf("bigint")) }),
639
1049
  memoryUsage: envFn(
@@ -651,17 +1061,27 @@ function defineEnv2() {
651
1061
  objAbs({ user: prim.num(), system: prim.num() })
652
1062
  ),
653
1063
  uptime: envFn([], prim.num()),
654
- nextTick: envFn([prim.unknown], undef()),
655
- on: envFn([prim.str(), prim.unknown], prim.unknown),
656
- once: envFn([prim.str(), prim.unknown], prim.unknown),
657
- off: envFn([prim.str(), prim.unknown], prim.unknown),
658
- emit: envFn([prim.str()], prim.bool())
1064
+ // 额外转发实参由 callback 形参吸收(CallbackFn brand 内部 variadic)
1065
+ nextTick: envFn([callbackFnBrand], undef(), void 0, {
1066
+ params: ["callback"]
1067
+ }),
1068
+ on: envFn([prim.str(), callbackFnBrand], brandOf("EventEmitter")),
1069
+ once: envFn([prim.str(), callbackFnBrand], brandOf("EventEmitter")),
1070
+ off: envFn([prim.str(), callbackFnBrand], brandOf("EventEmitter")),
1071
+ emit: envFn([prim.str(), anyParam], prim.bool(), void 0, {
1072
+ params: ["event", "...args"]
1073
+ })
659
1074
  }),
660
1075
  Buffer: objAbs({
661
- from: envFn([unionOf(prim.str(), arrOf(prim.num()))], bufferBrand),
662
- alloc: envFn([prim.num()], bufferBrand),
1076
+ from: envFn([unionOf(prim.str(), arrOf(prim.num()), bufferBrand)], bufferBrand),
1077
+ alloc: envFn(
1078
+ [prim.num(), unionOf(prim.str(), prim.num(), bufferBrand), prim.str()],
1079
+ bufferBrand,
1080
+ void 0,
1081
+ { params: ["size", "fill?", "encoding?"] }
1082
+ ),
663
1083
  allocUnsafe: envFn([prim.num()], bufferBrand),
664
- isBuffer: envFn([prim.unknown], prim.bool()),
1084
+ isBuffer: envFn([anyParam], prim.bool()),
665
1085
  byteLength: envFn(
666
1086
  [unionOf(prim.str(), bufferBrand)],
667
1087
  prim.num()
@@ -671,14 +1091,20 @@ function defineEnv2() {
671
1091
  }),
672
1092
  __dirname: prim.str(),
673
1093
  __filename: prim.str(),
674
- setTimeout: envFn([prim.unknown, prim.num()], prim.unknown),
675
- setInterval: envFn([prim.unknown, prim.num()], prim.unknown),
676
- setImmediate: envFn([prim.unknown], prim.unknown),
677
- clearTimeout: envFn([prim.unknown], undef()),
678
- clearInterval: envFn([prim.unknown], undef()),
679
- clearImmediate: envFn([prim.unknown], undef()),
680
- queueMicrotask: envFn([prim.unknown], undef()),
681
- structuredClone: envFn([prim.unknown], prim.unknown)
1094
+ setTimeout: envFn([callbackFnBrand, prim.num(), anyParam], brandOf("Timeout"), void 0, {
1095
+ params: ["callback", "ms", "...args"]
1096
+ }),
1097
+ setInterval: envFn([callbackFnBrand, prim.num(), anyParam], brandOf("Timeout"), void 0, {
1098
+ params: ["callback", "ms", "...args"]
1099
+ }),
1100
+ setImmediate: envFn([callbackFnBrand, anyParam], brandOf("Immediate"), void 0, {
1101
+ params: ["callback", "...args"]
1102
+ }),
1103
+ clearTimeout: envFn([brandOf("Timeout")], undef()),
1104
+ clearInterval: envFn([brandOf("Timeout")], undef()),
1105
+ clearImmediate: envFn([brandOf("Immediate")], undef()),
1106
+ queueMicrotask: envFn([callbackFnBrand], undef()),
1107
+ structuredClone: envFn([anyParam], anyValueBrand)
682
1108
  };
683
1109
  const modules = {
684
1110
  fs: fsModule,
@@ -702,7 +1128,9 @@ function defineEnv2() {
702
1128
  stream: streamModule,
703
1129
  "node:stream": streamModule,
704
1130
  querystring: querystringModule,
705
- "node:querystring": querystringModule
1131
+ "node:querystring": querystringModule,
1132
+ assert: assertModule,
1133
+ "node:assert": assertModule
706
1134
  };
707
1135
  return {
708
1136
  globals: { ...esEnv.globals, ...nodeGlobals },
package/dist/web.js CHANGED
@@ -8,7 +8,7 @@ import {
8
8
  promiseOf,
9
9
  undef,
10
10
  unionOf
11
- } from "./chunk-6RZUMVN5.js";
11
+ } from "./chunk-KRMQSDG3.js";
12
12
 
13
13
  // src/web.ts
14
14
  import { litValue, strLit, numLit } from "@nudojs/core";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nudojs/env",
3
- "version": "0.4.0",
3
+ "version": "0.4.2-beta.0",
4
4
  "engines": {
5
5
  "node": ">=20"
6
6
  },
@@ -35,7 +35,7 @@
35
35
  "registry": "https://registry.npmjs.org"
36
36
  },
37
37
  "dependencies": {
38
- "@nudojs/core": "2.0.1"
38
+ "@nudojs/core": "3.0.0-beta.0"
39
39
  },
40
40
  "scripts": {
41
41
  "build": "tsup src/es.ts src/web.ts src/node.ts --format esm --dts"