@inlang/paraglide-js 2.0.0-beta.20 → 2.0.0-beta.21
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/bundler-plugins/rollup.d.ts +1 -1
- package/dist/bundler-plugins/rollup.d.ts.map +1 -1
- package/dist/bundler-plugins/unplugin.d.ts.map +1 -1
- package/dist/bundler-plugins/unplugin.js +10 -17
- package/dist/compiler/compile-bundle.d.ts.map +1 -1
- package/dist/compiler/compile-bundle.js +9 -21
- package/dist/compiler/compile-bundle.test.js +62 -39
- package/dist/compiler/compile-message.d.ts.map +1 -1
- package/dist/compiler/compile-message.js +5 -2
- package/dist/compiler/compile-message.test.js +23 -0
- package/dist/compiler/compile-project.test.js +26 -0
- package/dist/compiler/compile.d.ts +6 -3
- package/dist/compiler/compile.d.ts.map +1 -1
- package/dist/compiler/compile.js +6 -2
- package/dist/compiler/compile.test.js +6 -2
- package/dist/compiler/compiler-options.d.ts +1 -1
- package/dist/compiler/compiler-options.js +1 -1
- package/dist/compiler/output-structure/locale-modules.d.ts.map +1 -1
- package/dist/compiler/output-structure/locale-modules.js +6 -5
- package/dist/compiler/output-structure/message-modules.d.ts.map +1 -1
- package/dist/compiler/output-structure/message-modules.js +37 -24
- package/dist/compiler/output-structure/message-modules.test.js +48 -0
- package/dist/compiler/runtime/create-runtime.d.ts.map +1 -1
- package/dist/compiler/runtime/create-runtime.js +6 -3
- package/dist/compiler/runtime/extract-locale-from-url.d.ts +2 -2
- package/dist/compiler/runtime/extract-locale-from-url.d.ts.map +1 -1
- package/dist/compiler/runtime/extract-locale-from-url.js +24 -2
- package/dist/compiler/runtime/extract-locale-from-url.test.js +12 -0
- package/dist/compiler/runtime/localize-href.d.ts +63 -27
- package/dist/compiler/runtime/localize-href.d.ts.map +1 -1
- package/dist/compiler/runtime/localize-href.js +64 -38
- package/dist/compiler/runtime/localize-url.d.ts +80 -8
- package/dist/compiler/runtime/localize-url.d.ts.map +1 -1
- package/dist/compiler/runtime/localize-url.js +146 -16
- package/dist/compiler/runtime/localize-url.test.js +84 -0
- package/dist/compiler/runtime/server-middleware.d.ts +1 -3
- package/dist/compiler/runtime/server-middleware.d.ts.map +1 -1
- package/dist/compiler/runtime/server-middleware.js +1 -3
- package/dist/compiler/runtime/variables.d.ts +1 -0
- package/dist/compiler/runtime/variables.d.ts.map +1 -1
- package/dist/compiler/runtime/variables.js +1 -0
- package/dist/compiler/safe-module-id.d.ts +8 -0
- package/dist/compiler/safe-module-id.d.ts.map +1 -0
- package/dist/compiler/safe-module-id.js +71 -0
- package/dist/compiler/safe-module-id.test.d.ts +2 -0
- package/dist/compiler/safe-module-id.test.d.ts.map +1 -0
- package/dist/compiler/safe-module-id.test.js +27 -0
- package/dist/services/env-variables/index.js +1 -1
- package/dist/services/file-handling/write-output.d.ts +1 -1
- package/dist/services/file-handling/write-output.d.ts.map +1 -1
- package/dist/services/file-handling/write-output.js +1 -1
- package/dist/services/file-handling/write-output.test.js +2 -1
- package/package.json +3 -3
|
@@ -1,38 +1,149 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { extractLocaleFromUrl } from "./extract-locale-from-url.js";
|
|
2
|
+
import { getLocale } from "./get-locale.js";
|
|
3
|
+
import { getUrlOrigin } from "./get-url-origin.js";
|
|
4
|
+
import { isLocale } from "./is-locale.js";
|
|
5
|
+
import { baseLocale, TREE_SHAKE_DEFAULT_URL_PATTERN_USED, urlPatterns, } from "./variables.js";
|
|
2
6
|
/**
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
7
|
+
* Lower-level URL localization function, primarily used in server contexts.
|
|
8
|
+
*
|
|
9
|
+
* This function is designed for server-side usage where you need precise control
|
|
10
|
+
* over URL localization, such as in middleware or request handlers. It works with
|
|
11
|
+
* URL objects and always returns absolute URLs.
|
|
12
|
+
*
|
|
13
|
+
* For client-side UI components, use `localizeHref()` instead, which provides
|
|
14
|
+
* a more convenient API with relative paths and automatic locale detection.
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* ```typescript
|
|
18
|
+
* // Server middleware example
|
|
19
|
+
* app.use((req, res, next) => {
|
|
20
|
+
* const url = new URL(req.url, `${req.protocol}://${req.headers.host}`);
|
|
21
|
+
* const localized = localizeUrl(url, { locale: "de" });
|
|
22
|
+
*
|
|
23
|
+
* if (localized.href !== url.href) {
|
|
24
|
+
* return res.redirect(localized.href);
|
|
25
|
+
* }
|
|
26
|
+
* next();
|
|
27
|
+
* });
|
|
28
|
+
* ```
|
|
29
|
+
*
|
|
30
|
+
* @example
|
|
31
|
+
* ```typescript
|
|
32
|
+
* // Using with URL patterns
|
|
33
|
+
* const url = new URL("https://example.com/about");
|
|
34
|
+
* localizeUrl(url, { locale: "de" });
|
|
35
|
+
* // => URL("https://example.com/de/about")
|
|
36
|
+
*
|
|
37
|
+
* // Using with domain-based localization
|
|
38
|
+
* const url = new URL("https://example.com/store");
|
|
39
|
+
* localizeUrl(url, { locale: "de" });
|
|
40
|
+
* // => URL("https://de.example.com/store")
|
|
41
|
+
* ```
|
|
42
|
+
*
|
|
43
|
+
* @param {string | URL} url - The URL to localize. If string, must be absolute.
|
|
44
|
+
* @param {Object} [options] - Options for localization
|
|
45
|
+
* @param {string} [options.locale] - Target locale. If not provided, uses getLocale()
|
|
46
|
+
* @returns {URL} The localized URL, always absolute
|
|
8
47
|
*/
|
|
9
48
|
export function localizeUrl(url, options) {
|
|
10
|
-
|
|
49
|
+
if (TREE_SHAKE_DEFAULT_URL_PATTERN_USED) {
|
|
50
|
+
return localizeUrlDefaultPattern(url, options);
|
|
51
|
+
}
|
|
52
|
+
const locale = options?.locale ?? getLocale();
|
|
53
|
+
const urlObj = typeof url === "string" ? new URL(url) : url;
|
|
54
|
+
const search = urlObj.search;
|
|
11
55
|
for (const element of urlPatterns) {
|
|
12
56
|
const pattern = new URLPattern(element.pattern);
|
|
13
57
|
const match = pattern.exec(urlObj.href);
|
|
14
58
|
if (match) {
|
|
15
59
|
/** @type {Record<string, string | null >} */
|
|
16
60
|
const overrides = {};
|
|
17
|
-
for (const [groupName, value] of Object.entries(element.localizedNamedGroups?.[
|
|
61
|
+
for (const [groupName, value] of Object.entries(element.localizedNamedGroups?.[locale] ?? {})) {
|
|
18
62
|
overrides[groupName] = value;
|
|
19
63
|
}
|
|
20
64
|
const groups = {
|
|
21
65
|
...aggregateGroups(match),
|
|
22
66
|
...overrides,
|
|
23
67
|
};
|
|
24
|
-
return fillPattern(element.pattern, groups);
|
|
68
|
+
return fillPattern(element.pattern, groups, search);
|
|
25
69
|
}
|
|
26
70
|
}
|
|
27
71
|
throw new Error(`No match found for ${url}`);
|
|
28
72
|
}
|
|
29
73
|
/**
|
|
30
|
-
*
|
|
74
|
+
* https://github.com/opral/inlang-paraglide-js/issues/381
|
|
75
|
+
*
|
|
76
|
+
* @param {string | URL} url
|
|
77
|
+
* @param {Object} [options]
|
|
78
|
+
* @param {string} [options.locale]
|
|
79
|
+
* @returns {URL}
|
|
80
|
+
*/
|
|
81
|
+
function localizeUrlDefaultPattern(url, options) {
|
|
82
|
+
const urlObj = typeof url === "string" ? new URL(url, getUrlOrigin()) : new URL(url);
|
|
83
|
+
const locale = options?.locale ?? getLocale();
|
|
84
|
+
const currentLocale = extractLocaleFromUrl(urlObj);
|
|
85
|
+
// If current locale matches target locale, no change needed
|
|
86
|
+
if (currentLocale === locale) {
|
|
87
|
+
return urlObj;
|
|
88
|
+
}
|
|
89
|
+
const pathSegments = urlObj.pathname.split("/").filter(Boolean);
|
|
90
|
+
// If current path starts with a locale, remove it
|
|
91
|
+
if (pathSegments.length > 0 && isLocale(pathSegments[0])) {
|
|
92
|
+
pathSegments.shift();
|
|
93
|
+
}
|
|
94
|
+
// For base locale, don't add prefix
|
|
95
|
+
if (locale === baseLocale) {
|
|
96
|
+
urlObj.pathname = "/" + pathSegments.join("/");
|
|
97
|
+
}
|
|
98
|
+
else {
|
|
99
|
+
// For other locales, add prefix
|
|
100
|
+
urlObj.pathname = "/" + locale + "/" + pathSegments.join("/");
|
|
101
|
+
}
|
|
102
|
+
return urlObj;
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Low-level URL de-localization function, primarily used in server contexts.
|
|
106
|
+
*
|
|
107
|
+
* This function is designed for server-side usage where you need precise control
|
|
108
|
+
* over URL de-localization, such as in middleware or request handlers. It works with
|
|
109
|
+
* URL objects and always returns absolute URLs.
|
|
110
|
+
*
|
|
111
|
+
* For client-side UI components, use `deLocalizeHref()` instead, which provides
|
|
112
|
+
* a more convenient API with relative paths.
|
|
113
|
+
*
|
|
114
|
+
* @example
|
|
115
|
+
* ```typescript
|
|
116
|
+
* // Server middleware example
|
|
117
|
+
* app.use((req, res, next) => {
|
|
118
|
+
* const url = new URL(req.url, `${req.protocol}://${req.headers.host}`);
|
|
119
|
+
* const baseUrl = deLocalizeUrl(url);
|
|
120
|
+
*
|
|
121
|
+
* // Store the base URL for later use
|
|
122
|
+
* req.baseUrl = baseUrl;
|
|
123
|
+
* next();
|
|
124
|
+
* });
|
|
125
|
+
* ```
|
|
126
|
+
*
|
|
127
|
+
* @example
|
|
128
|
+
* ```typescript
|
|
129
|
+
* // Using with URL patterns
|
|
130
|
+
* const url = new URL("https://example.com/de/about");
|
|
131
|
+
* deLocalizeUrl(url); // => URL("https://example.com/about")
|
|
31
132
|
*
|
|
32
|
-
*
|
|
133
|
+
* // Using with domain-based localization
|
|
134
|
+
* const url = new URL("https://de.example.com/store");
|
|
135
|
+
* deLocalizeUrl(url); // => URL("https://example.com/store")
|
|
136
|
+
* ```
|
|
137
|
+
*
|
|
138
|
+
* @param {string | URL} url - The URL to de-localize. If string, must be absolute.
|
|
139
|
+
* @returns {URL} The de-localized URL, always absolute
|
|
33
140
|
*/
|
|
34
141
|
export function deLocalizeUrl(url) {
|
|
35
|
-
|
|
142
|
+
if (TREE_SHAKE_DEFAULT_URL_PATTERN_USED) {
|
|
143
|
+
return deLocalizeUrlDefaultPattern(url);
|
|
144
|
+
}
|
|
145
|
+
const urlObj = new URL(url, getUrlOrigin());
|
|
146
|
+
const search = urlObj.search;
|
|
36
147
|
for (const element of urlPatterns) {
|
|
37
148
|
const pattern = new URLPattern(element.pattern);
|
|
38
149
|
const match = pattern.exec(urlObj.href);
|
|
@@ -46,11 +157,25 @@ export function deLocalizeUrl(url) {
|
|
|
46
157
|
...aggregateGroups(match),
|
|
47
158
|
...overrides,
|
|
48
159
|
};
|
|
49
|
-
return fillPattern(element.pattern, groups);
|
|
160
|
+
return fillPattern(element.pattern, groups, search);
|
|
50
161
|
}
|
|
51
162
|
}
|
|
52
163
|
throw new Error(`No match found for ${url}`);
|
|
53
164
|
}
|
|
165
|
+
/**
|
|
166
|
+
* De-localizes a URL using the default pattern (/:locale/*)
|
|
167
|
+
* @param {string|URL} url
|
|
168
|
+
* @returns {URL}
|
|
169
|
+
*/
|
|
170
|
+
function deLocalizeUrlDefaultPattern(url) {
|
|
171
|
+
const urlObj = typeof url === "string" ? new URL(url, getUrlOrigin()) : new URL(url);
|
|
172
|
+
const pathSegments = urlObj.pathname.split("/").filter(Boolean);
|
|
173
|
+
// If first segment is a locale, remove it
|
|
174
|
+
if (pathSegments.length > 0 && isLocale(pathSegments[0])) {
|
|
175
|
+
urlObj.pathname = "/" + pathSegments.slice(1).join("/");
|
|
176
|
+
}
|
|
177
|
+
return urlObj;
|
|
178
|
+
}
|
|
54
179
|
/**
|
|
55
180
|
* Fills a URL pattern with values for named groups, supporting all URLPattern-style modifiers:
|
|
56
181
|
*
|
|
@@ -67,9 +192,10 @@ export function deLocalizeUrl(url) {
|
|
|
67
192
|
*
|
|
68
193
|
* @param {string} pattern - The URL pattern containing named groups.
|
|
69
194
|
* @param {Record<string, string | null | undefined>} values - Object of values for named groups.
|
|
195
|
+
* @param {string} [search] - Optional search (query) parameters to preserve
|
|
70
196
|
* @returns {URL} - The constructed URL with named groups filled.
|
|
71
197
|
*/
|
|
72
|
-
function fillPattern(pattern, values) {
|
|
198
|
+
function fillPattern(pattern, values, search) {
|
|
73
199
|
const filled = pattern.replace(/(\/?):([a-zA-Z0-9_]+)(\([^)]*\))?([?+*]?)/g, (_, slash, name, __, modifier) => {
|
|
74
200
|
const value = values[name];
|
|
75
201
|
if (value === null) {
|
|
@@ -93,13 +219,17 @@ function fillPattern(pattern, values) {
|
|
|
93
219
|
}
|
|
94
220
|
return `${slash}${value}`;
|
|
95
221
|
});
|
|
96
|
-
|
|
222
|
+
const url = new URL(filled);
|
|
223
|
+
if (search) {
|
|
224
|
+
url.search = search;
|
|
225
|
+
}
|
|
226
|
+
return url;
|
|
97
227
|
}
|
|
98
228
|
/**
|
|
99
229
|
* Aggregates named groups from various parts of the URLPattern match result.
|
|
100
230
|
*
|
|
101
231
|
*
|
|
102
|
-
* @type {(match:
|
|
232
|
+
* @type {(match: any) => Record<string, string | null | undefined>}
|
|
103
233
|
*/
|
|
104
234
|
export function aggregateGroups(match) {
|
|
105
235
|
return {
|
|
@@ -202,3 +202,87 @@ test("localhost with portname", async () => {
|
|
|
202
202
|
expect(runtime.deLocalizeUrl(new URL("http://localhost:5173/")).href).toBe("http://localhost:5173/");
|
|
203
203
|
expect(runtime.deLocalizeUrl(new URL("https://localhost:5173/de")).href).toBe("https://localhost:5173/");
|
|
204
204
|
});
|
|
205
|
+
test("it keeps the query parameters", async () => {
|
|
206
|
+
const runtime = await createRuntimeForTesting({
|
|
207
|
+
baseLocale: "en",
|
|
208
|
+
locales: ["en", "de"],
|
|
209
|
+
compilerOptions: {
|
|
210
|
+
strategy: ["url"],
|
|
211
|
+
urlPatterns: [
|
|
212
|
+
{
|
|
213
|
+
pattern: "https://:domain(.*)/:locale(de)?/:path*",
|
|
214
|
+
deLocalizedNamedGroups: { locale: null },
|
|
215
|
+
localizedNamedGroups: {
|
|
216
|
+
en: { locale: null },
|
|
217
|
+
de: { locale: "de" },
|
|
218
|
+
},
|
|
219
|
+
},
|
|
220
|
+
],
|
|
221
|
+
},
|
|
222
|
+
});
|
|
223
|
+
expect(runtime.localizeUrl("https://example.com/about?foo=bar&baz=qux", {
|
|
224
|
+
locale: "de",
|
|
225
|
+
}).href).toBe("https://example.com/de/about?foo=bar&baz=qux");
|
|
226
|
+
expect(runtime.deLocalizeUrl("https://example.com/de/about?foo=bar&baz=qux").href).toBe("https://example.com/about?foo=bar&baz=qux");
|
|
227
|
+
});
|
|
228
|
+
test("uses getLocale when no locale is provided", async () => {
|
|
229
|
+
const runtime = await createRuntimeForTesting({
|
|
230
|
+
baseLocale: "en",
|
|
231
|
+
locales: ["en", "de"],
|
|
232
|
+
compilerOptions: {
|
|
233
|
+
strategy: ["url"],
|
|
234
|
+
urlPatterns: [
|
|
235
|
+
{
|
|
236
|
+
pattern: "https://:domain(.*)/:locale(de|en)?/:path(.*)?",
|
|
237
|
+
deLocalizedNamedGroups: { locale: null },
|
|
238
|
+
localizedNamedGroups: {
|
|
239
|
+
en: { locale: "en" },
|
|
240
|
+
de: { locale: "de" },
|
|
241
|
+
},
|
|
242
|
+
},
|
|
243
|
+
],
|
|
244
|
+
},
|
|
245
|
+
});
|
|
246
|
+
// Override getLocale to return German
|
|
247
|
+
runtime.overwriteGetLocale(() => "de");
|
|
248
|
+
expect(runtime.getLocale()).toBe("de");
|
|
249
|
+
// Should use "de" from getLocale since no locale provided
|
|
250
|
+
expect(runtime.localizeUrl("https://example.com/about").href).toBe("https://example.com/de/about");
|
|
251
|
+
// Should still use explicit locale when provided
|
|
252
|
+
expect(runtime.localizeUrl("https://example.com/about", { locale: "en" }).href).toBe("https://example.com/en/about");
|
|
253
|
+
});
|
|
254
|
+
// https://github.com/opral/inlang-paraglide-js/issues/381
|
|
255
|
+
test.each([
|
|
256
|
+
// empty url pattern will set TREE_SHAKE_DEFAULT_ULR_PATTERN_USED to true
|
|
257
|
+
{},
|
|
258
|
+
// real default url pattern to align behaviour
|
|
259
|
+
{
|
|
260
|
+
urlPatterns: [
|
|
261
|
+
{
|
|
262
|
+
pattern: ":protocol://:domain(.*)::port?/:locale(de|fr)?/:path(.*)?",
|
|
263
|
+
deLocalizedNamedGroups: { locale: null },
|
|
264
|
+
localizedNamedGroups: {
|
|
265
|
+
en: { locale: null },
|
|
266
|
+
de: { locale: "de" },
|
|
267
|
+
fr: { locale: "fr" },
|
|
268
|
+
},
|
|
269
|
+
},
|
|
270
|
+
],
|
|
271
|
+
},
|
|
272
|
+
])("default url pattern", async (compilerOptions) => {
|
|
273
|
+
const runtime = await createRuntimeForTesting({
|
|
274
|
+
baseLocale: "en",
|
|
275
|
+
locales: ["en", "de"],
|
|
276
|
+
compilerOptions,
|
|
277
|
+
});
|
|
278
|
+
runtime.overwriteGetLocale(() => "en");
|
|
279
|
+
expect(runtime.localizeUrl("https://example.com/about").href).toBe("https://example.com/about");
|
|
280
|
+
runtime.overwriteGetLocale(() => "de");
|
|
281
|
+
expect(runtime.localizeUrl("https://example.com/").href).toBe("https://example.com/de/");
|
|
282
|
+
expect(runtime.localizeUrl("https://example.com/about").href).toBe("https://example.com/de/about");
|
|
283
|
+
// Should still use explicit locale when provided
|
|
284
|
+
expect(runtime.localizeUrl("https://example.com/about", { locale: "de" }).href).toBe("https://example.com/de/about");
|
|
285
|
+
expect(runtime.localizeUrl("https://example.com/about", { locale: "en" }).href).toBe("https://example.com/about");
|
|
286
|
+
expect(runtime.deLocalizeUrl("https://example.com/de/about").href).toBe("https://example.com/about");
|
|
287
|
+
expect(runtime.deLocalizeUrl("https://example.com/about").href).toBe("https://example.com/about");
|
|
288
|
+
});
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
* @param {(args: { request: Request, locale: Locale }) => T | Promise<T>} resolve - Function to handle the request
|
|
19
19
|
*
|
|
20
20
|
* @returns {Promise<Response | any>} Returns either:
|
|
21
|
-
* - A
|
|
21
|
+
* - A `Response` object (302 redirect) if URL localization is needed
|
|
22
22
|
* - The result of the resolve function if no redirect is required
|
|
23
23
|
*
|
|
24
24
|
* @example
|
|
@@ -42,8 +42,6 @@
|
|
|
42
42
|
* });
|
|
43
43
|
* });
|
|
44
44
|
* ```
|
|
45
|
-
*
|
|
46
|
-
* @see {@link https://inlang.com/documentation/paraglide-js/server-middleware|Server Middleware Documentation}
|
|
47
45
|
*/
|
|
48
46
|
export function serverMiddleware<T>(request: Request, resolve: (args: {
|
|
49
47
|
request: Request;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server-middleware.d.ts","sourceRoot":"","sources":["../../../src/compiler/runtime/server-middleware.js"],"names":[],"mappings":"AAgBA
|
|
1
|
+
{"version":3,"file":"server-middleware.d.ts","sourceRoot":"","sources":["../../../src/compiler/runtime/server-middleware.js"],"names":[],"mappings":"AAgBA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4CG;AACH,iCA/Ba,CAAC,WAEH,OAAO,WACP,CAAC,IAAI,EAAE;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,KAAK,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,GAE5D,OAAO,CAAC,QAAQ,GAAG,GAAG,CAAC,CAyDnC"}
|
|
@@ -32,7 +32,7 @@ let serverMiddlewareAsyncStorage = undefined;
|
|
|
32
32
|
* @param {(args: { request: Request, locale: Locale }) => T | Promise<T>} resolve - Function to handle the request
|
|
33
33
|
*
|
|
34
34
|
* @returns {Promise<Response | any>} Returns either:
|
|
35
|
-
* - A
|
|
35
|
+
* - A `Response` object (302 redirect) if URL localization is needed
|
|
36
36
|
* - The result of the resolve function if no redirect is required
|
|
37
37
|
*
|
|
38
38
|
* @example
|
|
@@ -56,8 +56,6 @@ let serverMiddlewareAsyncStorage = undefined;
|
|
|
56
56
|
* });
|
|
57
57
|
* });
|
|
58
58
|
* ```
|
|
59
|
-
*
|
|
60
|
-
* @see {@link https://inlang.com/documentation/paraglide-js/server-middleware|Server Middleware Documentation}
|
|
61
59
|
*/
|
|
62
60
|
export async function serverMiddleware(request, resolve) {
|
|
63
61
|
if (!serverMiddlewareAsyncStorage) {
|
|
@@ -36,4 +36,5 @@ export const TREE_SHAKE_COOKIE_STRATEGY_USED: false;
|
|
|
36
36
|
export const TREE_SHAKE_URL_STRATEGY_USED: false;
|
|
37
37
|
export const TREE_SHAKE_GLOBAL_VARIABLE_STRATEGY_USED: false;
|
|
38
38
|
export const TREE_SHAKE_PREFERRED_LANGUAGE_STRATEGY_USED: false;
|
|
39
|
+
export const TREE_SHAKE_DEFAULT_URL_PATTERN_USED: false;
|
|
39
40
|
//# sourceMappingURL=variables.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"variables.d.ts","sourceRoot":"","sources":["../../../src/compiler/runtime/variables.js"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,yBAA0B,IAAI,CAAC;AAE/B;;;;;;;GAOG;AACH,4CAA2D;AAE3D,qBAAqB;AACrB,yBADW,MAAM,CACyB;AAE1C;;GAEG;AACH,uBAFU,KAAK,CAAC,QAAQ,GAAG,YAAY,GAAG,gBAAgB,GAAG,KAAK,GAAG,mBAAmB,CAAC,CAE9C;AAE3C;;;;GAIG;AACH,0BAFU,KAAK,CAAC;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,sBAAsB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC,CAAC;IAAC,oBAAoB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC,CAAC,CAAA;CAAE,CAAC,CAElI;AAE9B,8CAA+C,KAAK,CAAC;AAErD,2CAA4C,KAAK,CAAC;AAElD,uDAAwD,KAAK,CAAC;AAE9D,0DAA2D,KAAK,CAAC"}
|
|
1
|
+
{"version":3,"file":"variables.d.ts","sourceRoot":"","sources":["../../../src/compiler/runtime/variables.js"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,yBAA0B,IAAI,CAAC;AAE/B;;;;;;;GAOG;AACH,4CAA2D;AAE3D,qBAAqB;AACrB,yBADW,MAAM,CACyB;AAE1C;;GAEG;AACH,uBAFU,KAAK,CAAC,QAAQ,GAAG,YAAY,GAAG,gBAAgB,GAAG,KAAK,GAAG,mBAAmB,CAAC,CAE9C;AAE3C;;;;GAIG;AACH,0BAFU,KAAK,CAAC;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,sBAAsB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC,CAAC;IAAC,oBAAoB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC,CAAC,CAAA;CAAE,CAAC,CAElI;AAE9B,8CAA+C,KAAK,CAAC;AAErD,2CAA4C,KAAK,CAAC;AAElD,uDAAwD,KAAK,CAAC;AAE9D,0DAA2D,KAAK,CAAC;AAEjE,kDAAmD,KAAK,CAAC"}
|
|
@@ -32,3 +32,4 @@ export const TREE_SHAKE_COOKIE_STRATEGY_USED = false;
|
|
|
32
32
|
export const TREE_SHAKE_URL_STRATEGY_USED = false;
|
|
33
33
|
export const TREE_SHAKE_GLOBAL_VARIABLE_STRATEGY_USED = false;
|
|
34
34
|
export const TREE_SHAKE_PREFERRED_LANGUAGE_STRATEGY_USED = false;
|
|
35
|
+
export const TREE_SHAKE_DEFAULT_URL_PATTERN_USED = false;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Turns an unsafe module id like `helloWorld🍌` into a safe one like `helloworld__`.
|
|
3
|
+
*
|
|
4
|
+
* Mainly exists to support https://github.com/opral/inlang-paraglide-js/issues/285
|
|
5
|
+
*/
|
|
6
|
+
export declare function toSafeModuleId(id: string): string;
|
|
7
|
+
export declare function isSafeModuleId(id: string): boolean;
|
|
8
|
+
//# sourceMappingURL=safe-module-id.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"safe-module-id.d.ts","sourceRoot":"","sources":["../../src/compiler/safe-module-id.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAYjD;AAED,wBAAgB,cAAc,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAElD"}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Turns an unsafe module id like `helloWorld🍌` into a safe one like `helloworld__`.
|
|
3
|
+
*
|
|
4
|
+
* Mainly exists to support https://github.com/opral/inlang-paraglide-js/issues/285
|
|
5
|
+
*/
|
|
6
|
+
export function toSafeModuleId(id) {
|
|
7
|
+
const result = id.toLowerCase().replace(/[^a-z0-9_]/g, "_");
|
|
8
|
+
const startsWithNumber = result[0]?.match(/[0-9]/);
|
|
9
|
+
if (startsWithNumber) {
|
|
10
|
+
return "_" + result;
|
|
11
|
+
}
|
|
12
|
+
else if (reservedJsKeywords.includes(result)) {
|
|
13
|
+
return "_" + result;
|
|
14
|
+
}
|
|
15
|
+
return result;
|
|
16
|
+
}
|
|
17
|
+
export function isSafeModuleId(id) {
|
|
18
|
+
return toSafeModuleId(id) === id;
|
|
19
|
+
}
|
|
20
|
+
const reservedJsKeywords = [
|
|
21
|
+
"break",
|
|
22
|
+
"case",
|
|
23
|
+
"catch",
|
|
24
|
+
"class",
|
|
25
|
+
"const",
|
|
26
|
+
"continue",
|
|
27
|
+
"debugger",
|
|
28
|
+
"default",
|
|
29
|
+
"delete",
|
|
30
|
+
"do",
|
|
31
|
+
"else",
|
|
32
|
+
"export",
|
|
33
|
+
"extends",
|
|
34
|
+
"false",
|
|
35
|
+
"finally",
|
|
36
|
+
"for",
|
|
37
|
+
"function",
|
|
38
|
+
"if",
|
|
39
|
+
"import",
|
|
40
|
+
"in",
|
|
41
|
+
"instanceof",
|
|
42
|
+
"new",
|
|
43
|
+
"null",
|
|
44
|
+
"return",
|
|
45
|
+
"super",
|
|
46
|
+
"switch",
|
|
47
|
+
"this",
|
|
48
|
+
"throw",
|
|
49
|
+
"true",
|
|
50
|
+
"try",
|
|
51
|
+
"typeof",
|
|
52
|
+
"var",
|
|
53
|
+
"void",
|
|
54
|
+
"while",
|
|
55
|
+
"with",
|
|
56
|
+
//Strict mode reserved keywords
|
|
57
|
+
"let",
|
|
58
|
+
"static",
|
|
59
|
+
"yield",
|
|
60
|
+
"await",
|
|
61
|
+
//Reserved keywords for future use
|
|
62
|
+
"enum",
|
|
63
|
+
"implements",
|
|
64
|
+
"interface",
|
|
65
|
+
"package",
|
|
66
|
+
"private",
|
|
67
|
+
"protected",
|
|
68
|
+
"public",
|
|
69
|
+
// https://github.com/opral/inlang-paraglide-js/issues/331
|
|
70
|
+
"then",
|
|
71
|
+
];
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"safe-module-id.test.d.ts","sourceRoot":"","sources":["../../src/compiler/safe-module-id.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { test, expect } from "vitest";
|
|
2
|
+
import { toSafeModuleId } from "./safe-module-id.js";
|
|
3
|
+
test("handles emojis (because why not)", () => {
|
|
4
|
+
expect(toSafeModuleId("helloWorld🍌")).toBe("helloworld__");
|
|
5
|
+
});
|
|
6
|
+
// https://github.com/opral/inlang-paraglide-js/issues/395
|
|
7
|
+
test("makes everything lowercase", () => {
|
|
8
|
+
expect(toSafeModuleId("HelloWorld")).toBe("helloworld");
|
|
9
|
+
});
|
|
10
|
+
test('escapes "-" to "_"', () => {
|
|
11
|
+
expect(toSafeModuleId("de-DE-bavaria")).toBe("de_de_bavaria");
|
|
12
|
+
});
|
|
13
|
+
test("prefixes with _ if it starts with a number", () => {
|
|
14
|
+
expect(toSafeModuleId("123")).toBe("_123");
|
|
15
|
+
});
|
|
16
|
+
test("handles $ signs", () => {
|
|
17
|
+
expect(toSafeModuleId("default_e$")).toBe("default_e_");
|
|
18
|
+
});
|
|
19
|
+
test("handles . dots", () => {
|
|
20
|
+
expect(toSafeModuleId("hello.world.nested")).toBe("hello_world_nested");
|
|
21
|
+
});
|
|
22
|
+
test("transforms js reserved keywords", async () => {
|
|
23
|
+
expect(toSafeModuleId("import")).toBe("_import");
|
|
24
|
+
expect(toSafeModuleId("let")).toBe("_let");
|
|
25
|
+
// https://github.com/opral/inlang-paraglide-js/issues/331
|
|
26
|
+
expect(toSafeModuleId("then")).toBe("_then");
|
|
27
|
+
});
|
|
@@ -4,5 +4,5 @@ export declare function writeOutput(args: {
|
|
|
4
4
|
output: Record<string, string>;
|
|
5
5
|
fs: typeof nodeFs;
|
|
6
6
|
previousOutputHashes?: Record<string, string>;
|
|
7
|
-
}): Promise<Record<string, string
|
|
7
|
+
}): Promise<Record<string, string>>;
|
|
8
8
|
//# sourceMappingURL=write-output.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"write-output.d.ts","sourceRoot":"","sources":["../../../src/services/file-handling/write-output.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,MAAM,MAAM,kBAAkB,CAAC;AAE3C,wBAAsB,WAAW,CAAC,IAAI,EAAE;IACvC,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC/B,EAAE,EAAE,OAAO,MAAM,CAAC;IAClB,oBAAoB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC9C
|
|
1
|
+
{"version":3,"file":"write-output.d.ts","sourceRoot":"","sources":["../../../src/services/file-handling/write-output.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,MAAM,MAAM,kBAAkB,CAAC;AAE3C,wBAAsB,WAAW,CAAC,IAAI,EAAE;IACvC,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC/B,EAAE,EAAE,OAAO,MAAM,CAAC;IAClB,oBAAoB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC9C,mCA4CA"}
|
|
@@ -51,12 +51,13 @@ it("should only write once if the output hasn't changed", async () => {
|
|
|
51
51
|
output: { "test.txt": "test" },
|
|
52
52
|
fs,
|
|
53
53
|
});
|
|
54
|
-
await writeOutput({
|
|
54
|
+
const hashes2 = await writeOutput({
|
|
55
55
|
directory: "/output",
|
|
56
56
|
output: { "test.txt": "test" },
|
|
57
57
|
fs,
|
|
58
58
|
previousOutputHashes: hashes,
|
|
59
59
|
});
|
|
60
|
+
expect(hashes).toEqual(hashes2);
|
|
60
61
|
expect(await fs.readFile("/output/test.txt", { encoding: "utf-8" })).toBe("test");
|
|
61
62
|
expect(fs.writeFile).toHaveBeenCalledTimes(1);
|
|
62
63
|
});
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@inlang/paraglide-js",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "2.0.0-beta.
|
|
4
|
+
"version": "2.0.0-beta.21",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"publishConfig": {
|
|
7
7
|
"access": "public",
|
|
@@ -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/paraglide-js": "2.0.0-beta.
|
|
52
|
+
"@inlang/paraglide-js": "2.0.0-beta.21",
|
|
53
53
|
"@opral/tsconfig": "1.1.0",
|
|
54
|
-
"@inlang/plugin-message-format": "
|
|
54
|
+
"@inlang/plugin-message-format": "4.0.0"
|
|
55
55
|
},
|
|
56
56
|
"keywords": [
|
|
57
57
|
"inlang",
|