@driftless-sh/cli 0.1.47 → 0.1.49

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 CHANGED
@@ -213387,15 +213387,23 @@ var require_nestjs_extractor = __commonJS({
213387
213387
  };
213388
213388
  Object.defineProperty(exports2, "__esModule", { value: true });
213389
213389
  exports2.extractNestJS = extractNestJS;
213390
+ exports2.extractNestJSWithReport = extractNestJSWithReport;
213390
213391
  var node_path_1 = __importDefault(require("node:path"));
213391
213392
  var node_fs_1 = __importDefault(require("node:fs"));
213392
213393
  var typescript_1 = __importDefault(require_typescript());
213393
- function discoverFiles(rootPath) {
213394
+ var DEFAULT_MAX_FILE_BYTES = 15e5;
213395
+ function maxFileBytes() {
213396
+ const raw = Number(process.env.DRIFTLESS_MAX_FILE_BYTES);
213397
+ return Number.isFinite(raw) && raw > 0 ? Math.floor(raw) : DEFAULT_MAX_FILE_BYTES;
213398
+ }
213399
+ function discoverScanFiles(rootPath) {
213394
213400
  const files = [];
213401
+ const skipped = [];
213395
213402
  const srcDir = node_fs_1.default.existsSync(node_path_1.default.join(rootPath, "src")) ? node_path_1.default.join(rootPath, "src") : rootPath;
213396
213403
  if (!node_fs_1.default.existsSync(srcDir))
213397
- return files;
213404
+ return { files, skipped };
213398
213405
  const SKIP = /* @__PURE__ */ new Set(["node_modules", "dist", ".next", "build", ".turbo", "coverage"]);
213406
+ const cap = maxFileBytes();
213399
213407
  function walk(dir) {
213400
213408
  const entries = node_fs_1.default.readdirSync(dir, { withFileTypes: true });
213401
213409
  for (const entry of entries) {
@@ -213404,13 +213412,23 @@ var require_nestjs_extractor = __commonJS({
213404
213412
  if (SKIP.has(entry.name))
213405
213413
  continue;
213406
213414
  walk(full);
213407
- } else if (entry.isFile() && entry.name.endsWith(".ts") && !entry.name.endsWith(".d.ts") && !entry.name.endsWith(".spec.ts") && !entry.name.endsWith(".test.ts")) {
213408
- files.push(full);
213415
+ } else if (entry.isFile() && (entry.name.endsWith(".ts") || entry.name.endsWith(".tsx")) && !entry.name.endsWith(".d.ts") && !entry.name.endsWith(".spec.ts") && !entry.name.endsWith(".test.ts")) {
213416
+ let size = 0;
213417
+ try {
213418
+ size = node_fs_1.default.statSync(full).size;
213419
+ } catch {
213420
+ continue;
213421
+ }
213422
+ if (size > cap) {
213423
+ skipped.push({ path: node_path_1.default.relative(rootPath, full), bytes: size });
213424
+ } else {
213425
+ files.push(full);
213426
+ }
213409
213427
  }
213410
213428
  }
213411
213429
  }
213412
213430
  walk(srcDir);
213413
- return files;
213431
+ return { files, skipped };
213414
213432
  }
213415
213433
  function parseFile(filePath, rootPath) {
213416
213434
  const sourceText = node_fs_1.default.readFileSync(filePath, "utf8");
@@ -213477,10 +213495,11 @@ var require_nestjs_extractor = __commonJS({
213477
213495
  for (const d of decs || []) {
213478
213496
  if (getDecoratorName(d) !== "Module")
213479
213497
  continue;
213498
+ const emptyMeta = { imports: [], providers: [], controllers: [], globalGuards: [] };
213480
213499
  if (!typescript_1.default.isCallExpression(d.expression) || d.expression.arguments.length === 0)
213481
- return { imports: [], providers: [], controllers: [] };
213500
+ return emptyMeta;
213482
213501
  const obj = d.expression.arguments[0];
213483
- const meta = { imports: [], providers: [], controllers: [] };
213502
+ const meta = { imports: [], providers: [], controllers: [], globalGuards: [] };
213484
213503
  if (typescript_1.default.isObjectLiteralExpression(obj)) {
213485
213504
  for (const prop of obj.properties) {
213486
213505
  if (!typescript_1.default.isPropertyAssignment(prop) || !typescript_1.default.isIdentifier(prop.name))
@@ -213491,8 +213510,27 @@ var require_nestjs_extractor = __commonJS({
213491
213510
  if (!typescript_1.default.isArrayLiteralExpression(prop.initializer))
213492
213511
  continue;
213493
213512
  for (const el of prop.initializer.elements) {
213494
- if (typescript_1.default.isIdentifier(el))
213513
+ if (typescript_1.default.isIdentifier(el)) {
213495
213514
  meta[key].push(el.text);
213515
+ } else if (key === "providers" && typescript_1.default.isObjectLiteralExpression(el)) {
213516
+ let isAppGuard = false;
213517
+ let guardName = null;
213518
+ for (const p of el.properties) {
213519
+ if (!typescript_1.default.isPropertyAssignment(p) || !typescript_1.default.isIdentifier(p.name))
213520
+ continue;
213521
+ if (p.name.text === "provide") {
213522
+ const v = p.initializer;
213523
+ if (typescript_1.default.isIdentifier(v) && v.text === "APP_GUARD" || typescript_1.default.isPropertyAccessExpression(v) && typescript_1.default.isIdentifier(v.name) && v.name.text === "APP_GUARD") {
213524
+ isAppGuard = true;
213525
+ }
213526
+ } else if (p.name.text === "useClass" || p.name.text === "useExisting") {
213527
+ if (typescript_1.default.isIdentifier(p.initializer))
213528
+ guardName = p.initializer.text;
213529
+ }
213530
+ }
213531
+ if (isAppGuard && guardName)
213532
+ meta.globalGuards.push(guardName);
213533
+ }
213496
213534
  }
213497
213535
  }
213498
213536
  }
@@ -213860,10 +213898,15 @@ var require_nestjs_extractor = __commonJS({
213860
213898
  return c;
213861
213899
  }
213862
213900
  function extractNestJS(rootPath) {
213901
+ return extractNestJSWithReport(rootPath).components;
213902
+ }
213903
+ function extractNestJSWithReport(rootPath) {
213863
213904
  const components = [];
213864
- const files = discoverFiles(rootPath).filter((f) => isInSourceDir(node_path_1.default.relative(rootPath, f))).sort();
213905
+ const discovered = discoverScanFiles(rootPath);
213906
+ const files = discovered.files.filter((f) => isInSourceDir(node_path_1.default.relative(rootPath, f))).sort();
213907
+ const skipped = discovered.skipped.filter((s) => isInSourceDir(s.path));
213865
213908
  if (files.length === 0)
213866
- return components;
213909
+ return { components, skipped };
213867
213910
  const symbolIndex = /* @__PURE__ */ new Map();
213868
213911
  const moduleByDir = /* @__PURE__ */ new Map();
213869
213912
  for (const file of files) {
@@ -213979,12 +214022,13 @@ var require_nestjs_extractor = __commonJS({
213979
214022
  }, 1));
213980
214023
  }
213981
214024
  if (decorators.includes("Module")) {
214025
+ const globalGuards = cls.moduleMeta?.globalGuards ?? [];
213982
214026
  components.push(stamp({
213983
214027
  type: "module",
213984
214028
  name: className || "UnknownModule",
213985
214029
  file_path: facts.filePath,
213986
214030
  line_number: line,
213987
- metadata: {},
214031
+ metadata: globalGuards.length > 0 ? { global_guards: globalGuards } : {},
213988
214032
  relations: extractModuleRelations(cls, symbolIndex)
213989
214033
  }, 1));
213990
214034
  }
@@ -214030,7 +214074,7 @@ var require_nestjs_extractor = __commonJS({
214030
214074
  }
214031
214075
  }
214032
214076
  }
214033
- return components;
214077
+ return { components, skipped };
214034
214078
  }
214035
214079
  function extractModuleRelations(cls, symbolIndex) {
214036
214080
  const meta = cls.moduleMeta;
@@ -214305,7 +214349,7 @@ var require_dist = __commonJS({
214305
214349
  "../../libs/scanner/dist/index.js"(exports2) {
214306
214350
  "use strict";
214307
214351
  Object.defineProperty(exports2, "__esModule", { value: true });
214308
- exports2.enrichComponents = exports2.extractNestJS = exports2.identifyRepo = void 0;
214352
+ exports2.enrichComponents = exports2.extractNestJSWithReport = exports2.extractNestJS = exports2.identifyRepo = void 0;
214309
214353
  exports2.scanRepo = scanRepo2;
214310
214354
  var identity_1 = require_identity();
214311
214355
  Object.defineProperty(exports2, "identifyRepo", { enumerable: true, get: function() {
@@ -214315,6 +214359,9 @@ var require_dist = __commonJS({
214315
214359
  Object.defineProperty(exports2, "extractNestJS", { enumerable: true, get: function() {
214316
214360
  return nestjs_extractor_1.extractNestJS;
214317
214361
  } });
214362
+ Object.defineProperty(exports2, "extractNestJSWithReport", { enumerable: true, get: function() {
214363
+ return nestjs_extractor_1.extractNestJSWithReport;
214364
+ } });
214318
214365
  var enricher_1 = require_enricher();
214319
214366
  Object.defineProperty(exports2, "enrichComponents", { enumerable: true, get: function() {
214320
214367
  return enricher_1.enrichComponents;
@@ -214323,8 +214370,9 @@ var require_dist = __commonJS({
214323
214370
  const startMs = Date.now();
214324
214371
  const startMem = process.memoryUsage().heapUsed;
214325
214372
  const identity = (0, identity_1.identifyRepo)(rootPath);
214326
- let components = (0, nestjs_extractor_1.extractNestJS)(rootPath);
214327
- components = await (0, enricher_1.enrichComponents)(components);
214373
+ const extracted = (0, nestjs_extractor_1.extractNestJSWithReport)(rootPath);
214374
+ const skipped = extracted.skipped;
214375
+ let components = await (0, enricher_1.enrichComponents)(extracted.components);
214328
214376
  const uniqueFiles = new Set(components.map((c) => c.file_path));
214329
214377
  const stats = {
214330
214378
  total_files: uniqueFiles.size,
@@ -214343,7 +214391,8 @@ var require_dist = __commonJS({
214343
214391
  telemetry: {
214344
214392
  duration_ms: durationMs,
214345
214393
  memory_mb: memoryMb,
214346
- files_parsed: uniqueFiles.size
214394
+ files_parsed: uniqueFiles.size,
214395
+ skipped_files: skipped
214347
214396
  }
214348
214397
  };
214349
214398
  }
@@ -214576,7 +214625,7 @@ async function installSkillCommand() {
214576
214625
  // src/commands/init.ts
214577
214626
  function getVersion() {
214578
214627
  try {
214579
- return "0.1.47";
214628
+ return "0.1.49";
214580
214629
  } catch {
214581
214630
  return "0.0.0";
214582
214631
  }
@@ -214971,6 +215020,17 @@ async function initCommand(args) {
214971
215020
  } else {
214972
215021
  console.log(` Scan: ${scanMs}ms`);
214973
215022
  }
215023
+ const skippedFiles = telemetry?.skipped_files ?? [];
215024
+ if (skippedFiles.length > 0) {
215025
+ const mb = (n) => `${(n / 1e6).toFixed(1)} MB`;
215026
+ console.warn(` \u26A0 ${skippedFiles.length} file(s) skipped \u2014 over the per-file scan cap (not parsed):`);
215027
+ for (const f of skippedFiles.slice(0, 10)) {
215028
+ console.warn(` ${f.path} (${mb(f.bytes)})`);
215029
+ }
215030
+ if (skippedFiles.length > 10) console.warn(` \u2026 and ${skippedFiles.length - 10} more`);
215031
+ console.warn(" Generated/minified/vendored bundles are skipped to avoid OOM.");
215032
+ console.warn(" Override with DRIFTLESS_MAX_FILE_BYTES=<bytes> if a real source file was skipped.");
215033
+ }
214974
215034
  console.log("");
214975
215035
  let repo;
214976
215036
  try {
@@ -216631,10 +216691,14 @@ async function graphCommand(args) {
216631
216691
  const header = g2.file && g2.file !== g2.query_path ? `\u258C ${path} \u2192 ${g2.file}` : `\u258C ${path}`;
216632
216692
  console.log(`${header}
216633
216693
  `);
216694
+ if (g2.global_guards && g2.global_guards.length) {
216695
+ console.log(`global guards (APP_GUARD): ${g2.global_guards.join(", ")}
216696
+ `);
216697
+ }
216634
216698
  if (g2.entrypoints.length) {
216635
216699
  console.log("entrypoints (routes that reach this):");
216636
216700
  for (const e of g2.entrypoints) {
216637
- const guards = e.guards && e.guards.length ? ` [${e.guards.join(", ")}]` : "";
216701
+ const guards = e.guards && e.guards.length ? ` [${e.guards.join(", ")}]` : " [no auth detected \u2014 verify]";
216638
216702
  console.log(` ${e.method ?? "?"} ${e.path ?? "?"} \u2192 ${e.handler}${guards}`);
216639
216703
  }
216640
216704
  console.log("");
@@ -216668,7 +216732,10 @@ async function graphCommand(args) {
216668
216732
  console.log(` ${consumers.length} consumer component(s) across ${g.impacted_files.length} file(s)`);
216669
216733
  if (eps.length) {
216670
216734
  console.log(` ${eps.length} reachable endpoint(s):`);
216671
- for (const e of eps.slice(0, 15)) console.log(` ${e.method ?? "?"} ${e.path ?? "?"} \u2192 ${e.handler}`);
216735
+ for (const e of eps.slice(0, 15)) {
216736
+ const guards = e.guards && e.guards.length ? ` [${e.guards.join(", ")}]` : " [no auth detected \u2014 verify]";
216737
+ console.log(` ${e.method ?? "?"} ${e.path ?? "?"} \u2192 ${e.handler}${guards}`);
216738
+ }
216672
216739
  if (eps.length > 15) console.log(` \u2026 and ${eps.length - 15} more`);
216673
216740
  }
216674
216741
  console.log("");
@@ -216685,7 +216752,7 @@ async function graphCommand(args) {
216685
216752
  }
216686
216753
 
216687
216754
  // src/index.ts
216688
- var VERSION = "0.1.47";
216755
+ var VERSION = "0.1.49";
216689
216756
  var HELP_TEXT = `Driftless CLI v${VERSION} \u2014 Living repo context for humans and coding agents
216690
216757
 
216691
216758
  Install: npm install -g @driftless-sh/cli