@rimelight/ui 0.0.2 → 0.0.3
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 +5 -1
- 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 +45 -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 +268 -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 +160 -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 +20 -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 +53 -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 +37 -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 +1 -0
- package/src/middleware/sri.ts +76 -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
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import type { AstroIntegration } from "astro"
|
|
2
|
+
import { createHash } from "node:crypto"
|
|
3
|
+
|
|
4
|
+
interface SRIConfig {
|
|
5
|
+
security?: {
|
|
6
|
+
csp?: {
|
|
7
|
+
scriptDirective?: {
|
|
8
|
+
resources?: string[]
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
function assertSRIConfig(obj: unknown): asserts obj is SRIConfig {
|
|
15
|
+
if (!obj || typeof obj !== "object") throw new Error("Expected config")
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Astro SRI Integration Fetches external scripts at build-time and generates hashes for the SSR
|
|
20
|
+
* middleware.
|
|
21
|
+
*/
|
|
22
|
+
export function sri(): AstroIntegration {
|
|
23
|
+
const sriManifest: Record<string, string> = {}
|
|
24
|
+
|
|
25
|
+
return {
|
|
26
|
+
name: "sri",
|
|
27
|
+
hooks: {
|
|
28
|
+
"astro:config:setup": async ({ updateConfig, config, logger }) => {
|
|
29
|
+
logger.info("Initializing SRI Discovery...")
|
|
30
|
+
|
|
31
|
+
// 1. Identify External Scripts from CSP config
|
|
32
|
+
// We look into the custom 'security' block in astro.config.mjs
|
|
33
|
+
assertSRIConfig(config)
|
|
34
|
+
|
|
35
|
+
const security = config.security
|
|
36
|
+
const externalUrls: string[] = []
|
|
37
|
+
|
|
38
|
+
if (security?.csp?.scriptDirective?.resources) {
|
|
39
|
+
for (const resource of security.csp.scriptDirective.resources) {
|
|
40
|
+
if (resource.startsWith("https://")) {
|
|
41
|
+
externalUrls.push(resource)
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// 2. Fetch and Hash External Scripts
|
|
47
|
+
await Promise.all(
|
|
48
|
+
externalUrls.map(async (url) => {
|
|
49
|
+
try {
|
|
50
|
+
logger.info(`Fetching ${url} for SRI hashing...`)
|
|
51
|
+
const response = await fetch(url)
|
|
52
|
+
if (!response.ok) throw new Error(`HTTP ${response.status}`)
|
|
53
|
+
|
|
54
|
+
const buffer = await response.arrayBuffer()
|
|
55
|
+
const hash = createHash("sha384").update(Buffer.from(buffer)).digest("base64")
|
|
56
|
+
|
|
57
|
+
sriManifest[url] = `sha384-${hash}`
|
|
58
|
+
logger.info(`Successfully hashed ${url}`)
|
|
59
|
+
} catch (err: unknown) {
|
|
60
|
+
const message = err instanceof Error ? err.message : String(err)
|
|
61
|
+
logger.error(`Failed to fetch SRI for ${url}: ${message}`)
|
|
62
|
+
}
|
|
63
|
+
})
|
|
64
|
+
)
|
|
65
|
+
|
|
66
|
+
// 3. Provide hashes to the runtime via Vite's virtual module
|
|
67
|
+
const virtualModuleId = "virtual:sri-manifest"
|
|
68
|
+
const resolvedVirtualModuleId = "\0" + virtualModuleId
|
|
69
|
+
|
|
70
|
+
updateConfig({
|
|
71
|
+
vite: {
|
|
72
|
+
plugins: [
|
|
73
|
+
{
|
|
74
|
+
name: "vite-plugin-sri-manifest",
|
|
75
|
+
resolveId(id) {
|
|
76
|
+
if (id === virtualModuleId) return resolvedVirtualModuleId
|
|
77
|
+
return null
|
|
78
|
+
},
|
|
79
|
+
load(id) {
|
|
80
|
+
if (id === resolvedVirtualModuleId) {
|
|
81
|
+
return `export const manifest = ${JSON.stringify(sriManifest)};`
|
|
82
|
+
}
|
|
83
|
+
return null
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
]
|
|
87
|
+
}
|
|
88
|
+
})
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
@@ -1,73 +1,73 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Component Preview Renderer
|
|
3
|
-
*
|
|
4
|
-
* A simple registry-based system for rendering component previews with dynamic props. Import this
|
|
5
|
-
* module in your page to register component renderers.
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
export type RendererFunction = (props: Record<string, any>, container: HTMLElement) => void
|
|
9
|
-
|
|
10
|
-
const renderers = new Map<string, RendererFunction>()
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
* Register a component renderer
|
|
14
|
-
*
|
|
15
|
-
* @param componentName - The component name (e.g., 'hero', 'button')
|
|
16
|
-
* @param renderFn - Function that renders the component with given props
|
|
17
|
-
*/
|
|
18
|
-
export function registerRenderer(componentName: string, renderFn: RendererFunction) {
|
|
19
|
-
renderers.set(componentName, renderFn)
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
/**
|
|
23
|
-
* Get a registered renderer
|
|
24
|
-
*/
|
|
25
|
-
export function getRenderer(componentName: string): RendererFunction | undefined {
|
|
26
|
-
return renderers.get(componentName)
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
/**
|
|
30
|
-
* Update a preview container with new props
|
|
31
|
-
*/
|
|
32
|
-
export function renderPreview(
|
|
33
|
-
container: HTMLElement,
|
|
34
|
-
componentName: string,
|
|
35
|
-
props: Record<string, any>
|
|
36
|
-
) {
|
|
37
|
-
const renderer = renderers.get(componentName)
|
|
38
|
-
if (renderer) {
|
|
39
|
-
renderer(props, container)
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
/**
|
|
44
|
-
* Helper to create a simple attribute-based renderer For components that can update via data
|
|
45
|
-
* attributes and CSS
|
|
46
|
-
*/
|
|
47
|
-
export function createAttributeRenderer(
|
|
48
|
-
attributeMap: Record<string, string>,
|
|
49
|
-
classUpdater?: (props: Record<string, any>, element: HTMLElement) => void
|
|
50
|
-
): RendererFunction {
|
|
51
|
-
return (props, container) => {
|
|
52
|
-
// Update data attributes
|
|
53
|
-
Object.entries(props).forEach(([key, value]) => {
|
|
54
|
-
const attrName = attributeMap[key] || key
|
|
55
|
-
if (value === undefined || value === null) {
|
|
56
|
-
container.removeAttribute(`data-${attrName}`)
|
|
57
|
-
} else if (typeof value === "boolean") {
|
|
58
|
-
if (value) {
|
|
59
|
-
container.setAttribute(`data-${attrName}`, "true")
|
|
60
|
-
} else {
|
|
61
|
-
container.removeAttribute(`data-${attrName}`)
|
|
62
|
-
}
|
|
63
|
-
} else {
|
|
64
|
-
container.setAttribute(`data-${attrName}`, String(value))
|
|
65
|
-
}
|
|
66
|
-
})
|
|
67
|
-
|
|
68
|
-
// Call custom class updater if provided
|
|
69
|
-
if (classUpdater) {
|
|
70
|
-
classUpdater(props, container)
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
}
|
|
1
|
+
/**
|
|
2
|
+
* Component Preview Renderer
|
|
3
|
+
*
|
|
4
|
+
* A simple registry-based system for rendering component previews with dynamic props. Import this
|
|
5
|
+
* module in your page to register component renderers.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
export type RendererFunction = (props: Record<string, any>, container: HTMLElement) => void
|
|
9
|
+
|
|
10
|
+
const renderers = new Map<string, RendererFunction>()
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Register a component renderer
|
|
14
|
+
*
|
|
15
|
+
* @param componentName - The component name (e.g., 'hero', 'button')
|
|
16
|
+
* @param renderFn - Function that renders the component with given props
|
|
17
|
+
*/
|
|
18
|
+
export function registerRenderer(componentName: string, renderFn: RendererFunction) {
|
|
19
|
+
renderers.set(componentName, renderFn)
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Get a registered renderer
|
|
24
|
+
*/
|
|
25
|
+
export function getRenderer(componentName: string): RendererFunction | undefined {
|
|
26
|
+
return renderers.get(componentName)
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Update a preview container with new props
|
|
31
|
+
*/
|
|
32
|
+
export function renderPreview(
|
|
33
|
+
container: HTMLElement,
|
|
34
|
+
componentName: string,
|
|
35
|
+
props: Record<string, any>
|
|
36
|
+
) {
|
|
37
|
+
const renderer = renderers.get(componentName)
|
|
38
|
+
if (renderer) {
|
|
39
|
+
renderer(props, container)
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Helper to create a simple attribute-based renderer For components that can update via data
|
|
45
|
+
* attributes and CSS
|
|
46
|
+
*/
|
|
47
|
+
export function createAttributeRenderer(
|
|
48
|
+
attributeMap: Record<string, string>,
|
|
49
|
+
classUpdater?: (props: Record<string, any>, element: HTMLElement) => void
|
|
50
|
+
): RendererFunction {
|
|
51
|
+
return (props, container) => {
|
|
52
|
+
// Update data attributes
|
|
53
|
+
Object.entries(props).forEach(([key, value]) => {
|
|
54
|
+
const attrName = attributeMap[key] || key
|
|
55
|
+
if (value === undefined || value === null) {
|
|
56
|
+
container.removeAttribute(`data-${attrName}`)
|
|
57
|
+
} else if (typeof value === "boolean") {
|
|
58
|
+
if (value) {
|
|
59
|
+
container.setAttribute(`data-${attrName}`, "true")
|
|
60
|
+
} else {
|
|
61
|
+
container.removeAttribute(`data-${attrName}`)
|
|
62
|
+
}
|
|
63
|
+
} else {
|
|
64
|
+
container.setAttribute(`data-${attrName}`, String(value))
|
|
65
|
+
}
|
|
66
|
+
})
|
|
67
|
+
|
|
68
|
+
// Call custom class updater if provided
|
|
69
|
+
if (classUpdater) {
|
|
70
|
+
classUpdater(props, container)
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
package/src/lib/index.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
export * from "./turnstile"
|
|
2
|
-
export * from "./component-preview"
|
|
3
|
-
export * from "./showcase-preview-elements"
|
|
4
|
-
export * from "./showcase-renderer"
|
|
5
|
-
export * from "./showcase-utils"
|
|
6
|
-
export * from "./remark/remark-modified-time.ts"
|
|
1
|
+
export * from "./turnstile"
|
|
2
|
+
export * from "./component-preview"
|
|
3
|
+
export * from "./showcase-preview-elements"
|
|
4
|
+
export * from "./showcase-renderer"
|
|
5
|
+
export * from "./showcase-utils"
|
|
6
|
+
export * from "./remark/remark-modified-time.ts"
|
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
import { execSync } from "child_process"
|
|
2
|
-
|
|
3
|
-
export function remarkModifiedTime() {
|
|
4
|
-
return function (_tree: any, file: any) {
|
|
5
|
-
try {
|
|
6
|
-
const filepath = file.history[0]
|
|
7
|
-
const result = execSync(`git log -1 --pretty="format:%cI" "${filepath}"`)
|
|
8
|
-
file.data.astro.frontmatter.lastModified = result.toString()
|
|
9
|
-
} catch {
|
|
10
|
-
file.data.astro.frontmatter.lastModified = new Date().toISOString()
|
|
11
|
-
}
|
|
12
|
-
}
|
|
13
|
-
}
|
|
1
|
+
import { execSync } from "child_process"
|
|
2
|
+
|
|
3
|
+
export function remarkModifiedTime() {
|
|
4
|
+
return function (_tree: any, file: any) {
|
|
5
|
+
try {
|
|
6
|
+
const filepath = file.history[0]
|
|
7
|
+
const result = execSync(`git log -1 --pretty="format:%cI" "${filepath}"`)
|
|
8
|
+
file.data.astro.frontmatter.lastModified = result.toString()
|
|
9
|
+
} catch {
|
|
10
|
+
file.data.astro.frontmatter.lastModified = new Date().toISOString()
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
}
|