@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/next.esm.js ADDED
@@ -0,0 +1,329 @@
1
+ import { objectMergeWithDefaults, arrayUniqueByProperties } from '@koine/utils';
2
+ import { g as generateRedirectForPathname, a as generateRewriteForPathname, b as generateRedirects, c as generateRewrites, i as i18nCompiler } from './api.esm.js';
3
+ import { ContextReplacementPlugin } from 'webpack';
4
+ import { createRequire } from 'node:module';
5
+ import { i18nCompilerSync } from './compiler-sync.esm.js';
6
+ import 'next/dist/shared/lib/utils';
7
+ import 'node:fs';
8
+ import 'node:fs/promises';
9
+ import 'node:path';
10
+ import 'glob';
11
+ import 'node:https';
12
+ import 'minimatch';
13
+ import './formatRoutePathname.esm.js';
14
+ import '@koine/node';
15
+ import 'typescript';
16
+ import 'synckit';
17
+
18
+ // & { _branded: true };
19
+ function r(e, t) {
20
+ let { [t]: n, ...l } = e;
21
+ return {
22
+ [t]: n,
23
+ ...l
24
+ };
25
+ }
26
+ /**
27
+ * Transform the route translated defintion into a `pathname` and a `template`.
28
+ *
29
+ * Here we add the wildcard flag maybe found in the pathname to the template
30
+ * name too, this is because we do not want to have the wildcard in the JSON
31
+ * keys as those are also used to produce links through the `useTo` hook and
32
+ * having asterisks there is a bit cumbersome.
33
+ *
34
+ * @see https://nextjs.org/docs/messages/invalid-multi-match
35
+ */ function i(e) {
36
+ let { pathname: t, template: n } = e, l = t.split("/").filter((e)=>!!e), r = n.split("/").filter((e)=>!!e), i = {};
37
+ return {
38
+ pathname: "/" + l.map((e)=>{
39
+ let t = e.endsWith("*"), n = (e = e.replace("*", "")).startsWith("{{") && e.endsWith("}}"), l = n ? e.match(/{{(.+)}}/)?.[1].trim() ?? "" : e.trim(), r = encodeURIComponent(l) + (t ? "*" : "");
40
+ return i[l] = {
41
+ isDynamic: n,
42
+ hasWildcard: t
43
+ }, n ? `:${r}` : r;
44
+ }).join("/"),
45
+ template: "/" + r.map((e)=>{
46
+ let t = e.startsWith("[") && e.endsWith("]"), n = t ? e.match(/\[(.+)\]/)?.[1].trim() ?? "" : e.trim(), l = i[n]?.hasWildcard, r = encodeURIComponent(n) + (l ? "*" : "");
47
+ return t ? `:${r}` : r;
48
+ }).join("/")
49
+ };
50
+ }
51
+ /**
52
+ * Get routes map dictionary
53
+ */ function a(e = {}, t, n = "", l = "") {
54
+ let r = Object.keys(t).includes("[spa]");
55
+ for(let i in t){
56
+ let o = t[i], s = `${l}/${i}`;
57
+ "string" == typeof o ? (!r || r && [
58
+ "[spa]",
59
+ "index"
60
+ ].includes(i)) && (e[s] = {
61
+ template: s,
62
+ pathname: o,
63
+ wildcard: o.includes("*")
64
+ }) : r || a(e, o, n, s);
65
+ }
66
+ return e;
67
+ }
68
+ /**
69
+ * Removes `/index` from a template/url path
70
+ */ function o(e) {
71
+ return e.replace(/\/index$/, "");
72
+ }
73
+ /**
74
+ * Shared options to generate Next.js `rewrites` and `redirects`
75
+ */ /**
76
+ * A JSON file containing the routes definition mapping template folders
77
+ * to localised slugs. It supports slugs's dynamic portions.
78
+ * All translated slugs needs to be defined starting from root `/`.
79
+ * The `require("...json")` file for each locale should look like:
80
+ *
81
+ * ```json
82
+ * {
83
+ * "home": "/",
84
+ * "products": {
85
+ * "list": "/products",
86
+ * "[category]": "/products/{{ category }}",
87
+ * "[tag]": {
88
+ * "view": "/products/{{ category }}/{{ tag }}",
89
+ * "related": "/products/{{ category }}/{{ tag }}/related"
90
+ * }
91
+ * },
92
+ * "company": {
93
+ * "about": "/about",
94
+ * "contact": "/contact"
95
+ * }
96
+ * }
97
+ * ```
98
+ *
99
+ * Here we also account for wildcards, those should only be defined in the
100
+ * pathname part of the JSON file, e.g.:
101
+ *
102
+ * ```json
103
+ * {
104
+ * "category": {
105
+ * "[slug]": {
106
+ * "[id]": "/categories/{{ slug }}/{{ id }}*"
107
+ * }
108
+ * }
109
+ * }
110
+ * ```
111
+ * This might be desired when we want to have param-based pagination, e.g. when
112
+ * we have the following folder structure:
113
+ *
114
+ * ```yml
115
+ * |__/category
116
+ * |__/[slug]
117
+ * |__/[id]
118
+ * |__/[[...page]].tsx
119
+ * ```
120
+ *
121
+ * NB:
122
+ * When `routes` is used be sure to pass before than the `i18n.defaultLocale`
123
+ * configuration. That is used for localised routing.
124
+ */ /**
125
+ * @deprecated Better use the new `withI18n`
126
+ */ let withI18nLegacy = (s)=>{
127
+ let { i18nRoutes: c, ...f } = s;
128
+ if (!c) return f;
129
+ // set i18n related defaults grabbing them from basic next config i18n object
130
+ let { locales: u, defaultLocale: d } = f.i18n || {}, m = objectMergeWithDefaults({
131
+ locales: u || [
132
+ "en"
133
+ ],
134
+ defaultLocale: d || "en",
135
+ hideDefaultLocaleInUrl: !0,
136
+ localeParam: ""
137
+ }, c), { localeParam: p, locales: h, defaultLocale: y, routes: g } = m, b = {
138
+ ...f
139
+ };
140
+ if (p ? // NOTE: passing the i18n settings with the app router messes up everything
141
+ // especially while migrating from pages to app router, so opt out from that
142
+ // and only rely on our i18n implementation
143
+ delete b.i18n : (f.i18n = f.i18n || {
144
+ locales: h,
145
+ defaultLocale: y
146
+ }, f.i18n.defaultLocale = y, f.i18n.locales = h), g) {
147
+ let { redirects: t, rewrites: s } = b;
148
+ b.redirects = async ()=>{
149
+ let l = function(t) {
150
+ let { routes: l, defaultLocale: s, hideDefaultLocaleInUrl: c, trailingSlash: f, localeParamName: u, permanentRedirects: d, debug: m } = t, p = {
151
+ defaultLocale: s,
152
+ hideDefaultLocaleInUrl: c,
153
+ trailingSlash: f,
154
+ localeParamName: u,
155
+ permanentRedirects: d
156
+ }, h = r(l, s), y = [];
157
+ for(let e in h){
158
+ let t = a({}, l[e]);
159
+ for(let l in t){
160
+ let { template: r, pathname: a } = i(t[l]);
161
+ a !== o(r) && generateRedirectForPathname(p, e, o(r), o(a), y);
162
+ }
163
+ }
164
+ let g = arrayUniqueByProperties(y.filter(Boolean), [
165
+ "source",
166
+ "destination"
167
+ ]).map((e)=>u ? e : {
168
+ ...e,
169
+ locale: !1
170
+ });
171
+ return m && console.info("[@koine/next/plugin-legacy:generateRedirects]", g), g;
172
+ }(m);
173
+ return t ? [
174
+ ...l,
175
+ ...await t()
176
+ ] : l;
177
+ }, b.rewrites = async ()=>{
178
+ let t = function(t) {
179
+ let { routes: n, defaultLocale: s, hideDefaultLocaleInUrl: c, trailingSlash: f, localeParamName: u, debug: d } = t, m = {
180
+ defaultLocale: s,
181
+ hideDefaultLocaleInUrl: c,
182
+ trailingSlash: f,
183
+ localeParamName: u
184
+ }, p = r(n, s), h = [];
185
+ for(let e in p){
186
+ let t = a({}, n[e]);
187
+ for(let n in t){
188
+ let { template: r, pathname: a } = i(t[n]);
189
+ generateRewriteForPathname(m, e, o(r), o(a), h);
190
+ }
191
+ }
192
+ let y = arrayUniqueByProperties(h.filter(Boolean), [
193
+ "source",
194
+ "destination"
195
+ ]);
196
+ return d && console.info("[@koine/next/plugin-legacy:generateRewrites]", y), y;
197
+ }(m);
198
+ if (s) {
199
+ let e = await s();
200
+ return Array.isArray(e) ? {
201
+ beforeFiles: t,
202
+ afterFiles: e,
203
+ fallback: []
204
+ } : {
205
+ ...e,
206
+ beforeFiles: [
207
+ ...t,
208
+ ...e.beforeFiles || []
209
+ ]
210
+ };
211
+ }
212
+ return {
213
+ beforeFiles: t,
214
+ afterFiles: [],
215
+ fallback: []
216
+ };
217
+ };
218
+ }
219
+ return b;
220
+ };
221
+
222
+ let tweakNextConfig = (t, r)=>{
223
+ let { config: { defaultLocale: o, locales: i }, code: { options: { routes: { localeParamName: s } } } } = t;
224
+ return s ? // NOTE: passing the i18n settings with the app router messes up everything
225
+ // especially while migrating from pages to app router, so opt out from that
226
+ // and only rely on our i18n implementation
227
+ delete r.i18n : (r.i18n = r.i18n || {
228
+ locales: i,
229
+ defaultLocale: o
230
+ }, r.i18n.locales = i, r.i18n.defaultLocale = o), r.webpack = (t)=>(// @see https://github.com/date-fns/date-fns/blob/main/docs/webpack.md#removing-unused-languages-from-dynamic-import
231
+ t.plugins.push(new ContextReplacementPlugin(/^date-fns[/\\]locale$/, RegExp(`\\.[/\\\\](${i.join("|")})[/\\\\]index\\.js$`))), t), r;
232
+ };
233
+ let getRedirects = async (e, r)=>{
234
+ let o = generateRedirects(r.config, r.code.options.routes, r.code.routes.byId);
235
+ return e ? [
236
+ ...o,
237
+ ...await e()
238
+ ] : o;
239
+ };
240
+ let getRewrites = async (e, t)=>{
241
+ let o = generateRewrites(t.config, t.code.options.routes, t.code.routes.byId);
242
+ if (e) {
243
+ let t = await e();
244
+ return Array.isArray(t) ? {
245
+ beforeFiles: o,
246
+ afterFiles: t,
247
+ fallback: []
248
+ } : {
249
+ ...t,
250
+ beforeFiles: [
251
+ ...o,
252
+ ...t.beforeFiles || []
253
+ ]
254
+ };
255
+ }
256
+ return {
257
+ beforeFiles: o,
258
+ afterFiles: [],
259
+ fallback: []
260
+ };
261
+ };
262
+
263
+ /**
264
+ * See [`withNx`](https://github.com/nrwl/nx/blob/master/packages/next/plugins/with-nx.ts#L216)
265
+ * next plugin for inspiration on how to structure our async compiler task
266
+ *
267
+ * About next.config phases see https://github.com/vercel/next.js/discussions/48736
268
+ */ let withI18nAsync = (n = {})=>async ()=>/* phase: string */ {
269
+ let { i18nCompiler: a, redirects: o, rewrites: l, ...p } = n, s = p;
270
+ // const { PHASE_PRODUCTION_BUILD, PHASE_DEVELOPMENT_SERVER } = await import(
271
+ // "next/constants"
272
+ // );
273
+ // // bail if we are not building or running the dev server
274
+ // if (![PHASE_PRODUCTION_BUILD, PHASE_DEVELOPMENT_SERVER].includes(phase)) {
275
+ // return nextConfig;
276
+ // }
277
+ // bail if user has not defined the compiler options object
278
+ if (!a) return s;
279
+ let m = await i18nCompiler(a);
280
+ (s = tweakNextConfig(m, s)).redirects = ()=>getRedirects(o, m), s.rewrites = ()=>getRewrites(l, m);
281
+ let { code: { options: { adapter: c } } } = m;
282
+ if ("next-translate" === c.name && // const options = i18nConfig.code.adapter.options;
283
+ !1 !== c.options.loader) try {
284
+ s = (await import('next-translate-plugin').then((t)=>t.default))(s);
285
+ } // TODO: verify this:
286
+ // when using the locale param name structure just force to opt-out from
287
+ // next.js built in i18n support for pages router, this should also
288
+ // ease the cohexistence of pages and app router
289
+ // if (i18nResult.code.options.routes.localeParamName) {
290
+ // delete nextConfig.i18n;
291
+ // }
292
+ catch (t) {}
293
+ // console.log()
294
+ return s;
295
+ };
296
+
297
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
298
+ // @ts-ignore problem with cjs output
299
+ let l = createRequire(import.meta.url);
300
+ let withI18n = (e = {})=>{
301
+ let { i18nCompiler: n, redirects: m, rewrites: a, ...p } = e, s = p;
302
+ // bail if user has not defined the compiler options object
303
+ if (!n) return s;
304
+ let c = i18nCompilerSync(n);
305
+ (s = tweakNextConfig(c, s)).redirects = ()=>getRedirects(m, c), s.rewrites = ()=>getRewrites(a, c);
306
+ let { code: { options: { adapter: d } } } = c;
307
+ if ("next-translate" === d.name && !1 !== d.options.loader) try {
308
+ s = l("next-translate-plugin")(s), // TODO: verify this:
309
+ // when using the locale param name structure just force to opt-out from
310
+ // next.js built in i18n support for pages router, this should also
311
+ // ease the cohexistence of pages and app router
312
+ c.code.options.routes.localeParamName && delete s.i18n;
313
+ } catch (e) {}
314
+ // console.log()
315
+ return s;
316
+ }; // import { I18nWebpackPlugin } from "./webpackPluginI18n";
317
+ // TODO: move to next-translate adapter?
318
+ // return withTranslate(newNextConfig);
319
+ // nextConfig.webpack = (webpackConfig) => {
320
+ // // nextConfig.webpack = (_config, options) => {
321
+ // // const webpackConfig =
322
+ // // typeof nextConfig.webpack === "function"
323
+ // // ? nextConfig.webpack(_config, options)
324
+ // // : _config;
325
+ // webpackConfig.plugins.push(new I18nWebpackPlugin(config));
326
+ // return webpackConfig;
327
+ // };
328
+
329
+ export { withI18n, withI18nAsync, withI18nLegacy };
package/package.json ADDED
@@ -0,0 +1,62 @@
1
+ {
2
+ "name": "@koine/i18n",
3
+ "sideEffects": false,
4
+ "dependencies": {
5
+ "@koine/node": "2.0.0-beta.100",
6
+ "@koine/utils": "2.0.0-beta.100",
7
+ "glob": "^10.3.10",
8
+ "webpack": "^5.90.1",
9
+ "minimatch": "^9.0.3",
10
+ "synckit": "^0.9.0",
11
+ "typescript": "^5.3.3"
12
+ },
13
+ "peerDependencies": {
14
+ "next": "^14.0.4",
15
+ "next-translate-plugin": "^2.6.2"
16
+ },
17
+ "peerDependenciesMeta": {
18
+ "next": {
19
+ "optional": true
20
+ },
21
+ "next-translate": {
22
+ "optional": true
23
+ },
24
+ "next-translate-plugin": {
25
+ "optional": true
26
+ },
27
+ "react": {
28
+ "optional": true
29
+ }
30
+ },
31
+ "exports": {
32
+ "./package.json": "./package.json",
33
+ ".": {
34
+ "module": "./index.esm.js",
35
+ "import": "./index.cjs.mjs",
36
+ "default": "./index.cjs.js"
37
+ },
38
+ "./compiler": {
39
+ "module": "./compiler.esm.js",
40
+ "import": "./compiler.cjs.mjs",
41
+ "default": "./compiler.cjs.js"
42
+ },
43
+ "./compiler-sync": {
44
+ "module": "./compiler-sync.esm.js",
45
+ "import": "./compiler-sync.cjs.mjs",
46
+ "default": "./compiler-sync.cjs.js"
47
+ },
48
+ "./compiler-worker": {
49
+ "module": "./compiler-worker.esm.js",
50
+ "import": "./compiler-worker.cjs.mjs",
51
+ "default": "./compiler-worker.cjs.js"
52
+ },
53
+ "./next": {
54
+ "module": "./next.esm.js",
55
+ "import": "./next.cjs.mjs",
56
+ "default": "./next.cjs.js"
57
+ }
58
+ },
59
+ "module": "./index.esm.js",
60
+ "main": "./index.cjs.js",
61
+ "version": "2.0.0-beta.100"
62
+ }
package/types.d.ts ADDED
@@ -0,0 +1,48 @@
1
+ import type { JsonObject, Split } from "@koine/utils";
2
+ export declare namespace I18nUtils {
3
+ export type Join<A, Sep extends string = "", R extends string = ""> = A extends [infer First, ...infer Rest] ? Join<Rest, Sep, R extends "" ? `${First & string}` : `${R}${Sep}${First & string}`> : R;
4
+ export type BuildRecursiveJoin<TList, TSeparator extends string> = Exclude<TList extends [...infer ButLast, unknown] ? Join<ButLast, TSeparator> | BuildRecursiveJoin<ButLast, TSeparator> : never, "">;
5
+ type JoinObjectPath<S1, S2> = S1 extends string ? S2 extends string ? `${S1}.${S2}` : S1 : never;
6
+ type GetWithPath<BaseType, Keys extends readonly string[]> = Keys extends [] ? BaseType : Keys extends readonly [infer Head, ...infer Tail] ? GetWithPath<Head extends keyof BaseType ? BaseType[Head] : unknown, Extract<Tail, string[]>> : never;
7
+ export type Get<BaseType, Path extends string | readonly string[]> = GetWithPath<BaseType, Path extends string ? Split<Path, "."> : Path>;
8
+ export type Paths<T, TAsObj extends boolean = true> = {
9
+ [K in Extract<keyof T, string>]: T[K] extends Record<string, never> | never[] | "" ? never : T[K] extends Record<string, unknown> ? (TAsObj extends true ? `${K}` : never) | JoinObjectPath<K, Paths<T[K], TAsObj>> : T[K] extends string | number | boolean | Array<string | number | boolean | object> ? `${K}` : never;
10
+ }[Extract<keyof T, string>] extends infer O ? O : never;
11
+ export type AllPaths<TDictionary extends JsonObject> = {
12
+ [N in Extract<keyof TDictionary, string>]: {
13
+ [K in Extract<keyof TDictionary[N], string>]: TDictionary[N][K] extends Record<string, never> | never[] | "" ? never : TDictionary[N][K] extends Record<string, unknown> ? `${N}:${K}` | JoinObjectPath<K extends string ? `${N}:${K}` : `${N}:`, Paths<TDictionary[N][K]>> : TDictionary[N][K] extends string | number | boolean | Array<string | number | boolean | object> ? `${N}:${K}` : never;
14
+ }[Extract<keyof TDictionary[N], string>];
15
+ }[Extract<keyof TDictionary, string>] extends infer O ? O : never;
16
+ type Whitespace = `\u{20}`;
17
+ type TrimLeft<V extends string> = V extends `${Whitespace}${infer R}` ? TrimLeft<R> : V;
18
+ type TrimRight<V extends string> = V extends `${infer R}${Whitespace}` ? TrimRight<R> : V;
19
+ type Trim<V extends string> = TrimLeft<TrimRight<V>>;
20
+ type WithDynamicPortion<F extends string, D extends GenericDelimiters> = `${string}${F}${D["start"]}${string}${D["end"]}${F}${string}` | `${string}${F}${D["start"]}${string}${D["end"]}` | `${D["start"]}${string}${D["end"]}${F}${string}` | `${D["start"]}${string}${D["end"]}`;
21
+ type FilterOnlyStaticRouteId<T extends string, F extends string, D extends GenericDelimiters> = T extends WithDynamicPortion<F, D> ? never : T;
22
+ type FilterOnlyDynamicRouteId<T extends string, F extends string, D extends GenericDelimiters> = T extends WithDynamicPortion<F, D> ? T : never;
23
+ type InferredSeparator<T extends string> = T extends `${string}.${string}` ? "." : T extends `${string}/${string}` ? "/" : never;
24
+ type GenericDelimiters = {
25
+ start: string;
26
+ end: string;
27
+ };
28
+ type WithDelimitedString<Start extends string, End extends string> = `${string}${Start}${string}${End}${string}` | `${string}${Start}${string}${End}` | `${Start}${string}${End}${string}` | `${Start}${string}${End}`;
29
+ type InferredDelimiters<T extends string> = T extends WithDelimitedString<"[", "]"> ? {
30
+ start: "[";
31
+ end: "]";
32
+ } : T extends WithDelimitedString<"{{", "}}"> ? {
33
+ start: "{{";
34
+ end: "}}";
35
+ } : T extends WithDelimitedString<"{", "}"> ? {
36
+ start: "{";
37
+ end: "}";
38
+ } : never;
39
+ export type DynamicParams<T extends string, Separator extends string = InferredSeparator<T>, Delimiters extends GenericDelimiters = InferredDelimiters<T>> = string extends T ? Record<string, string> : T extends `${string}${Delimiters["start"]}${infer Param}${Delimiters["end"]}${Separator}${infer Rest}` ? {
40
+ [k in Trim<Param> | keyof DynamicParams<Rest>]: string | number;
41
+ } : T extends `${string}${Delimiters["start"]}${infer Param}${Delimiters["end"]}` ? {
42
+ [k in Trim<Param>]: string | number;
43
+ } : {};
44
+ export type RouteStrictIdStatic<T extends string> = FilterOnlyStaticRouteId<T, InferredSeparator<T>, InferredDelimiters<T>>;
45
+ export type RouteStrictIdDynamic<T extends string> = FilterOnlyDynamicRouteId<T, InferredSeparator<T>, InferredDelimiters<T>>;
46
+ export type RouteStrictId<T extends string> = RouteStrictIdStatic<T> | RouteStrictIdDynamic<T>;
47
+ export {};
48
+ }