ayezee-astro-cms 1.2.2 → 1.4.0
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 +75 -1
- package/dist/cms-helper.d.ts +17 -0
- package/dist/cms-helper.js +18 -0
- package/dist/integration.d.ts +20 -0
- package/dist/integration.js +146 -12
- package/package.json +5 -3
package/README.md
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
# @ayezee/astro-cms
|
|
2
2
|
|
|
3
|
-
AyeZee CMS integration for Astro with automatic data fetching, form handling, and
|
|
3
|
+
AyeZee CMS integration for Astro with automatic data fetching, form handling, validation, and analytics.
|
|
4
4
|
|
|
5
5
|
## Features
|
|
6
6
|
|
|
7
7
|
- 🚀 **Automatic Data Fetching** - Fetches CMS data during build time
|
|
8
|
+
- 📊 **Analytics Integration** - Auto-inject Umami analytics from dashboard settings
|
|
8
9
|
- 📦 **Type-Safe** - Full TypeScript support with proper types
|
|
9
10
|
- 🔄 **Build-Time Caching** - No runtime API calls needed
|
|
10
11
|
- ✅ **Form Validation** - Client-side and server-side validation support
|
|
@@ -86,6 +87,9 @@ ayezeeCms({
|
|
|
86
87
|
|
|
87
88
|
// Skip build if fetch fails (defaults to false)
|
|
88
89
|
skipOnError?: boolean;
|
|
90
|
+
|
|
91
|
+
// Enable automatic Umami analytics injection (defaults to true)
|
|
92
|
+
enableAnalytics?: boolean;
|
|
89
93
|
});
|
|
90
94
|
```
|
|
91
95
|
|
|
@@ -169,6 +173,28 @@ const info = getCacheInfo();
|
|
|
169
173
|
// Returns: { fetchedAt, version, moduleCount }
|
|
170
174
|
```
|
|
171
175
|
|
|
176
|
+
#### Analytics
|
|
177
|
+
|
|
178
|
+
```ts
|
|
179
|
+
import {
|
|
180
|
+
getAnalyticsConfig,
|
|
181
|
+
isAnalyticsEnabled,
|
|
182
|
+
getAnalyticsWebsiteId,
|
|
183
|
+
} from '@ayezee/astro-cms';
|
|
184
|
+
|
|
185
|
+
// Get full analytics configuration
|
|
186
|
+
const analytics = getAnalyticsConfig();
|
|
187
|
+
// Returns: { websiteId: string, baseUrl: string } | null
|
|
188
|
+
|
|
189
|
+
// Check if analytics is enabled
|
|
190
|
+
const enabled = isAnalyticsEnabled();
|
|
191
|
+
// Returns: boolean
|
|
192
|
+
|
|
193
|
+
// Get just the website ID
|
|
194
|
+
const websiteId = getAnalyticsWebsiteId();
|
|
195
|
+
// Returns: string | null
|
|
196
|
+
```
|
|
197
|
+
|
|
172
198
|
## TypeScript Support
|
|
173
199
|
|
|
174
200
|
The package exports all necessary types:
|
|
@@ -183,6 +209,54 @@ import type {
|
|
|
183
209
|
} from '@ayezee/astro-cms';
|
|
184
210
|
```
|
|
185
211
|
|
|
212
|
+
## Analytics Integration
|
|
213
|
+
|
|
214
|
+
The integration automatically injects Umami analytics if configured in your AyeZee Dashboard.
|
|
215
|
+
|
|
216
|
+
### How It Works
|
|
217
|
+
|
|
218
|
+
1. **Configure in Dashboard**: Set up Umami analytics in your project settings at `/admin/projects/{slug}/settings?tab=analytics`
|
|
219
|
+
2. **Automatic Injection**: The integration fetches your analytics config and automatically injects the Umami tracking script
|
|
220
|
+
3. **Zero Configuration**: No need to manually add script tags or manage website IDs
|
|
221
|
+
|
|
222
|
+
### Analytics Configuration
|
|
223
|
+
|
|
224
|
+
Analytics is enabled by default. The script will only be injected if you've configured Umami in the dashboard.
|
|
225
|
+
|
|
226
|
+
To disable automatic analytics injection:
|
|
227
|
+
|
|
228
|
+
```js
|
|
229
|
+
// astro.config.mjs
|
|
230
|
+
export default defineConfig({
|
|
231
|
+
integrations: [
|
|
232
|
+
ayezeeCms({
|
|
233
|
+
enableAnalytics: false, // Disable automatic Umami script injection
|
|
234
|
+
}),
|
|
235
|
+
],
|
|
236
|
+
});
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
### Manual Analytics Setup
|
|
240
|
+
|
|
241
|
+
If you need more control over when/where the analytics script loads, you can disable auto-injection and add it manually:
|
|
242
|
+
|
|
243
|
+
```astro
|
|
244
|
+
---
|
|
245
|
+
import { getAnalyticsConfig } from '@ayezee/astro-cms';
|
|
246
|
+
import cmsData from '../data/cms-cache.json';
|
|
247
|
+
|
|
248
|
+
const analytics = cmsData.analytics;
|
|
249
|
+
---
|
|
250
|
+
|
|
251
|
+
{analytics && (
|
|
252
|
+
<script
|
|
253
|
+
defer
|
|
254
|
+
src={`${analytics.baseUrl}/script.js`}
|
|
255
|
+
data-website-id={analytics.websiteId}
|
|
256
|
+
></script>
|
|
257
|
+
)}
|
|
258
|
+
```
|
|
259
|
+
|
|
186
260
|
## Advanced Usage
|
|
187
261
|
|
|
188
262
|
### Custom Cache Location
|
package/dist/cms-helper.d.ts
CHANGED
|
@@ -66,6 +66,10 @@ export interface CachedModule {
|
|
|
66
66
|
createdAt: string;
|
|
67
67
|
updatedAt: string;
|
|
68
68
|
}
|
|
69
|
+
export interface AnalyticsConfig {
|
|
70
|
+
websiteId: string;
|
|
71
|
+
baseUrl: string;
|
|
72
|
+
}
|
|
69
73
|
export interface CMSCache {
|
|
70
74
|
project: {
|
|
71
75
|
id: string;
|
|
@@ -74,6 +78,7 @@ export interface CMSCache {
|
|
|
74
78
|
domain?: string;
|
|
75
79
|
};
|
|
76
80
|
modules: CachedModule[];
|
|
81
|
+
analytics?: AnalyticsConfig | null;
|
|
77
82
|
fetchedAt: string;
|
|
78
83
|
version: string;
|
|
79
84
|
}
|
|
@@ -174,3 +179,15 @@ export declare function getCacheInfo(): {
|
|
|
174
179
|
version: string;
|
|
175
180
|
moduleCount: number;
|
|
176
181
|
};
|
|
182
|
+
/**
|
|
183
|
+
* Get analytics configuration if enabled
|
|
184
|
+
*/
|
|
185
|
+
export declare function getAnalyticsConfig(): AnalyticsConfig | null;
|
|
186
|
+
/**
|
|
187
|
+
* Check if analytics is enabled for this project
|
|
188
|
+
*/
|
|
189
|
+
export declare function isAnalyticsEnabled(): boolean;
|
|
190
|
+
/**
|
|
191
|
+
* Get the Umami website ID if analytics is configured
|
|
192
|
+
*/
|
|
193
|
+
export declare function getAnalyticsWebsiteId(): string | null;
|
package/dist/cms-helper.js
CHANGED
|
@@ -187,4 +187,22 @@ export function getCacheInfo() {
|
|
|
187
187
|
moduleCount: getCache().modules.length,
|
|
188
188
|
};
|
|
189
189
|
}
|
|
190
|
+
/**
|
|
191
|
+
* Get analytics configuration if enabled
|
|
192
|
+
*/
|
|
193
|
+
export function getAnalyticsConfig() {
|
|
194
|
+
return getCache().analytics || null;
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* Check if analytics is enabled for this project
|
|
198
|
+
*/
|
|
199
|
+
export function isAnalyticsEnabled() {
|
|
200
|
+
return !!getCache().analytics;
|
|
201
|
+
}
|
|
202
|
+
/**
|
|
203
|
+
* Get the Umami website ID if analytics is configured
|
|
204
|
+
*/
|
|
205
|
+
export function getAnalyticsWebsiteId() {
|
|
206
|
+
return getCache().analytics?.websiteId || null;
|
|
207
|
+
}
|
|
190
208
|
// Types are already exported above, no need to re-export
|
package/dist/integration.d.ts
CHANGED
|
@@ -45,6 +45,26 @@ export interface AyezeeCmsOptions {
|
|
|
45
45
|
* @default false
|
|
46
46
|
*/
|
|
47
47
|
skipOnError?: boolean;
|
|
48
|
+
/**
|
|
49
|
+
* Enable automatic Umami analytics script injection
|
|
50
|
+
* @default true
|
|
51
|
+
*/
|
|
52
|
+
enableAnalytics?: boolean;
|
|
53
|
+
/**
|
|
54
|
+
* Report site version to CMS dashboard for tracking
|
|
55
|
+
* @default true
|
|
56
|
+
*/
|
|
57
|
+
reportVersion?: boolean;
|
|
58
|
+
/**
|
|
59
|
+
* Site URL for version reporting (auto-detected if not provided)
|
|
60
|
+
* @default process.env.SITE_URL or process.env.URL
|
|
61
|
+
*/
|
|
62
|
+
siteUrl?: string;
|
|
63
|
+
/**
|
|
64
|
+
* Environment name for version reporting
|
|
65
|
+
* @default process.env.NODE_ENV or 'production'
|
|
66
|
+
*/
|
|
67
|
+
environment?: string;
|
|
48
68
|
}
|
|
49
69
|
/**
|
|
50
70
|
* AyeZee CMS Astro Integration
|
package/dist/integration.js
CHANGED
|
@@ -15,6 +15,8 @@
|
|
|
15
15
|
*/
|
|
16
16
|
import fs from 'fs';
|
|
17
17
|
import path from 'path';
|
|
18
|
+
// Package version - automatically updated during build
|
|
19
|
+
const PACKAGE_VERSION = '1.4.0';
|
|
18
20
|
/**
|
|
19
21
|
* Load environment variables from .env file
|
|
20
22
|
*/
|
|
@@ -48,15 +50,67 @@ function slugify(text) {
|
|
|
48
50
|
.replace(/[\s_-]+/g, '-')
|
|
49
51
|
.replace(/^-+|-+$/g, '');
|
|
50
52
|
}
|
|
53
|
+
/**
|
|
54
|
+
* Get Astro version from package.json
|
|
55
|
+
*/
|
|
56
|
+
function getAstroVersion() {
|
|
57
|
+
try {
|
|
58
|
+
const pkgPath = path.join(process.cwd(), 'node_modules', 'astro', 'package.json');
|
|
59
|
+
if (fs.existsSync(pkgPath)) {
|
|
60
|
+
const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf-8'));
|
|
61
|
+
return pkg.version;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
catch {
|
|
65
|
+
// Ignore errors
|
|
66
|
+
}
|
|
67
|
+
return undefined;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Report site version to CMS dashboard
|
|
71
|
+
*/
|
|
72
|
+
async function reportSiteVersion(baseUrl, apiKey, siteUrl, environment, astroVersion, logger) {
|
|
73
|
+
try {
|
|
74
|
+
const response = await fetch(`${baseUrl}/sites`, {
|
|
75
|
+
method: 'POST',
|
|
76
|
+
headers: {
|
|
77
|
+
'Content-Type': 'application/json',
|
|
78
|
+
...(apiKey && { 'Authorization': `Bearer ${apiKey}` }),
|
|
79
|
+
},
|
|
80
|
+
body: JSON.stringify({
|
|
81
|
+
siteUrl,
|
|
82
|
+
environment,
|
|
83
|
+
packageVersion: PACKAGE_VERSION,
|
|
84
|
+
astroVersion,
|
|
85
|
+
metadata: {
|
|
86
|
+
nodeVersion: process.version,
|
|
87
|
+
platform: process.platform,
|
|
88
|
+
buildTime: new Date().toISOString(),
|
|
89
|
+
},
|
|
90
|
+
}),
|
|
91
|
+
});
|
|
92
|
+
if (response.ok) {
|
|
93
|
+
logger.info(`📡 Reported site version to dashboard`);
|
|
94
|
+
}
|
|
95
|
+
else {
|
|
96
|
+
logger.warn(`⚠️ Failed to report site version: ${response.status}`);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
catch (error) {
|
|
100
|
+
// Don't fail the build if version reporting fails
|
|
101
|
+
logger.warn(`⚠️ Could not report site version (non-critical)`);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
51
104
|
/**
|
|
52
105
|
* AyeZee CMS Astro Integration
|
|
53
106
|
*/
|
|
54
107
|
export function ayezeeCms(options = {}) {
|
|
108
|
+
let analyticsConfig = null;
|
|
55
109
|
return {
|
|
56
110
|
name: 'ayezee-cms',
|
|
57
111
|
hooks: {
|
|
58
|
-
'astro:config:setup': async ({ config, logger }) => {
|
|
59
|
-
logger.info(
|
|
112
|
+
'astro:config:setup': async ({ config, logger, injectScript }) => {
|
|
113
|
+
logger.info(`🚀 AyeZee CMS v${PACKAGE_VERSION}: Fetching data...`);
|
|
60
114
|
// Load environment variables from .env
|
|
61
115
|
loadEnvFile();
|
|
62
116
|
// Get configuration
|
|
@@ -66,21 +120,45 @@ export function ayezeeCms(options = {}) {
|
|
|
66
120
|
const outputDir = options.outputDir || 'src/data';
|
|
67
121
|
const cacheFileName = options.cacheFileName || 'cms-cache.json';
|
|
68
122
|
const skipOnError = options.skipOnError || false;
|
|
69
|
-
|
|
123
|
+
const enableAnalytics = options.enableAnalytics !== false;
|
|
124
|
+
const reportVersion = options.reportVersion !== false;
|
|
125
|
+
const siteUrl = options.siteUrl || process.env.SITE_URL || process.env.URL || process.env.VERCEL_URL;
|
|
126
|
+
const environment = options.environment || process.env.NODE_ENV || 'production';
|
|
127
|
+
// Validate config with helpful error messages
|
|
70
128
|
if (!cmsDomain || !projectSlug) {
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
129
|
+
logger.error('');
|
|
130
|
+
logger.error('❌ AyeZee CMS Configuration Error');
|
|
131
|
+
logger.error('═══════════════════════════════════════════════════════════');
|
|
132
|
+
logger.error('');
|
|
133
|
+
logger.error('Missing required environment variables:');
|
|
134
|
+
if (!cmsDomain) {
|
|
135
|
+
logger.error(' ✗ PUBLIC_CMS_DOMAIN - The URL of your CMS dashboard');
|
|
136
|
+
logger.error(' Example: PUBLIC_CMS_DOMAIN=https://cms.yourdomain.com');
|
|
137
|
+
}
|
|
138
|
+
if (!projectSlug) {
|
|
139
|
+
logger.error(' ✗ PUBLIC_PROJECT_SLUG - Your project identifier');
|
|
140
|
+
logger.error(' Example: PUBLIC_PROJECT_SLUG=my-project');
|
|
141
|
+
}
|
|
142
|
+
logger.error('');
|
|
143
|
+
logger.error('Add these to your .env file:');
|
|
144
|
+
logger.error('');
|
|
145
|
+
logger.error(' PUBLIC_CMS_DOMAIN=https://your-cms-domain.com');
|
|
146
|
+
logger.error(' PUBLIC_PROJECT_SLUG=your-project-slug');
|
|
147
|
+
logger.error(' PUBLIC_AYEZEE_API_KEY=AZ_your_api_key (optional)');
|
|
148
|
+
logger.error('');
|
|
149
|
+
logger.error('═══════════════════════════════════════════════════════════');
|
|
150
|
+
logger.error('');
|
|
76
151
|
if (skipOnError) {
|
|
77
152
|
logger.warn('⚠️ Skipping CMS data fetch due to missing config');
|
|
153
|
+
logger.warn(' Build will continue with cached data (if available)');
|
|
78
154
|
return;
|
|
79
155
|
}
|
|
80
|
-
throw new Error(`AyeZee CMS integration requires PUBLIC_CMS_DOMAIN and PUBLIC_PROJECT_SLUG`
|
|
156
|
+
throw new Error(`AyeZee CMS integration requires PUBLIC_CMS_DOMAIN and PUBLIC_PROJECT_SLUG. ` +
|
|
157
|
+
`See the error messages above for details.`);
|
|
81
158
|
}
|
|
82
159
|
logger.info(` Domain: ${cmsDomain}`);
|
|
83
160
|
logger.info(` Project: ${projectSlug}`);
|
|
161
|
+
logger.info(` Environment: ${environment}`);
|
|
84
162
|
try {
|
|
85
163
|
// Build API URL
|
|
86
164
|
let domain = cmsDomain;
|
|
@@ -105,6 +183,11 @@ export function ayezeeCms(options = {}) {
|
|
|
105
183
|
}
|
|
106
184
|
const modules = modulesResult.data.modules;
|
|
107
185
|
logger.info(`✅ Found ${modules.length} modules`);
|
|
186
|
+
// Capture analytics configuration
|
|
187
|
+
if (modulesResult.data.analytics) {
|
|
188
|
+
analyticsConfig = modulesResult.data.analytics;
|
|
189
|
+
logger.info(`📊 Analytics configured: ${analyticsConfig.websiteId}`);
|
|
190
|
+
}
|
|
108
191
|
// Fetch data for each module
|
|
109
192
|
const modulesWithData = [];
|
|
110
193
|
for (const module of modules) {
|
|
@@ -147,6 +230,7 @@ export function ayezeeCms(options = {}) {
|
|
|
147
230
|
const cacheData = {
|
|
148
231
|
project: modulesResult.data.project,
|
|
149
232
|
modules: modulesWithData,
|
|
233
|
+
analytics: analyticsConfig,
|
|
150
234
|
fetchedAt: new Date().toISOString(),
|
|
151
235
|
version: '1.0',
|
|
152
236
|
};
|
|
@@ -161,13 +245,63 @@ export function ayezeeCms(options = {}) {
|
|
|
161
245
|
fs.writeFileSync(cachePath, JSON.stringify(cacheData, null, 2), 'utf-8');
|
|
162
246
|
logger.info(`✅ Cached data to: ${path.relative(process.cwd(), cachePath)}`);
|
|
163
247
|
logger.info(`📅 Fetched at: ${cacheData.fetchedAt}`);
|
|
248
|
+
// Inject Umami analytics script if configured
|
|
249
|
+
if (enableAnalytics && analyticsConfig) {
|
|
250
|
+
logger.info('📊 Injecting Umami analytics script...');
|
|
251
|
+
injectScript('head-inline', `
|
|
252
|
+
(function() {
|
|
253
|
+
var script = document.createElement('script');
|
|
254
|
+
script.defer = true;
|
|
255
|
+
script.src = '${analyticsConfig.baseUrl}/script.js';
|
|
256
|
+
script.setAttribute('data-website-id', '${analyticsConfig.websiteId}');
|
|
257
|
+
document.head.appendChild(script);
|
|
258
|
+
})();
|
|
259
|
+
`);
|
|
260
|
+
logger.info('✅ Umami analytics script injected');
|
|
261
|
+
}
|
|
262
|
+
// Report site version to dashboard (non-blocking)
|
|
263
|
+
if (reportVersion && siteUrl) {
|
|
264
|
+
const astroVersion = getAstroVersion();
|
|
265
|
+
reportSiteVersion(baseUrl, apiKey, siteUrl, environment, astroVersion, logger);
|
|
266
|
+
}
|
|
267
|
+
logger.info('');
|
|
268
|
+
logger.info('🎉 AyeZee CMS data fetched successfully!');
|
|
269
|
+
logger.info('');
|
|
164
270
|
}
|
|
165
271
|
catch (error) {
|
|
166
272
|
const errorMessage = error instanceof Error ? error.message : 'Unknown error';
|
|
167
|
-
logger.error('
|
|
168
|
-
logger.error(
|
|
273
|
+
logger.error('');
|
|
274
|
+
logger.error('❌ Failed to fetch CMS data');
|
|
275
|
+
logger.error('═══════════════════════════════════════════════════════════');
|
|
276
|
+
logger.error('');
|
|
277
|
+
logger.error(`Error: ${errorMessage}`);
|
|
278
|
+
logger.error('');
|
|
279
|
+
// Provide helpful troubleshooting tips
|
|
280
|
+
if (errorMessage.includes('ECONNREFUSED') || errorMessage.includes('fetch failed')) {
|
|
281
|
+
logger.error('Troubleshooting tips:');
|
|
282
|
+
logger.error(' 1. Is the CMS dashboard running?');
|
|
283
|
+
logger.error(` 2. Can you access ${cmsDomain} in your browser?`);
|
|
284
|
+
logger.error(' 3. Check your network connection');
|
|
285
|
+
logger.error(' 4. If using localhost, ensure the dashboard is started');
|
|
286
|
+
}
|
|
287
|
+
else if (errorMessage.includes('401') || errorMessage.includes('403')) {
|
|
288
|
+
logger.error('Troubleshooting tips:');
|
|
289
|
+
logger.error(' 1. Check that PUBLIC_AYEZEE_API_KEY is correct');
|
|
290
|
+
logger.error(' 2. Verify the API key has read permissions');
|
|
291
|
+
logger.error(' 3. Ensure the project slug matches your dashboard project');
|
|
292
|
+
}
|
|
293
|
+
else if (errorMessage.includes('404')) {
|
|
294
|
+
logger.error('Troubleshooting tips:');
|
|
295
|
+
logger.error(' 1. Verify PUBLIC_PROJECT_SLUG is correct');
|
|
296
|
+
logger.error(' 2. Check that the project exists in the dashboard');
|
|
297
|
+
logger.error(` 3. Project slug should match: ${projectSlug}`);
|
|
298
|
+
}
|
|
299
|
+
logger.error('');
|
|
300
|
+
logger.error('═══════════════════════════════════════════════════════════');
|
|
301
|
+
logger.error('');
|
|
169
302
|
if (skipOnError) {
|
|
170
|
-
logger.warn('⚠️ Continuing build
|
|
303
|
+
logger.warn('⚠️ Continuing build with cached data (skipOnError: true)');
|
|
304
|
+
logger.warn(' The site will use previously cached CMS data if available.');
|
|
171
305
|
return;
|
|
172
306
|
}
|
|
173
307
|
throw error;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ayezee-astro-cms",
|
|
3
|
-
"version": "1.
|
|
4
|
-
"description": "AyeZee CMS integration for Astro with automatic data fetching, form handling, and
|
|
3
|
+
"version": "1.4.0",
|
|
4
|
+
"description": "AyeZee CMS integration for Astro with automatic data fetching, form handling, validation, and analytics",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
7
7
|
"types": "./dist/index.d.ts",
|
|
@@ -40,7 +40,9 @@
|
|
|
40
40
|
"ayezee",
|
|
41
41
|
"integration",
|
|
42
42
|
"form",
|
|
43
|
-
"validation"
|
|
43
|
+
"validation",
|
|
44
|
+
"analytics",
|
|
45
|
+
"umami"
|
|
44
46
|
],
|
|
45
47
|
"author": "AyeZee Web Designs",
|
|
46
48
|
"license": "MIT",
|