@stacksjs/storage 0.70.88 → 0.70.91
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/dist/adapters/bun.d.ts +31 -0
- package/dist/adapters/bun.js +226 -0
- package/dist/adapters/index.d.ts +6 -0
- package/dist/adapters/index.js +5 -0
- package/dist/adapters/local.d.ts +38 -0
- package/dist/adapters/local.js +225 -0
- package/dist/adapters/memory.d.ts +38 -0
- package/dist/adapters/memory.js +318 -0
- package/dist/adapters/s3.d.ts +53 -0
- package/dist/adapters/s3.js +471 -0
- package/dist/adapters/scoped.d.ts +68 -0
- package/dist/adapters/scoped.js +142 -0
- package/dist/copy.d.ts +3 -0
- package/dist/copy.js +30 -0
- package/dist/delete.d.ts +8 -0
- package/dist/delete.js +103 -0
- package/dist/drivers/aws.d.ts +4 -0
- package/dist/drivers/aws.js +94 -0
- package/dist/drivers/bun.d.ts +4 -0
- package/dist/drivers/bun.js +88 -0
- package/dist/drivers/index.d.ts +4 -0
- package/dist/drivers/index.js +4 -0
- package/dist/drivers/local.d.ts +4 -0
- package/dist/drivers/local.js +88 -0
- package/dist/drivers/memory.d.ts +4 -0
- package/dist/drivers/memory.js +67 -0
- package/dist/facade.d.ts +53 -0
- package/dist/facade.js +226 -0
- package/dist/files.d.ts +52 -0
- package/dist/files.js +126 -0
- package/dist/folders.d.ts +18 -0
- package/dist/folders.js +36 -0
- package/dist/fs.d.ts +4 -0
- package/dist/fs.js +7 -0
- package/dist/glob.d.ts +13 -0
- package/dist/glob.js +40 -0
- package/dist/hash.d.ts +5 -0
- package/dist/hash.js +33 -0
- package/dist/helpers.d.ts +7 -0
- package/dist/helpers.js +28 -0
- package/dist/image.d.ts +55 -0
- package/dist/image.js +29 -0
- package/dist/index.d.ts +60 -0
- package/dist/index.js +27 -0
- package/dist/mime-verify.d.ts +65 -0
- package/dist/mime-verify.js +47 -0
- package/dist/move.d.ts +6 -0
- package/dist/move.js +55 -0
- package/dist/path-sanitize.d.ts +92 -0
- package/dist/path-sanitize.js +84 -0
- package/dist/put-file.d.ts +53 -0
- package/dist/put-file.js +85 -0
- package/dist/s3-presigned-post.d.ts +52 -0
- package/dist/s3-presigned-post.js +68 -0
- package/dist/signed-url.d.ts +69 -0
- package/dist/signed-url.js +86 -0
- package/dist/static-serve.d.ts +37 -0
- package/dist/static-serve.js +110 -0
- package/dist/storage.d.ts +9 -0
- package/dist/storage.js +9 -0
- package/dist/types/filesystem.d.ts +131 -0
- package/dist/types/filesystem.js +40 -0
- package/dist/types.d.ts +229 -0
- package/dist/types.js +25 -0
- package/dist/uploaded-file.d.ts +38 -0
- package/dist/uploaded-file.js +114 -0
- package/dist/visibility.d.ts +3 -0
- package/dist/visibility.js +3 -0
- package/dist/zip.d.ts +16 -0
- package/dist/zip.js +41 -0
- package/package.json +6 -6
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
import type { Buffer } from 'node:buffer';
|
|
2
|
+
/**
|
|
3
|
+
* Helper to create async iterable from array
|
|
4
|
+
*/
|
|
5
|
+
export declare function createDirectoryListing(entries: DirectoryEntry[]): DirectoryListing;
|
|
6
|
+
/**
|
|
7
|
+
* Convert expiry to milliseconds
|
|
8
|
+
*/
|
|
9
|
+
export declare function normalizeExpiryToMilliseconds(expiry: number | Date): number;
|
|
10
|
+
/**
|
|
11
|
+
* Convert expiry to Date
|
|
12
|
+
*/
|
|
13
|
+
export declare function normalizeExpiryToDate(expiry: number | Date): Date;
|
|
14
|
+
/**
|
|
15
|
+
* Check if entry is a file
|
|
16
|
+
*/
|
|
17
|
+
export declare function isFile(entry: DirectoryEntry | StatEntry): boolean;
|
|
18
|
+
/**
|
|
19
|
+
* Check if entry is a directory
|
|
20
|
+
*/
|
|
21
|
+
export declare function isDirectory(entry: DirectoryEntry | StatEntry): boolean;
|
|
22
|
+
/**
|
|
23
|
+
* File stat entry information
|
|
24
|
+
*/
|
|
25
|
+
export declare interface StatEntry {
|
|
26
|
+
path: string
|
|
27
|
+
type: 'file' | 'directory'
|
|
28
|
+
visibility: Visibility
|
|
29
|
+
size: number
|
|
30
|
+
lastModified: number
|
|
31
|
+
mimeType?: string
|
|
32
|
+
metadata?: Record<string, any>
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Options for `Storage.getStream(path, options?)`
|
|
36
|
+
* (stacksjs/stacks#1886).
|
|
37
|
+
*/
|
|
38
|
+
export declare interface GetStreamOptions {
|
|
39
|
+
signal?: AbortSignal
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Options for `Storage.putStream(path, stream, options?)`
|
|
43
|
+
* (stacksjs/stacks#1886). All fields are optional; the S3 driver
|
|
44
|
+
* reads them to tune its multipart pipeline, other drivers
|
|
45
|
+
* generally only honor `contentType` and `signal`.
|
|
46
|
+
*/
|
|
47
|
+
export declare interface PutStreamOptions {
|
|
48
|
+
contentType?: string
|
|
49
|
+
signal?: AbortSignal
|
|
50
|
+
partSize?: number
|
|
51
|
+
concurrency?: number
|
|
52
|
+
maxRetries?: number
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Result returned from `Storage.put()` (stacksjs/stacks#1888 S-8).
|
|
56
|
+
*
|
|
57
|
+
* Pre-fix `put()` returned `Promise<void>` — callers that wanted to
|
|
58
|
+
* record an etag for cache-invalidation or a size for storage-quota
|
|
59
|
+
* accounting had to issue a second `.stat()` round-trip. This shape
|
|
60
|
+
* carries the metadata back from the write itself.
|
|
61
|
+
*
|
|
62
|
+
* Fields beyond `path` are best-effort: drivers that don't expose
|
|
63
|
+
* (or can't cheaply compute) a value omit it rather than synthesizing
|
|
64
|
+
* a fake one. Callers should treat them as nullable.
|
|
65
|
+
*/
|
|
66
|
+
export declare interface PutResult {
|
|
67
|
+
path: string
|
|
68
|
+
size: number
|
|
69
|
+
contentType?: string
|
|
70
|
+
lastModified?: number
|
|
71
|
+
etag?: string
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Directory listing entry
|
|
75
|
+
*/
|
|
76
|
+
export declare interface DirectoryEntry {
|
|
77
|
+
path: string
|
|
78
|
+
type: 'file' | 'directory'
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Directory listing iterator
|
|
82
|
+
*/
|
|
83
|
+
export declare interface DirectoryListing extends AsyncIterable<DirectoryEntry> {
|
|
84
|
+
[Symbol.asyncIterator](): AsyncIterator<DirectoryEntry>
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Options for listing directories
|
|
88
|
+
*/
|
|
89
|
+
export declare interface ListOptions {
|
|
90
|
+
deep?: boolean
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Options for generating public URLs
|
|
94
|
+
*/
|
|
95
|
+
export declare interface PublicUrlOptions {
|
|
96
|
+
domain?: string
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Options for generating temporary URLs
|
|
100
|
+
*/
|
|
101
|
+
export declare interface TemporaryUrlOptions {
|
|
102
|
+
expiresIn: number | Date
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Options for generating signed (JWT-style) URLs.
|
|
106
|
+
*
|
|
107
|
+
* Distinct from `TemporaryUrlOptions` so adapters that don't natively
|
|
108
|
+
* support the richer claims set (in-memory mocks) can throw a clear
|
|
109
|
+
* "unsupported" error rather than silently returning a useless URL.
|
|
110
|
+
*/
|
|
111
|
+
export declare interface SignedUrlOptions {
|
|
112
|
+
expiresIn: number | Date
|
|
113
|
+
issuer?: string
|
|
114
|
+
baseUrl?: string
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Options for `presignedUploadPolicy()` — the POST-form upload
|
|
118
|
+
* primitive that S3 can enforce server-side (stacksjs/stacks#1888
|
|
119
|
+
* Phase B). Distinct from {@link PresignedUploadUrlOptions} (PUT-
|
|
120
|
+
* form): the POST policy carries a `Content-Length-Range` condition
|
|
121
|
+
* that S3 enforces server-side, so this is the right primitive when
|
|
122
|
+
* you genuinely need a size cap against an untrusted client.
|
|
123
|
+
*/
|
|
124
|
+
export declare interface PresignedUploadPolicyOptions {
|
|
125
|
+
key: string | { startsWith: string }
|
|
126
|
+
contentType: string | { startsWith: string }
|
|
127
|
+
contentLengthRange?: { min: number, max: number }
|
|
128
|
+
acl?: 'private' | 'public-read' | 'public-read-write' | 'authenticated-read' | 'bucket-owner-read' | 'bucket-owner-full-control'
|
|
129
|
+
expiresIn: number
|
|
130
|
+
fields?: Record<string, string>
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* What the caller hands to the browser. Submit as
|
|
134
|
+
* `multipart/form-data` to `url` with every entry of `fields` as a
|
|
135
|
+
* form field, then the actual file LAST under the field name
|
|
136
|
+
* `'file'`. `key` is what the upload will land at — store on the
|
|
137
|
+
* domain record.
|
|
138
|
+
*/
|
|
139
|
+
export declare interface PresignedUploadPolicy {
|
|
140
|
+
url: string
|
|
141
|
+
fields: Record<string, string>
|
|
142
|
+
key: string
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Options for `presignedUploadUrl()` (stacksjs/stacks#1856 Stage 6).
|
|
146
|
+
*/
|
|
147
|
+
export declare interface PresignedUploadUrlOptions {
|
|
148
|
+
contentType: string
|
|
149
|
+
expiresIn: number
|
|
150
|
+
dir?: string
|
|
151
|
+
filename?: string
|
|
152
|
+
maxBytes?: number
|
|
153
|
+
}
|
|
154
|
+
export declare interface PresignedUploadUrl {
|
|
155
|
+
url: string
|
|
156
|
+
path: string
|
|
157
|
+
key: string
|
|
158
|
+
contentType: string
|
|
159
|
+
maxBytes?: number
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* Checksum algorithm options
|
|
163
|
+
*/
|
|
164
|
+
export declare interface ChecksumOptions {
|
|
165
|
+
algorithm?: 'md5' | 'sha1' | 'sha256'
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* MIME type detection options
|
|
169
|
+
*/
|
|
170
|
+
export declare interface MimeTypeOptions {
|
|
171
|
+
useExtension?: boolean
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* Storage adapter configuration
|
|
175
|
+
*/
|
|
176
|
+
export declare interface StorageAdapterConfig {
|
|
177
|
+
root?: string
|
|
178
|
+
bucket?: string
|
|
179
|
+
region?: string
|
|
180
|
+
prefix?: string
|
|
181
|
+
credentials?: {
|
|
182
|
+
accessKeyId: string
|
|
183
|
+
secretAccessKey: string
|
|
184
|
+
sessionToken?: string
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* Base storage adapter interface
|
|
189
|
+
*/
|
|
190
|
+
export declare interface StorageAdapter {
|
|
191
|
+
write(path: string, contents: FileContents): Promise<PutResult>
|
|
192
|
+
read(path: string): Promise<FileContents>
|
|
193
|
+
readToString(path: string): Promise<string>
|
|
194
|
+
readToBuffer(path: string): Promise<Buffer>
|
|
195
|
+
readToUint8Array(path: string): Promise<Uint8Array>
|
|
196
|
+
deleteFile(path: string): Promise<void>
|
|
197
|
+
deleteDirectory(path: string): Promise<void>
|
|
198
|
+
createDirectory(path: string): Promise<void>
|
|
199
|
+
moveFile(from: string, to: string): Promise<void>
|
|
200
|
+
copyFile(from: string, to: string): Promise<void>
|
|
201
|
+
stat(path: string): Promise<StatEntry>
|
|
202
|
+
list(path: string, options?: ListOptions): DirectoryListing
|
|
203
|
+
changeVisibility(path: string, visibility: Visibility): Promise<void>
|
|
204
|
+
visibility(path: string): Promise<Visibility>
|
|
205
|
+
fileExists(path: string): Promise<boolean>
|
|
206
|
+
directoryExists(path: string): Promise<boolean>
|
|
207
|
+
publicUrl(path: string, options?: PublicUrlOptions): Promise<string>
|
|
208
|
+
temporaryUrl(path: string, options: TemporaryUrlOptions): Promise<string>
|
|
209
|
+
signedUrl?(path: string, options: SignedUrlOptions): Promise<string>
|
|
210
|
+
presignedUploadUrl?(options: PresignedUploadUrlOptions): Promise<PresignedUploadUrl>
|
|
211
|
+
presignedUploadPolicy?(options: PresignedUploadPolicyOptions): Promise<PresignedUploadPolicy>
|
|
212
|
+
getStream?(path: string, options?: GetStreamOptions): Promise<ReadableStream<Uint8Array>>
|
|
213
|
+
putStream?(path: string, stream: ReadableStream<Uint8Array>, options?: PutStreamOptions): Promise<PutResult>
|
|
214
|
+
checksum(path: string, options?: ChecksumOptions): Promise<string>
|
|
215
|
+
mimeType(path: string, options?: MimeTypeOptions): Promise<string>
|
|
216
|
+
lastModified(path: string): Promise<number>
|
|
217
|
+
fileSize(path: string): Promise<number>
|
|
218
|
+
}
|
|
219
|
+
/**
|
|
220
|
+
* File contents can be a string, Buffer, Uint8Array, or ReadableStream
|
|
221
|
+
*/
|
|
222
|
+
export type FileContents = string | Buffer | Uint8Array | ReadableStream;
|
|
223
|
+
/**
|
|
224
|
+
* Visibility options for files
|
|
225
|
+
*/
|
|
226
|
+
export declare enum Visibility {
|
|
227
|
+
PUBLIC = 'public',
|
|
228
|
+
PRIVATE = 'private',
|
|
229
|
+
}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
export var Visibility;
|
|
2
|
+
((Visibility) => {
|
|
3
|
+
Visibility.PUBLIC = "public";
|
|
4
|
+
Visibility.PRIVATE = "private";
|
|
5
|
+
})(Visibility ||= {});
|
|
6
|
+
export async function* createDirectoryListing(entries) {
|
|
7
|
+
for (const entry of entries)
|
|
8
|
+
yield entry;
|
|
9
|
+
}
|
|
10
|
+
export function normalizeExpiryToMilliseconds(expiry) {
|
|
11
|
+
if (expiry instanceof Date)
|
|
12
|
+
return expiry.getTime() - Date.now();
|
|
13
|
+
return expiry * 1000;
|
|
14
|
+
}
|
|
15
|
+
export function normalizeExpiryToDate(expiry) {
|
|
16
|
+
if (expiry instanceof Date)
|
|
17
|
+
return expiry;
|
|
18
|
+
return new Date(Date.now() + expiry * 1000);
|
|
19
|
+
}
|
|
20
|
+
export function isFile(entry) {
|
|
21
|
+
return entry.type === "file";
|
|
22
|
+
}
|
|
23
|
+
export function isDirectory(entry) {
|
|
24
|
+
return entry.type === "directory";
|
|
25
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Create UploadedFile from native File
|
|
3
|
+
*/
|
|
4
|
+
export declare function uploadedFile(file: File): UploadedFile;
|
|
5
|
+
/**
|
|
6
|
+
* Create multiple UploadedFiles from native Files
|
|
7
|
+
*/
|
|
8
|
+
export declare function uploadedFiles(files: File[]): UploadedFile[];
|
|
9
|
+
export declare interface UploadedFileOptions {
|
|
10
|
+
hashName?: boolean
|
|
11
|
+
}
|
|
12
|
+
export declare class UploadedFile {
|
|
13
|
+
constructor(file: File);
|
|
14
|
+
get name(): string;
|
|
15
|
+
get extension(): string;
|
|
16
|
+
get mimeType(): string;
|
|
17
|
+
get size(): number;
|
|
18
|
+
get file(): File;
|
|
19
|
+
hashName(extension?: string): string;
|
|
20
|
+
arrayBuffer(): Promise<ArrayBuffer>;
|
|
21
|
+
bytes(): Promise<Uint8Array>;
|
|
22
|
+
text(): Promise<string>;
|
|
23
|
+
isValid(): boolean;
|
|
24
|
+
store(path?: string, disk?: string): Promise<string>;
|
|
25
|
+
storeAs(path: string, name: string, disk?: string): Promise<string>;
|
|
26
|
+
storePublicly(path?: string): Promise<string>;
|
|
27
|
+
storePubliclyAs(path: string, name: string): Promise<string>;
|
|
28
|
+
move(path: string, disk?: string): Promise<string>;
|
|
29
|
+
getClientOriginalName(): string;
|
|
30
|
+
getClientOriginalExtension(): string;
|
|
31
|
+
getClientMimeType(): string;
|
|
32
|
+
getSize(): string;
|
|
33
|
+
isOneOf(mimeTypes: string[]): boolean;
|
|
34
|
+
isImage(): boolean;
|
|
35
|
+
isVideo(): boolean;
|
|
36
|
+
isAudio(): boolean;
|
|
37
|
+
isPdf(): boolean;
|
|
38
|
+
}
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import { basename, extname, join } from "node:path";
|
|
2
|
+
import { Storage } from "./facade";
|
|
3
|
+
|
|
4
|
+
export class UploadedFile {
|
|
5
|
+
_file;
|
|
6
|
+
_hashName = null;
|
|
7
|
+
constructor(file) {
|
|
8
|
+
this._file = file;
|
|
9
|
+
}
|
|
10
|
+
get name() {
|
|
11
|
+
return this._file.name;
|
|
12
|
+
}
|
|
13
|
+
get extension() {
|
|
14
|
+
return extname(this._file.name).slice(1).toLowerCase();
|
|
15
|
+
}
|
|
16
|
+
get mimeType() {
|
|
17
|
+
return this._file.type;
|
|
18
|
+
}
|
|
19
|
+
get size() {
|
|
20
|
+
return this._file.size;
|
|
21
|
+
}
|
|
22
|
+
get file() {
|
|
23
|
+
return this._file;
|
|
24
|
+
}
|
|
25
|
+
hashName(extension) {
|
|
26
|
+
if (!this._hashName) {
|
|
27
|
+
const hash = crypto.randomUUID().replace(/-/g, "").slice(0, 32), ext = extension || this.extension;
|
|
28
|
+
this._hashName = ext ? `${hash}.${ext}` : hash;
|
|
29
|
+
}
|
|
30
|
+
return this._hashName;
|
|
31
|
+
}
|
|
32
|
+
async arrayBuffer() {
|
|
33
|
+
return this._file.arrayBuffer();
|
|
34
|
+
}
|
|
35
|
+
async bytes() {
|
|
36
|
+
const buffer = await this._file.arrayBuffer();
|
|
37
|
+
return new Uint8Array(buffer);
|
|
38
|
+
}
|
|
39
|
+
async text() {
|
|
40
|
+
return this._file.text();
|
|
41
|
+
}
|
|
42
|
+
isValid() {
|
|
43
|
+
return this._file.size > 0;
|
|
44
|
+
}
|
|
45
|
+
async store(path = "", disk = "local") {
|
|
46
|
+
const filename = this.hashName(), fullPath = path ? join(path, filename) : filename, contents = await this.bytes();
|
|
47
|
+
await Storage.disk(disk).write(fullPath, contents);
|
|
48
|
+
return fullPath;
|
|
49
|
+
}
|
|
50
|
+
async storeAs(path, name, disk = "local") {
|
|
51
|
+
if (name.includes("..") || name.includes("/") || name.includes("\\"))
|
|
52
|
+
throw Error("Invalid filename: path traversal or directory separator detected");
|
|
53
|
+
const sanitizedName = basename(name), fullPath = path ? join(path, sanitizedName) : sanitizedName, contents = await this.bytes();
|
|
54
|
+
await Storage.disk(disk).write(fullPath, contents);
|
|
55
|
+
return fullPath;
|
|
56
|
+
}
|
|
57
|
+
async storePublicly(path = "") {
|
|
58
|
+
return this.store(path, "public");
|
|
59
|
+
}
|
|
60
|
+
async storePubliclyAs(path, name) {
|
|
61
|
+
return this.storeAs(path, name, "public");
|
|
62
|
+
}
|
|
63
|
+
async move(path, disk = "local") {
|
|
64
|
+
const contents = await this.bytes();
|
|
65
|
+
await Storage.disk(disk).write(path, contents);
|
|
66
|
+
return path;
|
|
67
|
+
}
|
|
68
|
+
getClientOriginalName() {
|
|
69
|
+
return basename(this._file.name, extname(this._file.name));
|
|
70
|
+
}
|
|
71
|
+
getClientOriginalExtension() {
|
|
72
|
+
return this.extension;
|
|
73
|
+
}
|
|
74
|
+
getClientMimeType() {
|
|
75
|
+
return this._file.type;
|
|
76
|
+
}
|
|
77
|
+
getSize() {
|
|
78
|
+
const bytes = this._file.size;
|
|
79
|
+
if (bytes < 1024)
|
|
80
|
+
return `${bytes} B`;
|
|
81
|
+
if (bytes < 1048576)
|
|
82
|
+
return `${(bytes / 1024).toFixed(2)} KB`;
|
|
83
|
+
if (bytes < 1073741824)
|
|
84
|
+
return `${(bytes / 1048576).toFixed(2)} MB`;
|
|
85
|
+
return `${(bytes / 1073741824).toFixed(2)} GB`;
|
|
86
|
+
}
|
|
87
|
+
isOneOf(mimeTypes) {
|
|
88
|
+
return mimeTypes.some((type) => {
|
|
89
|
+
if (type.endsWith("/*")) {
|
|
90
|
+
const category = type.slice(0, -2);
|
|
91
|
+
return this._file.type.startsWith(category);
|
|
92
|
+
}
|
|
93
|
+
return this._file.type === type;
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
isImage() {
|
|
97
|
+
return this._file.type.startsWith("image/");
|
|
98
|
+
}
|
|
99
|
+
isVideo() {
|
|
100
|
+
return this._file.type.startsWith("video/");
|
|
101
|
+
}
|
|
102
|
+
isAudio() {
|
|
103
|
+
return this._file.type.startsWith("audio/");
|
|
104
|
+
}
|
|
105
|
+
isPdf() {
|
|
106
|
+
return this._file.type === "application/pdf";
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
export function uploadedFile(file) {
|
|
110
|
+
return new UploadedFile(file);
|
|
111
|
+
}
|
|
112
|
+
export function uploadedFiles(files) {
|
|
113
|
+
return files.map((f) => new UploadedFile(f));
|
|
114
|
+
}
|
package/dist/zip.d.ts
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { ZlibCompressionOptions } from 'bun';
|
|
2
|
+
import type { CommandError, Subprocess } from '@stacksjs/types';
|
|
3
|
+
import type { Result } from '@stacksjs/error-handling';
|
|
4
|
+
export declare function zip(from: string | string[], to?: string, options?: ZipOptions): Promise<Result<Subprocess, CommandError>>;
|
|
5
|
+
export declare function unzip(paths: string | string[]): Promise<Result<Subprocess, CommandError>>;
|
|
6
|
+
export declare function archive(paths: string | string[]): Promise<Result<Subprocess, CommandError>>;
|
|
7
|
+
export declare function unarchive(paths: string | string[]): Promise<Result<Subprocess, CommandError>>;
|
|
8
|
+
export declare function compress(paths: string[]): Promise<Result<Subprocess, CommandError>>;
|
|
9
|
+
export declare function decompress(paths: string | string[]): Promise<Result<Subprocess, CommandError>>;
|
|
10
|
+
export declare function gzipSync(data: Uint8Array, options?: ZlibCompressionOptions): Uint8Array;
|
|
11
|
+
export declare function gunzipSync(data: Uint8Array): Uint8Array;
|
|
12
|
+
export declare function deflateSync(data: Uint8Array, options?: ZlibCompressionOptions): Uint8Array;
|
|
13
|
+
export declare function inflateSync(data: Uint8Array): Uint8Array;
|
|
14
|
+
declare interface ZipOptions {
|
|
15
|
+
cwd?: string
|
|
16
|
+
}
|
package/dist/zip.js
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { runCommand } from "@stacksjs/cli";
|
|
2
|
+
function shellEscape(_arg) {
|
|
3
|
+
return `'${_arg.replace(/'/g, "'\\''")}'`;
|
|
4
|
+
}
|
|
5
|
+
export async function zip(from, to, options) {
|
|
6
|
+
const toPath = to || "archive.zip";
|
|
7
|
+
if (Array.isArray(from)) {
|
|
8
|
+
const fromPath = from.map((f) => shellEscape(f)).join(" ");
|
|
9
|
+
return runCommand(`zip -r ${shellEscape(toPath)} ${fromPath}`, options);
|
|
10
|
+
}
|
|
11
|
+
return runCommand(`zip -r ${shellEscape(toPath)} ${shellEscape(from)}`, options);
|
|
12
|
+
}
|
|
13
|
+
export async function unzip(paths) {
|
|
14
|
+
if (Array.isArray(paths))
|
|
15
|
+
return runCommand(`unzip ${paths.map((p) => shellEscape(p)).join(" ")}`);
|
|
16
|
+
return runCommand(`unzip ${shellEscape(paths)}`);
|
|
17
|
+
}
|
|
18
|
+
export function archive(paths) {
|
|
19
|
+
return zip(paths);
|
|
20
|
+
}
|
|
21
|
+
export function unarchive(paths) {
|
|
22
|
+
return unzip(paths);
|
|
23
|
+
}
|
|
24
|
+
export function compress(paths) {
|
|
25
|
+
return zip(paths);
|
|
26
|
+
}
|
|
27
|
+
export function decompress(paths) {
|
|
28
|
+
return unzip(paths);
|
|
29
|
+
}
|
|
30
|
+
export function gzipSync(data, options) {
|
|
31
|
+
return Bun.gzipSync(data, options);
|
|
32
|
+
}
|
|
33
|
+
export function gunzipSync(data) {
|
|
34
|
+
return Bun.gunzipSync(data);
|
|
35
|
+
}
|
|
36
|
+
export function deflateSync(data, options) {
|
|
37
|
+
return Bun.deflateSync(data, options);
|
|
38
|
+
}
|
|
39
|
+
export function inflateSync(data) {
|
|
40
|
+
return Bun.inflateSync(data);
|
|
41
|
+
}
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "@stacksjs/storage",
|
|
3
3
|
"type": "module",
|
|
4
4
|
"sideEffects": false,
|
|
5
|
-
"version": "0.70.
|
|
5
|
+
"version": "0.70.91",
|
|
6
6
|
"description": "The Stacks file system.",
|
|
7
7
|
"author": "Chris Breuer",
|
|
8
8
|
"contributors": [
|
|
@@ -63,12 +63,12 @@
|
|
|
63
63
|
}
|
|
64
64
|
},
|
|
65
65
|
"devDependencies": {
|
|
66
|
-
"@stacksjs/arrays": "0.70.
|
|
66
|
+
"@stacksjs/arrays": "0.70.91",
|
|
67
67
|
"better-dx": "^0.2.16",
|
|
68
|
-
"@stacksjs/error-handling": "0.70.
|
|
69
|
-
"@stacksjs/path": "0.70.
|
|
70
|
-
"@stacksjs/strings": "0.70.
|
|
71
|
-
"@stacksjs/types": "0.70.
|
|
68
|
+
"@stacksjs/error-handling": "0.70.91",
|
|
69
|
+
"@stacksjs/path": "0.70.91",
|
|
70
|
+
"@stacksjs/strings": "0.70.91",
|
|
71
|
+
"@stacksjs/types": "0.70.91",
|
|
72
72
|
"sharp": "^0.35.3"
|
|
73
73
|
}
|
|
74
74
|
}
|