@cepseudo/assets 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 (43) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +204 -0
  3. package/dist/assets_manager.d.ts +643 -0
  4. package/dist/assets_manager.d.ts.map +1 -0
  5. package/dist/assets_manager.js +1217 -0
  6. package/dist/assets_manager.js.map +1 -0
  7. package/dist/assets_openapi.d.ts +9 -0
  8. package/dist/assets_openapi.d.ts.map +1 -0
  9. package/dist/assets_openapi.js +391 -0
  10. package/dist/assets_openapi.js.map +1 -0
  11. package/dist/async_upload.d.ts +20 -0
  12. package/dist/async_upload.d.ts.map +1 -0
  13. package/dist/async_upload.js +10 -0
  14. package/dist/async_upload.js.map +1 -0
  15. package/dist/index.d.ts +18 -0
  16. package/dist/index.d.ts.map +1 -0
  17. package/dist/index.js +17 -0
  18. package/dist/index.js.map +1 -0
  19. package/dist/map_manager.d.ts +61 -0
  20. package/dist/map_manager.d.ts.map +1 -0
  21. package/dist/map_manager.js +217 -0
  22. package/dist/map_manager.js.map +1 -0
  23. package/dist/presigned_upload_service.d.ts +52 -0
  24. package/dist/presigned_upload_service.d.ts.map +1 -0
  25. package/dist/presigned_upload_service.js +152 -0
  26. package/dist/presigned_upload_service.js.map +1 -0
  27. package/dist/tileset_manager.d.ts +128 -0
  28. package/dist/tileset_manager.d.ts.map +1 -0
  29. package/dist/tileset_manager.js +705 -0
  30. package/dist/tileset_manager.js.map +1 -0
  31. package/dist/upload_processor.d.ts +42 -0
  32. package/dist/upload_processor.d.ts.map +1 -0
  33. package/dist/upload_processor.js +138 -0
  34. package/dist/upload_processor.js.map +1 -0
  35. package/dist/upload_reconciler.d.ts +44 -0
  36. package/dist/upload_reconciler.d.ts.map +1 -0
  37. package/dist/upload_reconciler.js +140 -0
  38. package/dist/upload_reconciler.js.map +1 -0
  39. package/dist/utils/zip_utils.d.ts +66 -0
  40. package/dist/utils/zip_utils.d.ts.map +1 -0
  41. package/dist/utils/zip_utils.js +169 -0
  42. package/dist/utils/zip_utils.js.map +1 -0
  43. package/package.json +72 -0
@@ -0,0 +1,217 @@
1
+ import { AssetsManager } from './assets_manager.js';
2
+ /**
3
+ * Specialized Assets Manager for handling map layer data.
4
+ *
5
+ * Extends the base AssetsManager with specialized logic for:
6
+ * - Processing JSON layer objects containing map data
7
+ * - Extracting and analyzing layer metadata
8
+ * - Storing layer-specific information
9
+ *
10
+ * Inherits all CRUD endpoints from AssetsManager:
11
+ * - GET /{name} - List all layers
12
+ * - POST /{name}/upload - Upload layer data (overridden)
13
+ * - GET /{name}/:id - Get layer data
14
+ * - PUT /{name}/:id - Update layer metadata
15
+ * - DELETE /{name}/:id - Delete layer
16
+ * - GET /{name}/:id/download - Download layer data
17
+ */
18
+ export class MapManager extends AssetsManager {
19
+ /**
20
+ * Override the upload handler to process JSON layer objects instead of files.
21
+ *
22
+ * Processes the layer data:
23
+ * 1. Validates the layer object structure
24
+ * 2. Extracts layer-specific metadata
25
+ * 3. Stores the layer data as JSON
26
+ *
27
+ * @param req - HTTP request with layer JSON data
28
+ * @returns DataResponse with upload result
29
+ */
30
+ async handleUpload(req) {
31
+ try {
32
+ if (!req || !req.body) {
33
+ return {
34
+ status: 400,
35
+ content: JSON.stringify({
36
+ error: 'Invalid request: missing request body'
37
+ }),
38
+ headers: { 'Content-Type': 'application/json' }
39
+ };
40
+ }
41
+ // Authenticate request
42
+ const authResult = await this.authMiddleware.authenticate(req);
43
+ if (!authResult.success) {
44
+ return authResult.response;
45
+ }
46
+ const userRecord = authResult.userRecord;
47
+ const body = req.body;
48
+ const { layer, description } = body;
49
+ if (!layer) {
50
+ return {
51
+ status: 400,
52
+ content: JSON.stringify({
53
+ error: 'Missing required field: layer (JSON object)'
54
+ }),
55
+ headers: { 'Content-Type': 'application/json' }
56
+ };
57
+ }
58
+ // Validate layer structure
59
+ if (typeof layer !== 'object' || layer === null) {
60
+ return {
61
+ status: 400,
62
+ content: JSON.stringify({
63
+ error: 'Layer must be a valid JSON object'
64
+ }),
65
+ headers: { 'Content-Type': 'application/json' }
66
+ };
67
+ }
68
+ // Analyze layer content
69
+ const layerInfo = this.analyzeLayerContent(layer);
70
+ const config = this.getConfiguration();
71
+ const now = new Date();
72
+ // Convert layer object to JSON string for storage
73
+ const layerJson = JSON.stringify(layer, null, 2);
74
+ const layerBuffer = Buffer.from(layerJson, 'utf-8');
75
+ // Generate filename from layer name or use timestamp
76
+ const filename = `${layerInfo.layer_name || 'layer'}_${Date.now()}.json`;
77
+ // Store layer data using framework pattern
78
+ const url = await this.storage.save(layerBuffer, config.name, filename);
79
+ // Create extended metadata with layer-specific fields
80
+ const metadata = {
81
+ name: config.name,
82
+ type: config.contentType || 'application/json',
83
+ url,
84
+ date: now,
85
+ description: description || layerInfo.description || 'Map layer',
86
+ source: body.source || 'uploaded',
87
+ owner_id: userRecord.id ?? null,
88
+ filename,
89
+ // Layer-specific metadata
90
+ layer_type: layerInfo.layer_type,
91
+ layer_name: layerInfo.layer_name,
92
+ geometry_type: layerInfo.geometry_type,
93
+ properties_count: layerInfo.properties_count
94
+ };
95
+ await this.db.save(metadata);
96
+ return {
97
+ status: 200,
98
+ content: JSON.stringify({
99
+ message: 'Layer uploaded successfully',
100
+ layer_name: layerInfo.layer_name,
101
+ geometry_type: layerInfo.geometry_type,
102
+ properties_count: layerInfo.properties_count
103
+ }),
104
+ headers: { 'Content-Type': 'application/json' }
105
+ };
106
+ }
107
+ catch (error) {
108
+ return {
109
+ status: 500,
110
+ content: JSON.stringify({
111
+ error: error instanceof Error ? error.message : 'Unknown error'
112
+ }),
113
+ headers: { 'Content-Type': 'application/json' }
114
+ };
115
+ }
116
+ }
117
+ /**
118
+ * Analyze layer content to extract metadata
119
+ * @param layer - The layer object to analyze
120
+ * @returns Layer metadata information
121
+ */
122
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
123
+ analyzeLayerContent(layer) {
124
+ // Default values
125
+ let layer_type = 'unknown';
126
+ let layer_name = 'layer';
127
+ let geometry_type;
128
+ let properties_count = 0;
129
+ // Try to detect GeoJSON
130
+ if (layer.type === 'FeatureCollection' && Array.isArray(layer.features)) {
131
+ layer_type = 'geojson';
132
+ layer_name = layer.name || 'geojson_layer';
133
+ // Analyze first feature for geometry type
134
+ if (layer.features.length > 0) {
135
+ const firstFeature = layer.features[0];
136
+ if (firstFeature.geometry && firstFeature.geometry.type) {
137
+ geometry_type = firstFeature.geometry.type.toLowerCase();
138
+ }
139
+ // Count properties in first feature
140
+ if (firstFeature.properties) {
141
+ properties_count = Object.keys(firstFeature.properties).length;
142
+ }
143
+ }
144
+ }
145
+ // Try to detect single GeoJSON Feature
146
+ else if (layer.type === 'Feature' && layer.geometry) {
147
+ layer_type = 'geojson_feature';
148
+ layer_name = layer.properties?.name || 'feature';
149
+ geometry_type = layer.geometry.type?.toLowerCase();
150
+ properties_count = layer.properties ? Object.keys(layer.properties).length : 0;
151
+ }
152
+ // Try to detect other common layer formats
153
+ else if (layer.layers && Array.isArray(layer.layers)) {
154
+ layer_type = 'layer_group';
155
+ layer_name = layer.name || 'layer_group';
156
+ properties_count = layer.layers.length;
157
+ }
158
+ // Generic object
159
+ else {
160
+ layer_type = 'custom';
161
+ layer_name = layer.name || layer.title || layer.id || 'custom_layer';
162
+ properties_count = Object.keys(layer).length;
163
+ }
164
+ // Extract description from various fields
165
+ const description = layer.description || layer.desc || layer.summary;
166
+ return {
167
+ layer_type,
168
+ layer_name,
169
+ geometry_type,
170
+ properties_count,
171
+ description
172
+ };
173
+ }
174
+ /**
175
+ * Override retrieve to include layer-specific metadata in the response
176
+ */
177
+ async retrieve() {
178
+ try {
179
+ const assets = await this.getAllAssets();
180
+ const config = this.getConfiguration();
181
+ // Transform to include layer metadata
182
+ const assetsWithMetadata = assets.map(asset => ({
183
+ id: asset.id,
184
+ name: asset.name,
185
+ date: asset.date,
186
+ contentType: asset.contentType,
187
+ description: asset.description || '',
188
+ source: asset.source || '',
189
+ owner_id: asset.owner_id || null,
190
+ filename: asset.filename || '',
191
+ // Layer-specific fields
192
+ layer_type: asset.layer_type || '',
193
+ layer_name: asset.layer_name || '',
194
+ geometry_type: asset.geometry_type || null,
195
+ properties_count: asset.properties_count || 0,
196
+ // URLs for frontend
197
+ url: `/${config.endpoint}/${asset.id}`,
198
+ download_url: `/${config.endpoint}/${asset.id}/download`
199
+ }));
200
+ return {
201
+ status: 200,
202
+ content: JSON.stringify(assetsWithMetadata),
203
+ headers: { 'Content-Type': 'application/json' }
204
+ };
205
+ }
206
+ catch (error) {
207
+ return {
208
+ status: 500,
209
+ content: JSON.stringify({
210
+ error: error instanceof Error ? error.message : 'Unknown error'
211
+ }),
212
+ headers: { 'Content-Type': 'application/json' }
213
+ };
214
+ }
215
+ }
216
+ }
217
+ //# sourceMappingURL=map_manager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"map_manager.js","sourceRoot":"","sources":["../src/map_manager.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,52 @@
1
+ import type { DataResponse, DataRecord, TypedRequest, AssetsManagerConfiguration } from '@cepseudo/shared';
2
+ import type { StorageService } from '@cepseudo/storage';
3
+ import type { DatabaseAdapter } from '@cepseudo/database';
4
+ import type { AuthMiddleware } from '@cepseudo/auth';
5
+ /**
6
+ * Dependencies required by the presigned upload service.
7
+ * Provided by the AssetsManager that owns this service.
8
+ */
9
+ export interface PresignedUploadDeps {
10
+ db: DatabaseAdapter;
11
+ storage: StorageService;
12
+ authMiddleware: AuthMiddleware;
13
+ getConfiguration(): AssetsManagerConfiguration;
14
+ getAssetById(id: string): Promise<DataRecord | undefined>;
15
+ validateOwnership(asset: DataRecord, userId: number, headers?: Record<string, string | string[] | undefined>): DataResponse | undefined;
16
+ validateFileExtension(filename: string): boolean;
17
+ }
18
+ /**
19
+ * Handles presigned URL upload flow: request generation and confirmation.
20
+ *
21
+ * Extracted from AssetsManager to keep upload concerns separate from
22
+ * general asset CRUD operations.
23
+ */
24
+ export declare class PresignedUploadService {
25
+ private deps;
26
+ constructor(deps: PresignedUploadDeps);
27
+ /**
28
+ * Generate a presigned PUT URL for direct client-to-storage upload.
29
+ *
30
+ * Flow:
31
+ * 1. Authenticate user
32
+ * 2. Validate body (fileName, fileSize, contentType)
33
+ * 3. Check storage supports presigned URLs
34
+ * 4. Validate file extension
35
+ * 5. Generate presigned PUT URL
36
+ * 6. Save pending DB record
37
+ * 7. Return { fileId, uploadUrl, key, expiresAt }
38
+ */
39
+ handleUploadRequest(req: TypedRequest): Promise<DataResponse>;
40
+ /**
41
+ * Confirm that a file has been uploaded via the presigned URL.
42
+ *
43
+ * Flow:
44
+ * 1. Authenticate user
45
+ * 2. Fetch record, check ownership
46
+ * 3. Check upload_status === 'pending'
47
+ * 4. Verify file exists on storage via objectExists
48
+ * 5. Update record to completed with URL = presigned_key
49
+ */
50
+ handleConfirm(req: TypedRequest): Promise<DataResponse>;
51
+ }
52
+ //# sourceMappingURL=presigned_upload_service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"presigned_upload_service.d.ts","sourceRoot":"","sources":["../src/presigned_upload_service.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACR,YAAY,EACZ,UAAU,EACV,YAAY,EAGZ,0BAA0B,EAC7B,MAAM,kBAAkB,CAAA;AASzB,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAA;AACvD,OAAO,KAAK,EAAE,eAAe,EAAe,MAAM,oBAAoB,CAAA;AACtE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAA;AAEpD;;;GAGG;AACH,MAAM,WAAW,mBAAmB;IAChC,EAAE,EAAE,eAAe,CAAA;IACnB,OAAO,EAAE,cAAc,CAAA;IACvB,cAAc,EAAE,cAAc,CAAA;IAC9B,gBAAgB,IAAI,0BAA0B,CAAA;IAC9C,YAAY,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC,CAAA;IACzD,iBAAiB,CAAC,KAAK,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,SAAS,CAAC,GAAG,YAAY,GAAG,SAAS,CAAA;IACvI,qBAAqB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAA;CACnD;AAED;;;;;GAKG;AACH,qBAAa,sBAAsB;IAC/B,OAAO,CAAC,IAAI,CAAqB;gBAErB,IAAI,EAAE,mBAAmB;IAIrC;;;;;;;;;;;OAWG;IACG,mBAAmB,CAAC,GAAG,EAAE,YAAY,GAAG,OAAO,CAAC,YAAY,CAAC;IAsEnE;;;;;;;;;OASG;IACG,aAAa,CAAC,GAAG,EAAE,YAAY,GAAG,OAAO,CAAC,YAAY,CAAC;CA+DhE"}
@@ -0,0 +1,152 @@
1
+ import { successResponse, errorResponse, badRequestResponse, notFoundResponse, validateData, validatePresignedUploadRequest } from '@cepseudo/shared';
2
+ /**
3
+ * Handles presigned URL upload flow: request generation and confirmation.
4
+ *
5
+ * Extracted from AssetsManager to keep upload concerns separate from
6
+ * general asset CRUD operations.
7
+ */
8
+ export class PresignedUploadService {
9
+ constructor(deps) {
10
+ this.deps = deps;
11
+ }
12
+ /**
13
+ * Generate a presigned PUT URL for direct client-to-storage upload.
14
+ *
15
+ * Flow:
16
+ * 1. Authenticate user
17
+ * 2. Validate body (fileName, fileSize, contentType)
18
+ * 3. Check storage supports presigned URLs
19
+ * 4. Validate file extension
20
+ * 5. Generate presigned PUT URL
21
+ * 6. Save pending DB record
22
+ * 7. Return { fileId, uploadUrl, key, expiresAt }
23
+ */
24
+ async handleUploadRequest(req) {
25
+ try {
26
+ if (!req?.body) {
27
+ return badRequestResponse('Invalid request: missing request body');
28
+ }
29
+ // Authenticate user
30
+ const authResult = await this.deps.authMiddleware.authenticate(req);
31
+ if (!authResult.success) {
32
+ return authResult.response;
33
+ }
34
+ const userId = authResult.userRecord.id;
35
+ if (!userId) {
36
+ return errorResponse('Failed to retrieve user information');
37
+ }
38
+ // Check presigned URL support
39
+ if (!this.deps.storage.supportsPresignedUrls()) {
40
+ return badRequestResponse('Presigned uploads are not supported with the current storage backend');
41
+ }
42
+ // Validate request body
43
+ const validated = await validateData(validatePresignedUploadRequest, req.body);
44
+ const { fileName, contentType, description, source, is_public } = validated;
45
+ // Validate file extension
46
+ if (!this.deps.validateFileExtension(fileName)) {
47
+ const config = this.deps.getConfiguration();
48
+ return badRequestResponse(`Invalid file extension. Expected: ${config.extension}`);
49
+ }
50
+ const config = this.deps.getConfiguration();
51
+ const sanitizedFilename = fileName.replace(/[^a-zA-Z0-9._-]/g, '_');
52
+ const key = `${config.name}/${Date.now()}/${sanitizedFilename}`;
53
+ // Generate presigned URL (5 min expiry)
54
+ const presigned = await this.deps.storage.generatePresignedUploadUrl(key, contentType, 300);
55
+ // Save pending record in database
56
+ const metadata = {
57
+ name: config.name,
58
+ type: contentType,
59
+ url: '',
60
+ date: new Date(),
61
+ description: description || '',
62
+ source: source || '',
63
+ owner_id: userId,
64
+ filename: fileName,
65
+ is_public: is_public ?? true,
66
+ presigned_key: presigned.key,
67
+ presigned_expires_at: presigned.expiresAt
68
+ };
69
+ // Use upload_status field via updateById after save
70
+ const savedRecord = await this.deps.db.save(metadata);
71
+ await this.deps.db.updateById(config.name, savedRecord.id, {
72
+ upload_status: 'pending'
73
+ });
74
+ return successResponse({
75
+ fileId: savedRecord.id,
76
+ uploadUrl: presigned.url,
77
+ key: presigned.key,
78
+ expiresAt: presigned.expiresAt.toISOString()
79
+ });
80
+ }
81
+ catch (error) {
82
+ return errorResponse(error);
83
+ }
84
+ }
85
+ /**
86
+ * Confirm that a file has been uploaded via the presigned URL.
87
+ *
88
+ * Flow:
89
+ * 1. Authenticate user
90
+ * 2. Fetch record, check ownership
91
+ * 3. Check upload_status === 'pending'
92
+ * 4. Verify file exists on storage via objectExists
93
+ * 5. Update record to completed with URL = presigned_key
94
+ */
95
+ async handleConfirm(req) {
96
+ try {
97
+ // Authenticate user
98
+ const authResult = await this.deps.authMiddleware.authenticate(req);
99
+ if (!authResult.success) {
100
+ return authResult.response;
101
+ }
102
+ const userId = authResult.userRecord.id;
103
+ if (!userId) {
104
+ return errorResponse('Failed to retrieve user information');
105
+ }
106
+ const fileId = req.params?.fileId;
107
+ if (!fileId) {
108
+ return badRequestResponse('File ID is required');
109
+ }
110
+ const config = this.deps.getConfiguration();
111
+ const asset = await this.deps.getAssetById(fileId);
112
+ if (!asset) {
113
+ return notFoundResponse('Asset not found');
114
+ }
115
+ // Check ownership
116
+ const ownershipError = this.deps.validateOwnership(asset, userId, req.headers);
117
+ if (ownershipError) {
118
+ return ownershipError;
119
+ }
120
+ // Check status
121
+ if (asset.upload_status !== 'pending') {
122
+ return {
123
+ status: 409,
124
+ content: JSON.stringify({ error: `Upload is not pending (current status: ${asset.upload_status || 'completed'})` }),
125
+ headers: { 'Content-Type': 'application/json' }
126
+ };
127
+ }
128
+ // Verify file exists on storage
129
+ if (!asset.presigned_key) {
130
+ return badRequestResponse('No presigned key found for this record');
131
+ }
132
+ const existsResult = await this.deps.storage.objectExists(asset.presigned_key);
133
+ if (!existsResult.exists) {
134
+ return badRequestResponse('File not found on storage. Please upload the file using the presigned URL first.');
135
+ }
136
+ // Update record to completed
137
+ await this.deps.db.updateById(config.name, asset.id, {
138
+ upload_status: 'completed',
139
+ url: asset.presigned_key
140
+ });
141
+ return successResponse({
142
+ message: 'Upload confirmed successfully',
143
+ id: asset.id,
144
+ url: asset.presigned_key
145
+ });
146
+ }
147
+ catch (error) {
148
+ return errorResponse(error);
149
+ }
150
+ }
151
+ }
152
+ //# sourceMappingURL=presigned_upload_service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"presigned_upload_service.js","sourceRoot":"","sources":["../src/presigned_upload_service.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,128 @@
1
+ import { AssetsManager } from './assets_manager.js';
2
+ import type { DataResponse, OpenAPIComponentSpec, HttpMethod, TypedRequest } from '@cepseudo/shared';
3
+ import type { AsyncUploadable } from './async_upload.js';
4
+ import type { Queue } from 'bullmq';
5
+ /**
6
+ * Metadata stored in database for a tileset.
7
+ * Simplified: Cesium accesses files directly from OVH.
8
+ */
9
+ export interface TilesetMetadataRow {
10
+ id?: number;
11
+ name: string;
12
+ type: string;
13
+ /** Base path in storage for deletion (e.g., tilesets/123) */
14
+ url: string;
15
+ /** Public URL to tileset.json */
16
+ tileset_url: string;
17
+ date: Date;
18
+ description: string;
19
+ filename: string;
20
+ owner_id: number | null;
21
+ is_public?: boolean;
22
+ upload_status?: 'pending' | 'processing' | 'completed' | 'failed';
23
+ upload_job_id?: string;
24
+ upload_error?: string;
25
+ }
26
+ /**
27
+ * Specialized Assets Manager for handling 3D Tiles tilesets.
28
+ *
29
+ * This manager extracts uploaded ZIP files and stores each file in cloud storage (OVH S3),
30
+ * allowing Cesium and other 3D viewers to load tilesets directly via public URLs.
31
+ *
32
+ * ## How it works
33
+ *
34
+ * 1. User uploads a ZIP containing a 3D Tiles tileset
35
+ * 2. ZIP is extracted and all files are stored in OVH with public-read ACL
36
+ * 3. Database stores only the tileset.json URL and base path
37
+ * 4. Cesium loads tileset.json directly from OVH
38
+ * 5. Cesium fetches tiles using relative paths in tileset.json (directly from OVH)
39
+ *
40
+ * ## Endpoints
41
+ *
42
+ * - GET /{endpoint} - List all tilesets with their public URLs
43
+ * - POST /{endpoint} - Upload tileset ZIP (sync < 50MB, async >= 50MB)
44
+ * - GET /{endpoint}/:id/status - Poll async upload status
45
+ * - PUT /{endpoint}/:id - Update tileset metadata
46
+ * - DELETE /{endpoint}/:id - Delete tileset and all files from storage
47
+ *
48
+ * @example
49
+ * ```typescript
50
+ * class MyTilesetManager extends TilesetManager {
51
+ * getConfiguration() {
52
+ * return {
53
+ * name: 'tilesets',
54
+ * description: 'Manage 3D Tiles tilesets',
55
+ * contentType: 'application/json',
56
+ * endpoint: 'api/tilesets',
57
+ * extension: '.zip'
58
+ * }
59
+ * }
60
+ * }
61
+ *
62
+ * // After upload, response contains:
63
+ * // { tileset_url: 'https://bucket.s3.../tilesets/123/tileset.json' }
64
+ * //
65
+ * // Cesium loads directly:
66
+ * // Cesium.Cesium3DTileset.fromUrl(tileset_url)
67
+ * ```
68
+ */
69
+ export declare abstract class TilesetManager extends AssetsManager implements AsyncUploadable {
70
+ /** Upload queue for async processing (injected by engine) */
71
+ protected uploadQueue: Queue | null;
72
+ /**
73
+ * Set the upload queue for async job processing.
74
+ * Called by DigitalTwinEngine during initialization.
75
+ */
76
+ setUploadQueue(queue: Queue): void;
77
+ /**
78
+ * Handle tileset upload.
79
+ *
80
+ * - Files < 50MB: Synchronous extraction and upload
81
+ * - Files >= 50MB: Queued for async processing (returns 202)
82
+ */
83
+ handleUpload(req: TypedRequest): Promise<DataResponse>;
84
+ /**
85
+ * Authenticate user from request headers.
86
+ * Returns user ID on success, or error response on failure.
87
+ */
88
+ private authenticateUser;
89
+ /**
90
+ * Queue upload for background processing. Returns HTTP 202 immediately.
91
+ */
92
+ private handleAsyncUpload;
93
+ /**
94
+ * Process upload synchronously.
95
+ */
96
+ private handleSyncUpload;
97
+ /**
98
+ * Get upload status for async uploads.
99
+ */
100
+ handleGetStatus(req: TypedRequest): Promise<DataResponse>;
101
+ /**
102
+ * Override presigned upload confirmation for tilesets.
103
+ * Instead of marking as completed, queue a BullMQ job for ZIP extraction.
104
+ */
105
+ handleUploadConfirm(req: TypedRequest): Promise<DataResponse>;
106
+ /**
107
+ * List all tilesets with their public URLs.
108
+ */
109
+ retrieve(req?: TypedRequest): Promise<DataResponse>;
110
+ /**
111
+ * Delete tileset and all files from storage.
112
+ */
113
+ handleDelete(req: TypedRequest): Promise<DataResponse>;
114
+ /**
115
+ * Get HTTP endpoints for this manager.
116
+ */
117
+ getEndpoints(): Array<{
118
+ method: HttpMethod;
119
+ path: string;
120
+ handler: (req: TypedRequest) => Promise<DataResponse>;
121
+ responseType?: string;
122
+ }>;
123
+ /**
124
+ * Generate OpenAPI specification.
125
+ */
126
+ getOpenAPISpec(): OpenAPIComponentSpec;
127
+ }
128
+ //# sourceMappingURL=tileset_manager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tileset_manager.d.ts","sourceRoot":"","sources":["../src/tileset_manager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAA;AACnD,OAAO,KAAK,EAAE,YAAY,EAAE,oBAAoB,EAAE,UAAU,EAAE,YAAY,EAA2B,MAAM,kBAAkB,CAAA;AAc7H,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAA;AAExD,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAA;AAQnC;;;GAGG;AACH,MAAM,WAAW,kBAAkB;IAC/B,EAAE,CAAC,EAAE,MAAM,CAAA;IACX,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;IACZ,6DAA6D;IAC7D,GAAG,EAAE,MAAM,CAAA;IACX,iCAAiC;IACjC,WAAW,EAAE,MAAM,CAAA;IACnB,IAAI,EAAE,IAAI,CAAA;IACV,WAAW,EAAE,MAAM,CAAA;IACnB,QAAQ,EAAE,MAAM,CAAA;IAChB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAA;IACvB,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,aAAa,CAAC,EAAE,SAAS,GAAG,YAAY,GAAG,WAAW,GAAG,QAAQ,CAAA;IACjE,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,YAAY,CAAC,EAAE,MAAM,CAAA;CACxB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0CG;AACH,8BAAsB,cAAe,SAAQ,aAAc,YAAW,eAAe;IACjF,6DAA6D;IAC7D,SAAS,CAAC,WAAW,EAAE,KAAK,GAAG,IAAI,CAAO;IAE1C;;;OAGG;IACH,cAAc,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI;IAIlC;;;;;OAKG;IACY,YAAY,CAAC,GAAG,EAAE,YAAY,GAAG,OAAO,CAAC,YAAY,CAAC;IAsDrE;;;OAGG;YACW,gBAAgB;IAQ9B;;OAEG;YACW,iBAAiB;IAyE/B;;OAEG;YACW,gBAAgB;IAyE9B;;OAEG;IACG,eAAe,CAAC,GAAG,EAAE,YAAY,GAAG,OAAO,CAAC,YAAY,CAAC;IAwC/D;;;OAGG;IACY,mBAAmB,CAAC,GAAG,EAAE,YAAY,GAAG,OAAO,CAAC,YAAY,CAAC;IA6F5E;;OAEG;IACY,QAAQ,CAAC,GAAG,CAAC,EAAE,YAAY,GAAG,OAAO,CAAC,YAAY,CAAC;IAwClE;;OAEG;IACY,YAAY,CAAC,GAAG,EAAE,YAAY,GAAG,OAAO,CAAC,YAAY,CAAC;IA0DrE;;OAEG;IACM,YAAY,IAAI,KAAK,CAAC;QAC3B,MAAM,EAAE,UAAU,CAAA;QAClB,IAAI,EAAE,MAAM,CAAA;QACZ,OAAO,EAAE,CAAC,GAAG,EAAE,YAAY,KAAK,OAAO,CAAC,YAAY,CAAC,CAAA;QACrD,YAAY,CAAC,EAAE,MAAM,CAAA;KACxB,CAAC;IAwDF;;OAEG;IACM,cAAc,IAAI,oBAAoB;CA0LlD"}