@stacksjs/storage 0.70.44 → 0.70.53
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/LICENSE.md +21 -0
- package/dist/image.js +58 -0
- package/dist/index.js +2386 -1278
- package/dist/src/adapters/bun.d.ts +6 -4
- package/dist/src/adapters/index.d.ts +2 -0
- package/dist/src/adapters/local.d.ts +6 -4
- package/dist/src/adapters/memory.d.ts +4 -2
- package/dist/src/adapters/s3.d.ts +24 -7
- package/dist/src/adapters/scoped.d.ts +68 -0
- package/dist/src/facade.d.ts +14 -4
- package/dist/src/image.d.ts +55 -0
- package/dist/src/index.d.ts +34 -1
- package/dist/src/mime-verify.d.ts +65 -0
- package/dist/src/path-sanitize.d.ts +92 -0
- package/dist/src/put-file.d.ts +53 -0
- package/dist/src/s3-presigned-post.d.ts +52 -0
- package/dist/src/signed-url.d.ts +33 -1
- package/dist/src/types/filesystem.d.ts +31 -0
- package/dist/src/types.d.ts +90 -1
- package/package.json +7 -7
package/dist/src/signed-url.d.ts
CHANGED
|
@@ -8,6 +8,38 @@ import type { SignedUrlOptions } from './types';
|
|
|
8
8
|
* ```
|
|
9
9
|
*/
|
|
10
10
|
export declare function createSignedStorageToken(path: string, options: SignedUrlOptions): string;
|
|
11
|
+
/**
|
|
12
|
+
* Revoke a signed storage token so subsequent
|
|
13
|
+
* {@link verifySignedStorageToken} calls return
|
|
14
|
+
* `{ valid: false, reason: 'revoked' }`. Idempotent — calling
|
|
15
|
+
* twice is a no-op.
|
|
16
|
+
*
|
|
17
|
+
* Pass either the full JWS compact-form token or just the signature
|
|
18
|
+
* segment (the part after the second `.`); both work because
|
|
19
|
+
* verification keys off the signature segment.
|
|
20
|
+
*
|
|
21
|
+
* @example
|
|
22
|
+
* ```ts
|
|
23
|
+
* const url = await Storage.disk('local').signedUrl('reports/q4.pdf', { expiresIn: 3600 })
|
|
24
|
+
* // ... url is shared, then later leaked
|
|
25
|
+
* revokeSignedStorageToken(extractTokenFromUrl(url))
|
|
26
|
+
* // Any further fetch with that URL → 403
|
|
27
|
+
* ```
|
|
28
|
+
*/
|
|
29
|
+
export declare function revokeSignedStorageToken(token: string): void;
|
|
30
|
+
/**
|
|
31
|
+
* Check whether a signature has been revoked. Exposed for tests
|
|
32
|
+
* and for distributed-cache replicators that need to peek at the
|
|
33
|
+
* set; production callers should rely on {@link verifySignedStorageToken}
|
|
34
|
+
* to consult this automatically.
|
|
35
|
+
*/
|
|
36
|
+
export declare function isSignedStorageTokenRevoked(sigPart: string): boolean;
|
|
37
|
+
/**
|
|
38
|
+
* Test-only: clear the revocation set. The set is process-local
|
|
39
|
+
* and unbounded across tests would let one test's revoke bleed
|
|
40
|
+
* into another's verification.
|
|
41
|
+
*/
|
|
42
|
+
export declare function clearRevokedSignedStorageTokens(): void;
|
|
11
43
|
/**
|
|
12
44
|
* Verify a signed storage token. The caller MUST pass the requested
|
|
13
45
|
* path so we can ensure the token's `path` claim matches what the
|
|
@@ -32,6 +64,6 @@ declare interface SignedTokenClaims {
|
|
|
32
64
|
*/
|
|
33
65
|
export declare interface SignedTokenVerification {
|
|
34
66
|
valid: boolean
|
|
35
|
-
reason?: 'malformed' | 'bad_signature' | 'expired' | 'path_mismatch'
|
|
67
|
+
reason?: 'malformed' | 'bad_signature' | 'expired' | 'path_mismatch' | 'revoked'
|
|
36
68
|
claims?: SignedTokenClaims
|
|
37
69
|
}
|
|
@@ -42,6 +42,28 @@ export declare interface S3DiskConfig extends BaseDiskConfig {
|
|
|
42
42
|
secret: string
|
|
43
43
|
}
|
|
44
44
|
}
|
|
45
|
+
/**
|
|
46
|
+
* Userland-augmentable disk-name registry (stacksjs/stacks#1924).
|
|
47
|
+
*
|
|
48
|
+
* Empty by default — the framework can't know an app's configured
|
|
49
|
+
* disks at its own build time. Apps declare their disks once and get
|
|
50
|
+
* autocomplete on `Storage.disk('…')` everywhere:
|
|
51
|
+
*
|
|
52
|
+
* ```ts
|
|
53
|
+
* // types/storage.d.ts
|
|
54
|
+
* declare module '@stacksjs/storage' {
|
|
55
|
+
* interface KnownDisks {
|
|
56
|
+
* local: true
|
|
57
|
+
* public: true
|
|
58
|
+
* s3: true
|
|
59
|
+
* }
|
|
60
|
+
* }
|
|
61
|
+
* ```
|
|
62
|
+
*
|
|
63
|
+
* Mirrors the `DatabaseSchema` pattern from stacksjs/stacks#1923.
|
|
64
|
+
*/
|
|
65
|
+
// eslint-disable-next-line ts/no-empty-object-type
|
|
66
|
+
export declare interface KnownDisks {}
|
|
45
67
|
/**
|
|
46
68
|
* Main filesystem configuration
|
|
47
69
|
*
|
|
@@ -98,3 +120,12 @@ export type Visibility = 'public' | 'private';
|
|
|
98
120
|
* Union type for all disk configurations
|
|
99
121
|
*/
|
|
100
122
|
export type DiskConfig = LocalDiskConfig | S3DiskConfig;
|
|
123
|
+
/**
|
|
124
|
+
* A configured disk name (autocompletes to the keys of an augmented
|
|
125
|
+
* {@link KnownDisks}) or any other string. The `(string & {})` branch
|
|
126
|
+
* keeps the union from collapsing back to `string`, so known disks
|
|
127
|
+
* surface in autocomplete while arbitrary names still type-check —
|
|
128
|
+
* apps that haven't augmented `KnownDisks` keep compiling unchanged.
|
|
129
|
+
*/
|
|
130
|
+
// eslint-disable-next-line ts/no-empty-object-type
|
|
131
|
+
export type DiskName = (keyof KnownDisks & string) | (string & {});
|
package/dist/src/types.d.ts
CHANGED
|
@@ -32,6 +32,45 @@ export declare interface StatEntry {
|
|
|
32
32
|
mimeType?: string
|
|
33
33
|
metadata?: Record<string, any>
|
|
34
34
|
}
|
|
35
|
+
/**
|
|
36
|
+
* Options for `Storage.getStream(path, options?)`
|
|
37
|
+
* (stacksjs/stacks#1886).
|
|
38
|
+
*/
|
|
39
|
+
export declare interface GetStreamOptions {
|
|
40
|
+
signal?: AbortSignal
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Options for `Storage.putStream(path, stream, options?)`
|
|
44
|
+
* (stacksjs/stacks#1886). All fields are optional; the S3 driver
|
|
45
|
+
* reads them to tune its multipart pipeline, other drivers
|
|
46
|
+
* generally only honor `contentType` and `signal`.
|
|
47
|
+
*/
|
|
48
|
+
export declare interface PutStreamOptions {
|
|
49
|
+
contentType?: string
|
|
50
|
+
signal?: AbortSignal
|
|
51
|
+
partSize?: number
|
|
52
|
+
concurrency?: number
|
|
53
|
+
maxRetries?: number
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Result returned from `Storage.put()` (stacksjs/stacks#1888 S-8).
|
|
57
|
+
*
|
|
58
|
+
* Pre-fix `put()` returned `Promise<void>` — callers that wanted to
|
|
59
|
+
* record an etag for cache-invalidation or a size for storage-quota
|
|
60
|
+
* accounting had to issue a second `.stat()` round-trip. This shape
|
|
61
|
+
* carries the metadata back from the write itself.
|
|
62
|
+
*
|
|
63
|
+
* Fields beyond `path` are best-effort: drivers that don't expose
|
|
64
|
+
* (or can't cheaply compute) a value omit it rather than synthesizing
|
|
65
|
+
* a fake one. Callers should treat them as nullable.
|
|
66
|
+
*/
|
|
67
|
+
export declare interface PutResult {
|
|
68
|
+
path: string
|
|
69
|
+
size: number
|
|
70
|
+
contentType?: string
|
|
71
|
+
lastModified?: number
|
|
72
|
+
etag?: string
|
|
73
|
+
}
|
|
35
74
|
/**
|
|
36
75
|
* Directory listing entry
|
|
37
76
|
*/
|
|
@@ -75,6 +114,51 @@ export declare interface SignedUrlOptions {
|
|
|
75
114
|
issuer?: string
|
|
76
115
|
baseUrl?: string
|
|
77
116
|
}
|
|
117
|
+
/**
|
|
118
|
+
* Options for `presignedUploadPolicy()` — the POST-form upload
|
|
119
|
+
* primitive that S3 can enforce server-side (stacksjs/stacks#1888
|
|
120
|
+
* Phase B). Distinct from {@link PresignedUploadUrlOptions} (PUT-
|
|
121
|
+
* form): the POST policy carries a `Content-Length-Range` condition
|
|
122
|
+
* that S3 enforces server-side, so this is the right primitive when
|
|
123
|
+
* you genuinely need a size cap against an untrusted client.
|
|
124
|
+
*/
|
|
125
|
+
export declare interface PresignedUploadPolicyOptions {
|
|
126
|
+
key: string | { startsWith: string }
|
|
127
|
+
contentType: string | { startsWith: string }
|
|
128
|
+
contentLengthRange?: { min: number, max: number }
|
|
129
|
+
acl?: 'private' | 'public-read' | 'public-read-write' | 'authenticated-read' | 'bucket-owner-read' | 'bucket-owner-full-control'
|
|
130
|
+
expiresIn: number
|
|
131
|
+
fields?: Record<string, string>
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* What the caller hands to the browser. Submit as
|
|
135
|
+
* `multipart/form-data` to `url` with every entry of `fields` as a
|
|
136
|
+
* form field, then the actual file LAST under the field name
|
|
137
|
+
* `'file'`. `key` is what the upload will land at — store on the
|
|
138
|
+
* domain record.
|
|
139
|
+
*/
|
|
140
|
+
export declare interface PresignedUploadPolicy {
|
|
141
|
+
url: string
|
|
142
|
+
fields: Record<string, string>
|
|
143
|
+
key: string
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Options for `presignedUploadUrl()` (stacksjs/stacks#1856 Stage 6).
|
|
147
|
+
*/
|
|
148
|
+
export declare interface PresignedUploadUrlOptions {
|
|
149
|
+
contentType: string
|
|
150
|
+
expiresIn: number
|
|
151
|
+
dir?: string
|
|
152
|
+
filename?: string
|
|
153
|
+
maxBytes?: number
|
|
154
|
+
}
|
|
155
|
+
export declare interface PresignedUploadUrl {
|
|
156
|
+
url: string
|
|
157
|
+
path: string
|
|
158
|
+
key: string
|
|
159
|
+
contentType: string
|
|
160
|
+
maxBytes?: number
|
|
161
|
+
}
|
|
78
162
|
/**
|
|
79
163
|
* Checksum algorithm options
|
|
80
164
|
*/
|
|
@@ -98,13 +182,14 @@ export declare interface StorageAdapterConfig {
|
|
|
98
182
|
credentials?: {
|
|
99
183
|
accessKeyId: string
|
|
100
184
|
secretAccessKey: string
|
|
185
|
+
sessionToken?: string
|
|
101
186
|
}
|
|
102
187
|
}
|
|
103
188
|
/**
|
|
104
189
|
* Base storage adapter interface
|
|
105
190
|
*/
|
|
106
191
|
export declare interface StorageAdapter {
|
|
107
|
-
write(path: string, contents: FileContents): Promise<
|
|
192
|
+
write(path: string, contents: FileContents): Promise<PutResult>
|
|
108
193
|
read(path: string): Promise<FileContents>
|
|
109
194
|
readToString(path: string): Promise<string>
|
|
110
195
|
readToBuffer(path: string): Promise<Buffer>
|
|
@@ -123,6 +208,10 @@ export declare interface StorageAdapter {
|
|
|
123
208
|
publicUrl(path: string, options?: PublicUrlOptions): Promise<string>
|
|
124
209
|
temporaryUrl(path: string, options: TemporaryUrlOptions): Promise<string>
|
|
125
210
|
signedUrl?(path: string, options: SignedUrlOptions): Promise<string>
|
|
211
|
+
presignedUploadUrl?(options: PresignedUploadUrlOptions): Promise<PresignedUploadUrl>
|
|
212
|
+
presignedUploadPolicy?(options: PresignedUploadPolicyOptions): Promise<PresignedUploadPolicy>
|
|
213
|
+
getStream?(path: string, options?: GetStreamOptions): Promise<ReadableStream<Uint8Array>>
|
|
214
|
+
putStream?(path: string, stream: ReadableStream<Uint8Array>, options?: PutStreamOptions): Promise<PutResult>
|
|
126
215
|
checksum(path: string, options?: ChecksumOptions): Promise<string>
|
|
127
216
|
mimeType(path: string, options?: MimeTypeOptions): Promise<string>
|
|
128
217
|
lastModified(path: string): Promise<number>
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@stacksjs/storage",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.70.
|
|
4
|
+
"version": "0.70.53",
|
|
5
5
|
"description": "The Stacks file system.",
|
|
6
6
|
"author": "Chris Breuer",
|
|
7
7
|
"contributors": [
|
|
@@ -51,14 +51,14 @@
|
|
|
51
51
|
"prepublishOnly": "bun run build"
|
|
52
52
|
},
|
|
53
53
|
"dependencies": {
|
|
54
|
-
"@stacksjs/ts-cloud": "^0.
|
|
54
|
+
"@stacksjs/ts-cloud": "^0.7.12"
|
|
55
55
|
},
|
|
56
56
|
"devDependencies": {
|
|
57
|
-
"@stacksjs/arrays": "
|
|
57
|
+
"@stacksjs/arrays": "0.70.53",
|
|
58
58
|
"better-dx": "^0.2.12",
|
|
59
|
-
"@stacksjs/error-handling": "
|
|
60
|
-
"@stacksjs/path": "
|
|
61
|
-
"@stacksjs/strings": "
|
|
62
|
-
"@stacksjs/types": "
|
|
59
|
+
"@stacksjs/error-handling": "0.70.53",
|
|
60
|
+
"@stacksjs/path": "0.70.53",
|
|
61
|
+
"@stacksjs/strings": "0.70.53",
|
|
62
|
+
"@stacksjs/types": "0.70.53"
|
|
63
63
|
}
|
|
64
64
|
}
|