ayezee-astro-cms 1.3.0 → 1.5.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/dist/integration.d.ts +25 -0
- package/dist/integration.js +398 -55
- package/package.json +1 -1
package/dist/integration.d.ts
CHANGED
|
@@ -50,6 +50,31 @@ export interface AyezeeCmsOptions {
|
|
|
50
50
|
* @default true
|
|
51
51
|
*/
|
|
52
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;
|
|
68
|
+
/**
|
|
69
|
+
* Generate TypeScript types for module data
|
|
70
|
+
* @default true
|
|
71
|
+
*/
|
|
72
|
+
generateTypes?: boolean;
|
|
73
|
+
/**
|
|
74
|
+
* Generate a wrapper file that auto-initializes the CMS helper
|
|
75
|
+
* @default true
|
|
76
|
+
*/
|
|
77
|
+
generateWrapper?: boolean;
|
|
53
78
|
}
|
|
54
79
|
/**
|
|
55
80
|
* 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.5.0';
|
|
18
20
|
/**
|
|
19
21
|
* Load environment variables from .env file
|
|
20
22
|
*/
|
|
@@ -48,6 +50,240 @@ 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
|
+
* Convert a field type to a TypeScript type
|
|
71
|
+
*/
|
|
72
|
+
function fieldTypeToTsType(fieldType) {
|
|
73
|
+
switch (fieldType) {
|
|
74
|
+
case 'number':
|
|
75
|
+
case 'rating':
|
|
76
|
+
return 'number';
|
|
77
|
+
case 'checkbox':
|
|
78
|
+
case 'toggle':
|
|
79
|
+
return 'boolean';
|
|
80
|
+
case 'select':
|
|
81
|
+
case 'radio':
|
|
82
|
+
return 'string';
|
|
83
|
+
case 'multiselect':
|
|
84
|
+
case 'tags':
|
|
85
|
+
return 'string[]';
|
|
86
|
+
case 'json':
|
|
87
|
+
case 'object':
|
|
88
|
+
return 'Record<string, unknown>';
|
|
89
|
+
case 'date':
|
|
90
|
+
case 'datetime':
|
|
91
|
+
return 'string'; // ISO date string
|
|
92
|
+
case 'image':
|
|
93
|
+
case 'file':
|
|
94
|
+
case 'url':
|
|
95
|
+
case 'text':
|
|
96
|
+
case 'textarea':
|
|
97
|
+
case 'richtext':
|
|
98
|
+
case 'email':
|
|
99
|
+
case 'phone':
|
|
100
|
+
default:
|
|
101
|
+
return 'string';
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Convert a string to PascalCase for type names
|
|
106
|
+
*/
|
|
107
|
+
function toPascalCase(str) {
|
|
108
|
+
return str
|
|
109
|
+
.replace(/[-_\s]+(.)?/g, (_, c) => (c ? c.toUpperCase() : ''))
|
|
110
|
+
.replace(/^(.)/, (c) => c.toUpperCase());
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Generate TypeScript types for all modules
|
|
114
|
+
*/
|
|
115
|
+
function generateTypeDefinitions(modules) {
|
|
116
|
+
const lines = [
|
|
117
|
+
'/**',
|
|
118
|
+
' * Auto-generated TypeScript types for CMS modules',
|
|
119
|
+
' * Generated by ayezee-astro-cms integration',
|
|
120
|
+
' * DO NOT EDIT - This file is regenerated on each build',
|
|
121
|
+
' */',
|
|
122
|
+
'',
|
|
123
|
+
'// Base type for all module data items',
|
|
124
|
+
'export interface ModuleDataItem<T = Record<string, unknown>> {',
|
|
125
|
+
' id: string;',
|
|
126
|
+
' data: T;',
|
|
127
|
+
' sortOrder?: number;',
|
|
128
|
+
' status?: string;',
|
|
129
|
+
' createdAt: string;',
|
|
130
|
+
' updatedAt?: string;',
|
|
131
|
+
'}',
|
|
132
|
+
'',
|
|
133
|
+
];
|
|
134
|
+
for (const module of modules) {
|
|
135
|
+
const typeName = toPascalCase(module.instanceKey);
|
|
136
|
+
const dataTypeName = `${typeName}Data`;
|
|
137
|
+
const itemTypeName = `${typeName}Item`;
|
|
138
|
+
// Generate the data shape interface
|
|
139
|
+
lines.push(`// Module: ${module.label} (${module.instanceKey})`);
|
|
140
|
+
lines.push(`export interface ${dataTypeName} {`);
|
|
141
|
+
for (const field of module.fields) {
|
|
142
|
+
const tsType = fieldTypeToTsType(field.fieldType);
|
|
143
|
+
const optional = field.required ? '' : '?';
|
|
144
|
+
const comment = field.label !== field.key ? ` // ${field.label}` : '';
|
|
145
|
+
lines.push(` ${field.key}${optional}: ${tsType};${comment}`);
|
|
146
|
+
}
|
|
147
|
+
lines.push('}');
|
|
148
|
+
lines.push('');
|
|
149
|
+
// Generate the full item type (with id, createdAt, etc.)
|
|
150
|
+
lines.push(`export type ${itemTypeName} = ModuleDataItem<${dataTypeName}>;`);
|
|
151
|
+
lines.push('');
|
|
152
|
+
}
|
|
153
|
+
// Generate a union type of all module keys for type-safe lookups
|
|
154
|
+
lines.push('// All available module instance keys');
|
|
155
|
+
lines.push('export type ModuleInstanceKey =');
|
|
156
|
+
for (let i = 0; i < modules.length; i++) {
|
|
157
|
+
const comma = i < modules.length - 1 ? '' : ';';
|
|
158
|
+
lines.push(` | '${modules[i].instanceKey}'${comma}`);
|
|
159
|
+
}
|
|
160
|
+
lines.push('');
|
|
161
|
+
// Generate a mapping type for getModuleData
|
|
162
|
+
lines.push('// Type mapping for getModuleData helper');
|
|
163
|
+
lines.push('export interface ModuleDataMap {');
|
|
164
|
+
for (const module of modules) {
|
|
165
|
+
const itemTypeName = `${toPascalCase(module.instanceKey)}Item`;
|
|
166
|
+
lines.push(` '${module.instanceKey}': ${itemTypeName}[];`);
|
|
167
|
+
}
|
|
168
|
+
lines.push('}');
|
|
169
|
+
lines.push('');
|
|
170
|
+
return lines.join('\n');
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* Generate wrapper file that auto-initializes the CMS helper
|
|
174
|
+
*/
|
|
175
|
+
function generateWrapperFile() {
|
|
176
|
+
return `/**
|
|
177
|
+
* Auto-generated CMS wrapper with pre-initialized helper
|
|
178
|
+
* Generated by ayezee-astro-cms integration
|
|
179
|
+
* DO NOT EDIT - This file is regenerated on each build
|
|
180
|
+
*/
|
|
181
|
+
|
|
182
|
+
import cmsData from './cms-cache.json';
|
|
183
|
+
import {
|
|
184
|
+
initCmsHelper,
|
|
185
|
+
getProject,
|
|
186
|
+
getModules,
|
|
187
|
+
getModule,
|
|
188
|
+
getModuleByLabel,
|
|
189
|
+
getModuleBySlug,
|
|
190
|
+
getModulesByCategory,
|
|
191
|
+
getModulesByDataType,
|
|
192
|
+
getForms,
|
|
193
|
+
getCollections,
|
|
194
|
+
getSingletons,
|
|
195
|
+
getModuleData,
|
|
196
|
+
getModuleDataByLabel,
|
|
197
|
+
getModuleDataBySlug,
|
|
198
|
+
getTurnstileConfig,
|
|
199
|
+
isTurnstileEnabled,
|
|
200
|
+
getFormConfig,
|
|
201
|
+
getCacheInfo,
|
|
202
|
+
getAnalyticsConfig,
|
|
203
|
+
isAnalyticsEnabled,
|
|
204
|
+
getAnalyticsWebsiteId,
|
|
205
|
+
type CMSCache,
|
|
206
|
+
type CachedModule,
|
|
207
|
+
type ModuleDataItem,
|
|
208
|
+
type ModuleField,
|
|
209
|
+
type AnalyticsConfig,
|
|
210
|
+
} from 'ayezee-astro-cms';
|
|
211
|
+
|
|
212
|
+
// Auto-initialize on import
|
|
213
|
+
initCmsHelper(cmsData as unknown as CMSCache);
|
|
214
|
+
|
|
215
|
+
// Re-export everything for convenience
|
|
216
|
+
export {
|
|
217
|
+
getProject,
|
|
218
|
+
getModules,
|
|
219
|
+
getModule,
|
|
220
|
+
getModuleByLabel,
|
|
221
|
+
getModuleBySlug,
|
|
222
|
+
getModulesByCategory,
|
|
223
|
+
getModulesByDataType,
|
|
224
|
+
getForms,
|
|
225
|
+
getCollections,
|
|
226
|
+
getSingletons,
|
|
227
|
+
getModuleData,
|
|
228
|
+
getModuleDataByLabel,
|
|
229
|
+
getModuleDataBySlug,
|
|
230
|
+
getTurnstileConfig,
|
|
231
|
+
isTurnstileEnabled,
|
|
232
|
+
getFormConfig,
|
|
233
|
+
getCacheInfo,
|
|
234
|
+
getAnalyticsConfig,
|
|
235
|
+
isAnalyticsEnabled,
|
|
236
|
+
getAnalyticsWebsiteId,
|
|
237
|
+
};
|
|
238
|
+
|
|
239
|
+
// Re-export types
|
|
240
|
+
export type {
|
|
241
|
+
CMSCache,
|
|
242
|
+
CachedModule,
|
|
243
|
+
ModuleDataItem,
|
|
244
|
+
ModuleField,
|
|
245
|
+
AnalyticsConfig,
|
|
246
|
+
};
|
|
247
|
+
|
|
248
|
+
// Export the raw cache data for advanced use cases
|
|
249
|
+
export { cmsData };
|
|
250
|
+
`;
|
|
251
|
+
}
|
|
252
|
+
/**
|
|
253
|
+
* Report site version to CMS dashboard
|
|
254
|
+
*/
|
|
255
|
+
async function reportSiteVersion(baseUrl, apiKey, siteUrl, environment, astroVersion, logger) {
|
|
256
|
+
try {
|
|
257
|
+
const response = await fetch(`${baseUrl}/sites`, {
|
|
258
|
+
method: 'POST',
|
|
259
|
+
headers: {
|
|
260
|
+
'Content-Type': 'application/json',
|
|
261
|
+
...(apiKey && { 'Authorization': `Bearer ${apiKey}` }),
|
|
262
|
+
},
|
|
263
|
+
body: JSON.stringify({
|
|
264
|
+
siteUrl,
|
|
265
|
+
environment,
|
|
266
|
+
packageVersion: PACKAGE_VERSION,
|
|
267
|
+
astroVersion,
|
|
268
|
+
metadata: {
|
|
269
|
+
nodeVersion: process.version,
|
|
270
|
+
platform: process.platform,
|
|
271
|
+
buildTime: new Date().toISOString(),
|
|
272
|
+
},
|
|
273
|
+
}),
|
|
274
|
+
});
|
|
275
|
+
if (response.ok) {
|
|
276
|
+
logger.info(`📡 Reported site version to dashboard`);
|
|
277
|
+
}
|
|
278
|
+
else {
|
|
279
|
+
logger.warn(`⚠️ Failed to report site version: ${response.status}`);
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
catch (error) {
|
|
283
|
+
// Don't fail the build if version reporting fails
|
|
284
|
+
logger.warn(`⚠️ Could not report site version (non-critical)`);
|
|
285
|
+
}
|
|
286
|
+
}
|
|
51
287
|
/**
|
|
52
288
|
* AyeZee CMS Astro Integration
|
|
53
289
|
*/
|
|
@@ -57,7 +293,7 @@ export function ayezeeCms(options = {}) {
|
|
|
57
293
|
name: 'ayezee-cms',
|
|
58
294
|
hooks: {
|
|
59
295
|
'astro:config:setup': async ({ config, logger, injectScript }) => {
|
|
60
|
-
logger.info(
|
|
296
|
+
logger.info(`🚀 AyeZee CMS v${PACKAGE_VERSION}: Fetching data...`);
|
|
61
297
|
// Load environment variables from .env
|
|
62
298
|
loadEnvFile();
|
|
63
299
|
// Get configuration
|
|
@@ -68,21 +304,104 @@ export function ayezeeCms(options = {}) {
|
|
|
68
304
|
const cacheFileName = options.cacheFileName || 'cms-cache.json';
|
|
69
305
|
const skipOnError = options.skipOnError || false;
|
|
70
306
|
const enableAnalytics = options.enableAnalytics !== false;
|
|
71
|
-
|
|
307
|
+
const reportVersion = options.reportVersion !== false;
|
|
308
|
+
const siteUrl = options.siteUrl || process.env.SITE_URL || process.env.URL || process.env.VERCEL_URL;
|
|
309
|
+
const environment = options.environment || process.env.NODE_ENV || 'production';
|
|
310
|
+
// Validate config with helpful error messages
|
|
72
311
|
if (!cmsDomain || !projectSlug) {
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
312
|
+
logger.error('');
|
|
313
|
+
logger.error('❌ AyeZee CMS Configuration Error');
|
|
314
|
+
logger.error('═══════════════════════════════════════════════════════════');
|
|
315
|
+
logger.error('');
|
|
316
|
+
logger.error('Missing required environment variables:');
|
|
317
|
+
if (!cmsDomain) {
|
|
318
|
+
logger.error(' ✗ PUBLIC_CMS_DOMAIN - The URL of your CMS dashboard');
|
|
319
|
+
logger.error(' Example: PUBLIC_CMS_DOMAIN=https://cms.yourdomain.com');
|
|
320
|
+
}
|
|
321
|
+
if (!projectSlug) {
|
|
322
|
+
logger.error(' ✗ PUBLIC_PROJECT_SLUG - Your project identifier');
|
|
323
|
+
logger.error(' Example: PUBLIC_PROJECT_SLUG=my-project');
|
|
324
|
+
}
|
|
325
|
+
logger.error('');
|
|
326
|
+
logger.error('Add these to your .env file:');
|
|
327
|
+
logger.error('');
|
|
328
|
+
logger.error(' PUBLIC_CMS_DOMAIN=https://your-cms-domain.com');
|
|
329
|
+
logger.error(' PUBLIC_PROJECT_SLUG=your-project-slug');
|
|
330
|
+
logger.error(' PUBLIC_AYEZEE_API_KEY=AZ_your_api_key (optional)');
|
|
331
|
+
logger.error('');
|
|
332
|
+
logger.error('═══════════════════════════════════════════════════════════');
|
|
333
|
+
logger.error('');
|
|
78
334
|
if (skipOnError) {
|
|
79
335
|
logger.warn('⚠️ Skipping CMS data fetch due to missing config');
|
|
336
|
+
logger.warn(' Build will continue with cached data (if available)');
|
|
80
337
|
return;
|
|
81
338
|
}
|
|
82
|
-
throw new Error(`AyeZee CMS integration requires PUBLIC_CMS_DOMAIN and PUBLIC_PROJECT_SLUG`
|
|
339
|
+
throw new Error(`AyeZee CMS integration requires PUBLIC_CMS_DOMAIN and PUBLIC_PROJECT_SLUG. ` +
|
|
340
|
+
`See the error messages above for details.`);
|
|
83
341
|
}
|
|
342
|
+
const generateTypes = options.generateTypes !== false;
|
|
343
|
+
const generateWrapper = options.generateWrapper !== false;
|
|
84
344
|
logger.info(` Domain: ${cmsDomain}`);
|
|
85
345
|
logger.info(` Project: ${projectSlug}`);
|
|
346
|
+
logger.info(` Environment: ${environment}`);
|
|
347
|
+
// Get the data directory path
|
|
348
|
+
const dataDir = path.join(process.cwd(), outputDir);
|
|
349
|
+
const cachePath = path.join(dataDir, cacheFileName);
|
|
350
|
+
// Check if we can skip fetching in development mode
|
|
351
|
+
const isDev = environment === 'development' || process.env.NODE_ENV === 'development';
|
|
352
|
+
const forceFresh = process.env.CMS_FRESH === 'true';
|
|
353
|
+
const cacheExists = fs.existsSync(cachePath);
|
|
354
|
+
if (isDev && cacheExists && !forceFresh) {
|
|
355
|
+
logger.info('');
|
|
356
|
+
logger.info('📦 Using cached CMS data (dev mode)');
|
|
357
|
+
logger.info(' Run with CMS_FRESH=true to fetch fresh data');
|
|
358
|
+
logger.info('');
|
|
359
|
+
// Still generate types and wrapper from existing cache
|
|
360
|
+
if (generateTypes || generateWrapper) {
|
|
361
|
+
try {
|
|
362
|
+
const existingCache = JSON.parse(fs.readFileSync(cachePath, 'utf-8'));
|
|
363
|
+
if (generateTypes && existingCache.modules) {
|
|
364
|
+
const typesContent = generateTypeDefinitions(existingCache.modules);
|
|
365
|
+
const typesPath = path.join(dataDir, 'cms-types.ts');
|
|
366
|
+
fs.writeFileSync(typesPath, typesContent, 'utf-8');
|
|
367
|
+
logger.info(`✅ Generated types: ${path.relative(process.cwd(), typesPath)}`);
|
|
368
|
+
}
|
|
369
|
+
if (generateWrapper) {
|
|
370
|
+
const wrapperContent = generateWrapperFile();
|
|
371
|
+
const wrapperPath = path.join(dataDir, 'cms.ts');
|
|
372
|
+
fs.writeFileSync(wrapperPath, wrapperContent, 'utf-8');
|
|
373
|
+
logger.info(`✅ Generated wrapper: ${path.relative(process.cwd(), wrapperPath)}`);
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
catch {
|
|
377
|
+
logger.warn('⚠️ Could not generate types/wrapper from cached data');
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
// Handle analytics injection from cached data
|
|
381
|
+
if (enableAnalytics) {
|
|
382
|
+
try {
|
|
383
|
+
const existingCache = JSON.parse(fs.readFileSync(cachePath, 'utf-8'));
|
|
384
|
+
if (existingCache.analytics) {
|
|
385
|
+
analyticsConfig = existingCache.analytics;
|
|
386
|
+
injectScript('head-inline', `
|
|
387
|
+
(function() {
|
|
388
|
+
var script = document.createElement('script');
|
|
389
|
+
script.defer = true;
|
|
390
|
+
script.src = '${analyticsConfig.baseUrl}/script.js';
|
|
391
|
+
script.setAttribute('data-website-id', '${analyticsConfig.websiteId}');
|
|
392
|
+
document.head.appendChild(script);
|
|
393
|
+
})();
|
|
394
|
+
`);
|
|
395
|
+
logger.info('📊 Umami analytics script injected from cache');
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
catch {
|
|
399
|
+
// Ignore errors reading cache for analytics
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
logger.info('');
|
|
403
|
+
return;
|
|
404
|
+
}
|
|
86
405
|
try {
|
|
87
406
|
// Build API URL
|
|
88
407
|
let domain = cmsDomain;
|
|
@@ -91,9 +410,9 @@ export function ayezeeCms(options = {}) {
|
|
|
91
410
|
domain = `${protocol}://${domain}`;
|
|
92
411
|
}
|
|
93
412
|
const baseUrl = `${domain}/api/v1/projects/${projectSlug}`;
|
|
94
|
-
// Fetch modules
|
|
95
|
-
logger.info('📡 Fetching modules...');
|
|
96
|
-
const modulesResponse = await fetch(`${baseUrl}/modules`, {
|
|
413
|
+
// Fetch all modules with data in a single API call
|
|
414
|
+
logger.info('📡 Fetching modules with data...');
|
|
415
|
+
const modulesResponse = await fetch(`${baseUrl}/modules?include=data`, {
|
|
97
416
|
headers: {
|
|
98
417
|
...(apiKey && { 'Authorization': `Bearer ${apiKey}` }),
|
|
99
418
|
},
|
|
@@ -112,44 +431,21 @@ export function ayezeeCms(options = {}) {
|
|
|
112
431
|
analyticsConfig = modulesResult.data.analytics;
|
|
113
432
|
logger.info(`📊 Analytics configured: ${analyticsConfig.websiteId}`);
|
|
114
433
|
}
|
|
115
|
-
//
|
|
116
|
-
const modulesWithData =
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
modulesWithData.push({
|
|
131
|
-
...module,
|
|
132
|
-
slug: slugify(module.label),
|
|
133
|
-
data: dataResult.data?.data || [],
|
|
134
|
-
pagination: dataResult.data?.pagination || {
|
|
135
|
-
total: 0,
|
|
136
|
-
count: 0,
|
|
137
|
-
},
|
|
138
|
-
parameters: dataResult.data?.module?.parameters || {},
|
|
139
|
-
});
|
|
140
|
-
}
|
|
141
|
-
catch (error) {
|
|
142
|
-
const errorMessage = error instanceof Error ? error.message : 'Unknown error';
|
|
143
|
-
logger.warn(` ⚠️ Failed to fetch ${module.label}: ${errorMessage}`);
|
|
144
|
-
modulesWithData.push({
|
|
145
|
-
...module,
|
|
146
|
-
slug: slugify(module.label),
|
|
147
|
-
data: [],
|
|
148
|
-
pagination: { total: 0, count: 0 },
|
|
149
|
-
parameters: {},
|
|
150
|
-
});
|
|
151
|
-
}
|
|
152
|
-
}
|
|
434
|
+
// Transform modules to include slug and ensure consistent shape
|
|
435
|
+
const modulesWithData = modules.map((module) => {
|
|
436
|
+
const itemCount = module.data?.length || 0;
|
|
437
|
+
logger.info(` 📦 ${module.label}: ${itemCount} items`);
|
|
438
|
+
return {
|
|
439
|
+
...module,
|
|
440
|
+
slug: slugify(module.label),
|
|
441
|
+
data: module.data || [],
|
|
442
|
+
pagination: module.pagination || {
|
|
443
|
+
total: itemCount,
|
|
444
|
+
count: itemCount,
|
|
445
|
+
},
|
|
446
|
+
parameters: module.parameters || {},
|
|
447
|
+
};
|
|
448
|
+
});
|
|
153
449
|
// Create cache data
|
|
154
450
|
const cacheData = {
|
|
155
451
|
project: modulesResult.data.project,
|
|
@@ -158,17 +454,28 @@ export function ayezeeCms(options = {}) {
|
|
|
158
454
|
fetchedAt: new Date().toISOString(),
|
|
159
455
|
version: '1.0',
|
|
160
456
|
};
|
|
161
|
-
// Get the data directory path
|
|
162
|
-
const dataDir = path.join(process.cwd(), outputDir);
|
|
163
457
|
// Ensure directory exists
|
|
164
458
|
if (!fs.existsSync(dataDir)) {
|
|
165
459
|
fs.mkdirSync(dataDir, { recursive: true });
|
|
166
460
|
}
|
|
167
461
|
// Write cache file
|
|
168
|
-
const cachePath = path.join(dataDir, cacheFileName);
|
|
169
462
|
fs.writeFileSync(cachePath, JSON.stringify(cacheData, null, 2), 'utf-8');
|
|
170
463
|
logger.info(`✅ Cached data to: ${path.relative(process.cwd(), cachePath)}`);
|
|
171
464
|
logger.info(`📅 Fetched at: ${cacheData.fetchedAt}`);
|
|
465
|
+
// Generate TypeScript types
|
|
466
|
+
if (generateTypes) {
|
|
467
|
+
const typesContent = generateTypeDefinitions(modulesWithData);
|
|
468
|
+
const typesPath = path.join(dataDir, 'cms-types.ts');
|
|
469
|
+
fs.writeFileSync(typesPath, typesContent, 'utf-8');
|
|
470
|
+
logger.info(`✅ Generated types: ${path.relative(process.cwd(), typesPath)}`);
|
|
471
|
+
}
|
|
472
|
+
// Generate wrapper file
|
|
473
|
+
if (generateWrapper) {
|
|
474
|
+
const wrapperContent = generateWrapperFile();
|
|
475
|
+
const wrapperPath = path.join(dataDir, 'cms.ts');
|
|
476
|
+
fs.writeFileSync(wrapperPath, wrapperContent, 'utf-8');
|
|
477
|
+
logger.info(`✅ Generated wrapper: ${path.relative(process.cwd(), wrapperPath)}`);
|
|
478
|
+
}
|
|
172
479
|
// Inject Umami analytics script if configured
|
|
173
480
|
if (enableAnalytics && analyticsConfig) {
|
|
174
481
|
logger.info('📊 Injecting Umami analytics script...');
|
|
@@ -183,13 +490,49 @@ export function ayezeeCms(options = {}) {
|
|
|
183
490
|
`);
|
|
184
491
|
logger.info('✅ Umami analytics script injected');
|
|
185
492
|
}
|
|
493
|
+
// Report site version to dashboard (non-blocking)
|
|
494
|
+
if (reportVersion && siteUrl) {
|
|
495
|
+
const astroVersion = getAstroVersion();
|
|
496
|
+
reportSiteVersion(baseUrl, apiKey, siteUrl, environment, astroVersion, logger);
|
|
497
|
+
}
|
|
498
|
+
logger.info('');
|
|
499
|
+
logger.info('🎉 AyeZee CMS data fetched successfully!');
|
|
500
|
+
logger.info('');
|
|
186
501
|
}
|
|
187
502
|
catch (error) {
|
|
188
503
|
const errorMessage = error instanceof Error ? error.message : 'Unknown error';
|
|
189
|
-
logger.error('
|
|
190
|
-
logger.error(
|
|
504
|
+
logger.error('');
|
|
505
|
+
logger.error('❌ Failed to fetch CMS data');
|
|
506
|
+
logger.error('═══════════════════════════════════════════════════════════');
|
|
507
|
+
logger.error('');
|
|
508
|
+
logger.error(`Error: ${errorMessage}`);
|
|
509
|
+
logger.error('');
|
|
510
|
+
// Provide helpful troubleshooting tips
|
|
511
|
+
if (errorMessage.includes('ECONNREFUSED') || errorMessage.includes('fetch failed')) {
|
|
512
|
+
logger.error('Troubleshooting tips:');
|
|
513
|
+
logger.error(' 1. Is the CMS dashboard running?');
|
|
514
|
+
logger.error(` 2. Can you access ${cmsDomain} in your browser?`);
|
|
515
|
+
logger.error(' 3. Check your network connection');
|
|
516
|
+
logger.error(' 4. If using localhost, ensure the dashboard is started');
|
|
517
|
+
}
|
|
518
|
+
else if (errorMessage.includes('401') || errorMessage.includes('403')) {
|
|
519
|
+
logger.error('Troubleshooting tips:');
|
|
520
|
+
logger.error(' 1. Check that PUBLIC_AYEZEE_API_KEY is correct');
|
|
521
|
+
logger.error(' 2. Verify the API key has read permissions');
|
|
522
|
+
logger.error(' 3. Ensure the project slug matches your dashboard project');
|
|
523
|
+
}
|
|
524
|
+
else if (errorMessage.includes('404')) {
|
|
525
|
+
logger.error('Troubleshooting tips:');
|
|
526
|
+
logger.error(' 1. Verify PUBLIC_PROJECT_SLUG is correct');
|
|
527
|
+
logger.error(' 2. Check that the project exists in the dashboard');
|
|
528
|
+
logger.error(` 3. Project slug should match: ${projectSlug}`);
|
|
529
|
+
}
|
|
530
|
+
logger.error('');
|
|
531
|
+
logger.error('═══════════════════════════════════════════════════════════');
|
|
532
|
+
logger.error('');
|
|
191
533
|
if (skipOnError) {
|
|
192
|
-
logger.warn('⚠️ Continuing build
|
|
534
|
+
logger.warn('⚠️ Continuing build with cached data (skipOnError: true)');
|
|
535
|
+
logger.warn(' The site will use previously cached CMS data if available.');
|
|
193
536
|
return;
|
|
194
537
|
}
|
|
195
538
|
throw error;
|
package/package.json
CHANGED