@koine/i18n 2.0.0-beta.100

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 (149) hide show
  1. package/README.md +1 -0
  2. package/adapter-js/code/config.cjs.d.ts +3 -0
  3. package/adapter-js/code/config.d.ts +3 -0
  4. package/adapter-js/code/createT.d.ts +3 -0
  5. package/adapter-js/code/defaultI18nMetadata.d.ts +3 -0
  6. package/adapter-js/code/defaultLocale.d.ts +3 -0
  7. package/adapter-js/code/formatUrl.d.ts +3 -0
  8. package/adapter-js/code/getI18nAlternatesFromDom.d.ts +3 -0
  9. package/adapter-js/code/getI18nDictionaries.d.ts +3 -0
  10. package/adapter-js/code/getI18nMetadata.d.ts +3 -0
  11. package/adapter-js/code/getT.d.ts +3 -0
  12. package/adapter-js/code/index.d.ts +3 -0
  13. package/adapter-js/code/isLocale.d.ts +3 -0
  14. package/adapter-js/code/loadTranslations.d.ts +3 -0
  15. package/adapter-js/code/locales.d.ts +3 -0
  16. package/adapter-js/code/pathnameToRouteId.d.ts +3 -0
  17. package/adapter-js/code/routes.d.ts +3 -0
  18. package/adapter-js/code/routesError.d.ts +3 -0
  19. package/adapter-js/code/routesSlim.d.ts +3 -0
  20. package/adapter-js/code/routesSpa.d.ts +3 -0
  21. package/adapter-js/code/t.d.ts +3 -0
  22. package/adapter-js/code/tInterpolateParams.d.ts +3 -0
  23. package/adapter-js/code/tPluralise.d.ts +3 -0
  24. package/adapter-js/code/to.d.ts +3 -0
  25. package/adapter-js/code/toFns.d.ts +3 -0
  26. package/adapter-js/code/toFormat.d.ts +3 -0
  27. package/adapter-js/code/toSpa.d.ts +3 -0
  28. package/adapter-js/code/types.d.ts +3 -0
  29. package/adapter-js/index.d.ts +5 -0
  30. package/adapter-js/options.d.ts +4 -0
  31. package/adapter-next/code/I18nApp.d.ts +3 -0
  32. package/adapter-next/code/I18nHead.d.ts +3 -0
  33. package/adapter-next/code/I18nLayout.d.ts +3 -0
  34. package/adapter-next/code/I18nPage.d.ts +3 -0
  35. package/adapter-next/code/I18nRoot.d.ts +3 -0
  36. package/adapter-next/code/I18nSetter.d.ts +3 -0
  37. package/adapter-next/code/deprecated_useLocale.d.ts +3 -0
  38. package/adapter-next/code/i18nGet.d.ts +3 -0
  39. package/adapter-next/code/index.d.ts +3 -0
  40. package/adapter-next/code/next-redirects.d.ts +3 -0
  41. package/adapter-next/code/next-rewrites.d.ts +3 -0
  42. package/adapter-next/code/useRouteId.d.ts +3 -0
  43. package/adapter-next/code/useTo.d.ts +3 -0
  44. package/adapter-next/code/useToSpa.d.ts +3 -0
  45. package/adapter-next/index.d.ts +5 -0
  46. package/adapter-next/options.d.ts +4 -0
  47. package/adapter-next/plugin-async.d.ts +8 -0
  48. package/adapter-next/plugin-legacy.d.ts +18 -0
  49. package/adapter-next/plugin-shared.d.ts +9 -0
  50. package/adapter-next/plugin.d.ts +6 -0
  51. package/adapter-next/redirects.d.ts +5 -0
  52. package/adapter-next/rewrites.d.ts +5 -0
  53. package/adapter-next/transformPathname.d.ts +1 -0
  54. package/adapter-next/webpackPluginI18n.d.ts +7 -0
  55. package/adapter-next-translate/code/DynamicNamespaces.d.ts +3 -0
  56. package/adapter-next-translate/code/I18nProvider.d.ts +3 -0
  57. package/adapter-next-translate/code/T.d.ts +3 -0
  58. package/adapter-next-translate/code/TransText.d.ts +3 -0
  59. package/adapter-next-translate/code/getT.d.ts +3 -0
  60. package/adapter-next-translate/code/index.d.ts +3 -0
  61. package/adapter-next-translate/code/nextTranslateI18n.d.ts +3 -0
  62. package/adapter-next-translate/code/useLocale.d.ts +3 -0
  63. package/adapter-next-translate/code/useT.d.ts +3 -0
  64. package/adapter-next-translate/index.d.ts +5 -0
  65. package/adapter-next-translate/options.d.ts +3 -0
  66. package/adapter-react/code/I18nContext.d.ts +3 -0
  67. package/adapter-react/code/I18nEffects.d.ts +3 -0
  68. package/adapter-react/code/I18nHeadTags.d.ts +3 -0
  69. package/adapter-react/code/I18nMetadataContext.d.ts +3 -0
  70. package/adapter-react/code/I18nMetadataProvider.d.ts +3 -0
  71. package/adapter-react/code/I18nMetadataSetter.d.ts +3 -0
  72. package/adapter-react/code/I18nProvider.d.ts +3 -0
  73. package/adapter-react/code/I18nRouteContext.d.ts +3 -0
  74. package/adapter-react/code/I18nRouteProvider.d.ts +3 -0
  75. package/adapter-react/code/I18nRouteSetter.d.ts +3 -0
  76. package/adapter-react/code/T.d.ts +3 -0
  77. package/adapter-react/code/TransText.d.ts +3 -0
  78. package/adapter-react/code/formatElements.d.ts +3 -0
  79. package/adapter-react/code/index.d.ts +2 -0
  80. package/adapter-react/code/useI18nSwitch.d.ts +3 -0
  81. package/adapter-react/code/useLocale.d.ts +3 -0
  82. package/adapter-react/code/useRouteId.d.ts +3 -0
  83. package/adapter-react/code/useT.d.ts +3 -0
  84. package/adapter-react/index.d.ts +5 -0
  85. package/adapter-react/options.d.ts +2 -0
  86. package/api.cjs.js +4026 -0
  87. package/api.esm.js +4000 -0
  88. package/client/formatRoutePathname.d.ts +4 -0
  89. package/client/index.d.ts +3 -0
  90. package/client/interpolateTo.d.ts +4 -0
  91. package/client/routeHasDynamicPortion.d.ts +2 -0
  92. package/compiler/adapter.d.ts +10 -0
  93. package/compiler/api.d.ts +34 -0
  94. package/compiler/code/data-routes.d.ts +21 -0
  95. package/compiler/code/data-translations.d.ts +16 -0
  96. package/compiler/code/data.d.ts +17 -0
  97. package/compiler/code/generate.d.ts +10 -0
  98. package/compiler/code/index.d.ts +3 -0
  99. package/compiler/code/tsCompile.d.ts +2 -0
  100. package/compiler/code/write.d.ts +10 -0
  101. package/compiler/config.d.ts +21 -0
  102. package/compiler/createAdapter.d.ts +5 -0
  103. package/compiler/helpers.d.ts +3 -0
  104. package/compiler/input/data-local.d.ts +4 -0
  105. package/compiler/input/data-remote.d.ts +7 -0
  106. package/compiler/input/data.d.ts +4 -0
  107. package/compiler/input/index.d.ts +4 -0
  108. package/compiler/input/types.d.ts +14 -0
  109. package/compiler/input/write.d.ts +8 -0
  110. package/compiler/pluralisation.d.ts +37 -0
  111. package/compiler/summary/data.d.ts +6 -0
  112. package/compiler/summary/generate.d.ts +3 -0
  113. package/compiler/summary/index.d.ts +2 -0
  114. package/compiler/summary/write.d.ts +10 -0
  115. package/compiler/types.d.ts +94 -0
  116. package/compiler-sync.cjs.d.ts +1 -0
  117. package/compiler-sync.cjs.default.js +1 -0
  118. package/compiler-sync.cjs.js +11 -0
  119. package/compiler-sync.cjs.mjs +2 -0
  120. package/compiler-sync.d.ts +4 -0
  121. package/compiler-sync.esm.js +7 -0
  122. package/compiler-worker.cjs.d.ts +1 -0
  123. package/compiler-worker.cjs.default.js +1 -0
  124. package/compiler-worker.cjs.js +17 -0
  125. package/compiler-worker.cjs.mjs +2 -0
  126. package/compiler-worker.d.ts +1 -0
  127. package/compiler-worker.esm.js +15 -0
  128. package/compiler.cjs.d.ts +1 -0
  129. package/compiler.cjs.default.js +1 -0
  130. package/compiler.cjs.js +20 -0
  131. package/compiler.cjs.mjs +2 -0
  132. package/compiler.d.ts +2 -0
  133. package/compiler.esm.js +12 -0
  134. package/formatRoutePathname.cjs.js +10 -0
  135. package/formatRoutePathname.esm.js +8 -0
  136. package/index.cjs.d.ts +1 -0
  137. package/index.cjs.default.js +1 -0
  138. package/index.cjs.js +49 -0
  139. package/index.cjs.mjs +2 -0
  140. package/index.d.ts +2 -0
  141. package/index.esm.js +44 -0
  142. package/next.cjs.d.ts +1 -0
  143. package/next.cjs.default.js +1 -0
  144. package/next.cjs.js +353 -0
  145. package/next.cjs.mjs +2 -0
  146. package/next.d.ts +3 -0
  147. package/next.esm.js +329 -0
  148. package/package.json +62 -0
  149. package/types.d.ts +48 -0
package/api.cjs.js ADDED
@@ -0,0 +1,4026 @@
1
+ 'use strict';
2
+
3
+ var node_fs = require('node:fs');
4
+ var node_path = require('node:path');
5
+ var node = require('@koine/node');
6
+ var utils = require('@koine/utils');
7
+ var formatRoutePathname = require('./formatRoutePathname.cjs.js');
8
+ var t$2 = require('typescript');
9
+ var minimatch = require('minimatch');
10
+ var utils$1 = require('next/dist/shared/lib/utils');
11
+ var promises = require('node:fs/promises');
12
+ var glob = require('glob');
13
+ var node_https = require('node:https');
14
+
15
+ function _interopNamespace(e) {
16
+ if (e && e.__esModule) return e;
17
+ var n = Object.create(null);
18
+ if (e) {
19
+ Object.keys(e).forEach(function (k) {
20
+ if (k !== 'default') {
21
+ var d = Object.getOwnPropertyDescriptor(e, k);
22
+ Object.defineProperty(n, k, d.get ? d : {
23
+ enumerable: true,
24
+ get: function () { return e[k]; }
25
+ });
26
+ }
27
+ });
28
+ }
29
+ n["default"] = e;
30
+ return Object.freeze(n);
31
+ }
32
+
33
+ var t__namespace = /*#__PURE__*/_interopNamespace(t$2);
34
+
35
+ // /**
36
+ // * Adapter creator function, either _sync_ or _async_
37
+ // */
38
+ // export type AdapterCreator<T extends AdaptersName> = (
39
+ // arg: AdapterArg<T>,
40
+ // ) => Adapter<T> | Promise<Adapter<T>>;
41
+ // /**
42
+ // * Adapter anatomy
43
+ // */
44
+ // export type Adapter<T extends AdaptersName = AdaptersName> = {
45
+ // dependsOn?: AdaptersName[];
46
+ // files: AdapterFile<T>[];
47
+ // /**
48
+ // * Adapters like `next-translate` need the JSON file to be available
49
+ // */
50
+ // needsTranslationsFiles?: boolean;
51
+ // };
52
+ let createAdapter = (e, r)=>(o, p)=>r({
53
+ ...o,
54
+ adapterOptions: utils.objectMergeWithDefaults(e, p)
55
+ });
56
+
57
+ const adapterJsOptions = {
58
+ modularized: !1
59
+ }; /**
60
+ * - When `true` it outpus each function in a separate file with a `named` and a
61
+ * `default` export in order to fully support SWC modularizeImport optimization.
62
+ * You will use these functions with named exports from `@/i18n/t`, e.g.
63
+ * ```ts
64
+ * import { myMessage_key } from "@/i18n/t";
65
+ *
66
+ * myMessage_key();
67
+ * ```
68
+ * This import is transformed into `import myMessage_key from "@/i18n/t/myMessage_key";`
69
+ *
70
+ *
71
+ * - When `false` usage is:
72
+ * ```ts
73
+ * import { t } from "@/i18n";
74
+ *
75
+ * t.myMessage_key();
76
+ * ```
77
+ *
78
+ * @default false
79
+ */
80
+
81
+ var o$8 = (({ config: e })=>`
82
+ import { locales } from "./locales";
83
+ import { defaultLocale } from "./defaultLocale";
84
+
85
+ /**
86
+ */
87
+ export const config = {
88
+ locales,
89
+ defaultLocale,
90
+ hideDefaultLocaleInUrl: ${e.hideDefaultLocaleInUrl},
91
+ }
92
+
93
+ export default config;
94
+ `);
95
+
96
+ var m$6 = (({ config: e })=>`
97
+ const { locales } = require("./locales");
98
+ const { defaultLocale } = require("./defaultLocale");
99
+
100
+ const config = {
101
+ locales,
102
+ defaultLocale,
103
+ hideDefaultLocaleInUrl: ${e.hideDefaultLocaleInUrl},
104
+ };
105
+
106
+ exports.config = config;
107
+
108
+ module.exports = config;
109
+ `);
110
+
111
+ /**
112
+ * TODO: maybe use `params` to determine the right type with some kind of special
113
+ * token used in the route id
114
+ *
115
+ * NB: wrap the output of this function, e.g. `type A = {${dataParamsToTsInterfaceBody(params)}}`
116
+ */ let dataParamsToTsInterfaceBody = (e)=>Object.keys(e).reduce((r, t)=>{
117
+ let a = e[t], s = "";
118
+ switch(a){
119
+ case "number":
120
+ s = "number";
121
+ break;
122
+ case "string":
123
+ s = "string";
124
+ break;
125
+ default:
126
+ s = "string | number";
127
+ }
128
+ return r.push(`${t}: ${s};`), r;
129
+ }, []).join(" ");
130
+ let escapeEachChar = (e)=>e.split("").map((e)=>`\\${e}`).join("");
131
+
132
+ var r$5 = (({ config: t, options: n })=>{
133
+ let { start: r, end: a } = n.translations.tokens.dynamicDelimiters;
134
+ return `
135
+ import type { I18n } from "./types";
136
+ import { defaultLocale } from "./defaultLocale";
137
+ import { tInterpolateParams } from "./tInterpolateParams";
138
+
139
+ // An optional parameter allowEmptyStrings - true as default.
140
+ // If allowEmptyStrings parameter is marked as false,
141
+ // it should log an error when an empty string is attempted to be translated
142
+ // and return the namespace and key as result of the translation.
143
+ const allowEmptyStrings = true;
144
+
145
+ /**
146
+ * @see https://github.com/aralroca/next-translate/blob/master/src/transCore.tsx
147
+ */
148
+ export function createT<TNamespace extends I18n.TranslateNamespace>(
149
+ dictionaries: I18n.Dictionaries,
150
+ pluralRules: Intl.PluralRules,
151
+ locale: string = defaultLocale,
152
+ ) {
153
+ const interpolateUnknown = (
154
+ value: unknown,
155
+ query?: I18n.TranslationQuery | null,
156
+ ): typeof value => {
157
+ if (Array.isArray(value)) {
158
+ return value.map((val) => interpolateUnknown(val, query));
159
+ }
160
+ if (value instanceof Object) {
161
+ return objectInterpolation(
162
+ value as Record<string, unknown>,
163
+ query,
164
+ locale,
165
+ );
166
+ }
167
+ return interpolation(value as string, query, locale);
168
+ };
169
+
170
+ return <
171
+ TPath extends I18n.TranslationsPaths<
172
+ I18n.TranslationsDictionary[TNamespace]
173
+ >,
174
+ TReturn = I18n.TranslationAtPathFromNamespace<TNamespace, TPath>,
175
+ >(
176
+ key: TPath,
177
+ query?: I18n.TranslationQuery,
178
+ options?: I18n.TranslationOptions,
179
+ ): TReturn => {
180
+ const k = Array.isArray(key) ? key[0] : key;
181
+ const [namespace, i18nKey] = k.split("${n.translations.tokens.namespaceDelimiter}");
182
+ const dic = (namespace && dictionaries[namespace]) || {};
183
+ const pluralisedKey = getPluralisedKey(pluralRules, dic, i18nKey, query, options);
184
+ const dicValue = getDicValue(dic, pluralisedKey, query, options);
185
+ const value =
186
+ typeof dicValue === "object"
187
+ ? JSON.parse(JSON.stringify(dicValue))
188
+ : dicValue;
189
+
190
+ const empty =
191
+ typeof value === "undefined" ||
192
+ (typeof value === "object" && !Object.keys(value).length) ||
193
+ (value === "" && !allowEmptyStrings);
194
+
195
+ // no need to try interpolation
196
+ if (empty) {
197
+ return query === "" ? "" : k;
198
+ }
199
+
200
+ // this can return an empty string if either value was already empty
201
+ // or it contained only an interpolation (e.g. "{{name}}") and the query param was empty
202
+ return interpolateUnknown(value, query) as TReturn;
203
+ };
204
+ }
205
+
206
+ // const Empty = new Symbol("Empty tranlsation message")
207
+
208
+ /**
209
+ * Get value from key (allow nested keys as parent.children)
210
+ */
211
+ function getDicValue(
212
+ dic: I18n.TranslationsDictionaryLoose,
213
+ key: string = "",
214
+ query?: I18n.TranslationQuery,
215
+ options?: I18n.TranslationOptions,
216
+ ): unknown | undefined {
217
+ const keySeparator = ".";
218
+ const keyParts = keySeparator ? key.split(keySeparator) : [key];
219
+ const returnObjects =
220
+ query === "obj" ||
221
+ options === "obj" ||
222
+ (options instanceof Object && options.returnObjects);
223
+
224
+ if (key === keySeparator && returnObjects) return dic;
225
+
226
+ const value: string | object = keyParts.reduce(
227
+ (val: I18n.TranslationsDictionaryLoose | string, key: string) => {
228
+ if (typeof val === "string") {
229
+ return {};
230
+ }
231
+
232
+ const res = val[key as keyof typeof val];
233
+
234
+ // pass all truthy values or (empty) strings
235
+ return res || (typeof res === "string" ? res : {});
236
+ },
237
+ dic,
238
+ );
239
+
240
+ if (
241
+ typeof value === "string" ||
242
+ (returnObjects && Object.keys(value).length > 0)
243
+ ) {
244
+ return value;
245
+ }
246
+
247
+ if (Array.isArray(value) && returnObjects) return value;
248
+ return undefined;
249
+ }
250
+
251
+ /**
252
+ * Control plural keys depending the {{count}} variable
253
+ */
254
+ function getPluralisedKey(
255
+ pluralRules: Intl.PluralRules,
256
+ dic: I18n.TranslationsDictionaryLoose,
257
+ key: string,
258
+ query?: I18n.TranslationQuery | null,
259
+ options?: I18n.TranslationOptions,
260
+ ): string {
261
+ const count = query instanceof Object ? query.count : null;
262
+
263
+ if (!query || typeof count !== "number") return key;
264
+
265
+ const numKey = \`\${key}_\${count}\`;
266
+ if (getDicValue(dic, numKey, query, options) !== undefined) return numKey;
267
+
268
+ const pluralKey = \`\${key}_\${pluralRules.select(count)}\`;
269
+ if (getDicValue(dic, pluralKey, query, options) !== undefined) {
270
+ return pluralKey;
271
+ }
272
+
273
+ const nestedNumKey = \`\${key}.\${count}\`;
274
+ if (getDicValue(dic, nestedNumKey, query, options) !== undefined)
275
+ return nestedNumKey;
276
+
277
+ const nestedKey = \`\${key}.\${pluralRules.select(count)}\`;
278
+ if (getDicValue(dic, nestedKey, query, options) !== undefined)
279
+ return nestedKey;
280
+
281
+ return key;
282
+ }
283
+
284
+ /**
285
+ * Replace {{variables}} to query values
286
+ */
287
+ function interpolation(
288
+ text?: string,
289
+ query?: I18n.TranslationQuery | null,
290
+ _locale?: string | undefined,
291
+ ): string {
292
+ if (!text || !query || query === "obj") return text || "";
293
+
294
+ return tInterpolateParams(text, query);
295
+ // return Object.keys(query).reduce((all, key) => {
296
+ // // eslint-disable-next-line no-useless-escape
297
+ // const regex = new RegExp(\`${escapeEachChar(r)}\\s*\${key}(?:[\\s,]+([\\w-]*))?\\s*\$${escapeEachChar(a)}\`, "gm");
298
+ // return all.replace(regex, (_match) => query[key as keyof typeof query] as string);
299
+ // }, text);
300
+ }
301
+
302
+ function objectInterpolation(
303
+ obj: Record<string, string | unknown>,
304
+ query?: I18n.TranslationQuery | null,
305
+ locale?: string,
306
+ ) {
307
+ if (!query || Object.keys(query).length === 0) return obj;
308
+ Object.keys(obj).forEach((key) => {
309
+ if (obj[key] instanceof Object)
310
+ objectInterpolation(
311
+ obj[key] as Record<string, string | unknown>,
312
+ query,
313
+ locale,
314
+ );
315
+ if (typeof obj[key] === "string")
316
+ obj[key] = interpolation(obj[key] as string, query, locale);
317
+ });
318
+
319
+ return obj;
320
+ }
321
+ `;
322
+ });
323
+
324
+ var n$6 = (({})=>`
325
+ import type { I18n } from "./types";
326
+
327
+ /**
328
+ * @internal
329
+ */
330
+ export const defaultI18nMetadata: I18n.Metadata = {
331
+ canonical: "",
332
+ alternates: {}
333
+ }
334
+ `);
335
+
336
+ var a$7 = (({ config: e })=>`
337
+ import type { I18n } from "./types";
338
+
339
+ export const defaultLocale: I18n.Locale = "${e.defaultLocale}";
340
+
341
+ export default defaultLocale;
342
+ `);
343
+
344
+ var f$4 = (({ config: { baseUrl: a, trailingSlash: e } })=>`
345
+ /**
346
+ * @param pathname Normalised, always prepended with a locale (if needed) and a slash
347
+ */
348
+ export const formatUrl = (pathname: string) => "${a}" + ${e ? "pathname" : '(pathname === "/" ? "" : pathname)'};
349
+
350
+ export default formatUrl;
351
+ `);
352
+
353
+ var i$8 = (({})=>`
354
+ import { defaultLocale } from "./defaultLocale";
355
+ // import { loadTranslations } from "./loadTranslations";
356
+ import type { I18n } from "./types";
357
+
358
+ type GetI18nDictionariesOptions = {
359
+ locale?: I18n.Locale;
360
+ namespaces?: I18n.TranslateNamespace[];
361
+ };
362
+
363
+ export async function getI18nDictionaries({
364
+ locale = defaultLocale,
365
+ namespaces = [],
366
+ }: GetI18nDictionariesOptions) {
367
+ const translations =
368
+ (await Promise.all(
369
+ namespaces.map((namespace) =>
370
+ // prettier-ignore
371
+ import(\`./translations/\${locale}/\${namespace}.json\`).then((m) => m.default)
372
+ // loadTranslations(locale, namespace)
373
+ .catch(() => ({}))),
374
+ )) || [];
375
+
376
+ return namespaces.reduce((dictionaries, ns, idx) => {
377
+ dictionaries[ns] =
378
+ translations[idx] ||
379
+ (null as unknown as I18n.TranslationsDictionaryLoose);
380
+ return dictionaries;
381
+ }, {} as I18n.Dictionaries);
382
+ }
383
+
384
+ export default getI18nDictionaries;
385
+ `);
386
+
387
+ var s$8 = (({})=>`
388
+ import { defaultI18nMetadata } from "./defaultI18nMetadata";
389
+ import { defaultLocale } from "./defaultLocale";
390
+ import { formatUrl } from "./formatUrl";
391
+ import { locales } from "./locales";
392
+ import { type RouteIdError, isErrorRoute } from "./routesError";
393
+ import { to } from "./to";
394
+ import type { I18n } from "./types";
395
+
396
+ /**
397
+ * - All localised variants should always be included (despite the current lang)
398
+ * - We use the defaultLocale's URL as the \`x-default\` alternate value
399
+ *
400
+ * @internal
401
+ * @see https://developers.google.com/search/docs/specialty/international/localized-versions#html
402
+ */
403
+ type GetI18nMetadataOptions<TRouteId extends I18n.RouteId | RouteIdError> =
404
+ {
405
+ locale: I18n.Locale;
406
+ } & I18n.RouteArgs<TRouteId>;
407
+
408
+ export function getI18nMetadata<
409
+ TRouteId extends I18n.RouteId | RouteIdError,
410
+ >({ locale: currentLocale, id, params }: GetI18nMetadataOptions<TRouteId>) {
411
+ if (isErrorRoute(id)) return defaultI18nMetadata;
412
+ const alternates: I18n.Alternates = {
413
+ "x-default": formatUrl(
414
+ params ? to(id, params, defaultLocale) : to(id, defaultLocale),
415
+ ),
416
+ };
417
+ locales
418
+ .forEach((locale) => {
419
+ alternates[locale] = formatUrl(
420
+ params ? to(id, params, locale) : to(id, locale),
421
+ );
422
+ });
423
+
424
+ return {
425
+ alternates,
426
+ canonical: formatUrl(
427
+ params ? to(id, params, currentLocale) : to(id, currentLocale)
428
+ )
429
+ };
430
+ }
431
+
432
+ export default getI18nMetadata;
433
+ `);
434
+
435
+ var p$5 = (({})=>`
436
+ import { createT } from "./createT";
437
+ // import { loadTranslations } from "./loadTranslations";
438
+ import type { I18n } from "./types";
439
+
440
+ export async function getT<TNamespace extends I18n.TranslateNamespace>(
441
+ locale: I18n.Locale,
442
+ namespace: TNamespace,
443
+ ) {
444
+ // prettier-ignore
445
+ const translations = await import(\`./translations/\${locale}/\${namespace}.json\`).then((m) => m.default);
446
+ // const translations = await loadTranslations(locale, namespace);
447
+ const pluralRules = new Intl.PluralRules(locale);
448
+
449
+ const t = createT({ [namespace]: translations }, pluralRules, locale);
450
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
451
+ return ((i18nKey: string, ...args: any[]) =>
452
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
453
+ (t as any)(
454
+ \`\${namespace}:\${i18nKey}\`,
455
+ ...args,
456
+ )) as I18n.TranslateNamespaced<TNamespace>;
457
+ }
458
+
459
+ export default getT;
460
+
461
+ `);
462
+
463
+ var x$4 = (({})=>`
464
+ import { locales } from "./locales";
465
+ import type { I18n } from "./types";
466
+
467
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
468
+ export const isLocale = (payload: any): payload is I18n.Locale =>
469
+ locales.includes(payload);
470
+
471
+ export default isLocale;
472
+ `);
473
+
474
+ var d$6 = (({})=>`
475
+ import type { I18n } from "./types";
476
+
477
+ /**
478
+ * @internal
479
+ */
480
+ export const loadTranslations = (
481
+ locale: I18n.Locale,
482
+ namespace: I18n.TranslateNamespace,
483
+ ) =>
484
+ import(\`./translations/\${locale}/\${namespace}.json\`).then(
485
+ (m) => m.default,
486
+ );
487
+ `);
488
+
489
+ var l$4 = (({ config: e })=>{
490
+ let l = `[${e.locales.map((e)=>`"${e}"`).join(", ")}]`;
491
+ return `
492
+ export const locales = ${l} as const;
493
+
494
+ export default locales;
495
+ `;
496
+ });
497
+
498
+ var c$3 = (({ options: t })=>{
499
+ let { idDelimiter: a, optionalCatchAll: r, catchAll: o } = t.routes.tokens;
500
+ return `
501
+ /**
502
+ * Convert a URL like pathname to a "named route"
503
+ * E.g. it transforms:
504
+ * - \`/dashboard/user/[id]\` into \`dashboard.user.[id]\`
505
+ */
506
+ export const pathnameToRouteId = (pathname: string) =>
507
+ pathname
508
+ .replace(/^\\//g, "")
509
+ .replace(/\\//g, "${a}")
510
+ .replace(/${utils.escapeRegExp(a)}${utils.escapeRegExp(r.start)}.+$/, "")
511
+ .replace(/${utils.escapeRegExp(a)}${utils.escapeRegExp(o.start)}.+$/, "")
512
+ .replace(/\\/index$/, "");
513
+
514
+ export default pathnameToRouteId;
515
+ `;
516
+ });
517
+
518
+ var u$2 = (({ routes: t })=>{
519
+ let e = JSON.stringify(Object.fromEntries(Object.entries(t.byId).map(([t, { pathnames: e }])=>[
520
+ t,
521
+ e
522
+ ]).sort()), null, 2);
523
+ return `
524
+ /**
525
+ * @internal
526
+ */
527
+ export const routes = ${e} as const;
528
+
529
+ // export default routes;
530
+ `;
531
+ });
532
+
533
+ var g$2 = (({})=>`
534
+
535
+ export type RouteIdError = (typeof routesError)[number];
536
+
537
+ /**
538
+ * @internal
539
+ */
540
+ export const routesError = [
541
+ "404",
542
+ "500",
543
+ "403"
544
+ ] as const;
545
+
546
+ /**
547
+ * @internal
548
+ */
549
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
550
+ export const isErrorRoute = (payload: any): payload is RouteIdError =>
551
+ routesError.includes(payload);
552
+
553
+ // export default routesError;
554
+ `);
555
+
556
+ var I$3 = (({ routes: t })=>{
557
+ let e = JSON.stringify(Object.fromEntries(Object.entries(t.byId).map(([t, { pathnamesSlim: e, pathnames: r }])=>[
558
+ t,
559
+ e || r
560
+ ]).sort()), null, 2);
561
+ return `
562
+ /**
563
+ * @internal
564
+ */
565
+ export const routesSlim = ${e} as const;
566
+
567
+ // export default routesSlim;
568
+ `;
569
+ });
570
+
571
+ var T$2 = (({ routes: t })=>{
572
+ let e = JSON.stringify(Object.fromEntries(Object.entries(t.byId).filter(([, { pathnamesSpa: t }])=>!!t).map(([t, { pathnamesSpa: e }])=>[
573
+ t,
574
+ e
575
+ ]).sort()), null, 2);
576
+ return `
577
+ /**
578
+ * @internal
579
+ */
580
+ export const routesSpa = ${e} as const;
581
+
582
+ export default routesSpa;
583
+ `;
584
+ });
585
+
586
+ // /**
587
+ // * Control plural keys depending the {{count}} variable
588
+ // */
589
+ // function plural(
590
+ // pluralRules: Intl.PluralRules,
591
+ // dic: I18nDictionary,
592
+ // key: string,
593
+ // config: I18nConfig,
594
+ // query?: TranslationQuery | null,
595
+ // options?: {
596
+ // returnObjects?: boolean
597
+ // fallback?: string | string[]
598
+ // }
599
+ // ): string {
600
+ // if (!query || typeof query.count !== 'number') return key
601
+ // const numKey = `${key}_${query.count}`
602
+ // if (getDicValue(dic, numKey, config, options) !== undefined) return numKey
603
+ // const pluralKey = `${key}_${pluralRules.select(query.count)}`
604
+ // if (getDicValue(dic, pluralKey, config, options) !== undefined) {
605
+ // return pluralKey
606
+ // }
607
+ // const nestedNumKey = `${key}.${query.count}`
608
+ // if (getDicValue(dic, nestedNumKey, config, options) !== undefined)
609
+ // return nestedNumKey
610
+ // const nestedKey = `${key}.${pluralRules.select(query.count)}`
611
+ // if (getDicValue(dic, nestedKey, config, options) !== undefined)
612
+ // return nestedKey
613
+ // return key
614
+ // }
615
+ // const getP = (dic) => {
616
+ // return
617
+ // }
618
+ let i$7 = (t)=>utils.isString(t) || utils.isNumber(t) ? `"${t}"` : utils.isBoolean(t) ? `${t}` : utils.isArray(t) ? JSON.stringify(t) : `(${JSON.stringify(t)})`, s$7 = (e, r)=>utils.areEqual(e, r), p$4 = (t, e)=>{
619
+ let { defaultLocale: r } = t, l = "";
620
+ for(let t in e){
621
+ let o = e[t];
622
+ t === r || s$7(o, e[r]) || (l += `locale === "${t}" ? ${i$7(o)} : `);
623
+ }
624
+ return l + i$7(e[r]);
625
+ };
626
+ var S = (({ config: t, options: e, translations: r })=>{
627
+ let l = `
628
+ /* eslint-disable @typescript-eslint/no-unused-vars */
629
+ /* eslint-disable prefer-const */
630
+ import type { I18n } from "./types";
631
+ import { tInterpolateParams } from "./tInterpolateParams";
632
+ import { tPluralise } from "./tPluralise";
633
+
634
+ `, n = [], s = [];
635
+ for(let l in r){
636
+ let m = "", { values: u, params: f, plural: $ } = r[l], c = `${e.translations.fnsPrefix}${l}`;
637
+ $ && (f ? f.count = "number" : f = {
638
+ count: "number"
639
+ });
640
+ let P = [
641
+ f ? `params: { ${dataParamsToTsInterfaceBody(f)} }` : "",
642
+ // for ergonomy always allow the user to pass the locale
643
+ "locale?: I18n.Locale"
644
+ ].filter(Boolean).join(", ");
645
+ // const formatArgParams = params ? ", params" : "";
646
+ m += `export let ${c} = (${P}) => `;
647
+ let d = "";
648
+ utils.isPrimitive(u) ? d += i$7(u) : d += p$4(t, u), $ && (d = `tPluralise(${d}, params.count)`), m += d = f ? `tInterpolateParams(${d}, params);` : `${d};`, n.push(m), s.push(c);
649
+ }
650
+ return l + (n.join("\n") + // TODO: verify the impact of the following on bundle size, its relation to
651
+ // modularizeImports and maybe make this controllable through an adapter
652
+ // option
653
+ `\n\n` + `export const t = {\n ${s.join(",\n ")}\n};` + `\n\n`) + "export default t;";
654
+ });
655
+
656
+ var F = (({ options: a })=>{
657
+ let { start: t, end: r } = a.translations.tokens.dynamicDelimiters;
658
+ return `
659
+ /**
660
+ * @internal
661
+ */
662
+ /* eslint-disable prefer-const */
663
+ export let tInterpolateParams = (
664
+ value: string,
665
+ params?: object,
666
+ ) =>
667
+ params ? value.replace(
668
+ /${escapeEachChar(t)}(.*?)${escapeEachChar(r)}/g,
669
+ (_, key) =>
670
+ params[key.trim() as keyof typeof params] + "",
671
+ ) : value;
672
+
673
+ // export default tInterpolateParams;
674
+ `;
675
+ });
676
+
677
+ var L = (({})=>`
678
+ /* eslint-disable prefer-const */
679
+ let pluralRules = new Intl.PluralRules();
680
+
681
+ /**
682
+ * @internal
683
+ */
684
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
685
+ export let tPluralise = (values: any, count: number) =>
686
+ values[count] || values[pluralRules.select(count)] || (count === 0 ? values.zero : values["other"]);
687
+
688
+ // export default tPluralise;
689
+ `);
690
+
691
+ var M = (({})=>`
692
+ import { defaultLocale } from "./defaultLocale";
693
+ import { isLocale } from "./isLocale";
694
+ import { toFormat } from "./toFormat";
695
+ import { routesSlim } from "./routesSlim";
696
+ import type { I18n } from "./types";
697
+
698
+ /**
699
+ * *To* route utility
700
+ *
701
+ * @returns A localised relative URL based on your i18nCompiler configuration
702
+ */
703
+ export function to<Id extends I18n.RouteId>(
704
+ id: Id,
705
+ ...args: Id extends I18n.RouteIdDynamic
706
+ ?
707
+ | [I18n.RouteParams[Id]]
708
+ | [I18n.RouteParams[Id], I18n.Locale]
709
+ : [] | [I18n.Locale]
710
+ ) {
711
+ const locale = (isLocale(args[0]) ? args[0] : args[1]) || defaultLocale;
712
+
713
+ return toFormat(
714
+ locale,
715
+ (routesSlim[id] as Record<string, string>)[locale] ??
716
+ (routesSlim[id] as Record<string, string>)[defaultLocale] ??
717
+ routesSlim[id],
718
+ isLocale(args[0]) ? undefined : args[0]
719
+ ) as I18n.RoutePathnames[Id];
720
+ }
721
+
722
+ export default to;
723
+ `);
724
+
725
+ let e = (t, o)=>{
726
+ let { defaultLocale: e } = t, r = "";
727
+ for(let t in o){
728
+ let l = o[t];
729
+ t !== e && l !== o[e] && (r += `locale === "${t}" ? "${l}" : `);
730
+ }
731
+ return r + ('"' + o[e]) + '"';
732
+ };
733
+ var P = (({ config: r, routes: l, options: n })=>{
734
+ let a = 1 === r.locales.length, s = `
735
+ /* eslint-disable prefer-const */
736
+ import { toFormat } from "./toFormat";
737
+ import type { I18n } from "./types";
738
+
739
+ `, $ = [], i = [];
740
+ for(let s in l.byId){
741
+ let p = "", { pathnames: m, params: f } = l.byId[s], u = `${n.routes.fnsPrefix}${utils.changeCaseSnake(s)}`, c = `I18n.RouteParams["${s}"]`, F = [
742
+ f ? `params: ${c}` : "",
743
+ a ? "" : "locale?: I18n.Locale"
744
+ ].filter(Boolean).join(", "), d = a ? '""' : "locale", x = f ? ", params" : "";
745
+ p += `export let ${u} = (${F}) => `, utils.isString(m) ? p += `toFormat(${d}, "${m}"${x});` : p += `toFormat(${d}, ${e(r, m)}${x});`, $.push(p), i.push(u);
746
+ }
747
+ return s + ($.join("\n") + // TODO: verify the impact of the following on bundle size, its relation to
748
+ // modularizeImports and maybe make this controllable through an adapter
749
+ // option
750
+ `\n\n` + `export const toFns = {\n ${i.join(",\n ")}\n};` + `\n\n`) + "export default toFns;";
751
+ });
752
+
753
+ var j = (({ config: a })=>`
754
+ import { defaultLocale } from "./defaultLocale";
755
+
756
+ /**
757
+ * @internal
758
+ */
759
+ export function toFormat(
760
+ locale: string | undefined,
761
+ pathname: string,
762
+ params?: object,
763
+ ) {
764
+ locale = locale || defaultLocale;
765
+ if (process.env["NODE_ENV"] === "development") {
766
+ if (params) {
767
+ pathname.replace(/\\[(.*?)\\]/g, (_, dynamicKey) => {
768
+ const key = dynamicKey as Extract<keyof typeof params, string>;
769
+
770
+ if (!(key in params)) {
771
+ console.warn(
772
+ "[@koine/i18n]::toFormat, using '" +
773
+ pathname +
774
+ "' without param '" +
775
+ key +
776
+ "'",
777
+ { params }
778
+ );
779
+ }
780
+
781
+ if (!["string", "number"].includes(typeof params[key])) {
782
+ console.warn(
783
+ "[@koine/i18n]::toFormat, using '" +
784
+ pathname +
785
+ "' with unserializable param '" +
786
+ key +
787
+ "' (type '" +
788
+ Object.prototype.toString.call((params[key])).slice(8, -1) +
789
+ "')",
790
+ );
791
+ }
792
+ return "";
793
+ });
794
+ }
795
+ }
796
+
797
+ if (params) {
798
+ pathname = pathname.replace(
799
+ /\\[(.*?)\\]/g,
800
+ (_, key) =>
801
+ params[key as keyof typeof params] + "",
802
+ )
803
+ }
804
+ ${a.hideDefaultLocaleInUrl ? `
805
+ if (locale !== defaultLocale) {
806
+ return "/" + locale + (pathname === "/" ? "" : pathname);
807
+ }
808
+ ` : ""}
809
+ return pathname;
810
+ }
811
+
812
+ // export default toFormat;
813
+ `);
814
+
815
+ var h$3 = (({ config: o, options: t })=>{
816
+ let { idDelimiter: e } = t.routes.tokens;
817
+ return `
818
+ import { defaultLocale } from "./defaultLocale";
819
+ import { isLocale } from "./isLocale";
820
+ import { routesSpa } from "./routesSpa";
821
+ import { toFormat } from "./toFormat";
822
+ import type { I18n } from "./types";
823
+
824
+ /**
825
+ * *To spa* route utility
826
+ *
827
+ * @returns A localised relative URL based on your i18nCompiler configuration
828
+ */
829
+ export function toSpa<
830
+ Root extends keyof I18n.RouteSpa,
831
+ Path extends Extract<keyof I18n.RouteSpa[Root], string>,
832
+ >(
833
+ rootId: Root,
834
+ pathId: Path,
835
+ ...args: I18n.RouteJoinedId<Root, Path> extends I18n.RouteIdDynamic
836
+ ?
837
+ | [I18n.RouteParams[I18n.RouteJoinedId<Root, Path>]]
838
+ | [I18n.RouteParams[I18n.RouteJoinedId<Root, Path>], I18n.Locale]
839
+ : [] | [I18n.Locale]
840
+ ) {
841
+ const locale = (isLocale(args[0]) ? args[0] : args[1]) || defaultLocale;
842
+ const fullId = \`\${rootId}${e}\${pathId}\` as I18n.RouteJoinedId<Root, Path>;
843
+ return toFormat(
844
+ // FIXME: actually the locale will be prepended if hideDefaultLocaleInUrl will be false
845
+ "", // do not pass the locale so that won't be prepended
846
+ (routesSpa[fullId] as Record<string, string>)[locale],
847
+ args.length === 2
848
+ ? args[0]
849
+ : args[0] && !isLocale(args[0])
850
+ ? args[0]
851
+ : void 0,
852
+ ) as I18n.RouteSpa[Root][Path];
853
+ }
854
+
855
+ export default toSpa;
856
+ `;
857
+ });
858
+
859
+ /**
860
+ * @see https://github.com/aralroca/next-translate?tab=readme-ov-file#5-plurals
861
+ */ let s$6 = [
862
+ "zero",
863
+ "one",
864
+ "two",
865
+ "few",
866
+ "many",
867
+ "other"
868
+ ], i$6 = "other";
869
+ /**
870
+ * Is the given string a valid plural suffix?
871
+ */ let isPluralSuffix = (e)=>s$6.includes(e) || utils.isNumericLiteral(e);
872
+ /**
873
+ * Remove plural suffix from string
874
+ */ let removePluralSuffix = (e)=>{
875
+ let [l] = utils.splitReverse(e, "_");
876
+ return l ? e.replace(`_${l}`, "") : e;
877
+ };
878
+ /**
879
+ * Get plural suffix from string
880
+ */ let getPluralSuffix = (e)=>utils.splitReverse(e, "_")[0];
881
+ /**
882
+ * Is the translation value object key a plural form?
883
+ *
884
+ * Using `splitReverse` ensures to get the last underscore prefixed suffix
885
+ * even in a string with multiple underscores.
886
+ */ let isPluralKey = (e)=>{
887
+ let [l] = utils.splitReverse(e, "_");
888
+ return isPluralSuffix(l);
889
+ };
890
+ let a$6 = (e)=>{
891
+ let l = {};
892
+ return e.forEach((e)=>{
893
+ let [r] = utils.split(e, "_");
894
+ l[r] = l[r] || [], l[r].push(e);
895
+ }), l;
896
+ };
897
+ /**
898
+ * Some translations keys won't be used directly and should be omitted
899
+ * from the generated types, e.g. the plural versions of the same string.
900
+ */ let transformKeysForPlurals = (l)=>{
901
+ // only transform if we have the required plural suffix in the keys
902
+ if (l.some(hasRequiredPluralSuffix) || l.includes(i$6)) {
903
+ let r = l.filter(isPluralKey);
904
+ if (r.length) {
905
+ let t = [
906
+ ...l
907
+ ];
908
+ return utils.forin(a$6(r), (e, r)=>{
909
+ // add the plural root
910
+ l.includes(e) || t.push(e), // remove the plurals variations
911
+ r.forEach((e)=>{
912
+ l.includes(e) && (t = t.filter((l)=>l !== e));
913
+ });
914
+ }), t;
915
+ }
916
+ }
917
+ return l;
918
+ };
919
+ /**
920
+ * Check if the given key has the required plural suffix
921
+ */ let hasRequiredPluralSuffix = (e)=>isPluralKey(e) && getPluralSuffix(e) === i$6;
922
+ /**
923
+ * Does the translation value object has plurals version?
924
+ *
925
+ * NB: here we check only for the **required** plural suffix,
926
+ */ let hasPlurals = (e)=>Object.keys(e).some(hasRequiredPluralSuffix) || Object.keys(e).includes(i$6);
927
+ /**
928
+ * Is the translation value object only enumerating plurals version?
929
+ */ let hasOnlyPluralKeys = (e)=>!!hasPlurals(e) && 0 === pickNonPluralKeys(e).length;
930
+ /**
931
+ * Pick the translation value object keys that _have no_ to do with pluralisation
932
+ */ let pickNonPluralKeys = (e)=>Object.keys(e).filter((e)=>!isPluralSuffix(e));
933
+ /**
934
+ * Narrows the translation value object picking only keys that _have no_ to do
935
+ * with pluralisation
936
+ */ let pickNonPluralValue = (e)=>hasPlurals(e) ? utils.objectPick(e, pickNonPluralKeys(e)) : e;
937
+
938
+ let c$2 = (e, a)=>!utils.isArray(a) && utils.isObject(a) && hasPlurals(a) ? hasOnlyPluralKeys(a) ? `"${e}": string;` : `"${e}": ${d$5(pickNonPluralValue(a))}` : `"${e}": ${d$5(a)}`, d$5 = (e)=>{
939
+ let o = "", r = "";
940
+ if (utils.isBoolean(e) ? r = "boolean" : utils.isString(e) && (r = "string"), r) o += r + ";";
941
+ else if (e) {
942
+ if (utils.isArray(e)) {
943
+ let t = e[0];
944
+ o += `${d$5(t)}[];`;
945
+ } else if (utils.isObject(e)) {
946
+ o += "{";
947
+ let t = transformKeysForPlurals(Object.keys(e));
948
+ for(let a = 0; a < t.length; a++){
949
+ let s = t[a], // fallback to a string otherwise plurals without root definition would
950
+ // not get a type otherwise, e.g. ` pluralNoDefault_...` in __mocks__
951
+ n = e[s] || "";
952
+ o += c$2(s, n);
953
+ }
954
+ o += "};";
955
+ }
956
+ } else o += "";
957
+ return(// adjust syntax
958
+ (o = o.replace(/;\[\];/g, "[];")).replace(/;+/g, ";"));
959
+ }, u$1 = (e, t)=>{
960
+ let { translationFiles: a } = t, { defaultLocale: s } = e, n = a.filter((e)=>e.locale === s), o = [];
961
+ for(let e = 0; e < n.length; e++){
962
+ let { path: t, data: a } = n[e], s = t.replace(".json", "");
963
+ o.push(`"${s}": ${d$5(a)}`);
964
+ }
965
+ return o.sort();
966
+ }, h$2 = (t)=>{
967
+ let a = [];
968
+ return utils.forin(t.byId, (e, { params: t })=>{
969
+ t && a.push(`"${e}": { ${dataParamsToTsInterfaceBody(t)} };`);
970
+ }), a;
971
+ }, y$1 = (e)=>e.sort().map((e)=>`"${e}"`).join(" | "), T$1 = (e, t)=>y$1(Object.keys(e.byId).filter((a)=>t(a, e.byId[a]))), m$5 = (e)=>Object.keys(e.byId).reduce((t, a)=>{
972
+ if (e.byId[a].inWildcard) for(let s = 0; s < e.wildcardIds.length; s++){
973
+ let n = e.wildcardIds[s];
974
+ a.startsWith(n) && (t[n] = t[n] || [], t[n].push(a));
975
+ }
976
+ return t;
977
+ }, {}), f$3 = (e, t, a)=>{
978
+ let s = m$5(t), n = [];
979
+ for(let o in s){
980
+ let r = s[o].map(// remove the root id portion and the first character which is always
981
+ // the route `idDelimiter`
982
+ (e)=>e.split(o)[1].slice(1)), i = t.byId[o].pathnames[e.defaultLocale], l = [];
983
+ for(let s = 0; s < r.length; s++){
984
+ let n = r[s], p = `${o}${a.routes.tokens.idDelimiter}${n}`, c = t.byId[p].pathnames[e.defaultLocale].split(i)[1];
985
+ l.push(`"${n}": "${c}";`);
986
+ }
987
+ n.push(`"${o}": { ${l.join(" ")} }`);
988
+ }
989
+ return n;
990
+ }, g$1 = (e, t)=>{
991
+ let a = [];
992
+ for(let s in t.byId){
993
+ let n = t.byId[s];
994
+ a.push(`"${n.id}": "${n.pathnames[e.defaultLocale]}";`);
995
+ }
996
+ return a;
997
+ };
998
+ // TODO: maybe move the Translate types into the various adapters unless we
999
+ // will use the same api for all of them
1000
+ var y$2 = (({ config: e, input: t, routes: a, options: s })=>{
1001
+ let n = T$1(a, (e, { params: t })=>!t), o = T$1(a, (e, { params: t })=>!!t), // const routeIdSpa = buildRoutesUnion(routes, (_, { inWildcard }) => inWildcard);
1002
+ { idDelimiter: r } = s.routes.tokens;
1003
+ return `
1004
+ /* eslint-disable @typescript-eslint/no-namespace */
1005
+ /* eslint-disable @typescript-eslint/no-explicit-any */
1006
+ /* eslint-disable @typescript-eslint/ban-types */
1007
+ import type { Split } from "@koine/utils";
1008
+ import type { I18nUtils } from "@koine/i18n";
1009
+ import type { RouteIdError } from "./routesError";
1010
+
1011
+ export namespace I18n {
1012
+ /**
1013
+ * Any of the available locale code
1014
+ */
1015
+ export type Locale = ${e.locales.map((e)=>`"${e}"`).join(" | ")};
1016
+
1017
+ /**
1018
+ * Utility to map values by all available locales
1019
+ *
1020
+ * @usecase I need to map zendesk URLs to my project's locales
1021
+ */
1022
+ export type LocalesMap<T = any> = Record<Locale, T>;
1023
+
1024
+ /**
1025
+ * Any of the available route id
1026
+ */
1027
+ export type RouteId = RouteIdStatic | RouteIdDynamic;
1028
+
1029
+ /**
1030
+ * The static routes available ids
1031
+ */
1032
+ export type RouteIdStatic = ${n};
1033
+
1034
+ /**
1035
+ * The dynamic routes available ids
1036
+ */
1037
+ export type RouteIdDynamic = ${o};
1038
+
1039
+ /**
1040
+ * Map every SPA path divided by their roots to their actual pathname value for the default locale
1041
+ */
1042
+ export type RouteSpa = {
1043
+ ${f$3(e, a, s).join("\n ")}
1044
+ }
1045
+
1046
+ /**
1047
+ * Map every route id to its actual pathanem value for the default locale
1048
+ */
1049
+ export type RoutePathnames = {
1050
+ ${g$1(e, a).join("\n ")}
1051
+ }
1052
+
1053
+ /**
1054
+ * Route dynamic params dictionary for each dynamic route id
1055
+ */
1056
+ export type RouteParams = {
1057
+ ${h$2(a).join("\n ")}
1058
+ }
1059
+
1060
+ /**
1061
+ * Utility to join two route ids
1062
+ */
1063
+ export type RouteJoinedId<Root extends string, Tail extends string> = \`\${Root}${r}\${Tail}\` extends RouteId ? \`\${Root}${r}\${Tail}\` : never;
1064
+
1065
+ /**
1066
+ * Extract all children routes that starts with the given string
1067
+ *
1068
+ * This is useful to get the subroutes of an application area, e.g. all subroutes
1069
+ * of a dashboard, using it with: \` type DashboardRoutes = RoutesChildrenOf<"dashboard">;\`
1070
+ */
1071
+ export type RoutesChildrenOf<
1072
+ TStarts extends string,
1073
+ T extends string = RouteId,
1074
+ > = T extends \`\${TStarts}.\${infer First}\` ? \`\${TStarts}.\${First}\` : never;
1075
+
1076
+ /**
1077
+ * @internal
1078
+ */
1079
+ export type TranslationsDictionaryLoose = {
1080
+ [key: string]: string | TranslationsDictionaryLoose;
1081
+ };
1082
+
1083
+ /**
1084
+ * The types extracted from the translations JSON files, this is a little
1085
+ * more sophisticated than the type result of \`typeof "./en/messages.json"\`
1086
+ */
1087
+ export type TranslationsDictionary = {
1088
+ ${u$1(e, t).join("\n ")}
1089
+ }
1090
+
1091
+ /**
1092
+ * Any of the available translations namespaces
1093
+ */
1094
+ export type TranslateNamespace = Extract<keyof TranslationsDictionary, string>;
1095
+
1096
+ /**
1097
+ * Translation **value** found at a specific _path_ in the given _namespace_
1098
+ *
1099
+ * \`TPath\` can be any of all possible paths:
1100
+ * - \`myKey\` sub dictionaries within a namespace
1101
+ * - \`myKey.nested\` whatever nested level of nesting within a namespace
1102
+ */
1103
+ export type TranslationAtPathFromNamespace<
1104
+ TNamespace extends TranslateNamespace,
1105
+ TPath extends TranslationsPaths<TranslationsDictionary[TNamespace]>,
1106
+ > = TNamespace extends TranslateNamespace
1107
+ ? TPath extends string // TranslationsPaths<TranslationsDictionary[TNamespace]>
1108
+ ? I18nUtils.Get<TranslationsDictionary[TNamespace], TPath>
1109
+ : TranslationsDictionary[TNamespace]
1110
+ : never;
1111
+
1112
+ /**
1113
+ * The generic type passed and to use with {@link TranslationAtPath} when you
1114
+ * want to build a type extending that
1115
+ */
1116
+ export type TranslationAtPathGeneric =
1117
+ | TranslateNamespace
1118
+ | TranslationsAllPaths;
1119
+
1120
+ /**
1121
+ * Translation **value** found at a _path_
1122
+ *
1123
+ * \`TPath\` can be any of all possible paths begininng with a namespace:
1124
+ * - \`namespace\` only a namespace
1125
+ * - \`namespace:myKey\` sub dictionaries within a namespace
1126
+ * - \`namespace:myKey.nested\` whatever nested level of nesting
1127
+ */
1128
+ export type TranslationAtPath<TPath extends TranslationAtPathGeneric> =
1129
+ TPath extends TranslateNamespace
1130
+ ? TranslationsDictionary[TPath]
1131
+ : TPath extends \`\${infer Namespace}:\${infer Path}\`
1132
+ ? Namespace extends TranslateNamespace
1133
+ ? I18nUtils.Get<TranslationsDictionary[Namespace], Path>
1134
+ : never
1135
+ : never;
1136
+
1137
+ /**
1138
+ * All translations paths from the given _path_
1139
+ *
1140
+ * \`TPath\` can be any of all possible paths begininng with a namespace:
1141
+ * - \`namespace\` only a namespace
1142
+ * - \`namespace:myKey\` sub dictionaries within a namespace
1143
+ * - \`namespace:myKey.nested\` whatever nested level of nesting
1144
+ */
1145
+ export type TranslationsPathsFrom<TPath extends TranslationAtPathGeneric> =
1146
+ TPath extends TranslateNamespace
1147
+ ? TranslationsPaths<TranslationsDictionary[TPath]>
1148
+ : TPath extends \`\${infer Namespace}:\${infer Path}\`
1149
+ ? Namespace extends TranslateNamespace
1150
+ ? I18nUtils.Get<TranslationsDictionary[Namespace], Path> extends object
1151
+ ? TranslationsPaths<I18nUtils.Get<TranslationsDictionary[Namespace], Path>>
1152
+ : TranslationsPaths<TranslationsDictionary[Namespace]>
1153
+ : never
1154
+ : never;
1155
+
1156
+ /**
1157
+ * All translations _paths_ of the given one, e.g. if \`TPath\` would be
1158
+ * \`"dashboard.users.[id].edit"\` the generated type would be the union
1159
+ * \`"dashboard.users.[id]" | "dashboard.users" | "dashboard"\`.
1160
+ */
1161
+ export type TranslationsPathsAncestors<
1162
+ TPath extends string,
1163
+ TSeparator extends string = ".",
1164
+ > = I18nUtils.BuildRecursiveJoin<Split<TPath, TSeparator>, TSeparator>;
1165
+
1166
+ /**
1167
+ * Recursive mapped type to extract all usable string paths from a translation
1168
+ * definition object (usually from a JSON file).
1169
+ */
1170
+ export type TranslationsPaths<T, TAsObj extends boolean = true> = I18nUtils.Paths<T, TAsObj>;
1171
+
1172
+ /**
1173
+ * Recursive mapped type of all usable string paths from the whole translations
1174
+ * dictionary.
1175
+ */
1176
+ export type TranslationsAllPaths = I18nUtils.AllPaths<TranslationsDictionary>;
1177
+
1178
+ /**
1179
+ * Unlike in \`next-translate\` we allow passing some predefined arguments as
1180
+ * shortcuts for common use cases:
1181
+ * - \`"obj"\` as a shortcut for \`{ returnObjects: true }\`
1182
+ * - \`""\` as a shortcut for \`{ fallback: "" }\`
1183
+ *
1184
+ */
1185
+ type TranslationShortcut = "obj" | "";
1186
+
1187
+ /**
1188
+ * Query object to populate the returned translated string interpolating data
1189
+ * or a TranslationShortcut.
1190
+ *
1191
+ * NOTE: when using a shortcut passing TranslationOptions to \`t()\` is not supported
1192
+ * TODO: type safe this behaviour of the third argument (options).
1193
+ */
1194
+ type TranslationQuery =
1195
+ | undefined
1196
+ | null
1197
+ | TranslationShortcut
1198
+ | {
1199
+ [key: string]: string | number | boolean;
1200
+ };
1201
+
1202
+ /**
1203
+ * Options of the translate function or a TranslationShortcut.
1204
+ *
1205
+ * NOTE: when using a shortcut passing TranslationOptions to \`t()\` is not supported
1206
+ * TODO: type safe this behaviour of the third argument (options).
1207
+ */
1208
+ type TranslationOptions =
1209
+ | undefined
1210
+ | TranslationShortcut
1211
+ | {
1212
+ returnObjects?: boolean;
1213
+ fallback?: string | string[];
1214
+ default?: string;
1215
+ };
1216
+
1217
+ /**
1218
+ * Translate function which optionally accept a namespace as first argument
1219
+ */
1220
+ export type Translate<
1221
+ TNamespace extends TranslateNamespace | undefined = TranslateNamespace,
1222
+ > = TNamespace extends TranslateNamespace
1223
+ ? TranslateNamespaced<TNamespace>
1224
+ : TranslateDefault;
1225
+
1226
+ /**
1227
+ * Translate function **without** namespace, it allows to select any of the all
1228
+ * available strings in _all_ namespaces.
1229
+ */
1230
+ export type TranslateDefault = <
1231
+ TPath extends TranslationsAllPaths,
1232
+ TReturn = TranslationAtPath<TPath>,
1233
+ >(
1234
+ path: TPath,
1235
+ query?: TranslationQuery,
1236
+ options?: TranslationOptions,
1237
+ ) => TReturn;
1238
+
1239
+ /**
1240
+ * Translate function **with** namespace, it allows to select all available
1241
+ * strings _only_ in the given namespace.
1242
+ */
1243
+ export type TranslateNamespaced<TNamespace extends TranslateNamespace> = <
1244
+ TPath extends TranslationsPaths<TranslationsDictionary[TNamespace]>,
1245
+ TReturn = TranslationAtPathFromNamespace<TNamespace, TPath>,
1246
+ >(
1247
+ path: TPath,
1248
+ query?: TranslationQuery,
1249
+ options?: TranslationOptions,
1250
+ ) => TReturn;
1251
+
1252
+ /**
1253
+ * Translate function _loose_ type, to use only in implementations that uses
1254
+ * the \`t\` function indirectly without needng knowledge of the string it needs
1255
+ * to output.
1256
+ */
1257
+ export type TranslateLoose<TReturn = string> = (
1258
+ path?: any,
1259
+ query?: TranslationQuery,
1260
+ options?: TranslationOptions,
1261
+ ) => TReturn;
1262
+
1263
+ /**
1264
+ * Translate function _loosest_ type it allows to return string or object or array
1265
+ * or whatever basically.
1266
+ */
1267
+ export type TranslateLoosest<TReturn = any> = (
1268
+ path?: any,
1269
+ query?: TranslationQuery,
1270
+ options?: TranslationOptions,
1271
+ ) => TReturn;
1272
+
1273
+ /**
1274
+ * @internal
1275
+ */
1276
+ export type Dictionaries = Record<string, TranslationsDictionaryLoose>;
1277
+
1278
+ /**
1279
+ * @internal
1280
+ */
1281
+ export type RouteArgs<TRouteId extends RouteId | RouteIdError> =
1282
+ | {
1283
+ id: TRouteId extends RouteIdDynamic ? TRouteId : never;
1284
+ params: TRouteId extends RouteIdDynamic ? RouteParams[TRouteId] : never;
1285
+ }
1286
+ | {
1287
+ id: TRouteId extends RouteIdStatic | RouteIdError ? TRouteId : never;
1288
+ params?: undefined;
1289
+ };
1290
+
1291
+ /**
1292
+ * Params globally available from the URL/folder structure named accordingly
1293
+ * to the \`localeParam\` option, e.g. \`lang\` for a typical folder structure
1294
+ * such as \`/[lang]/my-route/page.tsx\`.
1295
+ */
1296
+ export type Params = {
1297
+ ${s.routes.localeParamName}: Locale;
1298
+ };
1299
+
1300
+ /**
1301
+ * Props available to each page/layout when a root \`localeParam\` is in place (e.g.
1302
+ * in the typical _next.js_ folder structure \`/[lang]/my-route/page.tsx\`).
1303
+ */
1304
+ export type Props<TProps = {}> = TProps & {
1305
+ params: Params;
1306
+ };
1307
+
1308
+ /**
1309
+ * Dictionary to generate SEO friendly alternate URLs \`<links>\` where:
1310
+ *
1311
+ * - _key_: \`x-default\` or any valid locale code (see [Google docs](https://developers.google.com/search/docs/specialty/international/localized-versions#language-codes))
1312
+ * - _value_: fully qualified and localised absolute URL
1313
+ *
1314
+ * It can also be an empty object, for instance with error routes.
1315
+ *
1316
+ * NOTE: this type should satisfy the nextjs type too that is:
1317
+ * TODO: maybe build a test for this
1318
+ * \`\`\`ts
1319
+ * import type { Metadata as NextMetadata } from "next";
1320
+ *
1321
+ * type Alternates = NonNullable<NextMetadata["alternates"]>["languages"];
1322
+ * \`\`\`
1323
+ */
1324
+ export type Alternates = Record<string, string>;
1325
+
1326
+ /**
1327
+ * I18n/routing related SEO metadata:
1328
+ *
1329
+ * NOTE: this type should satisfy the nextjs type too that is:
1330
+ * TODO: maybe build a test for this
1331
+ * \`\`\`ts
1332
+ * import type { Metadata as NextMetadata } from "next";
1333
+ *
1334
+ * type Metadata = NonNullable<NextMetadata["alternates"]>;
1335
+ * \`\`\`
1336
+ */
1337
+ export type Metadata = {
1338
+ alternates: Alternates;
1339
+ canonical: null | string;
1340
+ }
1341
+ }
1342
+ `;
1343
+ });
1344
+
1345
+ var t$1 = createAdapter(adapterJsOptions, ({})=>({
1346
+ files: [
1347
+ {
1348
+ name: "config.cjs",
1349
+ fn: m$6,
1350
+ ext: "js"
1351
+ },
1352
+ {
1353
+ name: "config",
1354
+ fn: o$8,
1355
+ ext: "ts",
1356
+ index: !0
1357
+ },
1358
+ {
1359
+ name: "createT",
1360
+ fn: r$5,
1361
+ ext: "ts",
1362
+ index: !0
1363
+ },
1364
+ {
1365
+ name: "defaultI18nMetadata",
1366
+ fn: n$6,
1367
+ ext: "ts"
1368
+ },
1369
+ {
1370
+ name: "defaultLocale",
1371
+ fn: a$7,
1372
+ ext: "ts",
1373
+ index: !0
1374
+ },
1375
+ {
1376
+ name: "formatUrl",
1377
+ fn: f$4,
1378
+ ext: "ts",
1379
+ index: !0
1380
+ },
1381
+ {
1382
+ name: "getI18nMetadata",
1383
+ fn: s$8,
1384
+ ext: "ts",
1385
+ index: !0
1386
+ },
1387
+ // TODO: probably remove it or move it to `i18n/client` public utils
1388
+ // {
1389
+ // name: "getI18nAlternatesFromDom",
1390
+ // fn: getI18nAlternatesFromDom,
1391
+ // ext: "ts",
1392
+ // index: true,
1393
+ // },
1394
+ {
1395
+ name: "getI18nDictionaries",
1396
+ fn: i$8,
1397
+ ext: "ts",
1398
+ index: !0
1399
+ },
1400
+ {
1401
+ name: "getT",
1402
+ fn: p$5,
1403
+ ext: "ts",
1404
+ index: !0
1405
+ },
1406
+ {
1407
+ name: "isLocale",
1408
+ fn: x$4,
1409
+ ext: "ts",
1410
+ index: !0
1411
+ },
1412
+ {
1413
+ name: "loadTranslations",
1414
+ fn: d$6,
1415
+ ext: "ts"
1416
+ },
1417
+ {
1418
+ name: "locales",
1419
+ fn: l$4,
1420
+ ext: "ts",
1421
+ index: !0
1422
+ },
1423
+ {
1424
+ name: "pathnameToRouteId",
1425
+ fn: c$3,
1426
+ ext: "ts",
1427
+ index: !0
1428
+ },
1429
+ {
1430
+ name: "routes",
1431
+ fn: u$2,
1432
+ ext: "ts"
1433
+ },
1434
+ {
1435
+ name: "routesError",
1436
+ fn: g$2,
1437
+ ext: "ts"
1438
+ },
1439
+ {
1440
+ name: "routesSlim",
1441
+ fn: I$3,
1442
+ ext: "ts"
1443
+ },
1444
+ {
1445
+ name: "routesSpa",
1446
+ fn: T$2,
1447
+ ext: "ts"
1448
+ },
1449
+ {
1450
+ name: "t",
1451
+ fn: S,
1452
+ ext: "ts",
1453
+ index: !0
1454
+ },
1455
+ {
1456
+ name: "tInterpolateParams",
1457
+ fn: F,
1458
+ ext: "ts"
1459
+ },
1460
+ {
1461
+ name: "to",
1462
+ fn: M,
1463
+ ext: "ts",
1464
+ index: !0
1465
+ },
1466
+ {
1467
+ name: "toFns",
1468
+ fn: P,
1469
+ ext: "ts",
1470
+ index: !0
1471
+ },
1472
+ {
1473
+ name: "toFormat",
1474
+ fn: j,
1475
+ ext: "ts"
1476
+ },
1477
+ {
1478
+ name: "toSpa",
1479
+ fn: h$3,
1480
+ ext: "ts",
1481
+ index: !0
1482
+ },
1483
+ {
1484
+ name: "tPluralise",
1485
+ fn: L,
1486
+ ext: "ts"
1487
+ },
1488
+ {
1489
+ name: "types",
1490
+ fn: y$2,
1491
+ ext: "ts",
1492
+ index: !0
1493
+ }
1494
+ ]
1495
+ }));
1496
+
1497
+ const adapterNextTranslateOptions = {};
1498
+
1499
+ var t = (({})=>`
1500
+ "use client";
1501
+
1502
+ import _DynamicNamespaces from "next-translate/DynamicNamespaces";
1503
+
1504
+ export const DynamicNamespaces = _DynamicNamespaces;
1505
+
1506
+ export default DynamicNamespaces;
1507
+ `);
1508
+
1509
+ var r$4 = (({})=>`
1510
+ "use client";
1511
+
1512
+ import _I18nProvider from "next-translate/I18nProvider";
1513
+
1514
+ export const I18nProvider = _I18nProvider;
1515
+
1516
+ export default I18nProvider;
1517
+ `);
1518
+
1519
+ var m$4 = (({})=>`
1520
+ "use client";
1521
+
1522
+ import type { TransProps } from "next-translate";
1523
+ import Trans from "next-translate/Trans";
1524
+ import type { I18n } from "./types";
1525
+
1526
+ export type TProps<
1527
+ TNamespace extends I18n.TranslateNamespace | undefined = undefined,
1528
+ > =
1529
+ | (Omit<TransProps, "i18nKey" | "ns"> & {
1530
+ i18nKey: I18n.TranslationsAllPaths;
1531
+ })
1532
+ | (Omit<TransProps, "i18nKey" | "ns"> & {
1533
+ ns: TNamespace;
1534
+ i18nKey: I18n.TranslationsPaths<TNamespace>;
1535
+ });
1536
+
1537
+ const TypedT = <
1538
+ TNamespace extends I18n.TranslateNamespace | undefined = undefined,
1539
+ >(
1540
+ props: TProps<TNamespace>,
1541
+ ) =>
1542
+ (<Trans {...(props as TransProps)} />) as React.ReactElement<
1543
+ TProps<TNamespace>
1544
+ >;
1545
+
1546
+ export const T = Trans as typeof TypedT;
1547
+
1548
+ export default T;
1549
+ `);
1550
+
1551
+ var o$7 = (({})=>`
1552
+ "use client";
1553
+
1554
+ import _TransText from "next-translate/TransText";
1555
+
1556
+ export const TransText = _TransText;
1557
+
1558
+ export default TransText;
1559
+ `);
1560
+
1561
+ var s$5 = (({})=>`
1562
+ import _getT from "next-translate/getT";
1563
+ import type { I18n } from "./types";
1564
+
1565
+ export type GetT = <
1566
+ TNamespace extends I18n.TranslateNamespace | undefined = undefined,
1567
+ >(
1568
+ locale?: I18n.Locale,
1569
+ namespace?: TNamespace,
1570
+ ) => Promise<I18n.Translate<TNamespace>>;
1571
+
1572
+ export const getT = _getT as GetT;
1573
+
1574
+ export default getT;
1575
+ `);
1576
+
1577
+ var a$5 = (({ config: a, adapterOptions: e })=>{
1578
+ let { loader: t } = e;
1579
+ return `
1580
+ /**
1581
+ * Get 'next-translate' configuration
1582
+ *
1583
+ * @see https://github.com/vinissimus/next-translate#how-are-translations-loaded
1584
+ *
1585
+ * @param {Omit<Partial<import("next-translate").I18nConfig>, "pages"> & { pages: Record<string, import("./types").I18n.TranslateNamespace[]> }} config
1586
+ */
1587
+ module.exports = (config = { pages: {} }) => {
1588
+ return {
1589
+ locales: [${a.locales.map((a)=>`"${a}"`).join(", ")}],
1590
+ defaultLocale: "${a.defaultLocale}",
1591
+ logBuild: false,${t ? "\n loadLocaleFrom: (locale, namespace) => import(`./translations/${locale}/${namespace}.json`).then((m) => m.default)," : ""}
1592
+ ...${JSON.stringify(e)},
1593
+ ...config,
1594
+ };
1595
+ }
1596
+ `;
1597
+ });
1598
+
1599
+ var i$5 = (({ config: e })=>`
1600
+ import useTranslation from "next-translate/useTranslation";
1601
+ import { defaultLocale } from "./defaultLocale";
1602
+ import type { I18n } from "./types";
1603
+
1604
+ export const useLocale = () => (useTranslation().lang as I18n.Locale) || defaultLocale;
1605
+
1606
+ export default useLocale;
1607
+ `);
1608
+
1609
+ var x$3 = (({})=>`
1610
+ "use client";
1611
+
1612
+ import { useMemo } from "react";
1613
+ import useTranslation from "next-translate/useTranslation";
1614
+ import type { I18n } from "./types";
1615
+
1616
+ /**
1617
+ * Wrap next-translate useTranslations for type safety and adds TranslationShortcut
1618
+ * as second/thir argument.
1619
+ *
1620
+ * @see https://github.com/vinissimus/next-translate/issues/513#issuecomment-779826418
1621
+ *
1622
+ * About the typescript support for translation strings see:
1623
+ * - https://github.com/vinissimus/next-translate/issues/721
1624
+ */
1625
+ export const useT = <TNamespace extends I18n.TranslateNamespace>(namespace: TNamespace) => {
1626
+ const t = useTranslation().t;
1627
+ const tMemoized = useMemo(
1628
+ () =>
1629
+ function <
1630
+ TPath extends I18n.TranslationsPaths<I18n.TranslationsDictionary[TNamespace]>,
1631
+ TReturn = I18n.TranslationAtPathFromNamespace<TNamespace, TPath>,
1632
+ >(s: TPath, q?: I18n.TranslationQuery, o?: I18n.TranslationOptions): TReturn {
1633
+ return t(
1634
+ (namespace ? namespace + ":" + s : s) as string,
1635
+ q === "obj" || q === "" ? null : q,
1636
+ q === "obj" || o === "obj"
1637
+ ? { returnObjects: true }
1638
+ : q === "" || o === ""
1639
+ ? { fallback: "" }
1640
+ : o,
1641
+ ) as TReturn;
1642
+ // ) as TReturn extends (undefined | never | unknown) ? TranslateReturn<I18n.TranslationQuery, I18n.TranslationOptions> : TReturn;
1643
+ // );
1644
+ },
1645
+ [t, namespace],
1646
+ );
1647
+ return tMemoized;
1648
+ };
1649
+
1650
+ export default useT;
1651
+ `);
1652
+
1653
+ var a$4 = createAdapter(adapterNextTranslateOptions, ({ adapterOptions: e })=>{
1654
+ let n = [
1655
+ {
1656
+ name: "getT",
1657
+ fn: s$5,
1658
+ ext: "ts",
1659
+ index: !0
1660
+ },
1661
+ {
1662
+ name: "nextTranslateI18n",
1663
+ fn: a$5,
1664
+ ext: "js"
1665
+ },
1666
+ {
1667
+ name: "T",
1668
+ fn: m$4,
1669
+ ext: "tsx",
1670
+ index: !0
1671
+ },
1672
+ {
1673
+ name: "TransText",
1674
+ fn: o$7,
1675
+ ext: "tsx",
1676
+ index: !0
1677
+ },
1678
+ {
1679
+ name: "useT",
1680
+ fn: x$3,
1681
+ ext: "ts",
1682
+ index: !0
1683
+ }
1684
+ ];
1685
+ return !1 === e.loader ? (n.push({
1686
+ name: "useLocale",
1687
+ fn: i$5,
1688
+ ext: "ts",
1689
+ index: !0
1690
+ }), n.push({
1691
+ name: "I18nProvider",
1692
+ fn: r$4,
1693
+ ext: "tsx",
1694
+ index: !0
1695
+ })) : // TODO: check, probably DynamicNamespaces does not work without the automatic loader?
1696
+ n.push({
1697
+ name: "DynamicNamespaces",
1698
+ fn: t,
1699
+ ext: "tsx",
1700
+ index: !0
1701
+ }), {
1702
+ dependsOn: [
1703
+ "next"
1704
+ ],
1705
+ needsTranslationsFiles: !0,
1706
+ files: n
1707
+ };
1708
+ });
1709
+
1710
+ const adapterNextOptions = {
1711
+ router: "app"
1712
+ }; /**
1713
+ * @default "app"
1714
+ */
1715
+
1716
+ var n$5 = (({})=>`
1717
+ "use client";
1718
+
1719
+ import type { AppProps } from "next/app";
1720
+ import { defaultI18nMetadata } from "./defaultI18nMetadata";
1721
+ import { defaultLocale } from "./defaultLocale";
1722
+ import { I18nProvider } from "./I18nProvider";
1723
+ import { I18nMetadataProvider } from "./I18nMetadataProvider";
1724
+ import { I18nEffects } from "./I18nEffects";
1725
+ import { I18nHead } from "./I18nHead";
1726
+ import type { I18n } from "./types";
1727
+
1728
+ /**
1729
+ * @internal
1730
+ */
1731
+ export type I18nAppPropsData = {
1732
+ i18n: {
1733
+ locale: I18n.Locale;
1734
+ dictionaries: I18n.Dictionaries;
1735
+ metadata: I18n.Metadata;
1736
+ }
1737
+ };
1738
+
1739
+ const i18nDefaults: I18nAppPropsData["i18n"] = {
1740
+ locale: defaultLocale,
1741
+ dictionaries: {},
1742
+ metadata: defaultI18nMetadata
1743
+ };
1744
+
1745
+ type I18nAppProps = React.PropsWithChildren<
1746
+ AppProps<I18nAppPropsData>["pageProps"]
1747
+ >;
1748
+
1749
+ /**
1750
+ * To use in \`_app.tsx\` file wrapping your component
1751
+ *
1752
+ * **For Pages Router only**
1753
+ *
1754
+ * NB: Consider that when using ISR with \`fallback: true\` the first load
1755
+ * will not have any useful i18n data (App's \`pageProps\` is an empty object),
1756
+ * hence we provide a \`i18nDefaults\` object.
1757
+ *
1758
+ * @usage
1759
+ * \`\`\`ts
1760
+ * export default function App(props: AppProps) {
1761
+ * const { Component, pageProps } = props;
1762
+ *
1763
+ * return (
1764
+ * <I18nApp {...pageProps}>
1765
+ * <Component {...pageProps} />
1766
+ * </I18nApp>
1767
+ * );
1768
+ * }
1769
+ * \`\`\`
1770
+ */
1771
+ export const I18nApp = (props: I18nAppProps) => {
1772
+ const { i18n, children } = props;
1773
+ const { locale, dictionaries, metadata } = i18n || i18nDefaults;
1774
+
1775
+ return (
1776
+ <I18nProvider
1777
+ locale={locale}
1778
+ dictionaries={dictionaries}
1779
+ >
1780
+ <I18nHead metadata={metadata} />
1781
+ <I18nMetadataProvider metadata={metadata}>
1782
+ {children}
1783
+ </I18nMetadataProvider>
1784
+ <I18nEffects />
1785
+ </I18nProvider>
1786
+ );
1787
+ };
1788
+
1789
+ export default I18nApp;
1790
+ `);
1791
+
1792
+ /**
1793
+ * We cannot re-use `I18nHeadTags` as NextHead component does needs HTML tags
1794
+ * to be its immediate children.
1795
+ *
1796
+ * @see https://nextjs.org/docs/pages/api-reference/components/head#use-minimal-nesting
1797
+ */ var r$3 = (({})=>`
1798
+ "use client";
1799
+
1800
+ import Head from "next/head";
1801
+ import { defaultI18nMetadata } from "./defaultI18nMetadata";
1802
+ import type { I18nHeadTagsProps } from "./I18nHeadTags";
1803
+
1804
+ export type I18nHeadProps = I18nHeadTagsProps;
1805
+
1806
+ /**
1807
+ * **For Pages Router only**
1808
+ *
1809
+ * @internal
1810
+ */
1811
+ export const I18nHead = (props: I18nHeadProps) => {
1812
+ const { metadata = defaultI18nMetadata } = props;
1813
+ const { alternates, canonical } = metadata;
1814
+
1815
+ return (
1816
+ <Head key="I18nHead">
1817
+ {canonical && (
1818
+ <link
1819
+ rel="canonical"
1820
+ href={canonical}
1821
+ key="canonical"
1822
+ />
1823
+ )}
1824
+ {Object.keys(alternates).map((locale) => (
1825
+ <link
1826
+ rel="alternate"
1827
+ hrefLang={locale}
1828
+ href={alternates[locale]}
1829
+ key={"alternate-" + locale}
1830
+ />
1831
+ ))}
1832
+ </Head>
1833
+ );
1834
+ };
1835
+
1836
+ // export default I18nHead;
1837
+ `);
1838
+
1839
+ var o$6 = (({})=>`
1840
+ import { I18nProvider } from "./I18nProvider";
1841
+ import { defaultLocale } from "./defaultLocale";
1842
+ import { getI18nDictionaries } from "./getI18nDictionaries";
1843
+ import type { I18n } from "./types";
1844
+
1845
+ export type I18nLayoutProps = React.PropsWithChildren<{
1846
+ locale?: I18n.Locale;
1847
+ namespaces?: I18n.TranslateNamespace[];
1848
+ }>;
1849
+
1850
+ /**
1851
+ * Optionally use this _in each_ \`layout.tsx\` where you have some translations
1852
+ * specific to that layout and its descendant layouts and pages
1853
+ *
1854
+ * **For App Router only**
1855
+ */
1856
+ export const I18nLayout = async ({
1857
+ locale = defaultLocale,
1858
+ namespaces = [],
1859
+ children,
1860
+ }: I18nLayoutProps) => {
1861
+ const dictionaries = await getI18nDictionaries({ locale, namespaces });
1862
+
1863
+ return (
1864
+ <I18nProvider
1865
+ locale={locale}
1866
+ dictionaries={dictionaries}
1867
+ >
1868
+ {children}
1869
+ </I18nProvider>
1870
+ );
1871
+ };
1872
+
1873
+ export default I18nLayout;
1874
+ `);
1875
+
1876
+ var m$3 = (({ config: { single: e }, options: { routes: { localeParamName: t } } })=>`
1877
+ /* eslint-disable @typescript-eslint/no-explicit-any */
1878
+ import { notFound } from "next/navigation";
1879
+ import { I18nMetadataSetter } from "./I18nMetadataSetter";
1880
+ import { I18nProvider } from "./I18nProvider";
1881
+ import { I18nRouteSetter } from "./I18nRouteSetter";
1882
+ import { defaultLocale } from "./defaultLocale";
1883
+ import { getI18nDictionaries } from "./getI18nDictionaries";
1884
+ import { getI18nMetadata } from "./getI18nMetadata";
1885
+ import { isLocale } from "./isLocale";
1886
+ import type { I18n } from "./types";
1887
+
1888
+ export type I18nPageProps<TRouteId extends I18n.RouteId> =
1889
+ React.PropsWithChildren<
1890
+ {
1891
+ locale${e ? "?" : ""}: I18n.Locale;
1892
+ namespaces?: I18n.TranslateNamespace[];
1893
+ } & I18n.RouteArgs<TRouteId>
1894
+ >;
1895
+
1896
+ /**
1897
+ * Use this _in each_ \`page.tsx\` render function
1898
+ *
1899
+ * **For App Router only**
1900
+ */
1901
+ export const I18nPage = async <TRouteId extends I18n.RouteId>(
1902
+ props: I18nPageProps<TRouteId>,
1903
+ ) => {
1904
+ const {
1905
+ locale = defaultLocale,
1906
+ namespaces = [],
1907
+ id,
1908
+ params,
1909
+ children,
1910
+ } = props;
1911
+ // @ts-expect-error FIXME: route conditional type
1912
+ const metadata = getI18nMetadata({ locale, id, params });
1913
+ const dictionaries = await getI18nDictionaries({ locale, namespaces });
1914
+
1915
+ return (
1916
+ <>
1917
+ <I18nRouteSetter id={id} />
1918
+ <I18nMetadataSetter metadata={metadata} />
1919
+ <I18nProvider
1920
+ locale={locale}
1921
+ dictionaries={dictionaries}
1922
+ >
1923
+ {children}
1924
+ </I18nProvider>
1925
+ </>
1926
+ );
1927
+ };
1928
+
1929
+ function locale(props: any): I18n.Locale;
1930
+ function locale(params: I18n.Props["params"]): I18n.Locale;
1931
+ function locale(props: I18n.Props): I18n.Locale;
1932
+ function locale(paramsOrProps: I18n.Props["params"] | I18n.Props) {
1933
+ const params = (paramsOrProps as any)?.params || paramsOrProps;
1934
+ if (params) {
1935
+ const locale = (params as any).${t};
1936
+
1937
+ if (isLocale(locale)) {
1938
+ return locale;
1939
+ }
1940
+ }
1941
+
1942
+ notFound();
1943
+ }
1944
+
1945
+ /**
1946
+ * Use this _in each_ \`page.tsx\` to get the current _locale_ from the page props
1947
+ *
1948
+ * It automatically 404s with next.js's \`notFound\` if the locale does not exists.
1949
+ *
1950
+ * **For App Router only**
1951
+ */
1952
+ I18nPage.locale = locale;
1953
+
1954
+ /**
1955
+ * Use this _in each_ \`page.tsx\` -> \`generateMetadata\` function
1956
+ *
1957
+ * **For App Router only**
1958
+ */
1959
+ I18nPage.metadata = <TRouteId extends I18n.RouteId>(
1960
+ options: Omit<I18nPageProps<TRouteId>, "namespaces">,
1961
+ ) => {
1962
+ // @ts-expect-error FIXME: route conditional type
1963
+ const { alternates, canonical } = getI18nMetadata(options);
1964
+
1965
+ return {
1966
+ alternates: {
1967
+ canonical,
1968
+ languages: alternates,
1969
+ },
1970
+ };
1971
+ };
1972
+
1973
+ export default I18nPage;
1974
+ `);
1975
+
1976
+ var i$4 = (({})=>`
1977
+ import { defaultI18nMetadata } from "./defaultI18nMetadata";
1978
+ import { I18nMetadataProvider } from "./I18nMetadataProvider";
1979
+ import { I18nRouteProvider } from "./I18nRouteProvider";
1980
+ import type { I18n } from "./types";
1981
+
1982
+ type I18nRootProps = React.PropsWithChildren;
1983
+
1984
+ /**
1985
+ * Use this _only once_ in the root \`layout.tsx\` at root folder of your app
1986
+ * directory (one up than the \`[lang]\` folder).
1987
+ *
1988
+ * **For App Router only**
1989
+ */
1990
+ export const I18nRoot = ({ children }: I18nRootProps) => {
1991
+ return (
1992
+ <I18nRouteProvider id={"" as I18n.RouteId}>
1993
+ <I18nMetadataProvider metadata={defaultI18nMetadata}>
1994
+ {children}
1995
+ </I18nMetadataProvider>
1996
+ </I18nRouteProvider>
1997
+ );
1998
+ };
1999
+
2000
+ export default I18nRoot;
2001
+ `);
2002
+
2003
+ var x$2 = (({ config: { single: t } })=>`
2004
+ "use client";
2005
+
2006
+ import { useContext, useEffect } from "react";
2007
+ import { I18nMetadataContext } from "./I18nMetadataContext";
2008
+ import { I18nHead } from "./I18nHead";
2009
+ import { formatUrl } from "./formatUrl";
2010
+ import { getI18nMetadata } from "./getI18nMetadata";
2011
+ import { to } from "./to";
2012
+ import type { I18n } from "./types";
2013
+ import { useLocale } from "./useLocale";
2014
+
2015
+ export type I18nSetterProps<TRouteId extends I18n.RouteId> =
2016
+ I18n.RouteArgs<TRouteId>;
2017
+
2018
+ /**
2019
+ * **For Pages Router only**
2020
+ *
2021
+ * Use this in in order to update the alternates and canonical URLs.
2022
+ * This is _required_ in all pages in order to update the data during navigation.
2023
+ *
2024
+ * This need is particularly evident with dynamic routes pages that use
2025
+ * \`fallback: true\` as the initial SSR does not have any useful i18n information
2026
+ * available. In those page be sure to render this component when the dynamic
2027
+ * data is ready, in other words when the pages router is not in fallback state
2028
+ * anymore: \`useRouter().isFallback === false\`.
2029
+ */
2030
+ export const I18nSetter = <TRouteId extends I18n.RouteId>(
2031
+ props: I18nSetterProps<TRouteId>,
2032
+ ) => {
2033
+ const { id, params } = props;
2034
+ const locale = useLocale();
2035
+ const [metadata, setMetadata] = useContext(I18nMetadataContext);
2036
+
2037
+ useEffect(() => {
2038
+ // @ts-expect-error FIXME: route conditional type
2039
+ setMetadata(getI18nMetadata({ locale, id, params }));
2040
+ }, [id, params, locale, setMetadata]);
2041
+
2042
+ return (
2043
+ <I18nHead metadata={metadata} />
2044
+ );
2045
+ };
2046
+
2047
+ export default I18nSetter;
2048
+ `);
2049
+
2050
+ var a$3 = (({ options: { routes: { localeParamName: t } } })=>`
2051
+ /* eslint-disable @typescript-eslint/no-explicit-any */
2052
+ import type { GetStaticPathsContext, GetStaticPropsContext } from "next";
2053
+ import type { I18nAppPropsData } from "./I18nApp";
2054
+ import { defaultI18nMetadata} from "./defaultI18nMetadata";
2055
+ import { getI18nMetadata } from "./getI18nMetadata";
2056
+ import { getI18nDictionaries } from "./getI18nDictionaries";
2057
+ import { isLocale } from "./isLocale";
2058
+ import { locales } from "./locales";
2059
+ import { type RouteIdError, isErrorRoute } from "./routesError";
2060
+ import type { I18n } from "./types";
2061
+
2062
+ /**
2063
+ * Get current _locale_ from \`getStaticProps\` context data (its first argument)
2064
+ */
2065
+ function locale(params: GetStaticPropsContext["params"]): I18n.Locale | undefined;
2066
+ function locale(ctx: GetStaticPropsContext): I18n.Locale | undefined;
2067
+ function locale(
2068
+ ctxOrParams: GetStaticPropsContext["params"] | GetStaticPropsContext,
2069
+ ) {
2070
+ const params = ctxOrParams?.params || ctxOrParams;
2071
+ if (params) {
2072
+ const locale = (params as any).${t};
2073
+
2074
+ if (isLocale(locale)) {
2075
+ return locale;
2076
+ }
2077
+ }
2078
+
2079
+ return; // defaultLocale;
2080
+ }
2081
+
2082
+ /**
2083
+ * Get localised paths to feed into \`getStaticPaths\`
2084
+ */
2085
+ const paths = <P extends { [key: string]: any }>(params?: P) =>
2086
+ locales.map((l) => ({
2087
+ params: { ${t}: l, ...(params || {}) },
2088
+ // locale: l,
2089
+ })) as Array<string | { params: P & { ${t}: I18n.Locale }; locale?: string }>;
2090
+
2091
+ /**
2092
+ * Function to use as \`getStaticPaths\` with \`fallback: false\`
2093
+ */
2094
+ const staticPaths = (_context?: GetStaticPathsContext) => ({
2095
+ paths: paths(),
2096
+ fallback: false,
2097
+ });
2098
+
2099
+ type I18nPropsOptions<
2100
+ TRouteId extends I18n.RouteId | RouteIdError,
2101
+ TParams,
2102
+ TData,
2103
+ > = {
2104
+ namespaces: I18n.TranslateNamespace[];
2105
+ // routeId: TRouteId;
2106
+ // routeParams?: TRouteId extends I18n.RouteIdDynamic
2107
+ // ? I18n.RouteParams[TRouteId]
2108
+ // : never;
2109
+ params?: TParams;
2110
+ data?: TData;
2111
+ } & (
2112
+ // as in I18n.RouteArgs
2113
+ | {
2114
+ routeId: TRouteId extends I18n.RouteIdDynamic ? TRouteId : never;
2115
+ routeParams: TRouteId extends I18n.RouteIdDynamic
2116
+ ? I18n.RouteParams[TRouteId]
2117
+ : never;
2118
+ }
2119
+ | {
2120
+ routeId: TRouteId extends I18n.RouteIdStatic | RouteIdError
2121
+ ? TRouteId
2122
+ : never;
2123
+ routeParams?: undefined;
2124
+ }
2125
+ );
2126
+
2127
+ /**
2128
+ * Get page props data feed into \`getStaticProps\`'s return
2129
+ */
2130
+ const props = async <
2131
+ TRouteId extends I18n.RouteId | RouteIdError,
2132
+ TParams,
2133
+ TData,
2134
+ >({
2135
+ locale,
2136
+ namespaces,
2137
+ routeId,
2138
+ routeParams,
2139
+ params,
2140
+ data,
2141
+ }: {
2142
+ locale: I18n.Locale;
2143
+ } & I18nPropsOptions<TRouteId, TParams, TData>) => {
2144
+ const props: I18nAppPropsData = {
2145
+ i18n: {
2146
+ locale: locale,
2147
+ metadata: isErrorRoute(routeId)
2148
+ ? defaultI18nMetadata
2149
+ : // @ts-expect-error FIXME: route conditional type
2150
+ getI18nMetadata({ locale, id: routeId, params: routeParams }),
2151
+ dictionaries: await getI18nDictionaries({ locale, namespaces }),
2152
+ },
2153
+ };
2154
+
2155
+ return {
2156
+ ...props,
2157
+ params: { ${t}: locale, ...(params || ({} as TParams)) },
2158
+ data: data || ({} as TData),
2159
+ };
2160
+ };
2161
+
2162
+ /**
2163
+ * Get page props data to use as immediate return of \`getStaticProps\`
2164
+ */
2165
+ const staticProps = async <
2166
+ TRouteId extends I18n.RouteId | RouteIdError,
2167
+ TParams,
2168
+ TData,
2169
+ >({
2170
+ ctx,
2171
+ revalidate,
2172
+ ...options
2173
+ }: {
2174
+ ctx: GetStaticPropsContext;
2175
+ revalidate?: number;
2176
+ } & I18nPropsOptions<TRouteId, TParams, TData>) => {
2177
+ const locale = ctx.params?.${t} as I18n.Locale;
2178
+
2179
+ return {
2180
+ // @ts-expect-error FIXME: route conditional type
2181
+ props: await props({ locale, ...options }),
2182
+ revalidate,
2183
+ };
2184
+ };
2185
+
2186
+ /**
2187
+ * **For Pages Router only**
2188
+ */
2189
+ export const i18nGet = {
2190
+ locale,
2191
+ paths,
2192
+ staticPaths,
2193
+ props,
2194
+ staticProps,
2195
+ };
2196
+
2197
+ export default i18nGet;
2198
+ `);
2199
+
2200
+ /**
2201
+ * Transform the route translated either into a `pathname` or a `template`.
2202
+ *
2203
+ * Here we add the wildcard flag maybe found in the pathname to the template
2204
+ * name too.
2205
+ *
2206
+ * @see https://nextjs.org/docs/messages/invalid-multi-match
2207
+ */ function transformPathname(e, t) {
2208
+ return "/" + e.split("/").filter(Boolean).map((e)=>e.startsWith("[[...") ? `:${encodeURIComponent(e.slice(5, -2))}` : e.startsWith("[[") ? `:${encodeURIComponent(e.slice(2, -2))}` : e.startsWith("[") ? `:${encodeURIComponent(e.slice(1, -1))}` : `${encodeURIComponent(e)}`).join("/") + (t ? "/:wildcard*" : "");
2209
+ }
2210
+
2211
+ function a$2(e) {
2212
+ let { localeSource: t, localeDestination: o, template: a, pathname: l, permanent: n } = e, i = formatRoutePathname.formatRoutePathname((t ? `${t}/` : "") + a), c = formatRoutePathname.formatRoutePathname((o ? `${o}/` : "") + l);
2213
+ // console.log(`redirect template "${source}" to pathname "${destination}"`);
2214
+ if (i !== c) return {
2215
+ source: i,
2216
+ destination: c,
2217
+ permanent: !!n
2218
+ };
2219
+ }
2220
+ function generateRedirectForPathname(e, t, r, o, l) {
2221
+ let { defaultLocale: n, hideDefaultLocaleInUrl: i, localeParamName: c, permanentRedirects: s } = e, p = t === n, u = p && !i, m = {
2222
+ template: r,
2223
+ pathname: o,
2224
+ permanent: s
2225
+ };
2226
+ c ? // app router:
2227
+ u ? l.push(a$2({
2228
+ ...m,
2229
+ localeDestination: t
2230
+ })) : p && i ? l.push(a$2({
2231
+ ...m,
2232
+ localeSource: t
2233
+ })) : p ? l.push(a$2(m)) : l.push(a$2({
2234
+ ...m,
2235
+ localeSource: t,
2236
+ localeDestination: t
2237
+ })) : // pages router:
2238
+ o !== r && (u ? l.push(a$2({
2239
+ ...m,
2240
+ localeDestination: t
2241
+ })) : p ? l.push(a$2(m)) : l.push(a$2({
2242
+ ...m,
2243
+ localeSource: t,
2244
+ localeDestination: t
2245
+ })));
2246
+ }
2247
+ /**
2248
+ * TODO: maybe write directly the vercel configuration?
2249
+ *
2250
+ * @see
2251
+ * - https://nextjs.org/docs/pages/api-reference/next-config-js/redirects
2252
+ * - https://vercel.com/docs/projects/project-configuration#redirects
2253
+ */ let generateRedirects = (r, { localeParamName: a, permanentRedirects: l, tokens: n }, i)=>{
2254
+ let c = {
2255
+ ...r,
2256
+ localeParamName: a,
2257
+ permanentRedirects: l
2258
+ }, s = RegExp(utils.escapeRegExp(n.idDelimiter), "g"), p = [];
2259
+ for(let e in i){
2260
+ let t = i[e], r = i[e].pathnames;
2261
+ for(let a in r){
2262
+ let l = r[a], // prettier-ignore
2263
+ n = transformPathname(e.replace(s, "/"), t.wildcard), i = transformPathname(l, t.wildcard);
2264
+ // we do not redirect urls children of wildcard urls
2265
+ if (t.inWildcard) break;
2266
+ generateRedirectForPathname(c, a, n, i, p);
2267
+ }
2268
+ }
2269
+ return utils.arrayUniqueByProperties(p.filter(Boolean), [
2270
+ "source",
2271
+ "destination"
2272
+ ]).sort((e, t)=>e.source.localeCompare(t.source)).map((e)=>a ? e : {
2273
+ ...e,
2274
+ locale: !1
2275
+ });
2276
+ };
2277
+
2278
+ var p$3 = (({ config: e, options: t, routes: o })=>{
2279
+ let l = JSON.stringify(generateRedirects(e, t.routes, o.byId), null, 2);
2280
+ return `module.exports = ${l}`;
2281
+ });
2282
+
2283
+ function o$5(e) {
2284
+ let { localeSource: t, localeDestination: a, template: o, pathname: l, passLocale: i } = e, n = "";
2285
+ t && (n = `/${t}`);
2286
+ let c = formatRoutePathname.formatRoutePathname(n + l), s = "";
2287
+ a && (s = `/${a}`);
2288
+ let p = formatRoutePathname.formatRoutePathname(s + o);
2289
+ // console.log(`rewrite pathname "${source}" to template "${destination}"`);
2290
+ if (c === p) return;
2291
+ let m = {
2292
+ source: c,
2293
+ destination: p
2294
+ };
2295
+ return !1 === i && (m.locale = !1), m;
2296
+ }
2297
+ const generateRewriteForPathname = (e, t, r, a, l)=>{
2298
+ let { defaultLocale: i, hideDefaultLocaleInUrl: n, localeParamName: c } = e, s = t === i && n, // TODO: maybe support other locales to be hidden in the URL other than the default?
2299
+ p = {
2300
+ template: r,
2301
+ pathname: a
2302
+ };
2303
+ c ? // app router:
2304
+ s ? l.push(o$5({
2305
+ ...p,
2306
+ localeDestination: t,
2307
+ passLocale: !1
2308
+ })) : l.push(// prettier-ignore
2309
+ o$5({
2310
+ ...p,
2311
+ localeSource: t,
2312
+ localeDestination: t,
2313
+ passLocale: !1
2314
+ })) : // pages router:
2315
+ // this condition only applies to the pages router as with the app one
2316
+ // even if the template matches the pathname we always need to rewrite
2317
+ // as the localeParam is always needed in the rewrite destination
2318
+ a !== r && (s ? l.push(o$5(p)) : l.push(// `passLocale` must be `false` or the locale prefixed rewrite won't
2319
+ // be applied and does not forward the locale to the route context
2320
+ // when the locale is included in the URL. In fact we explicitly
2321
+ // add the locale to the rewrite rule in order to get the least
2322
+ // amount of existing URLs which is a good SEO practice
2323
+ o$5({
2324
+ ...p,
2325
+ localeSource: t,
2326
+ passLocale: !1
2327
+ })));
2328
+ };
2329
+ /**
2330
+ * TODO: maybe write directly the vercel configuration?
2331
+ *
2332
+ * @see
2333
+ * - https://nextjs.org/docs/pages/api-reference/next-config-js/rewrites
2334
+ * - https://vercel.com/docs/projects/project-configuration#rewrites
2335
+ */ let generateRewrites = (r, { tokens: o, localeParamName: l, permanentRedirects: i }, n)=>{
2336
+ let c = {
2337
+ ...r,
2338
+ localeParamName: l,
2339
+ permanentRedirects: i
2340
+ }, s = RegExp(utils.escapeRegExp(o.idDelimiter), "g"), p = [];
2341
+ for(let e in n){
2342
+ let t = n[e], r = n[e].pathnames;
2343
+ for(let o in r){
2344
+ let l = r[o], i = e.replace(s, "/");
2345
+ // we do not rewrite urls children of wildcard urls
2346
+ if (t.inWildcard) break;
2347
+ // we need to rewrite both the root path...
2348
+ generateRewriteForPathname(c, o, transformPathname(i), transformPathname(l), p), t.wildcard && // and for wildcard routes the ones with the `/:segment*` portion
2349
+ generateRewriteForPathname(c, o, transformPathname(i, t.wildcard), transformPathname(l, t.wildcard), p);
2350
+ }
2351
+ }
2352
+ // simple sort by destination:
2353
+ // return a.destination.localeCompare(b.destination);
2354
+ // sort by locale
2355
+ // return a.
2356
+ return utils.arrayUniqueByProperties(p.filter(Boolean), [
2357
+ "source",
2358
+ "destination"
2359
+ ]).sort((e, t)=>// simple sort by source:
2360
+ e.source.localeCompare(t.source));
2361
+ };
2362
+
2363
+ var f$2 = (({ config: e, routes: t, options: o })=>{
2364
+ let l = JSON.stringify(generateRewrites(e, o.routes, t.byId), null, 2);
2365
+ return `module.exports = ${l}`;
2366
+ });
2367
+
2368
+ var s$4 = (({ options: { routes: { localeParamName: t } }, adapterOptions: { router: e } })=>{
2369
+ let o = t ? `.replace("[${t}]/", "")` : "";
2370
+ switch(e){
2371
+ case "app":
2372
+ return `
2373
+ "use client";
2374
+
2375
+ import { useContext } from "react";
2376
+ import { I18nRouteContext } from "./I18nRouteContext";
2377
+
2378
+ export const useRouteId = () => useContext(I18nRouteContext)[0];
2379
+
2380
+ export default useRouteId;
2381
+ `;
2382
+ case "pages":
2383
+ return `
2384
+ import { useRouter } from "next/router";
2385
+ import { pathnameToRouteId } from "./pathnameToRouteId";
2386
+ import type { I18n } from "./types";
2387
+
2388
+ export const useRouteId = () =>
2389
+ pathnameToRouteId(useRouter().pathname${o}) as I18n.RouteId;
2390
+
2391
+ export default useRouteId;
2392
+ `;
2393
+ default:
2394
+ return `
2395
+ "use client";
2396
+
2397
+ import { useContext } from "react";
2398
+ import { usePathname } from "next/navigation";
2399
+ import { useRouter } from "next/router";
2400
+ import { I18nRouteContext } from "./I18nRouteContext";
2401
+ import { pathnameToRouteId } from "./pathnameToRouteId";
2402
+ import type { I18n } from "./types";
2403
+
2404
+ export const useRouteId = () => {
2405
+ const fromCtx = useContext(I18nRouteContext)[0];
2406
+ let fromPages = "";
2407
+ let fromApp = "";
2408
+
2409
+ try {
2410
+ fromPages = pathnameToRouteId(
2411
+ useRouter().pathname${o},
2412
+ ) as I18n.RouteId;
2413
+ } catch (e) {
2414
+ fromApp = pathnameToRouteId(
2415
+ (usePathname() || "")${o},
2416
+ ) as I18n.RouteId;
2417
+ }
2418
+
2419
+ return fromCtx || fromPages || fromApp;
2420
+ };
2421
+
2422
+ export default useRouteId;
2423
+ `;
2424
+ }
2425
+ });
2426
+
2427
+ var d$4 = (({})=>`
2428
+ "use client";
2429
+
2430
+ import { to } from "./to";
2431
+ import type { I18n } from "./types";
2432
+ import { useLocale } from "./useLocale";
2433
+
2434
+ export type UseToReturn = ReturnType<typeof useTo>;
2435
+
2436
+ export const useTo = () => {
2437
+ const locale = useLocale();
2438
+ return <Id extends I18n.RouteId>(
2439
+ routeId: Id,
2440
+ ...args: Id extends I18n.RouteIdDynamic
2441
+ ? [params: I18n.RouteParams[Id]]
2442
+ : []
2443
+ ) =>
2444
+ args[0]
2445
+ ? // @ts-expect-error nevermind
2446
+ (to(routeId, args[0], locale) as I18n.RoutePathnames[Id])
2447
+ : // @ts-expect-error nevermind
2448
+ (to(routeId, locale) as I18n.RoutePathnames[Id]);
2449
+ };
2450
+
2451
+ export default useTo;
2452
+ `);
2453
+
2454
+ var I$2 = (({})=>`
2455
+ "use client";
2456
+
2457
+ import { toSpa } from "./toSpa";
2458
+ import type { I18n } from "./types";
2459
+ import { useLocale } from "./useLocale";
2460
+
2461
+ export type UseToSpaReturn = ReturnType<typeof useToSpa>;
2462
+
2463
+ export const useToSpa = () => {
2464
+ const locale = useLocale();
2465
+ return <
2466
+ Root extends keyof I18n.RouteSpa,
2467
+ Path extends Extract<keyof I18n.RouteSpa[Root], string>,
2468
+ >(
2469
+ root: Root,
2470
+ path: Path,
2471
+ ...args: I18n.RouteJoinedId<Root, Path> extends I18n.RouteIdDynamic
2472
+ ? [params: I18n.RouteParams[I18n.RouteJoinedId<Root, Path>]]
2473
+ : I18n.RouteJoinedId<Root, Path> extends I18n.RouteIdStatic
2474
+ ? []
2475
+ : never
2476
+ ) => {
2477
+ const [params] = args;
2478
+ return (
2479
+ // prettier-ignore
2480
+ // @ts-expect-error FIXME: types
2481
+ (params ? toSpa(root, path, params, locale) : toSpa(root, path, locale)) as I18n.RouteSpa[Root][Path]
2482
+ );
2483
+ };
2484
+ };
2485
+
2486
+ export default useToSpa;
2487
+ `);
2488
+
2489
+ var n$4 = createAdapter(adapterNextOptions, ({ adapterOptions: e })=>{
2490
+ let { router: t } = e, u = [
2491
+ // TODO: maybe remove these files, they are useful for debugging for now
2492
+ // but probably will be useless
2493
+ {
2494
+ name: "next-redirects",
2495
+ fn: p$3,
2496
+ ext: "js"
2497
+ },
2498
+ {
2499
+ name: "next-rewrites",
2500
+ fn: f$2,
2501
+ ext: "js"
2502
+ },
2503
+ {
2504
+ name: "useRouteId",
2505
+ fn: s$4,
2506
+ ext: "ts",
2507
+ index: !0
2508
+ },
2509
+ {
2510
+ name: "useTo",
2511
+ fn: d$4,
2512
+ ext: "ts",
2513
+ index: !0
2514
+ },
2515
+ {
2516
+ name: "useToSpa",
2517
+ fn: I$2,
2518
+ ext: "ts",
2519
+ index: !0
2520
+ }
2521
+ ];
2522
+ return ("app" === t || "migrating" === t) && (u = u.concat([
2523
+ {
2524
+ name: "I18nLayout",
2525
+ fn: o$6,
2526
+ ext: "tsx",
2527
+ index: !0
2528
+ },
2529
+ {
2530
+ name: "I18nPage",
2531
+ fn: m$3,
2532
+ ext: "tsx",
2533
+ index: !0
2534
+ },
2535
+ {
2536
+ name: "I18nRoot",
2537
+ fn: i$4,
2538
+ ext: "tsx",
2539
+ index: !0
2540
+ }
2541
+ ])), ("pages" === t || "migrating" === t) && (u = u.concat([
2542
+ {
2543
+ name: "I18nSetter",
2544
+ fn: x$2,
2545
+ ext: "tsx",
2546
+ index: !0
2547
+ },
2548
+ {
2549
+ name: "I18nApp",
2550
+ fn: n$5,
2551
+ ext: "tsx",
2552
+ index: !0
2553
+ },
2554
+ {
2555
+ name: "I18nHead",
2556
+ fn: r$3,
2557
+ ext: "tsx"
2558
+ },
2559
+ {
2560
+ name: "i18nGet",
2561
+ fn: a$3,
2562
+ ext: "ts",
2563
+ index: !0
2564
+ }
2565
+ ])), {
2566
+ dependsOn: [
2567
+ "react"
2568
+ ],
2569
+ files: u
2570
+ };
2571
+ });
2572
+
2573
+ const adapterReactOptions = {};
2574
+
2575
+ var n$3 = (({})=>`
2576
+ import React from "react";
2577
+ import { defaultLocale } from "./defaultLocale";
2578
+ import type { I18n } from "./types";
2579
+
2580
+ export type I18nContextValue = {
2581
+ t: I18n.Translate;
2582
+ locale: I18n.Locale;
2583
+ };
2584
+
2585
+ let _I18nContext;
2586
+
2587
+ // For serverComponents (app-dir), the context cannot be used and
2588
+ // this makes that all the imports to here don't break the build.
2589
+ // The use of this context is inside each util, depending pages-dir or app-dir.
2590
+ if (typeof React.createContext === "function") {
2591
+ _I18nContext = React.createContext<I18nContextValue>({
2592
+ t: ((key: string) => key) as I18n.Translate,
2593
+ locale: defaultLocale,
2594
+ });
2595
+ }
2596
+
2597
+ /**
2598
+ * @internal
2599
+ */
2600
+ export const I18nContext = _I18nContext as React.Context<I18nContextValue>;
2601
+
2602
+ // export default I18nContext;
2603
+ `);
2604
+
2605
+ var o$4 = (({})=>`
2606
+ "use client";
2607
+
2608
+ import { useEffect } from "react";
2609
+ import { dom } from "@koine/dom";
2610
+ import { useLocale } from "./useLocale";
2611
+
2612
+ /**
2613
+ * @internal
2614
+ */
2615
+ export const I18nEffects = () => {
2616
+ const currentLocale = useLocale();
2617
+
2618
+ useEffect(() => {
2619
+ if (currentLocale) {
2620
+ const html = dom("html");
2621
+ if (html) html.lang = currentLocale;
2622
+ }
2623
+ }, [currentLocale]);
2624
+
2625
+ return null;
2626
+ };
2627
+
2628
+ // export default I18nEffects;
2629
+ `);
2630
+
2631
+ var r$2 = (({})=>`
2632
+ "use client";
2633
+
2634
+ import { defaultI18nMetadata } from "./defaultI18nMetadata";
2635
+ import type { I18n } from "./types";
2636
+
2637
+ export type I18nHeadTagsProps = {
2638
+ metadata?: I18n.Metadata;
2639
+ };
2640
+
2641
+ /**
2642
+ * Renders the HTML tags to use in the \`<head>\`
2643
+ */
2644
+ export const I18nHeadTags = (props: I18nHeadTagsProps) => {
2645
+ const { metadata = defaultI18nMetadata } = props;
2646
+ const { alternates, canonical } = metadata;
2647
+
2648
+ return (
2649
+ <>
2650
+ {canonical && (
2651
+ <link
2652
+ rel="canonical"
2653
+ href={canonical}
2654
+ key="canonical"
2655
+ />
2656
+ )}
2657
+ {Object.keys(alternates).map((locale) => (
2658
+ <link
2659
+ rel="alternate"
2660
+ hrefLang={locale}
2661
+ href={alternates[locale]}
2662
+ key={"alternate-" + locale}
2663
+ />
2664
+ ))}
2665
+ </>
2666
+ );
2667
+ };
2668
+
2669
+ export default I18nHeadTags;
2670
+ `);
2671
+
2672
+ var m$2 = (({})=>`
2673
+ "use client";
2674
+
2675
+ import { createContext } from "react";
2676
+ import { defaultI18nMetadata } from "./defaultI18nMetadata";
2677
+ import type { I18n } from "./types";
2678
+
2679
+ type I18nMetadataContextValue = readonly [
2680
+ /** metadata */
2681
+ I18n.Metadata,
2682
+ /** setMetadata */
2683
+ React.Dispatch<React.SetStateAction<I18n.Metadata>>,
2684
+ ];
2685
+
2686
+ /**
2687
+ * @internal
2688
+ */
2689
+ export const I18nMetadataContext = createContext<I18nMetadataContextValue>([
2690
+ defaultI18nMetadata,
2691
+ () => (defaultI18nMetadata),
2692
+ ]);
2693
+
2694
+ // export default I18nMetadataContext;
2695
+ `);
2696
+
2697
+ var a$1 = (({})=>`
2698
+ "use client";
2699
+
2700
+ import { useMemo, useState } from "react";
2701
+ import type { I18n } from "@/i18n";
2702
+ import { I18nMetadataContext } from "./I18nMetadataContext";
2703
+
2704
+ type I18nMetadataProviderProps = React.PropsWithChildren<{
2705
+ metadata?: I18n.Metadata;
2706
+ }>;
2707
+
2708
+ /**
2709
+ * @internal
2710
+ */
2711
+ export function I18nMetadataProvider(props: I18nMetadataProviderProps) {
2712
+ const { children } = props;
2713
+ const [metadata, setMetadata] = useState<I18n.Metadata>(
2714
+ props.metadata || ({} as I18n.Metadata),
2715
+ );
2716
+ const value = useMemo(
2717
+ () => [metadata, setMetadata] as const,
2718
+ [metadata],
2719
+ );
2720
+
2721
+ return (
2722
+ <I18nMetadataContext.Provider value={value}>
2723
+ {children}
2724
+ </I18nMetadataContext.Provider>
2725
+ );
2726
+ }
2727
+
2728
+ // export default I18nMetadataProvider;
2729
+ `);
2730
+
2731
+ var x$1 = (({})=>`
2732
+ "use client";
2733
+
2734
+ import { useContext, useEffect } from "react";
2735
+ import { I18nMetadataContext } from "./I18nMetadataContext";
2736
+ import type { I18n } from "./types";
2737
+
2738
+ type I18nMetadataSetterProps = {
2739
+ metadata: I18n.Metadata;
2740
+ };
2741
+
2742
+ /**
2743
+ * NB: Do not use it next.js Pages router
2744
+ *
2745
+ * @internal
2746
+ */
2747
+ export const I18nMetadataSetter = (props: I18nMetadataSetterProps) => {
2748
+ const { metadata } = props;
2749
+ const [, setMetadata] = useContext(I18nMetadataContext);
2750
+
2751
+ useEffect(() => {
2752
+ setMetadata(metadata);
2753
+ }, [metadata, setMetadata]);
2754
+
2755
+ return null;
2756
+ };
2757
+
2758
+ // export default I18nMetadataSetter;
2759
+ `);
2760
+
2761
+ var f$1 = (({})=>`
2762
+ "use client";
2763
+
2764
+ import { I18nContext } from "./I18nContext";
2765
+ import { defaultLocale } from "./defaultLocale";
2766
+ import { createT } from "./createT";
2767
+ import type { I18n } from "./types";
2768
+
2769
+ export type I18nProviderProps = React.PropsWithChildren<{
2770
+ locale?: I18n.Locale;
2771
+ dictionaries?: I18n.Dictionaries;
2772
+ }>;
2773
+
2774
+ export const I18nProvider = ({
2775
+ locale = defaultLocale,
2776
+ dictionaries = {},
2777
+ children,
2778
+ }: I18nProviderProps) => {
2779
+ const pluralRules = new Intl.PluralRules(locale);
2780
+ const t = createT(dictionaries, pluralRules, locale) as I18n.Translate;
2781
+
2782
+ return (
2783
+ <I18nContext.Provider value={{ locale, t }}>{children}</I18nContext.Provider>
2784
+ );
2785
+ };
2786
+
2787
+ export default I18nProvider;
2788
+ `);
2789
+
2790
+ var i$3 = (({})=>`
2791
+ "use client";
2792
+
2793
+ import { createContext } from "react";
2794
+ import type { I18n } from "./types";
2795
+
2796
+ type I18nRouteContextValue = readonly [
2797
+ /** routeId */
2798
+ I18n.RouteId,
2799
+ /** setRouteId */
2800
+ React.Dispatch<React.SetStateAction<I18n.RouteId>>,
2801
+ ];
2802
+
2803
+ export const I18nRouteContext = createContext<I18nRouteContextValue>([
2804
+ "" as I18n.RouteId,
2805
+ () => "",
2806
+ ]);
2807
+
2808
+ // export default I18nRouteContext;
2809
+ `);
2810
+
2811
+ var s$3 = (({})=>`
2812
+ "use client";
2813
+
2814
+ import { useMemo, useState } from "react";
2815
+ import type { I18n } from "@/i18n";
2816
+ import { I18nRouteContext } from "./I18nRouteContext";
2817
+
2818
+ type I18nRouteProviderProps = React.PropsWithChildren<{
2819
+ id: I18n.RouteId;
2820
+ }>;
2821
+
2822
+ /**
2823
+ * @internal
2824
+ */
2825
+ export function I18nRouteProvider(props: I18nRouteProviderProps) {
2826
+ const { children } = props;
2827
+ const [id, setId] = useState<I18n.RouteId>(
2828
+ props.id || ("" as I18n.RouteId),
2829
+ );
2830
+ const value = useMemo(
2831
+ () => [id, setId] as const,
2832
+ [id],
2833
+ );
2834
+
2835
+ return (
2836
+ <I18nRouteContext.Provider value={value}>
2837
+ {children}
2838
+ </I18nRouteContext.Provider>
2839
+ );
2840
+ }
2841
+
2842
+ // export default I18nRouteProvider;
2843
+ `);
2844
+
2845
+ var d$3 = (({})=>`
2846
+ "use client";
2847
+
2848
+ import { useContext, useEffect } from "react";
2849
+ import { I18nRouteContext } from "./I18nRouteContext";
2850
+ import type { I18n } from "./types";
2851
+
2852
+ type I18nRouteSetterProps = {
2853
+ id: I18n.RouteId;
2854
+ };
2855
+
2856
+ /**
2857
+ * NB: Do not use it next.js Pages router
2858
+ *
2859
+ * @internal
2860
+ */
2861
+ export const I18nRouteSetter = (props: I18nRouteSetterProps) => {
2862
+ const { id } = props;
2863
+ const [, setRouteId] = useContext(I18nRouteContext);
2864
+
2865
+ useEffect(() => {
2866
+ setRouteId(id);
2867
+ }, [id, setRouteId]);
2868
+
2869
+ return null;
2870
+ };
2871
+
2872
+ // export default I18nRouteSetter;
2873
+ `);
2874
+
2875
+ var p$2 = (({})=>`
2876
+ "use client";
2877
+
2878
+ import { useMemo } from "react";
2879
+ import { formatElements } from "./formatElements";
2880
+ import type { I18n } from "./types";
2881
+ import { useT } from "./useT";
2882
+
2883
+ export type TProps = {
2884
+ i18nKey: I18n.TranslationsAllPaths;
2885
+ components?: React.ReactElement[] | Record<string, React.ReactElement>;
2886
+ values?: I18n.TranslationQuery;
2887
+ returnObjects?: boolean;
2888
+ };
2889
+
2890
+ /**
2891
+ * Translate transforming:
2892
+ * <0>This is an <1>example</1><0>
2893
+ * to -> <h1>This is an <b>example</b><h1>
2894
+ */
2895
+ export const T = ({
2896
+ i18nKey,
2897
+ values,
2898
+ components,
2899
+ returnObjects,
2900
+ }: TProps) => {
2901
+ const [namespace, path] = (i18nKey as string).split(":");
2902
+ const t = useT(namespace as I18n.TranslateNamespace) as I18n.TranslateLoose;
2903
+ const result = useMemo(() => {
2904
+ const text = t(path, values, {
2905
+ returnObjects,
2906
+ });
2907
+
2908
+ if (!text) return text;
2909
+
2910
+ if (!components || components.length === 0)
2911
+ return Array.isArray(text) ? text.map((item) => item) : text;
2912
+
2913
+ if (Array.isArray(text))
2914
+ return text.map((item) => formatElements(item, components));
2915
+
2916
+ return formatElements(text, components);
2917
+ }, [t, path, values, components, returnObjects]) as string;
2918
+
2919
+ return result;
2920
+ };
2921
+
2922
+ export default T;
2923
+ `);
2924
+
2925
+ var I$1 = (({})=>`
2926
+ "use client";
2927
+
2928
+ import { useMemo } from "react";
2929
+ import type { TProps } from "./T";
2930
+ import { formatElements } from "./formatElements";
2931
+
2932
+ export type TransTextProps = Pick<TProps, "components"> & {
2933
+ text: string;
2934
+ };
2935
+
2936
+ export const TransText = ({ text, components }: TransTextProps) => {
2937
+ return useMemo(
2938
+ () =>
2939
+ !components || components.length === 0
2940
+ ? text
2941
+ : formatElements(text, components),
2942
+ [text, components],
2943
+ ) as string;
2944
+ };
2945
+
2946
+ export default TransText;
2947
+ `);
2948
+
2949
+ var u = (({})=>`
2950
+ import { Fragment, cloneElement } from "react";
2951
+
2952
+ const tagParsingRegex = /<(\\w+) *>(.*?)<\\/\\1 *>|<(\\w+) *\\/>/;
2953
+
2954
+ const nlRe = /(?:\\r\\n|\\r|\\n)/g;
2955
+
2956
+ function getElements(
2957
+ parts: Array<string | undefined>,
2958
+ ): Array<string | undefined>[] {
2959
+ if (!parts.length) return [];
2960
+
2961
+ const [paired, children, unpaired, after] = parts.slice(0, 4);
2962
+
2963
+ return [
2964
+ [(paired || unpaired) as string, children || ("" as string), after],
2965
+ ].concat(getElements(parts.slice(4, parts.length)));
2966
+ }
2967
+
2968
+ /**
2969
+ * @internal
2970
+ * @see https://github.com/aralroca/next-translate/blob/master/src/formatElements.tsx
2971
+ */
2972
+ export function formatElements(
2973
+ value: string,
2974
+ elements: React.ReactElement[] | Record<string, React.ReactElement> = [],
2975
+ ): string | React.ReactNode[] {
2976
+ const parts = value.replace(nlRe, "").split(tagParsingRegex);
2977
+
2978
+ if (parts.length === 1) return value;
2979
+
2980
+ const tree: React.ReactNode[] = [];
2981
+
2982
+ const before = parts.shift();
2983
+ if (before) tree.push(before);
2984
+
2985
+ getElements(parts).forEach(([key, children, after], realIndex: number) => {
2986
+ const element = (elements as Record<string, React.ReactElement>)[
2987
+ key as string
2988
+ // eslint-disable-next-line react/jsx-no-useless-fragment
2989
+ ] || <Fragment />;
2990
+
2991
+ tree.push(
2992
+ cloneElement(
2993
+ element,
2994
+ { key: realIndex },
2995
+
2996
+ // format children for pair tags
2997
+ // unpaired tags might have children if it's a component passed as a variable
2998
+ children ? formatElements(children, elements) : element.props.children,
2999
+ ),
3000
+ );
3001
+
3002
+ if (after) tree.push(after);
3003
+ });
3004
+
3005
+ return tree;
3006
+ }
3007
+
3008
+ // export default formatElements;
3009
+ `);
3010
+
3011
+ var T = (({})=>`
3012
+ "use client";
3013
+
3014
+ import { useContext } from "react";
3015
+ import { I18nMetadataContext } from "./I18nMetadataContext";
3016
+
3017
+ export const useI18nSwitch = (
3018
+ absolute?: boolean,
3019
+ includeSearch?: boolean,
3020
+ includeHash?: boolean
3021
+ ) => {
3022
+ const { alternates: urls } = useContext(I18nMetadataContext)[0];
3023
+
3024
+ if (!absolute) {
3025
+ try {
3026
+ for (const locale in urls) {
3027
+ const absoluteUrl = urls[locale];
3028
+ if (absoluteUrl) {
3029
+ const url = new URL(absoluteUrl);
3030
+ urls[locale] = url.pathname;
3031
+ if (includeSearch) urls[locale] += url.search;
3032
+ if (includeHash) urls[locale] += url.hash;
3033
+ }
3034
+ }
3035
+ } catch(e) {
3036
+ // TODO: verify this: we could have empty/invalid languages URLs here?
3037
+ }
3038
+ }
3039
+
3040
+ return urls;
3041
+ }
3042
+
3043
+ export default useI18nSwitch;
3044
+ `);
3045
+
3046
+ var c$1 = (({})=>`
3047
+ "use client";
3048
+
3049
+ import { useContext } from "react";
3050
+ import { defaultLocale } from "./defaultLocale";
3051
+ import { I18nContext } from "./I18nContext";
3052
+
3053
+ export const useLocale = () => useContext(I18nContext).locale || defaultLocale;
3054
+
3055
+ export default useLocale;
3056
+ `);
3057
+
3058
+ var R = (({})=>`
3059
+ "use client";
3060
+
3061
+ import { useContext } from "react";
3062
+ import { I18nRouteContext } from "./I18nRouteContext";
3063
+
3064
+ export const useRouteId = () => useContext(I18nRouteContext)[0];
3065
+
3066
+ export default useRouteId;
3067
+ `);
3068
+
3069
+ var l$3 = (({})=>`
3070
+ "use client";
3071
+
3072
+ import { useContext, useMemo } from "react";
3073
+ import { I18nContext } from "./I18nContext";
3074
+ import type { I18n } from "./types";
3075
+
3076
+ export const useT = <T extends I18n.TranslateNamespace>(namespace: T) => {
3077
+ const t = useContext(I18nContext).t;
3078
+ return useMemo(
3079
+ () =>
3080
+ (key: string, ...args) =>
3081
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
3082
+ (t as any)(\`\${namespace}:\${key}\`, ...args),
3083
+ [t],
3084
+ ) as I18n.TranslateNamespaced<T>;
3085
+ };
3086
+
3087
+ export default useT;
3088
+
3089
+ `);
3090
+
3091
+ var r$1 = createAdapter(adapterReactOptions, ({})=>({
3092
+ dependsOn: [
3093
+ "js"
3094
+ ],
3095
+ files: [
3096
+ {
3097
+ name: "formatElements",
3098
+ fn: u,
3099
+ ext: "tsx"
3100
+ },
3101
+ {
3102
+ name: "I18nContext",
3103
+ fn: n$3,
3104
+ ext: "tsx"
3105
+ },
3106
+ {
3107
+ name: "I18nEffects",
3108
+ fn: o$4,
3109
+ ext: "tsx"
3110
+ },
3111
+ {
3112
+ name: "I18nHeadTags",
3113
+ fn: r$2,
3114
+ ext: "tsx",
3115
+ index: !0
3116
+ },
3117
+ {
3118
+ name: "I18nMetadataContext",
3119
+ fn: m$2,
3120
+ ext: "tsx"
3121
+ },
3122
+ {
3123
+ name: "I18nMetadataProvider",
3124
+ fn: a$1,
3125
+ ext: "tsx"
3126
+ },
3127
+ {
3128
+ name: "I18nMetadataSetter",
3129
+ fn: x$1,
3130
+ ext: "tsx"
3131
+ },
3132
+ {
3133
+ name: "I18nProvider",
3134
+ fn: f$1,
3135
+ ext: "tsx",
3136
+ index: !0
3137
+ },
3138
+ {
3139
+ name: "I18nRouteContext",
3140
+ fn: i$3,
3141
+ ext: "tsx"
3142
+ },
3143
+ {
3144
+ name: "I18nRouteProvider",
3145
+ fn: s$3,
3146
+ ext: "tsx"
3147
+ },
3148
+ {
3149
+ name: "I18nRouteSetter",
3150
+ fn: d$3,
3151
+ ext: "tsx"
3152
+ },
3153
+ {
3154
+ name: "T",
3155
+ fn: p$2,
3156
+ ext: "tsx",
3157
+ index: !0
3158
+ },
3159
+ {
3160
+ name: "TransText",
3161
+ fn: I$1,
3162
+ ext: "tsx",
3163
+ index: !0
3164
+ },
3165
+ {
3166
+ name: "useI18nSwitch",
3167
+ fn: T,
3168
+ ext: "ts",
3169
+ index: !0
3170
+ },
3171
+ {
3172
+ name: "useLocale",
3173
+ fn: c$1,
3174
+ ext: "ts",
3175
+ index: !0
3176
+ },
3177
+ {
3178
+ name: "useRouteId",
3179
+ fn: R,
3180
+ ext: "ts",
3181
+ index: !0
3182
+ },
3183
+ {
3184
+ name: "useT",
3185
+ fn: l$3,
3186
+ ext: "ts",
3187
+ index: !0
3188
+ }
3189
+ ]
3190
+ }));
3191
+
3192
+ let o$3 = (e)=>{
3193
+ let t = "";
3194
+ return e.filter((e)=>e.index).sort((e, t)=>e.name.localeCompare(t.name)).forEach((e)=>{
3195
+ t += `export * from "./${e.name}";\n`;
3196
+ }), t;
3197
+ }, s$2 = (e)=>{
3198
+ switch(e){
3199
+ case "js":
3200
+ break;
3201
+ case "next":
3202
+ return n$4;
3203
+ case "next-translate":
3204
+ return a$4;
3205
+ case "react":
3206
+ return r$1;
3207
+ }
3208
+ return t$1;
3209
+ }, /**
3210
+ * Recursively builds a list of adapters to use based on the `dependsOn` array
3211
+ * of the choosen adapter
3212
+ */ p$1 = async (t, { name: a, options: n = {} }, r = [])=>{
3213
+ let o = s$2(a)(t, n || {}), c = utils.isPromise(o) ? await o : o;
3214
+ return r = r.concat([
3215
+ c
3216
+ ]), c.dependsOn && await Promise.all(c.dependsOn.map(async (e)=>{
3217
+ r = r.concat(await p$1(t, {
3218
+ name: e
3219
+ }));
3220
+ })), r;
3221
+ }, i$2 = (e, t)=>{
3222
+ let { outputFiles: a } = e.options, // TODO: prettier does probably not make sense unless one wants to keep the
3223
+ // auto-generated files on git, maybe allow this as an option?
3224
+ // // prettier breaks jest, @see https://jestjs.io/docs/ecmascript-modules
3225
+ // // https://github.com/jestjs/jest/issues/14305
3226
+ // if (!process.env["JEST_WORKER_ID"]) {
3227
+ // const { format } = await import("prettier");
3228
+ // out = await format(out, {
3229
+ // parser: "typescript",
3230
+ // });
3231
+ // }
3232
+ n = t.reduce((e, t)=>{
3233
+ // NOTE: we allow adapters to produce the same files as their dependent's
3234
+ // parent adapters (defined with `dependsOn`), here we ensure the parent
3235
+ // adapters files do not override their children same-named ones which
3236
+ // should get the priority
3237
+ let a = e.map((e)=>e.name + e.ext);
3238
+ return [
3239
+ ...e,
3240
+ ...t.files.filter((e)=>!a.includes(e.name + e.ext))
3241
+ ];
3242
+ }, []).map((t)=>{
3243
+ let { fn: n, ...r } = t, o = a?.[r.name] || r.name;
3244
+ return {
3245
+ ...r,
3246
+ name: o,
3247
+ content: n({
3248
+ ...e,
3249
+ adapterOptions: e.options.adapter.options || {}
3250
+ })
3251
+ };
3252
+ });
3253
+ return(// automatically create an index file if the adapters want it
3254
+ o$3(n) && n.push({
3255
+ name: "index",
3256
+ ext: "ts",
3257
+ content: o$3(n)
3258
+ }), {
3259
+ files: n,
3260
+ // it is enough that just one adapter requires this
3261
+ needsTranslationsFiles: t.some((e)=>e.needsTranslationsFiles)
3262
+ });
3263
+ };
3264
+ let generateCode = async (e)=>i$2(e, await p$1(e, e.options.adapter));
3265
+
3266
+ let tsCompile = (o, i, s, // Set<string>,
3267
+ r)=>{
3268
+ let l = Array.from(s).filter((e)=>e.endsWith(".ts") || e.endsWith(".tsx")).map((t)=>node_path.join(o, i, t)), n = {
3269
+ noEmitOnError: !0,
3270
+ noImplicitAny: !0,
3271
+ declaration: !0,
3272
+ // target: ts.ScriptTarget.ES5,
3273
+ target: t__namespace.ScriptTarget.ESNext,
3274
+ // module: ts.ModuleKind.CommonJS,
3275
+ module: t__namespace.ModuleKind.ESNext,
3276
+ moduleResolution: t__namespace.ModuleResolutionKind.Bundler,
3277
+ resolveJsonModule: !0,
3278
+ allowJs: !1,
3279
+ esModuleInterop: !0,
3280
+ jsx: t__namespace.JsxEmit.ReactJSX,
3281
+ outDir: node_path.join(o, i),
3282
+ skipLibCheck: !0,
3283
+ noEmitHelpers: !0,
3284
+ importHelpers: !0,
3285
+ ...r || {}
3286
+ }, // Create a Program with an in-memory emit
3287
+ // const createdFiles: Record<string, string> = {};
3288
+ // const host = ts.createCompilerHost(compilerOptions);
3289
+ // host.writeFile = (fileName: string, contents: string) => createdFiles[fileName] = contents;
3290
+ a = t__namespace.createProgram(l, n), /* , host */ m = a.emit();
3291
+ return(// .concat(emitResultCjs.diagnostics);
3292
+ // const programCjs = ts.createProgram(rootNames, {
3293
+ // ...compilerOptions,
3294
+ // module: ts.ModuleKind.CommonJS,
3295
+ // moduleResolution: ts.ModuleResolutionKind.Classic,
3296
+ // declaration: false,
3297
+ // });
3298
+ // const emitResultCjs = programCjs.emit();
3299
+ t__namespace.getPreEmitDiagnostics(a).concat(m.diagnostics).forEach((e)=>{
3300
+ if (e.file) {
3301
+ let { line: o, character: i } = t__namespace.getLineAndCharacterOfPosition(e.file, // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
3302
+ e.start), s = t__namespace.flattenDiagnosticMessageText(e.messageText, "\n");
3303
+ console.log(`${e.file.fileName} (${o + 1},${i + 1}): ${s}`);
3304
+ } else console.log(t__namespace.flattenDiagnosticMessageText(e.messageText, "\n"));
3305
+ }), m);
3306
+ };
3307
+
3308
+ let n$2 = async (e, r, s, i)=>Promise.all(s.files.map(async ({ name: s, ext: o, content: n })=>{
3309
+ let l = `${s}.${o}`, d = node_path.join(e, r, l);
3310
+ await node.fsWrite(d, n), i.add(l);
3311
+ })), d$2 = (a, r, s)=>{
3312
+ let i = Array.from(s).filter((e)=>e.endsWith(".ts") || e.endsWith(".tsx"));
3313
+ tsCompile(a, r, i), i.forEach((i)=>{
3314
+ s.add(i.replace(/\.tsx?$/, ".js")), s.add(i.replace(/\.tsx?$/, ".d.ts")), // remove TypeScript files
3315
+ s.delete(i), node_fs.rmSync(node_path.join(a, r, i), {
3316
+ force: !0
3317
+ });
3318
+ });
3319
+ }, m$1 = async (e, r, { translationFiles: s }, i)=>Promise.all(s.map(async ({ data: s, locale: o, path: n })=>{
3320
+ let l = node_path.join("translations", o);
3321
+ await node.fsWrite(node_path.join(e, r, l, n), JSON.stringify(s)), i.add(l);
3322
+ })), f = (e, a, r, s)=>[
3323
+ node_path.join(e, a, ".gitignore"),
3324
+ Array.from(new Set([
3325
+ ...r,
3326
+ ...s
3327
+ ])).sort().map((e)=>`/${e}`).join(`\n`)
3328
+ ];
3329
+ /**
3330
+ * @default process.cwd()
3331
+ */ /**
3332
+ * Relative to the given `cwd`.
3333
+ *
3334
+ * Use a _dot_ named folder in order to be automatically ignored when your
3335
+ * i18n source files live in the same folder as the generated code
3336
+ */ let writeCode = async (e, t)=>{
3337
+ let { cwd: r = process.cwd(), output: i, skipTsCompile: o, skipGitignore: l, skipTranslations: p } = e, c = await generateCode(t), w = new Set(), y = new Set();
3338
+ await n$2(r, i, c, w), o || d$2(r, i, w), c.needsTranslationsFiles && !p && await m$1(r, i, t.input, y), l || await node.fsWrite(...f(r, i, y, w));
3339
+ };
3340
+
3341
+ const codeDataRoutesOptions = {
3342
+ /**
3343
+ * Set this to true once your routing setup is ready for production.
3344
+ *
3345
+ * @default false
3346
+ */ permanentRedirects: !1,
3347
+ /**
3348
+ * The name of the locale dynamic segment in the URL usually represented as
3349
+ * `[lang]/my-slugs` but without neither brackets nor slashes, so just `lang`
3350
+ *
3351
+ * @default "lang"
3352
+ */ localeParamName: "lang",
3353
+ /** @default "~.json" */ translationJsonFileName: "~.json",
3354
+ /**
3355
+ * Generated `route_id()` functions prefix, prepended to the automatically
3356
+ * generated function names.
3357
+ *
3358
+ * @default ""
3359
+ */ fnsPrefix: "",
3360
+ tokens: {
3361
+ /** @default "^" */ parentReference: "^",
3362
+ /** @default "." */ idDelimiter: ".",
3363
+ /**
3364
+ * @see https://nextjs.org/docs/pages/building-your-application/routing/dynamic-routes#catch-all-segments
3365
+ */ catchAll: {
3366
+ /** @default "[..." */ start: "[...",
3367
+ /** @default "]" */ end: "]"
3368
+ },
3369
+ /**
3370
+ * @see https://nextjs.org/docs/pages/building-your-application/routing/dynamic-routes#optional-catch-all-segments
3371
+ */ optionalCatchAll: {
3372
+ /** @default "[[..." */ start: "[[...",
3373
+ /** @default "]]" */ end: "]]"
3374
+ }
3375
+ }
3376
+ };
3377
+ let r = (t, a)=>{
3378
+ let { idDelimiter: l, parentReference: n, catchAll: r, optionalCatchAll: d } = a.tokens;
3379
+ return {
3380
+ ...t,
3381
+ ...a,
3382
+ reg: {
3383
+ trailingDelimiter: RegExp(`${utils.escapeRegExp(l)}+$`),
3384
+ indexEnd: RegExp(`${utils.escapeRegExp(l)}index$`),
3385
+ parentReference: RegExp(`^/${utils.escapeRegExp(n)}`),
3386
+ catchAll: RegExp(`${utils.escapeRegExp(r.start)}(.+)${utils.escapeRegExp(r.end)}$`),
3387
+ optionalCatchAll: RegExp(`${utils.escapeRegExp(d.start)}(.+)${utils.escapeRegExp(d.end)}$`)
3388
+ }
3389
+ };
3390
+ }, /**
3391
+ * Normalise user defined route id
3392
+ *
3393
+ * 1) remove ending `.index`
3394
+ */ d$1 = (e, { reg: t })=>{
3395
+ let a = e.replace(t.indexEnd, ""), l = t.optionalCatchAll.test(e), n = t.catchAll.test(e);
3396
+ return l && (a = a.replace(t.optionalCatchAll, "")), n && (a = a.replace(t.catchAll, "")), {
3397
+ routeId: a = a.replace(t.trailingDelimiter, ""),
3398
+ isCatchAll: n,
3399
+ isOptionalCatchAll: l
3400
+ };
3401
+ }, /**
3402
+ * Normalise user defined route pathname
3403
+ *
3404
+ * - ensures beginning slash
3405
+ * - replaces too many consecutive slashes
3406
+ * - removes the trailing slash
3407
+ * - removes `*` wildcard token
3408
+ * - normalises to `/my/[id]` dynamic params defined in any of these shapes:
3409
+ * - `/my/{{id}}`
3410
+ * - `/my/{{ id }}`
3411
+ * - `/my/[id]`
3412
+ * - `/my/[ id ]`
3413
+ * - `/my/{id}`
3414
+ * - `/my/{ id }`
3415
+ *
3416
+ * TODO: support also `/my/:id` syntax?
3417
+ */ i$1 = (e, t)=>formatRoutePathname.formatRoutePathname(e.replace(/\*/g, "").replace(/[[{]{1,2}(.*?)[\]}]{1,2}/g, (e, t)=>`[${t.trim()}]`), t), /**
3418
+ * Gathers a dictionary with the params extracted from the given (normalised)
3419
+ * route id
3420
+ */ s$1 = (e)=>{
3421
+ let t = e.match(/\[.*?\]/g);
3422
+ if (t) return t.map((e)=>e.slice(1, -1).trim()).reduce((e, t)=>(// TODO: maybe determine the more specific type with some kind of special
3423
+ // token used in the route id `[dynamicParam]` portion
3424
+ e[t] = "stringOrNumber", e), {});
3425
+ }, /**
3426
+ * Recursively replace `/^` references with the parent route value
3427
+ */ p = (e, t, a, l, n)=>{
3428
+ let { tokens: { parentReference: r, idDelimiter: d }, reg: i } = t, s = e.byId[l], o = s.pathnames[a];
3429
+ // beginning slash is always present here as the route value is already
3430
+ // normalised at this point
3431
+ if (o.startsWith(`/${r}`)) {
3432
+ // removes the slash + token
3433
+ o = o.replace(i.parentReference, "");
3434
+ // grab the parent id
3435
+ let r = l.split(d).slice(0, -1).join(d);
3436
+ if (!n || n && n(s, r)) {
3437
+ if (r) o = p(e, t, a, r, n) + o;
3438
+ else throw Error("Used a parent route token reference without a matching parent route");
3439
+ }
3440
+ }
3441
+ return o;
3442
+ }, /**
3443
+ * Mutate the routes data replacing the parent route tokens
3444
+ * NB: it mutates the data
3445
+ */ o$2 = (e, t)=>{
3446
+ for(let a in e.byId)for(let l in e.byId[a].pathnames)e.byId[a].pathnames[l] = p(e, t, l, a);
3447
+ }, /**
3448
+ * Mutate the routes data replacing the parent route tokens
3449
+ * NB: it mutates the data
3450
+ */ c = (e, t)=>{
3451
+ let a = (t, a)=>t.inWildcard && !e.wildcardIds.includes(a);
3452
+ for(let l in e.byId){
3453
+ let { inWildcard: n } = e.byId[l];
3454
+ if (n && e.byId[l].pathnamesSpa) for(let n in e.byId[l].pathnamesSpa)// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
3455
+ e.byId[l].pathnamesSpa[n] = p(e, t, n, l, a);
3456
+ else // discard unneeded data
3457
+ delete e.byId[l].pathnamesSpa;
3458
+ }
3459
+ }, /**
3460
+ * Optimize the route map by collapsing pathnames that are equal to the one for
3461
+ * the default locale
3462
+ *
3463
+ * NB: It mutates the data
3464
+ *
3465
+ * ```json
3466
+ * {
3467
+ * // from
3468
+ * "about": {
3469
+ * "en": "/about",
3470
+ * "nl": "/about"
3471
+ * },
3472
+ * "account.user.[id]": {
3473
+ * "en": "/account/user/{{ id }}",
3474
+ * "fi": "/account/user/{{ id }}",
3475
+ * "nl": "/rekening/gebruiker/{{ id }}"
3476
+ * },
3477
+ * // to
3478
+ * "about": "/about",
3479
+ * "account.user.[id]": {
3480
+ * "en": "/account/user/{{ id }}",
3481
+ * "nl": "/rekening/gebruiker/{{ id }}"
3482
+ * }
3483
+ * }
3484
+ * ```
3485
+ */ m = (e, t)=>{
3486
+ let { defaultLocale: a, locales: n } = t;
3487
+ for(let t in e.byId){
3488
+ let r = e.byId[t].pathnames, d = r[a], i = {};
3489
+ for(let e in r){
3490
+ let t = r[e];
3491
+ t !== d && (i[e] = t);
3492
+ }
3493
+ Object.keys(i).length === n.length - 1 || (// if we have the same number of optimized/non-optimized pathnames we do
3494
+ // not add the data
3495
+ Object.keys(i).length >= 1 ? (// if we have more than one optimized pathnames we do add the default locale one
3496
+ i[a] = d, e.byId[t].pathnamesSlim = utils.objectSortByKeysMatching(i, a)) : // otherwise it means that the pathname is the same for all locales
3497
+ e.byId[t].pathnamesSlim = d);
3498
+ }
3499
+ }, /**
3500
+ * Flag routes that are children of wildcards, a.k.a. child SPA routes
3501
+ *
3502
+ * NB: It mutates the data
3503
+ */ h$1 = (e)=>{
3504
+ if (e.wildcardIds.length) for(let t in e.byId)e.wildcardIds.some((e)=>t.startsWith(e) && e !== t) && (e.byId[t].inWildcard = !0);
3505
+ }, I = (e, n, r, p)=>{
3506
+ let o = utils.objectFlat(e, r.tokens.idDelimiter);
3507
+ for(let e in o){
3508
+ let t = o[e], // as I18nCompiler.RoutePathname;
3509
+ { routeId: a, isCatchAll: c, isOptionalCatchAll: m } = d$1(e, r);
3510
+ // if (isCatchAll || isOptionalCatchAll) console.log({ routeId, key });
3511
+ // if is the first pass for this routeId
3512
+ if (!p.byId[a]) {
3513
+ p.byId[a] = p.byId[a] || {};
3514
+ let e = s$1(a);
3515
+ p.byId[a].id = a, e && (p.byId[a].params = e), (c || m) && (p.byId[a].wildcard = !0, p.wildcardIds.push(a));
3516
+ }
3517
+ p.byId[a].pathnames = p.byId[a].pathnames || {}, // prettier-ignore
3518
+ p.byId[a].pathnames[n] = i$1(t, r), // prettier-ignore
3519
+ p.byId[a].pathnames = utils.objectSortByKeysMatching(p.byId[a].pathnames, r.defaultLocale), // just copy them for now, the difference treatment happens when resolving
3520
+ // the parent tokens
3521
+ p.byId[a].pathnamesSpa = {
3522
+ ...p.byId[a].pathnames
3523
+ };
3524
+ }
3525
+ // sort by route name
3526
+ p.byId = utils.objectSort(p.byId);
3527
+ };
3528
+ /**
3529
+ * Get routes data
3530
+ */ let getCodeDataRoutes = (e, t, { translationFiles: a })=>{
3531
+ let l = {
3532
+ byId: {},
3533
+ wildcardIds: []
3534
+ }, n = r(e, t);
3535
+ for(let e = 0; e < a.length; e++){
3536
+ let { path: r, locale: d, data: i } = a[e];
3537
+ r === t.translationJsonFileName && I(i, d, n, l);
3538
+ }
3539
+ return(// the order in which these mutations run matters!
3540
+ h$1(l), c(l, n), o$2(l, n), m(l, n), l);
3541
+ }; // /**
3542
+ // * Route id to TypeScript valid type/interface name
3543
+ // *
3544
+ // * @deprecated
3545
+ // */
3546
+ // const routeIdToTypeName = (routeId: string) =>
3547
+ // capitalize(changeCaseCamel(routeId));
3548
+
3549
+ const codeDataTranslationsOptions = {
3550
+ /**
3551
+ * A list of globs to run against source files, those that are matched will be
3552
+ * ignored
3553
+ *
3554
+ * @see https://www.npmjs.com/package/minimatch
3555
+ */ ignorePaths: [],
3556
+ /**
3557
+ * Given a translation value as `"myKey": ["two", "words"]`:
3558
+ * - when `true`: it outputs `t_myKey_0` and `t_myKey_1` functions
3559
+ * - when `false`: if `fnsAsDataCodes` is `true` it outputs `t_myKey` otherwise
3560
+ * it outputs nothing (TODO: maybe we could log this info in this case)
3561
+ *
3562
+ * NB: It is quite unlikely that you want to set this to `true`.
3563
+ *
3564
+ * @default false
3565
+ */ createArrayIndexBasedFns: !1,
3566
+ // TODO: add pluralisation config
3567
+ /**
3568
+ * It creates `t_` functions that returns objects and arrays to use as
3569
+ * data source.
3570
+ *
3571
+ * NB: this greatly increased the generated code, tree shaking will still
3572
+ * apply though.
3573
+ *
3574
+ * @default true
3575
+ */ fnsAsDataCodes: !0,
3576
+ /**
3577
+ * Generated `namespace_tKey()` functions prefix, prepended to the automatically
3578
+ * generated function names.
3579
+ *
3580
+ * @default ""
3581
+ */ fnsPrefix: "",
3582
+ tokens: {
3583
+ /** @default ":" */ namespaceDelimiter: ":",
3584
+ dynamicDelimiters: {
3585
+ /** @default "{{" */ start: "{{",
3586
+ /** @default "}}" */ end: "}}"
3587
+ }
3588
+ }
3589
+ };
3590
+ let g = RegExp(node_path.sep, "g"), /**
3591
+ * Normalise translation key
3592
+ */ v = (e)=>{
3593
+ let t = e.// replace tilde with dollar
3594
+ replace(/~/g, "$").// replace dash with underscore
3595
+ replace(/-/g, "_").replace(g, "_").// collapse consecutive underscores
3596
+ replace(/_+/g, "_").// ensure valid js identifier, allow only alphanumeric characters and few symbols
3597
+ replace(/[^a-zA-Z0-9_$]/gi, "");
3598
+ // ensure the key does not start with a number (invalid js)
3599
+ return /^[0-9]/.test(t) ? "$" + t : t;
3600
+ }, h = (e, t)=>{
3601
+ if (utils.isString(t)) {
3602
+ let { start: r, end: a } = e.tokens.dynamicDelimiters, l = RegExp(`${r}(.*?)${a}`, "gm"), s = t.match(l);
3603
+ if (s) return s.map((e)=>e.replace(r, "").replace(a, "").trim()).reduce((e, t)=>(// TODO: maybe determine the more specific type with some kind of special
3604
+ // token used in the route id `[dynamicParam]` portion
3605
+ e[t] = "stringOrNumber", e), {});
3606
+ }
3607
+ }, /**
3608
+ * This was an experiment to extract params to interpolate from non-flat
3609
+ * translations values, but that does not seem really needed as one
3610
+ * can always use `tInterpolateParams` directly on whatever string
3611
+ *
3612
+ * @deprecated
3613
+ */ // eslint-disable-next-line @typescript-eslint/no-unused-vars
3614
+ y = (e, t, r = {})=>{
3615
+ if (utils.isPrimitive(t)) {
3616
+ let a = h(e, t);
3617
+ return a && (r = {
3618
+ ...r,
3619
+ ...a
3620
+ }), r;
3621
+ }
3622
+ if (utils.isArray(t)) for(let a = 0; a < t.length; a++){
3623
+ let l = h(e, t[a]);
3624
+ l && (r = {
3625
+ ...r,
3626
+ ...l
3627
+ });
3628
+ }
3629
+ else for(let a in t){
3630
+ let l = y(e, t[a], r);
3631
+ l && (r = {
3632
+ ...r,
3633
+ ...l
3634
+ });
3635
+ }
3636
+ return {};
3637
+ }, // const addDataTranslationEntryForObjectValue = (
3638
+ // options: CodeDataTranslationsOptions,
3639
+ // id: string,
3640
+ // locale: I18nCompiler.Locale,
3641
+ // value: Exclude<Extract<I18nCompiler.DataTranslationValue, object>, string[]>,
3642
+ // dataTranslations: I18nCompiler.DataTranslations,
3643
+ // ) => {
3644
+ // // if (hasOnlyPluralKeys(value)) {
3645
+ // // return `'${key}': string;`;
3646
+ // // }
3647
+ // // if (!isArray(value) && isObject(value)) {
3648
+ // // if (hasOnlyPluralKeys(value)) {
3649
+ // // return `'${key}': string;`;
3650
+ // // }
3651
+ // // if (hasPlurals(value)) {
3652
+ // // return `'${key}': string | ${buildTypeForValue(pickNonPluralValue(value))}`;
3653
+ // // }
3654
+ // // }
3655
+ // // return `'${key}': ${buildTypeForValue(value)}`;
3656
+ // };
3657
+ /**
3658
+ * At this point the data translations have been calculated, this happens in a
3659
+ * second pass as we need to know all the translations keys to look for plural
3660
+ * variations.
3661
+ *
3662
+ * NB: we mutate the `dataTranslations`
3663
+ */ _ = (e, t)=>(Object.keys(t).filter(isPluralKey).forEach((r)=>{
3664
+ let a = removePluralSuffix(r), l = getPluralSuffix(r);
3665
+ // we only need to rearrange plurals defined as `x_one`, `x_other`, if plurals
3666
+ // are instead defined as objects `{ one: "", other: "" }` we just keep that
3667
+ // object structure for `values`
3668
+ if (// we need to create it if we only have `x_one` `x_other` but not `x`
3669
+ t[a] = t[a] || {}, t[r]) {
3670
+ let s = t[a].values || {};
3671
+ utils.forin(t[r].values, (r, i)=>{
3672
+ // we need to ensure the value is an object for pluralisation, so if
3673
+ // we encounter this structure:
3674
+ // { "plural": "Plural", "plural_one": "One", "plural_other": "Some" }
3675
+ // we just remove the first `plural` value as that key is instead used
3676
+ // to grab the right pluralised version from the object value we build
3677
+ // from the other plural-suffixed keys. TODO: maybe we could warn the
3678
+ // developer of improper usage of `plural` translation key, which is
3679
+ // simply useless
3680
+ // prettier-ignore
3681
+ s[r] = utils.isObject(s[r]) ? s[r] : {}, // prettier-ignore
3682
+ s[r][l] = i;
3683
+ let n = y(e, i);
3684
+ n && (t[a].params = {
3685
+ ...t[a].params || {},
3686
+ ...n
3687
+ });
3688
+ }), Object.keys(s).length && (t[a].values = s, t[a].plural = !0), // TODO: probaly here we should remove the non-plural keys from `values`
3689
+ // as they are anyway accessible from "deeper" functions e.g.
3690
+ // `withPluralAndOtherKeys({ count: 3 }) => "One" | "Many"`
3691
+ // `withPluralAndOtherKeys_nonPluralKey()` => "Yes"
3692
+ // delete ids that we re-arranged in the plural-ready object value
3693
+ delete t[r];
3694
+ }
3695
+ }), t), /**
3696
+ * Add entry to translations data
3697
+ */ x = (e, t, r, a, l)=>{
3698
+ if (utils.isPrimitive(a)) {
3699
+ l[t] = l[t] || {}, l[t].values = l[t].values || {}, l[t].values[r] = a, l[t].typeValue = "Primitive";
3700
+ let s = h(e, a);
3701
+ s && (l[t].params = s);
3702
+ } else {
3703
+ if (e.fnsAsDataCodes) {
3704
+ let e = utils.isArray(a) ? "Array" : "Object";
3705
+ l[t] = l[t] || {}, l[t].values = l[t].values || {}, l[t].values[r] = a, l[t].typeValue = e;
3706
+ }
3707
+ // @see comment on `extractTranslationParamsFromValue`
3708
+ // const params = extractTranslationParamsFromValue(options, value);
3709
+ // if (params) dataTranslations[id].params = params;
3710
+ if (utils.isArray(a)) {
3711
+ if (e.createArrayIndexBasedFns) for(let s = 0; s < a.length; s++)x(e, t + "_" + s, r, a[s], l);
3712
+ } else for(let s in a)x(e, t + "_" + v(s), r, a[s], l);
3713
+ }
3714
+ return l;
3715
+ }, /**
3716
+ * Get translation data recursively starting from a specific file
3717
+ */ D = (l, s, i)=>{
3718
+ let { locale: n, path: o } = s, p = node_path.join(node_path.dirname(o), node_path.basename(o, node_path.extname(o)));
3719
+ for(let e in s.data){
3720
+ let t = s.data[e];
3721
+ x(l, v(p + (e ? "_" + e : "")), n, t, i);
3722
+ }
3723
+ return i;
3724
+ };
3725
+ /**
3726
+ * Get translations data
3727
+ */ let getCodeDataTranslations = (e, t, { translationFiles: r })=>{
3728
+ let { ignorePaths: a } = t, l = {};
3729
+ for(let e = 0; e < r.length; e++)(!a || a && a.every((t)=>!minimatch.minimatch(r[e].path, t))) && D(t, r[e], l);
3730
+ // console.log("generateTypes: outputDir", outputDir, "outputPath", outputPath);
3731
+ return(// sort
3732
+ utils.objectSort(l = _(t, l)));
3733
+ };
3734
+
3735
+ let l$2 = {
3736
+ adapter: {
3737
+ name: "js",
3738
+ options: adapterJsOptions
3739
+ },
3740
+ outputFiles: {},
3741
+ routes: codeDataRoutesOptions,
3742
+ translations: codeDataTranslationsOptions
3743
+ };
3744
+ // TODO: make this works with generics based on chosen adapter?
3745
+ // defaultLocale: string;
3746
+ // index: string;
3747
+ // isLocale: string;
3748
+ // locales: string;
3749
+ // routes: string;
3750
+ // routesSlim: string;
3751
+ // to: string;
3752
+ // toFns: string;
3753
+ // toFormat: string;
3754
+ // types: string;
3755
+ let getCodeData = (o, a, r)=>{
3756
+ let n = utils.objectMergeWithDefaults(l$2, a);
3757
+ return n.translations.ignorePaths.push(n.routes.translationJsonFileName), // order locales
3758
+ r = {
3759
+ ...r,
3760
+ localesFolders: r.localesFolders.sort((t, a)=>o.defaultLocale ? -1 : t.localeCompare(a))
3761
+ }, {
3762
+ config: o,
3763
+ // TODO: types, remove this assertion
3764
+ options: n,
3765
+ input: r,
3766
+ routes: getCodeDataRoutes(o, n.routes, r),
3767
+ translations: getCodeDataTranslations(o, n.translations, r)
3768
+ };
3769
+ };
3770
+
3771
+ /**
3772
+ * Used to generate SEO optimized alternate URLs
3773
+ *
3774
+ * NB: It will be normalised and trailing slash stripped out in order to ease
3775
+ * and make consistent a simple concatenation with relative URLs.
3776
+ */ /**
3777
+ * Whether we have only a single locale.
3778
+ *
3779
+ * @computed
3780
+ */ const configDefaults = {
3781
+ baseUrl: "https://example.com",
3782
+ locales: [
3783
+ "en"
3784
+ ],
3785
+ defaultLocale: "en",
3786
+ hideDefaultLocaleInUrl: !0,
3787
+ trailingSlash: !1,
3788
+ single: !0
3789
+ };
3790
+ /**
3791
+ * Get basic i18n compiler config with defaults and automatic inference from
3792
+ * input data
3793
+ */ let getConfig = (a, o)=>{
3794
+ o && (o.baseUrl = utils.normaliseUrl(o.baseUrl), // dynamically define locales
3795
+ o.locales = o.locales || a.localesFolders, // ensure defaultLocale
3796
+ o.defaultLocale = o.defaultLocale || o.locales?.[0], // ensure boolean value
3797
+ o.hideDefaultLocaleInUrl = !!o.hideDefaultLocaleInUrl);
3798
+ let t = utils.objectMergeWithDefaults(configDefaults, o);
3799
+ return(// ensure sorted locales
3800
+ t.locales = t.locales.sort((l, e)=>t.defaultLocale ? -1 : l.localeCompare(e)), // compute single
3801
+ t.single = 1 === t.locales.length, t);
3802
+ };
3803
+
3804
+ /**
3805
+ * @default process.cwd()
3806
+ */ /**
3807
+ * @default undefined
3808
+ */ let n$1 = (e, r)=>{
3809
+ let { cwd: n = process.cwd(), output: i, pretty: o } = e;
3810
+ return [
3811
+ node_path.join(n, i),
3812
+ o ? JSON.stringify(r, null, 2) : JSON.stringify(r)
3813
+ ];
3814
+ };
3815
+ let writeInput = async (t, r)=>{
3816
+ await node.fsWrite(...n$1(t, r));
3817
+ };
3818
+
3819
+ let l$1 = (e)=>{
3820
+ let { cwd: t, ignore: a } = e;
3821
+ return glob.glob.sync("*", {
3822
+ cwd: t,
3823
+ withFileTypes: !0,
3824
+ ignore: [
3825
+ ...a,
3826
+ "node_modules/**"
3827
+ ]
3828
+ }).// onlyDirectories: true,
3829
+ // @see defaults https://www.npmjs.com/package/glob#dots
3830
+ // dot: false,
3831
+ filter((e)=>e.isDirectory()).map((e)=>e.relative()).sort((e, t)=>e.localeCompare(t));
3832
+ };
3833
+ let getInputDataLocal = async (e)=>{
3834
+ let { cwd: r = process.cwd(), ignore: s = [], source: p } = e, i = node_path.join(r, p), c = l$1({
3835
+ cwd: i,
3836
+ ignore: s
3837
+ }), n = [];
3838
+ return await Promise.all(c.map(async (r)=>{
3839
+ let l = await glob.glob("**/*.json", {
3840
+ cwd: node_path.join(i, r),
3841
+ ignore: e.ignore
3842
+ });
3843
+ await Promise.all(l.map(async (e)=>{
3844
+ let o = node_path.join(i, r, e), l = await promises.readFile(o, "utf8");
3845
+ l && n.push({
3846
+ path: e,
3847
+ data: JSON.parse(l),
3848
+ locale: r
3849
+ });
3850
+ }));
3851
+ })), {
3852
+ localesFolders: c,
3853
+ translationFiles: n
3854
+ };
3855
+ };
3856
+
3857
+ /**
3858
+ * Our github action `knitkode/koine/actions/i18n` creates a JSON file we can
3859
+ * read here, github serves it as text
3860
+ */ let getInputDataRemote = async (r)=>new Promise((l, o)=>{
3861
+ let { ignore: a = [], source: s } = r, n = s.startsWith(// import requestSync from "sync-request-curl";
3862
+ "https://raw.githubusercontent.com"), i = "", c = node_https.request(s, n ? {} : {
3863
+ headers: {
3864
+ Accept: "application/json"
3865
+ }
3866
+ }, (e)=>{
3867
+ e.setEncoding("utf8"), e.on("data", (e)=>{
3868
+ i += e;
3869
+ }), e.on("end", ()=>{
3870
+ try {
3871
+ let e = n ? JSON.parse(i) : i;
3872
+ l({
3873
+ ...e,
3874
+ localesFolders: a.length ? e.localesFolders.filter((e)=>a.every((r)=>!minimatch.minimatch(e, r))) : e.localesFolders,
3875
+ translationFiles: a.length ? e.translationFiles.filter((e)=>a.every((r)=>!minimatch.minimatch(e.path, r))) : e.translationFiles
3876
+ });
3877
+ } catch (e) {
3878
+ throw Error(`Failed to parse JSON from ${s}`);
3879
+ }
3880
+ });
3881
+ });
3882
+ c.on("error", (e)=>{
3883
+ console.error(e), o("");
3884
+ }), c.end();
3885
+ });
3886
+
3887
+ let getInputData = async (e)=>{
3888
+ let { source: o } = e;
3889
+ return utils$1.isAbsoluteUrl(o) ? await getInputDataRemote(e) : await getInputDataLocal(e);
3890
+ };
3891
+
3892
+ let o$1 = (e, t = {})=>{
3893
+ let r = "";
3894
+ if (e && "string" == typeof e) r += " " + e.trim();
3895
+ else if (Array.isArray(e)) for(let l = 0; l < e.length; l++)r += o$1(e[l], t);
3896
+ else if ("object" == typeof e) for(let l in e)r += o$1(e[l], t);
3897
+ return r;
3898
+ }, s = (e, t)=>{
3899
+ let { locale: r, path: l } = t, s = `${e}/${r}/${l}`, a = o$1(t.data), i = a.split(" ").filter(Boolean).length;
3900
+ return {
3901
+ characters: a.split(" ").filter(Boolean).join("").length,
3902
+ locale: r,
3903
+ path: l,
3904
+ url: s,
3905
+ words: i
3906
+ };
3907
+ };
3908
+ const summaryDataOptions = {};
3909
+ /**
3910
+ * Usually this is an absolute URL where to view the translation file
3911
+ */ let getSummaryData = (o, a, { translationFiles: i })=>{
3912
+ let { defaultLocale: f } = o, n = {};
3913
+ for(let e = 0; e < i.length; e++){
3914
+ let t = i[e], { locale: r } = t, l = s(a.sourceUrl, t);
3915
+ n[r] = n[r] || {}, n[r].files = n[r].files || [], n[r].files.push(l);
3916
+ }
3917
+ return utils.forin(// sort by default locale
3918
+ n = utils.objectSortByKeysMatching(n, f), (t, l)=>{
3919
+ n[t].characters = utils.arraySum(l.files.map((e)=>e.characters)), // sort files by path
3920
+ n[t].files = n[t].files.sort((e, t)=>e.path.localeCompare(t.path)), n[t].words = utils.arraySum(l.files.map((e)=>e.words)), // sort object keys
3921
+ n[t] = utils.objectSort(n[t]);
3922
+ }), n;
3923
+ };
3924
+
3925
+ let l = (e)=>{
3926
+ let h = {};
3927
+ return utils.forin(e, (t, e)=>{
3928
+ let { files: r } = e;
3929
+ for(let e = 0; e < r.length; e++){
3930
+ let l = r[e], { path: d } = l;
3931
+ h[d] = h[d] || {}, h[d][t] = l;
3932
+ }
3933
+ }), h = utils.objectSort(h);
3934
+ }, d = (e)=>{
3935
+ let r = l(e), h = "", d = "", a = [], o = 'style="border-right:1px solid grey"';
3936
+ return utils.forin(r, (e, r)=>{
3937
+ d += `<tr><td ${o}>${e}</td>`, utils.forin(r, (t, e)=>{
3938
+ let { characters: r, words: h, url: l } = e;
3939
+ a.includes(t) || a.push(t), d += `<td><a href="${l}">${t}</a></td><td>${h}</td><td ${o}>${r}</td>`;
3940
+ }), d += "</tr>";
3941
+ }), h += `<table><thead><tr><th ${o}>file path</th>` + a.map(()=>`<th>lang</th><th>words</th><th ${o}>chars</th>`).join("") + `</tr></thead><tbody>${d}</tbody></table>\n`;
3942
+ }, a = (e, r)=>{
3943
+ let h = "", l = "";
3944
+ return utils.forin(e, (t, e)=>{
3945
+ let { files: h, characters: d, words: a } = e, o = `${r.sourceUrl}/${t}`;
3946
+ l += `<tr><th><a href="${o}">${t}</a></th><td>${h.length}</td><td>${a}</td><td>${d}</td></tr>`;
3947
+ }), h += `<table><thead><tr><th>locale</th><th>files</th><th>words</th><th>chars</th></tr></thead><tbody>${l}</tbody></table>\n`;
3948
+ }, o = (t, e)=>"# Summary\n" + ("\n### By locale\n\n" + a(t, e) + "\n### By file path\n\n") + d(t);
3949
+ let generateSummary = (t, r)=>o(t, utils.objectMergeWithDefaults(summaryDataOptions, r));
3950
+
3951
+ /**
3952
+ * @default process.cwd()
3953
+ */ /**
3954
+ * Relative to the given `cwd`.
3955
+ */ /**
3956
+ * Relative to the given `cwd`.
3957
+ */ /**
3958
+ * @default undefined
3959
+ */ let i = (t, e, o, i)=>[
3960
+ node_path.join(o, i),
3961
+ t.pretty ? JSON.stringify(e, null, 2) : JSON.stringify(e)
3962
+ ], n = (t, e, i, n)=>[
3963
+ node_path.join(i, n),
3964
+ generateSummary(e, t)
3965
+ ];
3966
+ let writeSummary = async (r, e)=>{
3967
+ let { cwd: o = process.cwd(), outputJson: m, outputMarkdown: a, ...p } = r;
3968
+ return m && await node.fsWrite(...i(r, e, o, m)), a && await node.fsWrite(...n(p, e, o, a)), e;
3969
+ };
3970
+
3971
+ /**
3972
+ * i18nCompiler async api
3973
+ *
3974
+ * @public
3975
+ */ let i18nCompiler = async (a)=>{
3976
+ let { input: u, code: w, summary: s, ...n } = a, f = [], l = await getInputData(u), c = getConfig(l, n), // it would be easy to make this optional but it's nice to be able to always
3977
+ // predictably return data
3978
+ h = getCodeData(c, w, l);
3979
+ return u?.write && f.push(writeInput(u.write, l)), w?.write && f.push(writeCode({
3980
+ ...w,
3981
+ ...w.write
3982
+ }, h)), s?.write && f.push(writeSummary({
3983
+ ...s,
3984
+ ...s.write
3985
+ }, getSummaryData(c, s, l))), await Promise.all(f), {
3986
+ config: c,
3987
+ input: l,
3988
+ code: h
3989
+ };
3990
+ }; // /**
3991
+ // * i18nCompiler sync api
3992
+ // *
3993
+ // * @public
3994
+ // */
3995
+ // export let i18nCompilerSync = (options: I18nCompilerOptions) => {
3996
+ // const {
3997
+ // input: optsInput,
3998
+ // code: optsCode,
3999
+ // summary: optsSummary,
4000
+ // ...configOptions
4001
+ // } = options;
4002
+ // const input = getInputDataSync(optsInput);
4003
+ // const config = getConfig(input, configOptions);
4004
+ // // it would be easy to make this optional but it's nice to be able to always
4005
+ // // predictably return data
4006
+ // const code = getCodeData(config, optsCode, input);
4007
+ // if (optsInput?.write) {
4008
+ // writeInputSync(optsInput.write, input);
4009
+ // }
4010
+ // if (optsCode?.write) {
4011
+ // writeCodeSync({ ...optsCode, ...optsCode.write }, code);
4012
+ // }
4013
+ // if (optsSummary?.write) {
4014
+ // writeSummarySync(
4015
+ // { ...optsSummary, ...optsSummary.write },
4016
+ // getSummaryData(config, optsSummary, input),
4017
+ // );
4018
+ // }
4019
+ // return { config, input, code };
4020
+ // };
4021
+
4022
+ exports.generateRedirectForPathname = generateRedirectForPathname;
4023
+ exports.generateRedirects = generateRedirects;
4024
+ exports.generateRewriteForPathname = generateRewriteForPathname;
4025
+ exports.generateRewrites = generateRewrites;
4026
+ exports.i18nCompiler = i18nCompiler;