technical-debt-radar 1.2.0 → 1.2.2

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/index.js +59 -6
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -10797,7 +10797,7 @@ var require_volume_estimator = __commonJS({
10797
10797
  };
10798
10798
  })();
10799
10799
  Object.defineProperty(exports2, "__esModule", { value: true });
10800
- exports2.estimateVolumes = estimateVolumes2;
10800
+ exports2.estimateVolumes = estimateVolumes3;
10801
10801
  exports2.parseTypeORMEntities = parseTypeORMEntities;
10802
10802
  exports2.parsePrismaModels = parsePrismaModels;
10803
10803
  exports2.parseDrizzleTables = parseDrizzleTables;
@@ -10828,7 +10828,7 @@ var require_volume_estimator = __commonJS({
10828
10828
  size: "S"
10829
10829
  }
10830
10830
  ];
10831
- async function estimateVolumes2(projectPath) {
10831
+ async function estimateVolumes3(projectPath) {
10832
10832
  const prismaVolumes = await estimatePrismaVolumes(projectPath);
10833
10833
  if (Object.keys(prismaVolumes).length > 0)
10834
10834
  return prismaVolumes;
@@ -11265,7 +11265,7 @@ var require_volume_estimator = __commonJS({
11265
11265
  if (entryName !== "node_modules" && entryName !== "dist" && entryName !== ".git") {
11266
11266
  await scan(fullPath);
11267
11267
  }
11268
- } else if (entryName.endsWith(".model.ts") || entryName.endsWith(".model.js")) {
11268
+ } else if (entryName.endsWith(".model.ts") || entryName.endsWith(".model.js") || entryName.endsWith(".schema.ts") || entryName.endsWith(".schema.js")) {
11269
11269
  results.push(fullPath);
11270
11270
  }
11271
11271
  }
@@ -11313,10 +11313,13 @@ var require_volume_estimator = __commonJS({
11313
11313
  } catch {
11314
11314
  continue;
11315
11315
  }
11316
- if (!/mongoose\.model|new\s+Schema|new\s+mongoose\.Schema|\bmodel\s*\(\s*['"]/.test(content))
11316
+ if (!/mongoose\.model|new\s+Schema|new\s+mongoose\.Schema|\bmodel\s*\(\s*['"]|@Schema\s*\(/.test(content))
11317
11317
  continue;
11318
11318
  const models = parseMongooseModels(content);
11319
- for (const model of models) {
11319
+ const basename2 = path9.basename(filePath).replace(/\.(schema|model)\.(ts|js)$/, "");
11320
+ const filteredModels = models.length > 1 ? models.filter((m) => m.name.toLowerCase() === basename2.toLowerCase()) : models;
11321
+ const finalModels = filteredModels.length > 0 ? filteredModels : models;
11322
+ for (const model of finalModels) {
11320
11323
  let size = estimateModelSize(model.collectionName);
11321
11324
  if (model.hasCreatedAtIndex) {
11322
11325
  if (size === "S" || size === "M") {
@@ -11332,10 +11335,14 @@ var require_volume_estimator = __commonJS({
11332
11335
  }
11333
11336
  function parseMongooseModels(content) {
11334
11337
  const models = [];
11338
+ const seen = /* @__PURE__ */ new Set();
11335
11339
  const modelRegex = /(?:mongoose\.)?model\s*\(\s*['"](\w+)['"]/g;
11336
11340
  let match;
11337
11341
  while ((match = modelRegex.exec(content)) !== null) {
11338
11342
  const name = match[1];
11343
+ if (seen.has(name))
11344
+ continue;
11345
+ seen.add(name);
11339
11346
  const collectionName = defaultTableName(name);
11340
11347
  let hasCreatedAtIndex = false;
11341
11348
  if (/\.index\s*\(\s*\{[^}]*(createdAt|timestamp|created_at)[^}]*\}/i.test(content)) {
@@ -11346,6 +11353,22 @@ var require_volume_estimator = __commonJS({
11346
11353
  }
11347
11354
  models.push({ name, collectionName, hasCreatedAtIndex });
11348
11355
  }
11356
+ const schemaRegex = /@Schema\s*\([^)]*\)\s*(?:export\s+)?class\s+(\w+)/g;
11357
+ while ((match = schemaRegex.exec(content)) !== null) {
11358
+ const className = match[1];
11359
+ const name = className;
11360
+ if (seen.has(name))
11361
+ continue;
11362
+ seen.add(name);
11363
+ const collectionName = defaultTableName(name);
11364
+ let hasCreatedAtIndex = false;
11365
+ if (/@Schema\s*\(\s*\{[^}]*timestamps\s*:\s*true/.test(content)) {
11366
+ }
11367
+ if (/\.index\s*\(\s*\{[^}]*(createdAt|timestamp|created_at)[^}]*\}/i.test(content)) {
11368
+ hasCreatedAtIndex = true;
11369
+ }
11370
+ models.push({ name, collectionName, hasCreatedAtIndex });
11371
+ }
11349
11372
  return models;
11350
11373
  }
11351
11374
  function estimateModelSize(modelName) {
@@ -19326,6 +19349,30 @@ function buildTopHotspots(violations) {
19326
19349
  }
19327
19350
  return Array.from(byFile.entries()).map(([file, data]) => ({ file, ...data })).sort((a, b) => b.debtPoints - a.debtPoints).slice(0, 10);
19328
19351
  }
19352
+ async function detectDataVolumes(projectRoot, filePaths, existingVolumes) {
19353
+ let estimated = {};
19354
+ try {
19355
+ estimated = await (0, import_policy_engine.estimateVolumes)(projectRoot);
19356
+ } catch {
19357
+ }
19358
+ const volumes = { ...existingVolumes };
19359
+ for (const [entity, size] of Object.entries(estimated)) {
19360
+ if (!volumes[entity]) {
19361
+ volumes[entity] = size;
19362
+ }
19363
+ }
19364
+ const entityPattern = /\.(?:schema|entity|model)\.(ts|js)$/;
19365
+ for (const fp of filePaths) {
19366
+ if (!entityPattern.test(fp)) continue;
19367
+ const basename2 = path2.basename(fp);
19368
+ const entityName = basename2.replace(/\.(schema|entity|model)\.(ts|js)$/, "");
19369
+ if (!entityName || entityName === "index") continue;
19370
+ if (!volumes[entityName]) {
19371
+ volumes[entityName] = volumes["default"] ?? "S";
19372
+ }
19373
+ }
19374
+ return volumes;
19375
+ }
19329
19376
  var ANON_SCAN_DIR = path2.join(os2.homedir(), ".radar");
19330
19377
  var ANON_SCAN_FILE = path2.join(ANON_SCAN_DIR, ".anonymous-scan");
19331
19378
  function checkAnonymousScanAllowed() {
@@ -19540,11 +19587,17 @@ async function scanCommand(targetPath, options) {
19540
19587
  };
19541
19588
  try {
19542
19589
  await client.reportScan(reportData);
19590
+ const enrichedConfig = { ...loaded.parsedConfig };
19591
+ enrichedConfig.data_volumes = await detectDataVolumes(
19592
+ path2.resolve(targetPath),
19593
+ files,
19594
+ enrichedConfig.data_volumes ?? {}
19595
+ );
19543
19596
  await client.pushPolicyConfig({
19544
19597
  repoName: path2.basename(path2.resolve(targetPath)),
19545
19598
  radarYaml: loaded.radarYaml,
19546
19599
  rulesYaml: loaded.rulesYaml,
19547
- parsedConfig: loaded.parsedConfig
19600
+ parsedConfig: enrichedConfig
19548
19601
  }).catch(() => {
19549
19602
  });
19550
19603
  console.log(import_chalk.default.green(" \u2713 Results synced to dashboard: https://www.technicaldebtradar.com/dashboard"));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "technical-debt-radar",
3
- "version": "1.2.0",
3
+ "version": "1.2.2",
4
4
  "description": "Stop Node.js production crashes before merge. 47 detection patterns across 5 categories.",
5
5
  "bin": {
6
6
  "radar": "dist/index.js",