cognium-dev 3.30.0 → 3.34.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.
Files changed (2) hide show
  1. package/dist/cli.js +785 -9
  2. package/package.json +2 -2
package/dist/cli.js CHANGED
@@ -8990,6 +8990,754 @@ function findChildByTypeGo(node, type) {
8990
8990
  }
8991
8991
  return null;
8992
8992
  }
8993
+ // ../circle-ir/dist/core/extractors/runtime-registrations.js
8994
+ var HTTP_VERB_METHODS = new Set([
8995
+ "get",
8996
+ "post",
8997
+ "put",
8998
+ "patch",
8999
+ "delete",
9000
+ "head",
9001
+ "options",
9002
+ "all"
9003
+ ]);
9004
+ var MIDDLEWARE_METHODS = new Set(["use"]);
9005
+ var EVENT_LISTENER_METHODS = new Set(["on", "once", "ws"]);
9006
+ var EXPRESS_RECEIVER_NAMES = new Set([
9007
+ "app",
9008
+ "router",
9009
+ "server",
9010
+ "apiRouter",
9011
+ "fastify",
9012
+ "koa",
9013
+ "express"
9014
+ ]);
9015
+ var FRAMEWORK_MODULE_PATTERNS = [
9016
+ /^express$/,
9017
+ /^@?fastify(\/.*)?$/,
9018
+ /^koa$/,
9019
+ /^restify$/,
9020
+ /^hapi$/,
9021
+ /^@nestjs\/common$/,
9022
+ /^@nestjs\/core$/
9023
+ ];
9024
+ function extractRuntimeRegistrations(tree, cache, language, imports) {
9025
+ if (language === "javascript" || language === "typescript") {
9026
+ return extractJSRuntimeRegistrations(tree, cache, imports);
9027
+ }
9028
+ if (language === "python") {
9029
+ return extractPythonRuntimeRegistrations(tree, cache, imports);
9030
+ }
9031
+ if (language === "rust") {
9032
+ return extractRustRuntimeRegistrations(tree, cache);
9033
+ }
9034
+ return [];
9035
+ }
9036
+ function buildHandlerIndex(tree, cache, imports) {
9037
+ const decls = new Map;
9038
+ const recordDeclaration = (name2, node) => {
9039
+ if (!decls.has(name2)) {
9040
+ decls.set(name2, {
9041
+ line: node.startPosition.row + 1,
9042
+ column: node.startPosition.column
9043
+ });
9044
+ }
9045
+ };
9046
+ for (const fn of getNodesFromCache(tree.rootNode, "function_declaration", cache)) {
9047
+ const nameNode = fn.childForFieldName("name");
9048
+ if (nameNode)
9049
+ recordDeclaration(getNodeText(nameNode), fn);
9050
+ }
9051
+ const collectVarDeclarators = (parentType) => {
9052
+ for (const decl of getNodesFromCache(tree.rootNode, parentType, cache)) {
9053
+ for (let i2 = 0;i2 < decl.childCount; i2++) {
9054
+ const child = decl.child(i2);
9055
+ if (!child || child.type !== "variable_declarator")
9056
+ continue;
9057
+ const nameNode = child.childForFieldName("name");
9058
+ const valueNode = child.childForFieldName("value");
9059
+ if (!nameNode || !valueNode)
9060
+ continue;
9061
+ if (valueNode.type === "arrow_function" || valueNode.type === "function_expression" || valueNode.type === "function") {
9062
+ recordDeclaration(getNodeText(nameNode), child);
9063
+ }
9064
+ }
9065
+ }
9066
+ };
9067
+ collectVarDeclarators("lexical_declaration");
9068
+ collectVarDeclarators("variable_declaration");
9069
+ let hasFrameworkImport = false;
9070
+ if (imports) {
9071
+ for (const imp of imports) {
9072
+ const mod = imp.from_package ?? "";
9073
+ if (mod && FRAMEWORK_MODULE_PATTERNS.some((re) => re.test(mod))) {
9074
+ hasFrameworkImport = true;
9075
+ break;
9076
+ }
9077
+ }
9078
+ }
9079
+ return { declarations: decls, hasFrameworkImport };
9080
+ }
9081
+ function extractJSRuntimeRegistrations(tree, cache, imports) {
9082
+ const out2 = [];
9083
+ const index = buildHandlerIndex(tree, cache, imports);
9084
+ const callExpressions = getNodesFromCache(tree.rootNode, "call_expression", cache);
9085
+ for (const call of callExpressions) {
9086
+ const fnNode = call.childForFieldName("function");
9087
+ if (!fnNode || fnNode.type !== "member_expression")
9088
+ continue;
9089
+ const objectNode = fnNode.childForFieldName("object");
9090
+ const propertyNode = fnNode.childForFieldName("property");
9091
+ if (!objectNode || !propertyNode)
9092
+ continue;
9093
+ const method = getNodeText(propertyNode);
9094
+ const receiver = getNodeText(objectNode);
9095
+ const kind = classifyMethod(method);
9096
+ if (!kind)
9097
+ continue;
9098
+ if (!isExpressShapedReceiver(receiver) && !index.hasFrameworkImport) {
9099
+ continue;
9100
+ }
9101
+ const argsNode = call.childForFieldName("arguments");
9102
+ if (!argsNode)
9103
+ continue;
9104
+ const argNodes = getRealArgs(argsNode);
9105
+ if (argNodes.length === 0)
9106
+ continue;
9107
+ let path;
9108
+ let handlerStart = 0;
9109
+ const first = argNodes[0];
9110
+ if (first.type === "string") {
9111
+ path = stripQuotes(getNodeText(first));
9112
+ handlerStart = 1;
9113
+ } else if (first.type === "template_string" && !hasTemplateSubstitution(first)) {
9114
+ path = stripBackticks(getNodeText(first));
9115
+ handlerStart = 1;
9116
+ }
9117
+ for (let i2 = handlerStart;i2 < argNodes.length; i2++) {
9118
+ const handlerNode = argNodes[i2];
9119
+ const handler = resolveHandler(handlerNode, index);
9120
+ if (!handler)
9121
+ continue;
9122
+ out2.push({
9123
+ kind,
9124
+ framework: inferFramework(receiver, index.hasFrameworkImport),
9125
+ registrar: {
9126
+ method,
9127
+ receiver,
9128
+ line: call.startPosition.row + 1,
9129
+ column: call.startPosition.column
9130
+ },
9131
+ ...path !== undefined ? { path } : {},
9132
+ handler
9133
+ });
9134
+ }
9135
+ }
9136
+ return out2;
9137
+ }
9138
+ function classifyMethod(method) {
9139
+ if (HTTP_VERB_METHODS.has(method))
9140
+ return "http_route";
9141
+ if (MIDDLEWARE_METHODS.has(method))
9142
+ return "middleware";
9143
+ if (EVENT_LISTENER_METHODS.has(method))
9144
+ return "event_listener";
9145
+ return null;
9146
+ }
9147
+ function isExpressShapedReceiver(receiver) {
9148
+ if (EXPRESS_RECEIVER_NAMES.has(receiver))
9149
+ return true;
9150
+ if (/(?:Router|App|Server)$/.test(receiver))
9151
+ return true;
9152
+ return false;
9153
+ }
9154
+ function inferFramework(receiver, hasFrameworkImport) {
9155
+ if (receiver === "fastify")
9156
+ return "fastify";
9157
+ if (receiver === "koa")
9158
+ return "koa";
9159
+ if (receiver === "express")
9160
+ return "express";
9161
+ return hasFrameworkImport ? "express" : "unknown";
9162
+ }
9163
+ function getRealArgs(argsNode) {
9164
+ const out2 = [];
9165
+ for (let i2 = 0;i2 < argsNode.childCount; i2++) {
9166
+ const child = argsNode.child(i2);
9167
+ if (!child)
9168
+ continue;
9169
+ if (child.type === "(" || child.type === ")" || child.type === ",")
9170
+ continue;
9171
+ out2.push(child);
9172
+ }
9173
+ return out2;
9174
+ }
9175
+ function stripQuotes(s) {
9176
+ if (s.length >= 2 && (s[0] === '"' || s[0] === "'") && s[s.length - 1] === s[0]) {
9177
+ return s.slice(1, -1);
9178
+ }
9179
+ return s;
9180
+ }
9181
+ function stripBackticks(s) {
9182
+ if (s.length >= 2 && s[0] === "`" && s[s.length - 1] === "`") {
9183
+ return s.slice(1, -1);
9184
+ }
9185
+ return s;
9186
+ }
9187
+ function hasTemplateSubstitution(node) {
9188
+ for (let i2 = 0;i2 < node.childCount; i2++) {
9189
+ const child = node.child(i2);
9190
+ if (child && child.type === "template_substitution")
9191
+ return true;
9192
+ }
9193
+ return false;
9194
+ }
9195
+ function resolveHandler(node, index) {
9196
+ if (node.type === "arrow_function" || node.type === "function_expression" || node.type === "function") {
9197
+ return {
9198
+ name: null,
9199
+ line: node.startPosition.row + 1,
9200
+ column: node.startPosition.column
9201
+ };
9202
+ }
9203
+ if (node.type === "identifier") {
9204
+ const name2 = getNodeText(node);
9205
+ const decl = index.declarations.get(name2);
9206
+ if (decl) {
9207
+ return { name: name2, line: decl.line, column: decl.column };
9208
+ }
9209
+ return {
9210
+ name: name2,
9211
+ line: node.startPosition.row + 1,
9212
+ column: node.startPosition.column
9213
+ };
9214
+ }
9215
+ if (node.type === "member_expression") {
9216
+ return {
9217
+ name: getNodeText(node),
9218
+ line: node.startPosition.row + 1,
9219
+ column: node.startPosition.column
9220
+ };
9221
+ }
9222
+ return null;
9223
+ }
9224
+ var PY_HTTP_ROUTE_METHODS = new Set([
9225
+ "route",
9226
+ "get",
9227
+ "post",
9228
+ "put",
9229
+ "patch",
9230
+ "delete",
9231
+ "head",
9232
+ "options"
9233
+ ]);
9234
+ var PY_MIDDLEWARE_METHODS = new Set([
9235
+ "before_request",
9236
+ "after_request",
9237
+ "teardown_request",
9238
+ "before_first_request",
9239
+ "teardown_appcontext",
9240
+ "middleware"
9241
+ ]);
9242
+ var PY_EVENT_METHODS = new Set([
9243
+ "errorhandler",
9244
+ "on_event",
9245
+ "exception_handler"
9246
+ ]);
9247
+ var PY_STDLIB_DECORATORS = new Set([
9248
+ "property",
9249
+ "staticmethod",
9250
+ "classmethod",
9251
+ "abstractmethod",
9252
+ "cached_property",
9253
+ "dataclass",
9254
+ "cache",
9255
+ "lru_cache",
9256
+ "singledispatch",
9257
+ "singledispatchmethod",
9258
+ "contextmanager",
9259
+ "asynccontextmanager",
9260
+ "final",
9261
+ "override",
9262
+ "wraps"
9263
+ ]);
9264
+ function summarisePythonImports(imports) {
9265
+ const s = {
9266
+ hasFlask: false,
9267
+ hasFastApi: false,
9268
+ hasCelery: false,
9269
+ hasNumba: false,
9270
+ hasClick: false,
9271
+ hasPytest: false
9272
+ };
9273
+ if (!imports)
9274
+ return s;
9275
+ for (const imp of imports) {
9276
+ const mod = imp.from_package ?? "";
9277
+ if (!mod)
9278
+ continue;
9279
+ if (/^flask(\b|\.)/.test(mod))
9280
+ s.hasFlask = true;
9281
+ if (/^fastapi(\b|\.)/.test(mod) || /^starlette(\b|\.)/.test(mod))
9282
+ s.hasFastApi = true;
9283
+ if (/^celery(\b|\.)/.test(mod))
9284
+ s.hasCelery = true;
9285
+ if (/^numba(\b|\.)/.test(mod))
9286
+ s.hasNumba = true;
9287
+ if (/^click(\b|\.)/.test(mod))
9288
+ s.hasClick = true;
9289
+ if (/^pytest(\b|\.)/.test(mod))
9290
+ s.hasPytest = true;
9291
+ }
9292
+ return s;
9293
+ }
9294
+ function extractPythonRuntimeRegistrations(tree, cache, imports) {
9295
+ const out2 = [];
9296
+ const importSummary = summarisePythonImports(imports);
9297
+ const decoratedDefs = getNodesFromCache(tree.rootNode, "decorated_definition", cache);
9298
+ for (const dd of decoratedDefs) {
9299
+ let fnNode = null;
9300
+ const decorators = [];
9301
+ for (let i2 = 0;i2 < dd.childCount; i2++) {
9302
+ const child = dd.child(i2);
9303
+ if (!child)
9304
+ continue;
9305
+ if (child.type === "decorator") {
9306
+ decorators.push(child);
9307
+ } else if (child.type === "function_definition" || child.type === "async_function_definition") {
9308
+ fnNode = child;
9309
+ }
9310
+ }
9311
+ if (!fnNode || decorators.length === 0)
9312
+ continue;
9313
+ const handler = pythonHandlerFromFunctionDef(fnNode);
9314
+ if (!handler)
9315
+ continue;
9316
+ for (const dec of decorators) {
9317
+ const parsed = parsePythonDecorator(dec);
9318
+ if (!parsed)
9319
+ continue;
9320
+ const { receiver, method, path, line, column } = parsed;
9321
+ const { kind, framework } = classifyPythonDecorator(receiver, method, importSummary);
9322
+ out2.push({
9323
+ kind,
9324
+ framework,
9325
+ registrar: { method, receiver, line, column },
9326
+ ...path !== undefined ? { path } : {},
9327
+ handler
9328
+ });
9329
+ }
9330
+ }
9331
+ return out2;
9332
+ }
9333
+ function pythonHandlerFromFunctionDef(fn) {
9334
+ const nameNode = fn.childForFieldName("name");
9335
+ if (!nameNode)
9336
+ return null;
9337
+ return {
9338
+ name: getNodeText(nameNode),
9339
+ line: fn.startPosition.row + 1,
9340
+ column: fn.startPosition.column
9341
+ };
9342
+ }
9343
+ function parsePythonDecorator(dec) {
9344
+ let target = null;
9345
+ for (let i2 = 0;i2 < dec.childCount; i2++) {
9346
+ const child = dec.child(i2);
9347
+ if (!child || child.type === "@")
9348
+ continue;
9349
+ target = child;
9350
+ break;
9351
+ }
9352
+ if (!target)
9353
+ return null;
9354
+ const line = dec.startPosition.row + 1;
9355
+ const column = dec.startPosition.column;
9356
+ if (target.type === "identifier") {
9357
+ return { receiver: "", method: getNodeText(target), line, column };
9358
+ }
9359
+ if (target.type === "attribute") {
9360
+ const { receiver, method } = splitDottedAttribute(target);
9361
+ return { receiver, method, line, column };
9362
+ }
9363
+ if (target.type === "call") {
9364
+ const fnNode = target.childForFieldName("function");
9365
+ if (!fnNode)
9366
+ return null;
9367
+ let receiver = "";
9368
+ let method = "";
9369
+ if (fnNode.type === "identifier") {
9370
+ method = getNodeText(fnNode);
9371
+ } else if (fnNode.type === "attribute") {
9372
+ const split = splitDottedAttribute(fnNode);
9373
+ receiver = split.receiver;
9374
+ method = split.method;
9375
+ } else {
9376
+ method = getNodeText(fnNode);
9377
+ }
9378
+ const path = extractFirstStringArg(target);
9379
+ return { receiver, method, path, line, column };
9380
+ }
9381
+ return null;
9382
+ }
9383
+ function splitDottedAttribute(attr) {
9384
+ const objectNode = attr.childForFieldName("object");
9385
+ const attrNode = attr.childForFieldName("attribute");
9386
+ const method = attrNode ? getNodeText(attrNode) : "";
9387
+ const receiver = objectNode ? getNodeText(objectNode) : "";
9388
+ return { receiver, method };
9389
+ }
9390
+ function extractFirstStringArg(call) {
9391
+ const argsNode = call.childForFieldName("arguments");
9392
+ if (!argsNode)
9393
+ return;
9394
+ for (let i2 = 0;i2 < argsNode.childCount; i2++) {
9395
+ const child = argsNode.child(i2);
9396
+ if (!child)
9397
+ continue;
9398
+ if (child.type === "(" || child.type === ")" || child.type === ",")
9399
+ continue;
9400
+ if (child.type === "string") {
9401
+ return stripPythonStringQuotes(getNodeText(child));
9402
+ }
9403
+ return;
9404
+ }
9405
+ return;
9406
+ }
9407
+ function stripPythonStringQuotes(s) {
9408
+ const m = s.match(/^[bBrRuUfF]{0,2}(['"])(.*)\1$/s);
9409
+ if (m)
9410
+ return m[2];
9411
+ if (s.length >= 2 && (s[0] === '"' || s[0] === "'") && s[s.length - 1] === s[0]) {
9412
+ return s.slice(1, -1);
9413
+ }
9414
+ return s;
9415
+ }
9416
+ function classifyPythonDecorator(receiver, method, imp) {
9417
+ if (!receiver && PY_STDLIB_DECORATORS.has(method)) {
9418
+ return { kind: "decorator", framework: "stdlib" };
9419
+ }
9420
+ if (receiver) {
9421
+ const head = receiver.split(".")[0];
9422
+ if (head === "pytest") {
9423
+ return { kind: "decorator", framework: "pytest" };
9424
+ }
9425
+ if (head === "click") {
9426
+ return { kind: "decorator", framework: "click" };
9427
+ }
9428
+ if (head === "numba" || head === "nb") {
9429
+ return { kind: "decorator", framework: "numba" };
9430
+ }
9431
+ if (head === "celery") {
9432
+ return { kind: "decorator", framework: "celery" };
9433
+ }
9434
+ }
9435
+ if (receiver && PY_HTTP_ROUTE_METHODS.has(method)) {
9436
+ const isRoutey = isPyRouterReceiver(receiver);
9437
+ if (isRoutey) {
9438
+ let framework = "unknown";
9439
+ if (imp.hasFlask)
9440
+ framework = "flask";
9441
+ else if (imp.hasFastApi)
9442
+ framework = "fastapi";
9443
+ else if (method === "route")
9444
+ framework = "flask";
9445
+ else
9446
+ framework = "fastapi";
9447
+ return { kind: "http_route", framework };
9448
+ }
9449
+ }
9450
+ if (receiver && PY_MIDDLEWARE_METHODS.has(method)) {
9451
+ return { kind: "middleware", framework: imp.hasFlask ? "flask" : imp.hasFastApi ? "fastapi" : "unknown" };
9452
+ }
9453
+ if (receiver && PY_EVENT_METHODS.has(method)) {
9454
+ return { kind: "event_listener", framework: imp.hasFlask ? "flask" : imp.hasFastApi ? "fastapi" : "unknown" };
9455
+ }
9456
+ if (method === "task" && imp.hasCelery) {
9457
+ return { kind: "decorator", framework: "celery" };
9458
+ }
9459
+ if (!receiver && (method === "login_required" || method === "require_http_methods" || method === "api_view")) {
9460
+ return { kind: "decorator", framework: "django" };
9461
+ }
9462
+ return { kind: "decorator", framework: "unknown" };
9463
+ }
9464
+ function isPyRouterReceiver(receiver) {
9465
+ const head = receiver.split(".")[0];
9466
+ if (!head)
9467
+ return false;
9468
+ if (["app", "router", "blueprint", "bp", "api", "application"].includes(head))
9469
+ return true;
9470
+ if (/_(router|bp|blueprint|app|api)$/.test(head))
9471
+ return true;
9472
+ return false;
9473
+ }
9474
+ var RUST_STDLIB_TRAITS = new Set([
9475
+ "Display",
9476
+ "Debug",
9477
+ "Write",
9478
+ "From",
9479
+ "Into",
9480
+ "TryFrom",
9481
+ "TryInto",
9482
+ "AsRef",
9483
+ "AsMut",
9484
+ "ToString",
9485
+ "FromStr",
9486
+ "Iterator",
9487
+ "IntoIterator",
9488
+ "FromIterator",
9489
+ "DoubleEndedIterator",
9490
+ "ExactSizeIterator",
9491
+ "FusedIterator",
9492
+ "PartialEq",
9493
+ "Eq",
9494
+ "PartialOrd",
9495
+ "Ord",
9496
+ "Hash",
9497
+ "Default",
9498
+ "Copy",
9499
+ "Clone",
9500
+ "Send",
9501
+ "Sync",
9502
+ "Unpin",
9503
+ "Sized",
9504
+ "Any",
9505
+ "Drop",
9506
+ "Future",
9507
+ "IntoFuture",
9508
+ "Add",
9509
+ "Sub",
9510
+ "Mul",
9511
+ "Div",
9512
+ "Rem",
9513
+ "Neg",
9514
+ "Not",
9515
+ "AddAssign",
9516
+ "SubAssign",
9517
+ "MulAssign",
9518
+ "DivAssign",
9519
+ "RemAssign",
9520
+ "BitAnd",
9521
+ "BitOr",
9522
+ "BitXor",
9523
+ "Shl",
9524
+ "Shr",
9525
+ "Deref",
9526
+ "DerefMut",
9527
+ "Index",
9528
+ "IndexMut",
9529
+ "Fn",
9530
+ "FnMut",
9531
+ "FnOnce",
9532
+ "Error",
9533
+ "Read",
9534
+ "Write",
9535
+ "Seek",
9536
+ "BufRead",
9537
+ "Borrow",
9538
+ "BorrowMut",
9539
+ "ToOwned"
9540
+ ]);
9541
+ var RUST_TRAIT_FRAMEWORK_PREFIXES = [
9542
+ { prefix: /^actix(_web)?(::|$)/, framework: "actix" },
9543
+ { prefix: /^axum(::|$)/, framework: "axum" },
9544
+ { prefix: /^rocket(::|$)/, framework: "rocket" },
9545
+ { prefix: /^tokio(::|$)/, framework: "tokio" },
9546
+ { prefix: /^serde(_\w+)?(::|$)/, framework: "serde" },
9547
+ { prefix: /^std(::|$)/, framework: "stdlib" },
9548
+ { prefix: /^core(::|$)/, framework: "stdlib" },
9549
+ { prefix: /^alloc(::|$)/, framework: "stdlib" }
9550
+ ];
9551
+ function extractRustRuntimeRegistrations(tree, cache) {
9552
+ const regs = [];
9553
+ const implNodes = getNodesFromCache(tree.rootNode, "impl_item", cache);
9554
+ for (const impl of implNodes) {
9555
+ collectRustImplRegistrations(impl, regs);
9556
+ }
9557
+ const macroNodes = getNodesFromCache(tree.rootNode, "macro_invocation", cache);
9558
+ for (const macro of macroNodes) {
9559
+ const rec = parseInventorySubmit(macro);
9560
+ if (rec)
9561
+ regs.push(rec);
9562
+ }
9563
+ const attrNodes = getNodesFromCache(tree.rootNode, "attribute_item", cache);
9564
+ for (const attr of attrNodes) {
9565
+ const rec = parseDistributedSliceAttribute(attr);
9566
+ if (rec)
9567
+ regs.push(rec);
9568
+ }
9569
+ return regs;
9570
+ }
9571
+ function collectRustImplRegistrations(impl, regs) {
9572
+ const traitNode = impl.childForFieldName("trait");
9573
+ if (!traitNode)
9574
+ return;
9575
+ const typeNode = impl.childForFieldName("type");
9576
+ if (!typeNode)
9577
+ return;
9578
+ const traitText = getNodeText(traitNode).trim();
9579
+ const traitLastSegment = lastRustPathSegment(stripRustGenerics(traitText));
9580
+ const selfType = getNodeText(typeNode).trim();
9581
+ const framework = classifyRustTrait(traitText);
9582
+ const body2 = impl.childForFieldName("body");
9583
+ if (!body2)
9584
+ return;
9585
+ for (let i2 = 0;i2 < body2.childCount; i2++) {
9586
+ const child = body2.child(i2);
9587
+ if (!child || child.type !== "function_item")
9588
+ continue;
9589
+ const nameNode = child.childForFieldName("name");
9590
+ if (!nameNode)
9591
+ continue;
9592
+ const methodName = getNodeText(nameNode);
9593
+ regs.push({
9594
+ kind: "trait_impl",
9595
+ framework,
9596
+ registrar: {
9597
+ method: methodName,
9598
+ receiver: selfType,
9599
+ line: impl.startPosition.row + 1,
9600
+ column: impl.startPosition.column
9601
+ },
9602
+ path: traitLastSegment || traitText,
9603
+ handler: {
9604
+ name: methodName,
9605
+ line: child.startPosition.row + 1,
9606
+ column: child.startPosition.column
9607
+ }
9608
+ });
9609
+ }
9610
+ }
9611
+ function stripRustGenerics(text) {
9612
+ const idx = text.indexOf("<");
9613
+ return idx >= 0 ? text.slice(0, idx) : text;
9614
+ }
9615
+ function lastRustPathSegment(path) {
9616
+ const parts2 = path.split("::");
9617
+ return parts2[parts2.length - 1] || path;
9618
+ }
9619
+ function classifyRustTrait(traitText) {
9620
+ const stripped = stripRustGenerics(traitText).trim();
9621
+ const last = lastRustPathSegment(stripped);
9622
+ if (RUST_STDLIB_TRAITS.has(last))
9623
+ return "stdlib";
9624
+ for (const { prefix, framework } of RUST_TRAIT_FRAMEWORK_PREFIXES) {
9625
+ if (prefix.test(stripped))
9626
+ return framework;
9627
+ }
9628
+ return "unknown";
9629
+ }
9630
+ function parseInventorySubmit(macro) {
9631
+ const macroName = macro.childForFieldName("macro");
9632
+ if (!macroName)
9633
+ return null;
9634
+ const name2 = getNodeText(macroName).trim();
9635
+ if (name2 !== "inventory::submit" && name2 !== "submit")
9636
+ return null;
9637
+ if (name2 === "submit")
9638
+ return null;
9639
+ let tokenTree = null;
9640
+ for (let i2 = 0;i2 < macro.childCount; i2++) {
9641
+ const c = macro.child(i2);
9642
+ if (c && c.type === "token_tree") {
9643
+ tokenTree = c;
9644
+ break;
9645
+ }
9646
+ }
9647
+ if (!tokenTree)
9648
+ return null;
9649
+ const handlerName = firstIdentifierInTokenTree(tokenTree);
9650
+ return {
9651
+ kind: "trait_impl",
9652
+ framework: "inventory",
9653
+ registrar: {
9654
+ method: "submit",
9655
+ receiver: "inventory",
9656
+ line: macro.startPosition.row + 1,
9657
+ column: macro.startPosition.column
9658
+ },
9659
+ path: "inventory::submit",
9660
+ handler: {
9661
+ name: handlerName,
9662
+ line: tokenTree.startPosition.row + 1,
9663
+ column: tokenTree.startPosition.column
9664
+ }
9665
+ };
9666
+ }
9667
+ function firstIdentifierInTokenTree(tokenTree) {
9668
+ for (let i2 = 0;i2 < tokenTree.childCount; i2++) {
9669
+ const c = tokenTree.child(i2);
9670
+ if (!c)
9671
+ continue;
9672
+ if (c.type === "identifier" || c.type === "scoped_identifier" || c.type === "type_identifier") {
9673
+ return getNodeText(c).trim();
9674
+ }
9675
+ }
9676
+ return null;
9677
+ }
9678
+ function parseDistributedSliceAttribute(attrItem) {
9679
+ let attr = null;
9680
+ for (let i2 = 0;i2 < attrItem.childCount; i2++) {
9681
+ const c = attrItem.child(i2);
9682
+ if (c && c.type === "attribute") {
9683
+ attr = c;
9684
+ break;
9685
+ }
9686
+ }
9687
+ if (!attr)
9688
+ return null;
9689
+ const pathNode = attr.child(0);
9690
+ if (!pathNode)
9691
+ return null;
9692
+ const pathText = getNodeText(pathNode).trim();
9693
+ if (pathText !== "linkme::distributed_slice" && pathText !== "distributed_slice")
9694
+ return null;
9695
+ const parent = attrItem.parent;
9696
+ if (!parent)
9697
+ return null;
9698
+ let attrIndex = -1;
9699
+ for (let i2 = 0;i2 < parent.childCount; i2++) {
9700
+ const c = parent.child(i2);
9701
+ if (c && c.id === attrItem.id) {
9702
+ attrIndex = i2;
9703
+ break;
9704
+ }
9705
+ }
9706
+ if (attrIndex < 0)
9707
+ return null;
9708
+ let handlerNode = null;
9709
+ for (let j = attrIndex + 1;j < parent.childCount; j++) {
9710
+ const sib = parent.child(j);
9711
+ if (!sib)
9712
+ continue;
9713
+ if (sib.type === "attribute_item")
9714
+ continue;
9715
+ if (sib.type === "static_item" || sib.type === "function_item") {
9716
+ handlerNode = sib;
9717
+ }
9718
+ break;
9719
+ }
9720
+ if (!handlerNode)
9721
+ return null;
9722
+ const nameNode = handlerNode.childForFieldName("name");
9723
+ const handlerName = nameNode ? getNodeText(nameNode).trim() : null;
9724
+ return {
9725
+ kind: "trait_impl",
9726
+ framework: "linkme",
9727
+ registrar: {
9728
+ method: "distributed_slice",
9729
+ receiver: "linkme",
9730
+ line: attrItem.startPosition.row + 1,
9731
+ column: attrItem.startPosition.column
9732
+ },
9733
+ path: "linkme::distributed_slice",
9734
+ handler: {
9735
+ name: handlerName,
9736
+ line: handlerNode.startPosition.row + 1,
9737
+ column: handlerNode.startPosition.column
9738
+ }
9739
+ };
9740
+ }
8993
9741
  // ../circle-ir/dist/analysis/config-loader.js
8994
9742
  var DEFAULT_SOURCES = [
8995
9743
  { method: "getParameter", class: "HttpServletRequest", type: "http_param", severity: "high", return_tainted: true },
@@ -9125,6 +9873,11 @@ var DEFAULT_SOURCES = [
9125
9873
  { method: "getContent", class: "Block", type: "io_input", severity: "high", return_tainted: true },
9126
9874
  { method: "getParameters", class: "Block", type: "io_input", severity: "high", return_tainted: true },
9127
9875
  { method: "getRawContent", type: "io_input", severity: "high", return_tainted: true },
9876
+ { method: "get", class: "XWikiRequest", type: "http_param", severity: "high", return_tainted: true },
9877
+ { method: "getParameter", class: "XWikiRequest", type: "http_param", severity: "high", return_tainted: true },
9878
+ { method: "getParameterValues", class: "XWikiRequest", type: "http_param", severity: "high", return_tainted: true },
9879
+ { method: "getParameterMap", class: "XWikiRequest", type: "http_param", severity: "high", return_tainted: true },
9880
+ { method: "getHeader", class: "XWikiRequest", type: "http_header", severity: "high", return_tainted: true },
9128
9881
  { method: "getAttributes", class: "XMLReader", type: "io_input", severity: "high", return_tainted: true },
9129
9882
  { method: "getValue", class: "Attributes", type: "io_input", severity: "high", return_tainted: true },
9130
9883
  { method: "getLocalName", class: "Attributes", type: "io_input", severity: "high", return_tainted: true },
@@ -9622,6 +10375,8 @@ var DEFAULT_SINKS = [
9622
10375
  { method: "eval", class: "MVEL", type: "code_injection", cwe: "CWE-94", severity: "critical", arg_positions: [0] },
9623
10376
  { method: "createValueExpression", class: "ExpressionFactory", type: "code_injection", cwe: "CWE-94", severity: "critical", arg_positions: [1] },
9624
10377
  { method: "createMethodExpression", class: "ExpressionFactory", type: "code_injection", cwe: "CWE-94", severity: "critical", arg_positions: [1] },
10378
+ { method: "evaluateAttributeExpressions", class: "PropertyValue", type: "code_injection", cwe: "CWE-94", severity: "critical", arg_positions: [] },
10379
+ { method: "evaluateAttributeExpressions", type: "code_injection", cwe: "CWE-94", severity: "critical", arg_positions: [] },
9625
10380
  { method: "evaluate", class: "GroovyShell", type: "code_injection", cwe: "CWE-94", severity: "critical", arg_positions: [0] },
9626
10381
  { method: "parse", class: "GroovyShell", type: "code_injection", cwe: "CWE-94", severity: "critical", arg_positions: [0] },
9627
10382
  { method: "parseClass", class: "GroovyClassLoader", type: "code_injection", cwe: "CWE-94", severity: "critical", arg_positions: [0] },
@@ -9775,6 +10530,21 @@ var DEFAULT_SINKS = [
9775
10530
  { method: "cleanAttributes", class: "XHTMLWikiPrinter", type: "xss", cwe: "CWE-79", severity: "high", arg_positions: [0] },
9776
10531
  { method: "printXMLElement", class: "XHTMLWikiPrinter", type: "xss", cwe: "CWE-79", severity: "high", arg_positions: [0] },
9777
10532
  { method: "printXMLStartElement", class: "XHTMLWikiPrinter", type: "xss", cwe: "CWE-79", severity: "high", arg_positions: [0] },
10533
+ { method: "print", class: "WikiPrinter", type: "xss", cwe: "CWE-79", severity: "high", arg_positions: [0] },
10534
+ { method: "println", class: "WikiPrinter", type: "xss", cwe: "CWE-79", severity: "high", arg_positions: [0] },
10535
+ { method: "print", class: "DefaultWikiPrinter", type: "xss", cwe: "CWE-79", severity: "high", arg_positions: [0] },
10536
+ { method: "println", class: "DefaultWikiPrinter", type: "xss", cwe: "CWE-79", severity: "high", arg_positions: [0] },
10537
+ { method: "print", class: "XHTMLWikiPrinter", type: "xss", cwe: "CWE-79", severity: "high", arg_positions: [0] },
10538
+ { method: "println", class: "XHTMLWikiPrinter", type: "xss", cwe: "CWE-79", severity: "high", arg_positions: [0] },
10539
+ { method: "printXML", class: "XHTMLWikiPrinter", type: "xss", cwe: "CWE-79", severity: "high", arg_positions: [0] },
10540
+ { method: "printXMLComment", class: "XHTMLWikiPrinter", type: "xss", cwe: "CWE-79", severity: "high", arg_positions: [0] },
10541
+ { method: "print", class: "AnnotatedXHTMLWikiPrinter", type: "xss", cwe: "CWE-79", severity: "high", arg_positions: [0] },
10542
+ { method: "println", class: "AnnotatedXHTMLWikiPrinter", type: "xss", cwe: "CWE-79", severity: "high", arg_positions: [0] },
10543
+ { method: "printXMLElement", class: "AnnotatedXHTMLWikiPrinter", type: "xss", cwe: "CWE-79", severity: "high", arg_positions: [0] },
10544
+ { method: "printXMLStartElement", class: "AnnotatedXHTMLWikiPrinter", type: "xss", cwe: "CWE-79", severity: "high", arg_positions: [0] },
10545
+ { method: "render", class: "BlockRenderer", type: "xss", cwe: "CWE-79", severity: "high", arg_positions: [0] },
10546
+ { method: "render", class: "AbstractBlockRenderer", type: "xss", cwe: "CWE-79", severity: "high", arg_positions: [0] },
10547
+ { method: "render", class: "DefaultBlockRenderer", type: "xss", cwe: "CWE-79", severity: "high", arg_positions: [0] },
9778
10548
  { method: "initialize", class: "HTML5Renderer", type: "xss", cwe: "CWE-79", severity: "high", arg_positions: [0] },
9779
10549
  { method: "initialize", class: "XHTMLRenderer", type: "xss", cwe: "CWE-79", severity: "high", arg_positions: [0] },
9780
10550
  { method: "beginFormat", class: "HTML5ChainingRenderer", type: "xss", cwe: "CWE-79", severity: "high", arg_positions: [0] },
@@ -17880,7 +18650,7 @@ function extractEventHandlers(elementNode, eventHandlers) {
17880
18650
  const valueNode = findChildByType2(child, "quoted_attribute_value") ?? findChildByType2(child, "attribute_value");
17881
18651
  if (!valueNode)
17882
18652
  continue;
17883
- const code = stripQuotes(valueNode.text);
18653
+ const code = stripQuotes2(valueNode.text);
17884
18654
  if (code) {
17885
18655
  eventHandlers.push({
17886
18656
  code,
@@ -17913,7 +18683,7 @@ function getAttributeValue(tag, name2) {
17913
18683
  const nameNode = findChildByType2(child, "attribute_name");
17914
18684
  if (nameNode?.text.toLowerCase() === name2) {
17915
18685
  const valueNode = findChildByType2(child, "quoted_attribute_value") ?? findChildByType2(child, "attribute_value");
17916
- return valueNode ? stripQuotes(valueNode.text) : "";
18686
+ return valueNode ? stripQuotes2(valueNode.text) : "";
17917
18687
  }
17918
18688
  }
17919
18689
  return;
@@ -17926,7 +18696,7 @@ function findChildByType2(node, type) {
17926
18696
  }
17927
18697
  return null;
17928
18698
  }
17929
- function stripQuotes(text) {
18699
+ function stripQuotes2(text) {
17930
18700
  if (text.startsWith('"') && text.endsWith('"') || text.startsWith("'") && text.endsWith("'")) {
17931
18701
  return text.slice(1, -1);
17932
18702
  }
@@ -24242,7 +25012,7 @@ class SecurityHeadersPass {
24242
25012
  }
24243
25013
  function literalOf(arg) {
24244
25014
  if (arg.literal !== null && arg.literal !== undefined && arg.literal !== "") {
24245
- return stripQuotes2(arg.literal);
25015
+ return stripQuotes3(arg.literal);
24246
25016
  }
24247
25017
  const expr = arg.expression.trim();
24248
25018
  if (expr.startsWith('"') && expr.endsWith('"') || expr.startsWith("'") && expr.endsWith("'") || expr.startsWith("`") && expr.endsWith("`")) {
@@ -24252,7 +25022,7 @@ function literalOf(arg) {
24252
25022
  }
24253
25023
  return null;
24254
25024
  }
24255
- function stripQuotes2(s) {
25025
+ function stripQuotes3(s) {
24256
25026
  if (s.length < 2)
24257
25027
  return s;
24258
25028
  const first = s[0];
@@ -25705,7 +26475,9 @@ function getNodeTypesForLanguage(language) {
25705
26475
  "use_declaration",
25706
26476
  "let_declaration",
25707
26477
  "field_expression",
25708
- "scoped_identifier"
26478
+ "scoped_identifier",
26479
+ "attribute_item",
26480
+ "static_item"
25709
26481
  ]);
25710
26482
  case "python":
25711
26483
  return new Set([
@@ -25716,7 +26488,9 @@ function getNodeTypesForLanguage(language) {
25716
26488
  "import_from_statement",
25717
26489
  "assignment",
25718
26490
  "attribute",
25719
- "subscript"
26491
+ "subscript",
26492
+ "decorated_definition",
26493
+ "decorator"
25720
26494
  ]);
25721
26495
  case "javascript":
25722
26496
  case "typescript":
@@ -25808,6 +26582,7 @@ async function analyze(code, filePath, language, options = {}) {
25808
26582
  const exports = extractExports(types);
25809
26583
  const cfg = buildCFG(tree, language);
25810
26584
  const dfg = buildDFG(tree, nodeCache, language);
26585
+ const runtimeRegistrations = extractRuntimeRegistrations(tree, nodeCache, language, imports);
25811
26586
  const graph = new CodeGraph({
25812
26587
  meta,
25813
26588
  types,
@@ -25934,7 +26709,8 @@ async function analyze(code, filePath, language, options = {}) {
25934
26709
  unresolved,
25935
26710
  enriched,
25936
26711
  findings: findings.length > 0 ? findings : undefined,
25937
- metrics: { file: filePath, metrics: metricValues }
26712
+ metrics: { file: filePath, metrics: metricValues },
26713
+ runtime_registrations: runtimeRegistrations.length > 0 ? runtimeRegistrations : undefined
25938
26714
  };
25939
26715
  } finally {
25940
26716
  disposeTree(tree);
@@ -26083,7 +26859,7 @@ var colors = {
26083
26859
  };
26084
26860
 
26085
26861
  // src/version.ts
26086
- var version = "3.30.0";
26862
+ var version = "3.34.0";
26087
26863
 
26088
26864
  // src/formatters.ts
26089
26865
  var SINK_SEVERITY = {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cognium-dev",
3
- "version": "3.30.0",
3
+ "version": "3.34.0",
4
4
  "description": "Static Application Security Testing CLI for detecting security vulnerabilities via taint tracking",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -65,7 +65,7 @@
65
65
  "registry": "https://registry.npmjs.org/"
66
66
  },
67
67
  "dependencies": {
68
- "circle-ir": "^3.30.0"
68
+ "circle-ir": "^3.34.0"
69
69
  },
70
70
  "devDependencies": {
71
71
  "@types/node": "^25.5.0",