@nestm/storage 0.1.0-alpha.1 → 0.1.0-alpha.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +24 -0
- package/README.md +148 -16
- package/SECURITY.md +23 -0
- package/dist/core/index.d.ts +6 -0
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/index.js +4 -0
- package/dist/core/index.js.map +1 -0
- package/dist/files-sdk/files-sdk.driver.d.ts +36 -7
- package/dist/files-sdk/files-sdk.driver.d.ts.map +1 -1
- package/dist/files-sdk/files-sdk.driver.js +141 -20
- package/dist/files-sdk/files-sdk.driver.js.map +1 -1
- package/dist/files-sdk/index.d.ts +1 -1
- package/dist/files-sdk/index.d.ts.map +1 -1
- package/dist/files-sdk/index.js.map +1 -1
- package/dist/files-sdk/s3/index.d.ts +14 -0
- package/dist/files-sdk/s3/index.d.ts.map +1 -0
- package/dist/files-sdk/s3/index.js +108 -0
- package/dist/files-sdk/s3/index.js.map +1 -0
- package/dist/gateway/index.d.ts +1 -1
- package/dist/gateway/index.d.ts.map +1 -1
- package/dist/gateway/index.js.map +1 -1
- package/dist/gateway/storage-gateway.controller.d.ts +12 -11
- package/dist/gateway/storage-gateway.controller.d.ts.map +1 -1
- package/dist/gateway/storage-gateway.controller.js +209 -65
- package/dist/gateway/storage-gateway.controller.js.map +1 -1
- package/dist/gateway/storage-gateway.module.d.ts.map +1 -1
- package/dist/gateway/storage-gateway.module.js +60 -1
- package/dist/gateway/storage-gateway.module.js.map +1 -1
- package/dist/gateway/storage-gateway.tokens.d.ts +1 -0
- package/dist/gateway/storage-gateway.tokens.d.ts.map +1 -1
- package/dist/gateway/storage-gateway.tokens.js +1 -0
- package/dist/gateway/storage-gateway.tokens.js.map +1 -1
- package/dist/gateway/storage-gateway.types.d.ts +43 -0
- package/dist/gateway/storage-gateway.types.d.ts.map +1 -1
- package/dist/gateway/storage-gateway.types.js.map +1 -1
- package/dist/index.d.ts +1 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -3
- package/dist/index.js.map +1 -1
- package/dist/storage.client.d.ts +9 -3
- package/dist/storage.client.d.ts.map +1 -1
- package/dist/storage.client.js +40 -0
- package/dist/storage.client.js.map +1 -1
- package/dist/storage.driver.d.ts +6 -1
- package/dist/storage.driver.d.ts.map +1 -1
- package/dist/storage.driver.js.map +1 -1
- package/dist/storage.error.d.ts +3 -0
- package/dist/storage.error.d.ts.map +1 -1
- package/dist/storage.error.js +33 -1
- package/dist/storage.error.js.map +1 -1
- package/dist/storage.types.d.ts +39 -1
- package/dist/storage.types.d.ts.map +1 -1
- package/dist/storage.types.js.map +1 -1
- package/package.json +46 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,29 @@
|
|
|
1
1
|
# @nestm/storage
|
|
2
2
|
|
|
3
|
+
## 0.1.0-alpha.3
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- b947634: Harden storage integration boundaries with cross-copy-safe `StorageError`
|
|
8
|
+
detection, a package-owned S3 driver factory, conditional staged-object
|
|
9
|
+
promotion, and a mandatory parsed key policy plus signed-transfer limits for
|
|
10
|
+
the optional HTTP gateway.
|
|
11
|
+
|
|
12
|
+
### Patch Changes
|
|
13
|
+
|
|
14
|
+
- b947634: Map structurally branded `files-sdk` errors, including errors wrapped across
|
|
15
|
+
duplicate package copies, so missing objects retain the `NOT_FOUND` storage
|
|
16
|
+
error code.
|
|
17
|
+
|
|
18
|
+
## 0.1.0-alpha.2
|
|
19
|
+
|
|
20
|
+
### Minor Changes
|
|
21
|
+
|
|
22
|
+
- c4b54e7: Add a framework-neutral `@nestm/storage/core` entry point for the storage
|
|
23
|
+
client, driver contract, errors, operation types, and upload controls. NestJS
|
|
24
|
+
peers are now optional so non-Nest consumers can install and use the core API
|
|
25
|
+
without pulling in the framework.
|
|
26
|
+
|
|
3
27
|
## 0.1.0-alpha.1
|
|
4
28
|
|
|
5
29
|
### Minor Changes
|
package/README.md
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
# @nestm/storage
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
cross-store workflows, and an optional guarded HTTP
|
|
3
|
+
Framework-neutral storage clients with NestJS 12 integration, named stores,
|
|
4
|
+
explicit streaming I/O, cross-store workflows, and an optional guarded HTTP
|
|
5
|
+
gateway.
|
|
5
6
|
|
|
6
7
|
The package uses [`files-sdk`](https://github.com/haydenbleasel/files-sdk) as
|
|
7
8
|
its provider engine, but owns the API injected into Nest applications. Provider
|
|
@@ -13,13 +14,26 @@ SDK types, errors, and `files.raw` do not leak through the root package.
|
|
|
13
14
|
## Requirements
|
|
14
15
|
|
|
15
16
|
- Node.js 22.12 or newer
|
|
16
|
-
- NestJS `12.0.0-alpha.5` or newer in the Nest 12 prerelease line
|
|
17
17
|
- ESM
|
|
18
18
|
|
|
19
|
+
The framework-neutral `@nestm/storage/core` entry point does not require
|
|
20
|
+
NestJS. The root entry point and HTTP gateway additionally require NestJS
|
|
21
|
+
`12.0.0-alpha.5` or newer in the Nest 12 prerelease line, `reflect-metadata`,
|
|
22
|
+
and RxJS. Those framework peers are optional at installation time so core-only
|
|
23
|
+
consumers do not download NestJS.
|
|
24
|
+
|
|
19
25
|
## Install
|
|
20
26
|
|
|
21
27
|
```sh
|
|
22
|
-
pnpm add @nestm/storage@alpha
|
|
28
|
+
pnpm add @nestm/storage@alpha
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
The package-owned S3 factory needs no direct `files-sdk` import. Install the
|
|
32
|
+
pinned engine explicitly only when the application imports another adapter
|
|
33
|
+
such as `files-sdk/gcs`:
|
|
34
|
+
|
|
35
|
+
```sh
|
|
36
|
+
pnpm add files-sdk@2.2.2
|
|
23
37
|
```
|
|
24
38
|
|
|
25
39
|
Install only the native SDKs required by the chosen provider. For example:
|
|
@@ -46,16 +60,45 @@ its strict resolver. If npm reports an `ERESOLVE` error for Nest's own peers,
|
|
|
46
60
|
install with `npm install --legacy-peer-deps`; pnpm works with the repository's
|
|
47
61
|
checked-in peer-version policy.
|
|
48
62
|
|
|
63
|
+
## Framework-neutral core
|
|
64
|
+
|
|
65
|
+
Import storage primitives from `@nestm/storage/core` in workers, scripts, and
|
|
66
|
+
applications that do not use NestJS:
|
|
67
|
+
|
|
68
|
+
```ts
|
|
69
|
+
import {
|
|
70
|
+
StorageClient,
|
|
71
|
+
type StorageDriver,
|
|
72
|
+
type StorageUploadOptions,
|
|
73
|
+
} from '@nestm/storage/core';
|
|
74
|
+
|
|
75
|
+
declare const driver: StorageDriver;
|
|
76
|
+
|
|
77
|
+
const media = new StorageClient('media', driver);
|
|
78
|
+
|
|
79
|
+
await media.upload('avatars/user.png', image, {
|
|
80
|
+
contentType: 'image/png',
|
|
81
|
+
} satisfies StorageUploadOptions);
|
|
82
|
+
|
|
83
|
+
await media.onApplicationShutdown();
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
The core entry point exports `StorageClient`, the `StorageDriver` contract,
|
|
87
|
+
storage errors and operation types, and `StorageUploadControl`. It has no NestJS
|
|
88
|
+
runtime or declaration imports. Provider adapters remain available through
|
|
89
|
+
`@nestm/storage/files-sdk`.
|
|
90
|
+
|
|
49
91
|
## Configure named stores
|
|
50
92
|
|
|
51
|
-
|
|
52
|
-
bridge, and register the
|
|
93
|
+
Use the package-owned S3 factory when applicable. For other providers, create a
|
|
94
|
+
`files-sdk` adapter, wrap it through the explicit bridge, and register the
|
|
95
|
+
resulting driver:
|
|
53
96
|
|
|
54
97
|
```ts
|
|
55
98
|
import { Module } from '@nestjs/common';
|
|
56
|
-
import { s3 } from 'files-sdk/s3';
|
|
57
99
|
import { gcs } from 'files-sdk/gcs';
|
|
58
100
|
import { createFilesSdkDriver } from '@nestm/storage/files-sdk';
|
|
101
|
+
import { createS3StorageDriver } from '@nestm/storage/files-sdk/s3';
|
|
59
102
|
import { StorageModule } from '@nestm/storage';
|
|
60
103
|
|
|
61
104
|
export const StorageKey = {
|
|
@@ -70,11 +113,11 @@ export const StorageKey = {
|
|
|
70
113
|
stores: [
|
|
71
114
|
{
|
|
72
115
|
name: StorageKey.MEDIA,
|
|
73
|
-
driver:
|
|
74
|
-
adapter:
|
|
116
|
+
driver: createS3StorageDriver({
|
|
117
|
+
adapter: {
|
|
75
118
|
bucket: 'media',
|
|
76
119
|
region: 'us-east-1',
|
|
77
|
-
}
|
|
120
|
+
},
|
|
78
121
|
}),
|
|
79
122
|
},
|
|
80
123
|
{
|
|
@@ -160,11 +203,11 @@ StorageModule.forRootAsync({
|
|
|
160
203
|
name: 'media',
|
|
161
204
|
inject: [ConfigService],
|
|
162
205
|
useFactory: (config: ConfigService) =>
|
|
163
|
-
|
|
164
|
-
adapter:
|
|
206
|
+
createS3StorageDriver({
|
|
207
|
+
adapter: {
|
|
165
208
|
bucket: config.getOrThrow('MEDIA_BUCKET'),
|
|
166
209
|
region: config.getOrThrow('AWS_REGION'),
|
|
167
|
-
}
|
|
210
|
+
},
|
|
168
211
|
}),
|
|
169
212
|
},
|
|
170
213
|
],
|
|
@@ -187,6 +230,7 @@ whitespace.
|
|
|
187
230
|
`StorageClient` exposes:
|
|
188
231
|
|
|
189
232
|
- `upload`, `downloadStream`, `head`, `exists`, `delete`, `copy`, and `move`;
|
|
233
|
+
- conditional staged-object `promote` when the driver advertises it;
|
|
190
234
|
- `list`, cursor-aware `listAll`, and lazy `search`;
|
|
191
235
|
- `signDownload` and discriminated PUT/POST `signUpload`;
|
|
192
236
|
- `uploadMany`, `downloadMany`, `headMany`, `existsMany`, and `deleteMany`;
|
|
@@ -216,6 +260,37 @@ Node `Readable` uploads are accepted and converted to Web streams without
|
|
|
216
260
|
buffering. Provider capability gaps fail closed with `StorageError` rather than
|
|
217
261
|
silently discarding a range, metadata, or cache-control request.
|
|
218
262
|
|
|
263
|
+
### Race-free staged-object promotion
|
|
264
|
+
|
|
265
|
+
The S3 bridge advertises ETag- and version-conditional server-side copy. This
|
|
266
|
+
lets an application validate a staged object and copy that exact source to its
|
|
267
|
+
final key instead of re-reading whichever bytes occupy the staging key later:
|
|
268
|
+
|
|
269
|
+
```ts
|
|
270
|
+
import { StorageError, StorageErrorCode } from '@nestm/storage';
|
|
271
|
+
|
|
272
|
+
const staged = await media.head(stagingKey);
|
|
273
|
+
if (staged.etag === undefined) {
|
|
274
|
+
throw new StorageError('Provider did not return a source ETag.', {
|
|
275
|
+
code: StorageErrorCode.NOT_SUPPORTED,
|
|
276
|
+
});
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
// Validate size, declared MIME, and magic bytes before this call.
|
|
280
|
+
await media.file(stagingKey).promoteTo(finalKey, {
|
|
281
|
+
sourceEtag: staged.etag,
|
|
282
|
+
});
|
|
283
|
+
|
|
284
|
+
// Commit ready metadata first. Promotion deliberately retains the staged
|
|
285
|
+
// object so a failed database commit remains recoverable.
|
|
286
|
+
await media.delete(stagingKey);
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
`sourceVersion` can select an immutable S3 version and may be combined with
|
|
290
|
+
`sourceEtag`. A promotion without either identity is rejected. Drivers that do
|
|
291
|
+
not publish `capabilities.conditionalCopy` fail with `NOT_SUPPORTED` rather
|
|
292
|
+
than falling back to an unsafe ordinary copy.
|
|
293
|
+
|
|
219
294
|
### Resumable uploads
|
|
220
295
|
|
|
221
296
|
```ts
|
|
@@ -267,20 +342,42 @@ The gateway lives at `@nestm/storage/gateway` and is never mounted by
|
|
|
267
342
|
`StorageModule`.
|
|
268
343
|
|
|
269
344
|
```ts
|
|
270
|
-
import { Module } from '@nestjs/common';
|
|
345
|
+
import { Injectable, Module } from '@nestjs/common';
|
|
271
346
|
import {
|
|
272
347
|
StorageGatewayModule,
|
|
273
348
|
StorageGatewayOperation,
|
|
349
|
+
type StorageGatewayKeyPolicy,
|
|
274
350
|
} from '@nestm/storage/gateway';
|
|
275
351
|
|
|
352
|
+
@Injectable()
|
|
353
|
+
class TenantStorageKeyPolicy implements StorageGatewayKeyPolicy {
|
|
354
|
+
resolve({ input, request, target }) {
|
|
355
|
+
const tenantId = tenantIdFromAuthenticatedRequest(request);
|
|
356
|
+
const root = `tenants/${base64url(tenantId)}`;
|
|
357
|
+
if (target === 'pattern') {
|
|
358
|
+
// Search is already constrained by the separately resolved prefix.
|
|
359
|
+
return input?.value ?? '*';
|
|
360
|
+
}
|
|
361
|
+
return `${root}/${input?.value ?? ''}`;
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
@Module({
|
|
366
|
+
providers: [TenantStorageKeyPolicy],
|
|
367
|
+
exports: [TenantStorageKeyPolicy],
|
|
368
|
+
})
|
|
369
|
+
class StoragePolicyModule {}
|
|
370
|
+
|
|
276
371
|
@Module({
|
|
277
372
|
imports: [
|
|
278
373
|
AppStorageModule,
|
|
279
374
|
AuthModule,
|
|
375
|
+
StoragePolicyModule,
|
|
280
376
|
StorageGatewayModule.register({
|
|
281
|
-
imports: [AppStorageModule, AuthModule],
|
|
377
|
+
imports: [AppStorageModule, AuthModule, StoragePolicyModule],
|
|
282
378
|
store: 'media',
|
|
283
379
|
guards: [JwtAuthGuard],
|
|
380
|
+
keyPolicy: TenantStorageKeyPolicy,
|
|
284
381
|
mode: 'hybrid',
|
|
285
382
|
operations: [
|
|
286
383
|
StorageGatewayOperation.DOWNLOAD,
|
|
@@ -291,6 +388,9 @@ import {
|
|
|
291
388
|
StorageGatewayOperation.SIGN_UPLOAD,
|
|
292
389
|
],
|
|
293
390
|
maxUploadBytes: 100 * 1024 * 1024,
|
|
391
|
+
maxSignedUploadBytes: 10 * 1024 * 1024,
|
|
392
|
+
signedUploadContentTypes: ['image/jpeg', 'image/png'],
|
|
393
|
+
maxSignedUrlExpiresIn: 900,
|
|
294
394
|
maxListResults: 1000,
|
|
295
395
|
maxSearchResults: 1000,
|
|
296
396
|
proxyInlineContentTypes: ['image/jpeg', 'image/png'],
|
|
@@ -304,12 +404,39 @@ Registration fails without at least one existing Nest guard. The only bypass is
|
|
|
304
404
|
the explicit `allowUnauthenticated: true` development escape hatch. Operations
|
|
305
405
|
are deny-by-default and must be allowlisted individually.
|
|
306
406
|
|
|
407
|
+
Registration also fails without a `keyPolicy`. Guards answer whether a request
|
|
408
|
+
may reach the gateway; the key policy independently resolves every parsed
|
|
409
|
+
`key`, `prefix`, search `pattern`, `from`, and `to` value to the exact provider
|
|
410
|
+
path. It runs even when a list/search prefix was omitted, so the policy can
|
|
411
|
+
always impose a tenant root. Key-policy providers may be request scoped.
|
|
412
|
+
Returned paths are parsed again and reject absolute paths, backslashes, control
|
|
413
|
+
characters, empty segments, and dot/parent segments.
|
|
414
|
+
|
|
415
|
+
Existing single-tenant applications can temporarily set
|
|
416
|
+
`unsafeAllowUnscopedKeys: true` instead of `keyPolicy`. The name is intentional:
|
|
417
|
+
it preserves caller-controlled provider keys and must not be used on an exposed
|
|
418
|
+
or multi-tenant gateway. It cannot be combined with `keyPolicy`.
|
|
419
|
+
|
|
307
420
|
Proxy downloads default to `Content-Disposition: attachment` and always send
|
|
308
421
|
`X-Content-Type-Options: nosniff`. Add only trusted, non-active MIME types to
|
|
309
422
|
`proxyInlineContentTypes` when browser rendering is required. Search responses
|
|
310
423
|
are capped by `maxSearchResults`, and list pages by `maxListResults` (both
|
|
311
424
|
1,000 by default).
|
|
312
425
|
|
|
426
|
+
Every signed URL is capped by `maxSignedUrlExpiresIn` (3,600 seconds by
|
|
427
|
+
default). Signed uploads always carry a provider-enforced maximum size, capped
|
|
428
|
+
by `maxSignedUploadBytes`, and require an exact lowercase MIME type from
|
|
429
|
+
`signedUploadContentTypes`. The default direct-upload allowlist contains only
|
|
430
|
+
`application/octet-stream`. Gateway callers may request only the literal
|
|
431
|
+
`attachment` or `inline` response disposition; arbitrary response-header text
|
|
432
|
+
and filenames are rejected. A driver must also advertise
|
|
433
|
+
`signedUploadPolicy.contentType` and `signedUploadPolicy.sizeRange`; otherwise
|
|
434
|
+
the gateway refuses to mint the URL. `createS3StorageDriver()` advertises both
|
|
435
|
+
and uses S3 POST policy conditions. Signed downloads similarly require
|
|
436
|
+
`signedDownloadPolicy.expiresIn`. The S3 factory advertises it only when no
|
|
437
|
+
permanent `publicBaseUrl` was configured, preventing a configured TTL from
|
|
438
|
+
silently returning a non-expiring public link.
|
|
439
|
+
|
|
313
440
|
The fixed gateway prefix is `/storage`:
|
|
314
441
|
|
|
315
442
|
| Method | Path | Operation |
|
|
@@ -360,9 +487,14 @@ try {
|
|
|
360
487
|
}
|
|
361
488
|
```
|
|
362
489
|
|
|
490
|
+
`files-sdk` `NotFound` failures retain `StorageErrorCode.NOT_FOUND`, including
|
|
491
|
+
when a provider adapter and this driver resolve separate copies of `files-sdk`.
|
|
492
|
+
`isStorageError()` likewise recognizes branded and exact legacy structural
|
|
493
|
+
errors produced by a duplicated `@nestm/storage` package copy.
|
|
494
|
+
|
|
363
495
|
Capability flags cover range reads, native byte-level upload progress,
|
|
364
496
|
delimiter listing, metadata, cache control, resumable uploads, server-side
|
|
365
|
-
copy, and signed transfers.
|
|
497
|
+
copy, conditional promotion, and signed transfers.
|
|
366
498
|
Provider-specific native clients are intentionally not exposed from the root
|
|
367
499
|
package.
|
|
368
500
|
|
package/SECURITY.md
CHANGED
|
@@ -23,3 +23,26 @@ cross-store pruning, or dependency compromise are especially useful.
|
|
|
23
23
|
For a vulnerability originating in NestJS, `files-sdk`, or a provider SDK,
|
|
24
24
|
follow that project's security policy as well. You may still report it here
|
|
25
25
|
privately when this integration needs a mitigation.
|
|
26
|
+
|
|
27
|
+
## Gateway security boundary
|
|
28
|
+
|
|
29
|
+
Mounting the optional HTTP gateway requires both authentication guards and a
|
|
30
|
+
`StorageGatewayKeyPolicy`. The policy receives parsed paths and must derive the
|
|
31
|
+
provider key space from trusted request context. Do not treat a client prefix
|
|
32
|
+
or object key as a tenant identifier. `unsafeAllowUnscopedKeys` exists only to
|
|
33
|
+
migrate trusted single-tenant deployments and is unsafe on an exposed gateway.
|
|
34
|
+
|
|
35
|
+
Signed URL expiry, signed-upload byte size, and signed-upload MIME are bounded
|
|
36
|
+
by module configuration and cannot be increased by a request. Only `inline`
|
|
37
|
+
and `attachment` content dispositions are accepted. File type still must be
|
|
38
|
+
verified from magic bytes after upload; a signed MIME condition proves only
|
|
39
|
+
what header the uploader supplied. The gateway rejects signed-upload drivers
|
|
40
|
+
that do not advertise provider-enforced content-type and size-range policies.
|
|
41
|
+
It also rejects download adapters that cannot guarantee the requested expiry;
|
|
42
|
+
in particular, the S3 bridge does not treat `publicBaseUrl` links as expiring.
|
|
43
|
+
|
|
44
|
+
For staged uploads on S3, use `promote`/`promoteTo` with the ETag returned by
|
|
45
|
+
the validated `head` or with an immutable provider version. Ordinary `copy`
|
|
46
|
+
does not protect against a staging-key replay between validation and copy.
|
|
47
|
+
Conditional promotion keeps the staging source; delete it only after the
|
|
48
|
+
application's metadata transaction commits.
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { DEFAULT_BUFFER_LIMIT, StorageClient, type StorageFileHandle, } from '../storage.client.js';
|
|
2
|
+
export type { StorageDriver } from '../storage.driver.js';
|
|
3
|
+
export { StorageError, StorageErrorCode, isStorageError, normalizeStorageError, type StorageErrorOptions, } from '../storage.error.js';
|
|
4
|
+
export { StorageUploadControl, type StorageResumableToken, type StorageUploadStatus, } from '../storage-upload-control.js';
|
|
5
|
+
export type * from '../storage.types.js';
|
|
6
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/core/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,oBAAoB,EACpB,aAAa,EACb,KAAK,iBAAiB,GACvB,MAAM,sBAAsB,CAAC;AAC9B,YAAY,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,EACL,YAAY,EACZ,gBAAgB,EAChB,cAAc,EACd,qBAAqB,EACrB,KAAK,mBAAmB,GACzB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACL,oBAAoB,EACpB,KAAK,qBAAqB,EAC1B,KAAK,mBAAmB,GACzB,MAAM,8BAA8B,CAAC;AACtC,mBAAmB,qBAAqB,CAAC"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export { DEFAULT_BUFFER_LIMIT, StorageClient, } from '../storage.client.js';
|
|
2
|
+
export { StorageError, StorageErrorCode, isStorageError, normalizeStorageError, } from '../storage.error.js';
|
|
3
|
+
export { StorageUploadControl, } from '../storage-upload-control.js';
|
|
4
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/core/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,oBAAoB,EACpB,aAAa,GAEd,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EACL,YAAY,EACZ,gBAAgB,EAChB,cAAc,EACd,qBAAqB,GAEtB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACL,oBAAoB,GAGrB,MAAM,8BAA8B,CAAC","sourcesContent":["export {\n DEFAULT_BUFFER_LIMIT,\n StorageClient,\n type StorageFileHandle,\n} from '../storage.client.js';\nexport type { StorageDriver } from '../storage.driver.js';\nexport {\n StorageError,\n StorageErrorCode,\n isStorageError,\n normalizeStorageError,\n type StorageErrorOptions,\n} from '../storage.error.js';\nexport {\n StorageUploadControl,\n type StorageResumableToken,\n type StorageUploadStatus,\n} from '../storage-upload-control.js';\nexport type * from '../storage.types.js';\n"]}
|
|
@@ -1,24 +1,52 @@
|
|
|
1
1
|
import { type Adapter, type FilesOptions } from 'files-sdk';
|
|
2
|
+
import { StorageError } from '../storage.error.js';
|
|
2
3
|
import type { StorageDriver } from '../storage.driver.js';
|
|
3
|
-
import type { StorageBody, StorageDownloadOptions, StorageListOptions, StorageListResult, StorageObject, StorageObjectMetadata, StorageOperationOptions, StorageSearchOptions, StorageSignedDownloadOptions, StorageSignedUpload, StorageSignedUploadOptions, StorageUploadOptions, StorageUploadResult } from '../storage.types.js';
|
|
4
|
+
import type { StorageBody, StorageDownloadOptions, StorageListOptions, StorageListResult, StorageObject, StorageObjectMetadata, StorageOperationOptions, StorageConditionalCopyCapability, StoragePromotionOptions, StorageSearchOptions, StorageSignedUploadPolicyCapability, StorageSignedDownloadPolicyCapability, StorageSignedDownloadOptions, StorageSignedUpload, StorageSignedUploadOptions, StorageUploadOptions, StorageUploadResult } from '../storage.types.js';
|
|
4
5
|
export type FilesSdkDriverOptions<AdapterType extends Adapter> = FilesOptions<AdapterType>;
|
|
6
|
+
/**
|
|
7
|
+
* Optional adapter extension for providers that can conditionally copy an
|
|
8
|
+
* immutable source identity. Plain files-sdk adapters remain fully supported.
|
|
9
|
+
*/
|
|
10
|
+
export interface FilesSdkConditionalCopyAdapter {
|
|
11
|
+
readonly conditionalCopy: StorageConditionalCopyCapability;
|
|
12
|
+
promote(sourceKey: string, destinationKey: string, options: StoragePromotionOptions): Promise<void>;
|
|
13
|
+
}
|
|
14
|
+
export interface FilesSdkSignedUploadPolicyAdapter {
|
|
15
|
+
readonly signedUploadPolicy: StorageSignedUploadPolicyCapability;
|
|
16
|
+
}
|
|
17
|
+
export interface FilesSdkSignedDownloadPolicyAdapter {
|
|
18
|
+
readonly signedDownloadPolicy: StorageSignedDownloadPolicyCapability;
|
|
19
|
+
}
|
|
20
|
+
export declare function mapFilesSdkError(error: unknown): StorageError;
|
|
5
21
|
export declare class FilesSdkStorageDriver<AdapterType extends Adapter = Adapter> implements StorageDriver {
|
|
6
22
|
#private;
|
|
7
23
|
constructor(options: FilesSdkDriverOptions<AdapterType>);
|
|
8
24
|
get name(): string;
|
|
9
25
|
get capabilities(): {
|
|
26
|
+
nativeUploadProgress: boolean;
|
|
27
|
+
signedUploadPolicy?: {
|
|
28
|
+
contentType: boolean;
|
|
29
|
+
sizeRange: boolean;
|
|
30
|
+
};
|
|
31
|
+
signedUpload: "runtime";
|
|
32
|
+
signedDownloadPolicy?: {
|
|
33
|
+
expiresIn: boolean;
|
|
34
|
+
};
|
|
35
|
+
signedDownload: {
|
|
36
|
+
supported: boolean;
|
|
37
|
+
maxExpiresIn?: number;
|
|
38
|
+
};
|
|
39
|
+
conditionalCopy?: {
|
|
40
|
+
supported: boolean;
|
|
41
|
+
etag: boolean;
|
|
42
|
+
version: boolean;
|
|
43
|
+
};
|
|
10
44
|
cacheControl: boolean;
|
|
11
45
|
delimiter: boolean;
|
|
12
46
|
metadata: boolean;
|
|
13
47
|
rangeRead: boolean;
|
|
14
48
|
resumableUpload: boolean;
|
|
15
49
|
serverSideCopy: boolean;
|
|
16
|
-
signedDownload: {
|
|
17
|
-
supported: boolean;
|
|
18
|
-
maxExpiresIn?: number;
|
|
19
|
-
};
|
|
20
|
-
signedUpload: "runtime";
|
|
21
|
-
nativeUploadProgress: boolean;
|
|
22
50
|
};
|
|
23
51
|
upload(key: string, body: StorageBody, options?: StorageUploadOptions): Promise<StorageUploadResult>;
|
|
24
52
|
download(key: string, options?: StorageDownloadOptions): Promise<StorageObject>;
|
|
@@ -27,6 +55,7 @@ export declare class FilesSdkStorageDriver<AdapterType extends Adapter = Adapter
|
|
|
27
55
|
delete(key: string, options?: StorageOperationOptions): Promise<void>;
|
|
28
56
|
copy(sourceKey: string, destinationKey: string, options?: StorageOperationOptions): Promise<void>;
|
|
29
57
|
move(sourceKey: string, destinationKey: string, options?: StorageOperationOptions): Promise<void>;
|
|
58
|
+
promote(sourceKey: string, destinationKey: string, options: StoragePromotionOptions): Promise<void>;
|
|
30
59
|
list(options?: StorageListOptions): Promise<StorageListResult>;
|
|
31
60
|
search(pattern: string | RegExp, options?: StorageSearchOptions): AsyncIterable<StorageObjectMetadata>;
|
|
32
61
|
signDownload(key: string, options?: StorageSignedDownloadOptions): Promise<string>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"files-sdk.driver.d.ts","sourceRoot":"","sources":["../../src/files-sdk/files-sdk.driver.ts"],"names":[],"mappings":"AAEA,OAAO,EAGL,KAAK,OAAO,EAGZ,KAAK,YAAY,EAUlB,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"files-sdk.driver.d.ts","sourceRoot":"","sources":["../../src/files-sdk/files-sdk.driver.ts"],"names":[],"mappings":"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"}
|