@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,439 @@
|
|
|
1
|
+
import { promises as fs } from 'fs';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import chalk from 'chalk';
|
|
4
|
+
import { createPromptService } from '../utils/prompt-service.js';
|
|
5
|
+
import { createProject, listProjects } from '../api/projects.js';
|
|
6
|
+
import { configService } from '../utils/config.js';
|
|
7
|
+
import { checkAuth } from '../utils/auth.js';
|
|
8
|
+
import { login } from './login.js';
|
|
9
|
+
import { importService } from '../utils/import-service.js';
|
|
10
|
+
import { createGitHubActionFile, workflowExists } from '../utils/github.js';
|
|
11
|
+
import { directoryExists, findFirstExistingPath, getDirectoryContents } from '../utils/files.js';
|
|
12
|
+
import { verifyApiKey } from '../api/auth.js';
|
|
13
|
+
const PROJECT_TYPES = {
|
|
14
|
+
rails: {
|
|
15
|
+
directIndicators: ['config/application.rb', 'Gemfile'],
|
|
16
|
+
defaults: {
|
|
17
|
+
translationPath: 'config/locales/',
|
|
18
|
+
filePattern: '**/*.{yml,yaml}'
|
|
19
|
+
},
|
|
20
|
+
commonPaths: [
|
|
21
|
+
'config/locales'
|
|
22
|
+
]
|
|
23
|
+
},
|
|
24
|
+
nextjs: {
|
|
25
|
+
directIndicators: ['next.config.js', 'next.config.mjs'],
|
|
26
|
+
packageCheck: {
|
|
27
|
+
requires: ['next'],
|
|
28
|
+
oneOf: ['next-i18next', 'next-translate']
|
|
29
|
+
},
|
|
30
|
+
defaults: {
|
|
31
|
+
translationPath: 'public/locales/',
|
|
32
|
+
filePattern: '**/*.json'
|
|
33
|
+
},
|
|
34
|
+
commonPaths: [
|
|
35
|
+
'public/locales',
|
|
36
|
+
'src/locales',
|
|
37
|
+
'locales'
|
|
38
|
+
]
|
|
39
|
+
},
|
|
40
|
+
vueI18n: {
|
|
41
|
+
directIndicators: ['vue.config.js'],
|
|
42
|
+
packageCheck: {
|
|
43
|
+
oneOf: ['vue-i18n', '@nuxtjs/i18n']
|
|
44
|
+
},
|
|
45
|
+
defaults: {
|
|
46
|
+
translationPath: 'src/locales/',
|
|
47
|
+
filePattern: '**/*.json'
|
|
48
|
+
},
|
|
49
|
+
commonPaths: [
|
|
50
|
+
'src/locales',
|
|
51
|
+
'src/i18n',
|
|
52
|
+
'locales',
|
|
53
|
+
'i18n'
|
|
54
|
+
]
|
|
55
|
+
},
|
|
56
|
+
i18next: {
|
|
57
|
+
directIndicators: ['i18next.config.js', 'i18n.js', 'i18n/index.js'],
|
|
58
|
+
packageCheck: {
|
|
59
|
+
requires: ['i18next']
|
|
60
|
+
},
|
|
61
|
+
defaults: {
|
|
62
|
+
translationPath: 'public/locales/',
|
|
63
|
+
filePattern: '**/*.json'
|
|
64
|
+
},
|
|
65
|
+
commonPaths: [
|
|
66
|
+
'public/locales',
|
|
67
|
+
'src/locales',
|
|
68
|
+
'locales',
|
|
69
|
+
'src/i18n',
|
|
70
|
+
'i18n'
|
|
71
|
+
]
|
|
72
|
+
},
|
|
73
|
+
reactIntl: {
|
|
74
|
+
directIndicators: ['.babelrc'],
|
|
75
|
+
packageCheck: {
|
|
76
|
+
requires: ['react-intl']
|
|
77
|
+
},
|
|
78
|
+
defaults: {
|
|
79
|
+
translationPath: 'src/translations/',
|
|
80
|
+
filePattern: '**/*.json'
|
|
81
|
+
},
|
|
82
|
+
commonPaths: [
|
|
83
|
+
'src/i18n',
|
|
84
|
+
'src/translations',
|
|
85
|
+
'src/lang',
|
|
86
|
+
'src/locales',
|
|
87
|
+
'translations',
|
|
88
|
+
'locales'
|
|
89
|
+
]
|
|
90
|
+
},
|
|
91
|
+
gatsbyReact: {
|
|
92
|
+
directIndicators: ['gatsby-config.js'],
|
|
93
|
+
packageCheck: {
|
|
94
|
+
requires: ['gatsby'],
|
|
95
|
+
oneOf: ['gatsby-plugin-intl', 'gatsby-plugin-i18n']
|
|
96
|
+
},
|
|
97
|
+
defaults: {
|
|
98
|
+
translationPath: 'src/data/i18n/',
|
|
99
|
+
filePattern: '**/*.json'
|
|
100
|
+
},
|
|
101
|
+
commonPaths: [
|
|
102
|
+
'src/data/i18n',
|
|
103
|
+
'src/i18n',
|
|
104
|
+
'src/locales',
|
|
105
|
+
'locales'
|
|
106
|
+
]
|
|
107
|
+
},
|
|
108
|
+
react: {
|
|
109
|
+
directIndicators: ['src/App.js', 'src/App.jsx', 'src/index.js', 'src/index.jsx'],
|
|
110
|
+
packageCheck: {
|
|
111
|
+
requires: ['react']
|
|
112
|
+
},
|
|
113
|
+
defaults: {
|
|
114
|
+
translationPath: 'src/locales/',
|
|
115
|
+
filePattern: '**/*.{json,yml}'
|
|
116
|
+
},
|
|
117
|
+
commonPaths: [
|
|
118
|
+
'src/locales',
|
|
119
|
+
'public/locales',
|
|
120
|
+
'src/i18n',
|
|
121
|
+
'src/translations',
|
|
122
|
+
'src/lang',
|
|
123
|
+
'assets/i18n',
|
|
124
|
+
'locales'
|
|
125
|
+
]
|
|
126
|
+
},
|
|
127
|
+
generic: {
|
|
128
|
+
directIndicators: [],
|
|
129
|
+
defaults: {
|
|
130
|
+
translationPath: 'locales/',
|
|
131
|
+
filePattern: '**/*.{json,yml,yaml}'
|
|
132
|
+
},
|
|
133
|
+
commonPaths: [
|
|
134
|
+
'locales',
|
|
135
|
+
'src/locales',
|
|
136
|
+
'public/locales',
|
|
137
|
+
'src/i18n',
|
|
138
|
+
'src/translations',
|
|
139
|
+
'src/lang',
|
|
140
|
+
'assets/i18n',
|
|
141
|
+
'i18n',
|
|
142
|
+
'translations',
|
|
143
|
+
'lang'
|
|
144
|
+
]
|
|
145
|
+
}
|
|
146
|
+
};
|
|
147
|
+
async function checkPackageJson() {
|
|
148
|
+
try {
|
|
149
|
+
const content = await fs.readFile('package.json', 'utf8');
|
|
150
|
+
const pkg = JSON.parse(content);
|
|
151
|
+
return { ...pkg.dependencies, ...pkg.devDependencies };
|
|
152
|
+
}
|
|
153
|
+
catch {
|
|
154
|
+
return null;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
async function detectFramework(config) {
|
|
158
|
+
for (const indicator of config.directIndicators || []) {
|
|
159
|
+
try {
|
|
160
|
+
const stats = await fs.stat(indicator);
|
|
161
|
+
if (stats.isFile())
|
|
162
|
+
return true;
|
|
163
|
+
}
|
|
164
|
+
catch {
|
|
165
|
+
continue;
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
if (config.packageCheck) {
|
|
169
|
+
const deps = await checkPackageJson();
|
|
170
|
+
if (deps) {
|
|
171
|
+
const { requires = [], oneOf = [] } = config.packageCheck;
|
|
172
|
+
if (requires.length && !requires.every(pkg => deps[pkg])) {
|
|
173
|
+
return false;
|
|
174
|
+
}
|
|
175
|
+
if (oneOf.length && !oneOf.some(pkg => deps[pkg])) {
|
|
176
|
+
return false;
|
|
177
|
+
}
|
|
178
|
+
return true;
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
return false;
|
|
182
|
+
}
|
|
183
|
+
async function detectProjectType() {
|
|
184
|
+
for (const [type, config] of Object.entries(PROJECT_TYPES)) {
|
|
185
|
+
if (!config.directIndicators?.length && !config.packageCheck)
|
|
186
|
+
continue;
|
|
187
|
+
const isFramework = await detectFramework(config);
|
|
188
|
+
if (!isFramework)
|
|
189
|
+
continue;
|
|
190
|
+
if (config.commonPaths) {
|
|
191
|
+
const translationPath = await findFirstExistingPath(config.commonPaths);
|
|
192
|
+
if (translationPath) {
|
|
193
|
+
return {
|
|
194
|
+
type,
|
|
195
|
+
defaults: {
|
|
196
|
+
...config.defaults,
|
|
197
|
+
translationPath: `${translationPath}/`
|
|
198
|
+
}
|
|
199
|
+
};
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
return { type, defaults: config.defaults };
|
|
203
|
+
}
|
|
204
|
+
const commonPaths = PROJECT_TYPES.generic.commonPaths || [];
|
|
205
|
+
const translationPath = await findFirstExistingPath(commonPaths);
|
|
206
|
+
if (translationPath) {
|
|
207
|
+
const contents = await getDirectoryContents(translationPath);
|
|
208
|
+
if (contents) {
|
|
209
|
+
return {
|
|
210
|
+
type: 'detected',
|
|
211
|
+
defaults: {
|
|
212
|
+
translationPath: `${translationPath}/`,
|
|
213
|
+
filePattern: contents.jsonFiles.length > 0 && contents.yamlFiles.length === 0
|
|
214
|
+
? '**/*.json'
|
|
215
|
+
: '**/*.{json,yml,yaml}'
|
|
216
|
+
}
|
|
217
|
+
};
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
return {
|
|
221
|
+
type: 'generic',
|
|
222
|
+
defaults: PROJECT_TYPES.generic.defaults
|
|
223
|
+
};
|
|
224
|
+
}
|
|
225
|
+
async function promptForConfig(projectDefaults, projectService, promptService, console = global.console) {
|
|
226
|
+
const { choice: projectChoice, project: existingProject } = await promptService.selectProject(projectService);
|
|
227
|
+
if (!projectChoice) {
|
|
228
|
+
throw new Error('Project selection is required');
|
|
229
|
+
}
|
|
230
|
+
let projectId = projectChoice;
|
|
231
|
+
let newProject = null;
|
|
232
|
+
let config = await promptService.getProjectSetup();
|
|
233
|
+
if (!existingProject) {
|
|
234
|
+
config = {
|
|
235
|
+
projectName: await promptService.input({
|
|
236
|
+
message: 'Project name:',
|
|
237
|
+
default: path.basename(process.cwd()),
|
|
238
|
+
}),
|
|
239
|
+
sourceLocale: await promptService.input({
|
|
240
|
+
message: 'Source language - the language that we will translate from:',
|
|
241
|
+
default: 'en',
|
|
242
|
+
hint: 'Examples: "en" for en.json/en.yml, "en-US" for en-US.json, or directory name like "en" in /locales/en/common.json'
|
|
243
|
+
}),
|
|
244
|
+
outputLocales: (await promptService.input({
|
|
245
|
+
message: 'Target languages (comma-separated):',
|
|
246
|
+
hint: 'Must match your file names or directory names exactly. Examples: en.json → "en", fr-CA.json → "fr-CA", /locales/de/ → "de"'
|
|
247
|
+
})).split(',').map(lang => lang.trim()).filter(Boolean)
|
|
248
|
+
};
|
|
249
|
+
try {
|
|
250
|
+
newProject = await projectService.createProject({
|
|
251
|
+
name: config.projectName,
|
|
252
|
+
sourceLocale: config.sourceLocale,
|
|
253
|
+
targetLocales: config.outputLocales
|
|
254
|
+
});
|
|
255
|
+
projectId = newProject.id;
|
|
256
|
+
}
|
|
257
|
+
catch (error) {
|
|
258
|
+
console.log(chalk.red(`\n✗ Failed to create project: ${error.message}`));
|
|
259
|
+
return null;
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
else {
|
|
263
|
+
config = {
|
|
264
|
+
projectName: existingProject.name,
|
|
265
|
+
sourceLocale: existingProject.source_language,
|
|
266
|
+
outputLocales: existingProject.target_languages
|
|
267
|
+
};
|
|
268
|
+
}
|
|
269
|
+
const commonPaths = projectDefaults.defaults.commonPaths || PROJECT_TYPES.generic.commonPaths || [];
|
|
270
|
+
const existingDirs = [];
|
|
271
|
+
for (const dir of commonPaths) {
|
|
272
|
+
if (await directoryExists(dir)) {
|
|
273
|
+
existingDirs.push(dir);
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
let dirHint = `Directory containing your translation files for ${projectDefaults.type || 'your'} project`;
|
|
277
|
+
if (existingDirs.length > 0) {
|
|
278
|
+
dirHint += `. Found existing directories: ${existingDirs.map(d => `"${d}/"`).join(', ')}`;
|
|
279
|
+
}
|
|
280
|
+
else {
|
|
281
|
+
dirHint += `. Common paths: ${commonPaths.slice(0, 3).map(d => `"${d}/"`).join(', ')}`;
|
|
282
|
+
}
|
|
283
|
+
const translationPath = await promptService.input({
|
|
284
|
+
message: 'Translation files path:',
|
|
285
|
+
default: projectDefaults.defaults.translationPath,
|
|
286
|
+
hint: dirHint
|
|
287
|
+
});
|
|
288
|
+
let filePattern = projectDefaults.defaults.filePattern;
|
|
289
|
+
const contents = await getDirectoryContents(translationPath);
|
|
290
|
+
if (contents) {
|
|
291
|
+
if (contents.jsonFiles.length > 0 && contents.yamlFiles.length === 0) {
|
|
292
|
+
filePattern = '**/*.json';
|
|
293
|
+
}
|
|
294
|
+
else if (contents.jsonFiles.length === 0 && contents.yamlFiles.length > 0) {
|
|
295
|
+
filePattern = '**/*.{yml,yaml}';
|
|
296
|
+
}
|
|
297
|
+
else if (contents.jsonFiles.length > 0 && contents.yamlFiles.length > 0) {
|
|
298
|
+
filePattern = '**/*.{json,yml,yaml}';
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
const ignorePaths = await promptService.input({
|
|
302
|
+
message: 'Paths to ignore (comma-separated, leave empty for none):',
|
|
303
|
+
hint: 'Example: "locales/ignored,locales/temp"'
|
|
304
|
+
});
|
|
305
|
+
return {
|
|
306
|
+
projectId,
|
|
307
|
+
sourceLocale: config.sourceLocale,
|
|
308
|
+
outputLocales: config.outputLocales,
|
|
309
|
+
translationPath,
|
|
310
|
+
filePattern,
|
|
311
|
+
ignorePaths: ignorePaths.split(',').map(p => p.trim()).filter(Boolean),
|
|
312
|
+
newProject: !existingProject
|
|
313
|
+
};
|
|
314
|
+
}
|
|
315
|
+
export async function init(deps = {}) {
|
|
316
|
+
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;
|
|
317
|
+
const existingConfig = await configUtils.getProjectConfig(basePath);
|
|
318
|
+
if (existingConfig) {
|
|
319
|
+
console.log(chalk.yellow('Existing configuration found in localhero.json. Skipping initialization.'));
|
|
320
|
+
return;
|
|
321
|
+
}
|
|
322
|
+
const isAuthenticated = await authUtils.checkAuth();
|
|
323
|
+
if (!isAuthenticated) {
|
|
324
|
+
console.log('LocalHero.ai - Automate your i18n translations\n');
|
|
325
|
+
console.log(chalk.yellow('No API key found. Let\'s get you authenticated.'));
|
|
326
|
+
await loginFn({
|
|
327
|
+
console,
|
|
328
|
+
basePath,
|
|
329
|
+
promptService,
|
|
330
|
+
configUtils,
|
|
331
|
+
verifyApiKey,
|
|
332
|
+
isCalledFromInit: true
|
|
333
|
+
});
|
|
334
|
+
}
|
|
335
|
+
console.log('\nLet\'s set up configuration for your project.\n');
|
|
336
|
+
const projectDefaults = await detectProjectType();
|
|
337
|
+
const answers = await promptForConfig(projectDefaults, projectApi, promptService, console);
|
|
338
|
+
if (!answers) {
|
|
339
|
+
return;
|
|
340
|
+
}
|
|
341
|
+
const config = {
|
|
342
|
+
schemaVersion: '1.0',
|
|
343
|
+
projectId: answers.projectId,
|
|
344
|
+
sourceLocale: answers.sourceLocale,
|
|
345
|
+
outputLocales: answers.outputLocales,
|
|
346
|
+
translationFiles: {
|
|
347
|
+
paths: answers.translationPath ? [answers.translationPath] : [],
|
|
348
|
+
pattern: answers.filePattern || '**/*.{json,yml,yaml}',
|
|
349
|
+
ignore: answers.ignorePaths || []
|
|
350
|
+
},
|
|
351
|
+
lastSyncedAt: null
|
|
352
|
+
};
|
|
353
|
+
await configUtils.saveProjectConfig(config, basePath);
|
|
354
|
+
console.log(chalk.green('\n✓ Created localhero.json'));
|
|
355
|
+
if (answers.newProject) {
|
|
356
|
+
console.log(chalk.green(`✓ Project created, view it at: https://localhero.ai/projects/${answers.projectId}`));
|
|
357
|
+
}
|
|
358
|
+
console.log('Configuration:');
|
|
359
|
+
console.log(JSON.stringify(config, null, 2));
|
|
360
|
+
console.log(' ');
|
|
361
|
+
if (!workflowExists(basePath)) {
|
|
362
|
+
const shouldSetupGitHubAction = await promptService.confirm({
|
|
363
|
+
message: 'Would you like to set up GitHub Actions for automatic translations?',
|
|
364
|
+
default: true
|
|
365
|
+
});
|
|
366
|
+
if (shouldSetupGitHubAction) {
|
|
367
|
+
try {
|
|
368
|
+
const paths = answers.translationPath ? [answers.translationPath] : [''];
|
|
369
|
+
const workflowFile = await createGitHubActionFile(basePath, paths);
|
|
370
|
+
console.log(chalk.green(`\n✓ Created GitHub Action workflow at ${workflowFile}`));
|
|
371
|
+
console.log('\nNext steps:');
|
|
372
|
+
console.log('1. Add your API key to your repository\'s secrets:');
|
|
373
|
+
console.log(' - Go to Settings > Secrets and variables > Actions > New repository secret');
|
|
374
|
+
console.log(' - Name: LOCALHERO_API_KEY');
|
|
375
|
+
console.log(' - Value: [Your API Key] (find this at https://localhero.ai/api-keys or in your local .localhero_key file)');
|
|
376
|
+
console.log('\n2. Commit and push the workflow file to enable automatic translations\n');
|
|
377
|
+
}
|
|
378
|
+
catch (error) {
|
|
379
|
+
console.log(chalk.yellow('\nFailed to create GitHub Action workflow:'), error.message);
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
const shouldImport = await promptService.confirm({
|
|
384
|
+
message: 'Would you like to import existing translation files? (recommended)',
|
|
385
|
+
default: true
|
|
386
|
+
});
|
|
387
|
+
if (shouldImport) {
|
|
388
|
+
console.log('\nSearching for translation files in:');
|
|
389
|
+
console.log(`${config.translationFiles.paths.join(', ')}`);
|
|
390
|
+
try {
|
|
391
|
+
const importResult = await importUtils.importTranslations(config, basePath);
|
|
392
|
+
if (importResult.status === 'no_files') {
|
|
393
|
+
console.log(chalk.yellow('\nNo translation files found.'));
|
|
394
|
+
}
|
|
395
|
+
else if ((importResult.status === 'completed' || importResult.status === 'success') && importResult.statistics) {
|
|
396
|
+
console.log(chalk.green('\n✓ Successfully imported translations'));
|
|
397
|
+
console.log('\nImport summary:');
|
|
398
|
+
if (importResult.files) {
|
|
399
|
+
const sourceCount = importResult.files.source.length;
|
|
400
|
+
const targetCount = importResult.files.target.length;
|
|
401
|
+
console.log(`- ${sourceCount + targetCount} translation files imported`);
|
|
402
|
+
console.log(`- ${sourceCount} source files (${config.sourceLocale})`);
|
|
403
|
+
console.log(`- ${targetCount} target files (${config.outputLocales.join(', ')})`);
|
|
404
|
+
}
|
|
405
|
+
const stats = importResult.statistics;
|
|
406
|
+
if (stats) {
|
|
407
|
+
console.log(`- Total keys: ${stats.total_keys || 0}`);
|
|
408
|
+
if (Array.isArray(stats.languages)) {
|
|
409
|
+
const validLanguages = stats.languages.filter(lang => lang.code);
|
|
410
|
+
console.log(`- Languages: ${validLanguages.length}`);
|
|
411
|
+
validLanguages.forEach((lang) => {
|
|
412
|
+
console.log(` - ${lang.code}: ${lang.translated || 0} keys (${lang.missing || 0} missing)`);
|
|
413
|
+
});
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
if (importResult.warnings && importResult.warnings.length > 0) {
|
|
417
|
+
console.log(`\n${chalk.yellow('⚠')} Warnings:`);
|
|
418
|
+
importResult.warnings.forEach((warning) => {
|
|
419
|
+
const message = typeof warning === 'string' ? warning : warning.message || 'Unknown warning';
|
|
420
|
+
console.log(`- ${message}`);
|
|
421
|
+
});
|
|
422
|
+
}
|
|
423
|
+
if (importResult.translations_url) {
|
|
424
|
+
console.log(chalk.green(`\nView your translations at: ${importResult.translations_url}`));
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
else if (importResult.status === 'failed' || importResult.status === 'error') {
|
|
428
|
+
console.log(chalk.red('✗ Failed to import translations'));
|
|
429
|
+
console.log(chalk.red(`Error: ${importResult.error || 'Import failed'}`));
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
catch (error) {
|
|
433
|
+
console.log(chalk.red('✗ Failed to import translations'));
|
|
434
|
+
console.log(chalk.red(`Error: ${error.message || 'Import failed'}`));
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
console.log('\n🚀 Done! Start translating with: npx @localheroai/cli translate');
|
|
438
|
+
}
|
|
439
|
+
//# sourceMappingURL=init.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { createPromptService } from '../utils/prompt-service.js';
|
|
2
|
+
import { verifyApiKey as defaultVerifyApiKey } from '../api/auth.js';
|
|
3
|
+
import { configService } from '../utils/config.js';
|
|
4
|
+
interface LoginDependencies {
|
|
5
|
+
console?: Console;
|
|
6
|
+
basePath?: string;
|
|
7
|
+
promptService?: ReturnType<typeof createPromptService>;
|
|
8
|
+
verifyApiKey?: typeof defaultVerifyApiKey;
|
|
9
|
+
gitUtils?: {
|
|
10
|
+
updateGitignore: (path: string) => Promise<boolean>;
|
|
11
|
+
};
|
|
12
|
+
configUtils?: typeof configService;
|
|
13
|
+
isCalledFromInit?: boolean;
|
|
14
|
+
}
|
|
15
|
+
export declare function login(deps?: LoginDependencies): Promise<void>;
|
|
16
|
+
export {};
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
import { createPromptService } from '../utils/prompt-service.js';
|
|
3
|
+
import { updateGitignore } from '../utils/git.js';
|
|
4
|
+
import { verifyApiKey as defaultVerifyApiKey } from '../api/auth.js';
|
|
5
|
+
import { configService } from '../utils/config.js';
|
|
6
|
+
const API_KEY_PATTERN = /^tk_[a-zA-Z0-9]{48}$/;
|
|
7
|
+
export async function login(deps = {}) {
|
|
8
|
+
const { console = global.console, basePath = process.cwd(), promptService = createPromptService({ inquirer: await import('@inquirer/prompts') }), verifyApiKey = defaultVerifyApiKey, gitUtils = { updateGitignore }, configUtils = configService, isCalledFromInit = false } = deps;
|
|
9
|
+
const existingConfig = await configUtils.getAuthConfig(basePath);
|
|
10
|
+
if (existingConfig?.api_key) {
|
|
11
|
+
console.log(chalk.yellow('\n⚠️ Warning: This will replace your existing API key configuration'));
|
|
12
|
+
}
|
|
13
|
+
const apiKey = process.env.LOCALHERO_API_KEY || (console.log('\n→ Get your API key from: https://localhero.ai/api-keys'),
|
|
14
|
+
console.log('→ New to LocalHero? Sign up at: https://localhero.ai/signup'),
|
|
15
|
+
console.log('\nThe API key will be saved to .localhero_key, and automatically added to your .gitignore file.\n'),
|
|
16
|
+
await promptService.getApiKey());
|
|
17
|
+
if (!apiKey) {
|
|
18
|
+
throw new Error('User cancelled');
|
|
19
|
+
}
|
|
20
|
+
if (!API_KEY_PATTERN.test(apiKey)) {
|
|
21
|
+
throw new Error('Invalid API key format');
|
|
22
|
+
}
|
|
23
|
+
const result = await verifyApiKey(apiKey);
|
|
24
|
+
if (result.error) {
|
|
25
|
+
if (result.error.code === 'invalid_api_key') {
|
|
26
|
+
console.log(chalk.red('\n❌ ' + result.error.message));
|
|
27
|
+
console.log(chalk.blue('\nℹ️ Get a new API key at https://localhero.ai/api-keys'));
|
|
28
|
+
process.exit(1);
|
|
29
|
+
}
|
|
30
|
+
throw new Error(result.error.message);
|
|
31
|
+
}
|
|
32
|
+
const config = {
|
|
33
|
+
api_key: apiKey,
|
|
34
|
+
last_verified: new Date().toISOString()
|
|
35
|
+
};
|
|
36
|
+
await configUtils.saveAuthConfig(config, basePath);
|
|
37
|
+
const gitignoreUpdated = await gitUtils.updateGitignore(basePath);
|
|
38
|
+
console.log(chalk.green('\n✓ API key verified and saved to .localhero_key'));
|
|
39
|
+
if (gitignoreUpdated) {
|
|
40
|
+
console.log(chalk.green('✓ Added .localhero_key to .gitignore\n'));
|
|
41
|
+
}
|
|
42
|
+
const organization = result.organization;
|
|
43
|
+
console.log(chalk.blue(`💼️ Organization: ${organization.name}`));
|
|
44
|
+
if (organization.projects.length > 0) {
|
|
45
|
+
console.log(chalk.blue(`📚 Projects: ${organization.projects.map(p => p.name).join(', ')}`));
|
|
46
|
+
}
|
|
47
|
+
const projectConfig = await configUtils.getProjectConfig(basePath);
|
|
48
|
+
if (!projectConfig && !isCalledFromInit) {
|
|
49
|
+
console.log(chalk.yellow('\n⚠️ Almost there! You need to set up your project configuration.'));
|
|
50
|
+
console.log(chalk.blue('Run this next:'));
|
|
51
|
+
console.log(chalk.white('\n npx @localheroai/cli init\n'));
|
|
52
|
+
}
|
|
53
|
+
else if (!isCalledFromInit) {
|
|
54
|
+
console.log('\nYou\'re ready to start translating!');
|
|
55
|
+
console.log('Try running: npx @localheroai/cli translate');
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=login.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"login.js","sourceRoot":"","sources":["../../src/commands/login.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AACjE,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,EAAE,YAAY,IAAI,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AACrE,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAInD,MAAM,eAAe,GAAG,sBAAsB,CAAC;AAY/C,MAAM,CAAC,KAAK,UAAU,KAAK,CAAC,OAA0B,EAAE;IACtD,MAAM,EACJ,OAAO,GAAG,MAAM,CAAC,OAAO,EACxB,QAAQ,GAAG,OAAO,CAAC,GAAG,EAAE,EACxB,aAAa,GAAG,mBAAmB,CAAC,EAAE,QAAQ,EAAE,MAAM,MAAM,CAAC,mBAAmB,CAAC,EAAE,CAAC,EACpF,YAAY,GAAG,mBAAmB,EAClC,QAAQ,GAAG,EAAE,eAAe,EAAE,EAC9B,WAAW,GAAG,aAAa,EAC3B,gBAAgB,GAAG,KAAK,EACzB,GAAG,IAAI,CAAC;IAET,MAAM,cAAc,GAAG,MAAM,WAAW,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;IAEjE,IAAI,cAAc,EAAE,OAAO,EAAE,CAAC;QAC5B,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,sEAAsE,CAAC,CAAC,CAAC;IACpG,CAAC;IAED,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,iBAAiB,IAAI,CAC9C,OAAO,CAAC,GAAG,CAAC,0DAA0D,CAAC;QACvE,OAAO,CAAC,GAAG,CAAC,6DAA6D,CAAC;QAC1E,OAAO,CAAC,GAAG,CAAC,mGAAmG,CAAC;QAChH,MAAM,aAAa,CAAC,SAAS,EAAE,CAChC,CAAC;IAEF,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,IAAI,KAAK,CAAC,gBAAgB,CAAC,CAAC;IACpC,CAAC;IAED,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;QAClC,MAAM,IAAI,KAAK,CAAC,wBAAwB,CAAC,CAAC;IAC5C,CAAC;IAED,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,MAAM,CAAC,CAAC;IAE1C,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;QACjB,IAAI,MAAM,CAAC,KAAK,CAAC,IAAI,KAAK,iBAAiB,EAAE,CAAC;YAC5C,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC;YACtD,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,0DAA0D,CAAC,CAAC,CAAC;YACpF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QACD,MAAM,IAAI,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IACxC,CAAC;IAED,MAAM,MAAM,GAAe;QACzB,OAAO,EAAE,MAAM;QACf,aAAa,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;KACxC,CAAC;IAEF,MAAM,WAAW,CAAC,cAAc,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;IACnD,MAAM,gBAAgB,GAAG,MAAM,QAAQ,CAAC,eAAe,CAAC,QAAQ,CAAC,CAAC;IAElE,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,kDAAkD,CAAC,CAAC,CAAC;IAC7E,IAAI,gBAAgB,EAAE,CAAC;QACrB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,wCAAwC,CAAC,CAAC,CAAC;IACrE,CAAC;IAED,MAAM,YAAY,GAAG,MAAM,CAAC,YAA4B,CAAC;IACzD,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,sBAAsB,YAAY,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;IACnE,IAAI,YAAY,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACrC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,iBAAiB,YAAY,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;IAChG,CAAC;IAED,MAAM,aAAa,GAAG,MAAM,WAAW,CAAC,gBAAgB,CAAC,QAAQ,CAAC,CAAC;IAEnE,IAAI,CAAC,aAAa,IAAI,CAAC,gBAAgB,EAAE,CAAC;QACxC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,oEAAoE,CAAC,CAAC,CAAC;QAChG,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC,CAAC;QAC1C,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,iCAAiC,CAAC,CAAC,CAAC;IAC9D,CAAC;SAAM,IAAI,CAAC,gBAAgB,EAAE,CAAC;QAC7B,OAAO,CAAC,GAAG,CAAC,uCAAuC,CAAC,CAAC;QACrD,OAAO,CAAC,GAAG,CAAC,6CAA6C,CAAC,CAAC;IAC7D,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { syncService as defaultSyncService } from '../utils/sync-service.js';
|
|
2
|
+
import chalk from 'chalk';
|
|
3
|
+
export async function pull({ 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=pull.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pull.js","sourceRoot":"","sources":["../../src/commands/pull.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,56 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
import { importService as defaultImportService } from '../utils/import-service.js';
|
|
3
|
+
import { createPromptService } from '../utils/prompt-service.js';
|
|
4
|
+
import inquirer from 'inquirer';
|
|
5
|
+
const defaultPromptService = createPromptService({
|
|
6
|
+
inquirer: {
|
|
7
|
+
password: async (options) => inquirer.prompt([{ type: 'password', name: 'value', ...options }]).then(r => r.value),
|
|
8
|
+
select: async (options) => inquirer.prompt([{ type: 'list', name: 'value', ...options }]).then(r => r.value),
|
|
9
|
+
input: async (options) => inquirer.prompt([{ type: 'input', name: 'value', ...options }]).then(r => r.value),
|
|
10
|
+
confirm: async (options) => inquirer.prompt([{ type: 'confirm', name: 'value', ...options }]).then(r => r.value)
|
|
11
|
+
}
|
|
12
|
+
});
|
|
13
|
+
export async function push(config, options = {}, deps = {
|
|
14
|
+
importService: defaultImportService,
|
|
15
|
+
prompt: defaultPromptService,
|
|
16
|
+
console: console
|
|
17
|
+
}) {
|
|
18
|
+
const { verbose = false, yes = false } = options;
|
|
19
|
+
const { importService, prompt, console: consoleLog = console } = deps;
|
|
20
|
+
if (!yes) {
|
|
21
|
+
const confirmed = await prompt.confirm({
|
|
22
|
+
message: 'This will push your local translations to LocalHero.ai.\nYour changes will be versioned in the API for easy tracking.\nContinue?',
|
|
23
|
+
default: true
|
|
24
|
+
});
|
|
25
|
+
if (!confirmed) {
|
|
26
|
+
consoleLog.log(chalk.yellow('Push cancelled'));
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
const result = await importService.pushTranslations(config);
|
|
31
|
+
if (result.status === 'no_files') {
|
|
32
|
+
consoleLog.log(chalk.yellow('No translation files found'));
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
if (result.status === 'failed') {
|
|
36
|
+
throw new Error(result.error || 'Failed to push translations');
|
|
37
|
+
}
|
|
38
|
+
if (verbose) {
|
|
39
|
+
if (result.files?.target.length) {
|
|
40
|
+
consoleLog.log(chalk.green(`✓ Found ${result.files.target.length} translation files`));
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
const { statistics } = result;
|
|
44
|
+
if (statistics && (statistics.updated_translations > 0 || statistics.created_translations > 0)) {
|
|
45
|
+
if (statistics.updated_translations > 0) {
|
|
46
|
+
consoleLog.log(chalk.green(`✓ Updated ${statistics.updated_translations} translations`));
|
|
47
|
+
}
|
|
48
|
+
if (statistics.created_translations > 0) {
|
|
49
|
+
consoleLog.log(chalk.green(`✓ Added ${statistics.created_translations} new translations`));
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
else {
|
|
53
|
+
consoleLog.log(chalk.green('✓ No translations changes detected'));
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=push.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"push.js","sourceRoot":"","sources":["../../src/commands/push.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { SyncOptions } from '../types/index.js';
|
|
2
|
+
interface SyncResult {
|
|
3
|
+
totalUpdates?: number;
|
|
4
|
+
totalDeleted?: number;
|
|
5
|
+
[key: string]: any;
|
|
6
|
+
}
|
|
7
|
+
import type { CheckUpdatesResult, UpdatesContainer } from '../utils/sync-service.js';
|
|
8
|
+
interface SyncServiceInterface {
|
|
9
|
+
checkForUpdates: (options: {
|
|
10
|
+
verbose?: boolean;
|
|
11
|
+
}) => Promise<CheckUpdatesResult>;
|
|
12
|
+
applyUpdates: (updates: UpdatesContainer, options: {
|
|
13
|
+
verbose?: boolean;
|
|
14
|
+
}) => Promise<SyncResult>;
|
|
15
|
+
}
|
|
16
|
+
interface SyncDependencies {
|
|
17
|
+
syncService: SyncServiceInterface;
|
|
18
|
+
}
|
|
19
|
+
export declare function sync({ verbose }?: SyncOptions, deps?: SyncDependencies): Promise<SyncResult | void>;
|
|
20
|
+
export {};
|