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.
- package/README.md +15 -1
- package/dist/adapters/express.cjs +99 -3
- package/dist/adapters/express.cjs.map +1 -1
- package/dist/adapters/express.d.cts +2 -2
- package/dist/adapters/express.d.ts +2 -2
- package/dist/adapters/express.js +99 -3
- package/dist/adapters/express.js.map +1 -1
- package/dist/adapters/fetch.cjs +99 -3
- package/dist/adapters/fetch.cjs.map +1 -1
- package/dist/adapters/fetch.d.cts +2 -2
- package/dist/adapters/fetch.d.ts +2 -2
- package/dist/adapters/fetch.js +99 -3
- package/dist/adapters/fetch.js.map +1 -1
- package/dist/adapters/next.cjs +386 -20
- package/dist/adapters/next.cjs.map +1 -1
- package/dist/adapters/next.d.cts +2 -2
- package/dist/adapters/next.d.ts +2 -2
- package/dist/adapters/next.js +387 -20
- package/dist/adapters/next.js.map +1 -1
- package/dist/client/index.cjs +15 -1
- package/dist/client/index.cjs.map +1 -1
- package/dist/client/index.d.cts +12 -2
- package/dist/client/index.d.ts +12 -2
- package/dist/client/index.js +15 -1
- package/dist/client/index.js.map +1 -1
- package/dist/core/index.cjs +300 -19
- package/dist/core/index.cjs.map +1 -1
- package/dist/core/index.d.cts +8 -3
- package/dist/core/index.d.ts +8 -3
- package/dist/core/index.js +299 -18
- package/dist/core/index.js.map +1 -1
- package/dist/http/index.cjs +99 -3
- package/dist/http/index.cjs.map +1 -1
- package/dist/http/index.d.cts +5 -2
- package/dist/http/index.d.ts +5 -2
- package/dist/http/index.js +99 -3
- package/dist/http/index.js.map +1 -1
- package/dist/index.cjs +403 -21
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +4 -4
- package/dist/index.d.ts +4 -4
- package/dist/index.js +403 -21
- package/dist/index.js.map +1 -1
- package/dist/{manager-BbmXpgXN.d.ts → manager-BtW1-sC0.d.ts} +11 -1
- package/dist/{manager-gIjo-t8h.d.cts → manager-DSsCYKEz.d.cts} +11 -1
- package/dist/react/index.cjs +334 -31
- package/dist/react/index.cjs.map +1 -1
- package/dist/react/index.d.cts +1 -1
- package/dist/react/index.d.ts +1 -1
- package/dist/react/index.js +334 -31
- package/dist/react/index.js.map +1 -1
- package/dist/{types-g2IYvH3O.d.cts → types-B0yU5sod.d.cts} +51 -3
- package/dist/{types-g2IYvH3O.d.ts → types-B0yU5sod.d.ts} +51 -3
- package/package.json +1 -1
package/dist/core/index.cjs
CHANGED
|
@@ -21,7 +21,8 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
21
21
|
var core_exports = {};
|
|
22
22
|
__export(core_exports, {
|
|
23
23
|
S3FileManager: () => S3FileManager,
|
|
24
|
-
S3FileManagerAuthorizationError: () => S3FileManagerAuthorizationError
|
|
24
|
+
S3FileManagerAuthorizationError: () => S3FileManagerAuthorizationError,
|
|
25
|
+
S3FileManagerConflictError: () => S3FileManagerConflictError
|
|
25
26
|
});
|
|
26
27
|
module.exports = __toCommonJS(core_exports);
|
|
27
28
|
|
|
@@ -40,6 +41,15 @@ var S3FileManagerAuthorizationError = class extends Error {
|
|
|
40
41
|
this.code = code;
|
|
41
42
|
}
|
|
42
43
|
};
|
|
44
|
+
var S3FileManagerConflictError = class extends Error {
|
|
45
|
+
status;
|
|
46
|
+
code;
|
|
47
|
+
constructor(message, status = 409, code = "conflict") {
|
|
48
|
+
super(message);
|
|
49
|
+
this.status = status;
|
|
50
|
+
this.code = code;
|
|
51
|
+
}
|
|
52
|
+
};
|
|
43
53
|
|
|
44
54
|
// src/core/manager.ts
|
|
45
55
|
var DEFAULT_DELIMITER = "/";
|
|
@@ -72,6 +82,60 @@ function isNoSuchKeyError(err) {
|
|
|
72
82
|
}
|
|
73
83
|
return false;
|
|
74
84
|
}
|
|
85
|
+
function isNotFoundError(err) {
|
|
86
|
+
if (!err || typeof err !== "object") return false;
|
|
87
|
+
if ("name" in err && (err.name === "NotFound" || err.name === "NoSuchKey")) return true;
|
|
88
|
+
if ("$metadata" in err) {
|
|
89
|
+
const meta = err.$metadata;
|
|
90
|
+
if (meta?.httpStatusCode === 404) return true;
|
|
91
|
+
}
|
|
92
|
+
return false;
|
|
93
|
+
}
|
|
94
|
+
function isPreconditionFailedError(err) {
|
|
95
|
+
if (!err || typeof err !== "object") return false;
|
|
96
|
+
if ("name" in err && err.name === "PreconditionFailed") return true;
|
|
97
|
+
if ("Code" in err && err.Code === "PreconditionFailed") return true;
|
|
98
|
+
if ("$metadata" in err) {
|
|
99
|
+
const meta = err.$metadata;
|
|
100
|
+
if (meta?.httpStatusCode === 412) return true;
|
|
101
|
+
}
|
|
102
|
+
if ("message" in err && typeof err.message === "string") {
|
|
103
|
+
return err.message.includes("PreconditionFailed");
|
|
104
|
+
}
|
|
105
|
+
return false;
|
|
106
|
+
}
|
|
107
|
+
function resolveExpiresAt(expiresAt) {
|
|
108
|
+
if (expiresAt === null) return void 0;
|
|
109
|
+
if (!expiresAt) return void 0;
|
|
110
|
+
const parsed = new Date(expiresAt);
|
|
111
|
+
if (!Number.isFinite(parsed.getTime())) {
|
|
112
|
+
throw new Error("Invalid expiresAt value");
|
|
113
|
+
}
|
|
114
|
+
return parsed;
|
|
115
|
+
}
|
|
116
|
+
function toAttributes(path, obj) {
|
|
117
|
+
const {
|
|
118
|
+
ContentLength,
|
|
119
|
+
LastModified,
|
|
120
|
+
ETag,
|
|
121
|
+
ContentType,
|
|
122
|
+
CacheControl,
|
|
123
|
+
ContentDisposition,
|
|
124
|
+
Metadata,
|
|
125
|
+
Expires
|
|
126
|
+
} = obj;
|
|
127
|
+
return {
|
|
128
|
+
path,
|
|
129
|
+
...ContentLength !== void 0 ? { size: ContentLength } : {},
|
|
130
|
+
...LastModified ? { lastModified: LastModified.toISOString() } : {},
|
|
131
|
+
...ETag !== void 0 ? { etag: ETag } : {},
|
|
132
|
+
...ContentType ? { contentType: ContentType } : {},
|
|
133
|
+
...CacheControl ? { cacheControl: CacheControl } : {},
|
|
134
|
+
...ContentDisposition ? { contentDisposition: ContentDisposition } : {},
|
|
135
|
+
...Metadata ? { metadata: Metadata } : {},
|
|
136
|
+
...Expires ? { expiresAt: Expires.toISOString() } : {}
|
|
137
|
+
};
|
|
138
|
+
}
|
|
75
139
|
async function* listAllKeys(s3, bucket, prefix) {
|
|
76
140
|
let cursor;
|
|
77
141
|
while (true) {
|
|
@@ -111,6 +175,9 @@ var S3FileManager = class {
|
|
|
111
175
|
delimiter;
|
|
112
176
|
hooks;
|
|
113
177
|
authorizationMode;
|
|
178
|
+
lockFolderMoves;
|
|
179
|
+
lockPrefix;
|
|
180
|
+
lockTtlSeconds;
|
|
114
181
|
constructor(s3, options) {
|
|
115
182
|
this.s3 = s3;
|
|
116
183
|
this.bucket = options.bucket;
|
|
@@ -118,6 +185,9 @@ var S3FileManager = class {
|
|
|
118
185
|
this.rootPrefix = ensureTrailingDelimiter(trimSlashes(options.rootPrefix ?? ""), this.delimiter);
|
|
119
186
|
this.hooks = options.hooks;
|
|
120
187
|
this.authorizationMode = options.authorizationMode ?? "deny-by-default";
|
|
188
|
+
this.lockFolderMoves = options.lockFolderMoves ?? true;
|
|
189
|
+
this.lockPrefix = options.lockPrefix ?? ".s3kit/locks";
|
|
190
|
+
this.lockTtlSeconds = options.lockTtlSeconds ?? 60 * 15;
|
|
121
191
|
}
|
|
122
192
|
async authorize(args) {
|
|
123
193
|
const hasAuthHooks = Boolean(this.hooks?.authorize || this.hooks?.allowAction);
|
|
@@ -151,6 +221,87 @@ var S3FileManager = class {
|
|
|
151
221
|
}
|
|
152
222
|
return key.slice(this.rootPrefix.length);
|
|
153
223
|
}
|
|
224
|
+
lockKeyForPath(path) {
|
|
225
|
+
const safe = encodeURIComponent(path).replace(/%2F/g, "__");
|
|
226
|
+
const prefix = ensureTrailingDelimiter(trimSlashes(this.lockPrefix), this.delimiter);
|
|
227
|
+
return `${this.rootPrefix}${prefix}${safe}.json`;
|
|
228
|
+
}
|
|
229
|
+
async readFolderLockByKey(key) {
|
|
230
|
+
try {
|
|
231
|
+
const out = await this.s3.send(
|
|
232
|
+
new import_client_s3.HeadObjectCommand({
|
|
233
|
+
Bucket: this.bucket,
|
|
234
|
+
Key: key
|
|
235
|
+
})
|
|
236
|
+
);
|
|
237
|
+
const meta = out.Metadata ?? {};
|
|
238
|
+
const operation = meta.op === "folder.move" ? "folder.move" : void 0;
|
|
239
|
+
const fromPath = meta.from;
|
|
240
|
+
const toPath = meta.to;
|
|
241
|
+
const startedAt = meta.startedat;
|
|
242
|
+
const expiresAt = meta.expiresat ?? (out.Expires ? out.Expires.toISOString() : void 0);
|
|
243
|
+
if (!operation || !fromPath || !toPath || !startedAt || !expiresAt) return null;
|
|
244
|
+
return {
|
|
245
|
+
path: fromPath,
|
|
246
|
+
operation,
|
|
247
|
+
fromPath,
|
|
248
|
+
toPath,
|
|
249
|
+
startedAt,
|
|
250
|
+
expiresAt,
|
|
251
|
+
...meta.owner ? { owner: meta.owner } : {}
|
|
252
|
+
};
|
|
253
|
+
} catch (err) {
|
|
254
|
+
if (isNotFoundError(err)) return null;
|
|
255
|
+
throw err;
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
async acquireFolderMoveLock(fromPath, toPath, ctx) {
|
|
259
|
+
const startedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
260
|
+
const expiresAt = new Date(Date.now() + this.lockTtlSeconds * 1e3).toISOString();
|
|
261
|
+
const key = this.lockKeyForPath(fromPath);
|
|
262
|
+
const writeLock = async () => {
|
|
263
|
+
await this.s3.send(
|
|
264
|
+
new import_client_s3.PutObjectCommand({
|
|
265
|
+
Bucket: this.bucket,
|
|
266
|
+
Key: key,
|
|
267
|
+
ContentType: "application/json",
|
|
268
|
+
Expires: new Date(expiresAt),
|
|
269
|
+
Metadata: {
|
|
270
|
+
op: "folder.move",
|
|
271
|
+
from: fromPath,
|
|
272
|
+
to: toPath,
|
|
273
|
+
startedat: startedAt,
|
|
274
|
+
expiresat: expiresAt,
|
|
275
|
+
...ctx.userId ? { owner: String(ctx.userId) } : {}
|
|
276
|
+
},
|
|
277
|
+
IfNoneMatch: "*",
|
|
278
|
+
Body: ""
|
|
279
|
+
})
|
|
280
|
+
);
|
|
281
|
+
};
|
|
282
|
+
try {
|
|
283
|
+
await writeLock();
|
|
284
|
+
return key;
|
|
285
|
+
} catch (err) {
|
|
286
|
+
if (!isPreconditionFailedError(err)) throw err;
|
|
287
|
+
const existing = await this.readFolderLockByKey(key);
|
|
288
|
+
if (existing?.expiresAt) {
|
|
289
|
+
const exp = new Date(existing.expiresAt);
|
|
290
|
+
if (Number.isFinite(exp.getTime()) && exp.getTime() <= Date.now()) {
|
|
291
|
+
await this.s3.send(new import_client_s3.DeleteObjectCommand({ Bucket: this.bucket, Key: key }));
|
|
292
|
+
await writeLock();
|
|
293
|
+
return key;
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
throw new S3FileManagerConflictError("Folder rename already in progress");
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
async releaseFolderMoveLock(key) {
|
|
300
|
+
try {
|
|
301
|
+
await this.s3.send(new import_client_s3.DeleteObjectCommand({ Bucket: this.bucket, Key: key }));
|
|
302
|
+
} catch {
|
|
303
|
+
}
|
|
304
|
+
}
|
|
154
305
|
makeFolderEntry(path) {
|
|
155
306
|
const p = normalizePath(path);
|
|
156
307
|
const name = p === "" ? "" : p.split("/").at(-1) ?? "";
|
|
@@ -252,12 +403,39 @@ var S3FileManager = class {
|
|
|
252
403
|
await deleteKeysInBatches(this.s3, this.bucket, keys);
|
|
253
404
|
}
|
|
254
405
|
async deleteFiles(options, ctx = {}) {
|
|
255
|
-
const
|
|
256
|
-
|
|
257
|
-
|
|
406
|
+
const items = options.items ?? options.paths?.map((path) => ({ path }));
|
|
407
|
+
if (!items || items.length === 0) return;
|
|
408
|
+
const normalizedItems = items.map((item) => ({
|
|
409
|
+
path: normalizePath(item.path),
|
|
410
|
+
ifMatch: item.ifMatch,
|
|
411
|
+
ifNoneMatch: item.ifNoneMatch
|
|
412
|
+
}));
|
|
413
|
+
for (const item of normalizedItems) {
|
|
414
|
+
await this.authorize({ action: "file.delete", path: item.path, ctx });
|
|
415
|
+
}
|
|
416
|
+
const hasConditions = normalizedItems.some((item) => item.ifMatch || item.ifNoneMatch);
|
|
417
|
+
if (!hasConditions) {
|
|
418
|
+
const keys = normalizedItems.map((item) => this.pathToKey(item.path));
|
|
419
|
+
await deleteKeysInBatches(this.s3, this.bucket, keys);
|
|
420
|
+
return;
|
|
421
|
+
}
|
|
422
|
+
for (const item of normalizedItems) {
|
|
423
|
+
try {
|
|
424
|
+
await this.s3.send(
|
|
425
|
+
new import_client_s3.DeleteObjectCommand({
|
|
426
|
+
Bucket: this.bucket,
|
|
427
|
+
Key: this.pathToKey(item.path),
|
|
428
|
+
...item.ifMatch ? { IfMatch: item.ifMatch } : {},
|
|
429
|
+
...item.ifNoneMatch ? { IfNoneMatch: item.ifNoneMatch } : {}
|
|
430
|
+
})
|
|
431
|
+
);
|
|
432
|
+
} catch (err) {
|
|
433
|
+
if (isPreconditionFailedError(err)) {
|
|
434
|
+
throw new S3FileManagerConflictError("Delete conflict");
|
|
435
|
+
}
|
|
436
|
+
throw err;
|
|
437
|
+
}
|
|
258
438
|
}
|
|
259
|
-
const keys = paths.map((p) => this.pathToKey(p));
|
|
260
|
-
await deleteKeysInBatches(this.s3, this.bucket, keys);
|
|
261
439
|
}
|
|
262
440
|
async copy(options, ctx = {}) {
|
|
263
441
|
const isFolder = options.fromPath.endsWith(this.delimiter);
|
|
@@ -307,13 +485,21 @@ var S3FileManager = class {
|
|
|
307
485
|
await this.authorize({ action: "file.copy", fromPath, toPath, ctx });
|
|
308
486
|
const fromKey = this.pathToKey(fromPath);
|
|
309
487
|
const toKey = this.pathToKey(toPath);
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
488
|
+
try {
|
|
489
|
+
await this.s3.send(
|
|
490
|
+
new import_client_s3.CopyObjectCommand({
|
|
491
|
+
Bucket: this.bucket,
|
|
492
|
+
Key: toKey,
|
|
493
|
+
CopySource: encodeS3CopySource(this.bucket, fromKey),
|
|
494
|
+
...options.ifMatch ? { CopySourceIfMatch: options.ifMatch } : {}
|
|
495
|
+
})
|
|
496
|
+
);
|
|
497
|
+
} catch (err) {
|
|
498
|
+
if (isPreconditionFailedError(err)) {
|
|
499
|
+
throw new S3FileManagerConflictError("Copy conflict");
|
|
500
|
+
}
|
|
501
|
+
throw err;
|
|
502
|
+
}
|
|
317
503
|
}
|
|
318
504
|
async move(options, ctx = {}) {
|
|
319
505
|
const isFolder = options.fromPath.endsWith(this.delimiter);
|
|
@@ -323,19 +509,49 @@ var S3FileManager = class {
|
|
|
323
509
|
if (isFolder) {
|
|
324
510
|
const fromPathWithSlash = ensureTrailingDelimiter(fromPath, this.delimiter);
|
|
325
511
|
const toPathWithSlash = ensureTrailingDelimiter(toPath, this.delimiter);
|
|
512
|
+
let lockKey = null;
|
|
326
513
|
await this.authorize({
|
|
327
514
|
action: "folder.move",
|
|
328
515
|
fromPath: fromPathWithSlash,
|
|
329
516
|
toPath: toPathWithSlash,
|
|
330
517
|
ctx
|
|
331
518
|
});
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
519
|
+
try {
|
|
520
|
+
if (this.lockFolderMoves) {
|
|
521
|
+
lockKey = await this.acquireFolderMoveLock(fromPathWithSlash, toPathWithSlash, ctx);
|
|
522
|
+
}
|
|
523
|
+
await this.copy(options, ctx);
|
|
524
|
+
await this.deleteFolder({ path: fromPathWithSlash, recursive: true }, ctx);
|
|
525
|
+
return;
|
|
526
|
+
} finally {
|
|
527
|
+
if (lockKey) {
|
|
528
|
+
await this.releaseFolderMoveLock(lockKey);
|
|
529
|
+
}
|
|
530
|
+
}
|
|
335
531
|
}
|
|
336
532
|
await this.authorize({ action: "file.move", fromPath, toPath, ctx });
|
|
337
533
|
await this.copy(options, ctx);
|
|
338
|
-
|
|
534
|
+
try {
|
|
535
|
+
await this.deleteFiles(
|
|
536
|
+
{
|
|
537
|
+
items: [
|
|
538
|
+
{
|
|
539
|
+
path: fromPath,
|
|
540
|
+
...options.ifMatch ? { ifMatch: options.ifMatch } : {}
|
|
541
|
+
}
|
|
542
|
+
]
|
|
543
|
+
},
|
|
544
|
+
ctx
|
|
545
|
+
);
|
|
546
|
+
} catch (err) {
|
|
547
|
+
if (err instanceof S3FileManagerConflictError) {
|
|
548
|
+
try {
|
|
549
|
+
await this.deleteFiles({ paths: [toPath] }, ctx);
|
|
550
|
+
} catch {
|
|
551
|
+
}
|
|
552
|
+
}
|
|
553
|
+
throw err;
|
|
554
|
+
}
|
|
339
555
|
}
|
|
340
556
|
async prepareUploads(options, ctx = {}) {
|
|
341
557
|
const expiresIn = options.expiresInSeconds ?? 60 * 5;
|
|
@@ -344,19 +560,24 @@ var S3FileManager = class {
|
|
|
344
560
|
const path = normalizePath(item.path);
|
|
345
561
|
await this.authorize({ action: "upload.prepare", path, ctx });
|
|
346
562
|
const key = this.pathToKey(path);
|
|
563
|
+
const expiresAt = resolveExpiresAt(item.expiresAt);
|
|
347
564
|
const cmd = new import_client_s3.PutObjectCommand({
|
|
348
565
|
Bucket: this.bucket,
|
|
349
566
|
Key: key,
|
|
350
567
|
ContentType: item.contentType,
|
|
351
568
|
CacheControl: item.cacheControl,
|
|
352
569
|
ContentDisposition: item.contentDisposition,
|
|
353
|
-
Metadata: item.metadata
|
|
570
|
+
Metadata: item.metadata,
|
|
571
|
+
...expiresAt ? { Expires: expiresAt } : {},
|
|
572
|
+
...item.ifNoneMatch ? { IfNoneMatch: item.ifNoneMatch } : {}
|
|
354
573
|
});
|
|
355
574
|
const url = await (0, import_s3_request_presigner.getSignedUrl)(this.s3, cmd, { expiresIn });
|
|
356
575
|
const headers = {};
|
|
357
576
|
if (item.contentType) headers["Content-Type"] = item.contentType;
|
|
358
577
|
if (item.cacheControl) headers["Cache-Control"] = item.cacheControl;
|
|
359
578
|
if (item.contentDisposition) headers["Content-Disposition"] = item.contentDisposition;
|
|
579
|
+
if (expiresAt) headers.Expires = expiresAt.toUTCString();
|
|
580
|
+
if (item.ifNoneMatch) headers["If-None-Match"] = item.ifNoneMatch;
|
|
360
581
|
if (item.metadata) {
|
|
361
582
|
for (const [k, v] of Object.entries(item.metadata)) {
|
|
362
583
|
headers[`x-amz-meta-${k}`] = v;
|
|
@@ -371,6 +592,59 @@ var S3FileManager = class {
|
|
|
371
592
|
}
|
|
372
593
|
return result;
|
|
373
594
|
}
|
|
595
|
+
async getFileAttributes(options, ctx = {}) {
|
|
596
|
+
const path = normalizePath(options.path);
|
|
597
|
+
await this.authorize({ action: "file.attributes.get", path, ctx });
|
|
598
|
+
const key = this.pathToKey(path);
|
|
599
|
+
const out = await this.s3.send(
|
|
600
|
+
new import_client_s3.HeadObjectCommand({
|
|
601
|
+
Bucket: this.bucket,
|
|
602
|
+
Key: key
|
|
603
|
+
})
|
|
604
|
+
);
|
|
605
|
+
return toAttributes(path, out);
|
|
606
|
+
}
|
|
607
|
+
async setFileAttributes(options, ctx = {}) {
|
|
608
|
+
const path = normalizePath(options.path);
|
|
609
|
+
await this.authorize({ action: "file.attributes.set", path, ctx });
|
|
610
|
+
const key = this.pathToKey(path);
|
|
611
|
+
const current = await this.s3.send(
|
|
612
|
+
new import_client_s3.HeadObjectCommand({
|
|
613
|
+
Bucket: this.bucket,
|
|
614
|
+
Key: key
|
|
615
|
+
})
|
|
616
|
+
);
|
|
617
|
+
const baseMetadata = options.metadata ?? (current.Metadata ? { ...current.Metadata } : {});
|
|
618
|
+
const resolvedExpires = options.expiresAt === void 0 ? current.Expires : resolveExpiresAt(options.expiresAt);
|
|
619
|
+
try {
|
|
620
|
+
await this.s3.send(
|
|
621
|
+
new import_client_s3.CopyObjectCommand({
|
|
622
|
+
Bucket: this.bucket,
|
|
623
|
+
Key: key,
|
|
624
|
+
CopySource: encodeS3CopySource(this.bucket, key),
|
|
625
|
+
MetadataDirective: "REPLACE",
|
|
626
|
+
ContentType: options.contentType ?? current.ContentType,
|
|
627
|
+
CacheControl: options.cacheControl ?? current.CacheControl,
|
|
628
|
+
ContentDisposition: options.contentDisposition ?? current.ContentDisposition,
|
|
629
|
+
Metadata: baseMetadata,
|
|
630
|
+
...resolvedExpires ? { Expires: resolvedExpires } : {},
|
|
631
|
+
...options.ifMatch ? { CopySourceIfMatch: options.ifMatch } : {}
|
|
632
|
+
})
|
|
633
|
+
);
|
|
634
|
+
} catch (err) {
|
|
635
|
+
if (isPreconditionFailedError(err)) {
|
|
636
|
+
throw new S3FileManagerConflictError("Attribute update conflict");
|
|
637
|
+
}
|
|
638
|
+
throw err;
|
|
639
|
+
}
|
|
640
|
+
const updated = await this.s3.send(
|
|
641
|
+
new import_client_s3.HeadObjectCommand({
|
|
642
|
+
Bucket: this.bucket,
|
|
643
|
+
Key: key
|
|
644
|
+
})
|
|
645
|
+
);
|
|
646
|
+
return toAttributes(path, updated);
|
|
647
|
+
}
|
|
374
648
|
async search(options, ctx = {}) {
|
|
375
649
|
const query = options.query.toLowerCase().trim();
|
|
376
650
|
if (!query) {
|
|
@@ -443,10 +717,17 @@ var S3FileManager = class {
|
|
|
443
717
|
const expiresAt = new Date(Date.now() + expiresIn * 1e3).toISOString();
|
|
444
718
|
return { path, url, expiresAt };
|
|
445
719
|
}
|
|
720
|
+
async getFolderLock(options, ctx = {}) {
|
|
721
|
+
const path = ensureTrailingDelimiter(normalizePath(options.path), this.delimiter);
|
|
722
|
+
await this.authorize({ action: "folder.lock.get", path, ctx });
|
|
723
|
+
const key = this.lockKeyForPath(path);
|
|
724
|
+
return await this.readFolderLockByKey(key);
|
|
725
|
+
}
|
|
446
726
|
};
|
|
447
727
|
// Annotate the CommonJS export names for ESM import in node:
|
|
448
728
|
0 && (module.exports = {
|
|
449
729
|
S3FileManager,
|
|
450
|
-
S3FileManagerAuthorizationError
|
|
730
|
+
S3FileManagerAuthorizationError,
|
|
731
|
+
S3FileManagerConflictError
|
|
451
732
|
});
|
|
452
733
|
//# sourceMappingURL=index.cjs.map
|
package/dist/core/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/core/index.ts","../../src/core/manager.ts","../../src/core/errors.ts"],"sourcesContent":["export * from './types'\nexport * from './manager'\nexport * from './errors'\n","import {\n CopyObjectCommand,\n DeleteObjectCommand,\n DeleteObjectsCommand,\n ListObjectsV2Command,\n PutObjectCommand,\n S3Client,\n} from '@aws-sdk/client-s3'\nimport { GetObjectCommand } from '@aws-sdk/client-s3'\nimport { getSignedUrl } from '@aws-sdk/s3-request-presigner'\n\nimport type {\n S3CopyOptions,\n S3CreateFolderOptions,\n S3DeleteFilesOptions,\n S3DeleteFolderOptions,\n S3FileEntry,\n S3FileManagerAuthContext,\n S3FileManagerAuthorizationMode,\n S3FileManagerHooks,\n S3FileManagerOptions,\n S3FolderEntry,\n S3GetPreviewUrlOptions,\n S3GetPreviewUrlResult,\n S3ListOptions,\n S3ListResult,\n S3MoveOptions,\n S3PrepareUploadsOptions,\n S3PreparedUpload,\n S3SearchOptions,\n S3SearchResult,\n} from './types'\nimport { S3FileManagerAuthorizationError } from './errors'\n\nconst DEFAULT_DELIMITER = '/'\n\nfunction trimSlashes(input: string): string {\n return input.replace(/^\\/+/, '').replace(/\\/+$/, '')\n}\n\nfunction normalizePath(input: string): string {\n const raw = input.replace(/\\\\/g, '/')\n const noLeading = raw.replace(/^\\/+/, '')\n const segments = noLeading.split('/').filter((s) => s.length > 0)\n for (const seg of segments) {\n if (seg === '..') {\n throw new Error('Invalid path')\n }\n }\n return segments.join('/')\n}\n\nfunction ensureTrailingDelimiter(prefix: string, delimiter: string): string {\n if (prefix === '') return ''\n return prefix.endsWith(delimiter) ? prefix : `${prefix}${delimiter}`\n}\n\nfunction encodeS3CopySource(bucket: string, key: string): string {\n return encodeURIComponent(`${bucket}/${key}`).replace(/%2F/g, '/')\n}\n\nfunction isNoSuchKeyError(err: unknown): boolean {\n if (!err || typeof err !== 'object') return false\n if ('name' in err && err.name === 'NoSuchKey') return true\n if ('message' in err && typeof err.message === 'string') {\n return err.message.includes('The specified key does not exist')\n }\n return false\n}\n\nasync function* listAllKeys(\n s3: S3Client,\n bucket: string,\n prefix: string,\n): AsyncGenerator<string, void, void> {\n let cursor: string | undefined\n while (true) {\n const out = await s3.send(\n new ListObjectsV2Command({\n Bucket: bucket,\n Prefix: prefix,\n ContinuationToken: cursor,\n }),\n )\n\n for (const obj of out.Contents ?? []) {\n if (obj.Key) yield obj.Key\n }\n\n if (!out.IsTruncated) break\n cursor = out.NextContinuationToken\n }\n}\n\nasync function deleteKeysInBatches(s3: S3Client, bucket: string, keys: string[]): Promise<void> {\n const batchSize = 1000\n for (let i = 0; i < keys.length; i += batchSize) {\n const batch = keys.slice(i, i + batchSize)\n await s3.send(\n new DeleteObjectsCommand({\n Bucket: bucket,\n Delete: {\n Objects: batch.map((Key) => ({ Key })),\n Quiet: true,\n },\n }),\n )\n }\n}\n\nexport class S3FileManager<FileExtra = unknown, FolderExtra = unknown> {\n private readonly s3: S3Client\n private readonly bucket: string\n private readonly rootPrefix: string\n private readonly delimiter: string\n private readonly hooks: S3FileManagerHooks<FileExtra, FolderExtra> | undefined\n private readonly authorizationMode: S3FileManagerAuthorizationMode\n\n constructor(s3: S3Client, options: S3FileManagerOptions<FileExtra, FolderExtra>) {\n this.s3 = s3\n this.bucket = options.bucket\n this.delimiter = options.delimiter ?? DEFAULT_DELIMITER\n this.rootPrefix = ensureTrailingDelimiter(trimSlashes(options.rootPrefix ?? ''), this.delimiter)\n this.hooks = options.hooks\n this.authorizationMode = options.authorizationMode ?? 'deny-by-default'\n }\n\n private async authorize(\n args: Parameters<NonNullable<S3FileManagerHooks['authorize']>>[0],\n ): Promise<void> {\n const hasAuthHooks = Boolean(this.hooks?.authorize || this.hooks?.allowAction)\n\n if (this.hooks?.authorize) {\n const result = await this.hooks.authorize(args)\n if (result === false) {\n throw new S3FileManagerAuthorizationError('Unauthorized', 401, 'unauthorized')\n }\n }\n\n if (this.hooks?.allowAction) {\n const allowed = await this.hooks.allowAction(args)\n if (allowed === false) {\n throw new S3FileManagerAuthorizationError('Forbidden', 403, 'forbidden')\n }\n }\n\n if (!hasAuthHooks && this.authorizationMode === 'deny-by-default') {\n throw new S3FileManagerAuthorizationError('Unauthorized', 401, 'unauthorized')\n }\n }\n\n private pathToKey(path: string): string {\n const p = normalizePath(path)\n return `${this.rootPrefix}${p}`\n }\n\n private pathToFolderPrefix(path: string): string {\n const key = this.pathToKey(path)\n return ensureTrailingDelimiter(key, this.delimiter)\n }\n\n private keyToPath(key: string): string {\n if (!key.startsWith(this.rootPrefix)) {\n throw new Error('Key is outside of rootPrefix')\n }\n return key.slice(this.rootPrefix.length)\n }\n\n private makeFolderEntry(path: string): S3FolderEntry<FolderExtra> {\n const p = normalizePath(path)\n const name = p === '' ? '' : (p.split('/').at(-1) ?? '')\n return {\n type: 'folder',\n path: p === '' ? '' : ensureTrailingDelimiter(p, this.delimiter),\n name,\n }\n }\n\n private makeFileEntryFromKey(\n key: string,\n obj: {\n Size?: number\n LastModified?: Date\n ETag?: string\n },\n ): S3FileEntry<FileExtra> {\n const path = this.keyToPath(key)\n const name = path.split('/').at(-1) ?? ''\n return {\n type: 'file',\n path,\n name,\n ...(obj.Size !== undefined ? { size: obj.Size } : {}),\n ...(obj.LastModified ? { lastModified: obj.LastModified.toISOString() } : {}),\n ...(obj.ETag !== undefined ? { etag: obj.ETag } : {}),\n }\n }\n\n async list(\n options: S3ListOptions,\n ctx: S3FileManagerAuthContext = {},\n ): Promise<S3ListResult<FileExtra, FolderExtra>> {\n const path = normalizePath(options.path)\n await this.authorize({ action: 'list', path, ctx })\n\n const prefix = path === '' ? this.rootPrefix : this.pathToFolderPrefix(path)\n\n const out = await this.s3.send(\n new ListObjectsV2Command({\n Bucket: this.bucket,\n Prefix: prefix,\n Delimiter: this.delimiter,\n ContinuationToken: options.cursor,\n MaxKeys: options.limit,\n }),\n )\n\n const folders: Array<S3FolderEntry<FolderExtra>> = (\n (out.CommonPrefixes ?? []) as Array<{ Prefix?: string }>\n )\n .map((cp: { Prefix?: string }) => cp.Prefix)\n .filter((p: string | undefined): p is string => typeof p === 'string')\n .map((p: string) => {\n const rel = this.keyToPath(p)\n const folderPath = ensureTrailingDelimiter(trimSlashes(rel), this.delimiter)\n return this.makeFolderEntry(folderPath)\n })\n\n const files: Array<S3FileEntry<FileExtra>> = (\n (out.Contents ?? []) as Array<{\n Key?: string\n Size?: number\n LastModified?: Date\n ETag?: string\n }>\n )\n .filter((obj: { Key?: string }) => typeof obj.Key === 'string')\n .filter((obj: { Key?: string }) => obj.Key !== prefix)\n .map((obj) => this.makeFileEntryFromKey(obj.Key as string, obj))\n\n for (const folder of folders) {\n await this.hooks?.decorateFolder?.(folder, {\n path: folder.path,\n prefix: this.pathToFolderPrefix(folder.path),\n })\n }\n\n for (const file of files) {\n await this.hooks?.decorateFile?.(file, {\n path: file.path,\n key: this.pathToKey(file.path),\n })\n }\n\n const entries = [...folders, ...files].sort((a, b) => {\n if (a.type !== b.type) return a.type === 'folder' ? -1 : 1\n return a.name.localeCompare(b.name)\n })\n\n return {\n path,\n entries,\n ...(out.IsTruncated && out.NextContinuationToken\n ? { nextCursor: out.NextContinuationToken }\n : {}),\n }\n }\n\n async createFolder(\n options: S3CreateFolderOptions,\n ctx: S3FileManagerAuthContext = {},\n ): Promise<void> {\n const path = ensureTrailingDelimiter(normalizePath(options.path), this.delimiter)\n await this.authorize({ action: 'folder.create', path, ctx })\n\n const key = this.pathToFolderPrefix(path)\n await this.s3.send(\n new PutObjectCommand({\n Bucket: this.bucket,\n Key: key,\n Body: '',\n }),\n )\n }\n\n async deleteFolder(\n options: S3DeleteFolderOptions,\n ctx: S3FileManagerAuthContext = {},\n ): Promise<void> {\n const path = ensureTrailingDelimiter(normalizePath(options.path), this.delimiter)\n await this.authorize({ action: 'folder.delete', path, ctx })\n\n const prefix = this.pathToFolderPrefix(path)\n\n if (!options.recursive) {\n const out = await this.s3.send(\n new ListObjectsV2Command({\n Bucket: this.bucket,\n Prefix: prefix,\n MaxKeys: 2,\n }),\n )\n\n const keys = ((out.Contents ?? []) as Array<{ Key?: string }>)\n .map((o: { Key?: string }) => o.Key)\n .filter((k: string | undefined): k is string => typeof k === 'string' && k !== prefix)\n\n if (keys.length > 0) {\n throw new Error('Folder is not empty')\n }\n\n await this.s3.send(new DeleteObjectCommand({ Bucket: this.bucket, Key: prefix }))\n return\n }\n\n const keys: string[] = []\n for await (const key of listAllKeys(this.s3, this.bucket, prefix)) {\n keys.push(key)\n }\n\n if (keys.length === 0) return\n await deleteKeysInBatches(this.s3, this.bucket, keys)\n }\n\n async deleteFiles(\n options: S3DeleteFilesOptions,\n ctx: S3FileManagerAuthContext = {},\n ): Promise<void> {\n const paths = options.paths.map((p) => normalizePath(p))\n for (const path of paths) {\n await this.authorize({ action: 'file.delete', path, ctx })\n }\n\n const keys = paths.map((p) => this.pathToKey(p))\n await deleteKeysInBatches(this.s3, this.bucket, keys)\n }\n\n async copy(options: S3CopyOptions, ctx: S3FileManagerAuthContext = {}): Promise<void> {\n const isFolder = options.fromPath.endsWith(this.delimiter)\n const fromPath = normalizePath(options.fromPath)\n const toPath = normalizePath(options.toPath)\n if (fromPath === toPath) return\n\n if (isFolder) {\n const fromPathWithSlash = ensureTrailingDelimiter(fromPath, this.delimiter)\n const toPathWithSlash = ensureTrailingDelimiter(toPath, this.delimiter)\n\n await this.authorize({\n action: 'folder.copy',\n fromPath: fromPathWithSlash,\n toPath: toPathWithSlash,\n ctx,\n })\n\n const fromPrefix = this.pathToFolderPrefix(fromPathWithSlash)\n const toPrefix = this.pathToFolderPrefix(toPathWithSlash)\n\n // Try copying the folder object itself\n try {\n await this.s3.send(\n new CopyObjectCommand({\n Bucket: this.bucket,\n Key: toPrefix,\n CopySource: encodeS3CopySource(this.bucket, fromPrefix),\n }),\n )\n } catch {\n // Ignore errors if the source folder object doesn't exist\n }\n\n // Copy all children\n for await (const sourceKey of listAllKeys(this.s3, this.bucket, fromPrefix)) {\n if (sourceKey === fromPrefix) continue\n\n const relKey = sourceKey.slice(fromPrefix.length)\n const destKey = toPrefix + relKey\n\n try {\n await this.s3.send(\n new CopyObjectCommand({\n Bucket: this.bucket,\n Key: destKey,\n CopySource: encodeS3CopySource(this.bucket, sourceKey),\n }),\n )\n } catch (err) {\n if (isNoSuchKeyError(err)) continue\n throw err\n }\n }\n return\n }\n\n await this.authorize({ action: 'file.copy', fromPath, toPath, ctx })\n\n const fromKey = this.pathToKey(fromPath)\n const toKey = this.pathToKey(toPath)\n\n await this.s3.send(\n new CopyObjectCommand({\n Bucket: this.bucket,\n Key: toKey,\n CopySource: encodeS3CopySource(this.bucket, fromKey),\n }),\n )\n }\n\n async move(options: S3MoveOptions, ctx: S3FileManagerAuthContext = {}): Promise<void> {\n const isFolder = options.fromPath.endsWith(this.delimiter)\n const fromPath = normalizePath(options.fromPath)\n const toPath = normalizePath(options.toPath)\n if (fromPath === toPath) return\n\n if (isFolder) {\n const fromPathWithSlash = ensureTrailingDelimiter(fromPath, this.delimiter)\n const toPathWithSlash = ensureTrailingDelimiter(toPath, this.delimiter)\n\n await this.authorize({\n action: 'folder.move',\n fromPath: fromPathWithSlash,\n toPath: toPathWithSlash,\n ctx,\n })\n\n // Delegate to copy (handles recursion)\n await this.copy(options, ctx)\n\n // Delete original folder recursively\n await this.deleteFolder({ path: fromPathWithSlash, recursive: true }, ctx)\n return\n }\n\n await this.authorize({ action: 'file.move', fromPath, toPath, ctx })\n\n await this.copy(options, ctx)\n await this.deleteFiles({ paths: [fromPath] }, ctx)\n }\n\n async prepareUploads(\n options: S3PrepareUploadsOptions,\n ctx: S3FileManagerAuthContext = {},\n ): Promise<S3PreparedUpload[]> {\n const expiresIn = options.expiresInSeconds ?? 60 * 5\n\n const result: S3PreparedUpload[] = []\n\n for (const item of options.items) {\n const path = normalizePath(item.path)\n await this.authorize({ action: 'upload.prepare', path, ctx })\n\n const key = this.pathToKey(path)\n\n const cmd = new PutObjectCommand({\n Bucket: this.bucket,\n Key: key,\n ContentType: item.contentType,\n CacheControl: item.cacheControl,\n ContentDisposition: item.contentDisposition,\n Metadata: item.metadata,\n })\n\n const url = await getSignedUrl(this.s3, cmd, { expiresIn })\n const headers: Record<string, string> = {}\n if (item.contentType) headers['Content-Type'] = item.contentType\n if (item.cacheControl) headers['Cache-Control'] = item.cacheControl\n if (item.contentDisposition) headers['Content-Disposition'] = item.contentDisposition\n if (item.metadata) {\n for (const [k, v] of Object.entries(item.metadata)) {\n headers[`x-amz-meta-${k}`] = v\n }\n }\n\n result.push({\n path,\n url,\n method: 'PUT',\n headers,\n })\n }\n\n return result\n }\n\n async search(\n options: S3SearchOptions,\n ctx: S3FileManagerAuthContext = {},\n ): Promise<S3SearchResult<FileExtra, FolderExtra>> {\n const query = options.query.toLowerCase().trim()\n if (!query) {\n return { query: options.query, entries: [] }\n }\n\n await this.authorize({ action: 'search', ctx })\n\n const searchPrefix = options.path\n ? this.pathToFolderPrefix(normalizePath(options.path))\n : this.rootPrefix\n\n const entries: Array<S3FileEntry<FileExtra>> = []\n\n // Search through objects (cursor is the underlying S3 continuation token).\n // Results are returned in the natural S3 listing order (lexicographic by key),\n // which keeps pagination stable.\n const limit = options.limit ?? 500\n const recursive = options.recursive !== false\n let cursor: string | undefined = options.cursor\n let nextCursor: string | undefined\n\n while (entries.length < limit) {\n const out = await this.s3.send(\n new ListObjectsV2Command({\n Bucket: this.bucket,\n Prefix: searchPrefix,\n ContinuationToken: cursor,\n MaxKeys: 1000, // Fetch more to filter\n }),\n )\n\n nextCursor =\n out.IsTruncated && out.NextContinuationToken ? out.NextContinuationToken : undefined\n\n // Process files\n for (const obj of out.Contents ?? []) {\n if (!obj.Key || obj.Key === searchPrefix) continue\n\n const path = this.keyToPath(obj.Key)\n const name = path.split('/').at(-1) ?? ''\n\n if (!recursive && options.path) {\n const base = ensureTrailingDelimiter(normalizePath(options.path), this.delimiter)\n const rel = path.startsWith(base) ? path.slice(base.length) : path\n if (rel.includes(this.delimiter)) continue\n }\n\n if (!recursive && !options.path) {\n if (path.includes(this.delimiter)) continue\n }\n\n // Check if file name matches search query\n if (name.toLowerCase().includes(query)) {\n const fileEntry = this.makeFileEntryFromKey(obj.Key, {\n ...(obj.Size !== undefined ? { Size: obj.Size } : {}),\n ...(obj.LastModified !== undefined ? { LastModified: obj.LastModified } : {}),\n ...(obj.ETag !== undefined ? { ETag: obj.ETag } : {}),\n })\n await this.hooks?.decorateFile?.(fileEntry, {\n path: fileEntry.path,\n key: this.pathToKey(fileEntry.path),\n })\n entries.push(fileEntry)\n }\n\n if (entries.length >= limit) break\n }\n\n if (!out.IsTruncated || !out.NextContinuationToken) break\n cursor = out.NextContinuationToken\n }\n\n return {\n query: options.query,\n entries,\n ...(nextCursor ? { nextCursor } : {}),\n }\n }\n\n async getPreviewUrl(\n options: S3GetPreviewUrlOptions,\n ctx: S3FileManagerAuthContext = {},\n ): Promise<S3GetPreviewUrlResult> {\n const path = normalizePath(options.path)\n await this.authorize({ action: 'preview.get', path, ctx })\n\n const expiresIn = options.expiresInSeconds ?? 60 * 5\n const key = this.pathToKey(path)\n\n const cmd = new GetObjectCommand({\n Bucket: this.bucket,\n Key: key,\n ResponseContentDisposition: options.inline ? 'inline' : 'attachment',\n })\n\n const url = await getSignedUrl(this.s3, cmd, { expiresIn })\n\n const expiresAt = new Date(Date.now() + expiresIn * 1000).toISOString()\n return { path, url, expiresAt }\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"],"mappings":"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","names":["import_client_s3","keys"]}
|
|
1
|
+
{"version":3,"sources":["../../src/core/index.ts","../../src/core/manager.ts","../../src/core/errors.ts"],"sourcesContent":["export * from './types'\nexport * from './manager'\nexport * from './errors'\n","import {\n CopyObjectCommand,\n DeleteObjectCommand,\n DeleteObjectsCommand,\n HeadObjectCommand,\n type HeadObjectCommandOutput,\n ListObjectsV2Command,\n PutObjectCommand,\n S3Client,\n} from '@aws-sdk/client-s3'\nimport { GetObjectCommand } from '@aws-sdk/client-s3'\nimport { getSignedUrl } from '@aws-sdk/s3-request-presigner'\n\nimport type {\n S3CopyOptions,\n S3CreateFolderOptions,\n S3DeleteFilesOptions,\n S3DeleteFolderOptions,\n S3FileAttributes,\n S3FileEntry,\n S3FileManagerAuthContext,\n S3FileManagerAuthorizationMode,\n S3FileManagerHooks,\n S3FileManagerOptions,\n S3FolderLock,\n S3FolderEntry,\n S3GetFolderLockOptions,\n S3GetFileAttributesOptions,\n S3GetPreviewUrlOptions,\n S3GetPreviewUrlResult,\n S3ListOptions,\n S3ListResult,\n S3MoveOptions,\n S3PrepareUploadsOptions,\n S3PreparedUpload,\n S3SearchOptions,\n S3SearchResult,\n S3SetFileAttributesOptions,\n} from './types'\nimport { S3FileManagerAuthorizationError, S3FileManagerConflictError } from './errors'\n\nconst DEFAULT_DELIMITER = '/'\n\nfunction trimSlashes(input: string): string {\n return input.replace(/^\\/+/, '').replace(/\\/+$/, '')\n}\n\nfunction normalizePath(input: string): string {\n const raw = input.replace(/\\\\/g, '/')\n const noLeading = raw.replace(/^\\/+/, '')\n const segments = noLeading.split('/').filter((s) => s.length > 0)\n for (const seg of segments) {\n if (seg === '..') {\n throw new Error('Invalid path')\n }\n }\n return segments.join('/')\n}\n\nfunction ensureTrailingDelimiter(prefix: string, delimiter: string): string {\n if (prefix === '') return ''\n return prefix.endsWith(delimiter) ? prefix : `${prefix}${delimiter}`\n}\n\nfunction encodeS3CopySource(bucket: string, key: string): string {\n return encodeURIComponent(`${bucket}/${key}`).replace(/%2F/g, '/')\n}\n\nfunction isNoSuchKeyError(err: unknown): boolean {\n if (!err || typeof err !== 'object') return false\n if ('name' in err && err.name === 'NoSuchKey') return true\n if ('message' in err && typeof err.message === 'string') {\n return err.message.includes('The specified key does not exist')\n }\n return false\n}\n\nfunction isNotFoundError(err: unknown): boolean {\n if (!err || typeof err !== 'object') return false\n if ('name' in err && (err.name === 'NotFound' || err.name === 'NoSuchKey')) return true\n if ('$metadata' in err) {\n const meta = (err as { $metadata?: { httpStatusCode?: number } }).$metadata\n if (meta?.httpStatusCode === 404) return true\n }\n return false\n}\n\nfunction isPreconditionFailedError(err: unknown): boolean {\n if (!err || typeof err !== 'object') return false\n if ('name' in err && err.name === 'PreconditionFailed') return true\n if ('Code' in err && err.Code === 'PreconditionFailed') return true\n if ('$metadata' in err) {\n const meta = (err as { $metadata?: { httpStatusCode?: number } }).$metadata\n if (meta?.httpStatusCode === 412) return true\n }\n if ('message' in err && typeof err.message === 'string') {\n return err.message.includes('PreconditionFailed')\n }\n return false\n}\n\nfunction resolveExpiresAt(expiresAt: string | null | undefined): Date | undefined {\n if (expiresAt === null) return undefined\n if (!expiresAt) return undefined\n const parsed = new Date(expiresAt)\n if (!Number.isFinite(parsed.getTime())) {\n throw new Error('Invalid expiresAt value')\n }\n return parsed\n}\n\nfunction toAttributes(path: string, obj: HeadObjectCommandOutput): S3FileAttributes {\n const {\n ContentLength,\n LastModified,\n ETag,\n ContentType,\n CacheControl,\n ContentDisposition,\n Metadata,\n Expires,\n } = obj as {\n ContentLength?: number\n LastModified?: Date\n ETag?: string\n ContentType?: string\n CacheControl?: string\n ContentDisposition?: string\n Metadata?: Record<string, string>\n Expires?: Date\n }\n\n return {\n path,\n ...(ContentLength !== undefined ? { size: ContentLength } : {}),\n ...(LastModified ? { lastModified: LastModified.toISOString() } : {}),\n ...(ETag !== undefined ? { etag: ETag } : {}),\n ...(ContentType ? { contentType: ContentType } : {}),\n ...(CacheControl ? { cacheControl: CacheControl } : {}),\n ...(ContentDisposition ? { contentDisposition: ContentDisposition } : {}),\n ...(Metadata ? { metadata: Metadata } : {}),\n ...(Expires ? { expiresAt: Expires.toISOString() } : {}),\n }\n}\n\nasync function* listAllKeys(\n s3: S3Client,\n bucket: string,\n prefix: string,\n): AsyncGenerator<string, void, void> {\n let cursor: string | undefined\n while (true) {\n const out = await s3.send(\n new ListObjectsV2Command({\n Bucket: bucket,\n Prefix: prefix,\n ContinuationToken: cursor,\n }),\n )\n\n for (const obj of out.Contents ?? []) {\n if (obj.Key) yield obj.Key\n }\n\n if (!out.IsTruncated) break\n cursor = out.NextContinuationToken\n }\n}\n\nasync function deleteKeysInBatches(s3: S3Client, bucket: string, keys: string[]): Promise<void> {\n const batchSize = 1000\n for (let i = 0; i < keys.length; i += batchSize) {\n const batch = keys.slice(i, i + batchSize)\n await s3.send(\n new DeleteObjectsCommand({\n Bucket: bucket,\n Delete: {\n Objects: batch.map((Key) => ({ Key })),\n Quiet: true,\n },\n }),\n )\n }\n}\n\nexport class S3FileManager<FileExtra = unknown, FolderExtra = unknown> {\n private readonly s3: S3Client\n private readonly bucket: string\n private readonly rootPrefix: string\n private readonly delimiter: string\n private readonly hooks: S3FileManagerHooks<FileExtra, FolderExtra> | undefined\n private readonly authorizationMode: S3FileManagerAuthorizationMode\n private readonly lockFolderMoves: boolean\n private readonly lockPrefix: string\n private readonly lockTtlSeconds: number\n\n constructor(s3: S3Client, options: S3FileManagerOptions<FileExtra, FolderExtra>) {\n this.s3 = s3\n this.bucket = options.bucket\n this.delimiter = options.delimiter ?? DEFAULT_DELIMITER\n this.rootPrefix = ensureTrailingDelimiter(trimSlashes(options.rootPrefix ?? ''), this.delimiter)\n this.hooks = options.hooks\n this.authorizationMode = options.authorizationMode ?? 'deny-by-default'\n this.lockFolderMoves = options.lockFolderMoves ?? true\n this.lockPrefix = options.lockPrefix ?? '.s3kit/locks'\n this.lockTtlSeconds = options.lockTtlSeconds ?? 60 * 15\n }\n\n private async authorize(\n args: Parameters<NonNullable<S3FileManagerHooks['authorize']>>[0],\n ): Promise<void> {\n const hasAuthHooks = Boolean(this.hooks?.authorize || this.hooks?.allowAction)\n\n if (this.hooks?.authorize) {\n const result = await this.hooks.authorize(args)\n if (result === false) {\n throw new S3FileManagerAuthorizationError('Unauthorized', 401, 'unauthorized')\n }\n }\n\n if (this.hooks?.allowAction) {\n const allowed = await this.hooks.allowAction(args)\n if (allowed === false) {\n throw new S3FileManagerAuthorizationError('Forbidden', 403, 'forbidden')\n }\n }\n\n if (!hasAuthHooks && this.authorizationMode === 'deny-by-default') {\n throw new S3FileManagerAuthorizationError('Unauthorized', 401, 'unauthorized')\n }\n }\n\n private pathToKey(path: string): string {\n const p = normalizePath(path)\n return `${this.rootPrefix}${p}`\n }\n\n private pathToFolderPrefix(path: string): string {\n const key = this.pathToKey(path)\n return ensureTrailingDelimiter(key, this.delimiter)\n }\n\n private keyToPath(key: string): string {\n if (!key.startsWith(this.rootPrefix)) {\n throw new Error('Key is outside of rootPrefix')\n }\n return key.slice(this.rootPrefix.length)\n }\n\n private lockKeyForPath(path: string): string {\n const safe = encodeURIComponent(path).replace(/%2F/g, '__')\n const prefix = ensureTrailingDelimiter(trimSlashes(this.lockPrefix), this.delimiter)\n return `${this.rootPrefix}${prefix}${safe}.json`\n }\n\n private async readFolderLockByKey(key: string): Promise<S3FolderLock | null> {\n try {\n const out = await this.s3.send(\n new HeadObjectCommand({\n Bucket: this.bucket,\n Key: key,\n }),\n )\n const meta = out.Metadata ?? {}\n const operation = meta.op === 'folder.move' ? 'folder.move' : undefined\n const fromPath = meta.from\n const toPath = meta.to\n const startedAt = meta.startedat\n const expiresAt = meta.expiresat ?? (out.Expires ? out.Expires.toISOString() : undefined)\n if (!operation || !fromPath || !toPath || !startedAt || !expiresAt) return null\n return {\n path: fromPath,\n operation,\n fromPath,\n toPath,\n startedAt,\n expiresAt,\n ...(meta.owner ? { owner: meta.owner } : {}),\n }\n } catch (err) {\n if (isNotFoundError(err)) return null\n throw err\n }\n }\n\n private async acquireFolderMoveLock(\n fromPath: string,\n toPath: string,\n ctx: S3FileManagerAuthContext,\n ): Promise<string> {\n const startedAt = new Date().toISOString()\n const expiresAt = new Date(Date.now() + this.lockTtlSeconds * 1000).toISOString()\n const key = this.lockKeyForPath(fromPath)\n\n const writeLock = async () => {\n await this.s3.send(\n new PutObjectCommand({\n Bucket: this.bucket,\n Key: key,\n ContentType: 'application/json',\n Expires: new Date(expiresAt),\n Metadata: {\n op: 'folder.move',\n from: fromPath,\n to: toPath,\n startedat: startedAt,\n expiresat: expiresAt,\n ...(ctx.userId ? { owner: String(ctx.userId) } : {}),\n },\n IfNoneMatch: '*',\n Body: '',\n }),\n )\n }\n\n try {\n await writeLock()\n return key\n } catch (err) {\n if (!isPreconditionFailedError(err)) throw err\n const existing = await this.readFolderLockByKey(key)\n if (existing?.expiresAt) {\n const exp = new Date(existing.expiresAt)\n if (Number.isFinite(exp.getTime()) && exp.getTime() <= Date.now()) {\n await this.s3.send(new DeleteObjectCommand({ Bucket: this.bucket, Key: key }))\n await writeLock()\n return key\n }\n }\n throw new S3FileManagerConflictError('Folder rename already in progress')\n }\n }\n\n private async releaseFolderMoveLock(key: string): Promise<void> {\n try {\n await this.s3.send(new DeleteObjectCommand({ Bucket: this.bucket, Key: key }))\n } catch {\n // Best effort cleanup\n }\n }\n\n private makeFolderEntry(path: string): S3FolderEntry<FolderExtra> {\n const p = normalizePath(path)\n const name = p === '' ? '' : (p.split('/').at(-1) ?? '')\n return {\n type: 'folder',\n path: p === '' ? '' : ensureTrailingDelimiter(p, this.delimiter),\n name,\n }\n }\n\n private makeFileEntryFromKey(\n key: string,\n obj: {\n Size?: number\n LastModified?: Date\n ETag?: string\n },\n ): S3FileEntry<FileExtra> {\n const path = this.keyToPath(key)\n const name = path.split('/').at(-1) ?? ''\n return {\n type: 'file',\n path,\n name,\n ...(obj.Size !== undefined ? { size: obj.Size } : {}),\n ...(obj.LastModified ? { lastModified: obj.LastModified.toISOString() } : {}),\n ...(obj.ETag !== undefined ? { etag: obj.ETag } : {}),\n }\n }\n\n async list(\n options: S3ListOptions,\n ctx: S3FileManagerAuthContext = {},\n ): Promise<S3ListResult<FileExtra, FolderExtra>> {\n const path = normalizePath(options.path)\n await this.authorize({ action: 'list', path, ctx })\n\n const prefix = path === '' ? this.rootPrefix : this.pathToFolderPrefix(path)\n\n const out = await this.s3.send(\n new ListObjectsV2Command({\n Bucket: this.bucket,\n Prefix: prefix,\n Delimiter: this.delimiter,\n ContinuationToken: options.cursor,\n MaxKeys: options.limit,\n }),\n )\n\n const folders: Array<S3FolderEntry<FolderExtra>> = (\n (out.CommonPrefixes ?? []) as Array<{ Prefix?: string }>\n )\n .map((cp: { Prefix?: string }) => cp.Prefix)\n .filter((p: string | undefined): p is string => typeof p === 'string')\n .map((p: string) => {\n const rel = this.keyToPath(p)\n const folderPath = ensureTrailingDelimiter(trimSlashes(rel), this.delimiter)\n return this.makeFolderEntry(folderPath)\n })\n\n const files: Array<S3FileEntry<FileExtra>> = (\n (out.Contents ?? []) as Array<{\n Key?: string\n Size?: number\n LastModified?: Date\n ETag?: string\n }>\n )\n .filter((obj: { Key?: string }) => typeof obj.Key === 'string')\n .filter((obj: { Key?: string }) => obj.Key !== prefix)\n .map((obj) => this.makeFileEntryFromKey(obj.Key as string, obj))\n\n for (const folder of folders) {\n await this.hooks?.decorateFolder?.(folder, {\n path: folder.path,\n prefix: this.pathToFolderPrefix(folder.path),\n })\n }\n\n for (const file of files) {\n await this.hooks?.decorateFile?.(file, {\n path: file.path,\n key: this.pathToKey(file.path),\n })\n }\n\n const entries = [...folders, ...files].sort((a, b) => {\n if (a.type !== b.type) return a.type === 'folder' ? -1 : 1\n return a.name.localeCompare(b.name)\n })\n\n return {\n path,\n entries,\n ...(out.IsTruncated && out.NextContinuationToken\n ? { nextCursor: out.NextContinuationToken }\n : {}),\n }\n }\n\n async createFolder(\n options: S3CreateFolderOptions,\n ctx: S3FileManagerAuthContext = {},\n ): Promise<void> {\n const path = ensureTrailingDelimiter(normalizePath(options.path), this.delimiter)\n await this.authorize({ action: 'folder.create', path, ctx })\n\n const key = this.pathToFolderPrefix(path)\n await this.s3.send(\n new PutObjectCommand({\n Bucket: this.bucket,\n Key: key,\n Body: '',\n }),\n )\n }\n\n async deleteFolder(\n options: S3DeleteFolderOptions,\n ctx: S3FileManagerAuthContext = {},\n ): Promise<void> {\n const path = ensureTrailingDelimiter(normalizePath(options.path), this.delimiter)\n await this.authorize({ action: 'folder.delete', path, ctx })\n\n const prefix = this.pathToFolderPrefix(path)\n\n if (!options.recursive) {\n const out = await this.s3.send(\n new ListObjectsV2Command({\n Bucket: this.bucket,\n Prefix: prefix,\n MaxKeys: 2,\n }),\n )\n\n const keys = ((out.Contents ?? []) as Array<{ Key?: string }>)\n .map((o: { Key?: string }) => o.Key)\n .filter((k: string | undefined): k is string => typeof k === 'string' && k !== prefix)\n\n if (keys.length > 0) {\n throw new Error('Folder is not empty')\n }\n\n await this.s3.send(new DeleteObjectCommand({ Bucket: this.bucket, Key: prefix }))\n return\n }\n\n const keys: string[] = []\n for await (const key of listAllKeys(this.s3, this.bucket, prefix)) {\n keys.push(key)\n }\n\n if (keys.length === 0) return\n await deleteKeysInBatches(this.s3, this.bucket, keys)\n }\n\n async deleteFiles(\n options: S3DeleteFilesOptions,\n ctx: S3FileManagerAuthContext = {},\n ): Promise<void> {\n const items: Array<{ path: string; ifMatch?: string; ifNoneMatch?: string }> | undefined =\n options.items ?? options.paths?.map((path) => ({ path }))\n if (!items || items.length === 0) return\n\n const normalizedItems = items.map((item) => ({\n path: normalizePath(item.path),\n ifMatch: item.ifMatch,\n ifNoneMatch: item.ifNoneMatch,\n }))\n\n for (const item of normalizedItems) {\n await this.authorize({ action: 'file.delete', path: item.path, ctx })\n }\n\n const hasConditions = normalizedItems.some((item) => item.ifMatch || item.ifNoneMatch)\n if (!hasConditions) {\n const keys = normalizedItems.map((item) => this.pathToKey(item.path))\n await deleteKeysInBatches(this.s3, this.bucket, keys)\n return\n }\n\n for (const item of normalizedItems) {\n try {\n await this.s3.send(\n new DeleteObjectCommand({\n Bucket: this.bucket,\n Key: this.pathToKey(item.path),\n ...(item.ifMatch ? { IfMatch: item.ifMatch } : {}),\n ...(item.ifNoneMatch ? { IfNoneMatch: item.ifNoneMatch } : {}),\n }),\n )\n } catch (err) {\n if (isPreconditionFailedError(err)) {\n throw new S3FileManagerConflictError('Delete conflict')\n }\n throw err\n }\n }\n }\n\n async copy(options: S3CopyOptions, ctx: S3FileManagerAuthContext = {}): Promise<void> {\n const isFolder = options.fromPath.endsWith(this.delimiter)\n const fromPath = normalizePath(options.fromPath)\n const toPath = normalizePath(options.toPath)\n if (fromPath === toPath) return\n\n if (isFolder) {\n const fromPathWithSlash = ensureTrailingDelimiter(fromPath, this.delimiter)\n const toPathWithSlash = ensureTrailingDelimiter(toPath, this.delimiter)\n\n await this.authorize({\n action: 'folder.copy',\n fromPath: fromPathWithSlash,\n toPath: toPathWithSlash,\n ctx,\n })\n\n const fromPrefix = this.pathToFolderPrefix(fromPathWithSlash)\n const toPrefix = this.pathToFolderPrefix(toPathWithSlash)\n\n // Try copying the folder object itself\n try {\n await this.s3.send(\n new CopyObjectCommand({\n Bucket: this.bucket,\n Key: toPrefix,\n CopySource: encodeS3CopySource(this.bucket, fromPrefix),\n }),\n )\n } catch {\n // Ignore errors if the source folder object doesn't exist\n }\n\n // Copy all children\n for await (const sourceKey of listAllKeys(this.s3, this.bucket, fromPrefix)) {\n if (sourceKey === fromPrefix) continue\n\n const relKey = sourceKey.slice(fromPrefix.length)\n const destKey = toPrefix + relKey\n\n try {\n await this.s3.send(\n new CopyObjectCommand({\n Bucket: this.bucket,\n Key: destKey,\n CopySource: encodeS3CopySource(this.bucket, sourceKey),\n }),\n )\n } catch (err) {\n if (isNoSuchKeyError(err)) continue\n throw err\n }\n }\n return\n }\n\n await this.authorize({ action: 'file.copy', fromPath, toPath, ctx })\n\n const fromKey = this.pathToKey(fromPath)\n const toKey = this.pathToKey(toPath)\n\n try {\n await this.s3.send(\n new CopyObjectCommand({\n Bucket: this.bucket,\n Key: toKey,\n CopySource: encodeS3CopySource(this.bucket, fromKey),\n ...(options.ifMatch ? { CopySourceIfMatch: options.ifMatch } : {}),\n }),\n )\n } catch (err) {\n if (isPreconditionFailedError(err)) {\n throw new S3FileManagerConflictError('Copy conflict')\n }\n throw err\n }\n }\n\n async move(options: S3MoveOptions, ctx: S3FileManagerAuthContext = {}): Promise<void> {\n const isFolder = options.fromPath.endsWith(this.delimiter)\n const fromPath = normalizePath(options.fromPath)\n const toPath = normalizePath(options.toPath)\n if (fromPath === toPath) return\n\n if (isFolder) {\n const fromPathWithSlash = ensureTrailingDelimiter(fromPath, this.delimiter)\n const toPathWithSlash = ensureTrailingDelimiter(toPath, this.delimiter)\n let lockKey: string | null = null\n\n await this.authorize({\n action: 'folder.move',\n fromPath: fromPathWithSlash,\n toPath: toPathWithSlash,\n ctx,\n })\n\n try {\n if (this.lockFolderMoves) {\n lockKey = await this.acquireFolderMoveLock(fromPathWithSlash, toPathWithSlash, ctx)\n }\n\n // Delegate to copy (handles recursion)\n await this.copy(options, ctx)\n\n // Delete original folder recursively\n await this.deleteFolder({ path: fromPathWithSlash, recursive: true }, ctx)\n return\n } finally {\n if (lockKey) {\n await this.releaseFolderMoveLock(lockKey)\n }\n }\n }\n\n await this.authorize({ action: 'file.move', fromPath, toPath, ctx })\n\n await this.copy(options, ctx)\n try {\n await this.deleteFiles(\n {\n items: [\n {\n path: fromPath,\n ...(options.ifMatch ? { ifMatch: options.ifMatch } : {}),\n },\n ],\n },\n ctx,\n )\n } catch (err) {\n if (err instanceof S3FileManagerConflictError) {\n try {\n await this.deleteFiles({ paths: [toPath] }, ctx)\n } catch {\n // Best effort rollback\n }\n }\n throw err\n }\n }\n\n async prepareUploads(\n options: S3PrepareUploadsOptions,\n ctx: S3FileManagerAuthContext = {},\n ): Promise<S3PreparedUpload[]> {\n const expiresIn = options.expiresInSeconds ?? 60 * 5\n\n const result: S3PreparedUpload[] = []\n\n for (const item of options.items) {\n const path = normalizePath(item.path)\n await this.authorize({ action: 'upload.prepare', path, ctx })\n\n const key = this.pathToKey(path)\n\n const expiresAt = resolveExpiresAt(item.expiresAt)\n\n const cmd = new PutObjectCommand({\n Bucket: this.bucket,\n Key: key,\n ContentType: item.contentType,\n CacheControl: item.cacheControl,\n ContentDisposition: item.contentDisposition,\n Metadata: item.metadata,\n ...(expiresAt ? { Expires: expiresAt } : {}),\n ...(item.ifNoneMatch ? { IfNoneMatch: item.ifNoneMatch } : {}),\n })\n\n const url = await getSignedUrl(this.s3, cmd, { expiresIn })\n const headers: Record<string, string> = {}\n if (item.contentType) headers['Content-Type'] = item.contentType\n if (item.cacheControl) headers['Cache-Control'] = item.cacheControl\n if (item.contentDisposition) headers['Content-Disposition'] = item.contentDisposition\n if (expiresAt) headers.Expires = expiresAt.toUTCString()\n if (item.ifNoneMatch) headers['If-None-Match'] = item.ifNoneMatch\n if (item.metadata) {\n for (const [k, v] of Object.entries(item.metadata)) {\n headers[`x-amz-meta-${k}`] = v\n }\n }\n\n result.push({\n path,\n url,\n method: 'PUT',\n headers,\n })\n }\n\n return result\n }\n\n async getFileAttributes(\n options: S3GetFileAttributesOptions,\n ctx: S3FileManagerAuthContext = {},\n ): Promise<S3FileAttributes> {\n const path = normalizePath(options.path)\n await this.authorize({ action: 'file.attributes.get', path, ctx })\n\n const key = this.pathToKey(path)\n const out = await this.s3.send(\n new HeadObjectCommand({\n Bucket: this.bucket,\n Key: key,\n }),\n )\n\n return toAttributes(path, out)\n }\n\n async setFileAttributes(\n options: S3SetFileAttributesOptions,\n ctx: S3FileManagerAuthContext = {},\n ): Promise<S3FileAttributes> {\n const path = normalizePath(options.path)\n await this.authorize({ action: 'file.attributes.set', path, ctx })\n\n const key = this.pathToKey(path)\n const current = await this.s3.send(\n new HeadObjectCommand({\n Bucket: this.bucket,\n Key: key,\n }),\n )\n\n const baseMetadata = options.metadata ?? (current.Metadata ? { ...current.Metadata } : {})\n const resolvedExpires =\n options.expiresAt === undefined ? current.Expires : resolveExpiresAt(options.expiresAt)\n\n try {\n await this.s3.send(\n new CopyObjectCommand({\n Bucket: this.bucket,\n Key: key,\n CopySource: encodeS3CopySource(this.bucket, key),\n MetadataDirective: 'REPLACE',\n ContentType: options.contentType ?? current.ContentType,\n CacheControl: options.cacheControl ?? current.CacheControl,\n ContentDisposition: options.contentDisposition ?? current.ContentDisposition,\n Metadata: baseMetadata,\n ...(resolvedExpires ? { Expires: resolvedExpires } : {}),\n ...(options.ifMatch ? { CopySourceIfMatch: options.ifMatch } : {}),\n }),\n )\n } catch (err) {\n if (isPreconditionFailedError(err)) {\n throw new S3FileManagerConflictError('Attribute update conflict')\n }\n throw err\n }\n\n const updated = await this.s3.send(\n new HeadObjectCommand({\n Bucket: this.bucket,\n Key: key,\n }),\n )\n\n return toAttributes(path, updated)\n }\n\n async search(\n options: S3SearchOptions,\n ctx: S3FileManagerAuthContext = {},\n ): Promise<S3SearchResult<FileExtra, FolderExtra>> {\n const query = options.query.toLowerCase().trim()\n if (!query) {\n return { query: options.query, entries: [] }\n }\n\n await this.authorize({ action: 'search', ctx })\n\n const searchPrefix = options.path\n ? this.pathToFolderPrefix(normalizePath(options.path))\n : this.rootPrefix\n\n const entries: Array<S3FileEntry<FileExtra>> = []\n\n // Search through objects (cursor is the underlying S3 continuation token).\n // Results are returned in the natural S3 listing order (lexicographic by key),\n // which keeps pagination stable.\n const limit = options.limit ?? 500\n const recursive = options.recursive !== false\n let cursor: string | undefined = options.cursor\n let nextCursor: string | undefined\n\n while (entries.length < limit) {\n const out = await this.s3.send(\n new ListObjectsV2Command({\n Bucket: this.bucket,\n Prefix: searchPrefix,\n ContinuationToken: cursor,\n MaxKeys: 1000, // Fetch more to filter\n }),\n )\n\n nextCursor =\n out.IsTruncated && out.NextContinuationToken ? out.NextContinuationToken : undefined\n\n // Process files\n for (const obj of out.Contents ?? []) {\n if (!obj.Key || obj.Key === searchPrefix) continue\n\n const path = this.keyToPath(obj.Key)\n const name = path.split('/').at(-1) ?? ''\n\n if (!recursive && options.path) {\n const base = ensureTrailingDelimiter(normalizePath(options.path), this.delimiter)\n const rel = path.startsWith(base) ? path.slice(base.length) : path\n if (rel.includes(this.delimiter)) continue\n }\n\n if (!recursive && !options.path) {\n if (path.includes(this.delimiter)) continue\n }\n\n // Check if file name matches search query\n if (name.toLowerCase().includes(query)) {\n const fileEntry = this.makeFileEntryFromKey(obj.Key, {\n ...(obj.Size !== undefined ? { Size: obj.Size } : {}),\n ...(obj.LastModified !== undefined ? { LastModified: obj.LastModified } : {}),\n ...(obj.ETag !== undefined ? { ETag: obj.ETag } : {}),\n })\n await this.hooks?.decorateFile?.(fileEntry, {\n path: fileEntry.path,\n key: this.pathToKey(fileEntry.path),\n })\n entries.push(fileEntry)\n }\n\n if (entries.length >= limit) break\n }\n\n if (!out.IsTruncated || !out.NextContinuationToken) break\n cursor = out.NextContinuationToken\n }\n\n return {\n query: options.query,\n entries,\n ...(nextCursor ? { nextCursor } : {}),\n }\n }\n\n async getPreviewUrl(\n options: S3GetPreviewUrlOptions,\n ctx: S3FileManagerAuthContext = {},\n ): Promise<S3GetPreviewUrlResult> {\n const path = normalizePath(options.path)\n await this.authorize({ action: 'preview.get', path, ctx })\n\n const expiresIn = options.expiresInSeconds ?? 60 * 5\n const key = this.pathToKey(path)\n\n const cmd = new GetObjectCommand({\n Bucket: this.bucket,\n Key: key,\n ResponseContentDisposition: options.inline ? 'inline' : 'attachment',\n })\n\n const url = await getSignedUrl(this.s3, cmd, { expiresIn })\n\n const expiresAt = new Date(Date.now() + expiresIn * 1000).toISOString()\n return { path, url, expiresAt }\n }\n\n async getFolderLock(\n options: S3GetFolderLockOptions,\n ctx: S3FileManagerAuthContext = {},\n ): Promise<S3FolderLock | null> {\n const path = ensureTrailingDelimiter(normalizePath(options.path), this.delimiter)\n await this.authorize({ action: 'folder.lock.get', path, ctx })\n\n const key = this.lockKeyForPath(path)\n return await this.readFolderLockByKey(key)\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\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"],"mappings":"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","names":["import_client_s3","keys"]}
|
package/dist/core/index.d.cts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
export { q as S3CopyOptions, n as S3CreateFolderOptions, p as S3DeleteFilesOptions, o as S3DeleteFolderOptions, i as S3Entry,
|
|
2
|
-
export { S as S3FileManager } from '../manager-
|
|
1
|
+
export { q as S3CopyOptions, n as S3CreateFolderOptions, p as S3DeleteFilesOptions, o as S3DeleteFolderOptions, i as S3Entry, z as S3FileAttributes, A as S3FileDecorationArgs, h as S3FileEntry, S as S3FileManagerAction, e as S3FileManagerAllowActionHook, b as S3FileManagerAuthContext, f as S3FileManagerAuthorizationMode, c as S3FileManagerAuthorizeArgs, d as S3FileManagerAuthorizeHook, C as S3FileManagerHooks, D as S3FileManagerOptions, B as S3FolderDecorationArgs, g as S3FolderEntry, F as S3FolderLock, x as S3GetFileAttributesOptions, E as S3GetFolderLockOptions, v as S3GetPreviewUrlOptions, w as S3GetPreviewUrlResult, j as S3ListOptions, k as S3ListResult, r as S3MoveOptions, a as S3Path, s as S3PrepareUploadItem, u as S3PrepareUploadsOptions, t as S3PreparedUpload, l as S3SearchOptions, m as S3SearchResult, y as S3SetFileAttributesOptions } from '../types-B0yU5sod.cjs';
|
|
2
|
+
export { S as S3FileManager } from '../manager-DSsCYKEz.cjs';
|
|
3
3
|
import '@aws-sdk/client-s3';
|
|
4
4
|
|
|
5
5
|
declare class S3FileManagerAuthorizationError extends Error {
|
|
@@ -7,5 +7,10 @@ declare class S3FileManagerAuthorizationError extends Error {
|
|
|
7
7
|
readonly code: string;
|
|
8
8
|
constructor(message: string, status: number, code: string);
|
|
9
9
|
}
|
|
10
|
+
declare class S3FileManagerConflictError extends Error {
|
|
11
|
+
readonly status: number;
|
|
12
|
+
readonly code: string;
|
|
13
|
+
constructor(message: string, status?: number, code?: string);
|
|
14
|
+
}
|
|
10
15
|
|
|
11
|
-
export { S3FileManagerAuthorizationError };
|
|
16
|
+
export { S3FileManagerAuthorizationError, S3FileManagerConflictError };
|
package/dist/core/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
export { q as S3CopyOptions, n as S3CreateFolderOptions, p as S3DeleteFilesOptions, o as S3DeleteFolderOptions, i as S3Entry,
|
|
2
|
-
export { S as S3FileManager } from '../manager-
|
|
1
|
+
export { q as S3CopyOptions, n as S3CreateFolderOptions, p as S3DeleteFilesOptions, o as S3DeleteFolderOptions, i as S3Entry, z as S3FileAttributes, A as S3FileDecorationArgs, h as S3FileEntry, S as S3FileManagerAction, e as S3FileManagerAllowActionHook, b as S3FileManagerAuthContext, f as S3FileManagerAuthorizationMode, c as S3FileManagerAuthorizeArgs, d as S3FileManagerAuthorizeHook, C as S3FileManagerHooks, D as S3FileManagerOptions, B as S3FolderDecorationArgs, g as S3FolderEntry, F as S3FolderLock, x as S3GetFileAttributesOptions, E as S3GetFolderLockOptions, v as S3GetPreviewUrlOptions, w as S3GetPreviewUrlResult, j as S3ListOptions, k as S3ListResult, r as S3MoveOptions, a as S3Path, s as S3PrepareUploadItem, u as S3PrepareUploadsOptions, t as S3PreparedUpload, l as S3SearchOptions, m as S3SearchResult, y as S3SetFileAttributesOptions } from '../types-B0yU5sod.js';
|
|
2
|
+
export { S as S3FileManager } from '../manager-BtW1-sC0.js';
|
|
3
3
|
import '@aws-sdk/client-s3';
|
|
4
4
|
|
|
5
5
|
declare class S3FileManagerAuthorizationError extends Error {
|
|
@@ -7,5 +7,10 @@ declare class S3FileManagerAuthorizationError extends Error {
|
|
|
7
7
|
readonly code: string;
|
|
8
8
|
constructor(message: string, status: number, code: string);
|
|
9
9
|
}
|
|
10
|
+
declare class S3FileManagerConflictError extends Error {
|
|
11
|
+
readonly status: number;
|
|
12
|
+
readonly code: string;
|
|
13
|
+
constructor(message: string, status?: number, code?: string);
|
|
14
|
+
}
|
|
10
15
|
|
|
11
|
-
export { S3FileManagerAuthorizationError };
|
|
16
|
+
export { S3FileManagerAuthorizationError, S3FileManagerConflictError };
|