@rimelight/ui 0.0.2 → 0.0.4
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/package.json +6 -3
- package/src/components/carousel/carousel-script.ts +188 -188
- package/src/components/carousel/index.ts +1 -1
- package/src/components/input-otp/InputOtpTypes.ts +6 -6
- package/src/components/radio-group/RadioGroupTypes.ts +6 -6
- package/src/components/select/SelectTypes.ts +13 -13
- package/src/components/switch/SwitchTypes.ts +6 -6
- package/src/components/toast/index.ts +1 -1
- package/src/components/toast/toast-manager.ts +234 -234
- package/src/components/toggle/ToggleTypes.ts +14 -14
- package/src/config/cookies.ts +5 -5
- package/src/config/index.ts +3 -3
- package/src/config/links.ts +4 -4
- package/src/config/site.config.ts +27 -45
- package/src/domain/cms/index.ts +1 -1
- package/src/domain/cms/types.ts +20 -20
- package/src/domain/i18n/constants.ts +21 -21
- package/src/domain/i18n/cookie-storage.ts +13 -13
- package/src/domain/i18n/country-to-locale-map.ts +67 -67
- package/src/domain/i18n/fetcher.ts +278 -268
- package/src/domain/i18n/flags.ts +16 -16
- package/src/domain/i18n/format.ts +90 -90
- package/src/domain/i18n/index.ts +10 -10
- package/src/domain/i18n/middleware/i18n.ts +161 -160
- package/src/domain/i18n/resolve-locale.ts +55 -55
- package/src/domain/i18n/schema.ts +29 -29
- package/src/domain/index.ts +4 -4
- package/src/domain/seo/constants.ts +6 -20
- package/src/domain/seo/index.ts +3 -3
- package/src/domain/seo/services/index.ts +3 -3
- package/src/domain/seo/services/llms.ts +56 -53
- package/src/domain/seo/services/robots.ts +12 -12
- package/src/domain/seo/services/sitemap.ts +56 -56
- package/src/domain/seo/utils.ts +36 -37
- package/src/domain/theme/constants.ts +6 -6
- package/src/domain/theme/index.ts +2 -2
- package/src/domain/theme/schema.ts +10 -10
- package/src/env.d.ts +49 -49
- package/src/integrations/index.ts +1 -0
- package/src/integrations/sri.ts +92 -0
- package/src/lib/component-preview.ts +73 -73
- package/src/lib/index.ts +6 -6
- package/src/lib/remark/remark-modified-time.ts +13 -13
- package/src/lib/showcase-preview-elements.ts +408 -408
- package/src/lib/showcase-renderer.ts +218 -218
- package/src/lib/showcase-utils.ts +189 -189
- package/src/lib/turnstile.ts +35 -35
- package/src/lib/utils/starwind/positioning.ts +318 -318
- package/src/locales/de/blog.json +9 -9
- package/src/locales/de/common.json +19 -19
- package/src/locales/de/errors.json +6 -6
- package/src/locales/de/home.json +20 -20
- package/src/locales/de/messages.json +8 -8
- package/src/locales/de/nav.json +13 -13
- package/src/locales/de/projects.json +9 -9
- package/src/locales/de/services.json +43 -43
- package/src/locales/en/blog.json +9 -9
- package/src/locales/en/chat.json +29 -29
- package/src/locales/en/common.json +19 -19
- package/src/locales/en/cookie_notice.json +11 -11
- package/src/locales/en/editor.json +24 -24
- package/src/locales/en/errors.json +6 -6
- package/src/locales/en/home.json +20 -20
- package/src/locales/en/messages.json +8 -8
- package/src/locales/en/nav.json +13 -13
- package/src/locales/en/projects.json +9 -9
- package/src/locales/en/services.json +43 -43
- package/src/locales/es/blog.json +9 -9
- package/src/locales/es/common.json +19 -19
- package/src/locales/es/errors.json +6 -6
- package/src/locales/es/home.json +20 -20
- package/src/locales/es/messages.json +8 -8
- package/src/locales/es/nav.json +13 -13
- package/src/locales/es/projects.json +9 -9
- package/src/locales/es/services.json +43 -43
- package/src/locales/ja/blog.json +9 -9
- package/src/locales/ja/common.json +19 -19
- package/src/locales/ja/errors.json +6 -6
- package/src/locales/ja/home.json +20 -20
- package/src/locales/ja/messages.json +8 -8
- package/src/locales/ja/nav.json +13 -13
- package/src/locales/ja/projects.json +9 -9
- package/src/locales/ja/services.json +43 -43
- package/src/locales/pt/blog.json +9 -9
- package/src/locales/pt/chat.json +29 -29
- package/src/locales/pt/common.json +19 -19
- package/src/locales/pt/cookie_notice.json +11 -11
- package/src/locales/pt/editor.json +24 -24
- package/src/locales/pt/errors.json +6 -6
- package/src/locales/pt/home.json +20 -20
- package/src/locales/pt/messages.json +8 -8
- package/src/locales/pt/nav.json +13 -13
- package/src/locales/pt/projects.json +9 -9
- package/src/locales/pt/services.json +43 -43
- package/src/middleware/index.ts +2 -0
- package/src/middleware/security.ts +15 -0
- package/src/middleware/sri.ts +78 -0
- package/src/utils/index.ts +2 -2
- package/src/utils/server/cookies.ts +98 -98
- package/src/utils/server/index.ts +1 -1
- package/src/utils/shared/deep-merge.ts +36 -36
- package/src/utils/shared/embed.ts +105 -105
- package/src/utils/shared/index.ts +3 -3
- package/src/utils/shared/parse-boolean.ts +14 -14
- package/worker-configuration.d.ts +0 -14791
|
@@ -1,268 +1,278 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
}
|
|
12
|
-
import
|
|
13
|
-
import {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
*
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
const
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
*
|
|
254
|
-
*
|
|
255
|
-
*
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
1
|
+
import { TRANSLATIONS_VERSION } from "./runtime-constants"
|
|
2
|
+
let env: any = {}
|
|
3
|
+
try {
|
|
4
|
+
// @ts-ignore
|
|
5
|
+
const workers = await import(/* @vite-ignore */ "cloudflare:workers")
|
|
6
|
+
env = workers.env
|
|
7
|
+
} catch {
|
|
8
|
+
// Safe fallback for Node.js environments (Astro config, local scripts)
|
|
9
|
+
env = {}
|
|
10
|
+
}
|
|
11
|
+
import type { Locale, Namespace, PickSchema } from "./schema"
|
|
12
|
+
import { deepMerge } from "../../utils/shared/deep-merge"
|
|
13
|
+
import { parseBooleanFlag } from "../../utils/shared/parse-boolean"
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Minimal environment interface for i18n operations. Usually provided by Cloudflare Workers.
|
|
17
|
+
*/
|
|
18
|
+
interface Env {
|
|
19
|
+
TRANSLATIONS: {
|
|
20
|
+
get: (keys: string[], options: { type: "json"; cacheTtl?: number }) => Promise<Map<string, any>>
|
|
21
|
+
}
|
|
22
|
+
I18N_CACHE?: string
|
|
23
|
+
DEBUG_I18N?: string
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// Optional fallbacks (auto-loaded if generated)
|
|
27
|
+
let FALLBACKS: Record<string, unknown> | null = null
|
|
28
|
+
|
|
29
|
+
try {
|
|
30
|
+
FALLBACKS = await import("./fallbacks.generated.ts")
|
|
31
|
+
} catch {
|
|
32
|
+
FALLBACKS = null
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const KV_JSON_OPTIONS = { type: "json" as const, cacheTtl: 3600 }
|
|
36
|
+
|
|
37
|
+
function assertRecord(obj: unknown): asserts obj is Record<string, unknown> {
|
|
38
|
+
if (!obj || typeof obj !== "object") throw new Error("Expected record")
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function assertDefaultCache(obj: unknown): asserts obj is {
|
|
42
|
+
match: (r: Request) => Promise<Response | undefined>
|
|
43
|
+
put: (r: Request, res: Response) => Promise<void>
|
|
44
|
+
} {
|
|
45
|
+
if (!obj || typeof obj !== "object") throw new Error("Expected cache")
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function assertSchema<N extends Namespace>(obj: unknown): asserts obj is PickSchema<N> {
|
|
49
|
+
if (!obj) throw new Error("Expected schema")
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function assertA<N extends Namespace>(obj: unknown): asserts obj is PickSchema<N> {
|
|
53
|
+
if (!obj) throw new Error("Expected result")
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Runtime object provided by Astro via Astro.locals.
|
|
58
|
+
*/
|
|
59
|
+
export interface Runtime {
|
|
60
|
+
cf?: unknown
|
|
61
|
+
cfContext: { waitUntil: (p: Promise<unknown>) => void }
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Fetch translations from KV for a given locale and list of namespaces.
|
|
66
|
+
*
|
|
67
|
+
* Responsibilities:
|
|
68
|
+
*
|
|
69
|
+
* - Build KV keys using namespace and locale (isolated by KV namespace binding)
|
|
70
|
+
* - Optionally use edge cache (controlled by env flag I18N_CACHE)
|
|
71
|
+
* - On cache miss, read from KV and merge with optional FALLBACK_* dictionaries
|
|
72
|
+
* - Persist the merged payload back to the edge cache
|
|
73
|
+
* - If KV is unavailable, fall back to static FALLBACK_* dictionaries only
|
|
74
|
+
*/
|
|
75
|
+
export async function fetchTranslations<N extends Namespace>(
|
|
76
|
+
runtime: Runtime,
|
|
77
|
+
lang: Locale,
|
|
78
|
+
namespaces: readonly N[]
|
|
79
|
+
): Promise<PickSchema<N>> {
|
|
80
|
+
const useCache = isCacheEnabled(env)
|
|
81
|
+
|
|
82
|
+
if (!useCache) {
|
|
83
|
+
debug(env, "i18n cache DISABLED, using KV only", { lang, namespaces })
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
const { cache, waitUntil } = useCache ? getEdgeCache(runtime) : { cache: null, waitUntil: null }
|
|
87
|
+
|
|
88
|
+
const keys = namespaces.map((ns) => `${ns}:${lang}`)
|
|
89
|
+
|
|
90
|
+
const { cacheRequest } = buildCacheKey(lang, namespaces)
|
|
91
|
+
|
|
92
|
+
// 1. Try to serve from edge cache if available and enabled
|
|
93
|
+
if (useCache && cache) {
|
|
94
|
+
try {
|
|
95
|
+
const cached = await cache.match(cacheRequest)
|
|
96
|
+
|
|
97
|
+
if (cached) {
|
|
98
|
+
const json = await cached.json()
|
|
99
|
+
assertSchema<N>(json)
|
|
100
|
+
debug(env, "i18n cache HIT", { lang, namespaces })
|
|
101
|
+
return json
|
|
102
|
+
}
|
|
103
|
+
debug(env, "i18n cache MISS (no entry)", { lang, namespaces })
|
|
104
|
+
} catch (error) {
|
|
105
|
+
debug(env, "i18n cache READ error, falling back to KV", error)
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// 2. Cache is missing, disabled, or unavailable → read from KV
|
|
110
|
+
try {
|
|
111
|
+
const data = await loadTranslationsFromKV(env, keys, namespaces)
|
|
112
|
+
debug(env, "i18n KV OK", { lang, namespaces })
|
|
113
|
+
|
|
114
|
+
// 3. Store the resulting payload in the edge cache asynchronously (if enabled)
|
|
115
|
+
if (useCache && cache && waitUntil) {
|
|
116
|
+
try {
|
|
117
|
+
const response = new Response(JSON.stringify(data), {
|
|
118
|
+
headers: {
|
|
119
|
+
"Content-Type": "application/json; charset=utf-8",
|
|
120
|
+
"Cache-Control": "public, s-maxage=3600, stale-while-revalidate=86400"
|
|
121
|
+
}
|
|
122
|
+
})
|
|
123
|
+
|
|
124
|
+
const putPromise = cache.put(cacheRequest, response.clone())
|
|
125
|
+
|
|
126
|
+
// In real Workers: schedule as a background task.
|
|
127
|
+
// In dev / non-Workers: just await so cache is actually written.
|
|
128
|
+
if (waitUntil) {
|
|
129
|
+
waitUntil(putPromise)
|
|
130
|
+
} else {
|
|
131
|
+
await putPromise
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
debug(env, "i18n cache PUT completed", { lang, namespaces })
|
|
135
|
+
} catch (error) {
|
|
136
|
+
debug(env, "i18n cache WRITE error", error)
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
return data
|
|
141
|
+
} catch (error) {
|
|
142
|
+
debug(env, "i18n KV ERROR, using FALLBACK_* only", error)
|
|
143
|
+
|
|
144
|
+
// 4. Hard fallback to static FALLBACK_* constants if KV is unavailable
|
|
145
|
+
return buildFallbackOnly(namespaces)
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* Narrow runtime.caches and runtime.ctx to the minimal shape needed for using the Cache API and
|
|
151
|
+
* waitUntil in this module.
|
|
152
|
+
*/
|
|
153
|
+
function getEdgeCache(runtime: Runtime): {
|
|
154
|
+
cache: {
|
|
155
|
+
match: (r: Request) => Promise<Response | undefined>
|
|
156
|
+
put: (r: Request, res: Response) => Promise<void>
|
|
157
|
+
} | null
|
|
158
|
+
waitUntil: ((p: Promise<unknown>) => void) | null
|
|
159
|
+
} {
|
|
160
|
+
return {
|
|
161
|
+
cache: getCacheFromStorage(),
|
|
162
|
+
waitUntil: runtime.cfContext?.waitUntil ?? null
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
function getCacheFromStorage(): {
|
|
167
|
+
match: (r: Request) => Promise<Response | undefined>
|
|
168
|
+
put: (r: Request, res: Response) => Promise<void>
|
|
169
|
+
} | null {
|
|
170
|
+
const c = Reflect.get(Object(caches), "default")
|
|
171
|
+
try {
|
|
172
|
+
assertDefaultCache(c)
|
|
173
|
+
return c
|
|
174
|
+
} catch {
|
|
175
|
+
return null
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
/**
|
|
180
|
+
* Build a stable cache key and synthetic Request object used with the Cache API. The URL origin is
|
|
181
|
+
* irrelevant; only the string identity matters.
|
|
182
|
+
*/
|
|
183
|
+
function buildCacheKey<N extends Namespace>(
|
|
184
|
+
lang: Locale,
|
|
185
|
+
namespaces: readonly N[]
|
|
186
|
+
): { cacheId: string; cacheRequest: Request } {
|
|
187
|
+
const cacheId = `i18n:v${TRANSLATIONS_VERSION}:${lang}:${namespaces.join(",")}`
|
|
188
|
+
|
|
189
|
+
const cacheRequest = new Request(`https://i18n-cache/${encodeURIComponent(cacheId)}`)
|
|
190
|
+
|
|
191
|
+
return { cacheId, cacheRequest }
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
/**
|
|
195
|
+
* Read bulk translations from KV and merge with optional FALLBACK_* dictionaries. This is the main
|
|
196
|
+
* "happy-path" loader.
|
|
197
|
+
*/
|
|
198
|
+
async function loadTranslationsFromKV<N extends Namespace>(
|
|
199
|
+
environment: Env,
|
|
200
|
+
keys: string[],
|
|
201
|
+
namespaces: readonly N[]
|
|
202
|
+
): Promise<PickSchema<N>> {
|
|
203
|
+
const resultMap = await environment.TRANSLATIONS.get(keys, KV_JSON_OPTIONS)
|
|
204
|
+
|
|
205
|
+
const data: Partial<PickSchema<N>> = {}
|
|
206
|
+
|
|
207
|
+
for (let i = 0; i < namespaces.length; i++) {
|
|
208
|
+
const ns = namespaces[i]!
|
|
209
|
+
const key = keys[i]!
|
|
210
|
+
const value = resultMap.get(key) ?? {}
|
|
211
|
+
assertRecord(value)
|
|
212
|
+
|
|
213
|
+
const fallbackConstName = `FALLBACK_${String(ns).toUpperCase()}`
|
|
214
|
+
const fallback = FALLBACKS?.[fallbackConstName]
|
|
215
|
+
|
|
216
|
+
if (fallback) {
|
|
217
|
+
assertRecord(fallback)
|
|
218
|
+
Reflect.set(data, ns, deepMerge(fallback, value))
|
|
219
|
+
} else {
|
|
220
|
+
Reflect.set(data, ns, value)
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
assertA<N>(data)
|
|
225
|
+
return data
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
/**
|
|
229
|
+
* Build a payload using only FALLBACK_* dictionaries. Used when KV is unavailable or throws
|
|
230
|
+
* unexpectedly.
|
|
231
|
+
*/
|
|
232
|
+
function buildFallbackOnly<N extends Namespace>(namespaces: readonly N[]): PickSchema<N> {
|
|
233
|
+
const empty: Partial<PickSchema<N>> = {}
|
|
234
|
+
|
|
235
|
+
for (let i = 0; i < namespaces.length; i++) {
|
|
236
|
+
const ns = namespaces[i]!
|
|
237
|
+
const fallbackConstName = `FALLBACK_${String(ns).toUpperCase()}`
|
|
238
|
+
const fallback = FALLBACKS?.[fallbackConstName]
|
|
239
|
+
|
|
240
|
+
;(empty as Record<string, unknown>)[ns] = fallback ?? {}
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
assertSchema<N>(empty)
|
|
244
|
+
return empty
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
/**
|
|
248
|
+
* Determine whether edge caching is enabled.
|
|
249
|
+
*
|
|
250
|
+
* Wrangler var: I18N_CACHE = "on" | "off" | "true" | "false" | "1" | "0"
|
|
251
|
+
*
|
|
252
|
+
* After adding the variable:
|
|
253
|
+
*
|
|
254
|
+
* - Update wrangler.jsonc / wrangler.toml or .dev.vars
|
|
255
|
+
* - Run: npm run typegen
|
|
256
|
+
*/
|
|
257
|
+
function isCacheEnabled(environment: Env): boolean {
|
|
258
|
+
// env.I18N_CACHE is generated by `wrangler types`
|
|
259
|
+
return parseBooleanFlag(environment.I18N_CACHE, /* defaultValue */ true)
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
/**
|
|
263
|
+
* Debug logger controlled by a Wrangler variable.
|
|
264
|
+
*
|
|
265
|
+
* Wrangler var: DEBUG_I18N = "on" | "off" | "true" | "false" | "1" | "0"
|
|
266
|
+
*
|
|
267
|
+
* After adding the variable:
|
|
268
|
+
*
|
|
269
|
+
* - Update wrangler.jsonc / wrangler.toml or .dev.vars
|
|
270
|
+
* - Run: npm run typegen
|
|
271
|
+
*/
|
|
272
|
+
function debug(environment: Env, ...args: unknown[]) {
|
|
273
|
+
const enabled = parseBooleanFlag(environment.DEBUG_I18N, /* defaultValue */ false)
|
|
274
|
+
if (!enabled) return
|
|
275
|
+
|
|
276
|
+
// eslint-disable-next-line no-console
|
|
277
|
+
console.log(...args)
|
|
278
|
+
}
|
package/src/domain/i18n/flags.ts
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
import type { Locale } from "./schema"
|
|
2
|
-
|
|
3
|
-
// Explicit locale → flag mapping
|
|
4
|
-
export const FLAG_CODES = {
|
|
5
|
-
en: "us-4x3",
|
|
6
|
-
ja: "jp-4x3",
|
|
7
|
-
de: "de-4x3",
|
|
8
|
-
es: "es-4x3",
|
|
9
|
-
pt: "br-4x3"
|
|
10
|
-
} as const
|
|
11
|
-
|
|
12
|
-
export type FlagCode = (typeof FLAG_CODES)[keyof typeof FLAG_CODES]
|
|
13
|
-
|
|
14
|
-
export const localeToFlagCode = (locale: Locale): FlagCode | null => {
|
|
15
|
-
return locale in FLAG_CODES ? FLAG_CODES[locale] : null
|
|
16
|
-
}
|
|
1
|
+
import type { Locale } from "./schema"
|
|
2
|
+
|
|
3
|
+
// Explicit locale → flag mapping
|
|
4
|
+
export const FLAG_CODES = {
|
|
5
|
+
en: "us-4x3",
|
|
6
|
+
ja: "jp-4x3",
|
|
7
|
+
de: "de-4x3",
|
|
8
|
+
es: "es-4x3",
|
|
9
|
+
pt: "br-4x3"
|
|
10
|
+
} as const
|
|
11
|
+
|
|
12
|
+
export type FlagCode = (typeof FLAG_CODES)[keyof typeof FLAG_CODES]
|
|
13
|
+
|
|
14
|
+
export const localeToFlagCode = (locale: Locale): FlagCode | null => {
|
|
15
|
+
return locale in FLAG_CODES ? FLAG_CODES[locale] : null
|
|
16
|
+
}
|