@rimelight/config 0.0.7 → 0.0.8

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/astro/index.ts CHANGED
@@ -1,415 +1,421 @@
1
- import fs from "node:fs"
2
- import path from "node:path"
3
- import cloudflare from "@astrojs/cloudflare"
4
- import { cacheCloudflare } from "@astrojs/cloudflare/cache"
5
- import { fontProviders } from "astro/config"
6
-
7
- export interface CacheRulesPresetOptions {
8
- apiSwrSeconds?: number
9
- pageMaxAgeSeconds?: number
10
- customRules?: Record<string, any>
11
- }
12
-
13
- export function cacheRulesPreset(options: CacheRulesPresetOptions = {}): any {
14
- const { apiSwrSeconds = 600, pageMaxAgeSeconds = 300, customRules = {} } = options
15
- return {
16
- routeRules: {
17
- "/api/[...path]": {
18
- swr: apiSwrSeconds
19
- },
20
- "/[...path]": {
21
- maxAge: pageMaxAgeSeconds
22
- },
23
- ...customRules
24
- }
25
- }
26
- }
27
-
28
- export interface FontsPresetOptions {
29
- fontProviders?: any
30
- fonts?: any[]
31
- }
32
-
33
- export function fontsPreset(options: FontsPresetOptions = {}): any {
34
- const defaultFonts = [
35
- {
36
- name: "Noto Sans",
37
- cssVariable: "--font-sans",
38
- fallbacks: ["sans-serif"],
39
- subsets: ["latin", "latin-ext"],
40
- weights: [400, 500, 600, 700],
41
- styles: ["normal"]
42
- },
43
- {
44
- name: "Noto Serif",
45
- cssVariable: "--font-serif",
46
- fallbacks: ["serif"],
47
- subsets: ["latin", "latin-ext"],
48
- weights: [400, 700],
49
- styles: ["normal"]
50
- },
51
- {
52
- name: "JetBrains Mono",
53
- cssVariable: "--font-mono",
54
- fallbacks: ["monospace"],
55
- subsets: ["latin", "latin-ext"],
56
- weights: [400, 500, 700],
57
- styles: ["normal"]
58
- }
59
- ]
60
-
61
- const provider = (options.fontProviders || fontProviders)?.fontsource
62
- ? (options.fontProviders || fontProviders).fontsource()
63
- : undefined
64
-
65
- return {
66
- fonts: (options.fonts || defaultFonts).map((font) => ({
67
- ...(provider ? { provider } : {}),
68
- ...font
69
- }))
70
- }
71
- }
72
-
73
- export interface ImagePresetOptions {
74
- domains?: string[]
75
- layout?: "constrained" | "fixed" | "full-width" | "responsive"
76
- responsiveStyles?: boolean
77
- }
78
-
79
- export function imagePreset(options: ImagePresetOptions = {}): any {
80
- const { domains = [], layout = "constrained", responsiveStyles = true } = options
81
- return {
82
- image: {
83
- domains,
84
- layout,
85
- responsiveStyles
86
- }
87
- }
88
- }
89
-
90
- export interface CloudflarePresetOptions {
91
- adapter?: any
92
- cacheProvider?: any
93
- session?: boolean
94
- }
95
-
96
- export function cloudflarePreset(options: CloudflarePresetOptions = {}): any {
97
- const { adapter = cloudflare(), cacheProvider = cacheCloudflare(), session = false } = options
98
- return {
99
- output: "server" as const,
100
- session,
101
- adapter,
102
- cache: { provider: cacheProvider }
103
- }
104
- }
105
-
106
- export interface RimelightAstroOptions {
107
- domain?: string
108
- site?: string
109
- imageDomains?: string[]
110
- apiSwrSeconds?: number
111
- pageMaxAgeSeconds?: number
112
- adapter?: any
113
- cacheProvider?: any
114
- fonts?: any[]
115
- solid?: boolean | { include?: string[]; [key: string]: any }
116
- security?:
117
- | boolean
118
- | {
119
- domain?: string
120
- imgSrc?: string[]
121
- directives?: Record<string, any>
122
- [key: string]: any
123
- }
124
- i18n?:
125
- | boolean
126
- | {
127
- translations?: Record<string, any>
128
- locales?: string[]
129
- defaultLocale?: string
130
- prefixDefaultLocale?: boolean
131
- kvBinding?: string
132
- [key: string]: any
133
- }
134
- seo?:
135
- | boolean
136
- | {
137
- robots?: boolean | Record<string, any>
138
- sitemap?: boolean | Record<string, any>
139
- llms?: boolean | Record<string, any>
140
- [key: string]: any
141
- }
142
- cms?:
143
- | boolean
144
- | {
145
- storage?: any
146
- binding?: string
147
- auth?: string
148
- [key: string]: any
149
- }
150
- ui?:
151
- | boolean
152
- | {
153
- logos?: any
154
- shortcuts?: any
155
- [key: string]: any
156
- }
157
- integrations?: any[]
158
- vite?: {
159
- plugins?: any[]
160
- [key: string]: any
161
- }
162
- [key: string]: any
163
- }
164
-
165
- function discoverTranslations(dir = "./src/translations"): Record<string, any> {
166
- const translations: Record<string, any> = {}
167
- try {
168
- const resolvedDir = path.resolve(process.cwd(), dir)
169
- if (fs.existsSync(resolvedDir)) {
170
- const files = fs.readdirSync(resolvedDir)
171
- for (const file of files) {
172
- if (file.endsWith(".json")) {
173
- const locale = path.basename(file, ".json")
174
- const content = JSON.parse(fs.readFileSync(path.join(resolvedDir, file), "utf8"))
175
- translations[locale] = content
176
- }
177
- }
178
- }
179
- } catch {}
180
- return translations
181
- }
182
-
183
- function discoverLogos(dir = "./src/assets/logos"): Record<string, any> | undefined {
184
- try {
185
- const candidateDirs = [dir, "./src/assets/logo"]
186
- let resolvedDir: string | null = null
187
- for (const d of candidateDirs) {
188
- const p = path.resolve(process.cwd(), d)
189
- if (fs.existsSync(p) && fs.statSync(p).isDirectory()) {
190
- resolvedDir = p
191
- break
192
- }
193
- }
194
- if (!resolvedDir) return undefined
195
-
196
- const files = fs.readdirSync(resolvedDir)
197
- const logos: Record<string, any> = {}
198
-
199
- const variants = ["logomark", "logotype", "logo"]
200
- const modes = ["color", "white", "black", "light", "dark"]
201
- const extensions = [".svg", ".png", ".webp", ".jpg", ".jpeg", ".gif"]
202
-
203
- for (const variant of variants) {
204
- for (const mode of modes) {
205
- for (const ext of extensions) {
206
- const fileName = `${variant}_${mode}${ext}`
207
- if (files.includes(fileName)) {
208
- if (!logos[variant]) logos[variant] = {}
209
- const relPath = `./${path.relative(process.cwd(), path.join(resolvedDir, fileName)).replace(/\\/g, "/")}`
210
- logos[variant][mode] = relPath
211
- }
212
- }
213
- }
214
- for (const ext of extensions) {
215
- const fileName = `${variant}${ext}`
216
- if (files.includes(fileName) && !logos[variant]) {
217
- const relPath = `./${path.relative(process.cwd(), path.join(resolvedDir, fileName)).replace(/\\/g, "/")}`
218
- logos[variant] = relPath
219
- }
220
- }
221
- }
222
-
223
- return Object.keys(logos).length > 0 ? logos : undefined
224
- } catch {
225
- return undefined
226
- }
227
- }
228
-
229
- function defaultShortcuts(): Record<string, any> {
230
- return {
231
- categories: {
232
- system: { label: "System" },
233
- navigation: { label: "Navigation" }
234
- }
235
- }
236
- }
237
-
238
- function rimelightIntegration(
239
- options: RimelightAstroOptions,
240
- imageDomains: string[],
241
- domain?: string
242
- ) {
243
- return {
244
- name: "rimelight-auto-plugins",
245
- hooks: {
246
- "astro:config:setup": async ({ updateConfig }: { updateConfig: (config: any) => void }) => {
247
- const integrations: any[] = []
248
- const plugins: any[] = []
249
-
250
- if (options.solid) {
251
- const solidMod = await import("@astrojs/solid-js")
252
- const solidFn = (solidMod as any).default || solidMod
253
- const solidOpts =
254
- typeof options.solid === "object"
255
- ? options.solid
256
- : { include: ["**/solid/**", "**/*.tsx"] }
257
- integrations.push(solidFn(solidOpts))
258
- }
259
-
260
- if (options.seo) {
261
- const seoMod = await import("@rimelight/seo")
262
- const { rimelightSeo } = seoMod as any
263
- const seoOpts = typeof options.seo === "object" ? options.seo : {}
264
- integrations.push(rimelightSeo(seoOpts))
265
- }
266
-
267
- if (options.cms) {
268
- const cmsMod = await import("@rimelight/cms/integration")
269
- const { rimelightCms } = cmsMod as any
270
- const cmsOpts = typeof options.cms === "object" ? options.cms : {}
271
- let storage = cmsOpts.storage
272
- if (!storage) {
273
- const storageMod = await import("@rimelight/cms/storage")
274
- const { r2 } = storageMod as any
275
- storage = r2({ binding: cmsOpts.binding || "BLOB" })
276
- }
277
- integrations.push(
278
- rimelightCms({
279
- storage,
280
- auth: cmsOpts.auth || "./src/auth/auth.ts",
281
- ...cmsOpts
282
- })
283
- )
284
- }
285
-
286
- if (options.security) {
287
- const secMod = await import("@rimelight/security")
288
- const { security: securityFn } = secMod as any
289
- const secOpts = typeof options.security === "object" ? options.security : {}
290
- const defaultImgSrc = imageDomains.map((d: string) =>
291
- d.startsWith("http://") || d.startsWith("https://") ? d : `https://${d}`
292
- )
293
- const imgSrc = secOpts.imgSrc
294
- ? Array.from(new Set([...defaultImgSrc, ...secOpts.imgSrc]))
295
- : defaultImgSrc
296
-
297
- plugins.push(
298
- securityFn({
299
- domain: secOpts.domain || domain,
300
- imgSrc,
301
- ...secOpts
302
- })
303
- )
304
- }
305
-
306
- if (options.i18n) {
307
- const i18nMod = await import("@rimelight/i18n")
308
- const { i18n: i18nFn } = i18nMod as any
309
- const i18nOpts = typeof options.i18n === "object" ? options.i18n : {}
310
- const translations = i18nOpts.translations || discoverTranslations()
311
- const locales = i18nOpts.locales || Object.keys(translations)
312
- const defaultLocale = i18nOpts.defaultLocale || (locales.length > 0 ? locales[0] : "en")
313
- const kvBinding =
314
- i18nOpts.kvBinding ||
315
- (domain ? `${domain.replaceAll(".", "-")}_translations` : undefined)
316
-
317
- plugins.push(
318
- i18nFn({
319
- locales,
320
- defaultLocale,
321
- prefixDefaultLocale: i18nOpts.prefixDefaultLocale ?? true,
322
- translations,
323
- ...(kvBinding ? { kvBinding } : {}),
324
- ...i18nOpts
325
- })
326
- )
327
- }
328
-
329
- if (options.ui) {
330
- const uiMod = await import("@rimelight/ui")
331
- const { ui: uiFn } = uiMod as any
332
- const uiOpts = typeof options.ui === "object" ? options.ui : {}
333
- const discoveredLogos = discoverLogos()
334
-
335
- const mergedLogos = uiOpts.logos
336
- ? { ...discoveredLogos, ...uiOpts.logos }
337
- : discoveredLogos
338
-
339
- const mergedShortcuts =
340
- uiOpts.shortcuts === false
341
- ? undefined
342
- : {
343
- ...defaultShortcuts(),
344
- ...(typeof uiOpts.shortcuts === "object" ? uiOpts.shortcuts : {})
345
- }
346
-
347
- plugins.push(
348
- uiFn({
349
- ...(mergedLogos ? { logos: mergedLogos } : {}),
350
- ...(mergedShortcuts ? { shortcuts: mergedShortcuts } : {}),
351
- ...uiOpts
352
- })
353
- )
354
- }
355
-
356
- updateConfig({
357
- integrations,
358
- vite: {
359
- plugins
360
- }
361
- })
362
- }
363
- }
364
- }
365
- }
366
-
367
- export function rimelightAstroConfig(options: RimelightAstroOptions = {}): any {
368
- const {
369
- domain,
370
- site = domain ? `https://${domain}` : undefined,
371
- imageDomains = domain ? [domain, `cdn.${domain}`, "cdn.rimelight.com"] : [],
372
- apiSwrSeconds = 600,
373
- pageMaxAgeSeconds = 300,
374
- adapter,
375
- cacheProvider,
376
- fonts,
377
- solid,
378
- security,
379
- i18n,
380
- cms,
381
- ui,
382
- seo,
383
- integrations = [],
384
- vite = {},
385
- ...rest
386
- } = options
387
-
388
- const hasFlags = Boolean(solid || security || i18n || cms || ui || seo)
389
-
390
- return {
391
- ...(site ? { site } : {}),
392
- prefetch: {
393
- prefetchAll: true
394
- },
395
- ...cloudflarePreset({
396
- ...(adapter !== undefined ? { adapter } : {}),
397
- ...(cacheProvider !== undefined ? { cacheProvider } : {})
398
- }),
399
- ...cacheRulesPreset({
400
- ...(apiSwrSeconds !== undefined ? { apiSwrSeconds } : {}),
401
- ...(pageMaxAgeSeconds !== undefined ? { pageMaxAgeSeconds } : {})
402
- }),
403
- ...fontsPreset(fonts !== undefined ? { fonts } : {}),
404
- ...imagePreset({ domains: imageDomains }),
405
- markdown: {
406
- syntaxHighlight: "prism" as const
407
- },
408
- integrations: [
409
- ...(hasFlags ? [rimelightIntegration(options, imageDomains, domain)] : []),
410
- ...integrations
411
- ],
412
- vite,
413
- ...rest
414
- }
415
- }
1
+ import fs from "node:fs"
2
+ import path from "node:path"
3
+ import cloudflare from "@astrojs/cloudflare"
4
+ import { cacheCloudflare } from "@astrojs/cloudflare/cache"
5
+ import { fontProviders } from "astro/config"
6
+
7
+ export interface CacheRulesPresetOptions {
8
+ apiSwrSeconds?: number
9
+ pageMaxAgeSeconds?: number
10
+ customRules?: Record<string, any>
11
+ }
12
+
13
+ export function cacheRulesPreset(options: CacheRulesPresetOptions = {}): any {
14
+ const { apiSwrSeconds = 600, pageMaxAgeSeconds = 300, customRules = {} } = options
15
+ return {
16
+ routeRules: {
17
+ "/api/[...path]": {
18
+ swr: apiSwrSeconds
19
+ },
20
+ "/[...path]": {
21
+ maxAge: pageMaxAgeSeconds
22
+ },
23
+ ...customRules
24
+ }
25
+ }
26
+ }
27
+
28
+ export interface FontsPresetOptions {
29
+ fontProviders?: any
30
+ fonts?: any[]
31
+ }
32
+
33
+ export function fontsPreset(options: FontsPresetOptions = {}): any {
34
+ const defaultFonts = [
35
+ {
36
+ name: "Noto Sans",
37
+ cssVariable: "--font-sans",
38
+ fallbacks: ["sans-serif"],
39
+ subsets: ["latin", "latin-ext"],
40
+ weights: [400, 500, 600, 700],
41
+ styles: ["normal"]
42
+ },
43
+ {
44
+ name: "Noto Serif",
45
+ cssVariable: "--font-serif",
46
+ fallbacks: ["serif"],
47
+ subsets: ["latin", "latin-ext"],
48
+ weights: [400, 700],
49
+ styles: ["normal"]
50
+ },
51
+ {
52
+ name: "JetBrains Mono",
53
+ cssVariable: "--font-mono",
54
+ fallbacks: ["monospace"],
55
+ subsets: ["latin", "latin-ext"],
56
+ weights: [400, 500, 700],
57
+ styles: ["normal"]
58
+ }
59
+ ]
60
+
61
+ const provider = (options.fontProviders || fontProviders)?.fontsource
62
+ ? (options.fontProviders || fontProviders).fontsource()
63
+ : undefined
64
+
65
+ return {
66
+ fonts: (options.fonts || defaultFonts).map((font) => ({
67
+ ...(provider ? { provider } : {}),
68
+ ...font
69
+ }))
70
+ }
71
+ }
72
+
73
+ export interface ImagePresetOptions {
74
+ domains?: string[]
75
+ layout?: "constrained" | "fixed" | "full-width" | "responsive"
76
+ responsiveStyles?: boolean
77
+ }
78
+
79
+ export function imagePreset(options: ImagePresetOptions = {}): any {
80
+ const { domains = [], layout = "constrained", responsiveStyles = true } = options
81
+ return {
82
+ image: {
83
+ domains,
84
+ layout,
85
+ responsiveStyles
86
+ }
87
+ }
88
+ }
89
+
90
+ export interface CloudflarePresetOptions {
91
+ adapter?: any
92
+ cacheProvider?: any
93
+ session?: boolean
94
+ }
95
+
96
+ export function cloudflarePreset(options: CloudflarePresetOptions = {}): any {
97
+ const { adapter = cloudflare(), cacheProvider = cacheCloudflare(), session = false } = options
98
+ return {
99
+ output: "server" as const,
100
+ session,
101
+ adapter,
102
+ cache: { provider: cacheProvider }
103
+ }
104
+ }
105
+
106
+ export interface RimelightAstroOptions {
107
+ domain?: string
108
+ site?: string
109
+ imageDomains?: string[]
110
+ apiSwrSeconds?: number
111
+ pageMaxAgeSeconds?: number
112
+ adapter?: any
113
+ cacheProvider?: any
114
+ fonts?: any[]
115
+ solid?: boolean | { include?: string[]; [key: string]: any }
116
+ security?:
117
+ | boolean
118
+ | {
119
+ domain?: string
120
+ imgSrc?: string[]
121
+ directives?: Record<string, any>
122
+ [key: string]: any
123
+ }
124
+ i18n?:
125
+ | boolean
126
+ | {
127
+ translations?: Record<string, any>
128
+ locales?: string[]
129
+ defaultLocale?: string
130
+ prefixDefaultLocale?: boolean
131
+ kvBinding?: string
132
+ [key: string]: any
133
+ }
134
+ seo?:
135
+ | boolean
136
+ | {
137
+ robots?: boolean | Record<string, any>
138
+ sitemap?: boolean | Record<string, any>
139
+ rss?: boolean | Record<string, any>
140
+ llms?: boolean | Record<string, any>
141
+ llmsFull?: boolean | Record<string, any>
142
+ [key: string]: any
143
+ }
144
+ cms?:
145
+ | boolean
146
+ | {
147
+ storage?: any
148
+ binding?: string
149
+ auth?: string
150
+ [key: string]: any
151
+ }
152
+ ui?:
153
+ | boolean
154
+ | {
155
+ logos?: any
156
+ shortcuts?: any
157
+ [key: string]: any
158
+ }
159
+ integrations?: any[]
160
+ vite?: {
161
+ plugins?: any[]
162
+ [key: string]: any
163
+ }
164
+ [key: string]: any
165
+ }
166
+
167
+ function discoverTranslations(dir = "./src/translations"): Record<string, any> {
168
+ const translations: Record<string, any> = {}
169
+ try {
170
+ const resolvedDir = path.resolve(process.cwd(), dir)
171
+ if (fs.existsSync(resolvedDir)) {
172
+ const files = fs.readdirSync(resolvedDir)
173
+ for (const file of files) {
174
+ if (file.endsWith(".json")) {
175
+ const locale = path.basename(file, ".json")
176
+ const content = JSON.parse(fs.readFileSync(path.join(resolvedDir, file), "utf8"))
177
+ translations[locale] = content
178
+ }
179
+ }
180
+ }
181
+ } catch {}
182
+ return translations
183
+ }
184
+
185
+ function discoverLogos(dir = "./src/assets/logos"): Record<string, any> | undefined {
186
+ try {
187
+ const candidateDirs = [dir, "./src/assets/logo"]
188
+ let resolvedDir: string | null = null
189
+ for (const d of candidateDirs) {
190
+ const p = path.resolve(process.cwd(), d)
191
+ if (fs.existsSync(p) && fs.statSync(p).isDirectory()) {
192
+ resolvedDir = p
193
+ break
194
+ }
195
+ }
196
+ if (!resolvedDir) return undefined
197
+
198
+ const files = fs.readdirSync(resolvedDir)
199
+ const logos: Record<string, any> = {}
200
+
201
+ const variants = ["logomark", "logotype", "logo"]
202
+ const modes = ["color", "white", "black", "light", "dark"]
203
+ const extensions = [".svg", ".png", ".webp", ".jpg", ".jpeg", ".gif"]
204
+
205
+ for (const variant of variants) {
206
+ for (const mode of modes) {
207
+ for (const ext of extensions) {
208
+ const fileName = `${variant}_${mode}${ext}`
209
+ if (files.includes(fileName)) {
210
+ if (!logos[variant]) logos[variant] = {}
211
+ const relPath = `./${path.relative(process.cwd(), path.join(resolvedDir, fileName)).replace(/\\/g, "/")}`
212
+ logos[variant][mode] = relPath
213
+ }
214
+ }
215
+ }
216
+ for (const ext of extensions) {
217
+ const fileName = `${variant}${ext}`
218
+ if (files.includes(fileName) && !logos[variant]) {
219
+ const relPath = `./${path.relative(process.cwd(), path.join(resolvedDir, fileName)).replace(/\\/g, "/")}`
220
+ logos[variant] = relPath
221
+ }
222
+ }
223
+ }
224
+
225
+ return Object.keys(logos).length > 0 ? logos : undefined
226
+ } catch {
227
+ return undefined
228
+ }
229
+ }
230
+
231
+ function defaultShortcuts(): Record<string, any> {
232
+ return {
233
+ categories: {
234
+ system: { label: "System" },
235
+ navigation: { label: "Navigation" }
236
+ }
237
+ }
238
+ }
239
+
240
+ function rimelightIntegration(
241
+ options: RimelightAstroOptions,
242
+ imageDomains: string[],
243
+ domain?: string
244
+ ) {
245
+ return {
246
+ name: "rimelight-auto-plugins",
247
+ hooks: {
248
+ "astro:config:setup": async ({ updateConfig }: { updateConfig: (config: any) => void }) => {
249
+ const integrations: any[] = []
250
+ const plugins: any[] = []
251
+
252
+ if (options.solid) {
253
+ const solidMod = await import("@astrojs/solid-js")
254
+ const solidFn = (solidMod as any).default || solidMod
255
+ const solidOpts =
256
+ typeof options.solid === "object"
257
+ ? options.solid
258
+ : { include: ["**/solid/**", "**/*.tsx"] }
259
+ integrations.push(solidFn(solidOpts))
260
+ }
261
+
262
+ if (options.seo) {
263
+ const seoMod = await import("@rimelight/seo")
264
+ const seoFn =
265
+ (seoMod as any).rimelightSeo ||
266
+ (seoMod as any).default?.rimelightSeo ||
267
+ (seoMod as any).default ||
268
+ seoMod
269
+ const seoOpts = typeof options.seo === "object" ? options.seo : {}
270
+ integrations.push(seoFn(seoOpts))
271
+ }
272
+
273
+ if (options.cms) {
274
+ const cmsMod = await import("@rimelight/cms/integration")
275
+ const { rimelightCms } = cmsMod as any
276
+ const cmsOpts = typeof options.cms === "object" ? options.cms : {}
277
+ let storage = cmsOpts.storage
278
+ if (!storage) {
279
+ const storageMod = await import("@rimelight/cms/storage")
280
+ const { r2 } = storageMod as any
281
+ storage = r2({ binding: cmsOpts.binding || "BLOB" })
282
+ }
283
+ integrations.push(
284
+ rimelightCms({
285
+ storage,
286
+ auth: cmsOpts.auth || "./src/auth/auth.ts",
287
+ ...cmsOpts
288
+ })
289
+ )
290
+ }
291
+
292
+ if (options.security) {
293
+ const secMod = await import("@rimelight/security")
294
+ const { security: securityFn } = secMod as any
295
+ const secOpts = typeof options.security === "object" ? options.security : {}
296
+ const defaultImgSrc = imageDomains.map((d: string) =>
297
+ d.startsWith("http://") || d.startsWith("https://") ? d : `https://${d}`
298
+ )
299
+ const imgSrc = secOpts.imgSrc
300
+ ? Array.from(new Set([...defaultImgSrc, ...secOpts.imgSrc]))
301
+ : defaultImgSrc
302
+
303
+ plugins.push(
304
+ securityFn({
305
+ domain: secOpts.domain || domain,
306
+ imgSrc,
307
+ ...secOpts
308
+ })
309
+ )
310
+ }
311
+
312
+ if (options.i18n) {
313
+ const i18nMod = await import("@rimelight/i18n")
314
+ const { i18n: i18nFn } = i18nMod as any
315
+ const i18nOpts = typeof options.i18n === "object" ? options.i18n : {}
316
+ const translations = i18nOpts.translations || discoverTranslations()
317
+ const locales = i18nOpts.locales || Object.keys(translations)
318
+ const defaultLocale = i18nOpts.defaultLocale || (locales.length > 0 ? locales[0] : "en")
319
+ const kvBinding =
320
+ i18nOpts.kvBinding ||
321
+ (domain ? `${domain.replaceAll(".", "-")}_translations` : undefined)
322
+
323
+ plugins.push(
324
+ i18nFn({
325
+ locales,
326
+ defaultLocale,
327
+ prefixDefaultLocale: i18nOpts.prefixDefaultLocale ?? true,
328
+ translations,
329
+ ...(kvBinding ? { kvBinding } : {}),
330
+ ...i18nOpts
331
+ })
332
+ )
333
+ }
334
+
335
+ if (options.ui) {
336
+ const uiMod = await import("@rimelight/ui")
337
+ const { ui: uiFn } = uiMod as any
338
+ const uiOpts = typeof options.ui === "object" ? options.ui : {}
339
+ const discoveredLogos = discoverLogos()
340
+
341
+ const mergedLogos = uiOpts.logos
342
+ ? { ...discoveredLogos, ...uiOpts.logos }
343
+ : discoveredLogos
344
+
345
+ const mergedShortcuts =
346
+ uiOpts.shortcuts === false
347
+ ? undefined
348
+ : {
349
+ ...defaultShortcuts(),
350
+ ...(typeof uiOpts.shortcuts === "object" ? uiOpts.shortcuts : {})
351
+ }
352
+
353
+ plugins.push(
354
+ uiFn({
355
+ ...(mergedLogos ? { logos: mergedLogos } : {}),
356
+ ...(mergedShortcuts ? { shortcuts: mergedShortcuts } : {}),
357
+ ...uiOpts
358
+ })
359
+ )
360
+ }
361
+
362
+ updateConfig({
363
+ integrations,
364
+ vite: {
365
+ plugins
366
+ }
367
+ })
368
+ }
369
+ }
370
+ }
371
+ }
372
+
373
+ export function rimelightAstroConfig(options: RimelightAstroOptions = {}): any {
374
+ const {
375
+ domain,
376
+ site = domain ? `https://${domain}` : undefined,
377
+ imageDomains = domain ? [domain, `cdn.${domain}`, "cdn.rimelight.com"] : [],
378
+ apiSwrSeconds = 600,
379
+ pageMaxAgeSeconds = 300,
380
+ adapter,
381
+ cacheProvider,
382
+ fonts,
383
+ solid,
384
+ security,
385
+ i18n,
386
+ cms,
387
+ ui,
388
+ seo,
389
+ integrations = [],
390
+ vite = {},
391
+ ...rest
392
+ } = options
393
+
394
+ const hasFlags = Boolean(solid || security || i18n || cms || ui || seo)
395
+
396
+ return {
397
+ ...(site ? { site } : {}),
398
+ prefetch: {
399
+ prefetchAll: true
400
+ },
401
+ ...cloudflarePreset({
402
+ ...(adapter !== undefined ? { adapter } : {}),
403
+ ...(cacheProvider !== undefined ? { cacheProvider } : {})
404
+ }),
405
+ ...cacheRulesPreset({
406
+ ...(apiSwrSeconds !== undefined ? { apiSwrSeconds } : {}),
407
+ ...(pageMaxAgeSeconds !== undefined ? { pageMaxAgeSeconds } : {})
408
+ }),
409
+ ...fontsPreset(fonts !== undefined ? { fonts } : {}),
410
+ ...imagePreset({ domains: imageDomains }),
411
+ markdown: {
412
+ syntaxHighlight: "prism" as const
413
+ },
414
+ integrations: [
415
+ ...(hasFlags ? [rimelightIntegration(options, imageDomains, domain)] : []),
416
+ ...integrations
417
+ ],
418
+ vite,
419
+ ...rest
420
+ }
421
+ }