@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.
Files changed (114) hide show
  1. package/README +1 -1
  2. package/dist/api/auth.d.ts +2 -0
  3. package/dist/api/auth.js +28 -0
  4. package/dist/api/auth.js.map +1 -0
  5. package/dist/api/client.d.ts +3 -0
  6. package/dist/api/client.js +80 -0
  7. package/dist/api/client.js.map +1 -0
  8. package/dist/api/imports.d.ts +5 -0
  9. package/dist/api/imports.js +43 -0
  10. package/dist/api/imports.js.map +1 -0
  11. package/dist/api/projects.d.ts +2 -0
  12. package/dist/api/projects.js +42 -0
  13. package/dist/api/projects.js.map +1 -0
  14. package/dist/api/translations.d.ts +15 -0
  15. package/dist/api/translations.js +71 -0
  16. package/dist/api/translations.js.map +1 -0
  17. package/dist/cli.d.ts +2 -0
  18. package/dist/cli.js +79 -0
  19. package/dist/cli.js.map +1 -0
  20. package/dist/commands/_sync.js +22 -0
  21. package/dist/commands/_sync.js.map +1 -0
  22. package/dist/commands/_translate.js +3 -0
  23. package/dist/commands/_translate.js.map +1 -0
  24. package/dist/commands/init.d.ts +1 -0
  25. package/dist/commands/init.js +439 -0
  26. package/dist/commands/init.js.map +1 -0
  27. package/dist/commands/login.d.ts +16 -0
  28. package/dist/commands/login.js +58 -0
  29. package/dist/commands/login.js.map +1 -0
  30. package/dist/commands/pull.js +22 -0
  31. package/dist/commands/pull.js.map +1 -0
  32. package/dist/commands/push.js +56 -0
  33. package/dist/commands/push.js.map +1 -0
  34. package/dist/commands/sync.d.ts +20 -0
  35. package/dist/commands/sync.js +22 -0
  36. package/dist/commands/sync.js.map +1 -0
  37. package/dist/commands/translate.d.ts +14 -0
  38. package/dist/commands/translate.js +145 -0
  39. package/dist/commands/translate.js.map +1 -0
  40. package/dist/index.d.ts +5 -0
  41. package/dist/index.js +8 -0
  42. package/dist/index.js.map +1 -0
  43. package/dist/types/index.d.ts +75 -0
  44. package/dist/types/index.js +17 -0
  45. package/dist/types/index.js.map +1 -0
  46. package/dist/types/translate/index.js +2 -0
  47. package/dist/types/translate/index.js.map +1 -0
  48. package/dist/utils/auth.d.ts +2 -0
  49. package/dist/utils/auth.js +29 -0
  50. package/dist/utils/auth.js.map +1 -0
  51. package/dist/utils/common.js +9 -0
  52. package/dist/utils/common.js.map +1 -0
  53. package/dist/utils/config.d.ts +23 -0
  54. package/dist/utils/config.js +137 -0
  55. package/dist/utils/config.js.map +1 -0
  56. package/dist/utils/errors.js +37 -0
  57. package/dist/utils/errors.js.map +1 -0
  58. package/dist/utils/files.d.ts +32 -0
  59. package/dist/utils/files.js +347 -0
  60. package/dist/utils/files.js.map +1 -0
  61. package/dist/utils/git.d.ts +21 -0
  62. package/dist/utils/git.js +87 -0
  63. package/dist/utils/git.js.map +1 -0
  64. package/dist/utils/github.d.ts +241 -0
  65. package/dist/utils/github.js +161 -0
  66. package/dist/utils/github.js.map +1 -0
  67. package/dist/utils/import-service.d.ts +4 -0
  68. package/dist/utils/import-service.js +218 -0
  69. package/dist/utils/import-service.js.map +1 -0
  70. package/dist/utils/prompt-service.d.ts +44 -0
  71. package/dist/utils/prompt-service.js +104 -0
  72. package/dist/utils/prompt-service.js.map +1 -0
  73. package/dist/utils/sync-service.d.ts +58 -0
  74. package/dist/utils/sync-service.js +159 -0
  75. package/dist/utils/sync-service.js.map +1 -0
  76. package/dist/utils/translation-processor.js +197 -0
  77. package/dist/utils/translation-processor.js.map +1 -0
  78. package/dist/utils/translation-updater/common.d.ts +6 -0
  79. package/{src → dist}/utils/translation-updater/common.js +16 -10
  80. package/dist/utils/translation-updater/common.js.map +1 -0
  81. package/dist/utils/translation-updater/index.d.ts +5 -0
  82. package/{src → dist}/utils/translation-updater/index.js +21 -9
  83. package/dist/utils/translation-updater/index.js.map +1 -0
  84. package/dist/utils/translation-updater/json-handler.d.ts +5 -0
  85. package/{src → dist}/utils/translation-updater/json-handler.js +42 -31
  86. package/dist/utils/translation-updater/json-handler.js.map +1 -0
  87. package/dist/utils/translation-updater/yaml-handler.d.ts +5 -0
  88. package/{src → dist}/utils/translation-updater/yaml-handler.js +40 -41
  89. package/dist/utils/translation-updater/yaml-handler.js.map +1 -0
  90. package/dist/utils/translation-utils.d.ts +30 -0
  91. package/dist/utils/translation-utils.js +324 -0
  92. package/dist/utils/translation-utils.js.map +1 -0
  93. package/dist/utils/updater.js +38 -0
  94. package/dist/utils/updater.js.map +1 -0
  95. package/package.json +33 -28
  96. package/src/api/auth.js +0 -24
  97. package/src/api/client.js +0 -83
  98. package/src/api/imports.js +0 -22
  99. package/src/api/projects.js +0 -24
  100. package/src/api/translations.js +0 -58
  101. package/src/cli.js +0 -78
  102. package/src/commands/init.js +0 -485
  103. package/src/commands/login.js +0 -80
  104. package/src/commands/sync.js +0 -28
  105. package/src/commands/translate.js +0 -262
  106. package/src/utils/auth.js +0 -23
  107. package/src/utils/config.js +0 -125
  108. package/src/utils/files.js +0 -361
  109. package/src/utils/git.js +0 -72
  110. package/src/utils/github.js +0 -122
  111. package/src/utils/import-service.js +0 -129
  112. package/src/utils/prompt-service.js +0 -67
  113. package/src/utils/sync-service.js +0 -147
  114. package/src/utils/translation-utils.js +0 -237
@@ -0,0 +1,22 @@
1
+ import { syncService as defaultSyncService } from '../utils/sync-service.js';
2
+ import chalk from 'chalk';
3
+ export async function sync({ verbose = false } = {}, deps = { syncService: defaultSyncService }) {
4
+ const { syncService } = deps;
5
+ const { hasUpdates, updates } = await syncService.checkForUpdates(verbose);
6
+ if (!hasUpdates) {
7
+ console.log(chalk.green('✓ All translations are up to date'));
8
+ return;
9
+ }
10
+ const result = await syncService.applyUpdates(updates, verbose);
11
+ const { totalUpdates = 0, totalDeleted = 0 } = result;
12
+ if (!verbose) {
13
+ if (totalUpdates > 0) {
14
+ console.log(chalk.green(`✓ Updated ${totalUpdates} translations`));
15
+ }
16
+ if (totalDeleted > 0) {
17
+ console.log(chalk.green(`✓ Deleted ${totalDeleted} keys`));
18
+ }
19
+ }
20
+ return result;
21
+ }
22
+ //# sourceMappingURL=sync.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sync.js","sourceRoot":"","sources":["../../src/commands/sync.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,IAAI,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAC7E,OAAO,KAAK,MAAM,OAAO,CAAC;AAuB1B,MAAM,CAAC,KAAK,UAAU,IAAI,CACxB,EAAE,OAAO,GAAG,KAAK,KAA4B,EAAE,EAC/C,OAAyB,EAAE,WAAW,EAAE,kBAAkB,EAAE;IAE5D,MAAM,EAAE,WAAW,EAAE,GAAG,IAAI,CAAC;IAC7B,MAAM,EAAE,UAAU,EAAE,OAAO,EAAE,GAAG,MAAM,WAAW,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC;IAE3E,IAAI,CAAC,UAAU,EAAE,CAAC;QAChB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,mCAAmC,CAAC,CAAC,CAAC;QAC9D,OAAO;IACT,CAAC;IAED,MAAM,MAAM,GAAG,MAAM,WAAW,CAAC,YAAY,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IAEhE,MAAM,EAAE,YAAY,GAAG,CAAC,EAAE,YAAY,GAAG,CAAC,EAAE,GAAG,MAAM,CAAC;IAEtD,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,IAAI,YAAY,GAAG,CAAC,EAAE,CAAC;YACrB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,aAAa,YAAY,eAAe,CAAC,CAAC,CAAC;QACrE,CAAC;QAED,IAAI,YAAY,GAAG,CAAC,EAAE,CAAC;YACrB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,aAAa,YAAY,OAAO,CAAC,CAAC,CAAC;QAC7D,CAAC;IACH,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC"}
@@ -0,0 +1,14 @@
1
+ import { TranslateOptions } from '../types/index.js';
2
+ import { configService } from '../utils/config.js';
3
+ interface TranslateDependencies {
4
+ console?: Console;
5
+ basePath?: string;
6
+ configUtils?: typeof configService;
7
+ }
8
+ interface TranslateResult {
9
+ totalTranslated: number;
10
+ skipped: number;
11
+ errors: number;
12
+ }
13
+ export declare function translate({ verbose, commit }?: TranslateOptions, deps?: TranslateDependencies): Promise<TranslateResult>;
14
+ export {};
@@ -0,0 +1,145 @@
1
+ import chalk from 'chalk';
2
+ import { configService } from '../utils/config.js';
3
+ import { findTranslationFiles } from '../utils/files.js';
4
+ import { createTranslationJob, checkJobStatus } from '../api/translations.js';
5
+ import { updateTranslationFile } from '../utils/translation-updater/index.js';
6
+ import { checkAuth } from '../utils/auth.js';
7
+ import { findMissingTranslations, batchKeysWithMissing, findMissingTranslationsByLocale } from '../utils/translation-utils.js';
8
+ import { syncService } from '../utils/sync-service.js';
9
+ import { autoCommitChanges } from '../utils/github.js';
10
+ import { processTranslationBatches } from '../utils/translation-processor.js';
11
+ import { ApiResponseError } from '../types/index.js';
12
+ const defaultDeps = {
13
+ console,
14
+ configUtils: configService,
15
+ authUtils: { checkAuth },
16
+ fileUtils: { findTranslationFiles },
17
+ translationUtils: {
18
+ createTranslationJob,
19
+ checkJobStatus,
20
+ updateTranslationFile,
21
+ findMissingTranslations,
22
+ batchKeysWithMissing,
23
+ findMissingTranslationsByLocale
24
+ },
25
+ syncService,
26
+ gitUtils: { autoCommitChanges }
27
+ };
28
+ export async function translate(options = {}, deps = defaultDeps) {
29
+ const { console, configUtils, authUtils, fileUtils, translationUtils, syncService, gitUtils } = deps;
30
+ const { verbose } = options;
31
+ const isAuthenticated = await authUtils.checkAuth();
32
+ if (!isAuthenticated) {
33
+ console.error(chalk.red('\n✖ Your API key is invalid. Please run `npx @localheroai/cli login` to authenticate.\n'));
34
+ process.exit(1);
35
+ }
36
+ const config = await configUtils.getProjectConfig();
37
+ if (!config) {
38
+ console.error(chalk.red('\n✖ No configuration found. Please run `npx @localheroai/cli init` first.\n'));
39
+ process.exit(1);
40
+ return;
41
+ }
42
+ if (!config.translationFiles?.paths) {
43
+ console.error(chalk.red('\n✖ Invalid configuration: missing translationFiles.paths. Please run `npx @localheroai/cli init` to set up your configuration.\n'));
44
+ process.exit(1);
45
+ return;
46
+ }
47
+ const { hasUpdates, updates } = await syncService.checkForUpdates(verbose);
48
+ if (hasUpdates && updates) {
49
+ await syncService.applyUpdates(updates, verbose);
50
+ }
51
+ if (verbose) {
52
+ console.log(chalk.blue('\nℹ Using configuration:'));
53
+ console.log(chalk.gray(` Project ID: ${config.projectId}`));
54
+ console.log(chalk.gray(` Source locale: ${config.sourceLocale}`));
55
+ console.log(chalk.gray(` Output locales: ${config.outputLocales.join(', ')}`));
56
+ console.log(chalk.gray(` Translation files: ${config.translationFiles.paths.join(', ')}`));
57
+ }
58
+ const result = await fileUtils.findTranslationFiles(config, { verbose, returnFullResult: true });
59
+ const { sourceFiles, targetFilesByLocale, allFiles } = result;
60
+ if (!allFiles || allFiles.length === 0) {
61
+ console.error(chalk.red('\n✖ No translation files found in the specified paths.\n'));
62
+ process.exit(1);
63
+ }
64
+ if (verbose) {
65
+ console.log(chalk.blue(`\nℹ Found ${allFiles.length} translation files`));
66
+ }
67
+ if (sourceFiles.length === 0) {
68
+ console.error(chalk.red(`\n✖ No source files found for locale ${config.sourceLocale}\n`));
69
+ console.error(chalk.yellow('This could be due to one of the following issues:'));
70
+ console.error(chalk.yellow(` 1. No translation files with the source locale "${config.sourceLocale}" exist in the configured paths`));
71
+ console.error(chalk.yellow(' 2. The locale identifiers in your filenames don\'t match the expected pattern'));
72
+ console.error(chalk.yellow(' 3. There was an error parsing one or more files (check for syntax errors in YAML or JSON)\n'));
73
+ console.error(chalk.yellow('Try running with the --verbose flag for more detailed information.\n'));
74
+ process.exit(1);
75
+ }
76
+ if (verbose) {
77
+ console.log(chalk.blue(`ℹ Found ${sourceFiles.length} source files for locale ${config.sourceLocale}`));
78
+ }
79
+ const missingByLocale = translationUtils.findMissingTranslationsByLocale(sourceFiles, targetFilesByLocale, config, !!verbose, console);
80
+ const missingLocalesSummary = {};
81
+ Object.values(missingByLocale).forEach((data) => {
82
+ const { locale, keyCount = 0 } = data;
83
+ if (!missingLocalesSummary[locale]) {
84
+ missingLocalesSummary[locale] = { keyCount: 0, fileCount: 0 };
85
+ }
86
+ missingLocalesSummary[locale].keyCount += keyCount;
87
+ missingLocalesSummary[locale].fileCount += 1;
88
+ });
89
+ const missingLocales = Object.keys(missingLocalesSummary);
90
+ if (missingLocales.length === 0) {
91
+ console.log(chalk.green('✓ All translations are up to date'));
92
+ return;
93
+ }
94
+ if (verbose) {
95
+ console.log(chalk.blue('\nℹ Missing translations:'));
96
+ for (const [locale, data] of Object.entries(missingLocalesSummary)) {
97
+ console.log(chalk.gray(` ${locale}: ${data.keyCount} keys in ${data.fileCount} files`));
98
+ }
99
+ }
100
+ const { batches, errors } = translationUtils.batchKeysWithMissing(sourceFiles, missingByLocale);
101
+ if (errors.length > 0) {
102
+ console.error(chalk.red('\n✖ Errors occurred while preparing translation jobs:'));
103
+ for (const error of errors) {
104
+ console.error(chalk.red(` ${error.message}`));
105
+ }
106
+ process.exit(1);
107
+ }
108
+ try {
109
+ const translationResult = await processTranslationBatches(batches, missingByLocale, config, !!verbose, { console, translationUtils });
110
+ await configUtils.updateLastSyncedAt();
111
+ console.log(chalk.green('✓ Translations complete!'));
112
+ console.log(`» Updated ${translationResult.uniqueKeysTranslated.size} keys in ${translationResult.totalLanguages} languages`);
113
+ if (translationResult.uniqueKeysTranslated.size > 0) {
114
+ try {
115
+ gitUtils.autoCommitChanges(config.translationFiles.paths.join(' '));
116
+ }
117
+ catch (error) {
118
+ const err = error;
119
+ console.warn(chalk.yellow(`\nℹ Could not auto-commit changes: ${err.message}`));
120
+ }
121
+ }
122
+ if (translationResult.resultsBaseUrl && translationResult.allJobIds.length > 0) {
123
+ const jobIdsParam = translationResult.allJobIds.join(',');
124
+ console.log(`» View results at: ${translationResult.resultsBaseUrl}?job_ids=${jobIdsParam}`);
125
+ }
126
+ }
127
+ catch (error) {
128
+ if (error instanceof ApiResponseError) {
129
+ console.error(chalk.red(`\n✖ Error processing translation jobs: ${error.cliErrorMessage || error.message}`));
130
+ if (error.details) {
131
+ console.error(chalk.red(` ${error.details}`));
132
+ }
133
+ }
134
+ else {
135
+ // Handle any other type of error
136
+ const err = error;
137
+ console.error(chalk.red(`\n✖ Error processing translation jobs: ${err.message}\n`));
138
+ if (err.stack && process.env.DEBUG) {
139
+ console.error(chalk.dim(err.stack));
140
+ }
141
+ }
142
+ process.exit(1);
143
+ }
144
+ }
145
+ //# sourceMappingURL=translate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"translate.js","sourceRoot":"","sources":["../../src/commands/translate.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ export { login } from './commands/login.js';
2
+ export { sync } from './commands/sync.js';
3
+ export { configService } from './utils/config.js';
4
+ export { gitService } from './utils/git.js';
5
+ export * from './types/index.js';
package/dist/index.js ADDED
@@ -0,0 +1,8 @@
1
+ export { login } from './commands/login.js';
2
+ export { pull } from './commands/pull.js';
3
+ export { init } from './commands/init.js';
4
+ export { translate } from './commands/translate.js';
5
+ export { configService } from './utils/config.js';
6
+ export { gitService } from './utils/git.js';
7
+ export * from './types/index.js';
8
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,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,SAAS,EAAE,MAAM,yBAAyB,CAAC;AAEpD,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAClD,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAE5C,cAAc,kBAAkB,CAAC"}
@@ -0,0 +1,75 @@
1
+ export interface AuthConfig {
2
+ api_key: string;
3
+ last_verified: string;
4
+ }
5
+ export interface TranslationFile {
6
+ paths: string[];
7
+ ignore?: string[];
8
+ }
9
+ export interface ProjectConfig {
10
+ schemaVersion: string;
11
+ projectId: string;
12
+ sourceLocale: string;
13
+ outputLocales: string[];
14
+ translationFiles: TranslationFile;
15
+ lastSyncedAt: string | null;
16
+ }
17
+ export interface ApiError {
18
+ code: string;
19
+ message: string;
20
+ }
21
+ export interface Project {
22
+ id: string;
23
+ name: string;
24
+ }
25
+ export interface Organization {
26
+ name: string;
27
+ projects: Project[];
28
+ }
29
+ export interface VerifyApiKeyResult {
30
+ error?: ApiError;
31
+ organization?: Organization;
32
+ }
33
+ export interface TranslationOptions {
34
+ verbose?: boolean;
35
+ commit?: boolean;
36
+ }
37
+ export interface SyncOptions {
38
+ verbose?: boolean;
39
+ }
40
+ export interface FsDependencies {
41
+ readFile: (path: string, options: {
42
+ encoding: string;
43
+ }) => Promise<string>;
44
+ writeFile: (path: string, data: string, options?: any) => Promise<void>;
45
+ mkdir: (path: string, options?: any) => Promise<void>;
46
+ readdir: (path: string) => Promise<string[]>;
47
+ stat: (path: string) => Promise<any>;
48
+ access: (path: string, mode?: number) => Promise<void>;
49
+ }
50
+ export interface ConsoleDependencies {
51
+ log: (message?: any, ...optionalParams: any[]) => void;
52
+ error: (message?: any, ...optionalParams: any[]) => void;
53
+ warn: (message?: any, ...optionalParams: any[]) => void;
54
+ }
55
+ export interface ApiRequestOptions {
56
+ method?: string;
57
+ headers?: Record<string, string>;
58
+ body?: any;
59
+ apiKey?: string;
60
+ }
61
+ export interface ApiClientConfig {
62
+ baseUrl?: string;
63
+ apiKey?: string;
64
+ }
65
+ export interface TranslationData {
66
+ [locale: string]: {
67
+ [key: string]: string | TranslationData;
68
+ };
69
+ }
70
+ export interface TranslationUpdateResult {
71
+ added: number;
72
+ updated: number;
73
+ unchanged: number;
74
+ errors: string[];
75
+ }
@@ -0,0 +1,17 @@
1
+ // API Response Types
2
+ export class ApiResponseError extends Error {
3
+ cliErrorMessage;
4
+ code;
5
+ details;
6
+ data;
7
+ constructor(message) {
8
+ super(message);
9
+ this.name = 'ApiResponseError';
10
+ // These need to be initialized in the constructor
11
+ this.cliErrorMessage = message;
12
+ this.code = 'API_ERROR';
13
+ this.details = null;
14
+ this.data = null;
15
+ }
16
+ }
17
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AA2DA,qBAAqB;AACrB,MAAM,OAAO,gBAAiB,SAAQ,KAAK;IACzC,eAAe,CAAS;IACxB,IAAI,CAAS;IACb,OAAO,CAAa;IACpB,IAAI,CAAM;IAEV,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,kBAAkB,CAAC;QAC/B,kDAAkD;QAClD,IAAI,CAAC,eAAe,GAAG,OAAO,CAAC;QAC/B,IAAI,CAAC,IAAI,GAAG,WAAW,CAAC;QACxB,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;QACpB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;IACnB,CAAC;CACF"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/types/translate/index.ts"],"names":[],"mappings":""}
@@ -0,0 +1,2 @@
1
+ export function getApiKey(): Promise<string | undefined>;
2
+ export function checkAuth(): Promise<boolean>;
@@ -0,0 +1,29 @@
1
+ import { configService } from './config.js';
2
+ /**
3
+ * Gets the API key from environment variable or config file
4
+ * @returns The API key string or undefined if not found
5
+ */
6
+ export async function getApiKey() {
7
+ const envKey = process.env.LOCALHERO_API_KEY;
8
+ if (typeof envKey === 'string' && envKey.trim() !== '') {
9
+ return envKey;
10
+ }
11
+ const config = await configService.getAuthConfig();
12
+ return config?.api_key;
13
+ }
14
+ /**
15
+ * Checks if the user is authenticated with a valid API key
16
+ * @returns Boolean indicating if a valid API key was found
17
+ */
18
+ export async function checkAuth() {
19
+ try {
20
+ const apiKey = await getApiKey();
21
+ const isValidFormat = typeof apiKey === 'string' &&
22
+ /^tk_[a-f0-9]+$/.test(apiKey);
23
+ return isValidFormat;
24
+ }
25
+ catch {
26
+ return false;
27
+ }
28
+ }
29
+ //# sourceMappingURL=auth.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/utils/auth.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAG5C;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,SAAS;IAC7B,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC;IAC7C,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;QACvD,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,MAAM,MAAM,GAAsB,MAAM,aAAa,CAAC,aAAa,EAAE,CAAC;IACtE,OAAO,MAAM,EAAE,OAAO,CAAC;AACzB,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,SAAS;IAC7B,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,SAAS,EAAE,CAAC;QACjC,MAAM,aAAa,GAAG,OAAO,MAAM,KAAK,QAAQ;YAC9C,gBAAgB,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAEhC,OAAO,aAAa,CAAC;IACvB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Sleep for a specified number of milliseconds
3
+ * @param ms Number of milliseconds to sleep
4
+ * @returns Promise that resolves after the specified time
5
+ */
6
+ export function sleep(ms) {
7
+ return new Promise(resolve => setTimeout(resolve, ms));
8
+ }
9
+ //# sourceMappingURL=common.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"common.js","sourceRoot":"","sources":["../../src/utils/common.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,MAAM,UAAU,KAAK,CAAC,EAAU;IAC9B,OAAO,IAAI,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC;AACzD,CAAC"}
@@ -0,0 +1,23 @@
1
+ import { promises as fs } from 'fs';
2
+ import path from 'path';
3
+ import { AuthConfig, ProjectConfig } from '../types/index.js';
4
+ interface ConfigDependencies {
5
+ fs: typeof fs;
6
+ path: typeof path;
7
+ process: typeof process;
8
+ cwd: () => string;
9
+ }
10
+ interface ConfigService {
11
+ deps: ConfigDependencies;
12
+ setDependencies(customDeps?: Partial<ConfigDependencies>): ConfigService;
13
+ configFilePath(basePath?: string): string;
14
+ getAuthConfig(basePath?: string): Promise<AuthConfig | null>;
15
+ saveAuthConfig(config: AuthConfig, basePath?: string): Promise<void>;
16
+ getProjectConfig(basePath?: string): Promise<ProjectConfig | null>;
17
+ saveProjectConfig(config: Partial<ProjectConfig>, basePath?: string): Promise<void>;
18
+ validateProjectConfig(config: ProjectConfig): Promise<boolean>;
19
+ getValidProjectConfig(basePath?: string): Promise<ProjectConfig>;
20
+ updateLastSyncedAt(basePath?: string): Promise<ProjectConfig>;
21
+ }
22
+ export declare const configService: ConfigService;
23
+ export {};
@@ -0,0 +1,137 @@
1
+ import { promises as fs } from 'fs';
2
+ import path from 'path';
3
+ const AUTH_CONFIG_FILE = '.localhero_key';
4
+ const PROJECT_CONFIG_FILE = 'localhero.json';
5
+ const DEFAULT_PROJECT_CONFIG = {
6
+ schemaVersion: '1.0',
7
+ projectId: '',
8
+ sourceLocale: 'en',
9
+ outputLocales: [],
10
+ translationFiles: {
11
+ paths: [],
12
+ ignore: []
13
+ },
14
+ lastSyncedAt: null
15
+ };
16
+ const defaultDeps = {
17
+ fs,
18
+ path,
19
+ process,
20
+ cwd: process.cwd
21
+ };
22
+ export const configService = {
23
+ deps: { ...defaultDeps },
24
+ /**
25
+ * Set custom dependencies for testing
26
+ */
27
+ setDependencies(customDeps = {}) {
28
+ this.deps = { ...defaultDeps, ...customDeps };
29
+ return this;
30
+ },
31
+ /**
32
+ * Get the path to the config file
33
+ */
34
+ configFilePath(basePath) {
35
+ const { path } = this.deps;
36
+ const baseDir = basePath || this.deps.cwd();
37
+ return path.join(baseDir, PROJECT_CONFIG_FILE);
38
+ },
39
+ /**
40
+ * Get the authentication config
41
+ */
42
+ async getAuthConfig(basePath) {
43
+ const { fs, path } = this.deps;
44
+ const baseDir = basePath || this.deps.cwd();
45
+ try {
46
+ const configPath = path.join(baseDir, AUTH_CONFIG_FILE);
47
+ const content = await fs.readFile(configPath, 'utf8');
48
+ return JSON.parse(content);
49
+ }
50
+ catch {
51
+ return null;
52
+ }
53
+ },
54
+ /**
55
+ * Save the authentication config
56
+ */
57
+ async saveAuthConfig(config, basePath) {
58
+ const { fs, path } = this.deps;
59
+ const baseDir = basePath || this.deps.cwd();
60
+ const configPath = path.join(baseDir, AUTH_CONFIG_FILE);
61
+ await fs.writeFile(configPath, JSON.stringify(config, null, 2), {
62
+ mode: 0o600
63
+ });
64
+ },
65
+ /**
66
+ * Get the project config
67
+ */
68
+ async getProjectConfig(basePath) {
69
+ const { fs } = this.deps;
70
+ try {
71
+ const configPath = this.configFilePath(basePath);
72
+ const content = await fs.readFile(configPath, 'utf8');
73
+ const config = JSON.parse(content);
74
+ if (config.schemaVersion !== DEFAULT_PROJECT_CONFIG.schemaVersion) {
75
+ throw new Error(`Unsupported config schema version: ${config.schemaVersion}`);
76
+ }
77
+ return config;
78
+ }
79
+ catch (error) {
80
+ if (error.code === 'ENOENT') {
81
+ return null;
82
+ }
83
+ throw error;
84
+ }
85
+ },
86
+ /**
87
+ * Save the project config
88
+ */
89
+ async saveProjectConfig(config, basePath) {
90
+ const { fs } = this.deps;
91
+ const configPath = this.configFilePath(basePath);
92
+ const configWithSchema = {
93
+ ...DEFAULT_PROJECT_CONFIG,
94
+ ...config,
95
+ schemaVersion: DEFAULT_PROJECT_CONFIG.schemaVersion
96
+ };
97
+ await fs.writeFile(configPath, JSON.stringify(configWithSchema, null, 2));
98
+ },
99
+ /**
100
+ * Validate the project config
101
+ */
102
+ async validateProjectConfig(config) {
103
+ const required = ['projectId', 'sourceLocale', 'outputLocales', 'translationFiles'];
104
+ const missing = required.filter(key => !(key in config));
105
+ if (missing.length) {
106
+ throw new Error(`Missing required config: ${missing.join(', ')}. Run 'npx @localheroai/cli init' to set up your project.`);
107
+ }
108
+ if (!Array.isArray(config.outputLocales) || config.outputLocales.length === 0) {
109
+ throw new Error('outputLocales must be an array with at least one locale');
110
+ }
111
+ if (!config.translationFiles.paths || !Array.isArray(config.translationFiles.paths)) {
112
+ throw new Error('translationFiles.paths must be an array of paths');
113
+ }
114
+ return true;
115
+ },
116
+ /**
117
+ * Get the project config and validate it
118
+ */
119
+ async getValidProjectConfig(basePath) {
120
+ const config = await this.getProjectConfig(basePath);
121
+ if (!config) {
122
+ throw new Error('No project config found. Run `npx @localheroai/cli init` first');
123
+ }
124
+ await this.validateProjectConfig(config);
125
+ return config;
126
+ },
127
+ /**
128
+ * Update the lastSyncedAt field in the project config
129
+ */
130
+ async updateLastSyncedAt(basePath) {
131
+ const config = await this.getValidProjectConfig(basePath);
132
+ config.lastSyncedAt = new Date().toISOString();
133
+ await this.saveProjectConfig(config, basePath);
134
+ return config;
135
+ }
136
+ };
137
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/utils/config.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Custom error class for CLI errors that should exit the process
3
+ */
4
+ export class CliError extends Error {
5
+ exitCode;
6
+ constructor(message, exitCode = 1) {
7
+ super(message);
8
+ this.name = 'CliError';
9
+ this.exitCode = exitCode;
10
+ }
11
+ }
12
+ /**
13
+ * Create a new CLI error
14
+ * @param message Error message
15
+ * @param exitCode Optional exit code, defaults to 1
16
+ * @returns A new CliError
17
+ */
18
+ export function cliError(message, exitCode = 1) {
19
+ return new CliError(message, exitCode);
20
+ }
21
+ /**
22
+ * Handle a CLI error
23
+ * @param error The error to handle
24
+ * @param exitProcess Whether to exit the process (defaults to true)
25
+ * @returns The exit code if not exiting process
26
+ */
27
+ export function handleCliError(error, exitProcess = true) {
28
+ const isCliError = error instanceof CliError;
29
+ const exitCode = isCliError ? error.exitCode : 1;
30
+ const message = error instanceof Error ? error.message : String(error);
31
+ console.error(`\n✖ ${message}\n`);
32
+ if (exitProcess) {
33
+ process.exit(exitCode);
34
+ }
35
+ return exitCode;
36
+ }
37
+ //# sourceMappingURL=errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/utils/errors.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,OAAO,QAAS,SAAQ,KAAK;IACjC,QAAQ,CAAS;IAEjB,YAAY,OAAe,EAAE,WAAmB,CAAC;QAC/C,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,UAAU,CAAC;QACvB,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;IAC3B,CAAC;CACF;AAED;;;;;GAKG;AACH,MAAM,UAAU,QAAQ,CAAC,OAAe,EAAE,WAAmB,CAAC;IAC5D,OAAO,IAAI,QAAQ,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;AACzC,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,cAAc,CAAC,KAAc,EAAE,cAAuB,IAAI;IACxE,MAAM,UAAU,GAAG,KAAK,YAAY,QAAQ,CAAC;IAC7C,MAAM,QAAQ,GAAG,UAAU,CAAC,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;IACjD,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IAEvE,OAAO,CAAC,KAAK,CAAC,OAAO,OAAO,IAAI,CAAC,CAAC;IAElC,IAAI,WAAW,EAAE,CAAC;QAChB,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IACzB,CAAC;IAED,OAAO,QAAQ,CAAC;AAClB,CAAC"}
@@ -0,0 +1,32 @@
1
+ export function parseFile(content: any, format: any, filePath?: string): any;
2
+ export function extractLocaleFromPath(filePath: any, localeRegex: any, knownLocales?: any[]): any;
3
+ export function isValidLocale(locale: any): boolean;
4
+ export function flattenTranslations(obj: any, parentKey?: string): {};
5
+ export function findTranslationFiles(config: any, options?: {}): Promise<{
6
+ path: any;
7
+ format: string;
8
+ locale: any;
9
+ }[] | {
10
+ allFiles: {
11
+ path: any;
12
+ format: string;
13
+ locale: any;
14
+ }[];
15
+ sourceFiles: {
16
+ path: any;
17
+ format: string;
18
+ locale: any;
19
+ }[];
20
+ targetFilesByLocale: {};
21
+ }>;
22
+ export function unflattenTranslations(flatObj: any): {};
23
+ export function detectJsonFormat(obj: any): "nested" | "mixed" | "flat";
24
+ export function preserveJsonStructure(originalObj: any, newTranslations: any, format: any): any;
25
+ export function directoryExists(path: any, fsModule?: typeof fs): Promise<boolean>;
26
+ export function findFirstExistingPath(paths: any, fsModule?: typeof fs): Promise<any>;
27
+ export function getDirectoryContents(dir: any, fsModule?: typeof fs): Promise<{
28
+ files: string[];
29
+ jsonFiles: string[];
30
+ yamlFiles: string[];
31
+ } | null>;
32
+ import { promises as fs } from 'fs';