nudojs 1.2.0 → 1.3.1
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.js +1671 -581
- package/package.json +6 -6
package/dist/index.js
CHANGED
|
@@ -59,10 +59,14 @@ function termEquals(a, b) {
|
|
|
59
59
|
}
|
|
60
60
|
return false;
|
|
61
61
|
}
|
|
62
|
+
function litKeyString(v2) {
|
|
63
|
+
if (typeof v2 === "number" && Object.is(v2, -0)) return "-0";
|
|
64
|
+
return String(v2);
|
|
65
|
+
}
|
|
62
66
|
function termToString(t) {
|
|
63
67
|
if (t.op === "lit") {
|
|
64
68
|
if (typeof t.value === "string") return JSON.stringify(t.value);
|
|
65
|
-
if (typeof t.value === "number"
|
|
69
|
+
if (typeof t.value === "number") return litKeyString(t.value);
|
|
66
70
|
return String(t.value);
|
|
67
71
|
}
|
|
68
72
|
if (t.op === "var") return t.id;
|
|
@@ -1012,6 +1016,48 @@ var init_pred = __esm({
|
|
|
1012
1016
|
}
|
|
1013
1017
|
});
|
|
1014
1018
|
|
|
1019
|
+
// ../core/src/algebra/projection-budget.ts
|
|
1020
|
+
var PROJECTION_MAX_DEPTH, ProjectionBudget;
|
|
1021
|
+
var init_projection_budget = __esm({
|
|
1022
|
+
"../core/src/algebra/projection-budget.ts"() {
|
|
1023
|
+
"use strict";
|
|
1024
|
+
PROJECTION_MAX_DEPTH = 64;
|
|
1025
|
+
ProjectionBudget = class {
|
|
1026
|
+
#maxDepth;
|
|
1027
|
+
#path = [];
|
|
1028
|
+
#onPath = /* @__PURE__ */ new Set();
|
|
1029
|
+
/** 粘性:本次投影是否发生过截断("cycle" / "depth"),供台账记录 */
|
|
1030
|
+
truncated;
|
|
1031
|
+
constructor(maxDepth = PROJECTION_MAX_DEPTH) {
|
|
1032
|
+
this.#maxDepth = maxDepth;
|
|
1033
|
+
}
|
|
1034
|
+
/**
|
|
1035
|
+
* 进入一个 Abs(或 Shape)子树。返回 null → 继续递归,之后必须配对
|
|
1036
|
+
* `exit()`;返回 "cycle" | "depth" → 不得递归,按出口各自的约定渲染
|
|
1037
|
+
* 截断标记(不调用 exit——本次 enter 没有入栈)。
|
|
1038
|
+
*/
|
|
1039
|
+
enter(a) {
|
|
1040
|
+
if (this.#onPath.has(a)) {
|
|
1041
|
+
this.truncated = "cycle";
|
|
1042
|
+
return "cycle";
|
|
1043
|
+
}
|
|
1044
|
+
if (this.#path.length >= this.#maxDepth) {
|
|
1045
|
+
this.truncated = "depth";
|
|
1046
|
+
return "depth";
|
|
1047
|
+
}
|
|
1048
|
+
this.#path.push(a);
|
|
1049
|
+
this.#onPath.add(a);
|
|
1050
|
+
return null;
|
|
1051
|
+
}
|
|
1052
|
+
/** 离开子树(与返回 null 的 enter 严格配对)。 */
|
|
1053
|
+
exit() {
|
|
1054
|
+
const a = this.#path.pop();
|
|
1055
|
+
if (a !== void 0) this.#onPath.delete(a);
|
|
1056
|
+
}
|
|
1057
|
+
};
|
|
1058
|
+
}
|
|
1059
|
+
});
|
|
1060
|
+
|
|
1015
1061
|
// ../core/src/algebra/abs.ts
|
|
1016
1062
|
function anyVar(id, conf = "path") {
|
|
1017
1063
|
return { shape: { k: "any" }, term: { op: "var", id }, conf };
|
|
@@ -1075,13 +1121,34 @@ function confJoin(a, b) {
|
|
|
1075
1121
|
return rank[Math.max(ia < 0 ? 5 : ia, ib < 0 ? 5 : ib)];
|
|
1076
1122
|
}
|
|
1077
1123
|
function absToString(a) {
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
return
|
|
1124
|
+
return absToStringB(a, new ProjectionBudget());
|
|
1125
|
+
}
|
|
1126
|
+
function absToStringB(a, budget) {
|
|
1127
|
+
const stop2 = budget.enter(a);
|
|
1128
|
+
if (stop2) return stop2 === "cycle" ? "\u2026cycle" : "\u2026";
|
|
1129
|
+
try {
|
|
1130
|
+
const parts = [shapeToStringB(a.shape, budget)];
|
|
1131
|
+
if (a.term) parts.push(`term=${termToString(a.term)}`);
|
|
1132
|
+
if (a.pred && a.pred.op !== "true") parts.push(predToString(a.pred));
|
|
1133
|
+
parts.push(`#${a.conf}`);
|
|
1134
|
+
return parts.join(" ");
|
|
1135
|
+
} finally {
|
|
1136
|
+
budget.exit();
|
|
1137
|
+
}
|
|
1083
1138
|
}
|
|
1084
1139
|
function shapeToString(s) {
|
|
1140
|
+
return shapeToStringB(s, new ProjectionBudget());
|
|
1141
|
+
}
|
|
1142
|
+
function shapeToStringB(s, budget) {
|
|
1143
|
+
const stop2 = budget.enter(s);
|
|
1144
|
+
if (stop2) return stop2 === "cycle" ? "\u2026cycle" : "\u2026";
|
|
1145
|
+
try {
|
|
1146
|
+
return shapeToStringInner(s, budget);
|
|
1147
|
+
} finally {
|
|
1148
|
+
budget.exit();
|
|
1149
|
+
}
|
|
1150
|
+
}
|
|
1151
|
+
function shapeToStringInner(s, budget) {
|
|
1085
1152
|
switch (s.k) {
|
|
1086
1153
|
case "never":
|
|
1087
1154
|
return "never";
|
|
@@ -1093,22 +1160,22 @@ function shapeToString(s) {
|
|
|
1093
1160
|
return s.type;
|
|
1094
1161
|
case "obj": {
|
|
1095
1162
|
const entries = Object.entries(s.slots).map(
|
|
1096
|
-
([k, slot]) => `${k}${slot.optional ? "?" : ""}: ${
|
|
1163
|
+
([k, slot]) => `${k}${slot.optional ? "?" : ""}: ${absToStringB(slot.value, budget)}`
|
|
1097
1164
|
);
|
|
1098
1165
|
return `{ ${entries.join(", ")} }`;
|
|
1099
1166
|
}
|
|
1100
1167
|
case "arr":
|
|
1101
|
-
return `${
|
|
1168
|
+
return `${shapeToStringB(s.element.shape, budget)}[]`;
|
|
1102
1169
|
case "tuple":
|
|
1103
|
-
return `[${s.elements.map((e) =>
|
|
1170
|
+
return `[${s.elements.map((e) => shapeToStringB(e.shape, budget)).join(", ")}]`;
|
|
1104
1171
|
case "fn":
|
|
1105
1172
|
return `fn(${s.params.join(", ")})${s.name ? ` ${s.name}` : ""}`;
|
|
1106
1173
|
case "brand":
|
|
1107
1174
|
return s.name;
|
|
1108
1175
|
case "eff":
|
|
1109
|
-
return `${s.eff}<${
|
|
1176
|
+
return `${s.eff}<${shapeToStringB(s.inner.shape, budget)}>`;
|
|
1110
1177
|
case "sum":
|
|
1111
|
-
return s.members.map(
|
|
1178
|
+
return s.members.map((m) => absToStringB(m, budget)).join(" | ");
|
|
1112
1179
|
default:
|
|
1113
1180
|
return "\xB7";
|
|
1114
1181
|
}
|
|
@@ -1153,6 +1220,7 @@ var init_abs = __esm({
|
|
|
1153
1220
|
"use strict";
|
|
1154
1221
|
init_term();
|
|
1155
1222
|
init_pred();
|
|
1223
|
+
init_projection_budget();
|
|
1156
1224
|
never = { shape: { k: "never" }, conf: "exact" };
|
|
1157
1225
|
unknown = { shape: { k: "unknown" }, conf: "partial" };
|
|
1158
1226
|
anyAbs = { shape: { k: "any" }, conf: "path" };
|
|
@@ -15788,7 +15856,7 @@ function absFunction(params, impl, opts) {
|
|
|
15788
15856
|
return a;
|
|
15789
15857
|
}
|
|
15790
15858
|
function termKey2(t) {
|
|
15791
|
-
if (t.op === "lit") return `L:${typeof t.value}:${
|
|
15859
|
+
if (t.op === "lit") return `L:${typeof t.value}:${litKeyString(t.value)}`;
|
|
15792
15860
|
if (t.op === "var") return `V:${t.id}`;
|
|
15793
15861
|
return `A:${t.fn}(${t.args.map(termKey2).join(",")})`;
|
|
15794
15862
|
}
|
|
@@ -15904,6 +15972,7 @@ var init_abs_fn = __esm({
|
|
|
15904
15972
|
"../core/src/algebra/abs-fn.ts"() {
|
|
15905
15973
|
"use strict";
|
|
15906
15974
|
init_abs();
|
|
15975
|
+
init_term();
|
|
15907
15976
|
implByAbs = /* @__PURE__ */ new WeakMap();
|
|
15908
15977
|
}
|
|
15909
15978
|
});
|
|
@@ -16258,7 +16327,7 @@ function absShapeKey(a, seen = /* @__PURE__ */ new Set()) {
|
|
|
16258
16327
|
try {
|
|
16259
16328
|
const s = a.shape;
|
|
16260
16329
|
if (s.k === "prim") {
|
|
16261
|
-
if (a.term?.op === "lit") return `prim:${s.type}:${
|
|
16330
|
+
if (a.term?.op === "lit") return `prim:${s.type}:${litKeyString(a.term.value)}`;
|
|
16262
16331
|
const t = a.term ? termToString(a.term) : "";
|
|
16263
16332
|
const p = a.pred && a.pred.op !== "true" ? predToString(a.pred) : "";
|
|
16264
16333
|
return `prim:${s.type}:${t}:${p}`;
|
|
@@ -16270,7 +16339,7 @@ function absShapeKey(a, seen = /* @__PURE__ */ new Set()) {
|
|
|
16270
16339
|
const v2 = a.term.value;
|
|
16271
16340
|
if (v2 === void 0) return "unknown:undefined";
|
|
16272
16341
|
if (v2 === null) return "unknown:null";
|
|
16273
|
-
return `unknown:lit:${typeof v2}:${
|
|
16342
|
+
return `unknown:lit:${typeof v2}:${litKeyString(v2)}`;
|
|
16274
16343
|
}
|
|
16275
16344
|
if (a.term) return `unknown:${termToString(a.term)}`;
|
|
16276
16345
|
return "unknown";
|
|
@@ -16952,7 +17021,7 @@ function bindTypeVars(pattern, arg, map, depth = 0) {
|
|
|
16952
17021
|
}
|
|
16953
17022
|
if (ps.k === "obj" && as.k === "obj") {
|
|
16954
17023
|
for (const [key, slot] of Object.entries(ps.slots)) {
|
|
16955
|
-
const aSlot = as.slots
|
|
17024
|
+
const aSlot = getSlot(as.slots, key);
|
|
16956
17025
|
if (aSlot) bindTypeVars(slot.value, aSlot.value, map, depth + 1);
|
|
16957
17026
|
}
|
|
16958
17027
|
return;
|
|
@@ -19471,6 +19540,7 @@ function absToJsonNative(a, seen) {
|
|
|
19471
19540
|
if (t?.op === "lit") return t.value;
|
|
19472
19541
|
const s = a.shape;
|
|
19473
19542
|
if (s.k === "tuple") {
|
|
19543
|
+
if (a.shape.rest) return NOT_LITERAL;
|
|
19474
19544
|
seen.add(a);
|
|
19475
19545
|
const holes = a.shape.holes ?? [];
|
|
19476
19546
|
const out = [];
|
|
@@ -21902,51 +21972,15 @@ function toNumericAbs(a) {
|
|
|
21902
21972
|
}
|
|
21903
21973
|
return n;
|
|
21904
21974
|
}
|
|
21905
|
-
function updateAddAbs(a) {
|
|
21975
|
+
function updateAddAbs(a, phi2 = pTrue) {
|
|
21906
21976
|
const n = toNumericAbs(a);
|
|
21907
21977
|
const one = n.shape.k === "prim" && n.shape.type === "bigint" ? bigintLit(1n) : numLit(1);
|
|
21908
|
-
|
|
21909
|
-
return abs({ k: "prim", type: "bigint" }, void 0, void 0, confJoin(n.conf, "exact"));
|
|
21910
|
-
}
|
|
21911
|
-
return addNumeric(n, one);
|
|
21978
|
+
return add(n, one, phi2);
|
|
21912
21979
|
}
|
|
21913
|
-
function updateSubAbs(a) {
|
|
21980
|
+
function updateSubAbs(a, phi2 = pTrue) {
|
|
21914
21981
|
const n = toNumericAbs(a);
|
|
21915
21982
|
const one = n.shape.k === "prim" && n.shape.type === "bigint" ? bigintLit(1n) : numLit(1);
|
|
21916
|
-
|
|
21917
|
-
return abs({ k: "prim", type: "bigint" }, void 0, void 0, confJoin(n.conf, "exact"));
|
|
21918
|
-
}
|
|
21919
|
-
return subNumeric(n, one);
|
|
21920
|
-
}
|
|
21921
|
-
function addNumeric(a, b) {
|
|
21922
|
-
const ra = litValue(a);
|
|
21923
|
-
const rb = litValue(b);
|
|
21924
|
-
const va = ra.ok ? ra.value : void 0;
|
|
21925
|
-
const vb = rb.ok ? rb.value : void 0;
|
|
21926
|
-
if (typeof va === "bigint" && typeof vb === "bigint") return bigintLit(va + vb);
|
|
21927
|
-
if (typeof va === "number" && typeof vb === "number") return numLit(va + vb);
|
|
21928
|
-
const big = a.shape.k === "prim" && a.shape.type === "bigint" || typeof va === "bigint";
|
|
21929
|
-
return abs(
|
|
21930
|
-
{ k: "prim", type: big ? "bigint" : "number" },
|
|
21931
|
-
void 0,
|
|
21932
|
-
void 0,
|
|
21933
|
-
confJoin(confJoin(a.conf, b.conf), "path")
|
|
21934
|
-
);
|
|
21935
|
-
}
|
|
21936
|
-
function subNumeric(a, b) {
|
|
21937
|
-
const ra = litValue(a);
|
|
21938
|
-
const rb = litValue(b);
|
|
21939
|
-
const va = ra.ok ? ra.value : void 0;
|
|
21940
|
-
const vb = rb.ok ? rb.value : void 0;
|
|
21941
|
-
if (typeof va === "bigint" && typeof vb === "bigint") return bigintLit(va - vb);
|
|
21942
|
-
if (typeof va === "number" && typeof vb === "number") return numLit(va - vb);
|
|
21943
|
-
const big = a.shape.k === "prim" && a.shape.type === "bigint" || typeof va === "bigint";
|
|
21944
|
-
return abs(
|
|
21945
|
-
{ k: "prim", type: big ? "bigint" : "number" },
|
|
21946
|
-
void 0,
|
|
21947
|
-
void 0,
|
|
21948
|
-
confJoin(confJoin(a.conf, b.conf), "path")
|
|
21949
|
-
);
|
|
21983
|
+
return sub(n, one, phi2);
|
|
21950
21984
|
}
|
|
21951
21985
|
function toNumberAbs(a) {
|
|
21952
21986
|
if (isSymbolAbs(a)) {
|
|
@@ -22227,6 +22261,7 @@ var init_surface = __esm({
|
|
|
22227
22261
|
init_symbol_id();
|
|
22228
22262
|
init_term();
|
|
22229
22263
|
init_pred();
|
|
22264
|
+
init_arithmetic();
|
|
22230
22265
|
init_nudo_throw();
|
|
22231
22266
|
init_may_throw();
|
|
22232
22267
|
}
|
|
@@ -23019,24 +23054,40 @@ function leqShape(src, tgt, phi2, env2, depth) {
|
|
|
23019
23054
|
return leqWithPred(s.element, t.element, phi2, env2, depth + 1);
|
|
23020
23055
|
}
|
|
23021
23056
|
if (s.k === "tuple") {
|
|
23022
|
-
|
|
23057
|
+
const elsOk = s.elements.every((el) => leqWithPred(el, t.element, phi2, env2, depth + 1).ok);
|
|
23058
|
+
const restOk = !s.rest || leqWithPred(s.rest, t.element, phi2, env2, depth + 1).ok;
|
|
23059
|
+
return elsOk && restOk ? ok() : fail("tuple \u22AD arr");
|
|
23023
23060
|
}
|
|
23024
23061
|
return fail(`shape ${s.k} \u22AD arr`);
|
|
23025
23062
|
}
|
|
23026
23063
|
if (t.k === "tuple") {
|
|
23027
23064
|
if (s.k !== "tuple") return fail(`shape ${s.k} \u22AD tuple`);
|
|
23028
|
-
if (s.elements.length !== t.elements.length) {
|
|
23065
|
+
if (!t.rest && s.elements.length !== t.elements.length) {
|
|
23029
23066
|
return fail(`tuple arity ${s.elements.length} \u22AD ${t.elements.length}`);
|
|
23030
23067
|
}
|
|
23068
|
+
if (t.rest && s.elements.length < t.elements.length) {
|
|
23069
|
+
return fail(`tuple arity ${s.elements.length} \u22AD ${t.elements.length} (target requires ${t.elements.length})`);
|
|
23070
|
+
}
|
|
23071
|
+
if (s.rest && !t.rest) {
|
|
23072
|
+
return fail(`tuple rest \u22AD fixed arity ${t.elements.length}`);
|
|
23073
|
+
}
|
|
23031
23074
|
const sHoles = s.holes ?? [];
|
|
23032
23075
|
const tHoles = t.holes ?? [];
|
|
23033
|
-
|
|
23034
|
-
|
|
23076
|
+
const overlap = Math.min(s.elements.length, t.elements.length);
|
|
23077
|
+
for (let i = 0; i < overlap; i++) {
|
|
23078
|
+
if (sHoles.includes(i) !== tHoles.includes(i)) {
|
|
23079
|
+
return fail(`tuple holes [${sHoles.join(",")}] \u22AD [${tHoles.join(",")}]`);
|
|
23080
|
+
}
|
|
23035
23081
|
}
|
|
23036
|
-
for (let i = 0; i <
|
|
23037
|
-
const
|
|
23082
|
+
for (let i = 0; i < s.elements.length; i++) {
|
|
23083
|
+
const tgt2 = i < t.elements.length ? t.elements[i] : t.rest;
|
|
23084
|
+
const r = leqWithPred(s.elements[i], tgt2, phi2, env2, depth + 1);
|
|
23038
23085
|
if (!r.ok) return fail(`tuple[${i}]: ${r.reason}`);
|
|
23039
23086
|
}
|
|
23087
|
+
if (s.rest && t.rest) {
|
|
23088
|
+
const r = leqWithPred(s.rest, t.rest, phi2, env2, depth + 1);
|
|
23089
|
+
if (!r.ok) return fail(`tuple rest: ${r.reason}`);
|
|
23090
|
+
}
|
|
23040
23091
|
return ok();
|
|
23041
23092
|
}
|
|
23042
23093
|
if (t.k === "fn") {
|
|
@@ -23121,13 +23172,29 @@ function formatAbs(a, opts = {}) {
|
|
|
23121
23172
|
return parts.join(" ");
|
|
23122
23173
|
}
|
|
23123
23174
|
function formatShapeSlot(a) {
|
|
23124
|
-
|
|
23175
|
+
return formatShapeSlotB(a, new ProjectionBudget());
|
|
23176
|
+
}
|
|
23177
|
+
function formatShapeSlotB(a, budget) {
|
|
23178
|
+
const base = formatShapeB(a, budget);
|
|
23125
23179
|
if (!a.term || a.term.op === "lit") return base;
|
|
23126
23180
|
if (a.shape.k === "fn" || a.shape.k === "arr") return base;
|
|
23127
23181
|
if (a.shape.k === "any" && a.term.op === "var") return termToString(a.term);
|
|
23128
23182
|
return `${base} = ${termToString(a.term)}`;
|
|
23129
23183
|
}
|
|
23130
23184
|
function formatShape(a) {
|
|
23185
|
+
return formatShapeB(a, new ProjectionBudget());
|
|
23186
|
+
}
|
|
23187
|
+
function formatShapeB(a, budget) {
|
|
23188
|
+
const stop2 = budget.enter(a);
|
|
23189
|
+
if (stop2 === "cycle") return FORMAT_TRUNC.cycle;
|
|
23190
|
+
if (stop2 === "depth") return FORMAT_TRUNC.depth;
|
|
23191
|
+
try {
|
|
23192
|
+
return formatShapeInner(a, budget);
|
|
23193
|
+
} finally {
|
|
23194
|
+
budget.exit();
|
|
23195
|
+
}
|
|
23196
|
+
}
|
|
23197
|
+
function formatShapeInner(a, budget) {
|
|
23131
23198
|
const s = a.shape;
|
|
23132
23199
|
switch (s.k) {
|
|
23133
23200
|
case "never":
|
|
@@ -23154,28 +23221,28 @@ function formatShape(a) {
|
|
|
23154
23221
|
const entries = Object.entries(s.slots).map(([k, slot]) => {
|
|
23155
23222
|
const opt = slot.optional ? "?" : "";
|
|
23156
23223
|
const key = /^[A-Za-z_$][A-Za-z0-9_$]*$/.test(k) ? k : JSON.stringify(k);
|
|
23157
|
-
return `${key}${opt}: ${
|
|
23224
|
+
return `${key}${opt}: ${formatShapeB(slot.value, budget)}`;
|
|
23158
23225
|
});
|
|
23159
23226
|
return `{ ${entries.join(", ")} }`;
|
|
23160
23227
|
}
|
|
23161
23228
|
case "arr": {
|
|
23162
23229
|
if (s.element.shape.k === "any" && s.element.term?.op === "var") {
|
|
23163
|
-
return `arr(${
|
|
23230
|
+
return `arr(${formatShapeSlotB(s.element, budget)})`;
|
|
23164
23231
|
}
|
|
23165
|
-
return `${
|
|
23232
|
+
return `${formatShapeB(s.element, budget)}[]`;
|
|
23166
23233
|
}
|
|
23167
23234
|
case "tuple": {
|
|
23168
23235
|
const holes = s.holes ?? [];
|
|
23169
23236
|
const parts = s.elements.map(
|
|
23170
|
-
(el, i) => holes.includes(i) ? "" :
|
|
23237
|
+
(el, i) => holes.includes(i) ? "" : formatShapeB(el, budget)
|
|
23171
23238
|
);
|
|
23172
23239
|
if (s.rest) {
|
|
23173
|
-
parts.push(`...${
|
|
23240
|
+
parts.push(`...${formatShapeB(s.rest, budget)}`);
|
|
23174
23241
|
}
|
|
23175
23242
|
return `[${parts.join(", ")}]`;
|
|
23176
23243
|
}
|
|
23177
23244
|
case "fn": {
|
|
23178
|
-
const ret = s.returnType !== void 0 ?
|
|
23245
|
+
const ret = s.returnType !== void 0 ? formatShapeSlotB(s.returnType, budget) : "?";
|
|
23179
23246
|
const labels = s.params ?? [];
|
|
23180
23247
|
const paramTypes = s.paramTypes;
|
|
23181
23248
|
const hasMarkers = labels.some(
|
|
@@ -23187,7 +23254,7 @@ function formatShape(a) {
|
|
|
23187
23254
|
for (let i = 0; i < n; i++) {
|
|
23188
23255
|
const label = labels[i];
|
|
23189
23256
|
const type = paramTypes?.[i];
|
|
23190
|
-
const typeText = type !== void 0 ?
|
|
23257
|
+
const typeText = type !== void 0 ? formatShapeSlotB(type, budget) : void 0;
|
|
23191
23258
|
if (label?.startsWith("...")) {
|
|
23192
23259
|
ps.push(typeText ? `...${label.slice(3)}: ${typeText}` : label);
|
|
23193
23260
|
} else if (label?.endsWith("?")) {
|
|
@@ -23204,7 +23271,7 @@ function formatShape(a) {
|
|
|
23204
23271
|
return `(${renderLabeled().join(", ")}) => ${ret}`;
|
|
23205
23272
|
}
|
|
23206
23273
|
if (paramTypes && paramTypes.length > 0) {
|
|
23207
|
-
const ps = paramTypes.map((p) =>
|
|
23274
|
+
const ps = paramTypes.map((p) => formatShapeSlotB(p, budget));
|
|
23208
23275
|
return `(${ps.join(", ")}) => ${ret}`;
|
|
23209
23276
|
}
|
|
23210
23277
|
return `(${labels.join(", ")}) => ${ret}`;
|
|
@@ -23215,7 +23282,7 @@ function formatShape(a) {
|
|
|
23215
23282
|
if (slots) {
|
|
23216
23283
|
const arg = (key) => {
|
|
23217
23284
|
const sl = slots[key];
|
|
23218
|
-
return sl ?
|
|
23285
|
+
return sl ? formatShapeSlotB(sl.value, budget) : void 0;
|
|
23219
23286
|
};
|
|
23220
23287
|
if (s.name === "Map" || s.name === "ReadonlyMap" || s.name === "WeakMap") {
|
|
23221
23288
|
const k = arg("__key");
|
|
@@ -23230,12 +23297,12 @@ function formatShape(a) {
|
|
|
23230
23297
|
return `${s.name}`;
|
|
23231
23298
|
}
|
|
23232
23299
|
case "eff":
|
|
23233
|
-
return `${s.eff}<${
|
|
23300
|
+
return `${s.eff}<${formatShapeB(s.inner, budget)}>`;
|
|
23234
23301
|
case "sum": {
|
|
23235
23302
|
const seen = /* @__PURE__ */ new Set();
|
|
23236
23303
|
const parts = [];
|
|
23237
23304
|
for (const m of s.members) {
|
|
23238
|
-
const t =
|
|
23305
|
+
const t = formatShapeB(m, budget);
|
|
23239
23306
|
if (seen.has(t)) continue;
|
|
23240
23307
|
seen.add(t);
|
|
23241
23308
|
parts.push(t);
|
|
@@ -23259,12 +23326,15 @@ function formatAbsMultiline(a, label) {
|
|
|
23259
23326
|
lines.push(` conf: ${a.conf}`);
|
|
23260
23327
|
return lines.join("\n");
|
|
23261
23328
|
}
|
|
23329
|
+
var FORMAT_TRUNC;
|
|
23262
23330
|
var init_format = __esm({
|
|
23263
23331
|
"../core/src/algebra/format.ts"() {
|
|
23264
23332
|
"use strict";
|
|
23265
23333
|
init_abs();
|
|
23266
23334
|
init_term();
|
|
23267
23335
|
init_pred();
|
|
23336
|
+
init_projection_budget();
|
|
23337
|
+
FORMAT_TRUNC = { cycle: "\u2026cycle", depth: "\u2026" };
|
|
23268
23338
|
}
|
|
23269
23339
|
});
|
|
23270
23340
|
|
|
@@ -23938,12 +24008,19 @@ function parseNudoImportPayload(payload) {
|
|
|
23938
24008
|
if (s === "") return void 0;
|
|
23939
24009
|
const named = s.match(/^\{([^}]+)\}\s*from\s*["']([^"']+)["']$/);
|
|
23940
24010
|
if (named) {
|
|
23941
|
-
const names2 =
|
|
23942
|
-
|
|
24011
|
+
const names2 = [];
|
|
24012
|
+
const importedOfLocal = {};
|
|
24013
|
+
for (const x of named[1].split("\n").map((line) => line.replace(/^\s*\/\/\/?\s?/, "").trim()).join("\n").split(",").map((x2) => x2.trim()).filter(Boolean)) {
|
|
24014
|
+
const seg = x.split(/\s+as\s+/);
|
|
24015
|
+
const local = seg[seg.length - 1].trim();
|
|
24016
|
+
names2.push(local);
|
|
24017
|
+
if (seg.length > 1) importedOfLocal[local] = seg[0].trim();
|
|
24018
|
+
}
|
|
24019
|
+
return { names: names2, importedOfLocal, spec: named[2] };
|
|
23943
24020
|
}
|
|
23944
24021
|
const ns = s.match(/^\*\s+as\s+(\w+)\s+from\s*["']([^"']+)["']$/);
|
|
23945
24022
|
if (ns) {
|
|
23946
|
-
return { names: [`*${ns[1]}`], spec: ns[2] };
|
|
24023
|
+
return { names: [`*${ns[1]}`], importedOfLocal: {}, spec: ns[2] };
|
|
23947
24024
|
}
|
|
23948
24025
|
if (/^[\w$]+\s+from\b/.test(s) || /^[\w$]+\s*,/.test(s)) return "malformed-default";
|
|
23949
24026
|
return "malformed";
|
|
@@ -23953,7 +24030,7 @@ function fileDirectiveVisibleText(source) {
|
|
|
23953
24030
|
}
|
|
23954
24031
|
function extractFileEnvNames(source) {
|
|
23955
24032
|
const text = fileDirectiveVisibleText(source);
|
|
23956
|
-
const re = new RegExp(`${LINE_COMMENT_PREFIX}\\
|
|
24033
|
+
const re = new RegExp(`${LINE_COMMENT_PREFIX}[ \\t]*@nudo:env[ \\t]+([^\\n*]+)`, "g");
|
|
23957
24034
|
const out = [];
|
|
23958
24035
|
let m;
|
|
23959
24036
|
while (m = re.exec(text)) {
|
|
@@ -23964,7 +24041,7 @@ function extractFileEnvNames(source) {
|
|
|
23964
24041
|
function extractMockModuleRecords(source) {
|
|
23965
24042
|
const text = fileDirectiveVisibleText(source);
|
|
23966
24043
|
const re = new RegExp(
|
|
23967
|
-
`${LINE_COMMENT_PREFIX}\\
|
|
24044
|
+
`${LINE_COMMENT_PREFIX}[ \\t]*@nudo:mock-module[ \\t]+([^\\n]+)`,
|
|
23968
24045
|
"g"
|
|
23969
24046
|
);
|
|
23970
24047
|
const out = [];
|
|
@@ -24165,7 +24242,7 @@ var init_directive_scan = __esm({
|
|
|
24165
24242
|
init_parse_source();
|
|
24166
24243
|
isPathLikeEnv = (s) => /^[^\s]+$/.test(s) && (s.startsWith("./") || s.startsWith("../") || s.startsWith("/") || /\.(ts|js|mjs|cjs|tsx|jsx)$/.test(s));
|
|
24167
24244
|
LINE_COMMENT_PREFIX = "(?:^|[^/:])\\/\\/\\/?";
|
|
24168
|
-
CASE_NAME_REGEX = /(?:^|\n)[ \t]*(?:\*[ \t]
|
|
24245
|
+
CASE_NAME_REGEX = /(?:^|\n)[ \t]*(?:\*[ \t]*|\/[ \t]*)?@nudo:case[ \t]+"([^"\n]+)"[ \t]*\(/g;
|
|
24169
24246
|
}
|
|
24170
24247
|
});
|
|
24171
24248
|
|
|
@@ -24782,11 +24859,7 @@ var init_constraint = __esm({
|
|
|
24782
24859
|
});
|
|
24783
24860
|
|
|
24784
24861
|
// ../core/src/algebra/refine.ts
|
|
24785
|
-
function
|
|
24786
|
-
const out = [];
|
|
24787
|
-
for (const rec of extractNudoImportRecords(source)) {
|
|
24788
|
-
out.push({ names: rec.names, spec: rec.spec });
|
|
24789
|
-
}
|
|
24862
|
+
function diagnoseMalformedNudoImports(source) {
|
|
24790
24863
|
for (const bad of scanMalformedNudoImports(source)) {
|
|
24791
24864
|
if (bad === "malformed-default") {
|
|
24792
24865
|
collectDiag({
|
|
@@ -24800,7 +24873,13 @@ function extractNudoImports(source) {
|
|
|
24800
24873
|
});
|
|
24801
24874
|
}
|
|
24802
24875
|
}
|
|
24803
|
-
|
|
24876
|
+
}
|
|
24877
|
+
function extractNudoImports(source) {
|
|
24878
|
+
diagnoseMalformedNudoImports(source);
|
|
24879
|
+
return extractNudoImportRecords(source).map((rec) => ({
|
|
24880
|
+
names: rec.names,
|
|
24881
|
+
spec: rec.spec
|
|
24882
|
+
}));
|
|
24804
24883
|
}
|
|
24805
24884
|
function setRefineDiagCollector(fn2) {
|
|
24806
24885
|
refineDiagCollector = fn2;
|
|
@@ -24897,6 +24976,21 @@ function rewriteSidecarSource(src, fromFile) {
|
|
|
24897
24976
|
cuts.push({ start: stmt.start, end: decl.start, text: "" });
|
|
24898
24977
|
continue;
|
|
24899
24978
|
}
|
|
24979
|
+
if (!stmt.source) {
|
|
24980
|
+
let aliasPairs = false;
|
|
24981
|
+
for (const spec of stmt.specifiers) {
|
|
24982
|
+
if (spec.type !== "ExportSpecifier") continue;
|
|
24983
|
+
if (spec.local.type !== "Identifier") continue;
|
|
24984
|
+
const key = spec.exported.type === "Identifier" ? spec.exported.name : spec.exported.value;
|
|
24985
|
+
if (key === void 0) continue;
|
|
24986
|
+
exportPairs.push({ key, expr: spec.local.name });
|
|
24987
|
+
aliasPairs = true;
|
|
24988
|
+
}
|
|
24989
|
+
if (aliasPairs) {
|
|
24990
|
+
cuts.push({ start: stmt.start, end: stmt.end, text: "" });
|
|
24991
|
+
continue;
|
|
24992
|
+
}
|
|
24993
|
+
}
|
|
24900
24994
|
badExport("'export { \u2026 }' (list / re-export)");
|
|
24901
24995
|
if (stmt.start != null && stmt.end != null) {
|
|
24902
24996
|
cuts.push({ start: stmt.start, end: stmt.end, text: "" });
|
|
@@ -25053,14 +25147,15 @@ function execSidecar(src, opts, chain, preloaded) {
|
|
|
25053
25147
|
});
|
|
25054
25148
|
prologue.push(`var ${n.local} = __nudoInjects;`);
|
|
25055
25149
|
} else if (n.imported !== void 0) {
|
|
25056
|
-
|
|
25150
|
+
const hasOwnInject = Object.hasOwn(sidecarInjects, n.imported);
|
|
25151
|
+
if (!hasOwnInject) {
|
|
25057
25152
|
collectDiag({
|
|
25058
25153
|
code: "nudo:interface-load",
|
|
25059
25154
|
message: `sidecar import '{ ${n.imported} }' from '${imp.spec}' is not an injected builder`,
|
|
25060
25155
|
file: fromFile
|
|
25061
25156
|
});
|
|
25062
|
-
|
|
25063
|
-
if (n.local !== n.imported
|
|
25157
|
+
prologue.push(`var ${n.local} = undefined;`);
|
|
25158
|
+
} else if (n.local !== n.imported) {
|
|
25064
25159
|
prologue.push(`var ${n.local} = __nudoInjects[${JSON.stringify(n.imported)}];`);
|
|
25065
25160
|
}
|
|
25066
25161
|
} else {
|
|
@@ -25129,21 +25224,23 @@ function execSidecar(src, opts, chain, preloaded) {
|
|
|
25129
25224
|
if (n.ns) {
|
|
25130
25225
|
deps[n.local] = depExports;
|
|
25131
25226
|
} else if (n.imported !== void 0) {
|
|
25132
|
-
if (
|
|
25227
|
+
if (Object.hasOwn(depExports, n.imported)) {
|
|
25228
|
+
deps[n.local] = depExports[n.imported];
|
|
25229
|
+
} else {
|
|
25133
25230
|
collectDiag({
|
|
25134
25231
|
code: "nudo:interface-load",
|
|
25135
25232
|
message: `sidecar '${imp.spec}' has no export '${n.imported}'`,
|
|
25136
25233
|
file: fromFile
|
|
25137
25234
|
});
|
|
25235
|
+
deps[n.local] = void 0;
|
|
25138
25236
|
}
|
|
25139
|
-
deps[n.local] = depExports[n.imported];
|
|
25140
25237
|
} else {
|
|
25141
25238
|
collectDiag({
|
|
25142
25239
|
code: "nudo:interface-load",
|
|
25143
25240
|
message: `sidecar default import '${n.local}' from '${imp.spec}' has no default export (sidecars export named constraints only)`,
|
|
25144
25241
|
file: fromFile
|
|
25145
25242
|
});
|
|
25146
|
-
deps[n.local] = depExports.default;
|
|
25243
|
+
deps[n.local] = Object.hasOwn(depExports, "default") ? depExports.default : void 0;
|
|
25147
25244
|
}
|
|
25148
25245
|
}
|
|
25149
25246
|
}
|
|
@@ -25247,7 +25344,8 @@ function resetNudoModuleExecCache() {
|
|
|
25247
25344
|
}
|
|
25248
25345
|
function collectConstraints(source, opts) {
|
|
25249
25346
|
const map = /* @__PURE__ */ new Map();
|
|
25250
|
-
|
|
25347
|
+
diagnoseMalformedNudoImports(source);
|
|
25348
|
+
const imports = extractNudoImportRecords(source);
|
|
25251
25349
|
for (const imp of imports) {
|
|
25252
25350
|
if (!opts.loadModule || !opts.fromFile) {
|
|
25253
25351
|
collectDiag({
|
|
@@ -25302,19 +25400,20 @@ function collectConstraints(source, opts) {
|
|
|
25302
25400
|
}
|
|
25303
25401
|
continue;
|
|
25304
25402
|
}
|
|
25305
|
-
const
|
|
25403
|
+
const imported = imp.importedOfLocal[name] ?? name;
|
|
25404
|
+
const v2 = Object.hasOwn(exports, imported) ? exports[imported] : void 0;
|
|
25306
25405
|
if (isNudoConstraint(v2)) {
|
|
25307
25406
|
map.set(name, v2);
|
|
25308
25407
|
} else if (v2 === void 0) {
|
|
25309
25408
|
collectDiag({
|
|
25310
25409
|
code: "nudo:interface-load",
|
|
25311
|
-
message: `sidecar '${imp.spec}' has no export '${
|
|
25410
|
+
message: `sidecar '${imp.spec}' has no export '${imported}'`,
|
|
25312
25411
|
file: opts.fromFile
|
|
25313
25412
|
});
|
|
25314
25413
|
} else {
|
|
25315
25414
|
collectDiag({
|
|
25316
25415
|
code: "nudo:interface-load",
|
|
25317
|
-
message: `sidecar '${imp.spec}' export '${
|
|
25416
|
+
message: `sidecar '${imp.spec}' export '${imported}' is not a Nudo constraint`,
|
|
25318
25417
|
file: opts.fromFile
|
|
25319
25418
|
});
|
|
25320
25419
|
}
|
|
@@ -25345,7 +25444,13 @@ function extractRefinesFromSource(source, fnName, opts = {}) {
|
|
|
25345
25444
|
const [, param, cName] = m;
|
|
25346
25445
|
if (param === "return") continue;
|
|
25347
25446
|
const c = constraints.get(cName);
|
|
25348
|
-
if (!c)
|
|
25447
|
+
if (!c) {
|
|
25448
|
+
collectDiag({
|
|
25449
|
+
code: "nudo:contract-syntax",
|
|
25450
|
+
message: `Unknown constraint name '${cName}' in @nudo:contract (expected a name bound by @nudo:import)`
|
|
25451
|
+
});
|
|
25452
|
+
continue;
|
|
25453
|
+
}
|
|
25349
25454
|
out.push({
|
|
25350
25455
|
param,
|
|
25351
25456
|
pred: instantiateConstraint(c, param),
|
|
@@ -25382,7 +25487,13 @@ function extractRefineReturnFromSource(source, fnName, opts = {}) {
|
|
|
25382
25487
|
}
|
|
25383
25488
|
const cName = m[1];
|
|
25384
25489
|
const c = constraints.get(cName);
|
|
25385
|
-
if (!c)
|
|
25490
|
+
if (!c) {
|
|
25491
|
+
collectDiag({
|
|
25492
|
+
code: "nudo:contract-syntax",
|
|
25493
|
+
message: `Unknown constraint name '${cName}' in @nudo:contract return (expected a name bound by @nudo:import)`
|
|
25494
|
+
});
|
|
25495
|
+
continue;
|
|
25496
|
+
}
|
|
25386
25497
|
return { name: cName, constraint: c };
|
|
25387
25498
|
}
|
|
25388
25499
|
}
|
|
@@ -25451,8 +25562,10 @@ var init_unsupported = __esm({
|
|
|
25451
25562
|
NudoUnsupportedError = class extends Error {
|
|
25452
25563
|
reason;
|
|
25453
25564
|
loc;
|
|
25454
|
-
constructor(reason, loc) {
|
|
25455
|
-
super(
|
|
25565
|
+
constructor(reason, loc, detail) {
|
|
25566
|
+
super(
|
|
25567
|
+
detail ? `nudo:unsupported ${reason} (${detail})` : `nudo:unsupported ${reason}`
|
|
25568
|
+
);
|
|
25456
25569
|
this.name = "NudoUnsupportedError";
|
|
25457
25570
|
this.reason = reason;
|
|
25458
25571
|
this.loc = loc;
|
|
@@ -26911,15 +27024,15 @@ function transpileStatement(stmt, depth, opts) {
|
|
|
26911
27024
|
if (nsSpecs.length > 0) {
|
|
26912
27025
|
if (!stmt.source) return `${pad}/* export * as without source skipped */`;
|
|
26913
27026
|
return nsSpecs.map((s) => {
|
|
26914
|
-
const exported = s.exported.type === "Identifier" ? s.exported.name : s.exported.value;
|
|
27027
|
+
const exported = s.exported.type === "Identifier" ? s.exported.name : JSON.stringify(s.exported.value);
|
|
26915
27028
|
return `${pad}export * as ${exported} from ${JSON.stringify(stmt.source.value)};`;
|
|
26916
27029
|
}).join("\n");
|
|
26917
27030
|
}
|
|
26918
27031
|
const specs = stmt.specifiers.filter(
|
|
26919
27032
|
(s) => "local" in s
|
|
26920
27033
|
).map((s) => {
|
|
26921
|
-
const local = s.local.type === "Identifier" ? s.local.name : s.local.value;
|
|
26922
|
-
const exported = s.exported.type === "Identifier" ? s.exported.name : s.exported.value;
|
|
27034
|
+
const local = s.local.type === "Identifier" ? s.local.name : JSON.stringify(s.local.value);
|
|
27035
|
+
const exported = s.exported.type === "Identifier" ? s.exported.name : JSON.stringify(s.exported.value);
|
|
26923
27036
|
return local === exported ? local : `${local} as ${exported}`;
|
|
26924
27037
|
}).join(", ");
|
|
26925
27038
|
if (stmt.source) {
|
|
@@ -28886,10 +28999,10 @@ function $toNumeric(a) {
|
|
|
28886
28999
|
return toNumericAbs(a);
|
|
28887
29000
|
}
|
|
28888
29001
|
function $updateAdd(a) {
|
|
28889
|
-
return updateAddAbs(a);
|
|
29002
|
+
return updateAddAbs(a, currentExecPhi());
|
|
28890
29003
|
}
|
|
28891
29004
|
function $updateSub(a) {
|
|
28892
|
-
return updateSubAbs(a);
|
|
29005
|
+
return updateSubAbs(a, currentExecPhi());
|
|
28893
29006
|
}
|
|
28894
29007
|
function $neg(a) {
|
|
28895
29008
|
return negAbs(a);
|
|
@@ -29153,21 +29266,51 @@ var init_member_diag = __esm({
|
|
|
29153
29266
|
});
|
|
29154
29267
|
|
|
29155
29268
|
// ../core/src/algebra/exec/class-registry.ts
|
|
29269
|
+
function beginClassEpoch() {
|
|
29270
|
+
classEpoch++;
|
|
29271
|
+
}
|
|
29272
|
+
function drainClassCollisions() {
|
|
29273
|
+
return classCollisions.splice(0, classCollisions.length);
|
|
29274
|
+
}
|
|
29275
|
+
function specShape(spec) {
|
|
29276
|
+
const ctorName = spec.ctor?.name ?? "anon";
|
|
29277
|
+
const methods2 = Object.keys(spec.methods ?? {}).sort().join(",");
|
|
29278
|
+
const statics = Object.keys(spec.staticMethods ?? {}).sort().join(",");
|
|
29279
|
+
const accessors = Object.keys(spec.accessors ?? {}).sort().join(",");
|
|
29280
|
+
return `${ctorName}[${methods2}](${statics}){${accessors}}`;
|
|
29281
|
+
}
|
|
29156
29282
|
function registerEvalClass(spec) {
|
|
29283
|
+
const prev = classRegistry.get(spec.name);
|
|
29284
|
+
const prevEpoch = classEpochs.get(spec.name);
|
|
29285
|
+
if (prev && prev !== spec && // 同 epoch(同一次 run 内)注册两次才可能是真碰撞:
|
|
29286
|
+
// 块级作用域同名类。跨 epoch = 顺序重注册(常态)。
|
|
29287
|
+
prevEpoch === classEpoch && specShape(prev) !== specShape(spec)) {
|
|
29288
|
+
classCollisions.push({
|
|
29289
|
+
name: spec.name,
|
|
29290
|
+
previous: specShape(prev),
|
|
29291
|
+
next: specShape(spec)
|
|
29292
|
+
});
|
|
29293
|
+
}
|
|
29157
29294
|
classRegistry.set(spec.name, spec);
|
|
29295
|
+
classEpochs.set(spec.name, classEpoch);
|
|
29158
29296
|
}
|
|
29159
29297
|
function getEvalClass(name) {
|
|
29160
29298
|
return classRegistry.get(name);
|
|
29161
29299
|
}
|
|
29162
29300
|
function clearBClasses() {
|
|
29163
29301
|
classRegistry.clear();
|
|
29302
|
+
classEpochs.clear();
|
|
29303
|
+
classCollisions.length = 0;
|
|
29164
29304
|
}
|
|
29165
|
-
var classRegistry;
|
|
29305
|
+
var classRegistry, classEpoch, classEpochs, classCollisions;
|
|
29166
29306
|
var init_class_registry = __esm({
|
|
29167
29307
|
"../core/src/algebra/exec/class-registry.ts"() {
|
|
29168
29308
|
"use strict";
|
|
29169
29309
|
init_class_mark();
|
|
29170
29310
|
classRegistry = /* @__PURE__ */ new Map();
|
|
29311
|
+
classEpoch = 0;
|
|
29312
|
+
classEpochs = /* @__PURE__ */ new Map();
|
|
29313
|
+
classCollisions = [];
|
|
29171
29314
|
}
|
|
29172
29315
|
});
|
|
29173
29316
|
|
|
@@ -29691,6 +29834,8 @@ function $copy(a) {
|
|
|
29691
29834
|
{
|
|
29692
29835
|
k: "tuple",
|
|
29693
29836
|
elements: s.elements.map($copy),
|
|
29837
|
+
// rest 槽必须随快照迁移(与 hof snapshotAbs 同口径),否则副本丢尾段
|
|
29838
|
+
...s.rest ? { rest: $copy(s.rest) } : {},
|
|
29694
29839
|
holes: s.holes ? [...s.holes] : void 0
|
|
29695
29840
|
},
|
|
29696
29841
|
a.term,
|
|
@@ -29881,7 +30026,7 @@ function $idx(a, i) {
|
|
|
29881
30026
|
if (slots.length === 0) return objShape.open ? unknown : undef();
|
|
29882
30027
|
const joinSlotsWithUndef = () => joinAbs(slots.reduce((x, y) => joinAbs(x, y)), undef());
|
|
29883
30028
|
if (typeof iv === "string" || typeof iv === "number" || typeof iv === "boolean") {
|
|
29884
|
-
const slot = objShape.slots
|
|
30029
|
+
const slot = getSlot(objShape.slots, String(iv));
|
|
29885
30030
|
if (slot) return slot.value;
|
|
29886
30031
|
if (objShape.open) return unknown;
|
|
29887
30032
|
return undef();
|
|
@@ -30098,6 +30243,20 @@ function $arrRest(a, start) {
|
|
|
30098
30243
|
return parts.length ? parts.reduce((x, y) => joinAbs(x, y)) : unknown;
|
|
30099
30244
|
}
|
|
30100
30245
|
if (a.shape.k === "tuple") {
|
|
30246
|
+
if (a.shape.rest) {
|
|
30247
|
+
const sliced = a.shape.elements.slice(start);
|
|
30248
|
+
if (start < a.shape.elements.length && !shouldWidenArrayLiteral(sliced.length + 1)) {
|
|
30249
|
+
return abs(
|
|
30250
|
+
{ k: "tuple", elements: sliced, rest: a.shape.rest },
|
|
30251
|
+
void 0,
|
|
30252
|
+
void 0,
|
|
30253
|
+
a.conf
|
|
30254
|
+
);
|
|
30255
|
+
}
|
|
30256
|
+
const restEl = a.shape.rest.shape.k === "arr" ? a.shape.rest.shape.element : a.shape.rest;
|
|
30257
|
+
const el = sliced.reduce((x, y) => joinAbs(x, y), restEl);
|
|
30258
|
+
return abs({ k: "arr", element: el }, void 0, void 0, a.conf);
|
|
30259
|
+
}
|
|
30101
30260
|
return tupleOrWiden(a.shape.elements.slice(start), a.conf);
|
|
30102
30261
|
}
|
|
30103
30262
|
if (a.shape.k === "arr") return a;
|
|
@@ -32610,7 +32769,7 @@ function namespaceAbsOf(mod2) {
|
|
|
32610
32769
|
return abs({ k: "obj", slots, open: true }, void 0, void 0, "path");
|
|
32611
32770
|
}
|
|
32612
32771
|
function bindImports(node, env2, modules) {
|
|
32613
|
-
const mod2 = modules[node.source.value];
|
|
32772
|
+
const mod2 = Object.hasOwn(modules, node.source.value) ? modules[node.source.value] : void 0;
|
|
32614
32773
|
if (!mod2) {
|
|
32615
32774
|
for (const s of node.specifiers) {
|
|
32616
32775
|
env2.vars.set(s.local.name, unknown);
|
|
@@ -32622,7 +32781,8 @@ function bindImports(node, env2, modules) {
|
|
|
32622
32781
|
env2.vars.set(s.local.name, mod2.default ?? unknown);
|
|
32623
32782
|
} else if (s.type === "ImportSpecifier") {
|
|
32624
32783
|
const imported = s.imported.type === "Identifier" ? s.imported.name : String(s.imported);
|
|
32625
|
-
|
|
32784
|
+
const named = Object.hasOwn(mod2.named, imported) ? mod2.named[imported] : void 0;
|
|
32785
|
+
env2.vars.set(s.local.name, named ?? unknown);
|
|
32626
32786
|
} else if (s.type === "ImportNamespaceSpecifier") {
|
|
32627
32787
|
env2.vars.set(s.local.name, namespaceAbsOf(mod2));
|
|
32628
32788
|
}
|
|
@@ -32648,7 +32808,7 @@ function collectAbsExports(file, env2, modules) {
|
|
|
32648
32808
|
for (const stmt of file.program.body) {
|
|
32649
32809
|
if (stmt.type === "ExportNamedDeclaration") {
|
|
32650
32810
|
if (stmt.source && modules) {
|
|
32651
|
-
const mod2 = modules[stmt.source.value];
|
|
32811
|
+
const mod2 = Object.hasOwn(modules, stmt.source.value) ? modules[stmt.source.value] : void 0;
|
|
32652
32812
|
if (mod2) {
|
|
32653
32813
|
for (const spec of stmt.specifiers) {
|
|
32654
32814
|
if (spec.type === "ExportNamespaceSpecifier") {
|
|
@@ -32660,7 +32820,7 @@ function collectAbsExports(file, env2, modules) {
|
|
|
32660
32820
|
if (spec.type !== "ExportSpecifier") continue;
|
|
32661
32821
|
const local = spec.local.type === "Identifier" ? spec.local.name : spec.local.value;
|
|
32662
32822
|
const exported = spec.exported.type === "Identifier" ? spec.exported.name : spec.exported.value;
|
|
32663
|
-
const v2 = local === "default" ? mod2.default : mod2.named[local];
|
|
32823
|
+
const v2 = local === "default" ? mod2.default : Object.hasOwn(mod2.named, local) ? mod2.named[local] : void 0;
|
|
32664
32824
|
const slot = v2 ?? unknown;
|
|
32665
32825
|
if (exported === "default") defaultExport = slot;
|
|
32666
32826
|
else {
|
|
@@ -32706,7 +32866,7 @@ function collectAbsExports(file, env2, modules) {
|
|
|
32706
32866
|
}
|
|
32707
32867
|
}
|
|
32708
32868
|
} else if (stmt.type === "ExportAllDeclaration" && stmt.source && modules) {
|
|
32709
|
-
const mod2 = modules[stmt.source.value];
|
|
32869
|
+
const mod2 = Object.hasOwn(modules, stmt.source.value) ? modules[stmt.source.value] : void 0;
|
|
32710
32870
|
if (mod2?.named) {
|
|
32711
32871
|
for (const [k, v2] of Object.entries(mod2.named)) {
|
|
32712
32872
|
if (!explicitNames.has(k)) named[k] = v2;
|
|
@@ -33061,6 +33221,7 @@ ${js}`;
|
|
|
33061
33221
|
const fn2 = new Function(...argNames, `${js}
|
|
33062
33222
|
${ret}`);
|
|
33063
33223
|
setEvalBindingSink(bindings);
|
|
33224
|
+
beginClassEpoch();
|
|
33064
33225
|
try {
|
|
33065
33226
|
const result = fn2(...args);
|
|
33066
33227
|
runBindings.set(result, bindings);
|
|
@@ -33068,6 +33229,18 @@ ${ret}`);
|
|
|
33068
33229
|
} finally {
|
|
33069
33230
|
setEvalBindingSink(null);
|
|
33070
33231
|
drainPromiseMicros();
|
|
33232
|
+
noteDrainedClassCollisions();
|
|
33233
|
+
}
|
|
33234
|
+
}
|
|
33235
|
+
function noteDrainedClassCollisions() {
|
|
33236
|
+
for (const c of drainClassCollisions()) {
|
|
33237
|
+
noteEvalFallback(
|
|
33238
|
+
new NudoUnsupportedError(
|
|
33239
|
+
"class-collision",
|
|
33240
|
+
void 0,
|
|
33241
|
+
`class '${c.name}' registered again with a different shape (${c.previous} -> ${c.next}); name-keyed lookup may resolve to either definition`
|
|
33242
|
+
)
|
|
33243
|
+
);
|
|
33071
33244
|
}
|
|
33072
33245
|
}
|
|
33073
33246
|
function setEvalFallbackCollector(collector2) {
|
|
@@ -33125,14 +33298,16 @@ function isAbsVal(v2) {
|
|
|
33125
33298
|
}
|
|
33126
33299
|
function callTranspiledExportFull(exports, name, args, opts) {
|
|
33127
33300
|
enterEvalCallBudgetSession();
|
|
33301
|
+
beginClassEpoch();
|
|
33128
33302
|
try {
|
|
33129
33303
|
return callTranspiledExportFullInner(exports, name, args, opts);
|
|
33130
33304
|
} finally {
|
|
33131
33305
|
exitEvalCallBudgetSession();
|
|
33306
|
+
noteDrainedClassCollisions();
|
|
33132
33307
|
}
|
|
33133
33308
|
}
|
|
33134
33309
|
function callTranspiledExportFullInner(exports, name, args, opts) {
|
|
33135
|
-
const fn2 = exports[name];
|
|
33310
|
+
const fn2 = Object.hasOwn(exports, name) ? exports[name] : void 0;
|
|
33136
33311
|
if (typeof fn2 === "function") {
|
|
33137
33312
|
const callArgs = args.map(
|
|
33138
33313
|
(a) => a && typeof a === "object" && "shape" in a ? $copy(a) : a
|
|
@@ -33236,6 +33411,7 @@ var init_run = __esm({
|
|
|
33236
33411
|
init_transpile();
|
|
33237
33412
|
init_intrinsics();
|
|
33238
33413
|
init_unsupported();
|
|
33414
|
+
init_class_registry();
|
|
33239
33415
|
init_export_names();
|
|
33240
33416
|
init_may_throw();
|
|
33241
33417
|
init_builtins();
|
|
@@ -33949,7 +34125,9 @@ function localNamedExports(source) {
|
|
|
33949
34125
|
const identName = (n) => {
|
|
33950
34126
|
if (!n) return void 0;
|
|
33951
34127
|
if (n.type === "Identifier" && typeof n.name === "string") return n.name;
|
|
33952
|
-
if (n.type === "Literal" && typeof n.value === "string")
|
|
34128
|
+
if ((n.type === "StringLiteral" || n.type === "Literal") && typeof n.value === "string") {
|
|
34129
|
+
return n.value;
|
|
34130
|
+
}
|
|
33953
34131
|
return void 0;
|
|
33954
34132
|
};
|
|
33955
34133
|
const localClasses = /* @__PURE__ */ new Map();
|
|
@@ -34097,6 +34275,25 @@ function localNamedExports(source) {
|
|
|
34097
34275
|
}
|
|
34098
34276
|
return out;
|
|
34099
34277
|
}
|
|
34278
|
+
function exportedNameOfLocal(source, localName) {
|
|
34279
|
+
let ast;
|
|
34280
|
+
try {
|
|
34281
|
+
ast = parseSource(source, { errorRecovery: true });
|
|
34282
|
+
} catch {
|
|
34283
|
+
return void 0;
|
|
34284
|
+
}
|
|
34285
|
+
for (const stmt of ast.program.body) {
|
|
34286
|
+
if (stmt.type !== "ExportNamedDeclaration" || stmt.source) continue;
|
|
34287
|
+
for (const spec of stmt.specifiers) {
|
|
34288
|
+
if (spec.type !== "ExportSpecifier") continue;
|
|
34289
|
+
if (spec.local.type !== "Identifier" || spec.local.name !== localName) continue;
|
|
34290
|
+
const name = spec.exported.type === "Identifier" ? spec.exported.name : spec.exported.value;
|
|
34291
|
+
if (name === void 0 || name === localName || name === "default") continue;
|
|
34292
|
+
return name;
|
|
34293
|
+
}
|
|
34294
|
+
}
|
|
34295
|
+
return void 0;
|
|
34296
|
+
}
|
|
34100
34297
|
function generatedExportNames(sidecarSrc) {
|
|
34101
34298
|
const out = /* @__PURE__ */ new Set();
|
|
34102
34299
|
let ast;
|
|
@@ -34110,8 +34307,18 @@ function generatedExportNames(sidecarSrc) {
|
|
|
34110
34307
|
const stmt = stmts[i];
|
|
34111
34308
|
if (stmt.type !== "ExportNamedDeclaration") continue;
|
|
34112
34309
|
if (stmt.source) continue;
|
|
34310
|
+
if (stmt.start == null) continue;
|
|
34113
34311
|
const d = stmt.declaration;
|
|
34114
|
-
if (!d
|
|
34312
|
+
if (!d) {
|
|
34313
|
+
if (regionHasGeneratedMarker(stmts, i, sidecarSrc)) {
|
|
34314
|
+
for (const spec of stmt.specifiers) {
|
|
34315
|
+
if (spec.type !== "ExportSpecifier") continue;
|
|
34316
|
+
const name = spec.exported.type === "Identifier" ? spec.exported.name : spec.exported.value;
|
|
34317
|
+
if (name !== void 0) out.add(name);
|
|
34318
|
+
}
|
|
34319
|
+
}
|
|
34320
|
+
continue;
|
|
34321
|
+
}
|
|
34115
34322
|
const names2 = [];
|
|
34116
34323
|
if (d.type === "VariableDeclaration") {
|
|
34117
34324
|
for (const decl of d.declarations) {
|
|
@@ -34182,6 +34389,8 @@ function sidecarMayBind(sidecarNames, fnName, source) {
|
|
|
34182
34389
|
if (!sidecarNames) return true;
|
|
34183
34390
|
if (sidecarNames.size === 0) return true;
|
|
34184
34391
|
if (sidecarNames.has(fnName)) return true;
|
|
34392
|
+
const aliasExport = exportedNameOfLocal(source, fnName);
|
|
34393
|
+
if (aliasExport !== void 0 && sidecarNames.has(aliasExport)) return true;
|
|
34185
34394
|
if (sidecarNames.has("default") && isDefaultExportLocal(source, fnName)) return true;
|
|
34186
34395
|
if (fnName.includes(".")) {
|
|
34187
34396
|
const [cls, method] = fnName.split(".", 2);
|
|
@@ -34251,20 +34460,26 @@ function loadSidecarBinding(source, fnName, opts) {
|
|
|
34251
34460
|
}
|
|
34252
34461
|
return { ok: false };
|
|
34253
34462
|
}
|
|
34254
|
-
let binding = exports[fnName];
|
|
34463
|
+
let binding = Object.hasOwn(exports, fnName) ? exports[fnName] : void 0;
|
|
34464
|
+
if (binding === void 0) {
|
|
34465
|
+
const aliasExport2 = exportedNameOfLocal(source, fnName);
|
|
34466
|
+
if (aliasExport2 !== void 0 && Object.hasOwn(exports, aliasExport2)) {
|
|
34467
|
+
binding = exports[aliasExport2];
|
|
34468
|
+
}
|
|
34469
|
+
}
|
|
34255
34470
|
if (binding === void 0 && exports.default !== void 0 && isDefaultExportLocal(source, fnName)) {
|
|
34256
34471
|
binding = exports.default;
|
|
34257
34472
|
}
|
|
34258
34473
|
if (binding === void 0 && fnName.includes(".")) {
|
|
34259
34474
|
const [cls, method] = fnName.split(".", 2);
|
|
34260
|
-
binding = exports[`${cls}_${method}`];
|
|
34475
|
+
binding = Object.hasOwn(exports, `${cls}_${method}`) ? exports[`${cls}_${method}`] : void 0;
|
|
34261
34476
|
if (binding === void 0) {
|
|
34262
|
-
const bag = exports[cls];
|
|
34477
|
+
const bag = Object.hasOwn(exports, cls) ? exports[cls] : void 0;
|
|
34263
34478
|
if (bag && typeof bag === "object" && !isNudoConstraint(bag)) {
|
|
34264
|
-
binding = bag[method];
|
|
34479
|
+
binding = Object.hasOwn(bag, method) ? bag[method] : void 0;
|
|
34265
34480
|
}
|
|
34266
34481
|
}
|
|
34267
|
-
if (binding === void 0 && method !== void 0 && exports
|
|
34482
|
+
if (binding === void 0 && method !== void 0 && Object.hasOwn(exports, method)) {
|
|
34268
34483
|
collectDiag2({
|
|
34269
34484
|
code: "nudo:interface-load",
|
|
34270
34485
|
message: `sidecar key '${method}' does not bind '${fnName}' \u2014 use '${cls}.${method}', '${cls}_${method}', or nested { ${cls}: { ${method}: \u2026 } }`,
|
|
@@ -34290,7 +34505,8 @@ function loadSidecarBinding(source, fnName, opts) {
|
|
|
34290
34505
|
return { ok: false };
|
|
34291
34506
|
}
|
|
34292
34507
|
const generatedNames = generatedExportNames(sidecarSrc);
|
|
34293
|
-
const
|
|
34508
|
+
const aliasExport = exportedNameOfLocal(source, fnName);
|
|
34509
|
+
const isGenerated2 = generatedNames.has(fnName) || (aliasExport !== void 0 ? generatedNames.has(aliasExport) : false) || (fnName.includes(".") ? (() => {
|
|
34294
34510
|
const [cls, method] = fnName.split(".", 2);
|
|
34295
34511
|
return generatedNames.has(`${cls}_${method}`) || generatedNames.has(cls);
|
|
34296
34512
|
})() : false);
|
|
@@ -35216,7 +35432,7 @@ var init_promote_scan = __esm({
|
|
|
35216
35432
|
function termKey5(t, rename) {
|
|
35217
35433
|
switch (t.op) {
|
|
35218
35434
|
case "lit":
|
|
35219
|
-
return `L:${typeof t.value}:${
|
|
35435
|
+
return `L:${typeof t.value}:${litKeyString(t.value)}`;
|
|
35220
35436
|
case "var":
|
|
35221
35437
|
return `V:${rename?.get(t.id) ?? t.id}`;
|
|
35222
35438
|
case "app":
|
|
@@ -35323,6 +35539,9 @@ function collectPredVars(p, acc) {
|
|
|
35323
35539
|
case "typeof":
|
|
35324
35540
|
collectTermVars(p.t, acc);
|
|
35325
35541
|
return;
|
|
35542
|
+
case "assumeFinite":
|
|
35543
|
+
collectTermVars(p.t, acc);
|
|
35544
|
+
return;
|
|
35326
35545
|
}
|
|
35327
35546
|
}
|
|
35328
35547
|
function collectAbsVars(a, acc, seen) {
|
|
@@ -37705,7 +37924,7 @@ function scanLiteralCalls(source, knownFns, phi2, opts) {
|
|
|
37705
37924
|
if (absArg.shape.k === "unknown" && !absArg.term) return;
|
|
37706
37925
|
const slots = absArg.shape.k === "obj" ? absArg.shape.slots : void 0;
|
|
37707
37926
|
if (!slots) {
|
|
37708
|
-
if (absArg.shape.k !== "unknown" && absArg.shape.k !== "never") {
|
|
37927
|
+
if (absArg.shape.k !== "unknown" && absArg.shape.k !== "never" && absArg.shape.k !== "any") {
|
|
37709
37928
|
out.push({
|
|
37710
37929
|
severity: "error",
|
|
37711
37930
|
code: "nudo:constraint-violated",
|
|
@@ -38282,8 +38501,17 @@ var init_scan = __esm({
|
|
|
38282
38501
|
});
|
|
38283
38502
|
|
|
38284
38503
|
// ../core/src/algebra/projection.ts
|
|
38285
|
-
function absToConstraint(a) {
|
|
38504
|
+
function absToConstraint(a, budget = new ProjectionBudget()) {
|
|
38286
38505
|
if (!PROJECTABLE_CONF.has(a.conf)) return void 0;
|
|
38506
|
+
const stop2 = budget.enter(a);
|
|
38507
|
+
if (stop2) return void 0;
|
|
38508
|
+
try {
|
|
38509
|
+
return absToConstraintInner(a, budget);
|
|
38510
|
+
} finally {
|
|
38511
|
+
budget.exit();
|
|
38512
|
+
}
|
|
38513
|
+
}
|
|
38514
|
+
function absToConstraintInner(a, budget) {
|
|
38287
38515
|
const s = a.shape;
|
|
38288
38516
|
switch (s.k) {
|
|
38289
38517
|
case "prim":
|
|
@@ -38301,9 +38529,9 @@ function absToConstraint(a) {
|
|
|
38301
38529
|
case "any":
|
|
38302
38530
|
return a.pred?.op === "or" ? projectOrLiterals(a) : void 0;
|
|
38303
38531
|
case "obj":
|
|
38304
|
-
return projectObj(s.slots, s.index, s.open);
|
|
38532
|
+
return projectObj(s.slots, s.index, s.open, budget);
|
|
38305
38533
|
case "arr":
|
|
38306
|
-
return projectArr(s.element);
|
|
38534
|
+
return projectArr(s.element, budget);
|
|
38307
38535
|
case "sum":
|
|
38308
38536
|
return projectSum(s.members);
|
|
38309
38537
|
default:
|
|
@@ -38486,18 +38714,18 @@ function projectOrLiterals(a) {
|
|
|
38486
38714
|
}
|
|
38487
38715
|
return lits.length > 0 ? union(...lits) : void 0;
|
|
38488
38716
|
}
|
|
38489
|
-
function projectObj(slots, index2, open) {
|
|
38717
|
+
function projectObj(slots, index2, open, budget) {
|
|
38490
38718
|
if (index2 || open) return void 0;
|
|
38491
38719
|
const fields = {};
|
|
38492
38720
|
for (const [k, slot] of Object.entries(slots)) {
|
|
38493
|
-
const fc = absToConstraint(slot.value);
|
|
38721
|
+
const fc = absToConstraint(slot.value, budget);
|
|
38494
38722
|
if (!fc) return void 0;
|
|
38495
38723
|
fields[k] = { constraint: fc, ...slot.optional ? { optional: true } : {} };
|
|
38496
38724
|
}
|
|
38497
38725
|
return { __nudoConstraint: true, preds: [], fields };
|
|
38498
38726
|
}
|
|
38499
|
-
function projectArr(element) {
|
|
38500
|
-
const ec = absToConstraint(element);
|
|
38727
|
+
function projectArr(element, budget) {
|
|
38728
|
+
const ec = absToConstraint(element, budget);
|
|
38501
38729
|
if (ec) return array(ec);
|
|
38502
38730
|
if (element.shape.k === "prim" && isBuilderPrim(element.shape.type) && (!element.pred || element.pred.op === "true") && ARR_FALLBACK_CONF.has(element.conf)) {
|
|
38503
38731
|
return array(primConstraint(element.shape.type));
|
|
@@ -38607,6 +38835,7 @@ var init_projection = __esm({
|
|
|
38607
38835
|
init_objects();
|
|
38608
38836
|
init_term();
|
|
38609
38837
|
init_term();
|
|
38838
|
+
init_projection_budget();
|
|
38610
38839
|
PROJECTABLE_CONF = /* @__PURE__ */ new Set(["exact", "path"]);
|
|
38611
38840
|
ARR_FALLBACK_CONF = /* @__PURE__ */ new Set([
|
|
38612
38841
|
"exact",
|
|
@@ -39045,7 +39274,7 @@ function evalThrowsOf(source, fnName, args, opts = {}, phi2 = pTrue) {
|
|
|
39045
39274
|
}
|
|
39046
39275
|
};
|
|
39047
39276
|
try {
|
|
39048
|
-
if (fnName
|
|
39277
|
+
if (Object.hasOwn(exports, fnName)) return call(fnName, args);
|
|
39049
39278
|
if (fnName.includes(".")) {
|
|
39050
39279
|
const [clsName, methodName] = fnName.split(".", 2);
|
|
39051
39280
|
const clsAbs = exports[clsName ?? ""];
|
|
@@ -39091,12 +39320,9 @@ function widenForAssign(a) {
|
|
|
39091
39320
|
if (s.k === "tuple") {
|
|
39092
39321
|
const holes = new Set(s.holes ?? []);
|
|
39093
39322
|
const els = s.elements.filter((_, i) => !holes.has(i));
|
|
39094
|
-
|
|
39095
|
-
if (
|
|
39096
|
-
|
|
39097
|
-
} else if (s.rest) {
|
|
39098
|
-
el = widenForAssign(s.rest);
|
|
39099
|
-
}
|
|
39323
|
+
const parts = els.map(widenForAssign);
|
|
39324
|
+
if (s.rest) parts.push(widenForAssign(s.rest));
|
|
39325
|
+
const el = parts.length > 0 ? parts.reduce((x, y) => joinAbs(x, y)) : anyAbs;
|
|
39100
39326
|
return abs({ k: "arr", element: el }, void 0, void 0, a.conf);
|
|
39101
39327
|
}
|
|
39102
39328
|
if (s.k === "obj") {
|
|
@@ -40641,6 +40867,7 @@ __export(src_exports, {
|
|
|
40641
40867
|
interfaceSourceOf: () => interfaceSourceOf,
|
|
40642
40868
|
interfaceTierOf: () => interfaceTierOf,
|
|
40643
40869
|
isAbsApplyResult: () => isAbsApplyResult,
|
|
40870
|
+
isAbsVal: () => isAbsVal,
|
|
40644
40871
|
isArrMutator: () => isArrMutator,
|
|
40645
40872
|
isBigPrim: () => isBigPrim,
|
|
40646
40873
|
isDefinitelyFalse: () => isDefinitelyFalse,
|
|
@@ -41046,6 +41273,7 @@ function paramName(param) {
|
|
|
41046
41273
|
return void 0;
|
|
41047
41274
|
}
|
|
41048
41275
|
function unwrapDefaultExport(mod2) {
|
|
41276
|
+
if (mod2 == null) return void 0;
|
|
41049
41277
|
if (typeof mod2 === "function") return mod2;
|
|
41050
41278
|
return mod2.default;
|
|
41051
41279
|
}
|
|
@@ -41111,9 +41339,73 @@ function emitDirectiveDiag(d) {
|
|
|
41111
41339
|
function resetDirectiveDiagSeen() {
|
|
41112
41340
|
directiveDiagSeen.clear();
|
|
41113
41341
|
}
|
|
41342
|
+
function isSafeTypeExprNode(node) {
|
|
41343
|
+
switch (node.type) {
|
|
41344
|
+
case "NumericLiteral":
|
|
41345
|
+
case "StringLiteral":
|
|
41346
|
+
case "BooleanLiteral":
|
|
41347
|
+
case "NullLiteral":
|
|
41348
|
+
return true;
|
|
41349
|
+
case "Identifier":
|
|
41350
|
+
return node.name === "undefined";
|
|
41351
|
+
case "UnaryExpression":
|
|
41352
|
+
return node.operator === "-" && node.argument.type === "NumericLiteral";
|
|
41353
|
+
case "ArrayExpression":
|
|
41354
|
+
return node.elements.every(
|
|
41355
|
+
(el) => el !== null && el.type !== "SpreadElement" && isSafeTypeExprNode(el)
|
|
41356
|
+
);
|
|
41357
|
+
case "ObjectExpression":
|
|
41358
|
+
return node.properties.every((prop) => {
|
|
41359
|
+
if (prop.type !== "ObjectProperty") return false;
|
|
41360
|
+
if (prop.computed) return false;
|
|
41361
|
+
const key = prop.key;
|
|
41362
|
+
if (key.type !== "Identifier" && key.type !== "StringLiteral") return false;
|
|
41363
|
+
return isSafeTypeExprNode(prop.value);
|
|
41364
|
+
});
|
|
41365
|
+
case "CallExpression": {
|
|
41366
|
+
const argsOk = node.arguments.every(
|
|
41367
|
+
(arg) => arg.type !== "SpreadElement" && arg.type !== "ArgumentPlaceholder" && isSafeTypeExprNode(arg)
|
|
41368
|
+
);
|
|
41369
|
+
if (!argsOk) return false;
|
|
41370
|
+
return isSafeTypeExprCallee(node.callee);
|
|
41371
|
+
}
|
|
41372
|
+
default:
|
|
41373
|
+
return false;
|
|
41374
|
+
}
|
|
41375
|
+
}
|
|
41376
|
+
function isSafeTypeExprCallee(node) {
|
|
41377
|
+
if (node.type === "Identifier") {
|
|
41378
|
+
return CONSTRAINT_BUILDER_NAMES.includes(node.name);
|
|
41379
|
+
}
|
|
41380
|
+
if (node.type === "MemberExpression") {
|
|
41381
|
+
if (node.computed) return false;
|
|
41382
|
+
if (node.property.type !== "Identifier") return false;
|
|
41383
|
+
if (!TYPE_EXPR_CHAIN_METHODS.has(node.property.name)) return false;
|
|
41384
|
+
return isSafeTypeExprNode(node.object);
|
|
41385
|
+
}
|
|
41386
|
+
return false;
|
|
41387
|
+
}
|
|
41388
|
+
function isSafeTypeExprSource(s) {
|
|
41389
|
+
try {
|
|
41390
|
+
const ast = parse2(`(${s});`);
|
|
41391
|
+
if (ast.program.body.length !== 1) return false;
|
|
41392
|
+
const stmt = ast.program.body[0];
|
|
41393
|
+
if (stmt.type !== "ExpressionStatement") return false;
|
|
41394
|
+
return isSafeTypeExprNode(stmt.expression);
|
|
41395
|
+
} catch {
|
|
41396
|
+
return false;
|
|
41397
|
+
}
|
|
41398
|
+
}
|
|
41114
41399
|
function tryParseConstraint(expr) {
|
|
41115
41400
|
const s = expr.trim();
|
|
41116
41401
|
if (!CONSTRAINT_EXPR_RE.test(s)) return void 0;
|
|
41402
|
+
if (!isSafeTypeExprSource(s)) {
|
|
41403
|
+
emitDirectiveDiag({
|
|
41404
|
+
code: "nudo:directive-syntax",
|
|
41405
|
+
message: `Unsafe constraint expression rejected: ${s.slice(0, 80)} (only builder calls, chain methods, and literals are allowed)`
|
|
41406
|
+
});
|
|
41407
|
+
return void 0;
|
|
41408
|
+
}
|
|
41117
41409
|
try {
|
|
41118
41410
|
const src = `export const __nudo_case_arg = (${s});`;
|
|
41119
41411
|
const exports = execNudoModule(src);
|
|
@@ -41149,9 +41441,10 @@ function constraintSelfEqLit(c, selfIds) {
|
|
|
41149
41441
|
if (isSelf(b) && a.op === "lit") return { found: true, value: a.value };
|
|
41150
41442
|
return { found: false };
|
|
41151
41443
|
}
|
|
41152
|
-
function constraintToCaseArgAbs(c) {
|
|
41444
|
+
function constraintToCaseArgAbs(c, depth) {
|
|
41445
|
+
if (depth > MAX_CASE_ARG_DEPTH) return depthCapDiag(constraintPreview(c));
|
|
41153
41446
|
if (c.members && c.members.length > 0) {
|
|
41154
|
-
const parts = c.members.map((m) => constraintToCaseArgAbs(m));
|
|
41447
|
+
const parts = c.members.map((m) => constraintToCaseArgAbs(m, depth + 1));
|
|
41155
41448
|
if (parts.length === 1) return parts[0];
|
|
41156
41449
|
return { shape: { k: "sum", members: parts }, conf: "path" };
|
|
41157
41450
|
}
|
|
@@ -41166,12 +41459,12 @@ function constraintToCaseArgAbs(c) {
|
|
|
41166
41459
|
return absUndefLit();
|
|
41167
41460
|
}
|
|
41168
41461
|
if (c.element) {
|
|
41169
|
-
return absExact({ k: "arr", element: constraintToCaseArgAbs(c.element) });
|
|
41462
|
+
return absExact({ k: "arr", element: constraintToCaseArgAbs(c.element, depth + 1) });
|
|
41170
41463
|
}
|
|
41171
41464
|
if (c.fields) {
|
|
41172
41465
|
const slots = {};
|
|
41173
41466
|
for (const [key, field] of Object.entries(c.fields)) {
|
|
41174
|
-
slots[key] = { value: constraintToCaseArgAbs(field.constraint) };
|
|
41467
|
+
slots[key] = { value: constraintToCaseArgAbs(field.constraint, depth + 1) };
|
|
41175
41468
|
}
|
|
41176
41469
|
return absExact({ k: "obj", slots });
|
|
41177
41470
|
}
|
|
@@ -41184,18 +41477,33 @@ function constraintToCaseArgAbs(c) {
|
|
|
41184
41477
|
}
|
|
41185
41478
|
return constraintToEntryAbs(c, "__arg");
|
|
41186
41479
|
}
|
|
41187
|
-
function
|
|
41480
|
+
function depthCapDiag(expr) {
|
|
41481
|
+
emitDirectiveDiag({
|
|
41482
|
+
code: "nudo:directive-syntax",
|
|
41483
|
+
message: `Type expression nesting exceeds depth ${MAX_CASE_ARG_DEPTH}: ${expr.trim().slice(0, 40)} \u2026 (deeper structure collapses to unknown)`
|
|
41484
|
+
});
|
|
41485
|
+
return absUnknown2();
|
|
41486
|
+
}
|
|
41487
|
+
function constraintPreview(c) {
|
|
41488
|
+
if (c.element) return "array(\u2026)";
|
|
41489
|
+
if (c.members) return "union(\u2026)";
|
|
41490
|
+
if (c.fields) return "shape({ \u2026 })";
|
|
41491
|
+
if (c.fn) return "fn(\u2026)";
|
|
41492
|
+
return c.prim ? `${c.prim}()` : "constraint";
|
|
41493
|
+
}
|
|
41494
|
+
function parseCaseArgExpr(expr, depth = 0) {
|
|
41495
|
+
if (depth > MAX_CASE_ARG_DEPTH) return depthCapDiag(expr);
|
|
41188
41496
|
const constraint = tryParseConstraint(expr);
|
|
41189
41497
|
if (constraint) {
|
|
41190
41498
|
try {
|
|
41191
|
-
return constraintToCaseArgAbs(constraint);
|
|
41499
|
+
return constraintToCaseArgAbs(constraint, depth);
|
|
41192
41500
|
} catch {
|
|
41193
41501
|
return absUnknown2();
|
|
41194
41502
|
}
|
|
41195
41503
|
}
|
|
41196
|
-
return parseLiteralOrStructure(expr);
|
|
41504
|
+
return parseLiteralOrStructure(expr, depth);
|
|
41197
41505
|
}
|
|
41198
|
-
function parseLiteralOrStructure(expr) {
|
|
41506
|
+
function parseLiteralOrStructure(expr, depth) {
|
|
41199
41507
|
const s = expr.trim();
|
|
41200
41508
|
if (s === "true") return absLit(true);
|
|
41201
41509
|
if (s === "false") return absLit(false);
|
|
@@ -41214,17 +41522,20 @@ function parseLiteralOrStructure(expr) {
|
|
|
41214
41522
|
return absLit(s.slice(1, -1));
|
|
41215
41523
|
}
|
|
41216
41524
|
if (s.startsWith("{") && s.endsWith("}")) {
|
|
41217
|
-
return parseObjectLiteral(s.slice(1, -1).trim());
|
|
41525
|
+
return parseObjectLiteral(s.slice(1, -1).trim(), depth);
|
|
41218
41526
|
}
|
|
41219
41527
|
if (s.startsWith("[") && s.endsWith("]")) {
|
|
41220
41528
|
const content = s.slice(1, -1).trim();
|
|
41221
41529
|
if (!content) return absExact({ k: "tuple", elements: [] });
|
|
41222
41530
|
const elements = splitTopLevelArgs(content);
|
|
41223
|
-
return absExact({
|
|
41531
|
+
return absExact({
|
|
41532
|
+
k: "tuple",
|
|
41533
|
+
elements: elements.map((e) => parseCaseArgExpr(e, depth + 1))
|
|
41534
|
+
});
|
|
41224
41535
|
}
|
|
41225
41536
|
return absUnknown2();
|
|
41226
41537
|
}
|
|
41227
|
-
function parseObjectLiteral(content) {
|
|
41538
|
+
function parseObjectLiteral(content, depth) {
|
|
41228
41539
|
if (!content) return absExact({ k: "obj", slots: {} });
|
|
41229
41540
|
const entries = splitTopLevelArgs(content);
|
|
41230
41541
|
const slots = {};
|
|
@@ -41233,7 +41544,7 @@ function parseObjectLiteral(content) {
|
|
|
41233
41544
|
if (colonIdx === -1) continue;
|
|
41234
41545
|
const key = entry.slice(0, colonIdx).trim().replace(/^["']|["']$/g, "");
|
|
41235
41546
|
const val = entry.slice(colonIdx + 1).trim();
|
|
41236
|
-
slots[key] = { value: parseCaseArgExpr(val) };
|
|
41547
|
+
slots[key] = { value: parseCaseArgExpr(val, depth + 1) };
|
|
41237
41548
|
}
|
|
41238
41549
|
return absExact({ k: "obj", slots });
|
|
41239
41550
|
}
|
|
@@ -41399,6 +41710,13 @@ function parseSkipReturnsExpr(rest) {
|
|
|
41399
41710
|
if (inner !== null && s.slice(inner.length + 2).trim() === "") {
|
|
41400
41711
|
return parseAbsExprDiag(inner, "@nudo:skip (...)");
|
|
41401
41712
|
}
|
|
41713
|
+
if (inner === null) {
|
|
41714
|
+
emitDirectiveDiag({
|
|
41715
|
+
code: "nudo:directive-syntax",
|
|
41716
|
+
message: `@nudo:skip type expression has unclosed parenthesis (expected @nudo:skip (<typeExpr>)) \u2014 got: ${s.slice(0, 60)}`
|
|
41717
|
+
});
|
|
41718
|
+
return void 0;
|
|
41719
|
+
}
|
|
41402
41720
|
}
|
|
41403
41721
|
return void 0;
|
|
41404
41722
|
}
|
|
@@ -41492,7 +41810,8 @@ function parseSinonExpr(expr) {
|
|
|
41492
41810
|
return null;
|
|
41493
41811
|
}
|
|
41494
41812
|
function parseNudoMockExpr(expr) {
|
|
41495
|
-
|
|
41813
|
+
let s = expr.trim();
|
|
41814
|
+
while (s.startsWith("sinon.")) s = s.slice("sinon.".length);
|
|
41496
41815
|
const stubReturnsOnFirstMatch = s.match(/^stub\(\)\.returns\((.+)\)\.onFirstCall\(\)$/);
|
|
41497
41816
|
if (stubReturnsOnFirstMatch) {
|
|
41498
41817
|
const helper = stub.returns(parseAbsExpr(stubReturnsOnFirstMatch[1].trim()));
|
|
@@ -41563,9 +41882,6 @@ function parseNudoMockExpr(expr) {
|
|
|
41563
41882
|
if (s === "mock()") {
|
|
41564
41883
|
return mock();
|
|
41565
41884
|
}
|
|
41566
|
-
if (s.startsWith("sinon.")) {
|
|
41567
|
-
return parseNudoMockExpr(s.slice("sinon.".length));
|
|
41568
|
-
}
|
|
41569
41885
|
return null;
|
|
41570
41886
|
}
|
|
41571
41887
|
function parseDirectivesFromCommentTexts(comments) {
|
|
@@ -41675,8 +41991,17 @@ function scanMalformedCaseNames(text, caseArgSpans) {
|
|
|
41675
41991
|
while ((m = CASE_TAG_REGEX.exec(text)) !== null) {
|
|
41676
41992
|
if (inCaseArgs(m.index)) continue;
|
|
41677
41993
|
const rest = m[1].trim();
|
|
41678
|
-
|
|
41679
|
-
if (
|
|
41994
|
+
const legal = rest.match(/^("[^"]+")[ \t]*\(/);
|
|
41995
|
+
if (legal) {
|
|
41996
|
+
const parenIdx = m.index + m[0].length - m[1].length + legal[0].length - 1;
|
|
41997
|
+
if (extractBalancedParens(text, parenIdx) === null) {
|
|
41998
|
+
emitDirectiveDiag({
|
|
41999
|
+
code: "nudo:directive-syntax",
|
|
42000
|
+
message: `Malformed @nudo:case: unclosed argument list (missing closing ")") \u2014 got: @nudo:case ${rest.slice(0, 60)}`
|
|
42001
|
+
});
|
|
42002
|
+
}
|
|
42003
|
+
continue;
|
|
42004
|
+
}
|
|
41680
42005
|
let reason;
|
|
41681
42006
|
if (rest.startsWith("'")) {
|
|
41682
42007
|
reason = `single-quoted name (use double quotes: @nudo:case "name" (\u2026))`;
|
|
@@ -41716,6 +42041,14 @@ function scanMalformedMockNames(text, caseArgSpans) {
|
|
|
41716
42041
|
code: "nudo:directive-syntax",
|
|
41717
42042
|
message: `Malformed @nudo:mock name '${name}': not a valid identifier (use letters, digits, _, $; Unicode letters allowed)`
|
|
41718
42043
|
});
|
|
42044
|
+
continue;
|
|
42045
|
+
}
|
|
42046
|
+
const afterName = rest.slice(name.length);
|
|
42047
|
+
if (/^[ \t]+from[ \t]+"[^"\n]*$/.test(afterName)) {
|
|
42048
|
+
emitDirectiveDiag({
|
|
42049
|
+
code: "nudo:directive-syntax",
|
|
42050
|
+
message: `Malformed @nudo:mock from: unclosed quote in path (expected @nudo:mock ${name} from "path") \u2014 got: @nudo:mock ${rest.slice(0, 60)}`
|
|
42051
|
+
});
|
|
41719
42052
|
}
|
|
41720
42053
|
}
|
|
41721
42054
|
}
|
|
@@ -41742,6 +42075,28 @@ function extractDirectivesQuiet(ast) {
|
|
|
41742
42075
|
takeDirectiveDiagsSince(since);
|
|
41743
42076
|
return out;
|
|
41744
42077
|
}
|
|
42078
|
+
function stripInlineCommentPrefix(line, kind) {
|
|
42079
|
+
const s = kind === "block" ? line.replace(/^\s*\*\s?/, "") : line.replace(/^\//, "");
|
|
42080
|
+
return s.trim();
|
|
42081
|
+
}
|
|
42082
|
+
function findTrailingCommentStart(expr) {
|
|
42083
|
+
let inString = null;
|
|
42084
|
+
for (let i = 0; i < expr.length; i++) {
|
|
42085
|
+
const ch = expr[i];
|
|
42086
|
+
if (inString) {
|
|
42087
|
+
if (ch === inString) inString = null;
|
|
42088
|
+
continue;
|
|
42089
|
+
}
|
|
42090
|
+
if (ch === '"' || ch === "'") {
|
|
42091
|
+
inString = ch;
|
|
42092
|
+
continue;
|
|
42093
|
+
}
|
|
42094
|
+
if ((ch === " " || ch === " ") && /^[ \t]+(?:\/\/|\/\*)/.test(expr.slice(i))) {
|
|
42095
|
+
return i;
|
|
42096
|
+
}
|
|
42097
|
+
}
|
|
42098
|
+
return -1;
|
|
42099
|
+
}
|
|
41745
42100
|
function extractInlineDirectives(node) {
|
|
41746
42101
|
resetDirectiveDiagSeen();
|
|
41747
42102
|
const comments = node.leadingComments;
|
|
@@ -41749,39 +42104,56 @@ function extractInlineDirectives(node) {
|
|
|
41749
42104
|
const results = [];
|
|
41750
42105
|
for (const comment of comments) {
|
|
41751
42106
|
if (comment.type !== "CommentLine" && comment.type !== "CommentBlock") continue;
|
|
41752
|
-
const
|
|
41753
|
-
const
|
|
41754
|
-
|
|
41755
|
-
const
|
|
41756
|
-
|
|
41757
|
-
|
|
41758
|
-
const
|
|
42107
|
+
const kind = comment.type === "CommentLine" ? "line" : "block";
|
|
42108
|
+
for (const rawLine of comment.value.split("\n")) {
|
|
42109
|
+
const line = stripInlineCommentPrefix(rawLine, kind);
|
|
42110
|
+
const asMatch = line.match(AS_LINE_REGEX);
|
|
42111
|
+
if (asMatch) {
|
|
42112
|
+
const rawExpr = asMatch[1].trim();
|
|
42113
|
+
const trailingIdx = findTrailingCommentStart(rawExpr);
|
|
42114
|
+
if (trailingIdx !== -1) {
|
|
42115
|
+
const typePart = rawExpr.slice(0, trailingIdx).trim();
|
|
42116
|
+
emitDirectiveDiag({
|
|
42117
|
+
code: "nudo:directive-syntax",
|
|
42118
|
+
message: `Trailing comment in @nudo:as type expression: '${rawExpr}' (remove the comment; the type must be a clean expression)`
|
|
42119
|
+
});
|
|
42120
|
+
results.push({ kind: "as", typeAbs: typePart ? parseAbsExprDiag(typePart, "@nudo:as") : absUnknown2() });
|
|
42121
|
+
continue;
|
|
42122
|
+
}
|
|
42123
|
+
results.push({ kind: "as", typeAbs: parseAbsExprDiag(rawExpr, "@nudo:as") });
|
|
42124
|
+
continue;
|
|
42125
|
+
}
|
|
42126
|
+
if (AS_BARE_RE.test(line)) {
|
|
41759
42127
|
emitDirectiveDiag({
|
|
41760
42128
|
code: "nudo:directive-syntax",
|
|
41761
|
-
message:
|
|
42129
|
+
message: `@nudo:as requires a type expression (e.g. @nudo:as number())`
|
|
41762
42130
|
});
|
|
41763
|
-
results.push({ kind: "as", typeAbs: typePart ? parseAbsExprDiag(typePart, "@nudo:as") : absUnknown2() });
|
|
41764
42131
|
continue;
|
|
41765
42132
|
}
|
|
41766
|
-
|
|
41767
|
-
|
|
41768
|
-
|
|
41769
|
-
|
|
41770
|
-
|
|
41771
|
-
|
|
41772
|
-
|
|
41773
|
-
|
|
41774
|
-
|
|
41775
|
-
|
|
41776
|
-
|
|
41777
|
-
|
|
41778
|
-
|
|
41779
|
-
|
|
41780
|
-
|
|
41781
|
-
|
|
42133
|
+
const replaceMatch = line.match(REPLACE_LINE_REGEX);
|
|
42134
|
+
if (replaceMatch) {
|
|
42135
|
+
const raw = replaceMatch[1].trim();
|
|
42136
|
+
const sepIdx = findReplaceSeparator(raw);
|
|
42137
|
+
if (sepIdx !== -1) {
|
|
42138
|
+
const targetSource = raw.slice(0, sepIdx).trim();
|
|
42139
|
+
const typeExprStr = raw.slice(sepIdx + 1).trim();
|
|
42140
|
+
results.push({
|
|
42141
|
+
kind: "replace",
|
|
42142
|
+
targetSource,
|
|
42143
|
+
typeAbs: parseAbsExprDiag(typeExprStr, "@nudo:replace")
|
|
42144
|
+
});
|
|
42145
|
+
} else {
|
|
42146
|
+
emitDirectiveDiag({
|
|
42147
|
+
code: "nudo:directive-syntax",
|
|
42148
|
+
message: `Malformed @nudo:replace: cannot separate target from type (expected @nudo:replace <target> <typeExpr>) \u2014 got: ${raw.slice(0, 60)}`
|
|
42149
|
+
});
|
|
42150
|
+
}
|
|
42151
|
+
continue;
|
|
42152
|
+
}
|
|
42153
|
+
if (REPLACE_BARE_RE.test(line)) {
|
|
41782
42154
|
emitDirectiveDiag({
|
|
41783
42155
|
code: "nudo:directive-syntax",
|
|
41784
|
-
message:
|
|
42156
|
+
message: `@nudo:replace requires a target and type expression (expected @nudo:replace <target> <typeExpr>)`
|
|
41785
42157
|
});
|
|
41786
42158
|
}
|
|
41787
42159
|
}
|
|
@@ -41846,7 +42218,7 @@ function extractFileDirectives(ast) {
|
|
|
41846
42218
|
}
|
|
41847
42219
|
return results;
|
|
41848
42220
|
}
|
|
41849
|
-
var directiveDiagCollector, directiveDiagSeq, directiveDiags, MAX_DIRECTIVE_DIAGS, directiveDiagSeen, CASE_TAG_REGEX, JS_IDENT_RE, MOCK_INLINE_REGEX, MOCK_FROM_REGEX, MOCK_TAG_REGEX, PURE_REGEX, SKIP_REGEX, SAMPLE_REGEX, SAMPLE_NUM_RE,
|
|
42221
|
+
var directiveDiagCollector, directiveDiagSeq, directiveDiags, MAX_DIRECTIVE_DIAGS, directiveDiagSeen, CASE_TAG_REGEX, JS_IDENT_RE, MOCK_INLINE_REGEX, MOCK_FROM_REGEX, MOCK_TAG_REGEX, PURE_REGEX, SKIP_REGEX, SAMPLE_REGEX, SAMPLE_NUM_RE, TYPE_EXPR_CHAIN_METHODS, MAX_CASE_ARG_DEPTH, AS_LINE_REGEX, REPLACE_LINE_REGEX, AS_BARE_RE, REPLACE_BARE_RE, ENV_REGEX, MOCK_MODULE_REGEX;
|
|
41850
42222
|
var init_directives = __esm({
|
|
41851
42223
|
"../parser/src/directives.ts"() {
|
|
41852
42224
|
"use strict";
|
|
@@ -41857,18 +42229,32 @@ var init_directives = __esm({
|
|
|
41857
42229
|
directiveDiags = [];
|
|
41858
42230
|
MAX_DIRECTIVE_DIAGS = 1024;
|
|
41859
42231
|
directiveDiagSeen = /* @__PURE__ */ new Set();
|
|
41860
|
-
CASE_TAG_REGEX = /(?:^|\n)[ \t]*(?:\*[ \t]*)?@nudo:case\
|
|
42232
|
+
CASE_TAG_REGEX = /(?:^|\n)[ \t]*(?:\*[ \t]*|\/[ \t]*)?@nudo:case\b[ \t]*([^\n]*)/g;
|
|
41861
42233
|
JS_IDENT_RE = /^[\p{L}$_][\p{L}\p{N}$_]*$/u;
|
|
41862
|
-
MOCK_INLINE_REGEX = /(?:^|\n)[ \t]*(?:\*[ \t]*)?@nudo:mock\
|
|
41863
|
-
MOCK_FROM_REGEX = /(?:^|\n)[ \t]*(?:\*[ \t]*)?@nudo:mock\
|
|
41864
|
-
MOCK_TAG_REGEX = /(?:^|\n)[ \t]*(?:\*[ \t]*)?@nudo:mock\
|
|
41865
|
-
PURE_REGEX = /(?:^|\n)[ \t]*(?:\*[ \t]*)?@nudo:pure\b/g;
|
|
41866
|
-
SKIP_REGEX = /(?:^|\n)[ \t]*(?:\*[ \t]*)?@nudo:skip\b(?:[ \t]+(\S[^\n]*))?/g;
|
|
41867
|
-
SAMPLE_REGEX = /(?:^|\n)[ \t]*(?:\*[ \t]*)?@nudo:sample\b(?:[ \t]+(\S+))?/g;
|
|
42234
|
+
MOCK_INLINE_REGEX = /(?:^|\n)[ \t]*(?:\*[ \t]*|\/[ \t]*)?@nudo:mock\b[ \t]+([^\s=]+)[ \t]*=[ \t]*(.+)/g;
|
|
42235
|
+
MOCK_FROM_REGEX = /(?:^|\n)[ \t]*(?:\*[ \t]*|\/[ \t]*)?@nudo:mock\b[ \t]+([^\s]+)[ \t]+from[ \t]+"([^"\n]+)"/g;
|
|
42236
|
+
MOCK_TAG_REGEX = /(?:^|\n)[ \t]*(?:\*[ \t]*|\/[ \t]*)?@nudo:mock\b[ \t]*([^\n]*)/g;
|
|
42237
|
+
PURE_REGEX = /(?:^|\n)[ \t]*(?:\*[ \t]*|\/[ \t]*)?@nudo:pure\b/g;
|
|
42238
|
+
SKIP_REGEX = /(?:^|\n)[ \t]*(?:\*[ \t]*|\/[ \t]*)?@nudo:skip\b(?:[ \t]+(\S[^\n]*))?/g;
|
|
42239
|
+
SAMPLE_REGEX = /(?:^|\n)[ \t]*(?:\*[ \t]*|\/[ \t]*)?@nudo:sample\b(?:[ \t]+(\S+))?/g;
|
|
41868
42240
|
SAMPLE_NUM_RE = /^[+-]?(?:\d+\.?\d*|\.\d+)(?:[eE][+-]?\d+)?$/;
|
|
41869
|
-
|
|
41870
|
-
|
|
41871
|
-
|
|
42241
|
+
TYPE_EXPR_CHAIN_METHODS = /* @__PURE__ */ new Set([
|
|
42242
|
+
"gt",
|
|
42243
|
+
"ge",
|
|
42244
|
+
"lt",
|
|
42245
|
+
"le",
|
|
42246
|
+
"int",
|
|
42247
|
+
"min",
|
|
42248
|
+
"max",
|
|
42249
|
+
"length",
|
|
42250
|
+
"shift",
|
|
42251
|
+
"optional"
|
|
42252
|
+
]);
|
|
42253
|
+
MAX_CASE_ARG_DEPTH = 32;
|
|
42254
|
+
AS_LINE_REGEX = /^@nudo:as[ \t]+(.+)$/;
|
|
42255
|
+
REPLACE_LINE_REGEX = /^@nudo:replace[ \t]+(.+)$/;
|
|
42256
|
+
AS_BARE_RE = /^@nudo:as[ \t]*$/;
|
|
42257
|
+
REPLACE_BARE_RE = /^@nudo:replace[ \t]*$/;
|
|
41872
42258
|
ENV_REGEX = /^\/?\s*@nudo:env\s+(.+)/;
|
|
41873
42259
|
MOCK_MODULE_REGEX = /^\/?\s*@nudo:mock-module\s+(.+)/;
|
|
41874
42260
|
}
|
|
@@ -42112,6 +42498,27 @@ var init_inlay = __esm({
|
|
|
42112
42498
|
function isJsIdent(name) {
|
|
42113
42499
|
return JS_IDENT.test(name);
|
|
42114
42500
|
}
|
|
42501
|
+
function isJsBindingIdent(name) {
|
|
42502
|
+
return JS_BINDING_IDENT.test(name) && !JS_BINDING_RESERVED.has(name);
|
|
42503
|
+
}
|
|
42504
|
+
function toJsBindingIdent(name, used) {
|
|
42505
|
+
let base = name;
|
|
42506
|
+
if (!JS_BINDING_IDENT.test(base)) {
|
|
42507
|
+
base = base.replace(/[^\p{ID_Continue}$\u200C\u200D]/gu, "_");
|
|
42508
|
+
if (base.length === 0) base = "_";
|
|
42509
|
+
else if (!/^[$_\p{ID_Start}]/u.test(base)) base = `_${base}`;
|
|
42510
|
+
}
|
|
42511
|
+
if (JS_BINDING_RESERVED.has(base)) base = `_${base}`;
|
|
42512
|
+
if (!used) return base;
|
|
42513
|
+
let n = base;
|
|
42514
|
+
let i = 2;
|
|
42515
|
+
while (used.has(n)) {
|
|
42516
|
+
n = `${base}_${i}`;
|
|
42517
|
+
i++;
|
|
42518
|
+
}
|
|
42519
|
+
used.add(n);
|
|
42520
|
+
return n;
|
|
42521
|
+
}
|
|
42115
42522
|
function formatObjectKey(k) {
|
|
42116
42523
|
if (JS_IDENT.test(k)) return k;
|
|
42117
42524
|
if (JS_CANONICAL_INT.test(k)) return k;
|
|
@@ -42126,27 +42533,90 @@ function escapeTemplateTypeFixed(text) {
|
|
|
42126
42533
|
function sanitizeCommentText(text) {
|
|
42127
42534
|
return text.replace(/\*\//g, "*\\/").replace(/[\r\n\u2028\u2029\x00-\x08\x0b\x0c\x0e-\x1f\x7f]/g, " ");
|
|
42128
42535
|
}
|
|
42129
|
-
var JS_IDENT, JS_CANONICAL_INT;
|
|
42536
|
+
var JS_IDENT, JS_BINDING_IDENT, JS_BINDING_RESERVED, JS_CANONICAL_INT;
|
|
42130
42537
|
var init_codegen_escape = __esm({
|
|
42131
42538
|
"../core/src/algebra/codegen-escape.ts"() {
|
|
42132
42539
|
"use strict";
|
|
42133
42540
|
JS_IDENT = /^[A-Za-z_$][A-Za-z0-9_$]*$/;
|
|
42541
|
+
JS_BINDING_IDENT = /^(?:[$_\p{ID_Start}])(?:[$\u200C\u200D\p{ID_Continue}])*$/u;
|
|
42542
|
+
JS_BINDING_RESERVED = /* @__PURE__ */ new Set([
|
|
42543
|
+
// ECMA-262 keywords
|
|
42544
|
+
"break",
|
|
42545
|
+
"case",
|
|
42546
|
+
"catch",
|
|
42547
|
+
"class",
|
|
42548
|
+
"const",
|
|
42549
|
+
"continue",
|
|
42550
|
+
"debugger",
|
|
42551
|
+
"default",
|
|
42552
|
+
"delete",
|
|
42553
|
+
"do",
|
|
42554
|
+
"else",
|
|
42555
|
+
"enum",
|
|
42556
|
+
"export",
|
|
42557
|
+
"extends",
|
|
42558
|
+
"false",
|
|
42559
|
+
"finally",
|
|
42560
|
+
"for",
|
|
42561
|
+
"function",
|
|
42562
|
+
"if",
|
|
42563
|
+
"import",
|
|
42564
|
+
"in",
|
|
42565
|
+
"instanceof",
|
|
42566
|
+
"new",
|
|
42567
|
+
"null",
|
|
42568
|
+
"return",
|
|
42569
|
+
"super",
|
|
42570
|
+
"switch",
|
|
42571
|
+
"this",
|
|
42572
|
+
"throw",
|
|
42573
|
+
"true",
|
|
42574
|
+
"try",
|
|
42575
|
+
"typeof",
|
|
42576
|
+
"var",
|
|
42577
|
+
"void",
|
|
42578
|
+
"while",
|
|
42579
|
+
"with",
|
|
42580
|
+
"yield",
|
|
42581
|
+
// strict mode / module-code reserved
|
|
42582
|
+
"let",
|
|
42583
|
+
"static",
|
|
42584
|
+
"await",
|
|
42585
|
+
"implements",
|
|
42586
|
+
"interface",
|
|
42587
|
+
"package",
|
|
42588
|
+
"private",
|
|
42589
|
+
"protected",
|
|
42590
|
+
"public",
|
|
42591
|
+
// never legal bindings in strict / module code
|
|
42592
|
+
"eval",
|
|
42593
|
+
"arguments"
|
|
42594
|
+
]);
|
|
42134
42595
|
JS_CANONICAL_INT = /^(?:0|[1-9]\d*)$/;
|
|
42135
42596
|
}
|
|
42136
42597
|
});
|
|
42137
42598
|
|
|
42138
42599
|
// ../core/src/algebra/denote.ts
|
|
42139
42600
|
function denoteGuard(a, v2) {
|
|
42140
|
-
|
|
42141
|
-
|
|
42601
|
+
return denoteGuardB(a, v2, new ProjectionBudget());
|
|
42602
|
+
}
|
|
42603
|
+
function denoteGuardB(a, v2, budget) {
|
|
42604
|
+
const stop2 = budget.enter(a);
|
|
42605
|
+
if (stop2) return `/* nudo:truncated:${stop2} */ true`;
|
|
42606
|
+
try {
|
|
42607
|
+
if (a.term?.op === "lit" && (!a.pred || a.pred.op === "true")) {
|
|
42608
|
+
return eqGuard(v2, a.term.value);
|
|
42609
|
+
}
|
|
42610
|
+
const shape2 = denoteShape(a.shape, v2, budget);
|
|
42611
|
+
const pred = denotePred(a, v2);
|
|
42612
|
+
if (shape2 === "true") return pred;
|
|
42613
|
+
if (pred === "true") return shape2;
|
|
42614
|
+
return `(${shape2}) && (${pred})`;
|
|
42615
|
+
} finally {
|
|
42616
|
+
budget.exit();
|
|
42142
42617
|
}
|
|
42143
|
-
const shape2 = denoteShape(a.shape, v2);
|
|
42144
|
-
const pred = denotePred(a, v2);
|
|
42145
|
-
if (shape2 === "true") return pred;
|
|
42146
|
-
if (pred === "true") return shape2;
|
|
42147
|
-
return `(${shape2}) && (${pred})`;
|
|
42148
42618
|
}
|
|
42149
|
-
function denoteShape(s, v2) {
|
|
42619
|
+
function denoteShape(s, v2, budget) {
|
|
42150
42620
|
switch (s.k) {
|
|
42151
42621
|
case "never":
|
|
42152
42622
|
return "false";
|
|
@@ -42172,7 +42642,7 @@ function denoteShape(s, v2) {
|
|
|
42172
42642
|
const checks = [`typeof ${v2} === "object"`, `${v2} !== null`];
|
|
42173
42643
|
for (const [key, slot] of Object.entries(s.slots)) {
|
|
42174
42644
|
const access = safeMemberAccess(v2, key);
|
|
42175
|
-
const inner =
|
|
42645
|
+
const inner = denoteGuardB(slot.value, access, budget);
|
|
42176
42646
|
if (slot.optional) {
|
|
42177
42647
|
if (inner !== "true") checks.push(`(${access} === undefined || ${inner})`);
|
|
42178
42648
|
} else {
|
|
@@ -42182,7 +42652,7 @@ function denoteShape(s, v2) {
|
|
|
42182
42652
|
return checks.join(" && ");
|
|
42183
42653
|
}
|
|
42184
42654
|
case "arr":
|
|
42185
|
-
return `Array.isArray(${v2}) && ${v2}.every((item) => ${
|
|
42655
|
+
return `Array.isArray(${v2}) && ${v2}.every((item) => ${denoteGuardB(s.element, "item", budget)})`;
|
|
42186
42656
|
case "tuple": {
|
|
42187
42657
|
const checks = [`Array.isArray(${v2})`];
|
|
42188
42658
|
const minLen = s.elements.length;
|
|
@@ -42193,14 +42663,14 @@ function denoteShape(s, v2) {
|
|
|
42193
42663
|
checks.push(`!(${i} in ${v2})`);
|
|
42194
42664
|
return;
|
|
42195
42665
|
}
|
|
42196
|
-
const inner =
|
|
42666
|
+
const inner = denoteGuardB(el, `${v2}[${i}]`, budget);
|
|
42197
42667
|
if (inner !== "true") checks.push(inner);
|
|
42198
42668
|
});
|
|
42199
42669
|
for (const i of holes) {
|
|
42200
42670
|
if (i >= minLen) checks.push(`!(${i} in ${v2})`);
|
|
42201
42671
|
}
|
|
42202
42672
|
if (s.rest) {
|
|
42203
|
-
const rest =
|
|
42673
|
+
const rest = denoteGuardB(s.rest, "item", budget);
|
|
42204
42674
|
if (rest !== "true") {
|
|
42205
42675
|
checks.push(`${v2}.slice(${minLen}).every((item) => ${rest})`);
|
|
42206
42676
|
}
|
|
@@ -42213,10 +42683,10 @@ function denoteShape(s, v2) {
|
|
|
42213
42683
|
if (s.eff === "promise") return `${v2} instanceof Promise`;
|
|
42214
42684
|
return "true";
|
|
42215
42685
|
case "brand":
|
|
42216
|
-
return denoteShape(s.shape.shape, v2);
|
|
42686
|
+
return denoteShape(s.shape.shape, v2, budget);
|
|
42217
42687
|
case "sum": {
|
|
42218
42688
|
if (s.members.length === 0) return "false";
|
|
42219
|
-
const parts = s.members.map((m) =>
|
|
42689
|
+
const parts = s.members.map((m) => denoteGuardB(m, v2, budget));
|
|
42220
42690
|
return `(${parts.join(" || ")})`;
|
|
42221
42691
|
}
|
|
42222
42692
|
}
|
|
@@ -42310,6 +42780,7 @@ var init_denote = __esm({
|
|
|
42310
42780
|
"../core/src/algebra/denote.ts"() {
|
|
42311
42781
|
"use strict";
|
|
42312
42782
|
init_codegen_escape();
|
|
42783
|
+
init_projection_budget();
|
|
42313
42784
|
}
|
|
42314
42785
|
});
|
|
42315
42786
|
|
|
@@ -42327,8 +42798,10 @@ __export(internal_exports, {
|
|
|
42327
42798
|
MAX_PROMISE_MICROS: () => MAX_PROMISE_MICROS,
|
|
42328
42799
|
MAX_TOTAL_CALLS: () => MAX_TOTAL_CALLS,
|
|
42329
42800
|
OBJECT_PROTO_NAMES: () => OBJECT_PROTO_NAMES,
|
|
42801
|
+
PROJECTION_MAX_DEPTH: () => PROJECTION_MAX_DEPTH,
|
|
42330
42802
|
PROMISE_MICRO_ERROR_LABEL: () => PROMISE_MICRO_ERROR_LABEL,
|
|
42331
42803
|
PROMISE_MICRO_OVERFLOW_LABEL: () => PROMISE_MICRO_OVERFLOW_LABEL,
|
|
42804
|
+
ProjectionBudget: () => ProjectionBudget,
|
|
42332
42805
|
abortDerivationSession: () => abortDerivationSession,
|
|
42333
42806
|
absTemplateViews: () => absTemplateViews,
|
|
42334
42807
|
allFixedTextOfViews: () => allFixedTextOfViews,
|
|
@@ -42363,6 +42836,7 @@ __export(internal_exports, {
|
|
|
42363
42836
|
exceedsBudget: () => exceedsBudget,
|
|
42364
42837
|
exitCall: () => exitCall,
|
|
42365
42838
|
exitEvalCallBudgetSession: () => exitEvalCallBudgetSession,
|
|
42839
|
+
exportedNameOfLocal: () => exportedNameOfLocal,
|
|
42366
42840
|
extractAllLoadSpecs: () => extractAllLoadSpecs,
|
|
42367
42841
|
filterDeclaredThrows: () => filterDeclaredThrows,
|
|
42368
42842
|
filterGateThrows: () => filterGateThrows,
|
|
@@ -42391,6 +42865,7 @@ __export(internal_exports, {
|
|
|
42391
42865
|
instanceOf: () => instanceOf,
|
|
42392
42866
|
instantiateClass: () => instantiateClass,
|
|
42393
42867
|
isEvalMissingSlotEnabled: () => isEvalMissingSlotEnabled,
|
|
42868
|
+
isJsBindingIdent: () => isJsBindingIdent,
|
|
42394
42869
|
isJsIdent: () => isJsIdent,
|
|
42395
42870
|
isNullishAbs: () => isNullishAbs,
|
|
42396
42871
|
isTemplateLike: () => isTemplateLike,
|
|
@@ -42467,6 +42942,7 @@ __export(internal_exports, {
|
|
|
42467
42942
|
termNodes: () => termNodes,
|
|
42468
42943
|
throwAbsToKinds: () => throwAbsToKinds,
|
|
42469
42944
|
throwsKindCovered: () => throwsKindCovered,
|
|
42945
|
+
toJsBindingIdent: () => toJsBindingIdent,
|
|
42470
42946
|
truncatedAbs: () => truncatedAbs,
|
|
42471
42947
|
viewTemplateParts: () => viewTemplateParts,
|
|
42472
42948
|
withEvalBudgetOverride: () => withEvalBudgetOverride,
|
|
@@ -42478,6 +42954,7 @@ var init_internal = __esm({
|
|
|
42478
42954
|
"use strict";
|
|
42479
42955
|
init_code_text();
|
|
42480
42956
|
init_leak();
|
|
42957
|
+
init_projection_budget();
|
|
42481
42958
|
init_call_budget();
|
|
42482
42959
|
init_promise();
|
|
42483
42960
|
init_calls();
|
|
@@ -42486,6 +42963,7 @@ var init_internal = __esm({
|
|
|
42486
42963
|
init_stable_source_key();
|
|
42487
42964
|
init_fn_fp();
|
|
42488
42965
|
init_load_deps_fp();
|
|
42966
|
+
init_interface();
|
|
42489
42967
|
init_derivation();
|
|
42490
42968
|
init_inlay();
|
|
42491
42969
|
init_template();
|
|
@@ -52779,20 +53257,20 @@ function envLimits(env2) {
|
|
|
52779
53257
|
};
|
|
52780
53258
|
}
|
|
52781
53259
|
function pick2(key, env2, fallback) {
|
|
52782
|
-
const e = env2[key];
|
|
52783
|
-
if (typeof e === "number" && Number.isFinite(e)) return e;
|
|
52784
53260
|
const x = explicit[key];
|
|
52785
53261
|
if (typeof x === "number" && Number.isFinite(x)) return clampEntries(x, fallback);
|
|
53262
|
+
const e = env2[key];
|
|
53263
|
+
if (typeof e === "number" && Number.isFinite(e)) return e;
|
|
52786
53264
|
const p = fromProject[key];
|
|
52787
53265
|
if (typeof p === "number" && Number.isFinite(p)) return clampEntries(p, fallback);
|
|
52788
53266
|
return fallback;
|
|
52789
53267
|
}
|
|
52790
53268
|
function getSessionCacheLimits(env2 = process.env) {
|
|
52791
|
-
|
|
53269
|
+
const fromEnv = envLimits(env2);
|
|
52792
53270
|
return {
|
|
52793
|
-
maxFiles: pick2("maxFiles",
|
|
52794
|
-
maxFns: pick2("maxFns",
|
|
52795
|
-
maxEvalRuns: pick2("maxEvalRuns",
|
|
53271
|
+
maxFiles: pick2("maxFiles", fromEnv, DEFAULT_SESSION_CACHE_LIMITS.maxFiles),
|
|
53272
|
+
maxFns: pick2("maxFns", fromEnv, DEFAULT_SESSION_CACHE_LIMITS.maxFns),
|
|
53273
|
+
maxEvalRuns: pick2("maxEvalRuns", fromEnv, DEFAULT_SESSION_CACHE_LIMITS.maxEvalRuns)
|
|
52796
53274
|
};
|
|
52797
53275
|
}
|
|
52798
53276
|
function setSessionCacheLimits(partial2) {
|
|
@@ -52805,9 +53283,8 @@ function setSessionCacheFromProject(partial2) {
|
|
|
52805
53283
|
function resetSessionCacheLimitState() {
|
|
52806
53284
|
explicit = {};
|
|
52807
53285
|
fromProject = {};
|
|
52808
|
-
envCache = null;
|
|
52809
53286
|
}
|
|
52810
|
-
var DEFAULT_SESSION_CACHE_LIMITS, HARD_CAP, explicit, fromProject
|
|
53287
|
+
var DEFAULT_SESSION_CACHE_LIMITS, HARD_CAP, explicit, fromProject;
|
|
52811
53288
|
var init_session_cache_limits = __esm({
|
|
52812
53289
|
"../service/src/session-cache-limits.ts"() {
|
|
52813
53290
|
"use strict";
|
|
@@ -52819,7 +53296,6 @@ var init_session_cache_limits = __esm({
|
|
|
52819
53296
|
HARD_CAP = 65536;
|
|
52820
53297
|
explicit = {};
|
|
52821
53298
|
fromProject = {};
|
|
52822
|
-
envCache = null;
|
|
52823
53299
|
}
|
|
52824
53300
|
});
|
|
52825
53301
|
|
|
@@ -52954,15 +53430,22 @@ function findProjectConfig(startDir) {
|
|
|
52954
53430
|
while (dir !== root) {
|
|
52955
53431
|
const pkgPath = resolve6(dir, "package.json");
|
|
52956
53432
|
if (existsSync7(pkgPath)) {
|
|
53433
|
+
let pkg;
|
|
52957
53434
|
try {
|
|
52958
|
-
|
|
52959
|
-
|
|
52960
|
-
|
|
52961
|
-
|
|
52962
|
-
|
|
52963
|
-
|
|
52964
|
-
|
|
52965
|
-
|
|
53435
|
+
pkg = JSON.parse(readFileSync7(pkgPath, "utf-8"));
|
|
53436
|
+
} catch (err) {
|
|
53437
|
+
process.stderr?.write?.(
|
|
53438
|
+
`nudo: package.json parse failed at ${pkgPath} (${err instanceof Error ? err.message : String(err)}); project config disabled for this subtree (defaults + env apply)
|
|
53439
|
+
`
|
|
53440
|
+
);
|
|
53441
|
+
applyBForkBudgetFromConfig(null);
|
|
53442
|
+
return null;
|
|
53443
|
+
}
|
|
53444
|
+
const nudo = pkg && typeof pkg === "object" ? pkg.nudo : void 0;
|
|
53445
|
+
if (nudo) {
|
|
53446
|
+
setSessionCacheFromProject(nudo.sessionCache);
|
|
53447
|
+
applyBForkBudgetFromConfig(nudo);
|
|
53448
|
+
return { config: nudo, projectDir: dir };
|
|
52966
53449
|
}
|
|
52967
53450
|
}
|
|
52968
53451
|
const parent = dirname5(dir);
|
|
@@ -267994,8 +268477,8 @@ function collectExports(sourceFile) {
|
|
|
267994
268477
|
}
|
|
267995
268478
|
return out;
|
|
267996
268479
|
}
|
|
267997
|
-
function draftExportName(name) {
|
|
267998
|
-
return name.includes(".") ? name.replace(/\./g, "_") : name;
|
|
268480
|
+
function draftExportName(name, used) {
|
|
268481
|
+
return toJsBindingIdent(name.includes(".") ? name.replace(/\./g, "_") : name, used);
|
|
267999
268482
|
}
|
|
268000
268483
|
function formatDtsContractDraft(label, files, exports) {
|
|
268001
268484
|
const draftable = exports.filter((e) => e.dsl !== void 0);
|
|
@@ -268007,6 +268490,7 @@ function formatDtsContractDraft(label, files, exports) {
|
|
|
268007
268490
|
}
|
|
268008
268491
|
if (draftable.some((e) => /\bany\s*\(/.test(e.dsl))) used.add("any");
|
|
268009
268492
|
const importList = BUILDERS.filter((b) => used.has(b)).join(", ");
|
|
268493
|
+
const exportUsed = /* @__PURE__ */ new Set();
|
|
268010
268494
|
const lines = [
|
|
268011
268495
|
"// @nudo:draft",
|
|
268012
268496
|
`// Generated by \`nudo contract --from-dts\` from ${label}`,
|
|
@@ -268033,7 +268517,7 @@ function formatDtsContractDraft(label, files, exports) {
|
|
|
268033
268517
|
}
|
|
268034
268518
|
if (e.note) lines.push(`// ${e.name} \u2014 ${e.note}`);
|
|
268035
268519
|
else lines.push(`// ${e.name} \u2014 from TypeScript`);
|
|
268036
|
-
lines.push(`export const ${draftExportName(e.name)} = ${e.dsl};`);
|
|
268520
|
+
lines.push(`export const ${draftExportName(e.name, exportUsed)} = ${e.dsl};`);
|
|
268037
268521
|
if (e.name.includes(".")) {
|
|
268038
268522
|
lines.push(`// sidecar key may also be written as \`${e.name}\``);
|
|
268039
268523
|
}
|
|
@@ -268115,6 +268599,7 @@ var init_dts_contract_draft = __esm({
|
|
|
268115
268599
|
"../harvester/src/dts-contract-draft.ts"() {
|
|
268116
268600
|
"use strict";
|
|
268117
268601
|
import_typescript2 = __toESM(require_typescript(), 1);
|
|
268602
|
+
init_internal();
|
|
268118
268603
|
BUILDERS = [
|
|
268119
268604
|
"fn",
|
|
268120
268605
|
"number",
|
|
@@ -268265,8 +268750,8 @@ function formatHarvestSummary(h) {
|
|
|
268265
268750
|
return lines.join("\n");
|
|
268266
268751
|
}
|
|
268267
268752
|
function lookupHarvested(h, moduleName, exportName) {
|
|
268268
|
-
const mod2 = h.env.modules[moduleName];
|
|
268269
|
-
const a = mod2
|
|
268753
|
+
const mod2 = Object.hasOwn(h.env.modules, moduleName) ? h.env.modules[moduleName] : void 0;
|
|
268754
|
+
const a = (mod2 !== void 0 && Object.hasOwn(mod2, exportName) ? mod2[exportName] : void 0) ?? (Object.hasOwn(h.env.globals, exportName) ? h.env.globals[exportName] : void 0);
|
|
268270
268755
|
if (!a) return void 0;
|
|
268271
268756
|
return formatShape(a);
|
|
268272
268757
|
}
|
|
@@ -269300,7 +269785,7 @@ function collectRequireSpecs(node, out) {
|
|
|
269300
269785
|
};
|
|
269301
269786
|
visit2(node);
|
|
269302
269787
|
}
|
|
269303
|
-
function buildModulesForFile(source, fromFile, load, evalDep, depth, maxDepth, onIssue) {
|
|
269788
|
+
function buildModulesForFile(source, fromFile, load, evalDep, depth, maxDepth, onIssue, localDepsOut) {
|
|
269304
269789
|
const modules = {};
|
|
269305
269790
|
for (const spec of importSpecs(source)) {
|
|
269306
269791
|
if (spec.startsWith(".") || spec.startsWith("/")) {
|
|
@@ -269310,6 +269795,7 @@ function buildModulesForFile(source, fromFile, load, evalDep, depth, maxDepth, o
|
|
|
269310
269795
|
continue;
|
|
269311
269796
|
}
|
|
269312
269797
|
modules[spec] = evalDep(childPath, spec, fromFile, depth + 1);
|
|
269798
|
+
localDepsOut?.push(stablePathKey(childPath));
|
|
269313
269799
|
} else if (!spec.startsWith("node:")) {
|
|
269314
269800
|
const resolved = resolveNpmJsEntryDetailed(spec, dirname10(fromFile));
|
|
269315
269801
|
if (resolved.exportsUnresolved) {
|
|
@@ -269321,6 +269807,7 @@ function buildModulesForFile(source, fromFile, load, evalDep, depth, maxDepth, o
|
|
|
269321
269807
|
}
|
|
269322
269808
|
if (resolved.path) {
|
|
269323
269809
|
const executed = evalDep(resolved.path, spec, fromFile, depth + 1);
|
|
269810
|
+
localDepsOut?.push(stablePathKey(resolved.path));
|
|
269324
269811
|
if (executed && (executed.default !== void 0 || Object.keys(executed.named ?? {}).length > 0)) {
|
|
269325
269812
|
modules[spec] = executed;
|
|
269326
269813
|
continue;
|
|
@@ -269342,6 +269829,18 @@ function clearAbsModuleCache() {
|
|
|
269342
269829
|
function evictAbsModuleCacheFiles(paths) {
|
|
269343
269830
|
for (const p of paths) absModuleCache.delete(stablePathKey(p));
|
|
269344
269831
|
}
|
|
269832
|
+
function depFingerprintCurrent(deps) {
|
|
269833
|
+
for (const d of deps) {
|
|
269834
|
+
let src;
|
|
269835
|
+
try {
|
|
269836
|
+
src = readFileSync13(d.path, "utf-8");
|
|
269837
|
+
} catch {
|
|
269838
|
+
return false;
|
|
269839
|
+
}
|
|
269840
|
+
if (hashSource(src) !== d.hash) return false;
|
|
269841
|
+
}
|
|
269842
|
+
return true;
|
|
269843
|
+
}
|
|
269345
269844
|
function moduleLabel(p) {
|
|
269346
269845
|
const parts = p.split(/[/\\]/);
|
|
269347
269846
|
return parts[parts.length - 1] || p;
|
|
@@ -269426,7 +269925,7 @@ function collectMissingExportIssues(source, modules, fromFile) {
|
|
|
269426
269925
|
const checkName = (spec, name, kind) => {
|
|
269427
269926
|
const mod2 = modules[spec];
|
|
269428
269927
|
if (!mod2?.evaluated) return;
|
|
269429
|
-
const has = name === "default" ? mod2.default !== void 0 :
|
|
269928
|
+
const has = name === "default" ? mod2.default !== void 0 : Object.hasOwn(mod2.named, name);
|
|
269430
269929
|
if (!has) push(spec, name, kind);
|
|
269431
269930
|
};
|
|
269432
269931
|
const body = file.program?.body ?? [];
|
|
@@ -269459,11 +269958,15 @@ function evalAbsModuleGraph(entrySource, entryFile, opts = {}) {
|
|
|
269459
269958
|
const loading = [];
|
|
269460
269959
|
const issues = [];
|
|
269461
269960
|
const seenIssue = /* @__PURE__ */ new Set();
|
|
269961
|
+
const issueFlow = [];
|
|
269962
|
+
const depMeta = /* @__PURE__ */ new Map();
|
|
269462
269963
|
const pushIssue2 = (kind, label, reason) => {
|
|
269964
|
+
const iss = { kind, label, reason };
|
|
269965
|
+
issueFlow.push(iss);
|
|
269463
269966
|
const key = `${kind}:${label}`;
|
|
269464
269967
|
if (seenIssue.has(key)) return;
|
|
269465
269968
|
seenIssue.add(key);
|
|
269466
|
-
issues.push(
|
|
269969
|
+
issues.push(iss);
|
|
269467
269970
|
};
|
|
269468
269971
|
function evalDep(absPathRaw, spec, fromFile, depth) {
|
|
269469
269972
|
const absPath = stablePathKey(absPathRaw);
|
|
@@ -269481,9 +269984,13 @@ function evalAbsModuleGraph(entrySource, entryFile, opts = {}) {
|
|
|
269481
269984
|
if (shared) {
|
|
269482
269985
|
try {
|
|
269483
269986
|
const st = statSync9(absPath);
|
|
269484
|
-
if (st.mtimeMs === shared.mtimeMs && st.size === shared.size) {
|
|
269987
|
+
if (st.mtimeMs === shared.mtimeMs && st.size === shared.size && depFingerprintCurrent(shared.depFingerprints)) {
|
|
269485
269988
|
for (const iss of shared.issues) pushIssue2(iss.kind, iss.label, iss.reason);
|
|
269486
269989
|
cache2.set(absPath, shared.exports);
|
|
269990
|
+
depMeta.set(absPath, {
|
|
269991
|
+
contentHash: shared.contentHash,
|
|
269992
|
+
depFingerprints: shared.depFingerprints
|
|
269993
|
+
});
|
|
269487
269994
|
return shared.exports;
|
|
269488
269995
|
}
|
|
269489
269996
|
} catch {
|
|
@@ -269521,7 +270028,8 @@ function evalAbsModuleGraph(entrySource, entryFile, opts = {}) {
|
|
|
269521
270028
|
loading.pop();
|
|
269522
270029
|
return placeholder;
|
|
269523
270030
|
}
|
|
269524
|
-
const issueStart =
|
|
270031
|
+
const issueStart = issueFlow.length;
|
|
270032
|
+
const localDeps = [];
|
|
269525
270033
|
const modules2 = buildModulesForFile(
|
|
269526
270034
|
source,
|
|
269527
270035
|
absPath,
|
|
@@ -269531,7 +270039,8 @@ function evalAbsModuleGraph(entrySource, entryFile, opts = {}) {
|
|
|
269531
270039
|
maxDepth,
|
|
269532
270040
|
(kind, label, reason) => {
|
|
269533
270041
|
pushIssue2(kind, label, reason);
|
|
269534
|
-
}
|
|
270042
|
+
},
|
|
270043
|
+
localDeps
|
|
269535
270044
|
);
|
|
269536
270045
|
let exports;
|
|
269537
270046
|
const evalRun = tryRunTranspiled(source, { mode: "analyze", modules: modules2 });
|
|
@@ -269548,17 +270057,40 @@ function evalAbsModuleGraph(entrySource, entryFile, opts = {}) {
|
|
|
269548
270057
|
if (exports.default !== void 0) placeholder.default = exports.default;
|
|
269549
270058
|
if (exports.evaluated) placeholder.evaluated = true;
|
|
269550
270059
|
cache2.set(absPath, placeholder);
|
|
270060
|
+
const depFingerprints = [];
|
|
270061
|
+
const seenDep = /* @__PURE__ */ new Set();
|
|
270062
|
+
let untrackable = false;
|
|
270063
|
+
for (const depPath of localDeps) {
|
|
270064
|
+
const meta = depMeta.get(depPath);
|
|
270065
|
+
if (!meta) {
|
|
270066
|
+
untrackable = true;
|
|
270067
|
+
break;
|
|
270068
|
+
}
|
|
270069
|
+
if (!seenDep.has(depPath)) {
|
|
270070
|
+
seenDep.add(depPath);
|
|
270071
|
+
depFingerprints.push({ path: depPath, hash: meta.contentHash });
|
|
270072
|
+
}
|
|
270073
|
+
for (const e of meta.depFingerprints) {
|
|
270074
|
+
if (seenDep.has(e.path)) continue;
|
|
270075
|
+
seenDep.add(e.path);
|
|
270076
|
+
depFingerprints.push(e);
|
|
270077
|
+
}
|
|
270078
|
+
}
|
|
270079
|
+
const subtree = untrackable ? null : { contentHash: hashSource(source), depFingerprints };
|
|
270080
|
+
depMeta.set(absPath, subtree);
|
|
269551
270081
|
let fingerprint;
|
|
269552
270082
|
try {
|
|
269553
270083
|
const st = statSync9(absPath);
|
|
269554
270084
|
fingerprint = { mtimeMs: st.mtimeMs, size: st.size };
|
|
269555
270085
|
} catch {
|
|
269556
270086
|
}
|
|
269557
|
-
if (fingerprint) {
|
|
270087
|
+
if (fingerprint && subtree) {
|
|
269558
270088
|
absModuleCache.set(absPath, {
|
|
269559
270089
|
...fingerprint,
|
|
270090
|
+
contentHash: subtree.contentHash,
|
|
270091
|
+
depFingerprints: subtree.depFingerprints,
|
|
269560
270092
|
exports: placeholder,
|
|
269561
|
-
issues:
|
|
270093
|
+
issues: issueFlow.slice(issueStart)
|
|
269562
270094
|
});
|
|
269563
270095
|
}
|
|
269564
270096
|
return placeholder;
|
|
@@ -269602,7 +270134,7 @@ function importLocalBindings(source, modules) {
|
|
|
269602
270134
|
} else if (sp.type === "ImportSpecifier") {
|
|
269603
270135
|
const imported = sp.imported?.type === "StringLiteral" ? sp.imported.value : sp.imported?.name;
|
|
269604
270136
|
if (imported === void 0) continue;
|
|
269605
|
-
const absVal = imported === "default" ? mod2.default : mod2.named[imported];
|
|
270137
|
+
const absVal = imported === "default" ? mod2.default : Object.hasOwn(mod2.named, imported) ? mod2.named[imported] : void 0;
|
|
269606
270138
|
out.set(local, absVal ?? unknown);
|
|
269607
270139
|
}
|
|
269608
270140
|
}
|
|
@@ -269800,7 +270332,7 @@ function pickNamed(mock2, names2) {
|
|
|
269800
270332
|
if (mock2.default) def = mock2.default;
|
|
269801
270333
|
continue;
|
|
269802
270334
|
}
|
|
269803
|
-
const v2 = mock2.named[n];
|
|
270335
|
+
const v2 = Object.hasOwn(mock2.named, n) ? mock2.named[n] : void 0;
|
|
269804
270336
|
if (v2 !== void 0) named[n] = v2;
|
|
269805
270337
|
}
|
|
269806
270338
|
return def !== void 0 ? { named, default: def } : { named };
|
|
@@ -269885,6 +270417,7 @@ function trimAnalysisFileCache() {
|
|
|
269885
270417
|
}
|
|
269886
270418
|
}
|
|
269887
270419
|
function analysisCacheGet(filePath, source, auxKey) {
|
|
270420
|
+
if (getSessionCacheLimits().maxFiles <= 0) return void 0;
|
|
269888
270421
|
const key = stablePathKey(filePath);
|
|
269889
270422
|
const e = analysisByFile.get(key);
|
|
269890
270423
|
if (!e) return void 0;
|
|
@@ -269902,6 +270435,7 @@ function analysisCacheSet(filePath, source, auxKey, value) {
|
|
|
269902
270435
|
if (oldest === void 0) break;
|
|
269903
270436
|
analysisByFile.delete(oldest);
|
|
269904
270437
|
}
|
|
270438
|
+
analysisByFile.delete(key);
|
|
269905
270439
|
analysisByFile.set(key, { source, auxKey, value });
|
|
269906
270440
|
}
|
|
269907
270441
|
function evictAnalysisFileCacheForFiles(files) {
|
|
@@ -269943,6 +270477,7 @@ function trimFnAnalysisCache() {
|
|
|
269943
270477
|
}
|
|
269944
270478
|
}
|
|
269945
270479
|
function fnAnalysisCacheGet(key) {
|
|
270480
|
+
if (getSessionCacheLimits().maxFns <= 0) return void 0;
|
|
269946
270481
|
const k = normalizeFnCacheKey(key);
|
|
269947
270482
|
const hit = fnAnalysisCache.get(k);
|
|
269948
270483
|
if (hit !== void 0) {
|
|
@@ -269960,6 +270495,7 @@ function fnAnalysisCacheSet(key, value) {
|
|
|
269960
270495
|
if (oldest === void 0) break;
|
|
269961
270496
|
fnAnalysisCache.delete(oldest);
|
|
269962
270497
|
}
|
|
270498
|
+
fnAnalysisCache.delete(k);
|
|
269963
270499
|
fnAnalysisCache.set(k, value);
|
|
269964
270500
|
}
|
|
269965
270501
|
function evictFnAnalysisCacheForFiles(files) {
|
|
@@ -270150,7 +270686,11 @@ function collectEvalReplacements(source) {
|
|
|
270150
270686
|
}
|
|
270151
270687
|
};
|
|
270152
270688
|
visitStmts(file.program.body);
|
|
270153
|
-
} catch {
|
|
270689
|
+
} catch (err) {
|
|
270690
|
+
if (targets.length > 0 || asTargets.length > 0) {
|
|
270691
|
+
throw err;
|
|
270692
|
+
}
|
|
270693
|
+
noteEvalFallback(err);
|
|
270154
270694
|
}
|
|
270155
270695
|
return { targets, values, asTargets, asValues };
|
|
270156
270696
|
}
|
|
@@ -270192,6 +270732,7 @@ function evalCacheSet(filePath, stableSource, mode, envKey, mockKey, depKey, val
|
|
|
270192
270732
|
if (oldest === void 0) break;
|
|
270193
270733
|
evalRunByFile.delete(oldest);
|
|
270194
270734
|
}
|
|
270735
|
+
evalRunByFile.delete(key);
|
|
270195
270736
|
evalRunByFile.set(key, { stableSource, mode, envKey, mockKey, depKey, value });
|
|
270196
270737
|
}
|
|
270197
270738
|
function trimEvalCache() {
|
|
@@ -270210,7 +270751,7 @@ function tryRunEval(source, filePath, opts = {}) {
|
|
|
270210
270751
|
const stable = stableAnalyzeKeySource(source);
|
|
270211
270752
|
const depKey = evalDepKey(source, filePath);
|
|
270212
270753
|
const canCache = depKey !== null;
|
|
270213
|
-
if (canCache) {
|
|
270754
|
+
if (canCache && getSessionCacheLimits().maxEvalRuns > 0) {
|
|
270214
270755
|
const cacheKey = stablePathKey(filePath);
|
|
270215
270756
|
const cached2 = evalRunByFile.get(cacheKey);
|
|
270216
270757
|
if (cached2 && cached2.stableSource === stable && cached2.mode === mode && cached2.envKey === envKey && cached2.mockKey === mockKey && cached2.depKey === depKey) {
|
|
@@ -270274,7 +270815,7 @@ function tryRunEval(source, filePath, opts = {}) {
|
|
|
270274
270815
|
function tryEvalCallFull(source, filePath, fnName, args, opts = {}) {
|
|
270275
270816
|
const run = tryRunEval(source, filePath, { envNames: opts.envNames, mocks: opts.mocks });
|
|
270276
270817
|
if (!run) return void 0;
|
|
270277
|
-
if (!(
|
|
270818
|
+
if (!Object.hasOwn(run.exports, fnName)) return void 0;
|
|
270278
270819
|
const collected = [];
|
|
270279
270820
|
const memberDiags = [];
|
|
270280
270821
|
const prevCall = opts.collectCalls ? setEvalCallCollector((r) => collected.push(r)) : void 0;
|
|
@@ -270299,7 +270840,14 @@ function tryEvalCall(source, filePath, fnName, args, opts = {}) {
|
|
|
270299
270840
|
const full = tryEvalCallFull(source, filePath, fnName, args, opts);
|
|
270300
270841
|
if (!full) return void 0;
|
|
270301
270842
|
const r = full.result;
|
|
270302
|
-
if (!r)
|
|
270843
|
+
if (!isAbsVal(r)) {
|
|
270844
|
+
noteEvalFallback(
|
|
270845
|
+
new Error(
|
|
270846
|
+
`tryEvalCall: '${fnName}' result is not an Abs value (producer contract violation)`
|
|
270847
|
+
)
|
|
270848
|
+
);
|
|
270849
|
+
return void 0;
|
|
270850
|
+
}
|
|
270303
270851
|
if (r.shape.k === "never" && full.throws.shape.k !== "never") {
|
|
270304
270852
|
return void 0;
|
|
270305
270853
|
}
|
|
@@ -270502,13 +271050,14 @@ function safeAbsOrUnknown(a) {
|
|
|
270502
271050
|
}
|
|
270503
271051
|
function callRecordFromAbsCall(r, impMap) {
|
|
270504
271052
|
const argAbs = r.args.map(safeAbsOrUnknown);
|
|
270505
|
-
const threw =
|
|
271053
|
+
const threw = r.threw === true;
|
|
271054
|
+
const threwUnknown = r.threw === void 0;
|
|
270506
271055
|
const thrownOrResult = safeAbsOrUnknown(r.result);
|
|
270507
271056
|
const rec = {
|
|
270508
271057
|
fnName: r.fnName,
|
|
270509
271058
|
argAbs,
|
|
270510
271059
|
resultAbs: threw ? neverAbs : thrownOrResult,
|
|
270511
|
-
throwsAbs: threw ? thrownOrResult : neverAbs,
|
|
271060
|
+
throwsAbs: threw ? thrownOrResult : threwUnknown ? unknown : neverAbs,
|
|
270512
271061
|
callLoc: r.callLoc
|
|
270513
271062
|
};
|
|
270514
271063
|
const imp = impMap?.get(r.fnName) ?? // `ns.helper` / `Class.method`:先整名,再按首段点号拆命名空间成员
|
|
@@ -270978,19 +271527,23 @@ function collectDeclared(file) {
|
|
|
270978
271527
|
if (id.type === "Identifier") names2.add(id.name);
|
|
270979
271528
|
if (id.type === "ObjectPattern") {
|
|
270980
271529
|
for (const p of id.properties) {
|
|
270981
|
-
addId(p.value);
|
|
271530
|
+
addId(p.type === "RestElement" ? p.argument : p.value);
|
|
270982
271531
|
}
|
|
270983
271532
|
}
|
|
270984
271533
|
if (id.type === "ArrayPattern") {
|
|
270985
271534
|
for (const el of id.elements) addId(el);
|
|
270986
271535
|
}
|
|
271536
|
+
if (id.type === "AssignmentPattern") addId(id.left);
|
|
271537
|
+
if (id.type === "RestElement") addId(id.argument);
|
|
270987
271538
|
};
|
|
270988
271539
|
const visit2 = (node) => {
|
|
270989
271540
|
if (!node || typeof node !== "object") return;
|
|
270990
271541
|
const o = node;
|
|
270991
271542
|
switch (o.type) {
|
|
270992
271543
|
case "FunctionDeclaration":
|
|
271544
|
+
case "FunctionExpression":
|
|
270993
271545
|
case "ClassDeclaration":
|
|
271546
|
+
case "ClassExpression":
|
|
270994
271547
|
addId(o.id);
|
|
270995
271548
|
break;
|
|
270996
271549
|
case "VariableDeclarator":
|
|
@@ -271035,7 +271588,7 @@ function isStaticStringExpr(node) {
|
|
|
271035
271588
|
function isFreeUnknown(name, declared, seen, known) {
|
|
271036
271589
|
return !declared.has(name) && !known.has(name) && !name.startsWith("$") && !seen.has(name);
|
|
271037
271590
|
}
|
|
271038
|
-
function walkBuiltinUnknown(node, declared, out, seen, known,
|
|
271591
|
+
function walkBuiltinUnknown(node, declared, out, seen, known, namePosition = false) {
|
|
271039
271592
|
const n = node;
|
|
271040
271593
|
const flag = (idNode, name) => {
|
|
271041
271594
|
if (!isFreeUnknown(name, declared, seen, known)) return;
|
|
@@ -271057,20 +271610,21 @@ function walkBuiltinUnknown(node, declared, out, seen, known, parentKey) {
|
|
|
271057
271610
|
} else if (callee?.type === "Identifier") {
|
|
271058
271611
|
flag(n.callee, callee.name);
|
|
271059
271612
|
}
|
|
271060
|
-
} else if (n.type === "Identifier" && typeof n.name === "string" && n.name !== "require" &&
|
|
271613
|
+
} else if (n.type === "Identifier" && typeof n.name === "string" && n.name !== "require" && !namePosition) {
|
|
271061
271614
|
flag(node, n.name);
|
|
271062
271615
|
}
|
|
271063
271616
|
for (const key of Object.keys(n)) {
|
|
271064
271617
|
if (key === "loc" || key === "start" || key === "end") continue;
|
|
271618
|
+
const childIsName = (key === "key" || key === "property") && n.computed !== true || key === "local" || key === "id";
|
|
271065
271619
|
const v2 = n[key];
|
|
271066
271620
|
if (Array.isArray(v2)) {
|
|
271067
271621
|
v2.forEach((x) => {
|
|
271068
271622
|
if (x && typeof x === "object" && "type" in x) {
|
|
271069
|
-
walkBuiltinUnknown(x, declared, out, seen, known,
|
|
271623
|
+
walkBuiltinUnknown(x, declared, out, seen, known, childIsName);
|
|
271070
271624
|
}
|
|
271071
271625
|
});
|
|
271072
271626
|
} else if (v2 && typeof v2 === "object" && "type" in v2) {
|
|
271073
|
-
walkBuiltinUnknown(v2, declared, out, seen, known,
|
|
271627
|
+
walkBuiltinUnknown(v2, declared, out, seen, known, childIsName);
|
|
271074
271628
|
}
|
|
271075
271629
|
}
|
|
271076
271630
|
}
|
|
@@ -272834,10 +273388,16 @@ var init_disk_cache = __esm({
|
|
|
272834
273388
|
});
|
|
272835
273389
|
|
|
272836
273390
|
// ../service/src/watch-paths.ts
|
|
273391
|
+
function matchFormalSidecarSuffix(path) {
|
|
273392
|
+
for (const suffix of FORMAL_SIDECAR_SUFFIXES) {
|
|
273393
|
+
if (path.slice(-suffix.length).toLowerCase() === suffix) return suffix;
|
|
273394
|
+
}
|
|
273395
|
+
return void 0;
|
|
273396
|
+
}
|
|
272837
273397
|
function isSidecarPath(path) {
|
|
272838
273398
|
const lower = path.toLowerCase().replace(/\\/g, "/");
|
|
272839
273399
|
if (lower.includes(".nudo.draft.")) return false;
|
|
272840
|
-
return lower
|
|
273400
|
+
return matchFormalSidecarSuffix(lower) !== void 0;
|
|
272841
273401
|
}
|
|
272842
273402
|
function isProjectConfigPath(path) {
|
|
272843
273403
|
const norm = path.replace(/\\/g, "/");
|
|
@@ -272850,13 +273410,13 @@ function isWatchRelevantPath(path) {
|
|
|
272850
273410
|
}
|
|
272851
273411
|
function ambientSourcesOfSidecar(sidecarPath) {
|
|
272852
273412
|
const norm = sidecarPath.replace(/\\/g, "/");
|
|
272853
|
-
|
|
272854
|
-
|
|
272855
|
-
|
|
272856
|
-
const
|
|
272857
|
-
return
|
|
273413
|
+
if (norm.toLowerCase().includes(".nudo.draft.")) return [];
|
|
273414
|
+
const suffix = matchFormalSidecarSuffix(norm);
|
|
273415
|
+
if (!suffix) return [];
|
|
273416
|
+
const base = norm.slice(0, norm.length - suffix.length);
|
|
273417
|
+
return SIDECAR_AMBIENT_SUFFIXES[suffix].map((ext) => `${base}${ext}`);
|
|
272858
273418
|
}
|
|
272859
|
-
var PROJECT_CONFIG_BASENAMES;
|
|
273419
|
+
var PROJECT_CONFIG_BASENAMES, FORMAL_SIDECAR_SUFFIXES, SIDECAR_AMBIENT_SUFFIXES;
|
|
272860
273420
|
var init_watch_paths = __esm({
|
|
272861
273421
|
"../service/src/watch-paths.ts"() {
|
|
272862
273422
|
"use strict";
|
|
@@ -272871,6 +273431,12 @@ var init_watch_paths = __esm({
|
|
|
272871
273431
|
".nudorc",
|
|
272872
273432
|
".nudorc.json"
|
|
272873
273433
|
]);
|
|
273434
|
+
FORMAL_SIDECAR_SUFFIXES = [".nudo.js", ".nudo.mjs", ".nudo.ts"];
|
|
273435
|
+
SIDECAR_AMBIENT_SUFFIXES = {
|
|
273436
|
+
".nudo.js": [".js", ".mjs"],
|
|
273437
|
+
".nudo.mjs": [".js", ".mjs"],
|
|
273438
|
+
".nudo.ts": [".ts", ".mts"]
|
|
273439
|
+
};
|
|
272874
273440
|
}
|
|
272875
273441
|
});
|
|
272876
273442
|
|
|
@@ -273343,7 +273909,7 @@ var init_chunk_4TAFH6ZZ = __esm({
|
|
|
273343
273909
|
}
|
|
273344
273910
|
});
|
|
273345
273911
|
|
|
273346
|
-
// ../service/dist/chunk-
|
|
273912
|
+
// ../service/dist/chunk-2RP2Q6LJ.js
|
|
273347
273913
|
import { readFileSync as readFileSync17, existsSync as existsSync16, statSync as statSync10, mkdirSync as mkdirSync5, writeFileSync as writeFileSync5 } from "fs";
|
|
273348
273914
|
import { resolve as resolvePath2, join as joinPath2 } from "path";
|
|
273349
273915
|
import { pathToFileURL as pathToFileURL2 } from "url";
|
|
@@ -273524,20 +274090,20 @@ function envLimits2(env2) {
|
|
|
273524
274090
|
};
|
|
273525
274091
|
}
|
|
273526
274092
|
function pick3(key, env2, fallback) {
|
|
273527
|
-
const e = env2[key];
|
|
273528
|
-
if (typeof e === "number" && Number.isFinite(e)) return e;
|
|
273529
274093
|
const x = explicit2[key];
|
|
273530
274094
|
if (typeof x === "number" && Number.isFinite(x)) return clampEntries2(x, fallback);
|
|
274095
|
+
const e = env2[key];
|
|
274096
|
+
if (typeof e === "number" && Number.isFinite(e)) return e;
|
|
273531
274097
|
const p = fromProject2[key];
|
|
273532
274098
|
if (typeof p === "number" && Number.isFinite(p)) return clampEntries2(p, fallback);
|
|
273533
274099
|
return fallback;
|
|
273534
274100
|
}
|
|
273535
274101
|
function getSessionCacheLimits2(env2 = process.env) {
|
|
273536
|
-
|
|
274102
|
+
const fromEnv = envLimits2(env2);
|
|
273537
274103
|
return {
|
|
273538
|
-
maxFiles: pick3("maxFiles",
|
|
273539
|
-
maxFns: pick3("maxFns",
|
|
273540
|
-
maxEvalRuns: pick3("maxEvalRuns",
|
|
274104
|
+
maxFiles: pick3("maxFiles", fromEnv, DEFAULT_SESSION_CACHE_LIMITS2.maxFiles),
|
|
274105
|
+
maxFns: pick3("maxFns", fromEnv, DEFAULT_SESSION_CACHE_LIMITS2.maxFns),
|
|
274106
|
+
maxEvalRuns: pick3("maxEvalRuns", fromEnv, DEFAULT_SESSION_CACHE_LIMITS2.maxEvalRuns)
|
|
273541
274107
|
};
|
|
273542
274108
|
}
|
|
273543
274109
|
function setSessionCacheFromProject2(partial2) {
|
|
@@ -273646,15 +274212,22 @@ function findProjectConfig2(startDir) {
|
|
|
273646
274212
|
while (dir !== root) {
|
|
273647
274213
|
const pkgPath = resolve10(dir, "package.json");
|
|
273648
274214
|
if (existsSync22(pkgPath)) {
|
|
274215
|
+
let pkg;
|
|
273649
274216
|
try {
|
|
273650
|
-
|
|
273651
|
-
|
|
273652
|
-
|
|
273653
|
-
|
|
273654
|
-
|
|
273655
|
-
|
|
273656
|
-
|
|
273657
|
-
|
|
274217
|
+
pkg = JSON.parse(readFileSync22(pkgPath, "utf-8"));
|
|
274218
|
+
} catch (err) {
|
|
274219
|
+
process.stderr?.write?.(
|
|
274220
|
+
`nudo: package.json parse failed at ${pkgPath} (${err instanceof Error ? err.message : String(err)}); project config disabled for this subtree (defaults + env apply)
|
|
274221
|
+
`
|
|
274222
|
+
);
|
|
274223
|
+
applyBForkBudgetFromConfig2(null);
|
|
274224
|
+
return null;
|
|
274225
|
+
}
|
|
274226
|
+
const nudo = pkg && typeof pkg === "object" ? pkg.nudo : void 0;
|
|
274227
|
+
if (nudo) {
|
|
274228
|
+
setSessionCacheFromProject2(nudo.sessionCache);
|
|
274229
|
+
applyBForkBudgetFromConfig2(nudo);
|
|
274230
|
+
return { config: nudo, projectDir: dir };
|
|
273658
274231
|
}
|
|
273659
274232
|
}
|
|
273660
274233
|
const parent = dirname18(dir);
|
|
@@ -273806,9 +274379,9 @@ function resolveNpmJsEntryDetailed2(source, fromDir) {
|
|
|
273806
274379
|
}
|
|
273807
274380
|
return { path: tryInsidePkg2(pkgDir, subpath, tryFile), exportsUnresolved: false };
|
|
273808
274381
|
}
|
|
273809
|
-
var BUILTIN_ERROR_CLASSES2, BUILTIN_PROTOTYPE_CLASSES2, numA2, strA2, boolA2, unkA2, undefA2, nullA2, OBJECT_PROTOTYPE_METHODS2, BUILTIN_PROTOTYPE_METHOD_APPROXIMATIONS2, BoundedLruMap4, envFactories2, impliedDeps2, PATH_ENV_CACHE_MAX2, PATH_ENV_BY_PATH_MAX2, PATH_ENV_BASE_DIRS_MAX2, pathEnvCache2, pathEnvByPath2, pathEnvBaseDirs2, DEFAULT_SESSION_CACHE_LIMITS2, HARD_CAP2, explicit2, fromProject2,
|
|
273810
|
-
var
|
|
273811
|
-
"../service/dist/chunk-
|
|
274382
|
+
var BUILTIN_ERROR_CLASSES2, BUILTIN_PROTOTYPE_CLASSES2, numA2, strA2, boolA2, unkA2, undefA2, nullA2, OBJECT_PROTOTYPE_METHODS2, BUILTIN_PROTOTYPE_METHOD_APPROXIMATIONS2, BoundedLruMap4, envFactories2, impliedDeps2, PATH_ENV_CACHE_MAX2, PATH_ENV_BY_PATH_MAX2, PATH_ENV_BASE_DIRS_MAX2, pathEnvCache2, pathEnvByPath2, pathEnvBaseDirs2, DEFAULT_SESSION_CACHE_LIMITS2, HARD_CAP2, explicit2, fromProject2, DEFAULT_ANALYSIS_EXCLUDE2, DEFAULT_ANALYSIS_MODE2, JS_CONDITIONS2;
|
|
274383
|
+
var init_chunk_2RP2Q6LJ = __esm({
|
|
274384
|
+
"../service/dist/chunk-2RP2Q6LJ.js"() {
|
|
273812
274385
|
"use strict";
|
|
273813
274386
|
init_src();
|
|
273814
274387
|
init_es();
|
|
@@ -274074,7 +274647,6 @@ var init_chunk_RHEXBPQ6 = __esm({
|
|
|
274074
274647
|
HARD_CAP2 = 65536;
|
|
274075
274648
|
explicit2 = {};
|
|
274076
274649
|
fromProject2 = {};
|
|
274077
|
-
envCache2 = null;
|
|
274078
274650
|
DEFAULT_ANALYSIS_EXCLUDE2 = [
|
|
274079
274651
|
"**/node_modules/**",
|
|
274080
274652
|
"**/dist/**",
|
|
@@ -274085,7 +274657,7 @@ var init_chunk_RHEXBPQ6 = __esm({
|
|
|
274085
274657
|
}
|
|
274086
274658
|
});
|
|
274087
274659
|
|
|
274088
|
-
// ../service/dist/chunk-
|
|
274660
|
+
// ../service/dist/chunk-6GFPZGQS.js
|
|
274089
274661
|
import { existsSync as existsSync17, statSync as statSync11, readFileSync as readFileSync18 } from "fs";
|
|
274090
274662
|
import { dirname as dirname19, resolve as resolve11, join as join13 } from "path";
|
|
274091
274663
|
import { readFileSync as readFileSync42, statSync as statSync32 } from "fs";
|
|
@@ -274696,7 +275268,7 @@ function collectRequireSpecs2(node, out) {
|
|
|
274696
275268
|
};
|
|
274697
275269
|
visit2(node);
|
|
274698
275270
|
}
|
|
274699
|
-
function buildModulesForFile2(source, fromFile, load, evalDep, depth, maxDepth, onIssue) {
|
|
275271
|
+
function buildModulesForFile2(source, fromFile, load, evalDep, depth, maxDepth, onIssue, localDepsOut) {
|
|
274700
275272
|
const modules = {};
|
|
274701
275273
|
for (const spec of importSpecs2(source)) {
|
|
274702
275274
|
if (spec.startsWith(".") || spec.startsWith("/")) {
|
|
@@ -274706,6 +275278,7 @@ function buildModulesForFile2(source, fromFile, load, evalDep, depth, maxDepth,
|
|
|
274706
275278
|
continue;
|
|
274707
275279
|
}
|
|
274708
275280
|
modules[spec] = evalDep(childPath, spec, fromFile, depth + 1);
|
|
275281
|
+
localDepsOut?.push(stablePathKey(childPath));
|
|
274709
275282
|
} else if (!spec.startsWith("node:")) {
|
|
274710
275283
|
const resolved = resolveNpmJsEntryDetailed2(spec, dirname32(fromFile));
|
|
274711
275284
|
if (resolved.exportsUnresolved) {
|
|
@@ -274717,6 +275290,7 @@ function buildModulesForFile2(source, fromFile, load, evalDep, depth, maxDepth,
|
|
|
274717
275290
|
}
|
|
274718
275291
|
if (resolved.path) {
|
|
274719
275292
|
const executed = evalDep(resolved.path, spec, fromFile, depth + 1);
|
|
275293
|
+
localDepsOut?.push(stablePathKey(resolved.path));
|
|
274720
275294
|
if (executed && (executed.default !== void 0 || Object.keys(executed.named ?? {}).length > 0)) {
|
|
274721
275295
|
modules[spec] = executed;
|
|
274722
275296
|
continue;
|
|
@@ -274729,6 +275303,18 @@ function buildModulesForFile2(source, fromFile, load, evalDep, depth, maxDepth,
|
|
|
274729
275303
|
void maxDepth;
|
|
274730
275304
|
return modules;
|
|
274731
275305
|
}
|
|
275306
|
+
function depFingerprintCurrent2(deps) {
|
|
275307
|
+
for (const d of deps) {
|
|
275308
|
+
let src;
|
|
275309
|
+
try {
|
|
275310
|
+
src = readFileSync42(d.path, "utf-8");
|
|
275311
|
+
} catch {
|
|
275312
|
+
return false;
|
|
275313
|
+
}
|
|
275314
|
+
if (hashSource(src) !== d.hash) return false;
|
|
275315
|
+
}
|
|
275316
|
+
return true;
|
|
275317
|
+
}
|
|
274732
275318
|
function moduleLabel2(p) {
|
|
274733
275319
|
const parts = p.split(/[/\\]/);
|
|
274734
275320
|
return parts[parts.length - 1] || p;
|
|
@@ -274813,7 +275399,7 @@ function collectMissingExportIssues2(source, modules, fromFile) {
|
|
|
274813
275399
|
const checkName = (spec, name, kind) => {
|
|
274814
275400
|
const mod2 = modules[spec];
|
|
274815
275401
|
if (!mod2?.evaluated) return;
|
|
274816
|
-
const has = name === "default" ? mod2.default !== void 0 :
|
|
275402
|
+
const has = name === "default" ? mod2.default !== void 0 : Object.hasOwn(mod2.named, name);
|
|
274817
275403
|
if (!has) push(spec, name, kind);
|
|
274818
275404
|
};
|
|
274819
275405
|
const body = file.program?.body ?? [];
|
|
@@ -274846,11 +275432,15 @@ function evalAbsModuleGraph2(entrySource, entryFile, opts = {}) {
|
|
|
274846
275432
|
const loading = [];
|
|
274847
275433
|
const issues = [];
|
|
274848
275434
|
const seenIssue = /* @__PURE__ */ new Set();
|
|
275435
|
+
const issueFlow = [];
|
|
275436
|
+
const depMeta = /* @__PURE__ */ new Map();
|
|
274849
275437
|
const pushIssue2 = (kind, label, reason) => {
|
|
275438
|
+
const iss = { kind, label, reason };
|
|
275439
|
+
issueFlow.push(iss);
|
|
274850
275440
|
const key = `${kind}:${label}`;
|
|
274851
275441
|
if (seenIssue.has(key)) return;
|
|
274852
275442
|
seenIssue.add(key);
|
|
274853
|
-
issues.push(
|
|
275443
|
+
issues.push(iss);
|
|
274854
275444
|
};
|
|
274855
275445
|
function evalDep(absPathRaw, spec, fromFile, depth) {
|
|
274856
275446
|
const absPath = stablePathKey(absPathRaw);
|
|
@@ -274868,9 +275458,13 @@ function evalAbsModuleGraph2(entrySource, entryFile, opts = {}) {
|
|
|
274868
275458
|
if (shared) {
|
|
274869
275459
|
try {
|
|
274870
275460
|
const st = statSync32(absPath);
|
|
274871
|
-
if (st.mtimeMs === shared.mtimeMs && st.size === shared.size) {
|
|
275461
|
+
if (st.mtimeMs === shared.mtimeMs && st.size === shared.size && depFingerprintCurrent2(shared.depFingerprints)) {
|
|
274872
275462
|
for (const iss of shared.issues) pushIssue2(iss.kind, iss.label, iss.reason);
|
|
274873
275463
|
cache2.set(absPath, shared.exports);
|
|
275464
|
+
depMeta.set(absPath, {
|
|
275465
|
+
contentHash: shared.contentHash,
|
|
275466
|
+
depFingerprints: shared.depFingerprints
|
|
275467
|
+
});
|
|
274874
275468
|
return shared.exports;
|
|
274875
275469
|
}
|
|
274876
275470
|
} catch {
|
|
@@ -274908,7 +275502,8 @@ function evalAbsModuleGraph2(entrySource, entryFile, opts = {}) {
|
|
|
274908
275502
|
loading.pop();
|
|
274909
275503
|
return placeholder;
|
|
274910
275504
|
}
|
|
274911
|
-
const issueStart =
|
|
275505
|
+
const issueStart = issueFlow.length;
|
|
275506
|
+
const localDeps = [];
|
|
274912
275507
|
const modules2 = buildModulesForFile2(
|
|
274913
275508
|
source,
|
|
274914
275509
|
absPath,
|
|
@@ -274918,7 +275513,8 @@ function evalAbsModuleGraph2(entrySource, entryFile, opts = {}) {
|
|
|
274918
275513
|
maxDepth,
|
|
274919
275514
|
(kind, label, reason) => {
|
|
274920
275515
|
pushIssue2(kind, label, reason);
|
|
274921
|
-
}
|
|
275516
|
+
},
|
|
275517
|
+
localDeps
|
|
274922
275518
|
);
|
|
274923
275519
|
let exports;
|
|
274924
275520
|
const evalRun = tryRunTranspiled(source, { mode: "analyze", modules: modules2 });
|
|
@@ -274935,17 +275531,40 @@ function evalAbsModuleGraph2(entrySource, entryFile, opts = {}) {
|
|
|
274935
275531
|
if (exports.default !== void 0) placeholder.default = exports.default;
|
|
274936
275532
|
if (exports.evaluated) placeholder.evaluated = true;
|
|
274937
275533
|
cache2.set(absPath, placeholder);
|
|
275534
|
+
const depFingerprints = [];
|
|
275535
|
+
const seenDep = /* @__PURE__ */ new Set();
|
|
275536
|
+
let untrackable = false;
|
|
275537
|
+
for (const depPath of localDeps) {
|
|
275538
|
+
const meta = depMeta.get(depPath);
|
|
275539
|
+
if (!meta) {
|
|
275540
|
+
untrackable = true;
|
|
275541
|
+
break;
|
|
275542
|
+
}
|
|
275543
|
+
if (!seenDep.has(depPath)) {
|
|
275544
|
+
seenDep.add(depPath);
|
|
275545
|
+
depFingerprints.push({ path: depPath, hash: meta.contentHash });
|
|
275546
|
+
}
|
|
275547
|
+
for (const e of meta.depFingerprints) {
|
|
275548
|
+
if (seenDep.has(e.path)) continue;
|
|
275549
|
+
seenDep.add(e.path);
|
|
275550
|
+
depFingerprints.push(e);
|
|
275551
|
+
}
|
|
275552
|
+
}
|
|
275553
|
+
const subtree = untrackable ? null : { contentHash: hashSource(source), depFingerprints };
|
|
275554
|
+
depMeta.set(absPath, subtree);
|
|
274938
275555
|
let fingerprint;
|
|
274939
275556
|
try {
|
|
274940
275557
|
const st = statSync32(absPath);
|
|
274941
275558
|
fingerprint = { mtimeMs: st.mtimeMs, size: st.size };
|
|
274942
275559
|
} catch {
|
|
274943
275560
|
}
|
|
274944
|
-
if (fingerprint) {
|
|
275561
|
+
if (fingerprint && subtree) {
|
|
274945
275562
|
absModuleCache2.set(absPath, {
|
|
274946
275563
|
...fingerprint,
|
|
275564
|
+
contentHash: subtree.contentHash,
|
|
275565
|
+
depFingerprints: subtree.depFingerprints,
|
|
274947
275566
|
exports: placeholder,
|
|
274948
|
-
issues:
|
|
275567
|
+
issues: issueFlow.slice(issueStart)
|
|
274949
275568
|
});
|
|
274950
275569
|
}
|
|
274951
275570
|
return placeholder;
|
|
@@ -274989,7 +275608,7 @@ function importLocalBindings2(source, modules) {
|
|
|
274989
275608
|
} else if (sp.type === "ImportSpecifier") {
|
|
274990
275609
|
const imported = sp.imported?.type === "StringLiteral" ? sp.imported.value : sp.imported?.name;
|
|
274991
275610
|
if (imported === void 0) continue;
|
|
274992
|
-
const absVal = imported === "default" ? mod2.default : mod2.named[imported];
|
|
275611
|
+
const absVal = imported === "default" ? mod2.default : Object.hasOwn(mod2.named, imported) ? mod2.named[imported] : void 0;
|
|
274993
275612
|
out.set(local, absVal ?? unknown);
|
|
274994
275613
|
}
|
|
274995
275614
|
}
|
|
@@ -275132,7 +275751,7 @@ function pickNamed2(mock2, names2) {
|
|
|
275132
275751
|
if (mock2.default) def = mock2.default;
|
|
275133
275752
|
continue;
|
|
275134
275753
|
}
|
|
275135
|
-
const v2 = mock2.named[n];
|
|
275754
|
+
const v2 = Object.hasOwn(mock2.named, n) ? mock2.named[n] : void 0;
|
|
275136
275755
|
if (v2 !== void 0) named[n] = v2;
|
|
275137
275756
|
}
|
|
275138
275757
|
return def !== void 0 ? { named, default: def } : { named };
|
|
@@ -275192,6 +275811,7 @@ function applyMockModuleDirectivesFromSource2(source, base, opts) {
|
|
|
275192
275811
|
return applyMockModuleDirectives2(base, fileDirectives, opts);
|
|
275193
275812
|
}
|
|
275194
275813
|
function analysisCacheGet2(filePath, source, auxKey) {
|
|
275814
|
+
if (getSessionCacheLimits2().maxFiles <= 0) return void 0;
|
|
275195
275815
|
const key = stablePathKey(filePath);
|
|
275196
275816
|
const e = analysisByFile2.get(key);
|
|
275197
275817
|
if (!e) return void 0;
|
|
@@ -275209,6 +275829,7 @@ function analysisCacheSet2(filePath, source, auxKey, value) {
|
|
|
275209
275829
|
if (oldest === void 0) break;
|
|
275210
275830
|
analysisByFile2.delete(oldest);
|
|
275211
275831
|
}
|
|
275832
|
+
analysisByFile2.delete(key);
|
|
275212
275833
|
analysisByFile2.set(key, { source, auxKey, value });
|
|
275213
275834
|
}
|
|
275214
275835
|
function normalizeFnCacheKey2(key) {
|
|
@@ -275218,6 +275839,7 @@ function normalizeFnCacheKey2(key) {
|
|
|
275218
275839
|
return stablePathKey(filePath) + rest;
|
|
275219
275840
|
}
|
|
275220
275841
|
function fnAnalysisCacheGet2(key) {
|
|
275842
|
+
if (getSessionCacheLimits2().maxFns <= 0) return void 0;
|
|
275221
275843
|
const k = normalizeFnCacheKey2(key);
|
|
275222
275844
|
const hit = fnAnalysisCache2.get(k);
|
|
275223
275845
|
if (hit !== void 0) {
|
|
@@ -275235,6 +275857,7 @@ function fnAnalysisCacheSet2(key, value) {
|
|
|
275235
275857
|
if (oldest === void 0) break;
|
|
275236
275858
|
fnAnalysisCache2.delete(oldest);
|
|
275237
275859
|
}
|
|
275860
|
+
fnAnalysisCache2.delete(k);
|
|
275238
275861
|
fnAnalysisCache2.set(k, value);
|
|
275239
275862
|
}
|
|
275240
275863
|
function caseDirectiveKey2(directives, formatAbs6) {
|
|
@@ -275399,7 +276022,11 @@ function collectEvalReplacements2(source) {
|
|
|
275399
276022
|
}
|
|
275400
276023
|
};
|
|
275401
276024
|
visitStmts(file.program.body);
|
|
275402
|
-
} catch {
|
|
276025
|
+
} catch (err) {
|
|
276026
|
+
if (targets.length > 0 || asTargets.length > 0) {
|
|
276027
|
+
throw err;
|
|
276028
|
+
}
|
|
276029
|
+
noteEvalFallback(err);
|
|
275403
276030
|
}
|
|
275404
276031
|
return { targets, values, asTargets, asValues };
|
|
275405
276032
|
}
|
|
@@ -275426,6 +276053,7 @@ function evalCacheSet2(filePath, stableSource, mode, envKey, mockKey, depKey, va
|
|
|
275426
276053
|
if (oldest === void 0) break;
|
|
275427
276054
|
evalRunByFile2.delete(oldest);
|
|
275428
276055
|
}
|
|
276056
|
+
evalRunByFile2.delete(key);
|
|
275429
276057
|
evalRunByFile2.set(key, { stableSource, mode, envKey, mockKey, depKey, value });
|
|
275430
276058
|
}
|
|
275431
276059
|
function tryRunEval2(source, filePath, opts = {}) {
|
|
@@ -275436,7 +276064,7 @@ function tryRunEval2(source, filePath, opts = {}) {
|
|
|
275436
276064
|
const stable = stableAnalyzeKeySource(source);
|
|
275437
276065
|
const depKey = evalDepKey2(source, filePath);
|
|
275438
276066
|
const canCache = depKey !== null;
|
|
275439
|
-
if (canCache) {
|
|
276067
|
+
if (canCache && getSessionCacheLimits2().maxEvalRuns > 0) {
|
|
275440
276068
|
const cacheKey = stablePathKey(filePath);
|
|
275441
276069
|
const cached2 = evalRunByFile2.get(cacheKey);
|
|
275442
276070
|
if (cached2 && cached2.stableSource === stable && cached2.mode === mode && cached2.envKey === envKey && cached2.mockKey === mockKey && cached2.depKey === depKey) {
|
|
@@ -275500,7 +276128,7 @@ function tryRunEval2(source, filePath, opts = {}) {
|
|
|
275500
276128
|
function tryEvalCallFull2(source, filePath, fnName, args, opts = {}) {
|
|
275501
276129
|
const run = tryRunEval2(source, filePath, { envNames: opts.envNames, mocks: opts.mocks });
|
|
275502
276130
|
if (!run) return void 0;
|
|
275503
|
-
if (!(
|
|
276131
|
+
if (!Object.hasOwn(run.exports, fnName)) return void 0;
|
|
275504
276132
|
const collected = [];
|
|
275505
276133
|
const memberDiags = [];
|
|
275506
276134
|
const prevCall = opts.collectCalls ? setEvalCallCollector((r) => collected.push(r)) : void 0;
|
|
@@ -275525,7 +276153,14 @@ function tryEvalCall2(source, filePath, fnName, args, opts = {}) {
|
|
|
275525
276153
|
const full = tryEvalCallFull2(source, filePath, fnName, args, opts);
|
|
275526
276154
|
if (!full) return void 0;
|
|
275527
276155
|
const r = full.result;
|
|
275528
|
-
if (!r)
|
|
276156
|
+
if (!isAbsVal(r)) {
|
|
276157
|
+
noteEvalFallback(
|
|
276158
|
+
new Error(
|
|
276159
|
+
`tryEvalCall: '${fnName}' result is not an Abs value (producer contract violation)`
|
|
276160
|
+
)
|
|
276161
|
+
);
|
|
276162
|
+
return void 0;
|
|
276163
|
+
}
|
|
275529
276164
|
if (r.shape.k === "never" && full.throws.shape.k !== "never") {
|
|
275530
276165
|
return void 0;
|
|
275531
276166
|
}
|
|
@@ -275686,7 +276321,7 @@ function absFromSinon2(sinonExpr) {
|
|
|
275686
276321
|
}
|
|
275687
276322
|
return constantMockFn2(unknown);
|
|
275688
276323
|
}
|
|
275689
|
-
function
|
|
276324
|
+
function isAbsVal32(v2) {
|
|
275690
276325
|
return !!v2 && typeof v2 === "object" && "shape" in v2 && "conf" in v2;
|
|
275691
276326
|
}
|
|
275692
276327
|
function loadFromMockBinding2(name, fromPath, fromFile, loadModule) {
|
|
@@ -275718,7 +276353,7 @@ function loadFromMockBinding2(name, fromPath, fromFile, loadModule) {
|
|
|
275718
276353
|
let absVal;
|
|
275719
276354
|
if (val === void 0) {
|
|
275720
276355
|
absVal = undefAbs();
|
|
275721
|
-
} else if (
|
|
276356
|
+
} else if (isAbsVal32(val)) {
|
|
275722
276357
|
absVal = val;
|
|
275723
276358
|
} else if (typeof val === "function") {
|
|
275724
276359
|
const fn2 = val;
|
|
@@ -275979,13 +276614,14 @@ function safeAbsOrUnknown2(a) {
|
|
|
275979
276614
|
}
|
|
275980
276615
|
function callRecordFromAbsCall2(r, impMap) {
|
|
275981
276616
|
const argAbs = r.args.map(safeAbsOrUnknown2);
|
|
275982
|
-
const threw =
|
|
276617
|
+
const threw = r.threw === true;
|
|
276618
|
+
const threwUnknown = r.threw === void 0;
|
|
275983
276619
|
const thrownOrResult = safeAbsOrUnknown2(r.result);
|
|
275984
276620
|
const rec = {
|
|
275985
276621
|
fnName: r.fnName,
|
|
275986
276622
|
argAbs,
|
|
275987
276623
|
resultAbs: threw ? neverAbs2 : thrownOrResult,
|
|
275988
|
-
throwsAbs: threw ? thrownOrResult : neverAbs2,
|
|
276624
|
+
throwsAbs: threw ? thrownOrResult : threwUnknown ? unknown : neverAbs2,
|
|
275989
276625
|
callLoc: r.callLoc
|
|
275990
276626
|
};
|
|
275991
276627
|
const imp = impMap?.get(r.fnName) ?? // `ns.helper` / `Class.method`:先整名,再按首段点号拆命名空间成员
|
|
@@ -276089,19 +276725,23 @@ function collectDeclared2(file) {
|
|
|
276089
276725
|
if (id.type === "Identifier") names2.add(id.name);
|
|
276090
276726
|
if (id.type === "ObjectPattern") {
|
|
276091
276727
|
for (const p of id.properties) {
|
|
276092
|
-
addId(p.value);
|
|
276728
|
+
addId(p.type === "RestElement" ? p.argument : p.value);
|
|
276093
276729
|
}
|
|
276094
276730
|
}
|
|
276095
276731
|
if (id.type === "ArrayPattern") {
|
|
276096
276732
|
for (const el of id.elements) addId(el);
|
|
276097
276733
|
}
|
|
276734
|
+
if (id.type === "AssignmentPattern") addId(id.left);
|
|
276735
|
+
if (id.type === "RestElement") addId(id.argument);
|
|
276098
276736
|
};
|
|
276099
276737
|
const visit2 = (node) => {
|
|
276100
276738
|
if (!node || typeof node !== "object") return;
|
|
276101
276739
|
const o = node;
|
|
276102
276740
|
switch (o.type) {
|
|
276103
276741
|
case "FunctionDeclaration":
|
|
276742
|
+
case "FunctionExpression":
|
|
276104
276743
|
case "ClassDeclaration":
|
|
276744
|
+
case "ClassExpression":
|
|
276105
276745
|
addId(o.id);
|
|
276106
276746
|
break;
|
|
276107
276747
|
case "VariableDeclarator":
|
|
@@ -276146,7 +276786,7 @@ function isStaticStringExpr2(node) {
|
|
|
276146
276786
|
function isFreeUnknown2(name, declared, seen, known) {
|
|
276147
276787
|
return !declared.has(name) && !known.has(name) && !name.startsWith("$") && !seen.has(name);
|
|
276148
276788
|
}
|
|
276149
|
-
function walkBuiltinUnknown2(node, declared, out, seen, known,
|
|
276789
|
+
function walkBuiltinUnknown2(node, declared, out, seen, known, namePosition = false) {
|
|
276150
276790
|
const n = node;
|
|
276151
276791
|
const flag = (idNode, name) => {
|
|
276152
276792
|
if (!isFreeUnknown2(name, declared, seen, known)) return;
|
|
@@ -276168,20 +276808,21 @@ function walkBuiltinUnknown2(node, declared, out, seen, known, parentKey) {
|
|
|
276168
276808
|
} else if (callee?.type === "Identifier") {
|
|
276169
276809
|
flag(n.callee, callee.name);
|
|
276170
276810
|
}
|
|
276171
|
-
} else if (n.type === "Identifier" && typeof n.name === "string" && n.name !== "require" &&
|
|
276811
|
+
} else if (n.type === "Identifier" && typeof n.name === "string" && n.name !== "require" && !namePosition) {
|
|
276172
276812
|
flag(node, n.name);
|
|
276173
276813
|
}
|
|
276174
276814
|
for (const key of Object.keys(n)) {
|
|
276175
276815
|
if (key === "loc" || key === "start" || key === "end") continue;
|
|
276816
|
+
const childIsName = (key === "key" || key === "property") && n.computed !== true || key === "local" || key === "id";
|
|
276176
276817
|
const v2 = n[key];
|
|
276177
276818
|
if (Array.isArray(v2)) {
|
|
276178
276819
|
v2.forEach((x) => {
|
|
276179
276820
|
if (x && typeof x === "object" && "type" in x) {
|
|
276180
|
-
walkBuiltinUnknown2(x, declared, out, seen, known,
|
|
276821
|
+
walkBuiltinUnknown2(x, declared, out, seen, known, childIsName);
|
|
276181
276822
|
}
|
|
276182
276823
|
});
|
|
276183
276824
|
} else if (v2 && typeof v2 === "object" && "type" in v2) {
|
|
276184
|
-
walkBuiltinUnknown2(v2, declared, out, seen, known,
|
|
276825
|
+
walkBuiltinUnknown2(v2, declared, out, seen, known, childIsName);
|
|
276185
276826
|
}
|
|
276186
276827
|
}
|
|
276187
276828
|
}
|
|
@@ -277379,10 +278020,10 @@ function analyzeFile2(filePath, source, activeCases, externalCallRecords, loadMo
|
|
|
277379
278020
|
return cloneAnalysisResult2(result);
|
|
277380
278021
|
}
|
|
277381
278022
|
var MODULE_RESOLVE_EXTS2, ModuleReadError2, neverAbs2, undefAbs4, MAX_RECORD_TYPE_NODES2, ABS_MODULE_CACHE_MAX2, absModuleCache2, ENV_DEPENDENTS_MAX2, ENV_DEPENDENTS_PER_KEY_MAX2, envDependents2, analysisByFile2, fnAnalysisCache2, envHarvestConflictCollector2, evalRunByFile2, KNOWN_GLOBALS2, DEFAULT_CALLSITE_BUDGET3, COLLAPSE_LITERAL_THRESHOLD2;
|
|
277382
|
-
var
|
|
277383
|
-
"../service/dist/chunk-
|
|
278023
|
+
var init_chunk_6GFPZGQS = __esm({
|
|
278024
|
+
"../service/dist/chunk-6GFPZGQS.js"() {
|
|
277384
278025
|
"use strict";
|
|
277385
|
-
|
|
278026
|
+
init_chunk_2RP2Q6LJ();
|
|
277386
278027
|
init_src2();
|
|
277387
278028
|
init_src();
|
|
277388
278029
|
init_src2();
|
|
@@ -277518,12 +278159,14 @@ __export(emit_exports, {
|
|
|
277518
278159
|
insertGeneratedCaseDirectives: () => insertGeneratedCaseDirectives,
|
|
277519
278160
|
interfaceSurface: () => interfaceSurface,
|
|
277520
278161
|
isDraftableEntry: () => isDraftableEntry,
|
|
278162
|
+
matchSidecarFnDecl: () => matchSidecarFnDecl,
|
|
277521
278163
|
materializeAction: () => materializeAction,
|
|
277522
278164
|
projectAbsToSchema: () => projectAbsToSchema,
|
|
277523
278165
|
schemaNodeToZod: () => schemaNodeToZod,
|
|
277524
278166
|
serializeCaseArg: () => serializeCaseArg,
|
|
277525
278167
|
serializeCaseJson: () => serializeCaseJson,
|
|
277526
278168
|
shapeDslFromFields: () => shapeDslFromFields,
|
|
278169
|
+
sidecarBindingFor: () => sidecarBindingFor,
|
|
277527
278170
|
sidecarDraftPath: () => sidecarDraftPath,
|
|
277528
278171
|
stripGeneratedCaseDirectives: () => stripGeneratedCaseDirectives,
|
|
277529
278172
|
titleKindFor: () => titleKindFor,
|
|
@@ -277711,6 +278354,18 @@ function serializeObjectKey(key) {
|
|
|
277711
278354
|
return `"${key}"`;
|
|
277712
278355
|
}
|
|
277713
278356
|
function serializeCaseArg(a) {
|
|
278357
|
+
return serializeCaseArgB(a, new ProjectionBudget());
|
|
278358
|
+
}
|
|
278359
|
+
function serializeCaseArgB(a, budget) {
|
|
278360
|
+
const stop2 = budget.enter(a);
|
|
278361
|
+
if (stop2) return null;
|
|
278362
|
+
try {
|
|
278363
|
+
return serializeCaseArgInner(a, budget);
|
|
278364
|
+
} finally {
|
|
278365
|
+
budget.exit();
|
|
278366
|
+
}
|
|
278367
|
+
}
|
|
278368
|
+
function serializeCaseArgInner(a, budget) {
|
|
277714
278369
|
const s = a.shape;
|
|
277715
278370
|
if (a.term?.op === "lit") {
|
|
277716
278371
|
const v2 = a.term.value;
|
|
@@ -277740,20 +278395,21 @@ function serializeCaseArg(a) {
|
|
|
277740
278395
|
case "sum": {
|
|
277741
278396
|
const parts = [];
|
|
277742
278397
|
for (const member of s.members) {
|
|
277743
|
-
const ser =
|
|
278398
|
+
const ser = serializeCaseArgB(member, budget);
|
|
277744
278399
|
if (ser === null) return null;
|
|
277745
278400
|
parts.push(ser);
|
|
277746
278401
|
}
|
|
277747
278402
|
return `union(${parts.join(", ")})`;
|
|
277748
278403
|
}
|
|
277749
278404
|
case "arr": {
|
|
277750
|
-
const el =
|
|
278405
|
+
const el = serializeCaseArgB(s.element, budget);
|
|
277751
278406
|
return el === null ? null : `array(${el})`;
|
|
277752
278407
|
}
|
|
277753
278408
|
case "tuple": {
|
|
278409
|
+
if (s.rest) return null;
|
|
277754
278410
|
const parts = [];
|
|
277755
278411
|
for (const el of s.elements) {
|
|
277756
|
-
const ser =
|
|
278412
|
+
const ser = serializeCaseArgB(el, budget);
|
|
277757
278413
|
if (ser === null) return null;
|
|
277758
278414
|
parts.push(ser);
|
|
277759
278415
|
}
|
|
@@ -277762,7 +278418,7 @@ function serializeCaseArg(a) {
|
|
|
277762
278418
|
case "obj": {
|
|
277763
278419
|
const parts = [];
|
|
277764
278420
|
for (const [key, slot] of Object.entries(s.slots)) {
|
|
277765
|
-
const vs =
|
|
278421
|
+
const vs = serializeCaseArgB(slot.value, budget);
|
|
277766
278422
|
if (vs === null) return null;
|
|
277767
278423
|
const ks = serializeObjectKey(key);
|
|
277768
278424
|
if (ks === null) return null;
|
|
@@ -278039,6 +278695,17 @@ function unifiedDiff(a, b, path) {
|
|
|
278039
278695
|
}
|
|
278040
278696
|
return out.join("\n") + "\n";
|
|
278041
278697
|
}
|
|
278698
|
+
function exportNameRepr(name) {
|
|
278699
|
+
return JS_EXPORT_NAME.test(name) ? name : JSON.stringify(name);
|
|
278700
|
+
}
|
|
278701
|
+
function directBindingOk(name, taken) {
|
|
278702
|
+
return isJsBindingIdent(name) && !taken(name);
|
|
278703
|
+
}
|
|
278704
|
+
function allocNudoBinding(taken) {
|
|
278705
|
+
let n = 1;
|
|
278706
|
+
while (taken(`_nudo_${n}`)) n++;
|
|
278707
|
+
return `_nudo_${n}`;
|
|
278708
|
+
}
|
|
278042
278709
|
async function emitInterface(filePath, opts) {
|
|
278043
278710
|
const abs2 = resolve23(filePath);
|
|
278044
278711
|
if (isNodeModulesPath(abs2) || isNodeModulesPath(sidecarPathOf(abs2))) {
|
|
@@ -278077,7 +278744,10 @@ async function emitInterface(filePath, opts) {
|
|
|
278077
278744
|
`sidecar '${relative6(process.cwd(), sidecarPath) || sidecarPath}' is not parseable; fix it before emitting`
|
|
278078
278745
|
);
|
|
278079
278746
|
}
|
|
278080
|
-
for (const
|
|
278747
|
+
for (const s of sections) {
|
|
278748
|
+
for (const n of s.names) declared.delete(n);
|
|
278749
|
+
for (const b of s.bindings) declared.delete(b);
|
|
278750
|
+
}
|
|
278081
278751
|
const analysis = await analyzeFileAsync2(
|
|
278082
278752
|
abs2,
|
|
278083
278753
|
source,
|
|
@@ -278090,16 +278760,47 @@ async function emitInterface(filePath, opts) {
|
|
|
278090
278760
|
for (const f of analysis.functions) {
|
|
278091
278761
|
if (!fnByName.has(f.name)) fnByName.set(f.name, f);
|
|
278092
278762
|
}
|
|
278093
|
-
const
|
|
278763
|
+
const identityOfLocal = (local) => exportedNameOfLocal(source, local) ?? local;
|
|
278764
|
+
const localOf = /* @__PURE__ */ new Map();
|
|
278765
|
+
const identityOfFn = /* @__PURE__ */ new Map();
|
|
278766
|
+
for (const f of analysis.functions) {
|
|
278767
|
+
if (identityOfFn.has(f.name)) continue;
|
|
278768
|
+
const identity = identityOfLocal(f.name);
|
|
278769
|
+
identityOfFn.set(f.name, identity);
|
|
278770
|
+
if (!localOf.has(identity)) localOf.set(identity, f.name);
|
|
278771
|
+
}
|
|
278772
|
+
const fileExportOrder = [
|
|
278773
|
+
...new Set(
|
|
278774
|
+
analysis.functions.map((f) => identityOfFn.get(f.name)).filter((n) => exported.has(n))
|
|
278775
|
+
)
|
|
278776
|
+
];
|
|
278094
278777
|
let targetNames;
|
|
278095
278778
|
if (opts.fnNames && opts.fnNames.length > 0) {
|
|
278096
|
-
targetNames = [...new Set(opts.fnNames)];
|
|
278779
|
+
targetNames = [...new Set(opts.fnNames.map((n) => identityOfFn.get(n) ?? n))];
|
|
278097
278780
|
} else if (opts.all) {
|
|
278098
278781
|
targetNames = fileExportOrder;
|
|
278099
278782
|
} else {
|
|
278100
278783
|
targetNames = fileExportOrder.filter((n) => generatedNames.has(n));
|
|
278101
278784
|
}
|
|
278102
278785
|
const targetSet = new Set(targetNames);
|
|
278786
|
+
const takenBindings = /* @__PURE__ */ new Set();
|
|
278787
|
+
const claimFrom = (text) => {
|
|
278788
|
+
for (const n of topLevelDeclaredNames(text) ?? []) takenBindings.add(n);
|
|
278789
|
+
};
|
|
278790
|
+
if (opts.mode === "update") {
|
|
278791
|
+
claimFrom(removeSections(sidecarSrc, sections));
|
|
278792
|
+
for (const s of sections) {
|
|
278793
|
+
if (!s.names.some((n) => targetSet.has(n))) claimFrom(s.text);
|
|
278794
|
+
}
|
|
278795
|
+
} else {
|
|
278796
|
+
claimFrom(sidecarSrc);
|
|
278797
|
+
}
|
|
278798
|
+
const bindingOf = /* @__PURE__ */ new Map();
|
|
278799
|
+
for (const name of targetNames) {
|
|
278800
|
+
const binding = directBindingOk(name, (n) => takenBindings.has(n)) ? name : allocNudoBinding((n) => takenBindings.has(n));
|
|
278801
|
+
takenBindings.add(binding);
|
|
278802
|
+
bindingOf.set(name, binding);
|
|
278803
|
+
}
|
|
278103
278804
|
const written = [];
|
|
278104
278805
|
const skipped = [];
|
|
278105
278806
|
const issues = [];
|
|
@@ -278108,9 +278809,9 @@ async function emitInterface(filePath, opts) {
|
|
|
278108
278809
|
const planFor = (name) => {
|
|
278109
278810
|
const hit = planCache.get(name);
|
|
278110
278811
|
if (hit) return hit;
|
|
278111
|
-
const fn2 = fnByName.get(name);
|
|
278812
|
+
const fn2 = fnByName.get(localOf.get(name) ?? name);
|
|
278112
278813
|
const dsl = fn2 === void 0 ? void 0 : projectFunctionDsl(fn2);
|
|
278113
|
-
const roundTrip = dsl !== void 0 && roundTrips(sectionText(name, dsl, srcRel), name);
|
|
278814
|
+
const roundTrip = dsl !== void 0 && roundTrips(sectionText(name, dsl, srcRel, bindingOf.get(name)), name);
|
|
278114
278815
|
const rec = { dsl, roundTrip };
|
|
278115
278816
|
planCache.set(name, rec);
|
|
278116
278817
|
return rec;
|
|
@@ -278125,7 +278826,7 @@ async function emitInterface(filePath, opts) {
|
|
|
278125
278826
|
}
|
|
278126
278827
|
const acceptedAtomic = /* @__PURE__ */ new Set();
|
|
278127
278828
|
for (const name of targetNames) {
|
|
278128
|
-
if (!exported.has(name) || !fnByName.has(name)) {
|
|
278829
|
+
if (!exported.has(name) || !fnByName.has(localOf.get(name) ?? name)) {
|
|
278129
278830
|
skipped.push({
|
|
278130
278831
|
fn: name,
|
|
278131
278832
|
reason: "not-an-export"
|
|
@@ -278165,7 +278866,7 @@ async function emitInterface(filePath, opts) {
|
|
|
278165
278866
|
}
|
|
278166
278867
|
continue;
|
|
278167
278868
|
}
|
|
278168
|
-
const text = sectionText(name, plan.dsl, srcRel);
|
|
278869
|
+
const text = sectionText(name, plan.dsl, srcRel, bindingOf.get(name));
|
|
278169
278870
|
if (opts.mode === "add" && prev !== void 0) {
|
|
278170
278871
|
skipped.push({ fn: name, reason: "no-change" });
|
|
278171
278872
|
continue;
|
|
@@ -278262,10 +278963,12 @@ function projectFunctionDsl(fn2) {
|
|
|
278262
278963
|
const ret = retConstraint === void 0 ? "" : `, ${formatConstraint(retConstraint)}`;
|
|
278263
278964
|
return `fn({ ${paramParts.join(", ")} }${ret})`;
|
|
278264
278965
|
}
|
|
278265
|
-
function sectionText(fn2, dsl, srcRel) {
|
|
278966
|
+
function sectionText(fn2, dsl, srcRel, binding = fn2) {
|
|
278967
|
+
const decl = binding === fn2 ? `export const ${fn2} = ${dsl};` : `const ${binding} = ${dsl};
|
|
278968
|
+
export { ${binding} as ${exportNameRepr(fn2)} };`;
|
|
278266
278969
|
return `${GENERATED_HEADER}
|
|
278267
278970
|
// source: ${sanitizeCommentText(`${srcRel}:${fn2}`)}
|
|
278268
|
-
|
|
278971
|
+
${decl}
|
|
278269
278972
|
`;
|
|
278270
278973
|
}
|
|
278271
278974
|
function roundTrips(text, fn2) {
|
|
@@ -278288,23 +278991,62 @@ function collectGeneratedSections(sidecarSrc) {
|
|
|
278288
278991
|
} catch {
|
|
278289
278992
|
throw new Error("sidecar is not parseable");
|
|
278290
278993
|
}
|
|
278994
|
+
const stmts = ast.program.body;
|
|
278291
278995
|
const out = [];
|
|
278292
|
-
for (
|
|
278996
|
+
for (let i = 0; i < stmts.length; i++) {
|
|
278997
|
+
const stmt = stmts[i];
|
|
278293
278998
|
if (stmt.type !== "ExportNamedDeclaration" || stmt.source) continue;
|
|
278294
|
-
|
|
278295
|
-
|
|
278999
|
+
if (stmt.end == null) continue;
|
|
279000
|
+
const chain = [];
|
|
279001
|
+
for (let j = i; j >= 0; j--) {
|
|
279002
|
+
const p = stmts[j];
|
|
279003
|
+
if (j !== i && p.type !== "ImportDeclaration" && p.type !== "VariableDeclaration") break;
|
|
279004
|
+
chain.unshift(p);
|
|
279005
|
+
}
|
|
279006
|
+
let blockStart;
|
|
279007
|
+
for (const c of chain) {
|
|
279008
|
+
if (c.start == null) continue;
|
|
279009
|
+
const b = generatedCommentBlockStart(sidecarSrc, c.start);
|
|
279010
|
+
if (b !== void 0) {
|
|
279011
|
+
blockStart = b;
|
|
279012
|
+
break;
|
|
279013
|
+
}
|
|
279014
|
+
}
|
|
279015
|
+
if (blockStart === void 0) continue;
|
|
278296
279016
|
const names2 = [];
|
|
278297
|
-
|
|
278298
|
-
|
|
278299
|
-
|
|
279017
|
+
const bindings = [];
|
|
279018
|
+
const d = stmt.declaration;
|
|
279019
|
+
if (d) {
|
|
279020
|
+
if (d.type === "VariableDeclaration") {
|
|
279021
|
+
for (const decl of d.declarations) {
|
|
279022
|
+
if (decl.id.type === "Identifier") {
|
|
279023
|
+
names2.push(decl.id.name);
|
|
279024
|
+
bindings.push(decl.id.name);
|
|
279025
|
+
}
|
|
279026
|
+
}
|
|
279027
|
+
} else if (d.type === "FunctionDeclaration" || d.type === "ClassDeclaration") {
|
|
279028
|
+
if (d.id) {
|
|
279029
|
+
names2.push(d.id.name);
|
|
279030
|
+
bindings.push(d.id.name);
|
|
279031
|
+
}
|
|
279032
|
+
}
|
|
279033
|
+
} else {
|
|
279034
|
+
for (const spec of stmt.specifiers) {
|
|
279035
|
+
if (spec.type !== "ExportSpecifier") continue;
|
|
279036
|
+
names2.push(
|
|
279037
|
+
spec.exported.type === "Identifier" ? spec.exported.name : spec.exported.value
|
|
279038
|
+
);
|
|
279039
|
+
if (spec.local.type === "Identifier") bindings.push(spec.local.name);
|
|
278300
279040
|
}
|
|
278301
|
-
} else if (d.type === "FunctionDeclaration" || d.type === "ClassDeclaration") {
|
|
278302
|
-
if (d.id) names2.push(d.id.name);
|
|
278303
279041
|
}
|
|
278304
279042
|
if (names2.length === 0) continue;
|
|
278305
|
-
|
|
278306
|
-
|
|
278307
|
-
|
|
279043
|
+
out.push({
|
|
279044
|
+
names: names2,
|
|
279045
|
+
bindings,
|
|
279046
|
+
start: blockStart,
|
|
279047
|
+
end: stmt.end,
|
|
279048
|
+
text: sidecarSrc.slice(blockStart, stmt.end)
|
|
279049
|
+
});
|
|
278308
279050
|
}
|
|
278309
279051
|
return out;
|
|
278310
279052
|
}
|
|
@@ -278495,12 +279237,38 @@ function collectParamBodyReadTypes(source) {
|
|
|
278495
279237
|
const visitFn = (fnName, fnNode, paramNames) => {
|
|
278496
279238
|
if (paramNames.size === 0) return;
|
|
278497
279239
|
const byParam = /* @__PURE__ */ new Map();
|
|
278498
|
-
const add2 = (pname,
|
|
278499
|
-
if (
|
|
278500
|
-
|
|
278501
|
-
if (!
|
|
278502
|
-
|
|
279240
|
+
const add2 = (pname, path, hint) => {
|
|
279241
|
+
if (path.length === 0) return;
|
|
279242
|
+
let m = byParam.get(pname);
|
|
279243
|
+
if (!m) byParam.set(pname, m = /* @__PURE__ */ new Map());
|
|
279244
|
+
const k = JSON.stringify(path);
|
|
279245
|
+
let e = m.get(k);
|
|
279246
|
+
if (!e) m.set(k, e = { path, hints: [] });
|
|
279247
|
+
if (hint) e.hints.push(hint);
|
|
278503
279248
|
};
|
|
279249
|
+
const downChainPath = (mem) => {
|
|
279250
|
+
const keys = [];
|
|
279251
|
+
let cur = mem;
|
|
279252
|
+
let param;
|
|
279253
|
+
while (cur) {
|
|
279254
|
+
if (cur.type !== "MemberExpression" && cur.type !== "OptionalMemberExpression" || cur.computed === true) {
|
|
279255
|
+
return void 0;
|
|
279256
|
+
}
|
|
279257
|
+
const key = keyOf(cur.property);
|
|
279258
|
+
if (key === void 0) return void 0;
|
|
279259
|
+
keys.unshift(key);
|
|
279260
|
+
const obj2 = cur.object;
|
|
279261
|
+
if (!obj2) return void 0;
|
|
279262
|
+
if (obj2.type === "Identifier") {
|
|
279263
|
+
param = obj2.name;
|
|
279264
|
+
break;
|
|
279265
|
+
}
|
|
279266
|
+
cur = obj2;
|
|
279267
|
+
}
|
|
279268
|
+
if (param === void 0) return void 0;
|
|
279269
|
+
return { path: keys, param };
|
|
279270
|
+
};
|
|
279271
|
+
const synthMemberParent = (prop) => ({ type: "MemberExpression", property: { type: "Identifier", name: prop } });
|
|
278504
279272
|
const walk = (node, shadowed, parent, parentKey) => {
|
|
278505
279273
|
if (!node || typeof node !== "object") return;
|
|
278506
279274
|
const n = node;
|
|
@@ -278512,29 +279280,31 @@ function collectParamBodyReadTypes(source) {
|
|
|
278512
279280
|
const arg = n.argument;
|
|
278513
279281
|
const mem = arg;
|
|
278514
279282
|
if (mem && (mem.type === "MemberExpression" || mem.type === "OptionalMemberExpression")) {
|
|
278515
|
-
const
|
|
278516
|
-
|
|
278517
|
-
|
|
278518
|
-
|
|
278519
|
-
const pname = obj2.name;
|
|
278520
|
-
if (key !== void 0) {
|
|
278521
|
-
const gp = parent;
|
|
278522
|
-
add2(pname, key, hintFromTypeof(n, gp));
|
|
278523
|
-
}
|
|
279283
|
+
const chain = downChainPath(mem);
|
|
279284
|
+
if (chain && paramNames.has(chain.param) && !shadowed.has(chain.param)) {
|
|
279285
|
+
const gp = parent;
|
|
279286
|
+
add2(chain.param, chain.path, hintFromTypeof(n, gp));
|
|
278524
279287
|
}
|
|
278525
279288
|
}
|
|
278526
279289
|
}
|
|
278527
279290
|
if (n.type === "MemberExpression" || n.type === "OptionalMemberExpression") {
|
|
278528
|
-
const
|
|
278529
|
-
|
|
278530
|
-
const
|
|
278531
|
-
if (
|
|
278532
|
-
const
|
|
278533
|
-
|
|
278534
|
-
|
|
278535
|
-
|
|
278536
|
-
|
|
279291
|
+
const innerLink = !!parent && (parent.type === "MemberExpression" || parent.type === "OptionalMemberExpression") && parentKey === "object" && parent.computed !== true;
|
|
279292
|
+
if (innerLink) return;
|
|
279293
|
+
const chain = downChainPath(n);
|
|
279294
|
+
if (chain && paramNames.has(chain.param) && !shadowed.has(chain.param)) {
|
|
279295
|
+
const rev = chain.path;
|
|
279296
|
+
let leafLen = rev.length;
|
|
279297
|
+
let leafHint;
|
|
279298
|
+
for (let i = 0; i < rev.length; i++) {
|
|
279299
|
+
const nextProp = i + 1 < rev.length ? rev[i + 1] : void 0;
|
|
279300
|
+
const h = nextProp !== void 0 ? hintFromUse(synthMemberParent(nextProp), "object") : hintFromUse(parent, parentKey ?? "object");
|
|
279301
|
+
if (h) {
|
|
279302
|
+
leafLen = i + 1;
|
|
279303
|
+
leafHint = h;
|
|
279304
|
+
break;
|
|
279305
|
+
}
|
|
278537
279306
|
}
|
|
279307
|
+
add2(chain.param, rev.slice(0, leafLen), leafHint);
|
|
278538
279308
|
}
|
|
278539
279309
|
}
|
|
278540
279310
|
for (const k of Object.keys(n)) {
|
|
@@ -278550,13 +279320,20 @@ function collectParamBodyReadTypes(source) {
|
|
|
278550
279320
|
walk(fnNode, /* @__PURE__ */ new Set());
|
|
278551
279321
|
if (byParam.size === 0) return;
|
|
278552
279322
|
const fieldsOf = /* @__PURE__ */ new Map();
|
|
278553
|
-
for (const [pname,
|
|
278554
|
-
const
|
|
278555
|
-
for (const
|
|
278556
|
-
|
|
279323
|
+
for (const [pname, pathMap] of byParam) {
|
|
279324
|
+
const root = { hints: [], children: /* @__PURE__ */ new Map() };
|
|
279325
|
+
for (const { path, hints } of pathMap.values()) {
|
|
279326
|
+
let node = root;
|
|
279327
|
+
for (const seg of path) {
|
|
279328
|
+
let child = node.children.get(seg);
|
|
279329
|
+
if (!child) {
|
|
279330
|
+
node.children.set(seg, child = { hints: [], children: /* @__PURE__ */ new Map() });
|
|
279331
|
+
}
|
|
279332
|
+
node = child;
|
|
279333
|
+
}
|
|
279334
|
+
node.hints.push(...hints);
|
|
278557
279335
|
}
|
|
278558
|
-
|
|
278559
|
-
fieldsOf.set(pname, list);
|
|
279336
|
+
fieldsOf.set(pname, emitFields(root));
|
|
278560
279337
|
}
|
|
278561
279338
|
out.set(fnName, fieldsOf);
|
|
278562
279339
|
};
|
|
@@ -278635,6 +279412,24 @@ function collectParamBodyReadTypes(source) {
|
|
|
278635
279412
|
}
|
|
278636
279413
|
return out;
|
|
278637
279414
|
}
|
|
279415
|
+
function emitFields(trie) {
|
|
279416
|
+
const list = [];
|
|
279417
|
+
for (const [name, child] of [...trie.children.entries()].sort(
|
|
279418
|
+
(a, b) => a[0] < b[0] ? -1 : 1
|
|
279419
|
+
)) {
|
|
279420
|
+
if (child.children.size > 0) {
|
|
279421
|
+
list.push({
|
|
279422
|
+
field: name,
|
|
279423
|
+
type: "shape({ \u2026 })",
|
|
279424
|
+
via: "dereferenced member read (nested shape)",
|
|
279425
|
+
fields: emitFields(child)
|
|
279426
|
+
});
|
|
279427
|
+
} else {
|
|
279428
|
+
list.push({ field: name, ...mergeHints(child.hints) });
|
|
279429
|
+
}
|
|
279430
|
+
}
|
|
279431
|
+
return list;
|
|
279432
|
+
}
|
|
278638
279433
|
function mergeHints(hints) {
|
|
278639
279434
|
if (hints.length === 0) return { type: "any()", via: "read (no type evidence)" };
|
|
278640
279435
|
const types2 = [...new Set(hints.map((h) => h.type))];
|
|
@@ -278677,7 +279472,9 @@ function bodyReadFieldsFor(map, fnName, paramName2) {
|
|
|
278677
279472
|
}
|
|
278678
279473
|
function shapeDslFromFields(fields) {
|
|
278679
279474
|
if (fields.length === 0) return "shape({})";
|
|
278680
|
-
const parts = fields.map(
|
|
279475
|
+
const parts = fields.map(
|
|
279476
|
+
(f) => f.fields && f.fields.length > 0 ? `${f.field}: ${shapeDslFromFields(f.fields)}` : `${f.field}: ${f.type}`
|
|
279477
|
+
);
|
|
278681
279478
|
return `shape({ ${parts.join(", ")} })`;
|
|
278682
279479
|
}
|
|
278683
279480
|
function collectParamBodyAccesses(source) {
|
|
@@ -279042,8 +279839,8 @@ function toDraftBuilderDsl(display) {
|
|
|
279042
279839
|
}
|
|
279043
279840
|
);
|
|
279044
279841
|
}
|
|
279045
|
-
function draftExportName2(fnName) {
|
|
279046
|
-
return fnName.includes(".") ? fnName.replace(/\./g, "_") : fnName;
|
|
279842
|
+
function draftExportName2(fnName, used) {
|
|
279843
|
+
return toJsBindingIdent(fnName.includes(".") ? fnName.replace(/\./g, "_") : fnName, used);
|
|
279047
279844
|
}
|
|
279048
279845
|
function draftDsl(entry) {
|
|
279049
279846
|
const parts = entry.params.filter((p) => p.projected && p.constraint !== void 0).map((p) => {
|
|
@@ -279158,6 +279955,7 @@ ${suggestedBodyDsl(e.fn, e.params) ?? ""}`;
|
|
|
279158
279955
|
}
|
|
279159
279956
|
}
|
|
279160
279957
|
const importList = BUILDERS2.filter((b) => used.has(b)).join(", ");
|
|
279958
|
+
const exportUsed = /* @__PURE__ */ new Set();
|
|
279161
279959
|
const lines = [
|
|
279162
279960
|
"// @nudo:draft",
|
|
279163
279961
|
`// Generated by \`nudo contract --draft\` from ${sanitizeCommentText(filePath)}`,
|
|
@@ -279196,7 +279994,7 @@ ${suggestedBodyDsl(e.fn, e.params) ?? ""}`;
|
|
|
279196
279994
|
} else if (e.returnEvidence === "symbolic") {
|
|
279197
279995
|
lines.push(`// returns: ${sanitizeCommentText(e.returns?.display ?? "")} (symbolic)`);
|
|
279198
279996
|
}
|
|
279199
|
-
lines.push(`export const ${draftExportName2(e.fn)} = ${e.dsl};`);
|
|
279997
|
+
lines.push(`export const ${draftExportName2(e.fn, exportUsed)} = ${e.dsl};`);
|
|
279200
279998
|
if (e.fn.includes(".")) {
|
|
279201
279999
|
lines.push(
|
|
279202
280000
|
`// sidecar key may also be written as \`${sanitizeCommentText(e.fn)}\` / nested { ${sanitizeCommentText(e.fn.split(".")[1] ?? "")}: \u2026 }`
|
|
@@ -279875,7 +280673,8 @@ function formatDerivedSection(row, opts) {
|
|
|
279875
280673
|
retDsl = `, ${row.returns.dsl}`;
|
|
279876
280674
|
}
|
|
279877
280675
|
const namer = new NameAllocator(opts.takenNames);
|
|
279878
|
-
|
|
280676
|
+
const directBinding = directBindingOk(row.fn, (n) => namer.has(n));
|
|
280677
|
+
const binding = directBinding ? namer.claim(row.fn) : namer.claim(allocNudoBinding((n) => namer.has(n)));
|
|
279879
280678
|
const renames = /* @__PURE__ */ new Map();
|
|
279880
280679
|
const importLocals = [];
|
|
279881
280680
|
for (const [name, from] of [...importMap.entries()].sort((a, b) => a[0].localeCompare(b[0]))) {
|
|
@@ -279906,11 +280705,13 @@ function formatDerivedSection(row, opts) {
|
|
|
279906
280705
|
const spec = original === local ? local : `${original} as ${local}`;
|
|
279907
280706
|
return `import { ${spec} } from ${JSON.stringify(from)};`;
|
|
279908
280707
|
}).sort((a, b) => a.localeCompare(b));
|
|
280708
|
+
const exportStmt = directBinding ? `export const ${binding} = fn({ ${paramParts.join(", ")} }${retPart});` : `const ${binding} = fn({ ${paramParts.join(", ")} }${retPart});
|
|
280709
|
+
export { ${binding} as ${exportNameRepr(row.fn)} };`;
|
|
279909
280710
|
const lines = [
|
|
279910
280711
|
...importLineTexts,
|
|
279911
280712
|
...importLineTexts.length > 0 && renamedPreludes.length > 0 ? [""] : [],
|
|
279912
280713
|
...renamedPreludes,
|
|
279913
|
-
|
|
280714
|
+
exportStmt
|
|
279914
280715
|
];
|
|
279915
280716
|
const usedNames = /* @__PURE__ */ new Set();
|
|
279916
280717
|
for (const { local } of importLocals) usedNames.add(local);
|
|
@@ -279918,7 +280719,7 @@ function formatDerivedSection(row, opts) {
|
|
|
279918
280719
|
const n = preludeLocalName(line);
|
|
279919
280720
|
if (n) usedNames.add(n);
|
|
279920
280721
|
}
|
|
279921
|
-
usedNames.add(
|
|
280722
|
+
usedNames.add(binding);
|
|
279922
280723
|
return { text: lines.join("\n"), usedNames: [...usedNames] };
|
|
279923
280724
|
}
|
|
279924
280725
|
function collectTopLevelNames(src) {
|
|
@@ -280168,18 +280969,35 @@ function collectGeneratedSectionsRaw(src) {
|
|
|
280168
280969
|
if (stmt.type !== "ExportNamedDeclaration" || stmt.source) continue;
|
|
280169
280970
|
if (stmt.start == null || stmt.end == null || stmt.start < headerPos) continue;
|
|
280170
280971
|
const d = stmt.declaration;
|
|
280171
|
-
if (!d) continue;
|
|
280172
280972
|
const names2 = [];
|
|
280173
|
-
|
|
280174
|
-
|
|
280175
|
-
|
|
280973
|
+
const bindings = [];
|
|
280974
|
+
if (d) {
|
|
280975
|
+
if (d.type === "VariableDeclaration") {
|
|
280976
|
+
for (const decl of d.declarations) {
|
|
280977
|
+
if (decl.id.type === "Identifier") {
|
|
280978
|
+
names2.push(decl.id.name);
|
|
280979
|
+
bindings.push(decl.id.name);
|
|
280980
|
+
}
|
|
280981
|
+
}
|
|
280982
|
+
} else if (d.type === "FunctionDeclaration" || d.type === "ClassDeclaration") {
|
|
280983
|
+
if (d.id) {
|
|
280984
|
+
names2.push(d.id.name);
|
|
280985
|
+
bindings.push(d.id.name);
|
|
280986
|
+
}
|
|
280987
|
+
}
|
|
280988
|
+
} else {
|
|
280989
|
+
for (const spec of stmt.specifiers) {
|
|
280990
|
+
if (spec.type !== "ExportSpecifier") continue;
|
|
280991
|
+
names2.push(
|
|
280992
|
+
spec.exported.type === "Identifier" ? spec.exported.name : spec.exported.value
|
|
280993
|
+
);
|
|
280994
|
+
if (spec.local.type === "Identifier") bindings.push(spec.local.name);
|
|
280176
280995
|
}
|
|
280177
|
-
} else if (d.type === "FunctionDeclaration" || d.type === "ClassDeclaration") {
|
|
280178
|
-
if (d.id) names2.push(d.id.name);
|
|
280179
280996
|
}
|
|
280180
280997
|
if (names2.length === 0) continue;
|
|
280181
280998
|
out.push({
|
|
280182
280999
|
names: names2,
|
|
281000
|
+
bindings,
|
|
280183
281001
|
start: headerPos,
|
|
280184
281002
|
end: stmt.end,
|
|
280185
281003
|
text: src.slice(headerPos, stmt.end)
|
|
@@ -280201,9 +281019,6 @@ function findGeneratedHeaderOffsets(src) {
|
|
|
280201
281019
|
}
|
|
280202
281020
|
return out;
|
|
280203
281021
|
}
|
|
280204
|
-
function generatedSectionNames(src) {
|
|
280205
|
-
return new Set(collectGeneratedSectionsRaw(src).flatMap((s) => s.names));
|
|
280206
|
-
}
|
|
280207
281022
|
function handwrittenNames(src) {
|
|
280208
281023
|
if (src.trim() === "") return /* @__PURE__ */ new Set();
|
|
280209
281024
|
let ast;
|
|
@@ -280236,7 +281051,10 @@ function handwrittenNames(src) {
|
|
|
280236
281051
|
collect(stmt);
|
|
280237
281052
|
}
|
|
280238
281053
|
}
|
|
280239
|
-
for (const
|
|
281054
|
+
for (const s of collectGeneratedSectionsRaw(src)) {
|
|
281055
|
+
for (const n of s.names) names2.delete(n);
|
|
281056
|
+
for (const b of s.bindings) names2.delete(b);
|
|
281057
|
+
}
|
|
280240
281058
|
return names2;
|
|
280241
281059
|
}
|
|
280242
281060
|
function findGeneratedSectionText(src, fn2) {
|
|
@@ -280289,32 +281107,53 @@ function tsTypeParamName(id) {
|
|
|
280289
281107
|
if (n.length === 0) n = "T";
|
|
280290
281108
|
return n;
|
|
280291
281109
|
}
|
|
280292
|
-
function wrapComplexAbs(a, typeVars) {
|
|
280293
|
-
const ts3 =
|
|
281110
|
+
function wrapComplexAbs(a, typeVars, budget) {
|
|
281111
|
+
const ts3 = absToTSTypeB(a, typeVars, budget);
|
|
280294
281112
|
if (a.shape.k === "sum" || a.shape.k === "fn") return `(${ts3})`;
|
|
280295
281113
|
return ts3;
|
|
280296
281114
|
}
|
|
280297
|
-
function wrapUnionMember(a, typeVars) {
|
|
280298
|
-
const ts3 =
|
|
281115
|
+
function wrapUnionMember(a, typeVars, budget) {
|
|
281116
|
+
const ts3 = absToTSTypeB(a, typeVars, budget);
|
|
280299
281117
|
if (a.shape.k === "fn") return `(${ts3})`;
|
|
280300
281118
|
return ts3;
|
|
280301
281119
|
}
|
|
280302
|
-
function
|
|
280303
|
-
|
|
281120
|
+
function tsTplSafe(ts3) {
|
|
281121
|
+
if (ts3 === TS_TRUNC.cycle) return TS_TRUNC.cycleTpl;
|
|
281122
|
+
if (ts3 === TS_TRUNC.depth) return TS_TRUNC.depthTpl;
|
|
281123
|
+
return ts3;
|
|
280304
281124
|
}
|
|
280305
281125
|
function sanitizeParamName(name, index2) {
|
|
280306
|
-
|
|
280307
|
-
|
|
280308
|
-
|
|
281126
|
+
let optional = false;
|
|
281127
|
+
let base = name;
|
|
281128
|
+
if (base.endsWith("?")) {
|
|
281129
|
+
optional = true;
|
|
281130
|
+
base = base.slice(0, -1);
|
|
281131
|
+
}
|
|
281132
|
+
if (base.startsWith("...")) {
|
|
281133
|
+
const rest = base.slice(3);
|
|
281134
|
+
if (isJsBindingIdent(rest)) return `...${rest}${optional ? "?" : ""}`;
|
|
280309
281135
|
return `...arg${index2}`;
|
|
280310
281136
|
}
|
|
280311
|
-
if (
|
|
281137
|
+
if (isJsBindingIdent(base)) return `${base}${optional ? "?" : ""}`;
|
|
280312
281138
|
return `arg${index2}`;
|
|
280313
281139
|
}
|
|
280314
281140
|
function formatPropKey(k) {
|
|
280315
281141
|
return formatObjectKey(k);
|
|
280316
281142
|
}
|
|
280317
281143
|
function absToTSType(a, typeVars) {
|
|
281144
|
+
return absToTSTypeB(a, typeVars, new ProjectionBudget());
|
|
281145
|
+
}
|
|
281146
|
+
function absToTSTypeB(a, typeVars, budget) {
|
|
281147
|
+
const stop2 = budget.enter(a);
|
|
281148
|
+
if (stop2 === "cycle") return TS_TRUNC.cycle;
|
|
281149
|
+
if (stop2 === "depth") return TS_TRUNC.depth;
|
|
281150
|
+
try {
|
|
281151
|
+
return absToTSTypeInner(a, typeVars, budget);
|
|
281152
|
+
} finally {
|
|
281153
|
+
budget.exit();
|
|
281154
|
+
}
|
|
281155
|
+
}
|
|
281156
|
+
function absToTSTypeInner(a, typeVars, budget) {
|
|
280318
281157
|
if (a.shape.k === "any" && a.term?.op === "var" && typeVars) {
|
|
280319
281158
|
const mapped = typeVars.get(a.term.id);
|
|
280320
281159
|
if (mapped) return mapped;
|
|
@@ -280342,7 +281181,7 @@ function absToTSType(a, typeVars) {
|
|
|
280342
281181
|
const lvR = litValue(p);
|
|
280343
281182
|
const lv = lvR.ok ? lvR.value : void 0;
|
|
280344
281183
|
if (typeof lv === "string") return escapeTemplateTypeFixed(lv);
|
|
280345
|
-
return `\${${
|
|
281184
|
+
return `\${${tsTplSafe(absToTSTypeB(p, typeVars, budget))}}`;
|
|
280346
281185
|
}).join("");
|
|
280347
281186
|
return `\`${inner}\``;
|
|
280348
281187
|
}
|
|
@@ -280356,9 +281195,9 @@ function absToTSType(a, typeVars) {
|
|
|
280356
281195
|
return a.shape.type;
|
|
280357
281196
|
case "obj": {
|
|
280358
281197
|
const entries = Object.entries(a.shape.slots).map(([k, slot]) => {
|
|
280359
|
-
const inner =
|
|
281198
|
+
const inner = absToTSTypeB(slot.value, typeVars, budget);
|
|
280360
281199
|
if (slot.optional) {
|
|
280361
|
-
const t = wrapComplexAbs(slot.value, typeVars);
|
|
281200
|
+
const t = wrapComplexAbs(slot.value, typeVars, budget);
|
|
280362
281201
|
return `${formatPropKey(k)}: ${t} | undefined`;
|
|
280363
281202
|
}
|
|
280364
281203
|
return `${formatPropKey(k)}: ${inner}`;
|
|
@@ -280367,16 +281206,16 @@ function absToTSType(a, typeVars) {
|
|
|
280367
281206
|
return `{ ${entries.join("; ")} }`;
|
|
280368
281207
|
}
|
|
280369
281208
|
case "arr":
|
|
280370
|
-
return `${wrapComplexAbs(a.shape.element, typeVars)}[]`;
|
|
281209
|
+
return `${wrapComplexAbs(a.shape.element, typeVars, budget)}[]`;
|
|
280371
281210
|
case "tuple": {
|
|
280372
281211
|
const holes = a.shape.holes ?? [];
|
|
280373
281212
|
const parts = a.shape.elements.map((e, i) => {
|
|
280374
|
-
const ts3 =
|
|
281213
|
+
const ts3 = absToTSTypeB(e, typeVars, budget);
|
|
280375
281214
|
return holes.includes(i) ? `hole: ${ts3}` : ts3;
|
|
280376
281215
|
});
|
|
280377
281216
|
if (a.shape.rest) {
|
|
280378
281217
|
const rest = a.shape.rest;
|
|
280379
|
-
const restTs = rest.shape.k === "arr" ?
|
|
281218
|
+
const restTs = rest.shape.k === "arr" ? absToTSTypeB(rest, typeVars, budget) : `${wrapComplexAbs(rest, typeVars, budget)}[]`;
|
|
280380
281219
|
parts.push(`...${restTs}`);
|
|
280381
281220
|
}
|
|
280382
281221
|
return `[${parts.join(", ")}]`;
|
|
@@ -280388,22 +281227,27 @@ function absToTSType(a, typeVars) {
|
|
|
280388
281227
|
const name = sanitizeParamName(p, i);
|
|
280389
281228
|
const pt = paramTypes?.[i];
|
|
280390
281229
|
let typeStr;
|
|
280391
|
-
if (pt)
|
|
280392
|
-
|
|
281230
|
+
if (pt) {
|
|
281231
|
+
if (isRest) {
|
|
281232
|
+
typeStr = pt.shape.k === "arr" ? absToTSTypeB(pt, typeVars, budget) : `${wrapComplexAbs(pt, typeVars, budget)}[]`;
|
|
281233
|
+
} else {
|
|
281234
|
+
typeStr = absToTSTypeB(pt, typeVars, budget);
|
|
281235
|
+
}
|
|
281236
|
+
} else if (isRest) typeStr = "unknown[]";
|
|
280393
281237
|
else typeStr = "unknown";
|
|
280394
281238
|
return `${name}: ${typeStr}`;
|
|
280395
281239
|
}).join(", ");
|
|
280396
|
-
const ret = a.shape.returnType ?
|
|
281240
|
+
const ret = a.shape.returnType ? absToTSTypeB(a.shape.returnType, typeVars, budget) : "unknown";
|
|
280397
281241
|
return `(${params}) => ${ret}`;
|
|
280398
281242
|
}
|
|
280399
281243
|
case "brand":
|
|
280400
|
-
return
|
|
281244
|
+
return isJsBindingIdent(a.shape.name) || /^[A-Z][A-Za-z0-9_$]*$/.test(a.shape.name) ? a.shape.name : "unknown";
|
|
280401
281245
|
case "eff":
|
|
280402
281246
|
if (a.shape.eff === "promise")
|
|
280403
|
-
return `Promise<${
|
|
280404
|
-
return
|
|
281247
|
+
return `Promise<${absToTSTypeB(a.shape.inner, typeVars, budget)}>`;
|
|
281248
|
+
return absToTSTypeB(a.shape.inner, typeVars, budget);
|
|
280405
281249
|
case "sum": {
|
|
280406
|
-
const parts = a.shape.members.map((m) => wrapUnionMember(m, typeVars)).filter((p) => p !== "never");
|
|
281250
|
+
const parts = a.shape.members.map((m) => wrapUnionMember(m, typeVars, budget)).filter((p) => p !== "never");
|
|
280407
281251
|
const uniq = [...new Set(parts)];
|
|
280408
281252
|
if (uniq.length === 0) return "never";
|
|
280409
281253
|
if (uniq.length === 1) return uniq[0];
|
|
@@ -280419,32 +281263,47 @@ function caseArgAbs(c, i) {
|
|
|
280419
281263
|
function caseResultAbs(c) {
|
|
280420
281264
|
return c.abs;
|
|
280421
281265
|
}
|
|
280422
|
-
function widenParamAbs(a) {
|
|
281266
|
+
function widenParamAbs(a, budget = new ProjectionBudget()) {
|
|
281267
|
+
const stop2 = budget.enter(a);
|
|
281268
|
+
if (stop2) return a;
|
|
281269
|
+
try {
|
|
281270
|
+
return widenParamAbsInner(a, budget);
|
|
281271
|
+
} finally {
|
|
281272
|
+
budget.exit();
|
|
281273
|
+
}
|
|
281274
|
+
}
|
|
281275
|
+
function widenParamAbsInner(a, budget) {
|
|
280423
281276
|
const s = a.shape;
|
|
280424
281277
|
switch (s.k) {
|
|
280425
281278
|
case "prim":
|
|
280426
281279
|
return abs(s, void 0, void 0, "exact");
|
|
280427
281280
|
case "tuple": {
|
|
280428
|
-
const widened = s.elements.map(widenParamAbs);
|
|
281281
|
+
const widened = s.elements.map((el) => widenParamAbs(el, budget));
|
|
281282
|
+
const widenedRest = s.rest ? widenParamAbs(s.rest, budget) : void 0;
|
|
280429
281283
|
const holes = s.holes;
|
|
280430
281284
|
const first = widened[0];
|
|
280431
|
-
if (!holes?.length && first && widened.length > 0 && widened.every((el) => absToTSType(el) === absToTSType(first))) {
|
|
281285
|
+
if (!holes?.length && first && widened.length > 0 && widened.every((el) => absToTSType(el) === absToTSType(first)) && (!widenedRest || absToTSType(widenedRest) === absToTSType(first))) {
|
|
280432
281286
|
return abs({ k: "arr", element: first }, void 0, void 0, "exact");
|
|
280433
281287
|
}
|
|
280434
281288
|
return abs(
|
|
280435
|
-
{
|
|
281289
|
+
{
|
|
281290
|
+
k: "tuple",
|
|
281291
|
+
elements: widened,
|
|
281292
|
+
...widenedRest ? { rest: widenedRest } : {},
|
|
281293
|
+
...holes?.length ? { holes: [...holes] } : {}
|
|
281294
|
+
},
|
|
280436
281295
|
void 0,
|
|
280437
281296
|
void 0,
|
|
280438
281297
|
"exact"
|
|
280439
281298
|
);
|
|
280440
281299
|
}
|
|
280441
281300
|
case "arr":
|
|
280442
|
-
return abs({ k: "arr", element: widenParamAbs(s.element) }, void 0, void 0, "exact");
|
|
281301
|
+
return abs({ k: "arr", element: widenParamAbs(s.element, budget) }, void 0, void 0, "exact");
|
|
280443
281302
|
case "obj": {
|
|
280444
281303
|
const slots = {};
|
|
280445
281304
|
for (const [k, slot] of Object.entries(s.slots)) {
|
|
280446
281305
|
slots[k] = {
|
|
280447
|
-
value: widenParamAbs(slot.value),
|
|
281306
|
+
value: widenParamAbs(slot.value, budget),
|
|
280448
281307
|
...slot.optional ? { optional: true } : {}
|
|
280449
281308
|
};
|
|
280450
281309
|
}
|
|
@@ -280452,21 +281311,21 @@ function widenParamAbs(a) {
|
|
|
280452
281311
|
}
|
|
280453
281312
|
case "eff":
|
|
280454
281313
|
return abs(
|
|
280455
|
-
{ k: "eff", eff: s.eff, inner: widenParamAbs(s.inner) },
|
|
281314
|
+
{ k: "eff", eff: s.eff, inner: widenParamAbs(s.inner, budget) },
|
|
280456
281315
|
void 0,
|
|
280457
281316
|
void 0,
|
|
280458
281317
|
"exact"
|
|
280459
281318
|
);
|
|
280460
281319
|
case "brand":
|
|
280461
281320
|
return abs(
|
|
280462
|
-
{ k: "brand", name: s.name, shape: widenParamAbs(s.shape) },
|
|
281321
|
+
{ k: "brand", name: s.name, shape: widenParamAbs(s.shape, budget) },
|
|
280463
281322
|
void 0,
|
|
280464
281323
|
void 0,
|
|
280465
281324
|
"exact"
|
|
280466
281325
|
);
|
|
280467
281326
|
case "sum":
|
|
280468
281327
|
return abs(
|
|
280469
|
-
{ k: "sum", members: s.members.map(widenParamAbs) },
|
|
281328
|
+
{ k: "sum", members: s.members.map((m) => widenParamAbs(m, budget)) },
|
|
280470
281329
|
void 0,
|
|
280471
281330
|
void 0,
|
|
280472
281331
|
"exact"
|
|
@@ -280543,7 +281402,7 @@ function computeMainSignature(fn2) {
|
|
|
280543
281402
|
let name = getParamName(fn2, i);
|
|
280544
281403
|
const isRest = name.startsWith("...");
|
|
280545
281404
|
const bare = isRest ? name.slice(3) : name;
|
|
280546
|
-
if (!
|
|
281405
|
+
if (!isJsBindingIdent(bare)) {
|
|
280547
281406
|
name = isRest ? `...arg${i}` : `arg${i}`;
|
|
280548
281407
|
}
|
|
280549
281408
|
if (usedNames.has(name)) {
|
|
@@ -280616,7 +281475,7 @@ function computeHofSignature(fn2) {
|
|
|
280616
281475
|
const typeParams = [];
|
|
280617
281476
|
for (const id of [...free].sort()) {
|
|
280618
281477
|
let n = tsTypeParamName(id);
|
|
280619
|
-
if (used.has(n) ||
|
|
281478
|
+
if (used.has(n) || !isJsBindingIdent(n)) {
|
|
280620
281479
|
let i = 2;
|
|
280621
281480
|
while (used.has(`${n}${i}`)) i++;
|
|
280622
281481
|
n = `${n}${i}`;
|
|
@@ -280745,6 +281604,7 @@ function numericBound2(p, self, allowSelfVar) {
|
|
|
280745
281604
|
const nR = litOf(p.b);
|
|
280746
281605
|
const n = nR.ok ? nR.value : void 0;
|
|
280747
281606
|
if (typeof n !== "number") return "drop";
|
|
281607
|
+
if (!Number.isFinite(n)) return "drop";
|
|
280748
281608
|
if (p.a.op === "app" && p.a.fn === "length") return "skip";
|
|
280749
281609
|
if (allowSelfVar && isSelfVar2(p.a, self)) return { op: p.op, n };
|
|
280750
281610
|
if (p.a.op === "app" && (p.a.fn === "get" || p.a.fn === "length")) return "skip";
|
|
@@ -280757,6 +281617,7 @@ function lengthBound3(p, self) {
|
|
|
280757
281617
|
const nR = litOf(p.b);
|
|
280758
281618
|
const n = nR.ok ? nR.value : void 0;
|
|
280759
281619
|
if (typeof n !== "number") return void 0;
|
|
281620
|
+
if (!Number.isFinite(n)) return void 0;
|
|
280760
281621
|
if (p.op === "ge") return { dir: "min", n: Math.ceil(n) };
|
|
280761
281622
|
if (p.op === "gt") return { dir: "min", n: Math.floor(n) + 1 };
|
|
280762
281623
|
if (p.op === "le") return { dir: "max", n: Math.floor(n) };
|
|
@@ -280817,7 +281678,7 @@ function refinementsFromPreds(preds, opts) {
|
|
|
280817
281678
|
}
|
|
280818
281679
|
dropped.push(`pred not projected: ${predToString(p)}`);
|
|
280819
281680
|
}
|
|
280820
|
-
return { refinements, ...
|
|
281681
|
+
return { refinements, ...hasEqLit ? { eqLit } : {}, hasEqLit, dropped };
|
|
280821
281682
|
}
|
|
280822
281683
|
function constraintToSchemaNode(c) {
|
|
280823
281684
|
if (c.fn) return { k: "fn" };
|
|
@@ -280839,11 +281700,11 @@ function constraintToSchemaNode(c) {
|
|
|
280839
281700
|
}
|
|
280840
281701
|
const preds = c.preds ?? [];
|
|
280841
281702
|
const kind = c.prim === "number" ? "number" : c.prim === "string" ? "string" : c.prim === "boolean" ? "boolean" : c.prim ? "other" : "other";
|
|
280842
|
-
const { refinements, eqLit, dropped } = refinementsFromPreds(preds, {
|
|
281703
|
+
const { refinements, eqLit, hasEqLit, dropped } = refinementsFromPreds(preds, {
|
|
280843
281704
|
kind
|
|
280844
281705
|
// constraint 路径:absToConstraint 已把 self 改写成 __nudo_self__
|
|
280845
281706
|
});
|
|
280846
|
-
if (
|
|
281707
|
+
if (hasEqLit && (kind === "number" || kind === "string" || kind === "boolean" || !c.prim)) {
|
|
280847
281708
|
return { k: "lit", value: eqLit };
|
|
280848
281709
|
}
|
|
280849
281710
|
if (isIntFlag(c) && !refinements.some((r) => r.kind === "int")) {
|
|
@@ -280876,17 +281737,18 @@ function constraintDropped(c, prefix2 = "") {
|
|
|
280876
281737
|
}
|
|
280877
281738
|
if (n.fn) return;
|
|
280878
281739
|
const kind = n.prim === "number" ? "number" : n.prim === "string" ? "string" : n.prim === "boolean" ? "boolean" : "other";
|
|
280879
|
-
const {
|
|
281740
|
+
const { dropped } = refinementsFromPreds(n.preds ?? [], {
|
|
280880
281741
|
kind
|
|
280881
281742
|
});
|
|
280882
281743
|
for (const d of dropped) out.push(path ? `${path}: ${d}` : d);
|
|
280883
|
-
if (eqLit === void 0 && n.preds?.some((p) => p.op === "eq") && !isIntFlag(n)) {
|
|
280884
|
-
}
|
|
280885
281744
|
};
|
|
280886
281745
|
visit2(c, prefix2);
|
|
280887
281746
|
return out;
|
|
280888
281747
|
}
|
|
280889
281748
|
function absToSchemaNode(a) {
|
|
281749
|
+
return absToSchemaNodeB(a, new ProjectionBudget());
|
|
281750
|
+
}
|
|
281751
|
+
function absToSchemaNodeB(a, budget) {
|
|
280890
281752
|
const dropped = [];
|
|
280891
281753
|
if (a.term?.op === "lit") {
|
|
280892
281754
|
const v2 = a.term.value;
|
|
@@ -280901,7 +281763,7 @@ function absToSchemaNode(a) {
|
|
|
280901
281763
|
}
|
|
280902
281764
|
const conf = a.conf;
|
|
280903
281765
|
const lowConf = conf !== "exact" && conf !== "path";
|
|
280904
|
-
const projected = absToConstraint(a);
|
|
281766
|
+
const projected = absToConstraint(a, budget);
|
|
280905
281767
|
if (projected) {
|
|
280906
281768
|
const node = constraintToSchemaNode(projected);
|
|
280907
281769
|
dropped.push(...constraintDropped(projected));
|
|
@@ -280910,6 +281772,18 @@ function absToSchemaNode(a) {
|
|
|
280910
281772
|
if (lowConf) {
|
|
280911
281773
|
dropped.push(`conf=${conf}: contract projection skipped; shape-only fallback`);
|
|
280912
281774
|
}
|
|
281775
|
+
const stop2 = budget.enter(a);
|
|
281776
|
+
if (stop2) {
|
|
281777
|
+
dropped.push(`shape truncated (${stop2}) projected as unknown`);
|
|
281778
|
+
return { node: { k: "unknown" }, dropped };
|
|
281779
|
+
}
|
|
281780
|
+
try {
|
|
281781
|
+
return absToSchemaShape(a, budget, dropped);
|
|
281782
|
+
} finally {
|
|
281783
|
+
budget.exit();
|
|
281784
|
+
}
|
|
281785
|
+
}
|
|
281786
|
+
function absToSchemaShape(a, budget, dropped) {
|
|
280913
281787
|
const s = a.shape;
|
|
280914
281788
|
switch (s.k) {
|
|
280915
281789
|
case "never":
|
|
@@ -280926,12 +281800,12 @@ function absToSchemaNode(a) {
|
|
|
280926
281800
|
}
|
|
280927
281801
|
return { node: { k: "prim", type: s.type, refinements: [] }, dropped };
|
|
280928
281802
|
}
|
|
280929
|
-
const { refinements, eqLit, dropped: d } = refinementsFromPreds(leaves, {
|
|
281803
|
+
const { refinements, eqLit, hasEqLit, dropped: d } = refinementsFromPreds(leaves, {
|
|
280930
281804
|
kind,
|
|
280931
281805
|
self: a.term
|
|
280932
281806
|
});
|
|
280933
281807
|
dropped.push(...d);
|
|
280934
|
-
if (eqLit
|
|
281808
|
+
if (hasEqLit && (eqLit === void 0 || !Number.isNaN(eqLit))) {
|
|
280935
281809
|
return { node: { k: "lit", value: eqLit }, dropped };
|
|
280936
281810
|
}
|
|
280937
281811
|
return { node: { k: "prim", type: s.type, refinements }, dropped };
|
|
@@ -280945,7 +281819,7 @@ function absToSchemaNode(a) {
|
|
|
280945
281819
|
}
|
|
280946
281820
|
const slots = [];
|
|
280947
281821
|
for (const [key, slot] of Object.entries(s.slots)) {
|
|
280948
|
-
const sub2 =
|
|
281822
|
+
const sub2 = absToSchemaNodeB(slot.value, budget);
|
|
280949
281823
|
dropped.push(...sub2.dropped.map((n) => `${key}: ${n}`));
|
|
280950
281824
|
slots.push({ key, node: sub2.node, ...slot.optional ? { optional: true } : {} });
|
|
280951
281825
|
}
|
|
@@ -280955,7 +281829,7 @@ function absToSchemaNode(a) {
|
|
|
280955
281829
|
if (a.pred && a.pred.op !== "true") {
|
|
280956
281830
|
dropped.push(`arr pred not projected: ${predToString(a.pred)}`);
|
|
280957
281831
|
}
|
|
280958
|
-
const sub2 =
|
|
281832
|
+
const sub2 = absToSchemaNodeB(s.element, budget);
|
|
280959
281833
|
dropped.push(...sub2.dropped);
|
|
280960
281834
|
return { node: { k: "arr", element: sub2.node }, dropped };
|
|
280961
281835
|
}
|
|
@@ -280966,15 +281840,21 @@ function absToSchemaNode(a) {
|
|
|
280966
281840
|
dropped.push(`tuple hole at ${i} not projected (slot absent \u2260 undefined)`);
|
|
280967
281841
|
return { k: "unknown" };
|
|
280968
281842
|
}
|
|
280969
|
-
const sub2 =
|
|
281843
|
+
const sub2 = absToSchemaNodeB(e, budget);
|
|
280970
281844
|
dropped.push(...sub2.dropped);
|
|
280971
281845
|
return sub2.node;
|
|
280972
281846
|
});
|
|
280973
|
-
|
|
281847
|
+
let rest;
|
|
281848
|
+
if (s.rest) {
|
|
281849
|
+
const sub2 = absToSchemaNodeB(s.rest, budget);
|
|
281850
|
+
dropped.push(...sub2.dropped);
|
|
281851
|
+
rest = sub2.node;
|
|
281852
|
+
}
|
|
281853
|
+
return { node: { k: "tuple", elements, ...rest ? { rest } : {} }, dropped };
|
|
280974
281854
|
}
|
|
280975
281855
|
case "sum": {
|
|
280976
281856
|
const members = s.members.map((m) => {
|
|
280977
|
-
const sub2 =
|
|
281857
|
+
const sub2 = absToSchemaNodeB(m, budget);
|
|
280978
281858
|
dropped.push(...sub2.dropped);
|
|
280979
281859
|
return sub2.node;
|
|
280980
281860
|
});
|
|
@@ -280983,7 +281863,7 @@ function absToSchemaNode(a) {
|
|
|
280983
281863
|
case "fn":
|
|
280984
281864
|
return { node: { k: "fn" }, dropped };
|
|
280985
281865
|
case "eff": {
|
|
280986
|
-
const inner =
|
|
281866
|
+
const inner = absToSchemaNodeB(s.inner, budget);
|
|
280987
281867
|
dropped.push(...inner.dropped);
|
|
280988
281868
|
return {
|
|
280989
281869
|
node: s.eff === "promise" ? { k: "promise", inner: inner.node } : inner.node,
|
|
@@ -281042,8 +281922,10 @@ function schemaNodeToZod(node) {
|
|
|
281042
281922
|
}
|
|
281043
281923
|
case "arr":
|
|
281044
281924
|
return `z.array(${schemaNodeToZod(node.element)})`;
|
|
281045
|
-
case "tuple":
|
|
281046
|
-
|
|
281925
|
+
case "tuple": {
|
|
281926
|
+
const base = `z.tuple([${node.elements.map(schemaNodeToZod).join(", ")}])`;
|
|
281927
|
+
return node.rest ? `${base}.rest(${schemaNodeToZod(node.rest)})` : base;
|
|
281928
|
+
}
|
|
281047
281929
|
case "union":
|
|
281048
281930
|
return `z.union([${node.members.map(schemaNodeToZod).join(", ")}])`;
|
|
281049
281931
|
case "fn":
|
|
@@ -281068,24 +281950,23 @@ function projectAbsToSchema(a, opts) {
|
|
|
281068
281950
|
function absToSchemaSource(a, opts) {
|
|
281069
281951
|
return projectAbsToSchema(a, opts).source;
|
|
281070
281952
|
}
|
|
281071
|
-
function zodExportIdent(name) {
|
|
281072
|
-
|
|
281073
|
-
const cleaned = name.replace(/[^A-Za-z0-9_$]/g, "_");
|
|
281074
|
-
return /^[A-Za-z_$]/.test(cleaned) ? cleaned : `_${cleaned}`;
|
|
281953
|
+
function zodExportIdent(name, used) {
|
|
281954
|
+
return toJsBindingIdent(name, used);
|
|
281075
281955
|
}
|
|
281076
281956
|
function formatJsObjectKey(k) {
|
|
281077
281957
|
return formatObjectKey(k);
|
|
281078
281958
|
}
|
|
281079
|
-
function safeExportIdent(name) {
|
|
281080
|
-
return zodExportIdent(name);
|
|
281959
|
+
function safeExportIdent(name, used) {
|
|
281960
|
+
return zodExportIdent(name, used);
|
|
281081
281961
|
}
|
|
281082
281962
|
function absToZodSchemaModule(exports, opts) {
|
|
281083
281963
|
const dropped = [];
|
|
281084
281964
|
const decls = [];
|
|
281965
|
+
const used = /* @__PURE__ */ new Set();
|
|
281085
281966
|
for (const [name, abs2] of Object.entries(exports)) {
|
|
281086
281967
|
const p = projectAbsToSchema(abs2, { dialect: "zod" });
|
|
281087
281968
|
dropped.push(...p.dropped.map((n) => `${name}: ${n}`));
|
|
281088
|
-
decls.push(`export const ${zodExportIdent(name)} = ${p.source};`);
|
|
281969
|
+
decls.push(`export const ${zodExportIdent(name, used)} = ${p.source};`);
|
|
281089
281970
|
}
|
|
281090
281971
|
const banner = opts?.banner ?? `// @generated by nudo export --format schema \u2014 dialect: zod
|
|
281091
281972
|
// One-way lossy projection of Abs; do not edit. nudo check remains the gate.`;
|
|
@@ -281179,10 +282060,11 @@ function checkNode(node, value, path, issues) {
|
|
|
281179
282060
|
const rec = value;
|
|
281180
282061
|
for (const slot of node.slots) {
|
|
281181
282062
|
const key = slot.key;
|
|
281182
|
-
if (!(
|
|
282063
|
+
if (!Object.hasOwn(rec, key)) {
|
|
281183
282064
|
if (!slot.optional) pushIssue(issues, [...path, key], "required");
|
|
281184
282065
|
continue;
|
|
281185
282066
|
}
|
|
282067
|
+
if (rec[key] === void 0 && slot.optional) continue;
|
|
281186
282068
|
checkNode(slot.node, rec[key], [...path, key], issues);
|
|
281187
282069
|
}
|
|
281188
282070
|
return;
|
|
@@ -281205,6 +282087,11 @@ function checkNode(node, value, path, issues) {
|
|
|
281205
282087
|
node.elements.forEach((el, i) => {
|
|
281206
282088
|
checkNode(el, value[i], [...path, i], issues);
|
|
281207
282089
|
});
|
|
282090
|
+
if (node.rest) {
|
|
282091
|
+
for (let i = node.elements.length; i < value.length; i++) {
|
|
282092
|
+
checkNode(node.rest, value[i], [...path, i], issues);
|
|
282093
|
+
}
|
|
282094
|
+
}
|
|
281208
282095
|
return;
|
|
281209
282096
|
}
|
|
281210
282097
|
case "union": {
|
|
@@ -281229,10 +282116,10 @@ function validateSchemaNode(node, value) {
|
|
|
281229
282116
|
checkNode(node, value, [], issues);
|
|
281230
282117
|
return issues.length === 0 ? { value } : { issues };
|
|
281231
282118
|
}
|
|
281232
|
-
function makeStandardSchemaSource(exportName, node, dropped) {
|
|
282119
|
+
function makeStandardSchemaSource(exportName, node, dropped, used) {
|
|
281233
282120
|
const json = JSON.stringify(node);
|
|
281234
282121
|
const notes = dropped.length > 0 ? dropped.map((d) => `// ${sanitizeCommentText(d)}`).join("\n") + "\n" : "";
|
|
281235
|
-
return `${notes}export const ${safeExportIdent(exportName)} = {
|
|
282122
|
+
return `${notes}export const ${safeExportIdent(exportName, used)} = {
|
|
281236
282123
|
"~standard": {
|
|
281237
282124
|
version: 1,
|
|
281238
282125
|
vendor: "nudo",
|
|
@@ -281247,10 +282134,11 @@ function makeStandardSchemaSource(exportName, node, dropped) {
|
|
|
281247
282134
|
function absToStandardSchemaModule(exports, opts) {
|
|
281248
282135
|
const dropped = [];
|
|
281249
282136
|
const bodies = [];
|
|
282137
|
+
const used = /* @__PURE__ */ new Set();
|
|
281250
282138
|
for (const [name, abs2] of Object.entries(exports)) {
|
|
281251
282139
|
const { node, dropped: d } = absToSchemaNode(abs2);
|
|
281252
282140
|
dropped.push(...d.map((n) => `${name}: ${n}`));
|
|
281253
|
-
bodies.push(makeStandardSchemaSource(name, node, d.map((n) => `${name}: ${n}`)));
|
|
282141
|
+
bodies.push(makeStandardSchemaSource(name, node, d.map((n) => `${name}: ${n}`), used));
|
|
281254
282142
|
}
|
|
281255
282143
|
const banner = opts?.banner ?? `// @generated by nudo export --format standard \u2014 Standard Schema v1 (vendor: nudo)
|
|
281256
282144
|
// One-way lossy projection of Abs; do not edit. nudo check remains the gate.`;
|
|
@@ -281460,15 +282348,85 @@ ${tag}
|
|
|
281460
282348
|
]
|
|
281461
282349
|
};
|
|
281462
282350
|
}
|
|
281463
|
-
function
|
|
281464
|
-
const
|
|
282351
|
+
function* exportSpecifierParts(src) {
|
|
282352
|
+
const re = /\bexport\s*\{/g;
|
|
282353
|
+
let m;
|
|
282354
|
+
while ((m = re.exec(src)) !== null) {
|
|
282355
|
+
const parts = [];
|
|
282356
|
+
let cur = "";
|
|
282357
|
+
let quote;
|
|
282358
|
+
let close = -1;
|
|
282359
|
+
for (let i = m.index + m[0].length; i < src.length; i++) {
|
|
282360
|
+
const ch = src[i];
|
|
282361
|
+
if (quote !== void 0) {
|
|
282362
|
+
cur += ch;
|
|
282363
|
+
if (ch === "\\") {
|
|
282364
|
+
if (i + 1 < src.length) cur += src[i + 1];
|
|
282365
|
+
i++;
|
|
282366
|
+
} else if (ch === quote) {
|
|
282367
|
+
quote = void 0;
|
|
282368
|
+
}
|
|
282369
|
+
continue;
|
|
282370
|
+
}
|
|
282371
|
+
if (ch === '"' || ch === "'") {
|
|
282372
|
+
quote = ch;
|
|
282373
|
+
cur += ch;
|
|
282374
|
+
} else if (ch === ",") {
|
|
282375
|
+
parts.push(cur);
|
|
282376
|
+
cur = "";
|
|
282377
|
+
} else if (ch === "}") {
|
|
282378
|
+
parts.push(cur);
|
|
282379
|
+
cur = "";
|
|
282380
|
+
close = i;
|
|
282381
|
+
break;
|
|
282382
|
+
} else {
|
|
282383
|
+
cur += ch;
|
|
282384
|
+
}
|
|
282385
|
+
}
|
|
282386
|
+
if (close === -1) break;
|
|
282387
|
+
re.lastIndex = close + 1;
|
|
282388
|
+
for (const p of parts) yield p.trim();
|
|
282389
|
+
}
|
|
282390
|
+
}
|
|
282391
|
+
function sidecarBindingFor(sidecarSource, exportName) {
|
|
282392
|
+
for (const t of exportSpecifierParts(sidecarSource)) {
|
|
282393
|
+
if (!t) continue;
|
|
282394
|
+
const asMatch = /^([\w$]+)\s+as\s+(.+)$/.exec(t);
|
|
282395
|
+
if (!asMatch) continue;
|
|
282396
|
+
const local = asMatch[1];
|
|
282397
|
+
let exported = asMatch[2].trim();
|
|
282398
|
+
if (exported.startsWith('"') || exported.startsWith("'")) {
|
|
282399
|
+
try {
|
|
282400
|
+
exported = JSON.parse(exported.replace(/^'|'$/g, '"'));
|
|
282401
|
+
} catch {
|
|
282402
|
+
continue;
|
|
282403
|
+
}
|
|
282404
|
+
}
|
|
282405
|
+
if (exported === exportName) return local;
|
|
282406
|
+
}
|
|
282407
|
+
return void 0;
|
|
282408
|
+
}
|
|
282409
|
+
function matchSidecarFnDecl(sidecarSource, exportName) {
|
|
282410
|
+
const fn2 = escapeRegExp22(exportName);
|
|
281465
282411
|
const startRe = new RegExp(
|
|
281466
282412
|
`(?:export\\s+const\\s+${fn2}\\s*=\\s*|(?<![\\w$])${fn2}\\s*=\\s*)fn\\s*\\(`
|
|
281467
282413
|
);
|
|
281468
|
-
|
|
282414
|
+
let m = sidecarSource.match(startRe);
|
|
282415
|
+
if (!m || m.index === void 0) {
|
|
282416
|
+
const binding = sidecarBindingFor(sidecarSource, exportName);
|
|
282417
|
+
if (binding === void 0) return void 0;
|
|
282418
|
+
m = sidecarSource.match(
|
|
282419
|
+
new RegExp(`(?<![\\w$])${escapeRegExp22(binding)}\\s*=\\s*fn\\s*\\(`)
|
|
282420
|
+
);
|
|
282421
|
+
}
|
|
281469
282422
|
if (!m || m.index === void 0) return void 0;
|
|
281470
|
-
|
|
281471
|
-
|
|
282423
|
+
return { start: m.index, openParen: m.index + m[0].lastIndexOf("(") };
|
|
282424
|
+
}
|
|
282425
|
+
function wrapReturnNullable(sidecarSource, fnName) {
|
|
282426
|
+
const located = matchSidecarFnDecl(sidecarSource, fnName);
|
|
282427
|
+
if (located === void 0) return void 0;
|
|
282428
|
+
const start = located.start;
|
|
282429
|
+
const open = located.openParen;
|
|
281472
282430
|
let depth = 0;
|
|
281473
282431
|
let end = -1;
|
|
281474
282432
|
for (let i = open; i < sidecarSource.length; i++) {
|
|
@@ -281587,8 +282545,19 @@ function materializeAction(input) {
|
|
|
281587
282545
|
fields = fieldNames.map((f) => ({ field: f, type: "any()", via: "read (no type evidence)" }));
|
|
281588
282546
|
}
|
|
281589
282547
|
const shapeText = shapeDslFromFields(fields);
|
|
281590
|
-
const
|
|
282548
|
+
const direct = isJsBindingIdent(fn2);
|
|
282549
|
+
const clause = direct ? `export const ${fn2} = fn({ ${paramName2}: ${shapeText} });
|
|
282550
|
+
` : (() => {
|
|
282551
|
+
const used = new Set(
|
|
282552
|
+
[...(sidecarText ?? "").matchAll(/(?<![\w$])_nudo_(\d+)(?![\w$])/g)].map(
|
|
282553
|
+
(x) => x[0]
|
|
282554
|
+
)
|
|
282555
|
+
);
|
|
282556
|
+
const binding = allocNudoBinding((n) => used.has(n));
|
|
282557
|
+
return `const ${binding} = fn({ ${paramName2}: ${shapeText} });
|
|
282558
|
+
export { ${binding} as ${exportNameRepr(fn2)} };
|
|
281591
282559
|
`;
|
|
282560
|
+
})();
|
|
281592
282561
|
const next = sidecarText && sidecarText.trim().length > 0 ? sidecarText.endsWith("\n") ? sidecarText + clause : sidecarText + "\n" + clause : `// Generated by quickfix \u2014 review before accepting
|
|
281593
282562
|
${clause}`;
|
|
281594
282563
|
return {
|
|
@@ -281637,17 +282606,19 @@ ${clause}`;
|
|
|
281637
282606
|
}
|
|
281638
282607
|
return void 0;
|
|
281639
282608
|
}
|
|
281640
|
-
var GENERATED_PREFIX, GENERATED_CASE_LINE_REGEX, IDENT_KEY_REGEX, NUMBER_LITERAL_REGEX, UNSAFE_STRING_CHARS, UNSAFE_KEY_CHARS, CONTROL_CHARS, DIFF_CONTEXT, GENERATED_HEADER, STRING_METHODS2, NUMBER_METHODS, ARRAY_METHODS, NameAllocator, DERIVED_HEADER,
|
|
282609
|
+
var GENERATED_PREFIX, GENERATED_CASE_LINE_REGEX, IDENT_KEY_REGEX, NUMBER_LITERAL_REGEX, UNSAFE_STRING_CHARS, UNSAFE_KEY_CHARS, CONTROL_CHARS, DIFF_CONTEXT, JS_EXPORT_NAME, GENERATED_HEADER, STRING_METHODS2, NUMBER_METHODS, ARRAY_METHODS, NameAllocator, DERIVED_HEADER, TS_TRUNC, DIALECT_RENDERERS, CHECK_FN_SOURCE;
|
|
281641
282610
|
var init_emit2 = __esm({
|
|
281642
282611
|
"../service/dist/emit/index.js"() {
|
|
281643
282612
|
"use strict";
|
|
281644
282613
|
init_chunk_4TAFH6ZZ();
|
|
281645
|
-
|
|
281646
|
-
|
|
282614
|
+
init_chunk_6GFPZGQS();
|
|
282615
|
+
init_chunk_2RP2Q6LJ();
|
|
281647
282616
|
init_src();
|
|
281648
282617
|
init_src();
|
|
281649
282618
|
init_internal();
|
|
282619
|
+
init_internal();
|
|
281650
282620
|
init_src2();
|
|
282621
|
+
init_internal();
|
|
281651
282622
|
init_src();
|
|
281652
282623
|
init_internal();
|
|
281653
282624
|
init_src2();
|
|
@@ -281666,6 +282637,7 @@ var init_emit2 = __esm({
|
|
|
281666
282637
|
init_internal();
|
|
281667
282638
|
init_internal();
|
|
281668
282639
|
init_src();
|
|
282640
|
+
init_internal();
|
|
281669
282641
|
GENERATED_PREFIX = "call@";
|
|
281670
282642
|
GENERATED_CASE_LINE_REGEX = /^\s*\*?\s*@nudo:case\s+"(call@[^"]*)"/;
|
|
281671
282643
|
IDENT_KEY_REGEX = /^[A-Za-z_$][A-Za-z0-9_$]*$/;
|
|
@@ -281674,6 +282646,7 @@ var init_emit2 = __esm({
|
|
|
281674
282646
|
UNSAFE_KEY_CHARS = /[,()[\]{}:]/;
|
|
281675
282647
|
CONTROL_CHARS = /[\x00-\x1f\x7f]/;
|
|
281676
282648
|
DIFF_CONTEXT = 3;
|
|
282649
|
+
JS_EXPORT_NAME = /^(?:[$_\p{ID_Start}])(?:[$\u200C\u200D\p{ID_Continue}])*$/u;
|
|
281677
282650
|
GENERATED_HEADER = "// @generated by nudo \u2014 do not edit; regenerate with `nudo contract --emit`";
|
|
281678
282651
|
STRING_METHODS2 = /* @__PURE__ */ new Set([
|
|
281679
282652
|
"toLowerCase",
|
|
@@ -281740,6 +282713,10 @@ var init_emit2 = __esm({
|
|
|
281740
282713
|
constructor(initial) {
|
|
281741
282714
|
this.taken = new Set(initial ?? []);
|
|
281742
282715
|
}
|
|
282716
|
+
/** 名字是否已被占用(绑定别名分配用) */
|
|
282717
|
+
has(preferred) {
|
|
282718
|
+
return this.taken.has(preferred);
|
|
282719
|
+
}
|
|
281743
282720
|
claim(preferred) {
|
|
281744
282721
|
if (!this.taken.has(preferred)) {
|
|
281745
282722
|
this.taken.add(preferred);
|
|
@@ -281753,57 +282730,12 @@ var init_emit2 = __esm({
|
|
|
281753
282730
|
}
|
|
281754
282731
|
};
|
|
281755
282732
|
DERIVED_HEADER = "// @generated by nudo \u2014 do not edit; regenerate with `nudo contract --emit`";
|
|
281756
|
-
|
|
281757
|
-
"
|
|
281758
|
-
"
|
|
281759
|
-
"
|
|
281760
|
-
"
|
|
281761
|
-
|
|
281762
|
-
"continue",
|
|
281763
|
-
"debugger",
|
|
281764
|
-
"default",
|
|
281765
|
-
"delete",
|
|
281766
|
-
"do",
|
|
281767
|
-
"else",
|
|
281768
|
-
"enum",
|
|
281769
|
-
"export",
|
|
281770
|
-
"extends",
|
|
281771
|
-
"false",
|
|
281772
|
-
"finally",
|
|
281773
|
-
"for",
|
|
281774
|
-
"function",
|
|
281775
|
-
"if",
|
|
281776
|
-
"import",
|
|
281777
|
-
"in",
|
|
281778
|
-
"instanceof",
|
|
281779
|
-
"new",
|
|
281780
|
-
"null",
|
|
281781
|
-
"return",
|
|
281782
|
-
"super",
|
|
281783
|
-
"switch",
|
|
281784
|
-
"this",
|
|
281785
|
-
"throw",
|
|
281786
|
-
"true",
|
|
281787
|
-
"try",
|
|
281788
|
-
"typeof",
|
|
281789
|
-
"var",
|
|
281790
|
-
"void",
|
|
281791
|
-
"while",
|
|
281792
|
-
"with",
|
|
281793
|
-
"yield",
|
|
281794
|
-
"let",
|
|
281795
|
-
"static",
|
|
281796
|
-
"await",
|
|
281797
|
-
"implements",
|
|
281798
|
-
"interface",
|
|
281799
|
-
"package",
|
|
281800
|
-
"private",
|
|
281801
|
-
"protected",
|
|
281802
|
-
"public",
|
|
281803
|
-
"arguments",
|
|
281804
|
-
"eval",
|
|
281805
|
-
"constructor"
|
|
281806
|
-
]);
|
|
282733
|
+
TS_TRUNC = {
|
|
282734
|
+
cycle: "/* nudo:truncated:cycle */ unknown",
|
|
282735
|
+
depth: "/* nudo:truncated:depth */ unknown",
|
|
282736
|
+
cycleTpl: "/* nudo:truncated:cycle */ string",
|
|
282737
|
+
depthTpl: "/* nudo:truncated:depth */ string"
|
|
282738
|
+
};
|
|
281807
282739
|
DIALECT_RENDERERS = {
|
|
281808
282740
|
zod: schemaNodeToZod
|
|
281809
282741
|
};
|
|
@@ -281870,10 +282802,12 @@ function __nudoCheck(node, value, path, issues) {
|
|
|
281870
282802
|
}
|
|
281871
282803
|
for (const slot of node.slots) {
|
|
281872
282804
|
const key = slot.key;
|
|
281873
|
-
|
|
282805
|
+
// \u7F3A\u952E\u5224\u5B9A\u53EA\u7528\u81EA\u6709\u5C5E\u6027\uFF08BUG-018/S6-003\uFF1B\u4E24\u4EFD\u5B9E\u73B0\u987B\u540C\u53E3\u5F84\uFF09
|
|
282806
|
+
if (!Object.hasOwn(value, key)) {
|
|
281874
282807
|
if (!slot.optional) { path.push(key); push("required"); path.pop(); }
|
|
281875
282808
|
continue;
|
|
281876
282809
|
}
|
|
282810
|
+
if (value[key] === undefined && slot.optional) continue;
|
|
281877
282811
|
path.push(key);
|
|
281878
282812
|
__nudoCheck(slot.node, value[key], path, issues);
|
|
281879
282813
|
path.pop();
|
|
@@ -281896,6 +282830,13 @@ function __nudoCheck(node, value, path, issues) {
|
|
|
281896
282830
|
__nudoCheck(node.elements[i], value[i], path, issues);
|
|
281897
282831
|
path.pop();
|
|
281898
282832
|
}
|
|
282833
|
+
if (node.rest) {
|
|
282834
|
+
for (var ri = node.elements.length; ri < value.length; ri++) {
|
|
282835
|
+
path.push(ri);
|
|
282836
|
+
__nudoCheck(node.rest, value[ri], path, issues);
|
|
282837
|
+
path.pop();
|
|
282838
|
+
}
|
|
282839
|
+
}
|
|
281899
282840
|
return;
|
|
281900
282841
|
}
|
|
281901
282842
|
case "union": {
|
|
@@ -282089,7 +283030,7 @@ __export(migrate_exports, {
|
|
|
282089
283030
|
stripTsToJs: () => stripTsToJs
|
|
282090
283031
|
});
|
|
282091
283032
|
import {
|
|
282092
|
-
existsSync as
|
|
283033
|
+
existsSync as existsSync26,
|
|
282093
283034
|
mkdirSync as mkdirSync7,
|
|
282094
283035
|
readFileSync as readFileSync28,
|
|
282095
283036
|
readdirSync as readdirSync4,
|
|
@@ -282110,7 +283051,7 @@ function readJson(path) {
|
|
|
282110
283051
|
}
|
|
282111
283052
|
function writeFileAtomic(path, data) {
|
|
282112
283053
|
const dir = dirname27(path);
|
|
282113
|
-
if (!
|
|
283054
|
+
if (!existsSync26(dir)) mkdirSync7(dir, { recursive: true });
|
|
282114
283055
|
const tmp = `${path}.tmp-${process.pid}-${Date.now()}`;
|
|
282115
283056
|
try {
|
|
282116
283057
|
writeFileSync10(tmp, data, "utf-8");
|
|
@@ -282128,7 +283069,7 @@ function writeJson(path, value) {
|
|
|
282128
283069
|
`);
|
|
282129
283070
|
}
|
|
282130
283071
|
function snapshotFile(path) {
|
|
282131
|
-
if (!
|
|
283072
|
+
if (!existsSync26(path)) return { path, kind: "missing" };
|
|
282132
283073
|
try {
|
|
282133
283074
|
if (statSync15(path).isFile()) {
|
|
282134
283075
|
return { path, kind: "file", content: readFileSync28(path, "utf-8") };
|
|
@@ -282140,7 +283081,7 @@ function snapshotFile(path) {
|
|
|
282140
283081
|
}
|
|
282141
283082
|
function restoreSnapshot(snap) {
|
|
282142
283083
|
if (snap.kind === "missing") {
|
|
282143
|
-
if (
|
|
283084
|
+
if (existsSync26(snap.path)) rmSync3(snap.path, { force: true });
|
|
282144
283085
|
return;
|
|
282145
283086
|
}
|
|
282146
283087
|
if (snap.kind === "file") writeFileAtomic(snap.path, snap.content);
|
|
@@ -282237,7 +283178,7 @@ function unquoteYamlScalar(s) {
|
|
|
282237
283178
|
}
|
|
282238
283179
|
function parsePnpmWorkspacePackages(root) {
|
|
282239
283180
|
const yamlPath = join19(root, "pnpm-workspace.yaml");
|
|
282240
|
-
if (!
|
|
283181
|
+
if (!existsSync26(yamlPath)) return [];
|
|
282241
283182
|
let text;
|
|
282242
283183
|
try {
|
|
282243
283184
|
text = readFileSync28(yamlPath, "utf-8");
|
|
@@ -282299,17 +283240,17 @@ function packageRoots(root) {
|
|
|
282299
283240
|
if (w.startsWith("!")) continue;
|
|
282300
283241
|
if (w.endsWith("/*") || w.endsWith("/**")) {
|
|
282301
283242
|
const base = join19(root, w.replace(/\/\*\*?$/, ""));
|
|
282302
|
-
if (!
|
|
283243
|
+
if (!existsSync26(base)) continue;
|
|
282303
283244
|
for (const name of readdirSync4(base)) {
|
|
282304
283245
|
const p = join19(base, name);
|
|
282305
|
-
if (!
|
|
283246
|
+
if (!existsSync26(join19(p, "package.json"))) continue;
|
|
282306
283247
|
if (seen.has(p)) continue;
|
|
282307
283248
|
seen.add(p);
|
|
282308
283249
|
roots.push(p);
|
|
282309
283250
|
}
|
|
282310
283251
|
} else {
|
|
282311
283252
|
const p = join19(root, w);
|
|
282312
|
-
if (!
|
|
283253
|
+
if (!existsSync26(join19(p, "package.json"))) continue;
|
|
282313
283254
|
if (seen.has(p)) continue;
|
|
282314
283255
|
seen.add(p);
|
|
282315
283256
|
roots.push(p);
|
|
@@ -282537,7 +283478,7 @@ function findWorkflowDir(from) {
|
|
|
282537
283478
|
let cur = resolve19(from);
|
|
282538
283479
|
for (let i = 0; i < 6; i++) {
|
|
282539
283480
|
const wf = join19(cur, ".github", "workflows");
|
|
282540
|
-
if (
|
|
283481
|
+
if (existsSync26(wf) && statSync15(wf).isDirectory()) return wf;
|
|
282541
283482
|
const parent = dirname27(cur);
|
|
282542
283483
|
if (parent === cur) break;
|
|
282543
283484
|
cur = parent;
|
|
@@ -282583,7 +283524,7 @@ function rewriteWorkflowsNear(from, opts = {}) {
|
|
|
282583
283524
|
}
|
|
282584
283525
|
function resolveMigrateRoot(rootDir) {
|
|
282585
283526
|
const raw = resolve19(rootDir);
|
|
282586
|
-
if (!
|
|
283527
|
+
if (!existsSync26(raw)) {
|
|
282587
283528
|
throw new Error(`not found: ${rootDir}`);
|
|
282588
283529
|
}
|
|
282589
283530
|
return statSync15(raw).isDirectory() ? raw : dirname27(raw);
|
|
@@ -282607,9 +283548,9 @@ function migrateStatus(rootDir) {
|
|
|
282607
283548
|
...pkg?.devDependencies ?? {}
|
|
282608
283549
|
};
|
|
282609
283550
|
const markerPath = join19(r, ".nudo", "migrate-retired.json");
|
|
282610
|
-
const retired =
|
|
283551
|
+
const retired = existsSync26(markerPath) && statSync15(markerPath).isFile();
|
|
282611
283552
|
const retiringPath = join19(r, ".nudo", "migrate-retiring.json");
|
|
282612
|
-
const retiring = !retired &&
|
|
283553
|
+
const retiring = !retired && existsSync26(retiringPath) && statSync15(retiringPath).isFile();
|
|
282613
283554
|
const blockers = [];
|
|
282614
283555
|
if (retiring) {
|
|
282615
283556
|
blockers.push(
|
|
@@ -282630,9 +283571,9 @@ function migrateStatus(rootDir) {
|
|
|
282630
283571
|
}
|
|
282631
283572
|
rows.push({
|
|
282632
283573
|
root: relative12(process.cwd(), r) || ".",
|
|
282633
|
-
packageJson:
|
|
283574
|
+
packageJson: existsSync26(pkgPath),
|
|
282634
283575
|
typescriptDep: Boolean(deps.typescript),
|
|
282635
|
-
tsconfig:
|
|
283576
|
+
tsconfig: existsSync26(join19(r, "tsconfig.json")),
|
|
282636
283577
|
tscScripts,
|
|
282637
283578
|
tsFiles,
|
|
282638
283579
|
tsxFiles,
|
|
@@ -282672,7 +283613,7 @@ async function migrateStrip(paths, opts = {}) {
|
|
|
282672
283613
|
const files = [];
|
|
282673
283614
|
for (const p of paths) {
|
|
282674
283615
|
const abs2 = resolve19(p);
|
|
282675
|
-
if (!
|
|
283616
|
+
if (!existsSync26(abs2)) {
|
|
282676
283617
|
throw new Error(`not found: ${p}`);
|
|
282677
283618
|
}
|
|
282678
283619
|
if (statSync15(abs2).isDirectory()) {
|
|
@@ -282696,9 +283637,9 @@ async function migrateStrip(paths, opts = {}) {
|
|
|
282696
283637
|
const outFile = TSX_EXT.has(ext) ? file.replace(/\.tsx$/i, ".jsx") : file.replace(/\.tsx$/i, ".js").replace(/\.mts$/i, ".mjs").replace(/\.cts$/i, ".cjs").replace(/\.ts$/i, ".js");
|
|
282697
283638
|
const wouldClobberNonTs = outFile === file && !isStripSource(file);
|
|
282698
283639
|
if (opts.write && !wouldClobberNonTs) {
|
|
282699
|
-
if (opts.backup &&
|
|
283640
|
+
if (opts.backup && existsSync26(file) && !existsSync26(`${file}.bak`)) {
|
|
282700
283641
|
renameSync4(file, `${file}.bak`);
|
|
282701
|
-
} else if (opts.backup !== true &&
|
|
283642
|
+
} else if (opts.backup !== true && existsSync26(file) && extname(file).toLowerCase() !== extname(outFile).toLowerCase()) {
|
|
282702
283643
|
}
|
|
282703
283644
|
writeFileSync10(outFile, code2, "utf-8");
|
|
282704
283645
|
}
|
|
@@ -282708,7 +283649,7 @@ async function migrateStrip(paths, opts = {}) {
|
|
|
282708
283649
|
const draft = await draftInterface(outFile, { source: code2, bodyAccesses: true });
|
|
282709
283650
|
if (draft.draftSource && draft.draftSource.trim().length > 0) {
|
|
282710
283651
|
const sc = sidecarPathOf(outFile);
|
|
282711
|
-
if (!
|
|
283652
|
+
if (!existsSync26(sc)) {
|
|
282712
283653
|
mkdirSync7(dirname27(sc), { recursive: true });
|
|
282713
283654
|
writeFileSync10(sc, draft.draftSource, "utf-8");
|
|
282714
283655
|
sidecarDraft = sc;
|
|
@@ -282744,11 +283685,11 @@ function runTscBaseline(root, files) {
|
|
|
282744
283685
|
}
|
|
282745
283686
|
async function migrateVerify(paths, opts = {}) {
|
|
282746
283687
|
const { checkSource: checkSource2, formatCheckReport: formatCheckReport2, pTrue: pTrue3 } = await Promise.resolve().then(() => (init_src(), src_exports));
|
|
282747
|
-
const { defaultLoadModule: defaultLoadModule3, findProjectConfig: findProjectConfig3, interfaceConfig: interfaceConfig3, checkConfig: checkConfig2 } = await Promise.resolve().then(() => (init_src4(), src_exports4));
|
|
283688
|
+
const { collectSkipReturns: collectSkipReturns2, defaultLoadModule: defaultLoadModule3, findProjectConfig: findProjectConfig3, interfaceConfig: interfaceConfig3, checkConfig: checkConfig2 } = await Promise.resolve().then(() => (init_src4(), src_exports4));
|
|
282748
283689
|
const files = [];
|
|
282749
283690
|
for (const p of paths) {
|
|
282750
283691
|
const abs2 = resolve19(p);
|
|
282751
|
-
if (!
|
|
283692
|
+
if (!existsSync26(abs2)) {
|
|
282752
283693
|
throw new Error(`not found: ${p}`);
|
|
282753
283694
|
}
|
|
282754
283695
|
if (statSync15(abs2).isDirectory()) {
|
|
@@ -282774,7 +283715,9 @@ async function migrateVerify(paths, opts = {}) {
|
|
|
282774
283715
|
...autoBind === false ? { autoBind: false } : {},
|
|
282775
283716
|
...proj?.projectDir ? { projectDir: proj.projectDir } : {},
|
|
282776
283717
|
entryThrows: cCfg.entryThrows,
|
|
282777
|
-
...cCfg.ignoreThrows && cCfg.ignoreThrows.length > 0 ? { ignoreThrows: cCfg.ignoreThrows } : {}
|
|
283718
|
+
...cCfg.ignoreThrows && cCfg.ignoreThrows.length > 0 ? { ignoreThrows: cCfg.ignoreThrows } : {},
|
|
283719
|
+
// 与 nudo check 同源:@nudo:skip 的函数不评估 body(verify 的 ok 必须等于 check)
|
|
283720
|
+
skips: collectSkipReturns2(source)
|
|
282778
283721
|
});
|
|
282779
283722
|
const summary = `${report.summary.errors} error \xB7 ${report.summary.warnings} warning \xB7 ${report.summary.functions} fn`;
|
|
282780
283723
|
const row = {
|
|
@@ -282843,7 +283786,7 @@ function migrateRetire(rootDir, opts = {}) {
|
|
|
282843
283786
|
mkdirSync7(markerDir, { recursive: true });
|
|
282844
283787
|
commitWriteSet(root, ops);
|
|
282845
283788
|
const retiring = join19(markerDir, "migrate-retiring.json");
|
|
282846
|
-
if (
|
|
283789
|
+
if (existsSync26(retiring)) rmSync3(retiring, { force: true });
|
|
282847
283790
|
}
|
|
282848
283791
|
return {
|
|
282849
283792
|
root: relative12(process.cwd(), root) || ".",
|
|
@@ -283026,6 +283969,21 @@ function usageError(message, fix) {
|
|
|
283026
283969
|
console.error(message);
|
|
283027
283970
|
console.error(`fix: ${fix}`);
|
|
283028
283971
|
}
|
|
283972
|
+
function displayPathOf(p) {
|
|
283973
|
+
const rel = relative7(process.cwd(), p);
|
|
283974
|
+
return rel === "" || rel.startsWith("..") ? p : rel;
|
|
283975
|
+
}
|
|
283976
|
+
function variadicSwallowError(command, flags) {
|
|
283977
|
+
const list = flags.join(", ");
|
|
283978
|
+
const first = flags[0] ?? "--from";
|
|
283979
|
+
console.error(
|
|
283980
|
+
`error: \`nudo ${command}\` received no paths \u2014 variadic flag(s) ${list} consumed the following arguments`
|
|
283981
|
+
);
|
|
283982
|
+
console.error(
|
|
283983
|
+
`fix: separate variadic flags from paths with \`--\` (e.g. \`nudo ${command} ${first} a.js -- b.js\`) or list paths before the flags`
|
|
283984
|
+
);
|
|
283985
|
+
process.exitCode = 1;
|
|
283986
|
+
}
|
|
283029
283987
|
function reportPathErrors(errors) {
|
|
283030
283988
|
for (const e of errors) usageError(e.message, e.suggestion);
|
|
283031
283989
|
if (errors.length > 0) process.exitCode = 1;
|
|
@@ -283213,7 +284171,8 @@ function startWatch(paths, runOne, label) {
|
|
|
283213
284171
|
console.log(`[${(/* @__PURE__ */ new Date()).toLocaleTimeString()}] Watching for changes...`);
|
|
283214
284172
|
graph = buildModuleGraph(getFiles());
|
|
283215
284173
|
};
|
|
283216
|
-
runAll().catch(() => {
|
|
284174
|
+
runAll().catch((err) => {
|
|
284175
|
+
console.error(`nudo ${label} failed to start: ${err.message}`);
|
|
283217
284176
|
});
|
|
283218
284177
|
let debounceTimer = null;
|
|
283219
284178
|
const watchTarget = isDir ? primary : dirname21(primary);
|
|
@@ -283432,6 +284391,7 @@ async function runCheck(file, opts = {}) {
|
|
|
283432
284391
|
let cachedJson;
|
|
283433
284392
|
let algebraReport;
|
|
283434
284393
|
let mockFromErrors = [];
|
|
284394
|
+
let injectionSetupFailed = false;
|
|
283435
284395
|
if (cached2) {
|
|
283436
284396
|
cachedJson = cached2;
|
|
283437
284397
|
algebraReport = reportFromCachedJson(cached2);
|
|
@@ -283478,7 +284438,12 @@ async function runCheck(file, opts = {}) {
|
|
|
283478
284438
|
...reps.targets.length > 0 ? { replacements: reps.values, replacementTargets: reps.targets } : {},
|
|
283479
284439
|
...reps.asTargets.length > 0 ? { asOverrides: reps.asValues, asOverrideTargets: reps.asTargets } : {}
|
|
283480
284440
|
};
|
|
283481
|
-
} catch {
|
|
284441
|
+
} catch (err) {
|
|
284442
|
+
console.error(
|
|
284443
|
+
`error: eval injection setup failed: ${err.message}`
|
|
284444
|
+
);
|
|
284445
|
+
injectionSetupFailed = true;
|
|
284446
|
+
if (opts.gateFlags) opts.gateFlags.injectionSetupFailed = true;
|
|
283482
284447
|
}
|
|
283483
284448
|
algebraReport = checkSource2(filePath, source, pTrue3, {
|
|
283484
284449
|
loadModule,
|
|
@@ -283596,31 +284561,32 @@ async function runCheck(file, opts = {}) {
|
|
|
283596
284561
|
})) {
|
|
283597
284562
|
printDocsLinks(algebraReport.issues);
|
|
283598
284563
|
}
|
|
283599
|
-
if (useDisk && cacheKey && !cached2 && !opts.abs) {
|
|
284564
|
+
if (useDisk && cacheKey && !cached2 && !opts.abs && !injectionSetupFailed) {
|
|
283600
284565
|
try {
|
|
283601
284566
|
disk.set(cacheKey, serializeCheckJson2(algebraReport));
|
|
283602
284567
|
} catch {
|
|
283603
284568
|
}
|
|
283604
284569
|
}
|
|
283605
284570
|
if (opts.json && !opts.jsonCollect) {
|
|
283606
|
-
process.exitCode = checkJson.ok ? 0 : 1;
|
|
283607
|
-
} else if (!opts.jsonCollect && !algebraReport.ok) {
|
|
284571
|
+
process.exitCode = checkJson.ok && !injectionSetupFailed ? 0 : 1;
|
|
284572
|
+
} else if (!opts.jsonCollect && (!algebraReport.ok || injectionSetupFailed)) {
|
|
283608
284573
|
process.exitCode = 1;
|
|
283609
284574
|
}
|
|
283610
284575
|
}
|
|
283611
284576
|
async function runCheckFix(opts) {
|
|
283612
284577
|
const core = await Promise.resolve().then(() => (init_src(), src_exports));
|
|
283613
284578
|
const { checkSource: checkSource2, pTrue: pTrue3, sidecarPathOf: sidecarPathOf2, actionsForIssue: actionsForIssue2 } = core;
|
|
283614
|
-
const { collectSkipReturns: collectSkipReturns2, defaultLoadModule: defaultLoadModule3 } = await Promise.resolve().then(() => (init_src4(), src_exports4));
|
|
284579
|
+
const { collectSkipReturns: collectSkipReturns2, defaultLoadModule: defaultLoadModule3, findProjectConfig: findProjectConfig3, checkConfig: checkConfig2 } = await Promise.resolve().then(() => (init_src4(), src_exports4));
|
|
283615
284580
|
const {
|
|
283616
284581
|
materializeAction: materializeAction2,
|
|
283617
284582
|
applyTextEdits: applyTextEdits2,
|
|
283618
284583
|
unifiedDiff: unifiedDiff2
|
|
283619
284584
|
} = await Promise.resolve().then(() => (init_emit2(), emit_exports));
|
|
283620
|
-
const { writeFileSync: writeFileSync11, readFileSync: readFileSync29, existsSync:
|
|
284585
|
+
const { writeFileSync: writeFileSync11, readFileSync: readFileSync29, existsSync: existsSync27 } = await import("fs");
|
|
283621
284586
|
const only = opts.only && opts.only.length > 0 ? new Set(opts.only) : void 0;
|
|
283622
284587
|
let planned = 0;
|
|
283623
284588
|
let written = 0;
|
|
284589
|
+
let residualErrors = 0;
|
|
283624
284590
|
for (const file of opts.targets) {
|
|
283625
284591
|
let source;
|
|
283626
284592
|
try {
|
|
@@ -283628,17 +284594,26 @@ async function runCheckFix(opts) {
|
|
|
283628
284594
|
} catch {
|
|
283629
284595
|
continue;
|
|
283630
284596
|
}
|
|
284597
|
+
const proj = findProjectConfig3(dirname24(file));
|
|
284598
|
+
const cCfg = checkConfig2(proj?.config);
|
|
284599
|
+
const gate = checkGateFromConfig(proj?.config);
|
|
284600
|
+
const entryThrows = resolveEntryThrows(
|
|
284601
|
+
{ entryThrows: opts.entryThrows, profile: opts.profile },
|
|
284602
|
+
gate,
|
|
284603
|
+
cCfg.entryThrows
|
|
284604
|
+
);
|
|
284605
|
+
const ignoreThrows = mergeIgnoreThrows(opts.ignoreThrows, cCfg.ignoreThrows);
|
|
283631
284606
|
const report = checkSource2(file, source, pTrue3, {
|
|
283632
284607
|
loadModule: defaultLoadModule3,
|
|
283633
284608
|
fromFile: file,
|
|
283634
|
-
...
|
|
283635
|
-
|
|
284609
|
+
...ignoreThrows.length > 0 ? { ignoreThrows } : {},
|
|
284610
|
+
entryThrows,
|
|
283636
284611
|
skips: collectSkipReturns2(source)
|
|
283637
284612
|
});
|
|
283638
284613
|
const sidecar = sidecarPathOf2(file);
|
|
283639
284614
|
let sidecarText;
|
|
283640
284615
|
try {
|
|
283641
|
-
sidecarText =
|
|
284616
|
+
sidecarText = existsSync27(sidecar) ? readFileSync29(sidecar, "utf-8") : void 0;
|
|
283642
284617
|
} catch {
|
|
283643
284618
|
sidecarText = void 0;
|
|
283644
284619
|
}
|
|
@@ -283699,6 +284674,16 @@ async function runCheckFix(opts) {
|
|
|
283699
284674
|
}
|
|
283700
284675
|
}
|
|
283701
284676
|
}
|
|
284677
|
+
if (report.issues.some((i) => i.severity === "error")) {
|
|
284678
|
+
const post = checkSource2(file, source, pTrue3, {
|
|
284679
|
+
loadModule: defaultLoadModule3,
|
|
284680
|
+
fromFile: file,
|
|
284681
|
+
...ignoreThrows.length > 0 ? { ignoreThrows } : {},
|
|
284682
|
+
entryThrows,
|
|
284683
|
+
skips: collectSkipReturns2(source)
|
|
284684
|
+
});
|
|
284685
|
+
residualErrors += post.issues.filter((i) => i.severity === "error").length;
|
|
284686
|
+
}
|
|
283702
284687
|
}
|
|
283703
284688
|
const mode = opts.write ? "written" : "planned (dry-run)";
|
|
283704
284689
|
console.log(
|
|
@@ -283710,9 +284695,13 @@ check --fix: ${planned} edit(s) ${mode}${opts.write ? `, ${written} applied` : "
|
|
|
283710
284695
|
"hint: only [fix]/[adjust] are auto-applied; [silence]/[review] need a human (or LSP quickfix)"
|
|
283711
284696
|
);
|
|
283712
284697
|
}
|
|
284698
|
+
if (residualErrors > 0) {
|
|
284699
|
+
console.log(`check --fix: ${residualErrors} residual error(s) remain \u2014 gate stays red`);
|
|
284700
|
+
}
|
|
284701
|
+
return { planned, written, residualErrors };
|
|
283713
284702
|
}
|
|
283714
284703
|
function registerCheckCommand(program3) {
|
|
283715
|
-
program3.command("check").description("Gate contracts + entry throws; print signatures (CI). Day 0 observation lives here.").argument("
|
|
284704
|
+
program3.command("check").description("Gate contracts + entry throws; print signatures (CI). Day 0 observation lives here.").argument("[paths...]", "File(s) or directory(s) to check").option("--watch, -w", "Watch files and re-run check on change").option("--json", "Emit stable CheckJson (1 file) or CheckJsonMulti envelope (N files) for CI / Agent").option("--gha", "GitHub Actions inline annotations (::error/::warning). Auto when GITHUB_ACTIONS=true").option("--gitlab", "GitLab Code Quality JSON array (write as gl-code-quality-report.json)").option("--verbose", "Expand Abs signatures (term/pred/conf detail)").option("--abs", "Algebra face: term/pred/conf per function").option("--fn <name>", "With --abs: only this function").option("--assume <pred...>", "With --abs: assume constraints, e.g. x>0 y>=1").option("--generalize", "With --abs: polymorphic signatures via symbolic execution").option(
|
|
283716
284705
|
"--from <paths...>",
|
|
283717
284706
|
"Usage-site files: inject call records for cross-file domain evidence"
|
|
283718
284707
|
).option(
|
|
@@ -283729,6 +284718,28 @@ function registerCheckCommand(program3) {
|
|
|
283729
284718
|
"AI3: assume `name:type` bindings (e.g. raw:string) and report --target"
|
|
283730
284719
|
).option("--target <name>", "With --what-if: binding name whose inferred type to print").option("--fix", "Materialize one fix/adjust edit per issue (default --dry-run: print unified diff)").option("--only <codes...>", "With --fix: only these diagnostic codes (e.g. nudo:entry-may-throw)").option("--write", "With --fix: apply edits to disk (default dry-run)").option("--dry-run", "With --fix: print diffs only (default; kept for explicitness)").action(
|
|
283731
284720
|
async (paths, opts) => {
|
|
284721
|
+
if (paths.length === 0) {
|
|
284722
|
+
const swallowed = [
|
|
284723
|
+
...opts.from?.length ? ["--from"] : [],
|
|
284724
|
+
...opts.assume?.length ? ["--assume"] : [],
|
|
284725
|
+
...opts.whatIf?.length ? ["--what-if"] : [],
|
|
284726
|
+
...opts.only?.length ? ["--only"] : []
|
|
284727
|
+
];
|
|
284728
|
+
if (swallowed.length > 0) {
|
|
284729
|
+
variadicSwallowError("check", swallowed);
|
|
284730
|
+
return;
|
|
284731
|
+
}
|
|
284732
|
+
console.error("Usage error: `nudo check` needs at least one path.");
|
|
284733
|
+
process.exitCode = 1;
|
|
284734
|
+
return;
|
|
284735
|
+
}
|
|
284736
|
+
if (opts.fix && (opts.json || opts.abs || opts.gha || opts.gitlab || opts.watch || opts.verbose || opts.from && opts.from.length > 0 || opts.whatIf && opts.whatIf.length > 0)) {
|
|
284737
|
+
console.error(
|
|
284738
|
+
"error: --fix cannot be combined with --json/--abs/--gha/--gitlab/--watch/--verbose/--from/--what-if (materialization face; the CI gate is plain `nudo check`)"
|
|
284739
|
+
);
|
|
284740
|
+
process.exitCode = 1;
|
|
284741
|
+
return;
|
|
284742
|
+
}
|
|
283732
284743
|
if (opts.whatIf && opts.whatIf.length > 0) {
|
|
283733
284744
|
const targets2 = [];
|
|
283734
284745
|
for (const p of paths) targets2.push(...resolveTargets(p));
|
|
@@ -283786,7 +284797,7 @@ function registerCheckCommand(program3) {
|
|
|
283786
284797
|
const entryThrows = isEntryThrowsMode(opts.entryThrows) ? opts.entryThrows : void 0;
|
|
283787
284798
|
const profile = isGateProfile(opts.profile) ? opts.profile : void 0;
|
|
283788
284799
|
if (opts.fix) {
|
|
283789
|
-
await runCheckFix({
|
|
284800
|
+
const fix = await runCheckFix({
|
|
283790
284801
|
targets,
|
|
283791
284802
|
only: opts.only,
|
|
283792
284803
|
write: opts.write === true,
|
|
@@ -283794,6 +284805,9 @@ function registerCheckCommand(program3) {
|
|
|
283794
284805
|
entryThrows,
|
|
283795
284806
|
profile
|
|
283796
284807
|
});
|
|
284808
|
+
if (fix.residualErrors > 0) {
|
|
284809
|
+
process.exitCode = 1;
|
|
284810
|
+
}
|
|
283797
284811
|
return;
|
|
283798
284812
|
}
|
|
283799
284813
|
const shared = {
|
|
@@ -283817,13 +284831,14 @@ function registerCheckCommand(program3) {
|
|
|
283817
284831
|
const wantMulti = targets.length > 1 || allPathErrors.length > 0;
|
|
283818
284832
|
if (wantMulti) {
|
|
283819
284833
|
const collected = [];
|
|
284834
|
+
const gateFlags = {};
|
|
283820
284835
|
for (const t of targets) {
|
|
283821
|
-
await runCheck(t, { ...shared, json: true, jsonCollect: collected });
|
|
284836
|
+
await runCheck(t, { ...shared, json: true, jsonCollect: collected, gateFlags });
|
|
283822
284837
|
}
|
|
283823
284838
|
const { serializeCheckJsonMulti: multi } = await Promise.resolve().then(() => (init_src(), src_exports));
|
|
283824
284839
|
const envelope = attachPathErrors(multi(collected), allPathErrors);
|
|
283825
284840
|
console.log(JSON.stringify(envelope, null, 2));
|
|
283826
|
-
process.exitCode = envelope.ok ? 0 : 1;
|
|
284841
|
+
process.exitCode = envelope.ok && !gateFlags.injectionSetupFailed ? 0 : 1;
|
|
283827
284842
|
return;
|
|
283828
284843
|
}
|
|
283829
284844
|
if (targets.length === 1) {
|
|
@@ -284046,13 +285061,13 @@ async function runTest(file, opts = {}) {
|
|
|
284046
285061
|
if (report.failed > 0 || pathErrors.length > 0) process.exitCode = 1;
|
|
284047
285062
|
else process.exitCode = 0;
|
|
284048
285063
|
} else if (opts.abs) {
|
|
284049
|
-
const report = buildTestReport(filePath, result);
|
|
285064
|
+
const report = buildTestReport(displayPathOf(filePath), result);
|
|
284050
285065
|
await runAbsView(filePath, {});
|
|
284051
285066
|
console.log("");
|
|
284052
285067
|
console.log(formatTestReport(report));
|
|
284053
285068
|
if (report.failed > 0) process.exitCode = 1;
|
|
284054
285069
|
} else {
|
|
284055
|
-
const report = buildTestReport(filePath, result);
|
|
285070
|
+
const report = buildTestReport(displayPathOf(filePath), result);
|
|
284056
285071
|
console.log(formatTestReport(report));
|
|
284057
285072
|
if (report.failed > 0) process.exitCode = 1;
|
|
284058
285073
|
}
|
|
@@ -284091,8 +285106,17 @@ freeze \u2192 ${relPath} (${directiveCount} directive(s) across ${emitOut.writte
|
|
|
284091
285106
|
}
|
|
284092
285107
|
}
|
|
284093
285108
|
function registerTestCommand(program3) {
|
|
284094
|
-
program3.command("test").description("Report every inferred case (call@/entry@ + debug witnesses); assert declared expectations").argument("
|
|
285109
|
+
program3.command("test").description("Report every inferred case (call@/entry@ + debug witnesses); assert declared expectations").argument("[paths...]", "File(s) or directory(s)").option("--watch, -w", "Watch files and re-run test on change").option("--from <paths...>", "Usage-site files whose calls become synthesized cases").option("--freeze [mode]", "Solidify call-site witnesses as @nudo:case (mode: update | add; add is the default when the value is omitted)").option("--dry-run", "With --freeze: print a unified diff instead of writing").option("--exit-on-diff", "With --freeze --dry-run: exit 1 when the diff is non-empty").option("--json", "Output case facts as JSON (single file)").option("--abs", "Algebra face via check --abs").action(
|
|
284095
285110
|
async (paths, opts) => {
|
|
285111
|
+
if (paths.length === 0) {
|
|
285112
|
+
if (opts.from?.length) {
|
|
285113
|
+
variadicSwallowError("test", ["--from"]);
|
|
285114
|
+
return;
|
|
285115
|
+
}
|
|
285116
|
+
console.error("Usage error: `nudo test` needs at least one path.");
|
|
285117
|
+
process.exitCode = 1;
|
|
285118
|
+
return;
|
|
285119
|
+
}
|
|
284096
285120
|
const targets = [];
|
|
284097
285121
|
const pathErrors = [];
|
|
284098
285122
|
for (const p of paths) {
|
|
@@ -284481,6 +285505,10 @@ function registerContractCommand(program3) {
|
|
|
284481
285505
|
return;
|
|
284482
285506
|
}
|
|
284483
285507
|
if (paths.length === 0) {
|
|
285508
|
+
if (opts.from?.length) {
|
|
285509
|
+
variadicSwallowError("contract", ["--from"]);
|
|
285510
|
+
return;
|
|
285511
|
+
}
|
|
284484
285512
|
console.error(
|
|
284485
285513
|
"Usage error: `nudo contract` needs at least one path. " + (opts.emit ? "Writing filters: --fn <names> / --all (default: only refresh existing @generated segments)." : opts.draft ? "Draft mode: pass a file or directory." : "Print-only: pass a file or directory.")
|
|
284486
285514
|
);
|
|
@@ -284572,11 +285600,11 @@ function registerContractCommand(program3) {
|
|
|
284572
285600
|
}
|
|
284573
285601
|
|
|
284574
285602
|
// src/commands/export.ts
|
|
285603
|
+
import { readFileSync as readFileSync26, writeFileSync as writeFileSync9, mkdirSync as mkdirSync6 } from "fs";
|
|
285604
|
+
import { resolve as resolve17, relative as relative10, join as join18, basename as basename8 } from "path";
|
|
284575
285605
|
init_src();
|
|
284576
285606
|
init_emit2();
|
|
284577
285607
|
init_src4();
|
|
284578
|
-
import { readFileSync as readFileSync26, writeFileSync as writeFileSync9, mkdirSync as mkdirSync6 } from "fs";
|
|
284579
|
-
import { resolve as resolve17, relative as relative10, join as join18, basename as basename8 } from "path";
|
|
284580
285608
|
|
|
284581
285609
|
// src/export-format.ts
|
|
284582
285610
|
var EXPORT_FORMATS = ["schema", "standard", "guard", "dts", "all"];
|
|
@@ -284704,34 +285732,50 @@ ${mod2.source}`);
|
|
|
284704
285732
|
const schemaModule = Object.keys(schemaExports).length > 0 ? absToZodSchemaModule(schemaExports) : void 0;
|
|
284705
285733
|
if (output) {
|
|
284706
285734
|
const outDir = resolve17(output);
|
|
284707
|
-
|
|
285735
|
+
const ioError = (op) => ({
|
|
285736
|
+
path: outDir,
|
|
285737
|
+
code: "nudo:path-io",
|
|
285738
|
+
message: `export --out ${op} failed: ${displayPathOf(outDir)}`,
|
|
285739
|
+
suggestion: `check --out <dir> is writable and the path is a directory, then re-run nudo export`
|
|
285740
|
+
});
|
|
285741
|
+
try {
|
|
285742
|
+
mkdirSync6(outDir, { recursive: true });
|
|
285743
|
+
} catch {
|
|
285744
|
+
reportPathErrors([ioError("mkdir")]);
|
|
285745
|
+
return;
|
|
285746
|
+
}
|
|
284708
285747
|
const written = [];
|
|
284709
|
-
|
|
284710
|
-
|
|
284711
|
-
|
|
284712
|
-
|
|
284713
|
-
|
|
284714
|
-
|
|
284715
|
-
|
|
284716
|
-
const
|
|
284717
|
-
|
|
284718
|
-
|
|
284719
|
-
|
|
285748
|
+
try {
|
|
285749
|
+
if (schemaModule) {
|
|
285750
|
+
const p = join18(outDir, schemaFileName(stem, effectiveDialect));
|
|
285751
|
+
writeFileSync9(p, schemaModule.source, "utf-8");
|
|
285752
|
+
written.push(p);
|
|
285753
|
+
}
|
|
285754
|
+
if (standardChunks.length > 0) {
|
|
285755
|
+
for (const chunk of standardChunks) {
|
|
285756
|
+
const m = chunk.match(/\/\/ === (\S+) Standard Schema ===/);
|
|
285757
|
+
const fnStem = m?.[1] ?? stem;
|
|
285758
|
+
const p = join18(outDir, `${fnStem}.nudo.standard.ts`);
|
|
285759
|
+
const header = `// @generated by nudo export --format standard \u2014 Standard Schema v1 (vendor: nudo)
|
|
284720
285760
|
`;
|
|
284721
|
-
|
|
284722
|
-
|
|
285761
|
+
const body = chunk.startsWith("\n") ? chunk.slice(1) : chunk;
|
|
285762
|
+
writeFileSync9(p, body.includes("@generated") ? body + "\n" : header + body + "\n", "utf-8");
|
|
285763
|
+
written.push(p);
|
|
285764
|
+
}
|
|
285765
|
+
}
|
|
285766
|
+
if (guardChunks.length > 0) {
|
|
285767
|
+
const p = join18(outDir, `${stem}.nudo.guard.ts`);
|
|
285768
|
+
writeFileSync9(p, guardChunks.join("\n") + "\n", "utf-8");
|
|
284723
285769
|
written.push(p);
|
|
284724
285770
|
}
|
|
284725
|
-
|
|
284726
|
-
|
|
284727
|
-
|
|
284728
|
-
|
|
284729
|
-
|
|
284730
|
-
}
|
|
284731
|
-
|
|
284732
|
-
|
|
284733
|
-
writeFileSync9(p, dtsChunks.join("\n") + "\n", "utf-8");
|
|
284734
|
-
written.push(p);
|
|
285771
|
+
if (dtsChunks.length > 0) {
|
|
285772
|
+
const p = join18(outDir, `${stem}.d.ts`);
|
|
285773
|
+
writeFileSync9(p, dtsChunks.join("\n") + "\n", "utf-8");
|
|
285774
|
+
written.push(p);
|
|
285775
|
+
}
|
|
285776
|
+
} catch {
|
|
285777
|
+
reportPathErrors([ioError("write")]);
|
|
285778
|
+
return;
|
|
284735
285779
|
}
|
|
284736
285780
|
for (const p of written) {
|
|
284737
285781
|
console.log(`wrote ${relative10(process.cwd(), p)}`);
|
|
@@ -284776,21 +285820,30 @@ function registerExportCommand(program3) {
|
|
|
284776
285820
|
process.exitCode = 1;
|
|
284777
285821
|
return;
|
|
284778
285822
|
}
|
|
284779
|
-
|
|
285823
|
+
const { targets, errors } = resolveTargetsCollect(file);
|
|
285824
|
+
if (errors.length > 0) {
|
|
285825
|
+
reportPathErrors(errors);
|
|
285826
|
+
return;
|
|
285827
|
+
}
|
|
285828
|
+
if (targets.length !== 1) {
|
|
285829
|
+
console.error(
|
|
285830
|
+
`error: export takes exactly one analysis file (got ${targets.length} from ${file})`
|
|
285831
|
+
);
|
|
285832
|
+
console.error("fix: pass the single .js/.mjs/.ts file to project");
|
|
285833
|
+
process.exitCode = 1;
|
|
285834
|
+
return;
|
|
285835
|
+
}
|
|
285836
|
+
await runExport(targets[0], format, options.out, dialect);
|
|
284780
285837
|
}
|
|
284781
285838
|
);
|
|
284782
285839
|
}
|
|
284783
285840
|
|
|
284784
285841
|
// src/commands/health.ts
|
|
284785
285842
|
init_src4();
|
|
284786
|
-
import { readFileSync as readFileSync27, existsSync as
|
|
284787
|
-
import { resolve as resolve18, dirname as dirname26
|
|
284788
|
-
var displayPath = (p) => {
|
|
284789
|
-
const rel = relative11(process.cwd(), p);
|
|
284790
|
-
return rel === "" || rel.startsWith("..") ? p : rel;
|
|
284791
|
-
};
|
|
285843
|
+
import { readFileSync as readFileSync27, existsSync as existsSync25, statSync as statSync14 } from "fs";
|
|
285844
|
+
import { resolve as resolve18, dirname as dirname26 } from "path";
|
|
284792
285845
|
async function healthFile(filePath, records) {
|
|
284793
|
-
const report = { file:
|
|
285846
|
+
const report = { file: displayPathOf(filePath), functions: 0, entryOnly: 0, uncovered: [] };
|
|
284794
285847
|
let source;
|
|
284795
285848
|
try {
|
|
284796
285849
|
source = readFileSync27(filePath, "utf-8");
|
|
@@ -284859,13 +285912,16 @@ async function countInterfaceDrift(filePath) {
|
|
|
284859
285912
|
}
|
|
284860
285913
|
if (!/@generated/.test(scSrc)) return { count: 0 };
|
|
284861
285914
|
try {
|
|
284862
|
-
const { findProjectConfig: findProjectConfig3, interfaceConfig: interfaceConfig3 } = await Promise.resolve().then(() => (init_src4(), src_exports4));
|
|
285915
|
+
const { collectSkipReturns: collectSkipReturns2, findProjectConfig: findProjectConfig3, interfaceConfig: interfaceConfig3 } = await Promise.resolve().then(() => (init_src4(), src_exports4));
|
|
284863
285916
|
const proj = findProjectConfig3(dirname26(abs2));
|
|
284864
285917
|
const autoBind = interfaceConfig3(proj?.config).autoBind;
|
|
284865
|
-
const
|
|
285918
|
+
const source = rf(abs2, "utf-8");
|
|
285919
|
+
const r = checkSource2(abs2, source, pTrue3, {
|
|
284866
285920
|
loadModule: defaultLoadModule3,
|
|
284867
285921
|
fromFile: abs2,
|
|
284868
|
-
...autoBind === false ? { autoBind: false } : {}
|
|
285922
|
+
...autoBind === false ? { autoBind: false } : {},
|
|
285923
|
+
// 与 nudo check 同源:@nudo:skip 的函数不评估 body,不产出 drift 候选
|
|
285924
|
+
skips: collectSkipReturns2(source)
|
|
284869
285925
|
});
|
|
284870
285926
|
return { count: r.issues.filter((i) => i.code === "nudo:interface-drift").length };
|
|
284871
285927
|
} catch (e) {
|
|
@@ -284874,13 +285930,14 @@ async function countInterfaceDrift(filePath) {
|
|
|
284874
285930
|
}
|
|
284875
285931
|
async function runHealth(paths, opts) {
|
|
284876
285932
|
const targetPaths = paths.length > 0 ? paths : ["."];
|
|
284877
|
-
const
|
|
285933
|
+
const fromErrors = [];
|
|
285934
|
+
const externalRecords = opts.from?.length ? collectExternalRecords(opts.from, fromErrors) : void 0;
|
|
284878
285935
|
const files = [];
|
|
284879
285936
|
const reports = [];
|
|
284880
285937
|
for (const p of targetPaths) {
|
|
284881
285938
|
const abs2 = resolve18(p);
|
|
284882
|
-
if (!
|
|
284883
|
-
reports.push({ file:
|
|
285939
|
+
if (!existsSync25(abs2)) {
|
|
285940
|
+
reports.push({ file: displayPathOf(abs2), functions: 0, entryOnly: 0, uncovered: [], error: `File not found: ${displayPathOf(abs2)}` });
|
|
284884
285941
|
continue;
|
|
284885
285942
|
}
|
|
284886
285943
|
files.push(...statSync14(abs2).isDirectory() ? collectNudoFiles(abs2) : [abs2]);
|
|
@@ -284893,11 +285950,21 @@ async function runHealth(paths, opts) {
|
|
|
284893
285950
|
const errorCount = reports.filter((r) => r.error).length;
|
|
284894
285951
|
const uncoveredTotal = reports.reduce((n, r) => n + r.uncovered.length, 0);
|
|
284895
285952
|
const failed = driftCount > 0 || ifaceDriftCount > 0 || errorCount > 0;
|
|
285953
|
+
const ok2 = !failed && fromErrors.length === 0;
|
|
285954
|
+
process.exitCode = ok2 ? 0 : 1;
|
|
284896
285955
|
if (opts.json) {
|
|
284897
285956
|
console.log(
|
|
284898
285957
|
JSON.stringify(
|
|
284899
285958
|
{
|
|
284900
|
-
ok:
|
|
285959
|
+
ok: ok2,
|
|
285960
|
+
...fromErrors.length > 0 ? {
|
|
285961
|
+
pathErrors: fromErrors.map((e) => ({
|
|
285962
|
+
path: e.path,
|
|
285963
|
+
code: e.code,
|
|
285964
|
+
message: e.message,
|
|
285965
|
+
suggestion: e.suggestion
|
|
285966
|
+
}))
|
|
285967
|
+
} : {},
|
|
284901
285968
|
files: reports.map((r) => ({
|
|
284902
285969
|
file: r.file,
|
|
284903
285970
|
functions: r.functions,
|
|
@@ -284912,7 +285979,7 @@ async function runHealth(paths, opts) {
|
|
|
284912
285979
|
files: reports.length,
|
|
284913
285980
|
drift: driftCount,
|
|
284914
285981
|
interfaceDrift: ifaceDriftCount,
|
|
284915
|
-
errors: errorCount,
|
|
285982
|
+
errors: errorCount + fromErrors.length,
|
|
284916
285983
|
uncovered: uncoveredTotal,
|
|
284917
285984
|
internal_fallbacks: reports.reduce((n, r) => n + (r.internalFallbacks ?? 0), 0)
|
|
284918
285985
|
}
|
|
@@ -284922,8 +285989,16 @@ async function runHealth(paths, opts) {
|
|
|
284922
285989
|
)
|
|
284923
285990
|
);
|
|
284924
285991
|
} else {
|
|
285992
|
+
for (const e of fromErrors) {
|
|
285993
|
+
console.error(e.message);
|
|
285994
|
+
console.error(`fix: ${e.suggestion}`);
|
|
285995
|
+
}
|
|
284925
285996
|
if (reports.length === 0) {
|
|
284926
|
-
|
|
285997
|
+
if (fromErrors.length > 0) {
|
|
285998
|
+
console.log("Result: FAIL (path errors found)");
|
|
285999
|
+
} else {
|
|
286000
|
+
console.log("No files to check.");
|
|
286001
|
+
}
|
|
284927
286002
|
return;
|
|
284928
286003
|
}
|
|
284929
286004
|
for (const r of reports) {
|
|
@@ -284962,12 +286037,27 @@ async function runHealth(paths, opts) {
|
|
|
284962
286037
|
`
|
|
284963
286038
|
Summary: ${reports.length} file(s) \xB7 ${driftCount} case drift \xB7 ${ifaceDriftCount} contract drift \xB7 ${errorCount} error(s) \xB7 ${uncoveredTotal} uncovered function(s)` + (internalTotal > 0 ? ` \xB7 ${internalTotal} internal_fallback(s)` : "")
|
|
284964
286039
|
);
|
|
284965
|
-
console.log(
|
|
286040
|
+
console.log(
|
|
286041
|
+
ok2 ? "Result: OK (uncovered function(s) are informational only)" : fromErrors.length > 0 && !failed ? "Result: FAIL (path errors found)" : "Result: FAIL (drift or errors found)"
|
|
286042
|
+
);
|
|
284966
286043
|
}
|
|
284967
|
-
if (failed) process.exitCode = 1;
|
|
284968
286044
|
}
|
|
284969
286045
|
function registerHealthCommand(program3) {
|
|
284970
|
-
program3.command("health").description("Project health & drift: uncovered functions, witness drift, contract drift, analysis errors").argument("[paths...]", "File(s) or directory(s) (default: current directory)").option("--watch, -w", "Watch and re-run health on change").option("--from <paths...>", "Usage-site files for freeze-drift detection").option("--json", "Output as JSON").action(async (paths, opts) => {
|
|
286046
|
+
program3.command("health").description("Project health & drift: uncovered functions, witness drift, contract drift, analysis errors").argument("[paths...]", "File(s) or directory(s) (default: current directory; with --from, pass paths explicitly \u2014 e.g. `nudo health . --from usage.js`)").option("--watch, -w", "Watch and re-run health on change").option("--from <paths...>", "Usage-site files for freeze-drift detection").option("--json", "Output as JSON").action(async (paths, opts) => {
|
|
286047
|
+
if (opts.from?.length) {
|
|
286048
|
+
if (opts.from.length > 1) {
|
|
286049
|
+
variadicSwallowError("health", ["--from"]);
|
|
286050
|
+
return;
|
|
286051
|
+
}
|
|
286052
|
+
if (paths.length === 0) {
|
|
286053
|
+
console.error(
|
|
286054
|
+
"error: `nudo health` --from requires explicit paths when used without positional paths (previously defaulted to cwd scan)"
|
|
286055
|
+
);
|
|
286056
|
+
console.error("fix: use: `nudo health . --from usage.js`");
|
|
286057
|
+
process.exitCode = 1;
|
|
286058
|
+
return;
|
|
286059
|
+
}
|
|
286060
|
+
}
|
|
284971
286061
|
const fromPaths = opts.from;
|
|
284972
286062
|
const runOneDir = async () => {
|
|
284973
286063
|
await runHealth(paths, { ...fromPaths ? { from: fromPaths } : {}, json: opts.json });
|
|
@@ -285099,7 +286189,7 @@ function registerMigrateCommand(program3) {
|
|
|
285099
286189
|
|
|
285100
286190
|
// src/index.ts
|
|
285101
286191
|
var program2 = new Command();
|
|
285102
|
-
var argv = process.argv
|
|
286192
|
+
var argv = process.argv[2] === "--" ? [process.argv[0], process.argv[1], ...process.argv.slice(3)] : process.argv;
|
|
285103
286193
|
program2.name("nudo").description("JavaScript types, computed \u2014 check / test / contract / export / health / migrate").version(formatVersionOutput()).addHelpText(
|
|
285104
286194
|
"after",
|
|
285105
286195
|
`
|