@duffcloudservices/cms-astro 0.1.1 → 0.1.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/README.md +177 -177
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -1,177 +1,177 @@
|
|
|
1
|
-
# @duffcloudservices/cms-astro
|
|
2
|
-
|
|
3
|
-
Astro integration for DCS CMS content and SEO management.
|
|
4
|
-
|
|
5
|
-
## Installation
|
|
6
|
-
|
|
7
|
-
```bash
|
|
8
|
-
pnpm add @duffcloudservices/cms-astro
|
|
9
|
-
```
|
|
10
|
-
|
|
11
|
-
## Usage
|
|
12
|
-
|
|
13
|
-
### Configuration
|
|
14
|
-
|
|
15
|
-
```typescript
|
|
16
|
-
// astro.config.mjs
|
|
17
|
-
import { defineConfig } from 'astro/config'
|
|
18
|
-
import dcs from '@duffcloudservices/cms-astro'
|
|
19
|
-
|
|
20
|
-
export default defineConfig({
|
|
21
|
-
integrations: [dcs()],
|
|
22
|
-
})
|
|
23
|
-
```
|
|
24
|
-
|
|
25
|
-
### Using in Components
|
|
26
|
-
|
|
27
|
-
```astro
|
|
28
|
-
---
|
|
29
|
-
// src/pages/index.astro
|
|
30
|
-
import { t, getPageSeo, getPageContent } from '@duffcloudservices/cms-astro'
|
|
31
|
-
|
|
32
|
-
const seo = getPageSeo('home')
|
|
33
|
-
const content = getPageContent('home')
|
|
34
|
-
---
|
|
35
|
-
<html>
|
|
36
|
-
<head>
|
|
37
|
-
<title>{seo?.title}</title>
|
|
38
|
-
<meta name="description" content={seo?.description} />
|
|
39
|
-
{seo?.openGraph?.image && (
|
|
40
|
-
<meta property="og:image" content={seo.openGraph.image} />
|
|
41
|
-
)}
|
|
42
|
-
</head>
|
|
43
|
-
<body>
|
|
44
|
-
<h1>{t('home', 'hero.title', 'Welcome')}</h1>
|
|
45
|
-
<p>{t('home', 'hero.subtitle', 'Build amazing things')}</p>
|
|
46
|
-
|
|
47
|
-
<!-- Or use content object directly -->
|
|
48
|
-
<p>{content['cta.text']}</p>
|
|
49
|
-
</body>
|
|
50
|
-
</html>
|
|
51
|
-
```
|
|
52
|
-
|
|
53
|
-
### DCS Configuration Files
|
|
54
|
-
|
|
55
|
-
Create `.dcs/content.yaml`:
|
|
56
|
-
|
|
57
|
-
```yaml
|
|
58
|
-
version: 1
|
|
59
|
-
global:
|
|
60
|
-
nav.home: Home
|
|
61
|
-
footer.copyright: © 2026 Company
|
|
62
|
-
pages:
|
|
63
|
-
home:
|
|
64
|
-
hero.title: Welcome to Our Site
|
|
65
|
-
hero.subtitle: Build something amazing
|
|
66
|
-
cta.text: Get Started
|
|
67
|
-
```
|
|
68
|
-
|
|
69
|
-
Create `.dcs/seo.yaml`:
|
|
70
|
-
|
|
71
|
-
```yaml
|
|
72
|
-
version: 1
|
|
73
|
-
global:
|
|
74
|
-
siteName: My Site
|
|
75
|
-
defaultTitle: My Site
|
|
76
|
-
titleTemplate: "%s | My Site"
|
|
77
|
-
images:
|
|
78
|
-
ogDefault: /images/og-default.jpg
|
|
79
|
-
pages:
|
|
80
|
-
home:
|
|
81
|
-
title: Welcome
|
|
82
|
-
description: The homepage of My Site
|
|
83
|
-
```
|
|
84
|
-
|
|
85
|
-
## API
|
|
86
|
-
|
|
87
|
-
### Integration Options
|
|
88
|
-
|
|
89
|
-
```typescript
|
|
90
|
-
dcs({
|
|
91
|
-
contentPath: '.dcs/content.yaml', // Path to content file
|
|
92
|
-
seoPath: '.dcs/seo.yaml', // Path to SEO file
|
|
93
|
-
debug: false, // Enable debug logging
|
|
94
|
-
})
|
|
95
|
-
```
|
|
96
|
-
|
|
97
|
-
### Runtime Functions
|
|
98
|
-
|
|
99
|
-
#### `t(page, key, fallback?)`
|
|
100
|
-
|
|
101
|
-
Get text for a specific page and key.
|
|
102
|
-
|
|
103
|
-
```astro
|
|
104
|
-
{t('home', 'hero.title', 'Default Title')}
|
|
105
|
-
```
|
|
106
|
-
|
|
107
|
-
#### `getContent()`
|
|
108
|
-
|
|
109
|
-
Get the full content configuration object.
|
|
110
|
-
|
|
111
|
-
#### `getSeo()`
|
|
112
|
-
|
|
113
|
-
Get the full SEO configuration object.
|
|
114
|
-
|
|
115
|
-
#### `getPageContent(page)`
|
|
116
|
-
|
|
117
|
-
Get all content for a page (global merged with page-specific).
|
|
118
|
-
|
|
119
|
-
```astro
|
|
120
|
-
---
|
|
121
|
-
const content = getPageContent('home')
|
|
122
|
-
---
|
|
123
|
-
{Object.entries(content).map(([key, value]) => (
|
|
124
|
-
<p>{key}: {value}</p>
|
|
125
|
-
))}
|
|
126
|
-
```
|
|
127
|
-
|
|
128
|
-
#### `getPageSeo(page, overrides?)`
|
|
129
|
-
|
|
130
|
-
Get resolved SEO for a page with optional overrides.
|
|
131
|
-
|
|
132
|
-
```astro
|
|
133
|
-
---
|
|
134
|
-
const seo = getPageSeo('home', { title: 'Custom Title' })
|
|
135
|
-
---
|
|
136
|
-
<title>{seo?.title}</title>
|
|
137
|
-
```
|
|
138
|
-
|
|
139
|
-
## Advanced Usage
|
|
140
|
-
|
|
141
|
-
### Layout Component with SEO
|
|
142
|
-
|
|
143
|
-
```astro
|
|
144
|
-
---
|
|
145
|
-
// src/layouts/BaseLayout.astro
|
|
146
|
-
import { getPageSeo } from '@duffcloudservices/cms-astro'
|
|
147
|
-
|
|
148
|
-
interface Props {
|
|
149
|
-
page: string
|
|
150
|
-
titleOverride?: string
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
const { page, titleOverride } = Astro.props
|
|
154
|
-
const seo = getPageSeo(page, titleOverride ? { title: titleOverride } : undefined)
|
|
155
|
-
---
|
|
156
|
-
<!DOCTYPE html>
|
|
157
|
-
<html lang="en">
|
|
158
|
-
<head>
|
|
159
|
-
<meta charset="UTF-8" />
|
|
160
|
-
<meta name="viewport" content="width=device-width" />
|
|
161
|
-
<title>{seo?.title ?? 'My Site'}</title>
|
|
162
|
-
{seo?.description && (
|
|
163
|
-
<meta name="description" content={seo.description} />
|
|
164
|
-
)}
|
|
165
|
-
{seo?.canonical && (
|
|
166
|
-
<link rel="canonical" href={seo.canonical} />
|
|
167
|
-
)}
|
|
168
|
-
</head>
|
|
169
|
-
<body>
|
|
170
|
-
<slot />
|
|
171
|
-
</body>
|
|
172
|
-
</html>
|
|
173
|
-
```
|
|
174
|
-
|
|
175
|
-
## License
|
|
176
|
-
|
|
177
|
-
MIT
|
|
1
|
+
# @duffcloudservices/cms-astro
|
|
2
|
+
|
|
3
|
+
Astro integration for DCS CMS content and SEO management.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
pnpm add @duffcloudservices/cms-astro
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Usage
|
|
12
|
+
|
|
13
|
+
### Configuration
|
|
14
|
+
|
|
15
|
+
```typescript
|
|
16
|
+
// astro.config.mjs
|
|
17
|
+
import { defineConfig } from 'astro/config'
|
|
18
|
+
import dcs from '@duffcloudservices/cms-astro'
|
|
19
|
+
|
|
20
|
+
export default defineConfig({
|
|
21
|
+
integrations: [dcs()],
|
|
22
|
+
})
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
### Using in Components
|
|
26
|
+
|
|
27
|
+
```astro
|
|
28
|
+
---
|
|
29
|
+
// src/pages/index.astro
|
|
30
|
+
import { t, getPageSeo, getPageContent } from '@duffcloudservices/cms-astro'
|
|
31
|
+
|
|
32
|
+
const seo = getPageSeo('home')
|
|
33
|
+
const content = getPageContent('home')
|
|
34
|
+
---
|
|
35
|
+
<html>
|
|
36
|
+
<head>
|
|
37
|
+
<title>{seo?.title}</title>
|
|
38
|
+
<meta name="description" content={seo?.description} />
|
|
39
|
+
{seo?.openGraph?.image && (
|
|
40
|
+
<meta property="og:image" content={seo.openGraph.image} />
|
|
41
|
+
)}
|
|
42
|
+
</head>
|
|
43
|
+
<body>
|
|
44
|
+
<h1>{t('home', 'hero.title', 'Welcome')}</h1>
|
|
45
|
+
<p>{t('home', 'hero.subtitle', 'Build amazing things')}</p>
|
|
46
|
+
|
|
47
|
+
<!-- Or use content object directly -->
|
|
48
|
+
<p>{content['cta.text']}</p>
|
|
49
|
+
</body>
|
|
50
|
+
</html>
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
### DCS Configuration Files
|
|
54
|
+
|
|
55
|
+
Create `.dcs/content.yaml`:
|
|
56
|
+
|
|
57
|
+
```yaml
|
|
58
|
+
version: 1
|
|
59
|
+
global:
|
|
60
|
+
nav.home: Home
|
|
61
|
+
footer.copyright: © 2026 Company
|
|
62
|
+
pages:
|
|
63
|
+
home:
|
|
64
|
+
hero.title: Welcome to Our Site
|
|
65
|
+
hero.subtitle: Build something amazing
|
|
66
|
+
cta.text: Get Started
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
Create `.dcs/seo.yaml`:
|
|
70
|
+
|
|
71
|
+
```yaml
|
|
72
|
+
version: 1
|
|
73
|
+
global:
|
|
74
|
+
siteName: My Site
|
|
75
|
+
defaultTitle: My Site
|
|
76
|
+
titleTemplate: "%s | My Site"
|
|
77
|
+
images:
|
|
78
|
+
ogDefault: /images/og-default.jpg
|
|
79
|
+
pages:
|
|
80
|
+
home:
|
|
81
|
+
title: Welcome
|
|
82
|
+
description: The homepage of My Site
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
## API
|
|
86
|
+
|
|
87
|
+
### Integration Options
|
|
88
|
+
|
|
89
|
+
```typescript
|
|
90
|
+
dcs({
|
|
91
|
+
contentPath: '.dcs/content.yaml', // Path to content file
|
|
92
|
+
seoPath: '.dcs/seo.yaml', // Path to SEO file
|
|
93
|
+
debug: false, // Enable debug logging
|
|
94
|
+
})
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
### Runtime Functions
|
|
98
|
+
|
|
99
|
+
#### `t(page, key, fallback?)`
|
|
100
|
+
|
|
101
|
+
Get text for a specific page and key.
|
|
102
|
+
|
|
103
|
+
```astro
|
|
104
|
+
{t('home', 'hero.title', 'Default Title')}
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
#### `getContent()`
|
|
108
|
+
|
|
109
|
+
Get the full content configuration object.
|
|
110
|
+
|
|
111
|
+
#### `getSeo()`
|
|
112
|
+
|
|
113
|
+
Get the full SEO configuration object.
|
|
114
|
+
|
|
115
|
+
#### `getPageContent(page)`
|
|
116
|
+
|
|
117
|
+
Get all content for a page (global merged with page-specific).
|
|
118
|
+
|
|
119
|
+
```astro
|
|
120
|
+
---
|
|
121
|
+
const content = getPageContent('home')
|
|
122
|
+
---
|
|
123
|
+
{Object.entries(content).map(([key, value]) => (
|
|
124
|
+
<p>{key}: {value}</p>
|
|
125
|
+
))}
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
#### `getPageSeo(page, overrides?)`
|
|
129
|
+
|
|
130
|
+
Get resolved SEO for a page with optional overrides.
|
|
131
|
+
|
|
132
|
+
```astro
|
|
133
|
+
---
|
|
134
|
+
const seo = getPageSeo('home', { title: 'Custom Title' })
|
|
135
|
+
---
|
|
136
|
+
<title>{seo?.title}</title>
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
## Advanced Usage
|
|
140
|
+
|
|
141
|
+
### Layout Component with SEO
|
|
142
|
+
|
|
143
|
+
```astro
|
|
144
|
+
---
|
|
145
|
+
// src/layouts/BaseLayout.astro
|
|
146
|
+
import { getPageSeo } from '@duffcloudservices/cms-astro'
|
|
147
|
+
|
|
148
|
+
interface Props {
|
|
149
|
+
page: string
|
|
150
|
+
titleOverride?: string
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
const { page, titleOverride } = Astro.props
|
|
154
|
+
const seo = getPageSeo(page, titleOverride ? { title: titleOverride } : undefined)
|
|
155
|
+
---
|
|
156
|
+
<!DOCTYPE html>
|
|
157
|
+
<html lang="en">
|
|
158
|
+
<head>
|
|
159
|
+
<meta charset="UTF-8" />
|
|
160
|
+
<meta name="viewport" content="width=device-width" />
|
|
161
|
+
<title>{seo?.title ?? 'My Site'}</title>
|
|
162
|
+
{seo?.description && (
|
|
163
|
+
<meta name="description" content={seo.description} />
|
|
164
|
+
)}
|
|
165
|
+
{seo?.canonical && (
|
|
166
|
+
<link rel="canonical" href={seo.canonical} />
|
|
167
|
+
)}
|
|
168
|
+
</head>
|
|
169
|
+
<body>
|
|
170
|
+
<slot />
|
|
171
|
+
</body>
|
|
172
|
+
</html>
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
## License
|
|
176
|
+
|
|
177
|
+
MIT
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/integration.ts","../src/runtime.ts"],"names":["coreGetPageContent"],"mappings":"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","file":"index.js","sourcesContent":["/**\r\n * Astro Integration for DCS CMS\r\n *\r\n * Loads .dcs/content.yaml and .dcs/seo.yaml at build time and injects\r\n * them as global variables for use in Astro components.\r\n */\r\n\r\nimport type { AstroIntegration } from 'astro'\r\nimport { loadContentYaml, loadSeoYaml } from '@duffcloudservices/cms-core'\r\nimport fs from 'node:fs'\r\nimport path from 'node:path'\r\n\r\n/**\r\n * Options for the DCS Astro integration\r\n */\r\nexport interface DcsIntegrationOptions {\r\n /** Path to content.yaml relative to project root (default: '.dcs/content.yaml') */\r\n contentPath?: string\r\n /** Path to seo.yaml relative to project root (default: '.dcs/seo.yaml') */\r\n seoPath?: string\r\n /** Enable debug logging */\r\n debug?: boolean\r\n}\r\n\r\n/**\r\n * Find config file in common locations\r\n */\r\nfunction findConfigFile(filename: string, projectRoot: string): string | undefined {\r\n const possiblePaths = [\r\n path.resolve(projectRoot, filename),\r\n path.resolve(projectRoot, '..', filename),\r\n path.resolve(process.cwd(), filename),\r\n ]\r\n\r\n for (const testPath of possiblePaths) {\r\n if (fs.existsSync(testPath)) {\r\n return testPath\r\n }\r\n }\r\n\r\n return undefined\r\n}\r\n\r\n/**\r\n * DCS Astro integration.\r\n *\r\n * @param options - Integration options\r\n * @returns Astro integration\r\n *\r\n * @example\r\n * ```typescript\r\n * // astro.config.mjs\r\n * import { defineConfig } from 'astro/config'\r\n * import dcs from '@duffcloudservices/cms-astro'\r\n *\r\n * export default defineConfig({\r\n * integrations: [dcs()],\r\n * })\r\n * ```\r\n */\r\nexport default function dcsIntegration(\r\n options: DcsIntegrationOptions = {}\r\n): AstroIntegration {\r\n const {\r\n contentPath = '.dcs/content.yaml',\r\n seoPath = '.dcs/seo.yaml',\r\n debug = false,\r\n } = options\r\n\r\n return {\r\n name: '@duffcloudservices/cms-astro',\r\n hooks: {\r\n 'astro:config:setup': async ({ config, updateConfig, injectScript }) => {\r\n const projectRoot = config.root?.pathname ?? process.cwd()\r\n\r\n // Load content.yaml\r\n let contentJson = 'undefined'\r\n const contentFile = findConfigFile(contentPath, projectRoot)\r\n if (contentFile) {\r\n try {\r\n const content = await loadContentYaml(contentFile)\r\n contentJson = JSON.stringify(content)\r\n if (debug) {\r\n console.log(`[dcs-astro] Loaded content from ${contentFile}`)\r\n }\r\n } catch (err) {\r\n console.warn(`[dcs-astro] Error loading ${contentPath}:`, err)\r\n }\r\n } else if (debug) {\r\n console.log(`[dcs-astro] No content.yaml found at ${contentPath}`)\r\n }\r\n\r\n // Load seo.yaml\r\n let seoJson = 'undefined'\r\n const seoFile = findConfigFile(seoPath, projectRoot)\r\n if (seoFile) {\r\n try {\r\n const seo = await loadSeoYaml(seoFile)\r\n seoJson = JSON.stringify(seo)\r\n if (debug) {\r\n console.log(`[dcs-astro] Loaded SEO config from ${seoFile}`)\r\n }\r\n } catch (err) {\r\n console.warn(`[dcs-astro] Error loading ${seoPath}:`, err)\r\n }\r\n } else if (debug) {\r\n console.log(`[dcs-astro] No seo.yaml found at ${seoPath}`)\r\n }\r\n\r\n // Inject globals via head script\r\n injectScript(\r\n 'head-inline',\r\n `globalThis.__DCS_CONTENT__ = ${contentJson}; globalThis.__DCS_SEO__ = ${seoJson};`\r\n )\r\n\r\n // Also make available to Vite for SSR\r\n updateConfig({\r\n vite: {\r\n define: {\r\n __DCS_CONTENT__: contentJson,\r\n __DCS_SEO__: seoJson,\r\n },\r\n },\r\n })\r\n },\r\n },\r\n }\r\n}\r\n","/**\r\n * Runtime helpers for Astro components\r\n *\r\n * These functions provide access to DCS content and SEO configuration\r\n * that was injected at build time by the Astro integration.\r\n */\r\n\r\nimport {\r\n resolveTextKey,\r\n getPageContent as coreGetPageContent,\r\n resolveSeoForPage,\r\n type ContentConfiguration,\r\n type SeoConfiguration,\r\n type ResolvedSeo,\r\n} from '@duffcloudservices/cms-core'\r\n\r\n// Declare the globals injected by the integration\r\ndeclare const __DCS_CONTENT__: ContentConfiguration | undefined\r\ndeclare const __DCS_SEO__: SeoConfiguration | undefined\r\n\r\n/**\r\n * Get the content configuration.\r\n *\r\n * @returns Content configuration or undefined if not available\r\n */\r\nexport function getContent(): ContentConfiguration | undefined {\r\n try {\r\n if (__DCS_CONTENT__ !== undefined && __DCS_CONTENT__ !== null) {\r\n return __DCS_CONTENT__\r\n }\r\n } catch {\r\n // Not defined\r\n }\r\n return undefined\r\n}\r\n\r\n/**\r\n * Get the SEO configuration.\r\n *\r\n * @returns SEO configuration or undefined if not available\r\n */\r\nexport function getSeo(): SeoConfiguration | undefined {\r\n try {\r\n if (__DCS_SEO__ !== undefined && __DCS_SEO__ !== null) {\r\n return __DCS_SEO__\r\n }\r\n } catch {\r\n // Not defined\r\n }\r\n return undefined\r\n}\r\n\r\n/**\r\n * Get text for a specific page and key.\r\n *\r\n * @param page - Page slug matching entry in content.yaml\r\n * @param key - Text key to retrieve\r\n * @param fallback - Fallback value if key not found\r\n * @returns The resolved text value\r\n *\r\n * @example\r\n * ```astro\r\n * ---\r\n * import { t } from '@duffcloudservices/cms-astro'\r\n * ---\r\n * <h1>{t('home', 'hero.title', 'Welcome')}</h1>\r\n * ```\r\n */\r\nexport function t(page: string, key: string, fallback?: string): string {\r\n const content = getContent()\r\n if (!content) return fallback ?? key\r\n return resolveTextKey(content, page, key) ?? fallback ?? key\r\n}\r\n\r\n/**\r\n * Get all content for a specific page (merged global + page).\r\n *\r\n * @param page - Page slug\r\n * @returns Merged content object\r\n *\r\n * @example\r\n * ```astro\r\n * ---\r\n * import { getPageContent } from '@duffcloudservices/cms-astro'\r\n *\r\n * const content = getPageContent('home')\r\n * ---\r\n * <h1>{content['hero.title']}</h1>\r\n * ```\r\n */\r\nexport function getPageContent(page: string): Record<string, string> {\r\n const content = getContent()\r\n if (!content) return {}\r\n return coreGetPageContent(content, page)\r\n}\r\n\r\n/**\r\n * Get resolved SEO for a specific page.\r\n *\r\n * @param page - Page slug matching entry in seo.yaml\r\n * @param overrides - Optional overrides for title, description, or image\r\n * @returns Resolved SEO object or null if not available\r\n *\r\n * @example\r\n * ```astro\r\n * ---\r\n * import { getPageSeo } from '@duffcloudservices/cms-astro'\r\n *\r\n * const seo = getPageSeo('home')\r\n * ---\r\n * <html>\r\n * <head>\r\n * <title>{seo?.title}</title>\r\n * <meta name=\"description\" content={seo?.description} />\r\n * </head>\r\n * </html>\r\n * ```\r\n */\r\nexport function getPageSeo(\r\n page: string,\r\n overrides?: { title?: string; description?: string; image?: string }\r\n): ResolvedSeo | null {\r\n const seo = getSeo()\r\n if (!seo) return null\r\n\r\n const resolved = resolveSeoForPage(seo, page)\r\n return {\r\n ...resolved,\r\n ...(overrides?.title && { title: overrides.title }),\r\n ...(overrides?.description && { description: overrides.description }),\r\n ...(overrides?.image && { image: overrides.image }),\r\n }\r\n}\r\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/integration.ts","../src/runtime.ts"],"names":["coreGetPageContent"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Astro Integration for DCS CMS\n *\n * Loads .dcs/content.yaml and .dcs/seo.yaml at build time and injects\n * them as global variables for use in Astro components.\n */\n\nimport type { AstroIntegration } from 'astro'\nimport { loadContentYaml, loadSeoYaml } from '@duffcloudservices/cms-core'\nimport fs from 'node:fs'\nimport path from 'node:path'\n\n/**\n * Options for the DCS Astro integration\n */\nexport interface DcsIntegrationOptions {\n /** Path to content.yaml relative to project root (default: '.dcs/content.yaml') */\n contentPath?: string\n /** Path to seo.yaml relative to project root (default: '.dcs/seo.yaml') */\n seoPath?: string\n /** Enable debug logging */\n debug?: boolean\n}\n\n/**\n * Find config file in common locations\n */\nfunction findConfigFile(filename: string, projectRoot: string): string | undefined {\n const possiblePaths = [\n path.resolve(projectRoot, filename),\n path.resolve(projectRoot, '..', filename),\n path.resolve(process.cwd(), filename),\n ]\n\n for (const testPath of possiblePaths) {\n if (fs.existsSync(testPath)) {\n return testPath\n }\n }\n\n return undefined\n}\n\n/**\n * DCS Astro integration.\n *\n * @param options - Integration options\n * @returns Astro integration\n *\n * @example\n * ```typescript\n * // astro.config.mjs\n * import { defineConfig } from 'astro/config'\n * import dcs from '@duffcloudservices/cms-astro'\n *\n * export default defineConfig({\n * integrations: [dcs()],\n * })\n * ```\n */\nexport default function dcsIntegration(\n options: DcsIntegrationOptions = {}\n): AstroIntegration {\n const {\n contentPath = '.dcs/content.yaml',\n seoPath = '.dcs/seo.yaml',\n debug = false,\n } = options\n\n return {\n name: '@duffcloudservices/cms-astro',\n hooks: {\n 'astro:config:setup': async ({ config, updateConfig, injectScript }) => {\n const projectRoot = config.root?.pathname ?? process.cwd()\n\n // Load content.yaml\n let contentJson = 'undefined'\n const contentFile = findConfigFile(contentPath, projectRoot)\n if (contentFile) {\n try {\n const content = await loadContentYaml(contentFile)\n contentJson = JSON.stringify(content)\n if (debug) {\n console.log(`[dcs-astro] Loaded content from ${contentFile}`)\n }\n } catch (err) {\n console.warn(`[dcs-astro] Error loading ${contentPath}:`, err)\n }\n } else if (debug) {\n console.log(`[dcs-astro] No content.yaml found at ${contentPath}`)\n }\n\n // Load seo.yaml\n let seoJson = 'undefined'\n const seoFile = findConfigFile(seoPath, projectRoot)\n if (seoFile) {\n try {\n const seo = await loadSeoYaml(seoFile)\n seoJson = JSON.stringify(seo)\n if (debug) {\n console.log(`[dcs-astro] Loaded SEO config from ${seoFile}`)\n }\n } catch (err) {\n console.warn(`[dcs-astro] Error loading ${seoPath}:`, err)\n }\n } else if (debug) {\n console.log(`[dcs-astro] No seo.yaml found at ${seoPath}`)\n }\n\n // Inject globals via head script\n injectScript(\n 'head-inline',\n `globalThis.__DCS_CONTENT__ = ${contentJson}; globalThis.__DCS_SEO__ = ${seoJson};`\n )\n\n // Also make available to Vite for SSR\n updateConfig({\n vite: {\n define: {\n __DCS_CONTENT__: contentJson,\n __DCS_SEO__: seoJson,\n },\n },\n })\n },\n },\n }\n}\n","/**\n * Runtime helpers for Astro components\n *\n * These functions provide access to DCS content and SEO configuration\n * that was injected at build time by the Astro integration.\n */\n\nimport {\n resolveTextKey,\n getPageContent as coreGetPageContent,\n resolveSeoForPage,\n type ContentConfiguration,\n type SeoConfiguration,\n type ResolvedSeo,\n} from '@duffcloudservices/cms-core'\n\n// Declare the globals injected by the integration\ndeclare const __DCS_CONTENT__: ContentConfiguration | undefined\ndeclare const __DCS_SEO__: SeoConfiguration | undefined\n\n/**\n * Get the content configuration.\n *\n * @returns Content configuration or undefined if not available\n */\nexport function getContent(): ContentConfiguration | undefined {\n try {\n if (__DCS_CONTENT__ !== undefined && __DCS_CONTENT__ !== null) {\n return __DCS_CONTENT__\n }\n } catch {\n // Not defined\n }\n return undefined\n}\n\n/**\n * Get the SEO configuration.\n *\n * @returns SEO configuration or undefined if not available\n */\nexport function getSeo(): SeoConfiguration | undefined {\n try {\n if (__DCS_SEO__ !== undefined && __DCS_SEO__ !== null) {\n return __DCS_SEO__\n }\n } catch {\n // Not defined\n }\n return undefined\n}\n\n/**\n * Get text for a specific page and key.\n *\n * @param page - Page slug matching entry in content.yaml\n * @param key - Text key to retrieve\n * @param fallback - Fallback value if key not found\n * @returns The resolved text value\n *\n * @example\n * ```astro\n * ---\n * import { t } from '@duffcloudservices/cms-astro'\n * ---\n * <h1>{t('home', 'hero.title', 'Welcome')}</h1>\n * ```\n */\nexport function t(page: string, key: string, fallback?: string): string {\n const content = getContent()\n if (!content) return fallback ?? key\n return resolveTextKey(content, page, key) ?? fallback ?? key\n}\n\n/**\n * Get all content for a specific page (merged global + page).\n *\n * @param page - Page slug\n * @returns Merged content object\n *\n * @example\n * ```astro\n * ---\n * import { getPageContent } from '@duffcloudservices/cms-astro'\n *\n * const content = getPageContent('home')\n * ---\n * <h1>{content['hero.title']}</h1>\n * ```\n */\nexport function getPageContent(page: string): Record<string, string> {\n const content = getContent()\n if (!content) return {}\n return coreGetPageContent(content, page)\n}\n\n/**\n * Get resolved SEO for a specific page.\n *\n * @param page - Page slug matching entry in seo.yaml\n * @param overrides - Optional overrides for title, description, or image\n * @returns Resolved SEO object or null if not available\n *\n * @example\n * ```astro\n * ---\n * import { getPageSeo } from '@duffcloudservices/cms-astro'\n *\n * const seo = getPageSeo('home')\n * ---\n * <html>\n * <head>\n * <title>{seo?.title}</title>\n * <meta name=\"description\" content={seo?.description} />\n * </head>\n * </html>\n * ```\n */\nexport function getPageSeo(\n page: string,\n overrides?: { title?: string; description?: string; image?: string }\n): ResolvedSeo | null {\n const seo = getSeo()\n if (!seo) return null\n\n const resolved = resolveSeoForPage(seo, page)\n return {\n ...resolved,\n ...(overrides?.title && { title: overrides.title }),\n ...(overrides?.description && { description: overrides.description }),\n ...(overrides?.image && { image: overrides.image }),\n }\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@duffcloudservices/cms-astro",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.3",
|
|
4
4
|
"description": "Astro integration for DCS CMS content and SEO management",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
"astro": "^4.0.0 || ^5.0.0"
|
|
19
19
|
},
|
|
20
20
|
"dependencies": {
|
|
21
|
-
"@duffcloudservices/cms-core": "0.
|
|
21
|
+
"@duffcloudservices/cms-core": "0.4.5"
|
|
22
22
|
},
|
|
23
23
|
"devDependencies": {
|
|
24
24
|
"@types/node": "^20.11.0",
|