@localheroai/cli 0.0.3 → 0.0.6
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/README +1 -1
- package/dist/api/auth.d.ts +2 -0
- package/dist/api/auth.js +28 -0
- package/dist/api/auth.js.map +1 -0
- package/dist/api/client.d.ts +3 -0
- package/dist/api/client.js +80 -0
- package/dist/api/client.js.map +1 -0
- package/dist/api/imports.d.ts +5 -0
- package/dist/api/imports.js +43 -0
- package/dist/api/imports.js.map +1 -0
- package/dist/api/projects.d.ts +2 -0
- package/dist/api/projects.js +42 -0
- package/dist/api/projects.js.map +1 -0
- package/dist/api/translations.d.ts +15 -0
- package/dist/api/translations.js +71 -0
- package/dist/api/translations.js.map +1 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +79 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands/_sync.js +22 -0
- package/dist/commands/_sync.js.map +1 -0
- package/dist/commands/_translate.js +3 -0
- package/dist/commands/_translate.js.map +1 -0
- package/dist/commands/init.d.ts +1 -0
- package/dist/commands/init.js +439 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/login.d.ts +16 -0
- package/dist/commands/login.js +58 -0
- package/dist/commands/login.js.map +1 -0
- package/dist/commands/pull.js +22 -0
- package/dist/commands/pull.js.map +1 -0
- package/dist/commands/push.js +56 -0
- package/dist/commands/push.js.map +1 -0
- package/dist/commands/sync.d.ts +20 -0
- package/dist/commands/sync.js +22 -0
- package/dist/commands/sync.js.map +1 -0
- package/dist/commands/translate.d.ts +14 -0
- package/dist/commands/translate.js +145 -0
- package/dist/commands/translate.js.map +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.js +8 -0
- package/dist/index.js.map +1 -0
- package/dist/types/index.d.ts +75 -0
- package/dist/types/index.js +17 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/translate/index.js +2 -0
- package/dist/types/translate/index.js.map +1 -0
- package/dist/utils/auth.d.ts +2 -0
- package/dist/utils/auth.js +29 -0
- package/dist/utils/auth.js.map +1 -0
- package/dist/utils/common.js +9 -0
- package/dist/utils/common.js.map +1 -0
- package/dist/utils/config.d.ts +23 -0
- package/dist/utils/config.js +137 -0
- package/dist/utils/config.js.map +1 -0
- package/dist/utils/errors.js +37 -0
- package/dist/utils/errors.js.map +1 -0
- package/dist/utils/files.d.ts +32 -0
- package/dist/utils/files.js +347 -0
- package/dist/utils/files.js.map +1 -0
- package/dist/utils/git.d.ts +21 -0
- package/dist/utils/git.js +87 -0
- package/dist/utils/git.js.map +1 -0
- package/dist/utils/github.d.ts +241 -0
- package/dist/utils/github.js +161 -0
- package/dist/utils/github.js.map +1 -0
- package/dist/utils/import-service.d.ts +4 -0
- package/dist/utils/import-service.js +218 -0
- package/dist/utils/import-service.js.map +1 -0
- package/dist/utils/prompt-service.d.ts +44 -0
- package/dist/utils/prompt-service.js +104 -0
- package/dist/utils/prompt-service.js.map +1 -0
- package/dist/utils/sync-service.d.ts +58 -0
- package/dist/utils/sync-service.js +159 -0
- package/dist/utils/sync-service.js.map +1 -0
- package/dist/utils/translation-processor.js +197 -0
- package/dist/utils/translation-processor.js.map +1 -0
- package/dist/utils/translation-updater/common.d.ts +6 -0
- package/{src → dist}/utils/translation-updater/common.js +16 -10
- package/dist/utils/translation-updater/common.js.map +1 -0
- package/dist/utils/translation-updater/index.d.ts +5 -0
- package/{src → dist}/utils/translation-updater/index.js +21 -9
- package/dist/utils/translation-updater/index.js.map +1 -0
- package/dist/utils/translation-updater/json-handler.d.ts +5 -0
- package/{src → dist}/utils/translation-updater/json-handler.js +42 -31
- package/dist/utils/translation-updater/json-handler.js.map +1 -0
- package/dist/utils/translation-updater/yaml-handler.d.ts +5 -0
- package/{src → dist}/utils/translation-updater/yaml-handler.js +40 -41
- package/dist/utils/translation-updater/yaml-handler.js.map +1 -0
- package/dist/utils/translation-utils.d.ts +30 -0
- package/dist/utils/translation-utils.js +324 -0
- package/dist/utils/translation-utils.js.map +1 -0
- package/dist/utils/updater.js +38 -0
- package/dist/utils/updater.js.map +1 -0
- package/package.json +33 -28
- package/src/api/auth.js +0 -24
- package/src/api/client.js +0 -83
- package/src/api/imports.js +0 -22
- package/src/api/projects.js +0 -24
- package/src/api/translations.js +0 -58
- package/src/cli.js +0 -78
- package/src/commands/init.js +0 -485
- package/src/commands/login.js +0 -80
- package/src/commands/sync.js +0 -28
- package/src/commands/translate.js +0 -262
- package/src/utils/auth.js +0 -23
- package/src/utils/config.js +0 -125
- package/src/utils/files.js +0 -361
- package/src/utils/git.js +0 -72
- package/src/utils/github.js +0 -122
- package/src/utils/import-service.js +0 -129
- package/src/utils/prompt-service.js +0 -67
- package/src/utils/sync-service.js +0 -147
- package/src/utils/translation-utils.js +0 -237
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
interface ProjectService {
|
|
2
|
+
listProjects: () => Promise<Array<{
|
|
3
|
+
id: string;
|
|
4
|
+
name: string;
|
|
5
|
+
}>>;
|
|
6
|
+
}
|
|
7
|
+
interface ProjectSetup {
|
|
8
|
+
projectName: string;
|
|
9
|
+
sourceLocale: string;
|
|
10
|
+
outputLocales: string[];
|
|
11
|
+
translationPath: string;
|
|
12
|
+
ignorePaths: string[];
|
|
13
|
+
}
|
|
14
|
+
interface ProjectSelection {
|
|
15
|
+
choice: string;
|
|
16
|
+
project?: {
|
|
17
|
+
id: string;
|
|
18
|
+
name: string;
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
export declare function createPromptService(deps?: {
|
|
22
|
+
inquirer?: any;
|
|
23
|
+
}): {
|
|
24
|
+
getApiKey: () => Promise<string>;
|
|
25
|
+
getProjectSetup: () => Promise<ProjectSetup>;
|
|
26
|
+
select: <T>(options: {
|
|
27
|
+
message: string;
|
|
28
|
+
choices: Array<{
|
|
29
|
+
name: string;
|
|
30
|
+
value: T;
|
|
31
|
+
disabled?: boolean;
|
|
32
|
+
}>;
|
|
33
|
+
}) => Promise<T>;
|
|
34
|
+
input: (options: {
|
|
35
|
+
message: string;
|
|
36
|
+
default?: string;
|
|
37
|
+
}) => Promise<string>;
|
|
38
|
+
confirm: (options: {
|
|
39
|
+
message: string;
|
|
40
|
+
default?: boolean;
|
|
41
|
+
}) => Promise<boolean>;
|
|
42
|
+
selectProject: (projectService: ProjectService) => Promise<ProjectSelection>;
|
|
43
|
+
};
|
|
44
|
+
export {};
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Prompt service for handling CLI interactions with the user
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Creates a prompt service for handling CLI interactions
|
|
6
|
+
* @param deps Dependencies for the prompt service
|
|
7
|
+
* @returns The prompt service object
|
|
8
|
+
*/
|
|
9
|
+
export function createPromptService(deps = {}) {
|
|
10
|
+
const { inquirer = null } = deps;
|
|
11
|
+
return {
|
|
12
|
+
/**
|
|
13
|
+
* Prompts the user for an API key
|
|
14
|
+
* @returns The API key entered by the user
|
|
15
|
+
*/
|
|
16
|
+
async getApiKey() {
|
|
17
|
+
if (!inquirer)
|
|
18
|
+
return '';
|
|
19
|
+
return inquirer.password({
|
|
20
|
+
message: 'API Key:',
|
|
21
|
+
mask: '*'
|
|
22
|
+
});
|
|
23
|
+
},
|
|
24
|
+
/**
|
|
25
|
+
* Gets project setup information - defaults to empty values when inquirer is not available
|
|
26
|
+
* @returns Project setup information
|
|
27
|
+
*/
|
|
28
|
+
async getProjectSetup() {
|
|
29
|
+
if (!inquirer)
|
|
30
|
+
return {
|
|
31
|
+
projectName: '',
|
|
32
|
+
sourceLocale: '',
|
|
33
|
+
outputLocales: [],
|
|
34
|
+
translationPath: '',
|
|
35
|
+
ignorePaths: []
|
|
36
|
+
};
|
|
37
|
+
return {
|
|
38
|
+
projectName: '',
|
|
39
|
+
sourceLocale: '',
|
|
40
|
+
outputLocales: [],
|
|
41
|
+
translationPath: '',
|
|
42
|
+
ignorePaths: []
|
|
43
|
+
};
|
|
44
|
+
},
|
|
45
|
+
/**
|
|
46
|
+
* Prompts the user with a selection
|
|
47
|
+
* @param options Selection options
|
|
48
|
+
* @returns The selected value
|
|
49
|
+
*/
|
|
50
|
+
async select(options) {
|
|
51
|
+
if (!inquirer)
|
|
52
|
+
return 'new';
|
|
53
|
+
return inquirer.select(options);
|
|
54
|
+
},
|
|
55
|
+
/**
|
|
56
|
+
* Prompts the user for text input
|
|
57
|
+
* @param options Input options
|
|
58
|
+
* @returns The entered text
|
|
59
|
+
*/
|
|
60
|
+
async input(options) {
|
|
61
|
+
if (!inquirer)
|
|
62
|
+
return '';
|
|
63
|
+
return inquirer.input(options);
|
|
64
|
+
},
|
|
65
|
+
/**
|
|
66
|
+
* Prompts the user for confirmation
|
|
67
|
+
* @param options Confirmation options
|
|
68
|
+
* @returns True if confirmed, false otherwise
|
|
69
|
+
*/
|
|
70
|
+
async confirm(options) {
|
|
71
|
+
if (!inquirer)
|
|
72
|
+
return false;
|
|
73
|
+
return inquirer.confirm(options);
|
|
74
|
+
},
|
|
75
|
+
/**
|
|
76
|
+
* Prompts the user to select a project or create a new one
|
|
77
|
+
* @param projectService Service providing project operations
|
|
78
|
+
* @returns The selection result with the chosen project
|
|
79
|
+
*/
|
|
80
|
+
async selectProject(projectService) {
|
|
81
|
+
const projects = await projectService.listProjects();
|
|
82
|
+
if (!projects || projects.length === 0) {
|
|
83
|
+
return { choice: 'new' };
|
|
84
|
+
}
|
|
85
|
+
const choices = [
|
|
86
|
+
{ name: '✨ Create new project', value: 'new' },
|
|
87
|
+
{ name: '─────────────', value: 'separator', disabled: true },
|
|
88
|
+
...projects.map(p => ({
|
|
89
|
+
name: p.name,
|
|
90
|
+
value: p.id
|
|
91
|
+
}))
|
|
92
|
+
];
|
|
93
|
+
const projectChoice = await this.select({
|
|
94
|
+
message: 'Would you like to use an existing project or create a new one?',
|
|
95
|
+
choices
|
|
96
|
+
});
|
|
97
|
+
return {
|
|
98
|
+
choice: projectChoice,
|
|
99
|
+
project: projects.find(p => p.id === projectChoice)
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
//# sourceMappingURL=prompt-service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prompt-service.js","sourceRoot":"","sources":["../../src/utils/prompt-service.ts"],"names":[],"mappings":"AAAA;;GAEG;AA0EH;;;;GAIG;AACH,MAAM,UAAU,mBAAmB,CAAC,OAAkC,EAAE;IACtE,MAAM,EAAE,QAAQ,GAAG,IAAI,EAAE,GAAG,IAAI,CAAC;IAEjC,OAAO;QACL;;;WAGG;QACH,KAAK,CAAC,SAAS;YACb,IAAI,CAAC,QAAQ;gBAAE,OAAO,EAAE,CAAC;YACzB,OAAO,QAAQ,CAAC,QAAQ,CAAC;gBACvB,OAAO,EAAE,UAAU;gBACnB,IAAI,EAAE,GAAG;aACV,CAAC,CAAC;QACL,CAAC;QAED;;;WAGG;QACH,KAAK,CAAC,eAAe;YACnB,IAAI,CAAC,QAAQ;gBAAE,OAAO;oBACpB,WAAW,EAAE,EAAE;oBACf,YAAY,EAAE,EAAE;oBAChB,aAAa,EAAE,EAAE;oBACjB,eAAe,EAAE,EAAE;oBACnB,WAAW,EAAE,EAAE;iBAChB,CAAC;YAEF,OAAO;gBACL,WAAW,EAAE,EAAE;gBACf,YAAY,EAAE,EAAE;gBAChB,aAAa,EAAE,EAAE;gBACjB,eAAe,EAAE,EAAE;gBACnB,WAAW,EAAE,EAAE;aAChB,CAAC;QACJ,CAAC;QAED;;;;WAIG;QACH,KAAK,CAAC,MAAM,CAAC,OAAsB;YACjC,IAAI,CAAC,QAAQ;gBAAE,OAAO,KAAK,CAAC;YAC5B,OAAO,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QAClC,CAAC;QAED;;;;WAIG;QACH,KAAK,CAAC,KAAK,CAAC,OAAqB;YAC/B,IAAI,CAAC,QAAQ;gBAAE,OAAO,EAAE,CAAC;YACzB,OAAO,QAAQ,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QACjC,CAAC;QAED;;;;WAIG;QACH,KAAK,CAAC,OAAO,CAAC,OAAuB;YACnC,IAAI,CAAC,QAAQ;gBAAE,OAAO,KAAK,CAAC;YAC5B,OAAO,QAAQ,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QACnC,CAAC;QAED;;;;WAIG;QACH,KAAK,CAAC,aAAa,CAAC,cAAoF;YACtG,MAAM,QAAQ,GAAG,MAAM,cAAc,CAAC,YAAY,EAAE,CAAC;YAErD,IAAI,CAAC,QAAQ,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBACvC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC;YAC3B,CAAC;YAED,MAAM,OAAO,GAAG;gBACd,EAAE,IAAI,EAAE,sBAAsB,EAAE,KAAK,EAAE,KAAK,EAAE;gBAC9C,EAAE,IAAI,EAAE,eAAe,EAAE,KAAK,EAAE,WAAW,EAAE,QAAQ,EAAE,IAAI,EAAE;gBAC7D,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;oBACpB,IAAI,EAAE,CAAC,CAAC,IAAI;oBACZ,KAAK,EAAE,CAAC,CAAC,EAAE;iBACZ,CAAC,CAAC;aACJ,CAAC;YAEF,MAAM,aAAa,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC;gBACtC,OAAO,EAAE,gEAAgE;gBACzE,OAAO;aACR,CAAC,CAAC;YAEH,OAAO;gBACL,MAAM,EAAE,aAAa;gBACrB,OAAO,EAAE,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,aAAa,CAAC;aACpD,CAAC;QACJ,CAAC;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
export interface SyncOptions {
|
|
2
|
+
verbose?: boolean;
|
|
3
|
+
}
|
|
4
|
+
export interface Translation {
|
|
5
|
+
key: string;
|
|
6
|
+
value: string;
|
|
7
|
+
}
|
|
8
|
+
export interface Language {
|
|
9
|
+
code: string;
|
|
10
|
+
translations: Translation[];
|
|
11
|
+
}
|
|
12
|
+
export interface FileUpdate {
|
|
13
|
+
path: string;
|
|
14
|
+
languages: Language[];
|
|
15
|
+
}
|
|
16
|
+
export interface DeletedKey {
|
|
17
|
+
name: string;
|
|
18
|
+
}
|
|
19
|
+
export interface PaginationInfo {
|
|
20
|
+
current_page: number;
|
|
21
|
+
total_pages: number;
|
|
22
|
+
}
|
|
23
|
+
export interface UpdateResponse {
|
|
24
|
+
updates?: {
|
|
25
|
+
updated_keys?: FileUpdate[];
|
|
26
|
+
deleted_keys?: DeletedKey[];
|
|
27
|
+
};
|
|
28
|
+
pagination?: PaginationInfo;
|
|
29
|
+
}
|
|
30
|
+
export interface UpdatesContainer {
|
|
31
|
+
updates: {
|
|
32
|
+
files: FileUpdate[];
|
|
33
|
+
deleted_keys: DeletedKey[];
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
export interface CheckUpdatesResult {
|
|
37
|
+
hasUpdates: boolean;
|
|
38
|
+
updates?: UpdatesContainer;
|
|
39
|
+
}
|
|
40
|
+
export interface TranslationFile {
|
|
41
|
+
path: string;
|
|
42
|
+
locale: string;
|
|
43
|
+
}
|
|
44
|
+
export interface SourceFile {
|
|
45
|
+
path: string;
|
|
46
|
+
}
|
|
47
|
+
export interface FindTranslationFilesResult {
|
|
48
|
+
sourceFiles: SourceFile[];
|
|
49
|
+
[key: string]: any;
|
|
50
|
+
}
|
|
51
|
+
export interface SyncResult {
|
|
52
|
+
totalUpdates: number;
|
|
53
|
+
totalDeleted: number;
|
|
54
|
+
}
|
|
55
|
+
export declare const syncService: {
|
|
56
|
+
checkForUpdates({ verbose }?: SyncOptions): Promise<CheckUpdatesResult>;
|
|
57
|
+
applyUpdates(updates: UpdatesContainer, { verbose }?: SyncOptions): Promise<SyncResult>;
|
|
58
|
+
};
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
import { configService } from './config.js';
|
|
3
|
+
import { getUpdates } from '../api/translations.js';
|
|
4
|
+
import { updateTranslationFile, deleteKeysFromTranslationFile } from './translation-updater/index.js';
|
|
5
|
+
import { findTranslationFiles } from './files.js';
|
|
6
|
+
import path from 'path';
|
|
7
|
+
const MAX_PAGES = 20;
|
|
8
|
+
export const syncService = {
|
|
9
|
+
/**
|
|
10
|
+
* Check for updates since the last sync
|
|
11
|
+
* @param verbose Whether to show verbose output
|
|
12
|
+
* @returns Result with updates if any are available
|
|
13
|
+
*/
|
|
14
|
+
async checkForUpdates(verbose = false) {
|
|
15
|
+
const config = await configService.getValidProjectConfig();
|
|
16
|
+
if (!config.projectId) {
|
|
17
|
+
throw new Error('Project not initialized. Please run `localhero init` first.');
|
|
18
|
+
}
|
|
19
|
+
const since = config.lastSyncedAt || new Date(0).toISOString();
|
|
20
|
+
if (verbose) {
|
|
21
|
+
console.log(chalk.blue(`Checking for updates since ${since}`));
|
|
22
|
+
}
|
|
23
|
+
let allFiles = [];
|
|
24
|
+
let deletedKeys = [];
|
|
25
|
+
let currentPage = 1;
|
|
26
|
+
let hasMorePages = true;
|
|
27
|
+
while (hasMorePages && currentPage <= MAX_PAGES) {
|
|
28
|
+
const params = { since, page: currentPage };
|
|
29
|
+
const response = await getUpdates(config.projectId, params);
|
|
30
|
+
if (response.updates?.updated_keys?.length) {
|
|
31
|
+
allFiles = allFiles.concat(response.updates.updated_keys);
|
|
32
|
+
}
|
|
33
|
+
if (response.updates?.deleted_keys?.length) {
|
|
34
|
+
deletedKeys = deletedKeys.concat(response.updates.deleted_keys);
|
|
35
|
+
}
|
|
36
|
+
if (response.pagination) {
|
|
37
|
+
const { current_page, total_pages } = response.pagination;
|
|
38
|
+
hasMorePages = current_page < total_pages;
|
|
39
|
+
currentPage++;
|
|
40
|
+
if (verbose && hasMorePages) {
|
|
41
|
+
if (total_pages > MAX_PAGES) {
|
|
42
|
+
console.log(chalk.yellow(` ⚠️ Limiting to ${MAX_PAGES} pages out of ${total_pages} total`));
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
console.log(chalk.gray(` Fetching page ${currentPage} of ${total_pages}`));
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
else {
|
|
50
|
+
hasMorePages = false;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
if (!allFiles.length && !deletedKeys.length) {
|
|
54
|
+
return { hasUpdates: false };
|
|
55
|
+
}
|
|
56
|
+
return {
|
|
57
|
+
hasUpdates: true,
|
|
58
|
+
updates: {
|
|
59
|
+
updates: {
|
|
60
|
+
files: allFiles,
|
|
61
|
+
deleted_keys: deletedKeys
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
},
|
|
66
|
+
/**
|
|
67
|
+
* Apply updates to translation files
|
|
68
|
+
* @param updates Updates to apply
|
|
69
|
+
* @param verbose Whether to show verbose output
|
|
70
|
+
* @returns Result with the number of updates and deletes
|
|
71
|
+
*/
|
|
72
|
+
async applyUpdates(updates, verbose = false) {
|
|
73
|
+
let totalUpdates = 0;
|
|
74
|
+
let totalDeleted = 0;
|
|
75
|
+
// First, find all source files
|
|
76
|
+
const config = await configService.getValidProjectConfig();
|
|
77
|
+
const result = await findTranslationFiles(config, {
|
|
78
|
+
parseContent: false,
|
|
79
|
+
includeContent: false,
|
|
80
|
+
extractKeys: false,
|
|
81
|
+
returnFullResult: true,
|
|
82
|
+
verbose
|
|
83
|
+
});
|
|
84
|
+
const sourceFiles = result.sourceFiles;
|
|
85
|
+
// Create a map of source files by path
|
|
86
|
+
const sourceFilesByPath = {};
|
|
87
|
+
for (const sourceFile of sourceFiles) {
|
|
88
|
+
const dirName = path.dirname(sourceFile.path);
|
|
89
|
+
sourceFilesByPath[dirName] = sourceFile.path;
|
|
90
|
+
}
|
|
91
|
+
for (const file of updates.updates.files || []) {
|
|
92
|
+
// Find the corresponding source file
|
|
93
|
+
const dirName = path.dirname(file.path);
|
|
94
|
+
const sourceFilePath = sourceFilesByPath[dirName];
|
|
95
|
+
for (const lang of file.languages) {
|
|
96
|
+
if (verbose) {
|
|
97
|
+
console.log(chalk.blue(`Updating ${lang.code} translations in ${file.path}`));
|
|
98
|
+
}
|
|
99
|
+
const translations = {};
|
|
100
|
+
for (const translation of lang.translations) {
|
|
101
|
+
translations[translation.key] = translation.value;
|
|
102
|
+
if (verbose) {
|
|
103
|
+
const displayValue = translation.value.length > 100 ? `${translation.value.slice(0, 100)}…` : translation.value;
|
|
104
|
+
console.log(chalk.gray(` ${translation.key} = ${displayValue}`));
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
try {
|
|
108
|
+
await updateTranslationFile(file.path, translations, lang.code, sourceFilePath);
|
|
109
|
+
totalUpdates += Object.keys(translations).length;
|
|
110
|
+
}
|
|
111
|
+
catch (error) {
|
|
112
|
+
console.error(chalk.yellow(`⚠️ Failed to update ${file.path}: ${error.message}`));
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
const deletedKeys = updates.updates.deleted_keys || [];
|
|
117
|
+
if (deletedKeys.length > 0) {
|
|
118
|
+
if (verbose) {
|
|
119
|
+
console.log(chalk.blue(`\nProcessing ${deletedKeys.length} deleted keys`));
|
|
120
|
+
}
|
|
121
|
+
const translationFiles = await findTranslationFiles(config, {
|
|
122
|
+
parseContent: false,
|
|
123
|
+
includeContent: false,
|
|
124
|
+
extractKeys: false,
|
|
125
|
+
verbose
|
|
126
|
+
});
|
|
127
|
+
if (verbose) {
|
|
128
|
+
console.log(chalk.blue(`Found ${translationFiles.length} translation files to check for deleted keys`));
|
|
129
|
+
}
|
|
130
|
+
const keysToDelete = deletedKeys.map(key => key.name);
|
|
131
|
+
for (const file of translationFiles) {
|
|
132
|
+
try {
|
|
133
|
+
if (verbose) {
|
|
134
|
+
console.log(chalk.blue(`Checking for deleted keys in ${file.path} (${file.locale})`));
|
|
135
|
+
}
|
|
136
|
+
const deletedFromFile = await deleteKeysFromTranslationFile(file.path, keysToDelete, file.locale);
|
|
137
|
+
if (deletedFromFile.length > 0) {
|
|
138
|
+
totalDeleted += deletedFromFile.length;
|
|
139
|
+
if (verbose) {
|
|
140
|
+
console.log(chalk.green(`✓ Deleted ${deletedFromFile.length} keys from ${file.path}`));
|
|
141
|
+
for (const key of deletedFromFile) {
|
|
142
|
+
console.log(chalk.gray(` - ${key}`));
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
else if (verbose) {
|
|
147
|
+
console.log(chalk.gray(` No keys to delete in ${file.path}`));
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
catch (error) {
|
|
151
|
+
console.error(chalk.yellow(`⚠️ Failed to delete keys from ${file.path}: ${error.message}`));
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
await configService.updateLastSyncedAt();
|
|
156
|
+
return { totalUpdates, totalDeleted };
|
|
157
|
+
}
|
|
158
|
+
};
|
|
159
|
+
//# sourceMappingURL=sync-service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sync-service.js","sourceRoot":"","sources":["../../src/utils/sync-service.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
/**
|
|
3
|
+
* Creates a job request object for a batch of translations
|
|
4
|
+
*
|
|
5
|
+
* @param batch - The batch to create a job for
|
|
6
|
+
* @param missingByLocale - Missing translations by locale and file
|
|
7
|
+
* @param config - Project configuration
|
|
8
|
+
* @returns The job request object
|
|
9
|
+
*/
|
|
10
|
+
function createJobRequest(batch, missingByLocale, config) {
|
|
11
|
+
const targetPaths = {};
|
|
12
|
+
batch.localeEntries.forEach(localeSourceKey => {
|
|
13
|
+
const entry = missingByLocale[localeSourceKey];
|
|
14
|
+
targetPaths[entry.locale] = entry.targetPath;
|
|
15
|
+
});
|
|
16
|
+
return {
|
|
17
|
+
projectId: config.projectId,
|
|
18
|
+
sourceFiles: [batch.sourceFile],
|
|
19
|
+
targetLocales: batch.locales,
|
|
20
|
+
targetPaths
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Creates a mapping of job IDs to source files and locales
|
|
25
|
+
*
|
|
26
|
+
* @param jobs - Array of job objects from the API response
|
|
27
|
+
* @param sourceFilePath - Path to the source file
|
|
28
|
+
* @returns Mapping of job IDs to source information
|
|
29
|
+
*/
|
|
30
|
+
function createJobSourceMapping(jobs, sourceFilePath) {
|
|
31
|
+
const jobSourceMapping = {};
|
|
32
|
+
jobs.forEach(job => {
|
|
33
|
+
jobSourceMapping[job.id] = {
|
|
34
|
+
sourceFilePath,
|
|
35
|
+
locale: job.language?.code || ''
|
|
36
|
+
};
|
|
37
|
+
});
|
|
38
|
+
return jobSourceMapping;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Monitors a job's status until completion
|
|
42
|
+
*
|
|
43
|
+
* @param jobId - The ID of the job to monitor
|
|
44
|
+
* @param verbose - Whether to show verbose output
|
|
45
|
+
* @param translationUtils - Translation utilities
|
|
46
|
+
* @param console - Console for logging
|
|
47
|
+
* @returns The job status when completed
|
|
48
|
+
* @throws Error If the job fails or times out
|
|
49
|
+
*/
|
|
50
|
+
async function monitorJobStatus(jobId, verbose, translationUtils, console) {
|
|
51
|
+
if (verbose) {
|
|
52
|
+
console.log(chalk.blue(`\nℹ Checking job ${jobId}`));
|
|
53
|
+
}
|
|
54
|
+
let status;
|
|
55
|
+
let retries = 0;
|
|
56
|
+
const MAX_WAIT_MINUTES = 10;
|
|
57
|
+
const startTime = Date.now();
|
|
58
|
+
do {
|
|
59
|
+
status = await translationUtils.checkJobStatus(jobId, true);
|
|
60
|
+
if (status.status === 'failed') {
|
|
61
|
+
throw new Error(`Translation job failed: ${status.error_details || 'Unknown error'}`);
|
|
62
|
+
}
|
|
63
|
+
if (status.status === 'pending' || status.status === 'processing') {
|
|
64
|
+
const elapsed = Math.floor((Date.now() - startTime) / 1000);
|
|
65
|
+
if (elapsed > MAX_WAIT_MINUTES * 60) {
|
|
66
|
+
throw new Error(`Translation timed out after ${MAX_WAIT_MINUTES} minutes`);
|
|
67
|
+
}
|
|
68
|
+
const waitSeconds = Math.min(2 ** retries, 30);
|
|
69
|
+
if (verbose) {
|
|
70
|
+
console.log(chalk.blue(` Job ${jobId} is ${status.status}, checking again in ${waitSeconds}s...`));
|
|
71
|
+
}
|
|
72
|
+
await new Promise(resolve => setTimeout(resolve, waitSeconds * 1000));
|
|
73
|
+
retries = Math.min(retries + 1, 5);
|
|
74
|
+
return { jobId, status: 'pending' };
|
|
75
|
+
}
|
|
76
|
+
return { jobId, status: 'completed', data: status };
|
|
77
|
+
} while (status.status === 'pending' || status.status === 'processing');
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Applies completed translations to the target files
|
|
81
|
+
*
|
|
82
|
+
* @param jobStatus - The job status with translation data
|
|
83
|
+
* @param jobSourceMapping - Mapping of job IDs to source information
|
|
84
|
+
* @param missingByLocale - Missing translations by locale and file
|
|
85
|
+
* @param translationUtils - Translation utilities
|
|
86
|
+
* @param verbose - Whether to show verbose output
|
|
87
|
+
* @param console - Console for logging
|
|
88
|
+
* @param processedEntries - Set of already processed entries
|
|
89
|
+
* @param uniqueKeysTranslated - Set of unique keys that were translated
|
|
90
|
+
* @param stats - Statistics object to update
|
|
91
|
+
* @returns Whether translations were applied
|
|
92
|
+
*/
|
|
93
|
+
async function applyTranslations(jobStatus, jobSourceMapping, missingByLocale, translationUtils, verbose, console, processedEntries, uniqueKeysTranslated, stats) {
|
|
94
|
+
const { jobId, data } = jobStatus;
|
|
95
|
+
if (!data?.translations?.data || !data.language?.code) {
|
|
96
|
+
return false;
|
|
97
|
+
}
|
|
98
|
+
if (data.results_url && !stats.resultsBaseUrl) {
|
|
99
|
+
stats.resultsBaseUrl = data.results_url.split('?')[0];
|
|
100
|
+
}
|
|
101
|
+
const languageCode = data.language.code;
|
|
102
|
+
const sourceInfo = jobSourceMapping[jobId];
|
|
103
|
+
if (!sourceInfo || sourceInfo.locale !== languageCode) {
|
|
104
|
+
return false;
|
|
105
|
+
}
|
|
106
|
+
const localeSourceKey = `${languageCode}:${sourceInfo.sourceFilePath}`;
|
|
107
|
+
const entry = missingByLocale[localeSourceKey];
|
|
108
|
+
if (!entry || processedEntries.has(localeSourceKey)) {
|
|
109
|
+
return false;
|
|
110
|
+
}
|
|
111
|
+
const targetPath = entry.targetPath;
|
|
112
|
+
if (verbose) {
|
|
113
|
+
console.log(chalk.blue(` Updating translations for ${languageCode} in ${targetPath}`));
|
|
114
|
+
}
|
|
115
|
+
await translationUtils.updateTranslationFile(targetPath, data.translations.data, languageCode, entry.path);
|
|
116
|
+
Object.keys(entry.keys).forEach(key => uniqueKeysTranslated.add(key));
|
|
117
|
+
if (!processedEntries.has(`locale:${languageCode}`)) {
|
|
118
|
+
stats.totalLanguages++;
|
|
119
|
+
processedEntries.add(`locale:${languageCode}`);
|
|
120
|
+
}
|
|
121
|
+
processedEntries.add(localeSourceKey);
|
|
122
|
+
return true;
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Processes a single batch of translations
|
|
126
|
+
*
|
|
127
|
+
* @param batch - The batch to process
|
|
128
|
+
* @param missingByLocale - Missing translations by locale and file
|
|
129
|
+
* @param config - Project configuration
|
|
130
|
+
* @param verbose - Whether to show verbose output
|
|
131
|
+
* @param deps - Dependencies (console, translationUtils)
|
|
132
|
+
* @param processedEntries - Set of already processed entries
|
|
133
|
+
* @param uniqueKeysTranslated - Set of unique keys that were translated
|
|
134
|
+
* @param allJobIds - Array of all job IDs
|
|
135
|
+
* @param stats - Statistics object to update
|
|
136
|
+
*/
|
|
137
|
+
async function processBatch(batch, missingByLocale, config, verbose, deps, processedEntries, uniqueKeysTranslated, allJobIds, stats) {
|
|
138
|
+
const { console, translationUtils } = deps;
|
|
139
|
+
const sourceFilePath = batch.sourceFilePath;
|
|
140
|
+
const jobRequest = createJobRequest(batch, missingByLocale, config);
|
|
141
|
+
const response = await translationUtils.createTranslationJob(jobRequest);
|
|
142
|
+
const { jobs } = response;
|
|
143
|
+
const batchJobIds = jobs.map(job => job.id);
|
|
144
|
+
allJobIds.push(...batchJobIds);
|
|
145
|
+
const jobSourceMapping = createJobSourceMapping(jobs, sourceFilePath);
|
|
146
|
+
const pendingJobs = new Set(batchJobIds);
|
|
147
|
+
while (pendingJobs.size > 0) {
|
|
148
|
+
const jobPromises = Array.from(pendingJobs).map(async (jobId) => {
|
|
149
|
+
const jobStatus = await monitorJobStatus(jobId, verbose, translationUtils, console);
|
|
150
|
+
if (jobStatus.status === 'completed') {
|
|
151
|
+
await applyTranslations(jobStatus, jobSourceMapping, missingByLocale, translationUtils, verbose, console, processedEntries, uniqueKeysTranslated, stats);
|
|
152
|
+
}
|
|
153
|
+
return jobStatus;
|
|
154
|
+
});
|
|
155
|
+
// Wait for all jobs to be processed
|
|
156
|
+
const results = await Promise.all(jobPromises);
|
|
157
|
+
results.forEach(result => {
|
|
158
|
+
if (result.status === 'completed') {
|
|
159
|
+
pendingJobs.delete(result.jobId);
|
|
160
|
+
}
|
|
161
|
+
});
|
|
162
|
+
// If there are still pending jobs, wait before checking again
|
|
163
|
+
if (pendingJobs.size > 0) {
|
|
164
|
+
await new Promise(resolve => setTimeout(resolve, 2000));
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* Processes translation batches by creating translation jobs,
|
|
170
|
+
* monitoring their status, and applying translations when complete
|
|
171
|
+
*
|
|
172
|
+
* @param batches - Translation batches to process
|
|
173
|
+
* @param missingByLocale - Missing translations by locale and file
|
|
174
|
+
* @param config - Project configuration
|
|
175
|
+
* @param verbose - Whether to show verbose output
|
|
176
|
+
* @param deps - Dependencies (console, translationUtils)
|
|
177
|
+
* @returns Result containing statistics about the translation process
|
|
178
|
+
*/
|
|
179
|
+
export async function processTranslationBatches(batches, missingByLocale, config, verbose, deps) {
|
|
180
|
+
const stats = {
|
|
181
|
+
totalLanguages: 0,
|
|
182
|
+
resultsBaseUrl: null
|
|
183
|
+
};
|
|
184
|
+
const processedEntries = new Set();
|
|
185
|
+
const allJobIds = [];
|
|
186
|
+
const uniqueKeysTranslated = new Set();
|
|
187
|
+
for (const batch of batches) {
|
|
188
|
+
await processBatch(batch, missingByLocale, config, verbose, deps, processedEntries, uniqueKeysTranslated, allJobIds, stats);
|
|
189
|
+
}
|
|
190
|
+
return {
|
|
191
|
+
totalLanguages: stats.totalLanguages,
|
|
192
|
+
allJobIds,
|
|
193
|
+
resultsBaseUrl: stats.resultsBaseUrl,
|
|
194
|
+
uniqueKeysTranslated
|
|
195
|
+
};
|
|
196
|
+
}
|
|
197
|
+
//# sourceMappingURL=translation-processor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"translation-processor.js","sourceRoot":"","sources":["../../src/utils/translation-processor.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export function fileExists(filePath: any): Promise<boolean>;
|
|
2
|
+
export function ensureDirectoryExists(filePath: any): Promise<void>;
|
|
3
|
+
export function tryParseJsonArray(value: any): any[] | null;
|
|
4
|
+
export const SPECIAL_CHARS_REGEX: RegExp;
|
|
5
|
+
export const INTERPOLATION: "%{";
|
|
6
|
+
export const MAX_ARRAY_LENGTH: 1000;
|
|
@@ -1,44 +1,50 @@
|
|
|
1
1
|
import { promises as fs } from 'fs';
|
|
2
2
|
import path from 'path';
|
|
3
|
-
|
|
4
3
|
export const SPECIAL_CHARS_REGEX = /[:@#,[\]{}?|>&*!\n]/;
|
|
5
4
|
export const INTERPOLATION = '%{';
|
|
6
5
|
export const MAX_ARRAY_LENGTH = 1000;
|
|
7
|
-
|
|
6
|
+
/**
|
|
7
|
+
* Checks if a file exists at the specified path
|
|
8
|
+
*/
|
|
8
9
|
export async function fileExists(filePath) {
|
|
9
10
|
try {
|
|
10
11
|
await fs.access(filePath);
|
|
11
12
|
return true;
|
|
12
|
-
}
|
|
13
|
+
}
|
|
14
|
+
catch {
|
|
13
15
|
return false;
|
|
14
16
|
}
|
|
15
17
|
}
|
|
16
|
-
|
|
18
|
+
/**
|
|
19
|
+
* Ensures the directory for the provided file path exists
|
|
20
|
+
*/
|
|
17
21
|
export async function ensureDirectoryExists(filePath) {
|
|
18
22
|
const dir = path.dirname(filePath);
|
|
19
23
|
if (dir !== '.') {
|
|
20
24
|
await fs.mkdir(dir, { recursive: true });
|
|
21
25
|
}
|
|
22
26
|
}
|
|
23
|
-
|
|
27
|
+
/**
|
|
28
|
+
* Attempts to parse a string as a JSON array
|
|
29
|
+
* Returns the parsed array or null if parsing fails
|
|
30
|
+
*/
|
|
24
31
|
export function tryParseJsonArray(value) {
|
|
25
32
|
if (typeof value !== 'string' || !value.startsWith('["') || !value.endsWith('"]')) {
|
|
26
33
|
return null;
|
|
27
34
|
}
|
|
28
|
-
|
|
29
35
|
try {
|
|
30
36
|
const parsed = JSON.parse(value);
|
|
31
37
|
if (!Array.isArray(parsed)) {
|
|
32
38
|
return null;
|
|
33
39
|
}
|
|
34
|
-
|
|
35
40
|
if (parsed.length > MAX_ARRAY_LENGTH) {
|
|
36
41
|
console.warn(`Array length ${parsed.length} exceeds maximum allowed length of ${MAX_ARRAY_LENGTH}`);
|
|
37
42
|
return null;
|
|
38
43
|
}
|
|
39
|
-
|
|
40
44
|
return parsed;
|
|
41
|
-
}
|
|
45
|
+
}
|
|
46
|
+
catch {
|
|
42
47
|
return null;
|
|
43
48
|
}
|
|
44
|
-
}
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=common.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"common.js","sourceRoot":"","sources":["../../../src/utils/translation-updater/common.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,IAAI,EAAE,EAAE,MAAM,IAAI,CAAC;AACpC,OAAO,IAAI,MAAM,MAAM,CAAC;AAExB,MAAM,CAAC,MAAM,mBAAmB,GAAG,qBAAqB,CAAC;AACzD,MAAM,CAAC,MAAM,aAAa,GAAG,IAAI,CAAC;AAClC,MAAM,CAAC,MAAM,gBAAgB,GAAG,IAAI,CAAC;AAErC;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,QAAgB;IAC/C,IAAI,CAAC;QACH,MAAM,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;QAC1B,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,qBAAqB,CAAC,QAAgB;IAC1D,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IACnC,IAAI,GAAG,KAAK,GAAG,EAAE,CAAC;QAChB,MAAM,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC3C,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,iBAAiB,CAAC,KAAc;IAC9C,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QAClF,OAAO,IAAI,CAAC;IACd,CAAC;IAED,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QACjC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;YAC3B,OAAO,IAAI,CAAC;QACd,CAAC;QAED,IAAI,MAAM,CAAC,MAAM,GAAG,gBAAgB,EAAE,CAAC;YACrC,OAAO,CAAC,IAAI,CAAC,gBAAgB,MAAM,CAAC,MAAM,sCAAsC,gBAAgB,EAAE,CAAC,CAAC;YACpG,OAAO,IAAI,CAAC;QACd,CAAC;QAED,OAAO,MAAM,CAAC;IAChB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export function updateTranslationFile(filePath: any, translations: any, languageCode?: string, sourceFilePath?: null): Promise<{
|
|
2
|
+
updatedKeys: string[];
|
|
3
|
+
created: boolean;
|
|
4
|
+
}>;
|
|
5
|
+
export function deleteKeysFromTranslationFile(filePath: any, keysToDelete: any, languageCode?: string): Promise<any[]>;
|