@localheroai/cli 0.0.5 → 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 (116) 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/dist/utils/translation-updater/json-handler.js +123 -0
  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/dist/utils/translation-updater/yaml-handler.js +180 -0
  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 +26 -26
  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 -267
  106. package/src/utils/auth.js +0 -23
  107. package/src/utils/config.js +0 -125
  108. package/src/utils/files.js +0 -381
  109. package/src/utils/git.js +0 -72
  110. package/src/utils/github.js +0 -128
  111. package/src/utils/import-service.js +0 -128
  112. package/src/utils/prompt-service.js +0 -67
  113. package/src/utils/sync-service.js +0 -147
  114. package/src/utils/translation-updater/json-handler.js +0 -111
  115. package/src/utils/translation-updater/yaml-handler.js +0 -207
  116. package/src/utils/translation-utils.js +0 -278
package/README CHANGED
@@ -79,7 +79,7 @@ Configure the CLI behavior with these environment variables:
79
79
  LocalHero.ai automatically translate your I18n files when you push changes. During the `init` command, you'll be prompted to set up GitHub Actions.
80
80
 
81
81
  1. Add your API key to your repository secrets:
82
- - Go to Settings > Secrets > Actions
82
+ - Go to Settings > Secrets and variables > Actions
83
83
  - Create a new secret named `LOCALHERO_API_KEY`
84
84
  - Add your API key as the value
85
85
 
@@ -0,0 +1,2 @@
1
+ import { VerifyApiKeyResult } from '../types/index.js';
2
+ export declare function verifyApiKey(apiKey: string): Promise<VerifyApiKeyResult>;
@@ -0,0 +1,28 @@
1
+ import { apiRequest } from './client.js';
2
+ import { ApiResponseError } from '../types/index.js';
3
+ export async function verifyApiKey(apiKey) {
4
+ try {
5
+ return await apiRequest('/api/v1/auth/verify', {
6
+ apiKey
7
+ });
8
+ }
9
+ catch (error) {
10
+ if (error instanceof ApiResponseError) {
11
+ return {
12
+ error: {
13
+ code: error.code,
14
+ message: error.message
15
+ }
16
+ };
17
+ }
18
+ return {
19
+ error: {
20
+ code: error.code || 'verification_failed',
21
+ message: error instanceof Error && error.message
22
+ ? error.message
23
+ : 'Failed to verify API key'
24
+ }
25
+ };
26
+ }
27
+ }
28
+ //# sourceMappingURL=auth.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/api/auth.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAWrD,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,MAAc;IAC/C,IAAI,CAAC;QACH,OAAO,MAAM,UAAU,CAAC,qBAAqB,EAAE;YAC7C,MAAM;SACP,CAAC,CAAC;IACL,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,KAAK,YAAY,gBAAgB,EAAE,CAAC;YACtC,OAAO;gBACL,KAAK,EAAE;oBACL,IAAI,EAAE,KAAK,CAAC,IAAI;oBAChB,OAAO,EAAE,KAAK,CAAC,OAAO;iBACvB;aACF,CAAC;QACJ,CAAC;QAED,OAAO;YACL,KAAK,EAAE;gBACL,IAAI,EAAG,KAAa,CAAC,IAAI,IAAI,qBAAqB;gBAClD,OAAO,EAAE,KAAK,YAAY,KAAK,IAAI,KAAK,CAAC,OAAO;oBAC9C,CAAC,CAAC,KAAK,CAAC,OAAO;oBACf,CAAC,CAAC,0BAA0B;aAC/B;SACF,CAAC;IACJ,CAAC;AACH,CAAC"}
@@ -0,0 +1,3 @@
1
+ import { ApiRequestOptions } from '../types/index.js';
2
+ export declare function getApiHost(): string;
3
+ export declare function apiRequest<T = any>(endpoint: string, options?: ApiRequestOptions): Promise<T>;
@@ -0,0 +1,80 @@
1
+ import { ApiResponseError } from '../types/index.js';
2
+ const DEFAULT_API_HOST = 'https://api.localhero.ai';
3
+ export function getApiHost() {
4
+ return process.env.LOCALHERO_API_HOST || DEFAULT_API_HOST;
5
+ }
6
+ function getNetworkErrorMessage(error) {
7
+ if (error.code === 'ECONNREFUSED') {
8
+ return `Unable to connect to ${getApiHost()}. Please check your internet connection and try again.`;
9
+ }
10
+ if (error.cause?.code === 'ENOTFOUND') {
11
+ return `Could not resolve host ${getApiHost()}. Please check your internet connection and try again.`;
12
+ }
13
+ if (error.cause?.code === 'ETIMEDOUT') {
14
+ return `Connection to ${getApiHost()} timed out. Please try again later.`;
15
+ }
16
+ return `Network error while connecting to ${getApiHost()}. Please check your internet connection and try again.`;
17
+ }
18
+ export async function apiRequest(endpoint, options = {}) {
19
+ const apiHost = getApiHost();
20
+ const url = `${apiHost}${endpoint}`;
21
+ const apiKey = process.env.LOCALHERO_API_KEY || options.apiKey;
22
+ const headers = {
23
+ 'Content-Type': 'application/json',
24
+ ...options.headers
25
+ };
26
+ if (apiKey) {
27
+ headers['Authorization'] = `Bearer ${apiKey}`;
28
+ }
29
+ const fetchOptions = {
30
+ method: options.method || 'GET',
31
+ headers,
32
+ };
33
+ if (options.body) {
34
+ fetchOptions.body = JSON.stringify(options.body);
35
+ }
36
+ let response;
37
+ try {
38
+ response = await fetch(url, fetchOptions);
39
+ }
40
+ catch (error) {
41
+ const networkError = error;
42
+ const message = getNetworkErrorMessage(networkError);
43
+ networkError.message = message;
44
+ networkError.cliErrorMessage = message;
45
+ throw networkError;
46
+ }
47
+ let data;
48
+ try {
49
+ data = await response.json();
50
+ }
51
+ catch (error) {
52
+ const parseError = error;
53
+ const message = 'Failed to parse API response';
54
+ parseError.message = message;
55
+ parseError.cliErrorMessage = message;
56
+ throw parseError;
57
+ }
58
+ if (!response.ok) {
59
+ if (response.status === 401 && data?.error?.code === 'invalid_api_key') {
60
+ const message = 'Your API key is invalid or has been revoked. Please run `npx @localheroai/cli login` to update your API key.';
61
+ const error = new ApiResponseError(message);
62
+ error.cliErrorMessage = message;
63
+ error.code = 'invalid_api_key';
64
+ error.data = data;
65
+ error.details = null;
66
+ throw error;
67
+ }
68
+ const message = Array.isArray(data?.errors)
69
+ ? data.errors.map((err) => typeof err === 'string' ? err : err.message).join(', ')
70
+ : data?.error?.message || 'API request failed';
71
+ const error = new ApiResponseError(message);
72
+ error.cliErrorMessage = message;
73
+ error.code = data?.error?.code || 'API_ERROR';
74
+ error.details = data?.error?.details || null;
75
+ error.data = data;
76
+ throw error;
77
+ }
78
+ return data;
79
+ }
80
+ //# sourceMappingURL=client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/api/client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ export function createImport({ projectId, translations }: {
2
+ projectId: any;
3
+ translations: any;
4
+ }): Promise<any>;
5
+ export function checkImportStatus(projectId: any, importId: any): Promise<any>;
@@ -0,0 +1,43 @@
1
+ import { getApiKey } from '../utils/auth.js';
2
+ import { apiRequest } from './client.js';
3
+ /**
4
+ * Create a new import of translations
5
+ * @param params Import parameters
6
+ * @returns The created import details
7
+ */
8
+ export async function createImport(params) {
9
+ const apiKey = await getApiKey();
10
+ const response = await apiRequest(`/api/v1/projects/${params.projectId}/imports`, {
11
+ method: 'POST',
12
+ body: {
13
+ translations: params.translations
14
+ },
15
+ apiKey
16
+ });
17
+ return response;
18
+ }
19
+ export async function bulkUpdateTranslations(params) {
20
+ const apiKey = await getApiKey();
21
+ const response = await apiRequest(`/api/v1/projects/${params.projectId}/imports`, {
22
+ method: 'PATCH',
23
+ body: {
24
+ translations: params.translations
25
+ },
26
+ apiKey
27
+ });
28
+ return response;
29
+ }
30
+ /**
31
+ * Check the status of an import
32
+ * @param projectId The ID of the project
33
+ * @param importId The ID of the import to check
34
+ * @returns The import status response
35
+ */
36
+ export async function checkImportStatus(projectId, importId) {
37
+ const apiKey = await getApiKey();
38
+ const response = await apiRequest(`/api/v1/projects/${projectId}/imports/${importId}`, {
39
+ apiKey
40
+ });
41
+ return response;
42
+ }
43
+ //# sourceMappingURL=imports.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"imports.js","sourceRoot":"","sources":["../../src/api/imports.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AA6CzC;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,MAA0B;IAC3D,MAAM,MAAM,GAAG,MAAM,SAAS,EAAE,CAAC;IACjC,MAAM,QAAQ,GAAG,MAAM,UAAU,CAAC,oBAAoB,MAAM,CAAC,SAAS,UAAU,EAAE;QAChF,MAAM,EAAE,MAAM;QACd,IAAI,EAAE;YACJ,YAAY,EAAE,MAAM,CAAC,YAAY;SAClC;QACD,MAAM;KACP,CAAC,CAAC;IACH,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAAC,MAAoC;IAC/E,MAAM,MAAM,GAAG,MAAM,SAAS,EAAE,CAAC;IACjC,MAAM,QAAQ,GAAG,MAAM,UAAU,CAAC,oBAAoB,MAAM,CAAC,SAAS,UAAU,EAAE;QAChF,MAAM,EAAE,OAAO;QACf,IAAI,EAAE;YACJ,YAAY,EAAE,MAAM,CAAC,YAAY;SAClC;QACD,MAAM;KACP,CAAC,CAAC;IACH,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,SAAiB,EAAE,QAAgB;IACzE,MAAM,MAAM,GAAG,MAAM,SAAS,EAAE,CAAC;IACjC,MAAM,QAAQ,GAAG,MAAM,UAAU,CAAC,oBAAoB,SAAS,YAAY,QAAQ,EAAE,EAAE;QACrF,MAAM;KACP,CAAC,CAAC;IACH,OAAO,QAAQ,CAAC;AAClB,CAAC"}
@@ -0,0 +1,2 @@
1
+ export function listProjects(): Promise<any>;
2
+ export function createProject(data: any): Promise<any>;
@@ -0,0 +1,42 @@
1
+ import { getApiKey } from '../utils/auth.js';
2
+ import { apiRequest } from './client.js';
3
+ /**
4
+ * List all projects the user has access to
5
+ * @returns Array of project details
6
+ */
7
+ export async function listProjects() {
8
+ const apiKey = await getApiKey();
9
+ const response = await apiRequest('/api/v1/projects', { apiKey });
10
+ return response.projects;
11
+ }
12
+ /**
13
+ * Create a new project
14
+ * @param data Project creation parameters
15
+ * @returns The created project details
16
+ */
17
+ export async function createProject(data) {
18
+ const apiKey = await getApiKey();
19
+ const response = await apiRequest('/api/v1/projects', {
20
+ method: 'POST',
21
+ body: {
22
+ project: {
23
+ name: data.name,
24
+ source_language: data.sourceLocale,
25
+ target_languages: data.targetLocales
26
+ }
27
+ },
28
+ apiKey
29
+ });
30
+ return response.project;
31
+ }
32
+ /**
33
+ * Get details for a specific project
34
+ * @param projectId The ID of the project to fetch
35
+ * @returns The project details
36
+ */
37
+ export async function getProject(projectId) {
38
+ const apiKey = await getApiKey();
39
+ const response = await apiRequest(`/api/v1/projects/${projectId}`, { apiKey });
40
+ return response.project;
41
+ }
42
+ //# sourceMappingURL=projects.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"projects.js","sourceRoot":"","sources":["../../src/api/projects.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAczC;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY;IAChC,MAAM,MAAM,GAAG,MAAM,SAAS,EAAE,CAAC;IACjC,MAAM,QAAQ,GAAG,MAAM,UAAU,CAAC,kBAAkB,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC;IAClE,OAAO,QAAQ,CAAC,QAAQ,CAAC;AAC3B,CAAC;AAWD;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,IAAyB;IAC3D,MAAM,MAAM,GAAG,MAAM,SAAS,EAAE,CAAC;IACjC,MAAM,QAAQ,GAAG,MAAM,UAAU,CAAC,kBAAkB,EAAE;QACpD,MAAM,EAAE,MAAM;QACd,IAAI,EAAE;YACJ,OAAO,EAAE;gBACP,IAAI,EAAE,IAAI,CAAC,IAAI;gBACf,eAAe,EAAE,IAAI,CAAC,YAAY;gBAClC,gBAAgB,EAAE,IAAI,CAAC,aAAa;aACrC;SACF;QACD,MAAM;KACP,CAAC,CAAC;IACH,OAAO,QAAQ,CAAC,OAAO,CAAC;AAC1B,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,SAAiB;IAChD,MAAM,MAAM,GAAG,MAAM,SAAS,EAAE,CAAC;IACjC,MAAM,QAAQ,GAAG,MAAM,UAAU,CAAC,oBAAoB,SAAS,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC;IAC/E,OAAO,QAAQ,CAAC,OAAO,CAAC;AAC1B,CAAC"}
@@ -0,0 +1,15 @@
1
+ export function createTranslationJob({ sourceFiles, targetLocales, projectId, targetPaths }: {
2
+ sourceFiles: any;
3
+ targetLocales: any;
4
+ projectId: any;
5
+ targetPaths: any;
6
+ }): Promise<{
7
+ jobs: any;
8
+ totalJobs: any;
9
+ }>;
10
+ export function checkJobStatus(jobId: any, includeTranslations?: boolean): Promise<any>;
11
+ export function getTranslations(jobId: any): Promise<any>;
12
+ export function getUpdates(projectId: any, { since, page }: {
13
+ since: any;
14
+ page?: number | undefined;
15
+ }): Promise<any>;
@@ -0,0 +1,71 @@
1
+ import { getApiKey } from '../utils/auth.js';
2
+ import { apiRequest } from './client.js';
3
+ import { getCurrentBranch } from '../utils/git.js';
4
+ /**
5
+ * Create a new translation job
6
+ * @param params Job parameters
7
+ * @returns The created translation jobs
8
+ */
9
+ export async function createTranslationJob(params) {
10
+ const apiKey = await getApiKey();
11
+ const branch = await getCurrentBranch();
12
+ const response = await apiRequest(`/api/v1/projects/${params.projectId}/translation_jobs`, {
13
+ method: 'POST',
14
+ body: {
15
+ target_languages: params.targetLocales,
16
+ files: params.sourceFiles.map(file => ({
17
+ path: file.path,
18
+ content: file.content,
19
+ format: file.format,
20
+ target_paths: params.targetPaths
21
+ })),
22
+ ...(branch && { branch })
23
+ },
24
+ apiKey
25
+ });
26
+ if (!response.jobs || !response.jobs.length) {
27
+ throw new Error('No translation jobs were created');
28
+ }
29
+ return {
30
+ jobs: response.jobs,
31
+ totalJobs: response.jobs.length
32
+ };
33
+ }
34
+ /**
35
+ * Check the status of a translation job
36
+ * @param jobId The ID of the job to check
37
+ * @param includeTranslations Whether to include translations in the response
38
+ * @returns The job status
39
+ */
40
+ export async function checkJobStatus(jobId, includeTranslations = false) {
41
+ const apiKey = await getApiKey();
42
+ const endpoint = `/api/v1/translation_jobs/${jobId}${includeTranslations ? '?include_translations=true' : ''}`;
43
+ return apiRequest(endpoint, { apiKey });
44
+ }
45
+ /**
46
+ * Get translations for a completed job
47
+ * @param jobId The ID of the job
48
+ * @returns The translations
49
+ */
50
+ export async function getTranslations(jobId) {
51
+ const apiKey = await getApiKey();
52
+ return apiRequest(`/api/v1/translation_jobs/${jobId}/translations`, { apiKey });
53
+ }
54
+ /**
55
+ * Get translation updates for a project
56
+ * @param projectId The ID of the project
57
+ * @param params Parameters for the request
58
+ * @returns The updates
59
+ */
60
+ export async function getUpdates(projectId, { since, page = 1 }) {
61
+ const apiKey = await getApiKey();
62
+ if (!since) {
63
+ throw new Error('Missing required parameter: since (ISO 8601 timestamp)');
64
+ }
65
+ const queryParams = new URLSearchParams({
66
+ since,
67
+ page: page.toString()
68
+ });
69
+ return apiRequest(`/api/v1/projects/${projectId}/updates?${queryParams}`, { apiKey });
70
+ }
71
+ //# sourceMappingURL=translations.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"translations.js","sourceRoot":"","sources":["../../src/api/translations.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AA+BnD;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,oBAAoB,CAAC,MAAkC;IAC3E,MAAM,MAAM,GAAG,MAAM,SAAS,EAAE,CAAC;IACjC,MAAM,MAAM,GAAG,MAAM,gBAAgB,EAAE,CAAC;IAExC,MAAM,QAAQ,GAAG,MAAM,UAAU,CAAC,oBAAoB,MAAM,CAAC,SAAS,mBAAmB,EAAE;QACzF,MAAM,EAAE,MAAM;QACd,IAAI,EAAE;YACJ,gBAAgB,EAAE,MAAM,CAAC,aAAa;YACtC,KAAK,EAAE,MAAM,CAAC,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;gBACrC,IAAI,EAAE,IAAI,CAAC,IAAI;gBACf,OAAO,EAAE,IAAI,CAAC,OAAO;gBACrB,MAAM,EAAE,IAAI,CAAC,MAAM;gBACnB,YAAY,EAAE,MAAM,CAAC,WAAW;aACjC,CAAC,CAAC;YACH,GAAG,CAAC,MAAM,IAAI,EAAE,MAAM,EAAE,CAAC;SAC1B;QACD,MAAM;KACP,CAAC,CAAC;IAEH,IAAI,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;QAC5C,MAAM,IAAI,KAAK,CAAC,kCAAkC,CAAC,CAAC;IACtD,CAAC;IAED,OAAO;QACL,IAAI,EAAE,QAAQ,CAAC,IAAI;QACnB,SAAS,EAAE,QAAQ,CAAC,IAAI,CAAC,MAAM;KAChC,CAAC;AACJ,CAAC;AAgBD;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAClC,KAAa,EACb,mBAAmB,GAAG,KAAK;IAE3B,MAAM,MAAM,GAAG,MAAM,SAAS,EAAE,CAAC;IACjC,MAAM,QAAQ,GAAG,4BAA4B,KAAK,GAAG,mBAAmB,CAAC,CAAC,CAAC,4BAA4B,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;IAC/G,OAAO,UAAU,CAAC,QAAQ,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC;AAC1C,CAAC;AAOD;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,KAAa;IACjD,MAAM,MAAM,GAAG,MAAM,SAAS,EAAE,CAAC;IACjC,OAAO,UAAU,CAAC,4BAA4B,KAAK,eAAe,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC;AAClF,CAAC;AA2BD;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAC9B,SAAiB,EACjB,EAAE,KAAK,EAAE,IAAI,GAAG,CAAC,EAAoB;IAErC,MAAM,MAAM,GAAG,MAAM,SAAS,EAAE,CAAC;IAEjC,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,MAAM,IAAI,KAAK,CAAC,wDAAwD,CAAC,CAAC;IAC5E,CAAC;IAED,MAAM,WAAW,GAAG,IAAI,eAAe,CAAC;QACtC,KAAK;QACL,IAAI,EAAE,IAAI,CAAC,QAAQ,EAAE;KACtB,CAAC,CAAC;IAEH,OAAO,UAAU,CAAC,oBAAoB,SAAS,YAAY,WAAW,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC;AACxF,CAAC"}
package/dist/cli.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};
package/dist/cli.js ADDED
@@ -0,0 +1,79 @@
1
+ #!/usr/bin/env node
2
+ import { Command } from 'commander';
3
+ import chalk from 'chalk';
4
+ import { readFileSync } from 'fs';
5
+ import { fileURLToPath } from 'url';
6
+ import { dirname, resolve } from 'path';
7
+ import { login } from './commands/login.js';
8
+ import { pull } from './commands/pull.js';
9
+ import { push } from './commands/push.js';
10
+ import { init } from './commands/init.js';
11
+ import { translate } from './commands/translate.js';
12
+ import { configService } from './utils/config.js';
13
+ const __filename = fileURLToPath(import.meta.url);
14
+ const __dirname = dirname(__filename);
15
+ const program = new Command();
16
+ function getVersion() {
17
+ const packageJson = JSON.parse(readFileSync(resolve(__dirname, '../package.json'), 'utf-8'));
18
+ return packageJson.version;
19
+ }
20
+ function handleApiError(error) {
21
+ console.error(chalk.red(`❌ ${error.cliErrorMessage || error.message}`));
22
+ if (program.opts().debug) {
23
+ console.error(chalk.dim(error.stack || error));
24
+ if (error.cause) {
25
+ console.error(chalk.dim(error.cause.stack || error.cause));
26
+ }
27
+ }
28
+ else {
29
+ console.error(chalk.dim('\nRun with --debug for more information'));
30
+ }
31
+ process.exit(1);
32
+ }
33
+ function wrapCommandAction(action) {
34
+ return function (...args) {
35
+ return Promise.resolve(action(...args)).catch(handleApiError);
36
+ };
37
+ }
38
+ program
39
+ .name('localhero')
40
+ .description('CLI tool for automatic I18n translations with LocalHero.ai, more info at https://localhero.ai.')
41
+ .version(getVersion())
42
+ .option('--debug', 'Show debug information when errors occur')
43
+ .action(() => {
44
+ console.log('LocalHero.ai is automatic I18n translations service that easily integrates with your dev workflow.');
45
+ console.log(`\nVersion: ${getVersion()}`);
46
+ console.log('\n🔗 Visit https://localhero.ai for more information');
47
+ console.log('👏 Set up your project with `npx @localheroai/cli init`');
48
+ console.log('💡 Use --help to see available commands');
49
+ });
50
+ program
51
+ .command('login')
52
+ .description('Authenticate with LocalHero.ai using an API key')
53
+ .action(wrapCommandAction(() => login()));
54
+ program
55
+ .command('init')
56
+ .description('Initialize a new LocalHero.ai project')
57
+ .action(wrapCommandAction(() => init()));
58
+ program
59
+ .command('translate')
60
+ .description('Translate missing keys in your i18n files')
61
+ .option('-v, --verbose', 'Show detailed progress information')
62
+ .option('-c, --commit', 'Automatically commit changes (useful for CI/CD)')
63
+ .action(wrapCommandAction((options) => translate(options)));
64
+ program
65
+ .command('pull')
66
+ .description('Pull updates from LocalHero.ai to your local files')
67
+ .option('-v, --verbose', 'Show detailed progress information')
68
+ .action(wrapCommandAction((options) => pull(options)));
69
+ program
70
+ .command('push')
71
+ .description('Push updates from your local files to LocalHero.ai')
72
+ .option('-v, --verbose', 'Show detailed progress information')
73
+ .option('-y, --yes', 'Skip confirmation prompt')
74
+ .action(wrapCommandAction(async (options) => {
75
+ const config = await configService.getValidProjectConfig();
76
+ return push(config, options);
77
+ }));
78
+ program.parse();
79
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
@@ -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.js"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,IAAI,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAC7E,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,MAAM,CAAC,KAAK,UAAU,IAAI,CAAC,EAAE,OAAO,GAAG,KAAK,EAAE,GAAG,EAAE,EAAE,IAAI,GAAG,EAAE,WAAW,EAAE,kBAAkB,EAAE;IAC7F,MAAM,EAAE,WAAW,EAAE,GAAG,IAAI,CAAC;IAC7B,MAAM,EAAE,UAAU,EAAE,OAAO,EAAE,GAAG,MAAM,WAAW,CAAC,eAAe,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC;IAE/E,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,EAAE,OAAO,EAAE,CAAC,CAAC;IAEpE,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,3 @@
1
+ // This is a compatibility wrapper for the TypeScript implementation
2
+ export { translate } from './translate.ts';
3
+ //# sourceMappingURL=_translate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"_translate.js","sourceRoot":"","sources":["../../src/commands/_translate.js"],"names":[],"mappings":"AAAA,oEAAoE;AACpE,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC"}
@@ -0,0 +1 @@
1
+ export function init(deps?: {}): Promise<void>;