@vibgrate/cli 2026.611.3 → 2026.615.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{baseline-AXQGF3QD.js → baseline-4E3WWG4W.js} +2 -2
- package/dist/{chunk-DMVLVXIP.js → chunk-Y3VTYTQR.js} +1 -1
- package/dist/{chunk-VP7PK4VN.js → chunk-ZDCFG3EB.js} +517 -153
- package/dist/cli.js +882 -4
- package/dist/hcs-worker.js +323 -12
- package/dist/index.js +1 -1
- package/package.json +1 -1
package/dist/hcs-worker.js
CHANGED
|
@@ -2507,7 +2507,7 @@ var require_typescript = __commonJS({
|
|
|
2507
2507
|
SymbolDisplayPartKind: () => SymbolDisplayPartKind,
|
|
2508
2508
|
SymbolFlags: () => SymbolFlags,
|
|
2509
2509
|
SymbolFormatFlags: () => SymbolFormatFlags,
|
|
2510
|
-
SyntaxKind: () =>
|
|
2510
|
+
SyntaxKind: () => SyntaxKind20,
|
|
2511
2511
|
Ternary: () => Ternary,
|
|
2512
2512
|
ThrottledCancellationToken: () => ThrottledCancellationToken,
|
|
2513
2513
|
TokenClass: () => TokenClass,
|
|
@@ -6398,7 +6398,7 @@ Node ${formatSyntaxKind(node.kind)} was unexpected.`,
|
|
|
6398
6398
|
function formatSyntaxKind(kind) {
|
|
6399
6399
|
return formatEnum(
|
|
6400
6400
|
kind,
|
|
6401
|
-
|
|
6401
|
+
SyntaxKind20,
|
|
6402
6402
|
/*isFlags*/
|
|
6403
6403
|
false
|
|
6404
6404
|
);
|
|
@@ -7846,7 +7846,7 @@ ${lanes.join("\n")}
|
|
|
7846
7846
|
})(tracingEnabled || (tracingEnabled = {}));
|
|
7847
7847
|
var startTracing = tracingEnabled.startTracing;
|
|
7848
7848
|
var dumpTracingLegend = tracingEnabled.dumpLegend;
|
|
7849
|
-
var
|
|
7849
|
+
var SyntaxKind20 = /* @__PURE__ */ ((SyntaxKind52) => {
|
|
7850
7850
|
SyntaxKind52[SyntaxKind52["Unknown"] = 0] = "Unknown";
|
|
7851
7851
|
SyntaxKind52[SyntaxKind52["EndOfFileToken"] = 1] = "EndOfFileToken";
|
|
7852
7852
|
SyntaxKind52[SyntaxKind52["SingleLineCommentTrivia"] = 2] = "SingleLineCommentTrivia";
|
|
@@ -8352,7 +8352,7 @@ ${lanes.join("\n")}
|
|
|
8352
8352
|
/* LastKeyword */
|
|
8353
8353
|
] = "LastContextualKeyword";
|
|
8354
8354
|
return SyntaxKind52;
|
|
8355
|
-
})(
|
|
8355
|
+
})(SyntaxKind20 || {});
|
|
8356
8356
|
var NodeFlags = /* @__PURE__ */ ((NodeFlags3) => {
|
|
8357
8357
|
NodeFlags3[NodeFlags3["None"] = 0] = "None";
|
|
8358
8358
|
NodeFlags3[NodeFlags3["Let"] = 1] = "Let";
|
|
@@ -198758,7 +198758,7 @@ ${options.prefix}` : "\n" : options.prefix
|
|
|
198758
198758
|
SymbolDisplayPartKind: () => SymbolDisplayPartKind,
|
|
198759
198759
|
SymbolFlags: () => SymbolFlags,
|
|
198760
198760
|
SymbolFormatFlags: () => SymbolFormatFlags,
|
|
198761
|
-
SyntaxKind: () =>
|
|
198761
|
+
SyntaxKind: () => SyntaxKind20,
|
|
198762
198762
|
Ternary: () => Ternary,
|
|
198763
198763
|
ThrottledCancellationToken: () => ThrottledCancellationToken,
|
|
198764
198764
|
TokenClass: () => TokenClass,
|
|
@@ -293077,7 +293077,7 @@ function useColor() {
|
|
|
293077
293077
|
var program = new Command();
|
|
293078
293078
|
|
|
293079
293079
|
// src/main.ts
|
|
293080
|
-
var
|
|
293080
|
+
var import_ts_morph20 = __toESM(require_ts_morph(), 1);
|
|
293081
293081
|
|
|
293082
293082
|
// src/facts/fact-emitter.ts
|
|
293083
293083
|
init_esm_shims();
|
|
@@ -293206,6 +293206,21 @@ var NdjsonFactEmitter = class {
|
|
|
293206
293206
|
emitHookDeclared(p) {
|
|
293207
293207
|
this.emit("HookDeclared", p.hookId, p);
|
|
293208
293208
|
}
|
|
293209
|
+
// ── Behavioural specification facts (Phase 0) ────────────
|
|
293210
|
+
// Seeded by the assertion/spec content hash so identical code + identical
|
|
293211
|
+
// corpus yield identical factIds — the predictability guarantee.
|
|
293212
|
+
emitBehaviouralAssertion(p) {
|
|
293213
|
+
this.emit("BehaviouralAssertion", p.assertionId, p);
|
|
293214
|
+
}
|
|
293215
|
+
emitBehaviouralSpec(p) {
|
|
293216
|
+
this.emit("BehaviouralSpec", p.specId, p);
|
|
293217
|
+
}
|
|
293218
|
+
emitValidationRuleObserved(p) {
|
|
293219
|
+
this.emit("ValidationRuleObserved", p.ruleId, p);
|
|
293220
|
+
}
|
|
293221
|
+
emitMethodLogicObserved(p) {
|
|
293222
|
+
this.emit("MethodLogicObserved", p.logicId, p);
|
|
293223
|
+
}
|
|
293209
293224
|
emitCopybookResolved(p) {
|
|
293210
293225
|
this.emit("CopybookResolved", p.copybookId, p);
|
|
293211
293226
|
}
|
|
@@ -293598,6 +293613,7 @@ var RouteExtractor = class _RouteExtractor {
|
|
|
293598
293613
|
}
|
|
293599
293614
|
}
|
|
293600
293615
|
this.extractExpressRoutes(sf, filePath, emitter);
|
|
293616
|
+
this.extractArrayRegisteredRoutes(sf, filePath, emitter);
|
|
293601
293617
|
}
|
|
293602
293618
|
}
|
|
293603
293619
|
extractNestJsController(cls, filePath, emitter) {
|
|
@@ -293618,9 +293634,12 @@ var RouteExtractor = class _RouteExtractor {
|
|
|
293618
293634
|
httpMethod,
|
|
293619
293635
|
routePath: fullRoute,
|
|
293620
293636
|
handlerType: controllerName,
|
|
293621
|
-
|
|
293637
|
+
// Qualified so it matches the method-logic container and DAO callerSymbol.
|
|
293638
|
+
handlerName: `${controllerName}.${method.getName()}`,
|
|
293622
293639
|
filePath,
|
|
293623
|
-
startLine: method.getStartLineNumber()
|
|
293640
|
+
startLine: method.getStartLineNumber(),
|
|
293641
|
+
handlerStartLine: method.getStartLineNumber(),
|
|
293642
|
+
handlerEndLine: method.getEndLineNumber()
|
|
293624
293643
|
});
|
|
293625
293644
|
const requiresAuth = this.hasDecorator(method, "UseGuards") || this.hasDecorator(cls, "UseGuards");
|
|
293626
293645
|
emitter.emitEndpointMetadata({
|
|
@@ -293675,6 +293694,9 @@ var RouteExtractor = class _RouteExtractor {
|
|
|
293675
293694
|
if (httpMethod === "USE" || httpMethod === "ROUTE") continue;
|
|
293676
293695
|
const fullRoute = this.normalisePath(routePath);
|
|
293677
293696
|
const routeId = `route:${httpMethod.toLowerCase()}:${fullRoute}`;
|
|
293697
|
+
const handlerArg = args[args.length - 1];
|
|
293698
|
+
const hk = handlerArg.getKind();
|
|
293699
|
+
const inlineHandler = hk === import_ts_morph2.SyntaxKind.ArrowFunction || hk === import_ts_morph2.SyntaxKind.FunctionExpression;
|
|
293678
293700
|
emitter.emitRouteDeclared({
|
|
293679
293701
|
routeId,
|
|
293680
293702
|
httpMethod,
|
|
@@ -293682,7 +293704,9 @@ var RouteExtractor = class _RouteExtractor {
|
|
|
293682
293704
|
handlerType: "Express",
|
|
293683
293705
|
handlerName: `${httpMethod.toLowerCase()}:${fullRoute}`,
|
|
293684
293706
|
filePath,
|
|
293685
|
-
startLine: call.getStartLineNumber()
|
|
293707
|
+
startLine: call.getStartLineNumber(),
|
|
293708
|
+
handlerStartLine: inlineHandler ? handlerArg.getStartLineNumber() : void 0,
|
|
293709
|
+
handlerEndLine: inlineHandler ? handlerArg.getEndLineNumber() : void 0
|
|
293686
293710
|
});
|
|
293687
293711
|
emitter.emitEndpointMetadata({
|
|
293688
293712
|
routeId,
|
|
@@ -293724,6 +293748,92 @@ var RouteExtractor = class _RouteExtractor {
|
|
|
293724
293748
|
}
|
|
293725
293749
|
return text;
|
|
293726
293750
|
}
|
|
293751
|
+
/**
|
|
293752
|
+
* Routes registered by iterating an array of paths:
|
|
293753
|
+
* const paths = ['/a','/b']; paths.forEach((p) => router.get(p, handler));
|
|
293754
|
+
* The per-element `router.get(p, …)` calls are skipped by extractExpressRoutes
|
|
293755
|
+
* (the path arg is a variable, not a literal), so resolve them here.
|
|
293756
|
+
*/
|
|
293757
|
+
extractArrayRegisteredRoutes(sf, filePath, emitter) {
|
|
293758
|
+
for (const call of sf.getDescendantsOfKind(import_ts_morph2.SyntaxKind.CallExpression)) {
|
|
293759
|
+
const expr = call.getExpression();
|
|
293760
|
+
if (!import_ts_morph2.Node.isPropertyAccessExpression(expr)) continue;
|
|
293761
|
+
const iter = expr.getName();
|
|
293762
|
+
if (iter !== "forEach" && iter !== "map") continue;
|
|
293763
|
+
const cb = call.getArguments()[0];
|
|
293764
|
+
const cbk = cb?.getKind?.();
|
|
293765
|
+
if (cbk !== import_ts_morph2.SyntaxKind.ArrowFunction && cbk !== import_ts_morph2.SyntaxKind.FunctionExpression) continue;
|
|
293766
|
+
const params = cb.getParameters?.() ?? [];
|
|
293767
|
+
if (params.length === 0) continue;
|
|
293768
|
+
const loopVar = params[0].getName();
|
|
293769
|
+
const body = cb.getBody?.();
|
|
293770
|
+
if (!body) continue;
|
|
293771
|
+
const calls = [];
|
|
293772
|
+
if (body.getKind?.() === import_ts_morph2.SyntaxKind.CallExpression) calls.push(body);
|
|
293773
|
+
calls.push(...body.getDescendantsOfKind?.(import_ts_morph2.SyntaxKind.CallExpression) ?? []);
|
|
293774
|
+
let method = null;
|
|
293775
|
+
for (const ic of calls) {
|
|
293776
|
+
const ie = ic.getExpression();
|
|
293777
|
+
if (!import_ts_morph2.Node.isPropertyAccessExpression(ie)) continue;
|
|
293778
|
+
const m = ie.getName();
|
|
293779
|
+
if (!_RouteExtractor.EXPRESS_METHODS.has(m)) continue;
|
|
293780
|
+
const recv = ie.getExpression().getText();
|
|
293781
|
+
if (!recv.includes("app") && !recv.includes("router") && !recv.includes("server")) continue;
|
|
293782
|
+
const iargs = ic.getArguments();
|
|
293783
|
+
if (iargs.length < 1 || iargs[0].getText() !== loopVar) continue;
|
|
293784
|
+
method = m;
|
|
293785
|
+
break;
|
|
293786
|
+
}
|
|
293787
|
+
if (!method) continue;
|
|
293788
|
+
const httpMethod = method.toUpperCase();
|
|
293789
|
+
if (httpMethod === "USE" || httpMethod === "ROUTE") continue;
|
|
293790
|
+
for (const raw of this.resolveStringArray(expr.getExpression())) {
|
|
293791
|
+
const fullRoute = this.normalisePath(raw);
|
|
293792
|
+
const routeId = `route:${httpMethod.toLowerCase()}:${fullRoute}`;
|
|
293793
|
+
emitter.emitRouteDeclared({
|
|
293794
|
+
routeId,
|
|
293795
|
+
httpMethod,
|
|
293796
|
+
routePath: fullRoute,
|
|
293797
|
+
handlerType: "Express",
|
|
293798
|
+
handlerName: `${httpMethod.toLowerCase()}:${fullRoute}`,
|
|
293799
|
+
filePath,
|
|
293800
|
+
startLine: call.getStartLineNumber()
|
|
293801
|
+
});
|
|
293802
|
+
emitter.emitEndpointMetadata({
|
|
293803
|
+
routeId,
|
|
293804
|
+
operationId: null,
|
|
293805
|
+
tags: [],
|
|
293806
|
+
summary: null,
|
|
293807
|
+
responseTypes: [],
|
|
293808
|
+
requiresAuth: false,
|
|
293809
|
+
producesProblems: false
|
|
293810
|
+
});
|
|
293811
|
+
}
|
|
293812
|
+
}
|
|
293813
|
+
}
|
|
293814
|
+
/** Resolve an array expression (literal or a const-bound identifier) to its string elements. */
|
|
293815
|
+
resolveStringArray(node) {
|
|
293816
|
+
let arr = node;
|
|
293817
|
+
if (node?.getKind?.() === import_ts_morph2.SyntaxKind.Identifier) {
|
|
293818
|
+
const decls = node.getSymbol?.()?.getDeclarations?.() ?? [];
|
|
293819
|
+
for (const d of decls) {
|
|
293820
|
+
if (d.getKind?.() === import_ts_morph2.SyntaxKind.VariableDeclaration) {
|
|
293821
|
+
const init = d.getInitializer?.();
|
|
293822
|
+
if (init?.getKind?.() === import_ts_morph2.SyntaxKind.ArrayLiteralExpression) {
|
|
293823
|
+
arr = init;
|
|
293824
|
+
break;
|
|
293825
|
+
}
|
|
293826
|
+
}
|
|
293827
|
+
}
|
|
293828
|
+
}
|
|
293829
|
+
if (arr?.getKind?.() !== import_ts_morph2.SyntaxKind.ArrayLiteralExpression) return [];
|
|
293830
|
+
const out = [];
|
|
293831
|
+
for (const el of arr.getElements?.() ?? []) {
|
|
293832
|
+
const s = this.extractStringLiteral(el);
|
|
293833
|
+
if (s !== null) out.push(s);
|
|
293834
|
+
}
|
|
293835
|
+
return out;
|
|
293836
|
+
}
|
|
293727
293837
|
extractStringLiteral(node) {
|
|
293728
293838
|
const text = node.getText();
|
|
293729
293839
|
if (text.startsWith("'") && text.endsWith("'") || text.startsWith('"') && text.endsWith('"')) {
|
|
@@ -295388,6 +295498,7 @@ var DataAccessOperationExtractor = class _DataAccessOperationExtractor {
|
|
|
295388
295498
|
if (paramFlows.length > 0) {
|
|
295389
295499
|
this.applyParameterFlows(steps, paramFlows);
|
|
295390
295500
|
}
|
|
295501
|
+
steps.push(...this.extractGuards(method, steps.length + 1));
|
|
295391
295502
|
const payload = {
|
|
295392
295503
|
operationId: `dao:${filePath}:${line}`,
|
|
295393
295504
|
callerSymbol,
|
|
@@ -295414,6 +295525,7 @@ var DataAccessOperationExtractor = class _DataAccessOperationExtractor {
|
|
|
295414
295525
|
const steps = this.extractSteps(ormCalls, filePath);
|
|
295415
295526
|
const semanticKind = this.inferSemanticKind(steps);
|
|
295416
295527
|
const targetEntity = this.inferTargetEntity(ormCalls);
|
|
295528
|
+
steps.push(...this.extractGuards(func, steps.length + 1));
|
|
295417
295529
|
const returnType = func.getReturnType()?.getText() ?? null;
|
|
295418
295530
|
const returnsCollection = returnType ? /\[\]|Array/.test(returnType) : null;
|
|
295419
295531
|
const transactionScope = this.detectFunctionTransactionScope(func);
|
|
@@ -295442,6 +295554,7 @@ var DataAccessOperationExtractor = class _DataAccessOperationExtractor {
|
|
|
295442
295554
|
const steps = this.extractSteps(ormCalls, filePath);
|
|
295443
295555
|
const semanticKind = this.inferSemanticKind(steps);
|
|
295444
295556
|
const targetEntity = this.inferTargetEntity(ormCalls);
|
|
295557
|
+
steps.push(...this.extractGuards(arrow, steps.length + 1));
|
|
295445
295558
|
const payload = {
|
|
295446
295559
|
operationId: `dao:${filePath}:${line}`,
|
|
295447
295560
|
callerSymbol: name,
|
|
@@ -295495,6 +295608,39 @@ var DataAccessOperationExtractor = class _DataAccessOperationExtractor {
|
|
|
295495
295608
|
}
|
|
295496
295609
|
return steps;
|
|
295497
295610
|
}
|
|
295611
|
+
// ── Guard extraction (Phase 1.5: feeds HXL invariants) ────────────
|
|
295612
|
+
// Capture `if (cond) throw|return` early-exit guards inside a data-access
|
|
295613
|
+
// body as guard steps carrying the condition text. The deriver lowers each
|
|
295614
|
+
// predicateExpression through HXL into a static invariant.
|
|
295615
|
+
extractGuards(node, startOrder) {
|
|
295616
|
+
const out = [];
|
|
295617
|
+
let order = startOrder;
|
|
295618
|
+
let ifs = [];
|
|
295619
|
+
try {
|
|
295620
|
+
ifs = node.getDescendantsOfKind(import_ts_morph6.SyntaxKind.IfStatement);
|
|
295621
|
+
} catch {
|
|
295622
|
+
return out;
|
|
295623
|
+
}
|
|
295624
|
+
for (const ifStmt of ifs) {
|
|
295625
|
+
const then = ifStmt.getThenStatement?.();
|
|
295626
|
+
if (!then) continue;
|
|
295627
|
+
const stmts = then.getKind?.() === import_ts_morph6.SyntaxKind.Block ? then.getStatements() : [then];
|
|
295628
|
+
const exit = stmts.find(
|
|
295629
|
+
(s) => s.getKind() === import_ts_morph6.SyntaxKind.ThrowStatement || s.getKind() === import_ts_morph6.SyntaxKind.ReturnStatement
|
|
295630
|
+
);
|
|
295631
|
+
if (!exit) continue;
|
|
295632
|
+
const cond = ifStmt.getExpression?.()?.getText?.();
|
|
295633
|
+
if (!cond) continue;
|
|
295634
|
+
const isThrow = exit.getKind() === import_ts_morph6.SyntaxKind.ThrowStatement;
|
|
295635
|
+
let thrown = null;
|
|
295636
|
+
if (isThrow) {
|
|
295637
|
+
const e = exit.getExpression?.();
|
|
295638
|
+
thrown = e ? e.getText() : null;
|
|
295639
|
+
}
|
|
295640
|
+
out.push({ order: order++, kind: "guard", predicateExpression: cond, throwsOnFail: isThrow, sourceExpression: thrown });
|
|
295641
|
+
}
|
|
295642
|
+
return out;
|
|
295643
|
+
}
|
|
295498
295644
|
mapMethodToStep(method, call, order, filePath) {
|
|
295499
295645
|
const args = call.getArguments();
|
|
295500
295646
|
const firstArgText = args.length > 0 ? args[0].getText() : null;
|
|
@@ -298112,6 +298258,169 @@ var SqlObjectDeclaredExtractor = class {
|
|
|
298112
298258
|
}
|
|
298113
298259
|
};
|
|
298114
298260
|
|
|
298261
|
+
// src/extractors/validation-schema.ts
|
|
298262
|
+
init_esm_shims();
|
|
298263
|
+
var import_ts_morph18 = __toESM(require_ts_morph(), 1);
|
|
298264
|
+
var ValidationSchemaExtractor = class {
|
|
298265
|
+
async extract(sourceFiles, emitter) {
|
|
298266
|
+
const seen = /* @__PURE__ */ new Set();
|
|
298267
|
+
for (const sf of sourceFiles) {
|
|
298268
|
+
const filePath = sf.getFilePath();
|
|
298269
|
+
const calls = sf.getDescendantsOfKind(import_ts_morph18.SyntaxKind.CallExpression);
|
|
298270
|
+
for (const call of calls) {
|
|
298271
|
+
const exprText = call.getExpression().getText();
|
|
298272
|
+
if (exprText !== "z.object" && exprText !== "zod.object") continue;
|
|
298273
|
+
const args = call.getArguments();
|
|
298274
|
+
if (args.length === 0 || args[0].getKind() !== import_ts_morph18.SyntaxKind.ObjectLiteralExpression) continue;
|
|
298275
|
+
const schemaName = this.resolveSchemaName(call);
|
|
298276
|
+
const obj = args[0];
|
|
298277
|
+
for (const prop of obj.getProperties()) {
|
|
298278
|
+
if (prop.getKind() !== import_ts_morph18.SyntaxKind.PropertyAssignment) continue;
|
|
298279
|
+
const fieldName = prop.getName?.();
|
|
298280
|
+
const init = prop.getInitializer?.();
|
|
298281
|
+
if (!fieldName || !init) continue;
|
|
298282
|
+
const parsed = this.parseZodChain(init);
|
|
298283
|
+
if (!parsed) continue;
|
|
298284
|
+
const line = prop.getStartLineNumber();
|
|
298285
|
+
for (const r of parsed.rules) {
|
|
298286
|
+
const ruleId = `${schemaName}:${fieldName}:${r.rule}:${r.arg ?? ""}`;
|
|
298287
|
+
if (seen.has(ruleId)) continue;
|
|
298288
|
+
seen.add(ruleId);
|
|
298289
|
+
emitter.emitValidationRuleObserved({
|
|
298290
|
+
ruleId,
|
|
298291
|
+
schemaName,
|
|
298292
|
+
fieldName,
|
|
298293
|
+
fieldType: parsed.baseType,
|
|
298294
|
+
rule: r.rule,
|
|
298295
|
+
arg: r.arg,
|
|
298296
|
+
framework: "zod",
|
|
298297
|
+
filePath,
|
|
298298
|
+
line
|
|
298299
|
+
});
|
|
298300
|
+
}
|
|
298301
|
+
}
|
|
298302
|
+
}
|
|
298303
|
+
}
|
|
298304
|
+
}
|
|
298305
|
+
/** Walk up to the VariableDeclaration holding the z.object, for a schema name. */
|
|
298306
|
+
resolveSchemaName(call) {
|
|
298307
|
+
let node = call;
|
|
298308
|
+
for (let i = 0; i < 8 && node; i++) {
|
|
298309
|
+
node = node.getParent?.();
|
|
298310
|
+
if (node?.getKind?.() === import_ts_morph18.SyntaxKind.VariableDeclaration) {
|
|
298311
|
+
return node.getName?.() ?? "<anonymous>";
|
|
298312
|
+
}
|
|
298313
|
+
}
|
|
298314
|
+
return "<anonymous>";
|
|
298315
|
+
}
|
|
298316
|
+
/** Peel a zod method chain into a base type + ordered rules. */
|
|
298317
|
+
parseZodChain(node) {
|
|
298318
|
+
const rules = [];
|
|
298319
|
+
let baseType = "unknown";
|
|
298320
|
+
let cur = node;
|
|
298321
|
+
for (let guard = 0; guard < 50 && cur; guard++) {
|
|
298322
|
+
if (cur.getKind?.() !== import_ts_morph18.SyntaxKind.CallExpression) break;
|
|
298323
|
+
const callExpr = cur.getExpression?.();
|
|
298324
|
+
if (!callExpr || callExpr.getKind() !== import_ts_morph18.SyntaxKind.PropertyAccessExpression) break;
|
|
298325
|
+
const method = callExpr.getName();
|
|
298326
|
+
const obj = callExpr.getExpression();
|
|
298327
|
+
const objText = obj.getText?.();
|
|
298328
|
+
if (obj.getKind() === import_ts_morph18.SyntaxKind.Identifier && (objText === "z" || objText === "zod")) {
|
|
298329
|
+
baseType = method;
|
|
298330
|
+
break;
|
|
298331
|
+
}
|
|
298332
|
+
const args = cur.getArguments?.() ?? [];
|
|
298333
|
+
const arg = args.length > 0 ? args[0].getText().replace(/_/g, "") : null;
|
|
298334
|
+
rules.push({ rule: method, arg });
|
|
298335
|
+
cur = obj;
|
|
298336
|
+
}
|
|
298337
|
+
rules.reverse();
|
|
298338
|
+
return { baseType, rules };
|
|
298339
|
+
}
|
|
298340
|
+
};
|
|
298341
|
+
|
|
298342
|
+
// src/extractors/method-logic.ts
|
|
298343
|
+
init_esm_shims();
|
|
298344
|
+
var import_ts_morph19 = __toESM(require_ts_morph(), 1);
|
|
298345
|
+
var MethodLogicExtractor = class {
|
|
298346
|
+
async extract(sourceFiles, emitter) {
|
|
298347
|
+
for (const sf of sourceFiles) {
|
|
298348
|
+
const filePath = sf.getFilePath();
|
|
298349
|
+
const seen = /* @__PURE__ */ new Set();
|
|
298350
|
+
for (const ifStmt of sf.getDescendantsOfKind(import_ts_morph19.SyntaxKind.IfStatement)) {
|
|
298351
|
+
const then = ifStmt.getThenStatement();
|
|
298352
|
+
if (!then) continue;
|
|
298353
|
+
const stmts = then.getKind() === import_ts_morph19.SyntaxKind.Block ? then.getStatements() : [then];
|
|
298354
|
+
const exit = stmts.find(
|
|
298355
|
+
(s) => s.getKind() === import_ts_morph19.SyntaxKind.ThrowStatement || s.getKind() === import_ts_morph19.SyntaxKind.ReturnStatement
|
|
298356
|
+
);
|
|
298357
|
+
if (!exit) continue;
|
|
298358
|
+
const cond = ifStmt.getExpression()?.getText();
|
|
298359
|
+
if (!cond) continue;
|
|
298360
|
+
const isThrow = exit.getKind() === import_ts_morph19.SyntaxKind.ThrowStatement;
|
|
298361
|
+
const container = this.containerOf(ifStmt);
|
|
298362
|
+
const line = ifStmt.getStartLineNumber();
|
|
298363
|
+
const logicId = `${container}:guard:${line}`;
|
|
298364
|
+
if (seen.has(logicId)) continue;
|
|
298365
|
+
seen.add(logicId);
|
|
298366
|
+
emitter.emitMethodLogicObserved({
|
|
298367
|
+
logicId,
|
|
298368
|
+
containerSymbol: container,
|
|
298369
|
+
kind: "guard",
|
|
298370
|
+
expression: cond,
|
|
298371
|
+
effect: isThrow ? "throw" : "return",
|
|
298372
|
+
throwsType: isThrow ? exit.getExpression?.()?.getText() ?? null : null,
|
|
298373
|
+
filePath,
|
|
298374
|
+
line
|
|
298375
|
+
});
|
|
298376
|
+
}
|
|
298377
|
+
for (const ret of sf.getDescendantsOfKind(import_ts_morph19.SyntaxKind.ReturnStatement)) {
|
|
298378
|
+
const expr = ret.getExpression();
|
|
298379
|
+
if (!expr) continue;
|
|
298380
|
+
const k = expr.getKind();
|
|
298381
|
+
if (k !== import_ts_morph19.SyntaxKind.BinaryExpression && k !== import_ts_morph19.SyntaxKind.ConditionalExpression) continue;
|
|
298382
|
+
const container = this.containerOf(ret);
|
|
298383
|
+
const line = ret.getStartLineNumber();
|
|
298384
|
+
const logicId = `${container}:return:${line}`;
|
|
298385
|
+
if (seen.has(logicId)) continue;
|
|
298386
|
+
seen.add(logicId);
|
|
298387
|
+
emitter.emitMethodLogicObserved({
|
|
298388
|
+
logicId,
|
|
298389
|
+
containerSymbol: container,
|
|
298390
|
+
kind: "return",
|
|
298391
|
+
expression: expr.getText(),
|
|
298392
|
+
effect: null,
|
|
298393
|
+
throwsType: null,
|
|
298394
|
+
filePath,
|
|
298395
|
+
line
|
|
298396
|
+
});
|
|
298397
|
+
}
|
|
298398
|
+
}
|
|
298399
|
+
}
|
|
298400
|
+
/** Resolve the qualified symbol of the enclosing function/method. */
|
|
298401
|
+
containerOf(node) {
|
|
298402
|
+
let n = node;
|
|
298403
|
+
for (let i = 0; i < 30 && n; i++) {
|
|
298404
|
+
n = n.getParent?.();
|
|
298405
|
+
if (!n) break;
|
|
298406
|
+
const k = n.getKind?.();
|
|
298407
|
+
if (k === import_ts_morph19.SyntaxKind.MethodDeclaration) {
|
|
298408
|
+
const cls = n.getFirstAncestorByKind?.(import_ts_morph19.SyntaxKind.ClassDeclaration);
|
|
298409
|
+
const clsName = cls?.getName?.() ?? "<anon>";
|
|
298410
|
+
return `${clsName}.${n.getName?.() ?? "<anon>"}`;
|
|
298411
|
+
}
|
|
298412
|
+
if (k === import_ts_morph19.SyntaxKind.FunctionDeclaration) {
|
|
298413
|
+
return n.getName?.() ?? "<anon>";
|
|
298414
|
+
}
|
|
298415
|
+
if (k === import_ts_morph19.SyntaxKind.ArrowFunction || k === import_ts_morph19.SyntaxKind.FunctionExpression) {
|
|
298416
|
+
const vd = n.getFirstAncestorByKind?.(import_ts_morph19.SyntaxKind.VariableDeclaration);
|
|
298417
|
+
if (vd) return vd.getName?.() ?? "<anon>";
|
|
298418
|
+
}
|
|
298419
|
+
}
|
|
298420
|
+
return "<module>";
|
|
298421
|
+
}
|
|
298422
|
+
};
|
|
298423
|
+
|
|
298115
298424
|
// src/extractors/swift-api-calls.ts
|
|
298116
298425
|
init_esm_shims();
|
|
298117
298426
|
var SwiftApiCallExtractor = class {
|
|
@@ -373173,13 +373482,13 @@ function emitProgress(event) {
|
|
|
373173
373482
|
}
|
|
373174
373483
|
function createProject(projectPath) {
|
|
373175
373484
|
if (projectPath.endsWith("tsconfig.json")) {
|
|
373176
|
-
return new
|
|
373485
|
+
return new import_ts_morph20.Project({ tsConfigFilePath: projectPath });
|
|
373177
373486
|
}
|
|
373178
373487
|
const tsconfigPath = resolve2(projectPath, "tsconfig.json");
|
|
373179
373488
|
if (existsSync3(tsconfigPath)) {
|
|
373180
|
-
return new
|
|
373489
|
+
return new import_ts_morph20.Project({ tsConfigFilePath: tsconfigPath });
|
|
373181
373490
|
}
|
|
373182
|
-
const project = new
|
|
373491
|
+
const project = new import_ts_morph20.Project({
|
|
373183
373492
|
compilerOptions: {
|
|
373184
373493
|
allowJs: true,
|
|
373185
373494
|
checkJs: false,
|
|
@@ -373223,6 +373532,8 @@ async function runExtractors(sourceFiles, emitter) {
|
|
|
373223
373532
|
new EventConsumedExtractor(),
|
|
373224
373533
|
new ExternalServiceCallExtractor(),
|
|
373225
373534
|
new SqlObjectDeclaredExtractor(),
|
|
373535
|
+
new ValidationSchemaExtractor(),
|
|
373536
|
+
new MethodLogicExtractor(),
|
|
373226
373537
|
// Frontend / UI extractors
|
|
373227
373538
|
new ComponentExtractor(),
|
|
373228
373539
|
new ClientRouteExtractor(),
|
package/dist/index.js
CHANGED