nudojs 1.2.0 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +1585 -550
- package/package.json +5 -5
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) {
|
|
@@ -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
|
}
|
|
@@ -279042,8 +279784,8 @@ function toDraftBuilderDsl(display) {
|
|
|
279042
279784
|
}
|
|
279043
279785
|
);
|
|
279044
279786
|
}
|
|
279045
|
-
function draftExportName2(fnName) {
|
|
279046
|
-
return fnName.includes(".") ? fnName.replace(/\./g, "_") : fnName;
|
|
279787
|
+
function draftExportName2(fnName, used) {
|
|
279788
|
+
return toJsBindingIdent(fnName.includes(".") ? fnName.replace(/\./g, "_") : fnName, used);
|
|
279047
279789
|
}
|
|
279048
279790
|
function draftDsl(entry) {
|
|
279049
279791
|
const parts = entry.params.filter((p) => p.projected && p.constraint !== void 0).map((p) => {
|
|
@@ -279158,6 +279900,7 @@ ${suggestedBodyDsl(e.fn, e.params) ?? ""}`;
|
|
|
279158
279900
|
}
|
|
279159
279901
|
}
|
|
279160
279902
|
const importList = BUILDERS2.filter((b) => used.has(b)).join(", ");
|
|
279903
|
+
const exportUsed = /* @__PURE__ */ new Set();
|
|
279161
279904
|
const lines = [
|
|
279162
279905
|
"// @nudo:draft",
|
|
279163
279906
|
`// Generated by \`nudo contract --draft\` from ${sanitizeCommentText(filePath)}`,
|
|
@@ -279196,7 +279939,7 @@ ${suggestedBodyDsl(e.fn, e.params) ?? ""}`;
|
|
|
279196
279939
|
} else if (e.returnEvidence === "symbolic") {
|
|
279197
279940
|
lines.push(`// returns: ${sanitizeCommentText(e.returns?.display ?? "")} (symbolic)`);
|
|
279198
279941
|
}
|
|
279199
|
-
lines.push(`export const ${draftExportName2(e.fn)} = ${e.dsl};`);
|
|
279942
|
+
lines.push(`export const ${draftExportName2(e.fn, exportUsed)} = ${e.dsl};`);
|
|
279200
279943
|
if (e.fn.includes(".")) {
|
|
279201
279944
|
lines.push(
|
|
279202
279945
|
`// sidecar key may also be written as \`${sanitizeCommentText(e.fn)}\` / nested { ${sanitizeCommentText(e.fn.split(".")[1] ?? "")}: \u2026 }`
|
|
@@ -279875,7 +280618,8 @@ function formatDerivedSection(row, opts) {
|
|
|
279875
280618
|
retDsl = `, ${row.returns.dsl}`;
|
|
279876
280619
|
}
|
|
279877
280620
|
const namer = new NameAllocator(opts.takenNames);
|
|
279878
|
-
|
|
280621
|
+
const directBinding = directBindingOk(row.fn, (n) => namer.has(n));
|
|
280622
|
+
const binding = directBinding ? namer.claim(row.fn) : namer.claim(allocNudoBinding((n) => namer.has(n)));
|
|
279879
280623
|
const renames = /* @__PURE__ */ new Map();
|
|
279880
280624
|
const importLocals = [];
|
|
279881
280625
|
for (const [name, from] of [...importMap.entries()].sort((a, b) => a[0].localeCompare(b[0]))) {
|
|
@@ -279906,11 +280650,13 @@ function formatDerivedSection(row, opts) {
|
|
|
279906
280650
|
const spec = original === local ? local : `${original} as ${local}`;
|
|
279907
280651
|
return `import { ${spec} } from ${JSON.stringify(from)};`;
|
|
279908
280652
|
}).sort((a, b) => a.localeCompare(b));
|
|
280653
|
+
const exportStmt = directBinding ? `export const ${binding} = fn({ ${paramParts.join(", ")} }${retPart});` : `const ${binding} = fn({ ${paramParts.join(", ")} }${retPart});
|
|
280654
|
+
export { ${binding} as ${exportNameRepr(row.fn)} };`;
|
|
279909
280655
|
const lines = [
|
|
279910
280656
|
...importLineTexts,
|
|
279911
280657
|
...importLineTexts.length > 0 && renamedPreludes.length > 0 ? [""] : [],
|
|
279912
280658
|
...renamedPreludes,
|
|
279913
|
-
|
|
280659
|
+
exportStmt
|
|
279914
280660
|
];
|
|
279915
280661
|
const usedNames = /* @__PURE__ */ new Set();
|
|
279916
280662
|
for (const { local } of importLocals) usedNames.add(local);
|
|
@@ -279918,7 +280664,7 @@ function formatDerivedSection(row, opts) {
|
|
|
279918
280664
|
const n = preludeLocalName(line);
|
|
279919
280665
|
if (n) usedNames.add(n);
|
|
279920
280666
|
}
|
|
279921
|
-
usedNames.add(
|
|
280667
|
+
usedNames.add(binding);
|
|
279922
280668
|
return { text: lines.join("\n"), usedNames: [...usedNames] };
|
|
279923
280669
|
}
|
|
279924
280670
|
function collectTopLevelNames(src) {
|
|
@@ -280168,18 +280914,35 @@ function collectGeneratedSectionsRaw(src) {
|
|
|
280168
280914
|
if (stmt.type !== "ExportNamedDeclaration" || stmt.source) continue;
|
|
280169
280915
|
if (stmt.start == null || stmt.end == null || stmt.start < headerPos) continue;
|
|
280170
280916
|
const d = stmt.declaration;
|
|
280171
|
-
if (!d) continue;
|
|
280172
280917
|
const names2 = [];
|
|
280173
|
-
|
|
280174
|
-
|
|
280175
|
-
|
|
280918
|
+
const bindings = [];
|
|
280919
|
+
if (d) {
|
|
280920
|
+
if (d.type === "VariableDeclaration") {
|
|
280921
|
+
for (const decl of d.declarations) {
|
|
280922
|
+
if (decl.id.type === "Identifier") {
|
|
280923
|
+
names2.push(decl.id.name);
|
|
280924
|
+
bindings.push(decl.id.name);
|
|
280925
|
+
}
|
|
280926
|
+
}
|
|
280927
|
+
} else if (d.type === "FunctionDeclaration" || d.type === "ClassDeclaration") {
|
|
280928
|
+
if (d.id) {
|
|
280929
|
+
names2.push(d.id.name);
|
|
280930
|
+
bindings.push(d.id.name);
|
|
280931
|
+
}
|
|
280932
|
+
}
|
|
280933
|
+
} else {
|
|
280934
|
+
for (const spec of stmt.specifiers) {
|
|
280935
|
+
if (spec.type !== "ExportSpecifier") continue;
|
|
280936
|
+
names2.push(
|
|
280937
|
+
spec.exported.type === "Identifier" ? spec.exported.name : spec.exported.value
|
|
280938
|
+
);
|
|
280939
|
+
if (spec.local.type === "Identifier") bindings.push(spec.local.name);
|
|
280176
280940
|
}
|
|
280177
|
-
} else if (d.type === "FunctionDeclaration" || d.type === "ClassDeclaration") {
|
|
280178
|
-
if (d.id) names2.push(d.id.name);
|
|
280179
280941
|
}
|
|
280180
280942
|
if (names2.length === 0) continue;
|
|
280181
280943
|
out.push({
|
|
280182
280944
|
names: names2,
|
|
280945
|
+
bindings,
|
|
280183
280946
|
start: headerPos,
|
|
280184
280947
|
end: stmt.end,
|
|
280185
280948
|
text: src.slice(headerPos, stmt.end)
|
|
@@ -280201,9 +280964,6 @@ function findGeneratedHeaderOffsets(src) {
|
|
|
280201
280964
|
}
|
|
280202
280965
|
return out;
|
|
280203
280966
|
}
|
|
280204
|
-
function generatedSectionNames(src) {
|
|
280205
|
-
return new Set(collectGeneratedSectionsRaw(src).flatMap((s) => s.names));
|
|
280206
|
-
}
|
|
280207
280967
|
function handwrittenNames(src) {
|
|
280208
280968
|
if (src.trim() === "") return /* @__PURE__ */ new Set();
|
|
280209
280969
|
let ast;
|
|
@@ -280236,7 +280996,10 @@ function handwrittenNames(src) {
|
|
|
280236
280996
|
collect(stmt);
|
|
280237
280997
|
}
|
|
280238
280998
|
}
|
|
280239
|
-
for (const
|
|
280999
|
+
for (const s of collectGeneratedSectionsRaw(src)) {
|
|
281000
|
+
for (const n of s.names) names2.delete(n);
|
|
281001
|
+
for (const b of s.bindings) names2.delete(b);
|
|
281002
|
+
}
|
|
280240
281003
|
return names2;
|
|
280241
281004
|
}
|
|
280242
281005
|
function findGeneratedSectionText(src, fn2) {
|
|
@@ -280289,32 +281052,53 @@ function tsTypeParamName(id) {
|
|
|
280289
281052
|
if (n.length === 0) n = "T";
|
|
280290
281053
|
return n;
|
|
280291
281054
|
}
|
|
280292
|
-
function wrapComplexAbs(a, typeVars) {
|
|
280293
|
-
const ts3 =
|
|
281055
|
+
function wrapComplexAbs(a, typeVars, budget) {
|
|
281056
|
+
const ts3 = absToTSTypeB(a, typeVars, budget);
|
|
280294
281057
|
if (a.shape.k === "sum" || a.shape.k === "fn") return `(${ts3})`;
|
|
280295
281058
|
return ts3;
|
|
280296
281059
|
}
|
|
280297
|
-
function wrapUnionMember(a, typeVars) {
|
|
280298
|
-
const ts3 =
|
|
281060
|
+
function wrapUnionMember(a, typeVars, budget) {
|
|
281061
|
+
const ts3 = absToTSTypeB(a, typeVars, budget);
|
|
280299
281062
|
if (a.shape.k === "fn") return `(${ts3})`;
|
|
280300
281063
|
return ts3;
|
|
280301
281064
|
}
|
|
280302
|
-
function
|
|
280303
|
-
|
|
281065
|
+
function tsTplSafe(ts3) {
|
|
281066
|
+
if (ts3 === TS_TRUNC.cycle) return TS_TRUNC.cycleTpl;
|
|
281067
|
+
if (ts3 === TS_TRUNC.depth) return TS_TRUNC.depthTpl;
|
|
281068
|
+
return ts3;
|
|
280304
281069
|
}
|
|
280305
281070
|
function sanitizeParamName(name, index2) {
|
|
280306
|
-
|
|
280307
|
-
|
|
280308
|
-
|
|
281071
|
+
let optional = false;
|
|
281072
|
+
let base = name;
|
|
281073
|
+
if (base.endsWith("?")) {
|
|
281074
|
+
optional = true;
|
|
281075
|
+
base = base.slice(0, -1);
|
|
281076
|
+
}
|
|
281077
|
+
if (base.startsWith("...")) {
|
|
281078
|
+
const rest = base.slice(3);
|
|
281079
|
+
if (isJsBindingIdent(rest)) return `...${rest}${optional ? "?" : ""}`;
|
|
280309
281080
|
return `...arg${index2}`;
|
|
280310
281081
|
}
|
|
280311
|
-
if (
|
|
281082
|
+
if (isJsBindingIdent(base)) return `${base}${optional ? "?" : ""}`;
|
|
280312
281083
|
return `arg${index2}`;
|
|
280313
281084
|
}
|
|
280314
281085
|
function formatPropKey(k) {
|
|
280315
281086
|
return formatObjectKey(k);
|
|
280316
281087
|
}
|
|
280317
281088
|
function absToTSType(a, typeVars) {
|
|
281089
|
+
return absToTSTypeB(a, typeVars, new ProjectionBudget());
|
|
281090
|
+
}
|
|
281091
|
+
function absToTSTypeB(a, typeVars, budget) {
|
|
281092
|
+
const stop2 = budget.enter(a);
|
|
281093
|
+
if (stop2 === "cycle") return TS_TRUNC.cycle;
|
|
281094
|
+
if (stop2 === "depth") return TS_TRUNC.depth;
|
|
281095
|
+
try {
|
|
281096
|
+
return absToTSTypeInner(a, typeVars, budget);
|
|
281097
|
+
} finally {
|
|
281098
|
+
budget.exit();
|
|
281099
|
+
}
|
|
281100
|
+
}
|
|
281101
|
+
function absToTSTypeInner(a, typeVars, budget) {
|
|
280318
281102
|
if (a.shape.k === "any" && a.term?.op === "var" && typeVars) {
|
|
280319
281103
|
const mapped = typeVars.get(a.term.id);
|
|
280320
281104
|
if (mapped) return mapped;
|
|
@@ -280342,7 +281126,7 @@ function absToTSType(a, typeVars) {
|
|
|
280342
281126
|
const lvR = litValue(p);
|
|
280343
281127
|
const lv = lvR.ok ? lvR.value : void 0;
|
|
280344
281128
|
if (typeof lv === "string") return escapeTemplateTypeFixed(lv);
|
|
280345
|
-
return `\${${
|
|
281129
|
+
return `\${${tsTplSafe(absToTSTypeB(p, typeVars, budget))}}`;
|
|
280346
281130
|
}).join("");
|
|
280347
281131
|
return `\`${inner}\``;
|
|
280348
281132
|
}
|
|
@@ -280356,9 +281140,9 @@ function absToTSType(a, typeVars) {
|
|
|
280356
281140
|
return a.shape.type;
|
|
280357
281141
|
case "obj": {
|
|
280358
281142
|
const entries = Object.entries(a.shape.slots).map(([k, slot]) => {
|
|
280359
|
-
const inner =
|
|
281143
|
+
const inner = absToTSTypeB(slot.value, typeVars, budget);
|
|
280360
281144
|
if (slot.optional) {
|
|
280361
|
-
const t = wrapComplexAbs(slot.value, typeVars);
|
|
281145
|
+
const t = wrapComplexAbs(slot.value, typeVars, budget);
|
|
280362
281146
|
return `${formatPropKey(k)}: ${t} | undefined`;
|
|
280363
281147
|
}
|
|
280364
281148
|
return `${formatPropKey(k)}: ${inner}`;
|
|
@@ -280367,16 +281151,16 @@ function absToTSType(a, typeVars) {
|
|
|
280367
281151
|
return `{ ${entries.join("; ")} }`;
|
|
280368
281152
|
}
|
|
280369
281153
|
case "arr":
|
|
280370
|
-
return `${wrapComplexAbs(a.shape.element, typeVars)}[]`;
|
|
281154
|
+
return `${wrapComplexAbs(a.shape.element, typeVars, budget)}[]`;
|
|
280371
281155
|
case "tuple": {
|
|
280372
281156
|
const holes = a.shape.holes ?? [];
|
|
280373
281157
|
const parts = a.shape.elements.map((e, i) => {
|
|
280374
|
-
const ts3 =
|
|
281158
|
+
const ts3 = absToTSTypeB(e, typeVars, budget);
|
|
280375
281159
|
return holes.includes(i) ? `hole: ${ts3}` : ts3;
|
|
280376
281160
|
});
|
|
280377
281161
|
if (a.shape.rest) {
|
|
280378
281162
|
const rest = a.shape.rest;
|
|
280379
|
-
const restTs = rest.shape.k === "arr" ?
|
|
281163
|
+
const restTs = rest.shape.k === "arr" ? absToTSTypeB(rest, typeVars, budget) : `${wrapComplexAbs(rest, typeVars, budget)}[]`;
|
|
280380
281164
|
parts.push(`...${restTs}`);
|
|
280381
281165
|
}
|
|
280382
281166
|
return `[${parts.join(", ")}]`;
|
|
@@ -280388,22 +281172,27 @@ function absToTSType(a, typeVars) {
|
|
|
280388
281172
|
const name = sanitizeParamName(p, i);
|
|
280389
281173
|
const pt = paramTypes?.[i];
|
|
280390
281174
|
let typeStr;
|
|
280391
|
-
if (pt)
|
|
280392
|
-
|
|
281175
|
+
if (pt) {
|
|
281176
|
+
if (isRest) {
|
|
281177
|
+
typeStr = pt.shape.k === "arr" ? absToTSTypeB(pt, typeVars, budget) : `${wrapComplexAbs(pt, typeVars, budget)}[]`;
|
|
281178
|
+
} else {
|
|
281179
|
+
typeStr = absToTSTypeB(pt, typeVars, budget);
|
|
281180
|
+
}
|
|
281181
|
+
} else if (isRest) typeStr = "unknown[]";
|
|
280393
281182
|
else typeStr = "unknown";
|
|
280394
281183
|
return `${name}: ${typeStr}`;
|
|
280395
281184
|
}).join(", ");
|
|
280396
|
-
const ret = a.shape.returnType ?
|
|
281185
|
+
const ret = a.shape.returnType ? absToTSTypeB(a.shape.returnType, typeVars, budget) : "unknown";
|
|
280397
281186
|
return `(${params}) => ${ret}`;
|
|
280398
281187
|
}
|
|
280399
281188
|
case "brand":
|
|
280400
|
-
return
|
|
281189
|
+
return isJsBindingIdent(a.shape.name) || /^[A-Z][A-Za-z0-9_$]*$/.test(a.shape.name) ? a.shape.name : "unknown";
|
|
280401
281190
|
case "eff":
|
|
280402
281191
|
if (a.shape.eff === "promise")
|
|
280403
|
-
return `Promise<${
|
|
280404
|
-
return
|
|
281192
|
+
return `Promise<${absToTSTypeB(a.shape.inner, typeVars, budget)}>`;
|
|
281193
|
+
return absToTSTypeB(a.shape.inner, typeVars, budget);
|
|
280405
281194
|
case "sum": {
|
|
280406
|
-
const parts = a.shape.members.map((m) => wrapUnionMember(m, typeVars)).filter((p) => p !== "never");
|
|
281195
|
+
const parts = a.shape.members.map((m) => wrapUnionMember(m, typeVars, budget)).filter((p) => p !== "never");
|
|
280407
281196
|
const uniq = [...new Set(parts)];
|
|
280408
281197
|
if (uniq.length === 0) return "never";
|
|
280409
281198
|
if (uniq.length === 1) return uniq[0];
|
|
@@ -280419,32 +281208,47 @@ function caseArgAbs(c, i) {
|
|
|
280419
281208
|
function caseResultAbs(c) {
|
|
280420
281209
|
return c.abs;
|
|
280421
281210
|
}
|
|
280422
|
-
function widenParamAbs(a) {
|
|
281211
|
+
function widenParamAbs(a, budget = new ProjectionBudget()) {
|
|
281212
|
+
const stop2 = budget.enter(a);
|
|
281213
|
+
if (stop2) return a;
|
|
281214
|
+
try {
|
|
281215
|
+
return widenParamAbsInner(a, budget);
|
|
281216
|
+
} finally {
|
|
281217
|
+
budget.exit();
|
|
281218
|
+
}
|
|
281219
|
+
}
|
|
281220
|
+
function widenParamAbsInner(a, budget) {
|
|
280423
281221
|
const s = a.shape;
|
|
280424
281222
|
switch (s.k) {
|
|
280425
281223
|
case "prim":
|
|
280426
281224
|
return abs(s, void 0, void 0, "exact");
|
|
280427
281225
|
case "tuple": {
|
|
280428
|
-
const widened = s.elements.map(widenParamAbs);
|
|
281226
|
+
const widened = s.elements.map((el) => widenParamAbs(el, budget));
|
|
281227
|
+
const widenedRest = s.rest ? widenParamAbs(s.rest, budget) : void 0;
|
|
280429
281228
|
const holes = s.holes;
|
|
280430
281229
|
const first = widened[0];
|
|
280431
|
-
if (!holes?.length && first && widened.length > 0 && widened.every((el) => absToTSType(el) === absToTSType(first))) {
|
|
281230
|
+
if (!holes?.length && first && widened.length > 0 && widened.every((el) => absToTSType(el) === absToTSType(first)) && (!widenedRest || absToTSType(widenedRest) === absToTSType(first))) {
|
|
280432
281231
|
return abs({ k: "arr", element: first }, void 0, void 0, "exact");
|
|
280433
281232
|
}
|
|
280434
281233
|
return abs(
|
|
280435
|
-
{
|
|
281234
|
+
{
|
|
281235
|
+
k: "tuple",
|
|
281236
|
+
elements: widened,
|
|
281237
|
+
...widenedRest ? { rest: widenedRest } : {},
|
|
281238
|
+
...holes?.length ? { holes: [...holes] } : {}
|
|
281239
|
+
},
|
|
280436
281240
|
void 0,
|
|
280437
281241
|
void 0,
|
|
280438
281242
|
"exact"
|
|
280439
281243
|
);
|
|
280440
281244
|
}
|
|
280441
281245
|
case "arr":
|
|
280442
|
-
return abs({ k: "arr", element: widenParamAbs(s.element) }, void 0, void 0, "exact");
|
|
281246
|
+
return abs({ k: "arr", element: widenParamAbs(s.element, budget) }, void 0, void 0, "exact");
|
|
280443
281247
|
case "obj": {
|
|
280444
281248
|
const slots = {};
|
|
280445
281249
|
for (const [k, slot] of Object.entries(s.slots)) {
|
|
280446
281250
|
slots[k] = {
|
|
280447
|
-
value: widenParamAbs(slot.value),
|
|
281251
|
+
value: widenParamAbs(slot.value, budget),
|
|
280448
281252
|
...slot.optional ? { optional: true } : {}
|
|
280449
281253
|
};
|
|
280450
281254
|
}
|
|
@@ -280452,21 +281256,21 @@ function widenParamAbs(a) {
|
|
|
280452
281256
|
}
|
|
280453
281257
|
case "eff":
|
|
280454
281258
|
return abs(
|
|
280455
|
-
{ k: "eff", eff: s.eff, inner: widenParamAbs(s.inner) },
|
|
281259
|
+
{ k: "eff", eff: s.eff, inner: widenParamAbs(s.inner, budget) },
|
|
280456
281260
|
void 0,
|
|
280457
281261
|
void 0,
|
|
280458
281262
|
"exact"
|
|
280459
281263
|
);
|
|
280460
281264
|
case "brand":
|
|
280461
281265
|
return abs(
|
|
280462
|
-
{ k: "brand", name: s.name, shape: widenParamAbs(s.shape) },
|
|
281266
|
+
{ k: "brand", name: s.name, shape: widenParamAbs(s.shape, budget) },
|
|
280463
281267
|
void 0,
|
|
280464
281268
|
void 0,
|
|
280465
281269
|
"exact"
|
|
280466
281270
|
);
|
|
280467
281271
|
case "sum":
|
|
280468
281272
|
return abs(
|
|
280469
|
-
{ k: "sum", members: s.members.map(widenParamAbs) },
|
|
281273
|
+
{ k: "sum", members: s.members.map((m) => widenParamAbs(m, budget)) },
|
|
280470
281274
|
void 0,
|
|
280471
281275
|
void 0,
|
|
280472
281276
|
"exact"
|
|
@@ -280543,7 +281347,7 @@ function computeMainSignature(fn2) {
|
|
|
280543
281347
|
let name = getParamName(fn2, i);
|
|
280544
281348
|
const isRest = name.startsWith("...");
|
|
280545
281349
|
const bare = isRest ? name.slice(3) : name;
|
|
280546
|
-
if (!
|
|
281350
|
+
if (!isJsBindingIdent(bare)) {
|
|
280547
281351
|
name = isRest ? `...arg${i}` : `arg${i}`;
|
|
280548
281352
|
}
|
|
280549
281353
|
if (usedNames.has(name)) {
|
|
@@ -280616,7 +281420,7 @@ function computeHofSignature(fn2) {
|
|
|
280616
281420
|
const typeParams = [];
|
|
280617
281421
|
for (const id of [...free].sort()) {
|
|
280618
281422
|
let n = tsTypeParamName(id);
|
|
280619
|
-
if (used.has(n) ||
|
|
281423
|
+
if (used.has(n) || !isJsBindingIdent(n)) {
|
|
280620
281424
|
let i = 2;
|
|
280621
281425
|
while (used.has(`${n}${i}`)) i++;
|
|
280622
281426
|
n = `${n}${i}`;
|
|
@@ -280745,6 +281549,7 @@ function numericBound2(p, self, allowSelfVar) {
|
|
|
280745
281549
|
const nR = litOf(p.b);
|
|
280746
281550
|
const n = nR.ok ? nR.value : void 0;
|
|
280747
281551
|
if (typeof n !== "number") return "drop";
|
|
281552
|
+
if (!Number.isFinite(n)) return "drop";
|
|
280748
281553
|
if (p.a.op === "app" && p.a.fn === "length") return "skip";
|
|
280749
281554
|
if (allowSelfVar && isSelfVar2(p.a, self)) return { op: p.op, n };
|
|
280750
281555
|
if (p.a.op === "app" && (p.a.fn === "get" || p.a.fn === "length")) return "skip";
|
|
@@ -280757,6 +281562,7 @@ function lengthBound3(p, self) {
|
|
|
280757
281562
|
const nR = litOf(p.b);
|
|
280758
281563
|
const n = nR.ok ? nR.value : void 0;
|
|
280759
281564
|
if (typeof n !== "number") return void 0;
|
|
281565
|
+
if (!Number.isFinite(n)) return void 0;
|
|
280760
281566
|
if (p.op === "ge") return { dir: "min", n: Math.ceil(n) };
|
|
280761
281567
|
if (p.op === "gt") return { dir: "min", n: Math.floor(n) + 1 };
|
|
280762
281568
|
if (p.op === "le") return { dir: "max", n: Math.floor(n) };
|
|
@@ -280817,7 +281623,7 @@ function refinementsFromPreds(preds, opts) {
|
|
|
280817
281623
|
}
|
|
280818
281624
|
dropped.push(`pred not projected: ${predToString(p)}`);
|
|
280819
281625
|
}
|
|
280820
|
-
return { refinements, ...
|
|
281626
|
+
return { refinements, ...hasEqLit ? { eqLit } : {}, hasEqLit, dropped };
|
|
280821
281627
|
}
|
|
280822
281628
|
function constraintToSchemaNode(c) {
|
|
280823
281629
|
if (c.fn) return { k: "fn" };
|
|
@@ -280839,11 +281645,11 @@ function constraintToSchemaNode(c) {
|
|
|
280839
281645
|
}
|
|
280840
281646
|
const preds = c.preds ?? [];
|
|
280841
281647
|
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, {
|
|
281648
|
+
const { refinements, eqLit, hasEqLit, dropped } = refinementsFromPreds(preds, {
|
|
280843
281649
|
kind
|
|
280844
281650
|
// constraint 路径:absToConstraint 已把 self 改写成 __nudo_self__
|
|
280845
281651
|
});
|
|
280846
|
-
if (
|
|
281652
|
+
if (hasEqLit && (kind === "number" || kind === "string" || kind === "boolean" || !c.prim)) {
|
|
280847
281653
|
return { k: "lit", value: eqLit };
|
|
280848
281654
|
}
|
|
280849
281655
|
if (isIntFlag(c) && !refinements.some((r) => r.kind === "int")) {
|
|
@@ -280876,17 +281682,18 @@ function constraintDropped(c, prefix2 = "") {
|
|
|
280876
281682
|
}
|
|
280877
281683
|
if (n.fn) return;
|
|
280878
281684
|
const kind = n.prim === "number" ? "number" : n.prim === "string" ? "string" : n.prim === "boolean" ? "boolean" : "other";
|
|
280879
|
-
const {
|
|
281685
|
+
const { dropped } = refinementsFromPreds(n.preds ?? [], {
|
|
280880
281686
|
kind
|
|
280881
281687
|
});
|
|
280882
281688
|
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
281689
|
};
|
|
280886
281690
|
visit2(c, prefix2);
|
|
280887
281691
|
return out;
|
|
280888
281692
|
}
|
|
280889
281693
|
function absToSchemaNode(a) {
|
|
281694
|
+
return absToSchemaNodeB(a, new ProjectionBudget());
|
|
281695
|
+
}
|
|
281696
|
+
function absToSchemaNodeB(a, budget) {
|
|
280890
281697
|
const dropped = [];
|
|
280891
281698
|
if (a.term?.op === "lit") {
|
|
280892
281699
|
const v2 = a.term.value;
|
|
@@ -280901,7 +281708,7 @@ function absToSchemaNode(a) {
|
|
|
280901
281708
|
}
|
|
280902
281709
|
const conf = a.conf;
|
|
280903
281710
|
const lowConf = conf !== "exact" && conf !== "path";
|
|
280904
|
-
const projected = absToConstraint(a);
|
|
281711
|
+
const projected = absToConstraint(a, budget);
|
|
280905
281712
|
if (projected) {
|
|
280906
281713
|
const node = constraintToSchemaNode(projected);
|
|
280907
281714
|
dropped.push(...constraintDropped(projected));
|
|
@@ -280910,6 +281717,18 @@ function absToSchemaNode(a) {
|
|
|
280910
281717
|
if (lowConf) {
|
|
280911
281718
|
dropped.push(`conf=${conf}: contract projection skipped; shape-only fallback`);
|
|
280912
281719
|
}
|
|
281720
|
+
const stop2 = budget.enter(a);
|
|
281721
|
+
if (stop2) {
|
|
281722
|
+
dropped.push(`shape truncated (${stop2}) projected as unknown`);
|
|
281723
|
+
return { node: { k: "unknown" }, dropped };
|
|
281724
|
+
}
|
|
281725
|
+
try {
|
|
281726
|
+
return absToSchemaShape(a, budget, dropped);
|
|
281727
|
+
} finally {
|
|
281728
|
+
budget.exit();
|
|
281729
|
+
}
|
|
281730
|
+
}
|
|
281731
|
+
function absToSchemaShape(a, budget, dropped) {
|
|
280913
281732
|
const s = a.shape;
|
|
280914
281733
|
switch (s.k) {
|
|
280915
281734
|
case "never":
|
|
@@ -280926,12 +281745,12 @@ function absToSchemaNode(a) {
|
|
|
280926
281745
|
}
|
|
280927
281746
|
return { node: { k: "prim", type: s.type, refinements: [] }, dropped };
|
|
280928
281747
|
}
|
|
280929
|
-
const { refinements, eqLit, dropped: d } = refinementsFromPreds(leaves, {
|
|
281748
|
+
const { refinements, eqLit, hasEqLit, dropped: d } = refinementsFromPreds(leaves, {
|
|
280930
281749
|
kind,
|
|
280931
281750
|
self: a.term
|
|
280932
281751
|
});
|
|
280933
281752
|
dropped.push(...d);
|
|
280934
|
-
if (eqLit
|
|
281753
|
+
if (hasEqLit && (eqLit === void 0 || !Number.isNaN(eqLit))) {
|
|
280935
281754
|
return { node: { k: "lit", value: eqLit }, dropped };
|
|
280936
281755
|
}
|
|
280937
281756
|
return { node: { k: "prim", type: s.type, refinements }, dropped };
|
|
@@ -280945,7 +281764,7 @@ function absToSchemaNode(a) {
|
|
|
280945
281764
|
}
|
|
280946
281765
|
const slots = [];
|
|
280947
281766
|
for (const [key, slot] of Object.entries(s.slots)) {
|
|
280948
|
-
const sub2 =
|
|
281767
|
+
const sub2 = absToSchemaNodeB(slot.value, budget);
|
|
280949
281768
|
dropped.push(...sub2.dropped.map((n) => `${key}: ${n}`));
|
|
280950
281769
|
slots.push({ key, node: sub2.node, ...slot.optional ? { optional: true } : {} });
|
|
280951
281770
|
}
|
|
@@ -280955,7 +281774,7 @@ function absToSchemaNode(a) {
|
|
|
280955
281774
|
if (a.pred && a.pred.op !== "true") {
|
|
280956
281775
|
dropped.push(`arr pred not projected: ${predToString(a.pred)}`);
|
|
280957
281776
|
}
|
|
280958
|
-
const sub2 =
|
|
281777
|
+
const sub2 = absToSchemaNodeB(s.element, budget);
|
|
280959
281778
|
dropped.push(...sub2.dropped);
|
|
280960
281779
|
return { node: { k: "arr", element: sub2.node }, dropped };
|
|
280961
281780
|
}
|
|
@@ -280966,15 +281785,21 @@ function absToSchemaNode(a) {
|
|
|
280966
281785
|
dropped.push(`tuple hole at ${i} not projected (slot absent \u2260 undefined)`);
|
|
280967
281786
|
return { k: "unknown" };
|
|
280968
281787
|
}
|
|
280969
|
-
const sub2 =
|
|
281788
|
+
const sub2 = absToSchemaNodeB(e, budget);
|
|
280970
281789
|
dropped.push(...sub2.dropped);
|
|
280971
281790
|
return sub2.node;
|
|
280972
281791
|
});
|
|
280973
|
-
|
|
281792
|
+
let rest;
|
|
281793
|
+
if (s.rest) {
|
|
281794
|
+
const sub2 = absToSchemaNodeB(s.rest, budget);
|
|
281795
|
+
dropped.push(...sub2.dropped);
|
|
281796
|
+
rest = sub2.node;
|
|
281797
|
+
}
|
|
281798
|
+
return { node: { k: "tuple", elements, ...rest ? { rest } : {} }, dropped };
|
|
280974
281799
|
}
|
|
280975
281800
|
case "sum": {
|
|
280976
281801
|
const members = s.members.map((m) => {
|
|
280977
|
-
const sub2 =
|
|
281802
|
+
const sub2 = absToSchemaNodeB(m, budget);
|
|
280978
281803
|
dropped.push(...sub2.dropped);
|
|
280979
281804
|
return sub2.node;
|
|
280980
281805
|
});
|
|
@@ -280983,7 +281808,7 @@ function absToSchemaNode(a) {
|
|
|
280983
281808
|
case "fn":
|
|
280984
281809
|
return { node: { k: "fn" }, dropped };
|
|
280985
281810
|
case "eff": {
|
|
280986
|
-
const inner =
|
|
281811
|
+
const inner = absToSchemaNodeB(s.inner, budget);
|
|
280987
281812
|
dropped.push(...inner.dropped);
|
|
280988
281813
|
return {
|
|
280989
281814
|
node: s.eff === "promise" ? { k: "promise", inner: inner.node } : inner.node,
|
|
@@ -281042,8 +281867,10 @@ function schemaNodeToZod(node) {
|
|
|
281042
281867
|
}
|
|
281043
281868
|
case "arr":
|
|
281044
281869
|
return `z.array(${schemaNodeToZod(node.element)})`;
|
|
281045
|
-
case "tuple":
|
|
281046
|
-
|
|
281870
|
+
case "tuple": {
|
|
281871
|
+
const base = `z.tuple([${node.elements.map(schemaNodeToZod).join(", ")}])`;
|
|
281872
|
+
return node.rest ? `${base}.rest(${schemaNodeToZod(node.rest)})` : base;
|
|
281873
|
+
}
|
|
281047
281874
|
case "union":
|
|
281048
281875
|
return `z.union([${node.members.map(schemaNodeToZod).join(", ")}])`;
|
|
281049
281876
|
case "fn":
|
|
@@ -281068,24 +281895,23 @@ function projectAbsToSchema(a, opts) {
|
|
|
281068
281895
|
function absToSchemaSource(a, opts) {
|
|
281069
281896
|
return projectAbsToSchema(a, opts).source;
|
|
281070
281897
|
}
|
|
281071
|
-
function zodExportIdent(name) {
|
|
281072
|
-
|
|
281073
|
-
const cleaned = name.replace(/[^A-Za-z0-9_$]/g, "_");
|
|
281074
|
-
return /^[A-Za-z_$]/.test(cleaned) ? cleaned : `_${cleaned}`;
|
|
281898
|
+
function zodExportIdent(name, used) {
|
|
281899
|
+
return toJsBindingIdent(name, used);
|
|
281075
281900
|
}
|
|
281076
281901
|
function formatJsObjectKey(k) {
|
|
281077
281902
|
return formatObjectKey(k);
|
|
281078
281903
|
}
|
|
281079
|
-
function safeExportIdent(name) {
|
|
281080
|
-
return zodExportIdent(name);
|
|
281904
|
+
function safeExportIdent(name, used) {
|
|
281905
|
+
return zodExportIdent(name, used);
|
|
281081
281906
|
}
|
|
281082
281907
|
function absToZodSchemaModule(exports, opts) {
|
|
281083
281908
|
const dropped = [];
|
|
281084
281909
|
const decls = [];
|
|
281910
|
+
const used = /* @__PURE__ */ new Set();
|
|
281085
281911
|
for (const [name, abs2] of Object.entries(exports)) {
|
|
281086
281912
|
const p = projectAbsToSchema(abs2, { dialect: "zod" });
|
|
281087
281913
|
dropped.push(...p.dropped.map((n) => `${name}: ${n}`));
|
|
281088
|
-
decls.push(`export const ${zodExportIdent(name)} = ${p.source};`);
|
|
281914
|
+
decls.push(`export const ${zodExportIdent(name, used)} = ${p.source};`);
|
|
281089
281915
|
}
|
|
281090
281916
|
const banner = opts?.banner ?? `// @generated by nudo export --format schema \u2014 dialect: zod
|
|
281091
281917
|
// One-way lossy projection of Abs; do not edit. nudo check remains the gate.`;
|
|
@@ -281179,10 +282005,11 @@ function checkNode(node, value, path, issues) {
|
|
|
281179
282005
|
const rec = value;
|
|
281180
282006
|
for (const slot of node.slots) {
|
|
281181
282007
|
const key = slot.key;
|
|
281182
|
-
if (!(
|
|
282008
|
+
if (!Object.hasOwn(rec, key)) {
|
|
281183
282009
|
if (!slot.optional) pushIssue(issues, [...path, key], "required");
|
|
281184
282010
|
continue;
|
|
281185
282011
|
}
|
|
282012
|
+
if (rec[key] === void 0 && slot.optional) continue;
|
|
281186
282013
|
checkNode(slot.node, rec[key], [...path, key], issues);
|
|
281187
282014
|
}
|
|
281188
282015
|
return;
|
|
@@ -281205,6 +282032,11 @@ function checkNode(node, value, path, issues) {
|
|
|
281205
282032
|
node.elements.forEach((el, i) => {
|
|
281206
282033
|
checkNode(el, value[i], [...path, i], issues);
|
|
281207
282034
|
});
|
|
282035
|
+
if (node.rest) {
|
|
282036
|
+
for (let i = node.elements.length; i < value.length; i++) {
|
|
282037
|
+
checkNode(node.rest, value[i], [...path, i], issues);
|
|
282038
|
+
}
|
|
282039
|
+
}
|
|
281208
282040
|
return;
|
|
281209
282041
|
}
|
|
281210
282042
|
case "union": {
|
|
@@ -281229,10 +282061,10 @@ function validateSchemaNode(node, value) {
|
|
|
281229
282061
|
checkNode(node, value, [], issues);
|
|
281230
282062
|
return issues.length === 0 ? { value } : { issues };
|
|
281231
282063
|
}
|
|
281232
|
-
function makeStandardSchemaSource(exportName, node, dropped) {
|
|
282064
|
+
function makeStandardSchemaSource(exportName, node, dropped, used) {
|
|
281233
282065
|
const json = JSON.stringify(node);
|
|
281234
282066
|
const notes = dropped.length > 0 ? dropped.map((d) => `// ${sanitizeCommentText(d)}`).join("\n") + "\n" : "";
|
|
281235
|
-
return `${notes}export const ${safeExportIdent(exportName)} = {
|
|
282067
|
+
return `${notes}export const ${safeExportIdent(exportName, used)} = {
|
|
281236
282068
|
"~standard": {
|
|
281237
282069
|
version: 1,
|
|
281238
282070
|
vendor: "nudo",
|
|
@@ -281247,10 +282079,11 @@ function makeStandardSchemaSource(exportName, node, dropped) {
|
|
|
281247
282079
|
function absToStandardSchemaModule(exports, opts) {
|
|
281248
282080
|
const dropped = [];
|
|
281249
282081
|
const bodies = [];
|
|
282082
|
+
const used = /* @__PURE__ */ new Set();
|
|
281250
282083
|
for (const [name, abs2] of Object.entries(exports)) {
|
|
281251
282084
|
const { node, dropped: d } = absToSchemaNode(abs2);
|
|
281252
282085
|
dropped.push(...d.map((n) => `${name}: ${n}`));
|
|
281253
|
-
bodies.push(makeStandardSchemaSource(name, node, d.map((n) => `${name}: ${n}`)));
|
|
282086
|
+
bodies.push(makeStandardSchemaSource(name, node, d.map((n) => `${name}: ${n}`), used));
|
|
281254
282087
|
}
|
|
281255
282088
|
const banner = opts?.banner ?? `// @generated by nudo export --format standard \u2014 Standard Schema v1 (vendor: nudo)
|
|
281256
282089
|
// One-way lossy projection of Abs; do not edit. nudo check remains the gate.`;
|
|
@@ -281460,15 +282293,85 @@ ${tag}
|
|
|
281460
282293
|
]
|
|
281461
282294
|
};
|
|
281462
282295
|
}
|
|
281463
|
-
function
|
|
281464
|
-
const
|
|
282296
|
+
function* exportSpecifierParts(src) {
|
|
282297
|
+
const re = /\bexport\s*\{/g;
|
|
282298
|
+
let m;
|
|
282299
|
+
while ((m = re.exec(src)) !== null) {
|
|
282300
|
+
const parts = [];
|
|
282301
|
+
let cur = "";
|
|
282302
|
+
let quote;
|
|
282303
|
+
let close = -1;
|
|
282304
|
+
for (let i = m.index + m[0].length; i < src.length; i++) {
|
|
282305
|
+
const ch = src[i];
|
|
282306
|
+
if (quote !== void 0) {
|
|
282307
|
+
cur += ch;
|
|
282308
|
+
if (ch === "\\") {
|
|
282309
|
+
if (i + 1 < src.length) cur += src[i + 1];
|
|
282310
|
+
i++;
|
|
282311
|
+
} else if (ch === quote) {
|
|
282312
|
+
quote = void 0;
|
|
282313
|
+
}
|
|
282314
|
+
continue;
|
|
282315
|
+
}
|
|
282316
|
+
if (ch === '"' || ch === "'") {
|
|
282317
|
+
quote = ch;
|
|
282318
|
+
cur += ch;
|
|
282319
|
+
} else if (ch === ",") {
|
|
282320
|
+
parts.push(cur);
|
|
282321
|
+
cur = "";
|
|
282322
|
+
} else if (ch === "}") {
|
|
282323
|
+
parts.push(cur);
|
|
282324
|
+
cur = "";
|
|
282325
|
+
close = i;
|
|
282326
|
+
break;
|
|
282327
|
+
} else {
|
|
282328
|
+
cur += ch;
|
|
282329
|
+
}
|
|
282330
|
+
}
|
|
282331
|
+
if (close === -1) break;
|
|
282332
|
+
re.lastIndex = close + 1;
|
|
282333
|
+
for (const p of parts) yield p.trim();
|
|
282334
|
+
}
|
|
282335
|
+
}
|
|
282336
|
+
function sidecarBindingFor(sidecarSource, exportName) {
|
|
282337
|
+
for (const t of exportSpecifierParts(sidecarSource)) {
|
|
282338
|
+
if (!t) continue;
|
|
282339
|
+
const asMatch = /^([\w$]+)\s+as\s+(.+)$/.exec(t);
|
|
282340
|
+
if (!asMatch) continue;
|
|
282341
|
+
const local = asMatch[1];
|
|
282342
|
+
let exported = asMatch[2].trim();
|
|
282343
|
+
if (exported.startsWith('"') || exported.startsWith("'")) {
|
|
282344
|
+
try {
|
|
282345
|
+
exported = JSON.parse(exported.replace(/^'|'$/g, '"'));
|
|
282346
|
+
} catch {
|
|
282347
|
+
continue;
|
|
282348
|
+
}
|
|
282349
|
+
}
|
|
282350
|
+
if (exported === exportName) return local;
|
|
282351
|
+
}
|
|
282352
|
+
return void 0;
|
|
282353
|
+
}
|
|
282354
|
+
function matchSidecarFnDecl(sidecarSource, exportName) {
|
|
282355
|
+
const fn2 = escapeRegExp22(exportName);
|
|
281465
282356
|
const startRe = new RegExp(
|
|
281466
282357
|
`(?:export\\s+const\\s+${fn2}\\s*=\\s*|(?<![\\w$])${fn2}\\s*=\\s*)fn\\s*\\(`
|
|
281467
282358
|
);
|
|
281468
|
-
|
|
282359
|
+
let m = sidecarSource.match(startRe);
|
|
282360
|
+
if (!m || m.index === void 0) {
|
|
282361
|
+
const binding = sidecarBindingFor(sidecarSource, exportName);
|
|
282362
|
+
if (binding === void 0) return void 0;
|
|
282363
|
+
m = sidecarSource.match(
|
|
282364
|
+
new RegExp(`(?<![\\w$])${escapeRegExp22(binding)}\\s*=\\s*fn\\s*\\(`)
|
|
282365
|
+
);
|
|
282366
|
+
}
|
|
281469
282367
|
if (!m || m.index === void 0) return void 0;
|
|
281470
|
-
|
|
281471
|
-
|
|
282368
|
+
return { start: m.index, openParen: m.index + m[0].lastIndexOf("(") };
|
|
282369
|
+
}
|
|
282370
|
+
function wrapReturnNullable(sidecarSource, fnName) {
|
|
282371
|
+
const located = matchSidecarFnDecl(sidecarSource, fnName);
|
|
282372
|
+
if (located === void 0) return void 0;
|
|
282373
|
+
const start = located.start;
|
|
282374
|
+
const open = located.openParen;
|
|
281472
282375
|
let depth = 0;
|
|
281473
282376
|
let end = -1;
|
|
281474
282377
|
for (let i = open; i < sidecarSource.length; i++) {
|
|
@@ -281587,8 +282490,19 @@ function materializeAction(input) {
|
|
|
281587
282490
|
fields = fieldNames.map((f) => ({ field: f, type: "any()", via: "read (no type evidence)" }));
|
|
281588
282491
|
}
|
|
281589
282492
|
const shapeText = shapeDslFromFields(fields);
|
|
281590
|
-
const
|
|
282493
|
+
const direct = isJsBindingIdent(fn2);
|
|
282494
|
+
const clause = direct ? `export const ${fn2} = fn({ ${paramName2}: ${shapeText} });
|
|
282495
|
+
` : (() => {
|
|
282496
|
+
const used = new Set(
|
|
282497
|
+
[...(sidecarText ?? "").matchAll(/(?<![\w$])_nudo_(\d+)(?![\w$])/g)].map(
|
|
282498
|
+
(x) => x[0]
|
|
282499
|
+
)
|
|
282500
|
+
);
|
|
282501
|
+
const binding = allocNudoBinding((n) => used.has(n));
|
|
282502
|
+
return `const ${binding} = fn({ ${paramName2}: ${shapeText} });
|
|
282503
|
+
export { ${binding} as ${exportNameRepr(fn2)} };
|
|
281591
282504
|
`;
|
|
282505
|
+
})();
|
|
281592
282506
|
const next = sidecarText && sidecarText.trim().length > 0 ? sidecarText.endsWith("\n") ? sidecarText + clause : sidecarText + "\n" + clause : `// Generated by quickfix \u2014 review before accepting
|
|
281593
282507
|
${clause}`;
|
|
281594
282508
|
return {
|
|
@@ -281637,17 +282551,19 @@ ${clause}`;
|
|
|
281637
282551
|
}
|
|
281638
282552
|
return void 0;
|
|
281639
282553
|
}
|
|
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,
|
|
282554
|
+
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
282555
|
var init_emit2 = __esm({
|
|
281642
282556
|
"../service/dist/emit/index.js"() {
|
|
281643
282557
|
"use strict";
|
|
281644
282558
|
init_chunk_4TAFH6ZZ();
|
|
281645
|
-
|
|
281646
|
-
|
|
282559
|
+
init_chunk_6GFPZGQS();
|
|
282560
|
+
init_chunk_2RP2Q6LJ();
|
|
281647
282561
|
init_src();
|
|
281648
282562
|
init_src();
|
|
281649
282563
|
init_internal();
|
|
282564
|
+
init_internal();
|
|
281650
282565
|
init_src2();
|
|
282566
|
+
init_internal();
|
|
281651
282567
|
init_src();
|
|
281652
282568
|
init_internal();
|
|
281653
282569
|
init_src2();
|
|
@@ -281666,6 +282582,7 @@ var init_emit2 = __esm({
|
|
|
281666
282582
|
init_internal();
|
|
281667
282583
|
init_internal();
|
|
281668
282584
|
init_src();
|
|
282585
|
+
init_internal();
|
|
281669
282586
|
GENERATED_PREFIX = "call@";
|
|
281670
282587
|
GENERATED_CASE_LINE_REGEX = /^\s*\*?\s*@nudo:case\s+"(call@[^"]*)"/;
|
|
281671
282588
|
IDENT_KEY_REGEX = /^[A-Za-z_$][A-Za-z0-9_$]*$/;
|
|
@@ -281674,6 +282591,7 @@ var init_emit2 = __esm({
|
|
|
281674
282591
|
UNSAFE_KEY_CHARS = /[,()[\]{}:]/;
|
|
281675
282592
|
CONTROL_CHARS = /[\x00-\x1f\x7f]/;
|
|
281676
282593
|
DIFF_CONTEXT = 3;
|
|
282594
|
+
JS_EXPORT_NAME = /^(?:[$_\p{ID_Start}])(?:[$\u200C\u200D\p{ID_Continue}])*$/u;
|
|
281677
282595
|
GENERATED_HEADER = "// @generated by nudo \u2014 do not edit; regenerate with `nudo contract --emit`";
|
|
281678
282596
|
STRING_METHODS2 = /* @__PURE__ */ new Set([
|
|
281679
282597
|
"toLowerCase",
|
|
@@ -281740,6 +282658,10 @@ var init_emit2 = __esm({
|
|
|
281740
282658
|
constructor(initial) {
|
|
281741
282659
|
this.taken = new Set(initial ?? []);
|
|
281742
282660
|
}
|
|
282661
|
+
/** 名字是否已被占用(绑定别名分配用) */
|
|
282662
|
+
has(preferred) {
|
|
282663
|
+
return this.taken.has(preferred);
|
|
282664
|
+
}
|
|
281743
282665
|
claim(preferred) {
|
|
281744
282666
|
if (!this.taken.has(preferred)) {
|
|
281745
282667
|
this.taken.add(preferred);
|
|
@@ -281753,57 +282675,12 @@ var init_emit2 = __esm({
|
|
|
281753
282675
|
}
|
|
281754
282676
|
};
|
|
281755
282677
|
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
|
-
]);
|
|
282678
|
+
TS_TRUNC = {
|
|
282679
|
+
cycle: "/* nudo:truncated:cycle */ unknown",
|
|
282680
|
+
depth: "/* nudo:truncated:depth */ unknown",
|
|
282681
|
+
cycleTpl: "/* nudo:truncated:cycle */ string",
|
|
282682
|
+
depthTpl: "/* nudo:truncated:depth */ string"
|
|
282683
|
+
};
|
|
281807
282684
|
DIALECT_RENDERERS = {
|
|
281808
282685
|
zod: schemaNodeToZod
|
|
281809
282686
|
};
|
|
@@ -281870,10 +282747,12 @@ function __nudoCheck(node, value, path, issues) {
|
|
|
281870
282747
|
}
|
|
281871
282748
|
for (const slot of node.slots) {
|
|
281872
282749
|
const key = slot.key;
|
|
281873
|
-
|
|
282750
|
+
// \u7F3A\u952E\u5224\u5B9A\u53EA\u7528\u81EA\u6709\u5C5E\u6027\uFF08BUG-018/S6-003\uFF1B\u4E24\u4EFD\u5B9E\u73B0\u987B\u540C\u53E3\u5F84\uFF09
|
|
282751
|
+
if (!Object.hasOwn(value, key)) {
|
|
281874
282752
|
if (!slot.optional) { path.push(key); push("required"); path.pop(); }
|
|
281875
282753
|
continue;
|
|
281876
282754
|
}
|
|
282755
|
+
if (value[key] === undefined && slot.optional) continue;
|
|
281877
282756
|
path.push(key);
|
|
281878
282757
|
__nudoCheck(slot.node, value[key], path, issues);
|
|
281879
282758
|
path.pop();
|
|
@@ -281896,6 +282775,13 @@ function __nudoCheck(node, value, path, issues) {
|
|
|
281896
282775
|
__nudoCheck(node.elements[i], value[i], path, issues);
|
|
281897
282776
|
path.pop();
|
|
281898
282777
|
}
|
|
282778
|
+
if (node.rest) {
|
|
282779
|
+
for (var ri = node.elements.length; ri < value.length; ri++) {
|
|
282780
|
+
path.push(ri);
|
|
282781
|
+
__nudoCheck(node.rest, value[ri], path, issues);
|
|
282782
|
+
path.pop();
|
|
282783
|
+
}
|
|
282784
|
+
}
|
|
281899
282785
|
return;
|
|
281900
282786
|
}
|
|
281901
282787
|
case "union": {
|
|
@@ -282089,7 +282975,7 @@ __export(migrate_exports, {
|
|
|
282089
282975
|
stripTsToJs: () => stripTsToJs
|
|
282090
282976
|
});
|
|
282091
282977
|
import {
|
|
282092
|
-
existsSync as
|
|
282978
|
+
existsSync as existsSync26,
|
|
282093
282979
|
mkdirSync as mkdirSync7,
|
|
282094
282980
|
readFileSync as readFileSync28,
|
|
282095
282981
|
readdirSync as readdirSync4,
|
|
@@ -282110,7 +282996,7 @@ function readJson(path) {
|
|
|
282110
282996
|
}
|
|
282111
282997
|
function writeFileAtomic(path, data) {
|
|
282112
282998
|
const dir = dirname27(path);
|
|
282113
|
-
if (!
|
|
282999
|
+
if (!existsSync26(dir)) mkdirSync7(dir, { recursive: true });
|
|
282114
283000
|
const tmp = `${path}.tmp-${process.pid}-${Date.now()}`;
|
|
282115
283001
|
try {
|
|
282116
283002
|
writeFileSync10(tmp, data, "utf-8");
|
|
@@ -282128,7 +283014,7 @@ function writeJson(path, value) {
|
|
|
282128
283014
|
`);
|
|
282129
283015
|
}
|
|
282130
283016
|
function snapshotFile(path) {
|
|
282131
|
-
if (!
|
|
283017
|
+
if (!existsSync26(path)) return { path, kind: "missing" };
|
|
282132
283018
|
try {
|
|
282133
283019
|
if (statSync15(path).isFile()) {
|
|
282134
283020
|
return { path, kind: "file", content: readFileSync28(path, "utf-8") };
|
|
@@ -282140,7 +283026,7 @@ function snapshotFile(path) {
|
|
|
282140
283026
|
}
|
|
282141
283027
|
function restoreSnapshot(snap) {
|
|
282142
283028
|
if (snap.kind === "missing") {
|
|
282143
|
-
if (
|
|
283029
|
+
if (existsSync26(snap.path)) rmSync3(snap.path, { force: true });
|
|
282144
283030
|
return;
|
|
282145
283031
|
}
|
|
282146
283032
|
if (snap.kind === "file") writeFileAtomic(snap.path, snap.content);
|
|
@@ -282237,7 +283123,7 @@ function unquoteYamlScalar(s) {
|
|
|
282237
283123
|
}
|
|
282238
283124
|
function parsePnpmWorkspacePackages(root) {
|
|
282239
283125
|
const yamlPath = join19(root, "pnpm-workspace.yaml");
|
|
282240
|
-
if (!
|
|
283126
|
+
if (!existsSync26(yamlPath)) return [];
|
|
282241
283127
|
let text;
|
|
282242
283128
|
try {
|
|
282243
283129
|
text = readFileSync28(yamlPath, "utf-8");
|
|
@@ -282299,17 +283185,17 @@ function packageRoots(root) {
|
|
|
282299
283185
|
if (w.startsWith("!")) continue;
|
|
282300
283186
|
if (w.endsWith("/*") || w.endsWith("/**")) {
|
|
282301
283187
|
const base = join19(root, w.replace(/\/\*\*?$/, ""));
|
|
282302
|
-
if (!
|
|
283188
|
+
if (!existsSync26(base)) continue;
|
|
282303
283189
|
for (const name of readdirSync4(base)) {
|
|
282304
283190
|
const p = join19(base, name);
|
|
282305
|
-
if (!
|
|
283191
|
+
if (!existsSync26(join19(p, "package.json"))) continue;
|
|
282306
283192
|
if (seen.has(p)) continue;
|
|
282307
283193
|
seen.add(p);
|
|
282308
283194
|
roots.push(p);
|
|
282309
283195
|
}
|
|
282310
283196
|
} else {
|
|
282311
283197
|
const p = join19(root, w);
|
|
282312
|
-
if (!
|
|
283198
|
+
if (!existsSync26(join19(p, "package.json"))) continue;
|
|
282313
283199
|
if (seen.has(p)) continue;
|
|
282314
283200
|
seen.add(p);
|
|
282315
283201
|
roots.push(p);
|
|
@@ -282537,7 +283423,7 @@ function findWorkflowDir(from) {
|
|
|
282537
283423
|
let cur = resolve19(from);
|
|
282538
283424
|
for (let i = 0; i < 6; i++) {
|
|
282539
283425
|
const wf = join19(cur, ".github", "workflows");
|
|
282540
|
-
if (
|
|
283426
|
+
if (existsSync26(wf) && statSync15(wf).isDirectory()) return wf;
|
|
282541
283427
|
const parent = dirname27(cur);
|
|
282542
283428
|
if (parent === cur) break;
|
|
282543
283429
|
cur = parent;
|
|
@@ -282583,7 +283469,7 @@ function rewriteWorkflowsNear(from, opts = {}) {
|
|
|
282583
283469
|
}
|
|
282584
283470
|
function resolveMigrateRoot(rootDir) {
|
|
282585
283471
|
const raw = resolve19(rootDir);
|
|
282586
|
-
if (!
|
|
283472
|
+
if (!existsSync26(raw)) {
|
|
282587
283473
|
throw new Error(`not found: ${rootDir}`);
|
|
282588
283474
|
}
|
|
282589
283475
|
return statSync15(raw).isDirectory() ? raw : dirname27(raw);
|
|
@@ -282607,9 +283493,9 @@ function migrateStatus(rootDir) {
|
|
|
282607
283493
|
...pkg?.devDependencies ?? {}
|
|
282608
283494
|
};
|
|
282609
283495
|
const markerPath = join19(r, ".nudo", "migrate-retired.json");
|
|
282610
|
-
const retired =
|
|
283496
|
+
const retired = existsSync26(markerPath) && statSync15(markerPath).isFile();
|
|
282611
283497
|
const retiringPath = join19(r, ".nudo", "migrate-retiring.json");
|
|
282612
|
-
const retiring = !retired &&
|
|
283498
|
+
const retiring = !retired && existsSync26(retiringPath) && statSync15(retiringPath).isFile();
|
|
282613
283499
|
const blockers = [];
|
|
282614
283500
|
if (retiring) {
|
|
282615
283501
|
blockers.push(
|
|
@@ -282630,9 +283516,9 @@ function migrateStatus(rootDir) {
|
|
|
282630
283516
|
}
|
|
282631
283517
|
rows.push({
|
|
282632
283518
|
root: relative12(process.cwd(), r) || ".",
|
|
282633
|
-
packageJson:
|
|
283519
|
+
packageJson: existsSync26(pkgPath),
|
|
282634
283520
|
typescriptDep: Boolean(deps.typescript),
|
|
282635
|
-
tsconfig:
|
|
283521
|
+
tsconfig: existsSync26(join19(r, "tsconfig.json")),
|
|
282636
283522
|
tscScripts,
|
|
282637
283523
|
tsFiles,
|
|
282638
283524
|
tsxFiles,
|
|
@@ -282672,7 +283558,7 @@ async function migrateStrip(paths, opts = {}) {
|
|
|
282672
283558
|
const files = [];
|
|
282673
283559
|
for (const p of paths) {
|
|
282674
283560
|
const abs2 = resolve19(p);
|
|
282675
|
-
if (!
|
|
283561
|
+
if (!existsSync26(abs2)) {
|
|
282676
283562
|
throw new Error(`not found: ${p}`);
|
|
282677
283563
|
}
|
|
282678
283564
|
if (statSync15(abs2).isDirectory()) {
|
|
@@ -282696,9 +283582,9 @@ async function migrateStrip(paths, opts = {}) {
|
|
|
282696
283582
|
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
283583
|
const wouldClobberNonTs = outFile === file && !isStripSource(file);
|
|
282698
283584
|
if (opts.write && !wouldClobberNonTs) {
|
|
282699
|
-
if (opts.backup &&
|
|
283585
|
+
if (opts.backup && existsSync26(file) && !existsSync26(`${file}.bak`)) {
|
|
282700
283586
|
renameSync4(file, `${file}.bak`);
|
|
282701
|
-
} else if (opts.backup !== true &&
|
|
283587
|
+
} else if (opts.backup !== true && existsSync26(file) && extname(file).toLowerCase() !== extname(outFile).toLowerCase()) {
|
|
282702
283588
|
}
|
|
282703
283589
|
writeFileSync10(outFile, code2, "utf-8");
|
|
282704
283590
|
}
|
|
@@ -282708,7 +283594,7 @@ async function migrateStrip(paths, opts = {}) {
|
|
|
282708
283594
|
const draft = await draftInterface(outFile, { source: code2, bodyAccesses: true });
|
|
282709
283595
|
if (draft.draftSource && draft.draftSource.trim().length > 0) {
|
|
282710
283596
|
const sc = sidecarPathOf(outFile);
|
|
282711
|
-
if (!
|
|
283597
|
+
if (!existsSync26(sc)) {
|
|
282712
283598
|
mkdirSync7(dirname27(sc), { recursive: true });
|
|
282713
283599
|
writeFileSync10(sc, draft.draftSource, "utf-8");
|
|
282714
283600
|
sidecarDraft = sc;
|
|
@@ -282744,11 +283630,11 @@ function runTscBaseline(root, files) {
|
|
|
282744
283630
|
}
|
|
282745
283631
|
async function migrateVerify(paths, opts = {}) {
|
|
282746
283632
|
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));
|
|
283633
|
+
const { collectSkipReturns: collectSkipReturns2, defaultLoadModule: defaultLoadModule3, findProjectConfig: findProjectConfig3, interfaceConfig: interfaceConfig3, checkConfig: checkConfig2 } = await Promise.resolve().then(() => (init_src4(), src_exports4));
|
|
282748
283634
|
const files = [];
|
|
282749
283635
|
for (const p of paths) {
|
|
282750
283636
|
const abs2 = resolve19(p);
|
|
282751
|
-
if (!
|
|
283637
|
+
if (!existsSync26(abs2)) {
|
|
282752
283638
|
throw new Error(`not found: ${p}`);
|
|
282753
283639
|
}
|
|
282754
283640
|
if (statSync15(abs2).isDirectory()) {
|
|
@@ -282774,7 +283660,9 @@ async function migrateVerify(paths, opts = {}) {
|
|
|
282774
283660
|
...autoBind === false ? { autoBind: false } : {},
|
|
282775
283661
|
...proj?.projectDir ? { projectDir: proj.projectDir } : {},
|
|
282776
283662
|
entryThrows: cCfg.entryThrows,
|
|
282777
|
-
...cCfg.ignoreThrows && cCfg.ignoreThrows.length > 0 ? { ignoreThrows: cCfg.ignoreThrows } : {}
|
|
283663
|
+
...cCfg.ignoreThrows && cCfg.ignoreThrows.length > 0 ? { ignoreThrows: cCfg.ignoreThrows } : {},
|
|
283664
|
+
// 与 nudo check 同源:@nudo:skip 的函数不评估 body(verify 的 ok 必须等于 check)
|
|
283665
|
+
skips: collectSkipReturns2(source)
|
|
282778
283666
|
});
|
|
282779
283667
|
const summary = `${report.summary.errors} error \xB7 ${report.summary.warnings} warning \xB7 ${report.summary.functions} fn`;
|
|
282780
283668
|
const row = {
|
|
@@ -282843,7 +283731,7 @@ function migrateRetire(rootDir, opts = {}) {
|
|
|
282843
283731
|
mkdirSync7(markerDir, { recursive: true });
|
|
282844
283732
|
commitWriteSet(root, ops);
|
|
282845
283733
|
const retiring = join19(markerDir, "migrate-retiring.json");
|
|
282846
|
-
if (
|
|
283734
|
+
if (existsSync26(retiring)) rmSync3(retiring, { force: true });
|
|
282847
283735
|
}
|
|
282848
283736
|
return {
|
|
282849
283737
|
root: relative12(process.cwd(), root) || ".",
|
|
@@ -283026,6 +283914,21 @@ function usageError(message, fix) {
|
|
|
283026
283914
|
console.error(message);
|
|
283027
283915
|
console.error(`fix: ${fix}`);
|
|
283028
283916
|
}
|
|
283917
|
+
function displayPathOf(p) {
|
|
283918
|
+
const rel = relative7(process.cwd(), p);
|
|
283919
|
+
return rel === "" || rel.startsWith("..") ? p : rel;
|
|
283920
|
+
}
|
|
283921
|
+
function variadicSwallowError(command, flags) {
|
|
283922
|
+
const list = flags.join(", ");
|
|
283923
|
+
const first = flags[0] ?? "--from";
|
|
283924
|
+
console.error(
|
|
283925
|
+
`error: \`nudo ${command}\` received no paths \u2014 variadic flag(s) ${list} consumed the following arguments`
|
|
283926
|
+
);
|
|
283927
|
+
console.error(
|
|
283928
|
+
`fix: separate variadic flags from paths with \`--\` (e.g. \`nudo ${command} ${first} a.js -- b.js\`) or list paths before the flags`
|
|
283929
|
+
);
|
|
283930
|
+
process.exitCode = 1;
|
|
283931
|
+
}
|
|
283029
283932
|
function reportPathErrors(errors) {
|
|
283030
283933
|
for (const e of errors) usageError(e.message, e.suggestion);
|
|
283031
283934
|
if (errors.length > 0) process.exitCode = 1;
|
|
@@ -283213,7 +284116,8 @@ function startWatch(paths, runOne, label) {
|
|
|
283213
284116
|
console.log(`[${(/* @__PURE__ */ new Date()).toLocaleTimeString()}] Watching for changes...`);
|
|
283214
284117
|
graph = buildModuleGraph(getFiles());
|
|
283215
284118
|
};
|
|
283216
|
-
runAll().catch(() => {
|
|
284119
|
+
runAll().catch((err) => {
|
|
284120
|
+
console.error(`nudo ${label} failed to start: ${err.message}`);
|
|
283217
284121
|
});
|
|
283218
284122
|
let debounceTimer = null;
|
|
283219
284123
|
const watchTarget = isDir ? primary : dirname21(primary);
|
|
@@ -283432,6 +284336,7 @@ async function runCheck(file, opts = {}) {
|
|
|
283432
284336
|
let cachedJson;
|
|
283433
284337
|
let algebraReport;
|
|
283434
284338
|
let mockFromErrors = [];
|
|
284339
|
+
let injectionSetupFailed = false;
|
|
283435
284340
|
if (cached2) {
|
|
283436
284341
|
cachedJson = cached2;
|
|
283437
284342
|
algebraReport = reportFromCachedJson(cached2);
|
|
@@ -283478,7 +284383,12 @@ async function runCheck(file, opts = {}) {
|
|
|
283478
284383
|
...reps.targets.length > 0 ? { replacements: reps.values, replacementTargets: reps.targets } : {},
|
|
283479
284384
|
...reps.asTargets.length > 0 ? { asOverrides: reps.asValues, asOverrideTargets: reps.asTargets } : {}
|
|
283480
284385
|
};
|
|
283481
|
-
} catch {
|
|
284386
|
+
} catch (err) {
|
|
284387
|
+
console.error(
|
|
284388
|
+
`error: eval injection setup failed: ${err.message}`
|
|
284389
|
+
);
|
|
284390
|
+
injectionSetupFailed = true;
|
|
284391
|
+
if (opts.gateFlags) opts.gateFlags.injectionSetupFailed = true;
|
|
283482
284392
|
}
|
|
283483
284393
|
algebraReport = checkSource2(filePath, source, pTrue3, {
|
|
283484
284394
|
loadModule,
|
|
@@ -283596,31 +284506,32 @@ async function runCheck(file, opts = {}) {
|
|
|
283596
284506
|
})) {
|
|
283597
284507
|
printDocsLinks(algebraReport.issues);
|
|
283598
284508
|
}
|
|
283599
|
-
if (useDisk && cacheKey && !cached2 && !opts.abs) {
|
|
284509
|
+
if (useDisk && cacheKey && !cached2 && !opts.abs && !injectionSetupFailed) {
|
|
283600
284510
|
try {
|
|
283601
284511
|
disk.set(cacheKey, serializeCheckJson2(algebraReport));
|
|
283602
284512
|
} catch {
|
|
283603
284513
|
}
|
|
283604
284514
|
}
|
|
283605
284515
|
if (opts.json && !opts.jsonCollect) {
|
|
283606
|
-
process.exitCode = checkJson.ok ? 0 : 1;
|
|
283607
|
-
} else if (!opts.jsonCollect && !algebraReport.ok) {
|
|
284516
|
+
process.exitCode = checkJson.ok && !injectionSetupFailed ? 0 : 1;
|
|
284517
|
+
} else if (!opts.jsonCollect && (!algebraReport.ok || injectionSetupFailed)) {
|
|
283608
284518
|
process.exitCode = 1;
|
|
283609
284519
|
}
|
|
283610
284520
|
}
|
|
283611
284521
|
async function runCheckFix(opts) {
|
|
283612
284522
|
const core = await Promise.resolve().then(() => (init_src(), src_exports));
|
|
283613
284523
|
const { checkSource: checkSource2, pTrue: pTrue3, sidecarPathOf: sidecarPathOf2, actionsForIssue: actionsForIssue2 } = core;
|
|
283614
|
-
const { collectSkipReturns: collectSkipReturns2, defaultLoadModule: defaultLoadModule3 } = await Promise.resolve().then(() => (init_src4(), src_exports4));
|
|
284524
|
+
const { collectSkipReturns: collectSkipReturns2, defaultLoadModule: defaultLoadModule3, findProjectConfig: findProjectConfig3, checkConfig: checkConfig2 } = await Promise.resolve().then(() => (init_src4(), src_exports4));
|
|
283615
284525
|
const {
|
|
283616
284526
|
materializeAction: materializeAction2,
|
|
283617
284527
|
applyTextEdits: applyTextEdits2,
|
|
283618
284528
|
unifiedDiff: unifiedDiff2
|
|
283619
284529
|
} = await Promise.resolve().then(() => (init_emit2(), emit_exports));
|
|
283620
|
-
const { writeFileSync: writeFileSync11, readFileSync: readFileSync29, existsSync:
|
|
284530
|
+
const { writeFileSync: writeFileSync11, readFileSync: readFileSync29, existsSync: existsSync27 } = await import("fs");
|
|
283621
284531
|
const only = opts.only && opts.only.length > 0 ? new Set(opts.only) : void 0;
|
|
283622
284532
|
let planned = 0;
|
|
283623
284533
|
let written = 0;
|
|
284534
|
+
let residualErrors = 0;
|
|
283624
284535
|
for (const file of opts.targets) {
|
|
283625
284536
|
let source;
|
|
283626
284537
|
try {
|
|
@@ -283628,17 +284539,26 @@ async function runCheckFix(opts) {
|
|
|
283628
284539
|
} catch {
|
|
283629
284540
|
continue;
|
|
283630
284541
|
}
|
|
284542
|
+
const proj = findProjectConfig3(dirname24(file));
|
|
284543
|
+
const cCfg = checkConfig2(proj?.config);
|
|
284544
|
+
const gate = checkGateFromConfig(proj?.config);
|
|
284545
|
+
const entryThrows = resolveEntryThrows(
|
|
284546
|
+
{ entryThrows: opts.entryThrows, profile: opts.profile },
|
|
284547
|
+
gate,
|
|
284548
|
+
cCfg.entryThrows
|
|
284549
|
+
);
|
|
284550
|
+
const ignoreThrows = mergeIgnoreThrows(opts.ignoreThrows, cCfg.ignoreThrows);
|
|
283631
284551
|
const report = checkSource2(file, source, pTrue3, {
|
|
283632
284552
|
loadModule: defaultLoadModule3,
|
|
283633
284553
|
fromFile: file,
|
|
283634
|
-
...
|
|
283635
|
-
|
|
284554
|
+
...ignoreThrows.length > 0 ? { ignoreThrows } : {},
|
|
284555
|
+
entryThrows,
|
|
283636
284556
|
skips: collectSkipReturns2(source)
|
|
283637
284557
|
});
|
|
283638
284558
|
const sidecar = sidecarPathOf2(file);
|
|
283639
284559
|
let sidecarText;
|
|
283640
284560
|
try {
|
|
283641
|
-
sidecarText =
|
|
284561
|
+
sidecarText = existsSync27(sidecar) ? readFileSync29(sidecar, "utf-8") : void 0;
|
|
283642
284562
|
} catch {
|
|
283643
284563
|
sidecarText = void 0;
|
|
283644
284564
|
}
|
|
@@ -283699,6 +284619,16 @@ async function runCheckFix(opts) {
|
|
|
283699
284619
|
}
|
|
283700
284620
|
}
|
|
283701
284621
|
}
|
|
284622
|
+
if (report.issues.some((i) => i.severity === "error")) {
|
|
284623
|
+
const post = checkSource2(file, source, pTrue3, {
|
|
284624
|
+
loadModule: defaultLoadModule3,
|
|
284625
|
+
fromFile: file,
|
|
284626
|
+
...ignoreThrows.length > 0 ? { ignoreThrows } : {},
|
|
284627
|
+
entryThrows,
|
|
284628
|
+
skips: collectSkipReturns2(source)
|
|
284629
|
+
});
|
|
284630
|
+
residualErrors += post.issues.filter((i) => i.severity === "error").length;
|
|
284631
|
+
}
|
|
283702
284632
|
}
|
|
283703
284633
|
const mode = opts.write ? "written" : "planned (dry-run)";
|
|
283704
284634
|
console.log(
|
|
@@ -283710,9 +284640,13 @@ check --fix: ${planned} edit(s) ${mode}${opts.write ? `, ${written} applied` : "
|
|
|
283710
284640
|
"hint: only [fix]/[adjust] are auto-applied; [silence]/[review] need a human (or LSP quickfix)"
|
|
283711
284641
|
);
|
|
283712
284642
|
}
|
|
284643
|
+
if (residualErrors > 0) {
|
|
284644
|
+
console.log(`check --fix: ${residualErrors} residual error(s) remain \u2014 gate stays red`);
|
|
284645
|
+
}
|
|
284646
|
+
return { planned, written, residualErrors };
|
|
283713
284647
|
}
|
|
283714
284648
|
function registerCheckCommand(program3) {
|
|
283715
|
-
program3.command("check").description("Gate contracts + entry throws; print signatures (CI). Day 0 observation lives here.").argument("
|
|
284649
|
+
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
284650
|
"--from <paths...>",
|
|
283717
284651
|
"Usage-site files: inject call records for cross-file domain evidence"
|
|
283718
284652
|
).option(
|
|
@@ -283729,6 +284663,28 @@ function registerCheckCommand(program3) {
|
|
|
283729
284663
|
"AI3: assume `name:type` bindings (e.g. raw:string) and report --target"
|
|
283730
284664
|
).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
284665
|
async (paths, opts) => {
|
|
284666
|
+
if (paths.length === 0) {
|
|
284667
|
+
const swallowed = [
|
|
284668
|
+
...opts.from?.length ? ["--from"] : [],
|
|
284669
|
+
...opts.assume?.length ? ["--assume"] : [],
|
|
284670
|
+
...opts.whatIf?.length ? ["--what-if"] : [],
|
|
284671
|
+
...opts.only?.length ? ["--only"] : []
|
|
284672
|
+
];
|
|
284673
|
+
if (swallowed.length > 0) {
|
|
284674
|
+
variadicSwallowError("check", swallowed);
|
|
284675
|
+
return;
|
|
284676
|
+
}
|
|
284677
|
+
console.error("Usage error: `nudo check` needs at least one path.");
|
|
284678
|
+
process.exitCode = 1;
|
|
284679
|
+
return;
|
|
284680
|
+
}
|
|
284681
|
+
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)) {
|
|
284682
|
+
console.error(
|
|
284683
|
+
"error: --fix cannot be combined with --json/--abs/--gha/--gitlab/--watch/--verbose/--from/--what-if (materialization face; the CI gate is plain `nudo check`)"
|
|
284684
|
+
);
|
|
284685
|
+
process.exitCode = 1;
|
|
284686
|
+
return;
|
|
284687
|
+
}
|
|
283732
284688
|
if (opts.whatIf && opts.whatIf.length > 0) {
|
|
283733
284689
|
const targets2 = [];
|
|
283734
284690
|
for (const p of paths) targets2.push(...resolveTargets(p));
|
|
@@ -283786,7 +284742,7 @@ function registerCheckCommand(program3) {
|
|
|
283786
284742
|
const entryThrows = isEntryThrowsMode(opts.entryThrows) ? opts.entryThrows : void 0;
|
|
283787
284743
|
const profile = isGateProfile(opts.profile) ? opts.profile : void 0;
|
|
283788
284744
|
if (opts.fix) {
|
|
283789
|
-
await runCheckFix({
|
|
284745
|
+
const fix = await runCheckFix({
|
|
283790
284746
|
targets,
|
|
283791
284747
|
only: opts.only,
|
|
283792
284748
|
write: opts.write === true,
|
|
@@ -283794,6 +284750,9 @@ function registerCheckCommand(program3) {
|
|
|
283794
284750
|
entryThrows,
|
|
283795
284751
|
profile
|
|
283796
284752
|
});
|
|
284753
|
+
if (fix.residualErrors > 0) {
|
|
284754
|
+
process.exitCode = 1;
|
|
284755
|
+
}
|
|
283797
284756
|
return;
|
|
283798
284757
|
}
|
|
283799
284758
|
const shared = {
|
|
@@ -283817,13 +284776,14 @@ function registerCheckCommand(program3) {
|
|
|
283817
284776
|
const wantMulti = targets.length > 1 || allPathErrors.length > 0;
|
|
283818
284777
|
if (wantMulti) {
|
|
283819
284778
|
const collected = [];
|
|
284779
|
+
const gateFlags = {};
|
|
283820
284780
|
for (const t of targets) {
|
|
283821
|
-
await runCheck(t, { ...shared, json: true, jsonCollect: collected });
|
|
284781
|
+
await runCheck(t, { ...shared, json: true, jsonCollect: collected, gateFlags });
|
|
283822
284782
|
}
|
|
283823
284783
|
const { serializeCheckJsonMulti: multi } = await Promise.resolve().then(() => (init_src(), src_exports));
|
|
283824
284784
|
const envelope = attachPathErrors(multi(collected), allPathErrors);
|
|
283825
284785
|
console.log(JSON.stringify(envelope, null, 2));
|
|
283826
|
-
process.exitCode = envelope.ok ? 0 : 1;
|
|
284786
|
+
process.exitCode = envelope.ok && !gateFlags.injectionSetupFailed ? 0 : 1;
|
|
283827
284787
|
return;
|
|
283828
284788
|
}
|
|
283829
284789
|
if (targets.length === 1) {
|
|
@@ -284046,13 +285006,13 @@ async function runTest(file, opts = {}) {
|
|
|
284046
285006
|
if (report.failed > 0 || pathErrors.length > 0) process.exitCode = 1;
|
|
284047
285007
|
else process.exitCode = 0;
|
|
284048
285008
|
} else if (opts.abs) {
|
|
284049
|
-
const report = buildTestReport(filePath, result);
|
|
285009
|
+
const report = buildTestReport(displayPathOf(filePath), result);
|
|
284050
285010
|
await runAbsView(filePath, {});
|
|
284051
285011
|
console.log("");
|
|
284052
285012
|
console.log(formatTestReport(report));
|
|
284053
285013
|
if (report.failed > 0) process.exitCode = 1;
|
|
284054
285014
|
} else {
|
|
284055
|
-
const report = buildTestReport(filePath, result);
|
|
285015
|
+
const report = buildTestReport(displayPathOf(filePath), result);
|
|
284056
285016
|
console.log(formatTestReport(report));
|
|
284057
285017
|
if (report.failed > 0) process.exitCode = 1;
|
|
284058
285018
|
}
|
|
@@ -284091,8 +285051,17 @@ freeze \u2192 ${relPath} (${directiveCount} directive(s) across ${emitOut.writte
|
|
|
284091
285051
|
}
|
|
284092
285052
|
}
|
|
284093
285053
|
function registerTestCommand(program3) {
|
|
284094
|
-
program3.command("test").description("Report every inferred case (call@/entry@ + debug witnesses); assert declared expectations").argument("
|
|
285054
|
+
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
285055
|
async (paths, opts) => {
|
|
285056
|
+
if (paths.length === 0) {
|
|
285057
|
+
if (opts.from?.length) {
|
|
285058
|
+
variadicSwallowError("test", ["--from"]);
|
|
285059
|
+
return;
|
|
285060
|
+
}
|
|
285061
|
+
console.error("Usage error: `nudo test` needs at least one path.");
|
|
285062
|
+
process.exitCode = 1;
|
|
285063
|
+
return;
|
|
285064
|
+
}
|
|
284096
285065
|
const targets = [];
|
|
284097
285066
|
const pathErrors = [];
|
|
284098
285067
|
for (const p of paths) {
|
|
@@ -284481,6 +285450,10 @@ function registerContractCommand(program3) {
|
|
|
284481
285450
|
return;
|
|
284482
285451
|
}
|
|
284483
285452
|
if (paths.length === 0) {
|
|
285453
|
+
if (opts.from?.length) {
|
|
285454
|
+
variadicSwallowError("contract", ["--from"]);
|
|
285455
|
+
return;
|
|
285456
|
+
}
|
|
284484
285457
|
console.error(
|
|
284485
285458
|
"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
285459
|
);
|
|
@@ -284572,11 +285545,11 @@ function registerContractCommand(program3) {
|
|
|
284572
285545
|
}
|
|
284573
285546
|
|
|
284574
285547
|
// src/commands/export.ts
|
|
285548
|
+
import { readFileSync as readFileSync26, writeFileSync as writeFileSync9, mkdirSync as mkdirSync6 } from "fs";
|
|
285549
|
+
import { resolve as resolve17, relative as relative10, join as join18, basename as basename8 } from "path";
|
|
284575
285550
|
init_src();
|
|
284576
285551
|
init_emit2();
|
|
284577
285552
|
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
285553
|
|
|
284581
285554
|
// src/export-format.ts
|
|
284582
285555
|
var EXPORT_FORMATS = ["schema", "standard", "guard", "dts", "all"];
|
|
@@ -284704,34 +285677,50 @@ ${mod2.source}`);
|
|
|
284704
285677
|
const schemaModule = Object.keys(schemaExports).length > 0 ? absToZodSchemaModule(schemaExports) : void 0;
|
|
284705
285678
|
if (output) {
|
|
284706
285679
|
const outDir = resolve17(output);
|
|
284707
|
-
|
|
285680
|
+
const ioError = (op) => ({
|
|
285681
|
+
path: outDir,
|
|
285682
|
+
code: "nudo:path-io",
|
|
285683
|
+
message: `export --out ${op} failed: ${displayPathOf(outDir)}`,
|
|
285684
|
+
suggestion: `check --out <dir> is writable and the path is a directory, then re-run nudo export`
|
|
285685
|
+
});
|
|
285686
|
+
try {
|
|
285687
|
+
mkdirSync6(outDir, { recursive: true });
|
|
285688
|
+
} catch {
|
|
285689
|
+
reportPathErrors([ioError("mkdir")]);
|
|
285690
|
+
return;
|
|
285691
|
+
}
|
|
284708
285692
|
const written = [];
|
|
284709
|
-
|
|
284710
|
-
|
|
284711
|
-
|
|
284712
|
-
|
|
284713
|
-
|
|
284714
|
-
|
|
284715
|
-
|
|
284716
|
-
const
|
|
284717
|
-
|
|
284718
|
-
|
|
284719
|
-
|
|
285693
|
+
try {
|
|
285694
|
+
if (schemaModule) {
|
|
285695
|
+
const p = join18(outDir, schemaFileName(stem, effectiveDialect));
|
|
285696
|
+
writeFileSync9(p, schemaModule.source, "utf-8");
|
|
285697
|
+
written.push(p);
|
|
285698
|
+
}
|
|
285699
|
+
if (standardChunks.length > 0) {
|
|
285700
|
+
for (const chunk of standardChunks) {
|
|
285701
|
+
const m = chunk.match(/\/\/ === (\S+) Standard Schema ===/);
|
|
285702
|
+
const fnStem = m?.[1] ?? stem;
|
|
285703
|
+
const p = join18(outDir, `${fnStem}.nudo.standard.ts`);
|
|
285704
|
+
const header = `// @generated by nudo export --format standard \u2014 Standard Schema v1 (vendor: nudo)
|
|
284720
285705
|
`;
|
|
284721
|
-
|
|
284722
|
-
|
|
285706
|
+
const body = chunk.startsWith("\n") ? chunk.slice(1) : chunk;
|
|
285707
|
+
writeFileSync9(p, body.includes("@generated") ? body + "\n" : header + body + "\n", "utf-8");
|
|
285708
|
+
written.push(p);
|
|
285709
|
+
}
|
|
285710
|
+
}
|
|
285711
|
+
if (guardChunks.length > 0) {
|
|
285712
|
+
const p = join18(outDir, `${stem}.nudo.guard.ts`);
|
|
285713
|
+
writeFileSync9(p, guardChunks.join("\n") + "\n", "utf-8");
|
|
284723
285714
|
written.push(p);
|
|
284724
285715
|
}
|
|
284725
|
-
|
|
284726
|
-
|
|
284727
|
-
|
|
284728
|
-
|
|
284729
|
-
|
|
284730
|
-
}
|
|
284731
|
-
|
|
284732
|
-
|
|
284733
|
-
writeFileSync9(p, dtsChunks.join("\n") + "\n", "utf-8");
|
|
284734
|
-
written.push(p);
|
|
285716
|
+
if (dtsChunks.length > 0) {
|
|
285717
|
+
const p = join18(outDir, `${stem}.d.ts`);
|
|
285718
|
+
writeFileSync9(p, dtsChunks.join("\n") + "\n", "utf-8");
|
|
285719
|
+
written.push(p);
|
|
285720
|
+
}
|
|
285721
|
+
} catch {
|
|
285722
|
+
reportPathErrors([ioError("write")]);
|
|
285723
|
+
return;
|
|
284735
285724
|
}
|
|
284736
285725
|
for (const p of written) {
|
|
284737
285726
|
console.log(`wrote ${relative10(process.cwd(), p)}`);
|
|
@@ -284776,21 +285765,30 @@ function registerExportCommand(program3) {
|
|
|
284776
285765
|
process.exitCode = 1;
|
|
284777
285766
|
return;
|
|
284778
285767
|
}
|
|
284779
|
-
|
|
285768
|
+
const { targets, errors } = resolveTargetsCollect(file);
|
|
285769
|
+
if (errors.length > 0) {
|
|
285770
|
+
reportPathErrors(errors);
|
|
285771
|
+
return;
|
|
285772
|
+
}
|
|
285773
|
+
if (targets.length !== 1) {
|
|
285774
|
+
console.error(
|
|
285775
|
+
`error: export takes exactly one analysis file (got ${targets.length} from ${file})`
|
|
285776
|
+
);
|
|
285777
|
+
console.error("fix: pass the single .js/.mjs/.ts file to project");
|
|
285778
|
+
process.exitCode = 1;
|
|
285779
|
+
return;
|
|
285780
|
+
}
|
|
285781
|
+
await runExport(targets[0], format, options.out, dialect);
|
|
284780
285782
|
}
|
|
284781
285783
|
);
|
|
284782
285784
|
}
|
|
284783
285785
|
|
|
284784
285786
|
// src/commands/health.ts
|
|
284785
285787
|
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
|
-
};
|
|
285788
|
+
import { readFileSync as readFileSync27, existsSync as existsSync25, statSync as statSync14 } from "fs";
|
|
285789
|
+
import { resolve as resolve18, dirname as dirname26 } from "path";
|
|
284792
285790
|
async function healthFile(filePath, records) {
|
|
284793
|
-
const report = { file:
|
|
285791
|
+
const report = { file: displayPathOf(filePath), functions: 0, entryOnly: 0, uncovered: [] };
|
|
284794
285792
|
let source;
|
|
284795
285793
|
try {
|
|
284796
285794
|
source = readFileSync27(filePath, "utf-8");
|
|
@@ -284859,13 +285857,16 @@ async function countInterfaceDrift(filePath) {
|
|
|
284859
285857
|
}
|
|
284860
285858
|
if (!/@generated/.test(scSrc)) return { count: 0 };
|
|
284861
285859
|
try {
|
|
284862
|
-
const { findProjectConfig: findProjectConfig3, interfaceConfig: interfaceConfig3 } = await Promise.resolve().then(() => (init_src4(), src_exports4));
|
|
285860
|
+
const { collectSkipReturns: collectSkipReturns2, findProjectConfig: findProjectConfig3, interfaceConfig: interfaceConfig3 } = await Promise.resolve().then(() => (init_src4(), src_exports4));
|
|
284863
285861
|
const proj = findProjectConfig3(dirname26(abs2));
|
|
284864
285862
|
const autoBind = interfaceConfig3(proj?.config).autoBind;
|
|
284865
|
-
const
|
|
285863
|
+
const source = rf(abs2, "utf-8");
|
|
285864
|
+
const r = checkSource2(abs2, source, pTrue3, {
|
|
284866
285865
|
loadModule: defaultLoadModule3,
|
|
284867
285866
|
fromFile: abs2,
|
|
284868
|
-
...autoBind === false ? { autoBind: false } : {}
|
|
285867
|
+
...autoBind === false ? { autoBind: false } : {},
|
|
285868
|
+
// 与 nudo check 同源:@nudo:skip 的函数不评估 body,不产出 drift 候选
|
|
285869
|
+
skips: collectSkipReturns2(source)
|
|
284869
285870
|
});
|
|
284870
285871
|
return { count: r.issues.filter((i) => i.code === "nudo:interface-drift").length };
|
|
284871
285872
|
} catch (e) {
|
|
@@ -284874,13 +285875,14 @@ async function countInterfaceDrift(filePath) {
|
|
|
284874
285875
|
}
|
|
284875
285876
|
async function runHealth(paths, opts) {
|
|
284876
285877
|
const targetPaths = paths.length > 0 ? paths : ["."];
|
|
284877
|
-
const
|
|
285878
|
+
const fromErrors = [];
|
|
285879
|
+
const externalRecords = opts.from?.length ? collectExternalRecords(opts.from, fromErrors) : void 0;
|
|
284878
285880
|
const files = [];
|
|
284879
285881
|
const reports = [];
|
|
284880
285882
|
for (const p of targetPaths) {
|
|
284881
285883
|
const abs2 = resolve18(p);
|
|
284882
|
-
if (!
|
|
284883
|
-
reports.push({ file:
|
|
285884
|
+
if (!existsSync25(abs2)) {
|
|
285885
|
+
reports.push({ file: displayPathOf(abs2), functions: 0, entryOnly: 0, uncovered: [], error: `File not found: ${displayPathOf(abs2)}` });
|
|
284884
285886
|
continue;
|
|
284885
285887
|
}
|
|
284886
285888
|
files.push(...statSync14(abs2).isDirectory() ? collectNudoFiles(abs2) : [abs2]);
|
|
@@ -284893,11 +285895,21 @@ async function runHealth(paths, opts) {
|
|
|
284893
285895
|
const errorCount = reports.filter((r) => r.error).length;
|
|
284894
285896
|
const uncoveredTotal = reports.reduce((n, r) => n + r.uncovered.length, 0);
|
|
284895
285897
|
const failed = driftCount > 0 || ifaceDriftCount > 0 || errorCount > 0;
|
|
285898
|
+
const ok2 = !failed && fromErrors.length === 0;
|
|
285899
|
+
process.exitCode = ok2 ? 0 : 1;
|
|
284896
285900
|
if (opts.json) {
|
|
284897
285901
|
console.log(
|
|
284898
285902
|
JSON.stringify(
|
|
284899
285903
|
{
|
|
284900
|
-
ok:
|
|
285904
|
+
ok: ok2,
|
|
285905
|
+
...fromErrors.length > 0 ? {
|
|
285906
|
+
pathErrors: fromErrors.map((e) => ({
|
|
285907
|
+
path: e.path,
|
|
285908
|
+
code: e.code,
|
|
285909
|
+
message: e.message,
|
|
285910
|
+
suggestion: e.suggestion
|
|
285911
|
+
}))
|
|
285912
|
+
} : {},
|
|
284901
285913
|
files: reports.map((r) => ({
|
|
284902
285914
|
file: r.file,
|
|
284903
285915
|
functions: r.functions,
|
|
@@ -284912,7 +285924,7 @@ async function runHealth(paths, opts) {
|
|
|
284912
285924
|
files: reports.length,
|
|
284913
285925
|
drift: driftCount,
|
|
284914
285926
|
interfaceDrift: ifaceDriftCount,
|
|
284915
|
-
errors: errorCount,
|
|
285927
|
+
errors: errorCount + fromErrors.length,
|
|
284916
285928
|
uncovered: uncoveredTotal,
|
|
284917
285929
|
internal_fallbacks: reports.reduce((n, r) => n + (r.internalFallbacks ?? 0), 0)
|
|
284918
285930
|
}
|
|
@@ -284922,8 +285934,16 @@ async function runHealth(paths, opts) {
|
|
|
284922
285934
|
)
|
|
284923
285935
|
);
|
|
284924
285936
|
} else {
|
|
285937
|
+
for (const e of fromErrors) {
|
|
285938
|
+
console.error(e.message);
|
|
285939
|
+
console.error(`fix: ${e.suggestion}`);
|
|
285940
|
+
}
|
|
284925
285941
|
if (reports.length === 0) {
|
|
284926
|
-
|
|
285942
|
+
if (fromErrors.length > 0) {
|
|
285943
|
+
console.log("Result: FAIL (path errors found)");
|
|
285944
|
+
} else {
|
|
285945
|
+
console.log("No files to check.");
|
|
285946
|
+
}
|
|
284927
285947
|
return;
|
|
284928
285948
|
}
|
|
284929
285949
|
for (const r of reports) {
|
|
@@ -284962,12 +285982,27 @@ async function runHealth(paths, opts) {
|
|
|
284962
285982
|
`
|
|
284963
285983
|
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
285984
|
);
|
|
284965
|
-
console.log(
|
|
285985
|
+
console.log(
|
|
285986
|
+
ok2 ? "Result: OK (uncovered function(s) are informational only)" : fromErrors.length > 0 && !failed ? "Result: FAIL (path errors found)" : "Result: FAIL (drift or errors found)"
|
|
285987
|
+
);
|
|
284966
285988
|
}
|
|
284967
|
-
if (failed) process.exitCode = 1;
|
|
284968
285989
|
}
|
|
284969
285990
|
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) => {
|
|
285991
|
+
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) => {
|
|
285992
|
+
if (opts.from?.length) {
|
|
285993
|
+
if (opts.from.length > 1) {
|
|
285994
|
+
variadicSwallowError("health", ["--from"]);
|
|
285995
|
+
return;
|
|
285996
|
+
}
|
|
285997
|
+
if (paths.length === 0) {
|
|
285998
|
+
console.error(
|
|
285999
|
+
"error: `nudo health` --from requires explicit paths when used without positional paths (previously defaulted to cwd scan)"
|
|
286000
|
+
);
|
|
286001
|
+
console.error("fix: use: `nudo health . --from usage.js`");
|
|
286002
|
+
process.exitCode = 1;
|
|
286003
|
+
return;
|
|
286004
|
+
}
|
|
286005
|
+
}
|
|
284971
286006
|
const fromPaths = opts.from;
|
|
284972
286007
|
const runOneDir = async () => {
|
|
284973
286008
|
await runHealth(paths, { ...fromPaths ? { from: fromPaths } : {}, json: opts.json });
|
|
@@ -285099,7 +286134,7 @@ function registerMigrateCommand(program3) {
|
|
|
285099
286134
|
|
|
285100
286135
|
// src/index.ts
|
|
285101
286136
|
var program2 = new Command();
|
|
285102
|
-
var argv = process.argv
|
|
286137
|
+
var argv = process.argv[2] === "--" ? [process.argv[0], process.argv[1], ...process.argv.slice(3)] : process.argv;
|
|
285103
286138
|
program2.name("nudo").description("JavaScript types, computed \u2014 check / test / contract / export / health / migrate").version(formatVersionOutput()).addHelpText(
|
|
285104
286139
|
"after",
|
|
285105
286140
|
`
|