@better-translate/nextjs 1.0.0
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/LICENSE +21 -0
- package/README.md +5 -0
- package/dist/chunk-VW2LUTE7.js +291 -0
- package/dist/index.cjs +267 -0
- package/dist/index.d.cts +33 -0
- package/dist/index.d.ts +33 -0
- package/dist/index.js +20 -0
- package/dist/navigation.cjs +374 -0
- package/dist/navigation.d.cts +55 -0
- package/dist/navigation.d.ts +55 -0
- package/dist/navigation.js +163 -0
- package/dist/proxy.cjs +318 -0
- package/dist/proxy.d.cts +11 -0
- package/dist/proxy.d.ts +11 -0
- package/dist/proxy.js +86 -0
- package/dist/server.cjs +121 -0
- package/dist/server.d.cts +30 -0
- package/dist/server.d.ts +30 -0
- package/dist/server.js +98 -0
- package/package.json +67 -0
package/dist/proxy.cjs
ADDED
|
@@ -0,0 +1,318 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
28
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
+
|
|
30
|
+
// src/proxy.ts
|
|
31
|
+
var proxy_exports = {};
|
|
32
|
+
__export(proxy_exports, {
|
|
33
|
+
createProxy: () => createProxy,
|
|
34
|
+
defaultProxyMatcher: () => defaultProxyMatcher,
|
|
35
|
+
getProxyMatcher: () => getProxyMatcher,
|
|
36
|
+
withBetterTranslate: () => withBetterTranslate
|
|
37
|
+
});
|
|
38
|
+
module.exports = __toCommonJS(proxy_exports);
|
|
39
|
+
var import_intl_localematcher = require("@formatjs/intl-localematcher");
|
|
40
|
+
var import_negotiator = __toESM(require("negotiator"), 1);
|
|
41
|
+
var import_server = require("next/server");
|
|
42
|
+
|
|
43
|
+
// src/shared.ts
|
|
44
|
+
var DEFAULT_ROUTE_TEMPLATE = "/[lang]";
|
|
45
|
+
function hasLocale(locales, value) {
|
|
46
|
+
return locales.includes(value);
|
|
47
|
+
}
|
|
48
|
+
function normalizePathname(pathname) {
|
|
49
|
+
if (!pathname) {
|
|
50
|
+
return "/";
|
|
51
|
+
}
|
|
52
|
+
return pathname.startsWith("/") ? pathname : `/${pathname}`;
|
|
53
|
+
}
|
|
54
|
+
function getPathnameLocale(pathname, routing) {
|
|
55
|
+
const parsedTemplate = parseRouteTemplate(routing.routeTemplate);
|
|
56
|
+
const pathnameSegments = splitPathname(pathname);
|
|
57
|
+
if (pathnameSegments.length < parsedTemplate.localizedSegments.length) {
|
|
58
|
+
return void 0;
|
|
59
|
+
}
|
|
60
|
+
for (let index = 0; index < parsedTemplate.localizedSegments.length; index += 1) {
|
|
61
|
+
const templateSegment = parsedTemplate.localizedSegments[index];
|
|
62
|
+
const pathnameSegment = pathnameSegments[index];
|
|
63
|
+
if (index === parsedTemplate.localeSegmentIndex) {
|
|
64
|
+
if (!pathnameSegment || !hasLocale(routing.locales, pathnameSegment)) {
|
|
65
|
+
return void 0;
|
|
66
|
+
}
|
|
67
|
+
continue;
|
|
68
|
+
}
|
|
69
|
+
if (pathnameSegment !== templateSegment) {
|
|
70
|
+
return void 0;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
return pathnameSegments[parsedTemplate.localeSegmentIndex];
|
|
74
|
+
}
|
|
75
|
+
function isPathnameInScope(pathname, routing) {
|
|
76
|
+
if (getPathnameLocale(pathname, routing)) {
|
|
77
|
+
return true;
|
|
78
|
+
}
|
|
79
|
+
const parsedTemplate = parseRouteTemplate(routing.routeTemplate);
|
|
80
|
+
const pathnameSegments = splitPathname(pathname);
|
|
81
|
+
if (pathnameSegments.length < parsedTemplate.deLocalizedSegments.length) {
|
|
82
|
+
return false;
|
|
83
|
+
}
|
|
84
|
+
for (let index = 0; index < parsedTemplate.deLocalizedSegments.length; index += 1) {
|
|
85
|
+
if (pathnameSegments[index] !== parsedTemplate.deLocalizedSegments[index]) {
|
|
86
|
+
return false;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
return true;
|
|
90
|
+
}
|
|
91
|
+
function stripLocaleFromPathname(pathname, routing) {
|
|
92
|
+
const locale = getPathnameLocale(pathname, routing);
|
|
93
|
+
if (!locale) {
|
|
94
|
+
return normalizePathname(pathname);
|
|
95
|
+
}
|
|
96
|
+
const parsedTemplate = parseRouteTemplate(routing.routeTemplate);
|
|
97
|
+
const pathnameSegments = splitPathname(pathname);
|
|
98
|
+
pathnameSegments.splice(parsedTemplate.localeSegmentIndex, 1);
|
|
99
|
+
return joinPathname(pathnameSegments);
|
|
100
|
+
}
|
|
101
|
+
function localizePathname(pathname, locale, routing) {
|
|
102
|
+
const normalizedPathname = normalizePathname(pathname);
|
|
103
|
+
const deLocalizedPathname = stripLocaleFromPathname(
|
|
104
|
+
normalizedPathname,
|
|
105
|
+
routing
|
|
106
|
+
);
|
|
107
|
+
if (!isPathnameInScope(deLocalizedPathname, routing)) {
|
|
108
|
+
return normalizedPathname;
|
|
109
|
+
}
|
|
110
|
+
const parsedTemplate = parseRouteTemplate(routing.routeTemplate);
|
|
111
|
+
const pathnameSegments = splitPathname(deLocalizedPathname);
|
|
112
|
+
const localizedSegments = [...pathnameSegments];
|
|
113
|
+
localizedSegments.splice(parsedTemplate.localeSegmentIndex, 0, locale);
|
|
114
|
+
return joinPathname(localizedSegments);
|
|
115
|
+
}
|
|
116
|
+
function splitHrefString(href) {
|
|
117
|
+
const hashIndex = href.indexOf("#");
|
|
118
|
+
const searchIndex = href.indexOf("?");
|
|
119
|
+
const pathnameEnd = hashIndex === -1 ? searchIndex === -1 ? href.length : searchIndex : searchIndex === -1 ? hashIndex : Math.min(searchIndex, hashIndex);
|
|
120
|
+
const pathname = href.slice(0, pathnameEnd) || "/";
|
|
121
|
+
const search = searchIndex === -1 ? "" : href.slice(searchIndex, hashIndex === -1 ? href.length : hashIndex);
|
|
122
|
+
const hash = hashIndex === -1 ? "" : href.slice(hashIndex);
|
|
123
|
+
return {
|
|
124
|
+
pathname: normalizePathname(pathname),
|
|
125
|
+
search,
|
|
126
|
+
hash
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
function isAbsoluteHref(href) {
|
|
130
|
+
return /^[a-zA-Z][a-zA-Z\d+\-.]*:/.test(href) || href.startsWith("//");
|
|
131
|
+
}
|
|
132
|
+
function normalizeHost(host) {
|
|
133
|
+
return host.toLowerCase().replace(/:\d+$/, "");
|
|
134
|
+
}
|
|
135
|
+
function getDomainForLocale(routing, locale) {
|
|
136
|
+
return routing.domains?.find(
|
|
137
|
+
(domain) => getDomainLocales(domain).includes(locale)
|
|
138
|
+
);
|
|
139
|
+
}
|
|
140
|
+
function getLocaleFromDomain(routing, host) {
|
|
141
|
+
const normalizedHost = normalizeHost(host);
|
|
142
|
+
return routing.domains?.find(
|
|
143
|
+
(domain) => normalizeHost(domain.domain) === normalizedHost
|
|
144
|
+
)?.defaultLocale;
|
|
145
|
+
}
|
|
146
|
+
function buildDomainAwareHref(routing, href, locale, options) {
|
|
147
|
+
if (isAbsoluteHref(href)) {
|
|
148
|
+
return {
|
|
149
|
+
href,
|
|
150
|
+
external: true
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
const { hash, pathname, search } = splitHrefString(href);
|
|
154
|
+
const isScopedPath = isPathnameInScope(pathname, routing);
|
|
155
|
+
if (!isScopedPath) {
|
|
156
|
+
return {
|
|
157
|
+
href: `${pathname}${search}${hash}`,
|
|
158
|
+
external: false
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
const localizedPathname = localizePathname(pathname, locale, routing);
|
|
162
|
+
const localizedHref = `${localizedPathname}${search}${hash}`;
|
|
163
|
+
const targetDomain = getDomainForLocale(routing, locale);
|
|
164
|
+
if (!targetDomain) {
|
|
165
|
+
return {
|
|
166
|
+
href: localizedHref,
|
|
167
|
+
external: false
|
|
168
|
+
};
|
|
169
|
+
}
|
|
170
|
+
const targetHost = normalizeHost(targetDomain.domain);
|
|
171
|
+
const currentHost = options?.currentHost ? normalizeHost(options.currentHost) : void 0;
|
|
172
|
+
const shouldUseAbsolute = options?.forceAbsolute === true || currentHost === void 0 || currentHost !== targetHost;
|
|
173
|
+
if (!shouldUseAbsolute) {
|
|
174
|
+
return {
|
|
175
|
+
href: localizedHref,
|
|
176
|
+
external: false
|
|
177
|
+
};
|
|
178
|
+
}
|
|
179
|
+
const protocol = targetDomain.protocol ?? options?.protocol ?? "https";
|
|
180
|
+
return {
|
|
181
|
+
href: `${protocol}://${targetHost}${localizedHref}`,
|
|
182
|
+
external: currentHost === void 0 ? true : currentHost !== targetHost
|
|
183
|
+
};
|
|
184
|
+
}
|
|
185
|
+
function parseRouteTemplate(routeTemplate) {
|
|
186
|
+
const normalizedRouteTemplate = normalizePathname(
|
|
187
|
+
routeTemplate ?? DEFAULT_ROUTE_TEMPLATE
|
|
188
|
+
);
|
|
189
|
+
const localizedSegments = splitPathname(normalizedRouteTemplate);
|
|
190
|
+
let localeSegmentIndex = -1;
|
|
191
|
+
let localeParamName = "";
|
|
192
|
+
for (let index = 0; index < localizedSegments.length; index += 1) {
|
|
193
|
+
const segment = localizedSegments[index];
|
|
194
|
+
const dynamicMatch = /^\[([^\]/]+)\]$/.exec(segment);
|
|
195
|
+
if (!dynamicMatch) {
|
|
196
|
+
continue;
|
|
197
|
+
}
|
|
198
|
+
if (localeSegmentIndex !== -1) {
|
|
199
|
+
throw new Error(
|
|
200
|
+
`Route template "${normalizedRouteTemplate}" must contain exactly one dynamic locale segment.`
|
|
201
|
+
);
|
|
202
|
+
}
|
|
203
|
+
localeSegmentIndex = index;
|
|
204
|
+
localeParamName = dynamicMatch[1];
|
|
205
|
+
}
|
|
206
|
+
if (localeSegmentIndex === -1) {
|
|
207
|
+
throw new Error(
|
|
208
|
+
`Route template "${normalizedRouteTemplate}" must contain one dynamic locale segment like "[lang]".`
|
|
209
|
+
);
|
|
210
|
+
}
|
|
211
|
+
const deLocalizedSegments = localizedSegments.filter(
|
|
212
|
+
(_, index) => index !== localeSegmentIndex
|
|
213
|
+
);
|
|
214
|
+
const scopePrefixSegments = localizedSegments.slice(0, localeSegmentIndex);
|
|
215
|
+
return {
|
|
216
|
+
deLocalizedSegments,
|
|
217
|
+
localeParamName,
|
|
218
|
+
localeSegmentIndex,
|
|
219
|
+
localizedSegments,
|
|
220
|
+
routeTemplate: normalizedRouteTemplate,
|
|
221
|
+
scopePrefix: joinPathname(scopePrefixSegments)
|
|
222
|
+
};
|
|
223
|
+
}
|
|
224
|
+
function splitPathname(pathname) {
|
|
225
|
+
return normalizePathname(pathname).split("/").filter(Boolean);
|
|
226
|
+
}
|
|
227
|
+
function joinPathname(segments) {
|
|
228
|
+
if (segments.length === 0) {
|
|
229
|
+
return "/";
|
|
230
|
+
}
|
|
231
|
+
return `/${segments.join("/")}`;
|
|
232
|
+
}
|
|
233
|
+
function getDomainLocales(domain) {
|
|
234
|
+
if (!domain.locales || domain.locales.length === 0) {
|
|
235
|
+
return [domain.defaultLocale];
|
|
236
|
+
}
|
|
237
|
+
if (!domain.locales.includes(domain.defaultLocale)) {
|
|
238
|
+
return [...domain.locales, domain.defaultLocale];
|
|
239
|
+
}
|
|
240
|
+
return domain.locales;
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
// src/proxy.ts
|
|
244
|
+
var defaultProxyMatcher = [
|
|
245
|
+
"/((?!api|_next|_vercel|.*\\..*).*)"
|
|
246
|
+
];
|
|
247
|
+
function createProxy(routing, _options) {
|
|
248
|
+
return function proxy(request) {
|
|
249
|
+
const pathname = request.nextUrl.pathname;
|
|
250
|
+
if (!isPathnameInScope(pathname, routing)) {
|
|
251
|
+
return void 0;
|
|
252
|
+
}
|
|
253
|
+
const pathnameLocale = getPathnameLocale(pathname, routing);
|
|
254
|
+
const host = request.headers.get("x-forwarded-host") ?? request.headers.get("host") ?? request.nextUrl.host;
|
|
255
|
+
const locale = pathnameLocale ?? (host ? getLocaleFromDomain(routing, host) : void 0) ?? getPreferredLocale(
|
|
256
|
+
request.headers.get("accept-language"),
|
|
257
|
+
routing.locales,
|
|
258
|
+
routing.defaultLocale
|
|
259
|
+
);
|
|
260
|
+
const targetHref = buildDomainAwareHref(
|
|
261
|
+
routing,
|
|
262
|
+
`${pathname}${request.nextUrl.search}`,
|
|
263
|
+
locale,
|
|
264
|
+
{
|
|
265
|
+
currentHost: host ?? void 0,
|
|
266
|
+
forceAbsolute: !pathnameLocale,
|
|
267
|
+
protocol: request.nextUrl.protocol.replace(":", "")
|
|
268
|
+
}
|
|
269
|
+
);
|
|
270
|
+
const redirectUrl = targetHref.href.startsWith("/") ? new URL(targetHref.href, request.url).toString() : targetHref.href;
|
|
271
|
+
if (!pathnameLocale) {
|
|
272
|
+
return import_server.NextResponse.redirect(redirectUrl);
|
|
273
|
+
}
|
|
274
|
+
if (targetHref.external) {
|
|
275
|
+
return import_server.NextResponse.redirect(redirectUrl);
|
|
276
|
+
}
|
|
277
|
+
return void 0;
|
|
278
|
+
};
|
|
279
|
+
}
|
|
280
|
+
function withBetterTranslate(userProxy, routing, options) {
|
|
281
|
+
const betterTranslateProxy = createProxy(routing, options);
|
|
282
|
+
return async function composedProxy(request, event) {
|
|
283
|
+
const betterTranslateResult = await betterTranslateProxy(request, event);
|
|
284
|
+
if (betterTranslateResult) {
|
|
285
|
+
return betterTranslateResult;
|
|
286
|
+
}
|
|
287
|
+
return userProxy(request, event);
|
|
288
|
+
};
|
|
289
|
+
}
|
|
290
|
+
function getProxyMatcher(routing) {
|
|
291
|
+
const parsedTemplate = parseRouteTemplate(routing.routeTemplate);
|
|
292
|
+
if (parsedTemplate.scopePrefix === "/") {
|
|
293
|
+
return defaultProxyMatcher;
|
|
294
|
+
}
|
|
295
|
+
const escapedPrefix = escapeMatcherSegment(parsedTemplate.scopePrefix);
|
|
296
|
+
return [
|
|
297
|
+
parsedTemplate.scopePrefix,
|
|
298
|
+
`${escapedPrefix}/((?!.*\\..*).*)`
|
|
299
|
+
];
|
|
300
|
+
}
|
|
301
|
+
function getPreferredLocale(acceptLanguageHeader, locales, defaultLocale) {
|
|
302
|
+
const negotiator = new import_negotiator.default({
|
|
303
|
+
headers: {
|
|
304
|
+
"accept-language": acceptLanguageHeader ?? ""
|
|
305
|
+
}
|
|
306
|
+
});
|
|
307
|
+
return (0, import_intl_localematcher.match)(negotiator.languages(), locales, defaultLocale);
|
|
308
|
+
}
|
|
309
|
+
function escapeMatcherSegment(value) {
|
|
310
|
+
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
311
|
+
}
|
|
312
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
313
|
+
0 && (module.exports = {
|
|
314
|
+
createProxy,
|
|
315
|
+
defaultProxyMatcher,
|
|
316
|
+
getProxyMatcher,
|
|
317
|
+
withBetterTranslate
|
|
318
|
+
});
|
package/dist/proxy.d.cts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { RoutingConfig } from './index.cjs';
|
|
2
|
+
import { NextProxy } from 'next/server';
|
|
3
|
+
|
|
4
|
+
interface CreateProxyOptions {
|
|
5
|
+
}
|
|
6
|
+
declare const defaultProxyMatcher: readonly ["/((?!api|_next|_vercel|.*\\..*).*)"];
|
|
7
|
+
declare function createProxy<TLocale extends string>(routing: RoutingConfig<TLocale>, _options?: CreateProxyOptions): NextProxy;
|
|
8
|
+
declare function withBetterTranslate<TLocale extends string>(userProxy: NextProxy, routing: RoutingConfig<TLocale>, options?: CreateProxyOptions): NextProxy;
|
|
9
|
+
declare function getProxyMatcher<TLocale extends string>(routing: RoutingConfig<TLocale>): readonly string[];
|
|
10
|
+
|
|
11
|
+
export { type CreateProxyOptions, createProxy, defaultProxyMatcher, getProxyMatcher, withBetterTranslate };
|
package/dist/proxy.d.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { RoutingConfig } from './index.js';
|
|
2
|
+
import { NextProxy } from 'next/server';
|
|
3
|
+
|
|
4
|
+
interface CreateProxyOptions {
|
|
5
|
+
}
|
|
6
|
+
declare const defaultProxyMatcher: readonly ["/((?!api|_next|_vercel|.*\\..*).*)"];
|
|
7
|
+
declare function createProxy<TLocale extends string>(routing: RoutingConfig<TLocale>, _options?: CreateProxyOptions): NextProxy;
|
|
8
|
+
declare function withBetterTranslate<TLocale extends string>(userProxy: NextProxy, routing: RoutingConfig<TLocale>, options?: CreateProxyOptions): NextProxy;
|
|
9
|
+
declare function getProxyMatcher<TLocale extends string>(routing: RoutingConfig<TLocale>): readonly string[];
|
|
10
|
+
|
|
11
|
+
export { type CreateProxyOptions, createProxy, defaultProxyMatcher, getProxyMatcher, withBetterTranslate };
|
package/dist/proxy.js
ADDED
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import {
|
|
2
|
+
buildDomainAwareHref,
|
|
3
|
+
getLocaleFromDomain,
|
|
4
|
+
getPathnameLocale,
|
|
5
|
+
isPathnameInScope,
|
|
6
|
+
parseRouteTemplate
|
|
7
|
+
} from "./chunk-VW2LUTE7.js";
|
|
8
|
+
|
|
9
|
+
// src/proxy.ts
|
|
10
|
+
import { match } from "@formatjs/intl-localematcher";
|
|
11
|
+
import Negotiator from "negotiator";
|
|
12
|
+
import { NextResponse } from "next/server";
|
|
13
|
+
var defaultProxyMatcher = [
|
|
14
|
+
"/((?!api|_next|_vercel|.*\\..*).*)"
|
|
15
|
+
];
|
|
16
|
+
function createProxy(routing, _options) {
|
|
17
|
+
return function proxy(request) {
|
|
18
|
+
const pathname = request.nextUrl.pathname;
|
|
19
|
+
if (!isPathnameInScope(pathname, routing)) {
|
|
20
|
+
return void 0;
|
|
21
|
+
}
|
|
22
|
+
const pathnameLocale = getPathnameLocale(pathname, routing);
|
|
23
|
+
const host = request.headers.get("x-forwarded-host") ?? request.headers.get("host") ?? request.nextUrl.host;
|
|
24
|
+
const locale = pathnameLocale ?? (host ? getLocaleFromDomain(routing, host) : void 0) ?? getPreferredLocale(
|
|
25
|
+
request.headers.get("accept-language"),
|
|
26
|
+
routing.locales,
|
|
27
|
+
routing.defaultLocale
|
|
28
|
+
);
|
|
29
|
+
const targetHref = buildDomainAwareHref(
|
|
30
|
+
routing,
|
|
31
|
+
`${pathname}${request.nextUrl.search}`,
|
|
32
|
+
locale,
|
|
33
|
+
{
|
|
34
|
+
currentHost: host ?? void 0,
|
|
35
|
+
forceAbsolute: !pathnameLocale,
|
|
36
|
+
protocol: request.nextUrl.protocol.replace(":", "")
|
|
37
|
+
}
|
|
38
|
+
);
|
|
39
|
+
const redirectUrl = targetHref.href.startsWith("/") ? new URL(targetHref.href, request.url).toString() : targetHref.href;
|
|
40
|
+
if (!pathnameLocale) {
|
|
41
|
+
return NextResponse.redirect(redirectUrl);
|
|
42
|
+
}
|
|
43
|
+
if (targetHref.external) {
|
|
44
|
+
return NextResponse.redirect(redirectUrl);
|
|
45
|
+
}
|
|
46
|
+
return void 0;
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
function withBetterTranslate(userProxy, routing, options) {
|
|
50
|
+
const betterTranslateProxy = createProxy(routing, options);
|
|
51
|
+
return async function composedProxy(request, event) {
|
|
52
|
+
const betterTranslateResult = await betterTranslateProxy(request, event);
|
|
53
|
+
if (betterTranslateResult) {
|
|
54
|
+
return betterTranslateResult;
|
|
55
|
+
}
|
|
56
|
+
return userProxy(request, event);
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
function getProxyMatcher(routing) {
|
|
60
|
+
const parsedTemplate = parseRouteTemplate(routing.routeTemplate);
|
|
61
|
+
if (parsedTemplate.scopePrefix === "/") {
|
|
62
|
+
return defaultProxyMatcher;
|
|
63
|
+
}
|
|
64
|
+
const escapedPrefix = escapeMatcherSegment(parsedTemplate.scopePrefix);
|
|
65
|
+
return [
|
|
66
|
+
parsedTemplate.scopePrefix,
|
|
67
|
+
`${escapedPrefix}/((?!.*\\..*).*)`
|
|
68
|
+
];
|
|
69
|
+
}
|
|
70
|
+
function getPreferredLocale(acceptLanguageHeader, locales, defaultLocale) {
|
|
71
|
+
const negotiator = new Negotiator({
|
|
72
|
+
headers: {
|
|
73
|
+
"accept-language": acceptLanguageHeader ?? ""
|
|
74
|
+
}
|
|
75
|
+
});
|
|
76
|
+
return match(negotiator.languages(), locales, defaultLocale);
|
|
77
|
+
}
|
|
78
|
+
function escapeMatcherSegment(value) {
|
|
79
|
+
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
80
|
+
}
|
|
81
|
+
export {
|
|
82
|
+
createProxy,
|
|
83
|
+
defaultProxyMatcher,
|
|
84
|
+
getProxyMatcher,
|
|
85
|
+
withBetterTranslate
|
|
86
|
+
};
|
package/dist/server.cjs
ADDED
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/server.ts
|
|
21
|
+
var server_exports = {};
|
|
22
|
+
__export(server_exports, {
|
|
23
|
+
createServerHelpers: () => createServerHelpers,
|
|
24
|
+
getRequestConfig: () => getRequestConfig,
|
|
25
|
+
setRequestLocale: () => setRequestLocale
|
|
26
|
+
});
|
|
27
|
+
module.exports = __toCommonJS(server_exports);
|
|
28
|
+
var import_react = require("react");
|
|
29
|
+
var import_server = require("@better-translate/core/server");
|
|
30
|
+
function getRequestConfig(factory) {
|
|
31
|
+
return factory;
|
|
32
|
+
}
|
|
33
|
+
function setRequestLocale(locale) {
|
|
34
|
+
(0, import_server.setRequestLocale)(locale);
|
|
35
|
+
}
|
|
36
|
+
function createServerHelpers(requestConfig) {
|
|
37
|
+
const readRequestConfig = (0, import_react.cache)(async () => {
|
|
38
|
+
const resolved = await requestConfig();
|
|
39
|
+
const translator = resolved.translator;
|
|
40
|
+
return {
|
|
41
|
+
locale: resolved.locale,
|
|
42
|
+
translator
|
|
43
|
+
};
|
|
44
|
+
});
|
|
45
|
+
async function getResolvedLocale(options) {
|
|
46
|
+
const { locale: configLocale, translator } = await readRequestConfig();
|
|
47
|
+
return (0, import_server.resolveRequestLocale)(translator, {
|
|
48
|
+
locale: options?.config?.locale ?? options?.locale,
|
|
49
|
+
requestLocale: (0, import_server.getRequestLocale)(),
|
|
50
|
+
configLocale
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
async function getDirection(options) {
|
|
54
|
+
const [{ translator }, locale] = await Promise.all([
|
|
55
|
+
readRequestConfig(),
|
|
56
|
+
getResolvedLocale(options)
|
|
57
|
+
]);
|
|
58
|
+
return translator.getDirection({
|
|
59
|
+
config: typeof options?.config?.rtl === "boolean" ? {
|
|
60
|
+
rtl: options.config.rtl
|
|
61
|
+
} : void 0,
|
|
62
|
+
locale
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
async function isRtl(options) {
|
|
66
|
+
return await getDirection(options) === "rtl";
|
|
67
|
+
}
|
|
68
|
+
return {
|
|
69
|
+
async getAvailableLanguages() {
|
|
70
|
+
return (await readRequestConfig()).translator.getAvailableLanguages();
|
|
71
|
+
},
|
|
72
|
+
getDirection,
|
|
73
|
+
async getLocale() {
|
|
74
|
+
return getResolvedLocale();
|
|
75
|
+
},
|
|
76
|
+
async getMessages() {
|
|
77
|
+
const [{ translator }, locale] = await Promise.all([
|
|
78
|
+
readRequestConfig(),
|
|
79
|
+
getResolvedLocale()
|
|
80
|
+
]);
|
|
81
|
+
const loadedMessages = await translator.loadLocale(locale);
|
|
82
|
+
const cachedMessages = translator.getMessages()[locale];
|
|
83
|
+
if (loadedMessages) {
|
|
84
|
+
return loadedMessages;
|
|
85
|
+
}
|
|
86
|
+
if (cachedMessages) {
|
|
87
|
+
return cachedMessages;
|
|
88
|
+
}
|
|
89
|
+
throw new Error(
|
|
90
|
+
`Locale "${locale}" messages are not available. Preload them or register a loader in your Better Translate core config.`
|
|
91
|
+
);
|
|
92
|
+
},
|
|
93
|
+
isRtl,
|
|
94
|
+
async getTranslations(options) {
|
|
95
|
+
const [{ translator }, locale] = await Promise.all([
|
|
96
|
+
readRequestConfig(),
|
|
97
|
+
getResolvedLocale(options)
|
|
98
|
+
]);
|
|
99
|
+
await translator.loadLocale(locale);
|
|
100
|
+
return ((...args) => {
|
|
101
|
+
const [key, translateOptions] = args;
|
|
102
|
+
return translator.t(
|
|
103
|
+
key,
|
|
104
|
+
{
|
|
105
|
+
...translateOptions ?? {},
|
|
106
|
+
locale
|
|
107
|
+
}
|
|
108
|
+
);
|
|
109
|
+
});
|
|
110
|
+
},
|
|
111
|
+
async getTranslator() {
|
|
112
|
+
return (await readRequestConfig()).translator;
|
|
113
|
+
}
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
117
|
+
0 && (module.exports = {
|
|
118
|
+
createServerHelpers,
|
|
119
|
+
getRequestConfig,
|
|
120
|
+
setRequestLocale
|
|
121
|
+
});
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { ConfiguredTranslator, TranslationMessages, TranslationLanguageMetadata, TranslationConfig, TranslationDirection, DeepPartialMessages } from '@better-translate/core';
|
|
2
|
+
|
|
3
|
+
type AnyTranslator = ConfiguredTranslator<any, TranslationMessages>;
|
|
4
|
+
type InferTranslatorLocale<TTranslator> = TTranslator extends ConfiguredTranslator<infer TLocale, TranslationMessages> ? TLocale : never;
|
|
5
|
+
type InferTranslatorMessages<TTranslator> = TTranslator extends ConfiguredTranslator<string, infer TMessages> ? TMessages : TranslationMessages;
|
|
6
|
+
interface BetterTranslateRequestConfig<TTranslator extends AnyTranslator, TLocale extends InferTranslatorLocale<TTranslator> = InferTranslatorLocale<TTranslator>> {
|
|
7
|
+
locale?: TLocale;
|
|
8
|
+
translator: TTranslator;
|
|
9
|
+
}
|
|
10
|
+
type RequestConfigFactory<TTranslator extends AnyTranslator, TLocale extends InferTranslatorLocale<TTranslator> = InferTranslatorLocale<TTranslator>> = () => BetterTranslateRequestConfig<TTranslator, TLocale> | Promise<BetterTranslateRequestConfig<TTranslator, TLocale>>;
|
|
11
|
+
type RequestDirectionOptions<TLocale extends string> = {
|
|
12
|
+
locale?: TLocale;
|
|
13
|
+
config?: TranslationConfig<TLocale>;
|
|
14
|
+
};
|
|
15
|
+
interface ServerHelpers<TRequestLocale extends string, TTranslator extends AnyTranslator> {
|
|
16
|
+
getAvailableLanguages(): Promise<readonly TranslationLanguageMetadata<InferTranslatorLocale<TTranslator>>[]>;
|
|
17
|
+
getDirection(options?: RequestDirectionOptions<InferTranslatorLocale<TTranslator>>): Promise<TranslationDirection>;
|
|
18
|
+
getLocale(): Promise<TRequestLocale>;
|
|
19
|
+
getMessages(): Promise<DeepPartialMessages<InferTranslatorMessages<TTranslator>> | InferTranslatorMessages<TTranslator>>;
|
|
20
|
+
isRtl(options?: RequestDirectionOptions<InferTranslatorLocale<TTranslator>>): Promise<boolean>;
|
|
21
|
+
getTranslations(options?: {
|
|
22
|
+
locale?: InferTranslatorLocale<TTranslator>;
|
|
23
|
+
}): Promise<TTranslator["t"]>;
|
|
24
|
+
getTranslator(): Promise<TTranslator>;
|
|
25
|
+
}
|
|
26
|
+
declare function getRequestConfig<TTranslator extends AnyTranslator, TLocale extends InferTranslatorLocale<TTranslator> = InferTranslatorLocale<TTranslator>>(factory: RequestConfigFactory<TTranslator, TLocale>): RequestConfigFactory<TTranslator, TLocale>;
|
|
27
|
+
declare function setRequestLocale<TLocale extends string>(locale: TLocale | undefined): void;
|
|
28
|
+
declare function createServerHelpers<TTranslator extends AnyTranslator, TLocale extends InferTranslatorLocale<TTranslator> = InferTranslatorLocale<TTranslator>>(requestConfig: RequestConfigFactory<TTranslator, TLocale>): ServerHelpers<TLocale, TTranslator>;
|
|
29
|
+
|
|
30
|
+
export { type BetterTranslateRequestConfig, type RequestConfigFactory, type ServerHelpers, createServerHelpers, getRequestConfig, setRequestLocale };
|
package/dist/server.d.ts
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { ConfiguredTranslator, TranslationMessages, TranslationLanguageMetadata, TranslationConfig, TranslationDirection, DeepPartialMessages } from '@better-translate/core';
|
|
2
|
+
|
|
3
|
+
type AnyTranslator = ConfiguredTranslator<any, TranslationMessages>;
|
|
4
|
+
type InferTranslatorLocale<TTranslator> = TTranslator extends ConfiguredTranslator<infer TLocale, TranslationMessages> ? TLocale : never;
|
|
5
|
+
type InferTranslatorMessages<TTranslator> = TTranslator extends ConfiguredTranslator<string, infer TMessages> ? TMessages : TranslationMessages;
|
|
6
|
+
interface BetterTranslateRequestConfig<TTranslator extends AnyTranslator, TLocale extends InferTranslatorLocale<TTranslator> = InferTranslatorLocale<TTranslator>> {
|
|
7
|
+
locale?: TLocale;
|
|
8
|
+
translator: TTranslator;
|
|
9
|
+
}
|
|
10
|
+
type RequestConfigFactory<TTranslator extends AnyTranslator, TLocale extends InferTranslatorLocale<TTranslator> = InferTranslatorLocale<TTranslator>> = () => BetterTranslateRequestConfig<TTranslator, TLocale> | Promise<BetterTranslateRequestConfig<TTranslator, TLocale>>;
|
|
11
|
+
type RequestDirectionOptions<TLocale extends string> = {
|
|
12
|
+
locale?: TLocale;
|
|
13
|
+
config?: TranslationConfig<TLocale>;
|
|
14
|
+
};
|
|
15
|
+
interface ServerHelpers<TRequestLocale extends string, TTranslator extends AnyTranslator> {
|
|
16
|
+
getAvailableLanguages(): Promise<readonly TranslationLanguageMetadata<InferTranslatorLocale<TTranslator>>[]>;
|
|
17
|
+
getDirection(options?: RequestDirectionOptions<InferTranslatorLocale<TTranslator>>): Promise<TranslationDirection>;
|
|
18
|
+
getLocale(): Promise<TRequestLocale>;
|
|
19
|
+
getMessages(): Promise<DeepPartialMessages<InferTranslatorMessages<TTranslator>> | InferTranslatorMessages<TTranslator>>;
|
|
20
|
+
isRtl(options?: RequestDirectionOptions<InferTranslatorLocale<TTranslator>>): Promise<boolean>;
|
|
21
|
+
getTranslations(options?: {
|
|
22
|
+
locale?: InferTranslatorLocale<TTranslator>;
|
|
23
|
+
}): Promise<TTranslator["t"]>;
|
|
24
|
+
getTranslator(): Promise<TTranslator>;
|
|
25
|
+
}
|
|
26
|
+
declare function getRequestConfig<TTranslator extends AnyTranslator, TLocale extends InferTranslatorLocale<TTranslator> = InferTranslatorLocale<TTranslator>>(factory: RequestConfigFactory<TTranslator, TLocale>): RequestConfigFactory<TTranslator, TLocale>;
|
|
27
|
+
declare function setRequestLocale<TLocale extends string>(locale: TLocale | undefined): void;
|
|
28
|
+
declare function createServerHelpers<TTranslator extends AnyTranslator, TLocale extends InferTranslatorLocale<TTranslator> = InferTranslatorLocale<TTranslator>>(requestConfig: RequestConfigFactory<TTranslator, TLocale>): ServerHelpers<TLocale, TTranslator>;
|
|
29
|
+
|
|
30
|
+
export { type BetterTranslateRequestConfig, type RequestConfigFactory, type ServerHelpers, createServerHelpers, getRequestConfig, setRequestLocale };
|