@dittowords/cli 4.4.0 → 4.5.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.
Files changed (87) hide show
  1. package/.github/actions/install-node-dependencies/action.yml +24 -0
  2. package/.github/workflows/required-checks.yml +24 -0
  3. package/__mocks__/fs.js +2 -0
  4. package/bin/__mocks__/api.js +48 -0
  5. package/bin/__mocks__/api.js.map +1 -0
  6. package/bin/config.js +6 -4
  7. package/bin/config.js.map +1 -1
  8. package/bin/config.test.js +4 -3
  9. package/bin/config.test.js.map +1 -1
  10. package/bin/consts.js +19 -29
  11. package/bin/consts.js.map +1 -1
  12. package/bin/generate-suggestions.js +68 -58
  13. package/bin/generate-suggestions.js.map +1 -1
  14. package/bin/generate-suggestions.test.js +24 -13
  15. package/bin/generate-suggestions.test.js.map +1 -1
  16. package/bin/http/__mocks__/fetchComponentFolders.js +71 -0
  17. package/bin/http/__mocks__/fetchComponentFolders.js.map +1 -0
  18. package/bin/http/__mocks__/fetchComponents.js +73 -0
  19. package/bin/http/__mocks__/fetchComponents.js.map +1 -0
  20. package/bin/http/__mocks__/fetchVariants.js +71 -0
  21. package/bin/http/__mocks__/fetchVariants.js.map +1 -0
  22. package/bin/http/fetchComponentFolders.js +4 -4
  23. package/bin/http/fetchComponentFolders.js.map +1 -1
  24. package/bin/http/fetchComponents.js +4 -4
  25. package/bin/http/fetchComponents.js.map +1 -1
  26. package/bin/http/fetchVariants.js +2 -2
  27. package/bin/http/fetchVariants.js.map +1 -1
  28. package/bin/http/http.test.js +159 -0
  29. package/bin/http/http.test.js.map +1 -0
  30. package/bin/http/importComponents.js +9 -2
  31. package/bin/http/importComponents.js.map +1 -1
  32. package/bin/init/project.test.js +5 -28
  33. package/bin/init/project.test.js.map +1 -1
  34. package/bin/init/token.js +72 -27
  35. package/bin/init/token.js.map +1 -1
  36. package/bin/init/token.test.js +87 -9
  37. package/bin/init/token.test.js.map +1 -1
  38. package/bin/pull-lib.test.js +379 -0
  39. package/bin/pull-lib.test.js.map +1 -0
  40. package/bin/pull.js +13 -5
  41. package/bin/pull.js.map +1 -1
  42. package/bin/pull.test.js +100 -289
  43. package/bin/pull.test.js.map +1 -1
  44. package/bin/replace.js +22 -6
  45. package/bin/replace.js.map +1 -1
  46. package/bin/replace.test.js +53 -11
  47. package/bin/replace.test.js.map +1 -1
  48. package/bin/types.js +2 -2
  49. package/bin/types.js.map +1 -1
  50. package/bin/utils/determineModuleType.js +6 -7
  51. package/bin/utils/determineModuleType.js.map +1 -1
  52. package/bin/utils/determineModuleType.test.js +60 -0
  53. package/bin/utils/determineModuleType.test.js.map +1 -0
  54. package/bin/utils/getSelectedProjects.js +5 -5
  55. package/bin/utils/getSelectedProjects.js.map +1 -1
  56. package/bin/utils/quit.js +3 -3
  57. package/bin/utils/quit.js.map +1 -1
  58. package/jest.config.ts +16 -0
  59. package/lib/__mocks__/api.ts +12 -0
  60. package/lib/config.test.ts +3 -1
  61. package/lib/config.ts +4 -2
  62. package/lib/consts.ts +19 -17
  63. package/lib/generate-suggestions.test.ts +23 -11
  64. package/lib/generate-suggestions.ts +89 -79
  65. package/lib/http/__mocks__/fetchComponentFolders.ts +23 -0
  66. package/lib/http/__mocks__/fetchComponents.ts +24 -0
  67. package/lib/http/__mocks__/fetchVariants.ts +21 -0
  68. package/lib/http/fetchComponentFolders.ts +6 -4
  69. package/lib/http/fetchComponents.ts +5 -3
  70. package/lib/http/fetchVariants.ts +14 -3
  71. package/lib/http/http.test.ts +122 -0
  72. package/lib/http/importComponents.ts +8 -0
  73. package/lib/init/project.test.ts +4 -27
  74. package/lib/init/token.test.ts +55 -7
  75. package/lib/init/token.ts +76 -27
  76. package/lib/pull-lib.test.ts +367 -0
  77. package/lib/pull.test.ts +97 -310
  78. package/lib/pull.ts +11 -3
  79. package/lib/replace.test.ts +46 -10
  80. package/lib/replace.ts +20 -3
  81. package/lib/types.ts +5 -0
  82. package/lib/utils/determineModuleType.test.ts +48 -0
  83. package/lib/utils/determineModuleType.ts +4 -6
  84. package/lib/utils/getSelectedProjects.ts +3 -3
  85. package/lib/utils/quit.ts +1 -1
  86. package/package.json +4 -3
  87. package/jest.config.js +0 -6
@@ -0,0 +1,24 @@
1
+ name: "Install Node Dependencies"
2
+ description: "Attempts to install Node.js dependencing leveraging yarn and caching"
3
+
4
+ inputs:
5
+ working-directory:
6
+ required: false
7
+ description: "The directory to run the install command in"
8
+ default: ./
9
+
10
+ runs:
11
+ using: "composite"
12
+ steps:
13
+ - uses: actions/cache@v3
14
+ env:
15
+ cache-name: node_modules-cache
16
+ with:
17
+ path: ${{ inputs.working-directory }}node_modules
18
+ key: ${{ runner.os }}-build-${{ hashFiles('**/yarn.lock') }}
19
+ restore-keys: |
20
+ ${{ runner.os }}-build
21
+
22
+ - name: Install new dependencies
23
+ shell: bash
24
+ run: cd ${{ inputs.working-directory }} && yarn install --prefer-offline --frozen-lockfile
@@ -0,0 +1,24 @@
1
+ name: "Required Checks"
2
+
3
+ on:
4
+ pull_request:
5
+ branches:
6
+ - master
7
+
8
+ jobs:
9
+ jest-tests:
10
+ runs-on: ubuntu-20.04
11
+ timeout-minutes: 5
12
+ strategy:
13
+ fail-fast: false
14
+ steps:
15
+ - uses: actions/checkout@v3
16
+ - name: Use Node.js
17
+ uses: actions/setup-node@v3
18
+ with:
19
+ node-version: 20
20
+ - uses: ./.github/actions/install-node-dependencies
21
+ - name: Jest Tests
22
+ run: |
23
+ npx jest --ci --silent --maxWorkers=1
24
+ shell: bash
@@ -0,0 +1,2 @@
1
+ const { fs } = require("memfs");
2
+ module.exports = fs;
@@ -0,0 +1,48 @@
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]="51c68d0d-369a-5afd-94e3-53c6ae77c043")}catch(e){}}();
3
+
4
+ var __create = Object.create;
5
+ var __defProp = Object.defineProperty;
6
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
7
+ var __getOwnPropNames = Object.getOwnPropertyNames;
8
+ var __getProtoOf = Object.getPrototypeOf;
9
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
10
+ var __export = (target, all) => {
11
+ for (var name in all)
12
+ __defProp(target, name, { get: all[name], enumerable: true });
13
+ };
14
+ var __copyProps = (to, from, except, desc) => {
15
+ if (from && typeof from === "object" || typeof from === "function") {
16
+ for (let key of __getOwnPropNames(from))
17
+ if (!__hasOwnProp.call(to, key) && key !== except)
18
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
19
+ }
20
+ return to;
21
+ };
22
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
23
+ // If the importer is in node compatibility mode or this is not an ESM
24
+ // file that has been converted to a CommonJS file using a Babel-
25
+ // compatible transform (i.e. "__esModule" has not been set), then set
26
+ // "default" to the CommonJS "module.exports" for node compatibility.
27
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
28
+ mod
29
+ ));
30
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
31
+ var api_exports = {};
32
+ __export(api_exports, {
33
+ createApiClient: () => createApiClient
34
+ });
35
+ module.exports = __toCommonJS(api_exports);
36
+ var import_axios = __toESM(require("axios"));
37
+ var import_globals = require("@jest/globals");
38
+ import_globals.jest.mock("axios");
39
+ function createApiClient(_token) {
40
+ return import_axios.default;
41
+ }
42
+ // Annotate the CommonJS export names for ESM import in node:
43
+ 0 && (module.exports = {
44
+ createApiClient
45
+ });
46
+ //# sourceMappingURL=api.js.map
47
+
48
+ //# debugId=51c68d0d-369a-5afd-94e3-53c6ae77c043
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../lib/__mocks__/api.ts"],"sourcesContent":["import axios from \"axios\";\nimport { jest } from \"@jest/globals\";\n\njest.mock(\"axios\");\n\n// by returning the mocked module directly, we can mock responses in tests\n// like `axios.get.mockResolvedValue()`; otherwise, we'd be unable to mock\n// responses because `createApiClient` would be returning an axios instance\n// unaffected by mocks applied to the `axios` module itself.\nexport function createApiClient(_token?: string) {\n return axios;\n}\n"],"names":["axios"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,mBAAkB;AAClB,qBAAqB;AAErB,oBAAK,KAAK,OAAO;AAMV,SAAS,gBAAgB,QAAiB;AAC/C,SAAO,aAAAA;AACT","debug_id":"51c68d0d-369a-5afd-94e3-53c6ae77c043"}
package/bin/config.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]="907226eb-d4b7-553b-a3ea-7aa63bccb645")}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]="e8a84d0c-2e74-5c27-aee1-a1e1a393e89e")}catch(e){}}();
3
3
 
4
4
  var __create = Object.create;
5
5
  var __defProp = Object.defineProperty;
@@ -176,7 +176,8 @@ function parseSourceInformation(file) {
176
176
  richText,
177
177
  iosLocales,
178
178
  projects: projectsRoot,
179
- components: componentsRoot
179
+ components: componentsRoot,
180
+ disableJsDriver
180
181
  } = readProjectConfigData(file);
181
182
  const projects = (sources == null ? void 0 : sources.projects) || [];
182
183
  const projectNames = /* @__PURE__ */ new Set();
@@ -212,7 +213,8 @@ function parseSourceInformation(file) {
212
213
  hasComponentLibraryInProjects,
213
214
  componentRoot,
214
215
  componentFolders,
215
- localeByVariantApiId: iosLocales ? iosLocales.reduce((acc, e) => __spreadValues(__spreadValues({}, acc), e), {}) : void 0
216
+ localeByVariantApiId: iosLocales ? iosLocales.reduce((acc, e) => __spreadValues(__spreadValues({}, acc), e), {}) : void 0,
217
+ disableJsDriver
216
218
  };
217
219
  Sentry.setContext("config", (0, import_createSentryContext.createSentryContext)(result));
218
220
  return result;
@@ -237,4 +239,4 @@ var config_default = {
237
239
  });
238
240
  //# sourceMappingURL=config.js.map
239
241
 
240
- //# debugId=907226eb-d4b7-553b-a3ea-7aa63bccb645
242
+ //# debugId=e8a84d0c-2e74-5c27-aee1-a1e1a393e89e
package/bin/config.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../lib/config.ts"],"sourcesContent":["import fs from \"fs\";\nimport path from \"path\";\nimport url from \"url\";\nimport yaml from \"js-yaml\";\nimport * as Sentry from \"@sentry/node\";\n\nimport consts from \"./consts\";\nimport { createSentryContext } from \"./utils/createSentryContext\";\nimport { Project, ConfigYAML, SourceInformation } from \"./types\";\n\nexport const DEFAULT_CONFIG_JSON: ConfigYAML = {\n sources: {\n components: true,\n },\n variants: true,\n format: \"flat\",\n};\n\nexport const DEFAULT_CONFIG = yaml.dump(DEFAULT_CONFIG_JSON);\n\nfunction createFileIfMissing(filename: string, defaultContents?: any) {\n const dir = path.dirname(filename);\n\n // create the directory if it doesn't already exist\n if (!fs.existsSync(dir)) fs.mkdirSync(dir);\n\n // create the file if it doesn't already exist\n if (!fs.existsSync(filename)) {\n // create the file, writing the `defaultContents` if provided\n fs.writeFileSync(filename, defaultContents || \"\", \"utf-8\");\n }\n}\n\nfunction jsonIsConfigYAML(json: unknown): json is ConfigYAML {\n return typeof json === \"object\";\n}\n\nfunction jsonIsGlobalYAML(\n json: unknown\n): json is Record<string, { token: string }[]> {\n return (\n !!json &&\n typeof json === \"object\" &&\n Object.values(json).every(\n (arr) =>\n (arr as any).every &&\n arr.every(\n (val: any) =>\n typeof val === \"object\" && Object.keys(val).includes(\"token\")\n )\n )\n );\n}\n\n/**\n * Read data from a project config file\n * @param {string} file defaults to `PROJECT_CONFIG_FILE` defined in `constants.js`\n * @param {*} defaultData defaults to `{}`\n * @returns { ConfigYAML }\n */\nfunction readProjectConfigData(\n file = consts.PROJECT_CONFIG_FILE,\n defaultData = {}\n): ConfigYAML {\n createFileIfMissing(file, DEFAULT_CONFIG);\n const fileContents = fs.readFileSync(file, \"utf8\");\n const yamlData = yaml.load(fileContents);\n if (jsonIsConfigYAML(yamlData)) {\n return yamlData;\n }\n return defaultData;\n}\n\n/**\n * Read data from a global config file\n * @param {string} file defaults to `CONFIG_FILE` defined in `constants.js`\n * @param {*} defaultData defaults to `{}`\n * @returns { Record<string, { token: string }[]> }\n */\nfunction readGlobalConfigData(\n file = consts.CONFIG_FILE,\n defaultData = {}\n): Record<string, { token: string }[]> {\n createFileIfMissing(file);\n const fileContents = fs.readFileSync(file, \"utf8\");\n const yamlData = yaml.load(fileContents);\n if (jsonIsGlobalYAML(yamlData)) {\n return yamlData;\n }\n return defaultData;\n}\n\nfunction writeProjectConfigData(file: string, data: Partial<ConfigYAML>) {\n createFileIfMissing(file, DEFAULT_CONFIG);\n const existingData = readProjectConfigData(file);\n\n const configData: ConfigYAML = {\n ...existingData,\n ...data,\n sources: {\n ...existingData.sources,\n ...data.sources,\n },\n };\n\n const yamlStr = yaml.dump(configData);\n fs.writeFileSync(file, yamlStr, \"utf8\");\n}\n\nfunction writeGlobalConfigData(file: string, data: object) {\n createFileIfMissing(file);\n const existingData = readGlobalConfigData(file);\n const yamlStr = yaml.dump({ ...existingData, ...data });\n fs.writeFileSync(file, yamlStr, \"utf8\");\n}\n\nfunction justTheHost(host: string) {\n if (!host.includes(\"://\")) return host;\n return url.parse(host).hostname || \"\";\n}\n\nfunction deleteToken(file: string, host: string) {\n const data = readGlobalConfigData(file);\n const hostParsed = justTheHost(host);\n data[hostParsed] = [];\n data[hostParsed][0] = { token: \"\" };\n writeGlobalConfigData(file, data);\n}\n\nfunction saveToken(file: string, host: string, token: string) {\n const data = readGlobalConfigData(file);\n const hostParsed = justTheHost(host);\n data[hostParsed] = []; // only allow one token per host\n data[hostParsed][0] = { token };\n writeGlobalConfigData(file, data);\n}\n\nfunction getTokenFromEnv() {\n return process.env.DITTO_API_KEY;\n}\n\n/**\n *\n * @param {string} file\n * @param {string} host\n * @returns {Token}\n */\nfunction getToken(file: string, host: string) {\n const tokenFromEnv = getTokenFromEnv();\n if (tokenFromEnv) {\n return tokenFromEnv;\n }\n\n const data = readGlobalConfigData(file);\n const hostEntry = data[justTheHost(host)];\n if (!hostEntry) return undefined;\n const { length } = hostEntry;\n\n return hostEntry[length - 1].token;\n}\n\nconst IS_DUPLICATE = /-(\\d+$)/;\n\nfunction dedupeProjectName(projectNames: Set<string>, projectName: string) {\n let dedupedName = projectName;\n\n if (projectNames.has(dedupedName)) {\n while (projectNames.has(dedupedName)) {\n const [_, numberStr] = dedupedName.match(IS_DUPLICATE) || [];\n if (numberStr && !isNaN(parseInt(numberStr))) {\n dedupedName = `${dedupedName.replace(IS_DUPLICATE, \"\")}-${\n parseInt(numberStr) + 1\n }`;\n } else {\n dedupedName = `${dedupedName}-1`;\n }\n }\n }\n\n return dedupedName;\n}\n\n/**\n * Reads from the config file, filters out\n * invalid projects, dedupes those remaining, and returns:\n * - whether or not the data required to `pull` is present\n * - whether or not the component library should be fetched\n * - an array of valid, deduped projects\n * - the `variants` and `format` config options\n */\nfunction parseSourceInformation(file?: string): SourceInformation {\n const {\n sources,\n variants,\n format,\n status,\n richText,\n iosLocales,\n projects: projectsRoot,\n components: componentsRoot,\n } = readProjectConfigData(file);\n\n const projects = sources?.projects || [];\n\n const projectNames = new Set<string>();\n const validProjects: Project[] = [];\n let hasComponentLibraryInProjects = false;\n\n (projects || []).forEach((project) => {\n const isValid = project.id && project.name;\n if (!isValid) {\n return;\n }\n\n if (project.id === \"ditto_component_library\") {\n hasComponentLibraryInProjects = true;\n return;\n }\n\n project.fileName = dedupeProjectName(projectNames, project.name);\n projectNames.add(project.fileName);\n\n validProjects.push(project);\n });\n\n const shouldFetchComponentLibrary = Boolean(sources?.components);\n const componentRoot =\n typeof sources?.components === \"object\"\n ? sources.components.root\n : undefined;\n const componentFolders =\n typeof sources?.components === \"object\"\n ? sources.components.folders\n : undefined;\n\n /**\n * If it's not specified to fetch projects or the component library, then there\n * is no source data to pull.\n */\n const hasSourceData = !!validProjects.length || shouldFetchComponentLibrary;\n\n const result = {\n hasSourceData,\n validProjects,\n shouldFetchComponentLibrary,\n variants: variants || false,\n format,\n status,\n richText,\n hasTopLevelProjectsField: !!projectsRoot,\n hasTopLevelComponentsField: !!componentsRoot,\n hasComponentLibraryInProjects,\n componentRoot,\n componentFolders,\n localeByVariantApiId: iosLocales\n ? iosLocales.reduce((acc, e) => ({ ...acc, ...e }), {} as any)\n : undefined,\n };\n\n Sentry.setContext(\"config\", createSentryContext(result));\n\n return result;\n}\n\nexport default {\n createFileIfMissing,\n readProjectConfigData,\n readGlobalConfigData,\n writeGlobalConfigData,\n writeProjectConfigData,\n justTheHost,\n saveToken,\n deleteToken,\n getToken,\n getTokenFromEnv,\n parseSourceInformation,\n};\n"],"names":["yaml","path","fs","consts","url"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,gBAAe;AACf,kBAAiB;AACjB,iBAAgB;AAChB,qBAAiB;AACjB,aAAwB;AAExB,oBAAmB;AACnB,iCAAoC;AAG7B,MAAM,sBAAkC;AAAA,EAC7C,SAAS;AAAA,IACP,YAAY;AAAA,EACd;AAAA,EACA,UAAU;AAAA,EACV,QAAQ;AACV;AAEO,MAAM,iBAAiB,eAAAA,QAAK,KAAK,mBAAmB;AAE3D,SAAS,oBAAoB,UAAkB,iBAAuB;AACpE,QAAM,MAAM,YAAAC,QAAK,QAAQ,QAAQ;AAGjC,MAAI,CAAC,UAAAC,QAAG,WAAW,GAAG;AAAG,cAAAA,QAAG,UAAU,GAAG;AAGzC,MAAI,CAAC,UAAAA,QAAG,WAAW,QAAQ,GAAG;AAE5B,cAAAA,QAAG,cAAc,UAAU,mBAAmB,IAAI,OAAO;AAAA,EAC3D;AACF;AAEA,SAAS,iBAAiB,MAAmC;AAC3D,SAAO,OAAO,SAAS;AACzB;AAEA,SAAS,iBACP,MAC6C;AAC7C,SACE,CAAC,CAAC,QACF,OAAO,SAAS,YAChB,OAAO,OAAO,IAAI,EAAE;AAAA,IAClB,CAAC,QACE,IAAY,SACb,IAAI;AAAA,MACF,CAAC,QACC,OAAO,QAAQ,YAAY,OAAO,KAAK,GAAG,EAAE,SAAS,OAAO;AAAA,IAChE;AAAA,EACJ;AAEJ;AAQA,SAAS,sBACP,OAAO,cAAAC,QAAO,qBACd,cAAc,CAAC,GACH;AACZ,sBAAoB,MAAM,cAAc;AACxC,QAAM,eAAe,UAAAD,QAAG,aAAa,MAAM,MAAM;AACjD,QAAM,WAAW,eAAAF,QAAK,KAAK,YAAY;AACvC,MAAI,iBAAiB,QAAQ,GAAG;AAC9B,WAAO;AAAA,EACT;AACA,SAAO;AACT;AAQA,SAAS,qBACP,OAAO,cAAAG,QAAO,aACd,cAAc,CAAC,GACsB;AACrC,sBAAoB,IAAI;AACxB,QAAM,eAAe,UAAAD,QAAG,aAAa,MAAM,MAAM;AACjD,QAAM,WAAW,eAAAF,QAAK,KAAK,YAAY;AACvC,MAAI,iBAAiB,QAAQ,GAAG;AAC9B,WAAO;AAAA,EACT;AACA,SAAO;AACT;AAEA,SAAS,uBAAuB,MAAc,MAA2B;AACvE,sBAAoB,MAAM,cAAc;AACxC,QAAM,eAAe,sBAAsB,IAAI;AAE/C,QAAM,aAAyB,gDAC1B,eACA,OAF0B;AAAA,IAG7B,SAAS,kCACJ,aAAa,UACb,KAAK;AAAA,EAEZ;AAEA,QAAM,UAAU,eAAAA,QAAK,KAAK,UAAU;AACpC,YAAAE,QAAG,cAAc,MAAM,SAAS,MAAM;AACxC;AAEA,SAAS,sBAAsB,MAAc,MAAc;AACzD,sBAAoB,IAAI;AACxB,QAAM,eAAe,qBAAqB,IAAI;AAC9C,QAAM,UAAU,eAAAF,QAAK,KAAK,kCAAK,eAAiB,KAAM;AACtD,YAAAE,QAAG,cAAc,MAAM,SAAS,MAAM;AACxC;AAEA,SAAS,YAAY,MAAc;AACjC,MAAI,CAAC,KAAK,SAAS,KAAK;AAAG,WAAO;AAClC,SAAO,WAAAE,QAAI,MAAM,IAAI,EAAE,YAAY;AACrC;AAEA,SAAS,YAAY,MAAc,MAAc;AAC/C,QAAM,OAAO,qBAAqB,IAAI;AACtC,QAAM,aAAa,YAAY,IAAI;AACnC,OAAK,UAAU,IAAI,CAAC;AACpB,OAAK,UAAU,EAAE,CAAC,IAAI,EAAE,OAAO,GAAG;AAClC,wBAAsB,MAAM,IAAI;AAClC;AAEA,SAAS,UAAU,MAAc,MAAc,OAAe;AAC5D,QAAM,OAAO,qBAAqB,IAAI;AACtC,QAAM,aAAa,YAAY,IAAI;AACnC,OAAK,UAAU,IAAI,CAAC;AACpB,OAAK,UAAU,EAAE,CAAC,IAAI,EAAE,MAAM;AAC9B,wBAAsB,MAAM,IAAI;AAClC;AAEA,SAAS,kBAAkB;AACzB,SAAO,QAAQ,IAAI;AACrB;AAQA,SAAS,SAAS,MAAc,MAAc;AAC5C,QAAM,eAAe,gBAAgB;AACrC,MAAI,cAAc;AAChB,WAAO;AAAA,EACT;AAEA,QAAM,OAAO,qBAAqB,IAAI;AACtC,QAAM,YAAY,KAAK,YAAY,IAAI,CAAC;AACxC,MAAI,CAAC;AAAW,WAAO;AACvB,QAAM,EAAE,OAAO,IAAI;AAEnB,SAAO,UAAU,SAAS,CAAC,EAAE;AAC/B;AAEA,MAAM,eAAe;AAErB,SAAS,kBAAkB,cAA2B,aAAqB;AACzE,MAAI,cAAc;AAElB,MAAI,aAAa,IAAI,WAAW,GAAG;AACjC,WAAO,aAAa,IAAI,WAAW,GAAG;AACpC,YAAM,CAAC,GAAG,SAAS,IAAI,YAAY,MAAM,YAAY,KAAK,CAAC;AAC3D,UAAI,aAAa,CAAC,MAAM,SAAS,SAAS,CAAC,GAAG;AAC5C,sBAAc,GAAG,YAAY,QAAQ,cAAc,EAAE,CAAC,IACpD,SAAS,SAAS,IAAI,CACxB;AAAA,MACF,OAAO;AACL,sBAAc,GAAG,WAAW;AAAA,MAC9B;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;AAUA,SAAS,uBAAuB,MAAkC;AAChE,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,UAAU;AAAA,IACV,YAAY;AAAA,EACd,IAAI,sBAAsB,IAAI;AAE9B,QAAM,YAAW,mCAAS,aAAY,CAAC;AAEvC,QAAM,eAAe,oBAAI,IAAY;AACrC,QAAM,gBAA2B,CAAC;AAClC,MAAI,gCAAgC;AAEpC,GAAC,YAAY,CAAC,GAAG,QAAQ,CAAC,YAAY;AACpC,UAAM,UAAU,QAAQ,MAAM,QAAQ;AACtC,QAAI,CAAC,SAAS;AACZ;AAAA,IACF;AAEA,QAAI,QAAQ,OAAO,2BAA2B;AAC5C,sCAAgC;AAChC;AAAA,IACF;AAEA,YAAQ,WAAW,kBAAkB,cAAc,QAAQ,IAAI;AAC/D,iBAAa,IAAI,QAAQ,QAAQ;AAEjC,kBAAc,KAAK,OAAO;AAAA,EAC5B,CAAC;AAED,QAAM,8BAA8B,QAAQ,mCAAS,UAAU;AAC/D,QAAM,gBACJ,QAAO,mCAAS,gBAAe,WAC3B,QAAQ,WAAW,OACnB;AACN,QAAM,mBACJ,QAAO,mCAAS,gBAAe,WAC3B,QAAQ,WAAW,UACnB;AAMN,QAAM,gBAAgB,CAAC,CAAC,cAAc,UAAU;AAEhD,QAAM,SAAS;AAAA,IACb;AAAA,IACA;AAAA,IACA;AAAA,IACA,UAAU,YAAY;AAAA,IACtB;AAAA,IACA;AAAA,IACA;AAAA,IACA,0BAA0B,CAAC,CAAC;AAAA,IAC5B,4BAA4B,CAAC,CAAC;AAAA,IAC9B;AAAA,IACA;AAAA,IACA;AAAA,IACA,sBAAsB,aAClB,WAAW,OAAO,CAAC,KAAK,MAAO,kCAAK,MAAQ,IAAM,CAAC,CAAQ,IAC3D;AAAA,EACN;AAEA,SAAO,WAAW,cAAU,gDAAoB,MAAM,CAAC;AAEvD,SAAO;AACT;AAEA,IAAO,iBAAQ;AAAA,EACb;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF","debug_id":"907226eb-d4b7-553b-a3ea-7aa63bccb645"}
1
+ {"version":3,"sources":["../lib/config.ts"],"sourcesContent":["import fs from \"fs\";\nimport path from \"path\";\nimport url from \"url\";\nimport yaml from \"js-yaml\";\nimport * as Sentry from \"@sentry/node\";\n\nimport consts from \"./consts\";\nimport { createSentryContext } from \"./utils/createSentryContext\";\nimport { Project, ConfigYAML, SourceInformation, Source } from \"./types\";\n\nexport const DEFAULT_CONFIG_JSON: ConfigYAML = {\n sources: {\n components: true,\n },\n variants: true,\n format: \"flat\",\n};\n\nexport const DEFAULT_CONFIG = yaml.dump(DEFAULT_CONFIG_JSON);\n\nfunction createFileIfMissing(filename: string, defaultContents?: any) {\n const dir = path.dirname(filename);\n\n // create the directory if it doesn't already exist\n if (!fs.existsSync(dir)) fs.mkdirSync(dir);\n\n // create the file if it doesn't already exist\n if (!fs.existsSync(filename)) {\n // create the file, writing the `defaultContents` if provided\n fs.writeFileSync(filename, defaultContents || \"\", \"utf-8\");\n }\n}\n\nfunction jsonIsConfigYAML(json: unknown): json is ConfigYAML {\n return typeof json === \"object\";\n}\n\nfunction jsonIsGlobalYAML(\n json: unknown\n): json is Record<string, { token: string }[]> {\n return (\n !!json &&\n typeof json === \"object\" &&\n Object.values(json).every(\n (arr) =>\n (arr as any).every &&\n arr.every(\n (val: any) =>\n typeof val === \"object\" && Object.keys(val).includes(\"token\")\n )\n )\n );\n}\n\n/**\n * Read data from a project config file\n * @param {string} file defaults to `PROJECT_CONFIG_FILE` defined in `constants.js`\n * @param {*} defaultData defaults to `{}`\n * @returns { ConfigYAML }\n */\nfunction readProjectConfigData(\n file = consts.PROJECT_CONFIG_FILE,\n defaultData = {}\n): ConfigYAML {\n createFileIfMissing(file, DEFAULT_CONFIG);\n const fileContents = fs.readFileSync(file, \"utf8\");\n const yamlData = yaml.load(fileContents);\n if (jsonIsConfigYAML(yamlData)) {\n return yamlData;\n }\n return defaultData;\n}\n\n/**\n * Read data from a global config file\n * @param {string} file defaults to `CONFIG_FILE` defined in `constants.js`\n * @param {*} defaultData defaults to `{}`\n * @returns { Record<string, { token: string }[]> }\n */\nfunction readGlobalConfigData(\n file = consts.CONFIG_FILE,\n defaultData = {}\n): Record<string, { token: string }[]> {\n createFileIfMissing(file);\n const fileContents = fs.readFileSync(file, \"utf8\");\n const yamlData = yaml.load(fileContents);\n if (jsonIsGlobalYAML(yamlData)) {\n return yamlData;\n }\n return defaultData;\n}\n\nfunction writeProjectConfigData(file: string, data: Partial<ConfigYAML>) {\n createFileIfMissing(file, DEFAULT_CONFIG);\n const existingData = readProjectConfigData(file);\n\n const configData: ConfigYAML = {\n ...existingData,\n ...data,\n sources: {\n ...existingData.sources,\n ...data.sources,\n },\n };\n\n const yamlStr = yaml.dump(configData);\n fs.writeFileSync(file, yamlStr, \"utf8\");\n}\n\nfunction writeGlobalConfigData(file: string, data: object) {\n createFileIfMissing(file);\n const existingData = readGlobalConfigData(file);\n const yamlStr = yaml.dump({ ...existingData, ...data });\n fs.writeFileSync(file, yamlStr, \"utf8\");\n}\n\nfunction justTheHost(host: string) {\n if (!host.includes(\"://\")) return host;\n return url.parse(host).hostname || \"\";\n}\n\nfunction deleteToken(file: string, host: string) {\n const data = readGlobalConfigData(file);\n const hostParsed = justTheHost(host);\n data[hostParsed] = [];\n data[hostParsed][0] = { token: \"\" };\n writeGlobalConfigData(file, data);\n}\n\nfunction saveToken(file: string, host: string, token: string) {\n const data = readGlobalConfigData(file);\n const hostParsed = justTheHost(host);\n data[hostParsed] = []; // only allow one token per host\n data[hostParsed][0] = { token };\n writeGlobalConfigData(file, data);\n}\n\nfunction getTokenFromEnv() {\n return process.env.DITTO_API_KEY;\n}\n\n/**\n *\n * @param {string} file\n * @param {string} host\n * @returns {Token}\n */\nfunction getToken(file: string, host: string) {\n const tokenFromEnv = getTokenFromEnv();\n if (tokenFromEnv) {\n return tokenFromEnv;\n }\n\n const data = readGlobalConfigData(file);\n const hostEntry = data[justTheHost(host)];\n if (!hostEntry) return undefined;\n const { length } = hostEntry;\n\n return hostEntry[length - 1].token;\n}\n\nconst IS_DUPLICATE = /-(\\d+$)/;\n\nfunction dedupeProjectName(projectNames: Set<string>, projectName: string) {\n let dedupedName = projectName;\n\n if (projectNames.has(dedupedName)) {\n while (projectNames.has(dedupedName)) {\n const [_, numberStr] = dedupedName.match(IS_DUPLICATE) || [];\n if (numberStr && !isNaN(parseInt(numberStr))) {\n dedupedName = `${dedupedName.replace(IS_DUPLICATE, \"\")}-${\n parseInt(numberStr) + 1\n }`;\n } else {\n dedupedName = `${dedupedName}-1`;\n }\n }\n }\n\n return dedupedName;\n}\n\n/**\n * Reads from the config file, filters out\n * invalid projects, dedupes those remaining, and returns:\n * - whether or not the data required to `pull` is present\n * - whether or not the component library should be fetched\n * - an array of valid, deduped projects\n * - the `variants` and `format` config options\n */\nfunction parseSourceInformation(file?: string): SourceInformation {\n const {\n sources,\n variants,\n format,\n status,\n richText,\n iosLocales,\n projects: projectsRoot,\n components: componentsRoot,\n disableJsDriver,\n } = readProjectConfigData(file);\n\n const projects = sources?.projects || [];\n\n const projectNames = new Set<string>();\n const validProjects: Project[] = [];\n let hasComponentLibraryInProjects = false;\n\n (projects || []).forEach((project) => {\n const isValid = project.id && project.name;\n if (!isValid) {\n return;\n }\n\n if (project.id === \"ditto_component_library\") {\n hasComponentLibraryInProjects = true;\n return;\n }\n\n project.fileName = dedupeProjectName(projectNames, project.name);\n projectNames.add(project.fileName);\n\n validProjects.push(project);\n });\n\n const shouldFetchComponentLibrary = Boolean(sources?.components);\n const componentRoot =\n typeof sources?.components === \"object\"\n ? sources.components.root\n : undefined;\n const componentFolders =\n typeof sources?.components === \"object\"\n ? sources.components.folders\n : undefined;\n\n /**\n * If it's not specified to fetch projects or the component library, then there\n * is no source data to pull.\n */\n const hasSourceData = !!validProjects.length || shouldFetchComponentLibrary;\n\n const result: SourceInformation = {\n hasSourceData,\n validProjects,\n shouldFetchComponentLibrary,\n variants: variants || false,\n format,\n status,\n richText,\n hasTopLevelProjectsField: !!projectsRoot,\n hasTopLevelComponentsField: !!componentsRoot,\n hasComponentLibraryInProjects,\n componentRoot,\n componentFolders,\n localeByVariantApiId: iosLocales\n ? iosLocales.reduce((acc, e) => ({ ...acc, ...e }), {} as any)\n : undefined,\n disableJsDriver,\n };\n\n Sentry.setContext(\"config\", createSentryContext(result));\n\n return result;\n}\n\nexport default {\n createFileIfMissing,\n readProjectConfigData,\n readGlobalConfigData,\n writeGlobalConfigData,\n writeProjectConfigData,\n justTheHost,\n saveToken,\n deleteToken,\n getToken,\n getTokenFromEnv,\n parseSourceInformation,\n};\n"],"names":["yaml","path","fs","consts","url"],"mappings":"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","debug_id":"e8a84d0c-2e74-5c27-aee1-a1e1a393e89e"}
@@ -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]="569c989b-5686-534d-b379-744174394415")}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]="7a21b9a5-efe4-50f7-9b1f-38b0ce5ffb19")}catch(e){}}();
3
3
 
4
4
  var __create = Object.create;
5
5
  var __defProp = Object.defineProperty;
@@ -27,7 +27,8 @@ var import_fs = __toESM(require("fs"));
27
27
  var import_path = __toESM(require("path"));
28
28
  var import_js_yaml = __toESM(require("js-yaml"));
29
29
  var import_config = __toESM(require("./config"));
30
- const fakeHomedir = import_fs.default.mkdtempSync(import_path.default.join(__dirname, "../testing/tmp"));
30
+ jest.mock("fs");
31
+ const fakeHomedir = import_fs.default.mkdtempSync("/config-testing");
31
32
  describe("Config File", () => {
32
33
  const expectedConfigDir = import_path.default.join(fakeHomedir, ".config");
33
34
  beforeEach(() => {
@@ -89,4 +90,4 @@ describe("Tokens in config files", () => {
89
90
  });
90
91
  //# sourceMappingURL=config.test.js.map
91
92
 
92
- //# debugId=569c989b-5686-534d-b379-744174394415
93
+ //# debugId=7a21b9a5-efe4-50f7-9b1f-38b0ce5ffb19
@@ -1 +1 @@
1
- {"version":3,"sources":["../lib/config.test.ts"],"sourcesContent":["/* eslint-disable no-underscore-dangle */\nimport fs from \"fs\";\nimport path from \"path\";\nimport tempy from \"tempy\";\nimport yaml from \"js-yaml\";\nimport config from \"./config\";\n\nconst fakeHomedir = fs.mkdtempSync(path.join(__dirname, \"../testing/tmp\"));\n\ndescribe(\"Config File\", () => {\n const expectedConfigDir = path.join(fakeHomedir, \".config\");\n\n beforeEach(() => {\n if (!fs.existsSync(fakeHomedir)) fs.mkdirSync(fakeHomedir);\n });\n\n afterEach(() => {\n fs.rmdirSync(fakeHomedir, { recursive: true });\n });\n\n describe(\"createFileIfMissing\", () => {\n const expectedConfigFile = path.join(expectedConfigDir, \"ditto\");\n\n it(\"creates a config file if the config dir is missing\", () => {\n config.createFileIfMissing(expectedConfigFile);\n expect(fs.existsSync(expectedConfigFile)).toBeTruthy();\n });\n it(\"creates a config file if it's missing\", () => {\n fs.mkdirSync(expectedConfigDir);\n config.createFileIfMissing(expectedConfigFile);\n expect(fs.existsSync(expectedConfigFile)).toBeTruthy();\n });\n\n it(\"does nothing if it already exists\", () => {\n fs.mkdirSync(expectedConfigDir);\n fs.closeSync(fs.openSync(expectedConfigFile, \"w\"));\n config.createFileIfMissing(expectedConfigFile);\n expect(fs.existsSync(expectedConfigFile)).toBeTruthy();\n });\n });\n});\n\ndescribe(\"Tokens in config files\", () => {\n const configFile = path.join(fakeHomedir, \"ditto\");\n\n beforeEach(() => {\n config.createFileIfMissing(configFile);\n config.saveToken(configFile, \"testing.dittowords.com\", \"faketoken\");\n });\n\n afterEach(() => {\n fs.rmdirSync(fakeHomedir, { recursive: true });\n });\n\n describe(\"saveToken\", () => {\n it(\"creates a config file with config data\", () => {\n const fileContents = fs.readFileSync(configFile, \"utf8\");\n const configData = yaml.load(fileContents) as Record<string, any>;\n if (configData && typeof configData === \"object\") {\n expect(configData[\"testing.dittowords.com\"]).toBeDefined();\n expect(configData[\"testing.dittowords.com\"][0].token).toEqual(\n \"faketoken\"\n );\n } else {\n fail(\"Config Data should have been an object!\");\n }\n });\n });\n\n describe(\"getToken\", () => {\n it(\"can retrieve the saved token value\", () => {\n expect(config.getToken(configFile, \"testing.dittowords.com\")).toEqual(\n \"faketoken\"\n );\n });\n });\n});\n"],"names":["fs","path","config","yaml"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;AACA,gBAAe;AACf,kBAAiB;AAEjB,qBAAiB;AACjB,oBAAmB;AAEnB,MAAM,cAAc,UAAAA,QAAG,YAAY,YAAAC,QAAK,KAAK,WAAW,gBAAgB,CAAC;AAEzE,SAAS,eAAe,MAAM;AAC5B,QAAM,oBAAoB,YAAAA,QAAK,KAAK,aAAa,SAAS;AAE1D,aAAW,MAAM;AACf,QAAI,CAAC,UAAAD,QAAG,WAAW,WAAW;AAAG,gBAAAA,QAAG,UAAU,WAAW;AAAA,EAC3D,CAAC;AAED,YAAU,MAAM;AACd,cAAAA,QAAG,UAAU,aAAa,EAAE,WAAW,KAAK,CAAC;AAAA,EAC/C,CAAC;AAED,WAAS,uBAAuB,MAAM;AACpC,UAAM,qBAAqB,YAAAC,QAAK,KAAK,mBAAmB,OAAO;AAE/D,OAAG,sDAAsD,MAAM;AAC7D,oBAAAC,QAAO,oBAAoB,kBAAkB;AAC7C,aAAO,UAAAF,QAAG,WAAW,kBAAkB,CAAC,EAAE,WAAW;AAAA,IACvD,CAAC;AACD,OAAG,yCAAyC,MAAM;AAChD,gBAAAA,QAAG,UAAU,iBAAiB;AAC9B,oBAAAE,QAAO,oBAAoB,kBAAkB;AAC7C,aAAO,UAAAF,QAAG,WAAW,kBAAkB,CAAC,EAAE,WAAW;AAAA,IACvD,CAAC;AAED,OAAG,qCAAqC,MAAM;AAC5C,gBAAAA,QAAG,UAAU,iBAAiB;AAC9B,gBAAAA,QAAG,UAAU,UAAAA,QAAG,SAAS,oBAAoB,GAAG,CAAC;AACjD,oBAAAE,QAAO,oBAAoB,kBAAkB;AAC7C,aAAO,UAAAF,QAAG,WAAW,kBAAkB,CAAC,EAAE,WAAW;AAAA,IACvD,CAAC;AAAA,EACH,CAAC;AACH,CAAC;AAED,SAAS,0BAA0B,MAAM;AACvC,QAAM,aAAa,YAAAC,QAAK,KAAK,aAAa,OAAO;AAEjD,aAAW,MAAM;AACf,kBAAAC,QAAO,oBAAoB,UAAU;AACrC,kBAAAA,QAAO,UAAU,YAAY,0BAA0B,WAAW;AAAA,EACpE,CAAC;AAED,YAAU,MAAM;AACd,cAAAF,QAAG,UAAU,aAAa,EAAE,WAAW,KAAK,CAAC;AAAA,EAC/C,CAAC;AAED,WAAS,aAAa,MAAM;AAC1B,OAAG,0CAA0C,MAAM;AACjD,YAAM,eAAe,UAAAA,QAAG,aAAa,YAAY,MAAM;AACvD,YAAM,aAAa,eAAAG,QAAK,KAAK,YAAY;AACzC,UAAI,cAAc,OAAO,eAAe,UAAU;AAChD,eAAO,WAAW,wBAAwB,CAAC,EAAE,YAAY;AACzD,eAAO,WAAW,wBAAwB,EAAE,CAAC,EAAE,KAAK,EAAE;AAAA,UACpD;AAAA,QACF;AAAA,MACF,OAAO;AACL,aAAK,yCAAyC;AAAA,MAChD;AAAA,IACF,CAAC;AAAA,EACH,CAAC;AAED,WAAS,YAAY,MAAM;AACzB,OAAG,sCAAsC,MAAM;AAC7C,aAAO,cAAAD,QAAO,SAAS,YAAY,wBAAwB,CAAC,EAAE;AAAA,QAC5D;AAAA,MACF;AAAA,IACF,CAAC;AAAA,EACH,CAAC;AACH,CAAC","debug_id":"569c989b-5686-534d-b379-744174394415"}
1
+ {"version":3,"sources":["../lib/config.test.ts"],"sourcesContent":["/* eslint-disable no-underscore-dangle */\nimport fs from \"fs\";\nimport path from \"path\";\nimport tempy from \"tempy\";\nimport yaml from \"js-yaml\";\nimport config from \"./config\";\n\njest.mock(\"fs\");\n\nconst fakeHomedir = fs.mkdtempSync(\"/config-testing\");\n\ndescribe(\"Config File\", () => {\n const expectedConfigDir = path.join(fakeHomedir, \".config\");\n\n beforeEach(() => {\n if (!fs.existsSync(fakeHomedir)) fs.mkdirSync(fakeHomedir);\n });\n\n afterEach(() => {\n fs.rmdirSync(fakeHomedir, { recursive: true });\n });\n\n describe(\"createFileIfMissing\", () => {\n const expectedConfigFile = path.join(expectedConfigDir, \"ditto\");\n\n it(\"creates a config file if the config dir is missing\", () => {\n config.createFileIfMissing(expectedConfigFile);\n expect(fs.existsSync(expectedConfigFile)).toBeTruthy();\n });\n it(\"creates a config file if it's missing\", () => {\n fs.mkdirSync(expectedConfigDir);\n config.createFileIfMissing(expectedConfigFile);\n expect(fs.existsSync(expectedConfigFile)).toBeTruthy();\n });\n\n it(\"does nothing if it already exists\", () => {\n fs.mkdirSync(expectedConfigDir);\n fs.closeSync(fs.openSync(expectedConfigFile, \"w\"));\n config.createFileIfMissing(expectedConfigFile);\n expect(fs.existsSync(expectedConfigFile)).toBeTruthy();\n });\n });\n});\n\ndescribe(\"Tokens in config files\", () => {\n const configFile = path.join(fakeHomedir, \"ditto\");\n\n beforeEach(() => {\n config.createFileIfMissing(configFile);\n config.saveToken(configFile, \"testing.dittowords.com\", \"faketoken\");\n });\n\n afterEach(() => {\n fs.rmdirSync(fakeHomedir, { recursive: true });\n });\n\n describe(\"saveToken\", () => {\n it(\"creates a config file with config data\", () => {\n const fileContents = fs.readFileSync(configFile, \"utf8\");\n const configData = yaml.load(fileContents) as Record<string, any>;\n if (configData && typeof configData === \"object\") {\n expect(configData[\"testing.dittowords.com\"]).toBeDefined();\n expect(configData[\"testing.dittowords.com\"][0].token).toEqual(\n \"faketoken\"\n );\n } else {\n fail(\"Config Data should have been an object!\");\n }\n });\n });\n\n describe(\"getToken\", () => {\n it(\"can retrieve the saved token value\", () => {\n expect(config.getToken(configFile, \"testing.dittowords.com\")).toEqual(\n \"faketoken\"\n );\n });\n });\n});\n"],"names":["fs","path","config","yaml"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;AACA,gBAAe;AACf,kBAAiB;AAEjB,qBAAiB;AACjB,oBAAmB;AAEnB,KAAK,KAAK,IAAI;AAEd,MAAM,cAAc,UAAAA,QAAG,YAAY,iBAAiB;AAEpD,SAAS,eAAe,MAAM;AAC5B,QAAM,oBAAoB,YAAAC,QAAK,KAAK,aAAa,SAAS;AAE1D,aAAW,MAAM;AACf,QAAI,CAAC,UAAAD,QAAG,WAAW,WAAW;AAAG,gBAAAA,QAAG,UAAU,WAAW;AAAA,EAC3D,CAAC;AAED,YAAU,MAAM;AACd,cAAAA,QAAG,UAAU,aAAa,EAAE,WAAW,KAAK,CAAC;AAAA,EAC/C,CAAC;AAED,WAAS,uBAAuB,MAAM;AACpC,UAAM,qBAAqB,YAAAC,QAAK,KAAK,mBAAmB,OAAO;AAE/D,OAAG,sDAAsD,MAAM;AAC7D,oBAAAC,QAAO,oBAAoB,kBAAkB;AAC7C,aAAO,UAAAF,QAAG,WAAW,kBAAkB,CAAC,EAAE,WAAW;AAAA,IACvD,CAAC;AACD,OAAG,yCAAyC,MAAM;AAChD,gBAAAA,QAAG,UAAU,iBAAiB;AAC9B,oBAAAE,QAAO,oBAAoB,kBAAkB;AAC7C,aAAO,UAAAF,QAAG,WAAW,kBAAkB,CAAC,EAAE,WAAW;AAAA,IACvD,CAAC;AAED,OAAG,qCAAqC,MAAM;AAC5C,gBAAAA,QAAG,UAAU,iBAAiB;AAC9B,gBAAAA,QAAG,UAAU,UAAAA,QAAG,SAAS,oBAAoB,GAAG,CAAC;AACjD,oBAAAE,QAAO,oBAAoB,kBAAkB;AAC7C,aAAO,UAAAF,QAAG,WAAW,kBAAkB,CAAC,EAAE,WAAW;AAAA,IACvD,CAAC;AAAA,EACH,CAAC;AACH,CAAC;AAED,SAAS,0BAA0B,MAAM;AACvC,QAAM,aAAa,YAAAC,QAAK,KAAK,aAAa,OAAO;AAEjD,aAAW,MAAM;AACf,kBAAAC,QAAO,oBAAoB,UAAU;AACrC,kBAAAA,QAAO,UAAU,YAAY,0BAA0B,WAAW;AAAA,EACpE,CAAC;AAED,YAAU,MAAM;AACd,cAAAF,QAAG,UAAU,aAAa,EAAE,WAAW,KAAK,CAAC;AAAA,EAC/C,CAAC;AAED,WAAS,aAAa,MAAM;AAC1B,OAAG,0CAA0C,MAAM;AACjD,YAAM,eAAe,UAAAA,QAAG,aAAa,YAAY,MAAM;AACvD,YAAM,aAAa,eAAAG,QAAK,KAAK,YAAY;AACzC,UAAI,cAAc,OAAO,eAAe,UAAU;AAChD,eAAO,WAAW,wBAAwB,CAAC,EAAE,YAAY;AACzD,eAAO,WAAW,wBAAwB,EAAE,CAAC,EAAE,KAAK,EAAE;AAAA,UACpD;AAAA,QACF;AAAA,MACF,OAAO;AACL,aAAK,yCAAyC;AAAA,MAChD;AAAA,IACF,CAAC;AAAA,EACH,CAAC;AAED,WAAS,YAAY,MAAM;AACzB,OAAG,sCAAsC,MAAM;AAC7C,aAAO,cAAAD,QAAO,SAAS,YAAY,wBAAwB,CAAC,EAAE;AAAA,QAC5D;AAAA,MACF;AAAA,IACF,CAAC;AAAA,EACH,CAAC;AACH,CAAC","debug_id":"7a21b9a5-efe4-50f7-9b1f-38b0ce5ffb19"}
package/bin/consts.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]="2f4fc790-aa3c-5658-8839-9af5301ee3e0")}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]="dff8f642-ef0f-5ab4-bf87-60f6f51ca2b4")}catch(e){}}();
3
3
 
4
4
  var __create = Object.create;
5
5
  var __defProp = Object.defineProperty;
@@ -30,38 +30,28 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
30
30
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
31
31
  var consts_exports = {};
32
32
  __export(consts_exports, {
33
- API_HOST: () => API_HOST,
34
- CONFIG_FILE: () => CONFIG_FILE,
35
- PROJECT_CONFIG_FILE: () => PROJECT_CONFIG_FILE,
36
- TEXT_DIR: () => TEXT_DIR,
37
- TEXT_FILE: () => TEXT_FILE,
38
33
  default: () => consts_default
39
34
  });
40
35
  module.exports = __toCommonJS(consts_exports);
41
36
  var import_os = require("os");
42
37
  var import_path = __toESM(require("path"));
43
- const API_HOST = process.env.DITTO_API_HOST || "https://api.dittowords.com";
44
- const CONFIG_FILE = process.env.DITTO_CONFIG_FILE || import_path.default.join((0, import_os.homedir)(), ".config", "ditto");
45
- const PROJECT_CONFIG_FILE = import_path.default.normalize(
46
- import_path.default.join("ditto", "config.yml")
47
- );
48
- const TEXT_DIR = process.env.DITTO_TEXT_DIR || "ditto";
49
- const TEXT_FILE = import_path.default.normalize(import_path.default.join(TEXT_DIR, "text.json"));
50
- var consts_default = {
51
- API_HOST,
52
- CONFIG_FILE,
53
- PROJECT_CONFIG_FILE,
54
- TEXT_DIR,
55
- TEXT_FILE
56
- };
57
- // Annotate the CommonJS export names for ESM import in node:
58
- 0 && (module.exports = {
59
- API_HOST,
60
- CONFIG_FILE,
61
- PROJECT_CONFIG_FILE,
62
- TEXT_DIR,
63
- TEXT_FILE
64
- });
38
+ var consts_default = new class {
39
+ get API_HOST() {
40
+ return process.env.DITTO_API_HOST || "https://api.dittowords.com";
41
+ }
42
+ get CONFIG_FILE() {
43
+ return process.env.DITTO_CONFIG_FILE || import_path.default.join((0, import_os.homedir)(), ".config", "ditto");
44
+ }
45
+ get PROJECT_CONFIG_FILE() {
46
+ return import_path.default.normalize(import_path.default.join("ditto", "config.yml"));
47
+ }
48
+ get TEXT_DIR() {
49
+ return process.env.DITTO_TEXT_DIR || "ditto";
50
+ }
51
+ get TEXT_FILE() {
52
+ return import_path.default.normalize(import_path.default.join(this.TEXT_DIR, "text.json"));
53
+ }
54
+ }();
65
55
  //# sourceMappingURL=consts.js.map
66
56
 
67
- //# debugId=2f4fc790-aa3c-5658-8839-9af5301ee3e0
57
+ //# debugId=dff8f642-ef0f-5ab4-bf87-60f6f51ca2b4
package/bin/consts.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../lib/consts.ts"],"sourcesContent":["import { homedir } from \"os\";\nimport path from \"path\";\n\nexport const API_HOST =\n process.env.DITTO_API_HOST || \"https://api.dittowords.com\";\nexport const CONFIG_FILE =\n process.env.DITTO_CONFIG_FILE || path.join(homedir(), \".config\", \"ditto\");\nexport const PROJECT_CONFIG_FILE = path.normalize(\n path.join(\"ditto\", \"config.yml\")\n);\nexport const TEXT_DIR = process.env.DITTO_TEXT_DIR || \"ditto\";\nexport const TEXT_FILE = path.normalize(path.join(TEXT_DIR, \"text.json\"));\n\nexport default {\n API_HOST,\n CONFIG_FILE,\n PROJECT_CONFIG_FILE,\n TEXT_DIR,\n TEXT_FILE,\n};\n"],"names":["path"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,gBAAwB;AACxB,kBAAiB;AAEV,MAAM,WACX,QAAQ,IAAI,kBAAkB;AACzB,MAAM,cACX,QAAQ,IAAI,qBAAqB,YAAAA,QAAK,SAAK,mBAAQ,GAAG,WAAW,OAAO;AACnE,MAAM,sBAAsB,YAAAA,QAAK;AAAA,EACtC,YAAAA,QAAK,KAAK,SAAS,YAAY;AACjC;AACO,MAAM,WAAW,QAAQ,IAAI,kBAAkB;AAC/C,MAAM,YAAY,YAAAA,QAAK,UAAU,YAAAA,QAAK,KAAK,UAAU,WAAW,CAAC;AAExE,IAAO,iBAAQ;AAAA,EACb;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF","debug_id":"2f4fc790-aa3c-5658-8839-9af5301ee3e0"}
1
+ {"version":3,"sources":["../lib/consts.ts"],"sourcesContent":["import { homedir } from \"os\";\nimport path from \"path\";\n\nexport default new (class {\n get API_HOST() {\n return process.env.DITTO_API_HOST || \"https://api.dittowords.com\";\n }\n get CONFIG_FILE() {\n return (\n process.env.DITTO_CONFIG_FILE || path.join(homedir(), \".config\", \"ditto\")\n );\n }\n get PROJECT_CONFIG_FILE() {\n return path.normalize(path.join(\"ditto\", \"config.yml\"));\n }\n get TEXT_DIR() {\n return process.env.DITTO_TEXT_DIR || \"ditto\";\n }\n get TEXT_FILE() {\n return path.normalize(path.join(this.TEXT_DIR, \"text.json\"));\n }\n})();\n"],"names":["path"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,gBAAwB;AACxB,kBAAiB;AAEjB,IAAO,iBAAQ,IAAK,MAAM;AAAA,EACxB,IAAI,WAAW;AACb,WAAO,QAAQ,IAAI,kBAAkB;AAAA,EACvC;AAAA,EACA,IAAI,cAAc;AAChB,WACE,QAAQ,IAAI,qBAAqB,YAAAA,QAAK,SAAK,mBAAQ,GAAG,WAAW,OAAO;AAAA,EAE5E;AAAA,EACA,IAAI,sBAAsB;AACxB,WAAO,YAAAA,QAAK,UAAU,YAAAA,QAAK,KAAK,SAAS,YAAY,CAAC;AAAA,EACxD;AAAA,EACA,IAAI,WAAW;AACb,WAAO,QAAQ,IAAI,kBAAkB;AAAA,EACvC;AAAA,EACA,IAAI,YAAY;AACd,WAAO,YAAAA,QAAK,UAAU,YAAAA,QAAK,KAAK,KAAK,UAAU,WAAW,CAAC;AAAA,EAC7D;AACF,EAAG","debug_id":"dff8f642-ef0f-5ab4-bf87-60f6f51ca2b4"}
@@ -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]="f22b8e5d-ede9-5c90-a7aa-258036e348df")}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]="c9f5e9e0-d691-51c4-b6ad-7649590ad798")}catch(e){}}();
3
3
 
4
4
  var __create = Object.create;
5
5
  var __defProp = Object.defineProperty;
@@ -71,7 +71,7 @@ __export(generate_suggestions_exports, {
71
71
  generateSuggestions: () => generateSuggestions
72
72
  });
73
73
  module.exports = __toCommonJS(generate_suggestions_exports);
74
- var import_fs_extra = __toESM(require("fs-extra"));
74
+ var import_fs = __toESM(require("fs"));
75
75
  var import_glob = __toESM(require("glob"));
76
76
  var import_parser = require("@babel/parser");
77
77
  var import_traverse = __toESM(require("@babel/traverse"));
@@ -95,66 +95,76 @@ function findComponentsInJSXFiles(params) {
95
95
  ignore: "**/node_modules/**"
96
96
  });
97
97
  const promises = [];
98
- for (const file of files) {
99
- promises.push(
100
- import_fs_extra.default.readFile(file, "utf-8").then((code) => {
101
- const ast = (0, import_parser.parse)(code, {
102
- sourceType: "module",
103
- plugins: ["jsx", "typescript"]
104
- });
105
- (0, import_traverse.default)(ast, {
106
- JSXText(path) {
107
- for (const [compApiId, component] of Object.entries(
108
- params.components
109
- )) {
110
- if (!result[compApiId]) {
111
- result[compApiId] = __spreadProps(__spreadValues({
112
- apiId: compApiId
113
- }, component), {
114
- occurrences: {}
115
- });
116
- }
117
- if (
118
- // Skip white space lines
119
- !/^\s*$/.test(path.node.value) && !/^\s*$/.test(component.text) && path.node.value.includes(component.text)
120
- ) {
121
- const escapedText = component.text.replace(
122
- /[.*+?^${}()|[\]\\]/g,
123
- "\\$&"
98
+ function handleFile(file) {
99
+ return __async(this, null, function* () {
100
+ const code = yield new Promise(
101
+ (resolve, reject) => import_fs.default.readFile(file, "utf-8", (err, data) => {
102
+ if (err) {
103
+ reject(err);
104
+ } else {
105
+ resolve(data);
106
+ }
107
+ })
108
+ );
109
+ const ast = (0, import_parser.parse)(code, {
110
+ sourceType: "module",
111
+ plugins: ["jsx", "typescript"]
112
+ });
113
+ (0, import_traverse.default)(ast, {
114
+ JSXText(path) {
115
+ for (const [compApiId, component] of Object.entries(
116
+ params.components
117
+ )) {
118
+ if (!result[compApiId]) {
119
+ result[compApiId] = __spreadProps(__spreadValues({
120
+ apiId: compApiId
121
+ }, component), {
122
+ occurrences: {}
123
+ });
124
+ }
125
+ if (
126
+ // Skip white space lines
127
+ !/^\s*$/.test(path.node.value) && !/^\s*$/.test(component.text) && path.node.value.includes(component.text)
128
+ ) {
129
+ const escapedText = component.text.replace(
130
+ /[.*+?^${}()|[\]\\]/g,
131
+ "\\$&"
132
+ );
133
+ const regex = new RegExp(escapedText, "g");
134
+ let match;
135
+ while ((match = regex.exec(path.node.value)) !== null) {
136
+ const lines = path.node.value.slice(0, match.index).split("\n");
137
+ if (!path.node.loc) {
138
+ continue;
139
+ }
140
+ const lineNumber = path.node.loc.start.line + lines.length - 1;
141
+ const codeLines = code.split("\n");
142
+ const line = codeLines[lineNumber - 1];
143
+ const preview = replaceAt(
144
+ line,
145
+ match.index,
146
+ component.text,
147
+ `${component.text}`
124
148
  );
125
- const regex = new RegExp(escapedText, "g");
126
- let match;
127
- while ((match = regex.exec(path.node.value)) !== null) {
128
- const lines = path.node.value.slice(0, match.index).split("\n");
129
- if (!path.node.loc) {
130
- continue;
131
- }
132
- const lineNumber = path.node.loc.start.line + lines.length - 1;
133
- const codeLines = code.split("\n");
134
- const line = codeLines[lineNumber - 1];
135
- const preview = replaceAt(
136
- line,
137
- match.index,
138
- component.text,
139
- `${component.text}`
140
- );
141
- if (!result[compApiId]["occurrences"][file]) {
142
- result[compApiId]["occurrences"][file] = [];
143
- }
144
- result[compApiId]["occurrences"][file].push({
145
- lineNumber,
146
- preview
147
- });
149
+ if (!result[compApiId]["occurrences"][file]) {
150
+ result[compApiId]["occurrences"][file] = [];
148
151
  }
152
+ result[compApiId]["occurrences"][file].push({
153
+ lineNumber,
154
+ preview
155
+ });
149
156
  }
150
- if (Object.keys(result[compApiId]["occurrences"]).length === 0) {
151
- delete result[compApiId];
152
- }
157
+ }
158
+ if (Object.keys(result[compApiId]["occurrences"]).length === 0) {
159
+ delete result[compApiId];
153
160
  }
154
161
  }
155
- });
156
- })
157
- );
162
+ }
163
+ });
164
+ });
165
+ }
166
+ for (const file of files) {
167
+ promises.push(handleFile(file));
158
168
  }
159
169
  yield Promise.all(promises);
160
170
  return result;
@@ -170,4 +180,4 @@ function replaceAt(str, index, searchString, replacement) {
170
180
  });
171
181
  //# sourceMappingURL=generate-suggestions.js.map
172
182
 
173
- //# debugId=f22b8e5d-ede9-5c90-a7aa-258036e348df
183
+ //# debugId=c9f5e9e0-d691-51c4-b6ad-7649590ad798
@@ -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\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
+ {"version":3,"sources":["../lib/generate-suggestions.ts"],"sourcesContent":["import fs from \"fs\";\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(\n params: (\n | { directory: string; files?: string[] }\n | { files: string[]; directory?: string }\n ) & {\n components: FetchComponentResponse;\n }\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 async function handleFile(file: string) {\n const code = await new Promise<string>((resolve, reject) =>\n fs.readFile(file, \"utf-8\", (err, data) => {\n if (err) {\n reject(err);\n } else {\n resolve(data);\n }\n })\n );\n\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.slice(0, match.index).split(\"\\n\");\n\n if (!path.node.loc) {\n continue;\n }\n\n const lineNumber = 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 for (const file of files) {\n promises.push(handleFile(file));\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":"c9f5e9e0-d691-51c4-b6ad-7649590ad798"}
@@ -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]="c4359991-3262-5990-9114-03bc3f03990b")}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]="bd23df8e-2e66-5de9-8b6b-5a3ca81ea0a8")}catch(e){}}();
3
3
 
4
4
  var __create = Object.create;
5
5
  var __defProp = Object.defineProperty;
@@ -43,21 +43,34 @@ var __async = (__this, __arguments, generator) => {
43
43
  step((generator = generator.apply(__this, __arguments)).next());
44
44
  });
45
45
  };
46
- var import_promises = __toESM(require("fs/promises"));
46
+ var import_fs = __toESM(require("fs"));
47
47
  var import_path = __toESM(require("path"));
48
48
  var import_generate_suggestions = require("./generate-suggestions");
49
+ jest.mock("fs");
49
50
  describe("findTextInJSXFiles", () => {
50
51
  function createTempFile(filename, content) {
51
52
  return __async(this, null, function* () {
52
- const filePath = import_path.default.join(".", filename);
53
- yield import_promises.default.writeFile(filePath, content);
53
+ const filePath = import_path.default.join("/", filename);
54
+ yield new Promise((resolve, reject) => {
55
+ try {
56
+ import_fs.default.writeFile(filePath, content, () => resolve(null));
57
+ } catch (e) {
58
+ reject(e);
59
+ }
60
+ });
54
61
  return filePath;
55
62
  });
56
63
  }
57
64
  function deleteTempFile(filename) {
58
65
  return __async(this, null, function* () {
59
- const filePath = import_path.default.join(".", filename);
60
- yield import_promises.default.unlink(filePath);
66
+ const filePath = import_path.default.join("/", filename);
67
+ yield new Promise((resolve, reject) => {
68
+ try {
69
+ import_fs.default.unlink(filePath, resolve);
70
+ } catch (e) {
71
+ reject(e);
72
+ }
73
+ });
61
74
  });
62
75
  }
63
76
  it("should return an empty obj when no files are found", () => __async(exports, null, function* () {
@@ -112,7 +125,7 @@ describe("findTextInJSXFiles", () => {
112
125
  }
113
126
  };
114
127
  const result = yield (0, import_generate_suggestions.findComponentsInJSXFiles)({
115
- directory: ".",
128
+ directory: "/",
116
129
  components: {
117
130
  "search-string": {
118
131
  name: "Search String",
@@ -152,8 +165,7 @@ describe("findTextInJSXFiles", () => {
152
165
  }
153
166
  };
154
167
  const result = yield (0, import_generate_suggestions.findComponentsInJSXFiles)({
155
- directory: ".",
156
- files: ["file1.jsx"],
168
+ files: ["/file1.jsx"],
157
169
  components: {
158
170
  "search-string": {
159
171
  name: "Search String",
@@ -165,9 +177,8 @@ describe("findTextInJSXFiles", () => {
165
177
  });
166
178
  expect(result).toEqual(expectedResult);
167
179
  try {
168
- const result2 = yield (0, import_generate_suggestions.findComponentsInJSXFiles)({
169
- directory: ".",
170
- files: ["file2.jsx"],
180
+ yield (0, import_generate_suggestions.findComponentsInJSXFiles)({
181
+ files: ["/file2.jsx"],
171
182
  components: {
172
183
  "search-string": {
173
184
  name: "Search String",
@@ -186,4 +197,4 @@ describe("findTextInJSXFiles", () => {
186
197
  });
187
198
  //# sourceMappingURL=generate-suggestions.test.js.map
188
199
 
189
- //# debugId=c4359991-3262-5990-9114-03bc3f03990b
200
+ //# debugId=bd23df8e-2e66-5de9-8b6b-5a3ca81ea0a8