@dittowords/cli 4.3.0 → 4.4.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.
Files changed (85) hide show
  1. package/.github/actions/install-node-dependencies/action.yml +24 -0
  2. package/.github/workflows/required-checks.yml +24 -0
  3. package/.sentryclirc +3 -0
  4. package/__mocks__/fs.js +2 -0
  5. package/bin/__mocks__/api.js +48 -0
  6. package/bin/__mocks__/api.js.map +1 -0
  7. package/bin/config.test.js +4 -3
  8. package/bin/config.test.js.map +1 -1
  9. package/bin/consts.js +19 -29
  10. package/bin/consts.js.map +1 -1
  11. package/bin/ditto.js +12 -4
  12. package/bin/ditto.js.map +1 -1
  13. package/bin/generate-suggestions.js +68 -58
  14. package/bin/generate-suggestions.js.map +1 -1
  15. package/bin/generate-suggestions.test.js +24 -13
  16. package/bin/generate-suggestions.test.js.map +1 -1
  17. package/bin/http/__mocks__/fetchComponentFolders.js +71 -0
  18. package/bin/http/__mocks__/fetchComponentFolders.js.map +1 -0
  19. package/bin/http/__mocks__/fetchComponents.js +73 -0
  20. package/bin/http/__mocks__/fetchComponents.js.map +1 -0
  21. package/bin/http/__mocks__/fetchVariants.js +71 -0
  22. package/bin/http/__mocks__/fetchVariants.js.map +1 -0
  23. package/bin/http/fetchComponentFolders.js +4 -4
  24. package/bin/http/fetchComponentFolders.js.map +1 -1
  25. package/bin/http/fetchComponents.js +4 -4
  26. package/bin/http/fetchComponents.js.map +1 -1
  27. package/bin/http/fetchVariants.js +6 -3
  28. package/bin/http/fetchVariants.js.map +1 -1
  29. package/bin/http/http.test.js +159 -0
  30. package/bin/http/http.test.js.map +1 -0
  31. package/bin/http/importComponents.js +9 -2
  32. package/bin/http/importComponents.js.map +1 -1
  33. package/bin/init/project.test.js +5 -28
  34. package/bin/init/project.test.js.map +1 -1
  35. package/bin/init/token.js +72 -27
  36. package/bin/init/token.js.map +1 -1
  37. package/bin/init/token.test.js +87 -9
  38. package/bin/init/token.test.js.map +1 -1
  39. package/bin/pull-lib.test.js +379 -0
  40. package/bin/pull-lib.test.js.map +1 -0
  41. package/bin/pull.js +15 -4
  42. package/bin/pull.js.map +1 -1
  43. package/bin/pull.test.js +73 -290
  44. package/bin/pull.test.js.map +1 -1
  45. package/bin/replace.js +22 -6
  46. package/bin/replace.js.map +1 -1
  47. package/bin/replace.test.js +53 -11
  48. package/bin/replace.test.js.map +1 -1
  49. package/bin/utils/determineModuleType.js +6 -7
  50. package/bin/utils/determineModuleType.js.map +1 -1
  51. package/bin/utils/determineModuleType.test.js +60 -0
  52. package/bin/utils/determineModuleType.test.js.map +1 -0
  53. package/bin/utils/getSelectedProjects.js +5 -5
  54. package/bin/utils/getSelectedProjects.js.map +1 -1
  55. package/bin/utils/quit.js +3 -3
  56. package/bin/utils/quit.js.map +1 -1
  57. package/jest.config.ts +16 -0
  58. package/lib/__mocks__/api.ts +12 -0
  59. package/lib/config.test.ts +3 -1
  60. package/lib/consts.ts +19 -17
  61. package/lib/ditto.ts +9 -1
  62. package/lib/generate-suggestions.test.ts +23 -11
  63. package/lib/generate-suggestions.ts +89 -79
  64. package/lib/http/__mocks__/fetchComponentFolders.ts +23 -0
  65. package/lib/http/__mocks__/fetchComponents.ts +24 -0
  66. package/lib/http/__mocks__/fetchVariants.ts +21 -0
  67. package/lib/http/fetchComponentFolders.ts +6 -4
  68. package/lib/http/fetchComponents.ts +5 -3
  69. package/lib/http/fetchVariants.ts +15 -4
  70. package/lib/http/http.test.ts +122 -0
  71. package/lib/http/importComponents.ts +8 -0
  72. package/lib/init/project.test.ts +4 -27
  73. package/lib/init/token.test.ts +55 -7
  74. package/lib/init/token.ts +76 -27
  75. package/lib/pull-lib.test.ts +367 -0
  76. package/lib/pull.test.ts +63 -316
  77. package/lib/pull.ts +13 -2
  78. package/lib/replace.test.ts +46 -10
  79. package/lib/replace.ts +20 -3
  80. package/lib/utils/determineModuleType.test.ts +48 -0
  81. package/lib/utils/determineModuleType.ts +4 -6
  82. package/lib/utils/getSelectedProjects.ts +3 -3
  83. package/lib/utils/quit.ts +1 -1
  84. package/package.json +4 -3
  85. package/jest.config.js +0 -6
package/bin/pull.test.js CHANGED
@@ -1,12 +1,26 @@
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]="3d53a7f0-4cb6-57db-948f-db309cf2611a")}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]="ad385829-c058-59ae-8358-bf84acb2d6d9")}catch(e){}}();
3
3
 
4
4
  var __create = Object.create;
5
5
  var __defProp = Object.defineProperty;
6
6
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
7
7
  var __getOwnPropNames = Object.getOwnPropertyNames;
8
+ var __getOwnPropSymbols = Object.getOwnPropertySymbols;
8
9
  var __getProtoOf = Object.getPrototypeOf;
9
10
  var __hasOwnProp = Object.prototype.hasOwnProperty;
11
+ var __propIsEnum = Object.prototype.propertyIsEnumerable;
12
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
13
+ var __spreadValues = (a, b) => {
14
+ for (var prop in b || (b = {}))
15
+ if (__hasOwnProp.call(b, prop))
16
+ __defNormalProp(a, prop, b[prop]);
17
+ if (__getOwnPropSymbols)
18
+ for (var prop of __getOwnPropSymbols(b)) {
19
+ if (__propIsEnum.call(b, prop))
20
+ __defNormalProp(a, prop, b[prop]);
21
+ }
22
+ return a;
23
+ };
10
24
  var __copyProps = (to, from, except, desc) => {
11
25
  if (from && typeof from === "object" || typeof from === "function") {
12
26
  for (let key of __getOwnPropNames(from))
@@ -43,298 +57,67 @@ var __async = (__this, __arguments, generator) => {
43
57
  step((generator = generator.apply(__this, __arguments)).next());
44
58
  });
45
59
  };
46
- var import_fs = __toESM(require("fs"));
47
- var import_path = __toESM(require("path"));
48
- var import_api = require("./api");
60
+ var import_pull = require("./pull");
61
+ var import_memfs = require("memfs");
49
62
  var import_consts = __toESM(require("./consts"));
50
- var import_pull = __toESM(require("./pull"));
51
- jest.mock("./api", () => ({
52
- createApiClient: jest.fn()
53
- // this needs to be mocked in each test that requires it
54
- }));
55
- const testProjects = [
56
- {
57
- id: "1",
58
- name: "Project 1",
59
- fileName: "Project 1"
60
- },
61
- { id: "2", name: "Project 2", fileName: "Project 2" }
62
- ];
63
- const mockApi = (0, import_api.createApiClient)();
64
- jest.mock("./consts", () => ({
65
- TEXT_DIR: ".testing",
66
- API_HOST: "https://api.dittowords.com",
67
- CONFIG_FILE: ".testing/ditto",
68
- PROJECT_CONFIG_FILE: ".testing/config.yml",
69
- TEXT_FILE: ".testing/text.json"
70
- }));
71
- const {
72
- _testing: { cleanOutputFiles, downloadAndSaveVariant, downloadAndSaveBase }
73
- } = import_pull.default;
74
- const variant = "english";
75
- const cleanOutputDir = () => {
76
- if (import_fs.default.existsSync(import_consts.default.TEXT_DIR))
77
- import_fs.default.rmSync(import_consts.default.TEXT_DIR, { recursive: true, force: true });
78
- import_fs.default.mkdirSync(import_consts.default.TEXT_DIR);
79
- };
80
- afterAll(() => {
81
- import_fs.default.rmSync(import_consts.default.TEXT_DIR, { force: true, recursive: true });
82
- });
83
- describe("cleanOutputFiles", () => {
84
- it("removes .js, .json, .xml, .strings, .stringsdict files", () => {
85
- cleanOutputDir();
86
- import_fs.default.writeFileSync(import_path.default.resolve(import_consts.default.TEXT_DIR, "test.json"), "test");
87
- import_fs.default.writeFileSync(import_path.default.resolve(import_consts.default.TEXT_DIR, "test.js"), "test");
88
- import_fs.default.writeFileSync(import_path.default.resolve(import_consts.default.TEXT_DIR, "test.xml"), "test");
89
- import_fs.default.writeFileSync(import_path.default.resolve(import_consts.default.TEXT_DIR, "test.strings"), "test");
90
- import_fs.default.writeFileSync(import_path.default.resolve(import_consts.default.TEXT_DIR, "test.stringsdict"), "test");
91
- import_fs.default.writeFileSync(import_path.default.resolve(import_consts.default.TEXT_DIR, "test.txt"), "test");
92
- expect(import_fs.default.readdirSync(import_consts.default.TEXT_DIR).length).toEqual(6);
93
- cleanOutputFiles();
94
- expect(import_fs.default.readdirSync(import_consts.default.TEXT_DIR).length).toEqual(1);
95
- });
63
+ var import_globals = require("@jest/globals");
64
+ var import_axios = __toESM(require("axios"));
65
+ var import_fs = __toESM(require("fs"));
66
+ const axiosMock = import_globals.jest.mocked(import_axios.default);
67
+ import_globals.jest.mock("fs");
68
+ import_globals.jest.mock("./api");
69
+ import_globals.jest.mock("./http/fetchComponentFolders");
70
+ import_globals.jest.mock("./http/fetchComponents");
71
+ import_globals.jest.mock("./http/fetchVariants");
72
+ const defaultEnv = __spreadValues({}, process.env);
73
+ beforeEach(() => {
74
+ import_memfs.vol.reset();
75
+ process.env = __spreadValues({}, defaultEnv);
96
76
  });
97
- describe("downloadAndSaveBase", () => {
98
- beforeAll(() => {
99
- if (!import_fs.default.existsSync(import_consts.default.TEXT_DIR)) {
100
- import_fs.default.mkdirSync(import_consts.default.TEXT_DIR);
101
- }
102
- });
103
- beforeEach(() => {
104
- cleanOutputDir();
105
- });
106
- const mockDataFlat = { hello: "world" };
107
- const mockDataNested = { hello: { text: "world" } };
108
- const mockDataStructured = { hello: { text: "world" } };
109
- const mockDataIcu = { hello: "world" };
110
- const mockDataAndroid = `
111
- <?xml version="1.0" encoding="utf-8"?>
112
- <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
113
- <string name="hello-world" ditto_api_id="hello-world">Hello World</string>
114
- </resources>
115
- `;
116
- const mockDataIosStrings = `
117
- "hello" = "world";
118
- `;
119
- const mockDataIosStringsDict = `
120
- <?xml version="1.0" encoding="utf-8"?>
121
- <plist version="1.0">
122
- <dict>
123
- <key>hello-world</key>
124
- <dict>
125
- <key>NSStringLocalizedFormatKey</key>
126
- <string>%1$#@count@</string>
127
- <key>count</key>
128
- <dict>
129
- <key>NSStringFormatSpecTypeKey</key>
130
- <string>NSStringPluralRuleType</string>
131
- <key>NSStringFormatValueTypeKey</key>
132
- <string>d</string>
133
- <key>other</key>
134
- <string>espanol</string>
135
- </dict>
136
- </dict>
137
- </dict>
138
- </plist>
139
- `;
140
- const formats = [
141
- { format: "flat", data: mockDataFlat, ext: ".json" },
142
- { format: "nested", data: mockDataNested, ext: ".json" },
143
- { format: "structured", data: mockDataStructured, ext: ".json" },
144
- { format: "icu", data: mockDataIcu, ext: ".json" },
145
- { format: "android", data: mockDataAndroid, ext: ".xml" },
146
- { format: "ios-strings", data: mockDataIosStrings, ext: ".strings" },
147
- {
148
- format: "ios-stringsdict",
149
- data: mockDataIosStringsDict,
150
- ext: ".stringsdict"
151
- }
152
- ];
153
- const mockApiCall = (data) => {
154
- import_api.createApiClient.mockImplementation(() => ({
155
- get: () => ({ data })
156
- }));
157
- };
158
- const verifySavedData = (format, data, ext) => __async(exports, null, function* () {
159
- const output = yield downloadAndSaveBase({
160
- projects: testProjects,
161
- format
162
- });
163
- expect(/successfully saved/i.test(output)).toEqual(true);
164
- const directoryContents = import_fs.default.readdirSync(import_consts.default.TEXT_DIR);
165
- expect(directoryContents.length).toEqual(testProjects.length);
166
- expect(directoryContents.every((f) => f.endsWith(ext))).toBe(true);
167
- const fileDataString = import_fs.default.readFileSync(
168
- import_path.default.resolve(import_consts.default.TEXT_DIR, directoryContents[0]),
169
- "utf8"
77
+ const mockGlobalConfigFile = `
78
+ api.dittowords.com:
79
+ - token: xxx-xxx-xxx
80
+ `;
81
+ const mockProjectConfigFile = `
82
+ sources:
83
+ components: true
84
+ projects:
85
+ - id: project-id-1
86
+ name: Test Project
87
+ variants: true
88
+ `;
89
+ describe("pull", () => {
90
+ it("correctly writes files to disk per source for basic config", () => __async(exports, null, function* () {
91
+ process.env.DITTO_TEXT_DIR = "/ditto";
92
+ process.env.DITTO_PROJECT_CONFIG_FILE = "/ditto/config.yml";
93
+ axiosMock.get.mockImplementation(
94
+ () => Promise.resolve({ data: "data" })
170
95
  );
171
- switch (format) {
172
- case "android":
173
- case "ios-strings":
174
- case "ios-stringsdict":
175
- expect(typeof data).toBe("string");
176
- expect(fileDataString.replace(/\s/g, "")).toEqual(
177
- data.replace(/\s/g, "")
178
- );
179
- break;
180
- case "flat":
181
- case "nested":
182
- case "structured":
183
- case "icu":
184
- default:
185
- expect(JSON.parse(fileDataString)).toEqual(data);
186
- break;
187
- }
188
- });
189
- formats.forEach(({ format, data, ext }) => {
190
- it(`writes the ${format} format to disk`, () => __async(exports, null, function* () {
191
- mockApiCall(data);
192
- yield verifySavedData(format, data, ext);
193
- }));
194
- });
195
- });
196
- describe("getFormatDataIsValid", () => {
197
- it("handles flat format appropriately", () => {
198
- expect(import_pull.getFormatDataIsValid.flat("{}")).toBe(false);
199
- expect(import_pull.getFormatDataIsValid.flat(`{ "hello": "world" }`)).toBe(true);
200
- expect(
201
- import_pull.getFormatDataIsValid.flat(`{
202
- "__variant-name": "English",
203
- "__variant-description": ""
204
- }`)
205
- ).toBe(false);
206
- expect(
207
- import_pull.getFormatDataIsValid.flat(`{
208
- "__variant-name": "English",
209
- "__variant-description": "",
210
- "hello": "world"
211
- }`)
212
- ).toBe(true);
213
- });
214
- it("handles structured format appropriately", () => {
215
- expect(import_pull.getFormatDataIsValid.structured("{}")).toBe(false);
216
- expect(
217
- import_pull.getFormatDataIsValid.structured(`{ "hello": { "text": "world" } }`)
218
- ).toBe(true);
219
- expect(
220
- import_pull.getFormatDataIsValid.structured(`{
221
- "__variant-name": "English",
222
- "__variant-description": ""
223
- }`)
224
- ).toBe(false);
225
- expect(
226
- import_pull.getFormatDataIsValid.structured(`{
227
- "__variant-name": "English",
228
- "__variant-description": "",
229
- "hello": { "text": "world" }
230
- }`)
231
- ).toBe(true);
232
- });
233
- it("handles icu format appropriately", () => {
234
- expect(import_pull.getFormatDataIsValid.icu("{}")).toBe(false);
235
- expect(import_pull.getFormatDataIsValid.icu(`{ "hello": "world" }`)).toBe(true);
236
- expect(
237
- import_pull.getFormatDataIsValid.icu(`{
238
- "__variant-name": "English",
239
- "__variant-description": ""
240
- }`)
241
- ).toBe(false);
242
- expect(
243
- import_pull.getFormatDataIsValid.icu(`{
244
- "__variant-name": "English",
245
- "__variant-description": "",
246
- "hello": "world"
247
- }`)
248
- ).toBe(true);
249
- });
250
- it("handles android format appropriately", () => {
251
- expect(
252
- import_pull.getFormatDataIsValid.android(`
253
- <?xml version="1.0" encoding="utf-8"?>
254
- <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"/>
255
- `)
256
- ).toBe(false);
257
- expect(
258
- import_pull.getFormatDataIsValid.android(`
259
- <?xml version="1.0" encoding="utf-8"?>
260
- <!--Variant Name: English-->
261
- <!--Variant Description: -->
262
- <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"/>
263
- `)
264
- ).toBe(false);
265
- expect(
266
- import_pull.getFormatDataIsValid.android(`
267
- <?xml version="1.0" encoding="utf-8"?>
268
- <!--Variant Name: English-->
269
- <!--Variant Description: -->
270
- <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
271
- <string name="hello-world" ditto_api_id="hello-world">Hello World</string>
272
- </resources>
273
- `)
274
- ).toBe(true);
275
- });
276
- it("handles ios-strings format appropriately", () => {
277
- expect(import_pull.getFormatDataIsValid["ios-strings"]("")).toBe(false);
278
- expect(
279
- import_pull.getFormatDataIsValid["ios-strings"](`
280
- /* Variant Name: English */
281
- /* Variant Description: */
282
- `)
283
- ).toBe(false);
284
- expect(
285
- import_pull.getFormatDataIsValid["ios-strings"](`
286
- /* Variant Name: English */
287
- /* Variant Description: */
288
- "Hello" = "World";
289
- `)
290
- ).toBe(true);
291
- });
292
- it("handles ios-stringsdict format appropriately", () => {
293
- expect(
294
- import_pull.getFormatDataIsValid["ios-stringsdict"](`
295
- <?xml version="1.0" encoding="utf-8"?>
296
- <plist version="1.0">
297
- <dict/>
298
- </plist>
299
- `)
300
- ).toBe(false);
301
- expect(
302
- import_pull.getFormatDataIsValid["ios-stringsdict"](`
303
- <?xml version="1.0" encoding="utf-8"?>
304
- <!--Variant Name: English-->
305
- <!--Variant Description: -->
306
- <plist version="1.0">
307
- <dict/>
308
- </plist>
309
- `)
310
- ).toBe(false);
311
- expect(
312
- import_pull.getFormatDataIsValid["ios-stringsdict"](`
313
- <?xml version="1.0" encoding="utf-8"?>
314
- <!--Variant Name: English-->
315
- <!--Variant Description: -->
316
- <plist version="1.0">
317
- <dict>
318
- <key>Hello World</key>
319
- <dict>
320
- <key>NSStringLocalizedFormatKey</key>
321
- <string>%1$#@count@</string>
322
- <key>count</key>
323
- <dict>
324
- <key>NSStringFormatSpecTypeKey</key>
325
- <string>NSStringPluralRuleType</string>
326
- <key>NSStringFormatValueTypeKey</key>
327
- <string>d</string>
328
- <key>other</key>
329
- <string>espanol</string>
330
- </dict>
331
- </dict>
332
- </dict>
333
- </plist>
334
- `)
335
- ).toBe(true);
336
- });
96
+ import_memfs.vol.fromJSON({
97
+ [import_consts.default.CONFIG_FILE]: mockGlobalConfigFile,
98
+ [import_consts.default.PROJECT_CONFIG_FILE]: mockProjectConfigFile
99
+ });
100
+ yield (0, import_pull.pull)();
101
+ const filesOnDiskExpected = /* @__PURE__ */ new Set([
102
+ "components__example-folder__base.json",
103
+ "components__example-folder__example-variant-1.json",
104
+ "components__example-folder__example-variant-2.json",
105
+ "components__root__base.json",
106
+ "components__root__example-variant-1.json",
107
+ "components__root__example-variant-2.json",
108
+ "test-project__base.json",
109
+ "test-project__example-variant-1.json",
110
+ "test-project__example-variant-2.json",
111
+ "index.d.ts",
112
+ "index.js"
113
+ ]);
114
+ const filesOnDisk = import_fs.default.readdirSync("/ditto");
115
+ filesOnDisk.forEach((file) => {
116
+ filesOnDiskExpected.delete(file);
117
+ });
118
+ expect(filesOnDiskExpected.size).toBe(0);
119
+ }));
337
120
  });
338
121
  //# sourceMappingURL=pull.test.js.map
339
122
 
340
- //# debugId=3d53a7f0-4cb6-57db-948f-db309cf2611a
123
+ //# debugId=ad385829-c058-59ae-8358-bf84acb2d6d9
@@ -1 +1 @@
1
- {"version":3,"sources":["../lib/pull.test.ts"],"sourcesContent":["import fs from \"fs\";\nimport path from \"path\";\n\njest.mock(\"./api\", () => ({\n createApiClient: jest.fn(), // this needs to be mocked in each test that requires it\n}));\nimport { createApiClient } from \"./api\";\n\nconst testProjects: Project[] = [\n {\n id: \"1\",\n name: \"Project 1\",\n fileName: \"Project 1\",\n },\n { id: \"2\", name: \"Project 2\", fileName: \"Project 2\" },\n];\n\n// TODO: all tests in this file currently failing because we're re-instantiating the api client\n// everywhere and are unable to mock the return type separately for each instance of usage.\n// We need to refactor to share one api client everywhere instead of always re-creating it.\nconst mockApi = createApiClient() as any as jest.Mocked<\n ReturnType<typeof createApiClient>\n>;\n\njest.mock(\"./consts\", () => ({\n TEXT_DIR: \".testing\",\n API_HOST: \"https://api.dittowords.com\",\n CONFIG_FILE: \".testing/ditto\",\n PROJECT_CONFIG_FILE: \".testing/config.yml\",\n TEXT_FILE: \".testing/text.json\",\n}));\n\nimport consts from \"./consts\";\nimport allPull, { getFormatDataIsValid } from \"./pull\";\nimport { Project, SupportedExtension, SupportedFormat } from \"./types\";\n\nconst {\n _testing: { cleanOutputFiles, downloadAndSaveVariant, downloadAndSaveBase },\n} = allPull;\nconst variant = \"english\";\n\nconst cleanOutputDir = () => {\n if (fs.existsSync(consts.TEXT_DIR))\n fs.rmSync(consts.TEXT_DIR, { recursive: true, force: true });\n\n fs.mkdirSync(consts.TEXT_DIR);\n};\n\nafterAll(() => {\n fs.rmSync(consts.TEXT_DIR, { force: true, recursive: true });\n});\n\ndescribe(\"cleanOutputFiles\", () => {\n it(\"removes .js, .json, .xml, .strings, .stringsdict files\", () => {\n cleanOutputDir();\n\n fs.writeFileSync(path.resolve(consts.TEXT_DIR, \"test.json\"), \"test\");\n fs.writeFileSync(path.resolve(consts.TEXT_DIR, \"test.js\"), \"test\");\n fs.writeFileSync(path.resolve(consts.TEXT_DIR, \"test.xml\"), \"test\");\n fs.writeFileSync(path.resolve(consts.TEXT_DIR, \"test.strings\"), \"test\");\n fs.writeFileSync(path.resolve(consts.TEXT_DIR, \"test.stringsdict\"), \"test\");\n // this file shouldn't be deleted\n fs.writeFileSync(path.resolve(consts.TEXT_DIR, \"test.txt\"), \"test\");\n\n expect(fs.readdirSync(consts.TEXT_DIR).length).toEqual(6);\n\n cleanOutputFiles();\n\n expect(fs.readdirSync(consts.TEXT_DIR).length).toEqual(1);\n });\n});\n\ndescribe(\"downloadAndSaveBase\", () => {\n beforeAll(() => {\n if (!fs.existsSync(consts.TEXT_DIR)) {\n fs.mkdirSync(consts.TEXT_DIR);\n }\n });\n\n beforeEach(() => {\n cleanOutputDir();\n });\n\n const mockDataFlat = { hello: \"world\" };\n const mockDataNested = { hello: { text: \"world\" } };\n const mockDataStructured = { hello: { text: \"world\" } };\n const mockDataIcu = { hello: \"world\" };\n const mockDataAndroid = `\n <?xml version=\"1.0\" encoding=\"utf-8\"?>\n <resources xmlns:xliff=\"urn:oasis:names:tc:xliff:document:1.2\">\n <string name=\"hello-world\" ditto_api_id=\"hello-world\">Hello World</string>\n </resources>\n `;\n const mockDataIosStrings = `\n \"hello\" = \"world\"; \n `;\n const mockDataIosStringsDict = `\n <?xml version=\"1.0\" encoding=\"utf-8\"?>\n <plist version=\"1.0\">\n <dict>\n <key>hello-world</key>\n <dict>\n <key>NSStringLocalizedFormatKey</key>\n <string>%1$#@count@</string>\n <key>count</key>\n <dict>\n <key>NSStringFormatSpecTypeKey</key>\n <string>NSStringPluralRuleType</string>\n <key>NSStringFormatValueTypeKey</key>\n <string>d</string>\n <key>other</key>\n <string>espanol</string>\n </dict>\n </dict>\n </dict>\n </plist>\n `;\n\n const formats: Array<{\n format: SupportedFormat;\n data: Object;\n ext: SupportedExtension;\n }> = [\n { format: \"flat\", data: mockDataFlat, ext: \".json\" },\n { format: \"nested\", data: mockDataNested, ext: \".json\" },\n { format: \"structured\", data: mockDataStructured, ext: \".json\" },\n { format: \"icu\", data: mockDataIcu, ext: \".json\" },\n { format: \"android\", data: mockDataAndroid, ext: \".xml\" },\n { format: \"ios-strings\", data: mockDataIosStrings, ext: \".strings\" },\n {\n format: \"ios-stringsdict\",\n data: mockDataIosStringsDict,\n ext: \".stringsdict\",\n },\n ];\n\n const mockApiCall = (data: unknown) => {\n (createApiClient as any).mockImplementation(() => ({\n get: () => ({ data }),\n }));\n };\n\n const verifySavedData = async (\n format: SupportedFormat,\n data: unknown,\n ext: SupportedExtension\n ) => {\n const output = await downloadAndSaveBase({\n projects: testProjects,\n format: format,\n } as any);\n expect(/successfully saved/i.test(output)).toEqual(true);\n const directoryContents = fs.readdirSync(consts.TEXT_DIR);\n expect(directoryContents.length).toEqual(testProjects.length);\n expect(directoryContents.every((f) => f.endsWith(ext))).toBe(true);\n const fileDataString = fs.readFileSync(\n path.resolve(consts.TEXT_DIR, directoryContents[0]),\n \"utf8\"\n );\n\n switch (format) {\n case \"android\":\n case \"ios-strings\":\n case \"ios-stringsdict\":\n expect(typeof data).toBe(\"string\");\n expect(fileDataString.replace(/\\s/g, \"\")).toEqual(\n (data as string).replace(/\\s/g, \"\")\n );\n break;\n\n case \"flat\":\n case \"nested\":\n case \"structured\":\n case \"icu\":\n default:\n expect(JSON.parse(fileDataString)).toEqual(data);\n break;\n }\n };\n\n formats.forEach(({ format, data, ext }) => {\n it(`writes the ${format} format to disk`, async () => {\n mockApiCall(data);\n await verifySavedData(format, data, ext);\n });\n });\n});\n\ndescribe(\"getFormatDataIsValid\", () => {\n it(\"handles flat format appropriately\", () => {\n expect(getFormatDataIsValid.flat(\"{}\")).toBe(false);\n expect(getFormatDataIsValid.flat(`{ \"hello\": \"world\" }`)).toBe(true);\n expect(\n getFormatDataIsValid.flat(`{\n \"__variant-name\": \"English\",\n \"__variant-description\": \"\"\n }`)\n ).toBe(false);\n expect(\n getFormatDataIsValid.flat(`{\n \"__variant-name\": \"English\",\n \"__variant-description\": \"\",\n \"hello\": \"world\"\n }`)\n ).toBe(true);\n });\n it(\"handles structured format appropriately\", () => {\n expect(getFormatDataIsValid.structured(\"{}\")).toBe(false);\n expect(\n getFormatDataIsValid.structured(`{ \"hello\": { \"text\": \"world\" } }`)\n ).toBe(true);\n expect(\n getFormatDataIsValid.structured(`{\n \"__variant-name\": \"English\",\n \"__variant-description\": \"\"\n }`)\n ).toBe(false);\n expect(\n getFormatDataIsValid.structured(`{\n \"__variant-name\": \"English\",\n \"__variant-description\": \"\",\n \"hello\": { \"text\": \"world\" }\n }`)\n ).toBe(true);\n });\n it(\"handles icu format appropriately\", () => {\n expect(getFormatDataIsValid.icu(\"{}\")).toBe(false);\n expect(getFormatDataIsValid.icu(`{ \"hello\": \"world\" }`)).toBe(true);\n expect(\n getFormatDataIsValid.icu(`{\n \"__variant-name\": \"English\",\n \"__variant-description\": \"\"\n }`)\n ).toBe(false);\n expect(\n getFormatDataIsValid.icu(`{\n \"__variant-name\": \"English\",\n \"__variant-description\": \"\",\n \"hello\": \"world\"\n }`)\n ).toBe(true);\n });\n it(\"handles android format appropriately\", () => {\n expect(\n getFormatDataIsValid.android(`\n <?xml version=\"1.0\" encoding=\"utf-8\"?>\n <resources xmlns:xliff=\"urn:oasis:names:tc:xliff:document:1.2\"/>\n `)\n ).toBe(false);\n expect(\n getFormatDataIsValid.android(`\n <?xml version=\"1.0\" encoding=\"utf-8\"?>\n <!--Variant Name: English-->\n <!--Variant Description: -->\n <resources xmlns:xliff=\"urn:oasis:names:tc:xliff:document:1.2\"/>\n `)\n ).toBe(false);\n expect(\n getFormatDataIsValid.android(`\n <?xml version=\"1.0\" encoding=\"utf-8\"?>\n <!--Variant Name: English-->\n <!--Variant Description: -->\n <resources xmlns:xliff=\"urn:oasis:names:tc:xliff:document:1.2\">\n <string name=\"hello-world\" ditto_api_id=\"hello-world\">Hello World</string>\n </resources>\n `)\n ).toBe(true);\n });\n it(\"handles ios-strings format appropriately\", () => {\n expect(getFormatDataIsValid[\"ios-strings\"](\"\")).toBe(false);\n expect(\n getFormatDataIsValid[\"ios-strings\"](`\n /* Variant Name: English */\n /* Variant Description: */\n `)\n ).toBe(false);\n expect(\n getFormatDataIsValid[\"ios-strings\"](`\n /* Variant Name: English */\n /* Variant Description: */\n \"Hello\" = \"World\";\n `)\n ).toBe(true);\n });\n it(\"handles ios-stringsdict format appropriately\", () => {\n expect(\n getFormatDataIsValid[\"ios-stringsdict\"](`\n <?xml version=\"1.0\" encoding=\"utf-8\"?>\n <plist version=\"1.0\">\n <dict/>\n </plist>\n `)\n ).toBe(false);\n expect(\n getFormatDataIsValid[\"ios-stringsdict\"](`\n <?xml version=\"1.0\" encoding=\"utf-8\"?>\n <!--Variant Name: English-->\n <!--Variant Description: -->\n <plist version=\"1.0\">\n <dict/>\n </plist>\n `)\n ).toBe(false);\n expect(\n getFormatDataIsValid[\"ios-stringsdict\"](`\n <?xml version=\"1.0\" encoding=\"utf-8\"?>\n <!--Variant Name: English-->\n <!--Variant Description: -->\n <plist version=\"1.0\">\n <dict>\n <key>Hello World</key>\n <dict>\n <key>NSStringLocalizedFormatKey</key>\n <string>%1$#@count@</string>\n <key>count</key>\n <dict>\n <key>NSStringFormatSpecTypeKey</key>\n <string>NSStringPluralRuleType</string>\n <key>NSStringFormatValueTypeKey</key>\n <string>d</string>\n <key>other</key>\n <string>espanol</string>\n </dict>\n </dict>\n </dict>\n </plist>\n `)\n ).toBe(true);\n });\n});\n"],"names":["allPull","fs","consts","path"],"mappings":"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","debug_id":"3d53a7f0-4cb6-57db-948f-db309cf2611a"}
1
+ {"version":3,"sources":["../lib/pull.test.ts"],"sourcesContent":["import { pull } from \"./pull\";\nimport { vol } from \"memfs\";\nimport consts from \"./consts\";\nimport { jest } from \"@jest/globals\";\nimport axios from \"axios\";\nconst axiosMock = jest.mocked(axios);\nimport fs from \"fs\";\n\njest.mock(\"fs\");\njest.mock(\"./api\");\n\njest.mock(\"./http/fetchComponentFolders\");\njest.mock(\"./http/fetchComponents\");\njest.mock(\"./http/fetchVariants\");\n\nconst defaultEnv = { ...process.env };\n\nbeforeEach(() => {\n vol.reset();\n process.env = { ...defaultEnv };\n});\n\nconst mockGlobalConfigFile = `\napi.dittowords.com:\n - token: xxx-xxx-xxx\n`;\nconst mockProjectConfigFile = `\nsources:\n components: true\n projects:\n - id: project-id-1\n name: Test Project\nvariants: true\n`;\n\ndescribe(\"pull\", () => {\n it(\"correctly writes files to disk per source for basic config\", async () => {\n process.env.DITTO_TEXT_DIR = \"/ditto\";\n process.env.DITTO_PROJECT_CONFIG_FILE = \"/ditto/config.yml\";\n\n // we need to manually mock responses for the http calls that happen\n // directly within the pull function; we don't need to mock the http\n // calls that happen by way of http/* function calls since those have\n // their own mocks already.\n axiosMock.get.mockImplementation(\n (): Promise<any> => Promise.resolve({ data: \"data\" })\n );\n\n vol.fromJSON({\n [consts.CONFIG_FILE]: mockGlobalConfigFile,\n [consts.PROJECT_CONFIG_FILE]: mockProjectConfigFile,\n });\n\n await pull();\n\n const filesOnDiskExpected = new Set([\n \"components__example-folder__base.json\",\n \"components__example-folder__example-variant-1.json\",\n \"components__example-folder__example-variant-2.json\",\n \"components__root__base.json\",\n \"components__root__example-variant-1.json\",\n \"components__root__example-variant-2.json\",\n \"test-project__base.json\",\n \"test-project__example-variant-1.json\",\n \"test-project__example-variant-2.json\",\n \"index.d.ts\",\n \"index.js\",\n ]);\n\n const filesOnDisk = fs.readdirSync(\"/ditto\");\n filesOnDisk.forEach((file) => {\n filesOnDiskExpected.delete(file);\n });\n\n expect(filesOnDiskExpected.size).toBe(0);\n });\n});\n"],"names":["axios","consts","fs"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,kBAAqB;AACrB,mBAAoB;AACpB,oBAAmB;AACnB,qBAAqB;AACrB,mBAAkB;AAElB,gBAAe;AADf,MAAM,YAAY,oBAAK,OAAO,aAAAA,OAAK;AAGnC,oBAAK,KAAK,IAAI;AACd,oBAAK,KAAK,OAAO;AAEjB,oBAAK,KAAK,8BAA8B;AACxC,oBAAK,KAAK,wBAAwB;AAClC,oBAAK,KAAK,sBAAsB;AAEhC,MAAM,aAAa,mBAAK,QAAQ;AAEhC,WAAW,MAAM;AACf,mBAAI,MAAM;AACV,UAAQ,MAAM,mBAAK;AACrB,CAAC;AAED,MAAM,uBAAuB;AAAA;AAAA;AAAA;AAI7B,MAAM,wBAAwB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAS9B,SAAS,QAAQ,MAAM;AACrB,KAAG,8DAA8D,MAAY;AAC3E,YAAQ,IAAI,iBAAiB;AAC7B,YAAQ,IAAI,4BAA4B;AAMxC,cAAU,IAAI;AAAA,MACZ,MAAoB,QAAQ,QAAQ,EAAE,MAAM,OAAO,CAAC;AAAA,IACtD;AAEA,qBAAI,SAAS;AAAA,MACX,CAAC,cAAAC,QAAO,WAAW,GAAG;AAAA,MACtB,CAAC,cAAAA,QAAO,mBAAmB,GAAG;AAAA,IAChC,CAAC;AAED,cAAM,kBAAK;AAEX,UAAM,sBAAsB,oBAAI,IAAI;AAAA,MAClC;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAED,UAAM,cAAc,UAAAC,QAAG,YAAY,QAAQ;AAC3C,gBAAY,QAAQ,CAAC,SAAS;AAC5B,0BAAoB,OAAO,IAAI;AAAA,IACjC,CAAC;AAED,WAAO,oBAAoB,IAAI,EAAE,KAAK,CAAC;AAAA,EACzC,EAAC;AACH,CAAC","debug_id":"ad385829-c058-59ae-8358-bf84acb2d6d9"}
package/bin/replace.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]="68dcdcf7-5081-5b09-9769-c28ddf977785")}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]="76d5bf23-fec4-53e2-9669-a83a306dc53e")}catch(e){}}();
3
3
 
4
4
  var __create = Object.create;
5
5
  var __defProp = Object.defineProperty;
@@ -55,14 +55,22 @@ __export(replace_exports, {
55
55
  replaceJSXTextInFile: () => replaceJSXTextInFile
56
56
  });
57
57
  module.exports = __toCommonJS(replace_exports);
58
- var import_fs_extra = __toESM(require("fs-extra"));
58
+ var import_fs = __toESM(require("fs"));
59
59
  var import_parser = require("@babel/parser");
60
60
  var import_traverse = __toESM(require("@babel/traverse"));
61
61
  var t = __toESM(require("@babel/types"));
62
62
  var import_core = require("@babel/core");
63
63
  function replaceJSXTextInFile(filePath, replacement, flags) {
64
64
  return __async(this, null, function* () {
65
- const code = yield import_fs_extra.default.readFile(filePath, "utf-8");
65
+ const code = yield new Promise(
66
+ (resolve, reject) => import_fs.default.readFile(filePath, "utf-8", (err, data) => {
67
+ if (err) {
68
+ reject(err);
69
+ } else {
70
+ resolve(data);
71
+ }
72
+ })
73
+ );
66
74
  const ast = (0, import_parser.parse)(code, {
67
75
  sourceType: "module",
68
76
  plugins: ["jsx", "typescript"]
@@ -107,7 +115,15 @@ function replaceJSXTextInFile(filePath, replacement, flags) {
107
115
  /* @ts-ignore */
108
116
  configFile: false
109
117
  });
110
- import_fs_extra.default.writeFile(filePath, transformedCode);
118
+ yield new Promise(
119
+ (resolve, reject) => import_fs.default.writeFile(filePath, transformedCode, (err) => {
120
+ if (err) {
121
+ reject(err);
122
+ } else {
123
+ resolve(null);
124
+ }
125
+ })
126
+ );
111
127
  });
112
128
  }
113
129
  function splitByCaseInsensitive(str, delimiter) {
@@ -138,7 +154,7 @@ function parseOptions(options) {
138
154
  );
139
155
  }
140
156
  const filePath = options[0];
141
- const isFilePathValid = import_fs_extra.default.existsSync(filePath) && import_fs_extra.default.lstatSync(filePath).isFile();
157
+ const isFilePathValid = import_fs.default.existsSync(filePath) && import_fs.default.lstatSync(filePath).isFile();
142
158
  if (!isFilePathValid) {
143
159
  throw new Error(`${filePath} is not a valid file path.`);
144
160
  }
@@ -152,4 +168,4 @@ function parseOptions(options) {
152
168
  });
153
169
  //# sourceMappingURL=replace.js.map
154
170
 
155
- //# debugId=68dcdcf7-5081-5b09-9769-c28ddf977785
171
+ //# debugId=76d5bf23-fec4-53e2-9669-a83a306dc53e
@@ -1 +1 @@
1
- {"version":3,"sources":["../lib/replace.ts"],"sourcesContent":["import fs from \"fs-extra\";\nimport { parse } from \"@babel/parser\";\nimport traverse from \"@babel/traverse\";\nimport * as t from \"@babel/types\";\nimport { transformFromAst } from \"@babel/core\";\n\nasync function replaceJSXTextInFile(\n filePath: string,\n replacement: { searchString: string; replaceWith: string },\n flags: {\n lineNumbers?: number[];\n }\n) {\n const code = await fs.readFile(filePath, \"utf-8\");\n const ast = parse(code, {\n sourceType: \"module\",\n plugins: [\"jsx\", \"typescript\"],\n });\n\n traverse(ast, {\n JSXText(path) {\n const { searchString, replaceWith } = replacement;\n\n const searchStringEscaped = searchString.replace(\n /[.*+?^${}()|[\\]\\\\]/g,\n \"\\\\$&\"\n );\n const regex = new RegExp(searchStringEscaped, \"gi\");\n if (regex.test(path.node.value)) {\n // Ignore if not on a line number that we want to replace.\n if (\n flags.lineNumbers &&\n path.node.loc &&\n !flags.lineNumbers.includes(path.node.loc.start.line)\n ) {\n return;\n }\n\n const splitValues = splitByCaseInsensitive(\n path.node.value,\n searchStringEscaped\n );\n const nodes: (t.JSXElement | t.JSXText)[] = [];\n\n splitValues.forEach((splitValue) => {\n if (splitValue.toLowerCase() === searchString.toLowerCase()) {\n const identifier = t.jsxIdentifier(\"DittoComponent\");\n const componentId = t.jsxAttribute(\n t.jsxIdentifier(\"componentId\"),\n t.stringLiteral(replaceWith)\n );\n const o = t.jsxOpeningElement(identifier, [componentId], true);\n const jsxElement = t.jsxElement(o, undefined, [], true);\n nodes.push(jsxElement);\n } else {\n nodes.push(t.jsxText(splitValue));\n }\n });\n\n path.replaceWithMultiple(nodes);\n }\n },\n });\n\n // transfromFromAst types are wrong?\n /* @ts-ignore */\n const { code: transformedCode } = transformFromAst(ast, code, {\n // Don't let this codebase's Babel config affect the code we're transforming.\n /* @ts-ignore */\n configFile: false,\n });\n fs.writeFile(filePath, transformedCode);\n}\n\nfunction splitByCaseInsensitive(str: string, delimiter: string) {\n return str.split(new RegExp(`(${delimiter})`, \"gi\")).filter((s) => s !== \"\");\n}\n\nfunction replace(options: string[], flags: { lineNumbers?: number[] }) {\n let filePath: string;\n let searchString: string;\n let replaceWith: string;\n\n try {\n const parsedOptions = parseOptions(options);\n filePath = parsedOptions.filePath;\n searchString = parsedOptions.searchString;\n replaceWith = parsedOptions.replaceWith;\n } catch (e) {\n console.error(e);\n console.error(\n \"Usage for replace: ditto-cli replace <file path> <search string> <replace with>\"\n );\n return;\n }\n\n replaceJSXTextInFile(filePath, { searchString, replaceWith }, flags);\n}\n\nfunction parseOptions(options: string[]): {\n filePath: string;\n searchString: string;\n replaceWith: string;\n} {\n if (options.length !== 3) {\n throw new Error(\n \"The options array must contain <file path> <search string> <replace with>.\"\n );\n }\n\n const filePath = options[0];\n // Check if the file path exists and points to a regular file (not a directory or other file system object).\n const isFilePathValid =\n fs.existsSync(filePath) && fs.lstatSync(filePath).isFile();\n\n if (!isFilePathValid) {\n throw new Error(`${filePath} is not a valid file path.`);\n }\n\n return { filePath, searchString: options[1], replaceWith: options[2] };\n}\n\nexport { replace, parseOptions, replaceJSXTextInFile };\n"],"names":["fs","traverse"],"mappings":"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","debug_id":"68dcdcf7-5081-5b09-9769-c28ddf977785"}
1
+ {"version":3,"sources":["../lib/replace.ts"],"sourcesContent":["import fs from \"fs\";\nimport { parse } from \"@babel/parser\";\nimport traverse from \"@babel/traverse\";\nimport * as t from \"@babel/types\";\nimport { transformFromAst } from \"@babel/core\";\n\nasync function replaceJSXTextInFile(\n filePath: string,\n replacement: { searchString: string; replaceWith: string },\n flags: {\n lineNumbers?: number[];\n }\n) {\n const code = await new Promise<string>((resolve, reject) =>\n fs.readFile(filePath, \"utf-8\", (err, data) => {\n if (err) {\n reject(err);\n } else {\n resolve(data);\n }\n })\n );\n const ast = parse(code, {\n sourceType: \"module\",\n plugins: [\"jsx\", \"typescript\"],\n });\n\n traverse(ast, {\n JSXText(path) {\n const { searchString, replaceWith } = replacement;\n\n const searchStringEscaped = searchString.replace(\n /[.*+?^${}()|[\\]\\\\]/g,\n \"\\\\$&\"\n );\n const regex = new RegExp(searchStringEscaped, \"gi\");\n if (regex.test(path.node.value)) {\n // Ignore if not on a line number that we want to replace.\n if (\n flags.lineNumbers &&\n path.node.loc &&\n !flags.lineNumbers.includes(path.node.loc.start.line)\n ) {\n return;\n }\n\n const splitValues = splitByCaseInsensitive(\n path.node.value,\n searchStringEscaped\n );\n const nodes: (t.JSXElement | t.JSXText)[] = [];\n\n splitValues.forEach((splitValue) => {\n if (splitValue.toLowerCase() === searchString.toLowerCase()) {\n const identifier = t.jsxIdentifier(\"DittoComponent\");\n const componentId = t.jsxAttribute(\n t.jsxIdentifier(\"componentId\"),\n t.stringLiteral(replaceWith)\n );\n const o = t.jsxOpeningElement(identifier, [componentId], true);\n const jsxElement = t.jsxElement(o, undefined, [], true);\n nodes.push(jsxElement);\n } else {\n nodes.push(t.jsxText(splitValue));\n }\n });\n\n path.replaceWithMultiple(nodes);\n }\n },\n });\n\n // transfromFromAst types are wrong?\n /* @ts-ignore */\n const { code: transformedCode } = transformFromAst(ast, code, {\n // Don't let this codebase's Babel config affect the code we're transforming.\n /* @ts-ignore */\n configFile: false,\n });\n\n await new Promise((resolve, reject) =>\n fs.writeFile(filePath, transformedCode, (err) => {\n if (err) {\n reject(err);\n } else {\n resolve(null);\n }\n })\n );\n}\n\nfunction splitByCaseInsensitive(str: string, delimiter: string) {\n return str.split(new RegExp(`(${delimiter})`, \"gi\")).filter((s) => s !== \"\");\n}\n\nfunction replace(options: string[], flags: { lineNumbers?: number[] }) {\n let filePath: string;\n let searchString: string;\n let replaceWith: string;\n\n try {\n const parsedOptions = parseOptions(options);\n filePath = parsedOptions.filePath;\n searchString = parsedOptions.searchString;\n replaceWith = parsedOptions.replaceWith;\n } catch (e) {\n console.error(e);\n console.error(\n \"Usage for replace: ditto-cli replace <file path> <search string> <replace with>\"\n );\n return;\n }\n\n replaceJSXTextInFile(filePath, { searchString, replaceWith }, flags);\n}\n\nfunction parseOptions(options: string[]): {\n filePath: string;\n searchString: string;\n replaceWith: string;\n} {\n if (options.length !== 3) {\n throw new Error(\n \"The options array must contain <file path> <search string> <replace with>.\"\n );\n }\n\n const filePath = options[0];\n // Check if the file path exists and points to a regular file (not a directory or other file system object).\n const isFilePathValid =\n fs.existsSync(filePath) && fs.lstatSync(filePath).isFile();\n\n if (!isFilePathValid) {\n throw new Error(`${filePath} is not a valid file path.`);\n }\n\n return { filePath, searchString: options[1], replaceWith: options[2] };\n}\n\nexport { replace, parseOptions, replaceJSXTextInFile };\n"],"names":["fs","traverse"],"mappings":"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","debug_id":"76d5bf23-fec4-53e2-9669-a83a306dc53e"}
@@ -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]="88bc0e18-7209-5d12-95f3-62e752160eb4")}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]="8d2eb72b-d2d6-5847-b480-cd39f4da1f7e")}catch(e){}}();
3
3
 
4
4
  var __create = Object.create;
5
5
  var __defProp = Object.defineProperty;
@@ -43,18 +43,31 @@ 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_replace = require("./replace");
48
+ jest.mock("fs");
48
49
  function createTempJSXFile(content) {
49
50
  return __async(this, null, function* () {
50
- const tempFile = "tempFile.jsx";
51
- yield import_promises.default.writeFile(tempFile, content);
51
+ const tempFile = "/tempFile.jsx";
52
+ yield new Promise((resolve, reject) => {
53
+ try {
54
+ import_fs.default.writeFile(tempFile, content, resolve);
55
+ } catch (e) {
56
+ reject(e);
57
+ }
58
+ });
52
59
  return tempFile;
53
60
  });
54
61
  }
55
62
  function deleteTempFile(filePath) {
56
63
  return __async(this, null, function* () {
57
- yield import_promises.default.unlink(filePath);
64
+ yield new Promise((resolve, reject) => {
65
+ try {
66
+ import_fs.default.unlink(filePath, resolve);
67
+ } catch (e) {
68
+ reject(e);
69
+ }
70
+ });
58
71
  });
59
72
  }
60
73
  describe("parseOptions", () => {
@@ -97,14 +110,22 @@ describe("parseOptions", () => {
97
110
  });
98
111
  describe("replaceJSXTextInFile", () => {
99
112
  afterEach(() => __async(exports, null, function* () {
100
- yield deleteTempFile("tempFile.jsx");
113
+ yield deleteTempFile("/tempFile.jsx");
101
114
  }));
102
115
  test("should replace JSX text with a DittoComponent", () => __async(exports, null, function* () {
103
116
  const tempFile = yield createTempJSXFile("<div>Hello, world</div>");
104
117
  const searchString = "world";
105
118
  const replaceWith = "some-id";
106
119
  yield (0, import_replace.replaceJSXTextInFile)(tempFile, { searchString, replaceWith }, {});
107
- const transformedCode = yield import_promises.default.readFile(tempFile, "utf-8");
120
+ const transformedCode = yield new Promise((resolve, reject) => {
121
+ import_fs.default.readFile(tempFile, "utf-8", (error, data) => {
122
+ if (error) {
123
+ reject(error);
124
+ } else {
125
+ resolve(data);
126
+ }
127
+ });
128
+ });
108
129
  expect(transformedCode).toContain(
109
130
  `<div>Hello, <DittoComponent componentId="${replaceWith}" /></div>`
110
131
  );
@@ -123,7 +144,14 @@ describe("replaceJSXTextInFile", () => {
123
144
  { searchString, replaceWith },
124
145
  { lineNumbers: [3] }
125
146
  );
126
- const transformedCode = yield import_promises.default.readFile(tempFile, "utf-8");
147
+ const transformedCode = yield new Promise(
148
+ (resolve, reject) => import_fs.default.readFile(tempFile, "utf-8", (error, data) => {
149
+ if (error)
150
+ reject(error);
151
+ else
152
+ resolve(data);
153
+ })
154
+ );
127
155
  expect(transformedCode).toContain(
128
156
  `<>
129
157
  <div>Hello, world</div>
@@ -136,7 +164,14 @@ describe("replaceJSXTextInFile", () => {
136
164
  const searchString = "world";
137
165
  const replaceWith = "some-id";
138
166
  yield (0, import_replace.replaceJSXTextInFile)(tempFile, { searchString, replaceWith }, {});
139
- const transformedCode = yield import_promises.default.readFile(tempFile, "utf-8");
167
+ const transformedCode = yield new Promise(
168
+ (resolve, reject) => import_fs.default.readFile(tempFile, "utf-8", (error, data) => {
169
+ if (error)
170
+ reject(error);
171
+ else
172
+ resolve(data);
173
+ })
174
+ );
140
175
  expect(transformedCode).toContain(
141
176
  `<div>HeLLo, <DittoComponent componentId="${replaceWith}" /></div>`
142
177
  );
@@ -146,10 +181,17 @@ describe("replaceJSXTextInFile", () => {
146
181
  const searchString = "foobar";
147
182
  const replaceWith = "some-id";
148
183
  yield (0, import_replace.replaceJSXTextInFile)(tempFile, { searchString, replaceWith }, {});
149
- const transformedCode = yield import_promises.default.readFile(tempFile, "utf-8");
184
+ const transformedCode = yield new Promise(
185
+ (resolve, reject) => import_fs.default.readFile(tempFile, "utf-8", (error, data) => {
186
+ if (error)
187
+ reject(error);
188
+ else
189
+ resolve(data);
190
+ })
191
+ );
150
192
  expect(transformedCode).toContain("<div>Hello, world!</div>");
151
193
  }));
152
194
  });
153
195
  //# sourceMappingURL=replace.test.js.map
154
196
 
155
- //# debugId=88bc0e18-7209-5d12-95f3-62e752160eb4
197
+ //# debugId=8d2eb72b-d2d6-5847-b480-cd39f4da1f7e