@rimelight/ui 0.0.1 → 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.
Files changed (103) hide show
  1. package/package.json +53 -49
  2. package/src/components/carousel/carousel-script.ts +188 -188
  3. package/src/components/carousel/index.ts +1 -1
  4. package/src/components/input-otp/InputOtpTypes.ts +6 -6
  5. package/src/components/radio-group/RadioGroupTypes.ts +6 -6
  6. package/src/components/select/SelectTypes.ts +13 -13
  7. package/src/components/switch/SwitchTypes.ts +6 -6
  8. package/src/components/toast/index.ts +1 -1
  9. package/src/components/toast/toast-manager.ts +234 -234
  10. package/src/components/toggle/ToggleTypes.ts +14 -14
  11. package/src/config/cookies.ts +5 -5
  12. package/src/config/index.ts +3 -3
  13. package/src/config/links.ts +4 -4
  14. package/src/config/site.config.ts +45 -45
  15. package/src/domain/cms/index.ts +1 -1
  16. package/src/domain/cms/types.ts +20 -20
  17. package/src/domain/i18n/constants.ts +21 -21
  18. package/src/domain/i18n/cookie-storage.ts +13 -13
  19. package/src/domain/i18n/country-to-locale-map.ts +67 -67
  20. package/src/domain/i18n/fetcher.ts +268 -268
  21. package/src/domain/i18n/flags.ts +16 -16
  22. package/src/domain/i18n/format.ts +90 -90
  23. package/src/domain/i18n/index.ts +10 -10
  24. package/src/domain/i18n/middleware/i18n.ts +160 -160
  25. package/src/domain/i18n/resolve-locale.ts +55 -55
  26. package/src/domain/i18n/schema.ts +29 -29
  27. package/src/domain/index.ts +4 -4
  28. package/src/domain/seo/constants.ts +20 -20
  29. package/src/domain/seo/index.ts +3 -3
  30. package/src/domain/seo/services/index.ts +3 -3
  31. package/src/domain/seo/services/llms.ts +53 -53
  32. package/src/domain/seo/services/robots.ts +12 -12
  33. package/src/domain/seo/services/sitemap.ts +56 -56
  34. package/src/domain/seo/utils.ts +37 -37
  35. package/src/domain/theme/constants.ts +6 -6
  36. package/src/domain/theme/index.ts +2 -2
  37. package/src/domain/theme/schema.ts +10 -10
  38. package/src/env.d.ts +49 -49
  39. package/src/integrations/index.ts +1 -0
  40. package/src/integrations/sri.ts +92 -0
  41. package/src/lib/component-preview.ts +73 -73
  42. package/src/lib/index.ts +6 -6
  43. package/src/lib/remark/remark-modified-time.ts +13 -13
  44. package/src/lib/showcase-preview-elements.ts +408 -408
  45. package/src/lib/showcase-renderer.ts +218 -218
  46. package/src/lib/showcase-utils.ts +189 -189
  47. package/src/lib/turnstile.ts +35 -35
  48. package/src/lib/utils/starwind/positioning.ts +318 -318
  49. package/src/locales/de/blog.json +9 -9
  50. package/src/locales/de/common.json +19 -19
  51. package/src/locales/de/errors.json +6 -6
  52. package/src/locales/de/home.json +20 -20
  53. package/src/locales/de/messages.json +8 -8
  54. package/src/locales/de/nav.json +13 -13
  55. package/src/locales/de/projects.json +9 -9
  56. package/src/locales/de/services.json +43 -43
  57. package/src/locales/en/blog.json +9 -9
  58. package/src/locales/en/chat.json +29 -29
  59. package/src/locales/en/common.json +19 -19
  60. package/src/locales/en/cookie_notice.json +11 -11
  61. package/src/locales/en/editor.json +24 -24
  62. package/src/locales/en/errors.json +6 -6
  63. package/src/locales/en/home.json +20 -20
  64. package/src/locales/en/messages.json +8 -8
  65. package/src/locales/en/nav.json +13 -13
  66. package/src/locales/en/projects.json +9 -9
  67. package/src/locales/en/services.json +43 -43
  68. package/src/locales/es/blog.json +9 -9
  69. package/src/locales/es/common.json +19 -19
  70. package/src/locales/es/errors.json +6 -6
  71. package/src/locales/es/home.json +20 -20
  72. package/src/locales/es/messages.json +8 -8
  73. package/src/locales/es/nav.json +13 -13
  74. package/src/locales/es/projects.json +9 -9
  75. package/src/locales/es/services.json +43 -43
  76. package/src/locales/ja/blog.json +9 -9
  77. package/src/locales/ja/common.json +19 -19
  78. package/src/locales/ja/errors.json +6 -6
  79. package/src/locales/ja/home.json +20 -20
  80. package/src/locales/ja/messages.json +8 -8
  81. package/src/locales/ja/nav.json +13 -13
  82. package/src/locales/ja/projects.json +9 -9
  83. package/src/locales/ja/services.json +43 -43
  84. package/src/locales/pt/blog.json +9 -9
  85. package/src/locales/pt/chat.json +29 -29
  86. package/src/locales/pt/common.json +19 -19
  87. package/src/locales/pt/cookie_notice.json +11 -11
  88. package/src/locales/pt/editor.json +24 -24
  89. package/src/locales/pt/errors.json +6 -6
  90. package/src/locales/pt/home.json +20 -20
  91. package/src/locales/pt/messages.json +8 -8
  92. package/src/locales/pt/nav.json +13 -13
  93. package/src/locales/pt/projects.json +9 -9
  94. package/src/locales/pt/services.json +43 -43
  95. package/src/middleware/index.ts +1 -0
  96. package/src/middleware/sri.ts +76 -0
  97. package/src/utils/index.ts +2 -2
  98. package/src/utils/server/cookies.ts +98 -98
  99. package/src/utils/server/index.ts +1 -1
  100. package/src/utils/shared/deep-merge.ts +36 -36
  101. package/src/utils/shared/embed.ts +105 -105
  102. package/src/utils/shared/index.ts +3 -3
  103. 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
+ }