digitaltwin-core 0.1.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.
Files changed (107) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +125 -0
  3. package/dist/components/assets_manager.d.ts +384 -0
  4. package/dist/components/assets_manager.d.ts.map +1 -0
  5. package/dist/components/assets_manager.js +637 -0
  6. package/dist/components/assets_manager.js.map +1 -0
  7. package/dist/components/collector.d.ts +62 -0
  8. package/dist/components/collector.d.ts.map +1 -0
  9. package/dist/components/collector.js +80 -0
  10. package/dist/components/collector.js.map +1 -0
  11. package/dist/components/global_assets_handler.d.ts +63 -0
  12. package/dist/components/global_assets_handler.d.ts.map +1 -0
  13. package/dist/components/global_assets_handler.js +127 -0
  14. package/dist/components/global_assets_handler.js.map +1 -0
  15. package/dist/components/handler.d.ts +33 -0
  16. package/dist/components/handler.d.ts.map +1 -0
  17. package/dist/components/handler.js +27 -0
  18. package/dist/components/handler.js.map +1 -0
  19. package/dist/components/harvester.d.ts +54 -0
  20. package/dist/components/harvester.d.ts.map +1 -0
  21. package/dist/components/harvester.js +253 -0
  22. package/dist/components/harvester.js.map +1 -0
  23. package/dist/components/index.d.ts +8 -0
  24. package/dist/components/index.d.ts.map +1 -0
  25. package/dist/components/index.js +6 -0
  26. package/dist/components/index.js.map +1 -0
  27. package/dist/components/interfaces.d.ts +18 -0
  28. package/dist/components/interfaces.d.ts.map +1 -0
  29. package/dist/components/interfaces.js +2 -0
  30. package/dist/components/interfaces.js.map +1 -0
  31. package/dist/components/types.d.ts +47 -0
  32. package/dist/components/types.d.ts.map +1 -0
  33. package/dist/components/types.js +2 -0
  34. package/dist/components/types.js.map +1 -0
  35. package/dist/database/adapters/knex_database_adapter.d.ts +47 -0
  36. package/dist/database/adapters/knex_database_adapter.d.ts.map +1 -0
  37. package/dist/database/adapters/knex_database_adapter.js +180 -0
  38. package/dist/database/adapters/knex_database_adapter.js.map +1 -0
  39. package/dist/database/database_adapter.d.ts +92 -0
  40. package/dist/database/database_adapter.d.ts.map +1 -0
  41. package/dist/database/database_adapter.js +6 -0
  42. package/dist/database/database_adapter.js.map +1 -0
  43. package/dist/engine/digital_twin_engine.d.ts +237 -0
  44. package/dist/engine/digital_twin_engine.d.ts.map +1 -0
  45. package/dist/engine/digital_twin_engine.js +574 -0
  46. package/dist/engine/digital_twin_engine.js.map +1 -0
  47. package/dist/engine/endpoints.d.ts +7 -0
  48. package/dist/engine/endpoints.d.ts.map +1 -0
  49. package/dist/engine/endpoints.js +18 -0
  50. package/dist/engine/endpoints.js.map +1 -0
  51. package/dist/engine/events.d.ts +13 -0
  52. package/dist/engine/events.d.ts.map +1 -0
  53. package/dist/engine/events.js +11 -0
  54. package/dist/engine/events.js.map +1 -0
  55. package/dist/engine/initializer.d.ts +8 -0
  56. package/dist/engine/initializer.d.ts.map +1 -0
  57. package/dist/engine/initializer.js +23 -0
  58. package/dist/engine/initializer.js.map +1 -0
  59. package/dist/engine/queue_manager.d.ts +78 -0
  60. package/dist/engine/queue_manager.d.ts.map +1 -0
  61. package/dist/engine/queue_manager.js +167 -0
  62. package/dist/engine/queue_manager.js.map +1 -0
  63. package/dist/engine/scheduler.d.ts +30 -0
  64. package/dist/engine/scheduler.d.ts.map +1 -0
  65. package/dist/engine/scheduler.js +378 -0
  66. package/dist/engine/scheduler.js.map +1 -0
  67. package/dist/env/env.d.ts +25 -0
  68. package/dist/env/env.d.ts.map +1 -0
  69. package/dist/env/env.js +55 -0
  70. package/dist/env/env.js.map +1 -0
  71. package/dist/index.d.ts +23 -0
  72. package/dist/index.d.ts.map +1 -0
  73. package/dist/index.js +31 -0
  74. package/dist/index.js.map +1 -0
  75. package/dist/storage/adapters/local_storage_service.d.ts +29 -0
  76. package/dist/storage/adapters/local_storage_service.d.ts.map +1 -0
  77. package/dist/storage/adapters/local_storage_service.js +50 -0
  78. package/dist/storage/adapters/local_storage_service.js.map +1 -0
  79. package/dist/storage/adapters/ovh_storage_service.d.ts +32 -0
  80. package/dist/storage/adapters/ovh_storage_service.d.ts.map +1 -0
  81. package/dist/storage/adapters/ovh_storage_service.js +70 -0
  82. package/dist/storage/adapters/ovh_storage_service.js.map +1 -0
  83. package/dist/storage/storage_factory.d.ts +14 -0
  84. package/dist/storage/storage_factory.d.ts.map +1 -0
  85. package/dist/storage/storage_factory.js +36 -0
  86. package/dist/storage/storage_factory.js.map +1 -0
  87. package/dist/storage/storage_service.d.ts +26 -0
  88. package/dist/storage/storage_service.d.ts.map +1 -0
  89. package/dist/storage/storage_service.js +7 -0
  90. package/dist/storage/storage_service.js.map +1 -0
  91. package/dist/types/data_record.d.ts +17 -0
  92. package/dist/types/data_record.d.ts.map +1 -0
  93. package/dist/types/data_record.js +2 -0
  94. package/dist/types/data_record.js.map +1 -0
  95. package/dist/utils/logger.d.ts +17 -0
  96. package/dist/utils/logger.d.ts.map +1 -0
  97. package/dist/utils/logger.js +35 -0
  98. package/dist/utils/logger.js.map +1 -0
  99. package/dist/utils/map_to_data_record.d.ts +10 -0
  100. package/dist/utils/map_to_data_record.d.ts.map +1 -0
  101. package/dist/utils/map_to_data_record.js +21 -0
  102. package/dist/utils/map_to_data_record.js.map +1 -0
  103. package/dist/utils/servable_endpoint.d.ts +6 -0
  104. package/dist/utils/servable_endpoint.d.ts.map +1 -0
  105. package/dist/utils/servable_endpoint.js +15 -0
  106. package/dist/utils/servable_endpoint.js.map +1 -0
  107. package/package.json +95 -0
@@ -0,0 +1,637 @@
1
+ /**
2
+ * Abstract base class for Assets Manager components.
3
+ *
4
+ * Provides file upload, storage, and retrieval capabilities following the Digital Twin framework patterns.
5
+ * Each concrete implementation manages a specific type of asset and creates its own database table.
6
+ *
7
+ * @abstract
8
+ * @class AssetsManager
9
+ * @implements {Component}
10
+ * @implements {Servable}
11
+ *
12
+ * @example
13
+ * ```typescript
14
+ * // Create concrete implementations for different asset types
15
+ * class GLTFAssetsManager extends AssetsManager {
16
+ * getConfiguration() {
17
+ * return { name: 'gltf', description: 'GLTF 3D models manager', ... }
18
+ * }
19
+ * }
20
+ *
21
+ * class PointCloudAssetsManager extends AssetsManager {
22
+ * getConfiguration() {
23
+ * return { name: 'pointcloud', description: 'Point cloud data manager', ... }
24
+ * }
25
+ * }
26
+ *
27
+ * // Usage in engine
28
+ * const gltfManager = new GLTFAssetsManager()
29
+ * gltfManager.setDependencies(database, storage)
30
+ *
31
+ * // Each creates its own table and endpoints:
32
+ * // - GLTFAssetsManager → table 'gltf', endpoints /gltf/*
33
+ * // - PointCloudAssetsManager → table 'pointcloud', endpoints /pointcloud/*
34
+ * ```
35
+ *
36
+ * @remarks
37
+ * Asset metadata is stored as dedicated columns in the database table:
38
+ * - id, name, url, date (standard columns)
39
+ * - description, source, owner_id, filename (asset-specific columns)
40
+ *
41
+ * Each concrete AssetsManager creates its own table based on the configuration name.
42
+ */
43
+ export class AssetsManager {
44
+ /**
45
+ * Injects dependencies into the assets manager.
46
+ *
47
+ * Called by the framework during component initialization.
48
+ *
49
+ * @param {DatabaseAdapter} db - The database adapter for metadata storage
50
+ * @param {StorageService} storage - The storage service for file persistence
51
+ *
52
+ * @example
53
+ * ```typescript
54
+ * const assetsManager = new MyAssetsManager()
55
+ * assetsManager.setDependencies(databaseAdapter, storageService)
56
+ * ```
57
+ */
58
+ setDependencies(db, storage) {
59
+ this.db = db;
60
+ this.storage = storage;
61
+ }
62
+ /**
63
+ * Validates that a source string is a valid URL.
64
+ *
65
+ * Used internally to ensure data provenance URLs are properly formatted.
66
+ *
67
+ * @private
68
+ * @param {string} source - The source URL to validate
69
+ * @returns {boolean} True if the source is a valid URL, false otherwise
70
+ *
71
+ * @example
72
+ * ```typescript
73
+ * this.validateSourceURL('https://example.com/data') // returns true
74
+ * this.validateSourceURL('not-a-url') // returns false
75
+ * ```
76
+ */
77
+ validateSourceURL(source) {
78
+ try {
79
+ new URL(source);
80
+ return true;
81
+ }
82
+ catch {
83
+ return false;
84
+ }
85
+ }
86
+ /**
87
+ * Upload a new asset file with metadata.
88
+ *
89
+ * Stores the file using the storage service and saves metadata to the database.
90
+ * Asset metadata is stored as dedicated columns in the database table.
91
+ *
92
+ * @param {CreateAssetRequest} request - The asset upload request
93
+ * @throws {Error} If source URL is invalid
94
+ *
95
+ * @example
96
+ * ```typescript
97
+ * await assetsManager.uploadAsset({
98
+ * description: '3D building model',
99
+ * source: 'https://city-data.example.com/buildings',
100
+ * owner_id: 'user123',
101
+ * filename: 'building.glb',
102
+ * file: fileBuffer
103
+ * })
104
+ * ```
105
+ */
106
+ async uploadAsset(request) {
107
+ if (!this.validateSourceURL(request.source)) {
108
+ throw new Error('Invalid source URL');
109
+ }
110
+ const config = this.getConfiguration();
111
+ const now = new Date();
112
+ // Store file using framework pattern
113
+ const url = await this.storage.save(request.file, config.name, request.filename);
114
+ // Create metadata with all asset-specific fields
115
+ const metadata = {
116
+ name: config.name,
117
+ type: config.contentType,
118
+ url,
119
+ date: now,
120
+ description: request.description,
121
+ source: request.source,
122
+ owner_id: request.owner_id,
123
+ filename: request.filename
124
+ };
125
+ await this.db.save(metadata);
126
+ }
127
+ /**
128
+ * Retrieve all assets for this component (like other components).
129
+ *
130
+ * Returns a JSON list of all assets with their metadata, following the
131
+ * framework pattern but adapted for assets management.
132
+ *
133
+ * @returns {Promise<DataResponse>} JSON response with all assets
134
+ */
135
+ async retrieve() {
136
+ try {
137
+ const assets = await this.getAllAssets();
138
+ const config = this.getConfiguration();
139
+ // Transform to include asset metadata and user-friendly URLs
140
+ const assetsWithMetadata = assets
141
+ .map(asset => {
142
+ return {
143
+ id: asset.id,
144
+ name: asset.name,
145
+ date: asset.date,
146
+ contentType: asset.contentType,
147
+ // Asset-specific metadata (from DB columns)
148
+ description: asset.description || '',
149
+ source: asset.source || '',
150
+ owner_id: asset.owner_id || null,
151
+ filename: asset.filename || '',
152
+ // Add URLs that the front-end can actually use
153
+ url: `/${config.name}/${asset.id}`, // For display/use
154
+ download_url: `/${config.name}/${asset.id}/download` // For download
155
+ };
156
+ })
157
+ .sort((a, b) => new Date(b.date).getTime() - new Date(a.date).getTime()); // Newest first
158
+ return {
159
+ status: 200,
160
+ content: JSON.stringify(assetsWithMetadata),
161
+ headers: { 'Content-Type': 'application/json' }
162
+ };
163
+ }
164
+ catch (error) {
165
+ return {
166
+ status: 500,
167
+ content: JSON.stringify({
168
+ error: error instanceof Error ? error.message : 'Unknown error'
169
+ }),
170
+ headers: { 'Content-Type': 'application/json' }
171
+ };
172
+ }
173
+ }
174
+ /**
175
+ * Get all assets for this component type.
176
+ *
177
+ * Retrieves all assets managed by this component, with their metadata.
178
+ * Uses a very old start date to get all records.
179
+ *
180
+ * @returns {Promise<DataRecord[]>} Array of all asset records
181
+ *
182
+ * @example
183
+ * ```typescript
184
+ * const allAssets = await assetsManager.getAllAssets()
185
+ * // Returns: [{ id, name, type, url, date, contentType }, ...]
186
+ * ```
187
+ */
188
+ async getAllAssets() {
189
+ const config = this.getConfiguration();
190
+ // Use getByDateRange with a very old start date to get all records
191
+ const veryOldDate = new Date('1970-01-01');
192
+ const farFutureDate = new Date('2099-12-31');
193
+ return await this.db.getByDateRange(config.name, veryOldDate, farFutureDate, 1000); // Max 1000 assets
194
+ }
195
+ /**
196
+ * Get asset by specific ID.
197
+ *
198
+ * @param {string} id - The asset ID to retrieve
199
+ * @returns {Promise<DataRecord | undefined>} The asset record or undefined if not found
200
+ *
201
+ * @example
202
+ * ```typescript
203
+ * const asset = await assetsManager.getAssetById('123')
204
+ * if (asset) {
205
+ * const fileData = await asset.data()
206
+ * }
207
+ * ```
208
+ */
209
+ async getAssetById(id) {
210
+ return await this.db.getById(id);
211
+ }
212
+ /**
213
+ * Update asset metadata by ID.
214
+ *
215
+ * Updates the metadata (description and/or source) of a specific asset.
216
+ * Asset metadata is stored as dedicated columns in the database.
217
+ *
218
+ * @param {string} id - The ID of the asset to update
219
+ * @param {UpdateAssetRequest} updates - The metadata updates to apply
220
+ * @throws {Error} If source URL is invalid or asset not found
221
+ *
222
+ * @example
223
+ * ```typescript
224
+ * await assetsManager.updateAssetMetadata('123', {
225
+ * description: 'Updated building model with new textures',
226
+ * source: 'https://updated-source.example.com'
227
+ * })
228
+ * ```
229
+ */
230
+ async updateAssetMetadata(id, updates) {
231
+ if (updates.source && !this.validateSourceURL(updates.source)) {
232
+ throw new Error('Invalid source URL');
233
+ }
234
+ const record = await this.db.getById(id);
235
+ if (!record) {
236
+ throw new Error(`Asset with ID ${id} not found`);
237
+ }
238
+ // Verify this asset belongs to our component
239
+ const config = this.getConfiguration();
240
+ if (record.name !== config.name) {
241
+ throw new Error(`Asset ${id} does not belong to component ${config.name}`);
242
+ }
243
+ // Apply updates, keeping existing values for non-updated fields
244
+ const updatedMetadata = {
245
+ id: parseInt(id),
246
+ name: config.name,
247
+ type: record.contentType,
248
+ url: record.url,
249
+ date: record.date, // Keep original date
250
+ description: updates.description ?? record.description ?? '',
251
+ source: updates.source ?? record.source ?? '',
252
+ owner_id: record.owner_id ?? null,
253
+ filename: record.filename ?? ''
254
+ };
255
+ // Update the record - delete and re-create with updated metadata
256
+ await this.db.delete(id);
257
+ await this.db.save(updatedMetadata);
258
+ }
259
+ /**
260
+ * Delete asset by ID.
261
+ *
262
+ * Removes a specific asset.
263
+ *
264
+ * @param {string} id - The ID of the asset to delete
265
+ * @throws {Error} If asset not found or doesn't belong to this component
266
+ *
267
+ * @example
268
+ * ```typescript
269
+ * await assetsManager.deleteAssetById('123')
270
+ * ```
271
+ */
272
+ async deleteAssetById(id) {
273
+ const record = await this.db.getById(id);
274
+ if (!record) {
275
+ throw new Error(`Asset with ID ${id} not found`);
276
+ }
277
+ // Verify this asset belongs to our component
278
+ const config = this.getConfiguration();
279
+ if (record.name !== config.name) {
280
+ throw new Error(`Asset ${id} does not belong to component ${config.name}`);
281
+ }
282
+ await this.db.delete(id);
283
+ }
284
+ /**
285
+ * Delete latest asset (simplified)
286
+ *
287
+ * Removes the most recently uploaded asset for this component type.
288
+ *
289
+ * @throws {Error} If no assets exist to delete
290
+ *
291
+ * @example
292
+ * ```typescript
293
+ * await assetsManager.deleteLatestAsset()
294
+ * ```
295
+ */
296
+ async deleteLatestAsset() {
297
+ const config = this.getConfiguration();
298
+ const record = await this.db.getLatestByName(config.name);
299
+ if (record) {
300
+ await this.db.delete(record.id.toString());
301
+ }
302
+ }
303
+ /**
304
+ * Get endpoints following the framework pattern
305
+ */
306
+ /**
307
+ * Get HTTP endpoints exposed by this assets manager.
308
+ *
309
+ * Returns the standard CRUD endpoints following the framework pattern.
310
+ *
311
+ * @returns {Array} Array of endpoint descriptors with methods, paths, and handlers
312
+ *
313
+ * @example
314
+ * ```typescript
315
+ * // For a manager with assetType: 'gltf', provides:
316
+ * GET /gltf - Get all assets
317
+ * POST /gltf/upload - Upload new asset
318
+ * GET /gltf/123 - Get specific asset
319
+ * PUT /gltf/123 - Update asset metadata
320
+ * GET /gltf/123/download - Download asset
321
+ * DELETE /gltf/123 - Delete asset
322
+ * ```
323
+ */
324
+ getEndpoints() {
325
+ const config = this.getConfiguration();
326
+ return [
327
+ {
328
+ method: 'get',
329
+ path: `/${config.name}`,
330
+ handler: this.retrieve.bind(this),
331
+ responseType: 'application/json',
332
+ },
333
+ {
334
+ method: 'post',
335
+ path: `/${config.name}/upload`,
336
+ handler: this.handleUpload.bind(this),
337
+ responseType: 'application/json',
338
+ },
339
+ {
340
+ method: 'get',
341
+ path: `/${config.name}/:id`,
342
+ handler: this.handleGetAsset.bind(this),
343
+ responseType: config.contentType,
344
+ },
345
+ {
346
+ method: 'put',
347
+ path: `/${config.name}/:id`,
348
+ handler: this.handleUpdate.bind(this),
349
+ responseType: 'application/json',
350
+ },
351
+ {
352
+ method: 'get',
353
+ path: `/${config.name}/:id/download`,
354
+ handler: this.handleDownload.bind(this),
355
+ responseType: config.contentType,
356
+ },
357
+ {
358
+ method: 'delete',
359
+ path: `/${config.name}/:id`,
360
+ handler: this.handleDelete.bind(this),
361
+ responseType: 'application/json',
362
+ }
363
+ ];
364
+ }
365
+ /**
366
+ * Handle upload endpoint
367
+ */
368
+ async handleUpload(req) {
369
+ try {
370
+ const { description, source, owner_id, filename } = req.body;
371
+ const file = req.file?.buffer;
372
+ if (!file || !description || !source || !owner_id || !filename) {
373
+ return {
374
+ status: 400,
375
+ content: JSON.stringify({
376
+ error: 'Missing required fields: description, source, owner_id, filename, file'
377
+ }),
378
+ headers: { 'Content-Type': 'application/json' }
379
+ };
380
+ }
381
+ await this.uploadAsset({
382
+ description,
383
+ source,
384
+ owner_id,
385
+ filename,
386
+ file
387
+ });
388
+ return {
389
+ status: 200,
390
+ content: JSON.stringify({ message: 'Asset uploaded successfully' }),
391
+ headers: { 'Content-Type': 'application/json' }
392
+ };
393
+ }
394
+ catch (error) {
395
+ return {
396
+ status: 500,
397
+ content: JSON.stringify({
398
+ error: error instanceof Error ? error.message : 'Unknown error'
399
+ }),
400
+ headers: { 'Content-Type': 'application/json' }
401
+ };
402
+ }
403
+ }
404
+ /**
405
+ * Handle update endpoint (PUT).
406
+ *
407
+ * Updates metadata for a specific asset by ID.
408
+ *
409
+ * @param {any} req - HTTP request object with params.id and body containing updates
410
+ * @returns {Promise<DataResponse>} HTTP response
411
+ *
412
+ * @example
413
+ * ```typescript
414
+ * // PUT /gltf/123
415
+ * // Body: { "description": "Updated model", "source": "https://new-source.com" }
416
+ * ```
417
+ */
418
+ async handleUpdate(req) {
419
+ try {
420
+ const { id } = req.params || {};
421
+ const { description, source } = req.body || {};
422
+ if (!id) {
423
+ return {
424
+ status: 400,
425
+ content: JSON.stringify({
426
+ error: 'Asset ID is required'
427
+ }),
428
+ headers: { 'Content-Type': 'application/json' }
429
+ };
430
+ }
431
+ if (!description && !source) {
432
+ return {
433
+ status: 400,
434
+ content: JSON.stringify({
435
+ error: 'At least one field (description or source) must be provided for update'
436
+ }),
437
+ headers: { 'Content-Type': 'application/json' }
438
+ };
439
+ }
440
+ const updates = {};
441
+ if (description !== undefined)
442
+ updates.description = description;
443
+ if (source !== undefined)
444
+ updates.source = source;
445
+ await this.updateAssetMetadata(id, updates);
446
+ return {
447
+ status: 200,
448
+ content: JSON.stringify({ message: 'Asset metadata updated successfully' }),
449
+ headers: { 'Content-Type': 'application/json' }
450
+ };
451
+ }
452
+ catch (error) {
453
+ return {
454
+ status: 500,
455
+ content: JSON.stringify({
456
+ error: error instanceof Error ? error.message : 'Unknown error'
457
+ }),
458
+ headers: { 'Content-Type': 'application/json' }
459
+ };
460
+ }
461
+ }
462
+ /**
463
+ * Handle get asset endpoint (GET).
464
+ *
465
+ * Returns the file content of a specific asset by ID for display/use in front-end.
466
+ * No download headers - just the raw file content.
467
+ *
468
+ * @param {any} req - HTTP request object with params.id
469
+ * @returns {Promise<DataResponse>} HTTP response with file content
470
+ *
471
+ * @example
472
+ * ```typescript
473
+ * // GET /gltf/123
474
+ * // Returns the .glb file content for display in 3D viewer
475
+ * ```
476
+ */
477
+ async handleGetAsset(req) {
478
+ try {
479
+ const { id } = req.params || {};
480
+ if (!id) {
481
+ return {
482
+ status: 400,
483
+ content: JSON.stringify({
484
+ error: 'Asset ID is required'
485
+ }),
486
+ headers: { 'Content-Type': 'application/json' }
487
+ };
488
+ }
489
+ const asset = await this.getAssetById(id);
490
+ if (!asset) {
491
+ return {
492
+ status: 404,
493
+ content: 'Asset not found',
494
+ headers: { 'Content-Type': 'text/plain' }
495
+ };
496
+ }
497
+ // Verify this asset belongs to our component
498
+ const config = this.getConfiguration();
499
+ if (asset.name !== config.name) {
500
+ return {
501
+ status: 404,
502
+ content: 'Asset not found',
503
+ headers: { 'Content-Type': 'text/plain' }
504
+ };
505
+ }
506
+ // Get the file content
507
+ const fileContent = await asset.data();
508
+ return {
509
+ status: 200,
510
+ content: fileContent,
511
+ headers: {
512
+ 'Content-Type': config.contentType
513
+ // No Content-Disposition - browser will display/use the file
514
+ }
515
+ };
516
+ }
517
+ catch (error) {
518
+ return {
519
+ status: 500,
520
+ content: JSON.stringify({
521
+ error: error instanceof Error ? error.message : 'Unknown error'
522
+ }),
523
+ headers: { 'Content-Type': 'application/json' }
524
+ };
525
+ }
526
+ }
527
+ /**
528
+ * Handle download endpoint (GET).
529
+ *
530
+ * Downloads the file content of a specific asset by ID with download headers.
531
+ * Forces browser to download the file rather than display it.
532
+ *
533
+ * @param {any} req - HTTP request object with params.id
534
+ * @returns {Promise<DataResponse>} HTTP response with file content and download headers
535
+ *
536
+ * @example
537
+ * ```typescript
538
+ * // GET /gltf/123/download
539
+ * // Returns the .glb file with download headers - browser will save it
540
+ * ```
541
+ */
542
+ async handleDownload(req) {
543
+ try {
544
+ const { id } = req.params || {};
545
+ if (!id) {
546
+ return {
547
+ status: 400,
548
+ content: JSON.stringify({
549
+ error: 'Asset ID is required'
550
+ }),
551
+ headers: { 'Content-Type': 'application/json' }
552
+ };
553
+ }
554
+ const asset = await this.getAssetById(id);
555
+ if (!asset) {
556
+ return {
557
+ status: 404,
558
+ content: 'Asset not found',
559
+ headers: { 'Content-Type': 'text/plain' }
560
+ };
561
+ }
562
+ // Verify this asset belongs to our component
563
+ const config = this.getConfiguration();
564
+ if (asset.name !== config.name) {
565
+ return {
566
+ status: 404,
567
+ content: 'Asset not found',
568
+ headers: { 'Content-Type': 'text/plain' }
569
+ };
570
+ }
571
+ // Get the file content
572
+ const fileContent = await asset.data();
573
+ // Get original filename from asset metadata
574
+ const filename = asset.filename || `asset_${id}`;
575
+ return {
576
+ status: 200,
577
+ content: fileContent,
578
+ headers: {
579
+ 'Content-Type': config.contentType,
580
+ 'Content-Disposition': `attachment; filename="${filename}"`
581
+ }
582
+ };
583
+ }
584
+ catch (error) {
585
+ return {
586
+ status: 500,
587
+ content: JSON.stringify({
588
+ error: error instanceof Error ? error.message : 'Unknown error'
589
+ }),
590
+ headers: { 'Content-Type': 'application/json' }
591
+ };
592
+ }
593
+ }
594
+ /**
595
+ * Handle delete endpoint (DELETE).
596
+ *
597
+ * Deletes a specific asset by ID.
598
+ *
599
+ * @param {any} req - HTTP request object with params.id
600
+ * @returns {Promise<DataResponse>} HTTP response
601
+ *
602
+ * @example
603
+ * ```typescript
604
+ * // DELETE /gltf/123
605
+ * ```
606
+ */
607
+ async handleDelete(req) {
608
+ try {
609
+ const { id } = req.params || {};
610
+ if (!id) {
611
+ return {
612
+ status: 400,
613
+ content: JSON.stringify({
614
+ error: 'Asset ID is required'
615
+ }),
616
+ headers: { 'Content-Type': 'application/json' }
617
+ };
618
+ }
619
+ await this.deleteAssetById(id);
620
+ return {
621
+ status: 200,
622
+ content: JSON.stringify({ message: 'Asset deleted successfully' }),
623
+ headers: { 'Content-Type': 'application/json' }
624
+ };
625
+ }
626
+ catch (error) {
627
+ return {
628
+ status: 500,
629
+ content: JSON.stringify({
630
+ error: error instanceof Error ? error.message : 'Unknown error'
631
+ }),
632
+ headers: { 'Content-Type': 'application/json' }
633
+ };
634
+ }
635
+ }
636
+ }
637
+ //# sourceMappingURL=assets_manager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"assets_manager.js","sourceRoot":"","sources":["../../src/components/assets_manager.ts"],"names":[],"mappings":"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"}