@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,450 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @kb-labs/devkit - TypeScript Types Checker
|
|
5
|
+
*
|
|
6
|
+
* Ensures all packages properly generate TypeScript declaration files (.d.ts).
|
|
7
|
+
* Detects technical debt like `dts: false` in tsup configs.
|
|
8
|
+
*
|
|
9
|
+
* Usage:
|
|
10
|
+
* kb-devkit-check-types # Check all packages
|
|
11
|
+
* kb-devkit-check-types --package=cli # Check specific package
|
|
12
|
+
* kb-devkit-check-types --fix # Auto-fix dts: false
|
|
13
|
+
* kb-devkit-check-types --json # JSON output
|
|
14
|
+
* kb-devkit-check-types --graph # Show types dependency graph
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
import fs from 'node:fs';
|
|
18
|
+
import path from 'node:path';
|
|
19
|
+
import { fileURLToPath } from 'node:url';
|
|
20
|
+
|
|
21
|
+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
22
|
+
|
|
23
|
+
// ANSI colors
|
|
24
|
+
const colors = {
|
|
25
|
+
reset: '\x1b[0m',
|
|
26
|
+
red: '\x1b[31m',
|
|
27
|
+
green: '\x1b[32m',
|
|
28
|
+
yellow: '\x1b[33m',
|
|
29
|
+
blue: '\x1b[34m',
|
|
30
|
+
magenta: '\x1b[35m',
|
|
31
|
+
cyan: '\x1b[36m',
|
|
32
|
+
gray: '\x1b[90m',
|
|
33
|
+
bold: '\x1b[1m',
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
function log(message, color = 'reset') {
|
|
37
|
+
if (!options.json) {
|
|
38
|
+
console.log(`${colors[color]}${message}${colors.reset}`);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// Parse CLI arguments
|
|
43
|
+
const args = process.argv.slice(2);
|
|
44
|
+
const options = {
|
|
45
|
+
fix: args.includes('--fix'),
|
|
46
|
+
json: args.includes('--json'),
|
|
47
|
+
graph: args.includes('--graph'),
|
|
48
|
+
verbose: args.includes('--verbose') || args.includes('-v'),
|
|
49
|
+
package: args.find((arg) => arg.startsWith('--package='))?.split('=')[1],
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Find all packages
|
|
54
|
+
*/
|
|
55
|
+
function findPackages(rootDir, filterPackage) {
|
|
56
|
+
const packages = [];
|
|
57
|
+
const entries = fs.readdirSync(rootDir, { withFileTypes: true });
|
|
58
|
+
|
|
59
|
+
for (const entry of entries) {
|
|
60
|
+
if (!entry.isDirectory() || !entry.name.startsWith('kb-labs-')) {continue;}
|
|
61
|
+
|
|
62
|
+
const repoPath = path.join(rootDir, entry.name);
|
|
63
|
+
const packagesDir = path.join(repoPath, 'packages');
|
|
64
|
+
|
|
65
|
+
if (!fs.existsSync(packagesDir)) {continue;}
|
|
66
|
+
|
|
67
|
+
const packageDirs = fs.readdirSync(packagesDir, { withFileTypes: true });
|
|
68
|
+
|
|
69
|
+
for (const pkgDir of packageDirs) {
|
|
70
|
+
if (!pkgDir.isDirectory()) {continue;}
|
|
71
|
+
|
|
72
|
+
if (filterPackage && pkgDir.name !== filterPackage) {continue;}
|
|
73
|
+
|
|
74
|
+
const packageJsonPath = path.join(packagesDir, pkgDir.name, 'package.json');
|
|
75
|
+
|
|
76
|
+
if (fs.existsSync(packageJsonPath)) {
|
|
77
|
+
packages.push({
|
|
78
|
+
path: packageJsonPath,
|
|
79
|
+
dir: path.join(packagesDir, pkgDir.name),
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
return packages;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Check if package has TypeScript source files
|
|
90
|
+
*/
|
|
91
|
+
function hasTypeScriptSources(packageDir) {
|
|
92
|
+
const srcDir = path.join(packageDir, 'src');
|
|
93
|
+
if (!fs.existsSync(srcDir)) {return false;}
|
|
94
|
+
|
|
95
|
+
function walkDir(dir) {
|
|
96
|
+
const entries = fs.readdirSync(dir, { withFileTypes: true });
|
|
97
|
+
|
|
98
|
+
for (const entry of entries) {
|
|
99
|
+
const fullPath = path.join(dir, entry.name);
|
|
100
|
+
|
|
101
|
+
if (entry.isDirectory()) {
|
|
102
|
+
if (walkDir(fullPath)) {return true;}
|
|
103
|
+
} else if (entry.isFile() && /\.(ts|tsx)$/.test(entry.name)) {
|
|
104
|
+
return true;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
return false;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
return walkDir(srcDir);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Check tsup.config for dts setting
|
|
116
|
+
*/
|
|
117
|
+
function checkTsupConfig(packageDir) {
|
|
118
|
+
const tsupConfigPath = path.join(packageDir, 'tsup.config.ts');
|
|
119
|
+
|
|
120
|
+
if (!fs.existsSync(tsupConfigPath)) {
|
|
121
|
+
return { exists: false };
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
const content = fs.readFileSync(tsupConfigPath, 'utf-8');
|
|
125
|
+
|
|
126
|
+
// Check for dts: false (bad!)
|
|
127
|
+
const hasDtsFalse = /dts\s*:\s*false/.test(content);
|
|
128
|
+
|
|
129
|
+
// Check for dts: true (good!)
|
|
130
|
+
const hasDtsTrue = /dts\s*:\s*true/.test(content);
|
|
131
|
+
|
|
132
|
+
// Check if dts is explicitly set
|
|
133
|
+
const hasDtsConfig = /dts\s*:/.test(content);
|
|
134
|
+
|
|
135
|
+
return {
|
|
136
|
+
exists: true,
|
|
137
|
+
path: tsupConfigPath,
|
|
138
|
+
content,
|
|
139
|
+
hasDtsFalse,
|
|
140
|
+
hasDtsTrue,
|
|
141
|
+
hasDtsConfig,
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* Check if package.json has types field
|
|
147
|
+
*/
|
|
148
|
+
function checkPackageJsonTypes(packagePath) {
|
|
149
|
+
const packageJson = JSON.parse(fs.readFileSync(packagePath, 'utf-8'));
|
|
150
|
+
|
|
151
|
+
return {
|
|
152
|
+
name: packageJson.name,
|
|
153
|
+
hasTypes: !!packageJson.types || !!packageJson.typings,
|
|
154
|
+
typesPath: packageJson.types || packageJson.typings,
|
|
155
|
+
hasExports: !!packageJson.exports,
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* Check if dist folder has .d.ts files
|
|
161
|
+
*/
|
|
162
|
+
function checkDistFolder(packageDir) {
|
|
163
|
+
const distDir = path.join(packageDir, 'dist');
|
|
164
|
+
|
|
165
|
+
if (!fs.existsSync(distDir)) {
|
|
166
|
+
return { exists: false, hasDts: false };
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
function hasDtsFiles(dir) {
|
|
170
|
+
const entries = fs.readdirSync(dir, { withFileTypes: true });
|
|
171
|
+
|
|
172
|
+
for (const entry of entries) {
|
|
173
|
+
const fullPath = path.join(dir, entry.name);
|
|
174
|
+
|
|
175
|
+
if (entry.isDirectory()) {
|
|
176
|
+
if (hasDtsFiles(fullPath)) {return true;}
|
|
177
|
+
} else if (entry.isFile() && entry.name.endsWith('.d.ts')) {
|
|
178
|
+
return true;
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
return false;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
return {
|
|
186
|
+
exists: true,
|
|
187
|
+
hasDts: hasDtsFiles(distDir),
|
|
188
|
+
};
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
/**
|
|
192
|
+
* Fix dts: false in tsup config
|
|
193
|
+
*/
|
|
194
|
+
function fixTsupConfig(tsupConfigPath, dryRun = false) {
|
|
195
|
+
const content = fs.readFileSync(tsupConfigPath, 'utf-8');
|
|
196
|
+
|
|
197
|
+
// Replace dts: false with dts: true
|
|
198
|
+
const fixed = content.replace(/dts\s*:\s*false/g, 'dts: true');
|
|
199
|
+
|
|
200
|
+
if (fixed !== content) {
|
|
201
|
+
if (!dryRun) {
|
|
202
|
+
fs.writeFileSync(tsupConfigPath, fixed);
|
|
203
|
+
}
|
|
204
|
+
return true;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
return false;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
/**
|
|
211
|
+
* Check single package
|
|
212
|
+
*/
|
|
213
|
+
function checkPackage(packageInfo) {
|
|
214
|
+
const { path: packagePath, dir: packageDir } = packageInfo;
|
|
215
|
+
const packageJson = checkPackageJsonTypes(packagePath);
|
|
216
|
+
const packageName = packageJson.name;
|
|
217
|
+
|
|
218
|
+
if (!packageName || !packageName.startsWith('@kb-labs/')) {
|
|
219
|
+
return null;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
const hasTS = hasTypeScriptSources(packageDir);
|
|
223
|
+
const tsupConfig = checkTsupConfig(packageDir);
|
|
224
|
+
const dist = checkDistFolder(packageDir);
|
|
225
|
+
|
|
226
|
+
const issues = [];
|
|
227
|
+
|
|
228
|
+
// TypeScript sources but no tsup config
|
|
229
|
+
if (hasTS && !tsupConfig.exists) {
|
|
230
|
+
issues.push({
|
|
231
|
+
type: 'no_tsup_config',
|
|
232
|
+
severity: 'warning',
|
|
233
|
+
message: 'Has TypeScript sources but no tsup.config.ts',
|
|
234
|
+
});
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
// tsup config with dts: false (technical debt!)
|
|
238
|
+
if (tsupConfig.hasDtsFalse) {
|
|
239
|
+
issues.push({
|
|
240
|
+
type: 'dts_false',
|
|
241
|
+
severity: 'error',
|
|
242
|
+
message: 'tsup.config.ts has dts: false (bad practice!)',
|
|
243
|
+
fixable: true,
|
|
244
|
+
});
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
// Has TypeScript but no dts config at all
|
|
248
|
+
if (hasTS && tsupConfig.exists && !tsupConfig.hasDtsConfig) {
|
|
249
|
+
issues.push({
|
|
250
|
+
type: 'no_dts_config',
|
|
251
|
+
severity: 'warning',
|
|
252
|
+
message: 'tsup.config.ts missing dts configuration',
|
|
253
|
+
});
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
// Has TypeScript but package.json has no types field
|
|
257
|
+
if (hasTS && !packageJson.hasTypes) {
|
|
258
|
+
issues.push({
|
|
259
|
+
type: 'no_types_field',
|
|
260
|
+
severity: 'error',
|
|
261
|
+
message: 'package.json missing "types" field',
|
|
262
|
+
});
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
// Has tsup with dts: true but no .d.ts files in dist
|
|
266
|
+
if (tsupConfig.hasDtsTrue && dist.exists && !dist.hasDts) {
|
|
267
|
+
issues.push({
|
|
268
|
+
type: 'no_dist_types',
|
|
269
|
+
severity: 'warning',
|
|
270
|
+
message: 'No .d.ts files found in dist/ (need to build?)',
|
|
271
|
+
});
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
return {
|
|
275
|
+
name: packageName,
|
|
276
|
+
dir: packageDir,
|
|
277
|
+
hasTypeScript: hasTS,
|
|
278
|
+
tsupConfig,
|
|
279
|
+
dist,
|
|
280
|
+
packageJson,
|
|
281
|
+
issues,
|
|
282
|
+
isClean: issues.length === 0,
|
|
283
|
+
};
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
/**
|
|
287
|
+
* Print results
|
|
288
|
+
*/
|
|
289
|
+
function printResults(results) {
|
|
290
|
+
log('\nš KB Labs TypeScript Types Checker\n', 'bold');
|
|
291
|
+
|
|
292
|
+
const allPackages = results.filter(r => r !== null);
|
|
293
|
+
const withIssues = allPackages.filter(r => !r.isClean);
|
|
294
|
+
const dtsFalse = allPackages.filter(r => r.issues.some(i => i.type === 'dts_false'));
|
|
295
|
+
const clean = allPackages.filter(r => r.isClean && r.hasTypeScript);
|
|
296
|
+
|
|
297
|
+
log(`Found ${allPackages.length} package(s) to check\n`, 'gray');
|
|
298
|
+
|
|
299
|
+
// Show packages with dts: false (technical debt!)
|
|
300
|
+
if (dtsFalse.length > 0) {
|
|
301
|
+
log(`š“ Technical Debt: ${dtsFalse.length} package(s) with dts: false\n`, 'red');
|
|
302
|
+
|
|
303
|
+
for (const result of dtsFalse) {
|
|
304
|
+
log(` ${result.name}`, 'yellow');
|
|
305
|
+
log(` ${result.tsupConfig.path}`, 'gray');
|
|
306
|
+
log(` āā Has "dts: false" - types not being generated!`, 'red');
|
|
307
|
+
|
|
308
|
+
if (options.fix) {
|
|
309
|
+
const fixed = fixTsupConfig(result.tsupConfig.path, false);
|
|
310
|
+
if (fixed) {
|
|
311
|
+
log(` ā
Fixed: Changed to "dts: true"`, 'green');
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
log('', 'reset');
|
|
316
|
+
|
|
317
|
+
if (!options.fix) {
|
|
318
|
+
log('š” Run with --fix to automatically change dts: false ā dts: true\n', 'cyan');
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
// Show other issues
|
|
323
|
+
const otherIssues = withIssues.filter(r => !r.issues.some(i => i.type === 'dts_false'));
|
|
324
|
+
|
|
325
|
+
if (otherIssues.length > 0) {
|
|
326
|
+
log(`ā ļø Other Issues: ${otherIssues.length} package(s)\n`, 'yellow');
|
|
327
|
+
|
|
328
|
+
for (const result of otherIssues) {
|
|
329
|
+
log(` ${result.name}`, 'yellow');
|
|
330
|
+
|
|
331
|
+
for (const issue of result.issues) {
|
|
332
|
+
const icon = issue.severity === 'error' ? 'ā' : 'ā ļø';
|
|
333
|
+
log(` ${icon} ${issue.message}`, 'gray');
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
log('', 'reset');
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
// Show clean packages (only in verbose mode)
|
|
340
|
+
if (options.verbose && clean.length > 0) {
|
|
341
|
+
log(`ā
Clean packages with types: ${clean.length}\n`, 'green');
|
|
342
|
+
|
|
343
|
+
for (const result of clean.slice(0, 10)) {
|
|
344
|
+
log(` ${result.name}`, 'gray');
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
if (clean.length > 10) {
|
|
348
|
+
log(` ... and ${clean.length - 10} more`, 'gray');
|
|
349
|
+
}
|
|
350
|
+
log('', 'reset');
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
// Summary
|
|
354
|
+
log('ā'.repeat(60) + '\n', 'gray');
|
|
355
|
+
log('š Summary:\n', 'blue');
|
|
356
|
+
|
|
357
|
+
log(` Total packages: ${allPackages.length}`, 'cyan');
|
|
358
|
+
log(` With TypeScript: ${allPackages.filter(r => r.hasTypeScript).length}`, 'cyan');
|
|
359
|
+
log(` ā
Clean: ${clean.length}`, 'green');
|
|
360
|
+
|
|
361
|
+
if (dtsFalse.length > 0) {
|
|
362
|
+
log(` š“ dts: false: ${dtsFalse.length} (technical debt!)`, 'red');
|
|
363
|
+
}
|
|
364
|
+
if (otherIssues.length > 0) {
|
|
365
|
+
log(` ā ļø Other issues: ${otherIssues.length}`, 'yellow');
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
log('', 'reset');
|
|
369
|
+
|
|
370
|
+
// Tips
|
|
371
|
+
log('š” Tips:', 'blue');
|
|
372
|
+
log(' ⢠Use --fix to automatically fix dts: false', 'gray');
|
|
373
|
+
log(' ⢠Use --verbose to see all packages', 'gray');
|
|
374
|
+
log(' ⢠Run pnpm run build after fixing configs', 'gray');
|
|
375
|
+
log('', 'reset');
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
/**
|
|
379
|
+
* Build types dependency graph
|
|
380
|
+
*/
|
|
381
|
+
function buildTypesDependencyGraph(results) {
|
|
382
|
+
const graph = new Map();
|
|
383
|
+
|
|
384
|
+
// Build graph of packages that provide types
|
|
385
|
+
for (const result of results) {
|
|
386
|
+
if (!result || !result.hasTypeScript) {continue;}
|
|
387
|
+
|
|
388
|
+
const hasTypes = result.tsupConfig.hasDtsTrue && !result.issues.some(i => i.type === 'dts_false');
|
|
389
|
+
|
|
390
|
+
graph.set(result.name, {
|
|
391
|
+
hasTypes,
|
|
392
|
+
issues: result.issues.length,
|
|
393
|
+
});
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
return graph;
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
/**
|
|
400
|
+
* Main function
|
|
401
|
+
*/
|
|
402
|
+
function main() {
|
|
403
|
+
const rootDir = process.cwd();
|
|
404
|
+
|
|
405
|
+
if (!options.json) {
|
|
406
|
+
log('\nš KB Labs TypeScript Types Checker\n', 'bold');
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
const packages = findPackages(rootDir, options.package);
|
|
410
|
+
|
|
411
|
+
if (packages.length === 0) {
|
|
412
|
+
log('ā ļø No KB Labs packages found', 'yellow');
|
|
413
|
+
process.exit(0);
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
// Check all packages
|
|
417
|
+
const results = packages.map(checkPackage);
|
|
418
|
+
|
|
419
|
+
if (options.json) {
|
|
420
|
+
const output = {
|
|
421
|
+
total: results.filter(r => r !== null).length,
|
|
422
|
+
withTypeScript: results.filter(r => r && r.hasTypeScript).length,
|
|
423
|
+
clean: results.filter(r => r && r.isClean && r.hasTypeScript).length,
|
|
424
|
+
dtsFalse: results.filter(r => r && r.issues.some(i => i.type === 'dts_false')).length,
|
|
425
|
+
issues: results.filter(r => r && !r.isClean).map(r => ({
|
|
426
|
+
name: r.name,
|
|
427
|
+
issues: r.issues,
|
|
428
|
+
})),
|
|
429
|
+
};
|
|
430
|
+
|
|
431
|
+
console.log(JSON.stringify(output, null, 2));
|
|
432
|
+
} else if (options.graph) {
|
|
433
|
+
const graph = buildTypesDependencyGraph(results);
|
|
434
|
+
log('\nš Types Dependency Graph\n', 'blue');
|
|
435
|
+
|
|
436
|
+
for (const [pkg, info] of graph.entries()) {
|
|
437
|
+
const status = info.hasTypes ? 'ā
' : 'ā';
|
|
438
|
+
log(`${status} ${pkg}${info.issues > 0 ? ` (${info.issues} issues)` : ''}`, info.hasTypes ? 'green' : 'red');
|
|
439
|
+
}
|
|
440
|
+
log('', 'reset');
|
|
441
|
+
} else {
|
|
442
|
+
printResults(results);
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
// Exit with error if issues found
|
|
446
|
+
const hasIssues = results.some(r => r && !r.isClean);
|
|
447
|
+
process.exit(hasIssues ? 1 : 0);
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
main();
|
|
@@ -0,0 +1,261 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @kb-labs/devkit - CI Combo Tool
|
|
5
|
+
*
|
|
6
|
+
* Runs all devkit checks in one command for CI/CD pipelines.
|
|
7
|
+
* Perfect for GitHub Actions, GitLab CI, or any CI/CD system.
|
|
8
|
+
*
|
|
9
|
+
* Checks performed:
|
|
10
|
+
* 1. Naming convention validation
|
|
11
|
+
* 2. Import issues (broken imports, unused deps, circular deps)
|
|
12
|
+
* 3. Export issues (unused exports, dead code)
|
|
13
|
+
* 4. Duplicate dependencies
|
|
14
|
+
* 5. Package structure validation
|
|
15
|
+
* 6. Path validation (workspace deps, exports, bin)
|
|
16
|
+
* 7. TypeScript types (dts generation, types field)
|
|
17
|
+
*
|
|
18
|
+
* Usage:
|
|
19
|
+
* kb-devkit-ci # Run all checks
|
|
20
|
+
* kb-devkit-ci --skip naming # Skip naming check
|
|
21
|
+
* kb-devkit-ci --only imports # Run only imports check
|
|
22
|
+
* kb-devkit-ci --json # Output JSON for parsing
|
|
23
|
+
*/
|
|
24
|
+
|
|
25
|
+
import { spawn } from 'node:child_process';
|
|
26
|
+
import path from 'node:path';
|
|
27
|
+
import { fileURLToPath } from 'node:url';
|
|
28
|
+
|
|
29
|
+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
30
|
+
|
|
31
|
+
// ANSI colors
|
|
32
|
+
const colors = {
|
|
33
|
+
reset: '\x1b[0m',
|
|
34
|
+
red: '\x1b[31m',
|
|
35
|
+
green: '\x1b[32m',
|
|
36
|
+
yellow: '\x1b[33m',
|
|
37
|
+
blue: '\x1b[34m',
|
|
38
|
+
magenta: '\x1b[35m',
|
|
39
|
+
cyan: '\x1b[36m',
|
|
40
|
+
gray: '\x1b[90m',
|
|
41
|
+
bold: '\x1b[1m',
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
function log(message, color = 'reset') {
|
|
45
|
+
console.log(`${colors[color]}${message}${colors.reset}`);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// Parse CLI arguments
|
|
49
|
+
const args = process.argv.slice(2);
|
|
50
|
+
const options = {
|
|
51
|
+
skip: args.find((arg) => arg.startsWith('--skip='))?.split('=')[1]?.split(',') || [],
|
|
52
|
+
only: args.find((arg) => arg.startsWith('--only='))?.split('=')[1]?.split(',') || [],
|
|
53
|
+
json: args.includes('--json'),
|
|
54
|
+
verbose: args.includes('--verbose') || args.includes('-v'),
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Available checks
|
|
59
|
+
*/
|
|
60
|
+
const CHECKS = {
|
|
61
|
+
naming: {
|
|
62
|
+
name: 'Naming Convention',
|
|
63
|
+
command: 'devkit-validate-naming.mjs',
|
|
64
|
+
emoji: 'š¦',
|
|
65
|
+
},
|
|
66
|
+
imports: {
|
|
67
|
+
name: 'Import Analysis',
|
|
68
|
+
command: 'devkit-check-imports.mjs',
|
|
69
|
+
emoji: 'š',
|
|
70
|
+
},
|
|
71
|
+
exports: {
|
|
72
|
+
name: 'Export Analysis',
|
|
73
|
+
command: 'devkit-check-exports.mjs',
|
|
74
|
+
emoji: 'š¤',
|
|
75
|
+
},
|
|
76
|
+
duplicates: {
|
|
77
|
+
name: 'Duplicate Dependencies',
|
|
78
|
+
command: 'devkit-check-duplicates.mjs',
|
|
79
|
+
emoji: 'š',
|
|
80
|
+
},
|
|
81
|
+
structure: {
|
|
82
|
+
name: 'Package Structure',
|
|
83
|
+
command: 'devkit-check-structure.mjs',
|
|
84
|
+
emoji: 'š',
|
|
85
|
+
},
|
|
86
|
+
paths: {
|
|
87
|
+
name: 'Path Validation',
|
|
88
|
+
command: 'devkit-check-paths.mjs',
|
|
89
|
+
emoji: 'š',
|
|
90
|
+
},
|
|
91
|
+
types: {
|
|
92
|
+
name: 'TypeScript Types',
|
|
93
|
+
command: 'devkit-check-types.mjs',
|
|
94
|
+
emoji: 'š',
|
|
95
|
+
},
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Run a single check
|
|
100
|
+
*/
|
|
101
|
+
function runCheck(checkId, check) {
|
|
102
|
+
return new Promise((resolve) => {
|
|
103
|
+
const startTime = Date.now();
|
|
104
|
+
const scriptPath = path.join(__dirname, check.command);
|
|
105
|
+
|
|
106
|
+
if (!options.json) {
|
|
107
|
+
log(`\n${check.emoji} Running ${check.name}...`, 'blue');
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
const child = spawn('node', [scriptPath], {
|
|
111
|
+
stdio: options.json ? 'pipe' : 'inherit',
|
|
112
|
+
cwd: process.cwd(),
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
let stdout = '';
|
|
116
|
+
let stderr = '';
|
|
117
|
+
|
|
118
|
+
if (options.json) {
|
|
119
|
+
child.stdout.on('data', (data) => {
|
|
120
|
+
stdout += data.toString();
|
|
121
|
+
});
|
|
122
|
+
child.stderr.on('data', (data) => {
|
|
123
|
+
stderr += data.toString();
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
child.on('close', (code) => {
|
|
128
|
+
const duration = ((Date.now() - startTime) / 1000).toFixed(2);
|
|
129
|
+
|
|
130
|
+
resolve({
|
|
131
|
+
checkId,
|
|
132
|
+
name: check.name,
|
|
133
|
+
emoji: check.emoji,
|
|
134
|
+
passed: code === 0,
|
|
135
|
+
exitCode: code,
|
|
136
|
+
duration: parseFloat(duration),
|
|
137
|
+
stdout,
|
|
138
|
+
stderr,
|
|
139
|
+
});
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
child.on('error', (err) => {
|
|
143
|
+
resolve({
|
|
144
|
+
checkId,
|
|
145
|
+
name: check.name,
|
|
146
|
+
emoji: check.emoji,
|
|
147
|
+
passed: false,
|
|
148
|
+
exitCode: 1,
|
|
149
|
+
duration: 0,
|
|
150
|
+
error: err.message,
|
|
151
|
+
});
|
|
152
|
+
});
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* Main function
|
|
158
|
+
*/
|
|
159
|
+
async function main() {
|
|
160
|
+
const startTime = Date.now();
|
|
161
|
+
|
|
162
|
+
if (!options.json) {
|
|
163
|
+
log('\nš KB Labs CI Checker\n', 'bold');
|
|
164
|
+
log('Running all devkit checks...\n', 'gray');
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
// Determine which checks to run
|
|
168
|
+
let checksToRun = Object.keys(CHECKS);
|
|
169
|
+
|
|
170
|
+
if (options.only.length > 0) {
|
|
171
|
+
checksToRun = checksToRun.filter((id) => options.only.includes(id));
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
if (options.skip.length > 0) {
|
|
175
|
+
checksToRun = checksToRun.filter((id) => !options.skip.includes(id));
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
if (checksToRun.length === 0) {
|
|
179
|
+
log('ā ļø No checks to run', 'yellow');
|
|
180
|
+
process.exit(0);
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
// Run all checks
|
|
184
|
+
const results = [];
|
|
185
|
+
|
|
186
|
+
for (const checkId of checksToRun) {
|
|
187
|
+
const check = CHECKS[checkId];
|
|
188
|
+
const result = await runCheck(checkId, check);
|
|
189
|
+
results.push(result);
|
|
190
|
+
|
|
191
|
+
if (!options.json) {
|
|
192
|
+
if (result.passed) {
|
|
193
|
+
log(` ā
${result.name} passed (${result.duration}s)`, 'green');
|
|
194
|
+
} else {
|
|
195
|
+
log(` ā ${result.name} failed (${result.duration}s)`, 'red');
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
const totalDuration = ((Date.now() - startTime) / 1000).toFixed(2);
|
|
201
|
+
|
|
202
|
+
// Print summary
|
|
203
|
+
const passed = results.filter((r) => r.passed).length;
|
|
204
|
+
const failed = results.filter((r) => !r.passed).length;
|
|
205
|
+
const total = results.length;
|
|
206
|
+
|
|
207
|
+
if (options.json) {
|
|
208
|
+
// JSON output for CI parsing
|
|
209
|
+
const output = {
|
|
210
|
+
summary: {
|
|
211
|
+
total,
|
|
212
|
+
passed,
|
|
213
|
+
failed,
|
|
214
|
+
duration: parseFloat(totalDuration),
|
|
215
|
+
success: failed === 0,
|
|
216
|
+
},
|
|
217
|
+
checks: results.map((r) => ({
|
|
218
|
+
id: r.checkId,
|
|
219
|
+
name: r.name,
|
|
220
|
+
passed: r.passed,
|
|
221
|
+
exitCode: r.exitCode,
|
|
222
|
+
duration: r.duration,
|
|
223
|
+
error: r.error,
|
|
224
|
+
})),
|
|
225
|
+
};
|
|
226
|
+
|
|
227
|
+
console.log(JSON.stringify(output, null, 2));
|
|
228
|
+
} else {
|
|
229
|
+
log('\n' + 'ā'.repeat(60) + '\n', 'gray');
|
|
230
|
+
log('š Summary:\n', 'blue');
|
|
231
|
+
|
|
232
|
+
log(` Total checks: ${total}`, 'cyan');
|
|
233
|
+
log(` ā
Passed: ${passed}`, 'green');
|
|
234
|
+
if (failed > 0) {
|
|
235
|
+
log(` ā Failed: ${failed}`, 'red');
|
|
236
|
+
}
|
|
237
|
+
log(` ā±ļø Duration: ${totalDuration}s`, 'gray');
|
|
238
|
+
|
|
239
|
+
log('', 'reset');
|
|
240
|
+
|
|
241
|
+
if (failed > 0) {
|
|
242
|
+
log('š” Failed checks:', 'yellow');
|
|
243
|
+
for (const result of results.filter((r) => !r.passed)) {
|
|
244
|
+
log(` ⢠${result.name}`, 'red');
|
|
245
|
+
}
|
|
246
|
+
log('', 'reset');
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
log('š” Tips:', 'blue');
|
|
250
|
+
log(' ⢠Run individual checks to see detailed output', 'gray');
|
|
251
|
+
log(' ⢠Use --skip=<check> to skip specific checks', 'gray');
|
|
252
|
+
log(' ⢠Use --only=<check> to run only specific checks', 'gray');
|
|
253
|
+
log(' ⢠Use --json for machine-readable output', 'gray');
|
|
254
|
+
log('', 'reset');
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
// Exit with appropriate code
|
|
258
|
+
process.exit(failed > 0 ? 1 : 0);
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
main();
|