@objectql/server 1.8.1 → 1.8.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +9 -0
- package/dist/adapters/node.d.ts +9 -1
- package/dist/adapters/node.js +30 -1
- package/dist/adapters/node.js.map +1 -1
- package/dist/file-handler.d.ts +50 -0
- package/dist/file-handler.js +354 -0
- package/dist/file-handler.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/storage.d.ts +35 -0
- package/dist/storage.js +181 -0
- package/dist/storage.js.map +1 -0
- package/dist/types.d.ts +72 -0
- package/package.json +16 -4
- package/src/adapters/node.ts +44 -2
- package/src/file-handler.ts +414 -0
- package/src/index.ts +2 -0
- package/src/storage.ts +171 -0
- package/src/types.ts +79 -0
- package/test/file-upload-integration.example.ts +201 -0
- package/test/file-validation.test.ts +131 -0
- package/test/storage.test.ts +104 -0
- package/tsconfig.tsbuildinfo +1 -1
package/CHANGELOG.md
CHANGED
package/dist/adapters/node.d.ts
CHANGED
|
@@ -1,8 +1,16 @@
|
|
|
1
1
|
import { IObjectQL } from '@objectql/types';
|
|
2
|
+
import { IFileStorage } from '../types';
|
|
2
3
|
import { IncomingMessage, ServerResponse } from 'http';
|
|
4
|
+
/**
|
|
5
|
+
* Options for createNodeHandler
|
|
6
|
+
*/
|
|
7
|
+
export interface NodeHandlerOptions {
|
|
8
|
+
/** File storage provider (defaults to LocalFileStorage) */
|
|
9
|
+
fileStorage?: IFileStorage;
|
|
10
|
+
}
|
|
3
11
|
/**
|
|
4
12
|
* Creates a standard Node.js HTTP request handler.
|
|
5
13
|
*/
|
|
6
|
-
export declare function createNodeHandler(app: IObjectQL): (req: IncomingMessage & {
|
|
14
|
+
export declare function createNodeHandler(app: IObjectQL, options?: NodeHandlerOptions): (req: IncomingMessage & {
|
|
7
15
|
body?: any;
|
|
8
16
|
}, res: ServerResponse) => Promise<void>;
|
package/dist/adapters/node.js
CHANGED
|
@@ -4,11 +4,22 @@ exports.createNodeHandler = createNodeHandler;
|
|
|
4
4
|
const server_1 = require("../server");
|
|
5
5
|
const types_1 = require("../types");
|
|
6
6
|
const openapi_1 = require("../openapi");
|
|
7
|
+
const file_handler_1 = require("../file-handler");
|
|
8
|
+
const storage_1 = require("../storage");
|
|
7
9
|
/**
|
|
8
10
|
* Creates a standard Node.js HTTP request handler.
|
|
9
11
|
*/
|
|
10
|
-
function createNodeHandler(app) {
|
|
12
|
+
function createNodeHandler(app, options) {
|
|
11
13
|
const server = new server_1.ObjectQLServer(app);
|
|
14
|
+
// Initialize file storage
|
|
15
|
+
const fileStorage = (options === null || options === void 0 ? void 0 : options.fileStorage) || new storage_1.LocalFileStorage({
|
|
16
|
+
baseDir: process.env.OBJECTQL_UPLOAD_DIR || './uploads',
|
|
17
|
+
baseUrl: process.env.OBJECTQL_BASE_URL || 'http://localhost:3000/api/files'
|
|
18
|
+
});
|
|
19
|
+
// Create file handlers
|
|
20
|
+
const uploadHandler = (0, file_handler_1.createFileUploadHandler)(fileStorage, app);
|
|
21
|
+
const batchUploadHandler = (0, file_handler_1.createBatchFileUploadHandler)(fileStorage, app);
|
|
22
|
+
const downloadHandler = (0, file_handler_1.createFileDownloadHandler)(fileStorage);
|
|
12
23
|
return async (req, res) => {
|
|
13
24
|
var _a;
|
|
14
25
|
// Handle OpenAPI spec request
|
|
@@ -156,6 +167,24 @@ function createNodeHandler(app) {
|
|
|
156
167
|
return;
|
|
157
168
|
}
|
|
158
169
|
}
|
|
170
|
+
// File Upload Endpoints
|
|
171
|
+
// POST /api/files/upload - Single file upload
|
|
172
|
+
if (pathName === '/api/files/upload' && method === 'POST') {
|
|
173
|
+
await uploadHandler(req, res);
|
|
174
|
+
return;
|
|
175
|
+
}
|
|
176
|
+
// POST /api/files/upload/batch - Batch file upload
|
|
177
|
+
if (pathName === '/api/files/upload/batch' && method === 'POST') {
|
|
178
|
+
await batchUploadHandler(req, res);
|
|
179
|
+
return;
|
|
180
|
+
}
|
|
181
|
+
// GET /api/files/:fileId - Download file
|
|
182
|
+
const fileMatch = pathName.match(/^\/api\/files\/([^/]+)$/);
|
|
183
|
+
if (fileMatch && method === 'GET') {
|
|
184
|
+
const fileId = fileMatch[1];
|
|
185
|
+
await downloadHandler(req, res, fileId);
|
|
186
|
+
return;
|
|
187
|
+
}
|
|
159
188
|
// Fallback or 404
|
|
160
189
|
if (req.method === 'POST') {
|
|
161
190
|
// Fallback for root POSTs if people forget /api/objectql but send to /api something
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"node.js","sourceRoot":"","sources":["../../src/adapters/node.ts"],"names":[],"mappings":";;
|
|
1
|
+
{"version":3,"file":"node.js","sourceRoot":"","sources":["../../src/adapters/node.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { IncomingMessage, ServerResponse } from 'http';
|
|
2
|
+
import { IFileStorage } from './types';
|
|
3
|
+
import { IObjectQL, FieldConfig } from '@objectql/types';
|
|
4
|
+
/**
|
|
5
|
+
* Parse multipart/form-data request
|
|
6
|
+
*/
|
|
7
|
+
export declare function parseMultipart(req: IncomingMessage, boundary: string): Promise<{
|
|
8
|
+
fields: Record<string, string>;
|
|
9
|
+
files: Array<{
|
|
10
|
+
fieldname: string;
|
|
11
|
+
filename: string;
|
|
12
|
+
mimeType: string;
|
|
13
|
+
buffer: Buffer;
|
|
14
|
+
}>;
|
|
15
|
+
}>;
|
|
16
|
+
/**
|
|
17
|
+
* Validate uploaded file against field configuration
|
|
18
|
+
*/
|
|
19
|
+
export declare function validateFile(file: {
|
|
20
|
+
filename: string;
|
|
21
|
+
mimeType: string;
|
|
22
|
+
buffer: Buffer;
|
|
23
|
+
}, fieldConfig?: FieldConfig, objectName?: string, fieldName?: string): {
|
|
24
|
+
valid: boolean;
|
|
25
|
+
error?: {
|
|
26
|
+
code: string;
|
|
27
|
+
message: string;
|
|
28
|
+
details?: any;
|
|
29
|
+
};
|
|
30
|
+
};
|
|
31
|
+
/**
|
|
32
|
+
* Send error response
|
|
33
|
+
*/
|
|
34
|
+
export declare function sendError(res: ServerResponse, statusCode: number, code: string, message: string, details?: any): void;
|
|
35
|
+
/**
|
|
36
|
+
* Send success response
|
|
37
|
+
*/
|
|
38
|
+
export declare function sendSuccess(res: ServerResponse, data: any): void;
|
|
39
|
+
/**
|
|
40
|
+
* Create file upload handler
|
|
41
|
+
*/
|
|
42
|
+
export declare function createFileUploadHandler(storage: IFileStorage, app: IObjectQL): (req: IncomingMessage, res: ServerResponse) => Promise<void>;
|
|
43
|
+
/**
|
|
44
|
+
* Create batch file upload handler
|
|
45
|
+
*/
|
|
46
|
+
export declare function createBatchFileUploadHandler(storage: IFileStorage, app: IObjectQL): (req: IncomingMessage, res: ServerResponse) => Promise<void>;
|
|
47
|
+
/**
|
|
48
|
+
* Create file download handler
|
|
49
|
+
*/
|
|
50
|
+
export declare function createFileDownloadHandler(storage: IFileStorage): (req: IncomingMessage, res: ServerResponse, fileId: string) => Promise<void>;
|
|
@@ -0,0 +1,354 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.parseMultipart = parseMultipart;
|
|
4
|
+
exports.validateFile = validateFile;
|
|
5
|
+
exports.sendError = sendError;
|
|
6
|
+
exports.sendSuccess = sendSuccess;
|
|
7
|
+
exports.createFileUploadHandler = createFileUploadHandler;
|
|
8
|
+
exports.createBatchFileUploadHandler = createBatchFileUploadHandler;
|
|
9
|
+
exports.createFileDownloadHandler = createFileDownloadHandler;
|
|
10
|
+
const types_1 = require("./types");
|
|
11
|
+
/**
|
|
12
|
+
* Parse multipart/form-data request
|
|
13
|
+
*/
|
|
14
|
+
function parseMultipart(req, boundary) {
|
|
15
|
+
return new Promise((resolve, reject) => {
|
|
16
|
+
const chunks = [];
|
|
17
|
+
req.on('data', (chunk) => chunks.push(chunk));
|
|
18
|
+
req.on('error', reject);
|
|
19
|
+
req.on('end', () => {
|
|
20
|
+
try {
|
|
21
|
+
const buffer = Buffer.concat(chunks);
|
|
22
|
+
const result = parseMultipartBuffer(buffer, boundary);
|
|
23
|
+
resolve(result);
|
|
24
|
+
}
|
|
25
|
+
catch (error) {
|
|
26
|
+
reject(error);
|
|
27
|
+
}
|
|
28
|
+
});
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
function parseMultipartBuffer(buffer, boundary) {
|
|
32
|
+
const fields = {};
|
|
33
|
+
const files = [];
|
|
34
|
+
const delimiter = Buffer.from(`--${boundary}`);
|
|
35
|
+
const parts = splitBuffer(buffer, delimiter);
|
|
36
|
+
for (const part of parts) {
|
|
37
|
+
if (part.length === 0 || part.toString().trim() === '--') {
|
|
38
|
+
continue;
|
|
39
|
+
}
|
|
40
|
+
// Find header/body separator (double CRLF)
|
|
41
|
+
const headerEnd = findSequence(part, Buffer.from('\r\n\r\n'));
|
|
42
|
+
if (headerEnd === -1)
|
|
43
|
+
continue;
|
|
44
|
+
const headerSection = part.slice(0, headerEnd).toString();
|
|
45
|
+
const bodySection = part.slice(headerEnd + 4);
|
|
46
|
+
// Parse Content-Disposition header
|
|
47
|
+
const dispositionMatch = headerSection.match(/Content-Disposition: form-data; name="([^"]+)"(?:; filename="([^"]+)")?/i);
|
|
48
|
+
if (!dispositionMatch)
|
|
49
|
+
continue;
|
|
50
|
+
const fieldname = dispositionMatch[1];
|
|
51
|
+
const filename = dispositionMatch[2];
|
|
52
|
+
if (filename) {
|
|
53
|
+
// This is a file upload
|
|
54
|
+
const contentTypeMatch = headerSection.match(/Content-Type: (.+)/i);
|
|
55
|
+
const mimeType = contentTypeMatch ? contentTypeMatch[1].trim() : 'application/octet-stream';
|
|
56
|
+
// Remove trailing CRLF from body
|
|
57
|
+
let fileBuffer = bodySection;
|
|
58
|
+
if (fileBuffer.length >= 2 && fileBuffer[fileBuffer.length - 2] === 0x0d && fileBuffer[fileBuffer.length - 1] === 0x0a) {
|
|
59
|
+
fileBuffer = fileBuffer.slice(0, -2);
|
|
60
|
+
}
|
|
61
|
+
files.push({ fieldname, filename, mimeType, buffer: fileBuffer });
|
|
62
|
+
}
|
|
63
|
+
else {
|
|
64
|
+
// This is a regular form field
|
|
65
|
+
let value = bodySection.toString('utf-8');
|
|
66
|
+
if (value.endsWith('\r\n')) {
|
|
67
|
+
value = value.slice(0, -2);
|
|
68
|
+
}
|
|
69
|
+
fields[fieldname] = value;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
return { fields, files };
|
|
73
|
+
}
|
|
74
|
+
function splitBuffer(buffer, delimiter) {
|
|
75
|
+
const parts = [];
|
|
76
|
+
let start = 0;
|
|
77
|
+
let pos = 0;
|
|
78
|
+
while (pos <= buffer.length - delimiter.length) {
|
|
79
|
+
let match = true;
|
|
80
|
+
for (let i = 0; i < delimiter.length; i++) {
|
|
81
|
+
if (buffer[pos + i] !== delimiter[i]) {
|
|
82
|
+
match = false;
|
|
83
|
+
break;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
if (match) {
|
|
87
|
+
if (pos > start) {
|
|
88
|
+
parts.push(buffer.slice(start, pos));
|
|
89
|
+
}
|
|
90
|
+
pos += delimiter.length;
|
|
91
|
+
start = pos;
|
|
92
|
+
}
|
|
93
|
+
else {
|
|
94
|
+
pos++;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
if (start < buffer.length) {
|
|
98
|
+
parts.push(buffer.slice(start));
|
|
99
|
+
}
|
|
100
|
+
return parts;
|
|
101
|
+
}
|
|
102
|
+
function findSequence(buffer, sequence) {
|
|
103
|
+
for (let i = 0; i <= buffer.length - sequence.length; i++) {
|
|
104
|
+
let match = true;
|
|
105
|
+
for (let j = 0; j < sequence.length; j++) {
|
|
106
|
+
if (buffer[i + j] !== sequence[j]) {
|
|
107
|
+
match = false;
|
|
108
|
+
break;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
if (match)
|
|
112
|
+
return i;
|
|
113
|
+
}
|
|
114
|
+
return -1;
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Validate uploaded file against field configuration
|
|
118
|
+
*/
|
|
119
|
+
function validateFile(file, fieldConfig, objectName, fieldName) {
|
|
120
|
+
// If no field config provided, allow the upload
|
|
121
|
+
if (!fieldConfig) {
|
|
122
|
+
return { valid: true };
|
|
123
|
+
}
|
|
124
|
+
const fileSize = file.buffer.length;
|
|
125
|
+
const fileName = file.filename;
|
|
126
|
+
const mimeType = file.mimeType;
|
|
127
|
+
// Validate file size
|
|
128
|
+
if (fieldConfig.max_size && fileSize > fieldConfig.max_size) {
|
|
129
|
+
return {
|
|
130
|
+
valid: false,
|
|
131
|
+
error: {
|
|
132
|
+
code: 'FILE_TOO_LARGE',
|
|
133
|
+
message: `File size (${fileSize} bytes) exceeds maximum allowed size (${fieldConfig.max_size} bytes)`,
|
|
134
|
+
details: {
|
|
135
|
+
file: fileName,
|
|
136
|
+
size: fileSize,
|
|
137
|
+
max_size: fieldConfig.max_size
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
if (fieldConfig.min_size && fileSize < fieldConfig.min_size) {
|
|
143
|
+
return {
|
|
144
|
+
valid: false,
|
|
145
|
+
error: {
|
|
146
|
+
code: 'FILE_TOO_SMALL',
|
|
147
|
+
message: `File size (${fileSize} bytes) is below minimum required size (${fieldConfig.min_size} bytes)`,
|
|
148
|
+
details: {
|
|
149
|
+
file: fileName,
|
|
150
|
+
size: fileSize,
|
|
151
|
+
min_size: fieldConfig.min_size
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
// Validate file type/extension
|
|
157
|
+
if (fieldConfig.accept && Array.isArray(fieldConfig.accept) && fieldConfig.accept.length > 0) {
|
|
158
|
+
const fileExt = fileName.substring(fileName.lastIndexOf('.')).toLowerCase();
|
|
159
|
+
const acceptedExtensions = fieldConfig.accept.map(ext => ext.toLowerCase());
|
|
160
|
+
if (!acceptedExtensions.includes(fileExt)) {
|
|
161
|
+
return {
|
|
162
|
+
valid: false,
|
|
163
|
+
error: {
|
|
164
|
+
code: 'FILE_TYPE_NOT_ALLOWED',
|
|
165
|
+
message: `File type '${fileExt}' is not allowed. Allowed types: ${acceptedExtensions.join(', ')}`,
|
|
166
|
+
details: {
|
|
167
|
+
file: fileName,
|
|
168
|
+
extension: fileExt,
|
|
169
|
+
allowed: acceptedExtensions
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
};
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
return { valid: true };
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* Send error response
|
|
179
|
+
*/
|
|
180
|
+
function sendError(res, statusCode, code, message, details) {
|
|
181
|
+
res.setHeader('Content-Type', 'application/json');
|
|
182
|
+
res.statusCode = statusCode;
|
|
183
|
+
res.end(JSON.stringify({
|
|
184
|
+
error: {
|
|
185
|
+
code,
|
|
186
|
+
message,
|
|
187
|
+
details
|
|
188
|
+
}
|
|
189
|
+
}));
|
|
190
|
+
}
|
|
191
|
+
/**
|
|
192
|
+
* Send success response
|
|
193
|
+
*/
|
|
194
|
+
function sendSuccess(res, data) {
|
|
195
|
+
res.setHeader('Content-Type', 'application/json');
|
|
196
|
+
res.statusCode = 200;
|
|
197
|
+
res.end(JSON.stringify({ data }));
|
|
198
|
+
}
|
|
199
|
+
/**
|
|
200
|
+
* Extract user ID from authorization header
|
|
201
|
+
* @internal This is a placeholder implementation. In production, integrate with actual auth middleware.
|
|
202
|
+
*/
|
|
203
|
+
function extractUserId(authHeader) {
|
|
204
|
+
if (!authHeader || !authHeader.startsWith('Bearer ')) {
|
|
205
|
+
return undefined;
|
|
206
|
+
}
|
|
207
|
+
// TODO: In production, decode JWT or validate token properly
|
|
208
|
+
// This is a placeholder implementation
|
|
209
|
+
console.warn('[Security] File upload authentication is using placeholder implementation. Integrate with actual auth system.');
|
|
210
|
+
return 'user_from_token';
|
|
211
|
+
}
|
|
212
|
+
/**
|
|
213
|
+
* Create file upload handler
|
|
214
|
+
*/
|
|
215
|
+
function createFileUploadHandler(storage, app) {
|
|
216
|
+
return async (req, res) => {
|
|
217
|
+
try {
|
|
218
|
+
// Check content type
|
|
219
|
+
const contentType = req.headers['content-type'];
|
|
220
|
+
if (!contentType || !contentType.startsWith('multipart/form-data')) {
|
|
221
|
+
sendError(res, 400, types_1.ErrorCode.INVALID_REQUEST, 'Content-Type must be multipart/form-data');
|
|
222
|
+
return;
|
|
223
|
+
}
|
|
224
|
+
// Extract boundary
|
|
225
|
+
const boundaryMatch = contentType.match(/boundary=(.+)/);
|
|
226
|
+
if (!boundaryMatch) {
|
|
227
|
+
sendError(res, 400, types_1.ErrorCode.INVALID_REQUEST, 'Missing boundary in Content-Type');
|
|
228
|
+
return;
|
|
229
|
+
}
|
|
230
|
+
const boundary = boundaryMatch[1];
|
|
231
|
+
// Parse multipart data
|
|
232
|
+
const { fields, files } = await parseMultipart(req, boundary);
|
|
233
|
+
if (files.length === 0) {
|
|
234
|
+
sendError(res, 400, types_1.ErrorCode.INVALID_REQUEST, 'No file provided');
|
|
235
|
+
return;
|
|
236
|
+
}
|
|
237
|
+
// Get field configuration if object and field are specified
|
|
238
|
+
let fieldConfig;
|
|
239
|
+
if (fields.object && fields.field) {
|
|
240
|
+
const objectConfig = app.getObject(fields.object);
|
|
241
|
+
if (objectConfig && objectConfig.fields) {
|
|
242
|
+
fieldConfig = objectConfig.fields[fields.field];
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
// Single file upload
|
|
246
|
+
const file = files[0];
|
|
247
|
+
// Validate file
|
|
248
|
+
const validation = validateFile(file, fieldConfig, fields.object, fields.field);
|
|
249
|
+
if (!validation.valid) {
|
|
250
|
+
sendError(res, 400, validation.error.code, validation.error.message, validation.error.details);
|
|
251
|
+
return;
|
|
252
|
+
}
|
|
253
|
+
// Extract user ID from authorization header
|
|
254
|
+
const userId = extractUserId(req.headers.authorization);
|
|
255
|
+
// Save file
|
|
256
|
+
const attachmentData = await storage.save(file.buffer, file.filename, file.mimeType, {
|
|
257
|
+
folder: fields.folder,
|
|
258
|
+
object: fields.object,
|
|
259
|
+
field: fields.field,
|
|
260
|
+
userId
|
|
261
|
+
});
|
|
262
|
+
sendSuccess(res, attachmentData);
|
|
263
|
+
}
|
|
264
|
+
catch (error) {
|
|
265
|
+
console.error('File upload error:', error);
|
|
266
|
+
sendError(res, 500, types_1.ErrorCode.INTERNAL_ERROR, 'File upload failed');
|
|
267
|
+
}
|
|
268
|
+
};
|
|
269
|
+
}
|
|
270
|
+
/**
|
|
271
|
+
* Create batch file upload handler
|
|
272
|
+
*/
|
|
273
|
+
function createBatchFileUploadHandler(storage, app) {
|
|
274
|
+
return async (req, res) => {
|
|
275
|
+
try {
|
|
276
|
+
// Check content type
|
|
277
|
+
const contentType = req.headers['content-type'];
|
|
278
|
+
if (!contentType || !contentType.startsWith('multipart/form-data')) {
|
|
279
|
+
sendError(res, 400, types_1.ErrorCode.INVALID_REQUEST, 'Content-Type must be multipart/form-data');
|
|
280
|
+
return;
|
|
281
|
+
}
|
|
282
|
+
// Extract boundary
|
|
283
|
+
const boundaryMatch = contentType.match(/boundary=(.+)/);
|
|
284
|
+
if (!boundaryMatch) {
|
|
285
|
+
sendError(res, 400, types_1.ErrorCode.INVALID_REQUEST, 'Missing boundary in Content-Type');
|
|
286
|
+
return;
|
|
287
|
+
}
|
|
288
|
+
const boundary = boundaryMatch[1];
|
|
289
|
+
// Parse multipart data
|
|
290
|
+
const { fields, files } = await parseMultipart(req, boundary);
|
|
291
|
+
if (files.length === 0) {
|
|
292
|
+
sendError(res, 400, types_1.ErrorCode.INVALID_REQUEST, 'No files provided');
|
|
293
|
+
return;
|
|
294
|
+
}
|
|
295
|
+
// Get field configuration if object and field are specified
|
|
296
|
+
let fieldConfig;
|
|
297
|
+
if (fields.object && fields.field) {
|
|
298
|
+
const objectConfig = app.getObject(fields.object);
|
|
299
|
+
if (objectConfig && objectConfig.fields) {
|
|
300
|
+
fieldConfig = objectConfig.fields[fields.field];
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
// Extract user ID from authorization header
|
|
304
|
+
const userId = extractUserId(req.headers.authorization);
|
|
305
|
+
// Upload all files
|
|
306
|
+
const uploadedFiles = [];
|
|
307
|
+
for (const file of files) {
|
|
308
|
+
// Validate each file
|
|
309
|
+
const validation = validateFile(file, fieldConfig, fields.object, fields.field);
|
|
310
|
+
if (!validation.valid) {
|
|
311
|
+
sendError(res, 400, validation.error.code, validation.error.message, validation.error.details);
|
|
312
|
+
return;
|
|
313
|
+
}
|
|
314
|
+
// Save file
|
|
315
|
+
const attachmentData = await storage.save(file.buffer, file.filename, file.mimeType, {
|
|
316
|
+
folder: fields.folder,
|
|
317
|
+
object: fields.object,
|
|
318
|
+
field: fields.field,
|
|
319
|
+
userId
|
|
320
|
+
});
|
|
321
|
+
uploadedFiles.push(attachmentData);
|
|
322
|
+
}
|
|
323
|
+
sendSuccess(res, uploadedFiles);
|
|
324
|
+
}
|
|
325
|
+
catch (error) {
|
|
326
|
+
console.error('Batch file upload error:', error);
|
|
327
|
+
sendError(res, 500, types_1.ErrorCode.INTERNAL_ERROR, 'Batch file upload failed');
|
|
328
|
+
}
|
|
329
|
+
};
|
|
330
|
+
}
|
|
331
|
+
/**
|
|
332
|
+
* Create file download handler
|
|
333
|
+
*/
|
|
334
|
+
function createFileDownloadHandler(storage) {
|
|
335
|
+
return async (req, res, fileId) => {
|
|
336
|
+
try {
|
|
337
|
+
const file = await storage.get(fileId);
|
|
338
|
+
if (!file) {
|
|
339
|
+
sendError(res, 404, types_1.ErrorCode.NOT_FOUND, 'File not found');
|
|
340
|
+
return;
|
|
341
|
+
}
|
|
342
|
+
// Set appropriate headers
|
|
343
|
+
res.setHeader('Content-Type', 'application/octet-stream');
|
|
344
|
+
res.setHeader('Content-Length', file.length);
|
|
345
|
+
res.statusCode = 200;
|
|
346
|
+
res.end(file);
|
|
347
|
+
}
|
|
348
|
+
catch (error) {
|
|
349
|
+
console.error('File download error:', error);
|
|
350
|
+
sendError(res, 500, types_1.ErrorCode.INTERNAL_ERROR, 'File download failed');
|
|
351
|
+
}
|
|
352
|
+
};
|
|
353
|
+
}
|
|
354
|
+
//# sourceMappingURL=file-handler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file-handler.js","sourceRoot":"","sources":["../src/file-handler.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -3,6 +3,8 @@ export * from './openapi';
|
|
|
3
3
|
export * from './server';
|
|
4
4
|
export * from './metadata';
|
|
5
5
|
export * from './studio';
|
|
6
|
+
export * from './storage';
|
|
7
|
+
export * from './file-handler';
|
|
6
8
|
export * from './adapters/node';
|
|
7
9
|
export * from './adapters/rest';
|
|
8
10
|
export * from './adapters/graphql';
|
package/dist/index.js
CHANGED
|
@@ -19,6 +19,8 @@ __exportStar(require("./openapi"), exports);
|
|
|
19
19
|
__exportStar(require("./server"), exports);
|
|
20
20
|
__exportStar(require("./metadata"), exports);
|
|
21
21
|
__exportStar(require("./studio"), exports);
|
|
22
|
+
__exportStar(require("./storage"), exports);
|
|
23
|
+
__exportStar(require("./file-handler"), exports);
|
|
22
24
|
// We export createNodeHandler from root for convenience,
|
|
23
25
|
// but in the future we might encourage 'import ... from @objectql/server/node'
|
|
24
26
|
__exportStar(require("./adapters/node"), exports);
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,0CAAwB;AACxB,4CAA0B;AAC1B,2CAAyB;AACzB,6CAA2B;AAC3B,2CAAyB;AACzB,0DAA0D;AAC1D,+EAA+E;AAC/E,kDAAgC;AAChC,sBAAsB;AACtB,kDAAgC;AAChC,yBAAyB;AACzB,qDAAmC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,0CAAwB;AACxB,4CAA0B;AAC1B,2CAAyB;AACzB,6CAA2B;AAC3B,2CAAyB;AACzB,4CAA0B;AAC1B,iDAA+B;AAC/B,0DAA0D;AAC1D,+EAA+E;AAC/E,kDAAgC;AAChC,sBAAsB;AACtB,kDAAgC;AAChC,yBAAyB;AACzB,qDAAmC"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { IFileStorage, AttachmentData, FileStorageOptions } from './types';
|
|
2
|
+
/**
|
|
3
|
+
* Local filesystem storage implementation for file attachments
|
|
4
|
+
*/
|
|
5
|
+
export declare class LocalFileStorage implements IFileStorage {
|
|
6
|
+
private baseDir;
|
|
7
|
+
private baseUrl;
|
|
8
|
+
constructor(options: {
|
|
9
|
+
baseDir: string;
|
|
10
|
+
baseUrl: string;
|
|
11
|
+
});
|
|
12
|
+
save(file: Buffer, filename: string, mimeType: string, options?: FileStorageOptions): Promise<AttachmentData>;
|
|
13
|
+
get(fileId: string): Promise<Buffer | null>;
|
|
14
|
+
delete(fileId: string): Promise<boolean>;
|
|
15
|
+
getPublicUrl(filePath: string): string;
|
|
16
|
+
/**
|
|
17
|
+
* Recursively search for a file by ID
|
|
18
|
+
*/
|
|
19
|
+
private findFile;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Memory storage implementation for testing
|
|
23
|
+
*/
|
|
24
|
+
export declare class MemoryFileStorage implements IFileStorage {
|
|
25
|
+
private files;
|
|
26
|
+
private baseUrl;
|
|
27
|
+
constructor(options: {
|
|
28
|
+
baseUrl: string;
|
|
29
|
+
});
|
|
30
|
+
save(file: Buffer, filename: string, mimeType: string, options?: FileStorageOptions): Promise<AttachmentData>;
|
|
31
|
+
get(fileId: string): Promise<Buffer | null>;
|
|
32
|
+
delete(fileId: string): Promise<boolean>;
|
|
33
|
+
getPublicUrl(filePath: string): string;
|
|
34
|
+
clear(): void;
|
|
35
|
+
}
|