@rudderjs/cli 4.4.0 → 4.5.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.
Files changed (59) hide show
  1. package/dist/commands/doctor.d.ts +12 -0
  2. package/dist/commands/doctor.d.ts.map +1 -0
  3. package/dist/commands/doctor.js +83 -0
  4. package/dist/commands/doctor.js.map +1 -0
  5. package/dist/doctor/boot-status.d.ts +10 -0
  6. package/dist/doctor/boot-status.d.ts.map +1 -0
  7. package/dist/doctor/boot-status.js +15 -0
  8. package/dist/doctor/boot-status.js.map +1 -0
  9. package/dist/doctor/built-in/_fs.d.ts +11 -0
  10. package/dist/doctor/built-in/_fs.d.ts.map +1 -0
  11. package/dist/doctor/built-in/_fs.js +53 -0
  12. package/dist/doctor/built-in/_fs.js.map +1 -0
  13. package/dist/doctor/built-in/deps.d.ts +2 -0
  14. package/dist/doctor/built-in/deps.d.ts.map +1 -0
  15. package/dist/doctor/built-in/deps.js +81 -0
  16. package/dist/doctor/built-in/deps.js.map +1 -0
  17. package/dist/doctor/built-in/env-vars.d.ts +2 -0
  18. package/dist/doctor/built-in/env-vars.d.ts.map +1 -0
  19. package/dist/doctor/built-in/env-vars.js +99 -0
  20. package/dist/doctor/built-in/env-vars.js.map +1 -0
  21. package/dist/doctor/built-in/index.d.ts +13 -0
  22. package/dist/doctor/built-in/index.d.ts.map +1 -0
  23. package/dist/doctor/built-in/index.js +18 -0
  24. package/dist/doctor/built-in/index.js.map +1 -0
  25. package/dist/doctor/built-in/node-version.d.ts +2 -0
  26. package/dist/doctor/built-in/node-version.d.ts.map +1 -0
  27. package/dist/doctor/built-in/node-version.js +72 -0
  28. package/dist/doctor/built-in/node-version.js.map +1 -0
  29. package/dist/doctor/built-in/package-manager.d.ts +2 -0
  30. package/dist/doctor/built-in/package-manager.d.ts.map +1 -0
  31. package/dist/doctor/built-in/package-manager.js +55 -0
  32. package/dist/doctor/built-in/package-manager.js.map +1 -0
  33. package/dist/doctor/built-in/runtime.d.ts +2 -0
  34. package/dist/doctor/built-in/runtime.d.ts.map +1 -0
  35. package/dist/doctor/built-in/runtime.js +82 -0
  36. package/dist/doctor/built-in/runtime.js.map +1 -0
  37. package/dist/doctor/built-in/structure.d.ts +2 -0
  38. package/dist/doctor/built-in/structure.d.ts.map +1 -0
  39. package/dist/doctor/built-in/structure.js +93 -0
  40. package/dist/doctor/built-in/structure.js.map +1 -0
  41. package/dist/doctor/fixer.d.ts +39 -0
  42. package/dist/doctor/fixer.d.ts.map +1 -0
  43. package/dist/doctor/fixer.js +80 -0
  44. package/dist/doctor/fixer.js.map +1 -0
  45. package/dist/doctor/load-package-checks.d.ts +2 -0
  46. package/dist/doctor/load-package-checks.d.ts.map +1 -0
  47. package/dist/doctor/load-package-checks.js +53 -0
  48. package/dist/doctor/load-package-checks.js.map +1 -0
  49. package/dist/doctor/orchestrator.d.ts +34 -0
  50. package/dist/doctor/orchestrator.d.ts.map +1 -0
  51. package/dist/doctor/orchestrator.js +65 -0
  52. package/dist/doctor/orchestrator.js.map +1 -0
  53. package/dist/doctor/reporter.d.ts +21 -0
  54. package/dist/doctor/reporter.d.ts.map +1 -0
  55. package/dist/doctor/reporter.js +151 -0
  56. package/dist/doctor/reporter.js.map +1 -0
  57. package/dist/index.js +5 -0
  58. package/dist/index.js.map +1 -1
  59. package/package.json +5 -5
@@ -0,0 +1,12 @@
1
+ import type { Command as CommanderCommand } from 'commander';
2
+ export interface DoctorCommandDeps {
3
+ /**
4
+ * Inject the CLI's bootApp so the doctor command can boot the app under
5
+ * `--deep`. Passed by reference rather than imported because the CLI's
6
+ * bootApp suppresses console output (provider chatter is noise here too)
7
+ * and the doctor command shouldn't reimplement that.
8
+ */
9
+ bootApp: () => Promise<void>;
10
+ }
11
+ export declare function doctorCommand(program: CommanderCommand, deps: DoctorCommandDeps): void;
12
+ //# sourceMappingURL=doctor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"doctor.d.ts","sourceRoot":"","sources":["../../src/commands/doctor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,IAAI,gBAAgB,EAAE,MAAM,WAAW,CAAA;AAQ5D,MAAM,WAAW,iBAAiB;IAChC;;;;;OAKG;IACH,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;CAC7B;AAED,wBAAgB,aAAa,CAAC,OAAO,EAAE,gBAAgB,EAAE,IAAI,EAAE,iBAAiB,GAAG,IAAI,CAmFtF"}
@@ -0,0 +1,83 @@
1
+ import { runChecks } from '../doctor/orchestrator.js';
2
+ import { renderReport, renderFixReport, exitCodeFor } from '../doctor/reporter.js';
3
+ import { loadPackageChecks } from '../doctor/load-package-checks.js';
4
+ import { loadBuiltInChecks } from '../doctor/built-in/index.js';
5
+ import { setBootStatus } from '../doctor/boot-status.js';
6
+ import { applyFixes } from '../doctor/fixer.js';
7
+ export function doctorCommand(program, deps) {
8
+ program
9
+ .command('doctor')
10
+ .description('Diagnose common setup issues in a RudderJS app')
11
+ .option('--deep', 'Also run checks that require booting the app (DB connect, port, …)')
12
+ .option('--fix', 'Auto-apply safe fixes for any failures that declare a fixer')
13
+ .option('--yes', 'Skip fix-mode prompts and apply every fixable failure')
14
+ .option('--verbose', 'Show detail block under each check (not just failures)')
15
+ .option('--json', 'Reserved for a future machine-readable output mode')
16
+ .option('--only <substring>', 'Only run checks whose id contains <substring>')
17
+ .action(async (opts) => {
18
+ if (opts.json) {
19
+ console.error('rudder doctor: --json is reserved for a future release (v1 has no JSON output).');
20
+ process.exit(2);
21
+ }
22
+ // Built-in CLI-owned checks (env, structure, deps, runtime) — registered
23
+ // eagerly via side-effect imports so they're present even if no framework
24
+ // package contributed any.
25
+ loadBuiltInChecks();
26
+ // Lazy-load package-contributed checks.
27
+ await loadPackageChecks();
28
+ // --deep boots the app once so runtime checks can interrogate the live
29
+ // DI container (DB client, queue connection, mail transport, etc.).
30
+ // Boot failure is captured as a check result, not a crash — the rest
31
+ // of the runtime suite then short-circuits to skipped, but the user
32
+ // still sees the boot error verbatim with the failing provider.
33
+ if (opts.deep) {
34
+ const t0 = performance.now();
35
+ try {
36
+ await deps.bootApp();
37
+ setBootStatus({ ok: true, durationMs: performance.now() - t0 });
38
+ }
39
+ catch (e) {
40
+ setBootStatus({
41
+ ok: false,
42
+ error: e instanceof Error ? `${e.message}\n${e.stack ?? ''}` : String(e),
43
+ durationMs: performance.now() - t0,
44
+ });
45
+ }
46
+ }
47
+ const runOpts = {};
48
+ if (opts.deep)
49
+ runOpts.deep = true;
50
+ if (opts.only !== undefined)
51
+ runOpts.filter = opts.only;
52
+ const reportOpts = {};
53
+ if (opts.verbose)
54
+ reportOpts.verbose = true;
55
+ // First pass — surface every failure to the user before touching anything.
56
+ const result = await runChecks(runOpts);
57
+ console.log(renderReport(result, reportOpts));
58
+ if (!opts.fix) {
59
+ process.exit(exitCodeFor(result));
60
+ }
61
+ // ── --fix path ──────────────────────────────────────
62
+ // Only fixable checks (warn/error with a fixer) are eligible. Prompt
63
+ // each unless --yes; never modify .env or package.json — fixers are
64
+ // idempotent regenerate-style operations only.
65
+ const fixOpts = {};
66
+ if (opts.yes)
67
+ fixOpts.yes = true;
68
+ const fixResult = await applyFixes(result.outcomes, fixOpts);
69
+ console.log('');
70
+ console.log(renderFixReport(fixResult, reportOpts));
71
+ // Second pass — confirm the fixers actually resolved the issues so
72
+ // the user doesn't have to eyeball it. Same runOpts so deep/only flags
73
+ // carry through.
74
+ if (fixResult.applied > 0) {
75
+ console.log('');
76
+ const second = await runChecks(runOpts);
77
+ console.log(renderReport(second, reportOpts));
78
+ process.exit(exitCodeFor(second));
79
+ }
80
+ process.exit(exitCodeFor(result));
81
+ });
82
+ }
83
+ //# sourceMappingURL=doctor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"doctor.js","sourceRoot":"","sources":["../../src/commands/doctor.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ export interface BootStatus {
2
+ ok: boolean;
3
+ error?: string;
4
+ /** Wall-clock ms the bootApp() call took (success or failure). */
5
+ durationMs: number;
6
+ }
7
+ export declare function setBootStatus(status: BootStatus): void;
8
+ export declare function getBootStatus(): BootStatus | null;
9
+ export declare function clearBootStatus(): void;
10
+ //# sourceMappingURL=boot-status.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"boot-status.d.ts","sourceRoot":"","sources":["../../src/doctor/boot-status.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,UAAU;IACzB,EAAE,EAAK,OAAO,CAAA;IACd,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,kEAAkE;IAClE,UAAU,EAAE,MAAM,CAAA;CACnB;AAID,wBAAgB,aAAa,CAAC,MAAM,EAAE,UAAU,GAAG,IAAI,CAEtD;AAED,wBAAgB,aAAa,IAAI,UAAU,GAAG,IAAI,CAEjD;AAED,wBAAgB,eAAe,IAAI,IAAI,CAEtC"}
@@ -0,0 +1,15 @@
1
+ // Boot status singleton — set by the doctor command's --deep path, read by
2
+ // runtime checks. Lives on globalThis so per-package checks (which import
3
+ // from @rudderjs/cli's dist subpath) see the same value.
4
+ const KEY = '__rudderjs_doctor_boot_status__';
5
+ export function setBootStatus(status) {
6
+ ;
7
+ globalThis[KEY] = status;
8
+ }
9
+ export function getBootStatus() {
10
+ return globalThis[KEY];
11
+ }
12
+ export function clearBootStatus() {
13
+ delete globalThis[KEY];
14
+ }
15
+ //# sourceMappingURL=boot-status.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"boot-status.js","sourceRoot":"","sources":["../../src/doctor/boot-status.ts"],"names":[],"mappings":"AAAA,2EAA2E;AAC3E,0EAA0E;AAC1E,yDAAyD;AASzD,MAAM,GAAG,GAAG,iCAAiC,CAAA;AAE7C,MAAM,UAAU,aAAa,CAAC,MAAkB;IAC9C,CAAC;IAAC,UAAsC,CAAC,GAAG,CAAC,GAAG,MAAM,CAAA;AACxD,CAAC;AAED,MAAM,UAAU,aAAa;IAC3B,OAAQ,UAAsC,CAAC,GAAG,CAAsB,CAAA;AAC1E,CAAC;AAED,MAAM,UAAU,eAAe;IAC7B,OAAQ,UAAsC,CAAC,GAAG,CAAC,CAAA;AACrD,CAAC"}
@@ -0,0 +1,11 @@
1
+ /** True if `<cwd>/<rel>` exists and is a file. */
2
+ export declare function fileExists(rel: string): boolean;
3
+ /** Read `<cwd>/<rel>` as a UTF-8 string. Returns null on any error. */
4
+ export declare function readFileSafe(rel: string): string | null;
5
+ /** `fs.stat(<cwd>/<rel>).mtimeMs` or null on error. */
6
+ export declare function mtimeMs(rel: string): number | null;
7
+ /** True if any of the given relative paths exists (file or dir). */
8
+ export declare function anyExists(rels: string[]): boolean;
9
+ /** Read JSON file at `<cwd>/<rel>` or null on error. */
10
+ export declare function readJsonSafe<T = unknown>(rel: string): T | null;
11
+ //# sourceMappingURL=_fs.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"_fs.d.ts","sourceRoot":"","sources":["../../../src/doctor/built-in/_fs.ts"],"names":[],"mappings":"AAGA,kDAAkD;AAClD,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAM/C;AAED,uEAAuE;AACvE,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAMvD;AAED,uDAAuD;AACvD,wBAAgB,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAMlD;AAED,oEAAoE;AACpE,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAQjD;AAED,wDAAwD;AACxD,wBAAgB,YAAY,CAAC,CAAC,GAAG,OAAO,EAAE,GAAG,EAAE,MAAM,GAAG,CAAC,GAAG,IAAI,CAQ/D"}
@@ -0,0 +1,53 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+ /** True if `<cwd>/<rel>` exists and is a file. */
4
+ export function fileExists(rel) {
5
+ try {
6
+ return fs.statSync(path.join(process.cwd(), rel)).isFile();
7
+ }
8
+ catch {
9
+ return false;
10
+ }
11
+ }
12
+ /** Read `<cwd>/<rel>` as a UTF-8 string. Returns null on any error. */
13
+ export function readFileSafe(rel) {
14
+ try {
15
+ return fs.readFileSync(path.join(process.cwd(), rel), 'utf-8');
16
+ }
17
+ catch {
18
+ return null;
19
+ }
20
+ }
21
+ /** `fs.stat(<cwd>/<rel>).mtimeMs` or null on error. */
22
+ export function mtimeMs(rel) {
23
+ try {
24
+ return fs.statSync(path.join(process.cwd(), rel)).mtimeMs;
25
+ }
26
+ catch {
27
+ return null;
28
+ }
29
+ }
30
+ /** True if any of the given relative paths exists (file or dir). */
31
+ export function anyExists(rels) {
32
+ for (const rel of rels) {
33
+ try {
34
+ fs.statSync(path.join(process.cwd(), rel));
35
+ return true;
36
+ }
37
+ catch { /* keep looking */ }
38
+ }
39
+ return false;
40
+ }
41
+ /** Read JSON file at `<cwd>/<rel>` or null on error. */
42
+ export function readJsonSafe(rel) {
43
+ const text = readFileSafe(rel);
44
+ if (text === null)
45
+ return null;
46
+ try {
47
+ return JSON.parse(text);
48
+ }
49
+ catch {
50
+ return null;
51
+ }
52
+ }
53
+ //# sourceMappingURL=_fs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"_fs.js","sourceRoot":"","sources":["../../../src/doctor/built-in/_fs.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAA;AACxB,OAAO,IAAI,MAAM,WAAW,CAAA;AAE5B,kDAAkD;AAClD,MAAM,UAAU,UAAU,CAAC,GAAW;IACpC,IAAI,CAAC;QACH,OAAO,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,GAAG,CAAC,CAAC,CAAC,MAAM,EAAE,CAAA;IAC5D,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAA;IACd,CAAC;AACH,CAAC;AAED,uEAAuE;AACvE,MAAM,UAAU,YAAY,CAAC,GAAW;IACtC,IAAI,CAAC;QACH,OAAO,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,GAAG,CAAC,EAAE,OAAO,CAAC,CAAA;IAChE,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAA;IACb,CAAC;AACH,CAAC;AAED,uDAAuD;AACvD,MAAM,UAAU,OAAO,CAAC,GAAW;IACjC,IAAI,CAAC;QACH,OAAO,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,GAAG,CAAC,CAAC,CAAC,OAAO,CAAA;IAC3D,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAA;IACb,CAAC;AACH,CAAC;AAED,oEAAoE;AACpE,MAAM,UAAU,SAAS,CAAC,IAAc;IACtC,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,IAAI,CAAC;YACH,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,GAAG,CAAC,CAAC,CAAA;YAC1C,OAAO,IAAI,CAAA;QACb,CAAC;QAAC,MAAM,CAAC,CAAC,kBAAkB,CAAC,CAAC;IAChC,CAAC;IACD,OAAO,KAAK,CAAA;AACd,CAAC;AAED,wDAAwD;AACxD,MAAM,UAAU,YAAY,CAAc,GAAW;IACnD,MAAM,IAAI,GAAG,YAAY,CAAC,GAAG,CAAC,CAAA;IAC9B,IAAI,IAAI,KAAK,IAAI;QAAE,OAAO,IAAI,CAAA;IAC9B,IAAI,CAAC;QACH,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAM,CAAA;IAC9B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAA;IACb,CAAC;AACH,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=deps.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"deps.d.ts","sourceRoot":"","sources":["../../../src/doctor/built-in/deps.ts"],"names":[],"mappings":""}
@@ -0,0 +1,81 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+ import { registerDoctorCheck } from '@rudderjs/console';
4
+ import { fileExists, mtimeMs, readJsonSafe } from './_fs.js';
5
+ function isResolvable(pkg) {
6
+ const target = path.join(process.cwd(), 'node_modules', pkg, 'package.json');
7
+ try {
8
+ return fs.statSync(target).isFile();
9
+ }
10
+ catch {
11
+ return false;
12
+ }
13
+ }
14
+ registerDoctorCheck({
15
+ id: 'deps:providers-manifest',
16
+ category: 'deps',
17
+ title: 'providers manifest',
18
+ run() {
19
+ const manifest = 'bootstrap/cache/providers.json';
20
+ if (!fileExists(manifest)) {
21
+ return {
22
+ status: 'warn',
23
+ message: 'missing — providers won\'t auto-discover',
24
+ fix: 'pnpm rudder providers:discover',
25
+ };
26
+ }
27
+ const manifestMtime = mtimeMs(manifest);
28
+ const pkgMtime = mtimeMs('package.json');
29
+ if (manifestMtime !== null && pkgMtime !== null && manifestMtime < pkgMtime) {
30
+ return {
31
+ status: 'warn',
32
+ message: 'older than package.json — packages added since last refresh',
33
+ fix: 'pnpm rudder providers:discover',
34
+ };
35
+ }
36
+ return { status: 'ok', message: 'present and current' };
37
+ },
38
+ async fixer() {
39
+ // Same logic as `rudder providers:discover` but invoked in-process so
40
+ // --fix doesn't shell out. `@rudderjs/core/commands/providers-discover`
41
+ // re-exports the two pure pieces — scanner + writer.
42
+ try {
43
+ const { scanProviders, writeProviderManifest } = await import(
44
+ /* @vite-ignore */ '@rudderjs/core/commands/providers-discover');
45
+ const sorted = scanProviders(process.cwd());
46
+ writeProviderManifest(process.cwd(), sorted);
47
+ return { status: 'ok', message: `regenerated (${sorted.length} provider${sorted.length === 1 ? '' : 's'})` };
48
+ }
49
+ catch (e) {
50
+ const msg = e instanceof Error ? e.message : String(e);
51
+ return { status: 'error', message: `could not regenerate: ${msg}` };
52
+ }
53
+ },
54
+ });
55
+ registerDoctorCheck({
56
+ id: 'deps:declared-installed',
57
+ category: 'deps',
58
+ title: '@rudderjs/* installed',
59
+ run() {
60
+ const pkg = readJsonSafe('package.json');
61
+ if (!pkg) {
62
+ return { status: 'error', message: 'package.json unreadable', fix: 'Check the file exists and is valid JSON' };
63
+ }
64
+ const declared = [
65
+ ...Object.keys(pkg.dependencies ?? {}),
66
+ ...Object.keys(pkg.devDependencies ?? {}),
67
+ ].filter(name => name.startsWith('@rudderjs/') || name === 'create-rudder-app');
68
+ const missing = declared.filter(name => !isResolvable(name));
69
+ if (missing.length > 0) {
70
+ return {
71
+ status: 'error',
72
+ message: `${missing.length} declared but not in node_modules: ${missing.join(', ')}`,
73
+ fix: 'Run your package manager install (e.g. `pnpm install`)',
74
+ };
75
+ }
76
+ return { status: 'ok', message: `${declared.length} declared, all resolvable` };
77
+ },
78
+ });
79
+ // `deps:auth-views` moved to @rudderjs/auth/doctor in Phase 3 — it's a
80
+ // package-specific concern that lives with the package that owns it.
81
+ //# sourceMappingURL=deps.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"deps.js","sourceRoot":"","sources":["../../../src/doctor/built-in/deps.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=env-vars.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"env-vars.d.ts","sourceRoot":"","sources":["../../../src/doctor/built-in/env-vars.ts"],"names":[],"mappings":""}
@@ -0,0 +1,99 @@
1
+ import { registerDoctorCheck } from '@rudderjs/console';
2
+ import { readFileSafe, fileExists } from './_fs.js';
3
+ /**
4
+ * Minimal `.env` parser — covers `KEY=value`, `KEY="value"`, comments, blanks.
5
+ * Doesn't expand `${VAR}` references; we only need to check declared keys.
6
+ */
7
+ function parseEnvText(text) {
8
+ const out = new Map();
9
+ for (const rawLine of text.split('\n')) {
10
+ const line = rawLine.replace(/^\s+|\s+$/g, '');
11
+ if (!line || line.startsWith('#'))
12
+ continue;
13
+ const eq = line.indexOf('=');
14
+ if (eq === -1)
15
+ continue;
16
+ const key = line.slice(0, eq).trim();
17
+ let value = line.slice(eq + 1).trim();
18
+ if ((value.startsWith('"') && value.endsWith('"')) || (value.startsWith("'") && value.endsWith("'"))) {
19
+ value = value.slice(1, -1);
20
+ }
21
+ out.set(key, value);
22
+ }
23
+ return out;
24
+ }
25
+ registerDoctorCheck({
26
+ id: 'env:dotenv-loadable',
27
+ category: 'env',
28
+ title: '.env file',
29
+ run() {
30
+ if (!fileExists('.env')) {
31
+ const exampleHint = fileExists('.env.example')
32
+ ? 'Run `cp .env.example .env` and fill in the secrets'
33
+ : 'Create a .env file with your config (APP_KEY, AUTH_SECRET, etc.)';
34
+ return { status: 'error', message: 'missing', fix: exampleHint };
35
+ }
36
+ const text = readFileSafe('.env');
37
+ if (text === null) {
38
+ return { status: 'error', message: 'present but unreadable', fix: 'Check file permissions on .env' };
39
+ }
40
+ const parsed = parseEnvText(text);
41
+ return { status: 'ok', message: `parses (${parsed.size} keys)` };
42
+ },
43
+ });
44
+ registerDoctorCheck({
45
+ id: 'env:app-key',
46
+ category: 'env',
47
+ title: 'APP_KEY',
48
+ run() {
49
+ const v = process.env['APP_KEY'];
50
+ if (!v) {
51
+ return {
52
+ status: 'error',
53
+ message: 'unset',
54
+ fix: 'Generate a 32-byte base64 key (e.g. `node -e "console.log(require(\'crypto\').randomBytes(32).toString(\'base64\'))"`) and put it in .env',
55
+ };
56
+ }
57
+ // APP_KEY can be raw or base64-encoded. Accept either form, validate decoded length.
58
+ let decodedLen;
59
+ try {
60
+ decodedLen = Buffer.from(v, 'base64').length;
61
+ }
62
+ catch {
63
+ decodedLen = Buffer.byteLength(v);
64
+ }
65
+ if (decodedLen < 32) {
66
+ return {
67
+ status: 'warn',
68
+ message: `present but only ${decodedLen} bytes — needs ≥ 32 for AES-256`,
69
+ fix: 'Generate a fresh 32-byte key with `node -e "console.log(require(\'crypto\').randomBytes(32).toString(\'base64\'))"`',
70
+ };
71
+ }
72
+ return { status: 'ok', message: `set, ${decodedLen} bytes` };
73
+ },
74
+ });
75
+ registerDoctorCheck({
76
+ id: 'env:app-env',
77
+ category: 'env',
78
+ title: 'APP_ENV',
79
+ run() {
80
+ const v = process.env['APP_ENV'] ?? process.env['NODE_ENV'];
81
+ if (!v) {
82
+ return {
83
+ status: 'warn',
84
+ message: 'unset — defaults to "production" in many adapters',
85
+ fix: 'Add `APP_ENV=local` (or `dev`/`staging`/`production`) to .env',
86
+ };
87
+ }
88
+ const known = ['local', 'dev', 'development', 'test', 'staging', 'production'];
89
+ if (!known.includes(v)) {
90
+ return {
91
+ status: 'warn',
92
+ message: `non-standard value "${v}"`,
93
+ fix: `Use one of: ${known.join(', ')}`,
94
+ };
95
+ }
96
+ return { status: 'ok', message: v };
97
+ },
98
+ });
99
+ //# sourceMappingURL=env-vars.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"env-vars.js","sourceRoot":"","sources":["../../../src/doctor/built-in/env-vars.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Built-in doctor checks owned by `@rudderjs/cli`. Each module's side-effect
3
+ * import calls `registerDoctorCheck()` so the checks are visible to the
4
+ * orchestrator after `loadBuiltInChecks()` runs.
5
+ */
6
+ import './node-version.js';
7
+ import './package-manager.js';
8
+ import './env-vars.js';
9
+ import './structure.js';
10
+ import './deps.js';
11
+ import './runtime.js';
12
+ export declare function loadBuiltInChecks(): void;
13
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/doctor/built-in/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,mBAAmB,CAAA;AAC1B,OAAO,sBAAsB,CAAA;AAC7B,OAAO,eAAe,CAAA;AACtB,OAAO,gBAAgB,CAAA;AACvB,OAAO,WAAW,CAAA;AAClB,OAAO,cAAc,CAAA;AAErB,wBAAgB,iBAAiB,IAAI,IAAI,CAKxC"}
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Built-in doctor checks owned by `@rudderjs/cli`. Each module's side-effect
3
+ * import calls `registerDoctorCheck()` so the checks are visible to the
4
+ * orchestrator after `loadBuiltInChecks()` runs.
5
+ */
6
+ import './node-version.js';
7
+ import './package-manager.js';
8
+ import './env-vars.js';
9
+ import './structure.js';
10
+ import './deps.js';
11
+ import './runtime.js';
12
+ export function loadBuiltInChecks() {
13
+ // Module loading is sufficient — side-effect imports above call
14
+ // registerDoctorCheck() at module-init time. This function exists so the
15
+ // doctor command can force the imports (otherwise tree-shaking would
16
+ // drop them).
17
+ }
18
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/doctor/built-in/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,mBAAmB,CAAA;AAC1B,OAAO,sBAAsB,CAAA;AAC7B,OAAO,eAAe,CAAA;AACtB,OAAO,gBAAgB,CAAA;AACvB,OAAO,WAAW,CAAA;AAClB,OAAO,cAAc,CAAA;AAErB,MAAM,UAAU,iBAAiB;IAC/B,gEAAgE;IAChE,yEAAyE;IACzE,qEAAqE;IACrE,cAAc;AAChB,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=node-version.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"node-version.d.ts","sourceRoot":"","sources":["../../../src/doctor/built-in/node-version.ts"],"names":[],"mappings":""}
@@ -0,0 +1,72 @@
1
+ import { registerDoctorCheck } from '@rudderjs/console';
2
+ import { readJsonSafe } from './_fs.js';
3
+ /**
4
+ * Loose semver `Major.Minor.Patch` parser — good enough to compare against a
5
+ * package.json `engines.node` range like `^20.19.0 || >=22.12.0`.
6
+ *
7
+ * We don't pull in `semver` because the CLI ships with the framework and
8
+ * pulling a 3rd-party parser for one comparison is wasteful. The range syntax
9
+ * we accept matches what create-rudder-app generates.
10
+ */
11
+ function parseVersion(v) {
12
+ const m = /^v?(\d+)\.(\d+)\.(\d+)/.exec(v);
13
+ return m ? [Number(m[1]), Number(m[2]), Number(m[3])] : null;
14
+ }
15
+ function cmp(a, b) {
16
+ for (let i = 0; i < 3; i++) {
17
+ const ai = a[i], bi = b[i];
18
+ if (ai !== bi)
19
+ return ai - bi;
20
+ }
21
+ return 0;
22
+ }
23
+ function matchesRange(version, range) {
24
+ // Handle `||` alternation
25
+ return range.split('||').some(part => matchesSingle(version, part.trim()));
26
+ }
27
+ function matchesSingle(version, range) {
28
+ // ^X.Y.Z — same major, >= X.Y.Z
29
+ let m = /^\^(\d+)\.(\d+)\.(\d+)$/.exec(range);
30
+ if (m) {
31
+ const target = [Number(m[1]), Number(m[2]), Number(m[3])];
32
+ return version[0] === target[0] && cmp(version, target) >= 0;
33
+ }
34
+ // >=X.Y.Z
35
+ m = /^>=\s*(\d+)\.(\d+)\.(\d+)$/.exec(range);
36
+ if (m) {
37
+ const target = [Number(m[1]), Number(m[2]), Number(m[3])];
38
+ return cmp(version, target) >= 0;
39
+ }
40
+ // Exact `X.Y.Z`
41
+ m = /^=?\s*(\d+)\.(\d+)\.(\d+)$/.exec(range);
42
+ if (m) {
43
+ const target = [Number(m[1]), Number(m[2]), Number(m[3])];
44
+ return cmp(version, target) === 0;
45
+ }
46
+ return false;
47
+ }
48
+ registerDoctorCheck({
49
+ id: 'env:node-version',
50
+ category: 'env',
51
+ title: 'Node version',
52
+ run() {
53
+ const pkg = readJsonSafe('package.json');
54
+ const range = pkg?.engines?.node;
55
+ const current = parseVersion(process.version);
56
+ if (!current) {
57
+ return { status: 'warn', message: `couldn't parse Node version "${process.version}"` };
58
+ }
59
+ if (!range) {
60
+ return { status: 'ok', message: `${process.version} (no engines.node constraint)` };
61
+ }
62
+ if (matchesRange(current, range)) {
63
+ return { status: 'ok', message: `${process.version} (matches ${range})` };
64
+ }
65
+ return {
66
+ status: 'error',
67
+ message: `${process.version} does not satisfy ${range}`,
68
+ fix: `Install a Node version matching ${range} (use \`nvm install\`, fnm, or asdf)`,
69
+ };
70
+ },
71
+ });
72
+ //# sourceMappingURL=node-version.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"node-version.js","sourceRoot":"","sources":["../../../src/doctor/built-in/node-version.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=package-manager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"package-manager.d.ts","sourceRoot":"","sources":["../../../src/doctor/built-in/package-manager.ts"],"names":[],"mappings":""}
@@ -0,0 +1,55 @@
1
+ import { registerDoctorCheck } from '@rudderjs/console';
2
+ import { fileExists } from './_fs.js';
3
+ function detect() {
4
+ const lockMap = [
5
+ ['pnpm-lock.yaml', 'pnpm'],
6
+ ['package-lock.json', 'npm'],
7
+ ['yarn.lock', 'yarn'],
8
+ ['bun.lockb', 'bun'],
9
+ ['bun.lock', 'bun'],
10
+ ];
11
+ const lockfiles = lockMap.filter(([f]) => fileExists(f)).map(([f]) => f);
12
+ const fromLockfile = lockfiles.length === 1
13
+ ? lockMap.find(([f]) => f === lockfiles[0])[1]
14
+ : null;
15
+ const ua = process.env['npm_config_user_agent'] ?? '';
16
+ const fromUserAgent = ua.startsWith('pnpm') ? 'pnpm' :
17
+ ua.startsWith('yarn') ? 'yarn' :
18
+ ua.startsWith('bun') ? 'bun' :
19
+ ua.startsWith('npm') ? 'npm' :
20
+ null;
21
+ return { fromLockfile, fromUserAgent, lockfiles };
22
+ }
23
+ registerDoctorCheck({
24
+ id: 'env:package-manager',
25
+ category: 'env',
26
+ title: 'Package manager',
27
+ run() {
28
+ const d = detect();
29
+ if (d.lockfiles.length === 0) {
30
+ return {
31
+ status: 'error',
32
+ message: 'no lockfile found',
33
+ fix: 'Run your package manager install (e.g. `pnpm install`, `npm install`, `yarn install`)',
34
+ };
35
+ }
36
+ if (d.lockfiles.length > 1) {
37
+ return {
38
+ status: 'warn',
39
+ message: `multiple lockfiles present: ${d.lockfiles.join(', ')}`,
40
+ fix: `Pick one PM and delete the others — mixed lockfiles cause flaky installs`,
41
+ };
42
+ }
43
+ const pm = d.fromLockfile;
44
+ const ua = d.fromUserAgent;
45
+ if (ua && ua !== pm) {
46
+ return {
47
+ status: 'warn',
48
+ message: `lockfile is ${pm} but ran with ${ua}`,
49
+ fix: `Run with ${pm} (\`${pm} install\`, \`${pm} <script>\`) to match the lockfile`,
50
+ };
51
+ }
52
+ return { status: 'ok', message: `${pm} — lockfile present` };
53
+ },
54
+ });
55
+ //# sourceMappingURL=package-manager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"package-manager.js","sourceRoot":"","sources":["../../../src/doctor/built-in/package-manager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAqB,MAAM,mBAAmB,CAAA;AAC1E,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAA;AAWrC,SAAS,MAAM;IACb,MAAM,OAAO,GAAqD;QAChE,CAAC,gBAAgB,EAAM,MAAM,CAAC;QAC9B,CAAC,mBAAmB,EAAG,KAAK,CAAC;QAC7B,CAAC,WAAW,EAAW,MAAM,CAAC;QAC9B,CAAC,WAAW,EAAW,KAAK,CAAC;QAC7B,CAAC,UAAU,EAAY,KAAK,CAAC;KAC9B,CAAA;IACD,MAAM,SAAS,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAA;IACxE,MAAM,YAAY,GAAG,SAAS,CAAC,MAAM,KAAK,CAAC;QACzC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,SAAS,CAAC,CAAC,CAAC,CAAE,CAAC,CAAC,CAAC;QAC/C,CAAC,CAAC,IAAI,CAAA;IAER,MAAM,EAAE,GAAG,OAAO,CAAC,GAAG,CAAC,uBAAuB,CAAC,IAAI,EAAE,CAAA;IACrD,MAAM,aAAa,GACjB,EAAE,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;QAChC,EAAE,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;YAChC,EAAE,CAAC,UAAU,CAAC,KAAK,CAAC,CAAE,CAAC,CAAC,KAAK,CAAC,CAAC;gBAC/B,EAAE,CAAC,UAAU,CAAC,KAAK,CAAC,CAAE,CAAC,CAAC,KAAK,CAAC,CAAC;oBAC/B,IAAI,CAAA;IAEN,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,SAAS,EAAE,CAAA;AACnD,CAAC;AAED,mBAAmB,CAAC;IAClB,EAAE,EAAQ,qBAAqB;IAC/B,QAAQ,EAAE,KAAK;IACf,KAAK,EAAK,iBAAiB;IAC3B,GAAG;QACD,MAAM,CAAC,GAAG,MAAM,EAAE,CAAA;QAClB,IAAI,CAAC,CAAC,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC7B,OAAO;gBACL,MAAM,EAAG,OAAO;gBAChB,OAAO,EAAE,mBAAmB;gBAC5B,GAAG,EAAM,uFAAuF;aACjG,CAAA;QACH,CAAC;QACD,IAAI,CAAC,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC3B,OAAO;gBACL,MAAM,EAAG,MAAM;gBACf,OAAO,EAAE,+BAA+B,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;gBAChE,GAAG,EAAM,0EAA0E;aACpF,CAAA;QACH,CAAC;QACD,MAAM,EAAE,GAAG,CAAC,CAAC,YAAa,CAAA;QAC1B,MAAM,EAAE,GAAG,CAAC,CAAC,aAAa,CAAA;QAC1B,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;YACpB,OAAO;gBACL,MAAM,EAAG,MAAM;gBACf,OAAO,EAAE,eAAe,EAAE,iBAAiB,EAAE,EAAE;gBAC/C,GAAG,EAAM,YAAY,EAAE,OAAO,EAAE,iBAAiB,EAAE,oCAAoC;aACxF,CAAA;QACH,CAAC;QACD,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,EAAE,qBAAqB,EAAE,CAAA;IAC9D,CAAC;CACF,CAAC,CAAA"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=runtime.d.ts.map