generaltranslation 9.0.3 → 9.0.5

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 (48) hide show
  1. package/CHANGELOG.md +22 -0
  2. package/dist/derive/condenseVars.js +2 -3
  3. package/dist/derive/utils/traverseHelpers.d.ts +1 -1
  4. package/dist/derive/utils/traverseHelpers.js +1 -1
  5. package/dist/derive/utils/traverseIcu.d.ts +1 -1
  6. package/dist/derive/utils/traverseIcu.js +1 -1
  7. package/dist/derive/utils/types.d.ts +1 -1
  8. package/dist/{derive-BvtWyo5B.cjs → derive-Cbl7M1SY.cjs} +7 -7
  9. package/dist/derive-Cbl7M1SY.cjs.map +1 -0
  10. package/dist/{derive-ClAsLQOX.mjs → derive-DDwuyrKI.mjs} +2 -2
  11. package/dist/derive-DDwuyrKI.mjs.map +1 -0
  12. package/dist/id.d.cts +1 -1
  13. package/dist/id.d.mts +1 -1
  14. package/dist/index.cjs +30 -13
  15. package/dist/index.cjs.map +1 -1
  16. package/dist/index.d.cts +4 -4
  17. package/dist/index.d.mts +4 -4
  18. package/dist/index.d.ts +3 -3
  19. package/dist/index.js +7 -5
  20. package/dist/index.mjs +30 -13
  21. package/dist/index.mjs.map +1 -1
  22. package/dist/internal.cjs +4 -97
  23. package/dist/internal.cjs.map +1 -1
  24. package/dist/internal.d.cts +1 -1
  25. package/dist/internal.d.mts +1 -1
  26. package/dist/internal.mjs +3 -96
  27. package/dist/internal.mjs.map +1 -1
  28. package/dist/{runtime-WSpZppgm.mjs → runtime-DsKdTOSO.mjs} +2 -2
  29. package/dist/{runtime-WSpZppgm.mjs.map → runtime-DsKdTOSO.mjs.map} +1 -1
  30. package/dist/{runtime-wK7jzE9f.cjs → runtime-mKpF6P4Q.cjs} +2 -2
  31. package/dist/{runtime-wK7jzE9f.cjs.map → runtime-mKpF6P4Q.cjs.map} +1 -1
  32. package/dist/runtime.cjs +1 -1
  33. package/dist/runtime.d.cts +2 -2
  34. package/dist/runtime.d.mts +2 -2
  35. package/dist/runtime.d.ts +1 -1
  36. package/dist/runtime.js +3 -3
  37. package/dist/runtime.mjs +1 -1
  38. package/dist/translate/awaitJobs.js +76 -32
  39. package/dist/types-dir/config.d.ts +2 -0
  40. package/dist/{types-algPgkHv.d.mts → types-iO493WgK.d.mts} +3 -2
  41. package/dist/{types-f-_m5D_X.d.cts → types-wj-Dtih8.d.cts} +3 -2
  42. package/dist/types.d.cts +1 -1
  43. package/dist/types.d.mts +1 -1
  44. package/package.json +3 -4
  45. package/dist/derive/utils/printIcuAst.d.ts +0 -12
  46. package/dist/derive/utils/printIcuAst.js +0 -138
  47. package/dist/derive-BvtWyo5B.cjs.map +0 -1
  48. package/dist/derive-ClAsLQOX.mjs.map +0 -1
package/CHANGELOG.md CHANGED
@@ -1,5 +1,27 @@
1
1
  # generaltranslation
2
2
 
3
+ ## 9.0.5
4
+
5
+ ### Patch Changes
6
+
7
+ - [#1889](https://github.com/generaltranslation/gt/pull/1889) [`29cd6b8`](https://github.com/generaltranslation/gt/commit/29cd6b89f3587d3253cfadde6bec925d8697324b) Thanks [@bgub](https://github.com/bgub)! - Allow `awaitJobs()` to poll job IDs directly and reuse that shared polling implementation for CLI and Sanity project setup.
8
+
9
+ - Updated dependencies [[`e55aaa9`](https://github.com/generaltranslation/gt/commit/e55aaa9cfdf6dfe3ab96d0eea927f255b66cd20d)]:
10
+ - @generaltranslation/icu@0.1.1
11
+ - @generaltranslation/format@0.1.4
12
+
13
+ ## 9.0.4
14
+
15
+ ### Patch Changes
16
+
17
+ - [#1974](https://github.com/generaltranslation/gt/pull/1974) [`bbf4eb0`](https://github.com/generaltranslation/gt/commit/bbf4eb0cf77160baa615776619acd7afe35697ba) Thanks [@ErnestM1234](https://github.com/ErnestM1234)! - Add opt-in locale routing for TanStack Start. Setting `localeRouting` in `gt.config.json` makes `gtMiddleware` prioritize locale path prefixes and updates client locale changes to keep the pathname in sync while leaving the default locale unprefixed.
18
+
19
+ - [#1929](https://github.com/generaltranslation/gt/pull/1929) [`f53bb5e`](https://github.com/generaltranslation/gt/commit/f53bb5ea4b4989a2a4ad3aebf464011f01e029ad) Thanks [@ErnestM1234](https://github.com/ErnestM1234)! - Replace the FormatJS ICU parser and runtime formatter dependencies with the new dependency-free `@generaltranslation/icu` package.
20
+
21
+ - Updated dependencies [[`f53bb5e`](https://github.com/generaltranslation/gt/commit/f53bb5ea4b4989a2a4ad3aebf464011f01e029ad)]:
22
+ - @generaltranslation/icu@0.1.0
23
+ - @generaltranslation/format@0.1.3
24
+
3
25
  ## 9.0.3
4
26
 
5
27
  ### Patch Changes
@@ -1,5 +1,4 @@
1
- import { TYPE } from '@formatjs/icu-messageformat-parser';
2
- import { printIcuAst } from './utils/printIcuAst';
1
+ import { printAST, TYPE } from '@generaltranslation/icu';
3
2
  import { traverseIcu } from './utils/traverseIcu';
4
3
  import { VAR_IDENTIFIER } from './utils/constants';
5
4
  import { isGTIndexedSelectElement } from './utils/traverseHelpers';
@@ -29,5 +28,5 @@ export function condenseVars(icuString) {
29
28
  options: { recurseIntoVisited: false },
30
29
  });
31
30
  // Serialize
32
- return printIcuAst(ast);
31
+ return printAST(ast);
33
32
  }
@@ -1,4 +1,4 @@
1
1
  import { GTIndexedSelectElement, GTUnindexedSelectElement } from './types';
2
- import type { MessageFormatElement } from '@formatjs/icu-messageformat-parser/types.js';
2
+ import { type MessageFormatElement } from '@generaltranslation/icu';
3
3
  export declare function isGTIndexedSelectElement(child: MessageFormatElement): child is GTIndexedSelectElement;
4
4
  export declare function isGTUnindexedSelectElement(child: MessageFormatElement): child is GTUnindexedSelectElement;
@@ -1,5 +1,5 @@
1
1
  import { GT_INDEXED_IDENTIFIER_REGEX, GT_UNINDEXED_IDENTIFIER_REGEX, } from './regex';
2
- import { TYPE } from '@formatjs/icu-messageformat-parser';
2
+ import { TYPE } from '@generaltranslation/icu';
3
3
  // Visit any _gt_# select
4
4
  export function isGTIndexedSelectElement(child) {
5
5
  var _a;
@@ -1,4 +1,4 @@
1
- import { MessageFormatElement, ParserOptions } from '@formatjs/icu-messageformat-parser';
1
+ import { type MessageFormatElement, type ParserOptions } from '@generaltranslation/icu';
2
2
  type TraverseIcuOptions = ParserOptions & {
3
3
  recurseIntoVisited?: boolean;
4
4
  };
@@ -9,7 +9,7 @@ var __rest = (this && this.__rest) || function (s, e) {
9
9
  }
10
10
  return t;
11
11
  };
12
- import { parse, TYPE, } from '@formatjs/icu-messageformat-parser';
12
+ import { parse, TYPE, } from '@generaltranslation/icu';
13
13
  /**
14
14
  * Given an ICU string, traverse the AST and call the visitor function for each element that matches the type T
15
15
  * @param icu - The ICU string to traverse
@@ -1,5 +1,5 @@
1
1
  import { VAR_IDENTIFIER } from './constants';
2
- import type { PluralOrSelectOption, LiteralElement, SelectElement } from '@formatjs/icu-messageformat-parser/types.js';
2
+ import type { PluralOrSelectOption, LiteralElement, SelectElement } from '@generaltranslation/icu';
3
3
  interface GTIndexedSelectOption extends PluralOrSelectOption {
4
4
  value: Array<LiteralElement>;
5
5
  }
@@ -1,4 +1,4 @@
1
- let _formatjs_icu_messageformat_parser = require("@formatjs/icu-messageformat-parser");
1
+ let _generaltranslation_icu = require("@generaltranslation/icu");
2
2
  //#region src/utils/isSupportedFileFormatTransform.ts
3
3
  const SUPPORTED_TRANSFORMATIONS = {
4
4
  GTJSON: ["GTJSON"],
@@ -51,7 +51,7 @@ function decode(base64) {
51
51
  * @note This function is a heavy operation, use sparingly
52
52
  */
53
53
  function traverseIcu({ icuString, shouldVisit, visitor, options: { recurseIntoVisited = true, ...otherOptions } }) {
54
- const ast = (0, _formatjs_icu_messageformat_parser.parse)(icuString, otherOptions);
54
+ const ast = (0, _generaltranslation_icu.parse)(icuString, otherOptions);
55
55
  handleChildren(ast);
56
56
  return ast;
57
57
  function handleChildren(children) {
@@ -64,8 +64,8 @@ function traverseIcu({ icuString, shouldVisit, visitor, options: { recurseIntoVi
64
64
  visited = true;
65
65
  }
66
66
  if (!visited || recurseIntoVisited) {
67
- if (child.type === _formatjs_icu_messageformat_parser.TYPE.select || child.type === _formatjs_icu_messageformat_parser.TYPE.plural) Object.values(child.options).map((option) => option.value).map(handleChildren);
68
- else if (child.type === _formatjs_icu_messageformat_parser.TYPE.tag) handleChildren(child.children);
67
+ if (child.type === _generaltranslation_icu.TYPE.select || child.type === _generaltranslation_icu.TYPE.plural) Object.values(child.options).map((option) => option.value).map(handleChildren);
68
+ else if (child.type === _generaltranslation_icu.TYPE.tag) handleChildren(child.children);
69
69
  }
70
70
  }
71
71
  }
@@ -80,10 +80,10 @@ const GT_UNINDEXED_IDENTIFIER_REGEX = new RegExp(`^${VAR_IDENTIFIER}$`);
80
80
  //#endregion
81
81
  //#region src/derive/utils/traverseHelpers.ts
82
82
  function isGTIndexedSelectElement(child) {
83
- return child.type === _formatjs_icu_messageformat_parser.TYPE.select && GT_INDEXED_IDENTIFIER_REGEX.test(child.value) && !!child.options.other && (child.options.other.value.length === 0 || child.options.other.value.length > 0 && child.options.other.value[0]?.type === _formatjs_icu_messageformat_parser.TYPE.literal);
83
+ return child.type === _generaltranslation_icu.TYPE.select && GT_INDEXED_IDENTIFIER_REGEX.test(child.value) && !!child.options.other && (child.options.other.value.length === 0 || child.options.other.value.length > 0 && child.options.other.value[0]?.type === _generaltranslation_icu.TYPE.literal);
84
84
  }
85
85
  function isGTUnindexedSelectElement(child) {
86
- return child.type === _formatjs_icu_messageformat_parser.TYPE.select && GT_UNINDEXED_IDENTIFIER_REGEX.test(child.value) && !!child.options.other && (child.options.other.value.length === 0 || child.options.other.value.length > 0 && child.options.other.value[0]?.type === _formatjs_icu_messageformat_parser.TYPE.literal);
86
+ return child.type === _generaltranslation_icu.TYPE.select && GT_UNINDEXED_IDENTIFIER_REGEX.test(child.value) && !!child.options.other && (child.options.other.value.length === 0 || child.options.other.value.length > 0 && child.options.other.value[0]?.type === _generaltranslation_icu.TYPE.literal);
87
87
  }
88
88
  //#endregion
89
89
  //#region src/derive/decodeVars.ts
@@ -275,4 +275,4 @@ Object.defineProperty(exports, "traverseIcu", {
275
275
  }
276
276
  });
277
277
 
278
- //# sourceMappingURL=derive-BvtWyo5B.cjs.map
278
+ //# sourceMappingURL=derive-Cbl7M1SY.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"derive-Cbl7M1SY.cjs","names":["TYPE","TYPE"],"sources":["../src/utils/isSupportedFileFormatTransform.ts","../src/utils/base64.ts","../src/derive/utils/traverseIcu.ts","../src/derive/utils/constants.ts","../src/derive/utils/regex.ts","../src/derive/utils/traverseHelpers.ts","../src/derive/decodeVars.ts","../src/derive/utils/sanitizeVar.ts","../src/derive/declareVar.ts","../src/derive/derive.ts"],"sourcesContent":["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","// 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","import {\n parse,\n TYPE,\n type MessageFormatElement,\n type ParserOptions,\n} from '@generaltranslation/icu';\n\ntype TraverseIcuOptions = ParserOptions & {\n recurseIntoVisited?: boolean;\n};\n\n/**\n * Given an ICU string, traverse the AST and call the visitor function for each element that matches the type T\n * @param icu - The ICU string to traverse\n * @param shouldVisit - A function that returns true if the element should be visited\n * @param visitor - A function that is called for each element that matches the type T\n * @returns The modified AST of the ICU string.\n *\n * @note This function is a heavy operation, use sparingly\n */\nexport function traverseIcu<T extends MessageFormatElement>({\n icuString,\n shouldVisit,\n visitor,\n options: { recurseIntoVisited = true, ...otherOptions },\n}: {\n icuString: string;\n shouldVisit: (element: MessageFormatElement) => element is T;\n visitor: (element: T) => void;\n options: TraverseIcuOptions;\n}): MessageFormatElement[] {\n const ast = parse(icuString, otherOptions);\n handleChildren(ast);\n return ast;\n\n function handleChildren(children: MessageFormatElement[]): void {\n children.map(handleChild);\n }\n\n function handleChild(child: MessageFormatElement) {\n // handle select var\n let visited = false;\n if (shouldVisit(child)) {\n visitor(child);\n visited = true;\n }\n // recurse on children\n if (!visited || recurseIntoVisited) {\n if (child.type === TYPE.select || child.type === TYPE.plural) {\n Object.values(child.options)\n .map((option) => option.value)\n .map(handleChildren);\n } else if (child.type === TYPE.tag) {\n handleChildren(child.children);\n }\n }\n }\n}\n","export const VAR_IDENTIFIER = '_gt_';\nexport const VAR_NAME_IDENTIFIER = '_gt_var_name';\n","import { VAR_IDENTIFIER } from './constants';\n\n// Regex for _gt_# select\nexport const GT_INDEXED_IDENTIFIER_REGEX = new RegExp(\n `^${VAR_IDENTIFIER}\\\\d+$`\n);\n\nexport const GT_UNINDEXED_IDENTIFIER_REGEX = new RegExp(`^${VAR_IDENTIFIER}$`);\n","import {\n GT_INDEXED_IDENTIFIER_REGEX,\n GT_UNINDEXED_IDENTIFIER_REGEX,\n} from './regex';\nimport { GTIndexedSelectElement, GTUnindexedSelectElement } from './types';\nimport { TYPE, type MessageFormatElement } from '@generaltranslation/icu';\n\n// Visit any _gt_# select\nexport function isGTIndexedSelectElement(\n child: MessageFormatElement\n): child is GTIndexedSelectElement {\n return (\n child.type === TYPE.select &&\n GT_INDEXED_IDENTIFIER_REGEX.test(child.value) &&\n !!child.options.other &&\n (child.options.other.value.length === 0 ||\n (child.options.other.value.length > 0 &&\n child.options.other.value[0]?.type === TYPE.literal))\n );\n}\n\n// Visit any _gt_ select\nexport function isGTUnindexedSelectElement(\n child: MessageFormatElement\n): child is GTUnindexedSelectElement {\n return (\n child.type === TYPE.select &&\n GT_UNINDEXED_IDENTIFIER_REGEX.test(child.value) &&\n !!child.options.other &&\n (child.options.other.value.length === 0 ||\n (child.options.other.value.length > 0 &&\n child.options.other.value[0]?.type === TYPE.literal))\n );\n}\n","import { traverseIcu } from './utils/traverseIcu';\nimport { VAR_IDENTIFIER } from './utils/constants';\nimport { GTUnindexedSelectElement } from './utils/types';\nimport { isGTUnindexedSelectElement } from './utils/traverseHelpers';\n\ntype Location = {\n start: number;\n end: number;\n value: string;\n};\n\n/**\n * Given an encoded ICU string, interpolate only _gt_ variables that have been marked with declareVar()\n * @example\n * const encodedIcu = \"Hi\" + declareVar(\"Brian\") + \", my name is {name}\"\n * // 'Hi {_gt_, select, other {Brian}}, my name is {name}'\n * decodeVars(encodedIcu)\n * // 'Hi Brian, my name is {name}'\n */\nexport function decodeVars(icuString: string): string {\n // Check if the string contains _gt_\n if (!icuString.includes(VAR_IDENTIFIER)) {\n return icuString;\n }\n\n // Record the location of the variable\n const variableLocations: Location[] = [];\n function visitor(child: GTUnindexedSelectElement): void {\n variableLocations.push({\n start: child.location?.start.offset ?? 0,\n end: child.location?.end.offset ?? 0,\n value:\n child.options.other.value.length > 0\n ? child.options.other.value[0].value\n : '',\n });\n }\n\n // Find all variable identifiers.\n traverseIcu({\n icuString,\n shouldVisit: isGTUnindexedSelectElement,\n visitor,\n options: {\n recurseIntoVisited: false,\n captureLocation: true,\n },\n });\n\n // Construct output string\n let previousIndex = 0;\n const outputList = [];\n for (let i = 0; i < variableLocations.length; i++) {\n outputList.push(icuString.slice(previousIndex, variableLocations[i].start));\n outputList.push(variableLocations[i].value);\n previousIndex = variableLocations[i].end;\n }\n if (previousIndex < icuString.length) {\n outputList.push(icuString.slice(previousIndex));\n }\n const outputString = outputList.join('');\n\n return outputString;\n}\n","/**\n * Sanitizes string by escaping ICU syntax\n *\n * Sanitize arbitrary string so it does not break the following ICU message syntax:\n * {_gt_, select, other {string_here}}\n *\n * Escapes ICU special characters by:\n * 1. Doubling all single quotes (U+0027 ')\n * 2. Adding a single quote before the first special character ({}<>)\n * 3. Adding a single quote after the last special character ({}<>)\n */\nexport function sanitizeVar(string: string): string {\n // First, double all single quotes (both ASCII and Unicode).\n let result = string.replace(/'/g, \"''\");\n\n // Find first and last positions of special characters\n const specialChars = /[{}<>]/;\n const firstSpecialIndex = result.search(specialChars);\n\n if (firstSpecialIndex === -1) {\n // No special characters; return with just doubled quotes.\n return result;\n }\n\n // Find last special character position\n let lastSpecialIndex = -1;\n for (let i = result.length - 1; i >= 0; i--) {\n if (specialChars.test(result[i])) {\n lastSpecialIndex = i;\n break;\n }\n }\n\n // Insert quotes around the special character region.\n result =\n result.slice(0, firstSpecialIndex) +\n \"'\" +\n result.slice(firstSpecialIndex, lastSpecialIndex + 1) +\n \"'\" +\n result.slice(lastSpecialIndex + 1);\n\n return result;\n}\n","import { VAR_IDENTIFIER, VAR_NAME_IDENTIFIER } from './utils/constants';\nimport { sanitizeVar } from './utils/sanitizeVar';\n\n/**\n * Mark as a non-translatable string. Use within a derive() call to mark content as not derivable (e.g., not possible to statically analyze).\n *\n * @example\n * function nonDerivableFunction() {\n * return Math.random();\n * }\n *\n * function derivableFunction() {\n * if (condition) {\n * return declareVar(nonDerivableFunction())\n * }\n * return 'John Doe';\n * }\n *\n * const gt = useGT();\n * gt(`My name is ${derive(derivableFunction())}`);\n *\n * @param {string | number | boolean | null | undefined} variable - The variable to sanitize.\n * @param {Object} [options] - The options for the sanitization.\n * @param {string} [options.$name] - The name of the variable.\n * @returns {string} The sanitized value.\n */\nexport function declareVar(\n variable: string | number | boolean | null | undefined,\n options?: { $name?: string }\n): string {\n // Variable section.\n const sanitizedVariable = sanitizeVar(String(variable ?? ''));\n const variableSection = ` other {${sanitizedVariable}}`;\n\n // Name section.\n let nameSection = '';\n if (options?.$name) {\n const sanitizedName = sanitizeVar(options.$name);\n nameSection = ` ${VAR_NAME_IDENTIFIER} {${sanitizedName}}`;\n }\n\n // interpolate\n return `{${VAR_IDENTIFIER}, select,${variableSection}${nameSection}}`;\n}\n","/**\n * Marks content as derivable by the GT compiler and CLI.\n *\n * Use `derive()` when a translation string or context needs content that is\n * computed from source code, but should still be discovered during extraction\n * instead of treated as a runtime interpolation variable. The CLI attempts to\n * resolve the derivable expression into every possible static value and\n * includes those values in the source content that gets translated.\n *\n * `derive()` returns its argument unchanged at runtime.\n *\n * Run `gt validate` after adding or changing `derive()` calls to verify that\n * each derivable expression can be resolved by the CLI before translating or\n * building.\n *\n * @example\n * ```jsx\n * function getSubject() {\n * return (Math.random() > 0.5) ? \"Alice\" : \"Brian\";\n * }\n * ...\n * gt(`My name is ${derive(getSubject())}`);\n * ```\n *\n * @param {T extends string | boolean | number | null | undefined} content - Content to derive for translation extraction.\n * @returns {T} The same content, unchanged at runtime.\n */\nexport function derive<T extends string | boolean | number | null | undefined>(\n content: T\n): T {\n return content;\n}\n"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import { TYPE, parse } from "@formatjs/icu-messageformat-parser";
1
+ import { TYPE, parse } from "@generaltranslation/icu";
2
2
  //#region src/utils/isSupportedFileFormatTransform.ts
3
3
  const SUPPORTED_TRANSFORMATIONS = {
4
4
  GTJSON: ["GTJSON"],
@@ -216,4 +216,4 @@ function derive(content) {
216
216
  //#endregion
217
217
  export { isGTUnindexedSelectElement as a, decode as c, isGTIndexedSelectElement as i, encode as l, declareVar as n, VAR_IDENTIFIER as o, decodeVars as r, traverseIcu as s, derive as t, isSupportedFileFormatTransform as u };
218
218
 
219
- //# sourceMappingURL=derive-ClAsLQOX.mjs.map
219
+ //# sourceMappingURL=derive-DDwuyrKI.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"derive-DDwuyrKI.mjs","names":[],"sources":["../src/utils/isSupportedFileFormatTransform.ts","../src/utils/base64.ts","../src/derive/utils/traverseIcu.ts","../src/derive/utils/constants.ts","../src/derive/utils/regex.ts","../src/derive/utils/traverseHelpers.ts","../src/derive/decodeVars.ts","../src/derive/utils/sanitizeVar.ts","../src/derive/declareVar.ts","../src/derive/derive.ts"],"sourcesContent":["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","// 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","import {\n parse,\n TYPE,\n type MessageFormatElement,\n type ParserOptions,\n} from '@generaltranslation/icu';\n\ntype TraverseIcuOptions = ParserOptions & {\n recurseIntoVisited?: boolean;\n};\n\n/**\n * Given an ICU string, traverse the AST and call the visitor function for each element that matches the type T\n * @param icu - The ICU string to traverse\n * @param shouldVisit - A function that returns true if the element should be visited\n * @param visitor - A function that is called for each element that matches the type T\n * @returns The modified AST of the ICU string.\n *\n * @note This function is a heavy operation, use sparingly\n */\nexport function traverseIcu<T extends MessageFormatElement>({\n icuString,\n shouldVisit,\n visitor,\n options: { recurseIntoVisited = true, ...otherOptions },\n}: {\n icuString: string;\n shouldVisit: (element: MessageFormatElement) => element is T;\n visitor: (element: T) => void;\n options: TraverseIcuOptions;\n}): MessageFormatElement[] {\n const ast = parse(icuString, otherOptions);\n handleChildren(ast);\n return ast;\n\n function handleChildren(children: MessageFormatElement[]): void {\n children.map(handleChild);\n }\n\n function handleChild(child: MessageFormatElement) {\n // handle select var\n let visited = false;\n if (shouldVisit(child)) {\n visitor(child);\n visited = true;\n }\n // recurse on children\n if (!visited || recurseIntoVisited) {\n if (child.type === TYPE.select || child.type === TYPE.plural) {\n Object.values(child.options)\n .map((option) => option.value)\n .map(handleChildren);\n } else if (child.type === TYPE.tag) {\n handleChildren(child.children);\n }\n }\n }\n}\n","export const VAR_IDENTIFIER = '_gt_';\nexport const VAR_NAME_IDENTIFIER = '_gt_var_name';\n","import { VAR_IDENTIFIER } from './constants';\n\n// Regex for _gt_# select\nexport const GT_INDEXED_IDENTIFIER_REGEX = new RegExp(\n `^${VAR_IDENTIFIER}\\\\d+$`\n);\n\nexport const GT_UNINDEXED_IDENTIFIER_REGEX = new RegExp(`^${VAR_IDENTIFIER}$`);\n","import {\n GT_INDEXED_IDENTIFIER_REGEX,\n GT_UNINDEXED_IDENTIFIER_REGEX,\n} from './regex';\nimport { GTIndexedSelectElement, GTUnindexedSelectElement } from './types';\nimport { TYPE, type MessageFormatElement } from '@generaltranslation/icu';\n\n// Visit any _gt_# select\nexport function isGTIndexedSelectElement(\n child: MessageFormatElement\n): child is GTIndexedSelectElement {\n return (\n child.type === TYPE.select &&\n GT_INDEXED_IDENTIFIER_REGEX.test(child.value) &&\n !!child.options.other &&\n (child.options.other.value.length === 0 ||\n (child.options.other.value.length > 0 &&\n child.options.other.value[0]?.type === TYPE.literal))\n );\n}\n\n// Visit any _gt_ select\nexport function isGTUnindexedSelectElement(\n child: MessageFormatElement\n): child is GTUnindexedSelectElement {\n return (\n child.type === TYPE.select &&\n GT_UNINDEXED_IDENTIFIER_REGEX.test(child.value) &&\n !!child.options.other &&\n (child.options.other.value.length === 0 ||\n (child.options.other.value.length > 0 &&\n child.options.other.value[0]?.type === TYPE.literal))\n );\n}\n","import { traverseIcu } from './utils/traverseIcu';\nimport { VAR_IDENTIFIER } from './utils/constants';\nimport { GTUnindexedSelectElement } from './utils/types';\nimport { isGTUnindexedSelectElement } from './utils/traverseHelpers';\n\ntype Location = {\n start: number;\n end: number;\n value: string;\n};\n\n/**\n * Given an encoded ICU string, interpolate only _gt_ variables that have been marked with declareVar()\n * @example\n * const encodedIcu = \"Hi\" + declareVar(\"Brian\") + \", my name is {name}\"\n * // 'Hi {_gt_, select, other {Brian}}, my name is {name}'\n * decodeVars(encodedIcu)\n * // 'Hi Brian, my name is {name}'\n */\nexport function decodeVars(icuString: string): string {\n // Check if the string contains _gt_\n if (!icuString.includes(VAR_IDENTIFIER)) {\n return icuString;\n }\n\n // Record the location of the variable\n const variableLocations: Location[] = [];\n function visitor(child: GTUnindexedSelectElement): void {\n variableLocations.push({\n start: child.location?.start.offset ?? 0,\n end: child.location?.end.offset ?? 0,\n value:\n child.options.other.value.length > 0\n ? child.options.other.value[0].value\n : '',\n });\n }\n\n // Find all variable identifiers.\n traverseIcu({\n icuString,\n shouldVisit: isGTUnindexedSelectElement,\n visitor,\n options: {\n recurseIntoVisited: false,\n captureLocation: true,\n },\n });\n\n // Construct output string\n let previousIndex = 0;\n const outputList = [];\n for (let i = 0; i < variableLocations.length; i++) {\n outputList.push(icuString.slice(previousIndex, variableLocations[i].start));\n outputList.push(variableLocations[i].value);\n previousIndex = variableLocations[i].end;\n }\n if (previousIndex < icuString.length) {\n outputList.push(icuString.slice(previousIndex));\n }\n const outputString = outputList.join('');\n\n return outputString;\n}\n","/**\n * Sanitizes string by escaping ICU syntax\n *\n * Sanitize arbitrary string so it does not break the following ICU message syntax:\n * {_gt_, select, other {string_here}}\n *\n * Escapes ICU special characters by:\n * 1. Doubling all single quotes (U+0027 ')\n * 2. Adding a single quote before the first special character ({}<>)\n * 3. Adding a single quote after the last special character ({}<>)\n */\nexport function sanitizeVar(string: string): string {\n // First, double all single quotes (both ASCII and Unicode).\n let result = string.replace(/'/g, \"''\");\n\n // Find first and last positions of special characters\n const specialChars = /[{}<>]/;\n const firstSpecialIndex = result.search(specialChars);\n\n if (firstSpecialIndex === -1) {\n // No special characters; return with just doubled quotes.\n return result;\n }\n\n // Find last special character position\n let lastSpecialIndex = -1;\n for (let i = result.length - 1; i >= 0; i--) {\n if (specialChars.test(result[i])) {\n lastSpecialIndex = i;\n break;\n }\n }\n\n // Insert quotes around the special character region.\n result =\n result.slice(0, firstSpecialIndex) +\n \"'\" +\n result.slice(firstSpecialIndex, lastSpecialIndex + 1) +\n \"'\" +\n result.slice(lastSpecialIndex + 1);\n\n return result;\n}\n","import { VAR_IDENTIFIER, VAR_NAME_IDENTIFIER } from './utils/constants';\nimport { sanitizeVar } from './utils/sanitizeVar';\n\n/**\n * Mark as a non-translatable string. Use within a derive() call to mark content as not derivable (e.g., not possible to statically analyze).\n *\n * @example\n * function nonDerivableFunction() {\n * return Math.random();\n * }\n *\n * function derivableFunction() {\n * if (condition) {\n * return declareVar(nonDerivableFunction())\n * }\n * return 'John Doe';\n * }\n *\n * const gt = useGT();\n * gt(`My name is ${derive(derivableFunction())}`);\n *\n * @param {string | number | boolean | null | undefined} variable - The variable to sanitize.\n * @param {Object} [options] - The options for the sanitization.\n * @param {string} [options.$name] - The name of the variable.\n * @returns {string} The sanitized value.\n */\nexport function declareVar(\n variable: string | number | boolean | null | undefined,\n options?: { $name?: string }\n): string {\n // Variable section.\n const sanitizedVariable = sanitizeVar(String(variable ?? ''));\n const variableSection = ` other {${sanitizedVariable}}`;\n\n // Name section.\n let nameSection = '';\n if (options?.$name) {\n const sanitizedName = sanitizeVar(options.$name);\n nameSection = ` ${VAR_NAME_IDENTIFIER} {${sanitizedName}}`;\n }\n\n // interpolate\n return `{${VAR_IDENTIFIER}, select,${variableSection}${nameSection}}`;\n}\n","/**\n * Marks content as derivable by the GT compiler and CLI.\n *\n * Use `derive()` when a translation string or context needs content that is\n * computed from source code, but should still be discovered during extraction\n * instead of treated as a runtime interpolation variable. The CLI attempts to\n * resolve the derivable expression into every possible static value and\n * includes those values in the source content that gets translated.\n *\n * `derive()` returns its argument unchanged at runtime.\n *\n * Run `gt validate` after adding or changing `derive()` calls to verify that\n * each derivable expression can be resolved by the CLI before translating or\n * building.\n *\n * @example\n * ```jsx\n * function getSubject() {\n * return (Math.random() > 0.5) ? \"Alice\" : \"Brian\";\n * }\n * ...\n * gt(`My name is ${derive(getSubject())}`);\n * ```\n *\n * @param {T extends string | boolean | number | null | undefined} content - Content to derive for translation extraction.\n * @returns {T} The same content, unchanged at runtime.\n */\nexport function derive<T extends string | boolean | number | null | undefined>(\n content: T\n): T {\n return content;\n}\n"],"mappings":"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"}
package/dist/id.d.cts CHANGED
@@ -1,4 +1,4 @@
1
- import { Dt as HashMetadata, m as JsxChildren } from "./types-f-_m5D_X.cjs";
1
+ import { Dt as HashMetadata, m as JsxChildren } from "./types-wj-Dtih8.cjs";
2
2
 
3
3
  //#region src/id/hashSource.d.ts
4
4
  /**
package/dist/id.d.mts CHANGED
@@ -1,4 +1,4 @@
1
- import { Dt as HashMetadata, m as JsxChildren } from "./types-algPgkHv.mjs";
1
+ import { Dt as HashMetadata, m as JsxChildren } from "./types-iO493WgK.mjs";
2
2
 
3
3
  //#region src/id/hashSource.d.ts
4
4
  /**
package/dist/index.cjs CHANGED
@@ -1,7 +1,7 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
2
  const require_api = require("./api-B2fSa2JN.cjs");
3
- const require_runtime = require("./runtime-wK7jzE9f.cjs");
4
- const require_derive = require("./derive-BvtWyo5B.cjs");
3
+ const require_runtime = require("./runtime-mKpF6P4Q.cjs");
4
+ const require_derive = require("./derive-Cbl7M1SY.cjs");
5
5
  let _generaltranslation_format = require("@generaltranslation/format");
6
6
  //#region src/translate/setupProject.ts
7
7
  /**
@@ -343,27 +343,36 @@ async function _checkJobStatus(jobIds, config, timeoutMs) {
343
343
  /**
344
344
  * @internal
345
345
  * Polls job statuses until all jobs are finished or the timeout is reached.
346
- * @param enqueueResult - The result from enqueueFiles.
346
+ * @param jobIds - Job IDs to poll.
347
347
  * @param options - Polling configuration.
348
348
  * @param config - API credentials and configuration.
349
349
  * @returns The final status of all jobs.
350
350
  */
351
- async function _awaitJobs(enqueueResult, options, config) {
351
+ async function _awaitJobIds(jobIds, options, config) {
352
352
  const pollingInterval = (options?.pollingIntervalSeconds ?? 5) * 1e3;
353
353
  const timeout = options?.timeoutSeconds !== void 0 ? options.timeoutSeconds * 1e3 : 600 * 1e3;
354
- const jobIds = Object.keys(enqueueResult.jobData);
355
354
  if (jobIds.length === 0) return {
356
355
  complete: true,
357
356
  jobs: []
358
357
  };
359
- const startTime = Date.now();
358
+ const deadline = Date.now() + timeout;
360
359
  const finalStatuses = new Map(jobIds.map((id) => [id, {
361
360
  jobId: id,
362
361
  status: "unknown"
363
362
  }]));
364
363
  const pendingJobIds = new Set(jobIds);
365
364
  while (pendingJobIds.size > 0) {
366
- const statuses = await _checkJobStatus(Array.from(pendingJobIds), config);
365
+ const remainingTime = deadline - Date.now();
366
+ if (remainingTime <= 0) break;
367
+ let statuses;
368
+ try {
369
+ statuses = await _checkJobStatus(Array.from(pendingJobIds), config, Math.min(remainingTime, require_api.defaultTimeout));
370
+ } catch (error) {
371
+ if (Date.now() >= deadline) break;
372
+ throw error;
373
+ }
374
+ if (Date.now() >= deadline) break;
375
+ const returnedJobIds = new Set(statuses.map(({ jobId }) => jobId));
367
376
  for (const job of statuses) if (job.status === "completed" || job.status === "failed" || job.status === "unknown") {
368
377
  finalStatuses.set(job.jobId, {
369
378
  jobId: job.jobId,
@@ -375,9 +384,17 @@ async function _awaitJobs(enqueueResult, options, config) {
375
384
  jobId: job.jobId,
376
385
  status: job.status
377
386
  });
387
+ for (const jobId of Array.from(pendingJobIds)) if (!returnedJobIds.has(jobId)) {
388
+ finalStatuses.set(jobId, {
389
+ jobId,
390
+ status: "unknown"
391
+ });
392
+ pendingJobIds.delete(jobId);
393
+ }
378
394
  if (pendingJobIds.size === 0) break;
379
- if (Date.now() - startTime >= timeout) break;
380
- await new Promise((resolve) => setTimeout(resolve, pollingInterval));
395
+ const remainingSleepTime = deadline - Date.now();
396
+ if (remainingSleepTime <= 0) break;
397
+ await new Promise((resolve) => setTimeout(resolve, Math.min(pollingInterval, remainingSleepTime)));
381
398
  }
382
399
  return {
383
400
  complete: pendingJobIds.size === 0,
@@ -655,15 +672,15 @@ var GT = class extends require_runtime.GTRuntime {
655
672
  return await _checkJobStatus(jobIds, this._getTranslationConfig(), timeoutMs);
656
673
  }
657
674
  /**
658
- * Polls job statuses until all jobs from enqueueFiles are finished or the timeout is reached.
675
+ * Polls job statuses until all jobs are finished or the timeout is reached.
659
676
  *
660
- * @param {EnqueueFilesResult} enqueueResult - The result returned from enqueueFiles.
677
+ * @param {EnqueueFilesResult | string[]} jobs - Job IDs or the result returned from enqueueFiles.
661
678
  * @param {AwaitJobsOptions} [options] - Polling configuration (interval, timeout).
662
679
  * @returns {Promise<AwaitJobsResult>} The final status of all jobs and whether they all completed.
663
680
  */
664
- async awaitJobs(enqueueResult, options) {
681
+ async awaitJobs(jobs, options) {
665
682
  this._validateAuth("awaitJobs");
666
- return await _awaitJobs(enqueueResult, options, this._getTranslationConfig());
683
+ return await _awaitJobIds(Array.isArray(jobs) ? jobs : Object.keys(jobs.jobData), options, this._getTranslationConfig());
667
684
  }
668
685
  /**
669
686
  * Enqueues translation jobs for previously uploaded source files.