s3kit 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (56) hide show
  1. package/README.md +398 -0
  2. package/dist/adapters/express.cjs +305 -0
  3. package/dist/adapters/express.cjs.map +1 -0
  4. package/dist/adapters/express.d.cts +10 -0
  5. package/dist/adapters/express.d.ts +10 -0
  6. package/dist/adapters/express.js +278 -0
  7. package/dist/adapters/express.js.map +1 -0
  8. package/dist/adapters/fetch.cjs +298 -0
  9. package/dist/adapters/fetch.cjs.map +1 -0
  10. package/dist/adapters/fetch.d.cts +9 -0
  11. package/dist/adapters/fetch.d.ts +9 -0
  12. package/dist/adapters/fetch.js +271 -0
  13. package/dist/adapters/fetch.js.map +1 -0
  14. package/dist/adapters/next.cjs +796 -0
  15. package/dist/adapters/next.cjs.map +1 -0
  16. package/dist/adapters/next.d.cts +28 -0
  17. package/dist/adapters/next.d.ts +28 -0
  18. package/dist/adapters/next.js +775 -0
  19. package/dist/adapters/next.js.map +1 -0
  20. package/dist/client/index.cjs +153 -0
  21. package/dist/client/index.cjs.map +1 -0
  22. package/dist/client/index.d.cts +59 -0
  23. package/dist/client/index.d.ts +59 -0
  24. package/dist/client/index.js +126 -0
  25. package/dist/client/index.js.map +1 -0
  26. package/dist/core/index.cjs +452 -0
  27. package/dist/core/index.cjs.map +1 -0
  28. package/dist/core/index.d.cts +11 -0
  29. package/dist/core/index.d.ts +11 -0
  30. package/dist/core/index.js +430 -0
  31. package/dist/core/index.js.map +1 -0
  32. package/dist/http/index.cjs +270 -0
  33. package/dist/http/index.cjs.map +1 -0
  34. package/dist/http/index.d.cts +49 -0
  35. package/dist/http/index.d.ts +49 -0
  36. package/dist/http/index.js +243 -0
  37. package/dist/http/index.js.map +1 -0
  38. package/dist/index.cjs +808 -0
  39. package/dist/index.cjs.map +1 -0
  40. package/dist/index.d.cts +6 -0
  41. package/dist/index.d.ts +6 -0
  42. package/dist/index.js +784 -0
  43. package/dist/index.js.map +1 -0
  44. package/dist/manager-BbmXpgXN.d.ts +29 -0
  45. package/dist/manager-gIjo-t8h.d.cts +29 -0
  46. package/dist/react/index.cjs +4320 -0
  47. package/dist/react/index.cjs.map +1 -0
  48. package/dist/react/index.css +155 -0
  49. package/dist/react/index.css.map +1 -0
  50. package/dist/react/index.d.cts +79 -0
  51. package/dist/react/index.d.ts +79 -0
  52. package/dist/react/index.js +4315 -0
  53. package/dist/react/index.js.map +1 -0
  54. package/dist/types-g2IYvH3O.d.cts +123 -0
  55. package/dist/types-g2IYvH3O.d.ts +123 -0
  56. package/package.json +100 -0
@@ -0,0 +1,298 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/adapters/fetch.ts
21
+ var fetch_exports = {};
22
+ __export(fetch_exports, {
23
+ createFetchHandler: () => createFetchHandler
24
+ });
25
+ module.exports = __toCommonJS(fetch_exports);
26
+
27
+ // src/core/errors.ts
28
+ var S3FileManagerAuthorizationError = class extends Error {
29
+ status;
30
+ code;
31
+ constructor(message, status, code) {
32
+ super(message);
33
+ this.status = status;
34
+ this.code = code;
35
+ }
36
+ };
37
+
38
+ // src/http/handler.ts
39
+ var S3FileManagerHttpError = class extends Error {
40
+ status;
41
+ code;
42
+ constructor(status, code, message) {
43
+ super(message);
44
+ this.status = status;
45
+ this.code = code;
46
+ }
47
+ };
48
+ function normalizeBasePath(basePath) {
49
+ if (!basePath) return "";
50
+ if (basePath === "/") return "";
51
+ return basePath.startsWith("/") ? basePath.replace(/\/+$/, "") : `/${basePath.replace(/\/+$/, "")}`;
52
+ }
53
+ function jsonError(status, code, message) {
54
+ return {
55
+ status,
56
+ headers: { "content-type": "application/json" },
57
+ body: {
58
+ error: {
59
+ code,
60
+ message
61
+ }
62
+ }
63
+ };
64
+ }
65
+ function ensureObject(body) {
66
+ if (body && typeof body === "object" && !Array.isArray(body))
67
+ return body;
68
+ throw new S3FileManagerHttpError(400, "invalid_body", "Expected JSON object body");
69
+ }
70
+ function optionalString(value, key) {
71
+ if (value === void 0) return void 0;
72
+ if (typeof value === "string") return value;
73
+ throw new S3FileManagerHttpError(400, "invalid_body", `Expected '${key}' to be a string`);
74
+ }
75
+ function requiredString(value, key) {
76
+ if (typeof value === "string") return value;
77
+ throw new S3FileManagerHttpError(400, "invalid_body", `Expected '${key}' to be a string`);
78
+ }
79
+ function optionalNumber(value, key) {
80
+ if (value === void 0) return void 0;
81
+ if (typeof value === "number" && Number.isFinite(value)) return value;
82
+ throw new S3FileManagerHttpError(400, "invalid_body", `Expected '${key}' to be a finite number`);
83
+ }
84
+ function optionalBoolean(value, key) {
85
+ if (value === void 0) return void 0;
86
+ if (typeof value === "boolean") return value;
87
+ throw new S3FileManagerHttpError(400, "invalid_body", `Expected '${key}' to be a boolean`);
88
+ }
89
+ function requiredStringArray(value, key) {
90
+ if (!Array.isArray(value)) {
91
+ throw new S3FileManagerHttpError(
92
+ 400,
93
+ "invalid_body",
94
+ `Expected '${key}' to be an array of strings`
95
+ );
96
+ }
97
+ for (const item of value) {
98
+ if (typeof item !== "string") {
99
+ throw new S3FileManagerHttpError(
100
+ 400,
101
+ "invalid_body",
102
+ `Expected '${key}' to be an array of strings`
103
+ );
104
+ }
105
+ }
106
+ return value;
107
+ }
108
+ function optionalStringRecord(value, key) {
109
+ if (value === void 0) return void 0;
110
+ if (!value || typeof value !== "object" || Array.isArray(value)) {
111
+ throw new S3FileManagerHttpError(
112
+ 400,
113
+ "invalid_body",
114
+ `Expected '${key}' to be an object of strings`
115
+ );
116
+ }
117
+ const out = {};
118
+ for (const [k, v] of Object.entries(value)) {
119
+ if (typeof v !== "string") {
120
+ throw new S3FileManagerHttpError(400, "invalid_body", `Expected '${key}.${k}' to be a string`);
121
+ }
122
+ out[k] = v;
123
+ }
124
+ return out;
125
+ }
126
+ function parseListOptions(body) {
127
+ const obj = ensureObject(body);
128
+ return {
129
+ path: requiredString(obj.path, "path"),
130
+ cursor: optionalString(obj.cursor, "cursor"),
131
+ limit: optionalNumber(obj.limit, "limit")
132
+ };
133
+ }
134
+ function parseSearchOptions(body) {
135
+ const obj = ensureObject(body);
136
+ return {
137
+ query: requiredString(obj.query, "query"),
138
+ path: optionalString(obj.path, "path"),
139
+ recursive: optionalBoolean(obj.recursive, "recursive"),
140
+ limit: optionalNumber(obj.limit, "limit"),
141
+ cursor: optionalString(obj.cursor, "cursor")
142
+ };
143
+ }
144
+ function parseCreateFolderOptions(body) {
145
+ const obj = ensureObject(body);
146
+ return { path: requiredString(obj.path, "path") };
147
+ }
148
+ function parseDeleteFolderOptions(body) {
149
+ const obj = ensureObject(body);
150
+ return {
151
+ path: requiredString(obj.path, "path"),
152
+ recursive: optionalBoolean(obj.recursive, "recursive")
153
+ };
154
+ }
155
+ function parseDeleteFilesOptions(body) {
156
+ const obj = ensureObject(body);
157
+ return { paths: requiredStringArray(obj.paths, "paths") };
158
+ }
159
+ function parseCopyMoveOptions(body) {
160
+ const obj = ensureObject(body);
161
+ return {
162
+ fromPath: requiredString(obj.fromPath, "fromPath"),
163
+ toPath: requiredString(obj.toPath, "toPath")
164
+ };
165
+ }
166
+ function parsePrepareUploadsOptions(body) {
167
+ const obj = ensureObject(body);
168
+ const itemsValue = obj.items;
169
+ if (!Array.isArray(itemsValue)) {
170
+ throw new S3FileManagerHttpError(400, "invalid_body", "Expected 'items' to be an array");
171
+ }
172
+ const items = itemsValue.map((raw, idx) => {
173
+ if (!raw || typeof raw !== "object" || Array.isArray(raw)) {
174
+ throw new S3FileManagerHttpError(
175
+ 400,
176
+ "invalid_body",
177
+ `Expected 'items[${idx}]' to be an object`
178
+ );
179
+ }
180
+ const item = raw;
181
+ return {
182
+ path: requiredString(item.path, `items[${idx}].path`),
183
+ contentType: optionalString(item.contentType, `items[${idx}].contentType`),
184
+ cacheControl: optionalString(item.cacheControl, `items[${idx}].cacheControl`),
185
+ contentDisposition: optionalString(
186
+ item.contentDisposition,
187
+ `items[${idx}].contentDisposition`
188
+ ),
189
+ metadata: optionalStringRecord(item.metadata, `items[${idx}].metadata`)
190
+ };
191
+ });
192
+ return {
193
+ items,
194
+ expiresInSeconds: optionalNumber(obj.expiresInSeconds, "expiresInSeconds")
195
+ };
196
+ }
197
+ function parsePreviewOptions(body) {
198
+ const obj = ensureObject(body);
199
+ return {
200
+ path: requiredString(obj.path, "path"),
201
+ expiresInSeconds: optionalNumber(obj.expiresInSeconds, "expiresInSeconds"),
202
+ inline: optionalBoolean(obj.inline, "inline")
203
+ };
204
+ }
205
+ function createS3FileManagerHttpHandler(options) {
206
+ const basePath = normalizeBasePath(options.api?.basePath);
207
+ if (!options.manager && !options.getManager) {
208
+ throw new Error("createS3FileManagerHttpHandler requires either manager or getManager");
209
+ }
210
+ return async (req) => {
211
+ try {
212
+ const ctx = await options.getContext?.(req) ?? {};
213
+ const manager = options.getManager ? await options.getManager(req, ctx) : options.manager;
214
+ const method = req.method.toUpperCase();
215
+ const path = req.path.startsWith(basePath) ? req.path.slice(basePath.length) || "/" : req.path;
216
+ if (method === "POST" && path === "/list") {
217
+ const out = await manager.list(parseListOptions(req.body), ctx);
218
+ return { status: 200, headers: { "content-type": "application/json" }, body: out };
219
+ }
220
+ if (method === "POST" && path === "/search") {
221
+ const out = await manager.search(parseSearchOptions(req.body), ctx);
222
+ return { status: 200, headers: { "content-type": "application/json" }, body: out };
223
+ }
224
+ if (method === "POST" && path === "/folder/create") {
225
+ await manager.createFolder(parseCreateFolderOptions(req.body), ctx);
226
+ return { status: 204 };
227
+ }
228
+ if (method === "POST" && path === "/folder/delete") {
229
+ await manager.deleteFolder(parseDeleteFolderOptions(req.body), ctx);
230
+ return { status: 204 };
231
+ }
232
+ if (method === "POST" && path === "/files/delete") {
233
+ await manager.deleteFiles(parseDeleteFilesOptions(req.body), ctx);
234
+ return { status: 204 };
235
+ }
236
+ if (method === "POST" && path === "/files/copy") {
237
+ await manager.copy(parseCopyMoveOptions(req.body), ctx);
238
+ return { status: 204 };
239
+ }
240
+ if (method === "POST" && path === "/files/move") {
241
+ await manager.move(parseCopyMoveOptions(req.body), ctx);
242
+ return { status: 204 };
243
+ }
244
+ if (method === "POST" && path === "/upload/prepare") {
245
+ const out = await manager.prepareUploads(parsePrepareUploadsOptions(req.body), ctx);
246
+ return { status: 200, headers: { "content-type": "application/json" }, body: out };
247
+ }
248
+ if (method === "POST" && path === "/preview") {
249
+ const out = await manager.getPreviewUrl(parsePreviewOptions(req.body), ctx);
250
+ return { status: 200, headers: { "content-type": "application/json" }, body: out };
251
+ }
252
+ return jsonError(404, "not_found", "Route not found");
253
+ } catch (err) {
254
+ if (err instanceof S3FileManagerHttpError) {
255
+ return jsonError(err.status, err.code, err.message);
256
+ }
257
+ if (err instanceof S3FileManagerAuthorizationError) {
258
+ return jsonError(err.status, err.code, err.message);
259
+ }
260
+ console.error("[S3FileManager Error]", err);
261
+ const message = err instanceof Error ? err.message : "Unknown error";
262
+ return jsonError(500, "internal_error", message);
263
+ }
264
+ };
265
+ }
266
+
267
+ // src/adapters/fetch.ts
268
+ async function readJsonBody(req) {
269
+ const ct = req.headers.get("content-type") ?? "";
270
+ if (!ct.includes("application/json")) return void 0;
271
+ return await req.json();
272
+ }
273
+ function createFetchHandler(options) {
274
+ const handler = createS3FileManagerHttpHandler(options);
275
+ return async (req) => {
276
+ const url = new URL(req.url);
277
+ const body = await readJsonBody(req);
278
+ const httpReq = {
279
+ method: req.method,
280
+ path: url.pathname,
281
+ query: Object.fromEntries(url.searchParams.entries()),
282
+ headers: Object.fromEntries(req.headers.entries()),
283
+ body
284
+ };
285
+ const out = await handler(httpReq);
286
+ const init = { status: out.status };
287
+ if (out.headers) init.headers = out.headers;
288
+ if (out.status === 204) {
289
+ return new Response(null, init);
290
+ }
291
+ return new Response(out.body ? JSON.stringify(out.body) : null, init);
292
+ };
293
+ }
294
+ // Annotate the CommonJS export names for ESM import in node:
295
+ 0 && (module.exports = {
296
+ createFetchHandler
297
+ });
298
+ //# sourceMappingURL=fetch.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/adapters/fetch.ts","../../src/core/errors.ts","../../src/http/handler.ts"],"sourcesContent":["import type { HttpRequest } from '../http/types'\nimport { createS3FileManagerHttpHandler } from '../http/handler'\n\nexport type FetchS3FileManagerHandlerOptions<FileExtra, FolderExtra> = Parameters<\n typeof createS3FileManagerHttpHandler<FileExtra, FolderExtra>\n>[0]\n\nasync function readJsonBody(req: Request): Promise<unknown> {\n const ct = req.headers.get('content-type') ?? ''\n if (!ct.includes('application/json')) return undefined\n return await req.json()\n}\n\nexport function createFetchHandler<FileExtra = unknown, FolderExtra = unknown>(\n options: FetchS3FileManagerHandlerOptions<FileExtra, FolderExtra>,\n): (req: Request) => Promise<Response> {\n const handler = createS3FileManagerHttpHandler(options)\n\n return async (req: Request) => {\n const url = new URL(req.url)\n const body = await readJsonBody(req)\n\n const httpReq: HttpRequest = {\n method: req.method,\n path: url.pathname,\n query: Object.fromEntries(url.searchParams.entries()),\n headers: Object.fromEntries(req.headers.entries()),\n body,\n }\n\n const out = await handler(httpReq)\n const init: ResponseInit = { status: out.status }\n if (out.headers) init.headers = out.headers\n\n if (out.status === 204) {\n return new Response(null, init)\n }\n\n return new Response(out.body ? JSON.stringify(out.body) : null, init)\n }\n}\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":"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","names":[]}
@@ -0,0 +1,9 @@
1
+ import { createS3FileManagerHttpHandler } from '../http/index.cjs';
2
+ import '../types-g2IYvH3O.cjs';
3
+ import '../manager-gIjo-t8h.cjs';
4
+ import '@aws-sdk/client-s3';
5
+
6
+ type FetchS3FileManagerHandlerOptions<FileExtra, FolderExtra> = Parameters<typeof createS3FileManagerHttpHandler<FileExtra, FolderExtra>>[0];
7
+ declare function createFetchHandler<FileExtra = unknown, FolderExtra = unknown>(options: FetchS3FileManagerHandlerOptions<FileExtra, FolderExtra>): (req: Request) => Promise<Response>;
8
+
9
+ export { type FetchS3FileManagerHandlerOptions, createFetchHandler };
@@ -0,0 +1,9 @@
1
+ import { createS3FileManagerHttpHandler } from '../http/index.js';
2
+ import '../types-g2IYvH3O.js';
3
+ import '../manager-BbmXpgXN.js';
4
+ import '@aws-sdk/client-s3';
5
+
6
+ type FetchS3FileManagerHandlerOptions<FileExtra, FolderExtra> = Parameters<typeof createS3FileManagerHttpHandler<FileExtra, FolderExtra>>[0];
7
+ declare function createFetchHandler<FileExtra = unknown, FolderExtra = unknown>(options: FetchS3FileManagerHandlerOptions<FileExtra, FolderExtra>): (req: Request) => Promise<Response>;
8
+
9
+ export { type FetchS3FileManagerHandlerOptions, createFetchHandler };
@@ -0,0 +1,271 @@
1
+ // src/core/errors.ts
2
+ var S3FileManagerAuthorizationError = class extends Error {
3
+ status;
4
+ code;
5
+ constructor(message, status, code) {
6
+ super(message);
7
+ this.status = status;
8
+ this.code = code;
9
+ }
10
+ };
11
+
12
+ // src/http/handler.ts
13
+ var S3FileManagerHttpError = class extends Error {
14
+ status;
15
+ code;
16
+ constructor(status, code, message) {
17
+ super(message);
18
+ this.status = status;
19
+ this.code = code;
20
+ }
21
+ };
22
+ function normalizeBasePath(basePath) {
23
+ if (!basePath) return "";
24
+ if (basePath === "/") return "";
25
+ return basePath.startsWith("/") ? basePath.replace(/\/+$/, "") : `/${basePath.replace(/\/+$/, "")}`;
26
+ }
27
+ function jsonError(status, code, message) {
28
+ return {
29
+ status,
30
+ headers: { "content-type": "application/json" },
31
+ body: {
32
+ error: {
33
+ code,
34
+ message
35
+ }
36
+ }
37
+ };
38
+ }
39
+ function ensureObject(body) {
40
+ if (body && typeof body === "object" && !Array.isArray(body))
41
+ return body;
42
+ throw new S3FileManagerHttpError(400, "invalid_body", "Expected JSON object body");
43
+ }
44
+ function optionalString(value, key) {
45
+ if (value === void 0) return void 0;
46
+ if (typeof value === "string") return value;
47
+ throw new S3FileManagerHttpError(400, "invalid_body", `Expected '${key}' to be a string`);
48
+ }
49
+ function requiredString(value, key) {
50
+ if (typeof value === "string") return value;
51
+ throw new S3FileManagerHttpError(400, "invalid_body", `Expected '${key}' to be a string`);
52
+ }
53
+ function optionalNumber(value, key) {
54
+ if (value === void 0) return void 0;
55
+ if (typeof value === "number" && Number.isFinite(value)) return value;
56
+ throw new S3FileManagerHttpError(400, "invalid_body", `Expected '${key}' to be a finite number`);
57
+ }
58
+ function optionalBoolean(value, key) {
59
+ if (value === void 0) return void 0;
60
+ if (typeof value === "boolean") return value;
61
+ throw new S3FileManagerHttpError(400, "invalid_body", `Expected '${key}' to be a boolean`);
62
+ }
63
+ function requiredStringArray(value, key) {
64
+ if (!Array.isArray(value)) {
65
+ throw new S3FileManagerHttpError(
66
+ 400,
67
+ "invalid_body",
68
+ `Expected '${key}' to be an array of strings`
69
+ );
70
+ }
71
+ for (const item of value) {
72
+ if (typeof item !== "string") {
73
+ throw new S3FileManagerHttpError(
74
+ 400,
75
+ "invalid_body",
76
+ `Expected '${key}' to be an array of strings`
77
+ );
78
+ }
79
+ }
80
+ return value;
81
+ }
82
+ function optionalStringRecord(value, key) {
83
+ if (value === void 0) return void 0;
84
+ if (!value || typeof value !== "object" || Array.isArray(value)) {
85
+ throw new S3FileManagerHttpError(
86
+ 400,
87
+ "invalid_body",
88
+ `Expected '${key}' to be an object of strings`
89
+ );
90
+ }
91
+ const out = {};
92
+ for (const [k, v] of Object.entries(value)) {
93
+ if (typeof v !== "string") {
94
+ throw new S3FileManagerHttpError(400, "invalid_body", `Expected '${key}.${k}' to be a string`);
95
+ }
96
+ out[k] = v;
97
+ }
98
+ return out;
99
+ }
100
+ function parseListOptions(body) {
101
+ const obj = ensureObject(body);
102
+ return {
103
+ path: requiredString(obj.path, "path"),
104
+ cursor: optionalString(obj.cursor, "cursor"),
105
+ limit: optionalNumber(obj.limit, "limit")
106
+ };
107
+ }
108
+ function parseSearchOptions(body) {
109
+ const obj = ensureObject(body);
110
+ return {
111
+ query: requiredString(obj.query, "query"),
112
+ path: optionalString(obj.path, "path"),
113
+ recursive: optionalBoolean(obj.recursive, "recursive"),
114
+ limit: optionalNumber(obj.limit, "limit"),
115
+ cursor: optionalString(obj.cursor, "cursor")
116
+ };
117
+ }
118
+ function parseCreateFolderOptions(body) {
119
+ const obj = ensureObject(body);
120
+ return { path: requiredString(obj.path, "path") };
121
+ }
122
+ function parseDeleteFolderOptions(body) {
123
+ const obj = ensureObject(body);
124
+ return {
125
+ path: requiredString(obj.path, "path"),
126
+ recursive: optionalBoolean(obj.recursive, "recursive")
127
+ };
128
+ }
129
+ function parseDeleteFilesOptions(body) {
130
+ const obj = ensureObject(body);
131
+ return { paths: requiredStringArray(obj.paths, "paths") };
132
+ }
133
+ function parseCopyMoveOptions(body) {
134
+ const obj = ensureObject(body);
135
+ return {
136
+ fromPath: requiredString(obj.fromPath, "fromPath"),
137
+ toPath: requiredString(obj.toPath, "toPath")
138
+ };
139
+ }
140
+ function parsePrepareUploadsOptions(body) {
141
+ const obj = ensureObject(body);
142
+ const itemsValue = obj.items;
143
+ if (!Array.isArray(itemsValue)) {
144
+ throw new S3FileManagerHttpError(400, "invalid_body", "Expected 'items' to be an array");
145
+ }
146
+ const items = itemsValue.map((raw, idx) => {
147
+ if (!raw || typeof raw !== "object" || Array.isArray(raw)) {
148
+ throw new S3FileManagerHttpError(
149
+ 400,
150
+ "invalid_body",
151
+ `Expected 'items[${idx}]' to be an object`
152
+ );
153
+ }
154
+ const item = raw;
155
+ return {
156
+ path: requiredString(item.path, `items[${idx}].path`),
157
+ contentType: optionalString(item.contentType, `items[${idx}].contentType`),
158
+ cacheControl: optionalString(item.cacheControl, `items[${idx}].cacheControl`),
159
+ contentDisposition: optionalString(
160
+ item.contentDisposition,
161
+ `items[${idx}].contentDisposition`
162
+ ),
163
+ metadata: optionalStringRecord(item.metadata, `items[${idx}].metadata`)
164
+ };
165
+ });
166
+ return {
167
+ items,
168
+ expiresInSeconds: optionalNumber(obj.expiresInSeconds, "expiresInSeconds")
169
+ };
170
+ }
171
+ function parsePreviewOptions(body) {
172
+ const obj = ensureObject(body);
173
+ return {
174
+ path: requiredString(obj.path, "path"),
175
+ expiresInSeconds: optionalNumber(obj.expiresInSeconds, "expiresInSeconds"),
176
+ inline: optionalBoolean(obj.inline, "inline")
177
+ };
178
+ }
179
+ function createS3FileManagerHttpHandler(options) {
180
+ const basePath = normalizeBasePath(options.api?.basePath);
181
+ if (!options.manager && !options.getManager) {
182
+ throw new Error("createS3FileManagerHttpHandler requires either manager or getManager");
183
+ }
184
+ return async (req) => {
185
+ try {
186
+ const ctx = await options.getContext?.(req) ?? {};
187
+ const manager = options.getManager ? await options.getManager(req, ctx) : options.manager;
188
+ const method = req.method.toUpperCase();
189
+ const path = req.path.startsWith(basePath) ? req.path.slice(basePath.length) || "/" : req.path;
190
+ if (method === "POST" && path === "/list") {
191
+ const out = await manager.list(parseListOptions(req.body), ctx);
192
+ return { status: 200, headers: { "content-type": "application/json" }, body: out };
193
+ }
194
+ if (method === "POST" && path === "/search") {
195
+ const out = await manager.search(parseSearchOptions(req.body), ctx);
196
+ return { status: 200, headers: { "content-type": "application/json" }, body: out };
197
+ }
198
+ if (method === "POST" && path === "/folder/create") {
199
+ await manager.createFolder(parseCreateFolderOptions(req.body), ctx);
200
+ return { status: 204 };
201
+ }
202
+ if (method === "POST" && path === "/folder/delete") {
203
+ await manager.deleteFolder(parseDeleteFolderOptions(req.body), ctx);
204
+ return { status: 204 };
205
+ }
206
+ if (method === "POST" && path === "/files/delete") {
207
+ await manager.deleteFiles(parseDeleteFilesOptions(req.body), ctx);
208
+ return { status: 204 };
209
+ }
210
+ if (method === "POST" && path === "/files/copy") {
211
+ await manager.copy(parseCopyMoveOptions(req.body), ctx);
212
+ return { status: 204 };
213
+ }
214
+ if (method === "POST" && path === "/files/move") {
215
+ await manager.move(parseCopyMoveOptions(req.body), ctx);
216
+ return { status: 204 };
217
+ }
218
+ if (method === "POST" && path === "/upload/prepare") {
219
+ const out = await manager.prepareUploads(parsePrepareUploadsOptions(req.body), ctx);
220
+ return { status: 200, headers: { "content-type": "application/json" }, body: out };
221
+ }
222
+ if (method === "POST" && path === "/preview") {
223
+ const out = await manager.getPreviewUrl(parsePreviewOptions(req.body), ctx);
224
+ return { status: 200, headers: { "content-type": "application/json" }, body: out };
225
+ }
226
+ return jsonError(404, "not_found", "Route not found");
227
+ } catch (err) {
228
+ if (err instanceof S3FileManagerHttpError) {
229
+ return jsonError(err.status, err.code, err.message);
230
+ }
231
+ if (err instanceof S3FileManagerAuthorizationError) {
232
+ return jsonError(err.status, err.code, err.message);
233
+ }
234
+ console.error("[S3FileManager Error]", err);
235
+ const message = err instanceof Error ? err.message : "Unknown error";
236
+ return jsonError(500, "internal_error", message);
237
+ }
238
+ };
239
+ }
240
+
241
+ // src/adapters/fetch.ts
242
+ async function readJsonBody(req) {
243
+ const ct = req.headers.get("content-type") ?? "";
244
+ if (!ct.includes("application/json")) return void 0;
245
+ return await req.json();
246
+ }
247
+ function createFetchHandler(options) {
248
+ const handler = createS3FileManagerHttpHandler(options);
249
+ return async (req) => {
250
+ const url = new URL(req.url);
251
+ const body = await readJsonBody(req);
252
+ const httpReq = {
253
+ method: req.method,
254
+ path: url.pathname,
255
+ query: Object.fromEntries(url.searchParams.entries()),
256
+ headers: Object.fromEntries(req.headers.entries()),
257
+ body
258
+ };
259
+ const out = await handler(httpReq);
260
+ const init = { status: out.status };
261
+ if (out.headers) init.headers = out.headers;
262
+ if (out.status === 204) {
263
+ return new Response(null, init);
264
+ }
265
+ return new Response(out.body ? JSON.stringify(out.body) : null, init);
266
+ };
267
+ }
268
+ export {
269
+ createFetchHandler
270
+ };
271
+ //# sourceMappingURL=fetch.js.map