@dittowords/cli 4.0.0 → 4.0.1-alpha.0
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 +12 -3
- package/bin/api.js +15 -3
- package/bin/api.js.map +1 -1
- package/bin/pull.js +13 -2
- package/bin/pull.js.map +1 -1
- package/lib/api.ts +17 -1
- package/lib/pull.ts +41 -27
- package/package.json +1 -1
- package/bin/sentry-test.js.map +0 -1
package/README.md
CHANGED
|
@@ -236,7 +236,7 @@ variants: true
|
|
|
236
236
|
The format that text data should be generated in. Accepted values:
|
|
237
237
|
|
|
238
238
|
- `structured`
|
|
239
|
-
|
|
239
|
+
- `flat`
|
|
240
240
|
- `android`
|
|
241
241
|
- `ios-strings`
|
|
242
242
|
- `ios-stringsdict` (will only include text that has pluralization enabled in Ditto)
|
|
@@ -338,13 +338,22 @@ richText: false
|
|
|
338
338
|
|
|
339
339
|
### `ditto/` Directory
|
|
340
340
|
|
|
341
|
-
This directory houses the configuration file (`ditto/config.yml`) used by the CLI and is also the default write destination for any files the CLI
|
|
341
|
+
This directory houses the configuration file (`ditto/config.yml`) used by the CLI and is also the default write destination for any output files the CLI writes to disk.
|
|
342
342
|
|
|
343
343
|
If you run the CLI in a directory that does not contain a `ditto/` folder, the folder and a default `config.yml` file will be automatically created.
|
|
344
344
|
|
|
345
345
|
#### Output Files
|
|
346
346
|
|
|
347
|
-
The CLI outputs data from Ditto by writing files to disk
|
|
347
|
+
The CLI outputs data from Ditto by writing files to disk. By default, these files are written to a `./ditto` folder relative to the current working directory, but the location of the output files can be customized by setting the environment variable `DITTO_TEXT_DIR`.
|
|
348
|
+
|
|
349
|
+
```bash
|
|
350
|
+
export DITTO_TEXT_DIR=./src/some-custom-path
|
|
351
|
+
|
|
352
|
+
# writes output files to ./src/some-custom-path
|
|
353
|
+
npx @dittowords/cli
|
|
354
|
+
```
|
|
355
|
+
|
|
356
|
+
The format and extension of such files will correspond to the `format` property of your configuration.
|
|
348
357
|
|
|
349
358
|
| **Format** | **File Extension** | **Common Usage** |
|
|
350
359
|
| :-------------: | :----------------: | :-----------------: |
|
package/bin/api.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]="a5a0c25e-7b00-51b0-9bcc-d86d951d5190")}catch(e){}}();
|
|
3
3
|
|
|
4
4
|
var __create = Object.create;
|
|
5
5
|
var __defProp = Object.defineProperty;
|
|
@@ -37,12 +37,24 @@ var import_axios = __toESM(require("axios"));
|
|
|
37
37
|
var import_config = __toESM(require("./config"));
|
|
38
38
|
var import_consts = __toESM(require("./consts"));
|
|
39
39
|
function createApiClient(token) {
|
|
40
|
-
|
|
40
|
+
const client = import_axios.default.create({
|
|
41
41
|
baseURL: import_consts.default.API_HOST,
|
|
42
42
|
headers: {
|
|
43
43
|
Authorization: `token ${token || import_config.default.getToken(import_consts.default.CONFIG_FILE, import_consts.default.API_HOST)}`
|
|
44
44
|
}
|
|
45
45
|
});
|
|
46
|
+
if (process.env.DEBUG_CLI) {
|
|
47
|
+
console.debug(`Host: ${import_consts.default.API_HOST}`);
|
|
48
|
+
client.interceptors.request.use((request) => {
|
|
49
|
+
console.debug("Starting Request", request.url);
|
|
50
|
+
return request;
|
|
51
|
+
});
|
|
52
|
+
client.interceptors.response.use((response) => {
|
|
53
|
+
console.debug("Response:", response);
|
|
54
|
+
return response;
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
return client;
|
|
46
58
|
}
|
|
47
59
|
// Annotate the CommonJS export names for ESM import in node:
|
|
48
60
|
0 && (module.exports = {
|
|
@@ -50,4 +62,4 @@ function createApiClient(token) {
|
|
|
50
62
|
});
|
|
51
63
|
//# sourceMappingURL=api.js.map
|
|
52
64
|
|
|
53
|
-
//# debugId=
|
|
65
|
+
//# debugId=a5a0c25e-7b00-51b0-9bcc-d86d951d5190
|
package/bin/api.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../lib/api.ts"],"sourcesContent":["import axios from \"axios\";\n\nimport config from \"./config\";\nimport consts from \"./consts\";\n\nexport function createApiClient(token?: string) {\n
|
|
1
|
+
{"version":3,"sources":["../lib/api.ts"],"sourcesContent":["import axios from \"axios\";\n\nimport config from \"./config\";\nimport consts from \"./consts\";\n\nexport function createApiClient(token?: string) {\n const client = axios.create({\n baseURL: consts.API_HOST,\n headers: {\n Authorization: `token ${\n token || config.getToken(consts.CONFIG_FILE, consts.API_HOST)\n }`,\n },\n });\n\n if (process.env.DEBUG_CLI) {\n console.debug(`Host: ${consts.API_HOST}`);\n\n client.interceptors.request.use((request) => {\n console.debug(\"Starting Request\", request.url);\n return request;\n });\n\n client.interceptors.response.use(response => {\n console.debug('Response:', response);\n return response;\n });\n }\n\n return client;\n}\n"],"names":["axios","consts","config"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,mBAAkB;AAElB,oBAAmB;AACnB,oBAAmB;AAEZ,SAAS,gBAAgB,OAAgB;AAC9C,QAAM,SAAS,aAAAA,QAAM,OAAO;AAAA,IAC1B,SAAS,cAAAC,QAAO;AAAA,IAChB,SAAS;AAAA,MACP,eAAe,SACb,SAAS,cAAAC,QAAO,SAAS,cAAAD,QAAO,aAAa,cAAAA,QAAO,QAAQ,CAC9D;AAAA,IACF;AAAA,EACF,CAAC;AAED,MAAI,QAAQ,IAAI,WAAW;AACzB,YAAQ,MAAM,SAAS,cAAAA,QAAO,QAAQ,EAAE;AAExC,WAAO,aAAa,QAAQ,IAAI,CAAC,YAAY;AAC3C,cAAQ,MAAM,oBAAoB,QAAQ,GAAG;AAC7C,aAAO;AAAA,IACT,CAAC;AAED,WAAO,aAAa,SAAS,IAAI,cAAY;AAC3C,cAAQ,MAAM,aAAa,QAAQ;AACnC,aAAO;AAAA,IACT,CAAC;AAAA,EACH;AAEA,SAAO;AACT","debug_id":"a5a0c25e-7b00-51b0-9bcc-d86d951d5190"}
|
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]="c9033e67-0b68-5118-944f-a91f2383e9dd")}catch(e){}}();
|
|
3
3
|
|
|
4
4
|
var __create = Object.create;
|
|
5
5
|
var __defProp = Object.defineProperty;
|
|
@@ -259,6 +259,14 @@ function cleanOutputFiles() {
|
|
|
259
259
|
function downloadAndSave(source, token, options) {
|
|
260
260
|
return __async(this, null, function* () {
|
|
261
261
|
const api = (0, import_api.createApiClient)();
|
|
262
|
+
if (process.env.DEBUG_CLI) {
|
|
263
|
+
try {
|
|
264
|
+
yield api.get("/health");
|
|
265
|
+
console.debug("Can connect to api.dittowords.com");
|
|
266
|
+
} catch (e) {
|
|
267
|
+
console.debug("CANNOT connect to api.dittowords.com");
|
|
268
|
+
}
|
|
269
|
+
}
|
|
262
270
|
const {
|
|
263
271
|
validProjects,
|
|
264
272
|
format: formatFromSource,
|
|
@@ -463,6 +471,9 @@ const pull = (options) => __async(void 0, null, function* () {
|
|
|
463
471
|
const meta = options ? options.meta : {};
|
|
464
472
|
const token = import_config.default.getToken(import_consts.default.CONFIG_FILE, import_consts.default.API_HOST);
|
|
465
473
|
const sourceInformation = import_config.default.parseSourceInformation();
|
|
474
|
+
if (process.env.DEBUG_CLI === "true") {
|
|
475
|
+
console.debug(`Token: ${token}`);
|
|
476
|
+
}
|
|
466
477
|
try {
|
|
467
478
|
return yield downloadAndSave(sourceInformation, token, { meta });
|
|
468
479
|
} catch (e) {
|
|
@@ -500,4 +511,4 @@ var pull_default = {
|
|
|
500
511
|
});
|
|
501
512
|
//# sourceMappingURL=pull.js.map
|
|
502
513
|
|
|
503
|
-
//# debugId=
|
|
514
|
+
//# debugId=c9033e67-0b68-5118-944f-a91f2383e9dd
|
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\";\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\n if (process.env.DEBUG_CLI) {\n try {\n await api.get(\"/health\");\n console.debug(\"Can connect to api.dittowords.com\");\n } catch {\n console.debug(\"CANNOT connect to api.dittowords.com\");\n }\n }\n\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 if (process.env.DEBUG_CLI === \"true\") {\n console.debug(`Token: ${token}`);\n }\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":"c9033e67-0b68-5118-944f-a91f2383e9dd"}
|
package/lib/api.ts
CHANGED
|
@@ -4,7 +4,7 @@ import config from "./config";
|
|
|
4
4
|
import consts from "./consts";
|
|
5
5
|
|
|
6
6
|
export function createApiClient(token?: string) {
|
|
7
|
-
|
|
7
|
+
const client = axios.create({
|
|
8
8
|
baseURL: consts.API_HOST,
|
|
9
9
|
headers: {
|
|
10
10
|
Authorization: `token ${
|
|
@@ -12,4 +12,20 @@ export function createApiClient(token?: string) {
|
|
|
12
12
|
}`,
|
|
13
13
|
},
|
|
14
14
|
});
|
|
15
|
+
|
|
16
|
+
if (process.env.DEBUG_CLI) {
|
|
17
|
+
console.debug(`Host: ${consts.API_HOST}`);
|
|
18
|
+
|
|
19
|
+
client.interceptors.request.use((request) => {
|
|
20
|
+
console.debug("Starting Request", request.url);
|
|
21
|
+
return request;
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
client.interceptors.response.use(response => {
|
|
25
|
+
console.debug('Response:', response);
|
|
26
|
+
return response;
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
return client;
|
|
15
31
|
}
|
package/lib/pull.ts
CHANGED
|
@@ -55,7 +55,7 @@ const FORMAT_EXTENSIONS = {
|
|
|
55
55
|
const getJsonFormatIsValid = (data: string) => {
|
|
56
56
|
try {
|
|
57
57
|
return Object.keys(JSON.parse(data)).some(
|
|
58
|
-
(k) => !k.startsWith("__variant")
|
|
58
|
+
(k) => !k.startsWith("__variant"),
|
|
59
59
|
);
|
|
60
60
|
} catch {
|
|
61
61
|
return false;
|
|
@@ -73,12 +73,12 @@ export const getFormatDataIsValid = {
|
|
|
73
73
|
};
|
|
74
74
|
|
|
75
75
|
const getFormat = (
|
|
76
|
-
formatFromSource: string | string[] | undefined
|
|
76
|
+
formatFromSource: string | string[] | undefined,
|
|
77
77
|
): SupportedFormat[] => {
|
|
78
78
|
const formats = (
|
|
79
79
|
Array.isArray(formatFromSource) ? formatFromSource : [formatFromSource]
|
|
80
80
|
).filter((format) =>
|
|
81
|
-
SUPPORTED_FORMATS.includes(format as SupportedFormat)
|
|
81
|
+
SUPPORTED_FORMATS.includes(format as SupportedFormat),
|
|
82
82
|
) as SupportedFormat[];
|
|
83
83
|
|
|
84
84
|
if (formats.length) {
|
|
@@ -123,7 +123,7 @@ async function downloadAndSaveVariant(
|
|
|
123
123
|
format: SupportedFormat,
|
|
124
124
|
status: string | undefined,
|
|
125
125
|
richText: boolean | undefined,
|
|
126
|
-
token?: Token
|
|
126
|
+
token?: Token,
|
|
127
127
|
) {
|
|
128
128
|
const api = createApiClient();
|
|
129
129
|
const params: Record<string, string | null> = { variant: variantApiId };
|
|
@@ -153,7 +153,7 @@ async function downloadAndSaveVariant(
|
|
|
153
153
|
const extension = getFormatExtension(format);
|
|
154
154
|
|
|
155
155
|
const filename = cleanFileName(
|
|
156
|
-
project.fileName + ("__" + (variantApiId || "base")) + extension
|
|
156
|
+
project.fileName + ("__" + (variantApiId || "base")) + extension,
|
|
157
157
|
);
|
|
158
158
|
const filepath = path.join(consts.TEXT_DIR, filename);
|
|
159
159
|
|
|
@@ -169,7 +169,7 @@ async function downloadAndSaveVariant(
|
|
|
169
169
|
|
|
170
170
|
await writeFile(filepath, dataString);
|
|
171
171
|
return getSavedMessage(filename);
|
|
172
|
-
})
|
|
172
|
+
}),
|
|
173
173
|
);
|
|
174
174
|
|
|
175
175
|
return savedMessages.join("");
|
|
@@ -181,12 +181,12 @@ async function downloadAndSaveVariants(
|
|
|
181
181
|
format: SupportedFormat,
|
|
182
182
|
status: string | undefined,
|
|
183
183
|
richText: boolean | undefined,
|
|
184
|
-
token?: Token
|
|
184
|
+
token?: Token,
|
|
185
185
|
) {
|
|
186
186
|
const messages = await Promise.all([
|
|
187
187
|
downloadAndSaveVariant(null, projects, format, status, richText, token),
|
|
188
188
|
...variants.map(({ apiID }: { apiID: string }) =>
|
|
189
|
-
downloadAndSaveVariant(apiID, projects, format, status, richText, token)
|
|
189
|
+
downloadAndSaveVariant(apiID, projects, format, status, richText, token),
|
|
190
190
|
),
|
|
191
191
|
]);
|
|
192
192
|
|
|
@@ -199,7 +199,7 @@ async function downloadAndSaveBase(
|
|
|
199
199
|
status: string | undefined,
|
|
200
200
|
richText?: boolean | undefined,
|
|
201
201
|
token?: Token,
|
|
202
|
-
options?: PullOptions
|
|
202
|
+
options?: PullOptions,
|
|
203
203
|
) {
|
|
204
204
|
const api = createApiClient();
|
|
205
205
|
const params = { ...options?.meta };
|
|
@@ -238,7 +238,7 @@ async function downloadAndSaveBase(
|
|
|
238
238
|
|
|
239
239
|
await writeFile(filepath, dataString);
|
|
240
240
|
return getSavedMessage(filename);
|
|
241
|
-
})
|
|
241
|
+
}),
|
|
242
242
|
);
|
|
243
243
|
|
|
244
244
|
return savedMessages.join("");
|
|
@@ -266,9 +266,19 @@ function cleanOutputFiles() {
|
|
|
266
266
|
async function downloadAndSave(
|
|
267
267
|
source: SourceInformation,
|
|
268
268
|
token?: Token,
|
|
269
|
-
options?: PullOptions
|
|
269
|
+
options?: PullOptions,
|
|
270
270
|
) {
|
|
271
271
|
const api = createApiClient();
|
|
272
|
+
|
|
273
|
+
if (process.env.DEBUG_CLI) {
|
|
274
|
+
try {
|
|
275
|
+
await api.get("/health");
|
|
276
|
+
console.debug("Can connect to api.dittowords.com");
|
|
277
|
+
} catch {
|
|
278
|
+
console.debug("CANNOT connect to api.dittowords.com");
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
|
|
272
282
|
const {
|
|
273
283
|
validProjects,
|
|
274
284
|
format: formatFromSource,
|
|
@@ -291,17 +301,17 @@ async function downloadAndSave(
|
|
|
291
301
|
]);
|
|
292
302
|
|
|
293
303
|
const allComponentFolders = Object.entries(
|
|
294
|
-
allComponentFoldersResponse
|
|
304
|
+
allComponentFoldersResponse,
|
|
295
305
|
).reduce(
|
|
296
306
|
(acc, [id, name]) => acc.concat([{ id, name }]),
|
|
297
|
-
[] as ComponentFolder[]
|
|
307
|
+
[] as ComponentFolder[],
|
|
298
308
|
);
|
|
299
309
|
|
|
300
310
|
try {
|
|
301
311
|
msg += cleanOutputFiles();
|
|
302
312
|
msg += `\nFetching the latest text from ${sourcesToText(
|
|
303
313
|
validProjects,
|
|
304
|
-
shouldFetchComponentLibrary
|
|
314
|
+
shouldFetchComponentLibrary,
|
|
305
315
|
)}\n`;
|
|
306
316
|
|
|
307
317
|
const meta = options ? options.meta : {};
|
|
@@ -403,7 +413,7 @@ async function downloadAndSave(
|
|
|
403
413
|
const namePostfix = `__${variantApiId || "base"}`;
|
|
404
414
|
|
|
405
415
|
const fileName = cleanFileName(
|
|
406
|
-
`${nameBase}${nameFolder}${namePostfix}${nameExt}
|
|
416
|
+
`${nameBase}${nameFolder}${namePostfix}${nameExt}`,
|
|
407
417
|
);
|
|
408
418
|
const filePath = path.join(consts.TEXT_DIR, fileName);
|
|
409
419
|
|
|
@@ -428,7 +438,7 @@ async function downloadAndSave(
|
|
|
428
438
|
});
|
|
429
439
|
|
|
430
440
|
return getSavedMessage(fileName);
|
|
431
|
-
})
|
|
441
|
+
}),
|
|
432
442
|
);
|
|
433
443
|
});
|
|
434
444
|
|
|
@@ -450,7 +460,7 @@ async function downloadAndSave(
|
|
|
450
460
|
format,
|
|
451
461
|
status,
|
|
452
462
|
richText,
|
|
453
|
-
token
|
|
463
|
+
token,
|
|
454
464
|
)
|
|
455
465
|
: await downloadAndSaveBase(
|
|
456
466
|
validProjects,
|
|
@@ -460,7 +470,7 @@ async function downloadAndSave(
|
|
|
460
470
|
token,
|
|
461
471
|
{
|
|
462
472
|
meta,
|
|
463
|
-
}
|
|
473
|
+
},
|
|
464
474
|
);
|
|
465
475
|
}
|
|
466
476
|
|
|
@@ -492,7 +502,7 @@ async function downloadAndSave(
|
|
|
492
502
|
if (e.response && e.response.status === 401) {
|
|
493
503
|
error = "You don't have access to the selected projects";
|
|
494
504
|
msg = `${output.errorText(error)}.\nChoose others using the ${output.info(
|
|
495
|
-
"project"
|
|
505
|
+
"project",
|
|
496
506
|
)} command, or update your API key.`;
|
|
497
507
|
return console.log(msg);
|
|
498
508
|
}
|
|
@@ -500,11 +510,11 @@ async function downloadAndSave(
|
|
|
500
510
|
error =
|
|
501
511
|
"One or more of the requested projects don't have Developer Mode enabled";
|
|
502
512
|
msg = `${output.errorText(
|
|
503
|
-
error
|
|
513
|
+
error,
|
|
504
514
|
)}.\nPlease choose different projects using the ${output.info(
|
|
505
|
-
"project"
|
|
515
|
+
"project",
|
|
506
516
|
)} command, or turn on Developer Mode for all selected projects. Learn more here: ${output.subtle(
|
|
507
|
-
"https://www.dittowords.com/docs/ditto-developer-mode"
|
|
517
|
+
"https://www.dittowords.com/docs/ditto-developer-mode",
|
|
508
518
|
)}.`;
|
|
509
519
|
return console.log(msg);
|
|
510
520
|
}
|
|
@@ -512,7 +522,7 @@ async function downloadAndSave(
|
|
|
512
522
|
error = "projects not found";
|
|
513
523
|
}
|
|
514
524
|
msg = `We hit an error fetching text from the projects: ${output.errorText(
|
|
515
|
-
error
|
|
525
|
+
error,
|
|
516
526
|
)}.\nChoose others using the ${output.info("project")} command.`;
|
|
517
527
|
return console.log(msg);
|
|
518
528
|
}
|
|
@@ -527,6 +537,10 @@ export const pull = async (options?: PullOptions) => {
|
|
|
527
537
|
const token = config.getToken(consts.CONFIG_FILE, consts.API_HOST);
|
|
528
538
|
const sourceInformation = config.parseSourceInformation();
|
|
529
539
|
|
|
540
|
+
if (process.env.DEBUG_CLI === "true") {
|
|
541
|
+
console.debug(`Token: ${token}`);
|
|
542
|
+
}
|
|
543
|
+
|
|
530
544
|
try {
|
|
531
545
|
return await downloadAndSave(sourceInformation, token, { meta });
|
|
532
546
|
} catch (e) {
|
|
@@ -535,15 +549,15 @@ export const pull = async (options?: PullOptions) => {
|
|
|
535
549
|
if (e instanceof AxiosError) {
|
|
536
550
|
return quit(
|
|
537
551
|
output.errorText(
|
|
538
|
-
"Something went wrong connecting to Ditto servers. Please contact support or try again later."
|
|
539
|
-
) + eventStr
|
|
552
|
+
"Something went wrong connecting to Ditto servers. Please contact support or try again later.",
|
|
553
|
+
) + eventStr,
|
|
540
554
|
);
|
|
541
555
|
}
|
|
542
556
|
|
|
543
557
|
return quit(
|
|
544
558
|
output.errorText(
|
|
545
|
-
"Something went wrong. Please contact support or try again later."
|
|
546
|
-
) + eventStr
|
|
559
|
+
"Something went wrong. Please contact support or try again later.",
|
|
560
|
+
) + eventStr,
|
|
547
561
|
);
|
|
548
562
|
}
|
|
549
563
|
};
|
package/package.json
CHANGED
package/bin/sentry-test.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../lib/sentry-test.ts"],"sourcesContent":["import * as Sentry from \"@sentry/node\";\nSentry.init({\n dsn: \"https://9c1d99fa4267f54c6b914f720b4ed3a2@o979374.ingest.sentry.io/4505705213919232\",\n debug: true,\n});\nSentry.captureException(new Error(\"new test exception\"));\nconsole.log(\"captured exception\");\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;AAAA,aAAwB;AACxB,OAAO,KAAK;AAAA,EACV,KAAK;AAAA,EACL,OAAO;AACT,CAAC;AACD,OAAO,iBAAiB,IAAI,MAAM,oBAAoB,CAAC;AACvD,QAAQ,IAAI,oBAAoB","debug_id":"01741d01-3103-54ae-87e5-0199defce6e9"}
|