@bitsness/grapuco-cli 0.1.9 → 0.1.11
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 +186 -4
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -2043,7 +2043,7 @@ var init_signature_extractors = __esm({
|
|
|
2043
2043
|
});
|
|
2044
2044
|
|
|
2045
2045
|
// src/parser/ingestion/utils/call-extractors.ts
|
|
2046
|
-
var CALL_ARGUMENT_LIST_TYPES, countCallArguments, MEMBER_ACCESS_NODE_TYPES, CONSTRUCTOR_CALL_NODE_TYPES, SCOPED_CALL_NODE_TYPES, inferCallForm, SIMPLE_RECEIVER_TYPES, extractReceiverName;
|
|
2046
|
+
var CALL_ARGUMENT_LIST_TYPES, countCallArguments, extractCallFirstStringArgument, MEMBER_ACCESS_NODE_TYPES, CONSTRUCTOR_CALL_NODE_TYPES, SCOPED_CALL_NODE_TYPES, inferCallForm, SIMPLE_RECEIVER_TYPES, extractReceiverName;
|
|
2047
2047
|
var init_call_extractors = __esm({
|
|
2048
2048
|
"src/parser/ingestion/utils/call-extractors.ts"() {
|
|
2049
2049
|
"use strict";
|
|
@@ -2074,6 +2074,43 @@ var init_call_extractors = __esm({
|
|
|
2074
2074
|
}
|
|
2075
2075
|
return count;
|
|
2076
2076
|
};
|
|
2077
|
+
extractCallFirstStringArgument = (callNode) => {
|
|
2078
|
+
if (!callNode) return void 0;
|
|
2079
|
+
let argsNode = callNode.childForFieldName("arguments") ?? callNode.children.find((child) => CALL_ARGUMENT_LIST_TYPES.has(child.type));
|
|
2080
|
+
if (!argsNode) {
|
|
2081
|
+
for (const child of callNode.children) {
|
|
2082
|
+
if (!child.isNamed) continue;
|
|
2083
|
+
const nested = child.children.find((gc) => CALL_ARGUMENT_LIST_TYPES.has(gc.type));
|
|
2084
|
+
if (nested) {
|
|
2085
|
+
argsNode = nested;
|
|
2086
|
+
break;
|
|
2087
|
+
}
|
|
2088
|
+
}
|
|
2089
|
+
}
|
|
2090
|
+
if (!argsNode) return void 0;
|
|
2091
|
+
let firstArg;
|
|
2092
|
+
for (const child of argsNode.children) {
|
|
2093
|
+
if (!child.isNamed || child.type === "comment") continue;
|
|
2094
|
+
firstArg = child;
|
|
2095
|
+
break;
|
|
2096
|
+
}
|
|
2097
|
+
if (!firstArg) return void 0;
|
|
2098
|
+
const stringTypes = /* @__PURE__ */ new Set([
|
|
2099
|
+
"string",
|
|
2100
|
+
"string_literal",
|
|
2101
|
+
"interpreted_string_literal",
|
|
2102
|
+
"raw_string_literal",
|
|
2103
|
+
"encapsed_string"
|
|
2104
|
+
]);
|
|
2105
|
+
if (stringTypes.has(firstArg.type)) {
|
|
2106
|
+
let text = firstArg.text;
|
|
2107
|
+
if (text.startsWith('"') && text.endsWith('"') || text.startsWith("'") && text.endsWith("'") || text.startsWith("`") && text.endsWith("`")) {
|
|
2108
|
+
return text.substring(1, text.length - 1);
|
|
2109
|
+
}
|
|
2110
|
+
return text;
|
|
2111
|
+
}
|
|
2112
|
+
return void 0;
|
|
2113
|
+
};
|
|
2077
2114
|
MEMBER_ACCESS_NODE_TYPES = /* @__PURE__ */ new Set([
|
|
2078
2115
|
"member_expression",
|
|
2079
2116
|
// TS/JS: obj.method()
|
|
@@ -2203,6 +2240,13 @@ var init_call_extractors = __esm({
|
|
|
2203
2240
|
if (SIMPLE_RECEIVER_TYPES.has(receiver.type)) {
|
|
2204
2241
|
return receiver.text;
|
|
2205
2242
|
}
|
|
2243
|
+
if (receiver.type === "member_expression" || receiver.type === "attribute") {
|
|
2244
|
+
const obj = receiver.childForFieldName("object");
|
|
2245
|
+
const prop = receiver.childForFieldName("property") || receiver.childForFieldName("attribute");
|
|
2246
|
+
if (obj && prop && (obj.text === "this" || obj.text === "self")) {
|
|
2247
|
+
return prop.text;
|
|
2248
|
+
}
|
|
2249
|
+
}
|
|
2206
2250
|
if (receiver.type === "call") {
|
|
2207
2251
|
const func = receiver.childForFieldName("function");
|
|
2208
2252
|
if (func?.text === "super") return "super";
|
|
@@ -5234,6 +5278,125 @@ var init_nestjs_routes = __esm({
|
|
|
5234
5278
|
}
|
|
5235
5279
|
});
|
|
5236
5280
|
|
|
5281
|
+
// src/parser/ingestion/workers/extractors/nestjs-events.ts
|
|
5282
|
+
function detectClassLevelSubscriber(classNode, className, filePath, events) {
|
|
5283
|
+
for (const child of classNode.children) {
|
|
5284
|
+
if (child.type !== "decorator") continue;
|
|
5285
|
+
const callExp = child.children.find((c) => c.type === "call_expression");
|
|
5286
|
+
if (!callExp) continue;
|
|
5287
|
+
const funcName = callExp.childForFieldName("function")?.text;
|
|
5288
|
+
if (!funcName || !CLASS_SUBSCRIBER_DECORATORS.has(funcName)) continue;
|
|
5289
|
+
const argsNode = callExp.childForFieldName("arguments");
|
|
5290
|
+
if (!argsNode) continue;
|
|
5291
|
+
let topicName = null;
|
|
5292
|
+
for (const arg of argsNode.children) {
|
|
5293
|
+
if (arg.type === "string") {
|
|
5294
|
+
topicName = arg.text.substring(1, arg.text.length - 1);
|
|
5295
|
+
break;
|
|
5296
|
+
}
|
|
5297
|
+
}
|
|
5298
|
+
if (!topicName) continue;
|
|
5299
|
+
const classBody = classNode.childForFieldName("body");
|
|
5300
|
+
if (!classBody) continue;
|
|
5301
|
+
let handlerMethodName = null;
|
|
5302
|
+
let handlerLine = classNode.startPosition.row;
|
|
5303
|
+
for (const member of classBody.children) {
|
|
5304
|
+
if (member.type === "method_definition") {
|
|
5305
|
+
const mName = member.childForFieldName("name")?.text;
|
|
5306
|
+
if (mName && HANDLER_METHOD_NAMES.has(mName)) {
|
|
5307
|
+
handlerMethodName = mName;
|
|
5308
|
+
handlerLine = member.startPosition.row;
|
|
5309
|
+
break;
|
|
5310
|
+
}
|
|
5311
|
+
}
|
|
5312
|
+
}
|
|
5313
|
+
events.push({
|
|
5314
|
+
filePath,
|
|
5315
|
+
topicName,
|
|
5316
|
+
className,
|
|
5317
|
+
methodName: handlerMethodName || className,
|
|
5318
|
+
framework: `bullmq-${funcName.toLowerCase()}`,
|
|
5319
|
+
lineNumber: handlerLine
|
|
5320
|
+
});
|
|
5321
|
+
}
|
|
5322
|
+
}
|
|
5323
|
+
var CLASS_SUBSCRIBER_DECORATORS, HANDLER_METHOD_NAMES, extractNestJSEvents;
|
|
5324
|
+
var init_nestjs_events = __esm({
|
|
5325
|
+
"src/parser/ingestion/workers/extractors/nestjs-events.ts"() {
|
|
5326
|
+
"use strict";
|
|
5327
|
+
CLASS_SUBSCRIBER_DECORATORS = /* @__PURE__ */ new Set([
|
|
5328
|
+
"Processor",
|
|
5329
|
+
// BullMQ @Processor('queueName')
|
|
5330
|
+
"WorkerHost",
|
|
5331
|
+
// BullMQ alternate pattern
|
|
5332
|
+
"Consumer",
|
|
5333
|
+
// KafkaJS / custom consumers
|
|
5334
|
+
"RabbitSubscribe"
|
|
5335
|
+
// @golevelup/nestjs-rabbitmq
|
|
5336
|
+
]);
|
|
5337
|
+
HANDLER_METHOD_NAMES = /* @__PURE__ */ new Set([
|
|
5338
|
+
"process",
|
|
5339
|
+
// BullMQ WorkerHost.process()
|
|
5340
|
+
"handleMessage",
|
|
5341
|
+
// Generic consumer pattern
|
|
5342
|
+
"handle",
|
|
5343
|
+
// Generic handler
|
|
5344
|
+
"execute"
|
|
5345
|
+
// CQRS-style
|
|
5346
|
+
]);
|
|
5347
|
+
extractNestJSEvents = (tree, filePath) => {
|
|
5348
|
+
const events = [];
|
|
5349
|
+
const rootNode = tree.rootNode;
|
|
5350
|
+
const walk = (node, currentClass = null) => {
|
|
5351
|
+
if (node.type === "class_declaration") {
|
|
5352
|
+
const nameNode = node.childForFieldName("name");
|
|
5353
|
+
currentClass = nameNode ? nameNode.text : null;
|
|
5354
|
+
detectClassLevelSubscriber(node, currentClass, filePath, events);
|
|
5355
|
+
}
|
|
5356
|
+
if (node.type === "method_definition") {
|
|
5357
|
+
const methodNameNode = node.childForFieldName("name");
|
|
5358
|
+
const methodName = methodNameNode ? methodNameNode.text : null;
|
|
5359
|
+
for (const child of node.children) {
|
|
5360
|
+
if (child.type === "decorator") {
|
|
5361
|
+
const callExp = child.children.find((c) => c.type === "call_expression");
|
|
5362
|
+
if (callExp) {
|
|
5363
|
+
const funcName = callExp.childForFieldName("function")?.text;
|
|
5364
|
+
if (funcName === "EventPattern" || funcName === "MessagePattern") {
|
|
5365
|
+
const argsNode = callExp.childForFieldName("arguments");
|
|
5366
|
+
if (argsNode) {
|
|
5367
|
+
let topicName = null;
|
|
5368
|
+
for (const arg of argsNode.children) {
|
|
5369
|
+
if (arg.type === "string") {
|
|
5370
|
+
topicName = arg.text.substring(1, arg.text.length - 1);
|
|
5371
|
+
break;
|
|
5372
|
+
}
|
|
5373
|
+
}
|
|
5374
|
+
if (topicName) {
|
|
5375
|
+
events.push({
|
|
5376
|
+
filePath,
|
|
5377
|
+
topicName,
|
|
5378
|
+
className: currentClass,
|
|
5379
|
+
methodName,
|
|
5380
|
+
framework: funcName === "EventPattern" ? "nestjs-event" : "nestjs-message",
|
|
5381
|
+
lineNumber: node.startPosition.row
|
|
5382
|
+
});
|
|
5383
|
+
}
|
|
5384
|
+
}
|
|
5385
|
+
}
|
|
5386
|
+
}
|
|
5387
|
+
}
|
|
5388
|
+
}
|
|
5389
|
+
}
|
|
5390
|
+
for (const child of node.children) {
|
|
5391
|
+
walk(child, currentClass);
|
|
5392
|
+
}
|
|
5393
|
+
};
|
|
5394
|
+
walk(rootNode);
|
|
5395
|
+
return events;
|
|
5396
|
+
};
|
|
5397
|
+
}
|
|
5398
|
+
});
|
|
5399
|
+
|
|
5237
5400
|
// src/parser/ingestion/workers/extractors/php-eloquent.ts
|
|
5238
5401
|
function findDescendant2(node, type) {
|
|
5239
5402
|
if (node.type === type) return node;
|
|
@@ -5349,6 +5512,7 @@ var init_parse_worker = __esm({
|
|
|
5349
5512
|
init_call_routing();
|
|
5350
5513
|
init_laravel_routes();
|
|
5351
5514
|
init_nestjs_routes();
|
|
5515
|
+
init_nestjs_events();
|
|
5352
5516
|
init_php_eloquent();
|
|
5353
5517
|
init_parser_loader();
|
|
5354
5518
|
_require = (0, import_node_module.createRequire)(__filename);
|
|
@@ -5406,6 +5570,7 @@ var init_parse_worker = __esm({
|
|
|
5406
5570
|
calls: [],
|
|
5407
5571
|
heritage: [],
|
|
5408
5572
|
routes: [],
|
|
5573
|
+
eventSubscribers: [],
|
|
5409
5574
|
constructorBindings: [],
|
|
5410
5575
|
fileCount: 0
|
|
5411
5576
|
};
|
|
@@ -5613,6 +5778,18 @@ var init_parse_worker = __esm({
|
|
|
5613
5778
|
const callForm = inferCallForm(callNode, callNameNode);
|
|
5614
5779
|
const receiverName = callForm === "member" ? extractReceiverName(callNameNode) : void 0;
|
|
5615
5780
|
const receiverTypeName = receiverName ? typeEnv.lookup(receiverName, callNode) : void 0;
|
|
5781
|
+
let channelArgument;
|
|
5782
|
+
const BROKER_CALL_METHODS = /* @__PURE__ */ new Set(["publish", "emit", "sendToQueue", "produce", "send", "broadcast", "dispatch"]);
|
|
5783
|
+
const AMBIGUOUS_BROKER_METHODS = /* @__PURE__ */ new Set(["add", "enqueue"]);
|
|
5784
|
+
if (BROKER_CALL_METHODS.has(calledName)) {
|
|
5785
|
+
channelArgument = extractCallFirstStringArgument(callNode);
|
|
5786
|
+
} else if (AMBIGUOUS_BROKER_METHODS.has(calledName)) {
|
|
5787
|
+
const recName = receiverName?.toLowerCase() || "";
|
|
5788
|
+
const recType = receiverTypeName?.toLowerCase() || "";
|
|
5789
|
+
if (recName.includes("queue") || recName.includes("job") || recName.includes("mq") || recName.includes("worker") || recType.includes("queue")) {
|
|
5790
|
+
channelArgument = extractCallFirstStringArgument(callNode);
|
|
5791
|
+
}
|
|
5792
|
+
}
|
|
5616
5793
|
result.calls.push({
|
|
5617
5794
|
filePath: file.path,
|
|
5618
5795
|
calledName,
|
|
@@ -5620,7 +5797,8 @@ var init_parse_worker = __esm({
|
|
|
5620
5797
|
argCount: countCallArguments(callNode),
|
|
5621
5798
|
...callForm !== void 0 ? { callForm } : {},
|
|
5622
5799
|
...receiverName !== void 0 ? { receiverName } : {},
|
|
5623
|
-
...receiverTypeName !== void 0 ? { receiverTypeName } : {}
|
|
5800
|
+
...receiverTypeName !== void 0 ? { receiverTypeName } : {},
|
|
5801
|
+
...channelArgument !== void 0 ? { channelArgument } : {}
|
|
5624
5802
|
});
|
|
5625
5803
|
}
|
|
5626
5804
|
}
|
|
@@ -5779,6 +5957,8 @@ var init_parse_worker = __esm({
|
|
|
5779
5957
|
if (language === "typescript" /* TypeScript */ && /\.controller\./.test(file.path)) {
|
|
5780
5958
|
const nestRoutes = extractNestJSRoutes(tree, file.path);
|
|
5781
5959
|
result.routes.push(...nestRoutes);
|
|
5960
|
+
const nestEvents = extractNestJSEvents(tree, file.path);
|
|
5961
|
+
result.eventSubscribers.push(...nestEvents);
|
|
5782
5962
|
}
|
|
5783
5963
|
try {
|
|
5784
5964
|
if (tree && typeof tree.delete === "function") {
|
|
@@ -5796,6 +5976,7 @@ var init_parse_worker = __esm({
|
|
|
5796
5976
|
calls: [],
|
|
5797
5977
|
heritage: [],
|
|
5798
5978
|
routes: [],
|
|
5979
|
+
eventSubscribers: [],
|
|
5799
5980
|
constructorBindings: [],
|
|
5800
5981
|
fileCount: 0
|
|
5801
5982
|
};
|
|
@@ -5808,6 +5989,7 @@ var init_parse_worker = __esm({
|
|
|
5808
5989
|
target.calls.push(...src.calls);
|
|
5809
5990
|
target.heritage.push(...src.heritage);
|
|
5810
5991
|
target.routes.push(...src.routes);
|
|
5992
|
+
target.eventSubscribers.push(...src.eventSubscribers);
|
|
5811
5993
|
target.constructorBindings.push(...src.constructorBindings);
|
|
5812
5994
|
target.fileCount += src.fileCount;
|
|
5813
5995
|
};
|
|
@@ -5825,7 +6007,7 @@ var init_parse_worker = __esm({
|
|
|
5825
6007
|
}
|
|
5826
6008
|
if (msg && msg.type === "flush") {
|
|
5827
6009
|
import_node_worker_threads.parentPort.postMessage({ type: "result", data: accumulated });
|
|
5828
|
-
accumulated = { nodes: [], relationships: [], symbols: [], imports: [], calls: [], heritage: [], routes: [], constructorBindings: [], fileCount: 0 };
|
|
6010
|
+
accumulated = { nodes: [], relationships: [], symbols: [], imports: [], calls: [], heritage: [], routes: [], eventSubscribers: [], constructorBindings: [], fileCount: 0 };
|
|
5829
6011
|
cumulativeProcessed = 0;
|
|
5830
6012
|
return;
|
|
5831
6013
|
}
|
|
@@ -6530,7 +6712,7 @@ var require_package = __commonJS({
|
|
|
6530
6712
|
"package.json"(exports2, module2) {
|
|
6531
6713
|
module2.exports = {
|
|
6532
6714
|
name: "@bitsness/grapuco-cli",
|
|
6533
|
-
version: "0.1.
|
|
6715
|
+
version: "0.1.11",
|
|
6534
6716
|
description: "Grapuco CLI \u2014 Parse your code locally, sync architecture to cloud. Zero source code upload.",
|
|
6535
6717
|
type: "commonjs",
|
|
6536
6718
|
bin: {
|