@localheroai/cli 0.0.41 → 0.0.43
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/dist/cli.js +12 -1
- package/dist/cli.js.map +1 -1
- package/dist/commands/init.js +298 -125
- package/dist/commands/init.js.map +1 -1
- package/dist/utils/files.js +18 -7
- package/dist/utils/files.js.map +1 -1
- package/dist/utils/github.js +11 -11
- package/dist/utils/github.js.map +1 -1
- package/dist/utils/po-utils.js +72 -48
- package/dist/utils/po-utils.js.map +1 -1
- package/dist/utils/translation-utils.js +5 -5
- package/dist/utils/translation-utils.js.map +1 -1
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -65,7 +65,18 @@ program
|
|
|
65
65
|
program
|
|
66
66
|
.command('init')
|
|
67
67
|
.description('Initialize a new LocalHero.ai project')
|
|
68
|
-
.
|
|
68
|
+
.option('-y, --yes', 'Non-interactive mode: use flag values and never prompt')
|
|
69
|
+
.option('--project-id <id>', 'Use an existing project (skips creation)')
|
|
70
|
+
.option('--project-name <name>', 'Name for a new project (defaults to current directory name)')
|
|
71
|
+
.option('--source-locale <code>', 'Source locale, e.g. "en"')
|
|
72
|
+
.option('--target-locales <codes>', 'Comma-separated target locales, e.g. "sv,de,fr,nb-NO"')
|
|
73
|
+
.option('--path <dir>', 'Translation files directory, e.g. "config/locales/"')
|
|
74
|
+
.option('--pattern <glob>', 'Override detected file pattern')
|
|
75
|
+
.option('--ignore <paths>', 'Comma-separated ignore paths')
|
|
76
|
+
.option('--api-key <key>', 'API key for non-interactive authentication')
|
|
77
|
+
.option('--skip-import', 'Do not import existing translation files')
|
|
78
|
+
.option('--github-action', 'Create a GitHub Actions workflow (off by default in --yes mode)')
|
|
79
|
+
.action(wrapCommandAction((options) => init({ options })));
|
|
69
80
|
program
|
|
70
81
|
.command('translate')
|
|
71
82
|
.description('Translate missing keys in your i18n files')
|
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,YAAY,EAAE,MAAM,IAAI,CAAC;AAClC,OAAO,EAAE,aAAa,EAAE,MAAM,KAAK,CAAC;AACpC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AACxC,OAAO,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAC;AAC5C,OAAO,EAAE,IAAI,EAAE,MAAM,oBAAoB,CAAC;AAC1C,OAAO,EAAE,IAAI,EAAE,MAAM,oBAAoB,CAAC;AAC1C,OAAO,EAAE,IAAI,
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|
package/dist/commands/init.js
CHANGED
|
@@ -11,6 +11,15 @@ import { createGitHubActionFile, workflowExists } from '../utils/github.js';
|
|
|
11
11
|
import { directoryExists, findFirstExistingPath, getDirectoryContents } from '../utils/files.js';
|
|
12
12
|
import { verifyApiKey } from '../api/auth.js';
|
|
13
13
|
import { Spinner } from '../utils/spinner.js';
|
|
14
|
+
export class MissingFlagsError extends Error {
|
|
15
|
+
flags;
|
|
16
|
+
constructor(flags) {
|
|
17
|
+
const hint = '\n(or use --project-id to reuse an existing project)';
|
|
18
|
+
super(`Missing required flags for --yes: ${flags.join(', ')}${hint}`);
|
|
19
|
+
this.name = 'MissingFlagsError';
|
|
20
|
+
this.flags = flags;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
14
23
|
const PROJECT_TYPES = {
|
|
15
24
|
django: {
|
|
16
25
|
directIndicators: ['manage.py'],
|
|
@@ -36,6 +45,21 @@ const PROJECT_TYPES = {
|
|
|
36
45
|
'config/locales'
|
|
37
46
|
]
|
|
38
47
|
},
|
|
48
|
+
nextIntl: {
|
|
49
|
+
directIndicators: [],
|
|
50
|
+
packageCheck: {
|
|
51
|
+
requires: ['next', 'next-intl']
|
|
52
|
+
},
|
|
53
|
+
defaults: {
|
|
54
|
+
translationPath: 'messages/',
|
|
55
|
+
filePattern: '**/*.json'
|
|
56
|
+
},
|
|
57
|
+
commonPaths: [
|
|
58
|
+
'messages',
|
|
59
|
+
'src/messages',
|
|
60
|
+
'app/messages'
|
|
61
|
+
]
|
|
62
|
+
},
|
|
39
63
|
nextjs: {
|
|
40
64
|
directIndicators: ['next.config.js', 'next.config.mjs'],
|
|
41
65
|
packageCheck: {
|
|
@@ -85,6 +109,29 @@ const PROJECT_TYPES = {
|
|
|
85
109
|
'i18n'
|
|
86
110
|
]
|
|
87
111
|
},
|
|
112
|
+
lingui: {
|
|
113
|
+
directIndicators: [
|
|
114
|
+
'lingui.config.js',
|
|
115
|
+
'lingui.config.ts',
|
|
116
|
+
'lingui.config.cjs',
|
|
117
|
+
'lingui.config.mjs',
|
|
118
|
+
'.linguirc',
|
|
119
|
+
'.linguirc.json'
|
|
120
|
+
],
|
|
121
|
+
packageCheck: {
|
|
122
|
+
oneOf: ['@lingui/cli', '@lingui/core', '@lingui/react', '@lingui/macro']
|
|
123
|
+
},
|
|
124
|
+
defaults: {
|
|
125
|
+
translationPath: 'src/locales/',
|
|
126
|
+
filePattern: '**/*.po',
|
|
127
|
+
sourceCodePaths: ['src/**/*.{ts,tsx,js,jsx}']
|
|
128
|
+
},
|
|
129
|
+
commonPaths: [
|
|
130
|
+
'src/locales',
|
|
131
|
+
'locales',
|
|
132
|
+
'locale'
|
|
133
|
+
]
|
|
134
|
+
},
|
|
88
135
|
reactIntl: {
|
|
89
136
|
directIndicators: ['.babelrc'],
|
|
90
137
|
packageCheck: {
|
|
@@ -150,7 +197,10 @@ const PROJECT_TYPES = {
|
|
|
150
197
|
'public/locales',
|
|
151
198
|
'config/locales',
|
|
152
199
|
'locales',
|
|
200
|
+
'messages',
|
|
201
|
+
'src/messages',
|
|
153
202
|
'src/i18n',
|
|
203
|
+
'app/i18n',
|
|
154
204
|
'src/translations',
|
|
155
205
|
'src/lang',
|
|
156
206
|
'assets/i18n',
|
|
@@ -196,6 +246,22 @@ async function detectFramework(config) {
|
|
|
196
246
|
}
|
|
197
247
|
return false;
|
|
198
248
|
}
|
|
249
|
+
export function buildFilePatternFromContents(contents) {
|
|
250
|
+
const formats = [];
|
|
251
|
+
if (contents.jsonFiles.length > 0)
|
|
252
|
+
formats.push('json');
|
|
253
|
+
if (contents.yamlFiles.length > 0)
|
|
254
|
+
formats.push('yml', 'yaml');
|
|
255
|
+
if (contents.poFiles.length > 0)
|
|
256
|
+
formats.push('po');
|
|
257
|
+
if (formats.length === 0) {
|
|
258
|
+
return '**/*.{json,yml,yaml,po}';
|
|
259
|
+
}
|
|
260
|
+
if (formats.length === 1 && formats[0] !== 'yml') {
|
|
261
|
+
return `**/*.${formats[0]}`;
|
|
262
|
+
}
|
|
263
|
+
return `**/*.{${formats.join(',')}}`;
|
|
264
|
+
}
|
|
199
265
|
async function detectProjectType() {
|
|
200
266
|
for (const [type, config] of Object.entries(PROJECT_TYPES)) {
|
|
201
267
|
if (!config.directIndicators?.length && !config.packageCheck)
|
|
@@ -234,18 +300,7 @@ async function detectProjectType() {
|
|
|
234
300
|
defaults: {
|
|
235
301
|
commonPaths: commonPaths,
|
|
236
302
|
translationPath: `${translationPath}/`,
|
|
237
|
-
filePattern: (
|
|
238
|
-
const formats = [];
|
|
239
|
-
if (contents.jsonFiles.length > 0)
|
|
240
|
-
formats.push('json');
|
|
241
|
-
if (contents.yamlFiles.length > 0)
|
|
242
|
-
formats.push('yml', 'yaml');
|
|
243
|
-
if (contents.poFiles.length > 0)
|
|
244
|
-
formats.push('po');
|
|
245
|
-
return formats.length === 1 && formats[0] !== 'yml'
|
|
246
|
-
? `**/*.${formats[0]}`
|
|
247
|
-
: `**/*.{${formats.join(',')}}`;
|
|
248
|
-
})()
|
|
303
|
+
filePattern: buildFilePatternFromContents(contents)
|
|
249
304
|
}
|
|
250
305
|
};
|
|
251
306
|
}
|
|
@@ -325,8 +380,8 @@ async function handleImportProcess(config, basePath, importUtils, console, confi
|
|
|
325
380
|
return { success: false, hasWarnings: false };
|
|
326
381
|
}
|
|
327
382
|
}
|
|
328
|
-
async function handleGitHubWorkflowSetup(basePath, translationPaths, promptService, console) {
|
|
329
|
-
if (workflowExists(basePath)) {
|
|
383
|
+
async function handleGitHubWorkflowSetup(basePath, translationPaths, promptService, console, githubUtils, autoAnswer, sourceCodePaths) {
|
|
384
|
+
if (githubUtils.workflowExists(basePath)) {
|
|
330
385
|
console.log(chalk.green('✓ GitHub Actions workflow found'));
|
|
331
386
|
console.log(chalk.yellow('\n⚠️ Remember to add your API key to repository secrets:'));
|
|
332
387
|
console.log(' Name: LOCALHERO_API_KEY');
|
|
@@ -334,15 +389,21 @@ async function handleGitHubWorkflowSetup(basePath, translationPaths, promptServi
|
|
|
334
389
|
console.log(' Location: Repository Settings → Secrets and variables → Actions (On GitHub repo page)\n');
|
|
335
390
|
return { created: false };
|
|
336
391
|
}
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
}
|
|
392
|
+
let shouldSetupGitHubAction;
|
|
393
|
+
if (autoAnswer !== undefined) {
|
|
394
|
+
shouldSetupGitHubAction = autoAnswer;
|
|
395
|
+
}
|
|
396
|
+
else {
|
|
397
|
+
shouldSetupGitHubAction = await promptService.confirm({
|
|
398
|
+
message: 'Would you like to set up GitHub Actions for automatic translations?',
|
|
399
|
+
default: true
|
|
400
|
+
});
|
|
401
|
+
}
|
|
341
402
|
if (!shouldSetupGitHubAction) {
|
|
342
403
|
return { created: false };
|
|
343
404
|
}
|
|
344
405
|
try {
|
|
345
|
-
const workflowFile = await createGitHubActionFile(basePath, translationPaths);
|
|
406
|
+
const workflowFile = await githubUtils.createGitHubActionFile(basePath, translationPaths, sourceCodePaths);
|
|
346
407
|
console.log(chalk.green(`\n✓ Created GitHub Action workflow at ${workflowFile}`));
|
|
347
408
|
console.log('\nNext steps:');
|
|
348
409
|
console.log('1. Add your API key to your repository\'s secrets:');
|
|
@@ -358,6 +419,17 @@ async function handleGitHubWorkflowSetup(basePath, translationPaths, promptServi
|
|
|
358
419
|
return { created: false, error: errorMessage };
|
|
359
420
|
}
|
|
360
421
|
}
|
|
422
|
+
function printLinguiWorkflowNotice(console) {
|
|
423
|
+
console.log(chalk.yellow('\n⚠️ Lingui projects need an extract step in the workflow'));
|
|
424
|
+
console.log('\nLingui generates .po files from your source code via `lingui extract`.');
|
|
425
|
+
console.log('Add this step to the workflow before the localhero-action step:\n');
|
|
426
|
+
console.log(chalk.gray(' - uses: actions/setup-node@v4'));
|
|
427
|
+
console.log(chalk.gray(' with:'));
|
|
428
|
+
console.log(chalk.gray(' node-version: \'20\''));
|
|
429
|
+
console.log(chalk.gray(' - run: npm ci'));
|
|
430
|
+
console.log(chalk.gray(' - run: npx lingui extract'));
|
|
431
|
+
console.log('\nWithout this, the workflow will not pick up new translatable strings.\n');
|
|
432
|
+
}
|
|
361
433
|
function displayFinalInstructions(workflowCreated, workflowExists, hasErrors, console) {
|
|
362
434
|
if (hasErrors) {
|
|
363
435
|
return;
|
|
@@ -374,8 +446,8 @@ function displayFinalInstructions(workflowCreated, workflowExists, hasErrors, co
|
|
|
374
446
|
}
|
|
375
447
|
console.log(' npx @localheroai/cli translate');
|
|
376
448
|
}
|
|
377
|
-
async function handleExistingConfiguration(existingConfig, deps) {
|
|
378
|
-
const { console, basePath, promptService, authUtils, projectApi,
|
|
449
|
+
async function handleExistingConfiguration(existingConfig, options, nonInteractive, deps) {
|
|
450
|
+
const { console, basePath, promptService, authUtils, projectApi, importUtils, configUtils, githubUtils } = deps;
|
|
379
451
|
let workflowCreated = false;
|
|
380
452
|
console.log(chalk.green('✓ Configuration found! Let\'s verify and set up your API access.\n'));
|
|
381
453
|
const validation = await validateExistingConfig(existingConfig);
|
|
@@ -389,19 +461,8 @@ async function handleExistingConfiguration(existingConfig, deps) {
|
|
|
389
461
|
console.log(` Source: ${existingConfig.sourceLocale}`);
|
|
390
462
|
console.log(` Targets: ${existingConfig.outputLocales.join(', ')}`);
|
|
391
463
|
console.log(` Pattern: ${existingConfig.translationFiles?.pattern || 'not specified'}\n`);
|
|
392
|
-
|
|
393
|
-
if (
|
|
394
|
-
console.log('Let\'s connect to your LocalHero account.');
|
|
395
|
-
await loginFn({
|
|
396
|
-
console,
|
|
397
|
-
basePath,
|
|
398
|
-
promptService,
|
|
399
|
-
configUtils: deps.configUtils,
|
|
400
|
-
verifyApiKey: authUtils.verifyApiKey,
|
|
401
|
-
isCalledFromInit: true
|
|
402
|
-
});
|
|
403
|
-
}
|
|
404
|
-
else {
|
|
464
|
+
await ensureAuthenticated(nonInteractive, options, deps);
|
|
465
|
+
if (await authUtils.checkAuth()) {
|
|
405
466
|
console.log(chalk.green('✓ API key found and valid'));
|
|
406
467
|
try {
|
|
407
468
|
const projects = await projectApi.listProjects();
|
|
@@ -414,72 +475,70 @@ async function handleExistingConfiguration(existingConfig, deps) {
|
|
|
414
475
|
console.log(chalk.green('✓ Project access verified'));
|
|
415
476
|
}
|
|
416
477
|
catch {
|
|
478
|
+
if (nonInteractive) {
|
|
479
|
+
throw new Error('Could not verify project access against the Localhero API');
|
|
480
|
+
}
|
|
417
481
|
console.log(chalk.yellow('⚠️ Could not verify project access. Continuing anyway...\n'));
|
|
418
482
|
}
|
|
419
483
|
}
|
|
420
|
-
// Check if we've previously imported files
|
|
421
484
|
if (existingConfig.lastSyncedAt) {
|
|
422
485
|
console.log(chalk.green('✓ Translation files previously imported'));
|
|
423
486
|
}
|
|
424
487
|
else {
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
}
|
|
488
|
+
let shouldImport;
|
|
489
|
+
if (nonInteractive) {
|
|
490
|
+
shouldImport = !options.skipImport;
|
|
491
|
+
}
|
|
492
|
+
else {
|
|
493
|
+
shouldImport = await promptService.confirm({
|
|
494
|
+
message: 'Would you like to import existing translation files? (recommended)',
|
|
495
|
+
default: true
|
|
496
|
+
});
|
|
497
|
+
}
|
|
429
498
|
if (shouldImport) {
|
|
430
499
|
await handleImportProcess(existingConfig, basePath, importUtils, console, configUtils);
|
|
431
500
|
}
|
|
432
501
|
}
|
|
433
|
-
const workflowResult = await handleGitHubWorkflowSetup(basePath, existingConfig.translationFiles?.paths || [''], promptService, console);
|
|
502
|
+
const workflowResult = await handleGitHubWorkflowSetup(basePath, existingConfig.translationFiles?.paths || [''], promptService, console, githubUtils, nonInteractive ? options.githubAction === true : undefined);
|
|
434
503
|
workflowCreated = workflowResult.created;
|
|
435
|
-
displayFinalInstructions(workflowCreated, workflowExists(basePath), false, console);
|
|
504
|
+
displayFinalInstructions(workflowCreated, githubUtils.workflowExists(basePath), false, console);
|
|
436
505
|
}
|
|
437
|
-
async function handleNewProjectSetup(deps) {
|
|
438
|
-
const { console, basePath, promptService,
|
|
439
|
-
|
|
440
|
-
if (!
|
|
441
|
-
console.log('
|
|
442
|
-
console.log(chalk.yellow('No API key found. Let\'s get you authenticated.'));
|
|
443
|
-
await loginFn({
|
|
444
|
-
console,
|
|
445
|
-
basePath,
|
|
446
|
-
promptService,
|
|
447
|
-
configUtils,
|
|
448
|
-
verifyApiKey: authUtils.verifyApiKey || verifyApiKey,
|
|
449
|
-
isCalledFromInit: true
|
|
450
|
-
});
|
|
506
|
+
async function handleNewProjectSetup(options, nonInteractive, deps) {
|
|
507
|
+
const { console, basePath, promptService, projectApi, importUtils, configUtils, githubUtils } = deps;
|
|
508
|
+
await ensureAuthenticated(nonInteractive, options, deps);
|
|
509
|
+
if (!nonInteractive) {
|
|
510
|
+
console.log('\nLet\'s set up configuration for your project.\n');
|
|
451
511
|
}
|
|
452
|
-
console.log('\nLet\'s set up configuration for your project.\n');
|
|
453
512
|
let workflowCreated = false;
|
|
454
513
|
const projectDefaults = await detectProjectType();
|
|
455
|
-
const
|
|
456
|
-
|
|
514
|
+
const inputs = nonInteractive
|
|
515
|
+
? await collectInputsFromFlags(options, projectDefaults, projectApi, console)
|
|
516
|
+
: await collectInputsInteractive(projectDefaults, projectApi, promptService, console);
|
|
517
|
+
const finalized = await finalizeProjectAndBuildConfig(inputs, projectDefaults, projectApi, console);
|
|
518
|
+
if (!finalized) {
|
|
457
519
|
return;
|
|
458
520
|
}
|
|
459
|
-
const config =
|
|
460
|
-
schemaVersion: '1.0',
|
|
461
|
-
projectId: answers.projectId,
|
|
462
|
-
sourceLocale: answers.sourceLocale,
|
|
463
|
-
outputLocales: answers.outputLocales,
|
|
464
|
-
translationFiles: {
|
|
465
|
-
paths: answers.translationPath ? [answers.translationPath] : [],
|
|
466
|
-
pattern: answers.filePattern || '**/*.{json,yml,yaml,po}',
|
|
467
|
-
ignore: answers.ignorePaths || [],
|
|
468
|
-
...(projectDefaults.defaults.workflow && { workflow: projectDefaults.defaults.workflow })
|
|
469
|
-
},
|
|
470
|
-
lastSyncedAt: null
|
|
471
|
-
};
|
|
521
|
+
const { config, newProject, url } = finalized;
|
|
472
522
|
await configUtils.saveProjectConfig(config, basePath);
|
|
473
523
|
console.log(chalk.green('\n✓ Created localhero.json'));
|
|
474
|
-
if (
|
|
475
|
-
console.log(chalk.green(`✓ Project created, view it at: ${
|
|
524
|
+
if (newProject && url) {
|
|
525
|
+
console.log(chalk.green(`✓ Project created, view it at: ${url}\n`));
|
|
476
526
|
}
|
|
477
|
-
const workflowResult = await handleGitHubWorkflowSetup(basePath,
|
|
527
|
+
const workflowResult = await handleGitHubWorkflowSetup(basePath, config.translationFiles.paths.length > 0 ? config.translationFiles.paths : [''], promptService, console, githubUtils, nonInteractive ? options.githubAction === true : undefined, projectDefaults.defaults.sourceCodePaths);
|
|
478
528
|
workflowCreated = workflowResult.created;
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
529
|
+
if (workflowCreated && projectDefaults.type === 'lingui') {
|
|
530
|
+
printLinguiWorkflowNotice(console);
|
|
531
|
+
}
|
|
532
|
+
let shouldImport;
|
|
533
|
+
if (nonInteractive) {
|
|
534
|
+
shouldImport = !options.skipImport;
|
|
535
|
+
}
|
|
536
|
+
else {
|
|
537
|
+
shouldImport = await promptService.confirm({
|
|
538
|
+
message: 'Would you like to import existing translation files? (recommended)',
|
|
539
|
+
default: true
|
|
540
|
+
});
|
|
541
|
+
}
|
|
483
542
|
let hasErrors = false;
|
|
484
543
|
if (shouldImport) {
|
|
485
544
|
console.log('\nSearching for translation files in:');
|
|
@@ -487,48 +546,50 @@ async function handleNewProjectSetup(deps) {
|
|
|
487
546
|
const importResult = await handleImportProcess(config, basePath, importUtils, console, configUtils);
|
|
488
547
|
hasErrors = !importResult.success;
|
|
489
548
|
}
|
|
490
|
-
displayFinalInstructions(workflowCreated, workflowExists(basePath), hasErrors, console);
|
|
549
|
+
displayFinalInstructions(workflowCreated, githubUtils.workflowExists(basePath), hasErrors, console);
|
|
550
|
+
}
|
|
551
|
+
function normalizeTrailingSlash(p) {
|
|
552
|
+
return p.endsWith('/') ? p : `${p}/`;
|
|
491
553
|
}
|
|
492
|
-
|
|
554
|
+
function parseCsv(raw) {
|
|
555
|
+
return (raw ?? '').split(',').map(s => s.trim()).filter(Boolean);
|
|
556
|
+
}
|
|
557
|
+
function filterSourceFromTargets(sourceLocale, rawTargets, console) {
|
|
558
|
+
const filtered = rawTargets.filter(lang => lang !== sourceLocale);
|
|
559
|
+
if (filtered.length < rawTargets.length) {
|
|
560
|
+
console.log(chalk.yellow(`⚠️ Source language '${sourceLocale}' removed from target languages`));
|
|
561
|
+
}
|
|
562
|
+
return filtered;
|
|
563
|
+
}
|
|
564
|
+
async function collectInputsInteractive(projectDefaults, projectService, promptService, console) {
|
|
493
565
|
const { choice: projectChoice, project: existingProject } = await promptService.selectProject(projectService);
|
|
494
566
|
if (!projectChoice) {
|
|
495
567
|
throw new Error('Project selection is required');
|
|
496
568
|
}
|
|
497
|
-
let
|
|
498
|
-
let
|
|
499
|
-
let
|
|
500
|
-
let config;
|
|
569
|
+
let projectName;
|
|
570
|
+
let sourceLocale;
|
|
571
|
+
let outputLocales;
|
|
501
572
|
if (!existingProject) {
|
|
502
|
-
|
|
573
|
+
sourceLocale = await promptService.input({
|
|
503
574
|
message: 'Source language locale:',
|
|
504
575
|
default: 'en',
|
|
505
576
|
hint: '\nThis is the language we will translate FROM. Enter the locale code as it appears in your I18n files. Examples:\n\n Framework File Structure Enter\n ----------- -------------------------------- --------\n Rails config/locales/en.yml en\n React locales/en_GB.json en_GB\n Next.js public/locales/en-US/common.json en-US\n'
|
|
506
577
|
});
|
|
507
|
-
const rawOutputLocales = (await promptService.input({
|
|
578
|
+
const rawOutputLocales = parseCsv(await promptService.input({
|
|
508
579
|
message: 'Target language locales (comma-separated):',
|
|
509
580
|
hint: '\nThese are the languages we will translate TO. Enter locale codes as they appear in your files:\n\n Pattern Type Target Files Enter\n ------------------ -------------------------------- --------------------\n Basic de.json, fr.json, es.json de,fr,es\n Region-specific fr-CA.json, es-MX.json, de-AT.json fr-CA,es-MX,de-AT\n Directory-based /locales/ja/, /locales/zh/ ja,zh\n'
|
|
510
|
-
}))
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
projectName: await promptService.input({
|
|
517
|
-
message: 'Project name:',
|
|
518
|
-
default: path.basename(process.cwd()),
|
|
519
|
-
}),
|
|
520
|
-
sourceLocale,
|
|
521
|
-
outputLocales
|
|
522
|
-
};
|
|
581
|
+
}));
|
|
582
|
+
outputLocales = filterSourceFromTargets(sourceLocale, rawOutputLocales, console);
|
|
583
|
+
projectName = await promptService.input({
|
|
584
|
+
message: 'Project name:',
|
|
585
|
+
default: path.basename(process.cwd()),
|
|
586
|
+
});
|
|
523
587
|
}
|
|
524
588
|
else {
|
|
525
|
-
// existingProject is guaranteed to exist here since !existingProject was false
|
|
526
589
|
const project = existingProject;
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
outputLocales: project.target_languages
|
|
531
|
-
};
|
|
590
|
+
projectName = project.name;
|
|
591
|
+
sourceLocale = project.source_language;
|
|
592
|
+
outputLocales = project.target_languages;
|
|
532
593
|
}
|
|
533
594
|
const commonPaths = projectDefaults.defaults.commonPaths || [];
|
|
534
595
|
const existingDirs = [];
|
|
@@ -552,20 +613,100 @@ async function promptForConfig(projectDefaults, projectService, promptService, c
|
|
|
552
613
|
});
|
|
553
614
|
const filePattern = projectDefaults.defaults.filePattern;
|
|
554
615
|
const defaultIgnorePaths = projectDefaults.defaults.ignorePaths || [];
|
|
555
|
-
const
|
|
616
|
+
const ignorePathsRaw = await promptService.input({
|
|
556
617
|
message: 'Paths to ignore (comma-separated, leave empty for none):',
|
|
557
618
|
hint: ' Example: locales/ignored,locales/temp',
|
|
558
619
|
default: defaultIgnorePaths.join(', ')
|
|
559
620
|
});
|
|
560
|
-
|
|
621
|
+
return {
|
|
622
|
+
mode: existingProject ? 'existing' : 'new',
|
|
623
|
+
existingProject: existingProject,
|
|
624
|
+
projectName,
|
|
625
|
+
sourceLocale,
|
|
626
|
+
outputLocales,
|
|
627
|
+
translationPath,
|
|
628
|
+
filePattern,
|
|
629
|
+
ignorePaths: parseCsv(ignorePathsRaw)
|
|
630
|
+
};
|
|
631
|
+
}
|
|
632
|
+
async function collectInputsFromFlags(options, projectDefaults, projectService, console) {
|
|
633
|
+
const filePattern = options.pattern ?? projectDefaults.defaults.filePattern;
|
|
634
|
+
const ignorePaths = options.ignore !== undefined
|
|
635
|
+
? parseCsv(options.ignore)
|
|
636
|
+
: (projectDefaults.defaults.ignorePaths ?? []);
|
|
637
|
+
if (options.projectId) {
|
|
638
|
+
const projects = await projectService.listProjects();
|
|
639
|
+
const match = projects.find(p => p.id === options.projectId);
|
|
640
|
+
if (!match) {
|
|
641
|
+
throw new Error(`Project ${options.projectId} not found in your organization`);
|
|
642
|
+
}
|
|
643
|
+
const providedSource = options.sourceLocale;
|
|
644
|
+
const providedTargets = options.targetLocales ? parseCsv(options.targetLocales) : undefined;
|
|
645
|
+
const conflictsSource = providedSource !== undefined && providedSource !== match.source_language;
|
|
646
|
+
const conflictsTargets = providedTargets !== undefined &&
|
|
647
|
+
(providedTargets.length !== match.target_languages.length ||
|
|
648
|
+
providedTargets.some(l => !match.target_languages.includes(l)));
|
|
649
|
+
if (conflictsSource || conflictsTargets) {
|
|
650
|
+
const warnings = [];
|
|
651
|
+
if (conflictsSource)
|
|
652
|
+
warnings.push('--source-locale');
|
|
653
|
+
if (conflictsTargets)
|
|
654
|
+
warnings.push('--target-locales');
|
|
655
|
+
console.log(chalk.yellow(`⚠️ Ignoring ${warnings.join(' and ')}; using project '${match.name}' locales (source: ${match.source_language}, targets: ${match.target_languages.join(', ')})`));
|
|
656
|
+
}
|
|
657
|
+
if (!options.path) {
|
|
658
|
+
throw new MissingFlagsError(['--path']);
|
|
659
|
+
}
|
|
660
|
+
return {
|
|
661
|
+
mode: 'existing',
|
|
662
|
+
existingProject: match,
|
|
663
|
+
projectName: match.name,
|
|
664
|
+
sourceLocale: match.source_language,
|
|
665
|
+
outputLocales: match.target_languages,
|
|
666
|
+
translationPath: normalizeTrailingSlash(options.path),
|
|
667
|
+
filePattern,
|
|
668
|
+
ignorePaths
|
|
669
|
+
};
|
|
670
|
+
}
|
|
671
|
+
const missing = [];
|
|
672
|
+
if (!options.sourceLocale)
|
|
673
|
+
missing.push('--source-locale');
|
|
674
|
+
if (!options.targetLocales || parseCsv(options.targetLocales).length === 0)
|
|
675
|
+
missing.push('--target-locales');
|
|
676
|
+
if (!options.path)
|
|
677
|
+
missing.push('--path');
|
|
678
|
+
if (missing.length > 0) {
|
|
679
|
+
throw new MissingFlagsError(missing);
|
|
680
|
+
}
|
|
681
|
+
const sourceLocale = options.sourceLocale;
|
|
682
|
+
const outputLocales = filterSourceFromTargets(sourceLocale, parseCsv(options.targetLocales), console);
|
|
683
|
+
if (outputLocales.length === 0) {
|
|
684
|
+
throw new Error('After removing the source locale, no target locales remain');
|
|
685
|
+
}
|
|
686
|
+
return {
|
|
687
|
+
mode: 'new',
|
|
688
|
+
projectName: options.projectName ?? path.basename(process.cwd()),
|
|
689
|
+
sourceLocale,
|
|
690
|
+
outputLocales,
|
|
691
|
+
translationPath: normalizeTrailingSlash(options.path),
|
|
692
|
+
filePattern,
|
|
693
|
+
ignorePaths
|
|
694
|
+
};
|
|
695
|
+
}
|
|
696
|
+
async function finalizeProjectAndBuildConfig(inputs, projectDefaults, projectService, console) {
|
|
697
|
+
let projectId;
|
|
698
|
+
let projectUrl;
|
|
699
|
+
let isNewProject;
|
|
700
|
+
if (inputs.mode === 'new') {
|
|
561
701
|
try {
|
|
562
|
-
|
|
563
|
-
name:
|
|
564
|
-
sourceLocale:
|
|
565
|
-
targetLocales:
|
|
702
|
+
const created = await projectService.createProject({
|
|
703
|
+
name: inputs.projectName,
|
|
704
|
+
sourceLocale: inputs.sourceLocale,
|
|
705
|
+
targetLocales: inputs.outputLocales
|
|
566
706
|
});
|
|
567
|
-
projectId =
|
|
568
|
-
projectUrl =
|
|
707
|
+
projectId = created.id;
|
|
708
|
+
projectUrl = created.url;
|
|
709
|
+
isNewProject = true;
|
|
569
710
|
}
|
|
570
711
|
catch (error) {
|
|
571
712
|
const errorMessage = error instanceof Error ? error.message : 'Unknown error';
|
|
@@ -574,23 +715,54 @@ async function promptForConfig(projectDefaults, projectService, promptService, c
|
|
|
574
715
|
}
|
|
575
716
|
}
|
|
576
717
|
else {
|
|
577
|
-
const project = existingProject;
|
|
718
|
+
const project = inputs.existingProject;
|
|
578
719
|
projectId = project.id;
|
|
579
720
|
projectUrl = project.url;
|
|
721
|
+
isNewProject = false;
|
|
580
722
|
}
|
|
581
|
-
|
|
723
|
+
const config = {
|
|
724
|
+
schemaVersion: '1.0',
|
|
582
725
|
projectId,
|
|
583
|
-
sourceLocale:
|
|
584
|
-
outputLocales:
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
726
|
+
sourceLocale: inputs.sourceLocale,
|
|
727
|
+
outputLocales: inputs.outputLocales,
|
|
728
|
+
translationFiles: {
|
|
729
|
+
paths: inputs.translationPath ? [inputs.translationPath] : [],
|
|
730
|
+
pattern: inputs.filePattern || '**/*.{json,yml,yaml,po}',
|
|
731
|
+
ignore: inputs.ignorePaths,
|
|
732
|
+
...(projectDefaults.defaults.workflow && { workflow: projectDefaults.defaults.workflow })
|
|
733
|
+
},
|
|
734
|
+
lastSyncedAt: null
|
|
590
735
|
};
|
|
736
|
+
return { config, newProject: isNewProject, url: projectUrl };
|
|
737
|
+
}
|
|
738
|
+
async function ensureAuthenticated(nonInteractive, options, deps) {
|
|
739
|
+
const { console, basePath, promptService, configUtils, authUtils, login: loginFn } = deps;
|
|
740
|
+
if (await authUtils.checkAuth()) {
|
|
741
|
+
return;
|
|
742
|
+
}
|
|
743
|
+
const envKey = process.env.LOCALHERO_API_KEY;
|
|
744
|
+
const apiKey = options.apiKey || (envKey && envKey.length > 0 ? envKey : undefined);
|
|
745
|
+
if (apiKey || !nonInteractive) {
|
|
746
|
+
if (!nonInteractive && !apiKey) {
|
|
747
|
+
console.log('Localhero.ai - Automate your i18n translations\n');
|
|
748
|
+
console.log(chalk.yellow('No API key found. Let\'s get you authenticated.'));
|
|
749
|
+
}
|
|
750
|
+
await loginFn({
|
|
751
|
+
console,
|
|
752
|
+
basePath,
|
|
753
|
+
promptService,
|
|
754
|
+
configUtils,
|
|
755
|
+
verifyApiKey: authUtils.verifyApiKey || verifyApiKey,
|
|
756
|
+
isCalledFromInit: true,
|
|
757
|
+
...(apiKey ? { apiKey } : {})
|
|
758
|
+
});
|
|
759
|
+
return;
|
|
760
|
+
}
|
|
761
|
+
throw new Error('API key required: pass --api-key, set LOCALHERO_API_KEY, or run `localhero login` first');
|
|
591
762
|
}
|
|
592
763
|
export async function init(deps = {}) {
|
|
593
|
-
const { console = global.console, basePath = process.cwd(), promptService = createPromptService({ inquirer: await import('@inquirer/prompts') }), configUtils = configService, authUtils = { checkAuth }, importUtils = importService, projectApi = { createProject, listProjects }, login: loginFn = login } = deps;
|
|
764
|
+
const { console = global.console, basePath = process.cwd(), promptService = createPromptService({ inquirer: await import('@inquirer/prompts') }), configUtils = configService, authUtils = { checkAuth }, importUtils = importService, projectApi = { createProject, listProjects }, githubUtils = { createGitHubActionFile, workflowExists }, login: loginFn = login, options = {} } = deps;
|
|
765
|
+
const nonInteractive = options.yes === true;
|
|
594
766
|
const requiredDeps = {
|
|
595
767
|
console,
|
|
596
768
|
basePath,
|
|
@@ -599,14 +771,15 @@ export async function init(deps = {}) {
|
|
|
599
771
|
authUtils,
|
|
600
772
|
importUtils,
|
|
601
773
|
projectApi,
|
|
774
|
+
githubUtils,
|
|
602
775
|
login: loginFn
|
|
603
776
|
};
|
|
604
777
|
const existingConfig = await configUtils.getProjectConfig(basePath);
|
|
605
778
|
if (existingConfig) {
|
|
606
|
-
await handleExistingConfiguration(existingConfig, requiredDeps);
|
|
779
|
+
await handleExistingConfiguration(existingConfig, options, nonInteractive, requiredDeps);
|
|
607
780
|
}
|
|
608
781
|
else {
|
|
609
|
-
await handleNewProjectSetup(requiredDeps);
|
|
782
|
+
await handleNewProjectSetup(options, nonInteractive, requiredDeps);
|
|
610
783
|
}
|
|
611
784
|
}
|
|
612
785
|
//# sourceMappingURL=init.js.map
|