digitaltwin-core 0.14.2 → 1.0.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 (227) hide show
  1. package/LICENSE +20 -20
  2. package/README.md +494 -359
  3. package/dist/auth/apisix_parser.d.ts +141 -0
  4. package/dist/auth/apisix_parser.d.ts.map +1 -0
  5. package/dist/auth/apisix_parser.js +161 -0
  6. package/dist/auth/apisix_parser.js.map +1 -0
  7. package/dist/auth/auth_config.d.ts +126 -0
  8. package/dist/auth/auth_config.d.ts.map +1 -0
  9. package/dist/auth/auth_config.js +169 -0
  10. package/dist/auth/auth_config.js.map +1 -0
  11. package/dist/auth/auth_provider.d.ts +118 -0
  12. package/dist/auth/auth_provider.d.ts.map +1 -0
  13. package/dist/auth/auth_provider.js +8 -0
  14. package/dist/auth/auth_provider.js.map +1 -0
  15. package/dist/auth/auth_provider_factory.d.ts +91 -0
  16. package/dist/auth/auth_provider_factory.d.ts.map +1 -0
  17. package/dist/auth/auth_provider_factory.js +146 -0
  18. package/dist/auth/auth_provider_factory.js.map +1 -0
  19. package/dist/auth/index.d.ts +8 -0
  20. package/dist/auth/index.d.ts.map +1 -0
  21. package/dist/auth/index.js +7 -0
  22. package/dist/auth/index.js.map +1 -0
  23. package/dist/auth/providers/gateway_auth_provider.d.ts +78 -0
  24. package/dist/auth/providers/gateway_auth_provider.d.ts.map +1 -0
  25. package/dist/auth/providers/gateway_auth_provider.js +109 -0
  26. package/dist/auth/providers/gateway_auth_provider.js.map +1 -0
  27. package/dist/auth/providers/index.d.ts +4 -0
  28. package/dist/auth/providers/index.d.ts.map +1 -0
  29. package/dist/auth/providers/index.js +4 -0
  30. package/dist/auth/providers/index.js.map +1 -0
  31. package/dist/auth/providers/jwt_auth_provider.d.ts +91 -0
  32. package/dist/auth/providers/jwt_auth_provider.d.ts.map +1 -0
  33. package/dist/auth/providers/jwt_auth_provider.js +204 -0
  34. package/dist/auth/providers/jwt_auth_provider.js.map +1 -0
  35. package/dist/auth/providers/no_auth_provider.d.ts +61 -0
  36. package/dist/auth/providers/no_auth_provider.d.ts.map +1 -0
  37. package/dist/auth/providers/no_auth_provider.js +76 -0
  38. package/dist/auth/providers/no_auth_provider.js.map +1 -0
  39. package/dist/auth/types.d.ts +100 -0
  40. package/dist/auth/types.d.ts.map +1 -0
  41. package/dist/auth/types.js +2 -0
  42. package/dist/auth/types.js.map +1 -0
  43. package/dist/auth/user_service.d.ts +86 -0
  44. package/dist/auth/user_service.d.ts.map +1 -0
  45. package/dist/auth/user_service.js +237 -0
  46. package/dist/auth/user_service.js.map +1 -0
  47. package/dist/components/assets_manager.d.ts +662 -0
  48. package/dist/components/assets_manager.d.ts.map +1 -0
  49. package/dist/components/assets_manager.js +1537 -0
  50. package/dist/components/assets_manager.js.map +1 -0
  51. package/dist/components/async_upload.d.ts +20 -0
  52. package/dist/components/async_upload.d.ts.map +1 -0
  53. package/dist/components/async_upload.js +10 -0
  54. package/dist/components/async_upload.js.map +1 -0
  55. package/dist/components/collector.d.ts +203 -0
  56. package/dist/components/collector.d.ts.map +1 -0
  57. package/dist/components/collector.js +214 -0
  58. package/dist/components/collector.js.map +1 -0
  59. package/dist/components/custom_table_manager.d.ts +503 -0
  60. package/dist/components/custom_table_manager.d.ts.map +1 -0
  61. package/dist/components/custom_table_manager.js +1023 -0
  62. package/dist/components/custom_table_manager.js.map +1 -0
  63. package/dist/components/global_assets_handler.d.ts +63 -0
  64. package/dist/components/global_assets_handler.d.ts.map +1 -0
  65. package/dist/components/global_assets_handler.js +127 -0
  66. package/dist/components/global_assets_handler.js.map +1 -0
  67. package/dist/components/handler.d.ts +104 -0
  68. package/dist/components/handler.d.ts.map +1 -0
  69. package/dist/components/handler.js +110 -0
  70. package/dist/components/handler.js.map +1 -0
  71. package/dist/components/harvester.d.ts +182 -0
  72. package/dist/components/harvester.d.ts.map +1 -0
  73. package/dist/components/harvester.js +406 -0
  74. package/dist/components/harvester.js.map +1 -0
  75. package/dist/components/index.d.ts +11 -0
  76. package/dist/components/index.d.ts.map +1 -0
  77. package/dist/components/index.js +9 -0
  78. package/dist/components/index.js.map +1 -0
  79. package/dist/components/interfaces.d.ts +126 -0
  80. package/dist/components/interfaces.d.ts.map +1 -0
  81. package/dist/components/interfaces.js +8 -0
  82. package/dist/components/interfaces.js.map +1 -0
  83. package/dist/components/map_manager.d.ts +61 -0
  84. package/dist/components/map_manager.d.ts.map +1 -0
  85. package/dist/components/map_manager.js +242 -0
  86. package/dist/components/map_manager.js.map +1 -0
  87. package/dist/components/tileset_manager.d.ts +125 -0
  88. package/dist/components/tileset_manager.d.ts.map +1 -0
  89. package/dist/components/tileset_manager.js +623 -0
  90. package/dist/components/tileset_manager.js.map +1 -0
  91. package/dist/components/types.d.ts +226 -0
  92. package/dist/components/types.d.ts.map +1 -0
  93. package/dist/components/types.js +8 -0
  94. package/dist/components/types.js.map +1 -0
  95. package/dist/database/adapters/knex_database_adapter.d.ts +97 -0
  96. package/dist/database/adapters/knex_database_adapter.d.ts.map +1 -0
  97. package/dist/database/adapters/knex_database_adapter.js +729 -0
  98. package/dist/database/adapters/knex_database_adapter.js.map +1 -0
  99. package/dist/database/database_adapter.d.ts +262 -0
  100. package/dist/database/database_adapter.d.ts.map +1 -0
  101. package/dist/database/database_adapter.js +46 -0
  102. package/dist/database/database_adapter.js.map +1 -0
  103. package/dist/engine/digital_twin_engine.d.ts +295 -0
  104. package/dist/engine/digital_twin_engine.d.ts.map +1 -0
  105. package/dist/engine/digital_twin_engine.js +907 -0
  106. package/dist/engine/digital_twin_engine.js.map +1 -0
  107. package/dist/engine/endpoints.d.ts +47 -0
  108. package/dist/engine/endpoints.d.ts.map +1 -0
  109. package/dist/engine/endpoints.js +88 -0
  110. package/dist/engine/endpoints.js.map +1 -0
  111. package/dist/engine/error_handler.d.ts +20 -0
  112. package/dist/engine/error_handler.d.ts.map +1 -0
  113. package/dist/engine/error_handler.js +69 -0
  114. package/dist/engine/error_handler.js.map +1 -0
  115. package/dist/engine/events.d.ts +93 -0
  116. package/dist/engine/events.d.ts.map +1 -0
  117. package/dist/engine/events.js +71 -0
  118. package/dist/engine/events.js.map +1 -0
  119. package/dist/engine/health.d.ts +112 -0
  120. package/dist/engine/health.d.ts.map +1 -0
  121. package/dist/engine/health.js +190 -0
  122. package/dist/engine/health.js.map +1 -0
  123. package/dist/engine/initializer.d.ts +62 -0
  124. package/dist/engine/initializer.d.ts.map +1 -0
  125. package/dist/engine/initializer.js +108 -0
  126. package/dist/engine/initializer.js.map +1 -0
  127. package/dist/engine/queue_manager.d.ts +87 -0
  128. package/dist/engine/queue_manager.d.ts.map +1 -0
  129. package/dist/engine/queue_manager.js +196 -0
  130. package/dist/engine/queue_manager.js.map +1 -0
  131. package/dist/engine/scheduler.d.ts +30 -0
  132. package/dist/engine/scheduler.d.ts.map +1 -0
  133. package/dist/engine/scheduler.js +378 -0
  134. package/dist/engine/scheduler.js.map +1 -0
  135. package/dist/engine/upload_processor.d.ts +36 -0
  136. package/dist/engine/upload_processor.d.ts.map +1 -0
  137. package/dist/engine/upload_processor.js +113 -0
  138. package/dist/engine/upload_processor.js.map +1 -0
  139. package/dist/env/env.d.ts +134 -0
  140. package/dist/env/env.d.ts.map +1 -0
  141. package/dist/env/env.js +177 -0
  142. package/dist/env/env.js.map +1 -0
  143. package/dist/errors/index.d.ts +94 -0
  144. package/dist/errors/index.d.ts.map +1 -0
  145. package/dist/errors/index.js +149 -0
  146. package/dist/errors/index.js.map +1 -0
  147. package/dist/index.d.ts +55 -0
  148. package/dist/index.d.ts.map +1 -0
  149. package/dist/index.js +65 -0
  150. package/dist/index.js.map +1 -0
  151. package/dist/openapi/generator.d.ts +93 -0
  152. package/dist/openapi/generator.d.ts.map +1 -0
  153. package/dist/openapi/generator.js +293 -0
  154. package/dist/openapi/generator.js.map +1 -0
  155. package/dist/openapi/index.d.ts +9 -0
  156. package/dist/openapi/index.d.ts.map +1 -0
  157. package/dist/openapi/index.js +9 -0
  158. package/dist/openapi/index.js.map +1 -0
  159. package/dist/openapi/types.d.ts +182 -0
  160. package/dist/openapi/types.d.ts.map +1 -0
  161. package/dist/openapi/types.js +16 -0
  162. package/dist/openapi/types.js.map +1 -0
  163. package/dist/storage/adapters/local_storage_service.d.ts +57 -0
  164. package/dist/storage/adapters/local_storage_service.d.ts.map +1 -0
  165. package/dist/storage/adapters/local_storage_service.js +132 -0
  166. package/dist/storage/adapters/local_storage_service.js.map +1 -0
  167. package/dist/storage/adapters/ovh_storage_service.d.ts +72 -0
  168. package/dist/storage/adapters/ovh_storage_service.d.ts.map +1 -0
  169. package/dist/storage/adapters/ovh_storage_service.js +205 -0
  170. package/dist/storage/adapters/ovh_storage_service.js.map +1 -0
  171. package/dist/storage/storage_factory.d.ts +14 -0
  172. package/dist/storage/storage_factory.d.ts.map +1 -0
  173. package/dist/storage/storage_factory.js +43 -0
  174. package/dist/storage/storage_factory.js.map +1 -0
  175. package/dist/storage/storage_service.d.ts +163 -0
  176. package/dist/storage/storage_service.d.ts.map +1 -0
  177. package/dist/storage/storage_service.js +58 -0
  178. package/dist/storage/storage_service.js.map +1 -0
  179. package/dist/types/data_record.d.ts +123 -0
  180. package/dist/types/data_record.d.ts.map +1 -0
  181. package/dist/types/data_record.js +8 -0
  182. package/dist/types/data_record.js.map +1 -0
  183. package/dist/utils/graceful_shutdown.d.ts +44 -0
  184. package/dist/utils/graceful_shutdown.d.ts.map +1 -0
  185. package/dist/utils/graceful_shutdown.js +79 -0
  186. package/dist/utils/graceful_shutdown.js.map +1 -0
  187. package/dist/utils/http_responses.d.ts +175 -0
  188. package/dist/utils/http_responses.d.ts.map +1 -0
  189. package/dist/utils/http_responses.js +216 -0
  190. package/dist/utils/http_responses.js.map +1 -0
  191. package/dist/utils/index.d.ts +8 -0
  192. package/dist/utils/index.d.ts.map +1 -0
  193. package/dist/utils/index.js +6 -0
  194. package/dist/utils/index.js.map +1 -0
  195. package/dist/utils/logger.d.ts +74 -0
  196. package/dist/utils/logger.d.ts.map +1 -0
  197. package/dist/utils/logger.js +92 -0
  198. package/dist/utils/logger.js.map +1 -0
  199. package/dist/utils/map_to_data_record.d.ts +10 -0
  200. package/dist/utils/map_to_data_record.d.ts.map +1 -0
  201. package/dist/utils/map_to_data_record.js +36 -0
  202. package/dist/utils/map_to_data_record.js.map +1 -0
  203. package/dist/utils/safe_async.d.ts +50 -0
  204. package/dist/utils/safe_async.d.ts.map +1 -0
  205. package/dist/utils/safe_async.js +90 -0
  206. package/dist/utils/safe_async.js.map +1 -0
  207. package/dist/utils/servable_endpoint.d.ts +63 -0
  208. package/dist/utils/servable_endpoint.d.ts.map +1 -0
  209. package/dist/utils/servable_endpoint.js +67 -0
  210. package/dist/utils/servable_endpoint.js.map +1 -0
  211. package/dist/utils/zip_utils.d.ts +66 -0
  212. package/dist/utils/zip_utils.d.ts.map +1 -0
  213. package/dist/utils/zip_utils.js +169 -0
  214. package/dist/utils/zip_utils.js.map +1 -0
  215. package/dist/validation/index.d.ts +3 -0
  216. package/dist/validation/index.d.ts.map +1 -0
  217. package/dist/validation/index.js +7 -0
  218. package/dist/validation/index.js.map +1 -0
  219. package/dist/validation/schemas.d.ts +273 -0
  220. package/dist/validation/schemas.d.ts.map +1 -0
  221. package/dist/validation/schemas.js +82 -0
  222. package/dist/validation/schemas.js.map +1 -0
  223. package/dist/validation/validate.d.ts +49 -0
  224. package/dist/validation/validate.d.ts.map +1 -0
  225. package/dist/validation/validate.js +110 -0
  226. package/dist/validation/validate.js.map +1 -0
  227. package/package.json +23 -13
@@ -0,0 +1,623 @@
1
+ import { AssetsManager } from './assets_manager.js';
2
+ import { extractAndStoreArchive } from '../utils/zip_utils.js';
3
+ import { ApisixAuthParser } from '../auth/apisix_parser.js';
4
+ import { AuthConfig } from '../auth/auth_config.js';
5
+ import fs from 'fs/promises';
6
+ import { successResponse, errorResponse, badRequestResponse, unauthorizedResponse, notFoundResponse, forbiddenResponse } from '../utils/http_responses.js';
7
+ import { safeAsync, safeCleanup } from '../utils/safe_async.js';
8
+ import { Logger } from '../utils/logger.js';
9
+ const logger = new Logger('TilesetManager');
10
+ /** Threshold for async upload (50MB) */
11
+ const ASYNC_UPLOAD_THRESHOLD = 50 * 1024 * 1024;
12
+ /**
13
+ * Specialized Assets Manager for handling 3D Tiles tilesets.
14
+ *
15
+ * This manager extracts uploaded ZIP files and stores each file in cloud storage (OVH S3),
16
+ * allowing Cesium and other 3D viewers to load tilesets directly via public URLs.
17
+ *
18
+ * ## How it works
19
+ *
20
+ * 1. User uploads a ZIP containing a 3D Tiles tileset
21
+ * 2. ZIP is extracted and all files are stored in OVH with public-read ACL
22
+ * 3. Database stores only the tileset.json URL and base path
23
+ * 4. Cesium loads tileset.json directly from OVH
24
+ * 5. Cesium fetches tiles using relative paths in tileset.json (directly from OVH)
25
+ *
26
+ * ## Endpoints
27
+ *
28
+ * - GET /{endpoint} - List all tilesets with their public URLs
29
+ * - POST /{endpoint} - Upload tileset ZIP (sync < 50MB, async >= 50MB)
30
+ * - GET /{endpoint}/:id/status - Poll async upload status
31
+ * - PUT /{endpoint}/:id - Update tileset metadata
32
+ * - DELETE /{endpoint}/:id - Delete tileset and all files from storage
33
+ *
34
+ * @example
35
+ * ```typescript
36
+ * class MyTilesetManager extends TilesetManager {
37
+ * getConfiguration() {
38
+ * return {
39
+ * name: 'tilesets',
40
+ * description: 'Manage 3D Tiles tilesets',
41
+ * contentType: 'application/json',
42
+ * endpoint: 'api/tilesets',
43
+ * extension: '.zip'
44
+ * }
45
+ * }
46
+ * }
47
+ *
48
+ * // After upload, response contains:
49
+ * // { tileset_url: 'https://bucket.s3.../tilesets/123/tileset.json' }
50
+ * //
51
+ * // Cesium loads directly:
52
+ * // Cesium.Cesium3DTileset.fromUrl(tileset_url)
53
+ * ```
54
+ */
55
+ export class TilesetManager extends AssetsManager {
56
+ constructor() {
57
+ super(...arguments);
58
+ /** Upload queue for async processing (injected by engine) */
59
+ this.uploadQueue = null;
60
+ }
61
+ /**
62
+ * Set the upload queue for async job processing.
63
+ * Called by DigitalTwinEngine during initialization.
64
+ */
65
+ setUploadQueue(queue) {
66
+ this.uploadQueue = queue;
67
+ }
68
+ /**
69
+ * Handle tileset upload.
70
+ *
71
+ * - Files < 50MB: Synchronous extraction and upload
72
+ * - Files >= 50MB: Queued for async processing (returns 202)
73
+ */
74
+ async handleUpload(req) {
75
+ try {
76
+ if (!req?.body) {
77
+ return badRequestResponse('Invalid request: missing request body');
78
+ }
79
+ // Authenticate user
80
+ const userId = await this.authenticateUser(req);
81
+ if (typeof userId !== 'number') {
82
+ return userId; // Returns error response
83
+ }
84
+ // Validate request
85
+ const { description } = req.body;
86
+ const filePath = req.file?.path;
87
+ const fileBuffer = req.file?.buffer;
88
+ const filename = req.file?.originalname || req.body.filename;
89
+ const fileSize = req.file?.size || fileBuffer?.length || 0;
90
+ if (!filePath && !fileBuffer) {
91
+ return badRequestResponse('Missing required field: ZIP file');
92
+ }
93
+ if (!description) {
94
+ if (filePath)
95
+ await safeAsync(() => fs.unlink(filePath), 'cleanup temp file on validation error', logger);
96
+ return badRequestResponse('Missing required field: description');
97
+ }
98
+ if (!filename) {
99
+ if (filePath)
100
+ await safeAsync(() => fs.unlink(filePath), 'cleanup temp file on validation error', logger);
101
+ return badRequestResponse('Filename could not be determined from uploaded file');
102
+ }
103
+ if (!filename.toLowerCase().endsWith('.zip')) {
104
+ if (filePath)
105
+ await safeAsync(() => fs.unlink(filePath), 'cleanup temp file on validation error', logger);
106
+ return badRequestResponse('Invalid file extension. Expected: .zip');
107
+ }
108
+ const config = this.getConfiguration();
109
+ const isPublic = req.body.is_public !== undefined ? Boolean(req.body.is_public) : true;
110
+ // Route to async or sync based on file size and queue availability
111
+ if (this.uploadQueue && filePath && fileSize >= ASYNC_UPLOAD_THRESHOLD) {
112
+ return this.handleAsyncUpload(userId, filePath, filename, description, isPublic, config);
113
+ }
114
+ return this.handleSyncUpload(userId, filePath, fileBuffer, filename, description, isPublic, config);
115
+ }
116
+ catch (error) {
117
+ if (req.file?.path)
118
+ await safeAsync(() => fs.unlink(req.file.path), 'cleanup temp file on error', logger);
119
+ return errorResponse(error);
120
+ }
121
+ }
122
+ /**
123
+ * Authenticate user from request headers.
124
+ * Returns user ID on success, or error response on failure.
125
+ */
126
+ async authenticateUser(req) {
127
+ if (AuthConfig.isAuthDisabled()) {
128
+ const userRecord = await this.userService.findOrCreateUser({
129
+ id: AuthConfig.getAnonymousUserId(),
130
+ roles: []
131
+ });
132
+ return userRecord.id;
133
+ }
134
+ if (!ApisixAuthParser.hasValidAuth(req.headers || {})) {
135
+ return unauthorizedResponse();
136
+ }
137
+ const authUser = ApisixAuthParser.parseAuthHeaders(req.headers || {});
138
+ if (!authUser) {
139
+ return unauthorizedResponse('Invalid authentication headers');
140
+ }
141
+ const userRecord = await this.userService.findOrCreateUser(authUser);
142
+ if (!userRecord.id) {
143
+ return errorResponse('Failed to retrieve user information');
144
+ }
145
+ return userRecord.id;
146
+ }
147
+ /**
148
+ * Queue upload for background processing. Returns HTTP 202 immediately.
149
+ */
150
+ async handleAsyncUpload(userId, filePath, filename, description, isPublic, config) {
151
+ let recordId = null;
152
+ try {
153
+ // Create pending record (url will be updated after extraction)
154
+ const metadata = {
155
+ name: config.name,
156
+ type: 'application/json',
157
+ url: '',
158
+ tileset_url: '',
159
+ date: new Date(),
160
+ description,
161
+ filename,
162
+ owner_id: userId,
163
+ is_public: isPublic,
164
+ upload_status: 'pending'
165
+ };
166
+ const savedRecord = await this.db.save(metadata);
167
+ recordId = savedRecord.id;
168
+ const jobData = {
169
+ type: 'tileset',
170
+ recordId,
171
+ tempFilePath: filePath,
172
+ componentName: config.name,
173
+ userId,
174
+ filename,
175
+ description
176
+ };
177
+ const job = await this.uploadQueue?.add(`tileset-${recordId}`, jobData, {
178
+ jobId: `tileset-upload-${recordId}`
179
+ });
180
+ if (!job)
181
+ throw new Error('Failed to queue upload job');
182
+ await this.db.updateById(config.name, recordId, { upload_job_id: job.id });
183
+ return {
184
+ status: 202,
185
+ content: JSON.stringify({
186
+ message: 'Tileset upload accepted, processing in background',
187
+ id: recordId,
188
+ job_id: job.id,
189
+ status: 'pending',
190
+ status_url: `/${config.endpoint}/${recordId}/status`
191
+ }),
192
+ headers: { 'Content-Type': 'application/json' }
193
+ };
194
+ }
195
+ catch (error) {
196
+ await safeCleanup([
197
+ {
198
+ operation: () => recordId !== null ? this.db.delete(String(recordId), config.name) : Promise.resolve(),
199
+ context: 'delete record on async upload error'
200
+ },
201
+ { operation: () => fs.unlink(filePath), context: 'cleanup temp file on async upload error' }
202
+ ], logger);
203
+ throw error;
204
+ }
205
+ }
206
+ /**
207
+ * Process upload synchronously.
208
+ */
209
+ async handleSyncUpload(userId, filePath, fileBuffer, filename, description, isPublic, config) {
210
+ let zipBuffer;
211
+ try {
212
+ const readBuffer = fileBuffer || (filePath ? await fs.readFile(filePath) : null);
213
+ if (!readBuffer)
214
+ throw new Error('No file data available');
215
+ zipBuffer = readBuffer;
216
+ }
217
+ catch (error) {
218
+ return errorResponse(`Failed to read uploaded file: ${error instanceof Error ? error.message : 'Unknown error'}`);
219
+ }
220
+ try {
221
+ // Generate unique base path using timestamp
222
+ const basePath = `${config.name}/${Date.now()}`;
223
+ // Extract ZIP and upload all files to storage
224
+ const extractResult = await extractAndStoreArchive(zipBuffer, this.storage, basePath);
225
+ if (!extractResult.root_file) {
226
+ // Clean up uploaded files
227
+ await safeAsync(() => this.storage.deleteByPrefix(basePath), 'cleanup storage on invalid tileset', logger);
228
+ return badRequestResponse('Invalid tileset: no tileset.json found in the ZIP archive');
229
+ }
230
+ // Build the public URL for tileset.json
231
+ const tilesetPath = `${basePath}/${extractResult.root_file}`;
232
+ const tilesetUrl = this.storage.getPublicUrl(tilesetPath);
233
+ // Save metadata to database (url = basePath for deletion)
234
+ const metadata = {
235
+ name: config.name,
236
+ type: 'application/json',
237
+ url: basePath,
238
+ tileset_url: tilesetUrl,
239
+ date: new Date(),
240
+ description,
241
+ filename,
242
+ owner_id: userId,
243
+ is_public: isPublic,
244
+ upload_status: 'completed'
245
+ };
246
+ const savedRecord = await this.db.save(metadata);
247
+ // Clean up temp file
248
+ if (filePath)
249
+ await safeAsync(() => fs.unlink(filePath), 'cleanup temp file after sync upload', logger);
250
+ return successResponse({
251
+ message: 'Tileset uploaded successfully',
252
+ id: savedRecord.id,
253
+ tileset_url: tilesetUrl,
254
+ file_count: extractResult.file_count
255
+ });
256
+ }
257
+ catch (error) {
258
+ if (filePath)
259
+ await safeAsync(() => fs.unlink(filePath), 'cleanup temp file on sync upload error', logger);
260
+ throw error;
261
+ }
262
+ }
263
+ /**
264
+ * Get upload status for async uploads.
265
+ */
266
+ async handleGetStatus(req) {
267
+ try {
268
+ const { id } = req.params || {};
269
+ if (!id) {
270
+ return badRequestResponse('Asset ID is required');
271
+ }
272
+ const asset = await this.getAssetById(id);
273
+ if (!asset) {
274
+ return notFoundResponse('Tileset not found');
275
+ }
276
+ const record = asset;
277
+ if (record.upload_status === 'completed') {
278
+ return successResponse({
279
+ id: record.id,
280
+ status: 'completed',
281
+ tileset_url: record.tileset_url
282
+ });
283
+ }
284
+ if (record.upload_status === 'failed') {
285
+ return successResponse({
286
+ id: record.id,
287
+ status: 'failed',
288
+ error: record.upload_error || 'Upload failed'
289
+ });
290
+ }
291
+ return successResponse({
292
+ id: record.id,
293
+ status: record.upload_status || 'unknown',
294
+ job_id: record.upload_job_id
295
+ });
296
+ }
297
+ catch (error) {
298
+ return errorResponse(error);
299
+ }
300
+ }
301
+ /**
302
+ * List all tilesets with their public URLs.
303
+ */
304
+ async retrieve(req) {
305
+ try {
306
+ const assets = await this.getAllAssets();
307
+ const isAdmin = req && ApisixAuthParser.isAdmin(req.headers || {});
308
+ // Get authenticated user ID if available
309
+ let authenticatedUserId = null;
310
+ if (req && ApisixAuthParser.hasValidAuth(req.headers || {})) {
311
+ const authUser = ApisixAuthParser.parseAuthHeaders(req.headers || {});
312
+ if (authUser) {
313
+ const userRecord = await this.userService.findOrCreateUser(authUser);
314
+ authenticatedUserId = userRecord.id || null;
315
+ }
316
+ }
317
+ // Filter to visible assets only (unless admin)
318
+ const visibleAssets = isAdmin
319
+ ? assets
320
+ : assets.filter(asset => asset.is_public || (authenticatedUserId !== null && asset.owner_id === authenticatedUserId));
321
+ // Transform to response format
322
+ const response = visibleAssets.map(asset => ({
323
+ id: asset.id,
324
+ description: asset.description || '',
325
+ filename: asset.filename || '',
326
+ date: asset.date,
327
+ owner_id: asset.owner_id || null,
328
+ is_public: asset.is_public ?? true,
329
+ tileset_url: asset.tileset_url || '',
330
+ upload_status: asset.upload_status || 'completed'
331
+ }));
332
+ return successResponse(response);
333
+ }
334
+ catch (error) {
335
+ return errorResponse(error);
336
+ }
337
+ }
338
+ /**
339
+ * Delete tileset and all files from storage.
340
+ */
341
+ async handleDelete(req) {
342
+ try {
343
+ // Authenticate user
344
+ const userId = await this.authenticateUser(req);
345
+ if (typeof userId !== 'number') {
346
+ return userId;
347
+ }
348
+ const { id } = req.params || {};
349
+ if (!id) {
350
+ return badRequestResponse('Asset ID is required');
351
+ }
352
+ const asset = await this.getAssetById(id);
353
+ if (!asset) {
354
+ return notFoundResponse('Tileset not found');
355
+ }
356
+ // Check ownership (admins can delete any)
357
+ const isAdmin = ApisixAuthParser.isAdmin(req.headers || {});
358
+ if (!isAdmin && asset.owner_id !== null && asset.owner_id !== userId) {
359
+ return forbiddenResponse('You can only delete your own assets');
360
+ }
361
+ // Block deletion while upload in progress
362
+ if (asset.upload_status === 'pending' || asset.upload_status === 'processing') {
363
+ return {
364
+ status: 409,
365
+ content: JSON.stringify({ error: 'Cannot delete tileset while upload is in progress' }),
366
+ headers: { 'Content-Type': 'application/json' }
367
+ };
368
+ }
369
+ // Delete all files from storage
370
+ // Support both new format (url = basePath) and legacy format (file_index.files)
371
+ const legacyFileIndex = asset.file_index;
372
+ if (legacyFileIndex?.files && legacyFileIndex.files.length > 0) {
373
+ // Legacy format: delete individual files from file_index
374
+ logger.info(`Deleting ${legacyFileIndex.files.length} files (legacy format)`);
375
+ for (const file of legacyFileIndex.files) {
376
+ await safeAsync(() => this.storage.delete(file.path), `delete legacy file ${file.path}`, logger);
377
+ }
378
+ }
379
+ else if (asset.url) {
380
+ // New format: url contains basePath, use deleteByPrefix
381
+ const deletedCount = await this.storage.deleteByPrefix(asset.url);
382
+ logger.info(`Deleted ${deletedCount} files from ${asset.url}`);
383
+ }
384
+ // Delete database record
385
+ await this.deleteAssetById(id);
386
+ return successResponse({ message: 'Tileset deleted successfully' });
387
+ }
388
+ catch (error) {
389
+ return errorResponse(error);
390
+ }
391
+ }
392
+ /**
393
+ * Get HTTP endpoints for this manager.
394
+ */
395
+ getEndpoints() {
396
+ const config = this.getConfiguration();
397
+ return [
398
+ // Status endpoint (for async upload polling)
399
+ {
400
+ method: 'get',
401
+ path: `/${config.endpoint}/:id/status`,
402
+ handler: this.handleGetStatus.bind(this),
403
+ responseType: 'application/json'
404
+ },
405
+ // List tilesets
406
+ {
407
+ method: 'get',
408
+ path: `/${config.endpoint}`,
409
+ handler: this.retrieve.bind(this),
410
+ responseType: 'application/json'
411
+ },
412
+ // Upload tileset
413
+ {
414
+ method: 'post',
415
+ path: `/${config.endpoint}`,
416
+ handler: this.handleUpload.bind(this),
417
+ responseType: 'application/json'
418
+ },
419
+ // Update metadata
420
+ {
421
+ method: 'put',
422
+ path: `/${config.endpoint}/:id`,
423
+ handler: this.handleUpdate.bind(this),
424
+ responseType: 'application/json'
425
+ },
426
+ // Delete tileset
427
+ {
428
+ method: 'delete',
429
+ path: `/${config.endpoint}/:id`,
430
+ handler: this.handleDelete.bind(this),
431
+ responseType: 'application/json'
432
+ }
433
+ ];
434
+ }
435
+ /**
436
+ * Generate OpenAPI specification.
437
+ */
438
+ getOpenAPISpec() {
439
+ const config = this.getConfiguration();
440
+ const basePath = `/${config.endpoint}`;
441
+ const tagName = config.tags?.[0] || config.name;
442
+ return {
443
+ paths: {
444
+ [basePath]: {
445
+ get: {
446
+ summary: 'List all tilesets',
447
+ description: 'Returns all tilesets with their public URLs for Cesium loading',
448
+ tags: [tagName],
449
+ responses: {
450
+ '200': {
451
+ description: 'List of tilesets',
452
+ content: {
453
+ 'application/json': {
454
+ schema: {
455
+ type: 'array',
456
+ items: { $ref: '#/components/schemas/TilesetResponse' }
457
+ }
458
+ }
459
+ }
460
+ }
461
+ }
462
+ },
463
+ post: {
464
+ summary: 'Upload a tileset',
465
+ description: 'Upload a ZIP file containing a 3D Tiles tileset. Files < 50MB are processed synchronously, larger files are queued.',
466
+ tags: [tagName],
467
+ security: [{ ApiKeyAuth: [] }],
468
+ requestBody: {
469
+ required: true,
470
+ content: {
471
+ 'multipart/form-data': {
472
+ schema: {
473
+ type: 'object',
474
+ required: ['file', 'description'],
475
+ properties: {
476
+ file: {
477
+ type: 'string',
478
+ format: 'binary',
479
+ description: 'ZIP file containing tileset'
480
+ },
481
+ description: { type: 'string', description: 'Tileset description' },
482
+ is_public: {
483
+ type: 'boolean',
484
+ description: 'Whether tileset is public (default: true)'
485
+ }
486
+ }
487
+ }
488
+ }
489
+ }
490
+ },
491
+ responses: {
492
+ '200': {
493
+ description: 'Tileset uploaded successfully (sync)',
494
+ content: {
495
+ 'application/json': {
496
+ schema: {
497
+ type: 'object',
498
+ properties: {
499
+ message: { type: 'string' },
500
+ id: { type: 'integer' },
501
+ tileset_url: {
502
+ type: 'string',
503
+ description: 'Public URL to load in Cesium'
504
+ },
505
+ file_count: { type: 'integer' }
506
+ }
507
+ }
508
+ }
509
+ }
510
+ },
511
+ '202': {
512
+ description: 'Upload accepted for async processing',
513
+ content: {
514
+ 'application/json': {
515
+ schema: {
516
+ type: 'object',
517
+ properties: {
518
+ message: { type: 'string' },
519
+ id: { type: 'integer' },
520
+ status: { type: 'string' },
521
+ status_url: { type: 'string' }
522
+ }
523
+ }
524
+ }
525
+ }
526
+ },
527
+ '400': { description: 'Bad request - missing fields or invalid file' },
528
+ '401': { description: 'Unauthorized' }
529
+ }
530
+ }
531
+ },
532
+ [`${basePath}/{id}/status`]: {
533
+ get: {
534
+ summary: 'Get upload status',
535
+ description: 'Poll the status of an async upload',
536
+ tags: [tagName],
537
+ parameters: [{ name: 'id', in: 'path', required: true, schema: { type: 'string' } }],
538
+ responses: {
539
+ '200': {
540
+ description: 'Upload status',
541
+ content: {
542
+ 'application/json': {
543
+ schema: {
544
+ type: 'object',
545
+ properties: {
546
+ id: { type: 'integer' },
547
+ status: {
548
+ type: 'string',
549
+ enum: ['pending', 'processing', 'completed', 'failed']
550
+ },
551
+ tileset_url: { type: 'string' },
552
+ error: { type: 'string' }
553
+ }
554
+ }
555
+ }
556
+ }
557
+ },
558
+ '404': { description: 'Tileset not found' }
559
+ }
560
+ }
561
+ },
562
+ [`${basePath}/{id}`]: {
563
+ put: {
564
+ summary: 'Update tileset metadata',
565
+ tags: [tagName],
566
+ security: [{ ApiKeyAuth: [] }],
567
+ parameters: [{ name: 'id', in: 'path', required: true, schema: { type: 'string' } }],
568
+ requestBody: {
569
+ content: {
570
+ 'application/json': {
571
+ schema: {
572
+ type: 'object',
573
+ properties: {
574
+ description: { type: 'string' },
575
+ is_public: { type: 'boolean' }
576
+ }
577
+ }
578
+ }
579
+ }
580
+ },
581
+ responses: {
582
+ '200': { description: 'Updated successfully' },
583
+ '401': { description: 'Unauthorized' },
584
+ '403': { description: 'Forbidden' },
585
+ '404': { description: 'Not found' }
586
+ }
587
+ },
588
+ delete: {
589
+ summary: 'Delete tileset',
590
+ description: 'Delete tileset and all files from storage',
591
+ tags: [tagName],
592
+ security: [{ ApiKeyAuth: [] }],
593
+ parameters: [{ name: 'id', in: 'path', required: true, schema: { type: 'string' } }],
594
+ responses: {
595
+ '200': { description: 'Deleted successfully' },
596
+ '401': { description: 'Unauthorized' },
597
+ '403': { description: 'Forbidden' },
598
+ '404': { description: 'Not found' },
599
+ '409': { description: 'Upload in progress' }
600
+ }
601
+ }
602
+ }
603
+ },
604
+ tags: [{ name: tagName, description: config.description }],
605
+ schemas: {
606
+ TilesetResponse: {
607
+ type: 'object',
608
+ properties: {
609
+ id: { type: 'integer' },
610
+ description: { type: 'string' },
611
+ filename: { type: 'string' },
612
+ date: { type: 'string', format: 'date-time' },
613
+ owner_id: { type: 'integer', nullable: true },
614
+ is_public: { type: 'boolean' },
615
+ tileset_url: { type: 'string', description: 'Public URL to load in Cesium' },
616
+ upload_status: { type: 'string', enum: ['pending', 'processing', 'completed', 'failed'] }
617
+ }
618
+ }
619
+ }
620
+ };
621
+ }
622
+ }
623
+ //# sourceMappingURL=tileset_manager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tileset_manager.js","sourceRoot":"","sources":["../../src/components/tileset_manager.ts"],"names":[],"mappings":"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"}