s3kit 0.1.0 → 0.1.1

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 (54) hide show
  1. package/README.md +15 -1
  2. package/dist/adapters/express.cjs +99 -3
  3. package/dist/adapters/express.cjs.map +1 -1
  4. package/dist/adapters/express.d.cts +2 -2
  5. package/dist/adapters/express.d.ts +2 -2
  6. package/dist/adapters/express.js +99 -3
  7. package/dist/adapters/express.js.map +1 -1
  8. package/dist/adapters/fetch.cjs +99 -3
  9. package/dist/adapters/fetch.cjs.map +1 -1
  10. package/dist/adapters/fetch.d.cts +2 -2
  11. package/dist/adapters/fetch.d.ts +2 -2
  12. package/dist/adapters/fetch.js +99 -3
  13. package/dist/adapters/fetch.js.map +1 -1
  14. package/dist/adapters/next.cjs +386 -20
  15. package/dist/adapters/next.cjs.map +1 -1
  16. package/dist/adapters/next.d.cts +2 -2
  17. package/dist/adapters/next.d.ts +2 -2
  18. package/dist/adapters/next.js +387 -20
  19. package/dist/adapters/next.js.map +1 -1
  20. package/dist/client/index.cjs +15 -1
  21. package/dist/client/index.cjs.map +1 -1
  22. package/dist/client/index.d.cts +12 -2
  23. package/dist/client/index.d.ts +12 -2
  24. package/dist/client/index.js +15 -1
  25. package/dist/client/index.js.map +1 -1
  26. package/dist/core/index.cjs +300 -19
  27. package/dist/core/index.cjs.map +1 -1
  28. package/dist/core/index.d.cts +8 -3
  29. package/dist/core/index.d.ts +8 -3
  30. package/dist/core/index.js +299 -18
  31. package/dist/core/index.js.map +1 -1
  32. package/dist/http/index.cjs +99 -3
  33. package/dist/http/index.cjs.map +1 -1
  34. package/dist/http/index.d.cts +5 -2
  35. package/dist/http/index.d.ts +5 -2
  36. package/dist/http/index.js +99 -3
  37. package/dist/http/index.js.map +1 -1
  38. package/dist/index.cjs +403 -21
  39. package/dist/index.cjs.map +1 -1
  40. package/dist/index.d.cts +4 -4
  41. package/dist/index.d.ts +4 -4
  42. package/dist/index.js +403 -21
  43. package/dist/index.js.map +1 -1
  44. package/dist/{manager-BbmXpgXN.d.ts → manager-BtW1-sC0.d.ts} +11 -1
  45. package/dist/{manager-gIjo-t8h.d.cts → manager-DSsCYKEz.d.cts} +11 -1
  46. package/dist/react/index.cjs +334 -31
  47. package/dist/react/index.cjs.map +1 -1
  48. package/dist/react/index.d.cts +1 -1
  49. package/dist/react/index.d.ts +1 -1
  50. package/dist/react/index.js +334 -31
  51. package/dist/react/index.js.map +1 -1
  52. package/dist/{types-g2IYvH3O.d.cts → types-B0yU5sod.d.cts} +51 -3
  53. package/dist/{types-g2IYvH3O.d.ts → types-B0yU5sod.d.ts} +51 -3
  54. package/package.json +1 -1
@@ -34,6 +34,15 @@ var S3FileManagerAuthorizationError = class extends Error {
34
34
  this.code = code;
35
35
  }
36
36
  };
37
+ var S3FileManagerConflictError = class extends Error {
38
+ status;
39
+ code;
40
+ constructor(message, status = 409, code = "conflict") {
41
+ super(message);
42
+ this.status = status;
43
+ this.code = code;
44
+ }
45
+ };
37
46
 
38
47
  // src/http/handler.ts
39
48
  var S3FileManagerHttpError = class extends Error {
@@ -72,6 +81,21 @@ function optionalString(value, key) {
72
81
  if (typeof value === "string") return value;
73
82
  throw new S3FileManagerHttpError(400, "invalid_body", `Expected '${key}' to be a string`);
74
83
  }
84
+ function optionalStringOrNull(value, key) {
85
+ if (value === void 0) return void 0;
86
+ if (value === null) return null;
87
+ if (typeof value === "string") return value;
88
+ throw new S3FileManagerHttpError(400, "invalid_body", `Expected '${key}' to be a string`);
89
+ }
90
+ function optionalDateStringOrNull(value, key) {
91
+ const raw = optionalStringOrNull(value, key);
92
+ if (raw === void 0 || raw === null) return raw;
93
+ const parsed = new Date(raw);
94
+ if (!Number.isFinite(parsed.getTime())) {
95
+ throw new S3FileManagerHttpError(400, "invalid_body", `Expected '${key}' to be a date string`);
96
+ }
97
+ return raw;
98
+ }
75
99
  function requiredString(value, key) {
76
100
  if (typeof value === "string") return value;
77
101
  throw new S3FileManagerHttpError(400, "invalid_body", `Expected '${key}' to be a string`);
@@ -154,13 +178,38 @@ function parseDeleteFolderOptions(body) {
154
178
  }
155
179
  function parseDeleteFilesOptions(body) {
156
180
  const obj = ensureObject(body);
157
- return { paths: requiredStringArray(obj.paths, "paths") };
181
+ const itemsValue = obj.items;
182
+ const items = Array.isArray(itemsValue) ? itemsValue.map((raw, idx) => {
183
+ if (!raw || typeof raw !== "object" || Array.isArray(raw)) {
184
+ throw new S3FileManagerHttpError(
185
+ 400,
186
+ "invalid_body",
187
+ `Expected 'items[${idx}]' to be an object`
188
+ );
189
+ }
190
+ const item = raw;
191
+ return {
192
+ path: requiredString(item.path, `items[${idx}].path`),
193
+ ifMatch: optionalString(item.ifMatch, `items[${idx}].ifMatch`),
194
+ ifNoneMatch: optionalString(item.ifNoneMatch, `items[${idx}].ifNoneMatch`)
195
+ };
196
+ }) : void 0;
197
+ const paths = obj.paths !== void 0 ? requiredStringArray(obj.paths, "paths") : void 0;
198
+ if (!paths && !items) {
199
+ throw new S3FileManagerHttpError(
200
+ 400,
201
+ "invalid_body",
202
+ "Expected 'paths' or 'items' to be provided"
203
+ );
204
+ }
205
+ return { ...paths ? { paths } : {}, ...items ? { items } : {} };
158
206
  }
159
207
  function parseCopyMoveOptions(body) {
160
208
  const obj = ensureObject(body);
161
209
  return {
162
210
  fromPath: requiredString(obj.fromPath, "fromPath"),
163
- toPath: requiredString(obj.toPath, "toPath")
211
+ toPath: requiredString(obj.toPath, "toPath"),
212
+ ifMatch: optionalString(obj.ifMatch, "ifMatch")
164
213
  };
165
214
  }
166
215
  function parsePrepareUploadsOptions(body) {
@@ -186,7 +235,9 @@ function parsePrepareUploadsOptions(body) {
186
235
  item.contentDisposition,
187
236
  `items[${idx}].contentDisposition`
188
237
  ),
189
- metadata: optionalStringRecord(item.metadata, `items[${idx}].metadata`)
238
+ metadata: optionalStringRecord(item.metadata, `items[${idx}].metadata`),
239
+ expiresAt: optionalDateStringOrNull(item.expiresAt, `items[${idx}].expiresAt`),
240
+ ifNoneMatch: optionalString(item.ifNoneMatch, `items[${idx}].ifNoneMatch`)
190
241
  };
191
242
  });
192
243
  return {
@@ -202,6 +253,30 @@ function parsePreviewOptions(body) {
202
253
  inline: optionalBoolean(obj.inline, "inline")
203
254
  };
204
255
  }
256
+ function parseGetFolderLockOptions(body) {
257
+ const obj = ensureObject(body);
258
+ return {
259
+ path: requiredString(obj.path, "path")
260
+ };
261
+ }
262
+ function parseGetFileAttributesOptions(body) {
263
+ const obj = ensureObject(body);
264
+ return {
265
+ path: requiredString(obj.path, "path")
266
+ };
267
+ }
268
+ function parseSetFileAttributesOptions(body) {
269
+ const obj = ensureObject(body);
270
+ return {
271
+ path: requiredString(obj.path, "path"),
272
+ contentType: optionalString(obj.contentType, "contentType"),
273
+ cacheControl: optionalString(obj.cacheControl, "cacheControl"),
274
+ contentDisposition: optionalString(obj.contentDisposition, "contentDisposition"),
275
+ metadata: optionalStringRecord(obj.metadata, "metadata"),
276
+ expiresAt: optionalDateStringOrNull(obj.expiresAt, "expiresAt"),
277
+ ifMatch: optionalString(obj.ifMatch, "ifMatch")
278
+ };
279
+ }
205
280
  function createS3FileManagerHttpHandler(options) {
206
281
  const basePath = normalizeBasePath(options.api?.basePath);
207
282
  if (!options.manager && !options.getManager) {
@@ -249,6 +324,24 @@ function createS3FileManagerHttpHandler(options) {
249
324
  const out = await manager.getPreviewUrl(parsePreviewOptions(req.body), ctx);
250
325
  return { status: 200, headers: { "content-type": "application/json" }, body: out };
251
326
  }
327
+ if (method === "POST" && path === "/folder/lock/get") {
328
+ const out = await manager.getFolderLock(parseGetFolderLockOptions(req.body), ctx);
329
+ return { status: 200, headers: { "content-type": "application/json" }, body: out };
330
+ }
331
+ if (method === "POST" && path === "/file/attributes/get") {
332
+ const out = await manager.getFileAttributes(
333
+ parseGetFileAttributesOptions(req.body),
334
+ ctx
335
+ );
336
+ return { status: 200, headers: { "content-type": "application/json" }, body: out };
337
+ }
338
+ if (method === "POST" && path === "/file/attributes/set") {
339
+ const out = await manager.setFileAttributes(
340
+ parseSetFileAttributesOptions(req.body),
341
+ ctx
342
+ );
343
+ return { status: 200, headers: { "content-type": "application/json" }, body: out };
344
+ }
252
345
  return jsonError(404, "not_found", "Route not found");
253
346
  } catch (err) {
254
347
  if (err instanceof S3FileManagerHttpError) {
@@ -257,6 +350,9 @@ function createS3FileManagerHttpHandler(options) {
257
350
  if (err instanceof S3FileManagerAuthorizationError) {
258
351
  return jsonError(err.status, err.code, err.message);
259
352
  }
353
+ if (err instanceof S3FileManagerConflictError) {
354
+ return jsonError(err.status, err.code, err.message);
355
+ }
260
356
  console.error("[S3FileManager Error]", err);
261
357
  const message = err instanceof Error ? err.message : "Unknown error";
262
358
  return jsonError(500, "internal_error", message);
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/http/index.ts","../../src/core/errors.ts","../../src/http/handler.ts"],"sourcesContent":["export * from './types'\nexport * from './handler'\n","export class S3FileManagerAuthorizationError extends Error {\n readonly status: number\n readonly code: string\n\n constructor(message: string, status: number, code: string) {\n super(message)\n this.status = status\n this.code = code\n }\n}\n","import type { S3FileManager } from '../core/manager'\nimport { S3FileManagerAuthorizationError } from '../core/errors'\nimport type { S3FileManagerAuthContext } from '../core/types'\nimport type { HttpRequest, HttpResponse, S3FileManagerApiOptions } from './types'\n\nclass S3FileManagerHttpError extends Error {\n readonly status: number\n readonly code: string\n\n constructor(status: number, code: string, message: string) {\n super(message)\n this.status = status\n this.code = code\n }\n}\n\nfunction normalizeBasePath(basePath?: string): string {\n if (!basePath) return ''\n if (basePath === '/') return ''\n return basePath.startsWith('/')\n ? basePath.replace(/\\/+$/, '')\n : `/${basePath.replace(/\\/+$/, '')}`\n}\n\nfunction jsonError(status: number, code: string, message: string): HttpResponse {\n return {\n status,\n headers: { 'content-type': 'application/json' },\n body: {\n error: {\n code,\n message,\n },\n },\n }\n}\n\nfunction ensureObject(body: unknown): Record<string, unknown> {\n if (body && typeof body === 'object' && !Array.isArray(body))\n return body as Record<string, unknown>\n throw new S3FileManagerHttpError(400, 'invalid_body', 'Expected JSON object body')\n}\n\nfunction optionalString(value: unknown, key: string): string | undefined {\n if (value === undefined) return undefined\n if (typeof value === 'string') return value\n throw new S3FileManagerHttpError(400, 'invalid_body', `Expected '${key}' to be a string`)\n}\n\nfunction requiredString(value: unknown, key: string): string {\n if (typeof value === 'string') return value\n throw new S3FileManagerHttpError(400, 'invalid_body', `Expected '${key}' to be a string`)\n}\n\nfunction optionalNumber(value: unknown, key: string): number | undefined {\n if (value === undefined) return undefined\n if (typeof value === 'number' && Number.isFinite(value)) return value\n throw new S3FileManagerHttpError(400, 'invalid_body', `Expected '${key}' to be a finite number`)\n}\n\nfunction optionalBoolean(value: unknown, key: string): boolean | undefined {\n if (value === undefined) return undefined\n if (typeof value === 'boolean') return value\n throw new S3FileManagerHttpError(400, 'invalid_body', `Expected '${key}' to be a boolean`)\n}\n\nfunction requiredStringArray(value: unknown, key: string): string[] {\n if (!Array.isArray(value)) {\n throw new S3FileManagerHttpError(\n 400,\n 'invalid_body',\n `Expected '${key}' to be an array of strings`,\n )\n }\n for (const item of value) {\n if (typeof item !== 'string') {\n throw new S3FileManagerHttpError(\n 400,\n 'invalid_body',\n `Expected '${key}' to be an array of strings`,\n )\n }\n }\n return value\n}\n\nfunction optionalStringRecord(value: unknown, key: string): Record<string, string> | undefined {\n if (value === undefined) return undefined\n if (!value || typeof value !== 'object' || Array.isArray(value)) {\n throw new S3FileManagerHttpError(\n 400,\n 'invalid_body',\n `Expected '${key}' to be an object of strings`,\n )\n }\n const out: Record<string, string> = {}\n for (const [k, v] of Object.entries(value)) {\n if (typeof v !== 'string') {\n throw new S3FileManagerHttpError(400, 'invalid_body', `Expected '${key}.${k}' to be a string`)\n }\n out[k] = v\n }\n return out\n}\n\nfunction parseListOptions(body: unknown) {\n const obj = ensureObject(body)\n return {\n path: requiredString(obj.path, 'path'),\n cursor: optionalString(obj.cursor, 'cursor'),\n limit: optionalNumber(obj.limit, 'limit'),\n }\n}\n\nfunction parseSearchOptions(body: unknown) {\n const obj = ensureObject(body)\n return {\n query: requiredString(obj.query, 'query'),\n path: optionalString(obj.path, 'path'),\n recursive: optionalBoolean(obj.recursive, 'recursive'),\n limit: optionalNumber(obj.limit, 'limit'),\n cursor: optionalString(obj.cursor, 'cursor'),\n }\n}\n\nfunction parseCreateFolderOptions(body: unknown) {\n const obj = ensureObject(body)\n return { path: requiredString(obj.path, 'path') }\n}\n\nfunction parseDeleteFolderOptions(body: unknown) {\n const obj = ensureObject(body)\n return {\n path: requiredString(obj.path, 'path'),\n recursive: optionalBoolean(obj.recursive, 'recursive'),\n }\n}\n\nfunction parseDeleteFilesOptions(body: unknown) {\n const obj = ensureObject(body)\n return { paths: requiredStringArray(obj.paths, 'paths') }\n}\n\nfunction parseCopyMoveOptions(body: unknown) {\n const obj = ensureObject(body)\n return {\n fromPath: requiredString(obj.fromPath, 'fromPath'),\n toPath: requiredString(obj.toPath, 'toPath'),\n }\n}\n\nfunction parsePrepareUploadsOptions(body: unknown) {\n const obj = ensureObject(body)\n const itemsValue = obj.items\n if (!Array.isArray(itemsValue)) {\n throw new S3FileManagerHttpError(400, 'invalid_body', \"Expected 'items' to be an array\")\n }\n\n const items = itemsValue.map((raw, idx) => {\n if (!raw || typeof raw !== 'object' || Array.isArray(raw)) {\n throw new S3FileManagerHttpError(\n 400,\n 'invalid_body',\n `Expected 'items[${idx}]' to be an object`,\n )\n }\n const item = raw as Record<string, unknown>\n return {\n path: requiredString(item.path, `items[${idx}].path`),\n contentType: optionalString(item.contentType, `items[${idx}].contentType`),\n cacheControl: optionalString(item.cacheControl, `items[${idx}].cacheControl`),\n contentDisposition: optionalString(\n item.contentDisposition,\n `items[${idx}].contentDisposition`,\n ),\n metadata: optionalStringRecord(item.metadata, `items[${idx}].metadata`),\n }\n })\n\n return {\n items,\n expiresInSeconds: optionalNumber(obj.expiresInSeconds, 'expiresInSeconds'),\n }\n}\n\nfunction parsePreviewOptions(body: unknown) {\n const obj = ensureObject(body)\n return {\n path: requiredString(obj.path, 'path'),\n expiresInSeconds: optionalNumber(obj.expiresInSeconds, 'expiresInSeconds'),\n inline: optionalBoolean(obj.inline, 'inline'),\n }\n}\n\nexport interface CreateS3FileManagerHttpHandlerOptions<FileExtra, FolderExtra> {\n manager?: S3FileManager<FileExtra, FolderExtra>\n getManager?: (\n req: HttpRequest,\n ctx: S3FileManagerAuthContext,\n ) => S3FileManager<FileExtra, FolderExtra> | Promise<S3FileManager<FileExtra, FolderExtra>>\n getContext?: (req: HttpRequest) => Promise<S3FileManagerAuthContext> | S3FileManagerAuthContext\n api?: S3FileManagerApiOptions\n}\n\nexport function createS3FileManagerHttpHandler<FileExtra = unknown, FolderExtra = unknown>(\n options: CreateS3FileManagerHttpHandlerOptions<FileExtra, FolderExtra>,\n): (req: HttpRequest) => Promise<HttpResponse> {\n const basePath = normalizeBasePath(options.api?.basePath)\n\n if (!options.manager && !options.getManager) {\n throw new Error('createS3FileManagerHttpHandler requires either manager or getManager')\n }\n\n return async (req: HttpRequest): Promise<HttpResponse> => {\n try {\n const ctx = (await options.getContext?.(req)) ?? {}\n const manager = options.getManager ? await options.getManager(req, ctx) : options.manager!\n const method = req.method.toUpperCase()\n const path = req.path.startsWith(basePath) ? req.path.slice(basePath.length) || '/' : req.path\n\n if (method === 'POST' && path === '/list') {\n const out = await manager.list(parseListOptions(req.body) as any, ctx)\n return { status: 200, headers: { 'content-type': 'application/json' }, body: out as any }\n }\n\n if (method === 'POST' && path === '/search') {\n const out = await manager.search(parseSearchOptions(req.body) as any, ctx)\n return { status: 200, headers: { 'content-type': 'application/json' }, body: out as any }\n }\n\n if (method === 'POST' && path === '/folder/create') {\n await manager.createFolder(parseCreateFolderOptions(req.body) as any, ctx)\n return { status: 204 }\n }\n\n if (method === 'POST' && path === '/folder/delete') {\n await manager.deleteFolder(parseDeleteFolderOptions(req.body) as any, ctx)\n return { status: 204 }\n }\n\n if (method === 'POST' && path === '/files/delete') {\n await manager.deleteFiles(parseDeleteFilesOptions(req.body) as any, ctx)\n return { status: 204 }\n }\n\n if (method === 'POST' && path === '/files/copy') {\n await manager.copy(parseCopyMoveOptions(req.body) as any, ctx)\n return { status: 204 }\n }\n\n if (method === 'POST' && path === '/files/move') {\n await manager.move(parseCopyMoveOptions(req.body) as any, ctx)\n return { status: 204 }\n }\n\n if (method === 'POST' && path === '/upload/prepare') {\n const out = await manager.prepareUploads(parsePrepareUploadsOptions(req.body) as any, ctx)\n return { status: 200, headers: { 'content-type': 'application/json' }, body: out as any }\n }\n\n if (method === 'POST' && path === '/preview') {\n const out = await manager.getPreviewUrl(parsePreviewOptions(req.body) as any, ctx)\n return { status: 200, headers: { 'content-type': 'application/json' }, body: out as any }\n }\n\n return jsonError(404, 'not_found', 'Route not found')\n } catch (err) {\n if (err instanceof S3FileManagerHttpError) {\n return jsonError(err.status, err.code, err.message)\n }\n if (err instanceof S3FileManagerAuthorizationError) {\n return jsonError(err.status, err.code, err.message)\n }\n\n console.error('[S3FileManager Error]', err)\n const message = err instanceof Error ? err.message : 'Unknown error'\n return jsonError(500, 'internal_error', message)\n }\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAO,IAAM,kCAAN,cAA8C,MAAM;AAAA,EAChD;AAAA,EACA;AAAA,EAET,YAAY,SAAiB,QAAgB,MAAc;AACzD,UAAM,OAAO;AACb,SAAK,SAAS;AACd,SAAK,OAAO;AAAA,EACd;AACF;;;ACJA,IAAM,yBAAN,cAAqC,MAAM;AAAA,EAChC;AAAA,EACA;AAAA,EAET,YAAY,QAAgB,MAAc,SAAiB;AACzD,UAAM,OAAO;AACb,SAAK,SAAS;AACd,SAAK,OAAO;AAAA,EACd;AACF;AAEA,SAAS,kBAAkB,UAA2B;AACpD,MAAI,CAAC,SAAU,QAAO;AACtB,MAAI,aAAa,IAAK,QAAO;AAC7B,SAAO,SAAS,WAAW,GAAG,IAC1B,SAAS,QAAQ,QAAQ,EAAE,IAC3B,IAAI,SAAS,QAAQ,QAAQ,EAAE,CAAC;AACtC;AAEA,SAAS,UAAU,QAAgB,MAAc,SAA+B;AAC9E,SAAO;AAAA,IACL;AAAA,IACA,SAAS,EAAE,gBAAgB,mBAAmB;AAAA,IAC9C,MAAM;AAAA,MACJ,OAAO;AAAA,QACL;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;AAEA,SAAS,aAAa,MAAwC;AAC5D,MAAI,QAAQ,OAAO,SAAS,YAAY,CAAC,MAAM,QAAQ,IAAI;AACzD,WAAO;AACT,QAAM,IAAI,uBAAuB,KAAK,gBAAgB,2BAA2B;AACnF;AAEA,SAAS,eAAe,OAAgB,KAAiC;AACvE,MAAI,UAAU,OAAW,QAAO;AAChC,MAAI,OAAO,UAAU,SAAU,QAAO;AACtC,QAAM,IAAI,uBAAuB,KAAK,gBAAgB,aAAa,GAAG,kBAAkB;AAC1F;AAEA,SAAS,eAAe,OAAgB,KAAqB;AAC3D,MAAI,OAAO,UAAU,SAAU,QAAO;AACtC,QAAM,IAAI,uBAAuB,KAAK,gBAAgB,aAAa,GAAG,kBAAkB;AAC1F;AAEA,SAAS,eAAe,OAAgB,KAAiC;AACvE,MAAI,UAAU,OAAW,QAAO;AAChC,MAAI,OAAO,UAAU,YAAY,OAAO,SAAS,KAAK,EAAG,QAAO;AAChE,QAAM,IAAI,uBAAuB,KAAK,gBAAgB,aAAa,GAAG,yBAAyB;AACjG;AAEA,SAAS,gBAAgB,OAAgB,KAAkC;AACzE,MAAI,UAAU,OAAW,QAAO;AAChC,MAAI,OAAO,UAAU,UAAW,QAAO;AACvC,QAAM,IAAI,uBAAuB,KAAK,gBAAgB,aAAa,GAAG,mBAAmB;AAC3F;AAEA,SAAS,oBAAoB,OAAgB,KAAuB;AAClE,MAAI,CAAC,MAAM,QAAQ,KAAK,GAAG;AACzB,UAAM,IAAI;AAAA,MACR;AAAA,MACA;AAAA,MACA,aAAa,GAAG;AAAA,IAClB;AAAA,EACF;AACA,aAAW,QAAQ,OAAO;AACxB,QAAI,OAAO,SAAS,UAAU;AAC5B,YAAM,IAAI;AAAA,QACR;AAAA,QACA;AAAA,QACA,aAAa,GAAG;AAAA,MAClB;AAAA,IACF;AAAA,EACF;AACA,SAAO;AACT;AAEA,SAAS,qBAAqB,OAAgB,KAAiD;AAC7F,MAAI,UAAU,OAAW,QAAO;AAChC,MAAI,CAAC,SAAS,OAAO,UAAU,YAAY,MAAM,QAAQ,KAAK,GAAG;AAC/D,UAAM,IAAI;AAAA,MACR;AAAA,MACA;AAAA,MACA,aAAa,GAAG;AAAA,IAClB;AAAA,EACF;AACA,QAAM,MAA8B,CAAC;AACrC,aAAW,CAAC,GAAG,CAAC,KAAK,OAAO,QAAQ,KAAK,GAAG;AAC1C,QAAI,OAAO,MAAM,UAAU;AACzB,YAAM,IAAI,uBAAuB,KAAK,gBAAgB,aAAa,GAAG,IAAI,CAAC,kBAAkB;AAAA,IAC/F;AACA,QAAI,CAAC,IAAI;AAAA,EACX;AACA,SAAO;AACT;AAEA,SAAS,iBAAiB,MAAe;AACvC,QAAM,MAAM,aAAa,IAAI;AAC7B,SAAO;AAAA,IACL,MAAM,eAAe,IAAI,MAAM,MAAM;AAAA,IACrC,QAAQ,eAAe,IAAI,QAAQ,QAAQ;AAAA,IAC3C,OAAO,eAAe,IAAI,OAAO,OAAO;AAAA,EAC1C;AACF;AAEA,SAAS,mBAAmB,MAAe;AACzC,QAAM,MAAM,aAAa,IAAI;AAC7B,SAAO;AAAA,IACL,OAAO,eAAe,IAAI,OAAO,OAAO;AAAA,IACxC,MAAM,eAAe,IAAI,MAAM,MAAM;AAAA,IACrC,WAAW,gBAAgB,IAAI,WAAW,WAAW;AAAA,IACrD,OAAO,eAAe,IAAI,OAAO,OAAO;AAAA,IACxC,QAAQ,eAAe,IAAI,QAAQ,QAAQ;AAAA,EAC7C;AACF;AAEA,SAAS,yBAAyB,MAAe;AAC/C,QAAM,MAAM,aAAa,IAAI;AAC7B,SAAO,EAAE,MAAM,eAAe,IAAI,MAAM,MAAM,EAAE;AAClD;AAEA,SAAS,yBAAyB,MAAe;AAC/C,QAAM,MAAM,aAAa,IAAI;AAC7B,SAAO;AAAA,IACL,MAAM,eAAe,IAAI,MAAM,MAAM;AAAA,IACrC,WAAW,gBAAgB,IAAI,WAAW,WAAW;AAAA,EACvD;AACF;AAEA,SAAS,wBAAwB,MAAe;AAC9C,QAAM,MAAM,aAAa,IAAI;AAC7B,SAAO,EAAE,OAAO,oBAAoB,IAAI,OAAO,OAAO,EAAE;AAC1D;AAEA,SAAS,qBAAqB,MAAe;AAC3C,QAAM,MAAM,aAAa,IAAI;AAC7B,SAAO;AAAA,IACL,UAAU,eAAe,IAAI,UAAU,UAAU;AAAA,IACjD,QAAQ,eAAe,IAAI,QAAQ,QAAQ;AAAA,EAC7C;AACF;AAEA,SAAS,2BAA2B,MAAe;AACjD,QAAM,MAAM,aAAa,IAAI;AAC7B,QAAM,aAAa,IAAI;AACvB,MAAI,CAAC,MAAM,QAAQ,UAAU,GAAG;AAC9B,UAAM,IAAI,uBAAuB,KAAK,gBAAgB,iCAAiC;AAAA,EACzF;AAEA,QAAM,QAAQ,WAAW,IAAI,CAAC,KAAK,QAAQ;AACzC,QAAI,CAAC,OAAO,OAAO,QAAQ,YAAY,MAAM,QAAQ,GAAG,GAAG;AACzD,YAAM,IAAI;AAAA,QACR;AAAA,QACA;AAAA,QACA,mBAAmB,GAAG;AAAA,MACxB;AAAA,IACF;AACA,UAAM,OAAO;AACb,WAAO;AAAA,MACL,MAAM,eAAe,KAAK,MAAM,SAAS,GAAG,QAAQ;AAAA,MACpD,aAAa,eAAe,KAAK,aAAa,SAAS,GAAG,eAAe;AAAA,MACzE,cAAc,eAAe,KAAK,cAAc,SAAS,GAAG,gBAAgB;AAAA,MAC5E,oBAAoB;AAAA,QAClB,KAAK;AAAA,QACL,SAAS,GAAG;AAAA,MACd;AAAA,MACA,UAAU,qBAAqB,KAAK,UAAU,SAAS,GAAG,YAAY;AAAA,IACxE;AAAA,EACF,CAAC;AAED,SAAO;AAAA,IACL;AAAA,IACA,kBAAkB,eAAe,IAAI,kBAAkB,kBAAkB;AAAA,EAC3E;AACF;AAEA,SAAS,oBAAoB,MAAe;AAC1C,QAAM,MAAM,aAAa,IAAI;AAC7B,SAAO;AAAA,IACL,MAAM,eAAe,IAAI,MAAM,MAAM;AAAA,IACrC,kBAAkB,eAAe,IAAI,kBAAkB,kBAAkB;AAAA,IACzE,QAAQ,gBAAgB,IAAI,QAAQ,QAAQ;AAAA,EAC9C;AACF;AAYO,SAAS,+BACd,SAC6C;AAC7C,QAAM,WAAW,kBAAkB,QAAQ,KAAK,QAAQ;AAExD,MAAI,CAAC,QAAQ,WAAW,CAAC,QAAQ,YAAY;AAC3C,UAAM,IAAI,MAAM,sEAAsE;AAAA,EACxF;AAEA,SAAO,OAAO,QAA4C;AACxD,QAAI;AACF,YAAM,MAAO,MAAM,QAAQ,aAAa,GAAG,KAAM,CAAC;AAClD,YAAM,UAAU,QAAQ,aAAa,MAAM,QAAQ,WAAW,KAAK,GAAG,IAAI,QAAQ;AAClF,YAAM,SAAS,IAAI,OAAO,YAAY;AACtC,YAAM,OAAO,IAAI,KAAK,WAAW,QAAQ,IAAI,IAAI,KAAK,MAAM,SAAS,MAAM,KAAK,MAAM,IAAI;AAE1F,UAAI,WAAW,UAAU,SAAS,SAAS;AACzC,cAAM,MAAM,MAAM,QAAQ,KAAK,iBAAiB,IAAI,IAAI,GAAU,GAAG;AACrE,eAAO,EAAE,QAAQ,KAAK,SAAS,EAAE,gBAAgB,mBAAmB,GAAG,MAAM,IAAW;AAAA,MAC1F;AAEA,UAAI,WAAW,UAAU,SAAS,WAAW;AAC3C,cAAM,MAAM,MAAM,QAAQ,OAAO,mBAAmB,IAAI,IAAI,GAAU,GAAG;AACzE,eAAO,EAAE,QAAQ,KAAK,SAAS,EAAE,gBAAgB,mBAAmB,GAAG,MAAM,IAAW;AAAA,MAC1F;AAEA,UAAI,WAAW,UAAU,SAAS,kBAAkB;AAClD,cAAM,QAAQ,aAAa,yBAAyB,IAAI,IAAI,GAAU,GAAG;AACzE,eAAO,EAAE,QAAQ,IAAI;AAAA,MACvB;AAEA,UAAI,WAAW,UAAU,SAAS,kBAAkB;AAClD,cAAM,QAAQ,aAAa,yBAAyB,IAAI,IAAI,GAAU,GAAG;AACzE,eAAO,EAAE,QAAQ,IAAI;AAAA,MACvB;AAEA,UAAI,WAAW,UAAU,SAAS,iBAAiB;AACjD,cAAM,QAAQ,YAAY,wBAAwB,IAAI,IAAI,GAAU,GAAG;AACvE,eAAO,EAAE,QAAQ,IAAI;AAAA,MACvB;AAEA,UAAI,WAAW,UAAU,SAAS,eAAe;AAC/C,cAAM,QAAQ,KAAK,qBAAqB,IAAI,IAAI,GAAU,GAAG;AAC7D,eAAO,EAAE,QAAQ,IAAI;AAAA,MACvB;AAEA,UAAI,WAAW,UAAU,SAAS,eAAe;AAC/C,cAAM,QAAQ,KAAK,qBAAqB,IAAI,IAAI,GAAU,GAAG;AAC7D,eAAO,EAAE,QAAQ,IAAI;AAAA,MACvB;AAEA,UAAI,WAAW,UAAU,SAAS,mBAAmB;AACnD,cAAM,MAAM,MAAM,QAAQ,eAAe,2BAA2B,IAAI,IAAI,GAAU,GAAG;AACzF,eAAO,EAAE,QAAQ,KAAK,SAAS,EAAE,gBAAgB,mBAAmB,GAAG,MAAM,IAAW;AAAA,MAC1F;AAEA,UAAI,WAAW,UAAU,SAAS,YAAY;AAC5C,cAAM,MAAM,MAAM,QAAQ,cAAc,oBAAoB,IAAI,IAAI,GAAU,GAAG;AACjF,eAAO,EAAE,QAAQ,KAAK,SAAS,EAAE,gBAAgB,mBAAmB,GAAG,MAAM,IAAW;AAAA,MAC1F;AAEA,aAAO,UAAU,KAAK,aAAa,iBAAiB;AAAA,IACtD,SAAS,KAAK;AACZ,UAAI,eAAe,wBAAwB;AACzC,eAAO,UAAU,IAAI,QAAQ,IAAI,MAAM,IAAI,OAAO;AAAA,MACpD;AACA,UAAI,eAAe,iCAAiC;AAClD,eAAO,UAAU,IAAI,QAAQ,IAAI,MAAM,IAAI,OAAO;AAAA,MACpD;AAEA,cAAQ,MAAM,yBAAyB,GAAG;AAC1C,YAAM,UAAU,eAAe,QAAQ,IAAI,UAAU;AACrD,aAAO,UAAU,KAAK,kBAAkB,OAAO;AAAA,IACjD;AAAA,EACF;AACF;","names":[]}
1
+ {"version":3,"sources":["../../src/http/index.ts","../../src/core/errors.ts","../../src/http/handler.ts"],"sourcesContent":["export * from './types'\nexport * from './handler'\n","export class S3FileManagerAuthorizationError extends Error {\n readonly status: number\n readonly code: string\n\n constructor(message: string, status: number, code: string) {\n super(message)\n this.status = status\n this.code = code\n }\n}\n\nexport class S3FileManagerConflictError extends Error {\n readonly status: number\n readonly code: string\n\n constructor(message: string, status = 409, code = 'conflict') {\n super(message)\n this.status = status\n this.code = code\n }\n}\n","import type { S3FileManager } from '../core/manager'\nimport { S3FileManagerAuthorizationError, S3FileManagerConflictError } from '../core/errors'\nimport type { S3FileManagerAuthContext } from '../core/types'\nimport type { HttpRequest, HttpResponse, S3FileManagerApiOptions } from './types'\n\nclass S3FileManagerHttpError extends Error {\n readonly status: number\n readonly code: string\n\n constructor(status: number, code: string, message: string) {\n super(message)\n this.status = status\n this.code = code\n }\n}\n\nfunction normalizeBasePath(basePath?: string): string {\n if (!basePath) return ''\n if (basePath === '/') return ''\n return basePath.startsWith('/')\n ? basePath.replace(/\\/+$/, '')\n : `/${basePath.replace(/\\/+$/, '')}`\n}\n\nfunction jsonError(status: number, code: string, message: string): HttpResponse {\n return {\n status,\n headers: { 'content-type': 'application/json' },\n body: {\n error: {\n code,\n message,\n },\n },\n }\n}\n\nfunction ensureObject(body: unknown): Record<string, unknown> {\n if (body && typeof body === 'object' && !Array.isArray(body))\n return body as Record<string, unknown>\n throw new S3FileManagerHttpError(400, 'invalid_body', 'Expected JSON object body')\n}\n\nfunction optionalString(value: unknown, key: string): string | undefined {\n if (value === undefined) return undefined\n if (typeof value === 'string') return value\n throw new S3FileManagerHttpError(400, 'invalid_body', `Expected '${key}' to be a string`)\n}\n\nfunction optionalStringOrNull(value: unknown, key: string): string | null | undefined {\n if (value === undefined) return undefined\n if (value === null) return null\n if (typeof value === 'string') return value\n throw new S3FileManagerHttpError(400, 'invalid_body', `Expected '${key}' to be a string`)\n}\n\nfunction optionalDateStringOrNull(value: unknown, key: string): string | null | undefined {\n const raw = optionalStringOrNull(value, key)\n if (raw === undefined || raw === null) return raw\n const parsed = new Date(raw)\n if (!Number.isFinite(parsed.getTime())) {\n throw new S3FileManagerHttpError(400, 'invalid_body', `Expected '${key}' to be a date string`)\n }\n return raw\n}\n\nfunction requiredString(value: unknown, key: string): string {\n if (typeof value === 'string') return value\n throw new S3FileManagerHttpError(400, 'invalid_body', `Expected '${key}' to be a string`)\n}\n\nfunction optionalNumber(value: unknown, key: string): number | undefined {\n if (value === undefined) return undefined\n if (typeof value === 'number' && Number.isFinite(value)) return value\n throw new S3FileManagerHttpError(400, 'invalid_body', `Expected '${key}' to be a finite number`)\n}\n\nfunction optionalBoolean(value: unknown, key: string): boolean | undefined {\n if (value === undefined) return undefined\n if (typeof value === 'boolean') return value\n throw new S3FileManagerHttpError(400, 'invalid_body', `Expected '${key}' to be a boolean`)\n}\n\nfunction requiredStringArray(value: unknown, key: string): string[] {\n if (!Array.isArray(value)) {\n throw new S3FileManagerHttpError(\n 400,\n 'invalid_body',\n `Expected '${key}' to be an array of strings`,\n )\n }\n for (const item of value) {\n if (typeof item !== 'string') {\n throw new S3FileManagerHttpError(\n 400,\n 'invalid_body',\n `Expected '${key}' to be an array of strings`,\n )\n }\n }\n return value\n}\n\nfunction optionalStringRecord(value: unknown, key: string): Record<string, string> | undefined {\n if (value === undefined) return undefined\n if (!value || typeof value !== 'object' || Array.isArray(value)) {\n throw new S3FileManagerHttpError(\n 400,\n 'invalid_body',\n `Expected '${key}' to be an object of strings`,\n )\n }\n const out: Record<string, string> = {}\n for (const [k, v] of Object.entries(value)) {\n if (typeof v !== 'string') {\n throw new S3FileManagerHttpError(400, 'invalid_body', `Expected '${key}.${k}' to be a string`)\n }\n out[k] = v\n }\n return out\n}\n\nfunction parseListOptions(body: unknown) {\n const obj = ensureObject(body)\n return {\n path: requiredString(obj.path, 'path'),\n cursor: optionalString(obj.cursor, 'cursor'),\n limit: optionalNumber(obj.limit, 'limit'),\n }\n}\n\nfunction parseSearchOptions(body: unknown) {\n const obj = ensureObject(body)\n return {\n query: requiredString(obj.query, 'query'),\n path: optionalString(obj.path, 'path'),\n recursive: optionalBoolean(obj.recursive, 'recursive'),\n limit: optionalNumber(obj.limit, 'limit'),\n cursor: optionalString(obj.cursor, 'cursor'),\n }\n}\n\nfunction parseCreateFolderOptions(body: unknown) {\n const obj = ensureObject(body)\n return { path: requiredString(obj.path, 'path') }\n}\n\nfunction parseDeleteFolderOptions(body: unknown) {\n const obj = ensureObject(body)\n return {\n path: requiredString(obj.path, 'path'),\n recursive: optionalBoolean(obj.recursive, 'recursive'),\n }\n}\n\nfunction parseDeleteFilesOptions(body: unknown) {\n const obj = ensureObject(body)\n const itemsValue = obj.items\n const items = Array.isArray(itemsValue)\n ? itemsValue.map((raw, idx) => {\n if (!raw || typeof raw !== 'object' || Array.isArray(raw)) {\n throw new S3FileManagerHttpError(\n 400,\n 'invalid_body',\n `Expected 'items[${idx}]' to be an object`,\n )\n }\n const item = raw as Record<string, unknown>\n return {\n path: requiredString(item.path, `items[${idx}].path`),\n ifMatch: optionalString(item.ifMatch, `items[${idx}].ifMatch`),\n ifNoneMatch: optionalString(item.ifNoneMatch, `items[${idx}].ifNoneMatch`),\n }\n })\n : undefined\n\n const paths = obj.paths !== undefined ? requiredStringArray(obj.paths, 'paths') : undefined\n\n if (!paths && !items) {\n throw new S3FileManagerHttpError(\n 400,\n 'invalid_body',\n \"Expected 'paths' or 'items' to be provided\",\n )\n }\n\n return { ...(paths ? { paths } : {}), ...(items ? { items } : {}) }\n}\n\nfunction parseCopyMoveOptions(body: unknown) {\n const obj = ensureObject(body)\n return {\n fromPath: requiredString(obj.fromPath, 'fromPath'),\n toPath: requiredString(obj.toPath, 'toPath'),\n ifMatch: optionalString(obj.ifMatch, 'ifMatch'),\n }\n}\n\nfunction parsePrepareUploadsOptions(body: unknown) {\n const obj = ensureObject(body)\n const itemsValue = obj.items\n if (!Array.isArray(itemsValue)) {\n throw new S3FileManagerHttpError(400, 'invalid_body', \"Expected 'items' to be an array\")\n }\n\n const items = itemsValue.map((raw, idx) => {\n if (!raw || typeof raw !== 'object' || Array.isArray(raw)) {\n throw new S3FileManagerHttpError(\n 400,\n 'invalid_body',\n `Expected 'items[${idx}]' to be an object`,\n )\n }\n const item = raw as Record<string, unknown>\n return {\n path: requiredString(item.path, `items[${idx}].path`),\n contentType: optionalString(item.contentType, `items[${idx}].contentType`),\n cacheControl: optionalString(item.cacheControl, `items[${idx}].cacheControl`),\n contentDisposition: optionalString(\n item.contentDisposition,\n `items[${idx}].contentDisposition`,\n ),\n metadata: optionalStringRecord(item.metadata, `items[${idx}].metadata`),\n expiresAt: optionalDateStringOrNull(item.expiresAt, `items[${idx}].expiresAt`),\n ifNoneMatch: optionalString(item.ifNoneMatch, `items[${idx}].ifNoneMatch`),\n }\n })\n\n return {\n items,\n expiresInSeconds: optionalNumber(obj.expiresInSeconds, 'expiresInSeconds'),\n }\n}\n\nfunction parsePreviewOptions(body: unknown) {\n const obj = ensureObject(body)\n return {\n path: requiredString(obj.path, 'path'),\n expiresInSeconds: optionalNumber(obj.expiresInSeconds, 'expiresInSeconds'),\n inline: optionalBoolean(obj.inline, 'inline'),\n }\n}\n\nfunction parseGetFolderLockOptions(body: unknown) {\n const obj = ensureObject(body)\n return {\n path: requiredString(obj.path, 'path'),\n }\n}\n\nfunction parseGetFileAttributesOptions(body: unknown) {\n const obj = ensureObject(body)\n return {\n path: requiredString(obj.path, 'path'),\n }\n}\n\nfunction parseSetFileAttributesOptions(body: unknown) {\n const obj = ensureObject(body)\n return {\n path: requiredString(obj.path, 'path'),\n contentType: optionalString(obj.contentType, 'contentType'),\n cacheControl: optionalString(obj.cacheControl, 'cacheControl'),\n contentDisposition: optionalString(obj.contentDisposition, 'contentDisposition'),\n metadata: optionalStringRecord(obj.metadata, 'metadata'),\n expiresAt: optionalDateStringOrNull(obj.expiresAt, 'expiresAt'),\n ifMatch: optionalString(obj.ifMatch, 'ifMatch'),\n }\n}\n\nexport interface CreateS3FileManagerHttpHandlerOptions<FileExtra, FolderExtra> {\n manager?: S3FileManager<FileExtra, FolderExtra>\n getManager?: (\n req: HttpRequest,\n ctx: S3FileManagerAuthContext,\n ) => S3FileManager<FileExtra, FolderExtra> | Promise<S3FileManager<FileExtra, FolderExtra>>\n getContext?: (req: HttpRequest) => Promise<S3FileManagerAuthContext> | S3FileManagerAuthContext\n api?: S3FileManagerApiOptions\n}\n\nexport function createS3FileManagerHttpHandler<FileExtra = unknown, FolderExtra = unknown>(\n options: CreateS3FileManagerHttpHandlerOptions<FileExtra, FolderExtra>,\n): (req: HttpRequest) => Promise<HttpResponse> {\n const basePath = normalizeBasePath(options.api?.basePath)\n\n if (!options.manager && !options.getManager) {\n throw new Error('createS3FileManagerHttpHandler requires either manager or getManager')\n }\n\n return async (req: HttpRequest): Promise<HttpResponse> => {\n try {\n const ctx = (await options.getContext?.(req)) ?? {}\n const manager = options.getManager ? await options.getManager(req, ctx) : options.manager!\n const method = req.method.toUpperCase()\n const path = req.path.startsWith(basePath) ? req.path.slice(basePath.length) || '/' : req.path\n\n if (method === 'POST' && path === '/list') {\n const out = await manager.list(parseListOptions(req.body) as any, ctx)\n return { status: 200, headers: { 'content-type': 'application/json' }, body: out as any }\n }\n\n if (method === 'POST' && path === '/search') {\n const out = await manager.search(parseSearchOptions(req.body) as any, ctx)\n return { status: 200, headers: { 'content-type': 'application/json' }, body: out as any }\n }\n\n if (method === 'POST' && path === '/folder/create') {\n await manager.createFolder(parseCreateFolderOptions(req.body) as any, ctx)\n return { status: 204 }\n }\n\n if (method === 'POST' && path === '/folder/delete') {\n await manager.deleteFolder(parseDeleteFolderOptions(req.body) as any, ctx)\n return { status: 204 }\n }\n\n if (method === 'POST' && path === '/files/delete') {\n await manager.deleteFiles(parseDeleteFilesOptions(req.body) as any, ctx)\n return { status: 204 }\n }\n\n if (method === 'POST' && path === '/files/copy') {\n await manager.copy(parseCopyMoveOptions(req.body) as any, ctx)\n return { status: 204 }\n }\n\n if (method === 'POST' && path === '/files/move') {\n await manager.move(parseCopyMoveOptions(req.body) as any, ctx)\n return { status: 204 }\n }\n\n if (method === 'POST' && path === '/upload/prepare') {\n const out = await manager.prepareUploads(parsePrepareUploadsOptions(req.body) as any, ctx)\n return { status: 200, headers: { 'content-type': 'application/json' }, body: out as any }\n }\n\n if (method === 'POST' && path === '/preview') {\n const out = await manager.getPreviewUrl(parsePreviewOptions(req.body) as any, ctx)\n return { status: 200, headers: { 'content-type': 'application/json' }, body: out as any }\n }\n\n if (method === 'POST' && path === '/folder/lock/get') {\n const out = await manager.getFolderLock(parseGetFolderLockOptions(req.body) as any, ctx)\n return { status: 200, headers: { 'content-type': 'application/json' }, body: out as any }\n }\n\n if (method === 'POST' && path === '/file/attributes/get') {\n const out = await manager.getFileAttributes(\n parseGetFileAttributesOptions(req.body) as any,\n ctx,\n )\n return { status: 200, headers: { 'content-type': 'application/json' }, body: out as any }\n }\n\n if (method === 'POST' && path === '/file/attributes/set') {\n const out = await manager.setFileAttributes(\n parseSetFileAttributesOptions(req.body) as any,\n ctx,\n )\n return { status: 200, headers: { 'content-type': 'application/json' }, body: out as any }\n }\n\n return jsonError(404, 'not_found', 'Route not found')\n } catch (err) {\n if (err instanceof S3FileManagerHttpError) {\n return jsonError(err.status, err.code, err.message)\n }\n if (err instanceof S3FileManagerAuthorizationError) {\n return jsonError(err.status, err.code, err.message)\n }\n if (err instanceof S3FileManagerConflictError) {\n return jsonError(err.status, err.code, err.message)\n }\n\n console.error('[S3FileManager Error]', err)\n const message = err instanceof Error ? err.message : 'Unknown error'\n return jsonError(500, 'internal_error', message)\n }\n }\n}\n"],"mappings":"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","names":[]}
@@ -1,5 +1,5 @@
1
- import { j as S3ListOptions, l as S3SearchOptions, n as S3CreateFolderOptions, o as S3DeleteFolderOptions, p as S3DeleteFilesOptions, q as S3CopyOptions, r as S3MoveOptions, u as S3PrepareUploadsOptions, v as S3GetPreviewUrlOptions, b as S3FileManagerAuthContext } from '../types-g2IYvH3O.cjs';
2
- import { S as S3FileManager } from '../manager-gIjo-t8h.cjs';
1
+ import { j as S3ListOptions, l as S3SearchOptions, n as S3CreateFolderOptions, o as S3DeleteFolderOptions, p as S3DeleteFilesOptions, q as S3CopyOptions, r as S3MoveOptions, u as S3PrepareUploadsOptions, v as S3GetPreviewUrlOptions, E as S3GetFolderLockOptions, x as S3GetFileAttributesOptions, y as S3SetFileAttributesOptions, b as S3FileManagerAuthContext } from '../types-B0yU5sod.cjs';
2
+ import { S as S3FileManager } from '../manager-DSsCYKEz.cjs';
3
3
  import '@aws-sdk/client-s3';
4
4
 
5
5
  type JsonValue = string | number | boolean | null | {
@@ -33,6 +33,9 @@ interface S3FileManagerApiRequestMap {
33
33
  'POST /files/move': S3MoveOptions;
34
34
  'POST /upload/prepare': S3PrepareUploadsOptions;
35
35
  'POST /preview': S3GetPreviewUrlOptions;
36
+ 'POST /folder/lock/get': S3GetFolderLockOptions;
37
+ 'POST /file/attributes/get': S3GetFileAttributesOptions;
38
+ 'POST /file/attributes/set': S3SetFileAttributesOptions;
36
39
  }
37
40
  interface S3FileManagerApiOptions {
38
41
  basePath?: string;
@@ -1,5 +1,5 @@
1
- import { j as S3ListOptions, l as S3SearchOptions, n as S3CreateFolderOptions, o as S3DeleteFolderOptions, p as S3DeleteFilesOptions, q as S3CopyOptions, r as S3MoveOptions, u as S3PrepareUploadsOptions, v as S3GetPreviewUrlOptions, b as S3FileManagerAuthContext } from '../types-g2IYvH3O.js';
2
- import { S as S3FileManager } from '../manager-BbmXpgXN.js';
1
+ import { j as S3ListOptions, l as S3SearchOptions, n as S3CreateFolderOptions, o as S3DeleteFolderOptions, p as S3DeleteFilesOptions, q as S3CopyOptions, r as S3MoveOptions, u as S3PrepareUploadsOptions, v as S3GetPreviewUrlOptions, E as S3GetFolderLockOptions, x as S3GetFileAttributesOptions, y as S3SetFileAttributesOptions, b as S3FileManagerAuthContext } from '../types-B0yU5sod.js';
2
+ import { S as S3FileManager } from '../manager-BtW1-sC0.js';
3
3
  import '@aws-sdk/client-s3';
4
4
 
5
5
  type JsonValue = string | number | boolean | null | {
@@ -33,6 +33,9 @@ interface S3FileManagerApiRequestMap {
33
33
  'POST /files/move': S3MoveOptions;
34
34
  'POST /upload/prepare': S3PrepareUploadsOptions;
35
35
  'POST /preview': S3GetPreviewUrlOptions;
36
+ 'POST /folder/lock/get': S3GetFolderLockOptions;
37
+ 'POST /file/attributes/get': S3GetFileAttributesOptions;
38
+ 'POST /file/attributes/set': S3SetFileAttributesOptions;
36
39
  }
37
40
  interface S3FileManagerApiOptions {
38
41
  basePath?: string;
@@ -8,6 +8,15 @@ var S3FileManagerAuthorizationError = class extends Error {
8
8
  this.code = code;
9
9
  }
10
10
  };
11
+ var S3FileManagerConflictError = class extends Error {
12
+ status;
13
+ code;
14
+ constructor(message, status = 409, code = "conflict") {
15
+ super(message);
16
+ this.status = status;
17
+ this.code = code;
18
+ }
19
+ };
11
20
 
12
21
  // src/http/handler.ts
13
22
  var S3FileManagerHttpError = class extends Error {
@@ -46,6 +55,21 @@ function optionalString(value, key) {
46
55
  if (typeof value === "string") return value;
47
56
  throw new S3FileManagerHttpError(400, "invalid_body", `Expected '${key}' to be a string`);
48
57
  }
58
+ function optionalStringOrNull(value, key) {
59
+ if (value === void 0) return void 0;
60
+ if (value === null) return null;
61
+ if (typeof value === "string") return value;
62
+ throw new S3FileManagerHttpError(400, "invalid_body", `Expected '${key}' to be a string`);
63
+ }
64
+ function optionalDateStringOrNull(value, key) {
65
+ const raw = optionalStringOrNull(value, key);
66
+ if (raw === void 0 || raw === null) return raw;
67
+ const parsed = new Date(raw);
68
+ if (!Number.isFinite(parsed.getTime())) {
69
+ throw new S3FileManagerHttpError(400, "invalid_body", `Expected '${key}' to be a date string`);
70
+ }
71
+ return raw;
72
+ }
49
73
  function requiredString(value, key) {
50
74
  if (typeof value === "string") return value;
51
75
  throw new S3FileManagerHttpError(400, "invalid_body", `Expected '${key}' to be a string`);
@@ -128,13 +152,38 @@ function parseDeleteFolderOptions(body) {
128
152
  }
129
153
  function parseDeleteFilesOptions(body) {
130
154
  const obj = ensureObject(body);
131
- return { paths: requiredStringArray(obj.paths, "paths") };
155
+ const itemsValue = obj.items;
156
+ const items = Array.isArray(itemsValue) ? itemsValue.map((raw, idx) => {
157
+ if (!raw || typeof raw !== "object" || Array.isArray(raw)) {
158
+ throw new S3FileManagerHttpError(
159
+ 400,
160
+ "invalid_body",
161
+ `Expected 'items[${idx}]' to be an object`
162
+ );
163
+ }
164
+ const item = raw;
165
+ return {
166
+ path: requiredString(item.path, `items[${idx}].path`),
167
+ ifMatch: optionalString(item.ifMatch, `items[${idx}].ifMatch`),
168
+ ifNoneMatch: optionalString(item.ifNoneMatch, `items[${idx}].ifNoneMatch`)
169
+ };
170
+ }) : void 0;
171
+ const paths = obj.paths !== void 0 ? requiredStringArray(obj.paths, "paths") : void 0;
172
+ if (!paths && !items) {
173
+ throw new S3FileManagerHttpError(
174
+ 400,
175
+ "invalid_body",
176
+ "Expected 'paths' or 'items' to be provided"
177
+ );
178
+ }
179
+ return { ...paths ? { paths } : {}, ...items ? { items } : {} };
132
180
  }
133
181
  function parseCopyMoveOptions(body) {
134
182
  const obj = ensureObject(body);
135
183
  return {
136
184
  fromPath: requiredString(obj.fromPath, "fromPath"),
137
- toPath: requiredString(obj.toPath, "toPath")
185
+ toPath: requiredString(obj.toPath, "toPath"),
186
+ ifMatch: optionalString(obj.ifMatch, "ifMatch")
138
187
  };
139
188
  }
140
189
  function parsePrepareUploadsOptions(body) {
@@ -160,7 +209,9 @@ function parsePrepareUploadsOptions(body) {
160
209
  item.contentDisposition,
161
210
  `items[${idx}].contentDisposition`
162
211
  ),
163
- metadata: optionalStringRecord(item.metadata, `items[${idx}].metadata`)
212
+ metadata: optionalStringRecord(item.metadata, `items[${idx}].metadata`),
213
+ expiresAt: optionalDateStringOrNull(item.expiresAt, `items[${idx}].expiresAt`),
214
+ ifNoneMatch: optionalString(item.ifNoneMatch, `items[${idx}].ifNoneMatch`)
164
215
  };
165
216
  });
166
217
  return {
@@ -176,6 +227,30 @@ function parsePreviewOptions(body) {
176
227
  inline: optionalBoolean(obj.inline, "inline")
177
228
  };
178
229
  }
230
+ function parseGetFolderLockOptions(body) {
231
+ const obj = ensureObject(body);
232
+ return {
233
+ path: requiredString(obj.path, "path")
234
+ };
235
+ }
236
+ function parseGetFileAttributesOptions(body) {
237
+ const obj = ensureObject(body);
238
+ return {
239
+ path: requiredString(obj.path, "path")
240
+ };
241
+ }
242
+ function parseSetFileAttributesOptions(body) {
243
+ const obj = ensureObject(body);
244
+ return {
245
+ path: requiredString(obj.path, "path"),
246
+ contentType: optionalString(obj.contentType, "contentType"),
247
+ cacheControl: optionalString(obj.cacheControl, "cacheControl"),
248
+ contentDisposition: optionalString(obj.contentDisposition, "contentDisposition"),
249
+ metadata: optionalStringRecord(obj.metadata, "metadata"),
250
+ expiresAt: optionalDateStringOrNull(obj.expiresAt, "expiresAt"),
251
+ ifMatch: optionalString(obj.ifMatch, "ifMatch")
252
+ };
253
+ }
179
254
  function createS3FileManagerHttpHandler(options) {
180
255
  const basePath = normalizeBasePath(options.api?.basePath);
181
256
  if (!options.manager && !options.getManager) {
@@ -223,6 +298,24 @@ function createS3FileManagerHttpHandler(options) {
223
298
  const out = await manager.getPreviewUrl(parsePreviewOptions(req.body), ctx);
224
299
  return { status: 200, headers: { "content-type": "application/json" }, body: out };
225
300
  }
301
+ if (method === "POST" && path === "/folder/lock/get") {
302
+ const out = await manager.getFolderLock(parseGetFolderLockOptions(req.body), ctx);
303
+ return { status: 200, headers: { "content-type": "application/json" }, body: out };
304
+ }
305
+ if (method === "POST" && path === "/file/attributes/get") {
306
+ const out = await manager.getFileAttributes(
307
+ parseGetFileAttributesOptions(req.body),
308
+ ctx
309
+ );
310
+ return { status: 200, headers: { "content-type": "application/json" }, body: out };
311
+ }
312
+ if (method === "POST" && path === "/file/attributes/set") {
313
+ const out = await manager.setFileAttributes(
314
+ parseSetFileAttributesOptions(req.body),
315
+ ctx
316
+ );
317
+ return { status: 200, headers: { "content-type": "application/json" }, body: out };
318
+ }
226
319
  return jsonError(404, "not_found", "Route not found");
227
320
  } catch (err) {
228
321
  if (err instanceof S3FileManagerHttpError) {
@@ -231,6 +324,9 @@ function createS3FileManagerHttpHandler(options) {
231
324
  if (err instanceof S3FileManagerAuthorizationError) {
232
325
  return jsonError(err.status, err.code, err.message);
233
326
  }
327
+ if (err instanceof S3FileManagerConflictError) {
328
+ return jsonError(err.status, err.code, err.message);
329
+ }
234
330
  console.error("[S3FileManager Error]", err);
235
331
  const message = err instanceof Error ? err.message : "Unknown error";
236
332
  return jsonError(500, "internal_error", message);
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/core/errors.ts","../../src/http/handler.ts"],"sourcesContent":["export class S3FileManagerAuthorizationError extends Error {\n readonly status: number\n readonly code: string\n\n constructor(message: string, status: number, code: string) {\n super(message)\n this.status = status\n this.code = code\n }\n}\n","import type { S3FileManager } from '../core/manager'\nimport { S3FileManagerAuthorizationError } from '../core/errors'\nimport type { S3FileManagerAuthContext } from '../core/types'\nimport type { HttpRequest, HttpResponse, S3FileManagerApiOptions } from './types'\n\nclass S3FileManagerHttpError extends Error {\n readonly status: number\n readonly code: string\n\n constructor(status: number, code: string, message: string) {\n super(message)\n this.status = status\n this.code = code\n }\n}\n\nfunction normalizeBasePath(basePath?: string): string {\n if (!basePath) return ''\n if (basePath === '/') return ''\n return basePath.startsWith('/')\n ? basePath.replace(/\\/+$/, '')\n : `/${basePath.replace(/\\/+$/, '')}`\n}\n\nfunction jsonError(status: number, code: string, message: string): HttpResponse {\n return {\n status,\n headers: { 'content-type': 'application/json' },\n body: {\n error: {\n code,\n message,\n },\n },\n }\n}\n\nfunction ensureObject(body: unknown): Record<string, unknown> {\n if (body && typeof body === 'object' && !Array.isArray(body))\n return body as Record<string, unknown>\n throw new S3FileManagerHttpError(400, 'invalid_body', 'Expected JSON object body')\n}\n\nfunction optionalString(value: unknown, key: string): string | undefined {\n if (value === undefined) return undefined\n if (typeof value === 'string') return value\n throw new S3FileManagerHttpError(400, 'invalid_body', `Expected '${key}' to be a string`)\n}\n\nfunction requiredString(value: unknown, key: string): string {\n if (typeof value === 'string') return value\n throw new S3FileManagerHttpError(400, 'invalid_body', `Expected '${key}' to be a string`)\n}\n\nfunction optionalNumber(value: unknown, key: string): number | undefined {\n if (value === undefined) return undefined\n if (typeof value === 'number' && Number.isFinite(value)) return value\n throw new S3FileManagerHttpError(400, 'invalid_body', `Expected '${key}' to be a finite number`)\n}\n\nfunction optionalBoolean(value: unknown, key: string): boolean | undefined {\n if (value === undefined) return undefined\n if (typeof value === 'boolean') return value\n throw new S3FileManagerHttpError(400, 'invalid_body', `Expected '${key}' to be a boolean`)\n}\n\nfunction requiredStringArray(value: unknown, key: string): string[] {\n if (!Array.isArray(value)) {\n throw new S3FileManagerHttpError(\n 400,\n 'invalid_body',\n `Expected '${key}' to be an array of strings`,\n )\n }\n for (const item of value) {\n if (typeof item !== 'string') {\n throw new S3FileManagerHttpError(\n 400,\n 'invalid_body',\n `Expected '${key}' to be an array of strings`,\n )\n }\n }\n return value\n}\n\nfunction optionalStringRecord(value: unknown, key: string): Record<string, string> | undefined {\n if (value === undefined) return undefined\n if (!value || typeof value !== 'object' || Array.isArray(value)) {\n throw new S3FileManagerHttpError(\n 400,\n 'invalid_body',\n `Expected '${key}' to be an object of strings`,\n )\n }\n const out: Record<string, string> = {}\n for (const [k, v] of Object.entries(value)) {\n if (typeof v !== 'string') {\n throw new S3FileManagerHttpError(400, 'invalid_body', `Expected '${key}.${k}' to be a string`)\n }\n out[k] = v\n }\n return out\n}\n\nfunction parseListOptions(body: unknown) {\n const obj = ensureObject(body)\n return {\n path: requiredString(obj.path, 'path'),\n cursor: optionalString(obj.cursor, 'cursor'),\n limit: optionalNumber(obj.limit, 'limit'),\n }\n}\n\nfunction parseSearchOptions(body: unknown) {\n const obj = ensureObject(body)\n return {\n query: requiredString(obj.query, 'query'),\n path: optionalString(obj.path, 'path'),\n recursive: optionalBoolean(obj.recursive, 'recursive'),\n limit: optionalNumber(obj.limit, 'limit'),\n cursor: optionalString(obj.cursor, 'cursor'),\n }\n}\n\nfunction parseCreateFolderOptions(body: unknown) {\n const obj = ensureObject(body)\n return { path: requiredString(obj.path, 'path') }\n}\n\nfunction parseDeleteFolderOptions(body: unknown) {\n const obj = ensureObject(body)\n return {\n path: requiredString(obj.path, 'path'),\n recursive: optionalBoolean(obj.recursive, 'recursive'),\n }\n}\n\nfunction parseDeleteFilesOptions(body: unknown) {\n const obj = ensureObject(body)\n return { paths: requiredStringArray(obj.paths, 'paths') }\n}\n\nfunction parseCopyMoveOptions(body: unknown) {\n const obj = ensureObject(body)\n return {\n fromPath: requiredString(obj.fromPath, 'fromPath'),\n toPath: requiredString(obj.toPath, 'toPath'),\n }\n}\n\nfunction parsePrepareUploadsOptions(body: unknown) {\n const obj = ensureObject(body)\n const itemsValue = obj.items\n if (!Array.isArray(itemsValue)) {\n throw new S3FileManagerHttpError(400, 'invalid_body', \"Expected 'items' to be an array\")\n }\n\n const items = itemsValue.map((raw, idx) => {\n if (!raw || typeof raw !== 'object' || Array.isArray(raw)) {\n throw new S3FileManagerHttpError(\n 400,\n 'invalid_body',\n `Expected 'items[${idx}]' to be an object`,\n )\n }\n const item = raw as Record<string, unknown>\n return {\n path: requiredString(item.path, `items[${idx}].path`),\n contentType: optionalString(item.contentType, `items[${idx}].contentType`),\n cacheControl: optionalString(item.cacheControl, `items[${idx}].cacheControl`),\n contentDisposition: optionalString(\n item.contentDisposition,\n `items[${idx}].contentDisposition`,\n ),\n metadata: optionalStringRecord(item.metadata, `items[${idx}].metadata`),\n }\n })\n\n return {\n items,\n expiresInSeconds: optionalNumber(obj.expiresInSeconds, 'expiresInSeconds'),\n }\n}\n\nfunction parsePreviewOptions(body: unknown) {\n const obj = ensureObject(body)\n return {\n path: requiredString(obj.path, 'path'),\n expiresInSeconds: optionalNumber(obj.expiresInSeconds, 'expiresInSeconds'),\n inline: optionalBoolean(obj.inline, 'inline'),\n }\n}\n\nexport interface CreateS3FileManagerHttpHandlerOptions<FileExtra, FolderExtra> {\n manager?: S3FileManager<FileExtra, FolderExtra>\n getManager?: (\n req: HttpRequest,\n ctx: S3FileManagerAuthContext,\n ) => S3FileManager<FileExtra, FolderExtra> | Promise<S3FileManager<FileExtra, FolderExtra>>\n getContext?: (req: HttpRequest) => Promise<S3FileManagerAuthContext> | S3FileManagerAuthContext\n api?: S3FileManagerApiOptions\n}\n\nexport function createS3FileManagerHttpHandler<FileExtra = unknown, FolderExtra = unknown>(\n options: CreateS3FileManagerHttpHandlerOptions<FileExtra, FolderExtra>,\n): (req: HttpRequest) => Promise<HttpResponse> {\n const basePath = normalizeBasePath(options.api?.basePath)\n\n if (!options.manager && !options.getManager) {\n throw new Error('createS3FileManagerHttpHandler requires either manager or getManager')\n }\n\n return async (req: HttpRequest): Promise<HttpResponse> => {\n try {\n const ctx = (await options.getContext?.(req)) ?? {}\n const manager = options.getManager ? await options.getManager(req, ctx) : options.manager!\n const method = req.method.toUpperCase()\n const path = req.path.startsWith(basePath) ? req.path.slice(basePath.length) || '/' : req.path\n\n if (method === 'POST' && path === '/list') {\n const out = await manager.list(parseListOptions(req.body) as any, ctx)\n return { status: 200, headers: { 'content-type': 'application/json' }, body: out as any }\n }\n\n if (method === 'POST' && path === '/search') {\n const out = await manager.search(parseSearchOptions(req.body) as any, ctx)\n return { status: 200, headers: { 'content-type': 'application/json' }, body: out as any }\n }\n\n if (method === 'POST' && path === '/folder/create') {\n await manager.createFolder(parseCreateFolderOptions(req.body) as any, ctx)\n return { status: 204 }\n }\n\n if (method === 'POST' && path === '/folder/delete') {\n await manager.deleteFolder(parseDeleteFolderOptions(req.body) as any, ctx)\n return { status: 204 }\n }\n\n if (method === 'POST' && path === '/files/delete') {\n await manager.deleteFiles(parseDeleteFilesOptions(req.body) as any, ctx)\n return { status: 204 }\n }\n\n if (method === 'POST' && path === '/files/copy') {\n await manager.copy(parseCopyMoveOptions(req.body) as any, ctx)\n return { status: 204 }\n }\n\n if (method === 'POST' && path === '/files/move') {\n await manager.move(parseCopyMoveOptions(req.body) as any, ctx)\n return { status: 204 }\n }\n\n if (method === 'POST' && path === '/upload/prepare') {\n const out = await manager.prepareUploads(parsePrepareUploadsOptions(req.body) as any, ctx)\n return { status: 200, headers: { 'content-type': 'application/json' }, body: out as any }\n }\n\n if (method === 'POST' && path === '/preview') {\n const out = await manager.getPreviewUrl(parsePreviewOptions(req.body) as any, ctx)\n return { status: 200, headers: { 'content-type': 'application/json' }, body: out as any }\n }\n\n return jsonError(404, 'not_found', 'Route not found')\n } catch (err) {\n if (err instanceof S3FileManagerHttpError) {\n return jsonError(err.status, err.code, err.message)\n }\n if (err instanceof S3FileManagerAuthorizationError) {\n return jsonError(err.status, err.code, err.message)\n }\n\n console.error('[S3FileManager Error]', err)\n const message = err instanceof Error ? err.message : 'Unknown error'\n return jsonError(500, 'internal_error', message)\n }\n }\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../src/core/errors.ts","../../src/http/handler.ts"],"sourcesContent":["export class S3FileManagerAuthorizationError extends Error {\n readonly status: number\n readonly code: string\n\n constructor(message: string, status: number, code: string) {\n super(message)\n this.status = status\n this.code = code\n }\n}\n\nexport class S3FileManagerConflictError extends Error {\n readonly status: number\n readonly code: string\n\n constructor(message: string, status = 409, code = 'conflict') {\n super(message)\n this.status = status\n this.code = code\n }\n}\n","import type { S3FileManager } from '../core/manager'\nimport { S3FileManagerAuthorizationError, S3FileManagerConflictError } from '../core/errors'\nimport type { S3FileManagerAuthContext } from '../core/types'\nimport type { HttpRequest, HttpResponse, S3FileManagerApiOptions } from './types'\n\nclass S3FileManagerHttpError extends Error {\n readonly status: number\n readonly code: string\n\n constructor(status: number, code: string, message: string) {\n super(message)\n this.status = status\n this.code = code\n }\n}\n\nfunction normalizeBasePath(basePath?: string): string {\n if (!basePath) return ''\n if (basePath === '/') return ''\n return basePath.startsWith('/')\n ? basePath.replace(/\\/+$/, '')\n : `/${basePath.replace(/\\/+$/, '')}`\n}\n\nfunction jsonError(status: number, code: string, message: string): HttpResponse {\n return {\n status,\n headers: { 'content-type': 'application/json' },\n body: {\n error: {\n code,\n message,\n },\n },\n }\n}\n\nfunction ensureObject(body: unknown): Record<string, unknown> {\n if (body && typeof body === 'object' && !Array.isArray(body))\n return body as Record<string, unknown>\n throw new S3FileManagerHttpError(400, 'invalid_body', 'Expected JSON object body')\n}\n\nfunction optionalString(value: unknown, key: string): string | undefined {\n if (value === undefined) return undefined\n if (typeof value === 'string') return value\n throw new S3FileManagerHttpError(400, 'invalid_body', `Expected '${key}' to be a string`)\n}\n\nfunction optionalStringOrNull(value: unknown, key: string): string | null | undefined {\n if (value === undefined) return undefined\n if (value === null) return null\n if (typeof value === 'string') return value\n throw new S3FileManagerHttpError(400, 'invalid_body', `Expected '${key}' to be a string`)\n}\n\nfunction optionalDateStringOrNull(value: unknown, key: string): string | null | undefined {\n const raw = optionalStringOrNull(value, key)\n if (raw === undefined || raw === null) return raw\n const parsed = new Date(raw)\n if (!Number.isFinite(parsed.getTime())) {\n throw new S3FileManagerHttpError(400, 'invalid_body', `Expected '${key}' to be a date string`)\n }\n return raw\n}\n\nfunction requiredString(value: unknown, key: string): string {\n if (typeof value === 'string') return value\n throw new S3FileManagerHttpError(400, 'invalid_body', `Expected '${key}' to be a string`)\n}\n\nfunction optionalNumber(value: unknown, key: string): number | undefined {\n if (value === undefined) return undefined\n if (typeof value === 'number' && Number.isFinite(value)) return value\n throw new S3FileManagerHttpError(400, 'invalid_body', `Expected '${key}' to be a finite number`)\n}\n\nfunction optionalBoolean(value: unknown, key: string): boolean | undefined {\n if (value === undefined) return undefined\n if (typeof value === 'boolean') return value\n throw new S3FileManagerHttpError(400, 'invalid_body', `Expected '${key}' to be a boolean`)\n}\n\nfunction requiredStringArray(value: unknown, key: string): string[] {\n if (!Array.isArray(value)) {\n throw new S3FileManagerHttpError(\n 400,\n 'invalid_body',\n `Expected '${key}' to be an array of strings`,\n )\n }\n for (const item of value) {\n if (typeof item !== 'string') {\n throw new S3FileManagerHttpError(\n 400,\n 'invalid_body',\n `Expected '${key}' to be an array of strings`,\n )\n }\n }\n return value\n}\n\nfunction optionalStringRecord(value: unknown, key: string): Record<string, string> | undefined {\n if (value === undefined) return undefined\n if (!value || typeof value !== 'object' || Array.isArray(value)) {\n throw new S3FileManagerHttpError(\n 400,\n 'invalid_body',\n `Expected '${key}' to be an object of strings`,\n )\n }\n const out: Record<string, string> = {}\n for (const [k, v] of Object.entries(value)) {\n if (typeof v !== 'string') {\n throw new S3FileManagerHttpError(400, 'invalid_body', `Expected '${key}.${k}' to be a string`)\n }\n out[k] = v\n }\n return out\n}\n\nfunction parseListOptions(body: unknown) {\n const obj = ensureObject(body)\n return {\n path: requiredString(obj.path, 'path'),\n cursor: optionalString(obj.cursor, 'cursor'),\n limit: optionalNumber(obj.limit, 'limit'),\n }\n}\n\nfunction parseSearchOptions(body: unknown) {\n const obj = ensureObject(body)\n return {\n query: requiredString(obj.query, 'query'),\n path: optionalString(obj.path, 'path'),\n recursive: optionalBoolean(obj.recursive, 'recursive'),\n limit: optionalNumber(obj.limit, 'limit'),\n cursor: optionalString(obj.cursor, 'cursor'),\n }\n}\n\nfunction parseCreateFolderOptions(body: unknown) {\n const obj = ensureObject(body)\n return { path: requiredString(obj.path, 'path') }\n}\n\nfunction parseDeleteFolderOptions(body: unknown) {\n const obj = ensureObject(body)\n return {\n path: requiredString(obj.path, 'path'),\n recursive: optionalBoolean(obj.recursive, 'recursive'),\n }\n}\n\nfunction parseDeleteFilesOptions(body: unknown) {\n const obj = ensureObject(body)\n const itemsValue = obj.items\n const items = Array.isArray(itemsValue)\n ? itemsValue.map((raw, idx) => {\n if (!raw || typeof raw !== 'object' || Array.isArray(raw)) {\n throw new S3FileManagerHttpError(\n 400,\n 'invalid_body',\n `Expected 'items[${idx}]' to be an object`,\n )\n }\n const item = raw as Record<string, unknown>\n return {\n path: requiredString(item.path, `items[${idx}].path`),\n ifMatch: optionalString(item.ifMatch, `items[${idx}].ifMatch`),\n ifNoneMatch: optionalString(item.ifNoneMatch, `items[${idx}].ifNoneMatch`),\n }\n })\n : undefined\n\n const paths = obj.paths !== undefined ? requiredStringArray(obj.paths, 'paths') : undefined\n\n if (!paths && !items) {\n throw new S3FileManagerHttpError(\n 400,\n 'invalid_body',\n \"Expected 'paths' or 'items' to be provided\",\n )\n }\n\n return { ...(paths ? { paths } : {}), ...(items ? { items } : {}) }\n}\n\nfunction parseCopyMoveOptions(body: unknown) {\n const obj = ensureObject(body)\n return {\n fromPath: requiredString(obj.fromPath, 'fromPath'),\n toPath: requiredString(obj.toPath, 'toPath'),\n ifMatch: optionalString(obj.ifMatch, 'ifMatch'),\n }\n}\n\nfunction parsePrepareUploadsOptions(body: unknown) {\n const obj = ensureObject(body)\n const itemsValue = obj.items\n if (!Array.isArray(itemsValue)) {\n throw new S3FileManagerHttpError(400, 'invalid_body', \"Expected 'items' to be an array\")\n }\n\n const items = itemsValue.map((raw, idx) => {\n if (!raw || typeof raw !== 'object' || Array.isArray(raw)) {\n throw new S3FileManagerHttpError(\n 400,\n 'invalid_body',\n `Expected 'items[${idx}]' to be an object`,\n )\n }\n const item = raw as Record<string, unknown>\n return {\n path: requiredString(item.path, `items[${idx}].path`),\n contentType: optionalString(item.contentType, `items[${idx}].contentType`),\n cacheControl: optionalString(item.cacheControl, `items[${idx}].cacheControl`),\n contentDisposition: optionalString(\n item.contentDisposition,\n `items[${idx}].contentDisposition`,\n ),\n metadata: optionalStringRecord(item.metadata, `items[${idx}].metadata`),\n expiresAt: optionalDateStringOrNull(item.expiresAt, `items[${idx}].expiresAt`),\n ifNoneMatch: optionalString(item.ifNoneMatch, `items[${idx}].ifNoneMatch`),\n }\n })\n\n return {\n items,\n expiresInSeconds: optionalNumber(obj.expiresInSeconds, 'expiresInSeconds'),\n }\n}\n\nfunction parsePreviewOptions(body: unknown) {\n const obj = ensureObject(body)\n return {\n path: requiredString(obj.path, 'path'),\n expiresInSeconds: optionalNumber(obj.expiresInSeconds, 'expiresInSeconds'),\n inline: optionalBoolean(obj.inline, 'inline'),\n }\n}\n\nfunction parseGetFolderLockOptions(body: unknown) {\n const obj = ensureObject(body)\n return {\n path: requiredString(obj.path, 'path'),\n }\n}\n\nfunction parseGetFileAttributesOptions(body: unknown) {\n const obj = ensureObject(body)\n return {\n path: requiredString(obj.path, 'path'),\n }\n}\n\nfunction parseSetFileAttributesOptions(body: unknown) {\n const obj = ensureObject(body)\n return {\n path: requiredString(obj.path, 'path'),\n contentType: optionalString(obj.contentType, 'contentType'),\n cacheControl: optionalString(obj.cacheControl, 'cacheControl'),\n contentDisposition: optionalString(obj.contentDisposition, 'contentDisposition'),\n metadata: optionalStringRecord(obj.metadata, 'metadata'),\n expiresAt: optionalDateStringOrNull(obj.expiresAt, 'expiresAt'),\n ifMatch: optionalString(obj.ifMatch, 'ifMatch'),\n }\n}\n\nexport interface CreateS3FileManagerHttpHandlerOptions<FileExtra, FolderExtra> {\n manager?: S3FileManager<FileExtra, FolderExtra>\n getManager?: (\n req: HttpRequest,\n ctx: S3FileManagerAuthContext,\n ) => S3FileManager<FileExtra, FolderExtra> | Promise<S3FileManager<FileExtra, FolderExtra>>\n getContext?: (req: HttpRequest) => Promise<S3FileManagerAuthContext> | S3FileManagerAuthContext\n api?: S3FileManagerApiOptions\n}\n\nexport function createS3FileManagerHttpHandler<FileExtra = unknown, FolderExtra = unknown>(\n options: CreateS3FileManagerHttpHandlerOptions<FileExtra, FolderExtra>,\n): (req: HttpRequest) => Promise<HttpResponse> {\n const basePath = normalizeBasePath(options.api?.basePath)\n\n if (!options.manager && !options.getManager) {\n throw new Error('createS3FileManagerHttpHandler requires either manager or getManager')\n }\n\n return async (req: HttpRequest): Promise<HttpResponse> => {\n try {\n const ctx = (await options.getContext?.(req)) ?? {}\n const manager = options.getManager ? await options.getManager(req, ctx) : options.manager!\n const method = req.method.toUpperCase()\n const path = req.path.startsWith(basePath) ? req.path.slice(basePath.length) || '/' : req.path\n\n if (method === 'POST' && path === '/list') {\n const out = await manager.list(parseListOptions(req.body) as any, ctx)\n return { status: 200, headers: { 'content-type': 'application/json' }, body: out as any }\n }\n\n if (method === 'POST' && path === '/search') {\n const out = await manager.search(parseSearchOptions(req.body) as any, ctx)\n return { status: 200, headers: { 'content-type': 'application/json' }, body: out as any }\n }\n\n if (method === 'POST' && path === '/folder/create') {\n await manager.createFolder(parseCreateFolderOptions(req.body) as any, ctx)\n return { status: 204 }\n }\n\n if (method === 'POST' && path === '/folder/delete') {\n await manager.deleteFolder(parseDeleteFolderOptions(req.body) as any, ctx)\n return { status: 204 }\n }\n\n if (method === 'POST' && path === '/files/delete') {\n await manager.deleteFiles(parseDeleteFilesOptions(req.body) as any, ctx)\n return { status: 204 }\n }\n\n if (method === 'POST' && path === '/files/copy') {\n await manager.copy(parseCopyMoveOptions(req.body) as any, ctx)\n return { status: 204 }\n }\n\n if (method === 'POST' && path === '/files/move') {\n await manager.move(parseCopyMoveOptions(req.body) as any, ctx)\n return { status: 204 }\n }\n\n if (method === 'POST' && path === '/upload/prepare') {\n const out = await manager.prepareUploads(parsePrepareUploadsOptions(req.body) as any, ctx)\n return { status: 200, headers: { 'content-type': 'application/json' }, body: out as any }\n }\n\n if (method === 'POST' && path === '/preview') {\n const out = await manager.getPreviewUrl(parsePreviewOptions(req.body) as any, ctx)\n return { status: 200, headers: { 'content-type': 'application/json' }, body: out as any }\n }\n\n if (method === 'POST' && path === '/folder/lock/get') {\n const out = await manager.getFolderLock(parseGetFolderLockOptions(req.body) as any, ctx)\n return { status: 200, headers: { 'content-type': 'application/json' }, body: out as any }\n }\n\n if (method === 'POST' && path === '/file/attributes/get') {\n const out = await manager.getFileAttributes(\n parseGetFileAttributesOptions(req.body) as any,\n ctx,\n )\n return { status: 200, headers: { 'content-type': 'application/json' }, body: out as any }\n }\n\n if (method === 'POST' && path === '/file/attributes/set') {\n const out = await manager.setFileAttributes(\n parseSetFileAttributesOptions(req.body) as any,\n ctx,\n )\n return { status: 200, headers: { 'content-type': 'application/json' }, body: out as any }\n }\n\n return jsonError(404, 'not_found', 'Route not found')\n } catch (err) {\n if (err instanceof S3FileManagerHttpError) {\n return jsonError(err.status, err.code, err.message)\n }\n if (err instanceof S3FileManagerAuthorizationError) {\n return jsonError(err.status, err.code, err.message)\n }\n if (err instanceof S3FileManagerConflictError) {\n return jsonError(err.status, err.code, err.message)\n }\n\n console.error('[S3FileManager Error]', err)\n const message = err instanceof Error ? err.message : 'Unknown error'\n return jsonError(500, 'internal_error', message)\n }\n }\n}\n"],"mappings":"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","names":[]}