generaltranslation 8.2.14 → 8.2.16
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/CHANGELOG.md +17 -1
- package/dist/{base64-C6BHySOc.cjs → base64-YBGAXkqy.cjs} +58 -1
- package/dist/base64-YBGAXkqy.cjs.map +1 -0
- package/dist/{base64-CWITCfhU.mjs → base64-r7YWJYWt.mjs} +47 -2
- package/dist/base64-r7YWJYWt.mjs.map +1 -0
- package/dist/derive/condenseVars.d.ts +2 -0
- package/dist/derive/condenseVars.js +5 -2
- package/dist/id.d.cts +1 -1
- package/dist/id.d.mts +1 -1
- package/dist/index.cjs +64 -12
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.mts +1 -1
- package/dist/index.mjs +64 -12
- package/dist/index.mjs.map +1 -1
- package/dist/internal.cjs +7 -2
- package/dist/internal.cjs.map +1 -1
- package/dist/internal.d.cts +34 -2
- package/dist/internal.d.mts +34 -2
- package/dist/internal.d.ts +2 -0
- package/dist/internal.js +1 -0
- package/dist/internal.mjs +6 -3
- package/dist/internal.mjs.map +1 -1
- package/dist/logging/diagnostics.d.ts +18 -0
- package/dist/logging/diagnostics.js +64 -0
- package/dist/logging/errors.d.ts +1 -1
- package/dist/logging/errors.js +64 -11
- package/dist/{types-73XFwmhH.d.mts → types-CdRgQtET.d.cts} +2 -3
- package/dist/{types-YrrGRHBP.d.cts → types-Db2Dn3oN.d.mts} +2 -3
- package/dist/types.d.cts +1 -1
- package/dist/types.d.mts +1 -1
- package/dist/types.d.ts +1 -2
- package/package.json +2 -2
- package/dist/base64-C6BHySOc.cjs.map +0 -1
- package/dist/base64-CWITCfhU.mjs.map +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,22 @@
|
|
|
1
1
|
# generaltranslation
|
|
2
2
|
|
|
3
|
+
## 8.2.16
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [#1460](https://github.com/generaltranslation/gt/pull/1460) [`e041312`](https://github.com/generaltranslation/gt/commit/e04131263dd61e469db977bcc196dc1283e773d0) Thanks [@ErnestM1234](https://github.com/ErnestM1234)! - fix: escape characters in declareVar() for source locale consumed by condenseVars()
|
|
8
|
+
|
|
9
|
+
## 8.2.15
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- [#1416](https://github.com/generaltranslation/gt/pull/1416) [`bb3624e`](https://github.com/generaltranslation/gt/commit/bb3624e58546c334c04370a1f5a262238bd040fa) Thanks [@bgub](https://github.com/bgub)! - Honor custom locale region display-name overrides and simplify shared locale formatting helpers.
|
|
14
|
+
|
|
15
|
+
- [#1419](https://github.com/generaltranslation/gt/pull/1419) [`a877a2a`](https://github.com/generaltranslation/gt/commit/a877a2a5bd5ca47b199c6caf53a6d60d96e3a300) Thanks [@bgub](https://github.com/bgub)! - Improve diagnostic messages and package-local diagnostic formatting.
|
|
16
|
+
|
|
17
|
+
- Updated dependencies [[`bb3624e`](https://github.com/generaltranslation/gt/commit/bb3624e58546c334c04370a1f5a262238bd040fa)]:
|
|
18
|
+
- @generaltranslation/format@0.1.1
|
|
19
|
+
|
|
3
20
|
## 8.2.14
|
|
4
21
|
|
|
5
22
|
### Patch Changes
|
|
@@ -300,7 +317,6 @@
|
|
|
300
317
|
https://generaltranslation.com/blog/generaltranslation_v8
|
|
301
318
|
|
|
302
319
|
Please update the following packages to the latest version:
|
|
303
|
-
|
|
304
320
|
- generaltranslation: `7.9.1` or later
|
|
305
321
|
- gtx-cli: `2.4.15` or later
|
|
306
322
|
- gt-sanity: `1.0.11` or later
|
|
@@ -2,6 +2,51 @@
|
|
|
2
2
|
const libraryDefaultLocale = "en";
|
|
3
3
|
const defaultTimeout = 6e4;
|
|
4
4
|
//#endregion
|
|
5
|
+
//#region src/logging/diagnostics.ts
|
|
6
|
+
function ensureSentence(text) {
|
|
7
|
+
const trimmed = text.trim();
|
|
8
|
+
if (!trimmed) return "";
|
|
9
|
+
return /[.!?)]$/.test(trimmed) ? trimmed : `${trimmed}.`;
|
|
10
|
+
}
|
|
11
|
+
function stripSentence(text) {
|
|
12
|
+
const trimmed = text.trim();
|
|
13
|
+
let end = trimmed.length;
|
|
14
|
+
while (end > 0) {
|
|
15
|
+
const char = trimmed[end - 1];
|
|
16
|
+
if (char !== "." && char !== "!" && char !== "?") break;
|
|
17
|
+
end -= 1;
|
|
18
|
+
}
|
|
19
|
+
return trimmed.slice(0, end);
|
|
20
|
+
}
|
|
21
|
+
function lowercaseFirstWord(text) {
|
|
22
|
+
return text.replace(/^[A-Z][a-z]/, (match) => match.toLowerCase());
|
|
23
|
+
}
|
|
24
|
+
function formatDetails(details) {
|
|
25
|
+
if (!details) return "";
|
|
26
|
+
const detailText = Array.isArray(details) ? details.join(", ") : details;
|
|
27
|
+
if (!detailText.trim()) return "";
|
|
28
|
+
return ensureSentence(`Details: ${detailText}`);
|
|
29
|
+
}
|
|
30
|
+
function formatDiagnosticErrorDetails(error) {
|
|
31
|
+
if (error == null) return void 0;
|
|
32
|
+
return String(error);
|
|
33
|
+
}
|
|
34
|
+
function createDiagnosticMessage({ source, severity, whatHappened, reassurance, why, fix, wayOut, details, docsUrl }) {
|
|
35
|
+
const prefix = source ? severity ? `${source} ${severity}:` : `${source}:` : severity ? `${severity}:` : "";
|
|
36
|
+
const whatAndWhy = why ? `${stripSentence(whatHappened)} because ${lowercaseFirstWord(stripSentence(why))}` : whatHappened;
|
|
37
|
+
const shouldCombineWayOut = !!fix && !!wayOut && /^[a-z]/.test(stripSentence(wayOut));
|
|
38
|
+
const messageParts = [
|
|
39
|
+
whatAndWhy,
|
|
40
|
+
reassurance,
|
|
41
|
+
shouldCombineWayOut ? `${stripSentence(fix)}, or ${lowercaseFirstWord(stripSentence(wayOut))}` : fix,
|
|
42
|
+
shouldCombineWayOut ? void 0 : wayOut,
|
|
43
|
+
formatDetails(details)
|
|
44
|
+
].filter((part) => !!part).map(ensureSentence);
|
|
45
|
+
if (docsUrl) messageParts.push(`Learn more: ${docsUrl}`);
|
|
46
|
+
const message = messageParts.join(" ");
|
|
47
|
+
return prefix ? `${prefix} ${message}` : message;
|
|
48
|
+
}
|
|
49
|
+
//#endregion
|
|
5
50
|
//#region src/settings/settingsUrls.ts
|
|
6
51
|
const defaultCacheUrl = "https://cdn.gtx.dev";
|
|
7
52
|
const defaultBaseUrl = "https://api2.gtx.dev";
|
|
@@ -69,6 +114,12 @@ function decode(base64) {
|
|
|
69
114
|
return new TextDecoder().decode(bytes);
|
|
70
115
|
}
|
|
71
116
|
//#endregion
|
|
117
|
+
Object.defineProperty(exports, "createDiagnosticMessage", {
|
|
118
|
+
enumerable: true,
|
|
119
|
+
get: function() {
|
|
120
|
+
return createDiagnosticMessage;
|
|
121
|
+
}
|
|
122
|
+
});
|
|
72
123
|
Object.defineProperty(exports, "decode", {
|
|
73
124
|
enumerable: true,
|
|
74
125
|
get: function() {
|
|
@@ -105,6 +156,12 @@ Object.defineProperty(exports, "encode", {
|
|
|
105
156
|
return encode;
|
|
106
157
|
}
|
|
107
158
|
});
|
|
159
|
+
Object.defineProperty(exports, "formatDiagnosticErrorDetails", {
|
|
160
|
+
enumerable: true,
|
|
161
|
+
get: function() {
|
|
162
|
+
return formatDiagnosticErrorDetails;
|
|
163
|
+
}
|
|
164
|
+
});
|
|
108
165
|
Object.defineProperty(exports, "isSupportedFileFormatTransform", {
|
|
109
166
|
enumerable: true,
|
|
110
167
|
get: function() {
|
|
@@ -124,4 +181,4 @@ Object.defineProperty(exports, "validateFileFormatTransforms", {
|
|
|
124
181
|
}
|
|
125
182
|
});
|
|
126
183
|
|
|
127
|
-
//# sourceMappingURL=base64-
|
|
184
|
+
//# sourceMappingURL=base64-YBGAXkqy.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"base64-YBGAXkqy.cjs","names":[],"sources":["../src/settings/settings.ts","../src/logging/diagnostics.ts","../src/settings/settingsUrls.ts","../src/utils/isSupportedFileFormatTransform.ts","../src/translate/utils/validateFileFormatTransform.ts","../src/utils/base64.ts"],"sourcesContent":["export const libraryDefaultLocale = 'en' as const;\nexport const defaultTimeout = 60000;\n","export type DiagnosticSeverity = 'Error' | 'Warning';\n\n/**\n * Text slots follow the five-part error message model:\n * what happened, reassurance, why it happened, how to fix it, and a way out.\n */\nexport type DiagnosticMessageInput = {\n source?: string;\n severity?: DiagnosticSeverity;\n whatHappened: string;\n reassurance?: string;\n why?: string;\n fix?: string;\n wayOut?: string;\n details?: string | string[];\n docsUrl?: string;\n};\n\nfunction ensureSentence(text: string): string {\n const trimmed = text.trim();\n if (!trimmed) return '';\n return /[.!?)]$/.test(trimmed) ? trimmed : `${trimmed}.`;\n}\n\nfunction stripSentence(text: string): string {\n const trimmed = text.trim();\n let end = trimmed.length;\n while (end > 0) {\n const char = trimmed[end - 1];\n if (char !== '.' && char !== '!' && char !== '?') break;\n end -= 1;\n }\n return trimmed.slice(0, end);\n}\n\nfunction lowercaseFirstWord(text: string): string {\n return text.replace(/^[A-Z][a-z]/, (match) => match.toLowerCase());\n}\n\nfunction formatDetails(details: string | string[] | undefined): string {\n if (!details) return '';\n const detailText = Array.isArray(details) ? details.join(', ') : details;\n if (!detailText.trim()) return '';\n return ensureSentence(`Details: ${detailText}`);\n}\n\nexport function formatDiagnosticErrorDetails(\n error: unknown\n): string | undefined {\n if (error == null) return undefined;\n return String(error);\n}\n\nexport function createDiagnosticMessage({\n source,\n severity,\n whatHappened,\n reassurance,\n why,\n fix,\n wayOut,\n details,\n docsUrl,\n}: DiagnosticMessageInput): string {\n const prefix = source\n ? severity\n ? `${source} ${severity}:`\n : `${source}:`\n : severity\n ? `${severity}:`\n : '';\n const whatAndWhy = why\n ? `${stripSentence(whatHappened)} because ${lowercaseFirstWord(stripSentence(why))}`\n : whatHappened;\n const shouldCombineWayOut =\n !!fix && !!wayOut && /^[a-z]/.test(stripSentence(wayOut));\n const fixAndWayOut = shouldCombineWayOut\n ? `${stripSentence(fix)}, or ${lowercaseFirstWord(stripSentence(wayOut))}`\n : fix;\n const messageParts = [\n whatAndWhy,\n reassurance,\n fixAndWayOut,\n shouldCombineWayOut ? undefined : wayOut,\n formatDetails(details),\n ]\n .filter((part): part is string => !!part)\n .map(ensureSentence);\n\n if (docsUrl) {\n messageParts.push(`Learn more: ${docsUrl}`);\n }\n\n const message = messageParts.join(' ');\n return prefix ? `${prefix} ${message}` : message;\n}\n","export const defaultCacheUrl = 'https://cdn.gtx.dev' as const;\nexport const defaultBaseUrl = 'https://api2.gtx.dev' as const;\nexport const defaultRuntimeApiUrl = 'https://runtime2.gtx.dev' as const;\n","import type { FileFormat } from '../types-dir/api/file';\n\nconst SUPPORTED_TRANSFORMATIONS = {\n GTJSON: ['GTJSON'],\n JSON: ['JSON'],\n PO: ['PO'],\n // POT templates can produce translated PO catalog files.\n POT: ['POT', 'PO'],\n YAML: ['YAML'],\n MDX: ['MDX'],\n MD: ['MD'],\n TS: ['TS'],\n JS: ['JS'],\n HTML: ['HTML'],\n TXT: ['TXT'],\n TWILIO_CONTENT_JSON: ['TWILIO_CONTENT_JSON'],\n} as const satisfies Record<FileFormat, FileFormat[]>;\n\n/**\n * This function checks if a file format transformation is supported during translation\n * @param from - The source file format.\n * @param to - The target file format.\n * @returns True if the transformation is supported, false otherwise\n */\nexport function isSupportedFileFormatTransform(\n from: FileFormat,\n to: FileFormat\n): boolean {\n const toFormats: FileFormat[] | undefined = SUPPORTED_TRANSFORMATIONS[from];\n return toFormats?.includes(to) ?? false;\n}\n","import type { FileFormat } from '../../types-dir/api/file';\nimport { isSupportedFileFormatTransform } from '../../utils/isSupportedFileFormatTransform';\n\nexport type FileFormatTransformInput = {\n fileFormat?: FileFormat;\n transformFormat?: FileFormat;\n fileName?: string;\n fileId?: string;\n};\n\n/**\n * Returns a user-facing validation error when a requested file format transform\n * is missing source format context or is not currently supported.\n */\nexport function getFileFormatTransformError(\n file: FileFormatTransformInput\n): string | undefined {\n if (!file.transformFormat) return undefined;\n const fileLabel = file.fileName ?? file.fileId ?? 'unknown file';\n if (!file.fileFormat) {\n return `fileFormat is required when transformFormat is provided for ${fileLabel}`;\n }\n if (!isSupportedFileFormatTransform(file.fileFormat, file.transformFormat)) {\n return `Unsupported file format transform: ${file.fileFormat} -> ${file.transformFormat}`;\n }\n return undefined;\n}\n\n/**\n * Validates file format transforms before sending upload/enqueue requests.\n */\nexport function validateFileFormatTransforms(\n files: FileFormatTransformInput[]\n): void {\n for (const file of files) {\n const error = getFileFormatTransformError(file);\n if (error) throw new Error(error);\n }\n}\n","// Encode a string to base64\nexport function encode(data: string): string {\n if (typeof Buffer !== 'undefined') {\n // Node.js path.\n return Buffer.from(data, 'utf8').toString('base64');\n }\n // Browser path.\n const bytes = new TextEncoder().encode(data);\n let binary = '';\n for (let i = 0; i < bytes.length; i++) {\n binary += String.fromCharCode(bytes[i]);\n }\n return btoa(binary);\n}\n\n// Decode a base64 string to a string\nexport function decode(base64: string): string {\n if (typeof Buffer !== 'undefined') {\n // Node.js path.\n return Buffer.from(base64, 'base64').toString('utf8');\n }\n // Browser path.\n const binary = atob(base64);\n const bytes = new Uint8Array(binary.length);\n for (let i = 0; i < binary.length; i++) {\n bytes[i] = binary.charCodeAt(i);\n }\n return new TextDecoder().decode(bytes);\n}\n"],"mappings":"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"}
|
|
@@ -2,6 +2,51 @@
|
|
|
2
2
|
const libraryDefaultLocale = "en";
|
|
3
3
|
const defaultTimeout = 6e4;
|
|
4
4
|
//#endregion
|
|
5
|
+
//#region src/logging/diagnostics.ts
|
|
6
|
+
function ensureSentence(text) {
|
|
7
|
+
const trimmed = text.trim();
|
|
8
|
+
if (!trimmed) return "";
|
|
9
|
+
return /[.!?)]$/.test(trimmed) ? trimmed : `${trimmed}.`;
|
|
10
|
+
}
|
|
11
|
+
function stripSentence(text) {
|
|
12
|
+
const trimmed = text.trim();
|
|
13
|
+
let end = trimmed.length;
|
|
14
|
+
while (end > 0) {
|
|
15
|
+
const char = trimmed[end - 1];
|
|
16
|
+
if (char !== "." && char !== "!" && char !== "?") break;
|
|
17
|
+
end -= 1;
|
|
18
|
+
}
|
|
19
|
+
return trimmed.slice(0, end);
|
|
20
|
+
}
|
|
21
|
+
function lowercaseFirstWord(text) {
|
|
22
|
+
return text.replace(/^[A-Z][a-z]/, (match) => match.toLowerCase());
|
|
23
|
+
}
|
|
24
|
+
function formatDetails(details) {
|
|
25
|
+
if (!details) return "";
|
|
26
|
+
const detailText = Array.isArray(details) ? details.join(", ") : details;
|
|
27
|
+
if (!detailText.trim()) return "";
|
|
28
|
+
return ensureSentence(`Details: ${detailText}`);
|
|
29
|
+
}
|
|
30
|
+
function formatDiagnosticErrorDetails(error) {
|
|
31
|
+
if (error == null) return void 0;
|
|
32
|
+
return String(error);
|
|
33
|
+
}
|
|
34
|
+
function createDiagnosticMessage({ source, severity, whatHappened, reassurance, why, fix, wayOut, details, docsUrl }) {
|
|
35
|
+
const prefix = source ? severity ? `${source} ${severity}:` : `${source}:` : severity ? `${severity}:` : "";
|
|
36
|
+
const whatAndWhy = why ? `${stripSentence(whatHappened)} because ${lowercaseFirstWord(stripSentence(why))}` : whatHappened;
|
|
37
|
+
const shouldCombineWayOut = !!fix && !!wayOut && /^[a-z]/.test(stripSentence(wayOut));
|
|
38
|
+
const messageParts = [
|
|
39
|
+
whatAndWhy,
|
|
40
|
+
reassurance,
|
|
41
|
+
shouldCombineWayOut ? `${stripSentence(fix)}, or ${lowercaseFirstWord(stripSentence(wayOut))}` : fix,
|
|
42
|
+
shouldCombineWayOut ? void 0 : wayOut,
|
|
43
|
+
formatDetails(details)
|
|
44
|
+
].filter((part) => !!part).map(ensureSentence);
|
|
45
|
+
if (docsUrl) messageParts.push(`Learn more: ${docsUrl}`);
|
|
46
|
+
const message = messageParts.join(" ");
|
|
47
|
+
return prefix ? `${prefix} ${message}` : message;
|
|
48
|
+
}
|
|
49
|
+
//#endregion
|
|
5
50
|
//#region src/settings/settingsUrls.ts
|
|
6
51
|
const defaultCacheUrl = "https://cdn.gtx.dev";
|
|
7
52
|
const defaultBaseUrl = "https://api2.gtx.dev";
|
|
@@ -69,6 +114,6 @@ function decode(base64) {
|
|
|
69
114
|
return new TextDecoder().decode(bytes);
|
|
70
115
|
}
|
|
71
116
|
//#endregion
|
|
72
|
-
export { defaultBaseUrl as a,
|
|
117
|
+
export { defaultBaseUrl as a, createDiagnosticMessage as c, libraryDefaultLocale as d, isSupportedFileFormatTransform as i, formatDiagnosticErrorDetails as l, encode as n, defaultCacheUrl as o, validateFileFormatTransforms as r, defaultRuntimeApiUrl as s, decode as t, defaultTimeout as u };
|
|
73
118
|
|
|
74
|
-
//# sourceMappingURL=base64-
|
|
119
|
+
//# sourceMappingURL=base64-r7YWJYWt.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"base64-r7YWJYWt.mjs","names":[],"sources":["../src/settings/settings.ts","../src/logging/diagnostics.ts","../src/settings/settingsUrls.ts","../src/utils/isSupportedFileFormatTransform.ts","../src/translate/utils/validateFileFormatTransform.ts","../src/utils/base64.ts"],"sourcesContent":["export const libraryDefaultLocale = 'en' as const;\nexport const defaultTimeout = 60000;\n","export type DiagnosticSeverity = 'Error' | 'Warning';\n\n/**\n * Text slots follow the five-part error message model:\n * what happened, reassurance, why it happened, how to fix it, and a way out.\n */\nexport type DiagnosticMessageInput = {\n source?: string;\n severity?: DiagnosticSeverity;\n whatHappened: string;\n reassurance?: string;\n why?: string;\n fix?: string;\n wayOut?: string;\n details?: string | string[];\n docsUrl?: string;\n};\n\nfunction ensureSentence(text: string): string {\n const trimmed = text.trim();\n if (!trimmed) return '';\n return /[.!?)]$/.test(trimmed) ? trimmed : `${trimmed}.`;\n}\n\nfunction stripSentence(text: string): string {\n const trimmed = text.trim();\n let end = trimmed.length;\n while (end > 0) {\n const char = trimmed[end - 1];\n if (char !== '.' && char !== '!' && char !== '?') break;\n end -= 1;\n }\n return trimmed.slice(0, end);\n}\n\nfunction lowercaseFirstWord(text: string): string {\n return text.replace(/^[A-Z][a-z]/, (match) => match.toLowerCase());\n}\n\nfunction formatDetails(details: string | string[] | undefined): string {\n if (!details) return '';\n const detailText = Array.isArray(details) ? details.join(', ') : details;\n if (!detailText.trim()) return '';\n return ensureSentence(`Details: ${detailText}`);\n}\n\nexport function formatDiagnosticErrorDetails(\n error: unknown\n): string | undefined {\n if (error == null) return undefined;\n return String(error);\n}\n\nexport function createDiagnosticMessage({\n source,\n severity,\n whatHappened,\n reassurance,\n why,\n fix,\n wayOut,\n details,\n docsUrl,\n}: DiagnosticMessageInput): string {\n const prefix = source\n ? severity\n ? `${source} ${severity}:`\n : `${source}:`\n : severity\n ? `${severity}:`\n : '';\n const whatAndWhy = why\n ? `${stripSentence(whatHappened)} because ${lowercaseFirstWord(stripSentence(why))}`\n : whatHappened;\n const shouldCombineWayOut =\n !!fix && !!wayOut && /^[a-z]/.test(stripSentence(wayOut));\n const fixAndWayOut = shouldCombineWayOut\n ? `${stripSentence(fix)}, or ${lowercaseFirstWord(stripSentence(wayOut))}`\n : fix;\n const messageParts = [\n whatAndWhy,\n reassurance,\n fixAndWayOut,\n shouldCombineWayOut ? undefined : wayOut,\n formatDetails(details),\n ]\n .filter((part): part is string => !!part)\n .map(ensureSentence);\n\n if (docsUrl) {\n messageParts.push(`Learn more: ${docsUrl}`);\n }\n\n const message = messageParts.join(' ');\n return prefix ? `${prefix} ${message}` : message;\n}\n","export const defaultCacheUrl = 'https://cdn.gtx.dev' as const;\nexport const defaultBaseUrl = 'https://api2.gtx.dev' as const;\nexport const defaultRuntimeApiUrl = 'https://runtime2.gtx.dev' as const;\n","import type { FileFormat } from '../types-dir/api/file';\n\nconst SUPPORTED_TRANSFORMATIONS = {\n GTJSON: ['GTJSON'],\n JSON: ['JSON'],\n PO: ['PO'],\n // POT templates can produce translated PO catalog files.\n POT: ['POT', 'PO'],\n YAML: ['YAML'],\n MDX: ['MDX'],\n MD: ['MD'],\n TS: ['TS'],\n JS: ['JS'],\n HTML: ['HTML'],\n TXT: ['TXT'],\n TWILIO_CONTENT_JSON: ['TWILIO_CONTENT_JSON'],\n} as const satisfies Record<FileFormat, FileFormat[]>;\n\n/**\n * This function checks if a file format transformation is supported during translation\n * @param from - The source file format.\n * @param to - The target file format.\n * @returns True if the transformation is supported, false otherwise\n */\nexport function isSupportedFileFormatTransform(\n from: FileFormat,\n to: FileFormat\n): boolean {\n const toFormats: FileFormat[] | undefined = SUPPORTED_TRANSFORMATIONS[from];\n return toFormats?.includes(to) ?? false;\n}\n","import type { FileFormat } from '../../types-dir/api/file';\nimport { isSupportedFileFormatTransform } from '../../utils/isSupportedFileFormatTransform';\n\nexport type FileFormatTransformInput = {\n fileFormat?: FileFormat;\n transformFormat?: FileFormat;\n fileName?: string;\n fileId?: string;\n};\n\n/**\n * Returns a user-facing validation error when a requested file format transform\n * is missing source format context or is not currently supported.\n */\nexport function getFileFormatTransformError(\n file: FileFormatTransformInput\n): string | undefined {\n if (!file.transformFormat) return undefined;\n const fileLabel = file.fileName ?? file.fileId ?? 'unknown file';\n if (!file.fileFormat) {\n return `fileFormat is required when transformFormat is provided for ${fileLabel}`;\n }\n if (!isSupportedFileFormatTransform(file.fileFormat, file.transformFormat)) {\n return `Unsupported file format transform: ${file.fileFormat} -> ${file.transformFormat}`;\n }\n return undefined;\n}\n\n/**\n * Validates file format transforms before sending upload/enqueue requests.\n */\nexport function validateFileFormatTransforms(\n files: FileFormatTransformInput[]\n): void {\n for (const file of files) {\n const error = getFileFormatTransformError(file);\n if (error) throw new Error(error);\n }\n}\n","// Encode a string to base64\nexport function encode(data: string): string {\n if (typeof Buffer !== 'undefined') {\n // Node.js path.\n return Buffer.from(data, 'utf8').toString('base64');\n }\n // Browser path.\n const bytes = new TextEncoder().encode(data);\n let binary = '';\n for (let i = 0; i < bytes.length; i++) {\n binary += String.fromCharCode(bytes[i]);\n }\n return btoa(binary);\n}\n\n// Decode a base64 string to a string\nexport function decode(base64: string): string {\n if (typeof Buffer !== 'undefined') {\n // Node.js path.\n return Buffer.from(base64, 'base64').toString('utf8');\n }\n // Browser path.\n const binary = atob(base64);\n const bytes = new Uint8Array(binary.length);\n for (let i = 0; i < binary.length; i++) {\n bytes[i] = binary.charCodeAt(i);\n }\n return new TextDecoder().decode(bytes);\n}\n"],"mappings":"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"}
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Given an indexed ICU string, condenses any select to an argument
|
|
3
|
+
* Unindexed _gt_ source strings and indexed _gt_# translation strings
|
|
4
|
+
* are mutually exclusive.
|
|
3
5
|
* indexVars('Hello {_gt_1, select, other {World}}') => 'Hello {_gt_1}'
|
|
4
6
|
* @param {string} icuString - The ICU string to condense.
|
|
5
7
|
* @returns {string} The condensed ICU string.
|
|
@@ -3,15 +3,18 @@ import { printAST } from '@formatjs/icu-messageformat-parser/printer.js';
|
|
|
3
3
|
import { traverseIcu } from './utils/traverseIcu';
|
|
4
4
|
import { VAR_IDENTIFIER } from './utils/constants';
|
|
5
5
|
import { isGTIndexedSelectElement } from './utils/traverseHelpers';
|
|
6
|
+
var CONTAINS_INDEXED_GT_REGEX = new RegExp("".concat(VAR_IDENTIFIER, "\\d+"));
|
|
6
7
|
/**
|
|
7
8
|
* Given an indexed ICU string, condenses any select to an argument
|
|
9
|
+
* Unindexed _gt_ source strings and indexed _gt_# translation strings
|
|
10
|
+
* are mutually exclusive.
|
|
8
11
|
* indexVars('Hello {_gt_1, select, other {World}}') => 'Hello {_gt_1}'
|
|
9
12
|
* @param {string} icuString - The ICU string to condense.
|
|
10
13
|
* @returns {string} The condensed ICU string.
|
|
11
14
|
*/
|
|
12
15
|
export function condenseVars(icuString) {
|
|
13
|
-
// Check if the string contains _gt_
|
|
14
|
-
if (!
|
|
16
|
+
// Check if the string contains an indexed _gt_ identifier.
|
|
17
|
+
if (!CONTAINS_INDEXED_GT_REGEX.test(icuString)) {
|
|
15
18
|
return icuString;
|
|
16
19
|
}
|
|
17
20
|
// Replace with argument
|
package/dist/id.d.cts
CHANGED
package/dist/id.d.mts
CHANGED
package/dist/index.cjs
CHANGED
|
@@ -1,20 +1,72 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
-
const require_base64 = require("./base64-
|
|
2
|
+
const require_base64 = require("./base64-YBGAXkqy.cjs");
|
|
3
3
|
const require_ApiError = require("./ApiError-D-IBuHj6.cjs");
|
|
4
4
|
const require_id = require("./id-C2orn1MA.cjs");
|
|
5
5
|
let _generaltranslation_format = require("@generaltranslation/format");
|
|
6
6
|
//#region src/logging/errors.ts
|
|
7
|
-
const
|
|
8
|
-
const translationTimeoutError = (timeout) =>
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
const
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
7
|
+
const GT_SOURCE = "GT";
|
|
8
|
+
const translationTimeoutError = (timeout) => require_base64.createDiagnosticMessage({
|
|
9
|
+
source: GT_SOURCE,
|
|
10
|
+
severity: "Error",
|
|
11
|
+
whatHappened: `Translation request timed out after ${timeout}ms`,
|
|
12
|
+
fix: "Try again, or increase the request timeout if the source content is large"
|
|
13
|
+
});
|
|
14
|
+
const translationRequestFailedError = (error) => require_base64.createDiagnosticMessage({
|
|
15
|
+
source: GT_SOURCE,
|
|
16
|
+
severity: "Error",
|
|
17
|
+
whatHappened: "Translation request could not be completed",
|
|
18
|
+
fix: "Check your network connection and translation credentials, then try again",
|
|
19
|
+
details: error
|
|
20
|
+
});
|
|
21
|
+
const apiError = (status, statusText, error) => require_base64.createDiagnosticMessage({
|
|
22
|
+
source: GT_SOURCE,
|
|
23
|
+
severity: "Error",
|
|
24
|
+
whatHappened: `The translation API returned ${status} ${statusText}`,
|
|
25
|
+
fix: "Check the request configuration and try again",
|
|
26
|
+
details: error
|
|
27
|
+
});
|
|
28
|
+
require_base64.createDiagnosticMessage({
|
|
29
|
+
source: GT_SOURCE,
|
|
30
|
+
severity: "Error",
|
|
31
|
+
whatHappened: "Authentication failed",
|
|
32
|
+
fix: "Check that your API key and project ID are correct"
|
|
33
|
+
});
|
|
34
|
+
const noTargetLocaleProvidedError = (functionName) => require_base64.createDiagnosticMessage({
|
|
35
|
+
source: GT_SOURCE,
|
|
36
|
+
severity: "Error",
|
|
37
|
+
whatHappened: `Cannot call \`${functionName}\` without a specified locale`,
|
|
38
|
+
fix: `Pass a locale to \`${functionName}\` or specify targetLocale in the GT constructor`
|
|
39
|
+
});
|
|
40
|
+
const noSourceLocaleProvidedError = (functionName) => require_base64.createDiagnosticMessage({
|
|
41
|
+
source: GT_SOURCE,
|
|
42
|
+
severity: "Error",
|
|
43
|
+
whatHappened: `Cannot call \`${functionName}\` without a specified locale`,
|
|
44
|
+
fix: `Pass a locale to \`${functionName}\` or specify sourceLocale in the GT constructor`
|
|
45
|
+
});
|
|
46
|
+
const noProjectIdProvidedError = (functionName) => require_base64.createDiagnosticMessage({
|
|
47
|
+
source: GT_SOURCE,
|
|
48
|
+
severity: "Error",
|
|
49
|
+
whatHappened: `Cannot call \`${functionName}\` without a specified project ID`,
|
|
50
|
+
fix: `Pass a project ID to \`${functionName}\` or specify projectId in the GT constructor`
|
|
51
|
+
});
|
|
52
|
+
const noApiKeyProvidedError = (functionName) => require_base64.createDiagnosticMessage({
|
|
53
|
+
source: GT_SOURCE,
|
|
54
|
+
severity: "Error",
|
|
55
|
+
whatHappened: `Cannot call \`${functionName}\` without a specified API key`,
|
|
56
|
+
fix: `Pass an API key to \`${functionName}\` or specify apiKey in the GT constructor`
|
|
57
|
+
});
|
|
58
|
+
const invalidLocaleError = (locale) => require_base64.createDiagnosticMessage({
|
|
59
|
+
source: GT_SOURCE,
|
|
60
|
+
severity: "Error",
|
|
61
|
+
whatHappened: `Locale "${locale}" is not valid`,
|
|
62
|
+
fix: "Use a valid BCP 47 locale code or add a custom mapping"
|
|
63
|
+
});
|
|
64
|
+
const invalidLocalesError = (locales) => require_base64.createDiagnosticMessage({
|
|
65
|
+
source: GT_SOURCE,
|
|
66
|
+
severity: "Error",
|
|
67
|
+
whatHappened: `These locales are not valid: ${locales.join(", ")}`,
|
|
68
|
+
fix: "Use valid BCP 47 locale codes or add custom mappings"
|
|
69
|
+
});
|
|
18
70
|
//#endregion
|
|
19
71
|
//#region src/logging/logger.ts
|
|
20
72
|
const LOG_LEVELS = {
|