@kb-labs/quality-entry 2.93.0 → 2.96.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.
- package/dist/cli/commands/build-order.d.ts +5 -12
- package/dist/cli/commands/build-order.js +45 -97
- package/dist/cli/commands/build-order.js.map +1 -1
- package/dist/cli/commands/check-layers.d.ts +9 -0
- package/dist/cli/commands/check-layers.js +48 -0
- package/dist/cli/commands/check-layers.js.map +1 -0
- package/dist/cli/commands/context.d.ts +9 -0
- package/dist/cli/commands/context.js +94 -0
- package/dist/cli/commands/context.js.map +1 -0
- package/dist/cli/commands/coupling.d.ts +9 -0
- package/dist/cli/commands/coupling.js +35 -0
- package/dist/cli/commands/coupling.js.map +1 -0
- package/dist/cli/commands/dead-code.d.ts +4 -5
- package/dist/cli/commands/dead-code.js +41 -197
- package/dist/cli/commands/dead-code.js.map +1 -1
- package/dist/cli/commands/fix-deps.d.ts +2 -5
- package/dist/cli/commands/fix-deps.js +74 -83
- package/dist/cli/commands/fix-deps.js.map +1 -1
- package/dist/cli/commands/flags.d.ts +115 -1
- package/dist/cli/commands/flags.js +46 -1
- package/dist/cli/commands/flags.js.map +1 -1
- package/dist/cli/commands/gate.d.ts +9 -0
- package/dist/cli/commands/gate.js +59 -0
- package/dist/cli/commands/gate.js.map +1 -0
- package/dist/cli/commands/health.d.ts +4 -5
- package/dist/cli/commands/health.js +42 -191
- package/dist/cli/commands/health.js.map +1 -1
- package/dist/cli/commands/history.d.ts +9 -0
- package/dist/cli/commands/history.js +55 -0
- package/dist/cli/commands/history.js.map +1 -0
- package/dist/cli/commands/index.d.ts +6 -2
- package/dist/cli/commands/index.js +411 -828
- package/dist/cli/commands/index.js.map +1 -1
- package/dist/cli/commands/snapshot.d.ts +9 -0
- package/dist/cli/commands/snapshot.js +91 -0
- package/dist/cli/commands/snapshot.js.map +1 -0
- package/dist/cli/commands/stats.d.ts +4 -5
- package/dist/cli/commands/stats.js +17 -265
- package/dist/cli/commands/stats.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +198 -306
- package/dist/index.js.map +1 -1
- package/dist/manifest.d.ts +95 -82
- package/dist/manifest.js +198 -306
- package/dist/manifest.js.map +1 -1
- package/dist/rest/handlers/build-order-handler.d.ts +5 -13
- package/dist/rest/handlers/build-order-handler.js +14 -17
- package/dist/rest/handlers/build-order-handler.js.map +1 -1
- package/dist/rest/handlers/builds-handler.js +10 -6
- package/dist/rest/handlers/builds-handler.js.map +1 -1
- package/dist/rest/handlers/coupling-handler.d.ts +8 -0
- package/dist/rest/handlers/coupling-handler.js +28 -0
- package/dist/rest/handlers/coupling-handler.js.map +1 -0
- package/dist/rest/handlers/cycles-handler.js +16 -12
- package/dist/rest/handlers/cycles-handler.js.map +1 -1
- package/dist/rest/handlers/dependencies-handler.js +12 -8
- package/dist/rest/handlers/dependencies-handler.js.map +1 -1
- package/dist/rest/handlers/graph-handler.js +77 -73
- package/dist/rest/handlers/graph-handler.js.map +1 -1
- package/dist/rest/handlers/health-handler.d.ts +4 -11
- package/dist/rest/handlers/health-handler.js +35 -9
- package/dist/rest/handlers/health-handler.js.map +1 -1
- package/dist/rest/handlers/history-handler.d.ts +7 -0
- package/dist/rest/handlers/history-handler.js +21 -0
- package/dist/rest/handlers/history-handler.js.map +1 -0
- package/dist/rest/handlers/knip-handler.d.ts +8 -0
- package/dist/rest/handlers/knip-handler.js +31 -0
- package/dist/rest/handlers/knip-handler.js.map +1 -0
- package/dist/rest/handlers/layers-handler.d.ts +8 -0
- package/dist/rest/handlers/layers-handler.js +28 -0
- package/dist/rest/handlers/layers-handler.js.map +1 -0
- package/dist/rest/handlers/snapshot-handler.d.ts +7 -0
- package/dist/rest/handlers/snapshot-handler.js +67 -0
- package/dist/rest/handlers/snapshot-handler.js.map +1 -0
- package/dist/rest/handlers/stale-handler.js +13 -9
- package/dist/rest/handlers/stale-handler.js.map +1 -1
- package/dist/rest/handlers/stats-handler.d.ts +4 -9
- package/dist/rest/handlers/stats-handler.js +22 -18
- package/dist/rest/handlers/stats-handler.js.map +1 -1
- package/dist/rest/handlers/tests-handler.js +12 -8
- package/dist/rest/handlers/tests-handler.js.map +1 -1
- package/dist/rest/handlers/types-handler.js +10 -6
- package/dist/rest/handlers/types-handler.js.map +1 -1
- package/dist/widgets/117.js +24 -1
- package/dist/widgets/117.js.map +1 -1
- package/dist/widgets/370.js +1 -1
- package/dist/widgets/370.js.map +1 -1
- package/dist/widgets/62.js +97 -0
- package/dist/widgets/62.js.map +1 -0
- package/dist/widgets/__federation_expose_QualityOverview.js +1 -1
- package/dist/widgets/__federation_expose_QualityOverview.js.map +1 -1
- package/dist/widgets/mf-manifest.json +27 -27
- package/dist/widgets/mf-stats.json +27 -27
- package/dist/widgets/remoteEntry.js +2 -2
- package/dist/widgets/remoteEntry.js.map +1 -1
- package/package.json +9 -8
- package/dist/widgets/418.js +0 -39
- package/dist/widgets/418.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/rest/handlers/graph-handler.ts"],"names":[],"mappings":"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","file":"graph-handler.js","sourcesContent":["/**\n * POST /graph handler\n *\n * Visualize dependency graph in different modes:\n * - tree: dependency tree for package\n * - reverse: who depends on this package\n * - impact: what will be affected by changes\n * - stats: graph statistics\n */\n\nimport { defineHandler, type PluginContextV3, type RestInput } from '@kb-labs/sdk';\nimport {\n buildDependencyGraph,\n getReverseDependencies,\n getImpactAnalysis,\n type DependencyGraph,\n} from '@kb-labs/quality-core/graph';\n\nexport type GraphRequest = {\n packageName?: string;\n mode: 'tree' | 'reverse' | 'impact' | 'stats';\n};\n\nexport type GraphResponse = {\n mode: string;\n packageName?: string;\n tree?: DependencyTree;\n packages?: string[];\n stats?: GraphStats;\n};\n\nexport type DependencyTree = {\n name: string;\n children: DependencyTree[];\n};\n\nexport type GraphStats = {\n totalPackages: number;\n maxDepth: number;\n avgDependencies: number;\n mostDepended: Array<{ name: string; count: number }>;\n};\n\nexport default defineHandler({\n async execute(\n ctx: PluginContextV3,\n input: RestInput<GraphRequest, unknown>\n ): Promise<GraphResponse> {\n const { packageName, mode } = input.query ?? { mode: 'stats' };\n\n // Build dependency graph (cached with Map serialization)\n const cacheKey = `quality:graph:${ctx.cwd}`;\n const cached = await ctx.platform.cache.get<any>(cacheKey);\n\n let graph: DependencyGraph;\n\n if (cached) {\n // Deserialize: convert plain object back to Map\n graph = {\n nodes: new Map(Object.entries(cached.nodes).map(([key, value]: [string, any]) => [\n key,\n {\n ...value,\n deps: new Set(value.deps),\n devDeps: value.devDeps ? new Set(value.devDeps) : undefined,\n dependents: new Set(value.dependents),\n },\n ])),\n workspacePackages: new Set(cached.workspacePackages),\n };\n } else {\n graph = buildDependencyGraph(ctx.cwd);\n\n // Serialize: convert Map to plain object for Redis\n const serialized = {\n nodes: Object.fromEntries(\n Array.from(graph.nodes.entries()).map(([key, value]) => [\n key,\n {\n ...value,\n deps: Array.from(value.deps),\n devDeps: value.devDeps ? Array.from(value.devDeps) : undefined,\n dependents: Array.from(value.dependents),\n },\n ])\n ),\n workspacePackages: Array.from(graph.workspacePackages),\n };\n\n // Cache for 2 minutes\n await ctx.platform.cache.set(cacheKey, serialized, 120000);\n }\n\n // Handle different modes\n if (mode === 'stats') {\n return {\n mode,\n stats: calculateGraphStats(graph),\n };\n }\n\n if (mode === 'tree') {\n if (!packageName) {\n // Find root packages (packages that have no dependents - nothing depends on them)\n const rootPackages: string[] = [];\n for (const [name, node] of graph.nodes) {\n if (node.dependents.size === 0) {\n rootPackages.push(name);\n }\n }\n\n return {\n mode,\n tree: {\n name: 'Root Packages',\n children: rootPackages.map(pkg => buildDependencyTree(graph, pkg)),\n },\n };\n }\n return {\n mode,\n packageName,\n tree: buildDependencyTree(graph, packageName),\n };\n }\n\n if (!packageName) {\n throw new Error('packageName is required for reverse and impact modes');\n }\n\n if (mode === 'reverse') {\n const reverseDeps = getReverseDependencies(graph, packageName);\n return {\n mode,\n packageName,\n packages: Array.from(reverseDeps),\n };\n }\n\n if (mode === 'impact') {\n const affected = getImpactAnalysis(graph, packageName);\n return {\n mode,\n packageName,\n packages: Array.from(affected),\n };\n }\n\n throw new Error(`Unknown mode: ${mode}`);\n },\n});\n\n/**\n * Build dependency tree recursively\n */\nfunction buildDependencyTree(\n graph: DependencyGraph,\n packageName: string,\n visited: Set<string> = new Set()\n): DependencyTree {\n const node = graph.nodes.get(packageName);\n if (!node) {\n return { name: packageName, children: [] };\n }\n\n if (visited.has(packageName)) {\n return { name: `${packageName} (circular)`, children: [] };\n }\n\n visited.add(packageName);\n\n const children = Array.from(node.deps).map(dep =>\n buildDependencyTree(graph, dep, new Set(visited))\n );\n\n return {\n name: packageName,\n children,\n };\n}\n\n/**\n * Calculate graph statistics\n */\nfunction calculateGraphStats(graph: DependencyGraph): GraphStats {\n const { nodes } = graph;\n\n // Calculate average dependencies\n let totalDeps = 0;\n for (const node of nodes.values()) {\n totalDeps += node.deps.size;\n }\n const avgDeps = nodes.size > 0 ? totalDeps / nodes.size : 0;\n\n // Calculate max depth (longest dependency chain)\n let maxDepth = 0;\n for (const [name] of nodes) {\n const depth = calculateDepth(graph, name, new Set());\n if (depth > maxDepth) {\n maxDepth = depth;\n }\n }\n\n // Find most depended on packages (packages with most dependents)\n const dependentCounts = new Map<string, number>();\n for (const node of nodes.values()) {\n for (const dep of node.deps) {\n dependentCounts.set(dep, (dependentCounts.get(dep) ?? 0) + 1);\n }\n }\n\n const mostDepended = Array.from(dependentCounts.entries())\n .map(([name, count]) => ({ name, count }))\n .sort((a, b) => b.count - a.count)\n .slice(0, 5); // Top 5\n\n return {\n totalPackages: nodes.size,\n maxDepth,\n avgDependencies: Number.parseFloat(avgDeps.toFixed(2)),\n mostDepended,\n };\n}\n\n/**\n * Calculate depth of dependency chain from a package\n */\nfunction calculateDepth(\n graph: DependencyGraph,\n packageName: string,\n visited: Set<string>\n): number {\n const node = graph.nodes.get(packageName);\n if (!node || visited.has(packageName)) {\n return 0;\n }\n\n visited.add(packageName);\n\n let maxChildDepth = 0;\n for (const dep of node.deps) {\n const depth = calculateDepth(graph, dep, new Set(visited));\n if (depth > maxChildDepth) {\n maxChildDepth = depth;\n }\n }\n\n return 1 + maxChildDepth;\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../../../src/rest/handlers/graph-handler.ts"],"names":[],"mappings":"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","file":"graph-handler.js","sourcesContent":["/**\n * POST /graph handler\n *\n * Visualize dependency graph in different modes:\n * - tree: dependency tree for package\n * - reverse: who depends on this package\n * - impact: what will be affected by changes\n * - stats: graph statistics\n */\n\nimport { defineHandler, rethrowForRest, type PluginContextV3, type RestInput } from '@kb-labs/sdk';\nimport {\n buildDependencyGraph,\n getReverseDependencies,\n getImpactAnalysis,\n type DependencyGraph,\n} from '@kb-labs/quality-core/graph';\n\nexport type GraphRequest = {\n packageName?: string;\n mode: 'tree' | 'reverse' | 'impact' | 'stats';\n};\n\nexport type GraphResponse = {\n mode: string;\n packageName?: string;\n tree?: DependencyTree;\n packages?: string[];\n stats?: GraphStats;\n};\n\nexport type DependencyTree = {\n name: string;\n children: DependencyTree[];\n};\n\nexport type GraphStats = {\n totalPackages: number;\n maxDepth: number;\n avgDependencies: number;\n mostDepended: Array<{ name: string; count: number }>;\n};\n\nexport default defineHandler({\n async execute(\n ctx: PluginContextV3,\n input: RestInput<GraphRequest, unknown>\n ): Promise<GraphResponse> {\n try {\n const { packageName, mode } = input.query ?? { mode: 'stats' };\n\n // Build dependency graph (cached with Map serialization)\n const cacheKey = `quality:graph:${ctx.cwd}`;\n const cached = await ctx.platform.cache.get<any>(cacheKey);\n\n let graph: DependencyGraph;\n\n if (cached) {\n // Deserialize: convert plain object back to Map\n graph = {\n nodes: new Map(Object.entries(cached.nodes).map(([key, value]: [string, any]) => [\n key,\n {\n ...value,\n deps: new Set(value.deps),\n devDeps: value.devDeps ? new Set(value.devDeps) : undefined,\n dependents: new Set(value.dependents),\n },\n ])),\n workspacePackages: new Set(cached.workspacePackages),\n };\n } else {\n graph = buildDependencyGraph(ctx.cwd);\n\n // Serialize: convert Map to plain object for Redis\n const serialized = {\n nodes: Object.fromEntries(\n Array.from(graph.nodes.entries()).map(([key, value]) => [\n key,\n {\n ...value,\n deps: Array.from(value.deps),\n devDeps: value.devDeps ? Array.from(value.devDeps) : undefined,\n dependents: Array.from(value.dependents),\n },\n ])\n ),\n workspacePackages: Array.from(graph.workspacePackages),\n };\n\n // Cache for 2 minutes\n await ctx.platform.cache.set(cacheKey, serialized, 120000);\n }\n\n // Handle different modes\n if (mode === 'stats') {\n return {\n mode,\n stats: calculateGraphStats(graph),\n };\n }\n\n if (mode === 'tree') {\n if (!packageName) {\n // Find root packages (packages that have no dependents - nothing depends on them)\n const rootPackages: string[] = [];\n for (const [name, node] of graph.nodes) {\n if (node.dependents.size === 0) {\n rootPackages.push(name);\n }\n }\n\n return {\n mode,\n tree: {\n name: 'Root Packages',\n children: rootPackages.map(pkg => buildDependencyTree(graph, pkg)),\n },\n };\n }\n return {\n mode,\n packageName,\n tree: buildDependencyTree(graph, packageName),\n };\n }\n\n if (!packageName) {\n throw new Error('packageName is required for reverse and impact modes');\n }\n\n if (mode === 'reverse') {\n const reverseDeps = getReverseDependencies(graph, packageName);\n return {\n mode,\n packageName,\n packages: Array.from(reverseDeps),\n };\n }\n\n if (mode === 'impact') {\n const affected = getImpactAnalysis(graph, packageName);\n return {\n mode,\n packageName,\n packages: Array.from(affected),\n };\n }\n\n throw new Error(`Unknown mode: ${mode}`);\n } catch (err) {\n rethrowForRest(err);\n }\n },\n});\n\n/**\n * Build dependency tree recursively\n */\nfunction buildDependencyTree(\n graph: DependencyGraph,\n packageName: string,\n visited: Set<string> = new Set()\n): DependencyTree {\n const node = graph.nodes.get(packageName);\n if (!node) {\n return { name: packageName, children: [] };\n }\n\n if (visited.has(packageName)) {\n return { name: `${packageName} (circular)`, children: [] };\n }\n\n visited.add(packageName);\n\n const children = Array.from(node.deps).map(dep =>\n buildDependencyTree(graph, dep, new Set(visited))\n );\n\n return {\n name: packageName,\n children,\n };\n}\n\n/**\n * Calculate graph statistics\n */\nfunction calculateGraphStats(graph: DependencyGraph): GraphStats {\n const { nodes } = graph;\n\n // Calculate average dependencies\n let totalDeps = 0;\n for (const node of nodes.values()) {\n totalDeps += node.deps.size;\n }\n const avgDeps = nodes.size > 0 ? totalDeps / nodes.size : 0;\n\n // Calculate max depth (longest dependency chain)\n let maxDepth = 0;\n for (const [name] of nodes) {\n const depth = calculateDepth(graph, name, new Set());\n if (depth > maxDepth) {\n maxDepth = depth;\n }\n }\n\n // Find most depended on packages (packages with most dependents)\n const dependentCounts = new Map<string, number>();\n for (const node of nodes.values()) {\n for (const dep of node.deps) {\n dependentCounts.set(dep, (dependentCounts.get(dep) ?? 0) + 1);\n }\n }\n\n const mostDepended = Array.from(dependentCounts.entries())\n .map(([name, count]) => ({ name, count }))\n .sort((a, b) => b.count - a.count)\n .slice(0, 5); // Top 5\n\n return {\n totalPackages: nodes.size,\n maxDepth,\n avgDependencies: Number.parseFloat(avgDeps.toFixed(2)),\n mostDepended,\n };\n}\n\n/**\n * Calculate depth of dependency chain from a package\n */\nfunction calculateDepth(\n graph: DependencyGraph,\n packageName: string,\n visited: Set<string>\n): number {\n const node = graph.nodes.get(packageName);\n if (!node || visited.has(packageName)) {\n return 0;\n }\n\n visited.add(packageName);\n\n let maxChildDepth = 0;\n for (const dep of node.deps) {\n const depth = calculateDepth(graph, dep, new Set(visited));\n if (depth > maxChildDepth) {\n maxChildDepth = depth;\n }\n }\n\n return 1 + maxChildDepth;\n}\n"]}
|
|
@@ -1,15 +1,8 @@
|
|
|
1
1
|
import * as _kb_labs_shared_command_kit from '@kb-labs/shared-command-kit';
|
|
2
2
|
import { RestInput } from '@kb-labs/sdk';
|
|
3
|
-
import { HealthIssue } from '@kb-labs/quality-core/health';
|
|
4
3
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
}
|
|
8
|
-
type HealthResponse = {
|
|
9
|
-
score: number;
|
|
10
|
-
grade: string;
|
|
11
|
-
issues?: HealthIssue[];
|
|
12
|
-
};
|
|
13
|
-
declare const _default: _kb_labs_shared_command_kit.Handler<unknown, RestInput<HealthRequest, unknown, unknown>, HealthResponse>;
|
|
4
|
+
declare const _default: _kb_labs_shared_command_kit.Handler<unknown, RestInput<{
|
|
5
|
+
refresh?: boolean;
|
|
6
|
+
}, unknown, unknown>, {}>;
|
|
14
7
|
|
|
15
|
-
export {
|
|
8
|
+
export { _default as default };
|
|
@@ -1,16 +1,42 @@
|
|
|
1
|
-
import { defineHandler } from '@kb-labs/sdk';
|
|
2
|
-
import { calculateHealth } from '@kb-labs/quality-core
|
|
1
|
+
import { defineHandler, useConfig, rethrowForRest } from '@kb-labs/sdk';
|
|
2
|
+
import { analyzeLayering, analyzeTypes, analyzeCoupling, runKnip, calculateHealth } from '@kb-labs/quality-core';
|
|
3
|
+
import { defaultQualityConfig, CACHE_KEYS, CACHE_TTLS } from '@kb-labs/quality-contracts';
|
|
3
4
|
|
|
4
5
|
// src/rest/handlers/health-handler.ts
|
|
5
6
|
var health_handler_default = defineHandler({
|
|
6
7
|
async execute(ctx, input) {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
8
|
+
try {
|
|
9
|
+
const config = await useConfig();
|
|
10
|
+
const cfg = config ?? defaultQualityConfig;
|
|
11
|
+
const cwd = ctx.cwd ?? process.cwd();
|
|
12
|
+
const refresh = input.query?.refresh;
|
|
13
|
+
if (!refresh) {
|
|
14
|
+
const cached = await ctx.platform.cache.get(CACHE_KEYS.HEALTH);
|
|
15
|
+
if (cached) return cached;
|
|
16
|
+
}
|
|
17
|
+
const [layering, types] = await Promise.all([
|
|
18
|
+
analyzeLayering({ rootDir: cwd, layerMap: cfg.layers }),
|
|
19
|
+
analyzeTypes(cwd)
|
|
20
|
+
]);
|
|
21
|
+
const coupling = analyzeCoupling({ rootDir: cwd, layerMap: cfg.layers });
|
|
22
|
+
let knip = { unusedFiles: [], unusedExports: [], unusedDependencies: [], unlistedDependencies: [], totalIssues: 0 };
|
|
23
|
+
if (cfg.knip.enabled) {
|
|
24
|
+
knip = await runKnip({ shell: ctx.api.shell, rootDir: cwd });
|
|
25
|
+
}
|
|
26
|
+
const health = calculateHealth({
|
|
27
|
+
layering,
|
|
28
|
+
coupling,
|
|
29
|
+
types,
|
|
30
|
+
knip,
|
|
31
|
+
totalPackages: coupling.packages.length,
|
|
32
|
+
avgTestCoverage: null,
|
|
33
|
+
thresholds: cfg.thresholds
|
|
34
|
+
});
|
|
35
|
+
await ctx.platform.cache.set(CACHE_KEYS.HEALTH, health, CACHE_TTLS.FAST);
|
|
36
|
+
return health;
|
|
37
|
+
} catch (err) {
|
|
38
|
+
rethrowForRest(err);
|
|
39
|
+
}
|
|
14
40
|
}
|
|
15
41
|
});
|
|
16
42
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/rest/handlers/health-handler.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"sources":["../../../src/rest/handlers/health-handler.ts"],"names":[],"mappings":";;;;;AAUA,IAAO,yBAAQ,aAAA,CAAc;AAAA,EAC3B,MAAM,OAAA,CAAQ,GAAA,EAAsB,KAAA,EAAkD;AACpF,IAAA,IAAI;AACF,MAAA,MAAM,MAAA,GAAS,MAAM,SAAA,EAA+B;AACpD,MAAA,MAAM,MAAM,MAAA,IAAU,oBAAA;AACtB,MAAA,MAAM,GAAA,GAAM,GAAA,CAAI,GAAA,IAAO,OAAA,CAAQ,GAAA,EAAI;AACnC,MAAA,MAAM,OAAA,GAAU,MAAM,KAAA,EAAO,OAAA;AAE7B,MAAA,IAAI,CAAC,OAAA,EAAS;AACZ,QAAA,MAAM,SAAS,MAAM,GAAA,CAAI,SAAS,KAAA,CAAM,GAAA,CAAI,WAAW,MAAM,CAAA;AAC7D,QAAA,IAAI,QAAQ,OAAO,MAAA;AAAA,MACrB;AAEA,MAAA,MAAM,CAAC,QAAA,EAAU,KAAK,CAAA,GAAI,MAAM,QAAQ,GAAA,CAAI;AAAA,QAC1C,gBAAgB,EAAE,OAAA,EAAS,KAAK,QAAA,EAAU,GAAA,CAAI,QAAQ,CAAA;AAAA,QACtD,aAAa,GAAG;AAAA,OACjB,CAAA;AAED,MAAA,MAAM,QAAA,GAAW,gBAAgB,EAAE,OAAA,EAAS,KAAK,QAAA,EAAU,GAAA,CAAI,QAAQ,CAAA;AAEvE,MAAA,IAAI,IAAA,GAAmB,EAAE,WAAA,EAAa,IAAI,aAAA,EAAe,EAAC,EAAG,kBAAA,EAAoB,EAAC,EAAG,oBAAA,EAAsB,EAAC,EAAG,aAAa,CAAA,EAAE;AAC9H,MAAA,IAAI,GAAA,CAAI,KAAK,OAAA,EAAS;AACpB,QAAA,IAAA,GAAO,MAAM,QAAQ,EAAE,KAAA,EAAO,IAAI,GAAA,CAAI,KAAA,EAAO,OAAA,EAAS,GAAA,EAAK,CAAA;AAAA,MAC7D;AAEA,MAAA,MAAM,SAAS,eAAA,CAAgB;AAAA,QAC7B,QAAA;AAAA,QAAU,QAAA;AAAA,QAAU,KAAA;AAAA,QAAO,IAAA;AAAA,QAC3B,aAAA,EAAe,SAAS,QAAA,CAAS,MAAA;AAAA,QACjC,eAAA,EAAiB,IAAA;AAAA,QACjB,YAAY,GAAA,CAAI;AAAA,OACjB,CAAA;AAED,MAAA,MAAM,GAAA,CAAI,SAAS,KAAA,CAAM,GAAA,CAAI,WAAW,MAAA,EAAQ,MAAA,EAAQ,WAAW,IAAI,CAAA;AACvE,MAAA,OAAO,MAAA;AAAA,IACT,SAAS,GAAA,EAAK;AACZ,MAAA,cAAA,CAAe,GAAG,CAAA;AAAA,IACpB;AAAA,EACF;AACF,CAAC","file":"health-handler.js","sourcesContent":["import { defineHandler, rethrowForRest, useConfig, type PluginContextV3, type RestInput } from '@kb-labs/sdk';\nimport {\n analyzeLayering,\n analyzeCoupling,\n runKnip,\n analyzeTypes,\n calculateHealth,\n} from '@kb-labs/quality-core';\nimport { CACHE_KEYS, CACHE_TTLS, defaultQualityConfig, type QualityPluginConfig, type KnipReport } from '@kb-labs/quality-contracts';\n\nexport default defineHandler({\n async execute(ctx: PluginContextV3, input: RestInput<{ refresh?: boolean }, unknown>) {\n try {\n const config = await useConfig<QualityPluginConfig>();\n const cfg = config ?? defaultQualityConfig;\n const cwd = ctx.cwd ?? process.cwd();\n const refresh = input.query?.refresh;\n\n if (!refresh) {\n const cached = await ctx.platform.cache.get(CACHE_KEYS.HEALTH);\n if (cached) return cached;\n }\n\n const [layering, types] = await Promise.all([\n analyzeLayering({ rootDir: cwd, layerMap: cfg.layers }),\n analyzeTypes(cwd),\n ]);\n\n const coupling = analyzeCoupling({ rootDir: cwd, layerMap: cfg.layers });\n\n let knip: KnipReport = { unusedFiles: [], unusedExports: [], unusedDependencies: [], unlistedDependencies: [], totalIssues: 0 };\n if (cfg.knip.enabled) {\n knip = await runKnip({ shell: ctx.api.shell, rootDir: cwd });\n }\n\n const health = calculateHealth({\n layering, coupling, types, knip,\n totalPackages: coupling.packages.length,\n avgTestCoverage: null,\n thresholds: cfg.thresholds,\n });\n\n await ctx.platform.cache.set(CACHE_KEYS.HEALTH, health, CACHE_TTLS.FAST);\n return health;\n } catch (err) {\n rethrowForRest(err);\n }\n },\n});\n"]}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import * as _kb_labs_shared_command_kit from '@kb-labs/shared-command-kit';
|
|
2
|
+
import * as _kb_labs_quality_contracts from '@kb-labs/quality-contracts';
|
|
3
|
+
import { RestInput } from '@kb-labs/sdk';
|
|
4
|
+
|
|
5
|
+
declare const _default: _kb_labs_shared_command_kit.Handler<unknown, RestInput<unknown, unknown, unknown>, _kb_labs_quality_contracts.SnapshotHistory>;
|
|
6
|
+
|
|
7
|
+
export { _default as default };
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { defineHandler, useConfig, rethrowForRest } from '@kb-labs/sdk';
|
|
2
|
+
import { QualitySnapshotStore } from '@kb-labs/quality-core';
|
|
3
|
+
import { defaultQualityConfig } from '@kb-labs/quality-contracts';
|
|
4
|
+
|
|
5
|
+
// src/rest/handlers/history-handler.ts
|
|
6
|
+
var history_handler_default = defineHandler({
|
|
7
|
+
async execute(ctx, _input) {
|
|
8
|
+
try {
|
|
9
|
+
const config = await useConfig();
|
|
10
|
+
const cwd = ctx.cwd ?? process.cwd();
|
|
11
|
+
const store = new QualitySnapshotStore(cwd, config?.maxSnapshots ?? defaultQualityConfig.maxSnapshots);
|
|
12
|
+
return store.history();
|
|
13
|
+
} catch (err) {
|
|
14
|
+
rethrowForRest(err);
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
export { history_handler_default as default };
|
|
20
|
+
//# sourceMappingURL=history-handler.js.map
|
|
21
|
+
//# sourceMappingURL=history-handler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/rest/handlers/history-handler.ts"],"names":[],"mappings":";;;;;AAIA,IAAO,0BAAQ,aAAA,CAAc;AAAA,EAC3B,MAAM,OAAA,CAAQ,GAAA,EAAsB,MAAA,EAAqC;AACvE,IAAA,IAAI;AACF,MAAA,MAAM,MAAA,GAAS,MAAM,SAAA,EAA+B;AACpD,MAAA,MAAM,GAAA,GAAM,GAAA,CAAI,GAAA,IAAO,OAAA,CAAQ,GAAA,EAAI;AACnC,MAAA,MAAM,QAAQ,IAAI,oBAAA,CAAqB,KAAK,MAAA,EAAQ,YAAA,IAAgB,qBAAqB,YAAY,CAAA;AACrG,MAAA,OAAO,MAAM,OAAA,EAAQ;AAAA,IACvB,SAAS,GAAA,EAAK;AACZ,MAAA,cAAA,CAAe,GAAG,CAAA;AAAA,IACpB;AAAA,EACF;AACF,CAAC","file":"history-handler.js","sourcesContent":["import { defineHandler, rethrowForRest, useConfig, type PluginContextV3, type RestInput } from '@kb-labs/sdk';\nimport { QualitySnapshotStore } from '@kb-labs/quality-core';\nimport { defaultQualityConfig, type QualityPluginConfig } from '@kb-labs/quality-contracts';\n\nexport default defineHandler({\n async execute(ctx: PluginContextV3, _input: RestInput<unknown, unknown>) {\n try {\n const config = await useConfig<QualityPluginConfig>();\n const cwd = ctx.cwd ?? process.cwd();\n const store = new QualitySnapshotStore(cwd, config?.maxSnapshots ?? defaultQualityConfig.maxSnapshots);\n return store.history();\n } catch (err) {\n rethrowForRest(err);\n }\n },\n});\n"]}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import * as _kb_labs_shared_command_kit from '@kb-labs/shared-command-kit';
|
|
2
|
+
import { RestInput } from '@kb-labs/sdk';
|
|
3
|
+
|
|
4
|
+
declare const _default: _kb_labs_shared_command_kit.Handler<unknown, RestInput<{
|
|
5
|
+
refresh?: boolean;
|
|
6
|
+
}, unknown, unknown>, {}>;
|
|
7
|
+
|
|
8
|
+
export { _default as default };
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { defineHandler, useConfig, rethrowForRest } from '@kb-labs/sdk';
|
|
2
|
+
import { runKnip } from '@kb-labs/quality-core';
|
|
3
|
+
import { defaultQualityConfig, CACHE_KEYS, CACHE_TTLS } from '@kb-labs/quality-contracts';
|
|
4
|
+
|
|
5
|
+
// src/rest/handlers/knip-handler.ts
|
|
6
|
+
var knip_handler_default = defineHandler({
|
|
7
|
+
async execute(ctx, input) {
|
|
8
|
+
try {
|
|
9
|
+
const config = await useConfig();
|
|
10
|
+
const cfg = config ?? defaultQualityConfig;
|
|
11
|
+
const cwd = ctx.cwd ?? process.cwd();
|
|
12
|
+
const refresh = input.query?.refresh;
|
|
13
|
+
if (!refresh) {
|
|
14
|
+
const cached = await ctx.platform.cache.get(CACHE_KEYS.KNIP);
|
|
15
|
+
if (cached) return cached;
|
|
16
|
+
}
|
|
17
|
+
if (!cfg.knip.enabled) {
|
|
18
|
+
return { unusedFiles: [], unusedExports: [], unusedDependencies: [], unlistedDependencies: [], totalIssues: 0 };
|
|
19
|
+
}
|
|
20
|
+
const report = await runKnip({ shell: ctx.api.shell, rootDir: cwd });
|
|
21
|
+
await ctx.platform.cache.set(CACHE_KEYS.KNIP, report, CACHE_TTLS.SLOW);
|
|
22
|
+
return report;
|
|
23
|
+
} catch (err) {
|
|
24
|
+
rethrowForRest(err);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
export { knip_handler_default as default };
|
|
30
|
+
//# sourceMappingURL=knip-handler.js.map
|
|
31
|
+
//# sourceMappingURL=knip-handler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/rest/handlers/knip-handler.ts"],"names":[],"mappings":";;;;;AAIA,IAAO,uBAAQ,aAAA,CAAc;AAAA,EAC3B,MAAM,OAAA,CAAQ,GAAA,EAAsB,KAAA,EAAkD;AACpF,IAAA,IAAI;AACF,MAAA,MAAM,MAAA,GAAS,MAAM,SAAA,EAA+B;AACpD,MAAA,MAAM,MAAM,MAAA,IAAU,oBAAA;AACtB,MAAA,MAAM,GAAA,GAAM,GAAA,CAAI,GAAA,IAAO,OAAA,CAAQ,GAAA,EAAI;AACnC,MAAA,MAAM,OAAA,GAAU,MAAM,KAAA,EAAO,OAAA;AAE7B,MAAA,IAAI,CAAC,OAAA,EAAS;AACZ,QAAA,MAAM,SAAS,MAAM,GAAA,CAAI,SAAS,KAAA,CAAM,GAAA,CAAI,WAAW,IAAI,CAAA;AAC3D,QAAA,IAAI,QAAQ,OAAO,MAAA;AAAA,MACrB;AAEA,MAAA,IAAI,CAAC,GAAA,CAAI,IAAA,CAAK,OAAA,EAAS;AACrB,QAAA,OAAO,EAAE,WAAA,EAAa,EAAC,EAAG,eAAe,EAAC,EAAG,kBAAA,EAAoB,EAAC,EAAG,oBAAA,EAAsB,EAAC,EAAG,aAAa,CAAA,EAAE;AAAA,MAChH;AAEA,MAAA,MAAM,MAAA,GAAS,MAAM,OAAA,CAAQ,EAAE,KAAA,EAAO,IAAI,GAAA,CAAI,KAAA,EAAO,OAAA,EAAS,GAAA,EAAK,CAAA;AACnE,MAAA,MAAM,GAAA,CAAI,SAAS,KAAA,CAAM,GAAA,CAAI,WAAW,IAAA,EAAM,MAAA,EAAQ,WAAW,IAAI,CAAA;AACrE,MAAA,OAAO,MAAA;AAAA,IACT,SAAS,GAAA,EAAK;AACZ,MAAA,cAAA,CAAe,GAAG,CAAA;AAAA,IACpB;AAAA,EACF;AACF,CAAC","file":"knip-handler.js","sourcesContent":["import { defineHandler, rethrowForRest, useConfig, type PluginContextV3, type RestInput } from '@kb-labs/sdk';\nimport { runKnip } from '@kb-labs/quality-core';\nimport { CACHE_KEYS, CACHE_TTLS, defaultQualityConfig, type QualityPluginConfig } from '@kb-labs/quality-contracts';\n\nexport default defineHandler({\n async execute(ctx: PluginContextV3, input: RestInput<{ refresh?: boolean }, unknown>) {\n try {\n const config = await useConfig<QualityPluginConfig>();\n const cfg = config ?? defaultQualityConfig;\n const cwd = ctx.cwd ?? process.cwd();\n const refresh = input.query?.refresh;\n\n if (!refresh) {\n const cached = await ctx.platform.cache.get(CACHE_KEYS.KNIP);\n if (cached) return cached;\n }\n\n if (!cfg.knip.enabled) {\n return { unusedFiles: [], unusedExports: [], unusedDependencies: [], unlistedDependencies: [], totalIssues: 0 };\n }\n\n const report = await runKnip({ shell: ctx.api.shell, rootDir: cwd });\n await ctx.platform.cache.set(CACHE_KEYS.KNIP, report, CACHE_TTLS.SLOW);\n return report;\n } catch (err) {\n rethrowForRest(err);\n }\n },\n});\n"]}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import * as _kb_labs_shared_command_kit from '@kb-labs/shared-command-kit';
|
|
2
|
+
import { RestInput } from '@kb-labs/sdk';
|
|
3
|
+
|
|
4
|
+
declare const _default: _kb_labs_shared_command_kit.Handler<unknown, RestInput<{
|
|
5
|
+
refresh?: boolean;
|
|
6
|
+
}, unknown, unknown>, {}>;
|
|
7
|
+
|
|
8
|
+
export { _default as default };
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { defineHandler, useConfig, rethrowForRest } from '@kb-labs/sdk';
|
|
2
|
+
import { analyzeLayering } from '@kb-labs/quality-core';
|
|
3
|
+
import { defaultQualityConfig, CACHE_KEYS, CACHE_TTLS } from '@kb-labs/quality-contracts';
|
|
4
|
+
|
|
5
|
+
// src/rest/handlers/layers-handler.ts
|
|
6
|
+
var layers_handler_default = defineHandler({
|
|
7
|
+
async execute(ctx, input) {
|
|
8
|
+
try {
|
|
9
|
+
const config = await useConfig();
|
|
10
|
+
const cfg = config ?? defaultQualityConfig;
|
|
11
|
+
const cwd = ctx.cwd ?? process.cwd();
|
|
12
|
+
const refresh = input.query?.refresh;
|
|
13
|
+
if (!refresh) {
|
|
14
|
+
const cached = await ctx.platform.cache.get(CACHE_KEYS.LAYERS);
|
|
15
|
+
if (cached) return cached;
|
|
16
|
+
}
|
|
17
|
+
const report = await analyzeLayering({ rootDir: cwd, layerMap: cfg.layers });
|
|
18
|
+
await ctx.platform.cache.set(CACHE_KEYS.LAYERS, report, CACHE_TTLS.FAST);
|
|
19
|
+
return report;
|
|
20
|
+
} catch (err) {
|
|
21
|
+
rethrowForRest(err);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
export { layers_handler_default as default };
|
|
27
|
+
//# sourceMappingURL=layers-handler.js.map
|
|
28
|
+
//# sourceMappingURL=layers-handler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/rest/handlers/layers-handler.ts"],"names":[],"mappings":";;;;;AAIA,IAAO,yBAAQ,aAAA,CAAc;AAAA,EAC3B,MAAM,OAAA,CAAQ,GAAA,EAAsB,KAAA,EAAkD;AACpF,IAAA,IAAI;AACF,MAAA,MAAM,MAAA,GAAS,MAAM,SAAA,EAA+B;AACpD,MAAA,MAAM,MAAM,MAAA,IAAU,oBAAA;AACtB,MAAA,MAAM,GAAA,GAAM,GAAA,CAAI,GAAA,IAAO,OAAA,CAAQ,GAAA,EAAI;AACnC,MAAA,MAAM,OAAA,GAAU,MAAM,KAAA,EAAO,OAAA;AAE7B,MAAA,IAAI,CAAC,OAAA,EAAS;AACZ,QAAA,MAAM,SAAS,MAAM,GAAA,CAAI,SAAS,KAAA,CAAM,GAAA,CAAI,WAAW,MAAM,CAAA;AAC7D,QAAA,IAAI,QAAQ,OAAO,MAAA;AAAA,MACrB;AAEA,MAAA,MAAM,MAAA,GAAS,MAAM,eAAA,CAAgB,EAAE,SAAS,GAAA,EAAK,QAAA,EAAU,GAAA,CAAI,MAAA,EAAQ,CAAA;AAC3E,MAAA,MAAM,GAAA,CAAI,SAAS,KAAA,CAAM,GAAA,CAAI,WAAW,MAAA,EAAQ,MAAA,EAAQ,WAAW,IAAI,CAAA;AACvE,MAAA,OAAO,MAAA;AAAA,IACT,SAAS,GAAA,EAAK;AACZ,MAAA,cAAA,CAAe,GAAG,CAAA;AAAA,IACpB;AAAA,EACF;AACF,CAAC","file":"layers-handler.js","sourcesContent":["import { defineHandler, rethrowForRest, useConfig, type PluginContextV3, type RestInput } from '@kb-labs/sdk';\nimport { analyzeLayering } from '@kb-labs/quality-core';\nimport { CACHE_KEYS, CACHE_TTLS, defaultQualityConfig, type QualityPluginConfig } from '@kb-labs/quality-contracts';\n\nexport default defineHandler({\n async execute(ctx: PluginContextV3, input: RestInput<{ refresh?: boolean }, unknown>) {\n try {\n const config = await useConfig<QualityPluginConfig>();\n const cfg = config ?? defaultQualityConfig;\n const cwd = ctx.cwd ?? process.cwd();\n const refresh = input.query?.refresh;\n\n if (!refresh) {\n const cached = await ctx.platform.cache.get(CACHE_KEYS.LAYERS);\n if (cached) return cached;\n }\n\n const report = await analyzeLayering({ rootDir: cwd, layerMap: cfg.layers });\n await ctx.platform.cache.set(CACHE_KEYS.LAYERS, report, CACHE_TTLS.FAST);\n return report;\n } catch (err) {\n rethrowForRest(err);\n }\n },\n});\n"]}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import * as _kb_labs_shared_command_kit from '@kb-labs/shared-command-kit';
|
|
2
|
+
import * as _kb_labs_quality_contracts from '@kb-labs/quality-contracts';
|
|
3
|
+
import { RestInput } from '@kb-labs/sdk';
|
|
4
|
+
|
|
5
|
+
declare const _default: _kb_labs_shared_command_kit.Handler<unknown, RestInput<unknown, unknown, unknown>, _kb_labs_quality_contracts.QualitySnapshot>;
|
|
6
|
+
|
|
7
|
+
export { _default as default };
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { defineHandler, useConfig, rethrowForRest } from '@kb-labs/sdk';
|
|
2
|
+
import { analyzeLayering, analyzeTypes, analyzeCoupling, runKnip, calculateHealth, QualitySnapshotStore } from '@kb-labs/quality-core';
|
|
3
|
+
import { defaultQualityConfig } from '@kb-labs/quality-contracts';
|
|
4
|
+
|
|
5
|
+
// src/rest/handlers/snapshot-handler.ts
|
|
6
|
+
async function captureGit(shell, cwd) {
|
|
7
|
+
try {
|
|
8
|
+
const [c, b, m] = await Promise.all([
|
|
9
|
+
shell.exec("git", ["rev-parse", "--short", "HEAD"], { cwd, throwOnError: false }),
|
|
10
|
+
shell.exec("git", ["rev-parse", "--abbrev-ref", "HEAD"], { cwd, throwOnError: false }),
|
|
11
|
+
shell.exec("git", ["log", "-1", "--format=%s"], { cwd, throwOnError: false })
|
|
12
|
+
]);
|
|
13
|
+
if (!c.ok) return void 0;
|
|
14
|
+
return { commit: c.stdout.trim(), branch: b.stdout.trim() || "HEAD", message: m.stdout.trim() };
|
|
15
|
+
} catch {
|
|
16
|
+
return void 0;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
var snapshot_handler_default = defineHandler({
|
|
20
|
+
async execute(ctx, _input) {
|
|
21
|
+
try {
|
|
22
|
+
const config = await useConfig();
|
|
23
|
+
const cwd = ctx.cwd ?? process.cwd();
|
|
24
|
+
const cfg = config ?? defaultQualityConfig;
|
|
25
|
+
const [layering, types, git] = await Promise.all([
|
|
26
|
+
analyzeLayering({ rootDir: cwd, layerMap: cfg.layers }),
|
|
27
|
+
analyzeTypes(cwd),
|
|
28
|
+
captureGit(ctx.api.shell, cwd)
|
|
29
|
+
]);
|
|
30
|
+
const coupling = analyzeCoupling({ rootDir: cwd, layerMap: cfg.layers });
|
|
31
|
+
let knip = { unusedFiles: [], unusedExports: [], unusedDependencies: [], unlistedDependencies: [], totalIssues: 0 };
|
|
32
|
+
if (cfg.knip.enabled) {
|
|
33
|
+
knip = await runKnip({ shell: ctx.api.shell, rootDir: cwd });
|
|
34
|
+
}
|
|
35
|
+
const health = calculateHealth({
|
|
36
|
+
layering,
|
|
37
|
+
coupling,
|
|
38
|
+
types,
|
|
39
|
+
knip,
|
|
40
|
+
totalPackages: coupling.packages.length,
|
|
41
|
+
avgTestCoverage: null,
|
|
42
|
+
thresholds: cfg.thresholds
|
|
43
|
+
});
|
|
44
|
+
const store = new QualitySnapshotStore(cwd, cfg.maxSnapshots);
|
|
45
|
+
return store.save({
|
|
46
|
+
score: health.score,
|
|
47
|
+
grade: health.grade,
|
|
48
|
+
dimensions: health.dimensions,
|
|
49
|
+
counters: {
|
|
50
|
+
layeringViolations: layering.totalViolations,
|
|
51
|
+
avgInstability: coupling.avgInstability,
|
|
52
|
+
anyCount: types.packages.reduce((s, p) => s + p.anyCount, 0),
|
|
53
|
+
tsIgnoreCount: types.packages.reduce((s, p) => s + p.tsIgnoreCount, 0),
|
|
54
|
+
unusedFiles: knip.unusedFiles.length,
|
|
55
|
+
unusedDeps: knip.unusedDependencies.length
|
|
56
|
+
},
|
|
57
|
+
git: git ?? { commit: "", branch: "", message: "" }
|
|
58
|
+
});
|
|
59
|
+
} catch (err) {
|
|
60
|
+
rethrowForRest(err);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
export { snapshot_handler_default as default };
|
|
66
|
+
//# sourceMappingURL=snapshot-handler.js.map
|
|
67
|
+
//# sourceMappingURL=snapshot-handler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/rest/handlers/snapshot-handler.ts"],"names":[],"mappings":"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","file":"snapshot-handler.js","sourcesContent":["import { defineHandler, rethrowForRest, useConfig, type PluginContextV3, type RestInput, type ShellAPI } from '@kb-labs/sdk';\nimport {\n analyzeLayering,\n analyzeCoupling,\n runKnip,\n analyzeTypes,\n calculateHealth,\n QualitySnapshotStore,\n} from '@kb-labs/quality-core';\nimport { defaultQualityConfig, type QualityPluginConfig, type KnipReport } from '@kb-labs/quality-contracts';\n\nasync function captureGit(shell: ShellAPI, cwd: string) {\n try {\n const [c, b, m] = await Promise.all([\n shell.exec('git', ['rev-parse', '--short', 'HEAD'], { cwd, throwOnError: false }),\n shell.exec('git', ['rev-parse', '--abbrev-ref', 'HEAD'], { cwd, throwOnError: false }),\n shell.exec('git', ['log', '-1', '--format=%s'], { cwd, throwOnError: false }),\n ]);\n if (!c.ok) return undefined;\n return { commit: c.stdout.trim(), branch: b.stdout.trim() || 'HEAD', message: m.stdout.trim() };\n } catch {\n return undefined;\n }\n}\n\nexport default defineHandler({\n async execute(ctx: PluginContextV3, _input: RestInput<unknown, unknown>) {\n try {\n const config = await useConfig<QualityPluginConfig>();\n const cwd = ctx.cwd ?? process.cwd();\n const cfg = config ?? defaultQualityConfig;\n\n const [layering, types, git] = await Promise.all([\n analyzeLayering({ rootDir: cwd, layerMap: cfg.layers }),\n analyzeTypes(cwd),\n captureGit(ctx.api.shell, cwd),\n ]);\n\n const coupling = analyzeCoupling({ rootDir: cwd, layerMap: cfg.layers });\n\n let knip: KnipReport = { unusedFiles: [], unusedExports: [], unusedDependencies: [], unlistedDependencies: [], totalIssues: 0 };\n if (cfg.knip.enabled) {\n knip = await runKnip({ shell: ctx.api.shell, rootDir: cwd });\n }\n\n const health = calculateHealth({\n layering, coupling, types, knip,\n totalPackages: coupling.packages.length,\n avgTestCoverage: null,\n thresholds: cfg.thresholds,\n });\n\n const store = new QualitySnapshotStore(cwd, cfg.maxSnapshots);\n return store.save({\n score: health.score,\n grade: health.grade,\n dimensions: health.dimensions,\n counters: {\n layeringViolations: layering.totalViolations,\n avgInstability: coupling.avgInstability,\n anyCount: types.packages.reduce((s: number, p: { anyCount: number }) => s + p.anyCount, 0),\n tsIgnoreCount: types.packages.reduce((s: number, p: { tsIgnoreCount: number }) => s + p.tsIgnoreCount, 0),\n unusedFiles: knip.unusedFiles.length,\n unusedDeps: knip.unusedDependencies.length,\n },\n git: git ?? { commit: '', branch: '', message: '' },\n });\n } catch (err) {\n rethrowForRest(err);\n }\n },\n});\n"]}
|
|
@@ -1,17 +1,21 @@
|
|
|
1
|
-
import { defineHandler } from '@kb-labs/sdk';
|
|
1
|
+
import { defineHandler, rethrowForRest } from '@kb-labs/sdk';
|
|
2
2
|
import { analyzeStalePackages } from '@kb-labs/quality-core/stale';
|
|
3
3
|
|
|
4
4
|
// src/rest/handlers/stale-handler.ts
|
|
5
5
|
var stale_handler_default = defineHandler({
|
|
6
6
|
async execute(ctx, input) {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
7
|
+
try {
|
|
8
|
+
const { detailed } = input.query ?? {};
|
|
9
|
+
const analysis = await analyzeStalePackages(ctx.cwd, detailed);
|
|
10
|
+
return {
|
|
11
|
+
stalePackages: analysis.stalePackages,
|
|
12
|
+
totalStale: analysis.totalStale,
|
|
13
|
+
totalAffected: analysis.totalAffected,
|
|
14
|
+
criticalChains: detailed ? analysis.criticalChains : void 0
|
|
15
|
+
};
|
|
16
|
+
} catch (err) {
|
|
17
|
+
rethrowForRest(err);
|
|
18
|
+
}
|
|
15
19
|
}
|
|
16
20
|
});
|
|
17
21
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/rest/handlers/stale-handler.ts"],"names":[],"mappings":";;;;AAwCA,IAAO,wBAAQ,aAAA,CAAc;AAAA,EAC3B,MAAM,OAAA,CACJ,GAAA,EACA,KAAA,EACwB;AACxB,IAAA,MAAM,EAAE,QAAA,EAAS,GAAI,KAAA,CAAM,SAAS,EAAC;AAErC,
|
|
1
|
+
{"version":3,"sources":["../../../src/rest/handlers/stale-handler.ts"],"names":[],"mappings":";;;;AAwCA,IAAO,wBAAQ,aAAA,CAAc;AAAA,EAC3B,MAAM,OAAA,CACJ,GAAA,EACA,KAAA,EACwB;AACxB,IAAA,IAAI;AACF,MAAA,MAAM,EAAE,QAAA,EAAS,GAAI,KAAA,CAAM,SAAS,EAAC;AAErC,MAAA,MAAM,QAAA,GAAW,MAAM,oBAAA,CAAqB,GAAA,CAAI,KAAK,QAAQ,CAAA;AAE7D,MAAA,OAAO;AAAA,QACL,eAAe,QAAA,CAAS,aAAA;AAAA,QACxB,YAAY,QAAA,CAAS,UAAA;AAAA,QACrB,eAAe,QAAA,CAAS,aAAA;AAAA,QACxB,cAAA,EAAgB,QAAA,GAAW,QAAA,CAAS,cAAA,GAAiB,KAAA;AAAA,OACvD;AAAA,IACF,SAAS,GAAA,EAAK;AACZ,MAAA,cAAA,CAAe,GAAG,CAAA;AAAA,IACpB;AAAA,EACF;AACF,CAAC","file":"stale-handler.js","sourcesContent":["/**\n * GET /stale handler\n *\n * Detect stale packages that need rebuilding.\n * Shows packages where source is newer than dist, or dependencies were rebuilt.\n */\n\nimport { defineHandler, rethrowForRest, type PluginContextV3, type RestInput } from '@kb-labs/sdk';\nimport {\n analyzeStalePackages,\n} from '@kb-labs/quality-core/stale';\n\nexport type StaleRequest = {\n detailed?: boolean;\n};\n\nexport type StalePackage = {\n name: string;\n path: string;\n reason: 'source-newer' | 'dependency-rebuilt' | 'missing-dist';\n sourceModified?: string;\n distModified?: string;\n affectedPackages: string[];\n affectedCount: number;\n severity: 'critical' | 'high' | 'medium' | 'low';\n};\n\nexport type StaleChain = {\n root: string;\n affected: string[];\n depth: number;\n};\n\nexport type StaleResponse = {\n stalePackages: StalePackage[];\n totalStale: number;\n totalAffected: number;\n criticalChains?: StaleChain[];\n};\n\nexport default defineHandler({\n async execute(\n ctx: PluginContextV3,\n input: RestInput<StaleRequest, unknown>\n ): Promise<StaleResponse> {\n try {\n const { detailed } = input.query ?? {};\n\n const analysis = await analyzeStalePackages(ctx.cwd, detailed);\n\n return {\n stalePackages: analysis.stalePackages,\n totalStale: analysis.totalStale,\n totalAffected: analysis.totalAffected,\n criticalChains: detailed ? analysis.criticalChains : undefined,\n };\n } catch (err) {\n rethrowForRest(err);\n }\n },\n});\n"]}
|
|
@@ -1,16 +1,11 @@
|
|
|
1
1
|
import * as _kb_labs_shared_command_kit from '@kb-labs/shared-command-kit';
|
|
2
2
|
import { RestInput } from '@kb-labs/sdk';
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
includeHealth?: boolean;
|
|
6
|
-
};
|
|
7
|
-
type StatsResponse = {
|
|
4
|
+
interface StatsResult {
|
|
8
5
|
packages: number;
|
|
9
6
|
loc: number;
|
|
10
7
|
size: string;
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
};
|
|
14
|
-
declare const _default: _kb_labs_shared_command_kit.Handler<unknown, RestInput<StatsRequest, unknown, unknown>, StatsResponse>;
|
|
8
|
+
}
|
|
9
|
+
declare const _default: _kb_labs_shared_command_kit.Handler<unknown, RestInput<unknown, unknown, unknown>, StatsResult>;
|
|
15
10
|
|
|
16
|
-
export {
|
|
11
|
+
export { _default as default };
|
|
@@ -1,26 +1,30 @@
|
|
|
1
|
-
import { defineHandler } from '@kb-labs/sdk';
|
|
1
|
+
import { defineHandler, useCache, rethrowForRest } from '@kb-labs/sdk';
|
|
2
2
|
import { calculateStats } from '@kb-labs/quality-core/stats';
|
|
3
|
-
import { calculateHealth } from '@kb-labs/quality-core/health';
|
|
4
3
|
|
|
5
4
|
// src/rest/handlers/stats-handler.ts
|
|
5
|
+
var CACHE_KEY = "quality:stats";
|
|
6
|
+
var CACHE_TTL_MS = 5 * 60 * 1e3;
|
|
6
7
|
var stats_handler_default = defineHandler({
|
|
7
|
-
async execute(ctx,
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
8
|
+
async execute(ctx, _input) {
|
|
9
|
+
try {
|
|
10
|
+
const cache = useCache();
|
|
11
|
+
if (cache) {
|
|
12
|
+
const cached = await cache.get(CACHE_KEY);
|
|
13
|
+
if (cached) return cached;
|
|
14
|
+
}
|
|
15
|
+
const stats = await calculateStats(ctx.cwd);
|
|
16
|
+
const result = {
|
|
17
|
+
packages: stats.packages,
|
|
18
|
+
loc: stats.loc,
|
|
19
|
+
size: stats.sizeFormatted
|
|
20
|
+
};
|
|
21
|
+
if (cache) {
|
|
22
|
+
await cache.set(CACHE_KEY, result, CACHE_TTL_MS);
|
|
23
|
+
}
|
|
24
|
+
return result;
|
|
25
|
+
} catch (err) {
|
|
26
|
+
rethrowForRest(err);
|
|
16
27
|
}
|
|
17
|
-
return {
|
|
18
|
-
packages: stats.packages,
|
|
19
|
-
loc: stats.loc,
|
|
20
|
-
size: stats.sizeFormatted,
|
|
21
|
-
health,
|
|
22
|
-
grade
|
|
23
|
-
};
|
|
24
28
|
}
|
|
25
29
|
});
|
|
26
30
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/rest/handlers/stats-handler.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"sources":["../../../src/rest/handlers/stats-handler.ts"],"names":[],"mappings":";;;;AAGA,IAAM,SAAA,GAAY,eAAA;AAClB,IAAM,YAAA,GAAe,IAAI,EAAA,GAAK,GAAA;AAQ9B,IAAO,wBAAQ,aAAA,CAAc;AAAA,EAC3B,MAAM,OAAA,CAAQ,GAAA,EAAsB,MAAA,EAAqC;AACvE,IAAA,IAAI;AACF,MAAA,MAAM,QAAQ,QAAA,EAAS;AAEvB,MAAA,IAAI,KAAA,EAAO;AACT,QAAA,MAAM,MAAA,GAAS,MAAM,KAAA,CAAM,GAAA,CAAiB,SAAS,CAAA;AACrD,QAAA,IAAI,QAAQ,OAAO,MAAA;AAAA,MACrB;AAEA,MAAA,MAAM,KAAA,GAAQ,MAAM,cAAA,CAAe,GAAA,CAAI,GAAG,CAAA;AAC1C,MAAA,MAAM,MAAA,GAAsB;AAAA,QAC1B,UAAU,KAAA,CAAM,QAAA;AAAA,QAChB,KAAK,KAAA,CAAM,GAAA;AAAA,QACX,MAAM,KAAA,CAAM;AAAA,OACd;AAEA,MAAA,IAAI,KAAA,EAAO;AACT,QAAA,MAAM,KAAA,CAAM,GAAA,CAAI,SAAA,EAAW,MAAA,EAAQ,YAAY,CAAA;AAAA,MACjD;AAEA,MAAA,OAAO,MAAA;AAAA,IACT,SAAS,GAAA,EAAK;AACZ,MAAA,cAAA,CAAe,GAAG,CAAA;AAAA,IACpB;AAAA,EACF;AACF,CAAC","file":"stats-handler.js","sourcesContent":["import { defineHandler, rethrowForRest, useCache, type PluginContextV3, type RestInput } from '@kb-labs/sdk';\nimport { calculateStats } from '@kb-labs/quality-core/stats';\n\nconst CACHE_KEY = 'quality:stats';\nconst CACHE_TTL_MS = 5 * 60 * 1000;\n\ninterface StatsResult {\n packages: number;\n loc: number;\n size: string;\n}\n\nexport default defineHandler({\n async execute(ctx: PluginContextV3, _input: RestInput<unknown, unknown>) {\n try {\n const cache = useCache();\n\n if (cache) {\n const cached = await cache.get<StatsResult>(CACHE_KEY);\n if (cached) return cached;\n }\n\n const stats = await calculateStats(ctx.cwd);\n const result: StatsResult = {\n packages: stats.packages,\n loc: stats.loc,\n size: stats.sizeFormatted,\n };\n\n if (cache) {\n await cache.set(CACHE_KEY, result, CACHE_TTL_MS);\n }\n\n return result;\n } catch (err) {\n rethrowForRest(err);\n }\n },\n});\n"]}
|
|
@@ -1,16 +1,20 @@
|
|
|
1
|
-
import { defineHandler } from '@kb-labs/sdk';
|
|
1
|
+
import { defineHandler, rethrowForRest } from '@kb-labs/sdk';
|
|
2
2
|
import { runTests } from '@kb-labs/quality-core/tests';
|
|
3
3
|
|
|
4
4
|
// src/rest/handlers/tests-handler.ts
|
|
5
5
|
var tests_handler_default = defineHandler({
|
|
6
6
|
async execute(ctx, input) {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
7
|
+
try {
|
|
8
|
+
const { package: packageFilter, timeout, withCoverage, coverageOnly } = input.query ?? {};
|
|
9
|
+
return runTests(ctx.cwd, {
|
|
10
|
+
packageFilter,
|
|
11
|
+
timeout: timeout || 6e4,
|
|
12
|
+
withCoverage: withCoverage ?? false,
|
|
13
|
+
coverageOnly: coverageOnly ?? false
|
|
14
|
+
});
|
|
15
|
+
} catch (err) {
|
|
16
|
+
rethrowForRest(err);
|
|
17
|
+
}
|
|
14
18
|
}
|
|
15
19
|
});
|
|
16
20
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/rest/handlers/tests-handler.ts"],"names":[],"mappings":";;;;AAmBA,IAAO,wBAAQ,aAAA,CAAc;AAAA,EAC3B,MAAM,OAAA,CACJ,GAAA,EACA,KAAA,EACwB;AACxB,IAAA,MAAM,EAAE,SAAS,aAAA,EAAe,OAAA,EAAS,cAAc,YAAA,EAAa,GAAI,KAAA,CAAM,KAAA,IAAS,EAAC;AAExF,
|
|
1
|
+
{"version":3,"sources":["../../../src/rest/handlers/tests-handler.ts"],"names":[],"mappings":";;;;AAmBA,IAAO,wBAAQ,aAAA,CAAc;AAAA,EAC3B,MAAM,OAAA,CACJ,GAAA,EACA,KAAA,EACwB;AACxB,IAAA,IAAI;AACF,MAAA,MAAM,EAAE,SAAS,aAAA,EAAe,OAAA,EAAS,cAAc,YAAA,EAAa,GAAI,KAAA,CAAM,KAAA,IAAS,EAAC;AAExF,MAAA,OAAO,QAAA,CAAS,IAAI,GAAA,EAAK;AAAA,QACvB,aAAA;AAAA,QACA,SAAS,OAAA,IAAW,GAAA;AAAA,QACpB,cAAc,YAAA,IAAgB,KAAA;AAAA,QAC9B,cAAc,YAAA,IAAgB;AAAA,OAC/B,CAAA;AAAA,IACH,SAAS,GAAA,EAAK;AACZ,MAAA,cAAA,CAAe,GAAG,CAAA;AAAA,IACpB;AAAA,EACF;AACF,CAAC","file":"tests-handler.js","sourcesContent":["/**\n * GET /tests handler\n *\n * Test execution and coverage tracking across monorepo\n */\n\nimport { defineHandler, rethrowForRest, type PluginContextV3, type RestInput } from '@kb-labs/sdk';\nimport { runTests } from '@kb-labs/quality-core/tests';\nimport type { TestRunResult } from '@kb-labs/quality-contracts';\n\nexport type TestsRequest = {\n package?: string;\n timeout?: number;\n withCoverage?: boolean;\n coverageOnly?: boolean;\n};\n\nexport type TestsResponse = TestRunResult;\n\nexport default defineHandler({\n async execute(\n ctx: PluginContextV3,\n input: RestInput<TestsRequest, unknown>\n ): Promise<TestsResponse> {\n try {\n const { package: packageFilter, timeout, withCoverage, coverageOnly } = input.query ?? {};\n\n return runTests(ctx.cwd, {\n packageFilter,\n timeout: timeout || 60000,\n withCoverage: withCoverage ?? false,\n coverageOnly: coverageOnly ?? false,\n });\n } catch (err) {\n rethrowForRest(err);\n }\n },\n});\n"]}
|
|
@@ -1,14 +1,18 @@
|
|
|
1
|
-
import { defineHandler } from '@kb-labs/sdk';
|
|
1
|
+
import { defineHandler, rethrowForRest } from '@kb-labs/sdk';
|
|
2
2
|
import { analyzeTypes } from '@kb-labs/quality-core/types';
|
|
3
3
|
|
|
4
4
|
// src/rest/handlers/types-handler.ts
|
|
5
5
|
var types_handler_default = defineHandler({
|
|
6
6
|
async execute(ctx, input) {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
7
|
+
try {
|
|
8
|
+
const { package: packageFilter, errorsOnly } = input.query ?? {};
|
|
9
|
+
return analyzeTypes(ctx.cwd, {
|
|
10
|
+
packageFilter,
|
|
11
|
+
errorsOnly: errorsOnly ?? false
|
|
12
|
+
});
|
|
13
|
+
} catch (err) {
|
|
14
|
+
rethrowForRest(err);
|
|
15
|
+
}
|
|
12
16
|
}
|
|
13
17
|
});
|
|
14
18
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/rest/handlers/types-handler.ts"],"names":[],"mappings":";;;;AAiBA,IAAO,wBAAQ,aAAA,CAAc;AAAA,EAC3B,MAAM,OAAA,CACJ,GAAA,EACA,KAAA,EACwB;AACxB,IAAA,MAAM,EAAE,OAAA,EAAS,aAAA,EAAe,YAAW,GAAI,KAAA,CAAM,SAAS,EAAC;AAE/D,
|
|
1
|
+
{"version":3,"sources":["../../../src/rest/handlers/types-handler.ts"],"names":[],"mappings":";;;;AAiBA,IAAO,wBAAQ,aAAA,CAAc;AAAA,EAC3B,MAAM,OAAA,CACJ,GAAA,EACA,KAAA,EACwB;AACxB,IAAA,IAAI;AACF,MAAA,MAAM,EAAE,OAAA,EAAS,aAAA,EAAe,YAAW,GAAI,KAAA,CAAM,SAAS,EAAC;AAE/D,MAAA,OAAO,YAAA,CAAa,IAAI,GAAA,EAAK;AAAA,QAC3B,aAAA;AAAA,QACA,YAAY,UAAA,IAAc;AAAA,OAC3B,CAAA;AAAA,IACH,SAAS,GAAA,EAAK;AACZ,MAAA,cAAA,CAAe,GAAG,CAAA;AAAA,IACpB;AAAA,EACF;AACF,CAAC","file":"types-handler.js","sourcesContent":["/**\n * GET /types handler\n *\n * TypeScript type safety analysis across monorepo\n */\n\nimport { defineHandler, rethrowForRest, type PluginContextV3, type RestInput } from '@kb-labs/sdk';\nimport { analyzeTypes } from '@kb-labs/quality-core/types';\nimport type { TypeAnalysisResult } from '@kb-labs/quality-contracts';\n\nexport type TypesRequest = {\n package?: string;\n errorsOnly?: boolean;\n};\n\nexport type TypesResponse = TypeAnalysisResult;\n\nexport default defineHandler({\n async execute(\n ctx: PluginContextV3,\n input: RestInput<TypesRequest, unknown>\n ): Promise<TypesResponse> {\n try {\n const { package: packageFilter, errorsOnly } = input.query ?? {};\n\n return analyzeTypes(ctx.cwd, {\n packageFilter,\n errorsOnly: errorsOnly ?? false,\n });\n } catch (err) {\n rethrowForRest(err);\n }\n },\n});\n"]}
|