intor-cli 0.0.14 → 0.0.16

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 (117) hide show
  1. package/package.json +2 -3
  2. package/src/cli/commands/check.ts +23 -17
  3. package/src/cli/commands/discover.ts +32 -0
  4. package/src/cli/commands/generate.ts +35 -40
  5. package/src/cli/commands/index.ts +4 -0
  6. package/src/cli/commands/options/index.ts +1 -0
  7. package/src/cli/commands/options/options.ts +55 -0
  8. package/src/cli/commands/utils/normalize-message-files.ts +49 -0
  9. package/src/cli/commands/utils/normalize-reader-options.ts +15 -28
  10. package/src/cli/commands/validate.ts +26 -30
  11. package/src/cli/index.ts +38 -23
  12. package/src/cli/menu/index.ts +1 -0
  13. package/src/cli/menu/prompts/prompt-check.ts +74 -0
  14. package/src/cli/menu/prompts/prompt-discover.ts +25 -0
  15. package/src/cli/menu/prompts/prompt-generate.ts +106 -0
  16. package/src/cli/menu/prompts/prompt-validate.ts +49 -0
  17. package/src/cli/menu/prompts/shared/prompt-reader-options.ts +63 -0
  18. package/src/cli/menu/prompts/shared/shared.ts +76 -0
  19. package/src/cli/menu/run.ts +72 -0
  20. package/src/cli/version.ts +3 -0
  21. package/src/constants.ts +6 -0
  22. package/src/core/artifacts/index.ts +5 -0
  23. package/src/core/artifacts/schema/build-schema.ts +13 -0
  24. package/src/core/artifacts/schema/index.ts +3 -0
  25. package/src/core/{generated → artifacts/schema}/read-schema.ts +4 -4
  26. package/src/core/artifacts/schema/write-schema.ts +14 -0
  27. package/src/{build/build-types → core/artifacts/types/build}/build-types.ts +9 -10
  28. package/src/{build/build-types → core/artifacts/types/build}/utils/normalize-rich-infer-node.ts +1 -1
  29. package/src/{build/build-types → core/artifacts/types/build}/utils/render-infer-node.ts +1 -1
  30. package/src/core/artifacts/types/index.ts +2 -0
  31. package/src/core/artifacts/types/write-types.ts +8 -0
  32. package/src/core/artifacts/types.ts +20 -0
  33. package/src/core/collect-messages/collect-other-locale-messages.ts +5 -7
  34. package/src/core/collect-messages/collect-runtime-messages.ts +8 -6
  35. package/src/core/collect-messages/index.ts +1 -0
  36. package/src/core/collect-messages/readers.ts +1 -0
  37. package/src/core/collect-messages/types.ts +7 -1
  38. package/src/core/constants/index.ts +2 -0
  39. package/src/core/discover-configs/discover-configs.ts +47 -26
  40. package/src/core/extract-usages/extract-usages.ts +33 -24
  41. package/src/core/index.ts +12 -7
  42. package/src/core/infer-shape/index.ts +4 -0
  43. package/src/core/{infer-schema/messages/infer-messages-schema.ts → infer-shape/infer-messages-shape.ts} +5 -10
  44. package/src/core/{infer-schema/replacements/infer-replacements-schema.ts → infer-shape/infer-replacements-shape.ts} +6 -11
  45. package/src/core/{infer-schema/rich/infer-rich-schema.ts → infer-shape/infer-rich-shape.ts} +5 -10
  46. package/src/core/infer-shape/infer-shapes.ts +21 -0
  47. package/src/core/{infer-schema → infer-shape}/types.ts +4 -4
  48. package/src/core/scan/index.ts +2 -0
  49. package/src/core/{extract-usages/load-source-files-from-tscofnig.ts → scan/load-source-files.ts} +34 -15
  50. package/src/core/scan/scan-files.ts +25 -0
  51. package/src/features/check/build-scoped-usages.ts +35 -0
  52. package/src/features/check/check.ts +51 -53
  53. package/src/features/check/diagnostics/collect.ts +6 -2
  54. package/src/features/check/diagnostics/group.ts +0 -1
  55. package/src/features/check/index.ts +1 -0
  56. package/src/features/check/render-config-summary.ts +47 -0
  57. package/src/features/check/types.ts +12 -0
  58. package/src/features/discover/discover.ts +22 -0
  59. package/src/features/discover/index.ts +1 -0
  60. package/src/features/generate/generate.ts +56 -49
  61. package/src/features/generate/index.ts +1 -0
  62. package/src/features/generate/render-overrides.ts +73 -0
  63. package/src/features/generate/render-summary.ts +28 -0
  64. package/src/features/generate/types.ts +12 -0
  65. package/src/features/generate/utils/resolve-message-source.ts +20 -0
  66. package/src/features/generate/utils/validate-message-source.ts +53 -0
  67. package/src/features/index.ts +4 -3
  68. package/src/features/shared/to-relative-path.ts +10 -0
  69. package/src/features/shared/write-json-report.ts +19 -0
  70. package/src/features/validate/index.ts +1 -0
  71. package/src/features/validate/{messages/validate-messages-schema.ts → missing/collect-missing-messages.ts} +5 -5
  72. package/src/features/validate/{replacements/validate-replacements-schema.ts → missing/collect-missing-replacements.ts} +4 -4
  73. package/src/features/validate/missing/collect-missing-requirements.ts +44 -0
  74. package/src/features/validate/{rich/validate-rich-schema.ts → missing/collect-missing-rich.ts} +5 -5
  75. package/src/features/validate/render-config-summary.ts +47 -0
  76. package/src/features/validate/render-locale-blocks.ts +56 -0
  77. package/src/features/validate/types.ts +14 -0
  78. package/src/features/validate/validate.ts +38 -43
  79. package/src/logger.ts +95 -0
  80. package/src/render.ts +57 -0
  81. package/src/build/build-schemas/build-schemas.ts +0 -13
  82. package/src/build/build-schemas/index.ts +0 -1
  83. package/src/build/index.ts +0 -3
  84. package/src/build/types.ts +0 -20
  85. package/src/core/generated/index.ts +0 -6
  86. package/src/core/generated/write-messages-snapshot.ts +0 -27
  87. package/src/core/generated/write-schema.ts +0 -9
  88. package/src/core/generated/write-types.ts +0 -8
  89. package/src/core/infer-schema/index.ts +0 -4
  90. package/src/core/infer-schema/infer-schemas.ts +0 -20
  91. package/src/core/infer-schema/messages/index.ts +0 -1
  92. package/src/core/infer-schema/replacements/index.ts +0 -1
  93. package/src/core/infer-schema/rich/index.ts +0 -1
  94. package/src/core/scan-logger.ts +0 -10
  95. package/src/features/check/print-summary.ts +0 -28
  96. package/src/features/generate/print-configs.ts +0 -8
  97. package/src/features/generate/print-overrides.ts +0 -62
  98. package/src/features/generate/print-summary.ts +0 -26
  99. package/src/features/print.ts +0 -43
  100. package/src/features/validate/messages/index.ts +0 -1
  101. package/src/features/validate/print-summary.ts +0 -65
  102. package/src/features/validate/replacements/index.ts +0 -1
  103. package/src/features/validate/rich/index.ts +0 -1
  104. package/src/features/validate/validate-locale-messages.ts +0 -38
  105. /package/src/core/{generated → artifacts}/ensure-and-write.ts +0 -0
  106. /package/src/{build/build-types → core/artifacts/types/build}/index.ts +0 -0
  107. /package/src/{build/build-types → core/artifacts/types/build}/output/append-config-block.ts +0 -0
  108. /package/src/{build/build-types → core/artifacts/types/build}/output/append-footer.ts +0 -0
  109. /package/src/{build/build-types → core/artifacts/types/build}/output/append-header.ts +0 -0
  110. /package/src/{build/build-types → core/artifacts/types/build}/output/index.ts +0 -0
  111. /package/src/{build/build-types → core/artifacts/types/build}/utils/indent.ts +0 -0
  112. /package/src/core/{infer-schema/replacements → infer-shape/utils}/extract-interpolation-names.ts +0 -0
  113. /package/src/core/{infer-schema → infer-shape}/utils/infer-object.ts +0 -0
  114. /package/src/core/{infer-schema → infer-shape}/utils/is-message-object.ts +0 -0
  115. /package/src/core/{infer-schema → infer-shape}/utils/should-skip-key.ts +0 -0
  116. /package/src/core/{infer-schema → infer-shape}/utils/strip-internal-keys.ts +0 -0
  117. /package/src/features/{spinner.ts → shared/spinner.ts} +0 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "intor-cli",
3
- "version": "0.0.14",
3
+ "version": "0.0.16",
4
4
  "description": "The Intor CLI",
5
5
  "author": "Yiming Liao",
6
6
  "homepage": "https://github.com/yiming-liao/intor-cli#readme",
@@ -39,6 +39,7 @@
39
39
  "intor": "src/cli/index.ts"
40
40
  },
41
41
  "dependencies": {
42
+ "@clack/prompts": "^1.0.0",
42
43
  "@intor/reader-json5": "^0.1.0",
43
44
  "@intor/reader-md": "^0.1.4",
44
45
  "@intor/reader-toml": "^0.1.0",
@@ -64,8 +65,6 @@
64
65
  "eslint-plugin-unused-imports": "4.3.0",
65
66
  "knip": "5.79.0",
66
67
  "prettier": "3.7.4",
67
- "remark": "15.0.1",
68
- "remark-gfm": "4.0.1",
69
68
  "typescript": "5.9.3",
70
69
  "typescript-eslint": "8.51.0",
71
70
  "vitest": "4.0.16"
@@ -1,33 +1,39 @@
1
- import type { ExtractUsagesOptions } from "../../core/extract-usages/extract-usages";
1
+ import type { CliOption } from "./options";
2
2
  import type { CAC } from "cac";
3
+ import { features } from "../../constants";
3
4
  import { check } from "../../features";
5
+ import { options } from "./options";
4
6
 
5
7
  export function registerCheckCommand(cli: CAC) {
6
8
  cli
7
9
  // -----------------------------------------------------------------------
8
10
  // Command
9
11
  // -----------------------------------------------------------------------
10
- .command("check", "Validate intor translation usage")
12
+ .command(features.check.name, features.check.title)
11
13
 
12
14
  // -----------------------------------------------------------------------
13
- // Option
15
+ // Options
14
16
  // -----------------------------------------------------------------------
15
- .option(
16
- "--tsconfig <path>",
17
- "Path to tsconfig.json (default: tsconfig.json)",
18
- )
19
- .option("--debug", "Enable debug logging")
17
+ .option(...options.debug)
18
+ .option(...options.tsconfig)
19
+ .option(...options.format)
20
+ .option(...options.output)
20
21
 
21
22
  // -----------------------------------------------------------------------
22
23
  // Action
23
24
  // -----------------------------------------------------------------------
24
- .action(async (options: ExtractUsagesOptions) => {
25
- const { tsconfigPath, debug } = options;
26
- try {
27
- await check({ tsconfigPath, debug });
28
- } catch (error) {
29
- console.error(error);
30
- process.exitCode = 1;
31
- }
32
- });
25
+ .action(
26
+ async (
27
+ options: Pick<CliOption, "debug" | "tsconfig" | "format" | "output">,
28
+ ) => {
29
+ const { debug, tsconfig, format, output } = options;
30
+
31
+ try {
32
+ await check({ debug, tsconfigPath: tsconfig, format, output });
33
+ } catch (error) {
34
+ console.error(error instanceof Error ? error.message : error);
35
+ process.exitCode = 1;
36
+ }
37
+ },
38
+ );
33
39
  }
@@ -0,0 +1,32 @@
1
+ import type { CliOption } from "./options";
2
+ import type { CAC } from "cac";
3
+ import { features } from "../../constants";
4
+ import { discover } from "../../features";
5
+ import { options } from "./options";
6
+
7
+ export function registerDiscoverCommand(cli: CAC) {
8
+ cli
9
+ // -----------------------------------------------------------------------
10
+ // Command
11
+ // -----------------------------------------------------------------------
12
+ .command(features.discover.name, features.discover.title)
13
+
14
+ // -----------------------------------------------------------------------
15
+ // Options
16
+ // -----------------------------------------------------------------------
17
+ .option(...options.debug)
18
+
19
+ // -----------------------------------------------------------------------
20
+ // Action
21
+ // -----------------------------------------------------------------------
22
+ .action(async (options: Pick<CliOption, "debug">) => {
23
+ const { debug } = options;
24
+
25
+ try {
26
+ await discover({ debug });
27
+ } catch (error) {
28
+ console.error(error instanceof Error ? error.message : error);
29
+ process.exitCode = 1;
30
+ }
31
+ });
32
+ }
@@ -1,6 +1,10 @@
1
- import type { ExtraExt } from "../../core";
1
+ import type { CliOption } from "./options";
2
2
  import type { CAC } from "cac";
3
+ import { features } from "../../constants";
3
4
  import { generate } from "../../features";
5
+ import { version } from "../version";
6
+ import { options } from "./options";
7
+ import { normalizeMessageFiles } from "./utils/normalize-message-files";
4
8
  import { normalizeReaderOptions } from "./utils/normalize-reader-options";
5
9
 
6
10
  export function registerGenerateCommand(cli: CAC) {
@@ -8,53 +12,44 @@ export function registerGenerateCommand(cli: CAC) {
8
12
  // -----------------------------------------------------------------------
9
13
  // Command
10
14
  // -----------------------------------------------------------------------
11
- .command("generate", "Generate intor types and schemas")
15
+ .command(features.generate.name, features.generate.title)
12
16
 
13
17
  // -----------------------------------------------------------------------
14
18
  // Option
15
19
  // -----------------------------------------------------------------------
16
- .option(
17
- "--messages <path>",
18
- "Explicit messages file for schema generation (bypass runtime loader)",
19
- )
20
- .option(
21
- "--ext <ext>",
22
- "Enable extra messages file extension (repeatable)",
23
- { default: [] },
24
- )
25
- .option(
26
- "--reader <mapping>",
27
- "Custom reader mapping in the form <ext=path> (repeatable)",
28
- { default: [] },
29
- )
30
- .option(
31
- "--debug",
32
- "Print debug information during config discovery and generation",
33
- )
20
+ .option(...options.debug)
21
+ .option(...options.messageFile)
22
+ .option(...options.messageFiles)
23
+ .option(...options.ext)
24
+ .option(...options.reader)
34
25
 
35
26
  // -----------------------------------------------------------------------
36
27
  // Action
37
28
  // -----------------------------------------------------------------------
38
- .action(async (options) => {
39
- const { messages, ext, reader, debug } = options as {
40
- messages?: string;
41
- ext?: Array<ExtraExt>;
42
- reader?: string[];
43
- debug?: boolean;
44
- };
29
+ .action(
30
+ async (
31
+ options: Pick<
32
+ CliOption,
33
+ "debug" | "messageFile" | "messageFiles" | "ext" | "reader"
34
+ >,
35
+ ) => {
36
+ const { debug, messageFile, messageFiles, ...readerOptions } = options;
45
37
 
46
- const { exts, customReaders } = normalizeReaderOptions({ ext, reader });
38
+ const result = normalizeMessageFiles(messageFile, messageFiles);
39
+ const { exts, customReaders } = normalizeReaderOptions(readerOptions);
47
40
 
48
- try {
49
- await generate({
50
- messageFilePath: messages,
51
- exts,
52
- customReaders,
53
- debug,
54
- });
55
- } catch (error) {
56
- console.error(error);
57
- process.exitCode = 1;
58
- }
59
- });
41
+ try {
42
+ await generate({
43
+ debug,
44
+ messageSource: result,
45
+ exts,
46
+ customReaders,
47
+ toolVersion: version,
48
+ });
49
+ } catch (error) {
50
+ console.error(error instanceof Error ? error.message : error);
51
+ process.exitCode = 1;
52
+ }
53
+ },
54
+ );
60
55
  }
@@ -0,0 +1,4 @@
1
+ export { registerDiscoverCommand } from "./discover";
2
+ export { registerGenerateCommand } from "./generate";
3
+ export { registerCheckCommand } from "./check";
4
+ export { registerValidateCommand } from "./validate";
@@ -0,0 +1 @@
1
+ export { options, type CliOptions as CliOption } from "./options";
@@ -0,0 +1,55 @@
1
+ import type { CAC } from "cac";
2
+
3
+ export const options = {
4
+ debug: ["--debug", "Enable debug logging", { default: false }],
5
+
6
+ tsconfig: [
7
+ "--tsconfig <path>",
8
+ "Path to tsconfig.json (default: tsconfig.json)",
9
+ ],
10
+
11
+ messageFile: [
12
+ "--message-file <file>",
13
+ "Explicit message file for single-config projects",
14
+ ],
15
+
16
+ messageFiles: [
17
+ "--message-files <mapping...>",
18
+ "Explicit message file mapping in the form <configId=path> (repeatable)",
19
+ { default: [] },
20
+ ],
21
+
22
+ ext: [
23
+ "--ext <ext>",
24
+ "Enable extra messages file extension (repeatable)",
25
+ { default: [] },
26
+ ],
27
+
28
+ reader: [
29
+ "--reader <mapping>",
30
+ "Custom reader mapping in the form <ext=path> (repeatable)",
31
+ { default: [] },
32
+ ],
33
+
34
+ format: [
35
+ "--format <format>",
36
+ "Output format: human | json",
37
+ { default: "human" },
38
+ ],
39
+
40
+ output: [
41
+ "--output <file>",
42
+ "Write output to file (only applies to json format)",
43
+ ],
44
+ } as const satisfies Record<string, Parameters<CAC["option"]>>;
45
+
46
+ export interface CliOptions {
47
+ debug?: boolean;
48
+ tsconfig?: string;
49
+ messageFile?: string;
50
+ messageFiles?: string[];
51
+ ext?: string[];
52
+ reader?: string[];
53
+ format?: "human" | "json";
54
+ output?: string;
55
+ }
@@ -0,0 +1,49 @@
1
+ import type { MessageSource } from "../../../features";
2
+
3
+ /**
4
+ * Normalize message file CLI options into a MessageSource.
5
+ */
6
+ export function normalizeMessageFiles(
7
+ messageFile?: string,
8
+ messageFiles: string[] = [],
9
+ ): MessageSource {
10
+ if (messageFile && messageFiles.length > 0) {
11
+ throw new Error(
12
+ "Cannot use --message-file and --message-files at the same time.",
13
+ );
14
+ }
15
+
16
+ // --------------------------------------------------
17
+ // single mode
18
+ // --------------------------------------------------
19
+ if (messageFile) {
20
+ return {
21
+ mode: "single",
22
+ file: messageFile,
23
+ };
24
+ }
25
+
26
+ // --------------------------------------------------
27
+ // mapping mode
28
+ // --------------------------------------------------
29
+ if (messageFiles.length > 0) {
30
+ const files: Record<string, string> = {};
31
+
32
+ for (const messageFile of messageFiles) {
33
+ const [id, path] = messageFile.split("=", 2);
34
+ if (!id || !path) {
35
+ throw new Error(
36
+ `Invalid --message-files entry: "${messageFile}". Each entry must be in the form: <configId=path>`,
37
+ );
38
+ }
39
+ files[id] = path;
40
+ }
41
+
42
+ return {
43
+ mode: "mapping",
44
+ files,
45
+ };
46
+ }
47
+
48
+ return { mode: "none" };
49
+ }
@@ -1,46 +1,33 @@
1
- import type { ExtraExt } from "../../../core";
2
-
3
- export interface NormalizedReaderOptions {
4
- exts: ExtraExt[];
5
- customReaders?: Record<string, string>;
6
- }
7
-
8
- export interface RawReaderOptions {
9
- ext?: string | string[];
10
- reader?: string[];
11
- }
1
+ import type { ReaderOptions, ExtraExt } from "../../../core";
2
+ import type { CliOptions } from "../options/options";
12
3
 
13
4
  /**
14
- * Normalize CLI reader-related options:
15
- * - ext: string | string[] → string[]
16
- * - reader: ["md=./reader.ts"] → { md: "./reader.ts" }
5
+ * Normalize CLI reader-related options
17
6
  */
18
- export function normalizeReaderOptions(
19
- options: RawReaderOptions,
20
- ): NormalizedReaderOptions {
21
- // Normalize exts
22
- const exts = options.ext
23
- ? Array.isArray(options.ext)
24
- ? options.ext
25
- : [options.ext]
26
- : [];
27
-
7
+ export function normalizeReaderOptions({
8
+ ext = [],
9
+ reader = [],
10
+ }: Pick<CliOptions, "ext" | "reader">): ReaderOptions {
28
11
  // Normalize custom readers
29
12
  let customReaders: Record<string, string> | undefined;
30
13
 
31
- if (options.reader && options.reader.length > 0) {
14
+ if (reader && reader.length > 0) {
32
15
  customReaders = {};
33
16
 
34
- for (const item of options.reader) {
17
+ for (const item of reader) {
35
18
  const [key, value] = item.split("=", 2);
36
- if (!key || !value) continue;
19
+ if (!key || !value) {
20
+ throw new Error(
21
+ `Invalid --reader entry: "${item}". Each entry must be in the form: <ext=path>`,
22
+ );
23
+ }
37
24
 
38
25
  customReaders[key] = value;
39
26
  }
40
27
  }
41
28
 
42
29
  return {
43
- exts: exts as ExtraExt[],
30
+ exts: ext as ExtraExt[],
44
31
  customReaders,
45
32
  };
46
33
  }
@@ -1,6 +1,8 @@
1
- import type { ExtraExt } from "../../core";
1
+ import type { CliOptions } from "./options/options";
2
2
  import type { CAC } from "cac";
3
+ import { features } from "../../constants";
3
4
  import { validate } from "../../features";
5
+ import { options } from "./options";
4
6
  import { normalizeReaderOptions } from "./utils/normalize-reader-options";
5
7
 
6
8
  export function registerValidateCommand(cli: CAC) {
@@ -8,43 +10,37 @@ export function registerValidateCommand(cli: CAC) {
8
10
  // -----------------------------------------------------------------------
9
11
  // Command
10
12
  // -----------------------------------------------------------------------
11
- .command("validate", "Validate intor locale translations")
13
+ .command(features.validate.name, features.validate.title)
12
14
 
13
15
  // -----------------------------------------------------------------------
14
16
  // Option
15
17
  // -----------------------------------------------------------------------
16
- .option(
17
- "--ext <ext>",
18
- "Enable extra messages file extension (repeatable)",
19
- { default: [] },
20
- )
21
- .option(
22
- "--reader <mapping>",
23
- "Custom reader mapping in the form <ext=path> (repeatable)",
24
- { default: [] },
25
- )
26
- .option(
27
- "--debug",
28
- "Print debug information during config discovery and generation",
29
- )
18
+ .option(...options.debug)
19
+ .option(...options.ext)
20
+ .option(...options.reader)
21
+ .option(...options.format)
22
+ .option(...options.output)
30
23
 
31
24
  // -----------------------------------------------------------------------
32
25
  // Action
33
26
  // -----------------------------------------------------------------------
34
- .action(async (options) => {
35
- const { ext, reader, debug } = options as {
36
- ext?: Array<ExtraExt>;
37
- reader?: string[];
38
- debug?: boolean;
39
- };
27
+ .action(
28
+ async (
29
+ options: Pick<
30
+ CliOptions,
31
+ "debug" | "ext" | "reader" | "format" | "output"
32
+ >,
33
+ ) => {
34
+ const { debug, format, output, ...readerOptions } = options;
40
35
 
41
- const { exts, customReaders } = normalizeReaderOptions({ ext, reader });
36
+ const { exts, customReaders } = normalizeReaderOptions(readerOptions);
42
37
 
43
- try {
44
- await validate({ exts, customReaders, debug });
45
- } catch (error) {
46
- console.error(error);
47
- process.exitCode = 1;
48
- }
49
- });
38
+ try {
39
+ await validate({ debug, format, output, exts, customReaders });
40
+ } catch (error) {
41
+ console.error(error instanceof Error ? error.message : error);
42
+ process.exitCode = 1;
43
+ }
44
+ },
45
+ );
50
46
  }
package/src/cli/index.ts CHANGED
@@ -1,26 +1,41 @@
1
1
  #!/usr/bin/env tsx
2
2
 
3
3
  import { cac } from "cac";
4
- import { registerCheckCommand } from "./commands/check";
5
- import { registerGenerateCommand } from "./commands/generate";
6
- import { registerValidateCommand } from "./commands/validate";
7
-
8
- const cli = cac("intor");
9
-
10
- // ---------------------------------------------------------------------
11
- // Register commands
12
- // ---------------------------------------------------------------------
13
- registerGenerateCommand(cli);
14
- registerCheckCommand(cli);
15
- registerValidateCommand(cli);
16
-
17
- // ---------------------------------------------------------------------
18
- // Global options / help
19
- // ---------------------------------------------------------------------
20
- cli.help();
21
- cli.version("0.1.10");
22
-
23
- // ---------------------------------------------------------------------
24
- // Parse argv
25
- // ---------------------------------------------------------------------
26
- cli.parse();
4
+ import {
5
+ registerDiscoverCommand,
6
+ registerGenerateCommand,
7
+ registerCheckCommand,
8
+ registerValidateCommand,
9
+ } from "./commands";
10
+ import { run } from "./menu";
11
+
12
+ const VERSION = "0.1.10";
13
+
14
+ async function main() {
15
+ // argv = [node, script, ...args]
16
+ const args = process.argv.slice(2);
17
+
18
+ // -------------------------------------------------------------------
19
+ // Interactive menu bypasses CAC entirely
20
+ // -------------------------------------------------------------------
21
+ if (args.length === 0) {
22
+ await run();
23
+ return;
24
+ }
25
+
26
+ // -------------------------------------------------------------------
27
+ // Command mode (original CAC behavior)
28
+ // -------------------------------------------------------------------
29
+ const cli = cac("intor");
30
+
31
+ registerDiscoverCommand(cli);
32
+ registerGenerateCommand(cli);
33
+ registerCheckCommand(cli);
34
+ registerValidateCommand(cli);
35
+
36
+ cli.help();
37
+ cli.version(VERSION);
38
+ cli.parse(process.argv);
39
+ }
40
+
41
+ await main();
@@ -0,0 +1 @@
1
+ export { run } from "./run";
@@ -0,0 +1,74 @@
1
+ import type { CheckOptions } from "../../../features";
2
+ import { text, isCancel, confirm } from "@clack/prompts";
3
+ import {
4
+ promptMode,
5
+ promptDebug,
6
+ printOptionsSummary,
7
+ promptFormat,
8
+ promptOutput,
9
+ } from "./shared/shared";
10
+
11
+ export async function promptCheck(): Promise<CheckOptions | null> {
12
+ // ------------------------------------------------------------------
13
+ // Mode
14
+ // ------------------------------------------------------------------
15
+ const mode = await promptMode();
16
+ if (!mode) return null;
17
+ if (mode === "default") return {};
18
+
19
+ const options: CheckOptions = {};
20
+
21
+ // ------------------------------------------------------------------
22
+ // tsconfig path
23
+ // ------------------------------------------------------------------
24
+ const useCustomTsconfig = await confirm({
25
+ message: "Do you want to use a custom tsconfig file?",
26
+ initialValue: false,
27
+ });
28
+ if (isCancel(useCustomTsconfig)) return null;
29
+
30
+ if (useCustomTsconfig) {
31
+ const path = await text({
32
+ message: "Path to tsconfig file",
33
+ placeholder: "tsconfig.json",
34
+ defaultValue: "tsconfig.json",
35
+ });
36
+ if (isCancel(path)) return null;
37
+ options.tsconfigPath = path || undefined;
38
+ }
39
+
40
+ // ------------------------------------------------------------------
41
+ // Output format
42
+ // ------------------------------------------------------------------
43
+ const format = await promptFormat();
44
+ if (!format) return null;
45
+ options.format = format;
46
+
47
+ // ------------------------------------------------------------------
48
+ // Output file (only for json)
49
+ // ------------------------------------------------------------------
50
+ if (format === "json") {
51
+ const output = await promptOutput();
52
+ if (output === null) return null;
53
+ options.output = output;
54
+ }
55
+
56
+ // ------------------------------------------------------------------
57
+ // Debug
58
+ // ------------------------------------------------------------------
59
+ const debug = await promptDebug();
60
+ if (debug === null) return null;
61
+ if (debug) options.debug = true;
62
+
63
+ // ------------------------------------------------------------------
64
+ // Summary
65
+ // ------------------------------------------------------------------
66
+ printOptionsSummary("Check options", [
67
+ ["tsconfig", options.tsconfigPath ?? "tsconfig.json"],
68
+ ["format", options.format ?? "human"],
69
+ ["output", options.output ?? "stdout"],
70
+ ["debug", options.debug ? "on" : "off"],
71
+ ]);
72
+
73
+ return options;
74
+ }
@@ -0,0 +1,25 @@
1
+ import { promptDebug, printOptionsSummary } from "./shared/shared";
2
+
3
+ export interface DiscoverOptions {
4
+ debug?: boolean;
5
+ }
6
+
7
+ export async function promptDiscover(): Promise<DiscoverOptions | null> {
8
+ const options: DiscoverOptions = {};
9
+
10
+ // ------------------------------------------------------------------
11
+ // Debug
12
+ // ------------------------------------------------------------------
13
+ const debug = await promptDebug();
14
+ if (debug === null) return null;
15
+ if (debug) options.debug = true;
16
+
17
+ // ------------------------------------------------------------------
18
+ // Summary
19
+ // ------------------------------------------------------------------
20
+ printOptionsSummary("Discover options", [
21
+ ["debug", options.debug ? "on" : "off"],
22
+ ]);
23
+
24
+ return options;
25
+ }