@kb-labs/devkit 1.0.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/.cursorrules +32 -0
- package/.github/CODEOWNERS +2 -0
- package/.github/actions/setup-node-pnpm/action.yml +47 -0
- package/.github/workflow-templates/ci.yml +13 -0
- package/.github/workflow-templates/drift-check.yml +10 -0
- package/.github/workflow-templates/profiles-validate.yml +16 -0
- package/.github/workflow-templates/release.yml +8 -0
- package/.github/workflows/ci-reusable.yml +131 -0
- package/.github/workflows/drift-check-reusable.yml +23 -0
- package/.github/workflows/fixtures.yml +74 -0
- package/.github/workflows/profiles-validate-reusable.yml +67 -0
- package/.github/workflows/release-reusable.yml +50 -0
- package/.vscode/settings.json +23 -0
- package/AGENTS.md +130 -0
- package/LICENSE +21 -0
- package/README.md +1542 -0
- package/agents/devkit-maintainer/context.globs +15 -0
- package/agents/devkit-maintainer/permissions.yml +17 -0
- package/agents/devkit-maintainer/prompt.md +28 -0
- package/agents/devkit-maintainer/runbook.md +31 -0
- package/agents/docs-crafter/prompt.md +24 -0
- package/agents/docs-crafter/runbook.md +18 -0
- package/agents/release-manager/context.globs +7 -0
- package/agents/release-manager/prompt.md +27 -0
- package/agents/release-manager/runbook.md +17 -0
- package/agents/test-generator/context.globs +7 -0
- package/agents/test-generator/prompt.md +27 -0
- package/agents/test-generator/runbook.md +18 -0
- package/bin/devkit-architecture.mjs +1225 -0
- package/bin/devkit-build-order.mjs +500 -0
- package/bin/devkit-check-build-readiness.mjs +222 -0
- package/bin/devkit-check-commands.mjs +394 -0
- package/bin/devkit-check-configs.mjs +461 -0
- package/bin/devkit-check-deprecated.mjs +532 -0
- package/bin/devkit-check-duplicates.mjs +431 -0
- package/bin/devkit-check-exports.mjs +561 -0
- package/bin/devkit-check-imports.mjs +712 -0
- package/bin/devkit-check-paths.mjs +670 -0
- package/bin/devkit-check-scripts.mjs +335 -0
- package/bin/devkit-check-structure.mjs +495 -0
- package/bin/devkit-check-types.mjs +450 -0
- package/bin/devkit-ci.mjs +261 -0
- package/bin/devkit-core-gate.mjs +225 -0
- package/bin/devkit-fix-deps.mjs +1169 -0
- package/bin/devkit-freshness.mjs +199 -0
- package/bin/devkit-health.mjs +489 -0
- package/bin/devkit-migrate-configs.mjs +370 -0
- package/bin/devkit-paths.mjs +192 -0
- package/bin/devkit-stats.mjs +453 -0
- package/bin/devkit-sync.mjs +12 -0
- package/bin/devkit-tsup-external.mjs +148 -0
- package/bin/devkit-types-audit.mjs +615 -0
- package/bin/devkit-types-order.mjs +637 -0
- package/bin/devkit-validate-naming.mjs +203 -0
- package/bin/devkit-visualize.mjs +452 -0
- package/bin/kb-devkit-qa-history.mjs +453 -0
- package/bin/kb-devkit-qa.mjs +915 -0
- package/eslint/node.js +134 -0
- package/eslint/react.js +260 -0
- package/package.json +186 -0
- package/prettier/index.json +10 -0
- package/sync/index.mjs +693 -0
- package/templates/configs/README.md +306 -0
- package/templates/configs/eslint.config.js +27 -0
- package/templates/configs/package.json.bin +25 -0
- package/templates/configs/package.json.lib +30 -0
- package/templates/configs/tsconfig.build.json +15 -0
- package/templates/configs/tsconfig.json +9 -0
- package/templates/configs/tsup.config.bin.ts +34 -0
- package/templates/configs/tsup.config.cli.ts +41 -0
- package/templates/configs/tsup.config.dual.ts +46 -0
- package/templates/configs/tsup.config.ts +36 -0
- package/templates/package-json/README.md +290 -0
- package/templates/package-json/package.json.bin.template +40 -0
- package/templates/package-json/package.json.template +45 -0
- package/tsconfig/base.json +21 -0
- package/tsconfig/cli.json +12 -0
- package/tsconfig/dist/__tests__/cache.spec.d.ts +6 -0
- package/tsconfig/dist/__tests__/cache.spec.d.ts.map +1 -0
- package/tsconfig/dist/__tests__/cache.spec.js +85 -0
- package/tsconfig/dist/__tests__/cache.spec.js.map +1 -0
- package/tsconfig/dist/__tests__/fs-atomic.spec.d.ts +6 -0
- package/tsconfig/dist/__tests__/fs-atomic.spec.d.ts.map +1 -0
- package/tsconfig/dist/__tests__/fs-atomic.spec.js +153 -0
- package/tsconfig/dist/__tests__/fs-atomic.spec.js.map +1 -0
- package/tsconfig/dist/__tests__/init-workspace.spec.d.ts +6 -0
- package/tsconfig/dist/__tests__/init-workspace.spec.d.ts.map +1 -0
- package/tsconfig/dist/__tests__/init-workspace.spec.js +99 -0
- package/tsconfig/dist/__tests__/init-workspace.spec.js.map +1 -0
- package/tsconfig/dist/__tests__/kb-error.spec.d.ts +6 -0
- package/tsconfig/dist/__tests__/kb-error.spec.d.ts.map +1 -0
- package/tsconfig/dist/__tests__/kb-error.spec.js +190 -0
- package/tsconfig/dist/__tests__/kb-error.spec.js.map +1 -0
- package/tsconfig/dist/__tests__/preset-lockfile.spec.d.ts +6 -0
- package/tsconfig/dist/__tests__/preset-lockfile.spec.d.ts.map +1 -0
- package/tsconfig/dist/__tests__/preset-lockfile.spec.js +142 -0
- package/tsconfig/dist/__tests__/preset-lockfile.spec.js.map +1 -0
- package/tsconfig/dist/__tests__/product-config-profiles.spec.d.ts +6 -0
- package/tsconfig/dist/__tests__/product-config-profiles.spec.d.ts.map +1 -0
- package/tsconfig/dist/__tests__/product-config-profiles.spec.js +100 -0
- package/tsconfig/dist/__tests__/product-config-profiles.spec.js.map +1 -0
- package/tsconfig/dist/__tests__/product-config.spec.d.ts +6 -0
- package/tsconfig/dist/__tests__/product-config.spec.d.ts.map +1 -0
- package/tsconfig/dist/__tests__/product-config.spec.js +298 -0
- package/tsconfig/dist/__tests__/product-config.spec.js.map +1 -0
- package/tsconfig/dist/__tests__/runtime.spec.d.ts +2 -0
- package/tsconfig/dist/__tests__/runtime.spec.d.ts.map +1 -0
- package/tsconfig/dist/__tests__/runtime.spec.js +127 -0
- package/tsconfig/dist/__tests__/runtime.spec.js.map +1 -0
- package/tsconfig/dist/__tests__/upsert-lockfile.spec.d.ts +6 -0
- package/tsconfig/dist/__tests__/upsert-lockfile.spec.d.ts.map +1 -0
- package/tsconfig/dist/__tests__/upsert-lockfile.spec.js +251 -0
- package/tsconfig/dist/__tests__/upsert-lockfile.spec.js.map +1 -0
- package/tsconfig/dist/__tests__/validate-config.spec.d.ts +2 -0
- package/tsconfig/dist/__tests__/validate-config.spec.d.ts.map +1 -0
- package/tsconfig/dist/__tests__/validate-config.spec.js +14 -0
- package/tsconfig/dist/__tests__/validate-config.spec.js.map +1 -0
- package/tsconfig/dist/api/init-workspace.d.ts +10 -0
- package/tsconfig/dist/api/init-workspace.d.ts.map +1 -0
- package/tsconfig/dist/api/init-workspace.js +191 -0
- package/tsconfig/dist/api/init-workspace.js.map +1 -0
- package/tsconfig/dist/api/product-config.d.ts +21 -0
- package/tsconfig/dist/api/product-config.d.ts.map +1 -0
- package/tsconfig/dist/api/product-config.js +192 -0
- package/tsconfig/dist/api/product-config.js.map +1 -0
- package/tsconfig/dist/api/read-config.d.ts +22 -0
- package/tsconfig/dist/api/read-config.d.ts.map +1 -0
- package/tsconfig/dist/api/read-config.js +105 -0
- package/tsconfig/dist/api/read-config.js.map +1 -0
- package/tsconfig/dist/api/upsert-lockfile.d.ts +10 -0
- package/tsconfig/dist/api/upsert-lockfile.d.ts.map +1 -0
- package/tsconfig/dist/api/upsert-lockfile.js +63 -0
- package/tsconfig/dist/api/upsert-lockfile.js.map +1 -0
- package/tsconfig/dist/cache/fs-cache.d.ts +38 -0
- package/tsconfig/dist/cache/fs-cache.d.ts.map +1 -0
- package/tsconfig/dist/cache/fs-cache.js +142 -0
- package/tsconfig/dist/cache/fs-cache.js.map +1 -0
- package/tsconfig/dist/errors/kb-error.d.ts +32 -0
- package/tsconfig/dist/errors/kb-error.d.ts.map +1 -0
- package/tsconfig/dist/errors/kb-error.js +54 -0
- package/tsconfig/dist/errors/kb-error.js.map +1 -0
- package/tsconfig/dist/fs/__tests__/fs.spec.d.ts +2 -0
- package/tsconfig/dist/fs/__tests__/fs.spec.d.ts.map +1 -0
- package/tsconfig/dist/fs/__tests__/fs.spec.js +22 -0
- package/tsconfig/dist/fs/__tests__/fs.spec.js.map +1 -0
- package/tsconfig/dist/fs/fs.d.ts +6 -0
- package/tsconfig/dist/fs/fs.d.ts.map +1 -0
- package/tsconfig/dist/fs/fs.js +12 -0
- package/tsconfig/dist/fs/fs.js.map +1 -0
- package/tsconfig/dist/fs/index.d.ts +2 -0
- package/tsconfig/dist/fs/index.d.ts.map +1 -0
- package/tsconfig/dist/fs/index.js +2 -0
- package/tsconfig/dist/fs/index.js.map +1 -0
- package/tsconfig/dist/hash/config-hash.d.ts +17 -0
- package/tsconfig/dist/hash/config-hash.d.ts.map +1 -0
- package/tsconfig/dist/hash/config-hash.js +55 -0
- package/tsconfig/dist/hash/config-hash.js.map +1 -0
- package/tsconfig/dist/index.d.ts +5 -0
- package/tsconfig/dist/index.d.ts.map +1 -0
- package/tsconfig/dist/index.js +5 -0
- package/tsconfig/dist/index.js.map +1 -0
- package/tsconfig/dist/lockfile/lockfile.d.ts +54 -0
- package/tsconfig/dist/lockfile/lockfile.d.ts.map +1 -0
- package/tsconfig/dist/lockfile/lockfile.js +141 -0
- package/tsconfig/dist/lockfile/lockfile.js.map +1 -0
- package/tsconfig/dist/logging/__tests__/logger.spec.d.ts +2 -0
- package/tsconfig/dist/logging/__tests__/logger.spec.d.ts.map +1 -0
- package/tsconfig/dist/logging/__tests__/logger.spec.js +65 -0
- package/tsconfig/dist/logging/__tests__/logger.spec.js.map +1 -0
- package/tsconfig/dist/logging/__tests__/redaction.spec.d.ts +2 -0
- package/tsconfig/dist/logging/__tests__/redaction.spec.d.ts.map +1 -0
- package/tsconfig/dist/logging/__tests__/redaction.spec.js +34 -0
- package/tsconfig/dist/logging/__tests__/redaction.spec.js.map +1 -0
- package/tsconfig/dist/logging/__tests__/sinks-and-env.spec.d.ts +2 -0
- package/tsconfig/dist/logging/__tests__/sinks-and-env.spec.d.ts.map +1 -0
- package/tsconfig/dist/logging/__tests__/sinks-and-env.spec.js +90 -0
- package/tsconfig/dist/logging/__tests__/sinks-and-env.spec.js.map +1 -0
- package/tsconfig/dist/logging/index.d.ts +6 -0
- package/tsconfig/dist/logging/index.d.ts.map +1 -0
- package/tsconfig/dist/logging/index.js +6 -0
- package/tsconfig/dist/logging/index.js.map +1 -0
- package/tsconfig/dist/logging/logger.d.ts +9 -0
- package/tsconfig/dist/logging/logger.d.ts.map +1 -0
- package/tsconfig/dist/logging/logger.js +101 -0
- package/tsconfig/dist/logging/logger.js.map +1 -0
- package/tsconfig/dist/logging/redaction.d.ts +7 -0
- package/tsconfig/dist/logging/redaction.d.ts.map +1 -0
- package/tsconfig/dist/logging/redaction.js +23 -0
- package/tsconfig/dist/logging/redaction.js.map +1 -0
- package/tsconfig/dist/logging/sinks/json.d.ts +4 -0
- package/tsconfig/dist/logging/sinks/json.d.ts.map +1 -0
- package/tsconfig/dist/logging/sinks/json.js +23 -0
- package/tsconfig/dist/logging/sinks/json.js.map +1 -0
- package/tsconfig/dist/logging/sinks/stdout.d.ts +3 -0
- package/tsconfig/dist/logging/sinks/stdout.d.ts.map +1 -0
- package/tsconfig/dist/logging/sinks/stdout.js +24 -0
- package/tsconfig/dist/logging/sinks/stdout.js.map +1 -0
- package/tsconfig/dist/logging/types/index.d.ts +2 -0
- package/tsconfig/dist/logging/types/index.d.ts.map +1 -0
- package/tsconfig/dist/logging/types/index.js +2 -0
- package/tsconfig/dist/logging/types/index.js.map +1 -0
- package/tsconfig/dist/logging/types/types.d.ts +37 -0
- package/tsconfig/dist/logging/types/types.d.ts.map +1 -0
- package/tsconfig/dist/logging/types/types.js +2 -0
- package/tsconfig/dist/logging/types/types.js.map +1 -0
- package/tsconfig/dist/merge/layered-merge.d.ts +16 -0
- package/tsconfig/dist/merge/layered-merge.d.ts.map +1 -0
- package/tsconfig/dist/merge/layered-merge.js +97 -0
- package/tsconfig/dist/merge/layered-merge.js.map +1 -0
- package/tsconfig/dist/preset/resolve-preset.d.ts +29 -0
- package/tsconfig/dist/preset/resolve-preset.d.ts.map +1 -0
- package/tsconfig/dist/preset/resolve-preset.js +104 -0
- package/tsconfig/dist/preset/resolve-preset.js.map +1 -0
- package/tsconfig/dist/repo/__tests__/repo.spec.d.ts +2 -0
- package/tsconfig/dist/repo/__tests__/repo.spec.d.ts.map +1 -0
- package/tsconfig/dist/repo/__tests__/repo.spec.js +25 -0
- package/tsconfig/dist/repo/__tests__/repo.spec.js.map +1 -0
- package/tsconfig/dist/repo/index.d.ts +2 -0
- package/tsconfig/dist/repo/index.d.ts.map +1 -0
- package/tsconfig/dist/repo/index.js +2 -0
- package/tsconfig/dist/repo/index.js.map +1 -0
- package/tsconfig/dist/repo/repo.d.ts +6 -0
- package/tsconfig/dist/repo/repo.d.ts.map +1 -0
- package/tsconfig/dist/repo/repo.js +25 -0
- package/tsconfig/dist/repo/repo.js.map +1 -0
- package/tsconfig/dist/runtime/index.d.ts +2 -0
- package/tsconfig/dist/runtime/index.d.ts.map +1 -0
- package/tsconfig/dist/runtime/index.js +2 -0
- package/tsconfig/dist/runtime/index.js.map +1 -0
- package/tsconfig/dist/runtime/runtime.d.ts +46 -0
- package/tsconfig/dist/runtime/runtime.d.ts.map +1 -0
- package/tsconfig/dist/runtime/runtime.js +126 -0
- package/tsconfig/dist/runtime/runtime.js.map +1 -0
- package/tsconfig/dist/tsconfig.tools.tsbuildinfo +1 -0
- package/tsconfig/dist/tsconfig.tsbuildinfo +1 -0
- package/tsconfig/dist/types/index.d.ts +2 -0
- package/tsconfig/dist/types/index.d.ts.map +1 -0
- package/tsconfig/dist/types/index.js +2 -0
- package/tsconfig/dist/types/index.js.map +1 -0
- package/tsconfig/dist/types/init.d.ts +34 -0
- package/tsconfig/dist/types/init.d.ts.map +1 -0
- package/tsconfig/dist/types/init.js +6 -0
- package/tsconfig/dist/types/init.js.map +1 -0
- package/tsconfig/dist/types/preset.d.ts +27 -0
- package/tsconfig/dist/types/preset.d.ts.map +1 -0
- package/tsconfig/dist/types/preset.js +6 -0
- package/tsconfig/dist/types/preset.js.map +1 -0
- package/tsconfig/dist/types/types.d.ts +6 -0
- package/tsconfig/dist/types/types.d.ts.map +1 -0
- package/tsconfig/dist/types/types.js +2 -0
- package/tsconfig/dist/types/types.js.map +1 -0
- package/tsconfig/dist/utils/__tests__/env.spec.d.ts +2 -0
- package/tsconfig/dist/utils/__tests__/env.spec.d.ts.map +1 -0
- package/tsconfig/dist/utils/__tests__/env.spec.js +33 -0
- package/tsconfig/dist/utils/__tests__/env.spec.js.map +1 -0
- package/tsconfig/dist/utils/env.d.ts +7 -0
- package/tsconfig/dist/utils/env.d.ts.map +1 -0
- package/tsconfig/dist/utils/env.js +25 -0
- package/tsconfig/dist/utils/env.js.map +1 -0
- package/tsconfig/dist/utils/fs-atomic.d.ts +15 -0
- package/tsconfig/dist/utils/fs-atomic.d.ts.map +1 -0
- package/tsconfig/dist/utils/fs-atomic.js +45 -0
- package/tsconfig/dist/utils/fs-atomic.js.map +1 -0
- package/tsconfig/dist/utils/index.d.ts +3 -0
- package/tsconfig/dist/utils/index.d.ts.map +1 -0
- package/tsconfig/dist/utils/index.js +3 -0
- package/tsconfig/dist/utils/index.js.map +1 -0
- package/tsconfig/dist/utils/paths.d.ts +21 -0
- package/tsconfig/dist/utils/paths.d.ts.map +1 -0
- package/tsconfig/dist/utils/paths.js +32 -0
- package/tsconfig/dist/utils/paths.js.map +1 -0
- package/tsconfig/dist/utils/product-normalize.d.ts +27 -0
- package/tsconfig/dist/utils/product-normalize.d.ts.map +1 -0
- package/tsconfig/dist/utils/product-normalize.js +45 -0
- package/tsconfig/dist/utils/product-normalize.js.map +1 -0
- package/tsconfig/dist/validation/validate-config.d.ts +7 -0
- package/tsconfig/dist/validation/validate-config.d.ts.map +1 -0
- package/tsconfig/dist/validation/validate-config.js +22 -0
- package/tsconfig/dist/validation/validate-config.js.map +1 -0
- package/tsconfig/lib.json +13 -0
- package/tsconfig/node.json +12 -0
- package/tsconfig/react-app.json +8 -0
- package/tsconfig/react-lib.json +8 -0
- package/tsconfig/test.json +15 -0
- package/tsup/bin.js +172 -0
- package/tsup/dual.js +155 -0
- package/tsup/external-sync.mjs +41 -0
- package/tsup/external.mjs +109 -0
- package/tsup/node.js +65 -0
- package/tsup/react-lib.js +18 -0
- package/tsup/sdk.js +118 -0
- package/vite/react-app.js +50 -0
- package/vitest/node.js +37 -0
- package/vitest/react.js +39 -0
- package/vitest/vitest-setup.ts +9 -0
|
@@ -0,0 +1,532 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @kb-labs/devkit - Deprecated Code Checker
|
|
5
|
+
*
|
|
6
|
+
* Finds all @deprecated markers in the codebase with context:
|
|
7
|
+
* - JSDoc @deprecated tags
|
|
8
|
+
* - TypeScript @deprecated decorator patterns
|
|
9
|
+
* - Inline // @deprecated comments
|
|
10
|
+
*
|
|
11
|
+
* Provides:
|
|
12
|
+
* - Location and context for each deprecated item
|
|
13
|
+
* - Grouping by package
|
|
14
|
+
* - Statistics and summary
|
|
15
|
+
* - Multiple output formats (table, JSON, markdown)
|
|
16
|
+
*
|
|
17
|
+
* Usage:
|
|
18
|
+
* kb-devkit-check-deprecated # Check all packages
|
|
19
|
+
* kb-devkit-check-deprecated --package cli-core # Check specific package
|
|
20
|
+
* kb-devkit-check-deprecated --json # JSON output for AI/CI
|
|
21
|
+
* kb-devkit-check-deprecated --md # Markdown output
|
|
22
|
+
* kb-devkit-check-deprecated --stats # Show statistics only
|
|
23
|
+
* kb-devkit-check-deprecated --verbose # Show full context
|
|
24
|
+
*/
|
|
25
|
+
|
|
26
|
+
import fs from 'node:fs';
|
|
27
|
+
import path from 'node:path';
|
|
28
|
+
import { fileURLToPath } from 'node:url';
|
|
29
|
+
|
|
30
|
+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
31
|
+
|
|
32
|
+
// ANSI colors
|
|
33
|
+
const colors = {
|
|
34
|
+
reset: '\x1b[0m',
|
|
35
|
+
red: '\x1b[31m',
|
|
36
|
+
green: '\x1b[32m',
|
|
37
|
+
yellow: '\x1b[33m',
|
|
38
|
+
blue: '\x1b[34m',
|
|
39
|
+
magenta: '\x1b[35m',
|
|
40
|
+
cyan: '\x1b[36m',
|
|
41
|
+
gray: '\x1b[90m',
|
|
42
|
+
bold: '\x1b[1m',
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
function log(message, color = 'reset') {
|
|
46
|
+
if (!options.json && !options.md) {
|
|
47
|
+
console.log(`${colors[color]}${message}${colors.reset}`);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// Parse CLI arguments
|
|
52
|
+
const args = process.argv.slice(2);
|
|
53
|
+
const options = {
|
|
54
|
+
package: args.find((arg) => arg.startsWith('--package='))?.split('=')[1],
|
|
55
|
+
json: args.includes('--json'),
|
|
56
|
+
md: args.includes('--md'),
|
|
57
|
+
stats: args.includes('--stats'),
|
|
58
|
+
verbose: args.includes('--verbose') || args.includes('-v'),
|
|
59
|
+
help: args.includes('--help') || args.includes('-h'),
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
if (options.help) {
|
|
63
|
+
console.log(`
|
|
64
|
+
@kb-labs/devkit - Deprecated Code Checker
|
|
65
|
+
|
|
66
|
+
Finds all @deprecated markers in the codebase.
|
|
67
|
+
|
|
68
|
+
Usage:
|
|
69
|
+
kb-devkit-check-deprecated # Check all packages
|
|
70
|
+
kb-devkit-check-deprecated --package=cli-core # Check specific package
|
|
71
|
+
kb-devkit-check-deprecated --json # JSON output for AI/CI
|
|
72
|
+
kb-devkit-check-deprecated --md # Markdown output
|
|
73
|
+
kb-devkit-check-deprecated --stats # Show statistics only
|
|
74
|
+
kb-devkit-check-deprecated --verbose # Show full context
|
|
75
|
+
|
|
76
|
+
Options:
|
|
77
|
+
--package=NAME Check only specific package
|
|
78
|
+
--json Output as JSON (for CI/AI agents)
|
|
79
|
+
--md Output as Markdown table
|
|
80
|
+
--stats Show statistics summary only
|
|
81
|
+
--verbose, -v Show full context around deprecated items
|
|
82
|
+
--help, -h Show this help message
|
|
83
|
+
`);
|
|
84
|
+
process.exit(0);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Find all kb-labs-* packages
|
|
89
|
+
*/
|
|
90
|
+
function findPackages(rootDir, filterPackage) {
|
|
91
|
+
const packages = [];
|
|
92
|
+
const entries = fs.readdirSync(rootDir, { withFileTypes: true });
|
|
93
|
+
|
|
94
|
+
for (const entry of entries) {
|
|
95
|
+
if (!entry.isDirectory() || !entry.name.startsWith('kb-labs-')) {continue;}
|
|
96
|
+
|
|
97
|
+
const repoPath = path.join(rootDir, entry.name);
|
|
98
|
+
const packagesDir = path.join(repoPath, 'packages');
|
|
99
|
+
|
|
100
|
+
if (!fs.existsSync(packagesDir)) {continue;}
|
|
101
|
+
|
|
102
|
+
const packageDirs = fs.readdirSync(packagesDir, { withFileTypes: true });
|
|
103
|
+
|
|
104
|
+
for (const pkgDir of packageDirs) {
|
|
105
|
+
if (!pkgDir.isDirectory()) {continue;}
|
|
106
|
+
|
|
107
|
+
if (filterPackage && pkgDir.name !== filterPackage) {continue;}
|
|
108
|
+
|
|
109
|
+
const packageJsonPath = path.join(packagesDir, pkgDir.name, 'package.json');
|
|
110
|
+
const srcDir = path.join(packagesDir, pkgDir.name, 'src');
|
|
111
|
+
|
|
112
|
+
if (fs.existsSync(packageJsonPath) && fs.existsSync(srcDir)) {
|
|
113
|
+
try {
|
|
114
|
+
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf-8'));
|
|
115
|
+
packages.push({
|
|
116
|
+
name: packageJson.name,
|
|
117
|
+
shortName: pkgDir.name,
|
|
118
|
+
repo: entry.name,
|
|
119
|
+
path: path.join(packagesDir, pkgDir.name),
|
|
120
|
+
srcPath: srcDir,
|
|
121
|
+
});
|
|
122
|
+
} catch {
|
|
123
|
+
// Skip invalid package.json
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
return packages;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* Recursively find all TypeScript/JavaScript files
|
|
134
|
+
*/
|
|
135
|
+
function findSourceFiles(dir) {
|
|
136
|
+
const files = [];
|
|
137
|
+
const entries = fs.readdirSync(dir, { withFileTypes: true });
|
|
138
|
+
|
|
139
|
+
for (const entry of entries) {
|
|
140
|
+
const fullPath = path.join(dir, entry.name);
|
|
141
|
+
|
|
142
|
+
if (entry.isDirectory()) {
|
|
143
|
+
// Skip node_modules and dist
|
|
144
|
+
if (entry.name === 'node_modules' || entry.name === 'dist') {continue;}
|
|
145
|
+
files.push(...findSourceFiles(fullPath));
|
|
146
|
+
} else if (/\.(ts|tsx|js|jsx|mjs|cjs)$/.test(entry.name)) {
|
|
147
|
+
files.push(fullPath);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
return files;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* Extract deprecated items from file content
|
|
156
|
+
*/
|
|
157
|
+
function extractDeprecated(filePath, content) {
|
|
158
|
+
const deprecated = [];
|
|
159
|
+
const lines = content.split('\n');
|
|
160
|
+
|
|
161
|
+
// Only match JSDoc @deprecated - this is the standard way in TypeScript/JavaScript
|
|
162
|
+
// Pattern: /** ... @deprecated ... */
|
|
163
|
+
const jsdocPattern = /\/\*\*[\s\S]*?@deprecated\s*([^\n*]*)?[\s\S]*?\*\//g;
|
|
164
|
+
|
|
165
|
+
let match;
|
|
166
|
+
while ((match = jsdocPattern.exec(content)) !== null) {
|
|
167
|
+
// Skip if @deprecated is inside a regex literal or string (e.g., /@deprecated/i)
|
|
168
|
+
const jsdocContent = match[0];
|
|
169
|
+
if (/\/@deprecated\//.test(jsdocContent) || /['"`].*@deprecated.*['"`]/.test(jsdocContent)) {
|
|
170
|
+
continue;
|
|
171
|
+
}
|
|
172
|
+
const startIndex = match.index;
|
|
173
|
+
const endIndex = match.index + match[0].length;
|
|
174
|
+
const lineNumber = content.substring(0, startIndex).split('\n').length;
|
|
175
|
+
const endLine = content.substring(0, endIndex).split('\n').length;
|
|
176
|
+
|
|
177
|
+
// Extract reason from @deprecated line
|
|
178
|
+
const deprecatedLineMatch = match[0].match(/@deprecated\s*([^\n*]*)/);
|
|
179
|
+
const reason = (deprecatedLineMatch?.[1] || '').trim();
|
|
180
|
+
|
|
181
|
+
// Get context: the code AFTER the JSDoc comment
|
|
182
|
+
const contextLines = [];
|
|
183
|
+
for (let i = endLine; i < Math.min(endLine + 5, lines.length); i++) {
|
|
184
|
+
const line = lines[i];
|
|
185
|
+
// Skip empty lines
|
|
186
|
+
if (line.trim() === '') {continue;}
|
|
187
|
+
|
|
188
|
+
contextLines.push(line);
|
|
189
|
+
|
|
190
|
+
// Stop at declaration
|
|
191
|
+
if (/^\s*(export\s+)?(default\s+)?(async\s+)?(abstract\s+)?(function|class|interface|type|const|let|var|enum)\s+\w+/.test(line)) {
|
|
192
|
+
break;
|
|
193
|
+
}
|
|
194
|
+
if (contextLines.length >= 2) {break;}
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
// Try to extract the name of the deprecated item
|
|
198
|
+
let itemName = 'unknown';
|
|
199
|
+
const contextText = contextLines.join('\n');
|
|
200
|
+
|
|
201
|
+
// Match export declarations
|
|
202
|
+
const nameMatch = contextText.match(
|
|
203
|
+
/(?:export\s+)?(?:default\s+)?(?:async\s+)?(?:abstract\s+)?(?:function|class|interface|type|const|let|var|enum)\s+(\w+)/
|
|
204
|
+
);
|
|
205
|
+
if (nameMatch) {
|
|
206
|
+
itemName = nameMatch[1];
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
// Determine item type from context
|
|
210
|
+
let itemType = 'unknown';
|
|
211
|
+
if (/\bfunction\b/.test(contextText)) {itemType = 'function';}
|
|
212
|
+
else if (/\bclass\b/.test(contextText)) {itemType = 'class';}
|
|
213
|
+
else if (/\binterface\b/.test(contextText)) {itemType = 'interface';}
|
|
214
|
+
else if (/\btype\s+\w+/.test(contextText)) {itemType = 'type';}
|
|
215
|
+
else if (/\bconst\b/.test(contextText)) {itemType = 'const';}
|
|
216
|
+
else if (/\benum\b/.test(contextText)) {itemType = 'enum';}
|
|
217
|
+
else if (/\blet\b|\bvar\b/.test(contextText)) {itemType = 'variable';}
|
|
218
|
+
|
|
219
|
+
// Skip if no code follows (orphan comment)
|
|
220
|
+
if (contextLines.length === 0 || itemName === 'unknown') {
|
|
221
|
+
continue;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
deprecated.push({
|
|
225
|
+
file: filePath,
|
|
226
|
+
line: lineNumber,
|
|
227
|
+
type: 'jsdoc',
|
|
228
|
+
itemType,
|
|
229
|
+
itemName,
|
|
230
|
+
reason: reason || 'No reason provided',
|
|
231
|
+
context: contextLines.slice(0, 2).join('\n'),
|
|
232
|
+
});
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
// Deduplicate by item name + file (same item might have multiple @deprecated in same JSDoc)
|
|
236
|
+
const seen = new Set();
|
|
237
|
+
return deprecated.filter((item) => {
|
|
238
|
+
const key = `${item.file}:${item.itemName}`;
|
|
239
|
+
if (seen.has(key)) {return false;}
|
|
240
|
+
seen.add(key);
|
|
241
|
+
return true;
|
|
242
|
+
});
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
/**
|
|
246
|
+
* Analyze a single package
|
|
247
|
+
*/
|
|
248
|
+
function analyzePackage(pkg) {
|
|
249
|
+
const files = findSourceFiles(pkg.srcPath);
|
|
250
|
+
const deprecated = [];
|
|
251
|
+
|
|
252
|
+
for (const file of files) {
|
|
253
|
+
try {
|
|
254
|
+
const content = fs.readFileSync(file, 'utf-8');
|
|
255
|
+
const items = extractDeprecated(file, content);
|
|
256
|
+
deprecated.push(...items);
|
|
257
|
+
} catch {
|
|
258
|
+
// Skip unreadable files
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
return {
|
|
263
|
+
package: pkg.name,
|
|
264
|
+
shortName: pkg.shortName,
|
|
265
|
+
repo: pkg.repo,
|
|
266
|
+
deprecated,
|
|
267
|
+
fileCount: files.length,
|
|
268
|
+
};
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
/**
|
|
272
|
+
* Format output as table (default)
|
|
273
|
+
*/
|
|
274
|
+
function formatTable(results, rootDir) {
|
|
275
|
+
const totalDeprecated = results.reduce((sum, r) => sum + r.deprecated.length, 0);
|
|
276
|
+
|
|
277
|
+
if (totalDeprecated === 0) {
|
|
278
|
+
log('\nā
No @deprecated items found!\n', 'green');
|
|
279
|
+
return;
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
log(`\nš Found ${totalDeprecated} @deprecated item(s)\n`, 'yellow');
|
|
283
|
+
|
|
284
|
+
for (const result of results) {
|
|
285
|
+
if (result.deprecated.length === 0) {continue;}
|
|
286
|
+
|
|
287
|
+
log(`\nš¦ ${result.package} (${result.deprecated.length} deprecated)`, 'cyan');
|
|
288
|
+
log('ā'.repeat(60), 'gray');
|
|
289
|
+
|
|
290
|
+
for (const item of result.deprecated) {
|
|
291
|
+
const relativePath = path.relative(rootDir, item.file);
|
|
292
|
+
const location = `${relativePath}:${item.line}`;
|
|
293
|
+
|
|
294
|
+
log(` ā ļø ${item.itemType} ${colors.bold}${item.itemName}${colors.reset}`, 'yellow');
|
|
295
|
+
log(` š ${location}`, 'gray');
|
|
296
|
+
|
|
297
|
+
if (item.reason && item.reason !== 'No reason provided') {
|
|
298
|
+
log(` š¬ ${item.reason}`, 'gray');
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
if (options.verbose && item.context) {
|
|
302
|
+
log(' āā Context:', 'gray');
|
|
303
|
+
for (const line of item.context.split('\n')) {
|
|
304
|
+
log(` ā ${line}`, 'gray');
|
|
305
|
+
}
|
|
306
|
+
log(' āā', 'gray');
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
// Summary
|
|
312
|
+
log('\n' + 'ā'.repeat(60), 'gray');
|
|
313
|
+
log('š Summary:', 'blue');
|
|
314
|
+
|
|
315
|
+
const byType = {};
|
|
316
|
+
for (const result of results) {
|
|
317
|
+
for (const item of result.deprecated) {
|
|
318
|
+
byType[item.itemType] = (byType[item.itemType] || 0) + 1;
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
for (const [type, count] of Object.entries(byType).sort((a, b) => b[1] - a[1])) {
|
|
323
|
+
log(` ${type}: ${count}`, 'gray');
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
log(`\n Total: ${totalDeprecated} deprecated item(s) in ${results.filter((r) => r.deprecated.length > 0).length} package(s)`, 'yellow');
|
|
327
|
+
log('', 'reset');
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
/**
|
|
331
|
+
* Format output as JSON
|
|
332
|
+
*/
|
|
333
|
+
function formatJSON(results, rootDir) {
|
|
334
|
+
const output = {
|
|
335
|
+
summary: {
|
|
336
|
+
totalDeprecated: results.reduce((sum, r) => sum + r.deprecated.length, 0),
|
|
337
|
+
packagesWithDeprecated: results.filter((r) => r.deprecated.length > 0).length,
|
|
338
|
+
totalPackages: results.length,
|
|
339
|
+
byType: {},
|
|
340
|
+
},
|
|
341
|
+
packages: results
|
|
342
|
+
.filter((r) => r.deprecated.length > 0)
|
|
343
|
+
.map((r) => ({
|
|
344
|
+
name: r.package,
|
|
345
|
+
shortName: r.shortName,
|
|
346
|
+
repo: r.repo,
|
|
347
|
+
deprecatedCount: r.deprecated.length,
|
|
348
|
+
items: r.deprecated.map((item) => ({
|
|
349
|
+
name: item.itemName,
|
|
350
|
+
type: item.itemType,
|
|
351
|
+
file: path.relative(rootDir, item.file),
|
|
352
|
+
line: item.line,
|
|
353
|
+
reason: item.reason,
|
|
354
|
+
context: options.verbose ? item.context : undefined,
|
|
355
|
+
})),
|
|
356
|
+
})),
|
|
357
|
+
};
|
|
358
|
+
|
|
359
|
+
// Calculate byType
|
|
360
|
+
for (const result of results) {
|
|
361
|
+
for (const item of result.deprecated) {
|
|
362
|
+
output.summary.byType[item.itemType] = (output.summary.byType[item.itemType] || 0) + 1;
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
console.log(JSON.stringify(output, null, 2));
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
/**
|
|
370
|
+
* Format output as Markdown
|
|
371
|
+
*/
|
|
372
|
+
function formatMarkdown(results, rootDir) {
|
|
373
|
+
const totalDeprecated = results.reduce((sum, r) => sum + r.deprecated.length, 0);
|
|
374
|
+
|
|
375
|
+
console.log('# Deprecated Code Report\n');
|
|
376
|
+
console.log(`Generated: ${new Date().toISOString()}\n`);
|
|
377
|
+
|
|
378
|
+
console.log('## Summary\n');
|
|
379
|
+
console.log(`- **Total deprecated items:** ${totalDeprecated}`);
|
|
380
|
+
console.log(`- **Packages affected:** ${results.filter((r) => r.deprecated.length > 0).length}`);
|
|
381
|
+
console.log(`- **Total packages scanned:** ${results.length}\n`);
|
|
382
|
+
|
|
383
|
+
if (totalDeprecated === 0) {
|
|
384
|
+
console.log('ā
No deprecated items found!\n');
|
|
385
|
+
return;
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
// By type table
|
|
389
|
+
const byType = {};
|
|
390
|
+
for (const result of results) {
|
|
391
|
+
for (const item of result.deprecated) {
|
|
392
|
+
byType[item.itemType] = (byType[item.itemType] || 0) + 1;
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
console.log('### By Type\n');
|
|
397
|
+
console.log('| Type | Count |');
|
|
398
|
+
console.log('|------|-------|');
|
|
399
|
+
for (const [type, count] of Object.entries(byType).sort((a, b) => b[1] - a[1])) {
|
|
400
|
+
console.log(`| ${type} | ${count} |`);
|
|
401
|
+
}
|
|
402
|
+
console.log('');
|
|
403
|
+
|
|
404
|
+
// Detailed list
|
|
405
|
+
console.log('## Deprecated Items\n');
|
|
406
|
+
|
|
407
|
+
for (const result of results) {
|
|
408
|
+
if (result.deprecated.length === 0) {continue;}
|
|
409
|
+
|
|
410
|
+
console.log(`### ${result.package}\n`);
|
|
411
|
+
console.log(`| Item | Type | Location | Reason |`);
|
|
412
|
+
console.log(`|------|------|----------|--------|`);
|
|
413
|
+
|
|
414
|
+
for (const item of result.deprecated) {
|
|
415
|
+
const relativePath = path.relative(rootDir, item.file);
|
|
416
|
+
const location = `\`${relativePath}:${item.line}\``;
|
|
417
|
+
const reason = item.reason.replace(/\|/g, '\\|').substring(0, 50);
|
|
418
|
+
console.log(`| \`${item.itemName}\` | ${item.itemType} | ${location} | ${reason} |`);
|
|
419
|
+
}
|
|
420
|
+
console.log('');
|
|
421
|
+
}
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
/**
|
|
425
|
+
* Format output as stats only
|
|
426
|
+
*/
|
|
427
|
+
function formatStats(results) {
|
|
428
|
+
const totalDeprecated = results.reduce((sum, r) => sum + r.deprecated.length, 0);
|
|
429
|
+
const packagesWithDeprecated = results.filter((r) => r.deprecated.length > 0).length;
|
|
430
|
+
|
|
431
|
+
const byType = {};
|
|
432
|
+
const byRepo = {};
|
|
433
|
+
for (const result of results) {
|
|
434
|
+
for (const item of result.deprecated) {
|
|
435
|
+
byType[item.itemType] = (byType[item.itemType] || 0) + 1;
|
|
436
|
+
}
|
|
437
|
+
if (result.deprecated.length > 0) {
|
|
438
|
+
byRepo[result.repo] = (byRepo[result.repo] || 0) + result.deprecated.length;
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
if (options.json) {
|
|
443
|
+
console.log(
|
|
444
|
+
JSON.stringify(
|
|
445
|
+
{
|
|
446
|
+
totalDeprecated,
|
|
447
|
+
packagesWithDeprecated,
|
|
448
|
+
totalPackages: results.length,
|
|
449
|
+
byType,
|
|
450
|
+
byRepo,
|
|
451
|
+
},
|
|
452
|
+
null,
|
|
453
|
+
2
|
|
454
|
+
)
|
|
455
|
+
);
|
|
456
|
+
return;
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
log('\nš Deprecated Code Statistics\n', 'blue');
|
|
460
|
+
log(` Total deprecated items: ${totalDeprecated}`, totalDeprecated > 0 ? 'yellow' : 'green');
|
|
461
|
+
log(` Packages affected: ${packagesWithDeprecated} / ${results.length}`, 'gray');
|
|
462
|
+
|
|
463
|
+
if (totalDeprecated > 0) {
|
|
464
|
+
log('\n By Type:', 'cyan');
|
|
465
|
+
for (const [type, count] of Object.entries(byType).sort((a, b) => b[1] - a[1])) {
|
|
466
|
+
log(` ${type}: ${count}`, 'gray');
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
log('\n By Repository:', 'cyan');
|
|
470
|
+
for (const [repo, count] of Object.entries(byRepo).sort((a, b) => b[1] - a[1])) {
|
|
471
|
+
log(` ${repo}: ${count}`, 'gray');
|
|
472
|
+
}
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
log('', 'reset');
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
/**
|
|
479
|
+
* Main function
|
|
480
|
+
*/
|
|
481
|
+
async function main() {
|
|
482
|
+
try {
|
|
483
|
+
const rootDir = process.cwd();
|
|
484
|
+
|
|
485
|
+
if (!options.json && !options.md && !options.stats) {
|
|
486
|
+
log('š KB Labs Deprecated Code Checker\n', 'blue');
|
|
487
|
+
}
|
|
488
|
+
|
|
489
|
+
const packages = findPackages(rootDir, options.package);
|
|
490
|
+
|
|
491
|
+
if (packages.length === 0) {
|
|
492
|
+
log('ā No packages found. Make sure you run this from kb-labs root directory.', 'red');
|
|
493
|
+
process.exit(2);
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
if (!options.json && !options.md) {
|
|
497
|
+
log(`Scanning ${packages.length} package(s)...`, 'gray');
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
const results = [];
|
|
501
|
+
for (const pkg of packages) {
|
|
502
|
+
const result = analyzePackage(pkg);
|
|
503
|
+
results.push(result);
|
|
504
|
+
}
|
|
505
|
+
|
|
506
|
+
// Sort by deprecated count (most first)
|
|
507
|
+
results.sort((a, b) => b.deprecated.length - a.deprecated.length);
|
|
508
|
+
|
|
509
|
+
// Output based on format
|
|
510
|
+
if (options.stats) {
|
|
511
|
+
formatStats(results);
|
|
512
|
+
} else if (options.json) {
|
|
513
|
+
formatJSON(results, rootDir);
|
|
514
|
+
} else if (options.md) {
|
|
515
|
+
formatMarkdown(results, rootDir);
|
|
516
|
+
} else {
|
|
517
|
+
formatTable(results, rootDir);
|
|
518
|
+
}
|
|
519
|
+
|
|
520
|
+
// Exit with code 1 if deprecated items found (useful for CI awareness, not failure)
|
|
521
|
+
const totalDeprecated = results.reduce((sum, r) => sum + r.deprecated.length, 0);
|
|
522
|
+
process.exit(totalDeprecated > 0 ? 1 : 0);
|
|
523
|
+
} catch (error) {
|
|
524
|
+
console.error(`\nā Error: ${error.message}\n`);
|
|
525
|
+
if (process.env.DEBUG) {
|
|
526
|
+
console.error(error.stack);
|
|
527
|
+
}
|
|
528
|
+
process.exit(2);
|
|
529
|
+
}
|
|
530
|
+
}
|
|
531
|
+
|
|
532
|
+
main();
|