@inlang/paraglide-js 2.0.0 → 2.0.2
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/dist/compiler/runtime/get-locale.js +1 -1
- package/dist/compiler/runtime/set-locale.js +1 -1
- package/dist/compiler/server/middleware.d.ts.map +1 -1
- package/dist/compiler/server/middleware.js +55 -69
- package/dist/compiler/server/middleware.test.js +19 -0
- package/dist/services/env-variables/index.js +1 -1
- package/package.json +6 -6
|
@@ -45,7 +45,7 @@ export let getLocale = () => {
|
|
|
45
45
|
else if (strat === "baseLocale") {
|
|
46
46
|
locale = baseLocale;
|
|
47
47
|
}
|
|
48
|
-
else if (TREE_SHAKE_URL_STRATEGY_USED && strat === "url" && !isServer) {
|
|
48
|
+
else if (TREE_SHAKE_URL_STRATEGY_USED && strat === "url" && !isServer && typeof window !== 'undefined') {
|
|
49
49
|
locale = extractLocaleFromUrl(window.location.href);
|
|
50
50
|
}
|
|
51
51
|
else if (TREE_SHAKE_GLOBAL_VARIABLE_STRATEGY_USED &&
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"middleware.d.ts","sourceRoot":"","sources":["../../../src/compiler/server/middleware.js"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4DG;AACH,oCA9Ca,CAAC,WAEH,OAAO,WACP,CAAC,IAAI,EAAE;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,OAAO,cAAc,EAAE,MAAM,CAAA;CAAE,KAAK,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,GAEnF,OAAO,CAAC,QAAQ,CAAC,
|
|
1
|
+
{"version":3,"file":"middleware.d.ts","sourceRoot":"","sources":["../../../src/compiler/server/middleware.js"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4DG;AACH,oCA9Ca,CAAC,WAEH,OAAO,WACP,CAAC,IAAI,EAAE;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,OAAO,cAAc,EAAE,MAAM,CAAA;CAAE,KAAK,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,GAEnF,OAAO,CAAC,QAAQ,CAAC,CA0H7B"}
|
|
@@ -61,79 +61,65 @@ import * as runtime from "./runtime.js";
|
|
|
61
61
|
* ```
|
|
62
62
|
*/
|
|
63
63
|
export async function paraglideMiddleware(request, resolve) {
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
return Response.redirect(localizedUrl, 307);
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
// If the strategy includes "url", we need to de-localize the URL
|
|
84
|
-
// before passing it to the server middleware.
|
|
85
|
-
//
|
|
86
|
-
// The middleware is responsible for mapping a localized URL to the
|
|
87
|
-
// de-localized URL e.g. `/en/about` to `/about`. Otherwise,
|
|
88
|
-
// the server can't render the correct page.
|
|
89
|
-
const newRequest = runtime.strategy.includes("url")
|
|
90
|
-
? new Request(runtime.deLocalizeUrl(request.url), request)
|
|
91
|
-
: // need to create a new request object because some metaframeworks (nextjs!) throw otherwise
|
|
92
|
-
// https://github.com/opral/inlang-paraglide-js/issues/411
|
|
93
|
-
new Request(request);
|
|
94
|
-
// the message functions that have been called in this request
|
|
95
|
-
/** @type {Set<string>} */
|
|
96
|
-
const messageCalls = new Set();
|
|
97
|
-
const response = await runtime.serverAsyncLocalStorage?.run({ locale, origin, messageCalls }, () => resolve({ locale, request: newRequest }));
|
|
98
|
-
// Only modify HTML responses
|
|
99
|
-
if (runtime.experimentalMiddlewareLocaleSplitting &&
|
|
100
|
-
response.headers.get("Content-Type")?.includes("html")) {
|
|
101
|
-
const body = await response.text();
|
|
102
|
-
const messages = [];
|
|
103
|
-
// using .values() to avoid polyfilling in older projects. else the following error is thrown
|
|
104
|
-
// Type 'Set<string>' can only be iterated through when using the '--downlevelIteration' flag or with a '--target' of 'es2015' or higher.
|
|
105
|
-
for (const messageCall of Array.from(messageCalls)) {
|
|
106
|
-
const [id, locale] =
|
|
107
|
-
/** @type {[string, import("./runtime.js").Locale]} */ (messageCall.split(":"));
|
|
108
|
-
messages.push(`${id}: ${compiledBundles[id]?.[locale]}`);
|
|
109
|
-
}
|
|
110
|
-
const script = `<script>globalThis.__paraglide_ssr = { ${messages.join(",")} }</script>`;
|
|
111
|
-
// Insert the script before the closing head tag
|
|
112
|
-
const newBody = body.replace("</head>", `${script}</head>`);
|
|
113
|
-
// Create a new response with the modified body
|
|
114
|
-
// Clone all headers except Content-Length which will be set automatically
|
|
115
|
-
const newHeaders = new Headers(response.headers);
|
|
116
|
-
newHeaders.delete("Content-Length"); // Let the browser calculate the correct length
|
|
117
|
-
return new Response(newBody, {
|
|
118
|
-
status: response.status,
|
|
119
|
-
statusText: response.statusText,
|
|
120
|
-
headers: newHeaders,
|
|
121
|
-
});
|
|
64
|
+
if (!runtime.disableAsyncLocalStorage && !runtime.serverAsyncLocalStorage) {
|
|
65
|
+
const { AsyncLocalStorage } = await import("async_hooks");
|
|
66
|
+
runtime.overwriteServerAsyncLocalStorage(new AsyncLocalStorage());
|
|
67
|
+
}
|
|
68
|
+
else if (!runtime.serverAsyncLocalStorage) {
|
|
69
|
+
runtime.overwriteServerAsyncLocalStorage(createMockAsyncLocalStorage());
|
|
70
|
+
}
|
|
71
|
+
const locale = runtime.extractLocaleFromRequest(request);
|
|
72
|
+
const origin = new URL(request.url).origin;
|
|
73
|
+
// if the client makes a request to a URL that doesn't match
|
|
74
|
+
// the localizedUrl, redirect the client to the localized URL
|
|
75
|
+
if (request.headers.get("Sec-Fetch-Dest") === "document" &&
|
|
76
|
+
runtime.strategy.includes("url")) {
|
|
77
|
+
const localizedUrl = runtime.localizeUrl(request.url, { locale });
|
|
78
|
+
if (normalizeURL(localizedUrl.href) !== normalizeURL(request.url)) {
|
|
79
|
+
return Response.redirect(localizedUrl, 307);
|
|
122
80
|
}
|
|
123
|
-
return response;
|
|
124
81
|
}
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
82
|
+
// If the strategy includes "url", we need to de-localize the URL
|
|
83
|
+
// before passing it to the server middleware.
|
|
84
|
+
//
|
|
85
|
+
// The middleware is responsible for mapping a localized URL to the
|
|
86
|
+
// de-localized URL e.g. `/en/about` to `/about`. Otherwise,
|
|
87
|
+
// the server can't render the correct page.
|
|
88
|
+
const newRequest = runtime.strategy.includes("url")
|
|
89
|
+
? new Request(runtime.deLocalizeUrl(request.url), request)
|
|
90
|
+
: // need to create a new request object because some metaframeworks (nextjs!) throw otherwise
|
|
91
|
+
// https://github.com/opral/inlang-paraglide-js/issues/411
|
|
92
|
+
new Request(request);
|
|
93
|
+
// the message functions that have been called in this request
|
|
94
|
+
/** @type {Set<string>} */
|
|
95
|
+
const messageCalls = new Set();
|
|
96
|
+
const response = await runtime.serverAsyncLocalStorage?.run({ locale, origin, messageCalls }, () => resolve({ locale, request: newRequest }));
|
|
97
|
+
// Only modify HTML responses
|
|
98
|
+
if (runtime.experimentalMiddlewareLocaleSplitting &&
|
|
99
|
+
response.headers.get("Content-Type")?.includes("html")) {
|
|
100
|
+
const body = await response.text();
|
|
101
|
+
const messages = [];
|
|
102
|
+
// using .values() to avoid polyfilling in older projects. else the following error is thrown
|
|
103
|
+
// Type 'Set<string>' can only be iterated through when using the '--downlevelIteration' flag or with a '--target' of 'es2015' or higher.
|
|
104
|
+
for (const messageCall of Array.from(messageCalls)) {
|
|
105
|
+
const [id, locale] =
|
|
106
|
+
/** @type {[string, import("./runtime.js").Locale]} */ (messageCall.split(":"));
|
|
107
|
+
messages.push(`${id}: ${compiledBundles[id]?.[locale]}`);
|
|
108
|
+
}
|
|
109
|
+
const script = `<script>globalThis.__paraglide_ssr = { ${messages.join(",")} }</script>`;
|
|
110
|
+
// Insert the script before the closing head tag
|
|
111
|
+
const newBody = body.replace("</head>", `${script}</head>`);
|
|
112
|
+
// Create a new response with the modified body
|
|
113
|
+
// Clone all headers except Content-Length which will be set automatically
|
|
114
|
+
const newHeaders = new Headers(response.headers);
|
|
115
|
+
newHeaders.delete("Content-Length"); // Let the browser calculate the correct length
|
|
116
|
+
return new Response(newBody, {
|
|
117
|
+
status: response.status,
|
|
118
|
+
statusText: response.statusText,
|
|
119
|
+
headers: newHeaders,
|
|
135
120
|
});
|
|
136
121
|
}
|
|
122
|
+
return response;
|
|
137
123
|
}
|
|
138
124
|
/**
|
|
139
125
|
* Normalize url for comparison.
|
|
@@ -433,3 +433,22 @@ test("only redirects if the request.headers.get('Sec-Fetch-Dest') === 'document'
|
|
|
433
433
|
// Middleware should be called since no redirect for API requests
|
|
434
434
|
expect(apiMiddlewareResolveWasCalled).toBe(true);
|
|
435
435
|
});
|
|
436
|
+
// https://github.com/opral/inlang-paraglide-js/issues/477
|
|
437
|
+
test("does not catch errors thrown by downstream resolve call", async () => {
|
|
438
|
+
const runtime = await createParaglide({
|
|
439
|
+
project: await newProject({
|
|
440
|
+
settings: {
|
|
441
|
+
baseLocale: "en",
|
|
442
|
+
locales: ["en"],
|
|
443
|
+
},
|
|
444
|
+
}),
|
|
445
|
+
compilerOptions: {
|
|
446
|
+
strategy: ["url"],
|
|
447
|
+
},
|
|
448
|
+
});
|
|
449
|
+
await expect(() => runtime.paraglideMiddleware(new Request(new URL("https://example.com/page"), {
|
|
450
|
+
headers: { "Sec-Fetch-Dest": "document" },
|
|
451
|
+
}), () => {
|
|
452
|
+
throw new Error("Downstream error");
|
|
453
|
+
})).rejects.toThrow();
|
|
454
|
+
});
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@inlang/paraglide-js",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "2.0.
|
|
4
|
+
"version": "2.0.2",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"publishConfig": {
|
|
7
7
|
"access": "public",
|
|
@@ -30,8 +30,8 @@
|
|
|
30
30
|
"json5": "2.2.3",
|
|
31
31
|
"unplugin": "^2.1.2",
|
|
32
32
|
"urlpattern-polyfill": "^10.0.0",
|
|
33
|
-
"@inlang/
|
|
34
|
-
"@inlang/
|
|
33
|
+
"@inlang/sdk": "2.4.3",
|
|
34
|
+
"@inlang/recommend-sherlock": "0.2.1"
|
|
35
35
|
},
|
|
36
36
|
"devDependencies": {
|
|
37
37
|
"@eslint/js": "^9.18.0",
|
|
@@ -49,9 +49,9 @@
|
|
|
49
49
|
"typescript": "^5.7.3",
|
|
50
50
|
"typescript-eslint": "^8.20.0",
|
|
51
51
|
"vitest": "2.1.8",
|
|
52
|
-
"@inlang/
|
|
53
|
-
"@
|
|
54
|
-
"@
|
|
52
|
+
"@inlang/plugin-message-format": "4.0.0",
|
|
53
|
+
"@inlang/paraglide-js": "2.0.2",
|
|
54
|
+
"@opral/tsconfig": "1.1.0"
|
|
55
55
|
},
|
|
56
56
|
"keywords": [
|
|
57
57
|
"inlang",
|