@dittowords/cli 4.3.0 → 4.4.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/bin/ditto.js CHANGED
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  "use strict";
3
- !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]="ff164041-941a-57a6-b654-0be6a12eef74")}catch(e){}}();
3
+ !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]="e0848367-0157-5a11-9ce1-253245c62388")}catch(e){}}();
4
4
 
5
5
  var __create = Object.create;
6
6
  var __defProp = Object.defineProperty;
@@ -93,7 +93,12 @@ const CONFIG_FILE_RELIANT_COMMANDS = [
93
93
  const COMMANDS = [
94
94
  {
95
95
  name: "pull",
96
- description: "Sync copy from Ditto into the current working directory"
96
+ description: "Sync copy from Ditto into the current working directory",
97
+ flags: {
98
+ "--sample-data": {
99
+ description: "Include sample data. Currently only supports variants."
100
+ }
101
+ }
97
102
  },
98
103
  {
99
104
  name: "project",
@@ -219,7 +224,10 @@ const executeCommand = (command, options) => __async(exports, null, function* ()
219
224
  switch (command) {
220
225
  case "none":
221
226
  case "pull": {
222
- return (0, import_pull.pull)({ meta: (0, import_processMetaOption.default)(meta) });
227
+ return (0, import_pull.pull)({
228
+ meta: (0, import_processMetaOption.default)(meta),
229
+ includeSampleData: options.sampleData || false
230
+ });
223
231
  }
224
232
  case "project":
225
233
  case "project add": {
@@ -279,4 +287,4 @@ const main = () => __async(exports, null, function* () {
279
287
  main();
280
288
  //# sourceMappingURL=ditto.js.map
281
289
 
282
- //# debugId=ff164041-941a-57a6-b654-0be6a12eef74
290
+ //# debugId=e0848367-0157-5a11-9ce1-253245c62388
package/bin/ditto.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../lib/ditto.ts"],"sourcesContent":["#!/usr/bin/env node\n// This is the main entry point for the ditto-cli command.\nimport { program } from \"commander\";\n// to use V8's code cache to speed up instantiation time\nimport \"v8-compile-cache\";\nimport fs from \"fs\";\nimport path from \"path\";\nimport * as Sentry from \"@sentry/node\";\nimport { version as release } from \"../package.json\";\n\nimport { init, needsTokenOrSource } from \"./init/init\";\nimport { pull } from \"./pull\";\nimport { quit } from \"./utils/quit\";\nimport addProject from \"./add-project\";\nimport removeProject from \"./remove-project\";\nimport { replace } from \"./replace\";\nimport { generateSuggestions } from \"./generate-suggestions\";\n\nimport processMetaOption from \"./utils/processMetaOption\";\nimport { importComponents } from \"./importComponents\";\nimport { showComponentFolders } from \"./component-folders\";\n\nconst environment = process.env.ENV || \"development\";\nSentry.init({ dsn: process.env.SENTRY_DSN, environment, release });\n\nfunction getVersion(): string {\n const packageJsonPath = path.join(__dirname, \"..\", \"package.json\");\n const packageJsonContent = fs.readFileSync(packageJsonPath, \"utf8\");\n const packageJson = JSON.parse(packageJsonContent) as { version: string };\n return packageJson.version;\n}\n\nconst VERSION = getVersion();\n\nconst CONFIG_FILE_RELIANT_COMMANDS = [\n \"pull\",\n \"none\",\n \"project\",\n \"project add\",\n \"project remove\",\n];\n\ntype Command =\n | \"pull\"\n | \"project\"\n | \"project add\"\n | \"project remove\"\n | \"component-folders\"\n | \"generate-suggestions\"\n | \"replace\"\n | \"import-components\";\n\ninterface CommandConfig<T extends Command | \"add\" | \"remove\"> {\n name: T;\n description: string;\n commands?: CommandConfig<\"add\" | \"remove\">[];\n flags?: {\n [flag: string]: { description: string; processor?: (value: string) => any };\n };\n}\n\nconst COMMANDS: CommandConfig<Command>[] = [\n {\n name: \"pull\",\n description: \"Sync copy from Ditto into the current working directory\",\n },\n {\n name: \"project\",\n description: \"Add a Ditto project to sync copy from\",\n commands: [\n {\n name: \"add\",\n description: \"Add a Ditto project to sync copy from\",\n },\n {\n name: \"remove\",\n description: \"Stop syncing copy from a Ditto project\",\n },\n ],\n },\n {\n name: \"component-folders\",\n description:\n \"List component folders in your workspace. More information about component folders can be found here: https://www.dittowords.com/docs/component-folders.\",\n flags: {\n \"-s, --sample-data\": {\n description: \"Includes the sample components folder in the output\",\n },\n },\n },\n {\n name: \"generate-suggestions\",\n description: \"Find text that can be potentially replaced with Ditto text\",\n flags: {\n \"-d, --directory [value]\": {\n description: \"Directory to search for text\",\n },\n \"-f, --files [value]\": {\n description: \"Files to search for text (will override -d)\",\n processor: (value: string) => value.split(\",\"),\n },\n \"-cf, --component-folder [value]\": {\n description: \"Component folder to search for matches\",\n },\n },\n },\n {\n name: \"replace\",\n description: \"Find and replace Ditto text with code\",\n flags: {\n \"-ln, --line-numbers [value]\": {\n description: \"Only replace text on a specific line number\",\n processor: (value: string) => value.split(\",\").map(Number),\n },\n },\n },\n {\n name: \"import-components\",\n description:\n \"Import components via a file. For more information please see: https://www.dittowords.com/docs/importing-string-files.\",\n flags: {\n \"-t, --text [value]\": {\n description: \"Text column index (.csv format only)\",\n },\n \"-n, --component-name [value]\": {\n description: \"Name column indexes (comma separated) (.csv format only)\",\n },\n \"-no, --notes [value]\": {\n description: \"Notes column index (.csv format only)\",\n },\n \"-t, --tags [value]\": {\n description: \"Tags column index (.csv format only)\",\n },\n \"-s, --status [value]\": {\n description: \"Status column index (.csv format only)\",\n },\n \"-c, --component-id [value]\": {\n description: \"Component ID column index (.csv format only)\",\n },\n },\n },\n];\n\nconst setupCommands = () => {\n program.name(\"ditto-cli\");\n\n COMMANDS.forEach((commandConfig) => {\n const cmd = program\n .command(commandConfig.name)\n .description(commandConfig.description)\n .action((options) => {\n return executeCommand(commandConfig.name, options);\n });\n\n if (commandConfig.flags) {\n Object.entries(commandConfig.flags).forEach(\n ([flags, { description, processor }]) => {\n if (processor) {\n cmd.option(flags, description, processor);\n } else {\n cmd.option(flags, description);\n }\n },\n );\n }\n\n if (\"commands\" in commandConfig && commandConfig.commands) {\n commandConfig.commands.forEach((nestedCommand) => {\n cmd\n .command(nestedCommand.name)\n .description(nestedCommand.description)\n .action((str, options) => {\n if (commandConfig.name === \"project\") {\n const command =\n `${commandConfig.name} ${nestedCommand.name}` as Command;\n\n return executeCommand(command, options);\n }\n });\n });\n }\n });\n};\n\nconst setupOptions = () => {\n program.option(\n \"-m, --meta <data...>\",\n \"Include arbitrary data in requests to the Ditto API. Ex: -m githubActionRequest:true trigger:manual\",\n );\n program.version(VERSION, \"-v, --version\", \"Output the current version\");\n};\n\nconst executeCommand = async (\n command: Command | \"none\",\n options: any,\n): Promise<void> => {\n const needsInitialization =\n CONFIG_FILE_RELIANT_COMMANDS.includes(command) && needsTokenOrSource();\n\n if (needsInitialization) {\n try {\n await init();\n } catch (error) {\n quit(\"Exiting Ditto CLI...\");\n return;\n }\n }\n\n const { meta } = program.opts();\n switch (command) {\n case \"none\":\n case \"pull\": {\n return pull({ meta: processMetaOption(meta) });\n }\n case \"project\":\n case \"project add\": {\n // initialization already includes the selection of a source,\n // so if `project add` is called during initialization, don't\n // prompt the user to select a source again\n if (needsInitialization) return;\n\n return addProject();\n }\n case \"project remove\": {\n return removeProject();\n }\n case \"component-folders\": {\n return showComponentFolders({\n showSampleData: options.sampleData,\n });\n }\n case \"generate-suggestions\": {\n return generateSuggestions({\n directory: options.directory,\n files: options.files,\n componentFolder: options.componentFolder,\n });\n }\n case \"replace\": {\n return replace(options.args, {\n ...(options?.lineNumbers ? { lineNumbers: options.lineNumbers } : {}),\n });\n }\n case \"import-components\": {\n if (options.args.length === 0) {\n console.info(\"Please provide a file path.\");\n return;\n }\n return importComponents(options.args[0], {\n csvColumnMapping: {\n name: options.componentName,\n text: options.text,\n notes: options.notes,\n tags: options.tags,\n status: options.status,\n componentId: options.componentId,\n },\n });\n }\n default: {\n quit(\"Exiting Ditto CLI...\");\n return;\n }\n }\n};\n\nconst main = async () => {\n setupCommands();\n setupOptions();\n\n if (process.argv.length <= 2 && process.argv[1].includes(\"ditto-cli\")) {\n await executeCommand(\"none\", []);\n return;\n }\n\n program.parse(process.argv);\n};\n\nmain();\n"],"names":["release","path","fs","processMetaOption","addProject","removeProject"],"mappings":"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","debug_id":"ff164041-941a-57a6-b654-0be6a12eef74"}
1
+ {"version":3,"sources":["../lib/ditto.ts"],"sourcesContent":["#!/usr/bin/env node\n// This is the main entry point for the ditto-cli command.\nimport { program } from \"commander\";\n// to use V8's code cache to speed up instantiation time\nimport \"v8-compile-cache\";\nimport fs from \"fs\";\nimport path from \"path\";\nimport * as Sentry from \"@sentry/node\";\nimport { version as release } from \"../package.json\";\n\nimport { init, needsTokenOrSource } from \"./init/init\";\nimport { pull } from \"./pull\";\nimport { quit } from \"./utils/quit\";\nimport addProject from \"./add-project\";\nimport removeProject from \"./remove-project\";\nimport { replace } from \"./replace\";\nimport { generateSuggestions } from \"./generate-suggestions\";\n\nimport processMetaOption from \"./utils/processMetaOption\";\nimport { importComponents } from \"./importComponents\";\nimport { showComponentFolders } from \"./component-folders\";\n\nconst environment = process.env.ENV || \"development\";\nSentry.init({ dsn: process.env.SENTRY_DSN, environment, release });\n\nfunction getVersion(): string {\n const packageJsonPath = path.join(__dirname, \"..\", \"package.json\");\n const packageJsonContent = fs.readFileSync(packageJsonPath, \"utf8\");\n const packageJson = JSON.parse(packageJsonContent) as { version: string };\n return packageJson.version;\n}\n\nconst VERSION = getVersion();\n\nconst CONFIG_FILE_RELIANT_COMMANDS = [\n \"pull\",\n \"none\",\n \"project\",\n \"project add\",\n \"project remove\",\n];\n\ntype Command =\n | \"pull\"\n | \"project\"\n | \"project add\"\n | \"project remove\"\n | \"component-folders\"\n | \"generate-suggestions\"\n | \"replace\"\n | \"import-components\";\n\ninterface CommandConfig<T extends Command | \"add\" | \"remove\"> {\n name: T;\n description: string;\n commands?: CommandConfig<\"add\" | \"remove\">[];\n flags?: {\n [flag: string]: { description: string; processor?: (value: string) => any };\n };\n}\n\nconst COMMANDS: CommandConfig<Command>[] = [\n {\n name: \"pull\",\n description: \"Sync copy from Ditto into the current working directory\",\n flags: {\n \"--sample-data\": {\n description: \"Include sample data. Currently only supports variants.\",\n },\n },\n },\n {\n name: \"project\",\n description: \"Add a Ditto project to sync copy from\",\n commands: [\n {\n name: \"add\",\n description: \"Add a Ditto project to sync copy from\",\n },\n {\n name: \"remove\",\n description: \"Stop syncing copy from a Ditto project\",\n },\n ],\n },\n {\n name: \"component-folders\",\n description:\n \"List component folders in your workspace. More information about component folders can be found here: https://www.dittowords.com/docs/component-folders.\",\n flags: {\n \"-s, --sample-data\": {\n description: \"Includes the sample components folder in the output\",\n },\n },\n },\n {\n name: \"generate-suggestions\",\n description: \"Find text that can be potentially replaced with Ditto text\",\n flags: {\n \"-d, --directory [value]\": {\n description: \"Directory to search for text\",\n },\n \"-f, --files [value]\": {\n description: \"Files to search for text (will override -d)\",\n processor: (value: string) => value.split(\",\"),\n },\n \"-cf, --component-folder [value]\": {\n description: \"Component folder to search for matches\",\n },\n },\n },\n {\n name: \"replace\",\n description: \"Find and replace Ditto text with code\",\n flags: {\n \"-ln, --line-numbers [value]\": {\n description: \"Only replace text on a specific line number\",\n processor: (value: string) => value.split(\",\").map(Number),\n },\n },\n },\n {\n name: \"import-components\",\n description:\n \"Import components via a file. For more information please see: https://www.dittowords.com/docs/importing-string-files.\",\n flags: {\n \"-t, --text [value]\": {\n description: \"Text column index (.csv format only)\",\n },\n \"-n, --component-name [value]\": {\n description: \"Name column indexes (comma separated) (.csv format only)\",\n },\n \"-no, --notes [value]\": {\n description: \"Notes column index (.csv format only)\",\n },\n \"-t, --tags [value]\": {\n description: \"Tags column index (.csv format only)\",\n },\n \"-s, --status [value]\": {\n description: \"Status column index (.csv format only)\",\n },\n \"-c, --component-id [value]\": {\n description: \"Component ID column index (.csv format only)\",\n },\n },\n },\n];\n\nconst setupCommands = () => {\n program.name(\"ditto-cli\");\n\n COMMANDS.forEach((commandConfig) => {\n const cmd = program\n .command(commandConfig.name)\n .description(commandConfig.description)\n .action((options) => {\n return executeCommand(commandConfig.name, options);\n });\n\n if (commandConfig.flags) {\n Object.entries(commandConfig.flags).forEach(\n ([flags, { description, processor }]) => {\n if (processor) {\n cmd.option(flags, description, processor);\n } else {\n cmd.option(flags, description);\n }\n },\n );\n }\n\n if (\"commands\" in commandConfig && commandConfig.commands) {\n commandConfig.commands.forEach((nestedCommand) => {\n cmd\n .command(nestedCommand.name)\n .description(nestedCommand.description)\n .action((str, options) => {\n if (commandConfig.name === \"project\") {\n const command =\n `${commandConfig.name} ${nestedCommand.name}` as Command;\n\n return executeCommand(command, options);\n }\n });\n });\n }\n });\n};\n\nconst setupOptions = () => {\n program.option(\n \"-m, --meta <data...>\",\n \"Include arbitrary data in requests to the Ditto API. Ex: -m githubActionRequest:true trigger:manual\",\n );\n program.version(VERSION, \"-v, --version\", \"Output the current version\");\n};\n\nconst executeCommand = async (\n command: Command | \"none\",\n options: any,\n): Promise<void> => {\n const needsInitialization =\n CONFIG_FILE_RELIANT_COMMANDS.includes(command) && needsTokenOrSource();\n\n if (needsInitialization) {\n try {\n await init();\n } catch (error) {\n quit(\"Exiting Ditto CLI...\");\n return;\n }\n }\n\n const { meta } = program.opts();\n switch (command) {\n case \"none\":\n case \"pull\": {\n return pull({\n meta: processMetaOption(meta),\n includeSampleData: options.sampleData || false,\n });\n }\n case \"project\":\n case \"project add\": {\n // initialization already includes the selection of a source,\n // so if `project add` is called during initialization, don't\n // prompt the user to select a source again\n if (needsInitialization) return;\n\n return addProject();\n }\n case \"project remove\": {\n return removeProject();\n }\n case \"component-folders\": {\n return showComponentFolders({\n showSampleData: options.sampleData,\n });\n }\n case \"generate-suggestions\": {\n return generateSuggestions({\n directory: options.directory,\n files: options.files,\n componentFolder: options.componentFolder,\n });\n }\n case \"replace\": {\n return replace(options.args, {\n ...(options?.lineNumbers ? { lineNumbers: options.lineNumbers } : {}),\n });\n }\n case \"import-components\": {\n if (options.args.length === 0) {\n console.info(\"Please provide a file path.\");\n return;\n }\n return importComponents(options.args[0], {\n csvColumnMapping: {\n name: options.componentName,\n text: options.text,\n notes: options.notes,\n tags: options.tags,\n status: options.status,\n componentId: options.componentId,\n },\n });\n }\n default: {\n quit(\"Exiting Ditto CLI...\");\n return;\n }\n }\n};\n\nconst main = async () => {\n setupCommands();\n setupOptions();\n\n if (process.argv.length <= 2 && process.argv[1].includes(\"ditto-cli\")) {\n await executeCommand(\"none\", []);\n return;\n }\n\n program.parse(process.argv);\n};\n\nmain();\n"],"names":["release","path","fs","processMetaOption","addProject","removeProject"],"mappings":"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","debug_id":"e0848367-0157-5a11-9ce1-253245c62388"}
@@ -1,8 +1,10 @@
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]="866c8df7-6e86-5dbc-b01e-d7764199da24")}catch(e){}}();
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]="c14a7377-c36c-50e8-a4bf-0bf9e61b622c")}catch(e){}}();
3
3
 
4
4
  var __defProp = Object.defineProperty;
5
+ var __defProps = Object.defineProperties;
5
6
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
7
+ var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
6
8
  var __getOwnPropNames = Object.getOwnPropertyNames;
7
9
  var __getOwnPropSymbols = Object.getOwnPropertySymbols;
8
10
  var __hasOwnProp = Object.prototype.hasOwnProperty;
@@ -19,6 +21,7 @@ var __spreadValues = (a, b) => {
19
21
  }
20
22
  return a;
21
23
  };
24
+ var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
22
25
  var __export = (target, all) => {
23
26
  for (var name in all)
24
27
  __defProp(target, name, { get: all[name], enumerable: true });
@@ -66,7 +69,7 @@ function fetchVariants(_0) {
66
69
  }
67
70
  const { shouldFetchComponentLibrary, validProjects } = source;
68
71
  const config = {
69
- params: __spreadValues({}, options == null ? void 0 : options.meta)
72
+ params: __spreadProps(__spreadValues({}, options == null ? void 0 : options.meta), { showSampleData: options.includeSampleData })
70
73
  };
71
74
  if (validProjects.length && !shouldFetchComponentLibrary) {
72
75
  config.params.projectIds = validProjects.map(({ id }) => id);
@@ -81,4 +84,4 @@ function fetchVariants(_0) {
81
84
  });
82
85
  //# sourceMappingURL=fetchVariants.js.map
83
86
 
84
- //# debugId=866c8df7-6e86-5dbc-b01e-d7764199da24
87
+ //# debugId=c14a7377-c36c-50e8-a4bf-0bf9e61b622c
@@ -1 +1 @@
1
- {"version":3,"sources":["../../lib/http/fetchVariants.ts"],"sourcesContent":["import { AxiosRequestConfig } from \"axios\";\nimport { createApiClient } from \"../api\";\nimport { PullOptions } from \"../pull\";\nimport { SourceInformation } from \"../types\";\n\nexport async function fetchVariants(\n source: SourceInformation,\n options: PullOptions = {}\n) {\n const api = createApiClient();\n if (!source.variants) {\n return null;\n }\n\n const { shouldFetchComponentLibrary, validProjects } = source;\n\n const config: AxiosRequestConfig = {\n params: { ...options?.meta },\n };\n\n // if we're not syncing from the component library, then we pass the project ids\n // to limit the list of returned variants to only those that are relevant for the\n // specified projects\n if (validProjects.length && !shouldFetchComponentLibrary) {\n config.params.projectIds = validProjects.map(({ id }) => id);\n }\n\n const { data } = await api.get<{ apiID: string }[]>(\"/v1/variants\", config);\n\n return data;\n}\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AACA,iBAAgC;AAIhC,SAAsB,cACpB,IAEA;AAAA,6CAFA,QACA,UAAuB,CAAC,GACxB;AACA,UAAM,UAAM,4BAAgB;AAC5B,QAAI,CAAC,OAAO,UAAU;AACpB,aAAO;AAAA,IACT;AAEA,UAAM,EAAE,6BAA6B,cAAc,IAAI;AAEvD,UAAM,SAA6B;AAAA,MACjC,QAAQ,mBAAK,mCAAS;AAAA,IACxB;AAKA,QAAI,cAAc,UAAU,CAAC,6BAA6B;AACxD,aAAO,OAAO,aAAa,cAAc,IAAI,CAAC,EAAE,GAAG,MAAM,EAAE;AAAA,IAC7D;AAEA,UAAM,EAAE,KAAK,IAAI,MAAM,IAAI,IAAyB,gBAAgB,MAAM;AAE1E,WAAO;AAAA,EACT;AAAA","debug_id":"866c8df7-6e86-5dbc-b01e-d7764199da24"}
1
+ {"version":3,"sources":["../../lib/http/fetchVariants.ts"],"sourcesContent":["import { AxiosRequestConfig } from \"axios\";\nimport { createApiClient } from \"../api\";\nimport { PullOptions } from \"../pull\";\nimport { SourceInformation } from \"../types\";\n\nexport async function fetchVariants(\n source: SourceInformation,\n options: PullOptions = {}\n) {\n const api = createApiClient();\n if (!source.variants) {\n return null;\n }\n\n const { shouldFetchComponentLibrary, validProjects } = source;\n\n const config: AxiosRequestConfig = {\n params: { ...options?.meta, showSampleData: options.includeSampleData },\n };\n\n // if we're not syncing from the component library, then we pass the project ids\n // to limit the list of returned variants to only those that are relevant for the\n // specified projects\n if (validProjects.length && !shouldFetchComponentLibrary) {\n config.params.projectIds = validProjects.map(({ id }) => id);\n }\n\n const { data } = await api.get<{ apiID: string }[]>(\"/v1/variants\", config);\n\n return data;\n}\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AACA,iBAAgC;AAIhC,SAAsB,cACpB,IAEA;AAAA,6CAFA,QACA,UAAuB,CAAC,GACxB;AACA,UAAM,UAAM,4BAAgB;AAC5B,QAAI,CAAC,OAAO,UAAU;AACpB,aAAO;AAAA,IACT;AAEA,UAAM,EAAE,6BAA6B,cAAc,IAAI;AAEvD,UAAM,SAA6B;AAAA,MACjC,QAAQ,iCAAK,mCAAS,OAAd,EAAoB,gBAAgB,QAAQ,kBAAkB;AAAA,IACxE;AAKA,QAAI,cAAc,UAAU,CAAC,6BAA6B;AACxD,aAAO,OAAO,aAAa,cAAc,IAAI,CAAC,EAAE,GAAG,MAAM,EAAE;AAAA,IAC7D;AAEA,UAAM,EAAE,KAAK,IAAI,MAAM,IAAI,IAAyB,gBAAgB,MAAM;AAE1E,WAAO;AAAA,EACT;AAAA","debug_id":"c14a7377-c36c-50e8-a4bf-0bf9e61b622c"}
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]="3cdae5df-bbfa-57e1-8775-9447478223bf")}catch(e){}}();
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]="3c71d6e7-64f7-5e7e-80fa-9eb5e324a67b")}catch(e){}}();
3
3
 
4
4
  var __create = Object.create;
5
5
  var __defProp = Object.defineProperty;
@@ -303,7 +303,7 @@ function downloadAndSave(source, token, options) {
303
303
  const spinner = (0, import_ora.default)(msg);
304
304
  spinner.start();
305
305
  const [variants, allComponentFoldersResponse] = yield Promise.all([
306
- (0, import_fetchVariants.fetchVariants)(source),
306
+ (0, import_fetchVariants.fetchVariants)(source, options),
307
307
  (0, import_fetchComponentFolders.fetchComponentFolders)({})
308
308
  ]);
309
309
  const allComponentFolders = Object.entries(
@@ -507,10 +507,14 @@ Choose others using the ${import_output.default.info("project")} command.`;
507
507
  }
508
508
  const pull = (options) => __async(void 0, null, function* () {
509
509
  const meta = options ? options.meta : {};
510
+ const includeSampleData = (options == null ? void 0 : options.includeSampleData) || false;
510
511
  const token = import_config.default.getToken(import_consts.default.CONFIG_FILE, import_consts.default.API_HOST);
511
512
  const sourceInformation = import_config.default.parseSourceInformation();
512
513
  try {
513
- return yield downloadAndSave(sourceInformation, token, { meta });
514
+ return yield downloadAndSave(sourceInformation, token, {
515
+ meta,
516
+ includeSampleData
517
+ });
514
518
  } catch (e) {
515
519
  const eventId = Sentry.captureException(e);
516
520
  const eventStr = `
@@ -547,4 +551,4 @@ var pull_default = {
547
551
  });
548
552
  //# sourceMappingURL=pull.js.map
549
553
 
550
- //# debugId=3cdae5df-bbfa-57e1-8775-9447478223bf
554
+ //# debugId=3c71d6e7-64f7-5e7e-80fa-9eb5e324a67b
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 SupportedExtension,\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 \"nested\",\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\", \"nested\", \"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: Record<SupportedFormat, SupportedExtension> = {\n flat: \".json\",\n nested: \".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 nested: 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\n // we need to clean the folder name by itself first, otherwise we can\n // end up with \"empty\" words and weird hyphenation.\n const nameFolder = `__${cleanFileName(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":"3cdae5df-bbfa-57e1-8775-9447478223bf"}
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 SupportedExtension,\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 \"nested\",\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\", \"nested\", \"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: Record<SupportedFormat, SupportedExtension> = {\n flat: \".json\",\n nested: \".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 nested: 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, options),\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\n // we need to clean the folder name by itself first, otherwise we can\n // end up with \"empty\" words and weird hyphenation.\n const nameFolder = `__${cleanFileName(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 includeSampleData?: boolean;\n}\n\nexport const pull = async (options?: PullOptions) => {\n const meta = options ? options.meta : {};\n const includeSampleData = options?.includeSampleData || false\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, {\n meta,\n includeSampleData,\n });\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":"3c71d6e7-64f7-5e7e-80fa-9eb5e324a67b"}
package/lib/ditto.ts CHANGED
@@ -63,6 +63,11 @@ const COMMANDS: CommandConfig<Command>[] = [
63
63
  {
64
64
  name: "pull",
65
65
  description: "Sync copy from Ditto into the current working directory",
66
+ flags: {
67
+ "--sample-data": {
68
+ description: "Include sample data. Currently only supports variants.",
69
+ },
70
+ },
66
71
  },
67
72
  {
68
73
  name: "project",
@@ -210,7 +215,10 @@ const executeCommand = async (
210
215
  switch (command) {
211
216
  case "none":
212
217
  case "pull": {
213
- return pull({ meta: processMetaOption(meta) });
218
+ return pull({
219
+ meta: processMetaOption(meta),
220
+ includeSampleData: options.sampleData || false,
221
+ });
214
222
  }
215
223
  case "project":
216
224
  case "project add": {
@@ -15,7 +15,7 @@ export async function fetchVariants(
15
15
  const { shouldFetchComponentLibrary, validProjects } = source;
16
16
 
17
17
  const config: AxiosRequestConfig = {
18
- params: { ...options?.meta },
18
+ params: { ...options?.meta, showSampleData: options.includeSampleData },
19
19
  };
20
20
 
21
21
  // if we're not syncing from the component library, then we pass the project ids
package/lib/pull.ts CHANGED
@@ -327,7 +327,7 @@ async function downloadAndSave(
327
327
  spinner.start();
328
328
 
329
329
  const [variants, allComponentFoldersResponse] = await Promise.all([
330
- fetchVariants(source),
330
+ fetchVariants(source, options),
331
331
  fetchComponentFolders({}),
332
332
  ]);
333
333
 
@@ -578,15 +578,20 @@ async function downloadAndSave(
578
578
 
579
579
  export interface PullOptions {
580
580
  meta?: Record<string, string>;
581
+ includeSampleData?: boolean;
581
582
  }
582
583
 
583
584
  export const pull = async (options?: PullOptions) => {
584
585
  const meta = options ? options.meta : {};
586
+ const includeSampleData = options?.includeSampleData || false
585
587
  const token = config.getToken(consts.CONFIG_FILE, consts.API_HOST);
586
588
  const sourceInformation = config.parseSourceInformation();
587
589
 
588
590
  try {
589
- return await downloadAndSave(sourceInformation, token, { meta });
591
+ return await downloadAndSave(sourceInformation, token, {
592
+ meta,
593
+ includeSampleData,
594
+ });
590
595
  } catch (e) {
591
596
  const eventId = Sentry.captureException(e);
592
597
  const eventStr = `\n\nError ID: ${output.info(eventId)}`;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dittowords/cli",
3
- "version": "4.3.0",
3
+ "version": "4.4.0",
4
4
  "description": "Command Line Interface for Ditto (dittowords.com).",
5
5
  "license": "MIT",
6
6
  "main": "bin/index.js",