@intlayer/cli 5.5.9 → 5.5.11

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 (190) hide show
  1. package/README.md +42 -9
  2. package/dist/cjs/cli.cjs +78 -6
  3. package/dist/cjs/cli.cjs.map +1 -1
  4. package/dist/cjs/cli.test.cjs +435 -0
  5. package/dist/cjs/cli.test.cjs.map +1 -0
  6. package/dist/cjs/fill.cjs +8 -12
  7. package/dist/cjs/fill.cjs.map +1 -1
  8. package/dist/cjs/index.cjs +5 -1
  9. package/dist/cjs/index.cjs.map +1 -1
  10. package/dist/cjs/prompts/REVIEW_PROMPT.md +37 -0
  11. package/dist/cjs/prompts/TRANSLATE_PROMPT.md +38 -0
  12. package/dist/cjs/pull.cjs +10 -2
  13. package/dist/cjs/pull.cjs.map +1 -1
  14. package/dist/cjs/pushConfig.cjs +5 -1
  15. package/dist/cjs/pushConfig.cjs.map +1 -1
  16. package/dist/cjs/reviewDoc.cjs +203 -0
  17. package/dist/cjs/reviewDoc.cjs.map +1 -0
  18. package/dist/cjs/translateDoc.cjs +201 -0
  19. package/dist/cjs/translateDoc.cjs.map +1 -0
  20. package/dist/cjs/utils/calculateChunks.cjs +120 -0
  21. package/dist/cjs/utils/calculateChunks.cjs.map +1 -0
  22. package/dist/cjs/utils/calculateChunks.test.cjs +104 -0
  23. package/dist/cjs/utils/calculateChunks.test.cjs.map +1 -0
  24. package/dist/cjs/utils/calculrateChunkTest.md +9 -0
  25. package/dist/cjs/utils/checkAIAccess.cjs +40 -0
  26. package/dist/cjs/utils/checkAIAccess.cjs.map +1 -0
  27. package/dist/cjs/utils/checkFileModifiedRange.cjs +97 -0
  28. package/dist/cjs/utils/checkFileModifiedRange.cjs.map +1 -0
  29. package/dist/cjs/utils/checkFileModifiedRange.test.cjs +175 -0
  30. package/dist/cjs/utils/checkFileModifiedRange.test.cjs.map +1 -0
  31. package/dist/cjs/utils/checkLastUpdateTime.cjs +33 -0
  32. package/dist/cjs/utils/checkLastUpdateTime.cjs.map +1 -0
  33. package/dist/cjs/utils/chunkInference.cjs +58 -0
  34. package/dist/cjs/utils/chunkInference.cjs.map +1 -0
  35. package/dist/cjs/utils/fixChunkStartEndChars.cjs +47 -0
  36. package/dist/cjs/utils/fixChunkStartEndChars.cjs.map +1 -0
  37. package/dist/cjs/utils/fixChunkStartEndChars.test.cjs +81 -0
  38. package/dist/cjs/utils/fixChunkStartEndChars.test.cjs.map +1 -0
  39. package/dist/cjs/utils/formatTimeDiff.cjs +46 -0
  40. package/dist/cjs/utils/formatTimeDiff.cjs.map +1 -0
  41. package/dist/cjs/utils/formatTimeDiff.test.cjs +32 -0
  42. package/dist/cjs/utils/formatTimeDiff.test.cjs.map +1 -0
  43. package/dist/cjs/utils/getChunk.cjs +77 -0
  44. package/dist/cjs/utils/getChunk.cjs.map +1 -0
  45. package/dist/cjs/utils/getChunk.test.cjs +46 -0
  46. package/dist/cjs/utils/getChunk.test.cjs.map +1 -0
  47. package/dist/cjs/utils/getIsFileUpdatedRecently.cjs +36 -0
  48. package/dist/cjs/utils/getIsFileUpdatedRecently.cjs.map +1 -0
  49. package/dist/cjs/utils/getOutputFilePath.cjs +89 -0
  50. package/dist/cjs/utils/getOutputFilePath.cjs.map +1 -0
  51. package/dist/cjs/utils/getOutputFilePath.test.cjs +73 -0
  52. package/dist/cjs/utils/getOutputFilePath.test.cjs.map +1 -0
  53. package/dist/cjs/utils/getParentPackageJSON.cjs +47 -0
  54. package/dist/cjs/utils/getParentPackageJSON.cjs.map +1 -0
  55. package/dist/cjs/utils/listSpecialChars.cjs +78 -0
  56. package/dist/cjs/utils/listSpecialChars.cjs.map +1 -0
  57. package/dist/cjs/utils/listSpecialChars.test.cjs +58 -0
  58. package/dist/cjs/utils/listSpecialChars.test.cjs.map +1 -0
  59. package/dist/cjs/utils/reorderParagraphs.cjs +125 -0
  60. package/dist/cjs/utils/reorderParagraphs.cjs.map +1 -0
  61. package/dist/cjs/utils/reorderParagraphs.test.cjs +71 -0
  62. package/dist/cjs/utils/reorderParagraphs.test.cjs.map +1 -0
  63. package/dist/cjs/utils/splitTextByLine.cjs +35 -0
  64. package/dist/cjs/utils/splitTextByLine.cjs.map +1 -0
  65. package/dist/cjs/utils/splitTextByLine.test.cjs +14 -0
  66. package/dist/cjs/utils/splitTextByLine.test.cjs.map +1 -0
  67. package/dist/esm/cli.mjs +79 -7
  68. package/dist/esm/cli.mjs.map +1 -1
  69. package/dist/esm/cli.test.mjs +412 -0
  70. package/dist/esm/cli.test.mjs.map +1 -0
  71. package/dist/esm/fill.mjs +8 -12
  72. package/dist/esm/fill.mjs.map +1 -1
  73. package/dist/esm/index.mjs +2 -0
  74. package/dist/esm/index.mjs.map +1 -1
  75. package/dist/esm/prompts/REVIEW_PROMPT.md +37 -0
  76. package/dist/esm/prompts/TRANSLATE_PROMPT.md +38 -0
  77. package/dist/esm/pull.mjs +10 -2
  78. package/dist/esm/pull.mjs.map +1 -1
  79. package/dist/esm/pushConfig.mjs +5 -1
  80. package/dist/esm/pushConfig.mjs.map +1 -1
  81. package/dist/esm/reviewDoc.mjs +172 -0
  82. package/dist/esm/reviewDoc.mjs.map +1 -0
  83. package/dist/esm/translateDoc.mjs +170 -0
  84. package/dist/esm/translateDoc.mjs.map +1 -0
  85. package/dist/esm/utils/calculateChunks.mjs +96 -0
  86. package/dist/esm/utils/calculateChunks.mjs.map +1 -0
  87. package/dist/esm/utils/calculateChunks.test.mjs +103 -0
  88. package/dist/esm/utils/calculateChunks.test.mjs.map +1 -0
  89. package/dist/esm/utils/calculrateChunkTest.md +9 -0
  90. package/dist/esm/utils/checkAIAccess.mjs +16 -0
  91. package/dist/esm/utils/checkAIAccess.mjs.map +1 -0
  92. package/dist/esm/utils/checkFileModifiedRange.mjs +73 -0
  93. package/dist/esm/utils/checkFileModifiedRange.mjs.map +1 -0
  94. package/dist/esm/utils/checkFileModifiedRange.test.mjs +181 -0
  95. package/dist/esm/utils/checkFileModifiedRange.test.mjs.map +1 -0
  96. package/dist/esm/utils/checkLastUpdateTime.mjs +9 -0
  97. package/dist/esm/utils/checkLastUpdateTime.mjs.map +1 -0
  98. package/dist/esm/utils/chunkInference.mjs +34 -0
  99. package/dist/esm/utils/chunkInference.mjs.map +1 -0
  100. package/dist/esm/utils/fixChunkStartEndChars.mjs +23 -0
  101. package/dist/esm/utils/fixChunkStartEndChars.mjs.map +1 -0
  102. package/dist/esm/utils/fixChunkStartEndChars.test.mjs +80 -0
  103. package/dist/esm/utils/fixChunkStartEndChars.test.mjs.map +1 -0
  104. package/dist/esm/utils/formatTimeDiff.mjs +22 -0
  105. package/dist/esm/utils/formatTimeDiff.mjs.map +1 -0
  106. package/dist/esm/utils/formatTimeDiff.test.mjs +31 -0
  107. package/dist/esm/utils/formatTimeDiff.test.mjs.map +1 -0
  108. package/dist/esm/utils/getChunk.mjs +53 -0
  109. package/dist/esm/utils/getChunk.mjs.map +1 -0
  110. package/dist/esm/utils/getChunk.test.mjs +45 -0
  111. package/dist/esm/utils/getChunk.test.mjs.map +1 -0
  112. package/dist/esm/utils/getIsFileUpdatedRecently.mjs +12 -0
  113. package/dist/esm/utils/getIsFileUpdatedRecently.mjs.map +1 -0
  114. package/dist/esm/utils/getOutputFilePath.mjs +65 -0
  115. package/dist/esm/utils/getOutputFilePath.mjs.map +1 -0
  116. package/dist/esm/utils/getOutputFilePath.test.mjs +72 -0
  117. package/dist/esm/utils/getOutputFilePath.test.mjs.map +1 -0
  118. package/dist/esm/utils/getParentPackageJSON.mjs +23 -0
  119. package/dist/esm/utils/getParentPackageJSON.mjs.map +1 -0
  120. package/dist/esm/utils/listSpecialChars.mjs +54 -0
  121. package/dist/esm/utils/listSpecialChars.mjs.map +1 -0
  122. package/dist/esm/utils/listSpecialChars.test.mjs +57 -0
  123. package/dist/esm/utils/listSpecialChars.test.mjs.map +1 -0
  124. package/dist/esm/utils/reorderParagraphs.mjs +101 -0
  125. package/dist/esm/utils/reorderParagraphs.mjs.map +1 -0
  126. package/dist/esm/utils/reorderParagraphs.test.mjs +70 -0
  127. package/dist/esm/utils/reorderParagraphs.test.mjs.map +1 -0
  128. package/dist/esm/utils/splitTextByLine.mjs +11 -0
  129. package/dist/esm/utils/splitTextByLine.mjs.map +1 -0
  130. package/dist/esm/utils/splitTextByLine.test.mjs +13 -0
  131. package/dist/esm/utils/splitTextByLine.test.mjs.map +1 -0
  132. package/dist/types/cli.d.ts.map +1 -1
  133. package/dist/types/cli.test.d.ts +2 -0
  134. package/dist/types/cli.test.d.ts.map +1 -0
  135. package/dist/types/fill.d.ts.map +1 -1
  136. package/dist/types/index.d.ts +2 -0
  137. package/dist/types/index.d.ts.map +1 -1
  138. package/dist/types/pull.d.ts.map +1 -1
  139. package/dist/types/pushConfig.d.ts.map +1 -1
  140. package/dist/types/reviewDoc.d.ts +25 -0
  141. package/dist/types/reviewDoc.d.ts.map +1 -0
  142. package/dist/types/translateDoc.d.ts +25 -0
  143. package/dist/types/translateDoc.d.ts.map +1 -0
  144. package/dist/types/utils/calculateChunks.d.ts +9 -0
  145. package/dist/types/utils/calculateChunks.d.ts.map +1 -0
  146. package/dist/types/utils/calculateChunks.test.d.ts +2 -0
  147. package/dist/types/utils/calculateChunks.test.d.ts.map +1 -0
  148. package/dist/types/utils/checkAIAccess.d.ts +4 -0
  149. package/dist/types/utils/checkAIAccess.d.ts.map +1 -0
  150. package/dist/types/utils/checkFileModifiedRange.d.ts +11 -0
  151. package/dist/types/utils/checkFileModifiedRange.d.ts.map +1 -0
  152. package/dist/types/utils/checkFileModifiedRange.test.d.ts +2 -0
  153. package/dist/types/utils/checkFileModifiedRange.test.d.ts.map +1 -0
  154. package/dist/types/utils/checkLastUpdateTime.d.ts +9 -0
  155. package/dist/types/utils/checkLastUpdateTime.d.ts.map +1 -0
  156. package/dist/types/utils/chunkInference.d.ts +12 -0
  157. package/dist/types/utils/chunkInference.d.ts.map +1 -0
  158. package/dist/types/utils/fixChunkStartEndChars.d.ts +2 -0
  159. package/dist/types/utils/fixChunkStartEndChars.d.ts.map +1 -0
  160. package/dist/types/utils/fixChunkStartEndChars.test.d.ts +2 -0
  161. package/dist/types/utils/fixChunkStartEndChars.test.d.ts.map +1 -0
  162. package/dist/types/utils/formatTimeDiff.d.ts +2 -0
  163. package/dist/types/utils/formatTimeDiff.d.ts.map +1 -0
  164. package/dist/types/utils/formatTimeDiff.test.d.ts +2 -0
  165. package/dist/types/utils/formatTimeDiff.test.d.ts.map +1 -0
  166. package/dist/types/utils/getChunk.d.ts +9 -0
  167. package/dist/types/utils/getChunk.d.ts.map +1 -0
  168. package/dist/types/utils/getChunk.test.d.ts +2 -0
  169. package/dist/types/utils/getChunk.test.d.ts.map +1 -0
  170. package/dist/types/utils/getIsFileUpdatedRecently.d.ts +5 -0
  171. package/dist/types/utils/getIsFileUpdatedRecently.d.ts.map +1 -0
  172. package/dist/types/utils/getOutputFilePath.d.ts +26 -0
  173. package/dist/types/utils/getOutputFilePath.d.ts.map +1 -0
  174. package/dist/types/utils/getOutputFilePath.test.d.ts +2 -0
  175. package/dist/types/utils/getOutputFilePath.test.d.ts.map +1 -0
  176. package/dist/types/utils/getParentPackageJSON.d.ts +32 -0
  177. package/dist/types/utils/getParentPackageJSON.d.ts.map +1 -0
  178. package/dist/types/utils/listSpecialChars.d.ts +10 -0
  179. package/dist/types/utils/listSpecialChars.d.ts.map +1 -0
  180. package/dist/types/utils/listSpecialChars.test.d.ts +2 -0
  181. package/dist/types/utils/listSpecialChars.test.d.ts.map +1 -0
  182. package/dist/types/utils/reorderParagraphs.d.ts +8 -0
  183. package/dist/types/utils/reorderParagraphs.d.ts.map +1 -0
  184. package/dist/types/utils/reorderParagraphs.test.d.ts +2 -0
  185. package/dist/types/utils/reorderParagraphs.test.d.ts.map +1 -0
  186. package/dist/types/utils/splitTextByLine.d.ts +2 -0
  187. package/dist/types/utils/splitTextByLine.d.ts.map +1 -0
  188. package/dist/types/utils/splitTextByLine.test.d.ts +2 -0
  189. package/dist/types/utils/splitTextByLine.test.d.ts.map +1 -0
  190. package/package.json +14 -12
@@ -0,0 +1,89 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
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 __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+ var getOutputFilePath_exports = {};
20
+ __export(getOutputFilePath_exports, {
21
+ getOutputFilePath: () => getOutputFilePath
22
+ });
23
+ module.exports = __toCommonJS(getOutputFilePath_exports);
24
+ const getOutputFilePath = (filePath, locale, baseLocale) => {
25
+ if (!filePath || !locale || !baseLocale) {
26
+ throw new Error("filePath, locale, and baseLocale are required");
27
+ }
28
+ let outputFilePath = filePath;
29
+ const replacements = [
30
+ // Template placeholders (processed first)
31
+ {
32
+ pattern: /\{\{baseLocale\}\}/g,
33
+ replacement: "{{locale}}"
34
+ },
35
+ {
36
+ pattern: /\{\{baseLocaleName\}\}/g,
37
+ replacement: "{{localeName}}"
38
+ },
39
+ // Path separators (most specific first)
40
+ {
41
+ // Unix path separators
42
+ pattern: new RegExp(`/${baseLocale}/`, "g"),
43
+ replacement: `/${locale}/`
44
+ },
45
+ {
46
+ // Windows path separators
47
+ pattern: new RegExp(`\\\\${baseLocale}\\\\`, "g"),
48
+ replacement: `\\${locale}\\`
49
+ },
50
+ // File naming patterns
51
+ {
52
+ // file_en.md → file_fr.md
53
+ pattern: new RegExp(`_${baseLocale}\\.`, "g"),
54
+ replacement: `_${locale}.`
55
+ },
56
+ {
57
+ // /file_en.md → /file_fr.md
58
+ pattern: new RegExp(`/${baseLocale}_`, "g"),
59
+ replacement: `/${locale}_`
60
+ },
61
+ {
62
+ // Start of filename pattern en_guide.md → fr_guide.md (or after path separator)
63
+ pattern: new RegExp(`(^|[\\/])${baseLocale}_`, "g"),
64
+ replacement: `$1${locale}_`
65
+ },
66
+ {
67
+ // Dot delimited pattern guide.en.md → guide.fr.md
68
+ pattern: new RegExp(`\\.${baseLocale}\\.`, "g"),
69
+ replacement: `.${locale}.`
70
+ }
71
+ ];
72
+ for (const { pattern, replacement } of replacements) {
73
+ outputFilePath = outputFilePath.replace(pattern, replacement);
74
+ }
75
+ if (outputFilePath === filePath) {
76
+ const lastDotIndex = filePath.lastIndexOf(".");
77
+ if (lastDotIndex > 0) {
78
+ return `${filePath.slice(0, lastDotIndex)}.${locale}${filePath.slice(lastDotIndex)}`;
79
+ } else {
80
+ return `${filePath}.${locale}`;
81
+ }
82
+ }
83
+ return outputFilePath;
84
+ };
85
+ // Annotate the CommonJS export names for ESM import in node:
86
+ 0 && (module.exports = {
87
+ getOutputFilePath
88
+ });
89
+ //# sourceMappingURL=getOutputFilePath.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/utils/getOutputFilePath.ts"],"sourcesContent":["import type { LocalesValues } from '@intlayer/config';\n\n/**\n * Get the output file path by replacing the base locale with the target locale\n *\n * This function handles two types of replacements:\n * 1. Actual locale values (e.g., `/en/` → `/fr/`)\n * 2. Template placeholders (e.g., `{{baseLocale}}` → `{{locale}}`, `{{baseLocaleName}}` → `{{localeName}}`)\n *\n * Replacement patterns:\n * - `/baseLocale/` → `/locale/`\n * - `\\baseLocale\\` → `\\locale\\`\n * - `_baseLocale.` → `_locale.`\n * - `baseLocale_` → `locale_`\n * - `.baseLocaleName.` → `.localeName.`\n * - `{{baseLocale}}` → `{{locale}}`\n * - `{{baseLocaleName}}` → `{{localeName}}`\n *\n * If no patterns match, appends `.locale` to the file extension.\n *\n * @param filePath - The input file path\n * @param locale - The target locale\n * @param baseLocale - The base locale to replace\n * @returns The output file path with locale replacements\n */\nexport const getOutputFilePath = (\n filePath: string,\n locale: LocalesValues,\n baseLocale: LocalesValues\n): string => {\n if (!filePath || !locale || !baseLocale) {\n throw new Error('filePath, locale, and baseLocale are required');\n }\n\n let outputFilePath = filePath;\n\n // Define replacement patterns with global flag to replace all occurrences\n const replacements = [\n // Template placeholders (processed first)\n {\n pattern: /\\{\\{baseLocale\\}\\}/g,\n replacement: '{{locale}}',\n },\n {\n pattern: /\\{\\{baseLocaleName\\}\\}/g,\n replacement: '{{localeName}}',\n },\n\n // Path separators (most specific first)\n {\n // Unix path separators\n pattern: new RegExp(`/${baseLocale}/`, 'g'),\n replacement: `/${locale}/`,\n },\n {\n // Windows path separators\n pattern: new RegExp(`\\\\\\\\${baseLocale}\\\\\\\\`, 'g'),\n replacement: `\\\\${locale}\\\\`,\n },\n\n // File naming patterns\n {\n // file_en.md → file_fr.md\n pattern: new RegExp(`_${baseLocale}\\\\.`, 'g'),\n replacement: `_${locale}.`,\n },\n {\n // /file_en.md → /file_fr.md\n pattern: new RegExp(`/${baseLocale}_`, 'g'),\n replacement: `/${locale}_`,\n },\n {\n // Start of filename pattern en_guide.md → fr_guide.md (or after path separator)\n pattern: new RegExp(`(^|[\\\\/])${baseLocale}_`, 'g'),\n replacement: `$1${locale}_`,\n },\n {\n // Dot delimited pattern guide.en.md → guide.fr.md\n pattern: new RegExp(`\\\\.${baseLocale}\\\\.`, 'g'),\n replacement: `.${locale}.`,\n },\n ];\n\n // Apply all replacements\n for (const { pattern, replacement } of replacements) {\n outputFilePath = outputFilePath.replace(pattern, replacement);\n }\n\n // If no changes were made, append locale as extension\n if (outputFilePath === filePath) {\n const lastDotIndex = filePath.lastIndexOf('.');\n if (lastDotIndex > 0) {\n // Insert locale before the file extension\n return `${filePath.slice(0, lastDotIndex)}.${locale}${filePath.slice(lastDotIndex)}`;\n } else {\n // No extension found, just append\n return `${filePath}.${locale}`;\n }\n }\n\n return outputFilePath;\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAyBO,MAAM,oBAAoB,CAC/B,UACA,QACA,eACW;AACX,MAAI,CAAC,YAAY,CAAC,UAAU,CAAC,YAAY;AACvC,UAAM,IAAI,MAAM,+CAA+C;AAAA,EACjE;AAEA,MAAI,iBAAiB;AAGrB,QAAM,eAAe;AAAA;AAAA,IAEnB;AAAA,MACE,SAAS;AAAA,MACT,aAAa;AAAA,IACf;AAAA,IACA;AAAA,MACE,SAAS;AAAA,MACT,aAAa;AAAA,IACf;AAAA;AAAA,IAGA;AAAA;AAAA,MAEE,SAAS,IAAI,OAAO,IAAI,UAAU,KAAK,GAAG;AAAA,MAC1C,aAAa,IAAI,MAAM;AAAA,IACzB;AAAA,IACA;AAAA;AAAA,MAEE,SAAS,IAAI,OAAO,OAAO,UAAU,QAAQ,GAAG;AAAA,MAChD,aAAa,KAAK,MAAM;AAAA,IAC1B;AAAA;AAAA,IAGA;AAAA;AAAA,MAEE,SAAS,IAAI,OAAO,IAAI,UAAU,OAAO,GAAG;AAAA,MAC5C,aAAa,IAAI,MAAM;AAAA,IACzB;AAAA,IACA;AAAA;AAAA,MAEE,SAAS,IAAI,OAAO,IAAI,UAAU,KAAK,GAAG;AAAA,MAC1C,aAAa,IAAI,MAAM;AAAA,IACzB;AAAA,IACA;AAAA;AAAA,MAEE,SAAS,IAAI,OAAO,YAAY,UAAU,KAAK,GAAG;AAAA,MAClD,aAAa,KAAK,MAAM;AAAA,IAC1B;AAAA,IACA;AAAA;AAAA,MAEE,SAAS,IAAI,OAAO,MAAM,UAAU,OAAO,GAAG;AAAA,MAC9C,aAAa,IAAI,MAAM;AAAA,IACzB;AAAA,EACF;AAGA,aAAW,EAAE,SAAS,YAAY,KAAK,cAAc;AACnD,qBAAiB,eAAe,QAAQ,SAAS,WAAW;AAAA,EAC9D;AAGA,MAAI,mBAAmB,UAAU;AAC/B,UAAM,eAAe,SAAS,YAAY,GAAG;AAC7C,QAAI,eAAe,GAAG;AAEpB,aAAO,GAAG,SAAS,MAAM,GAAG,YAAY,CAAC,IAAI,MAAM,GAAG,SAAS,MAAM,YAAY,CAAC;AAAA,IACpF,OAAO;AAEL,aAAO,GAAG,QAAQ,IAAI,MAAM;AAAA,IAC9B;AAAA,EACF;AAEA,SAAO;AACT;","names":[]}
@@ -0,0 +1,73 @@
1
+ "use strict";
2
+ var import_config = require("@intlayer/config");
3
+ var import_vitest = require("vitest");
4
+ var import_getOutputFilePath = require('./getOutputFilePath.cjs');
5
+ const baseLocale = import_config.Locales.ENGLISH;
6
+ const targetLocale = import_config.Locales.FRENCH;
7
+ (0, import_vitest.describe)("getOutputFilePath", () => {
8
+ (0, import_vitest.it)("should replace locale in directory paths", () => {
9
+ (0, import_vitest.expect)(
10
+ (0, import_getOutputFilePath.getOutputFilePath)("/docs/en/guide.md", targetLocale, baseLocale)
11
+ ).toBe("/docs/fr/guide.md");
12
+ });
13
+ (0, import_vitest.it)("should handle Windows-style paths", () => {
14
+ (0, import_vitest.expect)(
15
+ (0, import_getOutputFilePath.getOutputFilePath)("\\docs\\en\\guide.md", targetLocale, baseLocale)
16
+ ).toBe("\\docs\\fr\\guide.md");
17
+ });
18
+ (0, import_vitest.it)("should replace locale in file naming patterns", () => {
19
+ (0, import_vitest.expect)((0, import_getOutputFilePath.getOutputFilePath)("guide_en.md", targetLocale, baseLocale)).toBe(
20
+ "guide_fr.md"
21
+ );
22
+ (0, import_vitest.expect)((0, import_getOutputFilePath.getOutputFilePath)("en_guide.md", targetLocale, baseLocale)).toBe(
23
+ "fr_guide.md"
24
+ );
25
+ });
26
+ (0, import_vitest.it)("should handle template placeholders", () => {
27
+ (0, import_vitest.expect)(
28
+ (0, import_getOutputFilePath.getOutputFilePath)(
29
+ "/docs/{{baseLocale}}/guide.md",
30
+ targetLocale,
31
+ baseLocale
32
+ )
33
+ ).toBe("/docs/{{locale}}/guide.md");
34
+ (0, import_vitest.expect)(
35
+ (0, import_getOutputFilePath.getOutputFilePath)("guide.{{baseLocaleName}}.md", targetLocale, baseLocale)
36
+ ).toBe("guide.{{localeName}}.md");
37
+ });
38
+ (0, import_vitest.it)("should handle locale name patterns", () => {
39
+ (0, import_vitest.expect)((0, import_getOutputFilePath.getOutputFilePath)("guide.en.md", targetLocale, baseLocale)).toBe(
40
+ "guide.fr.md"
41
+ );
42
+ });
43
+ (0, import_vitest.it)("should append locale when no patterns match", () => {
44
+ (0, import_vitest.expect)((0, import_getOutputFilePath.getOutputFilePath)("/docs/guide.md", targetLocale, baseLocale)).toBe(
45
+ "/docs/guide.fr.md"
46
+ );
47
+ });
48
+ (0, import_vitest.it)("should handle files without extensions", () => {
49
+ (0, import_vitest.expect)((0, import_getOutputFilePath.getOutputFilePath)("/docs/guide", targetLocale, baseLocale)).toBe(
50
+ "/docs/guide.fr"
51
+ );
52
+ });
53
+ (0, import_vitest.it)("should handle multiple occurrences", () => {
54
+ (0, import_vitest.expect)(
55
+ (0, import_getOutputFilePath.getOutputFilePath)("/en/docs/en/guide_en.md", targetLocale, baseLocale)
56
+ ).toBe("/fr/docs/fr/guide_fr.md");
57
+ });
58
+ (0, import_vitest.it)("should not duplicate locale parts for composite target locales", () => {
59
+ const compositeTarget = "en-GB";
60
+ (0, import_vitest.expect)((0, import_getOutputFilePath.getOutputFilePath)("/en/file.md", compositeTarget, baseLocale)).toBe(
61
+ "/en-GB/file.md"
62
+ );
63
+ });
64
+ (0, import_vitest.it)("should throw error for invalid inputs", () => {
65
+ (0, import_vitest.expect)(() => (0, import_getOutputFilePath.getOutputFilePath)("", targetLocale, baseLocale)).toThrow(
66
+ "filePath, locale, and baseLocale are required"
67
+ );
68
+ (0, import_vitest.expect)(
69
+ () => (0, import_getOutputFilePath.getOutputFilePath)("/docs/guide.md", "", baseLocale)
70
+ ).toThrow("filePath, locale, and baseLocale are required");
71
+ });
72
+ });
73
+ //# sourceMappingURL=getOutputFilePath.test.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/utils/getOutputFilePath.test.ts"],"sourcesContent":["import { Locales } from '@intlayer/config';\nimport { describe, expect, it } from 'vitest';\nimport { getOutputFilePath } from './getOutputFilePath';\n\nconst baseLocale = Locales.ENGLISH;\nconst targetLocale = Locales.FRENCH;\n\ndescribe('getOutputFilePath', () => {\n it('should replace locale in directory paths', () => {\n expect(\n getOutputFilePath('/docs/en/guide.md', targetLocale, baseLocale)\n ).toBe('/docs/fr/guide.md');\n });\n\n it('should handle Windows-style paths', () => {\n expect(\n getOutputFilePath('\\\\docs\\\\en\\\\guide.md', targetLocale, baseLocale)\n ).toBe('\\\\docs\\\\fr\\\\guide.md');\n });\n\n it('should replace locale in file naming patterns', () => {\n expect(getOutputFilePath('guide_en.md', targetLocale, baseLocale)).toBe(\n 'guide_fr.md'\n );\n\n expect(getOutputFilePath('en_guide.md', targetLocale, baseLocale)).toBe(\n 'fr_guide.md'\n );\n });\n\n it('should handle template placeholders', () => {\n expect(\n getOutputFilePath(\n '/docs/{{baseLocale}}/guide.md',\n targetLocale,\n baseLocale\n )\n ).toBe('/docs/{{locale}}/guide.md');\n\n expect(\n getOutputFilePath('guide.{{baseLocaleName}}.md', targetLocale, baseLocale)\n ).toBe('guide.{{localeName}}.md');\n });\n\n it('should handle locale name patterns', () => {\n expect(getOutputFilePath('guide.en.md', targetLocale, baseLocale)).toBe(\n 'guide.fr.md'\n );\n });\n\n it('should append locale when no patterns match', () => {\n expect(getOutputFilePath('/docs/guide.md', targetLocale, baseLocale)).toBe(\n '/docs/guide.fr.md'\n );\n });\n\n it('should handle files without extensions', () => {\n expect(getOutputFilePath('/docs/guide', targetLocale, baseLocale)).toBe(\n '/docs/guide.fr'\n );\n });\n\n it('should handle multiple occurrences', () => {\n expect(\n getOutputFilePath('/en/docs/en/guide_en.md', targetLocale, baseLocale)\n ).toBe('/fr/docs/fr/guide_fr.md');\n });\n\n it('should not duplicate locale parts for composite target locales', () => {\n const compositeTarget = 'en-GB' as unknown as Locales;\n expect(getOutputFilePath('/en/file.md', compositeTarget, baseLocale)).toBe(\n '/en-GB/file.md'\n );\n });\n\n it('should throw error for invalid inputs', () => {\n expect(() => getOutputFilePath('', targetLocale, baseLocale)).toThrow(\n 'filePath, locale, and baseLocale are required'\n );\n\n expect(() =>\n getOutputFilePath('/docs/guide.md', '' as Locales, baseLocale)\n ).toThrow('filePath, locale, and baseLocale are required');\n });\n});\n"],"mappings":";AAAA,oBAAwB;AACxB,oBAAqC;AACrC,+BAAkC;AAElC,MAAM,aAAa,sBAAQ;AAC3B,MAAM,eAAe,sBAAQ;AAAA,IAE7B,wBAAS,qBAAqB,MAAM;AAClC,wBAAG,4CAA4C,MAAM;AACnD;AAAA,UACE,4CAAkB,qBAAqB,cAAc,UAAU;AAAA,IACjE,EAAE,KAAK,mBAAmB;AAAA,EAC5B,CAAC;AAED,wBAAG,qCAAqC,MAAM;AAC5C;AAAA,UACE,4CAAkB,wBAAwB,cAAc,UAAU;AAAA,IACpE,EAAE,KAAK,sBAAsB;AAAA,EAC/B,CAAC;AAED,wBAAG,iDAAiD,MAAM;AACxD,kCAAO,4CAAkB,eAAe,cAAc,UAAU,CAAC,EAAE;AAAA,MACjE;AAAA,IACF;AAEA,kCAAO,4CAAkB,eAAe,cAAc,UAAU,CAAC,EAAE;AAAA,MACjE;AAAA,IACF;AAAA,EACF,CAAC;AAED,wBAAG,uCAAuC,MAAM;AAC9C;AAAA,UACE;AAAA,QACE;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF,EAAE,KAAK,2BAA2B;AAElC;AAAA,UACE,4CAAkB,+BAA+B,cAAc,UAAU;AAAA,IAC3E,EAAE,KAAK,yBAAyB;AAAA,EAClC,CAAC;AAED,wBAAG,sCAAsC,MAAM;AAC7C,kCAAO,4CAAkB,eAAe,cAAc,UAAU,CAAC,EAAE;AAAA,MACjE;AAAA,IACF;AAAA,EACF,CAAC;AAED,wBAAG,+CAA+C,MAAM;AACtD,kCAAO,4CAAkB,kBAAkB,cAAc,UAAU,CAAC,EAAE;AAAA,MACpE;AAAA,IACF;AAAA,EACF,CAAC;AAED,wBAAG,0CAA0C,MAAM;AACjD,kCAAO,4CAAkB,eAAe,cAAc,UAAU,CAAC,EAAE;AAAA,MACjE;AAAA,IACF;AAAA,EACF,CAAC;AAED,wBAAG,sCAAsC,MAAM;AAC7C;AAAA,UACE,4CAAkB,2BAA2B,cAAc,UAAU;AAAA,IACvE,EAAE,KAAK,yBAAyB;AAAA,EAClC,CAAC;AAED,wBAAG,kEAAkE,MAAM;AACzE,UAAM,kBAAkB;AACxB,kCAAO,4CAAkB,eAAe,iBAAiB,UAAU,CAAC,EAAE;AAAA,MACpE;AAAA,IACF;AAAA,EACF,CAAC;AAED,wBAAG,yCAAyC,MAAM;AAChD,8BAAO,UAAM,4CAAkB,IAAI,cAAc,UAAU,CAAC,EAAE;AAAA,MAC5D;AAAA,IACF;AAEA;AAAA,MAAO,UACL,4CAAkB,kBAAkB,IAAe,UAAU;AAAA,IAC/D,EAAE,QAAQ,+CAA+C;AAAA,EAC3D,CAAC;AACH,CAAC;","names":[]}
@@ -0,0 +1,47 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
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 __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+ var getParentPackageJSON_exports = {};
20
+ __export(getParentPackageJSON_exports, {
21
+ getParentPackageJSON: () => getParentPackageJSON
22
+ });
23
+ module.exports = __toCommonJS(getParentPackageJSON_exports);
24
+ var import_fs = require("fs");
25
+ var import_path = require("path");
26
+ const getParentPackageJSON = (startDir) => {
27
+ let currentDir = startDir;
28
+ while (currentDir !== (0, import_path.dirname)(currentDir)) {
29
+ const packageJsonPath = (0, import_path.resolve)(currentDir, "package.json");
30
+ if ((0, import_fs.existsSync)(packageJsonPath)) {
31
+ return JSON.parse((0, import_fs.readFileSync)(packageJsonPath, "utf8"));
32
+ }
33
+ currentDir = (0, import_path.dirname)(currentDir);
34
+ }
35
+ const rootPackageJsonPath = (0, import_path.resolve)(currentDir, "package.json");
36
+ if ((0, import_fs.existsSync)(rootPackageJsonPath)) {
37
+ return JSON.parse((0, import_fs.readFileSync)(rootPackageJsonPath, "utf8"));
38
+ }
39
+ throw new Error(
40
+ `No package.json found in any parent directory of ${startDir}`
41
+ );
42
+ };
43
+ // Annotate the CommonJS export names for ESM import in node:
44
+ 0 && (module.exports = {
45
+ getParentPackageJSON
46
+ });
47
+ //# sourceMappingURL=getParentPackageJSON.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/utils/getParentPackageJSON.ts"],"sourcesContent":["import { existsSync, readFileSync } from 'fs';\nimport { dirname, resolve } from 'path';\n\ntype PackageJSON = {\n name?: string;\n version?: string;\n private: boolean;\n description?: string;\n homepage?: string;\n bugs: {\n url?: string;\n };\n repository: {\n type?: string;\n url?: string;\n };\n license?: string;\n author: {\n name?: string;\n url?: string;\n };\n contributors?: {\n name?: string;\n email?: string;\n url?: string;\n }[];\n type?: string;\n scripts: Record<string, string>;\n devDependencies: Record<string, string>;\n packageManager?: string;\n engines: Record<string, string>;\n};\n\nexport const getParentPackageJSON = (startDir: string): PackageJSON => {\n let currentDir = startDir;\n\n while (currentDir !== dirname(currentDir)) {\n // Stop when we reach the root\n const packageJsonPath = resolve(currentDir, 'package.json');\n\n if (existsSync(packageJsonPath)) {\n return JSON.parse(readFileSync(packageJsonPath, 'utf8'));\n }\n\n // Move up one directory level\n currentDir = dirname(currentDir);\n }\n\n // Check the root directory as well\n const rootPackageJsonPath = resolve(currentDir, 'package.json');\n if (existsSync(rootPackageJsonPath)) {\n return JSON.parse(readFileSync(rootPackageJsonPath, 'utf8'));\n }\n\n // If no package.json is found in any parent directory\n throw new Error(\n `No package.json found in any parent directory of ${startDir}`\n );\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,gBAAyC;AACzC,kBAAiC;AAgC1B,MAAM,uBAAuB,CAAC,aAAkC;AACrE,MAAI,aAAa;AAEjB,SAAO,mBAAe,qBAAQ,UAAU,GAAG;AAEzC,UAAM,sBAAkB,qBAAQ,YAAY,cAAc;AAE1D,YAAI,sBAAW,eAAe,GAAG;AAC/B,aAAO,KAAK,UAAM,wBAAa,iBAAiB,MAAM,CAAC;AAAA,IACzD;AAGA,qBAAa,qBAAQ,UAAU;AAAA,EACjC;AAGA,QAAM,0BAAsB,qBAAQ,YAAY,cAAc;AAC9D,UAAI,sBAAW,mBAAmB,GAAG;AACnC,WAAO,KAAK,UAAM,wBAAa,qBAAqB,MAAM,CAAC;AAAA,EAC7D;AAGA,QAAM,IAAI;AAAA,IACR,oDAAoD,QAAQ;AAAA,EAC9D;AACF;","names":[]}
@@ -0,0 +1,78 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
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 __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+ var listSpecialChars_exports = {};
20
+ __export(listSpecialChars_exports, {
21
+ listSpecialChars: () => listSpecialChars
22
+ });
23
+ module.exports = __toCommonJS(listSpecialChars_exports);
24
+ const SPECIAL_CHARS = [
25
+ " ",
26
+ "\\",
27
+ "|",
28
+ "(",
29
+ ")",
30
+ "{",
31
+ "}",
32
+ "[",
33
+ "]",
34
+ "<",
35
+ ">",
36
+ '"',
37
+ "=",
38
+ "+",
39
+ "*",
40
+ "&",
41
+ "#",
42
+ "%",
43
+ "$",
44
+ "!",
45
+ "?",
46
+ ":",
47
+ ";",
48
+ "~"
49
+ ];
50
+ const listSpecialChars = (text) => {
51
+ const results = [];
52
+ let lineIndex = 0;
53
+ for (let i = 0; i < text.length; i++) {
54
+ const currentChar = text[i];
55
+ if (currentChar === "\n") {
56
+ results.push({
57
+ char: "\\",
58
+ lineStart: lineIndex,
59
+ charStart: i
60
+ });
61
+ lineIndex++;
62
+ continue;
63
+ }
64
+ if (SPECIAL_CHARS.includes(currentChar)) {
65
+ results.push({
66
+ char: currentChar,
67
+ lineStart: lineIndex,
68
+ charStart: i
69
+ });
70
+ }
71
+ }
72
+ return results;
73
+ };
74
+ // Annotate the CommonJS export names for ESM import in node:
75
+ 0 && (module.exports = {
76
+ listSpecialChars
77
+ });
78
+ //# sourceMappingURL=listSpecialChars.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/utils/listSpecialChars.ts"],"sourcesContent":["type ListCharResult = {\n char: string;\n /** First line index contained in this chunk (0-based) */\n lineStart: number;\n /** Start character index in the original text (0-based, inclusive)*/\n charStart: number;\n}[];\n\nconst SPECIAL_CHARS = [\n ' ',\n '\\\\',\n '|',\n '(',\n ')',\n '{',\n '}',\n '[',\n ']',\n '<',\n '>',\n '\"',\n '=',\n '+',\n '*',\n '&',\n '#',\n '%',\n '$',\n '!',\n '?',\n ':',\n ';',\n '~',\n];\n\nexport const listSpecialChars = (text: string): ListCharResult => {\n const results: ListCharResult = [];\n\n let lineIndex = 0;\n\n for (let i = 0; i < text.length; i++) {\n const currentChar = text[i];\n\n // Handle newline characters (\"\\n\"): treat them as a \"\\\\\" special char\n if (currentChar === '\\n') {\n results.push({\n char: '\\\\',\n lineStart: lineIndex,\n charStart: i,\n });\n\n // Move to the next line after recording the special char\n lineIndex++;\n continue;\n }\n\n // Check if the current character is one of the special characters\n if (SPECIAL_CHARS.includes(currentChar)) {\n results.push({\n char: currentChar,\n lineStart: lineIndex,\n charStart: i,\n });\n }\n }\n\n return results;\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAQA,MAAM,gBAAgB;AAAA,EACpB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAEO,MAAM,mBAAmB,CAAC,SAAiC;AAChE,QAAM,UAA0B,CAAC;AAEjC,MAAI,YAAY;AAEhB,WAAS,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK;AACpC,UAAM,cAAc,KAAK,CAAC;AAG1B,QAAI,gBAAgB,MAAM;AACxB,cAAQ,KAAK;AAAA,QACX,MAAM;AAAA,QACN,WAAW;AAAA,QACX,WAAW;AAAA,MACb,CAAC;AAGD;AACA;AAAA,IACF;AAGA,QAAI,cAAc,SAAS,WAAW,GAAG;AACvC,cAAQ,KAAK;AAAA,QACX,MAAM;AAAA,QACN,WAAW;AAAA,QACX,WAAW;AAAA,MACb,CAAC;AAAA,IACH;AAAA,EACF;AAEA,SAAO;AACT;","names":[]}
@@ -0,0 +1,58 @@
1
+ "use strict";
2
+ var import_vitest = require("vitest");
3
+ var import_listSpecialChars = require('./listSpecialChars.cjs');
4
+ const test = [
5
+ "Lorem ipsum dolor sit amet consectetur adipiscing elit. (Quisque faucibus ex sapien vitae pellentesque sem placerat). In id cursus mi pretium tellus duis convallis. Tempus leo eu aenean sed diam urna tempor. Pulvinar vivamus fringilla lacus nec metus bibendum egestas. Iaculis massa nisl malesuada lacinia integer nunc posuere. Ut hendrerit semper vel class aptent taciti sociosqu. Ad litora torquent per conubia nostra inceptos himenaeos.",
6
+ "Lorem ipsum dolor sit amet consectetur adipiscing elit! Quisque faucibus ex sapien vitae pellentesque sem placerat. In id cursus mi pretium tellus duis convallis. Tempus leo eu aenean sed diam urna tempor. Pulvinar vivamus fringilla lacus nec metus bibendum egestas. Iaculis massa nisl malesuada lacinia integer nunc posuere. Ut hendrerit semper vel class aptent taciti sociosqu. Ad litora torquent per conubia nostra inceptos himenaeos.",
7
+ "Lorem ipsum dolor sit amet consectetur adipiscing elit. Quisque faucibus ex sapien vitae pellentesque sem placerat. In id cursus mi pretium tellus duis convallis. Tempus leo eu aenean sed diam urna tempor. Pulvinar vivamus fringilla lacus nec metus bibendum egestas. Iaculis massa nisl malesuada lacinia integer nunc posuere. Ut hendrerit semper vel class aptent taciti sociosqu. Ad litora torquent per conubia nostra inceptos himenaeos.",
8
+ "Lorem ipsum dolor sit amet consectetur adipiscing elit.. Quisque faucibus ex sapien vitae pellentesque sem placerat. In id cursus mi pretium tellus duis convallis. Tempus leo eu aenean sed diam urna tempor. Pulvinar vivamus fringilla lacus nec metus bibendum egestas. Iaculis massa nisl malesuada lacinia integer nunc posuere. Ut hendrerit semper vel class aptent taciti sociosqu. Ad litora torquent per conubia nostra inceptos himenaeos.",
9
+ "Lorem ipsum dolor sit amet consectetur adipiscing elit. Quisque faucibus ex sapien vitae pellentesque sem placerat. In id cursus mi pretium tellus duis convallis. Tempus leo eu aenean sed diam urna tempor. Pulvinar vivamus fringilla lacus nec metus bibendum egestas. Iaculis massa nisl malesuada lacinia integer nunc posuere. Ut hendrerit semper vel class aptent taciti sociosqu. Ad litora torquent per conubia nostra inceptos himenaeos."
10
+ ].join("\n");
11
+ (0, import_vitest.describe)("listSpecialChars", () => {
12
+ (0, import_vitest.it)("should return an empty array if the text is empty", () => {
13
+ const text = "";
14
+ const result = (0, import_listSpecialChars.listSpecialChars)(text);
15
+ (0, import_vitest.expect)(result).toEqual([]);
16
+ });
17
+ (0, import_vitest.it)("should return an array of special characters", () => {
18
+ const result = (0, import_listSpecialChars.listSpecialChars)(test);
19
+ (0, import_vitest.expect)(result).toEqual([
20
+ {
21
+ char: "(",
22
+ charStart: 56,
23
+ lineStart: 0
24
+ },
25
+ {
26
+ char: ")",
27
+ charStart: 115,
28
+ lineStart: 0
29
+ },
30
+ {
31
+ char: "\\",
32
+ charStart: 439,
33
+ lineStart: 0
34
+ },
35
+ {
36
+ char: "!",
37
+ charStart: 494,
38
+ lineStart: 1
39
+ },
40
+ {
41
+ char: "\\",
42
+ charStart: 877,
43
+ lineStart: 1
44
+ },
45
+ {
46
+ char: "\\",
47
+ charStart: 1315,
48
+ lineStart: 2
49
+ },
50
+ {
51
+ char: "\\",
52
+ charStart: 1754,
53
+ lineStart: 3
54
+ }
55
+ ]);
56
+ });
57
+ });
58
+ //# sourceMappingURL=listSpecialChars.test.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/utils/listSpecialChars.test.ts"],"sourcesContent":["import { describe, expect, it } from 'vitest';\nimport { listSpecialChars } from './listSpecialChars';\n\nconst test = [\n 'Lorem ipsum dolor sit amet consectetur adipiscing elit. (Quisque faucibus ex sapien vitae pellentesque sem placerat). In id cursus mi pretium tellus duis convallis. Tempus leo eu aenean sed diam urna tempor. Pulvinar vivamus fringilla lacus nec metus bibendum egestas. Iaculis massa nisl malesuada lacinia integer nunc posuere. Ut hendrerit semper vel class aptent taciti sociosqu. Ad litora torquent per conubia nostra inceptos himenaeos.',\n 'Lorem ipsum dolor sit amet consectetur adipiscing elit! Quisque faucibus ex sapien vitae pellentesque sem placerat. In id cursus mi pretium tellus duis convallis. Tempus leo eu aenean sed diam urna tempor. Pulvinar vivamus fringilla lacus nec metus bibendum egestas. Iaculis massa nisl malesuada lacinia integer nunc posuere. Ut hendrerit semper vel class aptent taciti sociosqu. Ad litora torquent per conubia nostra inceptos himenaeos.',\n 'Lorem ipsum dolor sit amet consectetur adipiscing elit. Quisque faucibus ex sapien vitae pellentesque sem placerat. In id cursus mi pretium tellus duis convallis. Tempus leo eu aenean sed diam urna tempor. Pulvinar vivamus fringilla lacus nec metus bibendum egestas. Iaculis massa nisl malesuada lacinia integer nunc posuere. Ut hendrerit semper vel class aptent taciti sociosqu. Ad litora torquent per conubia nostra inceptos himenaeos.',\n 'Lorem ipsum dolor sit amet consectetur adipiscing elit.. Quisque faucibus ex sapien vitae pellentesque sem placerat. In id cursus mi pretium tellus duis convallis. Tempus leo eu aenean sed diam urna tempor. Pulvinar vivamus fringilla lacus nec metus bibendum egestas. Iaculis massa nisl malesuada lacinia integer nunc posuere. Ut hendrerit semper vel class aptent taciti sociosqu. Ad litora torquent per conubia nostra inceptos himenaeos.',\n 'Lorem ipsum dolor sit amet consectetur adipiscing elit. Quisque faucibus ex sapien vitae pellentesque sem placerat. In id cursus mi pretium tellus duis convallis. Tempus leo eu aenean sed diam urna tempor. Pulvinar vivamus fringilla lacus nec metus bibendum egestas. Iaculis massa nisl malesuada lacinia integer nunc posuere. Ut hendrerit semper vel class aptent taciti sociosqu. Ad litora torquent per conubia nostra inceptos himenaeos.',\n].join('\\n');\n\ndescribe('listSpecialChars', () => {\n it('should return an empty array if the text is empty', () => {\n const text = '';\n const result = listSpecialChars(text);\n expect(result).toEqual([]);\n });\n\n it('should return an array of special characters', () => {\n const result = listSpecialChars(test);\n expect(result).toEqual([\n {\n char: '(',\n charStart: 56,\n lineStart: 0,\n },\n {\n char: ')',\n charStart: 115,\n lineStart: 0,\n },\n {\n char: '\\\\',\n charStart: 439,\n lineStart: 0,\n },\n {\n char: '!',\n charStart: 494,\n lineStart: 1,\n },\n {\n char: '\\\\',\n charStart: 877,\n lineStart: 1,\n },\n {\n char: '\\\\',\n charStart: 1315,\n lineStart: 2,\n },\n {\n char: '\\\\',\n charStart: 1754,\n lineStart: 3,\n },\n ]);\n });\n});\n"],"mappings":";AAAA,oBAAqC;AACrC,8BAAiC;AAEjC,MAAM,OAAO;AAAA,EACX;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,EAAE,KAAK,IAAI;AAAA,IAEX,wBAAS,oBAAoB,MAAM;AACjC,wBAAG,qDAAqD,MAAM;AAC5D,UAAM,OAAO;AACb,UAAM,aAAS,0CAAiB,IAAI;AACpC,8BAAO,MAAM,EAAE,QAAQ,CAAC,CAAC;AAAA,EAC3B,CAAC;AAED,wBAAG,gDAAgD,MAAM;AACvD,UAAM,aAAS,0CAAiB,IAAI;AACpC,8BAAO,MAAM,EAAE,QAAQ;AAAA,MACrB;AAAA,QACE,MAAM;AAAA,QACN,WAAW;AAAA,QACX,WAAW;AAAA,MACb;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,WAAW;AAAA,QACX,WAAW;AAAA,MACb;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,WAAW;AAAA,QACX,WAAW;AAAA,MACb;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,WAAW;AAAA,QACX,WAAW;AAAA,MACb;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,WAAW;AAAA,QACX,WAAW;AAAA,MACb;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,WAAW;AAAA,QACX,WAAW;AAAA,MACb;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,WAAW;AAAA,QACX,WAAW;AAAA,MACb;AAAA,IACF,CAAC;AAAA,EACH,CAAC;AACH,CAAC;","names":[]}
@@ -0,0 +1,125 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
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 __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+ var reorderParagraphs_exports = {};
20
+ __export(reorderParagraphs_exports, {
21
+ reorderParagraphs: () => reorderParagraphs
22
+ });
23
+ module.exports = __toCommonJS(reorderParagraphs_exports);
24
+ var import_listSpecialChars = require('./listSpecialChars.cjs');
25
+ const splitByParagraph = (text) => {
26
+ const paragraphs = [];
27
+ const tokens = text.split(/(\n{2,})/);
28
+ for (let i = 0; i < tokens.length; i++) {
29
+ const token = tokens[i];
30
+ if (i % 2 === 0) {
31
+ if (token) paragraphs.push(token);
32
+ continue;
33
+ }
34
+ const pairsOfNewlines = Math.floor(token.length / 2);
35
+ const blankParagraphs = Math.max(0, pairsOfNewlines - 2);
36
+ for (let j = 0; j < blankParagraphs; j++) {
37
+ paragraphs.push("\n\n");
38
+ }
39
+ }
40
+ return paragraphs;
41
+ };
42
+ const paragraphMatches = (paragraph, baseParagraph, paragraphSignature, baseSignature) => {
43
+ if (paragraph === baseParagraph) return true;
44
+ if (paragraphSignature.length !== baseSignature.length) return false;
45
+ for (let i = 0; i < paragraphSignature.length; i++) {
46
+ if (paragraphSignature[i].char !== baseSignature[i].char) {
47
+ return false;
48
+ }
49
+ }
50
+ return true;
51
+ };
52
+ const reorderParagraphs = (textToReorder, baseFileContent) => {
53
+ const baseFileParagraphs = splitByParagraph(baseFileContent);
54
+ const textToReorderParagraphs = splitByParagraph(textToReorder);
55
+ const baseSignatures = baseFileParagraphs.map((p) => (0, import_listSpecialChars.listSpecialChars)(p));
56
+ const textSignatures = textToReorderParagraphs.map(
57
+ (p) => (0, import_listSpecialChars.listSpecialChars)(p)
58
+ );
59
+ const firstMatchIndexForBase = Array(
60
+ baseFileParagraphs.length
61
+ ).fill(-1);
62
+ const paragraphMatchedBaseIdx = Array(
63
+ textToReorderParagraphs.length
64
+ ).fill(null);
65
+ for (let i = 0; i < textToReorderParagraphs.length; i++) {
66
+ const paragraph = textToReorderParagraphs[i];
67
+ const sig = textSignatures[i];
68
+ let foundIdx = baseFileParagraphs.findIndex(
69
+ (baseParagraph, idx) => firstMatchIndexForBase[idx] === -1 && paragraph === baseParagraph
70
+ );
71
+ if (foundIdx === -1) {
72
+ foundIdx = baseFileParagraphs.findIndex(
73
+ (baseParagraph, idx) => firstMatchIndexForBase[idx] === -1 && paragraphMatches(paragraph, baseParagraph, sig, baseSignatures[idx])
74
+ );
75
+ }
76
+ if (foundIdx !== -1) {
77
+ firstMatchIndexForBase[foundIdx] = i;
78
+ paragraphMatchedBaseIdx[i] = foundIdx;
79
+ }
80
+ }
81
+ const insertAfterBaseIdx = Array(
82
+ textToReorderParagraphs.length
83
+ ).fill(-1);
84
+ let maxBaseIdxEncountered = -1;
85
+ for (let i = 0; i < textToReorderParagraphs.length; i++) {
86
+ const matchedBase = paragraphMatchedBaseIdx[i];
87
+ if (matchedBase !== null) {
88
+ if (matchedBase > maxBaseIdxEncountered) {
89
+ maxBaseIdxEncountered = matchedBase;
90
+ }
91
+ } else {
92
+ insertAfterBaseIdx[i] = maxBaseIdxEncountered;
93
+ }
94
+ }
95
+ const result = [];
96
+ const extraParagraphsBuckets = {};
97
+ insertAfterBaseIdx.forEach((afterIdx, paragraphIdx) => {
98
+ if (afterIdx === -1) return;
99
+ extraParagraphsBuckets[afterIdx] = extraParagraphsBuckets[afterIdx] || [];
100
+ extraParagraphsBuckets[afterIdx].push(paragraphIdx);
101
+ });
102
+ for (let bIdx = 0; bIdx < baseFileParagraphs.length; bIdx++) {
103
+ const matchedParagraphIdx = firstMatchIndexForBase[bIdx];
104
+ if (matchedParagraphIdx !== -1) {
105
+ result.push(textToReorderParagraphs[matchedParagraphIdx]);
106
+ }
107
+ if (extraParagraphsBuckets[bIdx]) {
108
+ extraParagraphsBuckets[bIdx].forEach((pIdx) => {
109
+ result.push(textToReorderParagraphs[pIdx]);
110
+ });
111
+ }
112
+ }
113
+ const leadingExtras = [];
114
+ insertAfterBaseIdx.forEach((afterIdx, pIdx) => {
115
+ if (afterIdx === -1 && paragraphMatchedBaseIdx[pIdx] === null) {
116
+ leadingExtras.push(textToReorderParagraphs[pIdx]);
117
+ }
118
+ });
119
+ return [...leadingExtras, ...result].join("\n\n");
120
+ };
121
+ // Annotate the CommonJS export names for ESM import in node:
122
+ 0 && (module.exports = {
123
+ reorderParagraphs
124
+ });
125
+ //# sourceMappingURL=reorderParagraphs.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/utils/reorderParagraphs.ts"],"sourcesContent":["import { listSpecialChars } from './listSpecialChars';\n\n/**\n * Split a text into paragraphs.\n *\n * We consider a paragraph boundary to be a block of at least two consecutive\n * new-lines that is immediately followed by a non-white-space character. This\n * way, internal blank lines that are part of the same paragraph (e.g. a list\n * item that purposely contains a visual break) are preserved while true\n * paragraph breaks – the ones generated when calling `arr.join(\"\\n\\n\")` in\n * the tests – are still detected.\n */\nconst splitByParagraph = (text: string): string[] => {\n const paragraphs: string[] = [];\n\n // Capture the delimiter so that we can inspect how many new-lines it\n // contains. We know that the test strings only use LF, so we keep the\n // regex simple here.\n const tokens = text.split(/(\\n{2,})/);\n\n for (let i = 0; i < tokens.length; i++) {\n const token = tokens[i];\n\n // Even-indexed tokens are the actual paragraph contents.\n if (i % 2 === 0) {\n if (token) paragraphs.push(token);\n continue;\n }\n\n // Odd-indexed tokens are the delimiters (>= two consecutive new-lines).\n // The first and last pairs represent the natural separators that are\n // added when paragraphs are later joined with \"\\n\\n\". Any additional\n // pairs in between correspond to *explicit* blank paragraphs that were\n // present in the original text and must therefore be preserved.\n const pairsOfNewlines = Math.floor(token.length / 2);\n const blankParagraphs = Math.max(0, pairsOfNewlines - 2);\n\n for (let j = 0; j < blankParagraphs; j++) {\n paragraphs.push('\\n\\n');\n }\n }\n\n return paragraphs;\n};\n\n/**\n * Determine whether two paragraphs match – either exactly, or by sharing the\n * same \"special-character signature\".\n */\nconst paragraphMatches = (\n paragraph: string,\n baseParagraph: string,\n paragraphSignature: ReturnType<typeof listSpecialChars>,\n baseSignature: ReturnType<typeof listSpecialChars>\n): boolean => {\n if (paragraph === baseParagraph) return true;\n // fallback to special-character signature comparison\n if (paragraphSignature.length !== baseSignature.length) return false;\n\n for (let i = 0; i < paragraphSignature.length; i++) {\n if (paragraphSignature[i].char !== baseSignature[i].char) {\n return false;\n }\n }\n return true;\n};\n\n/**\n * Re-order `textToReorder` so that its paragraphs follow the ordering found in\n * `baseFileContent`, while preserving any extra paragraphs (those not present\n * in the base file) in a position that is intuitive for a human reader: right\n * after the closest preceding paragraph coming from the base file.\n */\nexport const reorderParagraphs = (\n textToReorder: string,\n baseFileContent: string\n): string => {\n // 1. Split both texts into paragraphs and pre-compute their signatures.\n const baseFileParagraphs = splitByParagraph(baseFileContent);\n const textToReorderParagraphs = splitByParagraph(textToReorder);\n\n const baseSignatures = baseFileParagraphs.map((p) => listSpecialChars(p));\n const textSignatures = textToReorderParagraphs.map((p) =>\n listSpecialChars(p)\n );\n\n // 2. For every paragraph in the text to reorder, find the *first* base\n // paragraph it matches. We only allow each base paragraph to be matched\n // once. Any further identical paragraphs will be treated as \"extra\" and\n // will be positioned later on, next to their closest neighbour.\n const firstMatchIndexForBase: number[] = Array(\n baseFileParagraphs.length\n ).fill(-1);\n const paragraphMatchedBaseIdx: (number | null)[] = Array(\n textToReorderParagraphs.length\n ).fill(null);\n\n for (let i = 0; i < textToReorderParagraphs.length; i++) {\n const paragraph = textToReorderParagraphs[i];\n const sig = textSignatures[i];\n\n // exact match pass first for performance\n let foundIdx = baseFileParagraphs.findIndex(\n (baseParagraph, idx) =>\n firstMatchIndexForBase[idx] === -1 && paragraph === baseParagraph\n );\n\n if (foundIdx === -1) {\n // fallback to the signature comparison\n foundIdx = baseFileParagraphs.findIndex(\n (baseParagraph, idx) =>\n firstMatchIndexForBase[idx] === -1 &&\n paragraphMatches(paragraph, baseParagraph, sig, baseSignatures[idx])\n );\n }\n\n if (foundIdx !== -1) {\n firstMatchIndexForBase[foundIdx] = i;\n paragraphMatchedBaseIdx[i] = foundIdx;\n }\n }\n\n // 3. For the paragraphs that *didn't* get matched to a base paragraph, we\n // record the highest-numbered base paragraph that was matched *before* it\n // in the original text. The extra paragraph will later be placed right\n // after that paragraph in the final ordering.\n const insertAfterBaseIdx: number[] = Array(\n textToReorderParagraphs.length\n ).fill(-1);\n let maxBaseIdxEncountered = -1;\n\n for (let i = 0; i < textToReorderParagraphs.length; i++) {\n const matchedBase = paragraphMatchedBaseIdx[i];\n\n if (matchedBase !== null) {\n if (matchedBase > maxBaseIdxEncountered) {\n maxBaseIdxEncountered = matchedBase;\n }\n } else {\n insertAfterBaseIdx[i] = maxBaseIdxEncountered;\n }\n }\n\n // 4. Build the final, reordered list of paragraphs.\n const result: string[] = [];\n\n // Helper: quickly retrieve all indices of paragraphs that should be inserted\n // after a given base index, while keeping their original order.\n const extraParagraphsBuckets: Record<number, number[]> = {};\n insertAfterBaseIdx.forEach((afterIdx, paragraphIdx) => {\n if (afterIdx === -1) return; // will be handled later (if any)\n extraParagraphsBuckets[afterIdx] = extraParagraphsBuckets[afterIdx] || [];\n extraParagraphsBuckets[afterIdx].push(paragraphIdx);\n });\n\n for (let bIdx = 0; bIdx < baseFileParagraphs.length; bIdx++) {\n const matchedParagraphIdx = firstMatchIndexForBase[bIdx];\n\n if (matchedParagraphIdx !== -1) {\n result.push(textToReorderParagraphs[matchedParagraphIdx]);\n }\n\n if (extraParagraphsBuckets[bIdx]) {\n extraParagraphsBuckets[bIdx].forEach((pIdx) => {\n result.push(textToReorderParagraphs[pIdx]);\n });\n }\n }\n\n // Finally, if there were extra paragraphs appearing *before* any matched\n // base paragraph (insertAfterBaseIdx === -1), we prepend them to the output\n // in their original order.\n const leadingExtras: string[] = [];\n insertAfterBaseIdx.forEach((afterIdx, pIdx) => {\n if (afterIdx === -1 && paragraphMatchedBaseIdx[pIdx] === null) {\n leadingExtras.push(textToReorderParagraphs[pIdx]);\n }\n });\n\n return [...leadingExtras, ...result].join('\\n\\n');\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,8BAAiC;AAYjC,MAAM,mBAAmB,CAAC,SAA2B;AACnD,QAAM,aAAuB,CAAC;AAK9B,QAAM,SAAS,KAAK,MAAM,UAAU;AAEpC,WAAS,IAAI,GAAG,IAAI,OAAO,QAAQ,KAAK;AACtC,UAAM,QAAQ,OAAO,CAAC;AAGtB,QAAI,IAAI,MAAM,GAAG;AACf,UAAI,MAAO,YAAW,KAAK,KAAK;AAChC;AAAA,IACF;AAOA,UAAM,kBAAkB,KAAK,MAAM,MAAM,SAAS,CAAC;AACnD,UAAM,kBAAkB,KAAK,IAAI,GAAG,kBAAkB,CAAC;AAEvD,aAAS,IAAI,GAAG,IAAI,iBAAiB,KAAK;AACxC,iBAAW,KAAK,MAAM;AAAA,IACxB;AAAA,EACF;AAEA,SAAO;AACT;AAMA,MAAM,mBAAmB,CACvB,WACA,eACA,oBACA,kBACY;AACZ,MAAI,cAAc,cAAe,QAAO;AAExC,MAAI,mBAAmB,WAAW,cAAc,OAAQ,QAAO;AAE/D,WAAS,IAAI,GAAG,IAAI,mBAAmB,QAAQ,KAAK;AAClD,QAAI,mBAAmB,CAAC,EAAE,SAAS,cAAc,CAAC,EAAE,MAAM;AACxD,aAAO;AAAA,IACT;AAAA,EACF;AACA,SAAO;AACT;AAQO,MAAM,oBAAoB,CAC/B,eACA,oBACW;AAEX,QAAM,qBAAqB,iBAAiB,eAAe;AAC3D,QAAM,0BAA0B,iBAAiB,aAAa;AAE9D,QAAM,iBAAiB,mBAAmB,IAAI,CAAC,UAAM,0CAAiB,CAAC,CAAC;AACxE,QAAM,iBAAiB,wBAAwB;AAAA,IAAI,CAAC,UAClD,0CAAiB,CAAC;AAAA,EACpB;AAMA,QAAM,yBAAmC;AAAA,IACvC,mBAAmB;AAAA,EACrB,EAAE,KAAK,EAAE;AACT,QAAM,0BAA6C;AAAA,IACjD,wBAAwB;AAAA,EAC1B,EAAE,KAAK,IAAI;AAEX,WAAS,IAAI,GAAG,IAAI,wBAAwB,QAAQ,KAAK;AACvD,UAAM,YAAY,wBAAwB,CAAC;AAC3C,UAAM,MAAM,eAAe,CAAC;AAG5B,QAAI,WAAW,mBAAmB;AAAA,MAChC,CAAC,eAAe,QACd,uBAAuB,GAAG,MAAM,MAAM,cAAc;AAAA,IACxD;AAEA,QAAI,aAAa,IAAI;AAEnB,iBAAW,mBAAmB;AAAA,QAC5B,CAAC,eAAe,QACd,uBAAuB,GAAG,MAAM,MAChC,iBAAiB,WAAW,eAAe,KAAK,eAAe,GAAG,CAAC;AAAA,MACvE;AAAA,IACF;AAEA,QAAI,aAAa,IAAI;AACnB,6BAAuB,QAAQ,IAAI;AACnC,8BAAwB,CAAC,IAAI;AAAA,IAC/B;AAAA,EACF;AAMA,QAAM,qBAA+B;AAAA,IACnC,wBAAwB;AAAA,EAC1B,EAAE,KAAK,EAAE;AACT,MAAI,wBAAwB;AAE5B,WAAS,IAAI,GAAG,IAAI,wBAAwB,QAAQ,KAAK;AACvD,UAAM,cAAc,wBAAwB,CAAC;AAE7C,QAAI,gBAAgB,MAAM;AACxB,UAAI,cAAc,uBAAuB;AACvC,gCAAwB;AAAA,MAC1B;AAAA,IACF,OAAO;AACL,yBAAmB,CAAC,IAAI;AAAA,IAC1B;AAAA,EACF;AAGA,QAAM,SAAmB,CAAC;AAI1B,QAAM,yBAAmD,CAAC;AAC1D,qBAAmB,QAAQ,CAAC,UAAU,iBAAiB;AACrD,QAAI,aAAa,GAAI;AACrB,2BAAuB,QAAQ,IAAI,uBAAuB,QAAQ,KAAK,CAAC;AACxE,2BAAuB,QAAQ,EAAE,KAAK,YAAY;AAAA,EACpD,CAAC;AAED,WAAS,OAAO,GAAG,OAAO,mBAAmB,QAAQ,QAAQ;AAC3D,UAAM,sBAAsB,uBAAuB,IAAI;AAEvD,QAAI,wBAAwB,IAAI;AAC9B,aAAO,KAAK,wBAAwB,mBAAmB,CAAC;AAAA,IAC1D;AAEA,QAAI,uBAAuB,IAAI,GAAG;AAChC,6BAAuB,IAAI,EAAE,QAAQ,CAAC,SAAS;AAC7C,eAAO,KAAK,wBAAwB,IAAI,CAAC;AAAA,MAC3C,CAAC;AAAA,IACH;AAAA,EACF;AAKA,QAAM,gBAA0B,CAAC;AACjC,qBAAmB,QAAQ,CAAC,UAAU,SAAS;AAC7C,QAAI,aAAa,MAAM,wBAAwB,IAAI,MAAM,MAAM;AAC7D,oBAAc,KAAK,wBAAwB,IAAI,CAAC;AAAA,IAClD;AAAA,EACF,CAAC;AAED,SAAO,CAAC,GAAG,eAAe,GAAG,MAAM,EAAE,KAAK,MAAM;AAClD;","names":[]}
@@ -0,0 +1,71 @@
1
+ "use strict";
2
+ var import_vitest = require("vitest");
3
+ var import_reorderParagraphs = require('./reorderParagraphs.cjs');
4
+ const baseText = [
5
+ "! Lorem ipsum dolor sit amet consectetur adipiscing elit.",
6
+ // '> Lorem ipsum dolor sit amet consectetur adipiscing elit.', // Additional content
7
+ "+ Lorem dolor sit amet consectetur adipiscing elit.",
8
+ // Similar n1
9
+ "- Lorem ipsum dolor sit amet consectetur adipiscing elit.",
10
+ "\n\n",
11
+ // Empty line
12
+ "* Lorem ipsum dolor sit amet consectetur adipiscing elit.",
13
+ "Lorem ipsum dolor sit amet consectetur adipiscing elit.",
14
+ // No special char
15
+ "+ Lorem dolor sit amet consectetur adipiscing elit.",
16
+ // Similar n2
17
+ "+ Lorem ipsum dolor sit amet consectetur adipiscing elit.",
18
+ // Similar n3 but different content
19
+ "= Lorem ipsum dolor sit amet consectetur adipiscing elit.",
20
+ // Missing content
21
+ "& Lorem ipsum dolor sit amet consectetur adipiscing elit."
22
+ ].join("\n\n");
23
+ const textToReorder = [
24
+ "! Lorem ipsum dolor sit amet consectetur adipiscing elit.",
25
+ // '> Lorem ipsum dolor sit amet consectetur adipiscing elit.', // Additional content
26
+ "+ Lorem dolor sit amet consectetur adipiscing elit.",
27
+ // Similar n1
28
+ "\n\n",
29
+ // Empty line
30
+ "* Lorem ipsum dolor sit amet consectetur adipiscing elit.",
31
+ "- Lorem ipsum dolor sit amet consectetur adipiscing elit.",
32
+ "+ Lorem dolor sit amet consectetur adipiscing elit.",
33
+ // Similar n2
34
+ "Lorem ipsum dolor sit amet consectetur adipiscing elit.",
35
+ // No special char
36
+ "+ Lorem ipsum dolor sit amet consectetur adipiscing elit.",
37
+ // Similar n3 but different content
38
+ "& Lorem ipsum dolor sit amet consectetur adipiscing elit.",
39
+ "= Lorem ipsum dolor sit amet consectetur adipiscing elit."
40
+ // Missing content
41
+ ].join("\n\n");
42
+ const texReordered = [
43
+ "! Lorem ipsum dolor sit amet consectetur adipiscing elit.",
44
+ // '> Lorem ipsum dolor sit amet consectetur adipiscing elit.', // Additional content
45
+ "+ Lorem dolor sit amet consectetur adipiscing elit.",
46
+ // Similar n1
47
+ "- Lorem ipsum dolor sit amet consectetur adipiscing elit.",
48
+ "\n\n",
49
+ // Empty line
50
+ "* Lorem ipsum dolor sit amet consectetur adipiscing elit.",
51
+ "Lorem ipsum dolor sit amet consectetur adipiscing elit.",
52
+ // No special char
53
+ "+ Lorem dolor sit amet consectetur adipiscing elit.",
54
+ // Similar n2
55
+ "+ Lorem ipsum dolor sit amet consectetur adipiscing elit.",
56
+ // Similar n3 but different content
57
+ "= Lorem ipsum dolor sit amet consectetur adipiscing elit.",
58
+ // Missing content
59
+ "& Lorem ipsum dolor sit amet consectetur adipiscing elit."
60
+ ].join("\n\n");
61
+ (0, import_vitest.describe)("reorderParagraphs", () => {
62
+ (0, import_vitest.it)("should keep the same order when input matches base text", () => {
63
+ const result = (0, import_reorderParagraphs.reorderParagraphs)(baseText, baseText);
64
+ (0, import_vitest.expect)(result).toEqual(baseText);
65
+ });
66
+ (0, import_vitest.it)("should reorder the paragraphs", () => {
67
+ const result = (0, import_reorderParagraphs.reorderParagraphs)(textToReorder, baseText);
68
+ (0, import_vitest.expect)(result).toEqual(texReordered);
69
+ });
70
+ });
71
+ //# sourceMappingURL=reorderParagraphs.test.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/utils/reorderParagraphs.test.ts"],"sourcesContent":["import { describe, expect, it } from 'vitest';\nimport { reorderParagraphs } from './reorderParagraphs';\n\nconst baseText = [\n '! Lorem ipsum dolor sit amet consectetur adipiscing elit.',\n // '> Lorem ipsum dolor sit amet consectetur adipiscing elit.', // Additional content\n '+ Lorem dolor sit amet consectetur adipiscing elit.', // Similar n1\n '- Lorem ipsum dolor sit amet consectetur adipiscing elit.',\n '\\n\\n', // Empty line\n '* Lorem ipsum dolor sit amet consectetur adipiscing elit.',\n 'Lorem ipsum dolor sit amet consectetur adipiscing elit.', // No special char\n '+ Lorem dolor sit amet consectetur adipiscing elit.', // Similar n2\n '+ Lorem ipsum dolor sit amet consectetur adipiscing elit.', // Similar n3 but different content\n '= Lorem ipsum dolor sit amet consectetur adipiscing elit.', // Missing content\n '& Lorem ipsum dolor sit amet consectetur adipiscing elit.',\n].join('\\n\\n');\n\nconst textToReorder = [\n '! Lorem ipsum dolor sit amet consectetur adipiscing elit.',\n // '> Lorem ipsum dolor sit amet consectetur adipiscing elit.', // Additional content\n '+ Lorem dolor sit amet consectetur adipiscing elit.', // Similar n1\n '\\n\\n', // Empty line\n '* Lorem ipsum dolor sit amet consectetur adipiscing elit.',\n '- Lorem ipsum dolor sit amet consectetur adipiscing elit.',\n '+ Lorem dolor sit amet consectetur adipiscing elit.', // Similar n2\n 'Lorem ipsum dolor sit amet consectetur adipiscing elit.', // No special char\n '+ Lorem ipsum dolor sit amet consectetur adipiscing elit.', // Similar n3 but different content\n '& Lorem ipsum dolor sit amet consectetur adipiscing elit.',\n '= Lorem ipsum dolor sit amet consectetur adipiscing elit.', // Missing content\n].join('\\n\\n');\n\nconst texReordered = [\n '! Lorem ipsum dolor sit amet consectetur adipiscing elit.',\n // '> Lorem ipsum dolor sit amet consectetur adipiscing elit.', // Additional content\n '+ Lorem dolor sit amet consectetur adipiscing elit.', // Similar n1\n '- Lorem ipsum dolor sit amet consectetur adipiscing elit.',\n '\\n\\n', // Empty line\n '* Lorem ipsum dolor sit amet consectetur adipiscing elit.',\n 'Lorem ipsum dolor sit amet consectetur adipiscing elit.', // No special char\n '+ Lorem dolor sit amet consectetur adipiscing elit.', // Similar n2\n '+ Lorem ipsum dolor sit amet consectetur adipiscing elit.', // Similar n3 but different content\n '= Lorem ipsum dolor sit amet consectetur adipiscing elit.', // Missing content\n '& Lorem ipsum dolor sit amet consectetur adipiscing elit.',\n].join('\\n\\n');\n\ndescribe('reorderParagraphs', () => {\n it('should keep the same order when input matches base text', () => {\n const result = reorderParagraphs(baseText, baseText);\n expect(result).toEqual(baseText);\n });\n\n it('should reorder the paragraphs', () => {\n const result = reorderParagraphs(textToReorder, baseText);\n expect(result).toEqual(texReordered);\n });\n});\n"],"mappings":";AAAA,oBAAqC;AACrC,+BAAkC;AAElC,MAAM,WAAW;AAAA,EACf;AAAA;AAAA,EAEA;AAAA;AAAA,EACA;AAAA,EACA;AAAA;AAAA,EACA;AAAA,EACA;AAAA;AAAA,EACA;AAAA;AAAA,EACA;AAAA;AAAA,EACA;AAAA;AAAA,EACA;AACF,EAAE,KAAK,MAAM;AAEb,MAAM,gBAAgB;AAAA,EACpB;AAAA;AAAA,EAEA;AAAA;AAAA,EACA;AAAA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA;AAAA,EACA;AAAA;AAAA,EACA;AAAA;AAAA,EACA;AAAA,EACA;AAAA;AACF,EAAE,KAAK,MAAM;AAEb,MAAM,eAAe;AAAA,EACnB;AAAA;AAAA,EAEA;AAAA;AAAA,EACA;AAAA,EACA;AAAA;AAAA,EACA;AAAA,EACA;AAAA;AAAA,EACA;AAAA;AAAA,EACA;AAAA;AAAA,EACA;AAAA;AAAA,EACA;AACF,EAAE,KAAK,MAAM;AAAA,IAEb,wBAAS,qBAAqB,MAAM;AAClC,wBAAG,2DAA2D,MAAM;AAClE,UAAM,aAAS,4CAAkB,UAAU,QAAQ;AACnD,8BAAO,MAAM,EAAE,QAAQ,QAAQ;AAAA,EACjC,CAAC;AAED,wBAAG,iCAAiC,MAAM;AACxC,UAAM,aAAS,4CAAkB,eAAe,QAAQ;AACxD,8BAAO,MAAM,EAAE,QAAQ,YAAY;AAAA,EACrC,CAAC;AACH,CAAC;","names":[]}