@dittowords/cli 4.5.1 → 5.0.0-beta.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 (171) hide show
  1. package/README.md +6 -5
  2. package/bin/ditto.js +110 -285
  3. package/package.json +16 -10
  4. package/.github/actions/install-node-dependencies/action.yml +0 -24
  5. package/.github/workflows/required-checks.yml +0 -24
  6. package/.husky/pre-commit +0 -4
  7. package/.prettierignore +0 -0
  8. package/.prettierrc.json +0 -1
  9. package/__mocks__/fs.js +0 -2
  10. package/babel.config.js +0 -6
  11. package/bin/__mocks__/api.js +0 -48
  12. package/bin/__mocks__/api.js.map +0 -1
  13. package/bin/add-project.js +0 -104
  14. package/bin/add-project.js.map +0 -1
  15. package/bin/api.js +0 -53
  16. package/bin/api.js.map +0 -1
  17. package/bin/component-folders.js +0 -59
  18. package/bin/component-folders.js.map +0 -1
  19. package/bin/config.js +0 -242
  20. package/bin/config.js.map +0 -1
  21. package/bin/config.test.js +0 -93
  22. package/bin/config.test.js.map +0 -1
  23. package/bin/consts.js +0 -57
  24. package/bin/consts.js.map +0 -1
  25. package/bin/ditto.js.map +0 -1
  26. package/bin/generate-suggestions.js +0 -183
  27. package/bin/generate-suggestions.js.map +0 -1
  28. package/bin/generate-suggestions.test.js +0 -200
  29. package/bin/generate-suggestions.test.js.map +0 -1
  30. package/bin/http/__mocks__/fetchComponentFolders.js +0 -71
  31. package/bin/http/__mocks__/fetchComponentFolders.js.map +0 -1
  32. package/bin/http/__mocks__/fetchComponents.js +0 -73
  33. package/bin/http/__mocks__/fetchComponents.js.map +0 -1
  34. package/bin/http/__mocks__/fetchVariants.js +0 -71
  35. package/bin/http/__mocks__/fetchVariants.js.map +0 -1
  36. package/bin/http/fetchComponentFolders.js +0 -64
  37. package/bin/http/fetchComponentFolders.js.map +0 -1
  38. package/bin/http/fetchComponents.js +0 -78
  39. package/bin/http/fetchComponents.js.map +0 -1
  40. package/bin/http/fetchVariants.js +0 -87
  41. package/bin/http/fetchVariants.js.map +0 -1
  42. package/bin/http/http.test.js +0 -159
  43. package/bin/http/http.test.js.map +0 -1
  44. package/bin/http/importComponents.js +0 -114
  45. package/bin/http/importComponents.js.map +0 -1
  46. package/bin/importComponents.js +0 -65
  47. package/bin/importComponents.js.map +0 -1
  48. package/bin/init/init.js +0 -126
  49. package/bin/init/init.js.map +0 -1
  50. package/bin/init/project.js +0 -182
  51. package/bin/init/project.js.map +0 -1
  52. package/bin/init/project.test.js +0 -26
  53. package/bin/init/project.test.js.map +0 -1
  54. package/bin/init/token.js +0 -196
  55. package/bin/init/token.js.map +0 -1
  56. package/bin/init/token.test.js +0 -147
  57. package/bin/init/token.test.js.map +0 -1
  58. package/bin/output.js +0 -76
  59. package/bin/output.js.map +0 -1
  60. package/bin/pull-lib.test.js +0 -379
  61. package/bin/pull-lib.test.js.map +0 -1
  62. package/bin/pull.js +0 -562
  63. package/bin/pull.js.map +0 -1
  64. package/bin/pull.test.js +0 -151
  65. package/bin/pull.test.js.map +0 -1
  66. package/bin/remove-project.js +0 -99
  67. package/bin/remove-project.js.map +0 -1
  68. package/bin/replace.js +0 -171
  69. package/bin/replace.js.map +0 -1
  70. package/bin/replace.test.js +0 -197
  71. package/bin/replace.test.js.map +0 -1
  72. package/bin/types.js +0 -21
  73. package/bin/types.js.map +0 -1
  74. package/bin/utils/cleanFileName.js +0 -40
  75. package/bin/utils/cleanFileName.js.map +0 -1
  76. package/bin/utils/cleanFileName.test.js +0 -15
  77. package/bin/utils/cleanFileName.test.js.map +0 -1
  78. package/bin/utils/createSentryContext.js +0 -43
  79. package/bin/utils/createSentryContext.js.map +0 -1
  80. package/bin/utils/determineModuleType.js +0 -79
  81. package/bin/utils/determineModuleType.js.map +0 -1
  82. package/bin/utils/determineModuleType.test.js +0 -60
  83. package/bin/utils/determineModuleType.test.js.map +0 -1
  84. package/bin/utils/generateIOSBundles.js +0 -147
  85. package/bin/utils/generateIOSBundles.js.map +0 -1
  86. package/bin/utils/generateJsDriver.js +0 -178
  87. package/bin/utils/generateJsDriver.js.map +0 -1
  88. package/bin/utils/generateJsDriverTypeFile.js +0 -105
  89. package/bin/utils/generateJsDriverTypeFile.js.map +0 -1
  90. package/bin/utils/generateSwiftDriver.js +0 -93
  91. package/bin/utils/generateSwiftDriver.js.map +0 -1
  92. package/bin/utils/getSelectedProjects.js +0 -67
  93. package/bin/utils/getSelectedProjects.js.map +0 -1
  94. package/bin/utils/processMetaOption.js +0 -40
  95. package/bin/utils/processMetaOption.js.map +0 -1
  96. package/bin/utils/processMetaOption.test.js +0 -45
  97. package/bin/utils/processMetaOption.test.js.map +0 -1
  98. package/bin/utils/projectsToText.js +0 -58
  99. package/bin/utils/projectsToText.js.map +0 -1
  100. package/bin/utils/promptForProject.js +0 -96
  101. package/bin/utils/promptForProject.js.map +0 -1
  102. package/bin/utils/quit.js +0 -73
  103. package/bin/utils/quit.js.map +0 -1
  104. package/bin/utils/sourcesToText.js +0 -57
  105. package/bin/utils/sourcesToText.js.map +0 -1
  106. package/etsc.config.js +0 -13
  107. package/jest.config.ts +0 -16
  108. package/jsconfig.json +0 -5
  109. package/lib/__mocks__/api.ts +0 -12
  110. package/lib/add-project.ts +0 -48
  111. package/lib/api.ts +0 -15
  112. package/lib/component-folders.ts +0 -9
  113. package/lib/config.test.ts +0 -79
  114. package/lib/config.ts +0 -279
  115. package/lib/consts.ts +0 -22
  116. package/lib/ditto.ts +0 -285
  117. package/lib/generate-suggestions.test.ts +0 -169
  118. package/lib/generate-suggestions.ts +0 -166
  119. package/lib/http/__mocks__/fetchComponentFolders.ts +0 -23
  120. package/lib/http/__mocks__/fetchComponents.ts +0 -24
  121. package/lib/http/__mocks__/fetchVariants.ts +0 -21
  122. package/lib/http/fetchComponentFolders.ts +0 -23
  123. package/lib/http/fetchComponents.ts +0 -43
  124. package/lib/http/fetchVariants.ts +0 -42
  125. package/lib/http/http.test.ts +0 -122
  126. package/lib/http/importComponents.ts +0 -79
  127. package/lib/importComponents.ts +0 -24
  128. package/lib/init/init.ts +0 -79
  129. package/lib/init/project.test.ts +0 -26
  130. package/lib/init/project.ts +0 -136
  131. package/lib/init/token.test.ts +0 -99
  132. package/lib/init/token.ts +0 -156
  133. package/lib/output.ts +0 -21
  134. package/lib/pull-lib.test.ts +0 -367
  135. package/lib/pull.test.ts +0 -117
  136. package/lib/pull.ts +0 -629
  137. package/lib/remove-project.ts +0 -44
  138. package/lib/replace.test.ts +0 -157
  139. package/lib/replace.ts +0 -140
  140. package/lib/types.ts +0 -83
  141. package/lib/utils/cleanFileName.test.ts +0 -11
  142. package/lib/utils/cleanFileName.ts +0 -8
  143. package/lib/utils/createSentryContext.ts +0 -20
  144. package/lib/utils/determineModuleType.test.ts +0 -48
  145. package/lib/utils/determineModuleType.ts +0 -55
  146. package/lib/utils/generateIOSBundles.ts +0 -122
  147. package/lib/utils/generateJsDriver.ts +0 -207
  148. package/lib/utils/generateJsDriverTypeFile.ts +0 -75
  149. package/lib/utils/generateSwiftDriver.ts +0 -48
  150. package/lib/utils/getSelectedProjects.ts +0 -36
  151. package/lib/utils/processMetaOption.test.ts +0 -18
  152. package/lib/utils/processMetaOption.ts +0 -16
  153. package/lib/utils/projectsToText.ts +0 -29
  154. package/lib/utils/promptForProject.ts +0 -61
  155. package/lib/utils/quit.ts +0 -7
  156. package/lib/utils/sourcesToText.ts +0 -25
  157. package/pull_request_template.md +0 -20
  158. package/testfiles/en.json +0 -5
  159. package/testfiles/es.json +0 -5
  160. package/testfiles/fr.json +0 -5
  161. package/testfiles/test1.jsx +0 -18
  162. package/testfiles/test2.jsx +0 -9
  163. package/testing/.gitkeep +0 -0
  164. package/testing/fixtures/bad-yaml.yml +0 -6
  165. package/testing/fixtures/ditto-config-no-token +0 -2
  166. package/testing/fixtures/project-config-empty-projects.yml +0 -1
  167. package/testing/fixtures/project-config-no-id.yml +0 -2
  168. package/testing/fixtures/project-config-no-name.yml +0 -2
  169. package/testing/fixtures/project-config-pull.yml +0 -0
  170. package/testing/fixtures/project-config-working.yml +0 -3
  171. package/tsconfig.json +0 -16
@@ -1,379 +0,0 @@
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]="6ee446a4-669a-5c0e-b694-3351339a2723")}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 __copyProps = (to, from, except, desc) => {
11
- if (from && typeof from === "object" || typeof from === "function") {
12
- for (let key of __getOwnPropNames(from))
13
- if (!__hasOwnProp.call(to, key) && key !== except)
14
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
- }
16
- return to;
17
- };
18
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
19
- // If the importer is in node compatibility mode or this is not an ESM
20
- // file that has been converted to a CommonJS file using a Babel-
21
- // compatible transform (i.e. "__esModule" has not been set), then set
22
- // "default" to the CommonJS "module.exports" for node compatibility.
23
- isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
24
- mod
25
- ));
26
- var __async = (__this, __arguments, generator) => {
27
- return new Promise((resolve, reject) => {
28
- var fulfilled = (value) => {
29
- try {
30
- step(generator.next(value));
31
- } catch (e) {
32
- reject(e);
33
- }
34
- };
35
- var rejected = (value) => {
36
- try {
37
- step(generator.throw(value));
38
- } catch (e) {
39
- reject(e);
40
- }
41
- };
42
- var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
43
- step((generator = generator.apply(__this, __arguments)).next());
44
- });
45
- };
46
- var import_fs = __toESM(require("fs"));
47
- var import_path = __toESM(require("path"));
48
- var import_pull = require("./pull");
49
- var import_globals = require("@jest/globals");
50
- var import_axios = __toESM(require("axios"));
51
- var import_consts = __toESM(require("./consts"));
52
- var import_pull2 = __toESM(require("./pull"));
53
- const axiosMock = import_globals.jest.mocked(import_axios.default);
54
- import_globals.jest.mock("fs");
55
- import_globals.jest.mock("./api");
56
- const testProjects = [
57
- {
58
- id: "1",
59
- name: "Project 1",
60
- fileName: "Project 1"
61
- },
62
- { id: "2", name: "Project 2", fileName: "Project 2" }
63
- ];
64
- import_globals.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, downloadAndSaveBase }
73
- } = import_pull2.default;
74
- const cleanOutputDir = () => {
75
- if (import_fs.default.existsSync(import_consts.default.TEXT_DIR))
76
- import_fs.default.rmSync(import_consts.default.TEXT_DIR, { recursive: true, force: true });
77
- import_fs.default.mkdirSync(import_consts.default.TEXT_DIR);
78
- };
79
- afterAll(() => {
80
- import_fs.default.rmSync(import_consts.default.TEXT_DIR, { force: true, recursive: true });
81
- });
82
- describe("cleanOutputFiles", () => {
83
- it("removes .js, .json, .xml, .strings, .stringsdict files", () => {
84
- cleanOutputDir();
85
- import_fs.default.writeFileSync(import_path.default.resolve(import_consts.default.TEXT_DIR, "test.json"), "test");
86
- import_fs.default.writeFileSync(import_path.default.resolve(import_consts.default.TEXT_DIR, "test.js"), "test");
87
- import_fs.default.writeFileSync(import_path.default.resolve(import_consts.default.TEXT_DIR, "test.xml"), "test");
88
- import_fs.default.writeFileSync(import_path.default.resolve(import_consts.default.TEXT_DIR, "test.strings"), "test");
89
- import_fs.default.writeFileSync(import_path.default.resolve(import_consts.default.TEXT_DIR, "test.stringsdict"), "test");
90
- import_fs.default.writeFileSync(import_path.default.resolve(import_consts.default.TEXT_DIR, "test.txt"), "test");
91
- expect(import_fs.default.readdirSync(import_consts.default.TEXT_DIR).length).toEqual(6);
92
- cleanOutputFiles();
93
- expect(import_fs.default.readdirSync(import_consts.default.TEXT_DIR).length).toEqual(1);
94
- });
95
- });
96
- describe("downloadAndSaveBase", () => {
97
- beforeAll(() => {
98
- if (!import_fs.default.existsSync(import_consts.default.TEXT_DIR)) {
99
- import_fs.default.mkdirSync(import_consts.default.TEXT_DIR);
100
- }
101
- });
102
- beforeEach(() => {
103
- cleanOutputDir();
104
- });
105
- const mockDataFlat = { hello: "world" };
106
- const mockDataNested = { hello: { text: "world" } };
107
- const mockDataStructured = { hello: { text: "world" } };
108
- const mockDataIcu = { hello: "world" };
109
- const mockDataAndroid = `
110
- <?xml version="1.0" encoding="utf-8"?>
111
- <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
112
- <string name="hello-world" ditto_api_id="hello-world">Hello World</string>
113
- </resources>
114
- `;
115
- const mockDataIosStrings = `
116
- "hello" = "world";
117
- `;
118
- const mockDataIosStringsDict = `
119
- <?xml version="1.0" encoding="utf-8"?>
120
- <plist version="1.0">
121
- <dict>
122
- <key>hello-world</key>
123
- <dict>
124
- <key>NSStringLocalizedFormatKey</key>
125
- <string>%1$#@count@</string>
126
- <key>count</key>
127
- <dict>
128
- <key>NSStringFormatSpecTypeKey</key>
129
- <string>NSStringPluralRuleType</string>
130
- <key>NSStringFormatValueTypeKey</key>
131
- <string>d</string>
132
- <key>other</key>
133
- <string>espanol</string>
134
- </dict>
135
- </dict>
136
- </dict>
137
- </plist>
138
- `;
139
- const formats = [
140
- { format: "flat", data: mockDataFlat, ext: ".json" },
141
- { format: "nested", data: mockDataNested, ext: ".json" },
142
- { format: "structured", data: mockDataStructured, ext: ".json" },
143
- { format: "icu", data: mockDataIcu, ext: ".json" },
144
- { format: "android", data: mockDataAndroid, ext: ".xml" },
145
- { format: "ios-strings", data: mockDataIosStrings, ext: ".strings" },
146
- {
147
- format: "ios-stringsdict",
148
- data: mockDataIosStringsDict,
149
- ext: ".stringsdict"
150
- }
151
- ];
152
- const mockApiCall = (data) => {
153
- axiosMock.get.mockResolvedValue({ data });
154
- };
155
- const verifySavedData = (format, data, ext) => __async(exports, null, function* () {
156
- const output = yield downloadAndSaveBase({
157
- projects: testProjects,
158
- format
159
- });
160
- expect(/successfully saved/i.test(output)).toEqual(true);
161
- const directoryContents = import_fs.default.readdirSync(import_consts.default.TEXT_DIR);
162
- expect(directoryContents.length).toEqual(testProjects.length);
163
- expect(directoryContents.every((f) => f.endsWith(ext))).toBe(true);
164
- const fileDataString = import_fs.default.readFileSync(
165
- import_path.default.resolve(import_consts.default.TEXT_DIR, directoryContents[0]),
166
- "utf8"
167
- );
168
- switch (format) {
169
- case "android":
170
- case "ios-strings":
171
- case "ios-stringsdict":
172
- expect(typeof data).toBe("string");
173
- expect(fileDataString.replace(/\s/g, "")).toEqual(
174
- data.replace(/\s/g, "")
175
- );
176
- break;
177
- case "flat":
178
- case "nested":
179
- case "structured":
180
- case "icu":
181
- default:
182
- expect(JSON.parse(fileDataString)).toEqual(data);
183
- break;
184
- }
185
- });
186
- formats.forEach(({ format, data, ext }) => {
187
- it(`writes the ${format} format to disk`, () => __async(exports, null, function* () {
188
- mockApiCall(data);
189
- yield verifySavedData(format, data, ext);
190
- }));
191
- });
192
- });
193
- describe("getFormatDataIsValid", () => {
194
- it("handles flat format appropriately", () => {
195
- expect(import_pull2.getFormatDataIsValid.flat("{}")).toBe(false);
196
- expect(import_pull2.getFormatDataIsValid.flat(`{ "hello": "world" }`)).toBe(true);
197
- expect(
198
- import_pull2.getFormatDataIsValid.flat(`{
199
- "__variant-name": "English",
200
- "__variant-description": ""
201
- }`)
202
- ).toBe(false);
203
- expect(
204
- import_pull2.getFormatDataIsValid.flat(`{
205
- "__variant-name": "English",
206
- "__variant-description": "",
207
- "hello": "world"
208
- }`)
209
- ).toBe(true);
210
- });
211
- it("handles structured format appropriately", () => {
212
- expect(import_pull2.getFormatDataIsValid.structured("{}")).toBe(false);
213
- expect(
214
- import_pull2.getFormatDataIsValid.structured(`{ "hello": { "text": "world" } }`)
215
- ).toBe(true);
216
- expect(
217
- import_pull2.getFormatDataIsValid.structured(`{
218
- "__variant-name": "English",
219
- "__variant-description": ""
220
- }`)
221
- ).toBe(false);
222
- expect(
223
- import_pull2.getFormatDataIsValid.structured(`{
224
- "__variant-name": "English",
225
- "__variant-description": "",
226
- "hello": { "text": "world" }
227
- }`)
228
- ).toBe(true);
229
- });
230
- it("handles icu format appropriately", () => {
231
- expect(import_pull2.getFormatDataIsValid.icu("{}")).toBe(false);
232
- expect(import_pull2.getFormatDataIsValid.icu(`{ "hello": "world" }`)).toBe(true);
233
- expect(
234
- import_pull2.getFormatDataIsValid.icu(`{
235
- "__variant-name": "English",
236
- "__variant-description": ""
237
- }`)
238
- ).toBe(false);
239
- expect(
240
- import_pull2.getFormatDataIsValid.icu(`{
241
- "__variant-name": "English",
242
- "__variant-description": "",
243
- "hello": "world"
244
- }`)
245
- ).toBe(true);
246
- });
247
- it("handles android format appropriately", () => {
248
- expect(
249
- import_pull2.getFormatDataIsValid.android(`
250
- <?xml version="1.0" encoding="utf-8"?>
251
- <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"/>
252
- `)
253
- ).toBe(false);
254
- expect(
255
- import_pull2.getFormatDataIsValid.android(`
256
- <?xml version="1.0" encoding="utf-8"?>
257
- <!--Variant Name: English-->
258
- <!--Variant Description: -->
259
- <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"/>
260
- `)
261
- ).toBe(false);
262
- expect(
263
- import_pull2.getFormatDataIsValid.android(`
264
- <?xml version="1.0" encoding="utf-8"?>
265
- <!--Variant Name: English-->
266
- <!--Variant Description: -->
267
- <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
268
- <string name="hello-world" ditto_api_id="hello-world">Hello World</string>
269
- </resources>
270
- `)
271
- ).toBe(true);
272
- });
273
- it("handles ios-strings format appropriately", () => {
274
- expect(import_pull2.getFormatDataIsValid["ios-strings"]("")).toBe(false);
275
- expect(
276
- import_pull2.getFormatDataIsValid["ios-strings"](`
277
- /* Variant Name: English */
278
- /* Variant Description: */
279
- `)
280
- ).toBe(false);
281
- expect(
282
- import_pull2.getFormatDataIsValid["ios-strings"](`
283
- /* Variant Name: English */
284
- /* Variant Description: */
285
- "Hello" = "World";
286
- `)
287
- ).toBe(true);
288
- });
289
- it("handles ios-stringsdict format appropriately", () => {
290
- expect(
291
- import_pull2.getFormatDataIsValid["ios-stringsdict"](`
292
- <?xml version="1.0" encoding="utf-8"?>
293
- <plist version="1.0">
294
- <dict/>
295
- </plist>
296
- `)
297
- ).toBe(false);
298
- expect(
299
- import_pull2.getFormatDataIsValid["ios-stringsdict"](`
300
- <?xml version="1.0" encoding="utf-8"?>
301
- <!--Variant Name: English-->
302
- <!--Variant Description: -->
303
- <plist version="1.0">
304
- <dict/>
305
- </plist>
306
- `)
307
- ).toBe(false);
308
- expect(
309
- import_pull2.getFormatDataIsValid["ios-stringsdict"](`
310
- <?xml version="1.0" encoding="utf-8"?>
311
- <!--Variant Name: English-->
312
- <!--Variant Description: -->
313
- <plist version="1.0">
314
- <dict>
315
- <key>Hello World</key>
316
- <dict>
317
- <key>NSStringLocalizedFormatKey</key>
318
- <string>%1$#@count@</string>
319
- <key>count</key>
320
- <dict>
321
- <key>NSStringFormatSpecTypeKey</key>
322
- <string>NSStringPluralRuleType</string>
323
- <key>NSStringFormatValueTypeKey</key>
324
- <string>d</string>
325
- <key>other</key>
326
- <string>espanol</string>
327
- </dict>
328
- </dict>
329
- </dict>
330
- </plist>
331
- `)
332
- ).toBe(true);
333
- });
334
- });
335
- const { getJsonFormat } = import_pull._test;
336
- describe("getJsonFormat", () => {
337
- it("returns 'flat' if no format specified", () => {
338
- expect(getJsonFormat([])).toBe("flat");
339
- });
340
- it("returns 'flat' if invalid format specified", () => {
341
- expect(getJsonFormat(["invalid-format"])).toBe("flat");
342
- });
343
- it("returns valid specified formats", () => {
344
- expect(getJsonFormat(["structured"])).toBe("structured");
345
- expect(getJsonFormat(["nested"])).toBe("nested");
346
- expect(getJsonFormat(["icu"])).toBe("icu");
347
- expect(getJsonFormat(["flat"])).toBe("flat");
348
- });
349
- it("returns last of formats if multiple specified", () => {
350
- expect(getJsonFormat(["flat", "structured", "icu"])).toBe("icu");
351
- expect(getJsonFormat(["flat", "icu", "structured"])).toBe("structured");
352
- });
353
- });
354
- const { getJsonFormatIsValid } = import_pull._test;
355
- describe("getJsonFormatIsValid", () => {
356
- it("returns true for valid json", () => {
357
- expect(getJsonFormatIsValid(`{ "key": "value" }`)).toBe(true);
358
- expect(getJsonFormatIsValid(`{ "key": { "text": "value" }}`)).toBe(true);
359
- expect(getJsonFormatIsValid(`{ "nested": { "key": "value" }}`)).toBe(true);
360
- });
361
- it("returns false for empty json", () => {
362
- expect(getJsonFormatIsValid(`{}`)).toBe(false);
363
- });
364
- it("returns false for invalid json", () => {
365
- expect(getJsonFormatIsValid(`abcdefg`)).toBe(false);
366
- });
367
- });
368
- const { ensureEndsWithNewLine } = import_pull._test;
369
- describe("ensureEndsWithNewLine", () => {
370
- it("adds a newline to the end of a string if it doesn't already have one", () => {
371
- expect(ensureEndsWithNewLine("hello")).toBe("hello\n");
372
- });
373
- it("doesn't add a newline to the end of a string if it already has one", () => {
374
- expect(ensureEndsWithNewLine("hello\n")).toBe("hello\n");
375
- });
376
- });
377
- //# sourceMappingURL=pull-lib.test.js.map
378
-
379
- //# debugId=6ee446a4-669a-5c0e-b694-3351339a2723
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../lib/pull-lib.test.ts"],"sourcesContent":["import fs from \"fs\";\nimport path from \"path\";\nimport { _test } from \"./pull\";\nimport { jest } from \"@jest/globals\";\nimport axios from \"axios\";\nconst axiosMock = jest.mocked(axios);\n\njest.mock(\"fs\");\njest.mock(\"./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\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, downloadAndSaveBase },\n} = allPull;\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 axiosMock.get.mockResolvedValue({ data });\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\nconst { getJsonFormat } = _test;\ndescribe(\"getJsonFormat\", () => {\n it(\"returns 'flat' if no format specified\", () => {\n expect(getJsonFormat([])).toBe(\"flat\");\n });\n it(\"returns 'flat' if invalid format specified\", () => {\n expect(getJsonFormat([\"invalid-format\"])).toBe(\"flat\");\n });\n it(\"returns valid specified formats\", () => {\n expect(getJsonFormat([\"structured\"])).toBe(\"structured\");\n expect(getJsonFormat([\"nested\"])).toBe(\"nested\");\n expect(getJsonFormat([\"icu\"])).toBe(\"icu\");\n expect(getJsonFormat([\"flat\"])).toBe(\"flat\");\n });\n it(\"returns last of formats if multiple specified\", () => {\n expect(getJsonFormat([\"flat\", \"structured\", \"icu\"])).toBe(\"icu\");\n expect(getJsonFormat([\"flat\", \"icu\", \"structured\"])).toBe(\"structured\");\n });\n});\n\nconst { getJsonFormatIsValid } = _test;\ndescribe(\"getJsonFormatIsValid\", () => {\n it(\"returns true for valid json\", () => {\n expect(getJsonFormatIsValid(`{ \"key\": \"value\" }`)).toBe(true);\n expect(getJsonFormatIsValid(`{ \"key\": { \"text\": \"value\" }}`)).toBe(true);\n expect(getJsonFormatIsValid(`{ \"nested\": { \"key\": \"value\" }}`)).toBe(true);\n });\n it(\"returns false for empty json\", () => {\n expect(getJsonFormatIsValid(`{}`)).toBe(false);\n });\n it(\"returns false for invalid json\", () => {\n expect(getJsonFormatIsValid(`abcdefg`)).toBe(false);\n });\n});\n\nconst { ensureEndsWithNewLine } = _test;\ndescribe(\"ensureEndsWithNewLine\", () => {\n it(\"adds a newline to the end of a string if it doesn't already have one\", () => {\n expect(ensureEndsWithNewLine(\"hello\")).toBe(\"hello\\n\");\n });\n it(\"doesn't add a newline to the end of a string if it already has one\", () => {\n expect(ensureEndsWithNewLine(\"hello\\n\")).toBe(\"hello\\n\");\n });\n});\n"],"names":["import_pull","axios","allPull","fs","consts","path"],"mappings":"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","debug_id":"6ee446a4-669a-5c0e-b694-3351339a2723"}