@nudojs/harvester 0.2.3 → 0.2.5
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/dist/index.d.ts +5 -5
- package/dist/index.js +182 -108
- package/package.json +2 -2
package/dist/index.d.ts
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Abs } from '@nudojs/core';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
|
-
*
|
|
5
|
-
*
|
|
4
|
+
* Harvested env:Abs 原生(与 EnvDefinition 同形)。
|
|
5
|
+
* 收集与物化全程 Abs,不再经 TypeValue 桥。
|
|
6
6
|
*/
|
|
7
7
|
type HarvestedEnv = {
|
|
8
|
-
globals: Record<string,
|
|
9
|
-
modules: Record<string, Record<string,
|
|
8
|
+
globals: Record<string, Abs>;
|
|
9
|
+
modules: Record<string, Record<string, Abs>>;
|
|
10
10
|
stats: {
|
|
11
11
|
files: number;
|
|
12
12
|
symbols: number;
|
package/dist/index.js
CHANGED
|
@@ -1,11 +1,76 @@
|
|
|
1
1
|
// src/index.ts
|
|
2
2
|
import { readFileSync, statSync } from "fs";
|
|
3
3
|
import ts from "typescript";
|
|
4
|
-
import {
|
|
4
|
+
import {
|
|
5
|
+
abs as makeAbs,
|
|
6
|
+
lit as termLit,
|
|
7
|
+
numLit,
|
|
8
|
+
strLit,
|
|
9
|
+
boolLit,
|
|
10
|
+
objOf,
|
|
11
|
+
joinAbs
|
|
12
|
+
} from "@nudojs/core";
|
|
5
13
|
var MAX_ALIAS_DEPTH = 8;
|
|
6
14
|
function scopeKey(scope) {
|
|
7
15
|
return scope.moduleName ?? "\0global";
|
|
8
16
|
}
|
|
17
|
+
function absExact(shape) {
|
|
18
|
+
return makeAbs(shape, void 0, void 0, "exact");
|
|
19
|
+
}
|
|
20
|
+
function absNever() {
|
|
21
|
+
return absExact({ k: "never" });
|
|
22
|
+
}
|
|
23
|
+
function absUnknown() {
|
|
24
|
+
return makeAbs({ k: "unknown" }, void 0, void 0, "partial");
|
|
25
|
+
}
|
|
26
|
+
function absPrim(type) {
|
|
27
|
+
return absExact({ k: "prim", type });
|
|
28
|
+
}
|
|
29
|
+
function absNullLit() {
|
|
30
|
+
return makeAbs({ k: "unknown" }, termLit(null), void 0, "exact");
|
|
31
|
+
}
|
|
32
|
+
function absUndefLit() {
|
|
33
|
+
return makeAbs({ k: "unknown" }, termLit(void 0), void 0, "exact");
|
|
34
|
+
}
|
|
35
|
+
function absLit(value) {
|
|
36
|
+
if (typeof value === "number") return numLit(value);
|
|
37
|
+
if (typeof value === "string") return strLit(value);
|
|
38
|
+
if (typeof value === "boolean") return boolLit(value);
|
|
39
|
+
if (typeof value === "bigint") return absPrim("bigint");
|
|
40
|
+
if (value === null) return absNullLit();
|
|
41
|
+
return absUndefLit();
|
|
42
|
+
}
|
|
43
|
+
function absArr(element) {
|
|
44
|
+
return absExact({ k: "arr", element });
|
|
45
|
+
}
|
|
46
|
+
function absPromise(inner) {
|
|
47
|
+
return absExact({ k: "eff", eff: "promise", inner });
|
|
48
|
+
}
|
|
49
|
+
function absObj(properties) {
|
|
50
|
+
const slots = {};
|
|
51
|
+
for (const [k, v] of Object.entries(properties)) {
|
|
52
|
+
slots[k] = { value: v };
|
|
53
|
+
}
|
|
54
|
+
return objOf(slots);
|
|
55
|
+
}
|
|
56
|
+
function absBrand(name, properties) {
|
|
57
|
+
return absExact({ k: "brand", name, shape: absObj(properties) });
|
|
58
|
+
}
|
|
59
|
+
function absFnSig(paramTypes, returnType) {
|
|
60
|
+
return absExact({
|
|
61
|
+
k: "fn",
|
|
62
|
+
params: paramTypes.map((_, i) => `_arg${i}`),
|
|
63
|
+
paramTypes,
|
|
64
|
+
returnType
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
function absUnion(members) {
|
|
68
|
+
if (members.length === 0) return absNever();
|
|
69
|
+
return members.reduce((acc, m) => joinAbs(acc, m));
|
|
70
|
+
}
|
|
71
|
+
function isPlainUnknown(a) {
|
|
72
|
+
return a.shape.k === "unknown" && !(a.term?.op === "lit");
|
|
73
|
+
}
|
|
9
74
|
function harvestDts(files, opts) {
|
|
10
75
|
const maxBytes = opts?.maxFileBytes ?? 15e5;
|
|
11
76
|
const deadline = opts?.maxMs !== void 0 ? Date.now() + opts.maxMs : void 0;
|
|
@@ -70,7 +135,7 @@ function emitEnvModule(env, pkgName) {
|
|
|
70
135
|
if (keys.length < 2) continue;
|
|
71
136
|
const constName = `mod${constIndex++}`;
|
|
72
137
|
constNameByRecord.set(record, constName);
|
|
73
|
-
constLines.push(` const ${constName}: Record<string,
|
|
138
|
+
constLines.push(` const ${constName}: Record<string, unknown> = {`);
|
|
74
139
|
emitEntries(constLines, record, 2);
|
|
75
140
|
constLines.push(` };`);
|
|
76
141
|
constLines.push("");
|
|
@@ -78,11 +143,9 @@ function emitEnvModule(env, pkgName) {
|
|
|
78
143
|
const lines = [];
|
|
79
144
|
lines.push("// Auto-generated by nudo harvest \u2014 DO NOT EDIT");
|
|
80
145
|
lines.push(`// Source package: ${pkgName}`);
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
lines.push(`import { T } from "@nudojs/core";`);
|
|
85
|
-
}
|
|
146
|
+
lines.push(
|
|
147
|
+
'import { num, str, bool, never as absNever, unknown as absUnknown, numLit, strLit, boolLit, objOf, relationFn, abs as makeAbs } from "@nudojs/core";'
|
|
148
|
+
);
|
|
86
149
|
lines.push("");
|
|
87
150
|
lines.push("export function defineEnv() {");
|
|
88
151
|
lines.push(...constLines);
|
|
@@ -308,15 +371,15 @@ function materialize(ctx) {
|
|
|
308
371
|
if (p.t === "fn") {
|
|
309
372
|
if (rec[p.name] !== void 0) continue;
|
|
310
373
|
const value = signatureToFnSig(ctx, p.decls[0]);
|
|
311
|
-
const sig =
|
|
374
|
+
const sig = value.shape.k === "fn" ? value.shape : void 0;
|
|
312
375
|
if (sig) {
|
|
313
376
|
const returns = [];
|
|
314
377
|
for (const decl of p.decls) {
|
|
315
378
|
if (!decl.type) continue;
|
|
316
379
|
const ret = mapType(ctx, decl.type, 0);
|
|
317
|
-
if (ret
|
|
380
|
+
if (!isPlainUnknown(ret)) returns.push(ret);
|
|
318
381
|
}
|
|
319
|
-
sig.returnType = returns.length > 0 ? returns
|
|
382
|
+
sig.returnType = returns.length > 0 ? absUnion(returns) : absUnknown();
|
|
320
383
|
}
|
|
321
384
|
rec[p.name] = value;
|
|
322
385
|
continue;
|
|
@@ -324,8 +387,8 @@ function materialize(ctx) {
|
|
|
324
387
|
if (rec[p.name] !== void 0) continue;
|
|
325
388
|
switch (p.t) {
|
|
326
389
|
case "var": {
|
|
327
|
-
const mapped = p.typeNode ? mapType(ctx, p.typeNode, 0) :
|
|
328
|
-
if (mapped
|
|
390
|
+
const mapped = p.typeNode ? mapType(ctx, p.typeNode, 0) : absUnknown();
|
|
391
|
+
if (isPlainUnknown(mapped)) {
|
|
329
392
|
ctx.skipped++;
|
|
330
393
|
break;
|
|
331
394
|
}
|
|
@@ -339,19 +402,19 @@ function materialize(ctx) {
|
|
|
339
402
|
const params = [];
|
|
340
403
|
if (ctor) {
|
|
341
404
|
for (const param of ctor.parameters) {
|
|
342
|
-
let type = param.type ? mapType(ctx, param.type, 0) :
|
|
343
|
-
if (param.questionToken) type =
|
|
405
|
+
let type = param.type ? mapType(ctx, param.type, 0) : absUnknown();
|
|
406
|
+
if (param.questionToken) type = absUnion([type, absUndefLit()]);
|
|
344
407
|
params.push(type);
|
|
345
408
|
}
|
|
346
409
|
}
|
|
347
|
-
rec[p.name] =
|
|
410
|
+
rec[p.name] = absFnSig(params, instanceFor(ctx, p.lookup ?? p.name));
|
|
348
411
|
} else {
|
|
349
412
|
rec[p.name] = instanceFor(ctx, p.lookup ?? p.name);
|
|
350
413
|
}
|
|
351
414
|
break;
|
|
352
415
|
}
|
|
353
416
|
case "enum":
|
|
354
|
-
rec[p.name] =
|
|
417
|
+
rec[p.name] = absUnknown();
|
|
355
418
|
break;
|
|
356
419
|
}
|
|
357
420
|
}
|
|
@@ -375,9 +438,9 @@ function instanceFor(ctx, key) {
|
|
|
375
438
|
const cached = ctx.instanceCache.get(key);
|
|
376
439
|
if (cached !== void 0) return cached;
|
|
377
440
|
const decl = ctx.interfaces.get(key) ?? ctx.qualifiedInterfaces.get(key);
|
|
378
|
-
if (!decl) return
|
|
441
|
+
if (!decl) return absUnknown();
|
|
379
442
|
if (ctx.expanding.has(key)) {
|
|
380
|
-
return
|
|
443
|
+
return absBrand(decl.name?.text ?? key, {});
|
|
381
444
|
}
|
|
382
445
|
ctx.expanding.add(key);
|
|
383
446
|
const properties = {};
|
|
@@ -389,8 +452,8 @@ function instanceFor(ctx, key) {
|
|
|
389
452
|
if (ts.isPropertySignature(member) || ts.isPropertyDeclaration(member)) {
|
|
390
453
|
const name = memberName(member);
|
|
391
454
|
if (name === void 0) continue;
|
|
392
|
-
let type = member.type ? mapType(ctx, member.type, 0) :
|
|
393
|
-
if (member.questionToken) type =
|
|
455
|
+
let type = member.type ? mapType(ctx, member.type, 0) : absUnknown();
|
|
456
|
+
if (member.questionToken) type = absUnion([type, absUndefLit()]);
|
|
394
457
|
properties[name] = type;
|
|
395
458
|
} else if (ts.isMethodSignature(member) || ts.isMethodDeclaration(member)) {
|
|
396
459
|
const name = memberName(member);
|
|
@@ -405,7 +468,7 @@ function instanceFor(ctx, key) {
|
|
|
405
468
|
} finally {
|
|
406
469
|
ctx.expanding.delete(key);
|
|
407
470
|
}
|
|
408
|
-
const value =
|
|
471
|
+
const value = absBrand(decl.name?.text ?? key, properties);
|
|
409
472
|
ctx.instanceCache.set(key, value);
|
|
410
473
|
return value;
|
|
411
474
|
}
|
|
@@ -414,15 +477,15 @@ function signatureToFnSig(ctx, sig) {
|
|
|
414
477
|
let type;
|
|
415
478
|
if (param.dotDotDotToken) {
|
|
416
479
|
const inner = param.type && ts.isArrayTypeNode(param.type) ? param.type.elementType : param.type;
|
|
417
|
-
type = inner ?
|
|
480
|
+
type = inner ? absArr(mapType(ctx, inner, 0)) : absUnknown();
|
|
418
481
|
} else {
|
|
419
|
-
type = param.type ? mapType(ctx, param.type, 0) :
|
|
482
|
+
type = param.type ? mapType(ctx, param.type, 0) : absUnknown();
|
|
420
483
|
}
|
|
421
|
-
if (param.questionToken && !param.dotDotDotToken) type =
|
|
484
|
+
if (param.questionToken && !param.dotDotDotToken) type = absUnion([type, absUndefLit()]);
|
|
422
485
|
return type;
|
|
423
486
|
});
|
|
424
|
-
const returnType = sig.type ? mapType(ctx, sig.type, 0) :
|
|
425
|
-
return
|
|
487
|
+
const returnType = sig.type ? mapType(ctx, sig.type, 0) : absUnknown();
|
|
488
|
+
return absFnSig(paramTypes, returnType);
|
|
426
489
|
}
|
|
427
490
|
function mapTypeMembers(ctx, members, depth) {
|
|
428
491
|
const properties = {};
|
|
@@ -430,8 +493,8 @@ function mapTypeMembers(ctx, members, depth) {
|
|
|
430
493
|
if (ts.isPropertySignature(member)) {
|
|
431
494
|
const name = memberName(member);
|
|
432
495
|
if (name === void 0) continue;
|
|
433
|
-
let type = member.type ? mapType(ctx, member.type, depth) :
|
|
434
|
-
if (member.questionToken) type =
|
|
496
|
+
let type = member.type ? mapType(ctx, member.type, depth) : absUnknown();
|
|
497
|
+
if (member.questionToken) type = absUnion([type, absUndefLit()]);
|
|
435
498
|
properties[name] = type;
|
|
436
499
|
} else if (ts.isMethodSignature(member)) {
|
|
437
500
|
const name = memberName(member);
|
|
@@ -445,57 +508,60 @@ function mapTypeRef(ctx, node, depth) {
|
|
|
445
508
|
const name = typeNameString(node.typeName);
|
|
446
509
|
const args = node.typeArguments ?? [];
|
|
447
510
|
if ((name === "Array" || name === "ReadonlyArray") && args.length >= 1) {
|
|
448
|
-
return
|
|
511
|
+
return absArr(mapType(ctx, args[0], depth));
|
|
449
512
|
}
|
|
450
513
|
if (name === "Promise" && args.length >= 1) {
|
|
451
|
-
return
|
|
514
|
+
return absPromise(mapType(ctx, args[0], depth));
|
|
452
515
|
}
|
|
453
516
|
if (name === "Record") {
|
|
454
|
-
return
|
|
517
|
+
return absObj({});
|
|
455
518
|
}
|
|
456
519
|
if (ctx.interfaces.has(name) || ctx.qualifiedInterfaces.has(name)) {
|
|
457
520
|
return instanceFor(ctx, name);
|
|
458
521
|
}
|
|
459
522
|
const alias = ctx.aliases.get(name) ?? ctx.qualifiedAliases.get(name);
|
|
460
523
|
if (alias) return mapType(ctx, alias.type, depth + 1);
|
|
461
|
-
return
|
|
524
|
+
return absUnknown();
|
|
462
525
|
}
|
|
463
526
|
function mapType(ctx, node, depth) {
|
|
464
|
-
if (!node || depth > MAX_ALIAS_DEPTH) return
|
|
527
|
+
if (!node || depth > MAX_ALIAS_DEPTH) return absUnknown();
|
|
465
528
|
if (ts.isParenthesizedTypeNode(node)) return mapType(ctx, node.type, depth);
|
|
466
529
|
if (ts.isTypeReferenceNode(node)) return mapTypeRef(ctx, node, depth);
|
|
467
|
-
if (ts.isArrayTypeNode(node)) return
|
|
530
|
+
if (ts.isArrayTypeNode(node)) return absArr(mapType(ctx, node.elementType, depth));
|
|
468
531
|
if (ts.isTupleTypeNode(node)) {
|
|
469
532
|
for (const element of node.elements) {
|
|
470
533
|
const inner = ts.isNamedTupleMember(element) ? element.type : element;
|
|
471
|
-
return
|
|
534
|
+
return absArr(mapType(ctx, inner, depth));
|
|
472
535
|
}
|
|
473
|
-
return
|
|
536
|
+
return absUnknown();
|
|
474
537
|
}
|
|
475
538
|
if (ts.isUnionTypeNode(node)) {
|
|
476
|
-
return
|
|
539
|
+
return absUnion(node.types.map((t) => mapType(ctx, t, depth)));
|
|
477
540
|
}
|
|
478
541
|
if (ts.isIntersectionTypeNode(node)) {
|
|
479
542
|
const members = node.types.map((t) => mapType(ctx, t, depth));
|
|
480
|
-
if (members.length > 0 && members.every((m) => m.
|
|
543
|
+
if (members.length > 0 && members.every((m) => m.shape.k === "obj")) {
|
|
481
544
|
const properties = {};
|
|
482
545
|
for (const member of members) {
|
|
483
|
-
|
|
546
|
+
if (member.shape.k !== "obj") continue;
|
|
547
|
+
for (const [k, slot] of Object.entries(member.shape.slots)) {
|
|
548
|
+
properties[k] = slot.value;
|
|
549
|
+
}
|
|
484
550
|
}
|
|
485
|
-
return
|
|
551
|
+
return absObj(properties);
|
|
486
552
|
}
|
|
487
|
-
return members[0] ??
|
|
553
|
+
return members[0] ?? absUnknown();
|
|
488
554
|
}
|
|
489
555
|
if (ts.isLiteralTypeNode(node)) {
|
|
490
556
|
const lit = node.literal;
|
|
491
|
-
if (ts.isStringLiteral(lit)) return
|
|
492
|
-
if (ts.isNumericLiteral(lit)) return
|
|
493
|
-
if (lit.kind === ts.SyntaxKind.TrueKeyword) return
|
|
494
|
-
if (lit.kind === ts.SyntaxKind.FalseKeyword) return
|
|
557
|
+
if (ts.isStringLiteral(lit)) return absLit(lit.text);
|
|
558
|
+
if (ts.isNumericLiteral(lit)) return absLit(Number(lit.text));
|
|
559
|
+
if (lit.kind === ts.SyntaxKind.TrueKeyword) return absLit(true);
|
|
560
|
+
if (lit.kind === ts.SyntaxKind.FalseKeyword) return absLit(false);
|
|
495
561
|
if (ts.isPrefixUnaryExpression(lit) && lit.operator === ts.SyntaxKind.MinusToken && ts.isNumericLiteral(lit.operand)) {
|
|
496
|
-
return
|
|
562
|
+
return absLit(-Number(lit.operand.text));
|
|
497
563
|
}
|
|
498
|
-
return
|
|
564
|
+
return absUnknown();
|
|
499
565
|
}
|
|
500
566
|
if (ts.isFunctionTypeNode(node)) return signatureToFnSig(ctx, node);
|
|
501
567
|
if (ts.isTypeLiteralNode(node)) {
|
|
@@ -503,41 +569,41 @@ function mapType(ctx, node, depth) {
|
|
|
503
569
|
if (ctor) {
|
|
504
570
|
const params = [];
|
|
505
571
|
for (const param of ctor.parameters) {
|
|
506
|
-
let type = param.type ? mapType(ctx, param.type, depth) :
|
|
507
|
-
if (param.questionToken) type =
|
|
572
|
+
let type = param.type ? mapType(ctx, param.type, depth) : absUnknown();
|
|
573
|
+
if (param.questionToken) type = absUnion([type, absUndefLit()]);
|
|
508
574
|
params.push(type);
|
|
509
575
|
}
|
|
510
|
-
return
|
|
576
|
+
return absFnSig(params, ctor.type ? mapType(ctx, ctor.type, depth) : absUnknown());
|
|
511
577
|
}
|
|
512
|
-
return
|
|
578
|
+
return absObj(mapTypeMembers(ctx, node.members, depth));
|
|
513
579
|
}
|
|
514
580
|
if (ts.isTypeOperatorNode(node)) {
|
|
515
|
-
return node.operator === ts.SyntaxKind.ReadonlyKeyword ? mapType(ctx, node.type, depth) :
|
|
581
|
+
return node.operator === ts.SyntaxKind.ReadonlyKeyword ? mapType(ctx, node.type, depth) : absUnknown();
|
|
516
582
|
}
|
|
517
583
|
switch (node.kind) {
|
|
518
584
|
case ts.SyntaxKind.StringKeyword:
|
|
519
|
-
return
|
|
585
|
+
return absPrim("string");
|
|
520
586
|
case ts.SyntaxKind.NumberKeyword:
|
|
521
|
-
return
|
|
587
|
+
return absPrim("number");
|
|
522
588
|
case ts.SyntaxKind.BooleanKeyword:
|
|
523
|
-
return
|
|
589
|
+
return absPrim("boolean");
|
|
524
590
|
case ts.SyntaxKind.BigIntKeyword:
|
|
525
|
-
return
|
|
591
|
+
return absPrim("bigint");
|
|
526
592
|
case ts.SyntaxKind.SymbolKeyword:
|
|
527
|
-
return
|
|
593
|
+
return absPrim("symbol");
|
|
528
594
|
case ts.SyntaxKind.AnyKeyword:
|
|
529
595
|
case ts.SyntaxKind.UnknownKeyword:
|
|
530
596
|
case ts.SyntaxKind.ObjectKeyword:
|
|
531
|
-
return
|
|
597
|
+
return absUnknown();
|
|
532
598
|
case ts.SyntaxKind.VoidKeyword:
|
|
533
599
|
case ts.SyntaxKind.UndefinedKeyword:
|
|
534
|
-
return
|
|
600
|
+
return absUndefLit();
|
|
535
601
|
case ts.SyntaxKind.NeverKeyword:
|
|
536
|
-
return
|
|
602
|
+
return absNever();
|
|
537
603
|
case ts.SyntaxKind.NullKeyword:
|
|
538
|
-
return
|
|
604
|
+
return absNullLit();
|
|
539
605
|
default:
|
|
540
|
-
return
|
|
606
|
+
return absUnknown();
|
|
541
607
|
}
|
|
542
608
|
}
|
|
543
609
|
function indent(level) {
|
|
@@ -548,66 +614,74 @@ function emitKey(key) {
|
|
|
548
614
|
}
|
|
549
615
|
function emitEntries(lines, record, level) {
|
|
550
616
|
for (const [key, value] of Object.entries(record)) {
|
|
551
|
-
lines.push(`${indent(level)}${emitKey(key)}: ${
|
|
617
|
+
lines.push(`${indent(level)}${emitKey(key)}: ${emitAbs(value, /* @__PURE__ */ new Set())},`);
|
|
552
618
|
}
|
|
553
619
|
}
|
|
554
|
-
function
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
if (tv.value === null) return "T.null";
|
|
558
|
-
if (tv.value === void 0) return "T.undefined";
|
|
559
|
-
return `T.literal(${JSON.stringify(tv.value)})`;
|
|
560
|
-
case "primitive":
|
|
561
|
-
return `T.${tv.type}`;
|
|
562
|
-
case "unknown":
|
|
563
|
-
return "T.unknown";
|
|
620
|
+
function emitAbs(a, expanding) {
|
|
621
|
+
const s = a.shape;
|
|
622
|
+
switch (s.k) {
|
|
564
623
|
case "never":
|
|
565
|
-
return "
|
|
566
|
-
case "
|
|
567
|
-
|
|
624
|
+
return "absNever";
|
|
625
|
+
case "unknown":
|
|
626
|
+
if (a.term?.op === "lit") {
|
|
627
|
+
const v = a.term.value;
|
|
628
|
+
if (v === null) return `makeAbs({ k: "unknown" }, { op: "lit", value: null }, undefined, "exact")`;
|
|
629
|
+
if (v === void 0) return `makeAbs({ k: "unknown" }, { op: "lit", value: undefined }, undefined, "exact")`;
|
|
630
|
+
if (typeof v === "number") return `numLit(${JSON.stringify(v)})`;
|
|
631
|
+
if (typeof v === "boolean") return `boolLit(${v})`;
|
|
632
|
+
if (typeof v === "string") return `strLit(${JSON.stringify(v)})`;
|
|
633
|
+
}
|
|
634
|
+
return "absUnknown";
|
|
635
|
+
case "any":
|
|
636
|
+
return "absUnknown";
|
|
637
|
+
case "prim": {
|
|
638
|
+
if (a.term?.op === "lit") {
|
|
639
|
+
const v = a.term.value;
|
|
640
|
+
if (typeof v === "number") return `numLit(${JSON.stringify(v)})`;
|
|
641
|
+
if (typeof v === "boolean") return `boolLit(${v})`;
|
|
642
|
+
if (typeof v === "string") return `strLit(${JSON.stringify(v)})`;
|
|
643
|
+
}
|
|
644
|
+
if (s.type === "number") return "num()";
|
|
645
|
+
if (s.type === "string") return "str()";
|
|
646
|
+
if (s.type === "boolean") return "bool()";
|
|
647
|
+
return "absUnknown";
|
|
648
|
+
}
|
|
649
|
+
case "arr":
|
|
650
|
+
return `makeAbs({ k: "arr", element: ${emitAbs(s.element, expanding)} }, undefined, undefined, "exact")`;
|
|
568
651
|
case "tuple":
|
|
569
|
-
return `
|
|
570
|
-
case "
|
|
571
|
-
return `
|
|
572
|
-
case "
|
|
573
|
-
const entries = Object.entries(
|
|
574
|
-
([key,
|
|
652
|
+
return `makeAbs({ k: "tuple", elements: [${s.elements.map((e) => emitAbs(e, expanding)).join(", ")}] }, undefined, undefined, "exact")`;
|
|
653
|
+
case "eff":
|
|
654
|
+
return `makeAbs({ k: "eff", eff: ${JSON.stringify(s.eff)}, inner: ${emitAbs(s.inner, expanding)} }, undefined, undefined, "exact")`;
|
|
655
|
+
case "obj": {
|
|
656
|
+
const entries = Object.entries(s.slots).map(
|
|
657
|
+
([key, slot]) => `${emitKey(key)}: { value: ${emitAbs(slot.value, expanding)} }`
|
|
575
658
|
);
|
|
576
|
-
return `
|
|
659
|
+
return `objOf({ ${entries.join(", ")} })`;
|
|
577
660
|
}
|
|
578
|
-
case "
|
|
579
|
-
if (expanding.has(
|
|
580
|
-
return `
|
|
661
|
+
case "brand": {
|
|
662
|
+
if (expanding.has(s.name)) {
|
|
663
|
+
return `makeAbs({ k: "brand", name: ${JSON.stringify(s.name)}, shape: absUnknown }, undefined, undefined, "path")`;
|
|
581
664
|
}
|
|
582
|
-
expanding.add(
|
|
665
|
+
expanding.add(s.name);
|
|
583
666
|
try {
|
|
584
|
-
|
|
585
|
-
([key, value]) => `${emitKey(key)}: ${emitType(value, expanding)}`
|
|
586
|
-
);
|
|
587
|
-
return `T.instanceOf(${JSON.stringify(tv.className)}, { ${entries.join(", ")} })`;
|
|
667
|
+
return `makeAbs({ k: "brand", name: ${JSON.stringify(s.name)}, shape: ${emitAbs(s.shape, expanding)} }, undefined, undefined, "path")`;
|
|
588
668
|
} finally {
|
|
589
|
-
expanding.delete(
|
|
669
|
+
expanding.delete(s.name);
|
|
590
670
|
}
|
|
591
671
|
}
|
|
592
|
-
case "
|
|
593
|
-
if (
|
|
594
|
-
if (
|
|
595
|
-
return `
|
|
672
|
+
case "sum": {
|
|
673
|
+
if (s.members.length === 0) return "absNever";
|
|
674
|
+
if (s.members.length === 1) return emitAbs(s.members[0], expanding);
|
|
675
|
+
return `makeAbs({ k: "sum", members: [${s.members.map((m) => emitAbs(m, expanding)).join(", ")}] }, undefined, undefined, "exact")`;
|
|
596
676
|
}
|
|
597
|
-
case "
|
|
598
|
-
const
|
|
599
|
-
|
|
600
|
-
const
|
|
601
|
-
|
|
602
|
-
if (sig.throwsType && sig.throwsType.kind !== "never") {
|
|
603
|
-
return `T.fnSig([${params}], ${ret}, ${emitType(sig.throwsType, expanding)})`;
|
|
604
|
-
}
|
|
605
|
-
return `T.fnSig([${params}], ${ret})`;
|
|
677
|
+
case "fn": {
|
|
678
|
+
const pts = s.paramTypes ?? [];
|
|
679
|
+
const params = pts.map((p) => emitAbs(p, expanding)).join(", ");
|
|
680
|
+
const ret = s.returnType ? emitAbs(s.returnType, expanding) : "absUnknown";
|
|
681
|
+
return `relationFn([${params}], ${ret}, { conf: "exact" })`;
|
|
606
682
|
}
|
|
607
|
-
case "refined":
|
|
608
|
-
return emitType(tv.base, expanding);
|
|
609
683
|
default:
|
|
610
|
-
return "
|
|
684
|
+
return "absUnknown";
|
|
611
685
|
}
|
|
612
686
|
}
|
|
613
687
|
export {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nudojs/harvester",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.5",
|
|
4
4
|
"engines": {
|
|
5
5
|
"node": ">=20"
|
|
6
6
|
},
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
},
|
|
31
31
|
"dependencies": {
|
|
32
32
|
"typescript": "^5.8.0",
|
|
33
|
-
"@nudojs/core": "
|
|
33
|
+
"@nudojs/core": "2.0.0"
|
|
34
34
|
},
|
|
35
35
|
"scripts": {
|
|
36
36
|
"build": "tsup src/index.ts --format esm --dts"
|