@intlayer/cli 5.5.10 → 5.6.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.
- package/README.md +1 -1
- package/dist/cjs/cli.cjs +83 -9
- package/dist/cjs/cli.cjs.map +1 -1
- package/dist/cjs/cli.test.cjs +435 -0
- package/dist/cjs/cli.test.cjs.map +1 -0
- package/dist/cjs/fill.cjs +8 -12
- package/dist/cjs/fill.cjs.map +1 -1
- package/dist/cjs/index.cjs +5 -1
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/cjs/prompts/REVIEW_PROMPT.md +37 -0
- package/dist/cjs/prompts/TRANSLATE_PROMPT.md +38 -0
- package/dist/cjs/pull.cjs +10 -2
- package/dist/cjs/pull.cjs.map +1 -1
- package/dist/cjs/pushConfig.cjs +5 -1
- package/dist/cjs/pushConfig.cjs.map +1 -1
- package/dist/cjs/reviewDoc.cjs +229 -0
- package/dist/cjs/reviewDoc.cjs.map +1 -0
- package/dist/cjs/translateDoc.cjs +211 -0
- package/dist/cjs/translateDoc.cjs.map +1 -0
- package/dist/cjs/utils/calculateChunks.cjs +120 -0
- package/dist/cjs/utils/calculateChunks.cjs.map +1 -0
- package/dist/cjs/utils/calculateChunks.test.cjs +104 -0
- package/dist/cjs/utils/calculateChunks.test.cjs.map +1 -0
- package/dist/cjs/utils/calculrateChunkTest.md +9 -0
- package/dist/cjs/utils/checkAIAccess.cjs +40 -0
- package/dist/cjs/utils/checkAIAccess.cjs.map +1 -0
- package/dist/cjs/utils/checkFileModifiedRange.cjs +97 -0
- package/dist/cjs/utils/checkFileModifiedRange.cjs.map +1 -0
- package/dist/cjs/utils/checkFileModifiedRange.test.cjs +175 -0
- package/dist/cjs/utils/checkFileModifiedRange.test.cjs.map +1 -0
- package/dist/cjs/utils/checkLastUpdateTime.cjs +33 -0
- package/dist/cjs/utils/checkLastUpdateTime.cjs.map +1 -0
- package/dist/cjs/utils/chunkInference.cjs +58 -0
- package/dist/cjs/utils/chunkInference.cjs.map +1 -0
- package/dist/cjs/utils/fixChunkStartEndChars.cjs +47 -0
- package/dist/cjs/utils/fixChunkStartEndChars.cjs.map +1 -0
- package/dist/cjs/utils/fixChunkStartEndChars.test.cjs +81 -0
- package/dist/cjs/utils/fixChunkStartEndChars.test.cjs.map +1 -0
- package/dist/cjs/utils/formatTimeDiff.cjs +46 -0
- package/dist/cjs/utils/formatTimeDiff.cjs.map +1 -0
- package/dist/cjs/utils/formatTimeDiff.test.cjs +32 -0
- package/dist/cjs/utils/formatTimeDiff.test.cjs.map +1 -0
- package/dist/cjs/utils/getChunk.cjs +77 -0
- package/dist/cjs/utils/getChunk.cjs.map +1 -0
- package/dist/cjs/utils/getChunk.test.cjs +46 -0
- package/dist/cjs/utils/getChunk.test.cjs.map +1 -0
- package/dist/cjs/utils/getIsFileUpdatedRecently.cjs +36 -0
- package/dist/cjs/utils/getIsFileUpdatedRecently.cjs.map +1 -0
- package/dist/cjs/utils/getOutputFilePath.cjs +89 -0
- package/dist/cjs/utils/getOutputFilePath.cjs.map +1 -0
- package/dist/cjs/utils/getOutputFilePath.test.cjs +73 -0
- package/dist/cjs/utils/getOutputFilePath.test.cjs.map +1 -0
- package/dist/cjs/utils/getParentPackageJSON.cjs +47 -0
- package/dist/cjs/utils/getParentPackageJSON.cjs.map +1 -0
- package/dist/cjs/utils/listSpecialChars.cjs +78 -0
- package/dist/cjs/utils/listSpecialChars.cjs.map +1 -0
- package/dist/cjs/utils/listSpecialChars.test.cjs +58 -0
- package/dist/cjs/utils/listSpecialChars.test.cjs.map +1 -0
- package/dist/cjs/utils/reorderParagraphs.cjs +125 -0
- package/dist/cjs/utils/reorderParagraphs.cjs.map +1 -0
- package/dist/cjs/utils/reorderParagraphs.test.cjs +71 -0
- package/dist/cjs/utils/reorderParagraphs.test.cjs.map +1 -0
- package/dist/cjs/utils/splitTextByLine.cjs +35 -0
- package/dist/cjs/utils/splitTextByLine.cjs.map +1 -0
- package/dist/cjs/utils/splitTextByLine.test.cjs +14 -0
- package/dist/cjs/utils/splitTextByLine.test.cjs.map +1 -0
- package/dist/esm/cli.mjs +84 -10
- package/dist/esm/cli.mjs.map +1 -1
- package/dist/esm/cli.test.mjs +412 -0
- package/dist/esm/cli.test.mjs.map +1 -0
- package/dist/esm/fill.mjs +8 -12
- package/dist/esm/fill.mjs.map +1 -1
- package/dist/esm/index.mjs +2 -0
- package/dist/esm/index.mjs.map +1 -1
- package/dist/esm/prompts/REVIEW_PROMPT.md +37 -0
- package/dist/esm/prompts/TRANSLATE_PROMPT.md +38 -0
- package/dist/esm/pull.mjs +10 -2
- package/dist/esm/pull.mjs.map +1 -1
- package/dist/esm/pushConfig.mjs +5 -1
- package/dist/esm/pushConfig.mjs.map +1 -1
- package/dist/esm/reviewDoc.mjs +198 -0
- package/dist/esm/reviewDoc.mjs.map +1 -0
- package/dist/esm/translateDoc.mjs +180 -0
- package/dist/esm/translateDoc.mjs.map +1 -0
- package/dist/esm/utils/calculateChunks.mjs +96 -0
- package/dist/esm/utils/calculateChunks.mjs.map +1 -0
- package/dist/esm/utils/calculateChunks.test.mjs +103 -0
- package/dist/esm/utils/calculateChunks.test.mjs.map +1 -0
- package/dist/esm/utils/calculrateChunkTest.md +9 -0
- package/dist/esm/utils/checkAIAccess.mjs +16 -0
- package/dist/esm/utils/checkAIAccess.mjs.map +1 -0
- package/dist/esm/utils/checkFileModifiedRange.mjs +73 -0
- package/dist/esm/utils/checkFileModifiedRange.mjs.map +1 -0
- package/dist/esm/utils/checkFileModifiedRange.test.mjs +181 -0
- package/dist/esm/utils/checkFileModifiedRange.test.mjs.map +1 -0
- package/dist/esm/utils/checkLastUpdateTime.mjs +9 -0
- package/dist/esm/utils/checkLastUpdateTime.mjs.map +1 -0
- package/dist/esm/utils/chunkInference.mjs +34 -0
- package/dist/esm/utils/chunkInference.mjs.map +1 -0
- package/dist/esm/utils/fixChunkStartEndChars.mjs +23 -0
- package/dist/esm/utils/fixChunkStartEndChars.mjs.map +1 -0
- package/dist/esm/utils/fixChunkStartEndChars.test.mjs +80 -0
- package/dist/esm/utils/fixChunkStartEndChars.test.mjs.map +1 -0
- package/dist/esm/utils/formatTimeDiff.mjs +22 -0
- package/dist/esm/utils/formatTimeDiff.mjs.map +1 -0
- package/dist/esm/utils/formatTimeDiff.test.mjs +31 -0
- package/dist/esm/utils/formatTimeDiff.test.mjs.map +1 -0
- package/dist/esm/utils/getChunk.mjs +53 -0
- package/dist/esm/utils/getChunk.mjs.map +1 -0
- package/dist/esm/utils/getChunk.test.mjs +45 -0
- package/dist/esm/utils/getChunk.test.mjs.map +1 -0
- package/dist/esm/utils/getIsFileUpdatedRecently.mjs +12 -0
- package/dist/esm/utils/getIsFileUpdatedRecently.mjs.map +1 -0
- package/dist/esm/utils/getOutputFilePath.mjs +65 -0
- package/dist/esm/utils/getOutputFilePath.mjs.map +1 -0
- package/dist/esm/utils/getOutputFilePath.test.mjs +72 -0
- package/dist/esm/utils/getOutputFilePath.test.mjs.map +1 -0
- package/dist/esm/utils/getParentPackageJSON.mjs +23 -0
- package/dist/esm/utils/getParentPackageJSON.mjs.map +1 -0
- package/dist/esm/utils/listSpecialChars.mjs +54 -0
- package/dist/esm/utils/listSpecialChars.mjs.map +1 -0
- package/dist/esm/utils/listSpecialChars.test.mjs +57 -0
- package/dist/esm/utils/listSpecialChars.test.mjs.map +1 -0
- package/dist/esm/utils/reorderParagraphs.mjs +101 -0
- package/dist/esm/utils/reorderParagraphs.mjs.map +1 -0
- package/dist/esm/utils/reorderParagraphs.test.mjs +70 -0
- package/dist/esm/utils/reorderParagraphs.test.mjs.map +1 -0
- package/dist/esm/utils/splitTextByLine.mjs +11 -0
- package/dist/esm/utils/splitTextByLine.mjs.map +1 -0
- package/dist/esm/utils/splitTextByLine.test.mjs +13 -0
- package/dist/esm/utils/splitTextByLine.test.mjs.map +1 -0
- package/dist/types/cli.d.ts.map +1 -1
- package/dist/types/cli.test.d.ts +2 -0
- package/dist/types/cli.test.d.ts.map +1 -0
- package/dist/types/fill.d.ts.map +1 -1
- package/dist/types/index.d.ts +3 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/pull.d.ts.map +1 -1
- package/dist/types/pushConfig.d.ts.map +1 -1
- package/dist/types/reviewDoc.d.ts +27 -0
- package/dist/types/reviewDoc.d.ts.map +1 -0
- package/dist/types/translateDoc.d.ts +27 -0
- package/dist/types/translateDoc.d.ts.map +1 -0
- package/dist/types/utils/calculateChunks.d.ts +9 -0
- package/dist/types/utils/calculateChunks.d.ts.map +1 -0
- package/dist/types/utils/calculateChunks.test.d.ts +2 -0
- package/dist/types/utils/calculateChunks.test.d.ts.map +1 -0
- package/dist/types/utils/checkAIAccess.d.ts +4 -0
- package/dist/types/utils/checkAIAccess.d.ts.map +1 -0
- package/dist/types/utils/checkFileModifiedRange.d.ts +11 -0
- package/dist/types/utils/checkFileModifiedRange.d.ts.map +1 -0
- package/dist/types/utils/checkFileModifiedRange.test.d.ts +2 -0
- package/dist/types/utils/checkFileModifiedRange.test.d.ts.map +1 -0
- package/dist/types/utils/checkLastUpdateTime.d.ts +9 -0
- package/dist/types/utils/checkLastUpdateTime.d.ts.map +1 -0
- package/dist/types/utils/chunkInference.d.ts +12 -0
- package/dist/types/utils/chunkInference.d.ts.map +1 -0
- package/dist/types/utils/fixChunkStartEndChars.d.ts +2 -0
- package/dist/types/utils/fixChunkStartEndChars.d.ts.map +1 -0
- package/dist/types/utils/fixChunkStartEndChars.test.d.ts +2 -0
- package/dist/types/utils/fixChunkStartEndChars.test.d.ts.map +1 -0
- package/dist/types/utils/formatTimeDiff.d.ts +2 -0
- package/dist/types/utils/formatTimeDiff.d.ts.map +1 -0
- package/dist/types/utils/formatTimeDiff.test.d.ts +2 -0
- package/dist/types/utils/formatTimeDiff.test.d.ts.map +1 -0
- package/dist/types/utils/getChunk.d.ts +9 -0
- package/dist/types/utils/getChunk.d.ts.map +1 -0
- package/dist/types/utils/getChunk.test.d.ts +2 -0
- package/dist/types/utils/getChunk.test.d.ts.map +1 -0
- package/dist/types/utils/getIsFileUpdatedRecently.d.ts +5 -0
- package/dist/types/utils/getIsFileUpdatedRecently.d.ts.map +1 -0
- package/dist/types/utils/getOutputFilePath.d.ts +26 -0
- package/dist/types/utils/getOutputFilePath.d.ts.map +1 -0
- package/dist/types/utils/getOutputFilePath.test.d.ts +2 -0
- package/dist/types/utils/getOutputFilePath.test.d.ts.map +1 -0
- package/dist/types/utils/getParentPackageJSON.d.ts +32 -0
- package/dist/types/utils/getParentPackageJSON.d.ts.map +1 -0
- package/dist/types/utils/listSpecialChars.d.ts +10 -0
- package/dist/types/utils/listSpecialChars.d.ts.map +1 -0
- package/dist/types/utils/listSpecialChars.test.d.ts +2 -0
- package/dist/types/utils/listSpecialChars.test.d.ts.map +1 -0
- package/dist/types/utils/reorderParagraphs.d.ts +8 -0
- package/dist/types/utils/reorderParagraphs.d.ts.map +1 -0
- package/dist/types/utils/reorderParagraphs.test.d.ts +2 -0
- package/dist/types/utils/reorderParagraphs.test.d.ts.map +1 -0
- package/dist/types/utils/splitTextByLine.d.ts +2 -0
- package/dist/types/utils/splitTextByLine.d.ts.map +1 -0
- package/dist/types/utils/splitTextByLine.test.d.ts +2 -0
- package/dist/types/utils/splitTextByLine.test.d.ts.map +1 -0
- package/package.json +15 -13
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var import_vitest = require("vitest");
|
|
3
|
+
var import_formatTimeDiff = require('./formatTimeDiff.cjs');
|
|
4
|
+
(0, import_vitest.describe)("formatTimeDiff", () => {
|
|
5
|
+
const fixedNow = /* @__PURE__ */ new Date("2025-01-01T00:00:00Z");
|
|
6
|
+
(0, import_vitest.beforeEach)(() => {
|
|
7
|
+
import_vitest.vi.useFakeTimers();
|
|
8
|
+
import_vitest.vi.setSystemTime(fixedNow);
|
|
9
|
+
});
|
|
10
|
+
(0, import_vitest.afterEach)(() => {
|
|
11
|
+
import_vitest.vi.useRealTimers();
|
|
12
|
+
});
|
|
13
|
+
(0, import_vitest.it)("formats differences containing days", () => {
|
|
14
|
+
const past = new Date(
|
|
15
|
+
2 * 24 * 60 * 60 * 1e3 + // 2 days
|
|
16
|
+
3 * 60 * 60 * 1e3 + // 3 hours
|
|
17
|
+
4 * 60 * 1e3 + // 4 minutes
|
|
18
|
+
5 * 1e3
|
|
19
|
+
// 5 seconds
|
|
20
|
+
);
|
|
21
|
+
(0, import_vitest.expect)((0, import_formatTimeDiff.formatTimeDiff)(past)).toBe("2d 3h 4m 5s");
|
|
22
|
+
});
|
|
23
|
+
(0, import_vitest.it)("formats differences containing hours but no days", () => {
|
|
24
|
+
const past = new Date(3 * 60 * 60 * 1e3 + 15 * 60 * 1e3 + 20 * 1e3);
|
|
25
|
+
(0, import_vitest.expect)((0, import_formatTimeDiff.formatTimeDiff)(past)).toBe("3h 15m 20s");
|
|
26
|
+
});
|
|
27
|
+
(0, import_vitest.it)("formats differences containing only minutes and seconds", () => {
|
|
28
|
+
const past = new Date(7 * 60 * 1e3 + 45 * 1e3);
|
|
29
|
+
(0, import_vitest.expect)((0, import_formatTimeDiff.formatTimeDiff)(past)).toBe("7m 45s");
|
|
30
|
+
});
|
|
31
|
+
});
|
|
32
|
+
//# sourceMappingURL=formatTimeDiff.test.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/utils/formatTimeDiff.test.ts"],"sourcesContent":["import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';\nimport { formatTimeDiff } from './formatTimeDiff';\n\ndescribe('formatTimeDiff', () => {\n const fixedNow = new Date('2025-01-01T00:00:00Z');\n\n beforeEach(() => {\n // Use fake timers so \"now\" is deterministic across tests\n vi.useFakeTimers();\n vi.setSystemTime(fixedNow);\n });\n\n afterEach(() => {\n vi.useRealTimers();\n });\n\n it('formats differences containing days', () => {\n // 2 days, 3 hours, 4 minutes, 5 seconds ago\n const past = new Date(\n 2 * 24 * 60 * 60 * 1000 + // 2 days\n 3 * 60 * 60 * 1000 + // 3 hours\n 4 * 60 * 1000 + // 4 minutes\n 5 * 1000 // 5 seconds\n );\n\n expect(formatTimeDiff(past)).toBe('2d 3h 4m 5s');\n });\n\n it('formats differences containing hours but no days', () => {\n // 3 hours, 15 minutes, 20 seconds ago\n const past = new Date(3 * 60 * 60 * 1000 + 15 * 60 * 1000 + 20 * 1000);\n\n expect(formatTimeDiff(past)).toBe('3h 15m 20s');\n });\n\n it('formats differences containing only minutes and seconds', () => {\n // 7 minutes, 45 seconds ago\n const past = new Date(7 * 60 * 1000 + 45 * 1000);\n\n expect(formatTimeDiff(past)).toBe('7m 45s');\n });\n});\n"],"mappings":";AAAA,oBAAgE;AAChE,4BAA+B;AAAA,IAE/B,wBAAS,kBAAkB,MAAM;AAC/B,QAAM,WAAW,oBAAI,KAAK,sBAAsB;AAEhD,gCAAW,MAAM;AAEf,qBAAG,cAAc;AACjB,qBAAG,cAAc,QAAQ;AAAA,EAC3B,CAAC;AAED,+BAAU,MAAM;AACd,qBAAG,cAAc;AAAA,EACnB,CAAC;AAED,wBAAG,uCAAuC,MAAM;AAE9C,UAAM,OAAO,IAAI;AAAA,MACf,IAAI,KAAK,KAAK,KAAK;AAAA,MACjB,IAAI,KAAK,KAAK;AAAA,MACd,IAAI,KAAK;AAAA,MACT,IAAI;AAAA;AAAA,IACR;AAEA,kCAAO,sCAAe,IAAI,CAAC,EAAE,KAAK,aAAa;AAAA,EACjD,CAAC;AAED,wBAAG,oDAAoD,MAAM;AAE3D,UAAM,OAAO,IAAI,KAAK,IAAI,KAAK,KAAK,MAAO,KAAK,KAAK,MAAO,KAAK,GAAI;AAErE,kCAAO,sCAAe,IAAI,CAAC,EAAE,KAAK,YAAY;AAAA,EAChD,CAAC;AAED,wBAAG,2DAA2D,MAAM;AAElE,UAAM,OAAO,IAAI,KAAK,IAAI,KAAK,MAAO,KAAK,GAAI;AAE/C,kCAAO,sCAAe,IAAI,CAAC,EAAE,KAAK,QAAQ;AAAA,EAC5C,CAAC;AACH,CAAC;","names":[]}
|
|
@@ -0,0 +1,77 @@
|
|
|
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 getChunk_exports = {};
|
|
20
|
+
__export(getChunk_exports, {
|
|
21
|
+
getChunk: () => getChunk
|
|
22
|
+
});
|
|
23
|
+
module.exports = __toCommonJS(getChunk_exports);
|
|
24
|
+
var import_splitTextByLine = require('./splitTextByLine.cjs');
|
|
25
|
+
const getChunk = (text, options = {}) => {
|
|
26
|
+
const { lineStart, lineLength, charStart, charLength } = options;
|
|
27
|
+
if (lineStart === void 0 && lineLength === void 0 && charStart === void 0 && charLength === void 0) {
|
|
28
|
+
return text;
|
|
29
|
+
}
|
|
30
|
+
const lines = (0, import_splitTextByLine.splitTextByLines)(text);
|
|
31
|
+
const getCharIndexOfLineStart = (lineNumber) => {
|
|
32
|
+
if (lineNumber <= 0) return 0;
|
|
33
|
+
let idx = 0;
|
|
34
|
+
for (let i = 0; i < Math.min(lineNumber, lines.length); i++) {
|
|
35
|
+
idx += lines[i].length;
|
|
36
|
+
}
|
|
37
|
+
return idx;
|
|
38
|
+
};
|
|
39
|
+
const getCharIndexOfLineEnd = (lineNumber) => {
|
|
40
|
+
if (lineNumber >= lines.length) {
|
|
41
|
+
return text.length;
|
|
42
|
+
}
|
|
43
|
+
const line = lines[lineNumber];
|
|
44
|
+
const lineEnd = getCharIndexOfLineStart(lineNumber) + line.length;
|
|
45
|
+
return lineEnd;
|
|
46
|
+
};
|
|
47
|
+
let effectiveStart = 0;
|
|
48
|
+
let effectiveEnd = text.length;
|
|
49
|
+
if (lineStart !== void 0) {
|
|
50
|
+
effectiveStart = Math.max(
|
|
51
|
+
effectiveStart,
|
|
52
|
+
getCharIndexOfLineStart(lineStart)
|
|
53
|
+
);
|
|
54
|
+
}
|
|
55
|
+
if (charStart !== void 0) {
|
|
56
|
+
effectiveStart = Math.max(effectiveStart, charStart);
|
|
57
|
+
}
|
|
58
|
+
if (lineLength !== void 0) {
|
|
59
|
+
const endLine = (lineStart ?? 0) + lineLength - 1;
|
|
60
|
+
effectiveEnd = Math.min(effectiveEnd, getCharIndexOfLineEnd(endLine));
|
|
61
|
+
}
|
|
62
|
+
if (charLength !== void 0) {
|
|
63
|
+
effectiveEnd = Math.min(
|
|
64
|
+
effectiveEnd,
|
|
65
|
+
(charStart ?? effectiveStart) + charLength
|
|
66
|
+
);
|
|
67
|
+
}
|
|
68
|
+
if (effectiveStart >= effectiveEnd) {
|
|
69
|
+
return "";
|
|
70
|
+
}
|
|
71
|
+
return text.slice(effectiveStart, effectiveEnd);
|
|
72
|
+
};
|
|
73
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
74
|
+
0 && (module.exports = {
|
|
75
|
+
getChunk
|
|
76
|
+
});
|
|
77
|
+
//# sourceMappingURL=getChunk.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/utils/getChunk.ts"],"sourcesContent":["import { splitTextByLines } from './splitTextByLine';\n\ntype TrunkOptions = {\n lineStart?: number;\n lineLength?: number;\n charStart?: number;\n charLength?: number;\n};\n\nexport const getChunk = (text: string, options: TrunkOptions = {}): string => {\n const { lineStart, lineLength, charStart, charLength } = options;\n\n // Fast-path: if no filters were provided, return the whole text\n if (\n lineStart === undefined &&\n lineLength === undefined &&\n charStart === undefined &&\n charLength === undefined\n ) {\n return text;\n }\n\n // ---------------------------------------------------------------------------\n // Utility helpers to convert between line numbers and absolute char indices\n // ---------------------------------------------------------------------------\n const lines = splitTextByLines(text);\n\n const getCharIndexOfLineStart = (lineNumber: number): number => {\n if (lineNumber <= 0) return 0;\n // Sum the length of every previous line\n let idx = 0;\n for (let i = 0; i < Math.min(lineNumber, lines.length); i++) {\n idx += lines[i].length;\n }\n return idx;\n };\n\n const getCharIndexOfLineEnd = (lineNumber: number): number => {\n // If the requested line number exceeds the number of lines, clamp to the last character\n if (lineNumber >= lines.length) {\n return text.length;\n }\n const line = lines[lineNumber];\n const lineEnd = getCharIndexOfLineStart(lineNumber) + line.length;\n\n return lineEnd;\n };\n\n // ---------------------------------------------------------------------------\n // Compute the effective (inclusive) charStart/charEnd for the requested slice\n // ---------------------------------------------------------------------------\n let effectiveStart = 0; // inclusive\n let effectiveEnd = text.length; // exclusive\n\n // Apply line boundaries if provided\n if (lineStart !== undefined) {\n effectiveStart = Math.max(\n effectiveStart,\n getCharIndexOfLineStart(lineStart)\n );\n }\n\n // Apply character boundaries if provided\n if (charStart !== undefined) {\n effectiveStart = Math.max(effectiveStart, charStart);\n }\n\n // Apply line length boundary from lineStart (or 0)\n if (lineLength !== undefined) {\n const endLine = (lineStart ?? 0) + lineLength - 1;\n effectiveEnd = Math.min(effectiveEnd, getCharIndexOfLineEnd(endLine));\n }\n\n // Apply character length boundary from effectiveStart\n if (charLength !== undefined) {\n effectiveEnd = Math.min(\n effectiveEnd,\n (charStart ?? effectiveStart) + charLength\n );\n }\n\n // If bounds do not overlap, return empty string\n if (effectiveStart >= effectiveEnd) {\n return '';\n }\n\n return text.slice(effectiveStart, effectiveEnd);\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,6BAAiC;AAS1B,MAAM,WAAW,CAAC,MAAc,UAAwB,CAAC,MAAc;AAC5E,QAAM,EAAE,WAAW,YAAY,WAAW,WAAW,IAAI;AAGzD,MACE,cAAc,UACd,eAAe,UACf,cAAc,UACd,eAAe,QACf;AACA,WAAO;AAAA,EACT;AAKA,QAAM,YAAQ,yCAAiB,IAAI;AAEnC,QAAM,0BAA0B,CAAC,eAA+B;AAC9D,QAAI,cAAc,EAAG,QAAO;AAE5B,QAAI,MAAM;AACV,aAAS,IAAI,GAAG,IAAI,KAAK,IAAI,YAAY,MAAM,MAAM,GAAG,KAAK;AAC3D,aAAO,MAAM,CAAC,EAAE;AAAA,IAClB;AACA,WAAO;AAAA,EACT;AAEA,QAAM,wBAAwB,CAAC,eAA+B;AAE5D,QAAI,cAAc,MAAM,QAAQ;AAC9B,aAAO,KAAK;AAAA,IACd;AACA,UAAM,OAAO,MAAM,UAAU;AAC7B,UAAM,UAAU,wBAAwB,UAAU,IAAI,KAAK;AAE3D,WAAO;AAAA,EACT;AAKA,MAAI,iBAAiB;AACrB,MAAI,eAAe,KAAK;AAGxB,MAAI,cAAc,QAAW;AAC3B,qBAAiB,KAAK;AAAA,MACpB;AAAA,MACA,wBAAwB,SAAS;AAAA,IACnC;AAAA,EACF;AAGA,MAAI,cAAc,QAAW;AAC3B,qBAAiB,KAAK,IAAI,gBAAgB,SAAS;AAAA,EACrD;AAGA,MAAI,eAAe,QAAW;AAC5B,UAAM,WAAW,aAAa,KAAK,aAAa;AAChD,mBAAe,KAAK,IAAI,cAAc,sBAAsB,OAAO,CAAC;AAAA,EACtE;AAGA,MAAI,eAAe,QAAW;AAC5B,mBAAe,KAAK;AAAA,MAClB;AAAA,OACC,aAAa,kBAAkB;AAAA,IAClC;AAAA,EACF;AAGA,MAAI,kBAAkB,cAAc;AAClC,WAAO;AAAA,EACT;AAEA,SAAO,KAAK,MAAM,gBAAgB,YAAY;AAChD;","names":[]}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var import_vitest = require("vitest");
|
|
3
|
+
var import_getChunk = require('./getChunk.cjs');
|
|
4
|
+
const sampleText = [
|
|
5
|
+
"Line 0: The quick brown fox jumps over the lazy dog.",
|
|
6
|
+
"Line 1: Pack my box with five dozen liquor jugs.",
|
|
7
|
+
"Line 2: How razorback-jumping frogs can level six piqued gymnasts!",
|
|
8
|
+
"Line 3: Cozy lummox gives smart squid who asks for job pen.",
|
|
9
|
+
"Line 4: A mad boxer shot a quick, gloved jab to the jaw of his dizzy opponent."
|
|
10
|
+
].join("\n");
|
|
11
|
+
(0, import_vitest.describe)("getChunk", () => {
|
|
12
|
+
(0, import_vitest.it)("returns the whole text when no filters are provided", () => {
|
|
13
|
+
const result = (0, import_getChunk.getChunk)(sampleText);
|
|
14
|
+
(0, import_vitest.expect)(result).toBe(sampleText);
|
|
15
|
+
});
|
|
16
|
+
(0, import_vitest.it)("applies lineStart and lineLength filters", () => {
|
|
17
|
+
const result = (0, import_getChunk.getChunk)(sampleText, { lineStart: 1, lineLength: 2 });
|
|
18
|
+
const expected = [
|
|
19
|
+
"Line 1: Pack my box with five dozen liquor jugs.\n",
|
|
20
|
+
"Line 2: How razorback-jumping frogs can level six piqued gymnasts!\n"
|
|
21
|
+
].join("");
|
|
22
|
+
(0, import_vitest.expect)(result).toBe(expected);
|
|
23
|
+
});
|
|
24
|
+
(0, import_vitest.it)("applies charStart and charLength filters", () => {
|
|
25
|
+
const charStart = sampleText.indexOf("quick");
|
|
26
|
+
const charLength = "quick brown fox".length;
|
|
27
|
+
const result = (0, import_getChunk.getChunk)(sampleText, { charStart, charLength });
|
|
28
|
+
(0, import_vitest.expect)(result).toBe("quick brown fox");
|
|
29
|
+
});
|
|
30
|
+
(0, import_vitest.it)("combines line and char filters by intersecting their ranges", () => {
|
|
31
|
+
const partial = (0, import_getChunk.getChunk)(sampleText, {
|
|
32
|
+
lineStart: 0,
|
|
33
|
+
lineLength: 3,
|
|
34
|
+
// lines 0, 1, 2
|
|
35
|
+
// Grab only the first 10 characters of the selected block
|
|
36
|
+
charStart: 0,
|
|
37
|
+
charLength: 10
|
|
38
|
+
});
|
|
39
|
+
(0, import_vitest.expect)(partial).toBe("Line 0: Th");
|
|
40
|
+
});
|
|
41
|
+
(0, import_vitest.it)("returns an empty string when effectiveStart > effectiveEnd", () => {
|
|
42
|
+
const result = (0, import_getChunk.getChunk)(sampleText, { charStart: 10, charLength: 0 });
|
|
43
|
+
(0, import_vitest.expect)(result).toBe("");
|
|
44
|
+
});
|
|
45
|
+
});
|
|
46
|
+
//# sourceMappingURL=getChunk.test.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/utils/getChunk.test.ts"],"sourcesContent":["import { describe, expect, it } from 'vitest';\n\nimport { getChunk } from './getChunk';\n\n// Sample multiline string used across test cases\nconst sampleText = [\n 'Line 0: The quick brown fox jumps over the lazy dog.',\n 'Line 1: Pack my box with five dozen liquor jugs.',\n 'Line 2: How razorback-jumping frogs can level six piqued gymnasts!',\n 'Line 3: Cozy lummox gives smart squid who asks for job pen.',\n 'Line 4: A mad boxer shot a quick, gloved jab to the jaw of his dizzy opponent.',\n].join('\\n');\n\ndescribe('getChunk', () => {\n it('returns the whole text when no filters are provided', () => {\n const result = getChunk(sampleText);\n expect(result).toBe(sampleText);\n });\n\n it('applies lineStart and lineLength filters', () => {\n const result = getChunk(sampleText, { lineStart: 1, lineLength: 2 });\n\n // Expected substring is lines 1 and 2 plus the newline in-between\n const expected = [\n 'Line 1: Pack my box with five dozen liquor jugs.\\n',\n 'Line 2: How razorback-jumping frogs can level six piqued gymnasts!\\n',\n ].join('');\n\n expect(result).toBe(expected);\n });\n\n it('applies charStart and charLength filters', () => {\n // Grab substring \"quick brown fox\" from first line\n const charStart = sampleText.indexOf('quick');\n const charLength = 'quick brown fox'.length;\n\n const result = getChunk(sampleText, { charStart, charLength });\n\n expect(result).toBe('quick brown fox');\n });\n\n it('combines line and char filters by intersecting their ranges', () => {\n // Restrict to lines 0-2, then further to characters within those lines\n const partial = getChunk(sampleText, {\n lineStart: 0,\n lineLength: 3, // lines 0, 1, 2\n // Grab only the first 10 characters of the selected block\n charStart: 0,\n charLength: 10,\n });\n\n expect(partial).toBe('Line 0: Th');\n });\n\n it('returns an empty string when effectiveStart > effectiveEnd', () => {\n const result = getChunk(sampleText, { charStart: 10, charLength: 0 });\n expect(result).toBe('');\n });\n});\n"],"mappings":";AAAA,oBAAqC;AAErC,sBAAyB;AAGzB,MAAM,aAAa;AAAA,EACjB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,EAAE,KAAK,IAAI;AAAA,IAEX,wBAAS,YAAY,MAAM;AACzB,wBAAG,uDAAuD,MAAM;AAC9D,UAAM,aAAS,0BAAS,UAAU;AAClC,8BAAO,MAAM,EAAE,KAAK,UAAU;AAAA,EAChC,CAAC;AAED,wBAAG,4CAA4C,MAAM;AACnD,UAAM,aAAS,0BAAS,YAAY,EAAE,WAAW,GAAG,YAAY,EAAE,CAAC;AAGnE,UAAM,WAAW;AAAA,MACf;AAAA,MACA;AAAA,IACF,EAAE,KAAK,EAAE;AAET,8BAAO,MAAM,EAAE,KAAK,QAAQ;AAAA,EAC9B,CAAC;AAED,wBAAG,4CAA4C,MAAM;AAEnD,UAAM,YAAY,WAAW,QAAQ,OAAO;AAC5C,UAAM,aAAa,kBAAkB;AAErC,UAAM,aAAS,0BAAS,YAAY,EAAE,WAAW,WAAW,CAAC;AAE7D,8BAAO,MAAM,EAAE,KAAK,iBAAiB;AAAA,EACvC,CAAC;AAED,wBAAG,+DAA+D,MAAM;AAEtE,UAAM,cAAU,0BAAS,YAAY;AAAA,MACnC,WAAW;AAAA,MACX,YAAY;AAAA;AAAA;AAAA,MAEZ,WAAW;AAAA,MACX,YAAY;AAAA,IACd,CAAC;AAED,8BAAO,OAAO,EAAE,KAAK,YAAY;AAAA,EACnC,CAAC;AAED,wBAAG,8DAA8D,MAAM;AACrE,UAAM,aAAS,0BAAS,YAAY,EAAE,WAAW,IAAI,YAAY,EAAE,CAAC;AACpE,8BAAO,MAAM,EAAE,KAAK,EAAE;AAAA,EACxB,CAAC;AACH,CAAC;","names":[]}
|
|
@@ -0,0 +1,36 @@
|
|
|
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 getIsFileUpdatedRecently_exports = {};
|
|
20
|
+
__export(getIsFileUpdatedRecently_exports, {
|
|
21
|
+
getIsFileUpdatedRecently: () => getIsFileUpdatedRecently
|
|
22
|
+
});
|
|
23
|
+
module.exports = __toCommonJS(getIsFileUpdatedRecently_exports);
|
|
24
|
+
var import_fs = require("fs");
|
|
25
|
+
const SKIP_RANGE_OF_LAST_UPDATE_TIME = 0;
|
|
26
|
+
const getIsFileUpdatedRecently = (localeFilePath) => {
|
|
27
|
+
const stats = (0, import_fs.statSync)(localeFilePath);
|
|
28
|
+
const lastModified = new Date(stats.mtime);
|
|
29
|
+
const threshold = new Date(Date.now() - SKIP_RANGE_OF_LAST_UPDATE_TIME);
|
|
30
|
+
return lastModified > threshold;
|
|
31
|
+
};
|
|
32
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
33
|
+
0 && (module.exports = {
|
|
34
|
+
getIsFileUpdatedRecently
|
|
35
|
+
});
|
|
36
|
+
//# sourceMappingURL=getIsFileUpdatedRecently.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/utils/getIsFileUpdatedRecently.ts"],"sourcesContent":["import { statSync } from 'fs';\n\nconst SKIP_RANGE_OF_LAST_UPDATE_TIME: number = 0; //2 * 60 * 60 * 1000; // 2 hours\n\n/**\n * Check if file was updated recently, to skip re-translation\n */\nexport const getIsFileUpdatedRecently = (localeFilePath: string): boolean => {\n const stats = statSync(localeFilePath);\n const lastModified = new Date(stats.mtime);\n const threshold = new Date(Date.now() - SKIP_RANGE_OF_LAST_UPDATE_TIME);\n\n return lastModified > threshold;\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,gBAAyB;AAEzB,MAAM,iCAAyC;AAKxC,MAAM,2BAA2B,CAAC,mBAAoC;AAC3E,QAAM,YAAQ,oBAAS,cAAc;AACrC,QAAM,eAAe,IAAI,KAAK,MAAM,KAAK;AACzC,QAAM,YAAY,IAAI,KAAK,KAAK,IAAI,IAAI,8BAA8B;AAEtE,SAAO,eAAe;AACxB;","names":[]}
|
|
@@ -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":[]}
|