generaltranslation 9.4.0 → 9.4.2

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 CHANGED
@@ -1,5 +1,29 @@
1
1
  # generaltranslation
2
2
 
3
+ ## 9.4.2
4
+
5
+ ### Patch Changes
6
+
7
+ - Updated dependencies [[`a569f0d`](https://github.com/generaltranslation/gt/commit/a569f0d661ba6b28dc55375b56113a68403e2e8d)]:
8
+ - @generaltranslation/api@0.3.1
9
+
10
+ ## 9.4.1
11
+
12
+ ### Patch Changes
13
+
14
+ - [#2288](https://github.com/generaltranslation/gt/pull/2288) [`90109bf`](https://github.com/generaltranslation/gt/commit/90109bf9ec4900819023176320629a5069fd7b51) Thanks [@eoinest](https://github.com/eoinest)! - Preserve configured locale identities across negotiation, routing, hooks, cookies, translation loaders, and caches, including when GT services are enabled. For example, configuring `en-gb` keeps that spelling in application-facing values while GT service requests and formatting use `en-GB`.
15
+
16
+ Locale negotiation accepts equivalent spellings and returns a configured identity, preserving exact matches between distinct aliases for the same language. This also applies to request-header negotiation: an `Accept-Language` preference of `fr` can resolve to a configured `brand-french` alias. Preserve support for legacy tags such as `sh` and `cnr`, and retain existing custom mappings when validating partial `setConfig()` updates.
17
+
18
+ Translation loaders and local filenames must use the configured identity: a loader for configured `en-gb` receives `en-gb`, not `en-GB`. Configure canonical spelling instead if the application requires it. Custom mapping `code` values must use canonical spelling, for example `'en-gb': { code: 'en-GB' }`. Canonicalize locales at GT service boundaries, including nested source-file locales in translation uploads and requests through the shared CLI/Sanity adapter. Require canonical locale codes or explicit custom mappings for CLI commands that use GT translation services. For example, using `en-us` with the API requires `customMapping: { "en-us": { "code": "en-US" } }`; otherwise the command exits with guidance before running the translation workflow. Local-only commands and dry runs retain their existing validation. Restore configured identities in service metadata; without a corresponding requested identity, use the first matching configured locale.
19
+
20
+ Align server/browser locale values and expose the configured locale list through `useLocales()`. In Next.js, preserve configured identities in localized paths, route overrides, and locale availability. Resolve unsupported locale preferences before deciding whether to prefix the default locale, and cache locale resolution during middleware initialization.
21
+
22
+ For Next.js App Router, read locale and region from server-provided conditions. Setters write request cookies and retain pending values for the refresh callback; hooks keep reading the current server conditions until a new snapshot arrives, including when a locale switch is rejected. Use `router.refresh()` on Next.js 16.1 and newer and a document reload on older versions to avoid stale layout/provider snapshots after middleware redirects. Detect this capability at build time, retain the existing document reload when returning to the default locale, and leave other React integrations' cookie-backed behavior unchanged. This adds no request-time cookie reads and does not change App Router's existing `enableI18n` behavior.
23
+
24
+ - Updated dependencies [[`90109bf`](https://github.com/generaltranslation/gt/commit/90109bf9ec4900819023176320629a5069fd7b51)]:
25
+ - @generaltranslation/format@0.1.9
26
+
3
27
  ## 9.4.0
4
28
 
5
29
  ### Minor Changes
@@ -75,12 +75,12 @@ export declare function createGtApiAdapter(defaultConfig?: ApiClientConfig): {
75
75
  sourceLocale: string;
76
76
  }): Promise<{
77
77
  uploadedFiles: {
78
- branchId?: string;
78
+ branchId: string;
79
79
  fileId: string;
80
80
  versionId: string;
81
81
  fileName: string;
82
82
  fileFormat: import("@generaltranslation/api").FileFormat;
83
- dataFormat?: string;
83
+ dataFormat?: import("@generaltranslation/api").DataFormat;
84
84
  locale?: string;
85
85
  }[];
86
86
  }>;
@@ -89,12 +89,12 @@ export declare function createGtApiAdapter(defaultConfig?: ApiClientConfig): {
89
89
  sourceLocale: string;
90
90
  }): Promise<{
91
91
  uploadedFiles: {
92
- branchId?: string;
92
+ branchId: string;
93
93
  fileId: string;
94
94
  versionId: string;
95
95
  fileName: string;
96
96
  fileFormat: import("@generaltranslation/api").FileFormat;
97
- dataFormat?: string;
97
+ dataFormat?: import("@generaltranslation/api").DataFormat;
98
98
  locale?: string;
99
99
  }[];
100
100
  }>;
@@ -57,13 +57,18 @@ var __rest = (this && this.__rest) || function (s, e) {
57
57
  return t;
58
58
  };
59
59
  import { createApiClient, createBranch, DEFAULT_BATCH_SIZE, downloadFiles, enqueueFileTranslations, generateProjectContext, getFileInfo, getTranslationJobInfo, pollJobs, processBatches, uploadSourceFiles, uploadTranslations, } from '@generaltranslation/api';
60
- import { resolveAliasLocale, resolveCanonicalLocale, } from '@generaltranslation/format';
60
+ import { resolveAliasLocale, resolveCanonicalLocale, standardizeLocale, } from '@generaltranslation/format';
61
61
  import { decodeFileContent, encodeFileContent } from '../utils/base64';
62
62
  import { unwrapApiResult } from '../translate/utils/unwrapApiResult';
63
63
  export function createGtApiAdapter(defaultConfig) {
64
64
  var client = defaultConfig ? createApiClient(defaultConfig) : undefined;
65
65
  var configuredClientConfig = defaultConfig;
66
66
  var customMapping;
67
+ // Mapping resolves aliases; standardization also canonicalizes configured
68
+ // spellings such as en-us before they cross the service boundary.
69
+ function resolveServiceLocale(locale) {
70
+ return standardizeLocale(resolveCanonicalLocale(locale, customMapping));
71
+ }
67
72
  function getClient() {
68
73
  if (!client) {
69
74
  throw new Error('API client not configured — call configureApiClient first');
@@ -90,7 +95,7 @@ export function createGtApiAdapter(defaultConfig) {
90
95
  return resolveAliasLocale(locale, customMapping);
91
96
  },
92
97
  resolveCanonicalLocale: function (locale) {
93
- return resolveCanonicalLocale(locale, customMapping);
98
+ return resolveServiceLocale(locale);
94
99
  },
95
100
  createBranch: function (body) {
96
101
  return __awaiter(this, void 0, void 0, function () {
@@ -114,7 +119,7 @@ export function createGtApiAdapter(defaultConfig) {
114
119
  case 0:
115
120
  _a = unwrapApiResult;
116
121
  return [4 /*yield*/, getFileInfo({
117
- body: __assign(__assign({}, body), { translatedFiles: (_b = body.translatedFiles) === null || _b === void 0 ? void 0 : _b.map(function (file) { return (__assign(__assign({}, file), { locale: resolveCanonicalLocale(file.locale, customMapping) })); }) }),
122
+ body: __assign(__assign({}, body), { translatedFiles: (_b = body.translatedFiles) === null || _b === void 0 ? void 0 : _b.map(function (file) { return (__assign(__assign({}, file), { locale: resolveServiceLocale(file.locale) })); }) }),
118
123
  client: getClient(),
119
124
  })];
120
125
  case 1:
@@ -141,7 +146,7 @@ export function createGtApiAdapter(defaultConfig) {
141
146
  _a = unwrapApiResult;
142
147
  return [4 /*yield*/, downloadFiles({
143
148
  body: batch.map(function (file) { return (__assign(__assign({}, file), { locale: file.locale
144
- ? resolveCanonicalLocale(file.locale, customMapping)
149
+ ? resolveServiceLocale(file.locale)
145
150
  : undefined })); }),
146
151
  client: getClient(),
147
152
  })];
@@ -197,7 +202,7 @@ export function createGtApiAdapter(defaultConfig) {
197
202
  });
198
203
  }),
199
204
  locales: (_b = options.locales) === null || _b === void 0 ? void 0 : _b.map(function (locale) {
200
- return resolveCanonicalLocale(locale, customMapping);
205
+ return resolveServiceLocale(locale);
201
206
  }),
202
207
  force: options.force,
203
208
  },
@@ -216,7 +221,7 @@ export function createGtApiAdapter(defaultConfig) {
216
221
  switch (_a.label) {
217
222
  case 0:
218
223
  targetLocales = options.targetLocales.map(function (locale) {
219
- return resolveCanonicalLocale(locale, customMapping);
224
+ return resolveServiceLocale(locale);
220
225
  });
221
226
  return [4 /*yield*/, processBatches(files, function (batch) { return __awaiter(_this, void 0, void 0, function () {
222
227
  var response, _a, jobData;
@@ -238,7 +243,7 @@ export function createGtApiAdapter(defaultConfig) {
238
243
  }),
239
244
  targetLocales: targetLocales,
240
245
  sourceLocale: options.sourceLocale
241
- ? resolveCanonicalLocale(options.sourceLocale, customMapping)
246
+ ? resolveServiceLocale(options.sourceLocale)
242
247
  : undefined,
243
248
  // Consumers intentionally accept custom model-provider strings beyond
244
249
  // the OpenAPI enum; preserve the existing wire behavior at this boundary.
@@ -272,7 +277,7 @@ export function createGtApiAdapter(defaultConfig) {
272
277
  return __generator(this, function (_a) {
273
278
  switch (_a.label) {
274
279
  case 0:
275
- sourceLocale = resolveCanonicalLocale(options.sourceLocale, customMapping);
280
+ sourceLocale = resolveServiceLocale(options.sourceLocale);
276
281
  return [4 /*yield*/, processBatches(files, function (batch) { return __awaiter(_this, void 0, void 0, function () {
277
282
  var response, _a;
278
283
  return __generator(this, function (_b) {
@@ -284,7 +289,7 @@ export function createGtApiAdapter(defaultConfig) {
284
289
  data: batch.map(function (_a) {
285
290
  var source = _a.source;
286
291
  return ({
287
- source: __assign(__assign({}, source), { content: encodeFileContent(source.content, source.fileFormat), locale: resolveCanonicalLocale(source.locale, customMapping) }),
292
+ source: __assign(__assign({}, source), { content: encodeFileContent(source.content, source.fileFormat), locale: resolveServiceLocale(source.locale) }),
288
293
  });
289
294
  }),
290
295
  sourceLocale: sourceLocale,
@@ -343,11 +348,11 @@ export function createGtApiAdapter(defaultConfig) {
343
348
  data: batch.map(function (_a) {
344
349
  var source = _a.source, translations = _a.translations;
345
350
  return ({
346
- source: __assign(__assign({}, source), { content: encodeFileContent(source.content, source.fileFormat) }),
347
- translations: translations.map(function (translation) { return (__assign(__assign({}, translation), { locale: resolveCanonicalLocale(translation.locale, customMapping), content: encodeFileContent(translation.content, translation.fileFormat) })); }),
351
+ source: __assign(__assign({}, source), { content: encodeFileContent(source.content, source.fileFormat), locale: resolveServiceLocale(source.locale) }),
352
+ translations: translations.map(function (translation) { return (__assign(__assign({}, translation), { locale: resolveServiceLocale(translation.locale), content: encodeFileContent(translation.content, translation.fileFormat) })); }),
348
353
  });
349
354
  }),
350
- sourceLocale: resolveCanonicalLocale(options.sourceLocale, customMapping),
355
+ sourceLocale: resolveServiceLocale(options.sourceLocale),
351
356
  },
352
357
  client: getClient(),
353
358
  })];
package/dist/index.cjs CHANGED
@@ -1,6 +1,6 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
2
  const require_unwrapApiResult = require("./unwrapApiResult-Dv6Mfw_K.cjs");
3
- const require_runtime = require("./runtime-BGUJYxhI.cjs");
3
+ const require_runtime = require("./runtime-C25lwh9m.cjs");
4
4
  const require_derive = require("./derive-2CDqwrvS.cjs");
5
5
  const require_file = require("./file-B37WkCqM.cjs");
6
6
  let _generaltranslation_format = require("@generaltranslation/format");
@@ -774,7 +774,7 @@ var GT = class extends require_runtime.GTRuntime {
774
774
  this._validateAuth("setupProject");
775
775
  options = {
776
776
  ...options,
777
- locales: options?.locales?.map((locale) => this.resolveCanonicalLocale(locale))
777
+ locales: options?.locales?.map((locale) => this.resolveServiceLocale(locale))
778
778
  };
779
779
  return await _setupProject(files, this._getTranslationConfig(), options);
780
780
  }
@@ -839,11 +839,16 @@ var GT = class extends require_runtime.GTRuntime {
839
839
  require_runtime.gtInstanceLogger.error(error);
840
840
  throw new Error(error);
841
841
  }
842
+ const targetLocaleIdentities = [...mergedOptions.targetLocales];
842
843
  mergedOptions = {
843
844
  ...mergedOptions,
844
- targetLocales: mergedOptions.targetLocales.map((locale) => this.resolveCanonicalLocale(locale))
845
+ sourceLocale: this.resolveServiceLocale(mergedOptions.sourceLocale),
846
+ targetLocales: mergedOptions.targetLocales.map((locale) => this.resolveServiceLocale(locale))
847
+ };
848
+ return {
849
+ ...await _enqueueFiles(files, mergedOptions, this._getTranslationConfig()),
850
+ locales: targetLocaleIdentities
845
851
  };
846
- return await _enqueueFiles(files, mergedOptions, this._getTranslationConfig());
847
852
  }
848
853
  /**
849
854
  * Creates or upserts a file tag, associating a set of source files
@@ -864,7 +869,10 @@ var GT = class extends require_runtime.GTRuntime {
864
869
  */
865
870
  async publishFiles(files) {
866
871
  this._validateAuth("publishFiles");
867
- return await _publishFiles(files, this._getTranslationConfig());
872
+ return { results: (await _publishFiles(files, this._getTranslationConfig())).results.map((item) => ({
873
+ ...item,
874
+ ...item.locale && { locale: this.resolveServiceResponseLocale(item.locale) }
875
+ })) };
868
876
  }
869
877
  /**
870
878
  * Submits user edit diffs for existing translations so future generations preserve user intent.
@@ -878,7 +886,7 @@ var GT = class extends require_runtime.GTRuntime {
878
886
  ...payload,
879
887
  diffs: (payload.diffs || []).map((d) => ({
880
888
  ...d,
881
- locale: this.resolveCanonicalLocale(d.locale)
889
+ locale: this.resolveServiceLocale(d.locale)
882
890
  }))
883
891
  }, this._getTranslationConfig());
884
892
  }
@@ -910,23 +918,28 @@ var GT = class extends require_runtime.GTRuntime {
910
918
  */
911
919
  async getProjectInfo(options = {}) {
912
920
  this._validateAuth("getProjectInfo");
913
- return await _getProjectInfo(options, this._getTranslationConfig());
921
+ const result = await _getProjectInfo(options, this._getTranslationConfig());
922
+ return {
923
+ ...result,
924
+ defaultLocale: this.resolveServiceResponseLocale(result.defaultLocale),
925
+ currentLocales: result.currentLocales.map((locale) => this.resolveServiceResponseLocale(locale))
926
+ };
914
927
  }
915
928
  async queryFileData(data, options = {}) {
916
929
  this._validateAuth("queryFileData");
917
930
  data.translatedFiles = data.translatedFiles?.map((item) => ({
918
931
  ...item,
919
- locale: this.resolveCanonicalLocale(item.locale)
932
+ locale: this.resolveServiceLocale(item.locale)
920
933
  }));
921
934
  const result = await _queryFileData(data, options, this._getTranslationConfig());
922
935
  result.translatedFiles = result.translatedFiles?.map((item) => ({
923
936
  ...item,
924
- ...item.locale && { locale: this.resolveAliasLocale(item.locale) }
937
+ ...item.locale && { locale: this.resolveServiceResponseLocale(item.locale) }
925
938
  }));
926
939
  result.sourceFiles = result.sourceFiles?.map((item) => ({
927
940
  ...item,
928
- ...item.sourceLocale && { sourceLocale: this.resolveAliasLocale(item.sourceLocale) },
929
- locales: item.locales.map((locale) => this.resolveAliasLocale(locale))
941
+ ...item.sourceLocale && { sourceLocale: this.resolveServiceResponseLocale(item.sourceLocale) },
942
+ locales: item.locales.map((locale) => this.resolveServiceResponseLocale(locale))
930
943
  }));
931
944
  return result;
932
945
  }
@@ -949,10 +962,10 @@ var GT = class extends require_runtime.GTRuntime {
949
962
  const result = await _querySourceFile(data, options, this._getTranslationConfig());
950
963
  result.translations = result.translations.map((item) => ({
951
964
  ...item,
952
- ...item.locale && { locale: this.resolveAliasLocale(item.locale) }
965
+ ...item.locale && { locale: this.resolveServiceResponseLocale(item.locale) }
953
966
  }));
954
- result.sourceFile.locales = result.sourceFile.locales.map((locale) => this.resolveAliasLocale(locale));
955
- if (result.sourceFile.sourceLocale) result.sourceFile.sourceLocale = this.resolveAliasLocale(result.sourceFile.sourceLocale);
967
+ result.sourceFile.locales = result.sourceFile.locales.map((locale) => this.resolveServiceResponseLocale(locale));
968
+ if (result.sourceFile.sourceLocale) result.sourceFile.sourceLocale = this.resolveServiceResponseLocale(result.sourceFile.sourceLocale);
956
969
  return result;
957
970
  }
958
971
  /**
@@ -970,8 +983,8 @@ var GT = class extends require_runtime.GTRuntime {
970
983
  async getProjectData(projectId, options = {}) {
971
984
  this._validateAuth("getProjectData");
972
985
  const result = await _getProjectData(projectId, options, this._getTranslationConfig());
973
- result.currentLocales = result.currentLocales.map((item) => this.resolveAliasLocale(item));
974
- result.defaultLocale = this.resolveAliasLocale(result.defaultLocale);
986
+ result.currentLocales = result.currentLocales.map((item) => this.resolveServiceResponseLocale(item));
987
+ result.defaultLocale = this.resolveServiceResponseLocale(result.defaultLocale);
975
988
  return result;
976
989
  }
977
990
  /**
@@ -1000,7 +1013,7 @@ var GT = class extends require_runtime.GTRuntime {
1000
1013
  return (await _downloadFileBatch([{
1001
1014
  fileId: file.fileId,
1002
1015
  branchId: file.branchId,
1003
- locale: file.locale ? this.resolveCanonicalLocale(file.locale) : void 0,
1016
+ locale: file.locale ? this.resolveServiceLocale(file.locale) : void 0,
1004
1017
  versionId: file.versionId,
1005
1018
  useLatestAvailableVersion: file.useLatestAvailableVersion
1006
1019
  }], options, this._getTranslationConfig())).data?.[0]?.data ?? "";
@@ -1023,16 +1036,31 @@ var GT = class extends require_runtime.GTRuntime {
1023
1036
  */
1024
1037
  async downloadFileBatch(requests, options = {}) {
1025
1038
  this._validateAuth("downloadFileBatch");
1026
- requests = requests.map((request) => ({
1027
- ...request,
1028
- locale: request.locale ? this.resolveCanonicalLocale(request.locale) : void 0
1029
- }));
1039
+ const requestedFiles = /* @__PURE__ */ new Map();
1040
+ requests = requests.map((request) => {
1041
+ const locale = request.locale ? this.resolveServiceLocale(request.locale) : void 0;
1042
+ if (locale) {
1043
+ const key = JSON.stringify([request.fileId, locale]);
1044
+ const group = requestedFiles.get(key) ?? [];
1045
+ group.push(request);
1046
+ requestedFiles.set(key, group);
1047
+ }
1048
+ return {
1049
+ ...request,
1050
+ locale
1051
+ };
1052
+ });
1030
1053
  const result = await _downloadFileBatch(requests, options, this._getTranslationConfig());
1031
1054
  return {
1032
- files: result.data.map((file) => ({
1033
- ...file,
1034
- ...file.locale && { locale: this.resolveAliasLocale(file.locale) }
1035
- })),
1055
+ files: result.data.map((file) => {
1056
+ if (!file.locale) return file;
1057
+ const serviceLocale = this.standardizeLocale(file.locale);
1058
+ const matchingRequests = (requestedFiles.get(JSON.stringify([file.fileId, serviceLocale])) ?? []).filter((request) => (!request.branchId || request.branchId === file.branchId) && (!request.versionId || request.versionId === file.versionId));
1059
+ return {
1060
+ ...file,
1061
+ locale: matchingRequests.length === 1 ? matchingRequests[0].locale : this.resolveServiceResponseLocale(file.locale)
1062
+ };
1063
+ }),
1036
1064
  count: result.count
1037
1065
  };
1038
1066
  }
@@ -1052,13 +1080,13 @@ var GT = class extends require_runtime.GTRuntime {
1052
1080
  this._validateAuth("uploadSourceFiles");
1053
1081
  const mergedOptions = {
1054
1082
  ...options,
1055
- sourceLocale: this.resolveCanonicalLocale(options.sourceLocale ?? this.sourceLocale ?? "en")
1083
+ sourceLocale: this.resolveServiceLocale(options.sourceLocale ?? this.sourceLocale ?? "en")
1056
1084
  };
1057
1085
  files = files.map((f) => ({
1058
1086
  ...f,
1059
1087
  source: {
1060
1088
  ...f.source,
1061
- locale: this.resolveCanonicalLocale(f.source.locale)
1089
+ locale: this.resolveServiceLocale(f.source.locale)
1062
1090
  }
1063
1091
  }));
1064
1092
  const result = await _uploadSourceFiles(files, mergedOptions, this._getTranslationConfig());
@@ -1109,12 +1137,16 @@ var GT = class extends require_runtime.GTRuntime {
1109
1137
  require_runtime.gtInstanceLogger.error(error);
1110
1138
  throw new Error(error);
1111
1139
  }
1112
- mergedOptions.sourceLocale = this.resolveCanonicalLocale(mergedOptions.sourceLocale);
1140
+ mergedOptions.sourceLocale = this.resolveServiceLocale(mergedOptions.sourceLocale);
1113
1141
  const result = await _uploadTranslations(files.map((f) => ({
1114
1142
  ...f,
1143
+ source: {
1144
+ ...f.source,
1145
+ locale: this.resolveServiceLocale(f.source.locale)
1146
+ },
1115
1147
  translations: f.translations.map((t) => ({
1116
1148
  ...t,
1117
- locale: this.resolveCanonicalLocale(t.locale)
1149
+ locale: this.resolveServiceLocale(t.locale)
1118
1150
  }))
1119
1151
  })), mergedOptions, this._getTranslationConfig());
1120
1152
  return {