@oaysus/cli 0.1.13 → 0.1.15

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 (85) hide show
  1. package/README.md +35 -12
  2. package/dist/cli.d.ts.map +1 -1
  3. package/dist/cli.js +151 -85
  4. package/dist/cli.js.map +1 -1
  5. package/dist/components/App.d.ts +26 -10
  6. package/dist/components/App.d.ts.map +1 -1
  7. package/dist/components/App.js +23 -8
  8. package/dist/components/App.js.map +1 -1
  9. package/dist/components/SlashCommands.js +1 -1
  10. package/dist/lib/push.d.ts.map +1 -1
  11. package/dist/lib/push.js +29 -1
  12. package/dist/lib/push.js.map +1 -1
  13. package/dist/lib/shared/commands.d.ts +11 -1
  14. package/dist/lib/shared/commands.d.ts.map +1 -1
  15. package/dist/lib/shared/commands.js +55 -13
  16. package/dist/lib/shared/commands.js.map +1 -1
  17. package/dist/lib/shared/uploader.d.ts +1 -0
  18. package/dist/lib/shared/uploader.d.ts.map +1 -1
  19. package/dist/lib/shared/uploader.js +4 -2
  20. package/dist/lib/shared/uploader.js.map +1 -1
  21. package/dist/lib/site/asset-puller.d.ts +93 -0
  22. package/dist/lib/site/asset-puller.d.ts.map +1 -0
  23. package/dist/lib/site/asset-puller.js +376 -0
  24. package/dist/lib/site/asset-puller.js.map +1 -0
  25. package/dist/lib/site/asset-resolver.d.ts +44 -0
  26. package/dist/lib/site/asset-resolver.d.ts.map +1 -0
  27. package/dist/lib/site/asset-resolver.js +225 -0
  28. package/dist/lib/site/asset-resolver.js.map +1 -0
  29. package/dist/lib/site/asset-uploader.d.ts +58 -0
  30. package/dist/lib/site/asset-uploader.d.ts.map +1 -0
  31. package/dist/lib/site/asset-uploader.js +261 -0
  32. package/dist/lib/site/asset-uploader.js.map +1 -0
  33. package/dist/lib/site/index.d.ts +14 -0
  34. package/dist/lib/site/index.d.ts.map +1 -0
  35. package/dist/lib/site/index.js +15 -0
  36. package/dist/lib/site/index.js.map +1 -0
  37. package/dist/lib/site/metadata.d.ts +99 -0
  38. package/dist/lib/site/metadata.d.ts.map +1 -0
  39. package/dist/lib/site/metadata.js +470 -0
  40. package/dist/lib/site/metadata.js.map +1 -0
  41. package/dist/lib/site/page-publisher.d.ts +51 -0
  42. package/dist/lib/site/page-publisher.d.ts.map +1 -0
  43. package/dist/lib/site/page-publisher.js +460 -0
  44. package/dist/lib/site/page-publisher.js.map +1 -0
  45. package/dist/lib/site/page-puller.d.ts +93 -0
  46. package/dist/lib/site/page-puller.d.ts.map +1 -0
  47. package/dist/lib/site/page-puller.js +346 -0
  48. package/dist/lib/site/page-puller.js.map +1 -0
  49. package/dist/lib/site/page-validator.d.ts +29 -0
  50. package/dist/lib/site/page-validator.d.ts.map +1 -0
  51. package/dist/lib/site/page-validator.js +282 -0
  52. package/dist/lib/site/page-validator.js.map +1 -0
  53. package/dist/lib/site/project-loader.d.ts +45 -0
  54. package/dist/lib/site/project-loader.d.ts.map +1 -0
  55. package/dist/lib/site/project-loader.js +276 -0
  56. package/dist/lib/site/project-loader.js.map +1 -0
  57. package/dist/lib/site/shared-component-resolver.d.ts +89 -0
  58. package/dist/lib/site/shared-component-resolver.d.ts.map +1 -0
  59. package/dist/lib/site/shared-component-resolver.js +222 -0
  60. package/dist/lib/site/shared-component-resolver.js.map +1 -0
  61. package/dist/screens/WelcomeScreen.d.ts +26 -10
  62. package/dist/screens/WelcomeScreen.d.ts.map +1 -1
  63. package/dist/screens/WelcomeScreen.js +44 -21
  64. package/dist/screens/WelcomeScreen.js.map +1 -1
  65. package/dist/screens/site/SiteInitScreen.d.ts +12 -0
  66. package/dist/screens/site/SiteInitScreen.d.ts.map +1 -0
  67. package/dist/screens/site/SiteInitScreen.js +282 -0
  68. package/dist/screens/site/SiteInitScreen.js.map +1 -0
  69. package/dist/screens/site/SitePublishScreen.d.ts +15 -0
  70. package/dist/screens/site/SitePublishScreen.d.ts.map +1 -0
  71. package/dist/screens/site/SitePublishScreen.js +330 -0
  72. package/dist/screens/site/SitePublishScreen.js.map +1 -0
  73. package/dist/screens/site/SitePullScreen.d.ts +14 -0
  74. package/dist/screens/site/SitePullScreen.d.ts.map +1 -0
  75. package/dist/screens/site/SitePullScreen.js +455 -0
  76. package/dist/screens/site/SitePullScreen.js.map +1 -0
  77. package/dist/screens/site/SiteValidateScreen.d.ts +12 -0
  78. package/dist/screens/site/SiteValidateScreen.d.ts.map +1 -0
  79. package/dist/screens/site/SiteValidateScreen.js +201 -0
  80. package/dist/screens/site/SiteValidateScreen.js.map +1 -0
  81. package/dist/types/site.d.ts +348 -0
  82. package/dist/types/site.d.ts.map +1 -0
  83. package/dist/types/site.js +6 -0
  84. package/dist/types/site.js.map +1 -0
  85. package/package.json +1 -1
@@ -0,0 +1,376 @@
1
+ /**
2
+ * Asset Puller
3
+ * Pulls assets from the Oaysus DAM to local files
4
+ * Only downloads missing or changed assets (based on content hash)
5
+ */
6
+ import axios from 'axios';
7
+ import * as fs from 'fs/promises';
8
+ import * as path from 'path';
9
+ import * as crypto from 'crypto';
10
+ import { loadCredentials } from '../shared/auth.js';
11
+ import { SSO_BASE_URL, debug } from '../shared/config.js';
12
+ import { loadAssetManifest, saveAssetManifest } from './metadata.js';
13
+ /**
14
+ * Compute SHA-256 hash of a buffer
15
+ */
16
+ function computeHash(buffer) {
17
+ return crypto.createHash('sha256').update(buffer).digest('hex');
18
+ }
19
+ /**
20
+ * Check if a file exists
21
+ */
22
+ async function fileExists(filePath) {
23
+ try {
24
+ await fs.access(filePath);
25
+ return true;
26
+ }
27
+ catch {
28
+ return false;
29
+ }
30
+ }
31
+ // loadAssetManifest and saveAssetManifest are now imported from metadata.ts
32
+ // as loadAssetManifest and saveAssetManifest
33
+ /**
34
+ * Fetch all assets from the server
35
+ */
36
+ async function fetchAssets(websiteId, jwt) {
37
+ const url = `${SSO_BASE_URL}/hosting/dam/assets`;
38
+ debug('Fetching assets from:', url);
39
+ try {
40
+ const response = await axios.get(url, {
41
+ params: { websiteId },
42
+ headers: {
43
+ Authorization: `Bearer ${jwt}`,
44
+ },
45
+ });
46
+ if (response.data.success && response.data.assets) {
47
+ return { success: true, assets: response.data.assets };
48
+ }
49
+ return { success: false, assets: [], error: response.data.error || 'Unknown error' };
50
+ }
51
+ catch (error) {
52
+ let errorMessage = 'Failed to fetch assets';
53
+ if (axios.isAxiosError(error)) {
54
+ if (error.response?.status === 401) {
55
+ errorMessage = 'Authentication failed. Please run "oaysus login"';
56
+ }
57
+ else {
58
+ errorMessage = error.response?.data?.error ||
59
+ error.response?.data?.detail?.error ||
60
+ error.message;
61
+ }
62
+ }
63
+ else if (error instanceof Error) {
64
+ errorMessage = error.message;
65
+ }
66
+ return { success: false, assets: [], error: errorMessage };
67
+ }
68
+ }
69
+ /**
70
+ * Download a file from URL
71
+ */
72
+ async function downloadFile(url) {
73
+ const response = await axios.get(url, {
74
+ responseType: 'arraybuffer',
75
+ timeout: 60000, // 60 second timeout for large files
76
+ });
77
+ return Buffer.from(response.data);
78
+ }
79
+ /**
80
+ * Preview what assets would be pulled without actually pulling them
81
+ */
82
+ export async function previewAssetPull(options) {
83
+ const { projectPath, config } = options;
84
+ // Get credentials if not provided
85
+ let websiteId = options.websiteId || config.websiteId;
86
+ let jwt = options.jwt;
87
+ if (!websiteId || !jwt) {
88
+ const credentials = await loadCredentials();
89
+ if (!credentials) {
90
+ return {
91
+ success: false,
92
+ error: 'Not logged in. Please run "oaysus login"',
93
+ assets: [],
94
+ toDownload: [],
95
+ upToDate: [],
96
+ totalDownloadSize: 0,
97
+ };
98
+ }
99
+ websiteId = websiteId || credentials.websiteId;
100
+ jwt = jwt || credentials.jwt;
101
+ }
102
+ if (!websiteId) {
103
+ return {
104
+ success: false,
105
+ error: 'No website ID found',
106
+ assets: [],
107
+ toDownload: [],
108
+ upToDate: [],
109
+ totalDownloadSize: 0,
110
+ };
111
+ }
112
+ // Fetch assets from server
113
+ const fetchResult = await fetchAssets(websiteId, jwt);
114
+ if (!fetchResult.success) {
115
+ return {
116
+ success: false,
117
+ error: fetchResult.error || 'Failed to fetch assets',
118
+ assets: [],
119
+ toDownload: [],
120
+ upToDate: [],
121
+ totalDownloadSize: 0,
122
+ };
123
+ }
124
+ // Load existing manifest
125
+ const manifest = await loadAssetManifest(projectPath);
126
+ const assetsDir = path.join(projectPath, 'assets');
127
+ const assets = [];
128
+ const toDownload = [];
129
+ const upToDate = [];
130
+ let totalDownloadSize = 0;
131
+ for (const serverAsset of fetchResult.assets) {
132
+ const localPath = path.join(assetsDir, serverAsset.filename);
133
+ const manifestEntry = manifest.assets[serverAsset.filename];
134
+ const localExists = await fileExists(localPath);
135
+ let status = 'new';
136
+ if (localExists && manifestEntry) {
137
+ // Check if content hash matches (if server has hash)
138
+ if (serverAsset.contentHash && manifestEntry.contentHash === serverAsset.contentHash) {
139
+ status = 'up-to-date';
140
+ }
141
+ else if (serverAsset.contentHash) {
142
+ status = 'changed';
143
+ }
144
+ else {
145
+ // No server hash, check by computing local hash
146
+ try {
147
+ const localContent = await fs.readFile(localPath);
148
+ const localHash = computeHash(localContent);
149
+ if (localHash === manifestEntry.contentHash) {
150
+ status = 'up-to-date';
151
+ }
152
+ else {
153
+ status = 'changed';
154
+ }
155
+ }
156
+ catch {
157
+ status = 'changed';
158
+ }
159
+ }
160
+ }
161
+ const preview = {
162
+ filename: serverAsset.filename,
163
+ url: serverAsset.url,
164
+ sizeInBytes: serverAsset.sizeInBytes,
165
+ contentType: serverAsset.contentType,
166
+ status,
167
+ };
168
+ assets.push(preview);
169
+ if (status === 'up-to-date') {
170
+ upToDate.push(preview);
171
+ }
172
+ else {
173
+ toDownload.push(preview);
174
+ totalDownloadSize += serverAsset.sizeInBytes;
175
+ }
176
+ }
177
+ return {
178
+ success: true,
179
+ assets,
180
+ toDownload,
181
+ upToDate,
182
+ totalDownloadSize,
183
+ };
184
+ }
185
+ /**
186
+ * Pull all assets from the server to local files
187
+ * Only downloads missing or changed assets
188
+ */
189
+ export async function pullAssets(options) {
190
+ const { projectPath, config, force = false, dryRun = false, onProgress } = options;
191
+ // Get credentials if not provided
192
+ let websiteId = options.websiteId || config.websiteId;
193
+ let jwt = options.jwt;
194
+ if (!websiteId || !jwt) {
195
+ const credentials = await loadCredentials();
196
+ if (!credentials) {
197
+ return {
198
+ success: false,
199
+ assets: [],
200
+ total: 0,
201
+ downloaded: 0,
202
+ skipped: 0,
203
+ errorCount: 0,
204
+ errors: ['Not logged in. Please run "oaysus login"'],
205
+ };
206
+ }
207
+ websiteId = websiteId || credentials.websiteId;
208
+ jwt = jwt || credentials.jwt;
209
+ }
210
+ if (!websiteId) {
211
+ return {
212
+ success: false,
213
+ assets: [],
214
+ total: 0,
215
+ downloaded: 0,
216
+ skipped: 0,
217
+ errorCount: 0,
218
+ errors: ['No website ID found'],
219
+ };
220
+ }
221
+ // Fetch assets from server
222
+ if (onProgress) {
223
+ onProgress('fetching', 0, 1);
224
+ }
225
+ const fetchResult = await fetchAssets(websiteId, jwt);
226
+ if (!fetchResult.success) {
227
+ return {
228
+ success: false,
229
+ assets: [],
230
+ total: 0,
231
+ downloaded: 0,
232
+ skipped: 0,
233
+ errorCount: 0,
234
+ errors: [fetchResult.error || 'Failed to fetch assets'],
235
+ };
236
+ }
237
+ const serverAssets = fetchResult.assets;
238
+ if (serverAssets.length === 0) {
239
+ return {
240
+ success: true,
241
+ assets: [],
242
+ total: 0,
243
+ downloaded: 0,
244
+ skipped: 0,
245
+ errorCount: 0,
246
+ errors: [],
247
+ };
248
+ }
249
+ if (onProgress) {
250
+ onProgress('fetching', 1, 1);
251
+ }
252
+ // Ensure assets directory exists
253
+ const assetsDir = path.join(projectPath, 'assets');
254
+ if (!dryRun) {
255
+ await fs.mkdir(assetsDir, { recursive: true });
256
+ }
257
+ // Load existing manifest
258
+ const manifest = await loadAssetManifest(projectPath);
259
+ // Process each asset
260
+ const results = [];
261
+ let downloaded = 0;
262
+ let skipped = 0;
263
+ let errorCount = 0;
264
+ const errors = [];
265
+ for (let i = 0; i < serverAssets.length; i++) {
266
+ const serverAsset = serverAssets[i];
267
+ const localPath = path.join(assetsDir, serverAsset.filename);
268
+ const manifestEntry = manifest.assets[serverAsset.filename];
269
+ if (onProgress) {
270
+ onProgress('downloading', i + 1, serverAssets.length, serverAsset.filename);
271
+ }
272
+ // Determine if we need to download
273
+ let needsDownload = force;
274
+ if (!needsDownload) {
275
+ const localExists = await fileExists(localPath);
276
+ if (!localExists) {
277
+ needsDownload = true;
278
+ }
279
+ else if (manifestEntry && serverAsset.contentHash) {
280
+ // Compare server hash with manifest hash
281
+ needsDownload = manifestEntry.contentHash !== serverAsset.contentHash;
282
+ }
283
+ else if (manifestEntry) {
284
+ // No server hash, compute local hash and compare
285
+ try {
286
+ const localContent = await fs.readFile(localPath);
287
+ const localHash = computeHash(localContent);
288
+ needsDownload = localHash !== manifestEntry.contentHash;
289
+ }
290
+ catch {
291
+ needsDownload = true;
292
+ }
293
+ }
294
+ else {
295
+ // File exists but not in manifest, verify by downloading
296
+ needsDownload = true;
297
+ }
298
+ }
299
+ if (!needsDownload) {
300
+ results.push({
301
+ filename: serverAsset.filename,
302
+ action: 'skipped',
303
+ });
304
+ skipped++;
305
+ continue;
306
+ }
307
+ // Download the file
308
+ if (!dryRun) {
309
+ try {
310
+ const fileBuffer = await downloadFile(serverAsset.url);
311
+ const contentHash = computeHash(fileBuffer);
312
+ // Write file
313
+ await fs.writeFile(localPath, fileBuffer);
314
+ // Update manifest
315
+ manifest.assets[serverAsset.filename] = {
316
+ url: serverAsset.url,
317
+ contentType: serverAsset.contentType,
318
+ sizeInBytes: serverAsset.sizeInBytes,
319
+ width: serverAsset.width,
320
+ height: serverAsset.height,
321
+ altText: serverAsset.altText,
322
+ title: serverAsset.title,
323
+ contentHash: serverAsset.contentHash || contentHash,
324
+ };
325
+ results.push({
326
+ filename: serverAsset.filename,
327
+ action: 'downloaded',
328
+ });
329
+ downloaded++;
330
+ }
331
+ catch (error) {
332
+ const errorMessage = error instanceof Error ? error.message : 'Unknown error';
333
+ results.push({
334
+ filename: serverAsset.filename,
335
+ action: 'error',
336
+ error: errorMessage,
337
+ });
338
+ errors.push(`Failed to download ${serverAsset.filename}: ${errorMessage}`);
339
+ errorCount++;
340
+ }
341
+ }
342
+ else {
343
+ // Dry run - just record what would happen
344
+ results.push({
345
+ filename: serverAsset.filename,
346
+ action: 'downloaded',
347
+ });
348
+ downloaded++;
349
+ }
350
+ }
351
+ // Save updated manifest
352
+ if (!dryRun && downloaded > 0) {
353
+ await saveAssetManifest(projectPath, manifest);
354
+ }
355
+ return {
356
+ success: errorCount === 0,
357
+ assets: results,
358
+ total: serverAssets.length,
359
+ downloaded,
360
+ skipped,
361
+ errorCount,
362
+ errors,
363
+ };
364
+ }
365
+ /**
366
+ * Format bytes to human-readable size
367
+ */
368
+ export function formatBytes(bytes) {
369
+ if (bytes === 0)
370
+ return '0 B';
371
+ const k = 1024;
372
+ const sizes = ['B', 'KB', 'MB', 'GB'];
373
+ const i = Math.floor(Math.log(bytes) / Math.log(k));
374
+ return `${(bytes / Math.pow(k, i)).toFixed(1)} ${sizes[i]}`;
375
+ }
376
+ //# sourceMappingURL=asset-puller.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"asset-puller.js","sourceRoot":"","sources":["../../../src/lib/site/asset-puller.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,44 @@
1
+ /**
2
+ * Asset Resolver
3
+ * Finds local asset references (./assets/*) in component props
4
+ */
5
+ import type { PageDefinition, ComponentInstance, AssetReference, LoadedProject, UploadedAssetInfo } from '../../types/site.js';
6
+ /**
7
+ * Find all asset references in a component's props
8
+ */
9
+ export declare function findAssetsInComponent(component: ComponentInstance, componentIndex: number, pageFile: string): AssetReference[];
10
+ /**
11
+ * Find all asset references in a page definition
12
+ */
13
+ export declare function findAssetsInPage(page: PageDefinition, pageFile: string): AssetReference[];
14
+ /**
15
+ * Find all asset references across an entire project
16
+ */
17
+ export declare function findAllAssets(project: LoadedProject): AssetReference[];
18
+ /**
19
+ * Resolve a local asset path to an absolute file path
20
+ */
21
+ export declare function resolveAssetPath(assetRef: AssetReference, projectPath: string): string;
22
+ /**
23
+ * Check if a local asset file exists
24
+ */
25
+ export declare function assetExists(assetRef: AssetReference, projectPath: string): Promise<boolean>;
26
+ /**
27
+ * Get asset file info (size, mime type)
28
+ */
29
+ export declare function getAssetInfo(assetRef: AssetReference, projectPath: string): Promise<{
30
+ absolutePath: string;
31
+ size: number;
32
+ contentType: string;
33
+ } | null>;
34
+ /**
35
+ * Replace asset paths in a page definition with resolved asset objects
36
+ * Image paths are replaced with { id, url, width, height, alt } objects
37
+ * so the dashboard can recognize them as DAM assets
38
+ */
39
+ export declare function replaceAssetPaths(page: PageDefinition, assetMap: Map<string, UploadedAssetInfo>): PageDefinition;
40
+ /**
41
+ * Get unique asset paths from all references (deduplicated)
42
+ */
43
+ export declare function getUniqueAssetPaths(assets: AssetReference[]): string[];
44
+ //# sourceMappingURL=asset-resolver.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"asset-resolver.d.ts","sourceRoot":"","sources":["../../../src/lib/site/asset-resolver.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,KAAK,EACV,cAAc,EACd,iBAAiB,EACjB,cAAc,EACd,aAAa,EACb,iBAAiB,EAClB,MAAM,qBAAqB,CAAC;AA0E7B;;GAEG;AACH,wBAAgB,qBAAqB,CACnC,SAAS,EAAE,iBAAiB,EAC5B,cAAc,EAAE,MAAM,EACtB,QAAQ,EAAE,MAAM,GACf,cAAc,EAAE,CAsBlB;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,cAAc,EACpB,QAAQ,EAAE,MAAM,GACf,cAAc,EAAE,CAoBlB;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,aAAa,GAAG,cAAc,EAAE,CAStE;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAC9B,QAAQ,EAAE,cAAc,EACxB,WAAW,EAAE,MAAM,GAClB,MAAM,CAWR;AAED;;GAEG;AACH,wBAAsB,WAAW,CAC/B,QAAQ,EAAE,cAAc,EACxB,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,OAAO,CAAC,CAQlB;AAED;;GAEG;AACH,wBAAsB,YAAY,CAChC,QAAQ,EAAE,cAAc,EACxB,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC;IACT,YAAY,EAAE,MAAM,CAAC;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;CACrB,GAAG,IAAI,CAAC,CAiCR;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,cAAc,EACpB,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,iBAAiB,CAAC,GACvC,cAAc,CAiDhB;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,cAAc,EAAE,GAAG,MAAM,EAAE,CAGtE"}
@@ -0,0 +1,225 @@
1
+ /**
2
+ * Asset Resolver
3
+ * Finds local asset references (./assets/*) in component props
4
+ */
5
+ import fs from 'fs/promises';
6
+ import path from 'path';
7
+ // Patterns that indicate a local asset path
8
+ const LOCAL_ASSET_PATTERNS = [
9
+ /^\.\/assets\//, // ./assets/image.jpg
10
+ /^\.\.\/assets\//, // ../assets/image.jpg
11
+ /^assets\//, // assets/image.jpg (relative without dot)
12
+ ];
13
+ // Common image/media extensions to help identify asset paths
14
+ const ASSET_EXTENSIONS = [
15
+ '.jpg', '.jpeg', '.png', '.gif', '.webp', '.svg', '.ico',
16
+ '.mp4', '.webm', '.mov', '.avi',
17
+ '.mp3', '.wav', '.ogg',
18
+ '.pdf', '.doc', '.docx',
19
+ ];
20
+ /**
21
+ * Check if a value looks like a local asset path
22
+ */
23
+ function isLocalAssetPath(value) {
24
+ if (typeof value !== 'string')
25
+ return false;
26
+ if (!value)
27
+ return false;
28
+ // Check if matches local asset patterns
29
+ for (const pattern of LOCAL_ASSET_PATTERNS) {
30
+ if (pattern.test(value))
31
+ return true;
32
+ }
33
+ // Check if it's a relative path with known extension
34
+ if (value.startsWith('./') || value.startsWith('../')) {
35
+ const ext = path.extname(value).toLowerCase();
36
+ if (ASSET_EXTENSIONS.includes(ext))
37
+ return true;
38
+ }
39
+ return false;
40
+ }
41
+ /**
42
+ * Recursively find asset references in an object
43
+ */
44
+ function findAssetsInObject(obj, currentPath, pageFile, assets) {
45
+ if (obj === null || obj === undefined)
46
+ return;
47
+ if (typeof obj === 'string') {
48
+ if (isLocalAssetPath(obj)) {
49
+ assets.push({
50
+ localPath: obj,
51
+ propPath: [...currentPath],
52
+ pageFile,
53
+ });
54
+ }
55
+ return;
56
+ }
57
+ if (Array.isArray(obj)) {
58
+ obj.forEach((item, index) => {
59
+ findAssetsInObject(item, [...currentPath, index], pageFile, assets);
60
+ });
61
+ return;
62
+ }
63
+ if (typeof obj === 'object') {
64
+ for (const [key, value] of Object.entries(obj)) {
65
+ findAssetsInObject(value, [...currentPath, key], pageFile, assets);
66
+ }
67
+ }
68
+ }
69
+ /**
70
+ * Find all asset references in a component's props
71
+ */
72
+ export function findAssetsInComponent(component, componentIndex, pageFile) {
73
+ const assets = [];
74
+ // Search in props
75
+ findAssetsInObject(component.props, ['components', componentIndex, 'props'], pageFile, assets);
76
+ // Search in settings if present
77
+ if (component.settings) {
78
+ findAssetsInObject(component.settings, ['components', componentIndex, 'settings'], pageFile, assets);
79
+ }
80
+ return assets;
81
+ }
82
+ /**
83
+ * Find all asset references in a page definition
84
+ */
85
+ export function findAssetsInPage(page, pageFile) {
86
+ const assets = [];
87
+ // Search each component
88
+ page.components.forEach((component, index) => {
89
+ const componentAssets = findAssetsInComponent(component, index, pageFile);
90
+ assets.push(...componentAssets);
91
+ });
92
+ // Search in page settings (e.g., ogImage)
93
+ if (page.settings) {
94
+ findAssetsInObject(page.settings, ['settings'], pageFile, assets);
95
+ }
96
+ return assets;
97
+ }
98
+ /**
99
+ * Find all asset references across an entire project
100
+ */
101
+ export function findAllAssets(project) {
102
+ const assets = [];
103
+ for (const page of project.pages) {
104
+ const pageAssets = findAssetsInPage(page.definition, page.file);
105
+ assets.push(...pageAssets);
106
+ }
107
+ return assets;
108
+ }
109
+ /**
110
+ * Resolve a local asset path to an absolute file path
111
+ */
112
+ export function resolveAssetPath(assetRef, projectPath) {
113
+ // For standalone assets (no pageFile), resolve relative to project root
114
+ if (!assetRef.pageFile) {
115
+ return path.resolve(projectPath, assetRef.localPath);
116
+ }
117
+ // Get the directory containing the page file
118
+ const pageDir = path.dirname(path.join(projectPath, assetRef.pageFile));
119
+ // Resolve the asset path relative to the page file
120
+ return path.resolve(pageDir, assetRef.localPath);
121
+ }
122
+ /**
123
+ * Check if a local asset file exists
124
+ */
125
+ export async function assetExists(assetRef, projectPath) {
126
+ const absolutePath = resolveAssetPath(assetRef, projectPath);
127
+ try {
128
+ await fs.access(absolutePath);
129
+ return true;
130
+ }
131
+ catch {
132
+ return false;
133
+ }
134
+ }
135
+ /**
136
+ * Get asset file info (size, mime type)
137
+ */
138
+ export async function getAssetInfo(assetRef, projectPath) {
139
+ const absolutePath = resolveAssetPath(assetRef, projectPath);
140
+ try {
141
+ const stats = await fs.stat(absolutePath);
142
+ const ext = path.extname(absolutePath).toLowerCase();
143
+ // Determine content type from extension
144
+ const contentTypeMap = {
145
+ '.jpg': 'image/jpeg',
146
+ '.jpeg': 'image/jpeg',
147
+ '.png': 'image/png',
148
+ '.gif': 'image/gif',
149
+ '.webp': 'image/webp',
150
+ '.svg': 'image/svg+xml',
151
+ '.ico': 'image/x-icon',
152
+ '.mp4': 'video/mp4',
153
+ '.webm': 'video/webm',
154
+ '.mov': 'video/quicktime',
155
+ '.mp3': 'audio/mpeg',
156
+ '.wav': 'audio/wav',
157
+ '.ogg': 'audio/ogg',
158
+ '.pdf': 'application/pdf',
159
+ };
160
+ return {
161
+ absolutePath,
162
+ size: stats.size,
163
+ contentType: contentTypeMap[ext] || 'application/octet-stream',
164
+ };
165
+ }
166
+ catch {
167
+ return null;
168
+ }
169
+ }
170
+ /**
171
+ * Replace asset paths in a page definition with resolved asset objects
172
+ * Image paths are replaced with { id, url, width, height, alt } objects
173
+ * so the dashboard can recognize them as DAM assets
174
+ */
175
+ export function replaceAssetPaths(page, assetMap) {
176
+ // Deep clone the page to avoid mutating original
177
+ const cloned = JSON.parse(JSON.stringify(page));
178
+ // Helper to replace paths in an object
179
+ function replacePaths(obj) {
180
+ if (obj === null || obj === undefined)
181
+ return obj;
182
+ if (typeof obj === 'string') {
183
+ // Check if this path has a replacement
184
+ const assetInfo = assetMap.get(obj);
185
+ if (assetInfo) {
186
+ // Return the full asset object for image fields
187
+ // The dashboard expects { id, url, alt, width, height }
188
+ return assetInfo;
189
+ }
190
+ return obj;
191
+ }
192
+ if (Array.isArray(obj)) {
193
+ return obj.map(replacePaths);
194
+ }
195
+ if (typeof obj === 'object') {
196
+ const result = {};
197
+ for (const [key, value] of Object.entries(obj)) {
198
+ result[key] = replacePaths(value);
199
+ }
200
+ return result;
201
+ }
202
+ return obj;
203
+ }
204
+ // Replace in components
205
+ cloned.components = cloned.components.map(component => ({
206
+ ...component,
207
+ props: replacePaths(component.props),
208
+ settings: component.settings
209
+ ? replacePaths(component.settings)
210
+ : undefined,
211
+ }));
212
+ // Replace in settings
213
+ if (cloned.settings) {
214
+ cloned.settings = replacePaths(cloned.settings);
215
+ }
216
+ return cloned;
217
+ }
218
+ /**
219
+ * Get unique asset paths from all references (deduplicated)
220
+ */
221
+ export function getUniqueAssetPaths(assets) {
222
+ const unique = new Set(assets.map(a => a.localPath));
223
+ return Array.from(unique);
224
+ }
225
+ //# sourceMappingURL=asset-resolver.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"asset-resolver.js","sourceRoot":"","sources":["../../../src/lib/site/asset-resolver.ts"],"names":[],"mappings":"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"}