@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.
- package/README.md +1 -0
- package/adapter-js/code/config.cjs.d.ts +3 -0
- package/adapter-js/code/config.d.ts +3 -0
- package/adapter-js/code/createT.d.ts +3 -0
- package/adapter-js/code/defaultI18nMetadata.d.ts +3 -0
- package/adapter-js/code/defaultLocale.d.ts +3 -0
- package/adapter-js/code/formatUrl.d.ts +3 -0
- package/adapter-js/code/getI18nAlternatesFromDom.d.ts +3 -0
- package/adapter-js/code/getI18nDictionaries.d.ts +3 -0
- package/adapter-js/code/getI18nMetadata.d.ts +3 -0
- package/adapter-js/code/getT.d.ts +3 -0
- package/adapter-js/code/index.d.ts +3 -0
- package/adapter-js/code/isLocale.d.ts +3 -0
- package/adapter-js/code/loadTranslations.d.ts +3 -0
- package/adapter-js/code/locales.d.ts +3 -0
- package/adapter-js/code/pathnameToRouteId.d.ts +3 -0
- package/adapter-js/code/routes.d.ts +3 -0
- package/adapter-js/code/routesError.d.ts +3 -0
- package/adapter-js/code/routesSlim.d.ts +3 -0
- package/adapter-js/code/routesSpa.d.ts +3 -0
- package/adapter-js/code/t.d.ts +3 -0
- package/adapter-js/code/tInterpolateParams.d.ts +3 -0
- package/adapter-js/code/tPluralise.d.ts +3 -0
- package/adapter-js/code/to.d.ts +3 -0
- package/adapter-js/code/toFns.d.ts +3 -0
- package/adapter-js/code/toFormat.d.ts +3 -0
- package/adapter-js/code/toSpa.d.ts +3 -0
- package/adapter-js/code/types.d.ts +3 -0
- package/adapter-js/index.d.ts +5 -0
- package/adapter-js/options.d.ts +4 -0
- package/adapter-next/code/I18nApp.d.ts +3 -0
- package/adapter-next/code/I18nHead.d.ts +3 -0
- package/adapter-next/code/I18nLayout.d.ts +3 -0
- package/adapter-next/code/I18nPage.d.ts +3 -0
- package/adapter-next/code/I18nRoot.d.ts +3 -0
- package/adapter-next/code/I18nSetter.d.ts +3 -0
- package/adapter-next/code/deprecated_useLocale.d.ts +3 -0
- package/adapter-next/code/i18nGet.d.ts +3 -0
- package/adapter-next/code/index.d.ts +3 -0
- package/adapter-next/code/next-redirects.d.ts +3 -0
- package/adapter-next/code/next-rewrites.d.ts +3 -0
- package/adapter-next/code/useRouteId.d.ts +3 -0
- package/adapter-next/code/useTo.d.ts +3 -0
- package/adapter-next/code/useToSpa.d.ts +3 -0
- package/adapter-next/index.d.ts +5 -0
- package/adapter-next/options.d.ts +4 -0
- package/adapter-next/plugin-async.d.ts +8 -0
- package/adapter-next/plugin-legacy.d.ts +18 -0
- package/adapter-next/plugin-shared.d.ts +9 -0
- package/adapter-next/plugin.d.ts +6 -0
- package/adapter-next/redirects.d.ts +5 -0
- package/adapter-next/rewrites.d.ts +5 -0
- package/adapter-next/transformPathname.d.ts +1 -0
- package/adapter-next/webpackPluginI18n.d.ts +7 -0
- package/adapter-next-translate/code/DynamicNamespaces.d.ts +3 -0
- package/adapter-next-translate/code/I18nProvider.d.ts +3 -0
- package/adapter-next-translate/code/T.d.ts +3 -0
- package/adapter-next-translate/code/TransText.d.ts +3 -0
- package/adapter-next-translate/code/getT.d.ts +3 -0
- package/adapter-next-translate/code/index.d.ts +3 -0
- package/adapter-next-translate/code/nextTranslateI18n.d.ts +3 -0
- package/adapter-next-translate/code/useLocale.d.ts +3 -0
- package/adapter-next-translate/code/useT.d.ts +3 -0
- package/adapter-next-translate/index.d.ts +5 -0
- package/adapter-next-translate/options.d.ts +3 -0
- package/adapter-react/code/I18nContext.d.ts +3 -0
- package/adapter-react/code/I18nEffects.d.ts +3 -0
- package/adapter-react/code/I18nHeadTags.d.ts +3 -0
- package/adapter-react/code/I18nMetadataContext.d.ts +3 -0
- package/adapter-react/code/I18nMetadataProvider.d.ts +3 -0
- package/adapter-react/code/I18nMetadataSetter.d.ts +3 -0
- package/adapter-react/code/I18nProvider.d.ts +3 -0
- package/adapter-react/code/I18nRouteContext.d.ts +3 -0
- package/adapter-react/code/I18nRouteProvider.d.ts +3 -0
- package/adapter-react/code/I18nRouteSetter.d.ts +3 -0
- package/adapter-react/code/T.d.ts +3 -0
- package/adapter-react/code/TransText.d.ts +3 -0
- package/adapter-react/code/formatElements.d.ts +3 -0
- package/adapter-react/code/index.d.ts +2 -0
- package/adapter-react/code/useI18nSwitch.d.ts +3 -0
- package/adapter-react/code/useLocale.d.ts +3 -0
- package/adapter-react/code/useRouteId.d.ts +3 -0
- package/adapter-react/code/useT.d.ts +3 -0
- package/adapter-react/index.d.ts +5 -0
- package/adapter-react/options.d.ts +2 -0
- package/api.cjs.js +4026 -0
- package/api.esm.js +4000 -0
- package/client/formatRoutePathname.d.ts +4 -0
- package/client/index.d.ts +3 -0
- package/client/interpolateTo.d.ts +4 -0
- package/client/routeHasDynamicPortion.d.ts +2 -0
- package/compiler/adapter.d.ts +10 -0
- package/compiler/api.d.ts +34 -0
- package/compiler/code/data-routes.d.ts +21 -0
- package/compiler/code/data-translations.d.ts +16 -0
- package/compiler/code/data.d.ts +17 -0
- package/compiler/code/generate.d.ts +10 -0
- package/compiler/code/index.d.ts +3 -0
- package/compiler/code/tsCompile.d.ts +2 -0
- package/compiler/code/write.d.ts +10 -0
- package/compiler/config.d.ts +21 -0
- package/compiler/createAdapter.d.ts +5 -0
- package/compiler/helpers.d.ts +3 -0
- package/compiler/input/data-local.d.ts +4 -0
- package/compiler/input/data-remote.d.ts +7 -0
- package/compiler/input/data.d.ts +4 -0
- package/compiler/input/index.d.ts +4 -0
- package/compiler/input/types.d.ts +14 -0
- package/compiler/input/write.d.ts +8 -0
- package/compiler/pluralisation.d.ts +37 -0
- package/compiler/summary/data.d.ts +6 -0
- package/compiler/summary/generate.d.ts +3 -0
- package/compiler/summary/index.d.ts +2 -0
- package/compiler/summary/write.d.ts +10 -0
- package/compiler/types.d.ts +94 -0
- package/compiler-sync.cjs.d.ts +1 -0
- package/compiler-sync.cjs.default.js +1 -0
- package/compiler-sync.cjs.js +11 -0
- package/compiler-sync.cjs.mjs +2 -0
- package/compiler-sync.d.ts +4 -0
- package/compiler-sync.esm.js +7 -0
- package/compiler-worker.cjs.d.ts +1 -0
- package/compiler-worker.cjs.default.js +1 -0
- package/compiler-worker.cjs.js +17 -0
- package/compiler-worker.cjs.mjs +2 -0
- package/compiler-worker.d.ts +1 -0
- package/compiler-worker.esm.js +15 -0
- package/compiler.cjs.d.ts +1 -0
- package/compiler.cjs.default.js +1 -0
- package/compiler.cjs.js +20 -0
- package/compiler.cjs.mjs +2 -0
- package/compiler.d.ts +2 -0
- package/compiler.esm.js +12 -0
- package/formatRoutePathname.cjs.js +10 -0
- package/formatRoutePathname.esm.js +8 -0
- package/index.cjs.d.ts +1 -0
- package/index.cjs.default.js +1 -0
- package/index.cjs.js +49 -0
- package/index.cjs.mjs +2 -0
- package/index.d.ts +2 -0
- package/index.esm.js +44 -0
- package/next.cjs.d.ts +1 -0
- package/next.cjs.default.js +1 -0
- package/next.cjs.js +353 -0
- package/next.cjs.mjs +2 -0
- package/next.d.ts +3 -0
- package/next.esm.js +329 -0
- package/package.json +62 -0
- 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
|
+
}
|