@dittowords/cli 4.2.0 → 4.2.1

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]="298d9939-0eee-50da-a0d9-6a4b31b1fd34")}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]="ff164041-941a-57a6-b654-0be6a12eef74")}catch(e){}}();
4
4
 
5
5
  var __create = Object.create;
6
6
  var __defProp = Object.defineProperty;
@@ -83,6 +83,13 @@ function getVersion() {
83
83
  return packageJson.version;
84
84
  }
85
85
  const VERSION = getVersion();
86
+ const CONFIG_FILE_RELIANT_COMMANDS = [
87
+ "pull",
88
+ "none",
89
+ "project",
90
+ "project add",
91
+ "project remove"
92
+ ];
86
93
  const COMMANDS = [
87
94
  {
88
95
  name: "pull",
@@ -199,7 +206,7 @@ const setupOptions = () => {
199
206
  import_commander.program.version(VERSION, "-v, --version", "Output the current version");
200
207
  };
201
208
  const executeCommand = (command, options) => __async(exports, null, function* () {
202
- const needsInitialization = (0, import_init.needsTokenOrSource)();
209
+ const needsInitialization = CONFIG_FILE_RELIANT_COMMANDS.includes(command) && (0, import_init.needsTokenOrSource)();
203
210
  if (needsInitialization) {
204
211
  try {
205
212
  yield (0, import_init.init)();
@@ -272,4 +279,4 @@ const main = () => __async(exports, null, function* () {
272
279
  main();
273
280
  //# sourceMappingURL=ditto.js.map
274
281
 
275
- //# debugId=298d9939-0eee-50da-a0d9-6a4b31b1fd34
282
+ //# debugId=ff164041-941a-57a6-b654-0be6a12eef74
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\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 = needsTokenOrSource();\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":"298d9939-0eee-50da-a0d9-6a4b31b1fd34"}
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,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]="aa8e9998-6730-545b-965d-fd7d54610668")}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]="f22b8e5d-ede9-5c90-a7aa-258036e348df")}catch(e){}}();
3
3
 
4
4
  var __create = Object.create;
5
5
  var __defProp = Object.defineProperty;
@@ -114,7 +114,10 @@ function findComponentsInJSXFiles(params) {
114
114
  occurrences: {}
115
115
  });
116
116
  }
117
- if (path.node.value.includes(component.text)) {
117
+ if (
118
+ // Skip white space lines
119
+ !/^\s*$/.test(path.node.value) && !/^\s*$/.test(component.text) && path.node.value.includes(component.text)
120
+ ) {
118
121
  const escapedText = component.text.replace(
119
122
  /[.*+?^${}()|[\]\\]/g,
120
123
  "\\$&"
@@ -167,4 +170,4 @@ function replaceAt(str, index, searchString, replacement) {
167
170
  });
168
171
  //# sourceMappingURL=generate-suggestions.js.map
169
172
 
170
- //# debugId=aa8e9998-6730-545b-965d-fd7d54610668
173
+ //# debugId=f22b8e5d-ede9-5c90-a7aa-258036e348df
@@ -1 +1 @@
1
- {"version":3,"sources":["../lib/generate-suggestions.ts"],"sourcesContent":["import fs from \"fs-extra\";\nimport glob from \"glob\";\nimport { parse } from \"@babel/parser\";\nimport traverse from \"@babel/traverse\";\n\nimport {\n FetchComponentResponse,\n FetchComponentResponseComponent,\n fetchComponents,\n} from \"./http/fetchComponents\";\n\ninterface Occurrence {\n lineNumber: number;\n preview: string;\n}\n\ninterface Result extends FetchComponentResponseComponent {\n apiId: string;\n occurrences: {\n [file: string]: Occurrence[];\n };\n}\n\nasync function generateSuggestions(flags: {\n directory?: string;\n files?: string[];\n componentFolder?: string;\n}) {\n const components = await fetchComponents({\n ...(flags.componentFolder ? { componentFolder: flags.componentFolder} : {})\n });\n const directory = flags.directory || \".\";\n\n const results: { [apiId: string]: Result } = await findComponentsInJSXFiles({\n directory,\n files: flags.files,\n components,\n });\n\n // Display results to user\n console.log(JSON.stringify(results, null, 2));\n}\n\nasync function findComponentsInJSXFiles(params: {\n directory: string;\n files?: string[];\n components: FetchComponentResponse;\n}): Promise<{ [apiId: string]: Result }> {\n const result: { [apiId: string]: Result } = {};\n const files =\n params.files ||\n glob.sync(`${params.directory}/**/*.+(jsx|tsx)`, {\n ignore: \"**/node_modules/**\",\n });\n\n const promises: Promise<any>[] = [];\n\n for (const file of files) {\n promises.push(\n fs.readFile(file, \"utf-8\").then((code) => {\n const ast = parse(code, {\n sourceType: \"module\",\n plugins: [\"jsx\", \"typescript\"],\n });\n\n traverse(ast, {\n JSXText(path) {\n for (const [compApiId, component] of Object.entries(\n params.components\n )) {\n // If we haven't seen this component before, add it to the result\n if (!result[compApiId]) {\n result[compApiId] = {\n apiId: compApiId,\n ...component,\n occurrences: {},\n };\n }\n\n if (path.node.value.includes(component.text)) {\n // Escape all special characters from the text so we can use it in a regex\n const escapedText = component.text.replace(\n /[.*+?^${}()|[\\]\\\\]/g,\n \"\\\\$&\"\n );\n const regex = new RegExp(escapedText, \"g\");\n let match;\n while ((match = regex.exec(path.node.value)) !== null) {\n const lines = path.node.value\n .slice(0, match.index)\n .split(\"\\n\");\n\n if (!path.node.loc) {\n continue;\n }\n\n const lineNumber =\n path.node.loc.start.line + lines.length - 1;\n\n const codeLines = code.split(\"\\n\");\n const line = codeLines[lineNumber - 1];\n const preview = replaceAt(\n line,\n match.index,\n component.text,\n `${component.text}`\n );\n\n // Initialize the occurrences array if it doesn't exist\n if (!result[compApiId][\"occurrences\"][file]) {\n result[compApiId][\"occurrences\"][file] = [];\n }\n\n result[compApiId][\"occurrences\"][file].push({\n lineNumber,\n preview,\n });\n }\n }\n\n // Remove from result if no occurrences were found\n if (Object.keys(result[compApiId][\"occurrences\"]).length === 0) {\n delete result[compApiId];\n }\n }\n },\n });\n })\n );\n }\n\n await Promise.all(promises);\n\n return result;\n}\n\nfunction replaceAt(\n str: string,\n index: number,\n searchString: string,\n replacement: string\n) {\n return (\n str.substring(0, index) +\n str.substring(index, str.length).replace(searchString, replacement)\n );\n}\n\nexport { findComponentsInJSXFiles, generateSuggestions };\n"],"names":["glob","fs","traverse"],"mappings":"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","debug_id":"aa8e9998-6730-545b-965d-fd7d54610668"}
1
+ {"version":3,"sources":["../lib/generate-suggestions.ts"],"sourcesContent":["import fs from \"fs-extra\";\nimport glob from \"glob\";\nimport { parse } from \"@babel/parser\";\nimport traverse from \"@babel/traverse\";\n\nimport {\n FetchComponentResponse,\n FetchComponentResponseComponent,\n fetchComponents,\n} from \"./http/fetchComponents\";\n\ninterface Occurrence {\n lineNumber: number;\n preview: string;\n}\n\ninterface Result extends FetchComponentResponseComponent {\n apiId: string;\n occurrences: {\n [file: string]: Occurrence[];\n };\n}\n\nasync function generateSuggestions(flags: {\n directory?: string;\n files?: string[];\n componentFolder?: string;\n}) {\n const components = await fetchComponents({\n ...(flags.componentFolder\n ? { componentFolder: flags.componentFolder }\n : {}),\n });\n const directory = flags.directory || \".\";\n\n const results: { [apiId: string]: Result } = await findComponentsInJSXFiles({\n directory,\n files: flags.files,\n components,\n });\n\n // Display results to user\n console.log(JSON.stringify(results, null, 2));\n}\n\nasync function findComponentsInJSXFiles(params: {\n directory: string;\n files?: string[];\n components: FetchComponentResponse;\n}): Promise<{ [apiId: string]: Result }> {\n const result: { [apiId: string]: Result } = {};\n const files =\n params.files ||\n glob.sync(`${params.directory}/**/*.+(jsx|tsx)`, {\n ignore: \"**/node_modules/**\",\n });\n\n const promises: Promise<any>[] = [];\n\n for (const file of files) {\n promises.push(\n fs.readFile(file, \"utf-8\").then((code) => {\n const ast = parse(code, {\n sourceType: \"module\",\n plugins: [\"jsx\", \"typescript\"],\n });\n\n traverse(ast, {\n JSXText(path) {\n for (const [compApiId, component] of Object.entries(\n params.components,\n )) {\n // If we haven't seen this component before, add it to the result\n if (!result[compApiId]) {\n result[compApiId] = {\n apiId: compApiId,\n ...component,\n occurrences: {},\n };\n }\n\n if (\n // Skip white space lines\n !/^\\s*$/.test(path.node.value) &&\n !/^\\s*$/.test(component.text) &&\n path.node.value.includes(component.text)\n ) {\n // Escape all special characters from the text so we can use it in a regex\n const escapedText = component.text.replace(\n /[.*+?^${}()|[\\]\\\\]/g,\n \"\\\\$&\",\n );\n const regex = new RegExp(escapedText, \"g\");\n let match;\n while ((match = regex.exec(path.node.value)) !== null) {\n const lines = path.node.value\n .slice(0, match.index)\n .split(\"\\n\");\n\n if (!path.node.loc) {\n continue;\n }\n\n const lineNumber =\n path.node.loc.start.line + lines.length - 1;\n\n const codeLines = code.split(\"\\n\");\n const line = codeLines[lineNumber - 1];\n const preview = replaceAt(\n line,\n match.index,\n component.text,\n `${component.text}`,\n );\n\n // Initialize the occurrences array if it doesn't exist\n if (!result[compApiId][\"occurrences\"][file]) {\n result[compApiId][\"occurrences\"][file] = [];\n }\n\n result[compApiId][\"occurrences\"][file].push({\n lineNumber,\n preview,\n });\n }\n }\n\n // Remove from result if no occurrences were found\n if (Object.keys(result[compApiId][\"occurrences\"]).length === 0) {\n delete result[compApiId];\n }\n }\n },\n });\n }),\n );\n }\n\n await Promise.all(promises);\n\n return result;\n}\n\nfunction replaceAt(\n str: string,\n index: number,\n searchString: string,\n replacement: string,\n) {\n return (\n str.substring(0, index) +\n str.substring(index, str.length).replace(searchString, replacement)\n );\n}\n\nexport { findComponentsInJSXFiles, generateSuggestions };\n"],"names":["glob","fs","traverse"],"mappings":"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","debug_id":"f22b8e5d-ede9-5c90-a7aa-258036e348df"}
@@ -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]="d39c596f-987e-58e0-99f5-8f5f27ee9f5a")}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]="18334cda-4915-5b0f-9ca7-67da352f382b")}catch(e){}}();
3
3
 
4
4
  var __defProp = Object.defineProperty;
5
5
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
@@ -62,7 +62,7 @@ function fetchComponents(options) {
62
62
  }
63
63
  } else {
64
64
  const { data } = yield api.get(
65
- "/v1/components",
65
+ "/v1/components?format=structured",
66
66
  {}
67
67
  );
68
68
  return data;
@@ -75,4 +75,4 @@ function fetchComponents(options) {
75
75
  });
76
76
  //# sourceMappingURL=fetchComponents.js.map
77
77
 
78
- //# debugId=d39c596f-987e-58e0-99f5-8f5f27ee9f5a
78
+ //# debugId=18334cda-4915-5b0f-9ca7-67da352f382b
@@ -1 +1 @@
1
- {"version":3,"sources":["../../lib/http/fetchComponents.ts"],"sourcesContent":["import { createApiClient } from \"../api\";\n\nexport interface FetchComponentResponseComponent {\n name: string;\n text: string;\n status: \"NONE\" | \"WIP\" | \"REVIEW\" | \"FINAL\";\n folder: \"string\" | null;\n}\n\nexport interface FetchComponentResponse {\n [compApiId: string]: FetchComponentResponseComponent;\n}\n\nexport async function fetchComponents(options: {\n componentFolder?: string;\n}): Promise<FetchComponentResponse> {\n const api = createApiClient();\n\n if (options.componentFolder) {\n try {\n const { data } = await api.get<FetchComponentResponse>(\n `/v1/component-folders/${options.componentFolder}/components`,\n {}\n );\n\n return data;\n } catch (e) {\n console.log(\n `Failed to get components for ${options.componentFolder}. Please verify the folder's API ID.`\n );\n return {};\n }\n } else {\n const { data } = await api.get<FetchComponentResponse>(\n \"/v1/components\",\n {}\n );\n\n return data;\n }\n}\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,iBAAgC;AAahC,SAAsB,gBAAgB,SAEF;AAAA;AAClC,UAAM,UAAM,4BAAgB;AAE5B,QAAI,QAAQ,iBAAiB;AAC3B,UAAI;AACF,cAAM,EAAE,KAAK,IAAI,MAAM,IAAI;AAAA,UACzB,yBAAyB,QAAQ,eAAe;AAAA,UAChD,CAAC;AAAA,QACH;AAEA,eAAO;AAAA,MACT,SAAS,GAAG;AACV,gBAAQ;AAAA,UACN,gCAAgC,QAAQ,eAAe;AAAA,QACzD;AACA,eAAO,CAAC;AAAA,MACV;AAAA,IACF,OAAO;AACL,YAAM,EAAE,KAAK,IAAI,MAAM,IAAI;AAAA,QACzB;AAAA,QACA,CAAC;AAAA,MACH;AAEA,aAAO;AAAA,IACT;AAAA,EACF;AAAA","debug_id":"d39c596f-987e-58e0-99f5-8f5f27ee9f5a"}
1
+ {"version":3,"sources":["../../lib/http/fetchComponents.ts"],"sourcesContent":["import { createApiClient } from \"../api\";\n\nexport interface FetchComponentResponseComponent {\n name: string;\n text: string;\n status: \"NONE\" | \"WIP\" | \"REVIEW\" | \"FINAL\";\n folder: \"string\" | null;\n}\n\nexport interface FetchComponentResponse {\n [compApiId: string]: FetchComponentResponseComponent;\n}\n\nexport async function fetchComponents(options: {\n componentFolder?: string;\n}): Promise<FetchComponentResponse> {\n const api = createApiClient();\n\n if (options.componentFolder) {\n try {\n const { data } = await api.get<FetchComponentResponse>(\n `/v1/component-folders/${options.componentFolder}/components`,\n {}\n );\n\n return data;\n } catch (e) {\n console.log(\n `Failed to get components for ${options.componentFolder}. Please verify the folder's API ID.`\n );\n return {};\n }\n } else {\n const { data } = await api.get<FetchComponentResponse>(\n \"/v1/components?format=structured\",\n {}\n );\n\n return data;\n }\n}\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,iBAAgC;AAahC,SAAsB,gBAAgB,SAEF;AAAA;AAClC,UAAM,UAAM,4BAAgB;AAE5B,QAAI,QAAQ,iBAAiB;AAC3B,UAAI;AACF,cAAM,EAAE,KAAK,IAAI,MAAM,IAAI;AAAA,UACzB,yBAAyB,QAAQ,eAAe;AAAA,UAChD,CAAC;AAAA,QACH;AAEA,eAAO;AAAA,MACT,SAAS,GAAG;AACV,gBAAQ;AAAA,UACN,gCAAgC,QAAQ,eAAe;AAAA,QACzD;AACA,eAAO,CAAC;AAAA,MACV;AAAA,IACF,OAAO;AACL,YAAM,EAAE,KAAK,IAAI,MAAM,IAAI;AAAA,QACzB;AAAA,QACA,CAAC;AAAA,MACH;AAEA,aAAO;AAAA,IACT;AAAA,EACF;AAAA","debug_id":"18334cda-4915-5b0f-9ca7-67da352f382b"}
package/lib/ditto.ts CHANGED
@@ -32,6 +32,14 @@ function getVersion(): string {
32
32
 
33
33
  const VERSION = getVersion();
34
34
 
35
+ const CONFIG_FILE_RELIANT_COMMANDS = [
36
+ "pull",
37
+ "none",
38
+ "project",
39
+ "project add",
40
+ "project remove",
41
+ ];
42
+
35
43
  type Command =
36
44
  | "pull"
37
45
  | "project"
@@ -152,7 +160,7 @@ const setupCommands = () => {
152
160
  } else {
153
161
  cmd.option(flags, description);
154
162
  }
155
- }
163
+ },
156
164
  );
157
165
  }
158
166
 
@@ -177,16 +185,18 @@ const setupCommands = () => {
177
185
  const setupOptions = () => {
178
186
  program.option(
179
187
  "-m, --meta <data...>",
180
- "Include arbitrary data in requests to the Ditto API. Ex: -m githubActionRequest:true trigger:manual"
188
+ "Include arbitrary data in requests to the Ditto API. Ex: -m githubActionRequest:true trigger:manual",
181
189
  );
182
190
  program.version(VERSION, "-v, --version", "Output the current version");
183
191
  };
184
192
 
185
193
  const executeCommand = async (
186
194
  command: Command | "none",
187
- options: any
195
+ options: any,
188
196
  ): Promise<void> => {
189
- const needsInitialization = needsTokenOrSource();
197
+ const needsInitialization =
198
+ CONFIG_FILE_RELIANT_COMMANDS.includes(command) && needsTokenOrSource();
199
+
190
200
  if (needsInitialization) {
191
201
  try {
192
202
  await init();
@@ -27,7 +27,9 @@ async function generateSuggestions(flags: {
27
27
  componentFolder?: string;
28
28
  }) {
29
29
  const components = await fetchComponents({
30
- ...(flags.componentFolder ? { componentFolder: flags.componentFolder} : {})
30
+ ...(flags.componentFolder
31
+ ? { componentFolder: flags.componentFolder }
32
+ : {}),
31
33
  });
32
34
  const directory = flags.directory || ".";
33
35
 
@@ -66,7 +68,7 @@ async function findComponentsInJSXFiles(params: {
66
68
  traverse(ast, {
67
69
  JSXText(path) {
68
70
  for (const [compApiId, component] of Object.entries(
69
- params.components
71
+ params.components,
70
72
  )) {
71
73
  // If we haven't seen this component before, add it to the result
72
74
  if (!result[compApiId]) {
@@ -77,11 +79,16 @@ async function findComponentsInJSXFiles(params: {
77
79
  };
78
80
  }
79
81
 
80
- if (path.node.value.includes(component.text)) {
82
+ if (
83
+ // Skip white space lines
84
+ !/^\s*$/.test(path.node.value) &&
85
+ !/^\s*$/.test(component.text) &&
86
+ path.node.value.includes(component.text)
87
+ ) {
81
88
  // Escape all special characters from the text so we can use it in a regex
82
89
  const escapedText = component.text.replace(
83
90
  /[.*+?^${}()|[\]\\]/g,
84
- "\\$&"
91
+ "\\$&",
85
92
  );
86
93
  const regex = new RegExp(escapedText, "g");
87
94
  let match;
@@ -103,7 +110,7 @@ async function findComponentsInJSXFiles(params: {
103
110
  line,
104
111
  match.index,
105
112
  component.text,
106
- `${component.text}`
113
+ `${component.text}`,
107
114
  );
108
115
 
109
116
  // Initialize the occurrences array if it doesn't exist
@@ -125,7 +132,7 @@ async function findComponentsInJSXFiles(params: {
125
132
  }
126
133
  },
127
134
  });
128
- })
135
+ }),
129
136
  );
130
137
  }
131
138
 
@@ -138,7 +145,7 @@ function replaceAt(
138
145
  str: string,
139
146
  index: number,
140
147
  searchString: string,
141
- replacement: string
148
+ replacement: string,
142
149
  ) {
143
150
  return (
144
151
  str.substring(0, index) +
@@ -32,7 +32,7 @@ export async function fetchComponents(options: {
32
32
  }
33
33
  } else {
34
34
  const { data } = await api.get<FetchComponentResponse>(
35
- "/v1/components",
35
+ "/v1/components?format=structured",
36
36
  {}
37
37
  );
38
38
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dittowords/cli",
3
- "version": "4.2.0",
3
+ "version": "4.2.1",
4
4
  "description": "Command Line Interface for Ditto (dittowords.com).",
5
5
  "license": "MIT",
6
6
  "main": "bin/index.js",