@dittowords/cli 4.0.0 → 4.1.0-alpha
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.md +29 -364
- package/bin/config.js +5 -3
- package/bin/config.js.map +1 -1
- package/bin/generate-swift-struct.js +6 -0
- package/bin/generate-swift-struct.js.map +1 -0
- package/bin/http/fetchComponentFolders.js +3 -3
- package/bin/http/fetchComponentFolders.js.map +1 -1
- package/bin/http/fetchComponents.js +13 -5
- package/bin/http/fetchComponents.js.map +1 -1
- package/bin/http/fetchVariants.js +3 -3
- package/bin/http/fetchVariants.js.map +1 -1
- package/bin/init/project.js +3 -3
- package/bin/init/project.js.map +1 -1
- package/bin/pull.js +82 -38
- package/bin/pull.js.map +1 -1
- package/bin/pull.test.js +26 -24
- package/bin/pull.test.js.map +1 -1
- package/bin/types.js +2 -2
- package/bin/types.js.map +1 -1
- package/bin/utils/determineModuleType.js +80 -0
- package/bin/utils/determineModuleType.js.map +1 -0
- package/bin/utils/generateIOSBundles.js +147 -0
- package/bin/utils/generateIOSBundles.js.map +1 -0
- package/bin/utils/generateJsDriver.js +117 -58
- package/bin/utils/generateJsDriver.js.map +1 -1
- package/bin/utils/generateJsDriverTypeFile.js +105 -0
- package/bin/utils/generateJsDriverTypeFile.js.map +1 -0
- package/bin/utils/generateSwiftDriver.js +93 -0
- package/bin/utils/generateSwiftDriver.js.map +1 -0
- package/lib/config.ts +4 -0
- package/lib/http/fetchComponentFolders.ts +1 -1
- package/lib/http/fetchComponents.ts +14 -9
- package/lib/http/fetchVariants.ts +1 -1
- package/lib/init/project.ts +1 -1
- package/lib/pull.test.ts +24 -22
- package/lib/pull.ts +106 -55
- package/lib/types.ts +4 -0
- package/lib/utils/determineModuleType.ts +57 -0
- package/lib/utils/generateIOSBundles.ts +122 -0
- package/lib/utils/generateJsDriver.ts +156 -51
- package/lib/utils/generateJsDriverTypeFile.ts +75 -0
- package/lib/utils/generateSwiftDriver.ts +48 -0
- package/package.json +1 -1
package/bin/init/project.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:{},n=(new Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="
|
|
2
|
+
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:{},n=(new Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="f3a681ac-5186-5e65-b87b-f6b400899ab3")}catch(e){}}();
|
|
3
3
|
|
|
4
4
|
var __create = Object.create;
|
|
5
5
|
var __defProp = Object.defineProperty;
|
|
@@ -92,7 +92,7 @@ function listProjects(token, projectsAlreadySelected) {
|
|
|
92
92
|
spinner.start();
|
|
93
93
|
let response;
|
|
94
94
|
try {
|
|
95
|
-
response = yield api.get("/
|
|
95
|
+
response = yield api.get("/v1/projects");
|
|
96
96
|
} catch (e) {
|
|
97
97
|
spinner.stop();
|
|
98
98
|
throw e;
|
|
@@ -179,4 +179,4 @@ var project_default = { needsSource, collectAndSaveSource };
|
|
|
179
179
|
});
|
|
180
180
|
//# sourceMappingURL=project.js.map
|
|
181
181
|
|
|
182
|
-
//# debugId=
|
|
182
|
+
//# debugId=f3a681ac-5186-5e65-b87b-f6b400899ab3
|
package/bin/init/project.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../lib/init/project.ts"],"sourcesContent":["import ora from \"ora\";\n\nimport { createApiClient } from \"../api\";\nimport config from \"../config\";\nimport consts from \"../consts\";\nimport output from \"../output\";\nimport { collectAndSaveToken } from \"./token\";\nimport {\n getSelectedProjects,\n getIsUsingComponents,\n} from \"../utils/getSelectedProjects\";\nimport promptForProject from \"../utils/promptForProject\";\nimport { AxiosResponse } from \"axios\";\nimport { Project, Token } from \"../types\";\nimport { quit } from \"../utils/quit\";\n\nfunction saveProject(file: string, name: string, id: string) {\n if (id === \"components\") {\n config.writeProjectConfigData(file, {\n sources: { components: true },\n });\n return;\n }\n\n const projects = [...getSelectedProjects(file), { name, id }];\n config.writeProjectConfigData(file, { sources: { projects } });\n}\n\nexport const needsSource = () => {\n return !config.parseSourceInformation().hasSourceData;\n};\n\nasync function askForAnotherToken() {\n config.deleteToken(consts.CONFIG_FILE, consts.API_HOST);\n const message =\n \"Looks like the API key you have saved no longer works. Please enter another one.\";\n await collectAndSaveToken(message);\n}\n\nasync function listProjects(token: Token, projectsAlreadySelected: Project[]) {\n const api = createApiClient();\n const spinner = ora(\"Fetching sources in your workspace...\");\n spinner.start();\n\n let response: AxiosResponse<{ id: string; name: string }[]>;\n try {\n response = await api.get(\"/
|
|
1
|
+
{"version":3,"sources":["../../lib/init/project.ts"],"sourcesContent":["import ora from \"ora\";\n\nimport { createApiClient } from \"../api\";\nimport config from \"../config\";\nimport consts from \"../consts\";\nimport output from \"../output\";\nimport { collectAndSaveToken } from \"./token\";\nimport {\n getSelectedProjects,\n getIsUsingComponents,\n} from \"../utils/getSelectedProjects\";\nimport promptForProject from \"../utils/promptForProject\";\nimport { AxiosResponse } from \"axios\";\nimport { Project, Token } from \"../types\";\nimport { quit } from \"../utils/quit\";\n\nfunction saveProject(file: string, name: string, id: string) {\n if (id === \"components\") {\n config.writeProjectConfigData(file, {\n sources: { components: true },\n });\n return;\n }\n\n const projects = [...getSelectedProjects(file), { name, id }];\n config.writeProjectConfigData(file, { sources: { projects } });\n}\n\nexport const needsSource = () => {\n return !config.parseSourceInformation().hasSourceData;\n};\n\nasync function askForAnotherToken() {\n config.deleteToken(consts.CONFIG_FILE, consts.API_HOST);\n const message =\n \"Looks like the API key you have saved no longer works. Please enter another one.\";\n await collectAndSaveToken(message);\n}\n\nasync function listProjects(token: Token, projectsAlreadySelected: Project[]) {\n const api = createApiClient();\n const spinner = ora(\"Fetching sources in your workspace...\");\n spinner.start();\n\n let response: AxiosResponse<{ id: string; name: string }[]>;\n try {\n response = await api.get(\"/v1/projects\");\n } catch (e) {\n spinner.stop();\n throw e;\n }\n\n const projectsAlreadySelectedSet = projectsAlreadySelected.reduce(\n (set, project) => set.add(project.id.toString()),\n new Set<string>()\n );\n\n const result = response.data.filter(\n ({ id }) =>\n // covers an edge case where v0 of the API includes the component library\n // in the response from the `/project-names` endpoint\n id !== \"ditto_component_library\" &&\n !projectsAlreadySelectedSet.has(id.toString())\n );\n\n spinner.stop();\n\n return result;\n}\n\nasync function collectSource(token: Token, includeComponents: boolean) {\n const projectsAlreadySelected = getSelectedProjects();\n const componentSourceSelected = getIsUsingComponents();\n\n let sources = await listProjects(token, projectsAlreadySelected);\n if (includeComponents && !componentSourceSelected) {\n sources = [\n { id: \"ditto_component_library\", name: \"Ditto Component Library\" },\n ...sources,\n ];\n }\n\n if (!sources?.length) {\n console.log(\"You're currently syncing all projects in your workspace.\");\n console.log(\n output.warnText(\n \"Not seeing a project that you were expecting? Verify that developer mode is enabled on that project. More info: https://www.dittowords.com/docs/ditto-developer-mode\"\n )\n );\n return null;\n }\n\n return promptForProject({\n projects: sources,\n message: \"Choose the source you'd like to sync text from\",\n });\n}\n\nexport const collectAndSaveSource = async (\n { components = false }: { initialize?: boolean; components?: boolean } = {\n components: false,\n }\n) => {\n try {\n const token = config.getToken(consts.CONFIG_FILE, consts.API_HOST);\n const project = await collectSource(token, components);\n if (!project) {\n quit(null, 0);\n return;\n }\n\n console.log(\n \"\\n\" +\n `Thanks for adding ${output.info(\n project.name\n )} to your selected sources.\\n` +\n `We saved your updated configuration to: ${output.info(\n consts.PROJECT_CONFIG_FILE\n )}\\n`\n );\n\n saveProject(consts.PROJECT_CONFIG_FILE, project.name, project.id);\n } catch (e: any) {\n console.log(e);\n if (e.response && e.response.status === 404) {\n await askForAnotherToken();\n await collectAndSaveSource({ components });\n } else {\n quit(null, 2);\n }\n }\n};\n\nexport const _testing = { saveProject, needsSource };\n\nexport default { needsSource, collectAndSaveSource };\n"],"names":["config","consts","ora","output","promptForProject"],"mappings":"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","debug_id":"f3a681ac-5186-5e65-b87b-f6b400899ab3"}
|
package/bin/pull.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:{},n=(new Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="
|
|
2
|
+
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:{},n=(new Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="9f70f849-9f7e-59ce-9f0a-51c26028e270")}catch(e){}}();
|
|
3
3
|
|
|
4
4
|
var __create = Object.create;
|
|
5
5
|
var __defProp = Object.defineProperty;
|
|
@@ -66,7 +66,8 @@ var pull_exports = {};
|
|
|
66
66
|
__export(pull_exports, {
|
|
67
67
|
default: () => pull_default,
|
|
68
68
|
getFormatDataIsValid: () => getFormatDataIsValid,
|
|
69
|
-
pull: () => pull
|
|
69
|
+
pull: () => pull,
|
|
70
|
+
writeFile: () => writeFile
|
|
70
71
|
});
|
|
71
72
|
module.exports = __toCommonJS(pull_exports);
|
|
72
73
|
var import_fs = __toESM(require("fs"));
|
|
@@ -85,6 +86,8 @@ var import_fetchVariants = require("./http/fetchVariants");
|
|
|
85
86
|
var import_quit = require("./utils/quit");
|
|
86
87
|
var import_axios = require("axios");
|
|
87
88
|
var import_fetchComponentFolders = require("./http/fetchComponentFolders");
|
|
89
|
+
var import_generateSwiftDriver = require("./utils/generateSwiftDriver");
|
|
90
|
+
var import_generateIOSBundles = require("./utils/generateIOSBundles");
|
|
88
91
|
const ensureEndsWithNewLine = (str) => str + (/[\r\n]$/.test(str) ? "" : "\n");
|
|
89
92
|
const writeFile = (path2, data) => new Promise((r) => import_fs.default.writeFile(path2, ensureEndsWithNewLine(data), r));
|
|
90
93
|
const SUPPORTED_FORMATS = [
|
|
@@ -95,7 +98,14 @@ const SUPPORTED_FORMATS = [
|
|
|
95
98
|
"ios-stringsdict",
|
|
96
99
|
"icu"
|
|
97
100
|
];
|
|
101
|
+
const IOS_FORMATS = ["ios-strings", "ios-stringsdict"];
|
|
98
102
|
const JSON_FORMATS = ["flat", "structured", "icu"];
|
|
103
|
+
const getJsonFormat = (formats) => {
|
|
104
|
+
const jsonFormats = formats.filter(
|
|
105
|
+
(f) => JSON_FORMATS.includes(f)
|
|
106
|
+
);
|
|
107
|
+
return jsonFormats[jsonFormats.length - 1] || "flat";
|
|
108
|
+
};
|
|
99
109
|
const FORMAT_EXTENSIONS = {
|
|
100
110
|
flat: ".json",
|
|
101
111
|
structured: ".json",
|
|
@@ -146,8 +156,9 @@ function askForAnotherToken() {
|
|
|
146
156
|
yield (0, import_token.collectAndSaveToken)(message);
|
|
147
157
|
});
|
|
148
158
|
}
|
|
149
|
-
function downloadAndSaveVariant(variantApiId,
|
|
159
|
+
function downloadAndSaveVariant(variantApiId, requestOptions) {
|
|
150
160
|
return __async(this, null, function* () {
|
|
161
|
+
const { projects, format, status, richText, token } = requestOptions;
|
|
151
162
|
const api = (0, import_api.createApiClient)();
|
|
152
163
|
const params = { variant: variantApiId };
|
|
153
164
|
if (format)
|
|
@@ -163,7 +174,7 @@ function downloadAndSaveVariant(variantApiId, projects, format, status, richText
|
|
|
163
174
|
projectParams.status = project.status;
|
|
164
175
|
if (project.exclude_components)
|
|
165
176
|
projectParams.exclude_components = String(project.exclude_components);
|
|
166
|
-
const { data } = yield api.get(`/projects/${project.id}`, {
|
|
177
|
+
const { data } = yield api.get(`/v1/projects/${project.id}`, {
|
|
167
178
|
params: projectParams,
|
|
168
179
|
headers: { Authorization: `token ${token}` }
|
|
169
180
|
});
|
|
@@ -190,19 +201,20 @@ function downloadAndSaveVariant(variantApiId, projects, format, status, richText
|
|
|
190
201
|
return savedMessages.join("");
|
|
191
202
|
});
|
|
192
203
|
}
|
|
193
|
-
function downloadAndSaveVariants(
|
|
204
|
+
function downloadAndSaveVariants(requestOptions) {
|
|
194
205
|
return __async(this, null, function* () {
|
|
195
206
|
const messages = yield Promise.all([
|
|
196
|
-
downloadAndSaveVariant(null,
|
|
197
|
-
...variants.map(
|
|
198
|
-
({ apiID }) => downloadAndSaveVariant(apiID,
|
|
207
|
+
downloadAndSaveVariant(null, requestOptions),
|
|
208
|
+
...requestOptions.variants.map(
|
|
209
|
+
({ apiID }) => downloadAndSaveVariant(apiID, requestOptions)
|
|
199
210
|
)
|
|
200
211
|
]);
|
|
201
212
|
return messages.join("");
|
|
202
213
|
});
|
|
203
214
|
}
|
|
204
|
-
function downloadAndSaveBase(
|
|
215
|
+
function downloadAndSaveBase(requestOptions) {
|
|
205
216
|
return __async(this, null, function* () {
|
|
217
|
+
const { projects, format, status, richText, token, options } = requestOptions;
|
|
206
218
|
const api = (0, import_api.createApiClient)();
|
|
207
219
|
const params = __spreadValues({}, options == null ? void 0 : options.meta);
|
|
208
220
|
if (format)
|
|
@@ -218,7 +230,7 @@ function downloadAndSaveBase(projects, format, status, richText, token, options)
|
|
|
218
230
|
projectParams.status = project.status;
|
|
219
231
|
if (project.exclude_components)
|
|
220
232
|
projectParams.exclude_components = String(project.exclude_components);
|
|
221
|
-
const { data } = yield api.get(`/projects/${project.id}`, {
|
|
233
|
+
const { data } = yield api.get(`/v1/projects/${project.id}`, {
|
|
222
234
|
params: projectParams,
|
|
223
235
|
headers: { Authorization: `token ${token}` }
|
|
224
236
|
});
|
|
@@ -248,10 +260,18 @@ function cleanOutputFiles() {
|
|
|
248
260
|
if (!import_fs.default.existsSync(import_consts.default.TEXT_DIR)) {
|
|
249
261
|
import_fs.default.mkdirSync(import_consts.default.TEXT_DIR);
|
|
250
262
|
}
|
|
251
|
-
const
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
263
|
+
const directoryContents = import_fs.default.readdirSync(import_consts.default.TEXT_DIR, {
|
|
264
|
+
withFileTypes: true
|
|
265
|
+
});
|
|
266
|
+
directoryContents.forEach((item) => {
|
|
267
|
+
if (item.isDirectory() && /\.lproj$/.test(item.name)) {
|
|
268
|
+
return import_fs.default.rmSync(import_path.default.resolve(import_consts.default.TEXT_DIR, item.name), {
|
|
269
|
+
recursive: true,
|
|
270
|
+
force: true
|
|
271
|
+
});
|
|
272
|
+
}
|
|
273
|
+
if (item.isFile() && /\.js(on)?|\.xml|\.strings(dict)?$|\.swift$/.test(item.name)) {
|
|
274
|
+
return import_fs.default.unlinkSync(import_path.default.resolve(import_consts.default.TEXT_DIR, item.name));
|
|
255
275
|
}
|
|
256
276
|
});
|
|
257
277
|
return "Cleaning old output files..\n";
|
|
@@ -266,9 +286,16 @@ function downloadAndSave(source, token, options) {
|
|
|
266
286
|
status,
|
|
267
287
|
richText,
|
|
268
288
|
componentFolders: specifiedComponentFolders,
|
|
269
|
-
componentRoot
|
|
289
|
+
componentRoot,
|
|
290
|
+
localeByVariantApiId
|
|
270
291
|
} = source;
|
|
271
292
|
const formats = getFormat(formatFromSource);
|
|
293
|
+
const hasJSONFormat = formats.some(
|
|
294
|
+
(f) => JSON_FORMATS.includes(f)
|
|
295
|
+
);
|
|
296
|
+
const hasIOSFormat = formats.some((f) => IOS_FORMATS.includes(f));
|
|
297
|
+
const shouldGenerateIOSBundles = hasIOSFormat && localeByVariantApiId;
|
|
298
|
+
const shouldLogOutputFiles = !shouldGenerateIOSBundles;
|
|
272
299
|
let msg = "";
|
|
273
300
|
const spinner = (0, import_ora.default)(msg);
|
|
274
301
|
spinner.start();
|
|
@@ -345,7 +372,7 @@ Fetching the latest text from ${(0, import_sourcesToText.default)(
|
|
|
345
372
|
componentFolderParams.append("variant", variantApiId);
|
|
346
373
|
if (componentFolder.status)
|
|
347
374
|
componentFolderParams.append("status", componentFolder.status);
|
|
348
|
-
const url = componentFolder.id === "__root__" ? "/components?root_only=true" : `/component-folders/${componentFolder.id}/components`;
|
|
375
|
+
const url = componentFolder.id === "__root__" ? "/v1/components?root_only=true" : `/v1/component-folders/${componentFolder.id}/components`;
|
|
349
376
|
const { data } = yield api.get(url, {
|
|
350
377
|
params: componentFolderParams
|
|
351
378
|
});
|
|
@@ -378,7 +405,9 @@ Fetching the latest text from ${(0, import_sourcesToText.default)(
|
|
|
378
405
|
);
|
|
379
406
|
});
|
|
380
407
|
const messages = yield Promise.all(messagePromises);
|
|
381
|
-
|
|
408
|
+
if (shouldLogOutputFiles) {
|
|
409
|
+
msg += messages.join("");
|
|
410
|
+
}
|
|
382
411
|
});
|
|
383
412
|
}
|
|
384
413
|
if (shouldFetchComponentLibrary) {
|
|
@@ -388,23 +417,31 @@ Fetching the latest text from ${(0, import_sourcesToText.default)(
|
|
|
388
417
|
}
|
|
389
418
|
function fetchProjects(format) {
|
|
390
419
|
return __async(this, null, function* () {
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
420
|
+
let result = "";
|
|
421
|
+
if (variants) {
|
|
422
|
+
result = yield downloadAndSaveVariants({
|
|
423
|
+
variants,
|
|
424
|
+
projects: validProjects,
|
|
425
|
+
format,
|
|
426
|
+
status,
|
|
427
|
+
richText,
|
|
428
|
+
token
|
|
429
|
+
});
|
|
430
|
+
} else {
|
|
431
|
+
result = yield downloadAndSaveBase({
|
|
432
|
+
projects: validProjects,
|
|
433
|
+
format,
|
|
434
|
+
status,
|
|
435
|
+
richText,
|
|
436
|
+
token,
|
|
437
|
+
options: {
|
|
438
|
+
meta
|
|
439
|
+
}
|
|
440
|
+
});
|
|
441
|
+
}
|
|
442
|
+
if (shouldLogOutputFiles) {
|
|
443
|
+
msg += result;
|
|
444
|
+
}
|
|
408
445
|
});
|
|
409
446
|
}
|
|
410
447
|
if (validProjects.length) {
|
|
@@ -413,9 +450,15 @@ Fetching the latest text from ${(0, import_sourcesToText.default)(
|
|
|
413
450
|
}
|
|
414
451
|
}
|
|
415
452
|
const sources = [...validProjects, ...componentSources];
|
|
416
|
-
if (
|
|
417
|
-
msg += (0, import_generateJsDriver.generateJsDriver)(sources);
|
|
453
|
+
if (hasJSONFormat)
|
|
454
|
+
msg += (0, import_generateJsDriver.generateJsDriver)(sources, getJsonFormat(formats));
|
|
455
|
+
if (shouldGenerateIOSBundles) {
|
|
456
|
+
msg += "iOS locale information detected, generating bundles..\n\n";
|
|
457
|
+
msg += yield (0, import_generateIOSBundles.generateIOSBundles)(localeByVariantApiId);
|
|
458
|
+
msg += yield (0, import_generateSwiftDriver.generateSwiftDriver)(source);
|
|
459
|
+
}
|
|
418
460
|
msg += `
|
|
461
|
+
|
|
419
462
|
${import_output.default.success("Done")}!`;
|
|
420
463
|
spinner.stop();
|
|
421
464
|
return console.log(msg);
|
|
@@ -496,8 +539,9 @@ var pull_default = {
|
|
|
496
539
|
// Annotate the CommonJS export names for ESM import in node:
|
|
497
540
|
0 && (module.exports = {
|
|
498
541
|
getFormatDataIsValid,
|
|
499
|
-
pull
|
|
542
|
+
pull,
|
|
543
|
+
writeFile
|
|
500
544
|
});
|
|
501
545
|
//# sourceMappingURL=pull.js.map
|
|
502
546
|
|
|
503
|
-
//# debugId=
|
|
547
|
+
//# debugId=9f70f849-9f7e-59ce-9f0a-51c26028e270
|
package/bin/pull.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../lib/pull.ts"],"sourcesContent":["import fs from \"fs\";\nimport path from \"path\";\n\nimport ora from \"ora\";\nimport * as Sentry from \"@sentry/node\";\n\nimport { createApiClient } from \"./api\";\nimport config from \"./config\";\nimport consts from \"./consts\";\nimport output from \"./output\";\nimport { collectAndSaveToken } from \"./init/token\";\nimport sourcesToText from \"./utils/sourcesToText\";\nimport { generateJsDriver } from \"./utils/generateJsDriver\";\nimport { cleanFileName } from \"./utils/cleanFileName\";\nimport {\n SourceInformation,\n Token,\n Project,\n SupportedFormat,\n ComponentFolder,\n ComponentSource,\n Source,\n} from \"./types\";\nimport { fetchVariants } from \"./http/fetchVariants\";\nimport { quit } from \"./utils/quit\";\nimport { AxiosError } from \"axios\";\nimport { fetchComponentFolders } from \"./http/fetchComponentFolders\";\n\nconst ensureEndsWithNewLine = (str: string) =>\n str + (/[\\r\\n]$/.test(str) ? \"\" : \"\\n\");\n\nconst writeFile = (path: string, data: string) =>\n new Promise((r) => fs.writeFile(path, ensureEndsWithNewLine(data), r));\n\nconst SUPPORTED_FORMATS: SupportedFormat[] = [\n \"flat\",\n \"structured\",\n \"android\",\n \"ios-strings\",\n \"ios-stringsdict\",\n \"icu\",\n];\n\nconst JSON_FORMATS: SupportedFormat[] = [\"flat\", \"structured\", \"icu\"];\n\nconst FORMAT_EXTENSIONS = {\n flat: \".json\",\n structured: \".json\",\n android: \".xml\",\n \"ios-strings\": \".strings\",\n \"ios-stringsdict\": \".stringsdict\",\n icu: \".json\",\n};\n\nconst getJsonFormatIsValid = (data: string) => {\n try {\n return Object.keys(JSON.parse(data)).some(\n (k) => !k.startsWith(\"__variant\")\n );\n } catch {\n return false;\n }\n};\n\n// exported for test usage only\nexport const getFormatDataIsValid = {\n flat: getJsonFormatIsValid,\n structured: getJsonFormatIsValid,\n icu: getJsonFormatIsValid,\n android: (data: string) => data.includes(\"<string\"),\n \"ios-strings\": (data: string) => data.includes(`\" = \"`),\n \"ios-stringsdict\": (data: string) => data.includes(\"<key>\"),\n};\n\nconst getFormat = (\n formatFromSource: string | string[] | undefined\n): SupportedFormat[] => {\n const formats = (\n Array.isArray(formatFromSource) ? formatFromSource : [formatFromSource]\n ).filter((format) =>\n SUPPORTED_FORMATS.includes(format as SupportedFormat)\n ) as SupportedFormat[];\n\n if (formats.length) {\n return formats;\n }\n\n return [\"flat\"];\n};\n\nconst getFormatExtension = (format: SupportedFormat) => {\n return FORMAT_EXTENSIONS[format];\n};\n\nconst DEFAULT_FORMAT_KEYS = [\"projects\", \"exported_at\"];\nconst hasVariantData = (data: any) => {\n const hasTopLevelKeys =\n Object.keys(data).filter((key) => !DEFAULT_FORMAT_KEYS.includes(key))\n .length > 0;\n\n const hasProjectKeys = data.projects && Object.keys(data.projects).length > 0;\n\n return hasTopLevelKeys || hasProjectKeys;\n};\n\nasync function askForAnotherToken() {\n config.deleteToken(consts.CONFIG_FILE, consts.API_HOST);\n const message =\n \"Looks like the API key you have saved no longer works. Please enter another one.\";\n await collectAndSaveToken(message);\n}\n\n/**\n * For a given variant:\n * - if format is unspecified, fetch data for all projects from `/projects` and\n * save in `{variantApiId}.json`\n * - if format is `flat` or `structured`, fetch data for each project from `/project/:project_id` and\n * save in `{projectName}-${variantApiId}.json`\n */\nasync function downloadAndSaveVariant(\n variantApiId: string | null,\n projects: Project[],\n format: SupportedFormat,\n status: string | undefined,\n richText: boolean | undefined,\n token?: Token\n) {\n const api = createApiClient();\n const params: Record<string, string | null> = { variant: variantApiId };\n if (format) params.format = format;\n if (richText) params.includeRichText = richText.toString();\n\n // Root-level status gets set as the default if specified\n if (status) params.status = status;\n\n const savedMessages = await Promise.all(\n projects.map(async (project) => {\n const projectParams = { ...params };\n // If project-level status is specified, overrides root-level status\n if (project.status) projectParams.status = project.status;\n if (project.exclude_components)\n projectParams.exclude_components = String(project.exclude_components);\n\n const { data } = await api.get(`/projects/${project.id}`, {\n params: projectParams,\n headers: { Authorization: `token ${token}` },\n });\n\n if (!hasVariantData(data)) {\n return \"\";\n }\n\n const extension = getFormatExtension(format);\n\n const filename = cleanFileName(\n project.fileName + (\"__\" + (variantApiId || \"base\")) + extension\n );\n const filepath = path.join(consts.TEXT_DIR, filename);\n\n let dataString = data;\n if (extension === \".json\") {\n dataString = JSON.stringify(data, null, 2);\n }\n\n const dataIsValid = getFormatDataIsValid[format];\n if (!dataIsValid(dataString)) {\n return \"\";\n }\n\n await writeFile(filepath, dataString);\n return getSavedMessage(filename);\n })\n );\n\n return savedMessages.join(\"\");\n}\n\nasync function downloadAndSaveVariants(\n variants: { apiID: string }[],\n projects: Project[],\n format: SupportedFormat,\n status: string | undefined,\n richText: boolean | undefined,\n token?: Token\n) {\n const messages = await Promise.all([\n downloadAndSaveVariant(null, projects, format, status, richText, token),\n ...variants.map(({ apiID }: { apiID: string }) =>\n downloadAndSaveVariant(apiID, projects, format, status, richText, token)\n ),\n ]);\n\n return messages.join(\"\");\n}\n\nasync function downloadAndSaveBase(\n projects: Project[],\n format: SupportedFormat,\n status: string | undefined,\n richText?: boolean | undefined,\n token?: Token,\n options?: PullOptions\n) {\n const api = createApiClient();\n const params = { ...options?.meta };\n if (format) params.format = format;\n if (richText) params.includeRichText = richText.toString();\n\n // Root-level status gets set as the default if specified\n if (status) params.status = status;\n\n const savedMessages = await Promise.all(\n projects.map(async (project) => {\n const projectParams = { ...params };\n // If project-level status is specified, overrides root-level status\n if (project.status) projectParams.status = project.status;\n if (project.exclude_components)\n projectParams.exclude_components = String(project.exclude_components);\n\n const { data } = await api.get(`/projects/${project.id}`, {\n params: projectParams,\n headers: { Authorization: `token ${token}` },\n });\n\n const extension = getFormatExtension(format);\n const filename = cleanFileName(`${project.fileName}__base${extension}`);\n const filepath = path.join(consts.TEXT_DIR, filename);\n\n let dataString = data;\n if (extension === \".json\") {\n dataString = JSON.stringify(data, null, 2);\n }\n\n const dataIsValid = getFormatDataIsValid[format];\n if (!dataIsValid(dataString)) {\n return \"\";\n }\n\n await writeFile(filepath, dataString);\n return getSavedMessage(filename);\n })\n );\n\n return savedMessages.join(\"\");\n}\n\nfunction getSavedMessage(file: string) {\n return `Successfully saved to ${output.info(file)}\\n`;\n}\n\nfunction cleanOutputFiles() {\n if (!fs.existsSync(consts.TEXT_DIR)) {\n fs.mkdirSync(consts.TEXT_DIR);\n }\n\n const fileNames = fs.readdirSync(consts.TEXT_DIR);\n fileNames.forEach((fileName) => {\n if (/\\.js(on)?|\\.xml|\\.strings(dict)?$/.test(fileName)) {\n fs.unlinkSync(path.resolve(consts.TEXT_DIR, fileName));\n }\n });\n\n return \"Cleaning old output files..\\n\";\n}\n\nasync function downloadAndSave(\n source: SourceInformation,\n token?: Token,\n options?: PullOptions\n) {\n const api = createApiClient();\n const {\n validProjects,\n format: formatFromSource,\n shouldFetchComponentLibrary,\n status,\n richText,\n componentFolders: specifiedComponentFolders,\n componentRoot,\n } = source;\n\n const formats = getFormat(formatFromSource);\n\n let msg = \"\";\n const spinner = ora(msg);\n spinner.start();\n\n const [variants, allComponentFoldersResponse] = await Promise.all([\n fetchVariants(source),\n fetchComponentFolders(),\n ]);\n\n const allComponentFolders = Object.entries(\n allComponentFoldersResponse\n ).reduce(\n (acc, [id, name]) => acc.concat([{ id, name }]),\n [] as ComponentFolder[]\n );\n\n try {\n msg += cleanOutputFiles();\n msg += `\\nFetching the latest text from ${sourcesToText(\n validProjects,\n shouldFetchComponentLibrary\n )}\\n`;\n\n const meta = options ? options.meta : {};\n\n const rootRequest = {\n id: \"__root__\",\n name: \"Root\",\n // componentRoot can be a boolean or an object\n status:\n typeof source.componentRoot === \"object\"\n ? source.componentRoot.status\n : undefined,\n };\n\n let componentFolderRequests: ComponentFolder[] = [];\n\n // there's a lot of complex logic here, and it's tempting to want to\n // simplify it. however, it's difficult to get rid of the complexity\n // without sacrificing specificity and expressiveness.\n //\n // if folders specified..\n if (specifiedComponentFolders) {\n switch (componentRoot) {\n // .. and no root specified, you only get components in the specified folders\n case undefined:\n case false:\n componentFolderRequests.push(...specifiedComponentFolders);\n break;\n // .. and root specified, you get components in folders and the root\n default:\n componentFolderRequests.push(...specifiedComponentFolders);\n componentFolderRequests.push(rootRequest);\n break;\n }\n }\n // if no folders specified..\n else {\n switch (componentRoot) {\n // .. and no root specified, you get all components including those in folders\n case undefined:\n componentFolderRequests.push(...allComponentFolders);\n componentFolderRequests.push(rootRequest);\n break;\n // .. and root specified as false, you only get components in folders\n case false:\n componentFolderRequests.push(...allComponentFolders);\n break;\n // .. and root specified as true or config object, you only get components in the root\n default:\n componentFolderRequests.push(rootRequest);\n break;\n }\n }\n\n // this array is populated while fetching from the component library and is used when\n // generating the index.js driver file\n const componentSources: ComponentSource[] = [];\n\n async function fetchComponentLibrary(format: SupportedFormat) {\n // Always include a variant with an apiID of undefined to ensure that we\n // fetch the base text for the component library.\n const componentVariants = [{ apiID: undefined }, ...(variants || [])];\n\n const params = new URLSearchParams();\n if (options?.meta)\n Object.entries(options.meta).forEach(([k, v]) => params.append(k, v));\n if (format) params.append(\"format\", format);\n if (richText) params.append(\"includeRichText\", richText.toString());\n\n // Root-level status gets set as the default if specified\n if (status) params.append(\"status\", status);\n\n const messagePromises: Promise<string>[] = [];\n\n componentVariants.forEach(({ apiID: variantApiId }) => {\n messagePromises.push(\n ...componentFolderRequests.map(async (componentFolder) => {\n const componentFolderParams = new URLSearchParams(params);\n\n if (variantApiId)\n componentFolderParams.append(\"variant\", variantApiId);\n\n // If folder-level status is specified, overrides root-level status\n if (componentFolder.status)\n componentFolderParams.append(\"status\", componentFolder.status);\n\n const url =\n componentFolder.id === \"__root__\"\n ? \"/components?root_only=true\"\n : `/component-folders/${componentFolder.id}/components`;\n\n const { data } = await api.get(url, {\n params: componentFolderParams,\n });\n\n const nameExt = getFormatExtension(format);\n const nameBase = \"components\";\n const nameFolder = `__${componentFolder.name}`;\n const namePostfix = `__${variantApiId || \"base\"}`;\n\n const fileName = cleanFileName(\n `${nameBase}${nameFolder}${namePostfix}${nameExt}`\n );\n const filePath = path.join(consts.TEXT_DIR, fileName);\n\n let dataString = data;\n if (nameExt === \".json\") {\n dataString = JSON.stringify(data, null, 2);\n }\n\n const dataIsValid = getFormatDataIsValid[format];\n if (!dataIsValid(dataString)) {\n return \"\";\n }\n\n await writeFile(filePath, dataString);\n\n componentSources.push({\n type: \"components\",\n id: \"ditto_component_library\",\n name: \"ditto_component_library\",\n fileName,\n variant: variantApiId || \"base\",\n });\n\n return getSavedMessage(fileName);\n })\n );\n });\n\n const messages = await Promise.all(messagePromises);\n msg += messages.join(\"\");\n }\n\n if (shouldFetchComponentLibrary) {\n for (const format of formats) {\n await fetchComponentLibrary(format);\n }\n }\n\n async function fetchProjects(format: SupportedFormat) {\n msg += variants\n ? await downloadAndSaveVariants(\n variants,\n validProjects,\n format,\n status,\n richText,\n token\n )\n : await downloadAndSaveBase(\n validProjects,\n format,\n status,\n richText,\n token,\n {\n meta,\n }\n );\n }\n\n if (validProjects.length) {\n for (const format of formats) {\n await fetchProjects(format);\n }\n }\n\n const sources: Source[] = [...validProjects, ...componentSources];\n\n if (formats.some((f) => JSON_FORMATS.includes(f)))\n msg += generateJsDriver(sources);\n\n msg += `\\n${output.success(\"Done\")}!`;\n\n spinner.stop();\n return console.log(msg);\n } catch (e: any) {\n console.error(e);\n\n spinner.stop();\n let error = e.message;\n if (e.response && e.response.status === 404) {\n await askForAnotherToken();\n pull();\n return;\n }\n if (e.response && e.response.status === 401) {\n error = \"You don't have access to the selected projects\";\n msg = `${output.errorText(error)}.\\nChoose others using the ${output.info(\n \"project\"\n )} command, or update your API key.`;\n return console.log(msg);\n }\n if (e.response && e.response.status === 403) {\n error =\n \"One or more of the requested projects don't have Developer Mode enabled\";\n msg = `${output.errorText(\n error\n )}.\\nPlease choose different projects using the ${output.info(\n \"project\"\n )} command, or turn on Developer Mode for all selected projects. Learn more here: ${output.subtle(\n \"https://www.dittowords.com/docs/ditto-developer-mode\"\n )}.`;\n return console.log(msg);\n }\n if (e.response && e.response.status === 400) {\n error = \"projects not found\";\n }\n msg = `We hit an error fetching text from the projects: ${output.errorText(\n error\n )}.\\nChoose others using the ${output.info(\"project\")} command.`;\n return console.log(msg);\n }\n}\n\nexport interface PullOptions {\n meta?: Record<string, string>;\n}\n\nexport const pull = async (options?: PullOptions) => {\n const meta = options ? options.meta : {};\n const token = config.getToken(consts.CONFIG_FILE, consts.API_HOST);\n const sourceInformation = config.parseSourceInformation();\n\n try {\n return await downloadAndSave(sourceInformation, token, { meta });\n } catch (e) {\n const eventId = Sentry.captureException(e);\n const eventStr = `\\n\\nError ID: ${output.info(eventId)}`;\n if (e instanceof AxiosError) {\n return quit(\n output.errorText(\n \"Something went wrong connecting to Ditto servers. Please contact support or try again later.\"\n ) + eventStr\n );\n }\n\n return quit(\n output.errorText(\n \"Something went wrong. Please contact support or try again later.\"\n ) + eventStr\n );\n }\n};\n\nexport default {\n pull,\n _testing: {\n cleanOutputFiles,\n downloadAndSaveVariant,\n downloadAndSaveVariants,\n downloadAndSaveBase,\n },\n};\n"],"names":["path","fs","config","consts","output","ora","sourcesToText"],"mappings":"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","debug_id":"8e8abce7-7d1b-5b40-96a6-09318358142e"}
|
|
1
|
+
{"version":3,"sources":["../lib/pull.ts"],"sourcesContent":["import fs from \"fs\";\nimport path from \"path\";\n\nimport ora from \"ora\";\nimport * as Sentry from \"@sentry/node\";\n\nimport { createApiClient } from \"./api\";\nimport config from \"./config\";\nimport consts from \"./consts\";\nimport output from \"./output\";\nimport { collectAndSaveToken } from \"./init/token\";\nimport sourcesToText from \"./utils/sourcesToText\";\nimport { generateJsDriver } from \"./utils/generateJsDriver\";\nimport { cleanFileName } from \"./utils/cleanFileName\";\nimport {\n SourceInformation,\n Token,\n Project,\n SupportedFormat,\n ComponentFolder,\n ComponentSource,\n Source,\n} from \"./types\";\nimport { fetchVariants } from \"./http/fetchVariants\";\nimport { quit } from \"./utils/quit\";\nimport { AxiosError } from \"axios\";\nimport { fetchComponentFolders } from \"./http/fetchComponentFolders\";\nimport { generateSwiftDriver } from \"./utils/generateSwiftDriver\";\nimport { generateIOSBundles } from \"./utils/generateIOSBundles\";\n\ninterface IRequestOptions {\n projects: Project[];\n format: SupportedFormat;\n status: string | undefined;\n richText?: boolean | undefined;\n token?: Token;\n options?: PullOptions;\n}\n\ninterface IRequestOptionsWithVariants extends IRequestOptions {\n variants: { apiID: string }[];\n}\n\nconst ensureEndsWithNewLine = (str: string) =>\n str + (/[\\r\\n]$/.test(str) ? \"\" : \"\\n\");\n\nexport const writeFile = (path: string, data: string) =>\n new Promise((r) => fs.writeFile(path, ensureEndsWithNewLine(data), r));\n\nconst SUPPORTED_FORMATS: SupportedFormat[] = [\n \"flat\",\n \"structured\",\n \"android\",\n \"ios-strings\",\n \"ios-stringsdict\",\n \"icu\",\n];\n\nexport type JSONFormat = \"flat\" | \"nested\" | \"structured\" | \"icu\";\n\nconst IOS_FORMATS: SupportedFormat[] = [\"ios-strings\", \"ios-stringsdict\"];\nconst JSON_FORMATS: JSONFormat[] = [\"flat\", \"structured\", \"icu\"];\n\nconst getJsonFormat = (formats: string[]): JSONFormat => {\n // edge case: multiple json formats specified\n // we should grab the last one\n const jsonFormats = formats.filter((f) =>\n JSON_FORMATS.includes(f as JSONFormat)\n ) as JSONFormat[];\n\n return jsonFormats[jsonFormats.length - 1] || \"flat\";\n};\n\nconst FORMAT_EXTENSIONS = {\n flat: \".json\",\n structured: \".json\",\n android: \".xml\",\n \"ios-strings\": \".strings\",\n \"ios-stringsdict\": \".stringsdict\",\n icu: \".json\",\n};\n\nconst getJsonFormatIsValid = (data: string) => {\n try {\n return Object.keys(JSON.parse(data)).some(\n (k) => !k.startsWith(\"__variant\")\n );\n } catch {\n return false;\n }\n};\n\n// exported for test usage only\nexport const getFormatDataIsValid = {\n flat: getJsonFormatIsValid,\n structured: getJsonFormatIsValid,\n icu: getJsonFormatIsValid,\n android: (data: string) => data.includes(\"<string\"),\n \"ios-strings\": (data: string) => data.includes(`\" = \"`),\n \"ios-stringsdict\": (data: string) => data.includes(\"<key>\"),\n};\n\nconst getFormat = (\n formatFromSource: string | string[] | undefined\n): SupportedFormat[] => {\n const formats = (\n Array.isArray(formatFromSource) ? formatFromSource : [formatFromSource]\n ).filter((format) =>\n SUPPORTED_FORMATS.includes(format as SupportedFormat)\n ) as SupportedFormat[];\n\n if (formats.length) {\n return formats;\n }\n\n return [\"flat\"];\n};\n\nconst getFormatExtension = (format: SupportedFormat) => {\n return FORMAT_EXTENSIONS[format];\n};\n\nconst DEFAULT_FORMAT_KEYS = [\"projects\", \"exported_at\"];\nconst hasVariantData = (data: any) => {\n const hasTopLevelKeys =\n Object.keys(data).filter((key) => !DEFAULT_FORMAT_KEYS.includes(key))\n .length > 0;\n\n const hasProjectKeys = data.projects && Object.keys(data.projects).length > 0;\n\n return hasTopLevelKeys || hasProjectKeys;\n};\n\nasync function askForAnotherToken() {\n config.deleteToken(consts.CONFIG_FILE, consts.API_HOST);\n const message =\n \"Looks like the API key you have saved no longer works. Please enter another one.\";\n await collectAndSaveToken(message);\n}\n\n/**\n * For a given variant:\n * - if format is unspecified, fetch data for all projects from `/projects` and\n * save in `{variantApiId}.json`\n * - if format is `flat` or `structured`, fetch data for each project from `/project/:project_id` and\n * save in `{projectName}-${variantApiId}.json`\n */\nasync function downloadAndSaveVariant(\n variantApiId: string | null,\n requestOptions: IRequestOptions\n) {\n const { projects, format, status, richText, token } = requestOptions;\n const api = createApiClient();\n const params: Record<string, string | null> = { variant: variantApiId };\n if (format) params.format = format;\n if (richText) params.includeRichText = richText.toString();\n\n // Root-level status gets set as the default if specified\n if (status) params.status = status;\n\n const savedMessages = await Promise.all(\n projects.map(async (project) => {\n const projectParams = { ...params };\n // If project-level status is specified, overrides root-level status\n if (project.status) projectParams.status = project.status;\n if (project.exclude_components)\n projectParams.exclude_components = String(project.exclude_components);\n\n const { data } = await api.get(`/v1/projects/${project.id}`, {\n params: projectParams,\n headers: { Authorization: `token ${token}` },\n });\n\n if (!hasVariantData(data)) {\n return \"\";\n }\n\n const extension = getFormatExtension(format);\n\n const filename = cleanFileName(\n project.fileName + (\"__\" + (variantApiId || \"base\")) + extension\n );\n const filepath = path.join(consts.TEXT_DIR, filename);\n\n let dataString = data;\n if (extension === \".json\") {\n dataString = JSON.stringify(data, null, 2);\n }\n\n const dataIsValid = getFormatDataIsValid[format];\n if (!dataIsValid(dataString)) {\n return \"\";\n }\n\n await writeFile(filepath, dataString);\n return getSavedMessage(filename);\n })\n );\n\n return savedMessages.join(\"\");\n}\n\nasync function downloadAndSaveVariants(\n requestOptions: IRequestOptionsWithVariants\n) {\n const messages = await Promise.all([\n downloadAndSaveVariant(null, requestOptions),\n ...requestOptions.variants.map(({ apiID }: { apiID: string }) =>\n downloadAndSaveVariant(apiID, requestOptions)\n ),\n ]);\n\n return messages.join(\"\");\n}\n\nasync function downloadAndSaveBase(requestOptions: IRequestOptions) {\n const { projects, format, status, richText, token, options } = requestOptions;\n\n const api = createApiClient();\n const params = { ...options?.meta };\n if (format) params.format = format;\n if (richText) params.includeRichText = richText.toString();\n\n // Root-level status gets set as the default if specified\n if (status) params.status = status;\n\n const savedMessages = await Promise.all(\n projects.map(async (project) => {\n const projectParams = { ...params };\n // If project-level status is specified, overrides root-level status\n if (project.status) projectParams.status = project.status;\n if (project.exclude_components)\n projectParams.exclude_components = String(project.exclude_components);\n\n const { data } = await api.get(`/v1/projects/${project.id}`, {\n params: projectParams,\n headers: { Authorization: `token ${token}` },\n });\n\n const extension = getFormatExtension(format);\n const filename = cleanFileName(`${project.fileName}__base${extension}`);\n const filepath = path.join(consts.TEXT_DIR, filename);\n\n let dataString = data;\n if (extension === \".json\") {\n dataString = JSON.stringify(data, null, 2);\n }\n\n const dataIsValid = getFormatDataIsValid[format];\n if (!dataIsValid(dataString)) {\n return \"\";\n }\n\n await writeFile(filepath, dataString);\n return getSavedMessage(filename);\n })\n );\n\n return savedMessages.join(\"\");\n}\n\nfunction getSavedMessage(file: string) {\n return `Successfully saved to ${output.info(file)}\\n`;\n}\n\nfunction cleanOutputFiles() {\n if (!fs.existsSync(consts.TEXT_DIR)) {\n fs.mkdirSync(consts.TEXT_DIR);\n }\n\n const directoryContents = fs.readdirSync(consts.TEXT_DIR, {\n withFileTypes: true,\n });\n\n directoryContents.forEach((item) => {\n if (item.isDirectory() && /\\.lproj$/.test(item.name)) {\n return fs.rmSync(path.resolve(consts.TEXT_DIR, item.name), {\n recursive: true,\n force: true,\n });\n }\n\n if (\n item.isFile() &&\n /\\.js(on)?|\\.xml|\\.strings(dict)?$|\\.swift$/.test(item.name)\n ) {\n return fs.unlinkSync(path.resolve(consts.TEXT_DIR, item.name));\n }\n });\n\n return \"Cleaning old output files..\\n\";\n}\n\nasync function downloadAndSave(\n source: SourceInformation,\n token?: Token,\n options?: PullOptions\n) {\n const api = createApiClient();\n const {\n validProjects,\n format: formatFromSource,\n shouldFetchComponentLibrary,\n status,\n richText,\n componentFolders: specifiedComponentFolders,\n componentRoot,\n localeByVariantApiId,\n } = source;\n\n const formats = getFormat(formatFromSource);\n\n const hasJSONFormat = formats.some((f) =>\n JSON_FORMATS.includes(f as JSONFormat)\n );\n const hasIOSFormat = formats.some((f) => IOS_FORMATS.includes(f));\n const shouldGenerateIOSBundles = hasIOSFormat && localeByVariantApiId;\n\n const shouldLogOutputFiles = !shouldGenerateIOSBundles;\n\n let msg = \"\";\n const spinner = ora(msg);\n spinner.start();\n\n const [variants, allComponentFoldersResponse] = await Promise.all([\n fetchVariants(source),\n fetchComponentFolders(),\n ]);\n\n const allComponentFolders = Object.entries(\n allComponentFoldersResponse\n ).reduce(\n (acc, [id, name]) => acc.concat([{ id, name }]),\n [] as ComponentFolder[]\n );\n\n try {\n msg += cleanOutputFiles();\n msg += `\\nFetching the latest text from ${sourcesToText(\n validProjects,\n shouldFetchComponentLibrary\n )}\\n`;\n\n const meta = options ? options.meta : {};\n\n const rootRequest = {\n id: \"__root__\",\n name: \"Root\",\n // componentRoot can be a boolean or an object\n status:\n typeof source.componentRoot === \"object\"\n ? source.componentRoot.status\n : undefined,\n };\n\n let componentFolderRequests: ComponentFolder[] = [];\n\n // there's a lot of complex logic here, and it's tempting to want to\n // simplify it. however, it's difficult to get rid of the complexity\n // without sacrificing specificity and expressiveness.\n //\n // if folders specified..\n if (specifiedComponentFolders) {\n switch (componentRoot) {\n // .. and no root specified, you only get components in the specified folders\n case undefined:\n case false:\n componentFolderRequests.push(...specifiedComponentFolders);\n break;\n // .. and root specified, you get components in folders and the root\n default:\n componentFolderRequests.push(...specifiedComponentFolders);\n componentFolderRequests.push(rootRequest);\n break;\n }\n }\n // if no folders specified..\n else {\n switch (componentRoot) {\n // .. and no root specified, you get all components including those in folders\n case undefined:\n componentFolderRequests.push(...allComponentFolders);\n componentFolderRequests.push(rootRequest);\n break;\n // .. and root specified as false, you only get components in folders\n case false:\n componentFolderRequests.push(...allComponentFolders);\n break;\n // .. and root specified as true or config object, you only get components in the root\n default:\n componentFolderRequests.push(rootRequest);\n break;\n }\n }\n\n // this array is populated while fetching from the component library and is used when\n // generating the index.js driver file\n const componentSources: ComponentSource[] = [];\n\n async function fetchComponentLibrary(format: SupportedFormat) {\n // Always include a variant with an apiID of undefined to ensure that we\n // fetch the base text for the component library.\n const componentVariants = [{ apiID: undefined }, ...(variants || [])];\n\n const params = new URLSearchParams();\n if (options?.meta)\n Object.entries(options.meta).forEach(([k, v]) => params.append(k, v));\n if (format) params.append(\"format\", format);\n if (richText) params.append(\"includeRichText\", richText.toString());\n\n // Root-level status gets set as the default if specified\n if (status) params.append(\"status\", status);\n\n const messagePromises: Promise<string>[] = [];\n\n componentVariants.forEach(({ apiID: variantApiId }) => {\n messagePromises.push(\n ...componentFolderRequests.map(async (componentFolder) => {\n const componentFolderParams = new URLSearchParams(params);\n\n if (variantApiId)\n componentFolderParams.append(\"variant\", variantApiId);\n\n // If folder-level status is specified, overrides root-level status\n if (componentFolder.status)\n componentFolderParams.append(\"status\", componentFolder.status);\n\n const url =\n componentFolder.id === \"__root__\"\n ? \"/v1/components?root_only=true\"\n : `/v1/component-folders/${componentFolder.id}/components`;\n\n const { data } = await api.get(url, {\n params: componentFolderParams,\n });\n\n const nameExt = getFormatExtension(format);\n const nameBase = \"components\";\n const nameFolder = `__${componentFolder.name}`;\n const namePostfix = `__${variantApiId || \"base\"}`;\n\n const fileName = cleanFileName(\n `${nameBase}${nameFolder}${namePostfix}${nameExt}`\n );\n const filePath = path.join(consts.TEXT_DIR, fileName);\n\n let dataString = data;\n if (nameExt === \".json\") {\n dataString = JSON.stringify(data, null, 2);\n }\n\n const dataIsValid = getFormatDataIsValid[format];\n if (!dataIsValid(dataString)) {\n return \"\";\n }\n\n await writeFile(filePath, dataString);\n\n componentSources.push({\n type: \"components\",\n id: \"ditto_component_library\",\n name: \"ditto_component_library\",\n fileName,\n variant: variantApiId || \"base\",\n });\n\n return getSavedMessage(fileName);\n })\n );\n });\n\n const messages = await Promise.all(messagePromises);\n if (shouldLogOutputFiles) {\n msg += messages.join(\"\");\n }\n }\n\n if (shouldFetchComponentLibrary) {\n for (const format of formats) {\n await fetchComponentLibrary(format);\n }\n }\n\n async function fetchProjects(format: SupportedFormat) {\n let result = \"\";\n if (variants) {\n result = await downloadAndSaveVariants({\n variants,\n projects: validProjects,\n format,\n status,\n richText,\n token,\n });\n } else {\n result = await downloadAndSaveBase({\n projects: validProjects,\n format,\n status,\n richText,\n token,\n options: {\n meta,\n },\n });\n }\n\n if (shouldLogOutputFiles) {\n msg += result;\n }\n }\n\n if (validProjects.length) {\n for (const format of formats) {\n await fetchProjects(format);\n }\n }\n\n const sources: Source[] = [...validProjects, ...componentSources];\n\n if (hasJSONFormat) msg += generateJsDriver(sources, getJsonFormat(formats));\n\n if (shouldGenerateIOSBundles) {\n msg += \"iOS locale information detected, generating bundles..\\n\\n\";\n msg += await generateIOSBundles(localeByVariantApiId);\n msg += await generateSwiftDriver(source);\n }\n\n msg += `\\n\\n${output.success(\"Done\")}!`;\n\n spinner.stop();\n return console.log(msg);\n } catch (e: any) {\n console.error(e);\n\n spinner.stop();\n let error = e.message;\n if (e.response && e.response.status === 404) {\n await askForAnotherToken();\n pull();\n return;\n }\n if (e.response && e.response.status === 401) {\n error = \"You don't have access to the selected projects\";\n msg = `${output.errorText(error)}.\\nChoose others using the ${output.info(\n \"project\"\n )} command, or update your API key.`;\n return console.log(msg);\n }\n if (e.response && e.response.status === 403) {\n error =\n \"One or more of the requested projects don't have Developer Mode enabled\";\n msg = `${output.errorText(\n error\n )}.\\nPlease choose different projects using the ${output.info(\n \"project\"\n )} command, or turn on Developer Mode for all selected projects. Learn more here: ${output.subtle(\n \"https://www.dittowords.com/docs/ditto-developer-mode\"\n )}.`;\n return console.log(msg);\n }\n if (e.response && e.response.status === 400) {\n error = \"projects not found\";\n }\n msg = `We hit an error fetching text from the projects: ${output.errorText(\n error\n )}.\\nChoose others using the ${output.info(\"project\")} command.`;\n return console.log(msg);\n }\n}\n\nexport interface PullOptions {\n meta?: Record<string, string>;\n}\n\nexport const pull = async (options?: PullOptions) => {\n const meta = options ? options.meta : {};\n const token = config.getToken(consts.CONFIG_FILE, consts.API_HOST);\n const sourceInformation = config.parseSourceInformation();\n\n try {\n return await downloadAndSave(sourceInformation, token, { meta });\n } catch (e) {\n const eventId = Sentry.captureException(e);\n const eventStr = `\\n\\nError ID: ${output.info(eventId)}`;\n if (e instanceof AxiosError) {\n return quit(\n output.errorText(\n \"Something went wrong connecting to Ditto servers. Please contact support or try again later.\"\n ) + eventStr\n );\n }\n\n return quit(\n output.errorText(\n \"Something went wrong. Please contact support or try again later.\"\n ) + eventStr\n );\n }\n};\n\nexport default {\n pull,\n _testing: {\n cleanOutputFiles,\n downloadAndSaveVariant,\n downloadAndSaveVariants,\n downloadAndSaveBase,\n },\n};\n"],"names":["path","fs","config","consts","output","ora","sourcesToText"],"mappings":"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","debug_id":"9f70f849-9f7e-59ce-9f0a-51c26028e270"}
|
package/bin/pull.test.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:{},n=(new Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="
|
|
2
|
+
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:{},n=(new Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="587c3043-a9e4-58d4-9ce1-1464ba0c94e3")}catch(e){}}();
|
|
3
3
|
|
|
4
4
|
var __create = Object.create;
|
|
5
5
|
var __defProp = Object.defineProperty;
|
|
@@ -110,7 +110,10 @@ describe("downloadAndSaveBase", () => {
|
|
|
110
110
|
import_api.createApiClient.mockImplementation(() => ({
|
|
111
111
|
get: () => ({ data: mockData })
|
|
112
112
|
}));
|
|
113
|
-
const output = yield downloadAndSaveBase(
|
|
113
|
+
const output = yield downloadAndSaveBase({
|
|
114
|
+
projects: testProjects,
|
|
115
|
+
format: "flat"
|
|
116
|
+
});
|
|
114
117
|
expect(/successfully saved/i.test(output)).toEqual(true);
|
|
115
118
|
const directoryContents = import_fs.default.readdirSync(import_consts.default.TEXT_DIR);
|
|
116
119
|
expect(directoryContents.length).toEqual(testProjects.length);
|
|
@@ -131,11 +134,10 @@ describe("downloadAndSaveBase", () => {
|
|
|
131
134
|
import_api.createApiClient.mockImplementation(() => ({
|
|
132
135
|
get: () => ({ data: mockData })
|
|
133
136
|
}));
|
|
134
|
-
const output = yield downloadAndSaveBase(
|
|
135
|
-
testProjects,
|
|
136
|
-
"structured"
|
|
137
|
-
|
|
138
|
-
);
|
|
137
|
+
const output = yield downloadAndSaveBase({
|
|
138
|
+
projects: testProjects,
|
|
139
|
+
format: "structured"
|
|
140
|
+
});
|
|
139
141
|
expect(/successfully saved/i.test(output)).toEqual(true);
|
|
140
142
|
const directoryContents = import_fs.default.readdirSync(import_consts.default.TEXT_DIR);
|
|
141
143
|
expect(directoryContents.length).toEqual(testProjects.length);
|
|
@@ -156,7 +158,10 @@ describe("downloadAndSaveBase", () => {
|
|
|
156
158
|
import_api.createApiClient.mockImplementation(() => ({
|
|
157
159
|
get: () => ({ data: mockData })
|
|
158
160
|
}));
|
|
159
|
-
const output = yield downloadAndSaveBase(
|
|
161
|
+
const output = yield downloadAndSaveBase({
|
|
162
|
+
projects: testProjects,
|
|
163
|
+
format: "icu"
|
|
164
|
+
});
|
|
160
165
|
expect(/successfully saved/i.test(output)).toEqual(true);
|
|
161
166
|
const directoryContents = import_fs.default.readdirSync(import_consts.default.TEXT_DIR);
|
|
162
167
|
expect(directoryContents.length).toEqual(testProjects.length);
|
|
@@ -180,11 +185,10 @@ describe("downloadAndSaveBase", () => {
|
|
|
180
185
|
import_api.createApiClient.mockImplementation(() => ({
|
|
181
186
|
get: () => ({ data: mockData })
|
|
182
187
|
}));
|
|
183
|
-
const output = yield downloadAndSaveBase(
|
|
184
|
-
testProjects,
|
|
185
|
-
"android"
|
|
186
|
-
|
|
187
|
-
);
|
|
188
|
+
const output = yield downloadAndSaveBase({
|
|
189
|
+
projects: testProjects,
|
|
190
|
+
format: "android"
|
|
191
|
+
});
|
|
188
192
|
expect(/successfully saved/i.test(output)).toEqual(true);
|
|
189
193
|
const directoryContents = import_fs.default.readdirSync(import_consts.default.TEXT_DIR);
|
|
190
194
|
expect(directoryContents.length).toEqual(testProjects.length);
|
|
@@ -203,11 +207,10 @@ describe("downloadAndSaveBase", () => {
|
|
|
203
207
|
import_api.createApiClient.mockImplementation(() => ({
|
|
204
208
|
get: () => ({ data: mockData })
|
|
205
209
|
}));
|
|
206
|
-
const output = yield downloadAndSaveBase(
|
|
207
|
-
testProjects,
|
|
208
|
-
"ios-strings"
|
|
209
|
-
|
|
210
|
-
);
|
|
210
|
+
const output = yield downloadAndSaveBase({
|
|
211
|
+
projects: testProjects,
|
|
212
|
+
format: "ios-strings"
|
|
213
|
+
});
|
|
211
214
|
expect(/successfully saved/i.test(output)).toEqual(true);
|
|
212
215
|
const directoryContents = import_fs.default.readdirSync(import_consts.default.TEXT_DIR);
|
|
213
216
|
expect(directoryContents.length).toEqual(testProjects.length);
|
|
@@ -244,11 +247,10 @@ describe("downloadAndSaveBase", () => {
|
|
|
244
247
|
import_api.createApiClient.mockImplementation(() => ({
|
|
245
248
|
get: () => ({ data: mockData })
|
|
246
249
|
}));
|
|
247
|
-
const output = yield downloadAndSaveBase(
|
|
248
|
-
testProjects,
|
|
249
|
-
"ios-stringsdict"
|
|
250
|
-
|
|
251
|
-
);
|
|
250
|
+
const output = yield downloadAndSaveBase({
|
|
251
|
+
projects: testProjects,
|
|
252
|
+
format: "ios-stringsdict"
|
|
253
|
+
});
|
|
252
254
|
expect(/successfully saved/i.test(output)).toEqual(true);
|
|
253
255
|
const directoryContents = import_fs.default.readdirSync(import_consts.default.TEXT_DIR);
|
|
254
256
|
expect(directoryContents.length).toEqual(testProjects.length);
|
|
@@ -407,4 +409,4 @@ describe("getFormatDataIsValid", () => {
|
|
|
407
409
|
});
|
|
408
410
|
//# sourceMappingURL=pull.test.js.map
|
|
409
411
|
|
|
410
|
-
//# debugId=
|
|
412
|
+
//# debugId=587c3043-a9e4-58d4-9ce1-1464ba0c94e3
|