@rimelight/config 0.0.8 → 0.0.10

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