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.
- package/package.json +2 -3
- package/src/cli/commands/check.ts +23 -17
- package/src/cli/commands/discover.ts +32 -0
- package/src/cli/commands/generate.ts +35 -40
- package/src/cli/commands/index.ts +4 -0
- package/src/cli/commands/options/index.ts +1 -0
- package/src/cli/commands/options/options.ts +55 -0
- package/src/cli/commands/utils/normalize-message-files.ts +49 -0
- package/src/cli/commands/utils/normalize-reader-options.ts +15 -28
- package/src/cli/commands/validate.ts +26 -30
- package/src/cli/index.ts +38 -23
- package/src/cli/menu/index.ts +1 -0
- package/src/cli/menu/prompts/prompt-check.ts +74 -0
- package/src/cli/menu/prompts/prompt-discover.ts +25 -0
- package/src/cli/menu/prompts/prompt-generate.ts +106 -0
- package/src/cli/menu/prompts/prompt-validate.ts +49 -0
- package/src/cli/menu/prompts/shared/prompt-reader-options.ts +63 -0
- package/src/cli/menu/prompts/shared/shared.ts +76 -0
- package/src/cli/menu/run.ts +72 -0
- package/src/cli/version.ts +3 -0
- package/src/constants.ts +6 -0
- package/src/core/artifacts/index.ts +5 -0
- package/src/core/artifacts/schema/build-schema.ts +13 -0
- package/src/core/artifacts/schema/index.ts +3 -0
- package/src/core/{generated → artifacts/schema}/read-schema.ts +4 -4
- package/src/core/artifacts/schema/write-schema.ts +14 -0
- package/src/{build/build-types → core/artifacts/types/build}/build-types.ts +9 -10
- package/src/{build/build-types → core/artifacts/types/build}/utils/normalize-rich-infer-node.ts +1 -1
- package/src/{build/build-types → core/artifacts/types/build}/utils/render-infer-node.ts +1 -1
- package/src/core/artifacts/types/index.ts +2 -0
- package/src/core/artifacts/types/write-types.ts +8 -0
- package/src/core/artifacts/types.ts +20 -0
- package/src/core/collect-messages/collect-other-locale-messages.ts +5 -7
- package/src/core/collect-messages/collect-runtime-messages.ts +8 -6
- package/src/core/collect-messages/index.ts +1 -0
- package/src/core/collect-messages/readers.ts +1 -0
- package/src/core/collect-messages/types.ts +7 -1
- package/src/core/constants/index.ts +2 -0
- package/src/core/discover-configs/discover-configs.ts +47 -26
- package/src/core/extract-usages/extract-usages.ts +33 -24
- package/src/core/index.ts +12 -7
- package/src/core/infer-shape/index.ts +4 -0
- package/src/core/{infer-schema/messages/infer-messages-schema.ts → infer-shape/infer-messages-shape.ts} +5 -10
- package/src/core/{infer-schema/replacements/infer-replacements-schema.ts → infer-shape/infer-replacements-shape.ts} +6 -11
- package/src/core/{infer-schema/rich/infer-rich-schema.ts → infer-shape/infer-rich-shape.ts} +5 -10
- package/src/core/infer-shape/infer-shapes.ts +21 -0
- package/src/core/{infer-schema → infer-shape}/types.ts +4 -4
- package/src/core/scan/index.ts +2 -0
- package/src/core/{extract-usages/load-source-files-from-tscofnig.ts → scan/load-source-files.ts} +34 -15
- package/src/core/scan/scan-files.ts +25 -0
- package/src/features/check/build-scoped-usages.ts +35 -0
- package/src/features/check/check.ts +51 -53
- package/src/features/check/diagnostics/collect.ts +6 -2
- package/src/features/check/diagnostics/group.ts +0 -1
- package/src/features/check/index.ts +1 -0
- package/src/features/check/render-config-summary.ts +47 -0
- package/src/features/check/types.ts +12 -0
- package/src/features/discover/discover.ts +22 -0
- package/src/features/discover/index.ts +1 -0
- package/src/features/generate/generate.ts +56 -49
- package/src/features/generate/index.ts +1 -0
- package/src/features/generate/render-overrides.ts +73 -0
- package/src/features/generate/render-summary.ts +28 -0
- package/src/features/generate/types.ts +12 -0
- package/src/features/generate/utils/resolve-message-source.ts +20 -0
- package/src/features/generate/utils/validate-message-source.ts +53 -0
- package/src/features/index.ts +4 -3
- package/src/features/shared/to-relative-path.ts +10 -0
- package/src/features/shared/write-json-report.ts +19 -0
- package/src/features/validate/index.ts +1 -0
- package/src/features/validate/{messages/validate-messages-schema.ts → missing/collect-missing-messages.ts} +5 -5
- package/src/features/validate/{replacements/validate-replacements-schema.ts → missing/collect-missing-replacements.ts} +4 -4
- package/src/features/validate/missing/collect-missing-requirements.ts +44 -0
- package/src/features/validate/{rich/validate-rich-schema.ts → missing/collect-missing-rich.ts} +5 -5
- package/src/features/validate/render-config-summary.ts +47 -0
- package/src/features/validate/render-locale-blocks.ts +56 -0
- package/src/features/validate/types.ts +14 -0
- package/src/features/validate/validate.ts +38 -43
- package/src/logger.ts +95 -0
- package/src/render.ts +57 -0
- package/src/build/build-schemas/build-schemas.ts +0 -13
- package/src/build/build-schemas/index.ts +0 -1
- package/src/build/index.ts +0 -3
- package/src/build/types.ts +0 -20
- package/src/core/generated/index.ts +0 -6
- package/src/core/generated/write-messages-snapshot.ts +0 -27
- package/src/core/generated/write-schema.ts +0 -9
- package/src/core/generated/write-types.ts +0 -8
- package/src/core/infer-schema/index.ts +0 -4
- package/src/core/infer-schema/infer-schemas.ts +0 -20
- package/src/core/infer-schema/messages/index.ts +0 -1
- package/src/core/infer-schema/replacements/index.ts +0 -1
- package/src/core/infer-schema/rich/index.ts +0 -1
- package/src/core/scan-logger.ts +0 -10
- package/src/features/check/print-summary.ts +0 -28
- package/src/features/generate/print-configs.ts +0 -8
- package/src/features/generate/print-overrides.ts +0 -62
- package/src/features/generate/print-summary.ts +0 -26
- package/src/features/print.ts +0 -43
- package/src/features/validate/messages/index.ts +0 -1
- package/src/features/validate/print-summary.ts +0 -65
- package/src/features/validate/replacements/index.ts +0 -1
- package/src/features/validate/rich/index.ts +0 -1
- package/src/features/validate/validate-locale-messages.ts +0 -38
- /package/src/core/{generated → artifacts}/ensure-and-write.ts +0 -0
- /package/src/{build/build-types → core/artifacts/types/build}/index.ts +0 -0
- /package/src/{build/build-types → core/artifacts/types/build}/output/append-config-block.ts +0 -0
- /package/src/{build/build-types → core/artifacts/types/build}/output/append-footer.ts +0 -0
- /package/src/{build/build-types → core/artifacts/types/build}/output/append-header.ts +0 -0
- /package/src/{build/build-types → core/artifacts/types/build}/output/index.ts +0 -0
- /package/src/{build/build-types → core/artifacts/types/build}/utils/indent.ts +0 -0
- /package/src/core/{infer-schema/replacements → infer-shape/utils}/extract-interpolation-names.ts +0 -0
- /package/src/core/{infer-schema → infer-shape}/utils/infer-object.ts +0 -0
- /package/src/core/{infer-schema → infer-shape}/utils/is-message-object.ts +0 -0
- /package/src/core/{infer-schema → infer-shape}/utils/should-skip-key.ts +0 -0
- /package/src/core/{infer-schema → infer-shape}/utils/strip-internal-keys.ts +0 -0
- /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.
|
|
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 {
|
|
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(
|
|
12
|
+
.command(features.check.name, features.check.title)
|
|
11
13
|
|
|
12
14
|
// -----------------------------------------------------------------------
|
|
13
|
-
//
|
|
15
|
+
// Options
|
|
14
16
|
// -----------------------------------------------------------------------
|
|
15
|
-
.option(
|
|
16
|
-
|
|
17
|
-
|
|
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(
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
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 {
|
|
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(
|
|
15
|
+
.command(features.generate.name, features.generate.title)
|
|
12
16
|
|
|
13
17
|
// -----------------------------------------------------------------------
|
|
14
18
|
// Option
|
|
15
19
|
// -----------------------------------------------------------------------
|
|
16
|
-
.option(
|
|
17
|
-
|
|
18
|
-
|
|
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(
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
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
|
-
|
|
38
|
+
const result = normalizeMessageFiles(messageFile, messageFiles);
|
|
39
|
+
const { exts, customReaders } = normalizeReaderOptions(readerOptions);
|
|
47
40
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
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 @@
|
|
|
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
|
-
|
|
20
|
-
|
|
21
|
-
|
|
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 (
|
|
14
|
+
if (reader && reader.length > 0) {
|
|
32
15
|
customReaders = {};
|
|
33
16
|
|
|
34
|
-
for (const item of
|
|
17
|
+
for (const item of reader) {
|
|
35
18
|
const [key, value] = item.split("=", 2);
|
|
36
|
-
if (!key || !value)
|
|
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:
|
|
30
|
+
exts: ext as ExtraExt[],
|
|
44
31
|
customReaders,
|
|
45
32
|
};
|
|
46
33
|
}
|
|
@@ -1,6 +1,8 @@
|
|
|
1
|
-
import type {
|
|
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(
|
|
13
|
+
.command(features.validate.name, features.validate.title)
|
|
12
14
|
|
|
13
15
|
// -----------------------------------------------------------------------
|
|
14
16
|
// Option
|
|
15
17
|
// -----------------------------------------------------------------------
|
|
16
|
-
.option(
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
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(
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
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
|
-
|
|
36
|
+
const { exts, customReaders } = normalizeReaderOptions(readerOptions);
|
|
42
37
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
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 {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
//
|
|
19
|
-
//
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
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
|
+
}
|