@i18n-micro/cli 0.0.0-stage → 2.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/LICENSE +21 -0
- package/README.md +29 -2
- package/bin/i18n-micro.mjs +3 -0
- package/dist/chunks/check-BaP_H-mS.mjs +175 -0
- package/dist/chunks/clean-Do9z6D5j.mjs +68 -0
- package/dist/chunks/clean-bQVjG_2M.mjs +1 -0
- package/dist/chunks/export-C2J-pagB.mjs +219 -0
- package/dist/chunks/export-usBaNIpp.mjs +1 -0
- package/dist/chunks/extract-CJ8UfrVJ.mjs +30 -0
- package/dist/chunks/format-6CtMgO-M.mjs +26 -0
- package/dist/chunks/http-whB7a5ye.mjs +100 -0
- package/dist/chunks/import-CnL8U6Za.mjs +99 -0
- package/dist/chunks/info-rYas4Yw3.mjs +32 -0
- package/dist/chunks/json-BV_apCMu.mjs +439 -0
- package/dist/chunks/lint-BaEIQGMl.mjs +125 -0
- package/dist/chunks/nuxt-dKxG087V.mjs +366 -0
- package/dist/chunks/package-f9OTcDxl.mjs +3 -0
- package/dist/chunks/project-DgWgr7pF.mjs +206 -0
- package/dist/chunks/protect-D1HIuxmJ.mjs +36 -0
- package/dist/chunks/pseudo-oXBaONgF.mjs +32 -0
- package/dist/chunks/rename-uJnBX86A.mjs +117 -0
- package/dist/chunks/runner-wHXdhRdA.mjs +200 -0
- package/dist/chunks/search-Dj_Ynq_x.mjs +67 -0
- package/dist/chunks/source-Bx2lHSW7.mjs +744 -0
- package/dist/chunks/spec-BwZlT28L.mjs +507 -0
- package/dist/chunks/stats-BU-SmrVR.mjs +156 -0
- package/dist/chunks/sync-BY2EFEda.mjs +1 -0
- package/dist/chunks/sync-C0NVDabK.mjs +56 -0
- package/dist/chunks/sync-remote-y3ZATbF2.mjs +148 -0
- package/dist/chunks/text-to-i18n-DweavFLm.mjs +404 -0
- package/dist/chunks/translate-CmnmgAHX.mjs +543 -0
- package/dist/cli.mjs +4 -0
- package/dist/index.mjs +3 -0
- package/dist/src/cli.d.ts +1 -0
- package/dist/src/commands/check.d.ts +28 -0
- package/dist/src/commands/clean.d.ts +26 -0
- package/dist/src/commands/export.d.ts +10 -0
- package/dist/src/commands/extract.d.ts +6 -0
- package/dist/src/commands/format.d.ts +8 -0
- package/dist/src/commands/import.d.ts +8 -0
- package/dist/src/commands/info.d.ts +5 -0
- package/dist/src/commands/lint.d.ts +16 -0
- package/dist/src/commands/pseudo.d.ts +9 -0
- package/dist/src/commands/rename.d.ts +9 -0
- package/dist/src/commands/search.d.ts +20 -0
- package/dist/src/commands/stats.d.ts +20 -0
- package/dist/src/commands/sync-remote.d.ts +30 -0
- package/dist/src/commands/sync.d.ts +20 -0
- package/dist/src/commands/text-to-i18n.d.ts +10 -0
- package/dist/src/commands/translate.d.ts +14 -0
- package/dist/src/csv.d.ts +3 -0
- package/dist/src/errors.d.ts +22 -0
- package/dist/src/fs.d.ts +45 -0
- package/dist/src/glossary.d.ts +12 -0
- package/dist/src/help.d.ts +3 -0
- package/dist/src/http.d.ts +10 -0
- package/dist/src/index.d.ts +3 -0
- package/dist/src/json.d.ts +34 -0
- package/dist/src/lint-rules.d.ts +9 -0
- package/dist/src/log.d.ts +88 -0
- package/dist/src/nuxt.d.ts +66 -0
- package/dist/src/po.d.ts +14 -0
- package/dist/src/project.d.ts +64 -0
- package/dist/src/runner.d.ts +6 -0
- package/dist/src/source.d.ts +109 -0
- package/dist/src/spec.d.ts +57 -0
- package/dist/src/text-to-i18n.d.ts +46 -0
- package/dist/src/translate/ai.d.ts +2 -0
- package/dist/src/translate/drivers.d.ts +26 -0
- package/dist/src/translate/engine.d.ts +33 -0
- package/dist/src/translate/protect.d.ts +11 -0
- package/package.json +71 -3
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The command table: one source of truth for parsing, `--help` and the generated
|
|
3
|
+
* [command reference](https://s00d.github.io/nuxt-i18n-micro/api/cli).
|
|
4
|
+
*
|
|
5
|
+
* This file imports nothing, and handlers load on demand, so `--help` stays instant and the
|
|
6
|
+
* docs generator can read the table without pulling in parsers or vendor drivers.
|
|
7
|
+
*/
|
|
8
|
+
export interface ArgSpec {
|
|
9
|
+
type: 'string' | 'boolean' | 'positional';
|
|
10
|
+
description: string;
|
|
11
|
+
default?: string | boolean;
|
|
12
|
+
required?: boolean;
|
|
13
|
+
alias?: string;
|
|
14
|
+
/** Accepted values: anything else is a usage error. */
|
|
15
|
+
values?: readonly string[];
|
|
16
|
+
/** Parsed to a number and checked to be positive. */
|
|
17
|
+
numeric?: 'int' | 'number';
|
|
18
|
+
/** Shown in the docs where a computed default has no literal value. */
|
|
19
|
+
defaultHint?: string;
|
|
20
|
+
}
|
|
21
|
+
export type CommandHandler = (args: never) => Promise<void>;
|
|
22
|
+
export interface CommandSpec {
|
|
23
|
+
description: string;
|
|
24
|
+
group: CommandGroup;
|
|
25
|
+
args: Record<string, ArgSpec>;
|
|
26
|
+
examples?: string[];
|
|
27
|
+
load: () => Promise<{
|
|
28
|
+
default: CommandHandler;
|
|
29
|
+
}>;
|
|
30
|
+
}
|
|
31
|
+
export declare const COMMAND_GROUPS: readonly ["Inspect", "Translation workflow", "Refactoring", "Exchange"];
|
|
32
|
+
export type CommandGroup = (typeof COMMAND_GROUPS)[number];
|
|
33
|
+
/** Translation services of `translate`. A test keeps this equal to the drivers. */
|
|
34
|
+
export declare const SERVICES: readonly ["ai", "azure", "deepl", "google", "libretranslate", "yandexcloud"];
|
|
35
|
+
/** What `check` looks for. `duplicates` is off by default: the same word under two keys is often fine. */
|
|
36
|
+
export declare const CHECK_TYPES: readonly ["missing", "empty", "extra", "placeholders", "undefined", "unused", "duplicates"];
|
|
37
|
+
export type CheckType = (typeof CHECK_TYPES)[number];
|
|
38
|
+
export declare const LINT_RULES: readonly [{
|
|
39
|
+
readonly name: "no-trailing-spaces";
|
|
40
|
+
readonly description: "Spaces at the end of a value or a line";
|
|
41
|
+
readonly fixable: true;
|
|
42
|
+
}, {
|
|
43
|
+
readonly name: "no-multiple-spaces";
|
|
44
|
+
readonly description: "Two or more spaces in a row";
|
|
45
|
+
readonly fixable: true;
|
|
46
|
+
}, {
|
|
47
|
+
readonly name: "no-empty-translation";
|
|
48
|
+
readonly description: "An empty or blank value";
|
|
49
|
+
readonly fixable: false;
|
|
50
|
+
}];
|
|
51
|
+
export type LintRuleName = (typeof LINT_RULES)[number]['name'];
|
|
52
|
+
export declare const EXIT_CODES: ReadonlyArray<readonly [code: number, meaning: string]>;
|
|
53
|
+
export declare const CONFIG_FILES: ReadonlyArray<readonly [file: string, purpose: string]>;
|
|
54
|
+
export declare const ENVIRONMENT: ReadonlyArray<readonly [name: string, purpose: string]>;
|
|
55
|
+
/** Commands that went away, and what to run instead. */
|
|
56
|
+
export declare const REMOVED_COMMANDS: Record<string, string>;
|
|
57
|
+
export declare const commands: Record<string, CommandSpec>;
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { JsonObject } from './json.js';
|
|
2
|
+
export declare function toSlug(text: string): string;
|
|
3
|
+
export interface NewTranslation {
|
|
4
|
+
key: string;
|
|
5
|
+
value: string;
|
|
6
|
+
file: string;
|
|
7
|
+
line: number;
|
|
8
|
+
}
|
|
9
|
+
export interface Hardcoded {
|
|
10
|
+
file: string;
|
|
11
|
+
line: number;
|
|
12
|
+
text: string;
|
|
13
|
+
}
|
|
14
|
+
export interface ConvertOptions {
|
|
15
|
+
context?: string;
|
|
16
|
+
keyOverrides?: Record<string, string>;
|
|
17
|
+
skippedKeys?: string[];
|
|
18
|
+
}
|
|
19
|
+
/** Shared across files: known text reuses its key, generated keys stay unique. */
|
|
20
|
+
export declare class KeyRegistry {
|
|
21
|
+
private readonly options;
|
|
22
|
+
readonly created: Map<string, NewTranslation>;
|
|
23
|
+
/** Text left alone because its key would overwrite a value of the translation file. */
|
|
24
|
+
readonly blocked: Hardcoded[];
|
|
25
|
+
private readonly byText;
|
|
26
|
+
private readonly used;
|
|
27
|
+
/** The file with this run's keys in it: `pages.user` and `pages.user.save` cannot both be text. */
|
|
28
|
+
private readonly planned;
|
|
29
|
+
constructor(existing: Record<string, string>, tree?: JsonObject, options?: ConvertOptions);
|
|
30
|
+
private generate;
|
|
31
|
+
private block;
|
|
32
|
+
/** Key for `text`, or `null` when it stays as it is. */
|
|
33
|
+
keyFor(text: string, file: string, line: number): string | null;
|
|
34
|
+
/** Take back keys of a conversion that was thrown away. */
|
|
35
|
+
forget(keep: ReadonlySet<string>): void;
|
|
36
|
+
}
|
|
37
|
+
export interface Conversion {
|
|
38
|
+
/** The new file content. */
|
|
39
|
+
content: string;
|
|
40
|
+
/** Text that is half a sentence: a key per fragment cannot be translated. */
|
|
41
|
+
mixed: Hardcoded[];
|
|
42
|
+
/** Text in code. `$t` is not in scope everywhere, so it is reported and never rewritten. */
|
|
43
|
+
code: Hardcoded[];
|
|
44
|
+
}
|
|
45
|
+
/** One source file: `.vue` templates are rewritten, anything else is only read. */
|
|
46
|
+
export declare function convertSource(content: string, file: string, keys: KeyRegistry): Conversion;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { RequestOptions } from '../http.js';
|
|
2
|
+
export type DriverOptions = Record<string, string>;
|
|
3
|
+
export interface BatchRequest {
|
|
4
|
+
texts: string[];
|
|
5
|
+
from: string;
|
|
6
|
+
to: string;
|
|
7
|
+
token: string;
|
|
8
|
+
options: DriverOptions;
|
|
9
|
+
http: Pick<RequestOptions, 'retries' | 'retryDelayMs' | 'timeoutMs'>;
|
|
10
|
+
}
|
|
11
|
+
export interface Driver {
|
|
12
|
+
label: string;
|
|
13
|
+
/** Most strings one request may carry. */
|
|
14
|
+
maxBatch: number;
|
|
15
|
+
/** Most characters one request may carry. */
|
|
16
|
+
maxChars?: number;
|
|
17
|
+
/** Works without a key (free tier or a self-hosted server). */
|
|
18
|
+
keyOptional?: boolean;
|
|
19
|
+
/** Language codes as the service spells them. */
|
|
20
|
+
sourceLang?: (code: string) => string;
|
|
21
|
+
targetLang?: (code: string) => string;
|
|
22
|
+
translate(request: BatchRequest): Promise<string[]>;
|
|
23
|
+
}
|
|
24
|
+
export declare const drivers: Record<string, Driver>;
|
|
25
|
+
/** Services the old `nuxt-i18n-micro-cli` had: each name fails with the reason it is gone. */
|
|
26
|
+
export declare const removedServices: Record<string, string>;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { Driver, DriverOptions } from './drivers.js';
|
|
2
|
+
export interface TranslateItem {
|
|
3
|
+
key: string;
|
|
4
|
+
text: string;
|
|
5
|
+
}
|
|
6
|
+
export interface TranslationResult {
|
|
7
|
+
key: string;
|
|
8
|
+
value: string;
|
|
9
|
+
}
|
|
10
|
+
export interface EngineOptions {
|
|
11
|
+
service: string;
|
|
12
|
+
token: string;
|
|
13
|
+
options: DriverOptions;
|
|
14
|
+
chunkSize?: number;
|
|
15
|
+
pluralSeparator: string;
|
|
16
|
+
}
|
|
17
|
+
export declare function resolveDriver(service: string): Driver;
|
|
18
|
+
/** Parses `key:value,key:value`. Only the first colon splits: values are often URLs. */
|
|
19
|
+
export declare function parseOptions(text: string | undefined): DriverOptions;
|
|
20
|
+
/** Batches within what the service accepts, by count and by characters. */
|
|
21
|
+
export declare function buildBatches<T>(items: T[], size: (item: T) => number, maxCount: number, maxChars?: number): T[][];
|
|
22
|
+
export interface EngineResult {
|
|
23
|
+
translated: TranslationResult[];
|
|
24
|
+
/** Keys with no usable answer, a placeholder lost or no text: left untranslated rather than broken. */
|
|
25
|
+
rejected: string[];
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Translate one list of messages, plural forms and placeholders handled, into `to`.
|
|
29
|
+
*
|
|
30
|
+
* `onBatch` hears about every item as soon as its last form is back, so what was paid for can
|
|
31
|
+
* be saved before the next request. A failed request throws, and costs only what it carried.
|
|
32
|
+
*/
|
|
33
|
+
export declare function translateItems(items: TranslateItem[], from: string, to: string, config: EngineOptions, extra?: DriverOptions, onBatch?: (result: EngineResult) => void): Promise<EngineResult>;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export interface Protected {
|
|
2
|
+
masked: string;
|
|
3
|
+
tokens: string[];
|
|
4
|
+
}
|
|
5
|
+
/** Replaces placeholders with XML tags, the one thing every service with markup support leaves alone. */
|
|
6
|
+
export declare function protect(text: string): Protected;
|
|
7
|
+
export declare function restore(masked: string, tokens: string[]): string;
|
|
8
|
+
/** A placeholder lost, repeated, added or still masked after translation: such a value must not reach a locale file. */
|
|
9
|
+
export declare const isIntact: (translated: string, tokens: string[]) => boolean;
|
|
10
|
+
/** Services in HTML mode return `'` for an apostrophe. */
|
|
11
|
+
export declare const decodeEntities: (text: string) => string;
|
package/package.json
CHANGED
|
@@ -1,6 +1,74 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@i18n-micro/cli",
|
|
3
|
-
"version": "
|
|
4
|
-
"
|
|
5
|
-
"
|
|
3
|
+
"version": "2.0.0",
|
|
4
|
+
"description": "Command-line tools for nuxt-i18n-micro: extract, sync, translate, lint and audit locale files.",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"cli",
|
|
7
|
+
"i18n",
|
|
8
|
+
"localization",
|
|
9
|
+
"nuxt",
|
|
10
|
+
"translation"
|
|
11
|
+
],
|
|
12
|
+
"homepage": "https://github.com/s00d/nuxt-i18n-micro/tree/main/packages/cli#readme",
|
|
13
|
+
"bugs": {
|
|
14
|
+
"url": "https://github.com/s00d/nuxt-i18n-micro/issues"
|
|
15
|
+
},
|
|
16
|
+
"license": "MIT",
|
|
17
|
+
"author": {
|
|
18
|
+
"name": "s00d",
|
|
19
|
+
"email": "Virus191288@gmail.com",
|
|
20
|
+
"url": "https://s00d.github.io/"
|
|
21
|
+
},
|
|
22
|
+
"repository": {
|
|
23
|
+
"type": "git",
|
|
24
|
+
"url": "git+https://github.com/s00d/nuxt-i18n-micro.git",
|
|
25
|
+
"directory": "packages/cli"
|
|
26
|
+
},
|
|
27
|
+
"bin": {
|
|
28
|
+
"i18n-micro": "./bin/i18n-micro.mjs",
|
|
29
|
+
"i18n-micro-cli": "./bin/i18n-micro.mjs"
|
|
30
|
+
},
|
|
31
|
+
"files": [
|
|
32
|
+
"bin",
|
|
33
|
+
"dist",
|
|
34
|
+
"README.md",
|
|
35
|
+
"LICENSE"
|
|
36
|
+
],
|
|
37
|
+
"type": "module",
|
|
38
|
+
"sideEffects": false,
|
|
39
|
+
"types": "./dist/src/index.d.ts",
|
|
40
|
+
"exports": {
|
|
41
|
+
".": {
|
|
42
|
+
"types": "./dist/src/index.d.ts",
|
|
43
|
+
"default": "./dist/index.mjs"
|
|
44
|
+
},
|
|
45
|
+
"./package.json": "./package.json"
|
|
46
|
+
},
|
|
47
|
+
"publishConfig": {
|
|
48
|
+
"access": "public"
|
|
49
|
+
},
|
|
50
|
+
"dependencies": {
|
|
51
|
+
"@vue/compiler-sfc": "^3.5.44",
|
|
52
|
+
"citty": "^0.2.2",
|
|
53
|
+
"@i18n-micro/utils": "^2.0.0"
|
|
54
|
+
},
|
|
55
|
+
"devDependencies": {
|
|
56
|
+
"@nuxt/kit": "^3.18.0 || ^4.0.0",
|
|
57
|
+
"@types/node": "^22.19.0",
|
|
58
|
+
"nuxt": "^4.6.4",
|
|
59
|
+
"publint": "^0.3.25",
|
|
60
|
+
"typescript": "6.0.3",
|
|
61
|
+
"vite": "^8.3.5",
|
|
62
|
+
"vite-plugin-dts": "^5.1.2",
|
|
63
|
+
"vitest": "^5.1.0"
|
|
64
|
+
},
|
|
65
|
+
"engines": {
|
|
66
|
+
"node": ">=20"
|
|
67
|
+
},
|
|
68
|
+
"scripts": {
|
|
69
|
+
"build": "vite build",
|
|
70
|
+
"check:package": "publint",
|
|
71
|
+
"test": "vitest run",
|
|
72
|
+
"typecheck": "tsc --noEmit"
|
|
73
|
+
}
|
|
6
74
|
}
|