intor 2.1.0 → 2.2.1

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.
@@ -43,15 +43,15 @@ var setPathnameHeader = ({
43
43
  var PREFIX_PLACEHOLDER = "{locale}";
44
44
 
45
45
  // src/shared/utils/locale/normalize-locale.ts
46
+ var toCanonical = (input) => {
47
+ try {
48
+ return Intl.getCanonicalLocales(input)[0]?.toLowerCase();
49
+ } catch {
50
+ return;
51
+ }
52
+ };
46
53
  var normalizeLocale = (locale = "", supportedLocales = []) => {
47
54
  if (!locale || supportedLocales.length === 0) return;
48
- const toCanonical = (input) => {
49
- try {
50
- return Intl.getCanonicalLocales(input)[0]?.toLowerCase();
51
- } catch {
52
- return;
53
- }
54
- };
55
55
  const canonicalLocale = toCanonical(locale);
56
56
  if (!canonicalLocale) return;
57
57
  const supportedCanonicalMap = /* @__PURE__ */ new Map();
@@ -82,12 +82,12 @@ var resolvePreferredLocale = (acceptLanguageHeader, supportedLocales) => {
82
82
  const supportedLocalesSet = new Set(supportedLocales);
83
83
  const preferred = acceptLanguageHeader.split(",").map((part) => {
84
84
  const [lang, qValue] = part.split(";");
85
- const q = qValue ? parseFloat(qValue.split("=")[1]) : 1;
86
- if (isNaN(q)) {
85
+ const q = qValue ? Number.parseFloat(qValue.split("=")[1]) : 1;
86
+ if (Number.isNaN(q)) {
87
87
  return { lang: lang.trim(), q: 0 };
88
88
  }
89
89
  return { lang: lang.trim(), q };
90
- }).sort((a, b) => b.q - a.q).find(({ lang }) => supportedLocalesSet.has(lang))?.lang;
90
+ }).toSorted((a, b) => b.q - a.q).find(({ lang }) => supportedLocalesSet.has(lang))?.lang;
91
91
  return preferred;
92
92
  };
93
93
 
@@ -96,8 +96,8 @@ var normalizePathname = (rawPathname, options = {}) => {
96
96
  const length = rawPathname.length;
97
97
  let start = 0;
98
98
  let end = length - 1;
99
- while (start <= end && rawPathname.charCodeAt(start) <= 32) start++;
100
- while (end >= start && rawPathname.charCodeAt(end) <= 32) end--;
99
+ while (start <= end && (rawPathname.codePointAt(start) ?? 0) <= 32) start++;
100
+ while (end >= start && (rawPathname.codePointAt(end) ?? 0) <= 32) end--;
101
101
  if (start > end) return "/";
102
102
  let result = "";
103
103
  let hasSlash = false;
@@ -108,11 +108,7 @@ var normalizePathname = (rawPathname, options = {}) => {
108
108
  hasSlash = true;
109
109
  }
110
110
  } else {
111
- if (hasSlash || result === "") {
112
- result += "/" + char;
113
- } else {
114
- result += char;
115
- }
111
+ result += hasSlash || result === "" ? "/" + char : char;
116
112
  hasSlash = false;
117
113
  }
118
114
  }
@@ -136,8 +132,8 @@ var extractPathname = ({
136
132
  } else if (basePath && normalizedPathname === basePath) {
137
133
  prefixedPathname = "/";
138
134
  }
139
- const pathParts = prefixedPathname.split("/").filter(Boolean);
140
- const maybeLocale = pathParts[0] || "";
135
+ const pathPart = prefixedPathname.split("/").find(Boolean);
136
+ const maybeLocale = pathPart || "";
141
137
  const isLocalePrefixed = config.supportedLocales?.includes(maybeLocale);
142
138
  let unprefixedPathname = prefixedPathname;
143
139
  if (prefix === "all") {
@@ -170,7 +166,7 @@ var standardizePathname = ({
170
166
  PREFIX_PLACEHOLDER,
171
167
  normalizePathname(pathname)
172
168
  ];
173
- const standardizedPathname = parts.join("/").replace(/\/{2,}/g, "/");
169
+ const standardizedPathname = parts.join("/").replaceAll(/\/{2,}/g, "/");
174
170
  return normalizePathname(standardizedPathname);
175
171
  };
176
172
 
@@ -191,15 +187,11 @@ var localePrefixPathname = ({
191
187
  );
192
188
  }
193
189
  if (prefix === "except-default") {
194
- if (locale === config.defaultLocale) {
195
- return normalizePathname(
196
- standardizedPathname.replaceAll(`/${PREFIX_PLACEHOLDER}`, "")
197
- );
198
- } else {
199
- return normalizePathname(
200
- standardizedPathname.replaceAll(PREFIX_PLACEHOLDER, locale)
201
- );
202
- }
190
+ return locale === config.defaultLocale ? normalizePathname(
191
+ standardizedPathname.replaceAll(`/${PREFIX_PLACEHOLDER}`, "")
192
+ ) : normalizePathname(
193
+ standardizedPathname.replaceAll(PREFIX_PLACEHOLDER, locale)
194
+ );
203
195
  }
204
196
  return normalizePathname(
205
197
  standardizedPathname.replaceAll(`/${PREFIX_PLACEHOLDER}`, "")
@@ -249,12 +241,7 @@ var createResponse = ({
249
241
  locale
250
242
  });
251
243
  url.pathname = localePrefixedPathname;
252
- let response;
253
- if (responseType === "redirect") {
254
- response = NextResponse.redirect(url);
255
- } else {
256
- response = NextResponse.next();
257
- }
244
+ const response = responseType === "redirect" ? NextResponse.redirect(url) : NextResponse.next();
258
245
  if (locale) {
259
246
  setLocaleCookieEdge({
260
247
  request,
@@ -274,7 +261,8 @@ var determineInitialLocale = async (config) => {
274
261
  const { defaultLocale, supportedLocales, routing } = config;
275
262
  let initialLocale = defaultLocale;
276
263
  if (routing.firstVisit.localeSource === "browser") {
277
- const acceptLanguageHeader = (await headers()).get("accept-language") || void 0;
264
+ const headersStore = await headers();
265
+ const acceptLanguageHeader = headersStore.get("accept-language") || void 0;
278
266
  const preferredLocale = resolvePreferredLocale(
279
267
  acceptLanguageHeader,
280
268
  supportedLocales
@@ -285,10 +273,7 @@ var determineInitialLocale = async (config) => {
285
273
  };
286
274
 
287
275
  // src/adapters/next/middleware/handle-prefix/handle-prefix-all.ts
288
- var handlePrefixAll = async ({
289
- request,
290
- config
291
- }) => {
276
+ var handlePrefixAll = async (config, request) => {
292
277
  const { cookie, routing } = config;
293
278
  const { maybeLocale, isLocalePrefixed } = extractPathname({
294
279
  config,
@@ -326,10 +311,7 @@ var handlePrefixAll = async ({
326
311
  };
327
312
 
328
313
  // src/adapters/next/middleware/handle-prefix/handle-prefix-except-default.ts
329
- var handlePrefixExceptDefault = async ({
330
- request,
331
- config
332
- }) => {
314
+ var handlePrefixExceptDefault = async (config, request) => {
333
315
  const { defaultLocale, cookie, routing } = config;
334
316
  const { maybeLocale, isLocalePrefixed } = extractPathname({
335
317
  config,
@@ -379,10 +361,7 @@ var handlePrefixExceptDefault = async ({
379
361
  };
380
362
 
381
363
  // src/adapters/next/middleware/handle-prefix/handle-prefix-none.ts
382
- var handlePrefixNone = async ({
383
- request,
384
- config
385
- }) => {
364
+ var handlePrefixNone = async (config, request) => {
386
365
  let locale = request.cookies.get(config.cookie.name)?.value;
387
366
  if (!locale) {
388
367
  locale = await determineInitialLocale(config);
@@ -391,18 +370,15 @@ var handlePrefixNone = async ({
391
370
  };
392
371
 
393
372
  // src/adapters/next/middleware/intor-middleware.ts
394
- async function intorMiddleware({
395
- request,
396
- config
397
- }) {
373
+ async function intorMiddleware(config, request) {
398
374
  const { prefix } = config.routing;
399
375
  if (prefix === "none") {
400
- return handlePrefixNone({ request, config });
376
+ return handlePrefixNone(config, request);
401
377
  }
402
378
  if (prefix === "except-default") {
403
- return await handlePrefixExceptDefault({ request, config });
379
+ return await handlePrefixExceptDefault(config, request);
404
380
  }
405
- return await handlePrefixAll({ request, config });
381
+ return await handlePrefixAll(config, request);
406
382
  }
407
383
 
408
384
  export { PATHNAME_HEADER_NAME, intorMiddleware };
@@ -50,7 +50,7 @@ function getLogger({
50
50
  });
51
51
  pool.set(id, logger);
52
52
  if (pool.size > 1e3) {
53
- const keys = Array.from(pool.keys());
53
+ const keys = [...pool.keys()];
54
54
  for (const key of keys.slice(0, 200)) pool.delete(key);
55
55
  }
56
56
  }
@@ -61,7 +61,7 @@ function getLogger({
61
61
  var CACHE_KEY_DELIMITER = "|";
62
62
  var sanitize = (k) => k.replaceAll(/[\u200B-\u200D\uFEFF]/g, "").replaceAll(/[\r\n]/g, "").trim();
63
63
  var normalizeCacheKey = (key, delimiter = CACHE_KEY_DELIMITER) => {
64
- if (!key) return null;
64
+ if (key === null || key === void 0) return null;
65
65
  if (Array.isArray(key)) {
66
66
  if (key.length === 0) return null;
67
67
  const normalized = key.map((k) => {
@@ -85,56 +85,44 @@ var resolveNamespaces = ({
85
85
  pathname
86
86
  }) => {
87
87
  const { loader } = config;
88
- const {
89
- routeNamespaces = {},
90
- namespaces: fallbackNamespaces
91
- } = loader;
92
- const { unprefixedPathname } = extractPathname({ config, pathname });
93
- const standardizedPathname = standardizePathname({
94
- config,
95
- pathname: unprefixedPathname
96
- });
88
+ const { routeNamespaces = {}, namespaces } = loader || {};
89
+ const standardizedPathname = standardizePathname({ config, pathname });
97
90
  const placeholderRemovedPathname = standardizedPathname.replace(
98
91
  `/${PREFIX_PLACEHOLDER}`,
99
92
  ""
100
93
  );
101
- const defaultNamespaces = routeNamespaces.default ?? [];
102
- const exactMatchNamespaces = routeNamespaces[standardizedPathname] ?? routeNamespaces[placeholderRemovedPathname];
103
- if (exactMatchNamespaces) {
104
- return [...defaultNamespaces, ...exactMatchNamespaces];
105
- }
106
- let bestMatch = "";
107
- let bestNamespaces;
94
+ const collected = [
95
+ ...routeNamespaces.default || [],
96
+ // default
97
+ ...namespaces || [],
98
+ // default
99
+ ...routeNamespaces[standardizedPathname] || [],
100
+ // exact match
101
+ ...routeNamespaces[placeholderRemovedPathname] || []
102
+ // exact match
103
+ ];
108
104
  const prefixPatterns = Object.keys(routeNamespaces).filter(
109
105
  (pattern) => pattern.endsWith("/*")
110
106
  );
111
107
  for (const pattern of prefixPatterns) {
112
108
  const basePath = pattern.replace(/\/\*$/, "");
113
- if (standardizedPathname.startsWith(basePath)) {
114
- if (basePath.length > bestMatch.length) {
115
- bestMatch = basePath;
116
- bestNamespaces = routeNamespaces[pattern];
117
- }
109
+ if (standardizedPathname.startsWith(basePath) || placeholderRemovedPathname.startsWith(basePath)) {
110
+ collected.push(...routeNamespaces[pattern] || []);
118
111
  }
119
112
  }
120
- const matchedNamespaces = bestNamespaces ?? routeNamespaces["/*"] ?? fallbackNamespaces ?? [];
121
- if (matchedNamespaces.length > 0) {
122
- return [...defaultNamespaces, ...matchedNamespaces];
123
- } else {
124
- return [...defaultNamespaces];
125
- }
113
+ return [...new Set(collected)];
126
114
  };
127
115
 
128
116
  // src/shared/utils/locale/normalize-locale.ts
117
+ var toCanonical = (input) => {
118
+ try {
119
+ return Intl.getCanonicalLocales(input)[0]?.toLowerCase();
120
+ } catch {
121
+ return;
122
+ }
123
+ };
129
124
  var normalizeLocale = (locale = "", supportedLocales = []) => {
130
125
  if (!locale || supportedLocales.length === 0) return;
131
- const toCanonical = (input) => {
132
- try {
133
- return Intl.getCanonicalLocales(input)[0]?.toLowerCase();
134
- } catch {
135
- return;
136
- }
137
- };
138
126
  const canonicalLocale = toCanonical(locale);
139
127
  if (!canonicalLocale) return;
140
128
  const supportedCanonicalMap = /* @__PURE__ */ new Map();
@@ -165,12 +153,12 @@ var resolvePreferredLocale = (acceptLanguageHeader, supportedLocales) => {
165
153
  const supportedLocalesSet = new Set(supportedLocales);
166
154
  const preferred = acceptLanguageHeader.split(",").map((part) => {
167
155
  const [lang, qValue] = part.split(";");
168
- const q = qValue ? parseFloat(qValue.split("=")[1]) : 1;
169
- if (isNaN(q)) {
156
+ const q = qValue ? Number.parseFloat(qValue.split("=")[1]) : 1;
157
+ if (Number.isNaN(q)) {
170
158
  return { lang: lang.trim(), q: 0 };
171
159
  }
172
160
  return { lang: lang.trim(), q };
173
- }).sort((a, b) => b.q - a.q).find(({ lang }) => supportedLocalesSet.has(lang))?.lang;
161
+ }).toSorted((a, b) => b.q - a.q).find(({ lang }) => supportedLocalesSet.has(lang))?.lang;
174
162
  return preferred;
175
163
  };
176
164
 
@@ -179,8 +167,8 @@ var normalizePathname = (rawPathname, options = {}) => {
179
167
  const length = rawPathname.length;
180
168
  let start = 0;
181
169
  let end = length - 1;
182
- while (start <= end && rawPathname.charCodeAt(start) <= 32) start++;
183
- while (end >= start && rawPathname.charCodeAt(end) <= 32) end--;
170
+ while (start <= end && (rawPathname.codePointAt(start) ?? 0) <= 32) start++;
171
+ while (end >= start && (rawPathname.codePointAt(end) ?? 0) <= 32) end--;
184
172
  if (start > end) return "/";
185
173
  let result = "";
186
174
  let hasSlash = false;
@@ -191,11 +179,7 @@ var normalizePathname = (rawPathname, options = {}) => {
191
179
  hasSlash = true;
192
180
  }
193
181
  } else {
194
- if (hasSlash || result === "") {
195
- result += "/" + char;
196
- } else {
197
- result += char;
198
- }
182
+ result += hasSlash || result === "" ? "/" + char : char;
199
183
  hasSlash = false;
200
184
  }
201
185
  }
@@ -205,42 +189,6 @@ var normalizePathname = (rawPathname, options = {}) => {
205
189
  return result || "/";
206
190
  };
207
191
 
208
- // src/shared/utils/pathname/extract-pathname.ts
209
- var extractPathname = ({
210
- config,
211
- pathname: rawPathname
212
- }) => {
213
- const { routing, defaultLocale } = config;
214
- const { basePath, prefix } = routing;
215
- const normalizedPathname = normalizePathname(rawPathname);
216
- let prefixedPathname = normalizedPathname;
217
- if (basePath && normalizedPathname.startsWith(basePath + "/")) {
218
- prefixedPathname = normalizedPathname.slice(basePath.length) || "/";
219
- } else if (basePath && normalizedPathname === basePath) {
220
- prefixedPathname = "/";
221
- }
222
- const pathParts = prefixedPathname.split("/").filter(Boolean);
223
- const maybeLocale = pathParts[0] || "";
224
- const isLocalePrefixed = config.supportedLocales?.includes(maybeLocale);
225
- let unprefixedPathname = prefixedPathname;
226
- if (prefix === "all") {
227
- if (isLocalePrefixed) {
228
- unprefixedPathname = prefixedPathname.slice(maybeLocale.length + 1) || "/";
229
- }
230
- } else if (prefix === "except-default") {
231
- if (maybeLocale && maybeLocale !== defaultLocale && isLocalePrefixed) {
232
- unprefixedPathname = prefixedPathname.slice(maybeLocale.length + 1) || "/";
233
- }
234
- }
235
- return {
236
- basePath,
237
- prefixedPathname,
238
- unprefixedPathname,
239
- maybeLocale,
240
- isLocalePrefixed: Boolean(isLocalePrefixed)
241
- };
242
- };
243
-
244
192
  // src/shared/utils/pathname/standardize-pathname.ts
245
193
  var standardizePathname = ({
246
194
  config,
@@ -253,7 +201,7 @@ var standardizePathname = ({
253
201
  PREFIX_PLACEHOLDER,
254
202
  normalizePathname(pathname)
255
203
  ];
256
- const standardizedPathname = parts.join("/").replace(/\/{2,}/g, "/");
204
+ const standardizedPathname = parts.join("/").replaceAll(/\/{2,}/g, "/");
257
205
  return normalizePathname(standardizedPathname);
258
206
  };
259
207
 
@@ -307,21 +255,6 @@ var IntorError = class extends Error {
307
255
  }
308
256
  };
309
257
 
310
- // src/modules/messages/load-local-messages/utils/read-message-record-file.ts
311
- var readMessageRecordFile = async (filePath, loggerOptions) => {
312
- const fileName = path__default.default.basename(filePath, ".json");
313
- const content = await fs__default.default.readFile(filePath, "utf-8");
314
- const parsed = JSON.parse(content);
315
- if (typeof parsed !== "object" || parsed === null) {
316
- throw new IntorError({
317
- id: loggerOptions.id,
318
- code: "INTOR_INVALID_MESSAGE_FORMAT" /* INVALID_MESSAGE_FORMAT */,
319
- message: "Invalid message format"
320
- });
321
- }
322
- return { fileName, content: parsed };
323
- };
324
-
325
258
  // src/modules/messages/load-local-messages/load-namespace-group/parse-message-file.ts
326
259
  var MAX_PATH_LENGTH = 260;
327
260
  var parseMessageFile = async (filePath, loggerOptions) => {
@@ -342,9 +275,17 @@ var parseMessageFile = async (filePath, loggerOptions) => {
342
275
  return null;
343
276
  }
344
277
  try {
345
- const { content } = await readMessageRecordFile(trimmedPath, loggerOptions);
346
- logger.trace(`Message file loaded.`, { filePath: trimmedPath });
347
- return content;
278
+ const content = await fs__default.default.readFile(trimmedPath, "utf8");
279
+ const parsed = JSON.parse(content);
280
+ if (typeof parsed !== "object" || parsed === null) {
281
+ throw new IntorError({
282
+ id: loggerOptions.id,
283
+ code: "INTOR_INVALID_MESSAGE_FORMAT" /* INVALID_MESSAGE_FORMAT */,
284
+ message: "Invalid message format"
285
+ });
286
+ }
287
+ logger.trace("Message file loaded.", { filePath: trimmedPath });
288
+ return parsed;
348
289
  } catch (error) {
349
290
  logger.warn("Failed to parse message file.", {
350
291
  filePath: trimmedPath,
@@ -438,7 +379,7 @@ var addToNamespaceGroup = ({
438
379
  const filePathsSet = new Set(group.filePaths);
439
380
  if (!filePathsSet.has(filePath)) {
440
381
  filePathsSet.add(filePath);
441
- group.filePaths = Array.from(filePathsSet);
382
+ group.filePaths = [...filePathsSet];
442
383
  namespaceGroups.set(nsKey, group);
443
384
  }
444
385
  };
@@ -448,14 +389,15 @@ var traverseDirectory = async ({
448
389
  options,
449
390
  currentDirPath,
450
391
  namespaceGroups,
451
- namespacePathSegments
392
+ namespacePathSegments,
393
+ readdir = fs__default.default.readdir
452
394
  }) => {
453
395
  const { limit } = options;
454
396
  const loggerOptions = options.logger || { id: "default" };
455
397
  const baseLogger = getLogger({ ...loggerOptions });
456
398
  const logger = baseLogger.child({ scope: "traverse-directory" });
457
399
  try {
458
- const dirents = await fs__default.default.readdir(currentDirPath, { withFileTypes: true });
400
+ const dirents = await readdir(currentDirPath, { withFileTypes: true });
459
401
  const dirPromises = dirents.map(
460
402
  (dirent) => limit(async () => {
461
403
  const filePath = path__default.default.join(currentDirPath, dirent.name);
@@ -471,7 +413,8 @@ var traverseDirectory = async ({
471
413
  namespaceGroups,
472
414
  currentDirPath: filePath,
473
415
  namespacePathSegments: [...namespacePathSegments, dirent.name],
474
- options
416
+ options,
417
+ readdir
475
418
  });
476
419
  }
477
420
  }).catch((error) => {
@@ -546,7 +489,7 @@ var loadSingleLocale = async ({
546
489
  namespaceGroups: [...namespaceGroups.entries()].map(([ns, val]) => ({
547
490
  namespace: ns,
548
491
  isAtRoot: val.isAtRoot,
549
- fileCounts: val.filePaths.length
492
+ fileCount: val.filePaths.length
550
493
  }))
551
494
  });
552
495
  const namespaceGroupTasks = [...namespaceGroups.entries()].filter(
@@ -577,8 +520,8 @@ var loadLocaleWithFallback = async ({
577
520
  }) => {
578
521
  const baseLogger = getLogger({ ...loggerOptions });
579
522
  const logger = baseLogger.child({ scope: "load-locale-with-fallback" });
580
- const localesToTry = [targetLocale, ...fallbackLocales];
581
- for (const locale of localesToTry) {
523
+ const candidateLocales = [targetLocale, ...fallbackLocales];
524
+ for (const locale of candidateLocales) {
582
525
  try {
583
526
  const validNamespaces = await loadSingleLocale({
584
527
  basePath,
@@ -597,7 +540,7 @@ var loadLocaleWithFallback = async ({
597
540
  }
598
541
  }
599
542
  logger.warn("All fallback locales failed.", {
600
- attemptedLocales: localesToTry
543
+ attemptedLocales: candidateLocales
601
544
  });
602
545
  return;
603
546
  };
@@ -643,8 +586,8 @@ var loadLocalMessages = async ({
643
586
  loggerOptions.id,
644
587
  resolvedBasePath,
645
588
  locale,
646
- [...fallbackLocales ?? []].sort().join(","),
647
- [...namespaces ?? []].sort().join(",")
589
+ (fallbackLocales ?? []).toSorted().join(","),
590
+ (namespaces ?? []).toSorted().join(",")
648
591
  ]);
649
592
  if (cache.enabled && key) {
650
593
  const cached = await pool?.get(key);
@@ -789,8 +732,8 @@ var loadApiMessages = async ({
789
732
  loggerOptions.id,
790
733
  basePath,
791
734
  locale,
792
- [...fallbackLocales ?? []].sort().join(","),
793
- [...namespaces ?? []].sort().join(",")
735
+ (fallbackLocales ?? []).toSorted().join(","),
736
+ (namespaces ?? []).toSorted().join(",")
794
737
  ]);
795
738
  if (cache.enabled && key) {
796
739
  const cached = await pool?.get(key);
@@ -852,7 +795,7 @@ var loadMessages = async ({
852
795
  );
853
796
  return;
854
797
  }
855
- const { loader } = config;
798
+ const { id, loader, cache } = config;
856
799
  const fallbackLocales = config.fallbackLocales[locale] || [];
857
800
  const namespaces = resolveNamespaces({ config, pathname });
858
801
  logger.debug("Namespaces ready for loading.", {
@@ -867,8 +810,8 @@ var loadMessages = async ({
867
810
  locale,
868
811
  fallbackLocales,
869
812
  namespaces,
870
- cache: config.cache,
871
- logger: { id: config.id }
813
+ cache,
814
+ logger: { id }
872
815
  });
873
816
  } else if (loader.type === "api") {
874
817
  loadedMessages = await loadApiMessages({
@@ -876,7 +819,7 @@ var loadMessages = async ({
876
819
  locale,
877
820
  fallbackLocales,
878
821
  namespaces,
879
- logger: { id: config.id }
822
+ logger: { id }
880
823
  });
881
824
  }
882
825
  if (!loadedMessages || Object.keys(loadedMessages).length === 0) {
@@ -887,29 +830,23 @@ var loadMessages = async ({
887
830
 
888
831
  // src/modules/tools/get-translator.ts
889
832
  async function getTranslator(opts) {
890
- const { config, locale, pathname = "", preKey } = opts;
833
+ const { config, locale, pathname = "", preKey, handlers } = opts;
891
834
  const messages = await loadMessages({ config, locale, pathname });
892
835
  const translator = new intorTranslator.Translator({
893
836
  locale,
894
837
  messages,
895
838
  fallbackLocales: config.fallbackLocales,
896
839
  loadingMessage: config.translator?.loadingMessage,
897
- placeholder: config.translator?.placeholder
840
+ placeholder: config.translator?.placeholder,
841
+ handlers
898
842
  });
899
- const props = {
900
- messages,
901
- locale
843
+ const props = { messages, locale };
844
+ const scoped = translator.scoped(preKey);
845
+ return {
846
+ ...props,
847
+ hasKey: preKey ? scoped.hasKey : translator.hasKey,
848
+ t: preKey ? scoped.t : translator.t
902
849
  };
903
- if (preKey) {
904
- const scoped = translator.scoped(preKey);
905
- return { ...props, ...scoped };
906
- } else {
907
- return {
908
- ...props,
909
- t: translator.t,
910
- hasKey: translator.hasKey
911
- };
912
- }
913
850
  }
914
851
 
915
852
  // src/adapters/next/server/get-translator.ts