@harryy/react-file-browser 0.0.0 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. package/README.md +114 -28
  2. package/dist/adapters/cloud-adapter-base.d.ts +17 -17
  3. package/dist/adapters/cloud-adapter-base.d.ts.map +1 -1
  4. package/dist/adapters/in-memory/in-memory-file-browser-adapter.d.ts +18 -17
  5. package/dist/adapters/in-memory/in-memory-file-browser-adapter.d.ts.map +1 -1
  6. package/dist/adapters/in-memory/index.js +10 -2
  7. package/dist/adapters/in-memory/index.js.map +1 -1
  8. package/dist/adapters/r2/index.d.ts +3 -3
  9. package/dist/adapters/r2/index.d.ts.map +1 -1
  10. package/dist/adapters/r2/index.js.map +1 -1
  11. package/dist/adapters/s3/index.d.ts +3 -3
  12. package/dist/adapters/s3/index.d.ts.map +1 -1
  13. package/dist/adapters/s3/index.js.map +1 -1
  14. package/dist/adapters/s3-compatible-adapter.d.ts +16 -16
  15. package/dist/adapters/s3-compatible-adapter.d.ts.map +1 -1
  16. package/dist/adapters/supabase/index.d.ts +2 -2
  17. package/dist/adapters/supabase/index.d.ts.map +1 -1
  18. package/dist/adapters/supabase/index.js.map +1 -1
  19. package/dist/adapters/supabase/supabase-file-browser-adapter.d.ts +16 -16
  20. package/dist/adapters/supabase/supabase-file-browser-adapter.d.ts.map +1 -1
  21. package/dist/chunks/cloud-adapter-base-CBUoZYLS.js.map +1 -1
  22. package/dist/chunks/path-CPm7s9NF.js.map +1 -1
  23. package/dist/chunks/s3-compatible-adapter-D9agsn9e.js.map +1 -1
  24. package/dist/components/file-browser.d.ts +24 -4
  25. package/dist/components/file-browser.d.ts.map +1 -1
  26. package/dist/core/types.d.ts +12 -10
  27. package/dist/core/types.d.ts.map +1 -1
  28. package/dist/core/use-file-browser.d.ts +25 -13
  29. package/dist/core/use-file-browser.d.ts.map +1 -1
  30. package/dist/index.d.ts +1 -1
  31. package/dist/index.d.ts.map +1 -1
  32. package/dist/index.js +1238 -1058
  33. package/dist/index.js.map +1 -1
  34. package/dist/transfers/file-browser-provider.d.ts.map +1 -1
  35. package/dist/transfers/transfer-manager.d.ts +7 -3
  36. package/dist/transfers/transfer-manager.d.ts.map +1 -1
  37. package/package.json +1 -1
package/README.md CHANGED
@@ -1,15 +1,15 @@
1
- # react-file-browser
1
+ # @harryy/react-file-browser
2
2
 
3
3
  A standalone, storage-agnostic React file manager component. Ships UI and client logic only, with
4
4
  zero server code. Storage access goes through a host-provided adapter, so the same component drives
5
5
  S3, Cloudflare R2, Supabase Storage, an in-memory store, or any backend you implement.
6
6
 
7
- [![npm version](https://img.shields.io/npm/v/react-file-browser.svg)](https://www.npmjs.com/package/react-file-browser)
8
- [![npm downloads](https://img.shields.io/npm/dm/react-file-browser.svg)](https://www.npmjs.com/package/react-file-browser)
7
+ [![npm version](https://img.shields.io/npm/v/@harryy/react-file-browser.svg)](https://www.npmjs.com/package/@harryy/react-file-browser)
8
+ [![npm downloads](https://img.shields.io/npm/dm/@harryy/react-file-browser.svg)](https://www.npmjs.com/package/@harryy/react-file-browser)
9
9
  [![CI](https://github.com/harryy2510/react-file-browser/actions/workflows/ci.yml/badge.svg)](https://github.com/harryy2510/react-file-browser/actions/workflows/ci.yml)
10
- [![bundle size](https://img.shields.io/bundlephobia/minzip/react-file-browser)](https://bundlephobia.com/package/react-file-browser)
11
- [![types](https://img.shields.io/npm/types/react-file-browser.svg)](https://www.npmjs.com/package/react-file-browser)
12
- [![license](https://img.shields.io/npm/l/react-file-browser.svg)](LICENSE)
10
+ [![bundle size](https://img.shields.io/bundlephobia/minzip/@harryy/react-file-browser)](https://bundlephobia.com/package/@harryy/react-file-browser)
11
+ [![types](https://img.shields.io/npm/types/@harryy/react-file-browser.svg)](https://www.npmjs.com/package/@harryy/react-file-browser)
12
+ [![license](https://img.shields.io/npm/l/@harryy/react-file-browser.svg)](LICENSE)
13
13
 
14
14
  **[Live demo →](https://harryy2510.github.io/react-file-browser/)**
15
15
 
@@ -27,6 +27,8 @@ S3, Cloudflare R2, Supabase Storage, an in-memory store, or any backend you impl
27
27
  zip from signed URLs.
28
28
  - **Upload policies** — reject files by MIME type, size, remaining quota, or a custom validator before
29
29
  they enqueue.
30
+ - **Host extension points** — controlled path and search state, opaque item ids, typed metadata,
31
+ custom item/details rendering, conflict policy, and custom empty states.
30
32
  - **Themeable** with CSS variables that inherit your Tailwind v4 / design-system tokens. No global CSS
31
33
  shipped.
32
34
  - **Read-only mode**, comfortable/compact density, ESM-only, fully typed.
@@ -34,8 +36,8 @@ S3, Cloudflare R2, Supabase Storage, an in-memory store, or any backend you impl
34
36
  ## Install
35
37
 
36
38
  ```bash
37
- bun add react-file-browser
38
- # or: npm install react-file-browser
39
+ bun add @harryy/react-file-browser
40
+ # or: npm install @harryy/react-file-browser
39
41
  ```
40
42
 
41
43
  `react` and `react-dom` (>=18 <20) are peer dependencies. The AWS SDK and Supabase client are
@@ -44,8 +46,8 @@ optional peers, needed only for their respective adapters.
44
46
  ## Quick start
45
47
 
46
48
  ```tsx
47
- import { FileBrowser, FileBrowserProvider } from "react-file-browser";
48
- import { InMemoryFileBrowserAdapter } from "react-file-browser/adapters/in-memory";
49
+ import { FileBrowser, FileBrowserProvider } from "@harryy/react-file-browser";
50
+ import { InMemoryFileBrowserAdapter } from "@harryy/react-file-browser/adapters/in-memory";
49
51
 
50
52
  const adapter = new InMemoryFileBrowserAdapter();
51
53
 
@@ -62,6 +64,56 @@ export function App() {
62
64
  floating transfer widget, and the refresh guard. `FileBrowser` can mount on any page or modal and can
63
65
  unmount while transfers keep running.
64
66
 
67
+ ### Host integration
68
+
69
+ `FileNode.path` remains the immutable storage key used by browser operations. Hosts can additionally
70
+ provide an opaque `id` and typed, sanitized metadata for domain-specific routes and rendering:
71
+
72
+ ```tsx
73
+ import type { FileBrowserAdapter } from "@harryy/react-file-browser";
74
+ import { FileBrowser } from "@harryy/react-file-browser";
75
+
76
+ type IndexingMetadata = {
77
+ indexingStatus: "pending" | "ready" | "failed";
78
+ indexingError?: string;
79
+ };
80
+
81
+ declare const adapter: FileBrowserAdapter<IndexingMetadata>;
82
+
83
+ <FileBrowser<IndexingMetadata>
84
+ adapter={adapter}
85
+ rootLabel="Knowledge base"
86
+ path={path}
87
+ onPathChange={(nextPath, context) => {
88
+ if (context.source === "item" && context.item.id) {
89
+ navigateToFolder(context.item.id);
90
+ }
91
+ setPath(nextPath);
92
+ }}
93
+ searchQuery={searchQuery}
94
+ onSearchQueryChange={setSearchQuery}
95
+ renderItemMeta={(item) =>
96
+ item.metadata ? <IndexingStatus status={item.metadata.indexingStatus} /> : null
97
+ }
98
+ renderDetailsContent={(item, defaultContent) => (
99
+ <>
100
+ {defaultContent}
101
+ {item.metadata ? <IndexingDetails metadata={item.metadata} /> : null}
102
+ </>
103
+ )}
104
+ uploadConflictResolutions={["keep-both", "skip"]}
105
+ allowClientZipFallback={false}
106
+ />;
107
+ ```
108
+
109
+ `onPathChange` receives the target `FileNode` for item-originated folder navigation. Breadcrumb and
110
+ programmatic navigation may not have a node. Externally changing controlled `path` or `searchQuery`
111
+ updates the browser without firing the corresponding change callback again.
112
+
113
+ Controlled search does not require putting the query in the URL. Hosts handling sensitive filenames or
114
+ search terms should keep that state out of URLs, analytics, and other durable history surfaces unless
115
+ their data policy explicitly permits it.
116
+
65
117
  ## Mount points
66
118
 
67
119
  After a hard refresh, browsers cannot restore the original `File` object automatically. Use
@@ -83,10 +135,10 @@ is accepted:
83
135
 
84
136
  The core contract is the `FileBrowserAdapter` interface. Available built-in adapters:
85
137
 
86
- - `react-file-browser/adapters/in-memory`
87
- - `react-file-browser/adapters/s3`
88
- - `react-file-browser/adapters/r2`
89
- - `react-file-browser/adapters/supabase`
138
+ - `@harryy/react-file-browser/adapters/in-memory`
139
+ - `@harryy/react-file-browser/adapters/s3`
140
+ - `@harryy/react-file-browser/adapters/r2`
141
+ - `@harryy/react-file-browser/adapters/supabase`
90
142
 
91
143
  The in-memory adapter is usable for tests and demos. It can opt into multipart methods with
92
144
  `capabilities: { multipart: true }` and `multipartPartSize` so resumable upload flows are testable
@@ -99,7 +151,7 @@ S3 and R2 use the S3-compatible SDK surface when you provide a client and bucket
99
151
 
100
152
  ```ts
101
153
  import { S3Client } from "@aws-sdk/client-s3";
102
- import { S3FileBrowserAdapter } from "react-file-browser/adapters/s3";
154
+ import { S3FileBrowserAdapter } from "@harryy/react-file-browser/adapters/s3";
103
155
 
104
156
  const adapter = new S3FileBrowserAdapter({
105
157
  bucket: "assets",
@@ -115,7 +167,7 @@ const adapter = new S3FileBrowserAdapter({
115
167
 
116
168
  ```ts
117
169
  import { createClient } from "@supabase/supabase-js";
118
- import { SupabaseFileBrowserAdapter } from "react-file-browser/adapters/supabase";
170
+ import { SupabaseFileBrowserAdapter } from "@harryy/react-file-browser/adapters/supabase";
119
171
 
120
172
  const supabase = createClient(url, anonKey);
121
173
  const adapter = new SupabaseFileBrowserAdapter({
@@ -131,7 +183,7 @@ Implement the `FileBrowserAdapter` interface directly, or pass a custom `impleme
131
183
  adapter to delegate required and optional methods:
132
184
 
133
185
  ```ts
134
- import { S3FileBrowserAdapter } from "react-file-browser/adapters/s3";
186
+ import { S3FileBrowserAdapter } from "@harryy/react-file-browser/adapters/s3";
135
187
 
136
188
  const adapter = new S3FileBrowserAdapter({
137
189
  implementation: hostBackedAdapter,
@@ -151,18 +203,30 @@ or `bulkDownloadUrl`, those controls are hidden. Recursive folder drops are reje
151
203
  | --- | --- | --- | --- |
152
204
  | `adapter` | `FileBrowserAdapter` | — (required) | Storage backend. |
153
205
  | `initialPath` | `string` | `"/"` | Directory to open on mount. |
206
+ | `path` | `string` | None | Controlled current directory. |
207
+ | `onPathChange` | `(path, context) => void` | None | Receives item, breadcrumb, and programmatic navigation. |
208
+ | `searchQuery` | `string` | None | Controlled local search query. |
209
+ | `initialSearchQuery` | `string` | `""` | Initial uncontrolled search query. |
210
+ | `onSearchQueryChange` | `(query) => void` | None | Receives user-driven search changes. |
154
211
  | `density` | `"comfortable" \| "compact"` | `"comfortable"` | Row/tile density. |
155
212
  | `readOnly` | `boolean` | `false` | Hides all mutating affordances. |
156
213
  | `showDetailsPanel` | `boolean` | `true` | Toggles the right-hand details panel. |
157
- | `uploadPolicy` | `FileBrowserUploadPolicy` | — | Reject files before they enqueue. |
158
- | `warnZipSizeBytes` | `number` | — | Warn before building a large client-side zip. |
214
+ | `uploadPolicy` | `FileBrowserUploadPolicy` | None | Reject files before they enqueue. |
215
+ | `uploadConflictResolutions` | `FileBrowserUploadConflictResolution[]` | all | Allowed conflict-dialog actions. |
216
+ | `allowClientZipFallback` | `boolean` | `true` | Allows browser-built ZIPs when no server ZIP exists. |
217
+ | `warnZipSizeBytes` | `number` | None | Warn before building a large client-side zip. |
218
+ | `rootLabel` | `string` | `"Files"` | Root breadcrumb and navigation label. |
219
+ | `emptyState` | `{ title: ReactNode; description?: ReactNode }` | built in | Empty-folder content. |
220
+ | `renderItemMeta` | `(item, { view }) => ReactNode` | None | Host metadata below grid/list item names. |
221
+ | `renderDetailsContent` | `(item, defaultContent) => ReactNode` | None | Extends single-item details. |
222
+ | `className` | `string` | None | Class name merged onto the root browser surface. |
159
223
 
160
224
  ### `<FileBrowserProvider>` props
161
225
 
162
226
  | Prop | Type | Default | Description |
163
227
  | --- | --- | --- | --- |
164
228
  | `manager` | `TransferManager` | auto-created | Bring your own transfer manager. |
165
- | `options` | `TransferManagerOptions` | — | Storage, storage key, id factory, clock. |
229
+ | `options` | `TransferManagerOptions` | — | Storage, concurrency, storage key, id factory, clock. |
166
230
  | `resolveRestoredUpload` | `(upload) => ... \| undefined` | — | Reattach a `File` when resuming after reload. |
167
231
  | `showFloatingWidget` | `boolean` | `true` | Toggles the floating transfer widget. |
168
232
 
@@ -183,16 +247,19 @@ bulk failures so successful paths stay applied and failed paths roll back.
183
247
  `useFileBrowser({ adapter, initialPath })` exposes the full state and actions if you want to build your
184
248
  own UI. The `FileBrowser` component is a consumer of this hook.
185
249
 
250
+ It also accepts controlled `path`, `searchQuery`, and their change callbacks. `navigate(path)` emits a
251
+ `programmatic` path-change source, while `open(folder)` emits the complete target item.
252
+
186
253
  ### Entry points
187
254
 
188
255
  | Import | Contents |
189
256
  | --- | --- |
190
- | `react-file-browser` | `FileBrowser`, `FileBrowserProvider`, `useFileBrowser`, `TransferManager`, adapter types and errors, path utilities. |
191
- | `react-file-browser/adapters/in-memory` | `InMemoryFileBrowserAdapter`, `createInMemoryFileBrowserAdapter`. |
192
- | `react-file-browser/adapters/s3` | `S3FileBrowserAdapter`. |
193
- | `react-file-browser/adapters/r2` | `R2FileBrowserAdapter`. |
194
- | `react-file-browser/adapters/supabase` | `SupabaseFileBrowserAdapter`. |
195
- | `react-file-browser/theme` | `FILE_BROWSER_THEME_CONTRACT`, `getFileBrowserDensityAttributes`. |
257
+ | `@harryy/react-file-browser` | `FileBrowser`, `FileBrowserProvider`, `useFileBrowser`, `TransferManager`, adapter types and errors, path utilities. |
258
+ | `@harryy/react-file-browser/adapters/in-memory` | `InMemoryFileBrowserAdapter`, `createInMemoryFileBrowserAdapter`. |
259
+ | `@harryy/react-file-browser/adapters/s3` | `S3FileBrowserAdapter`. |
260
+ | `@harryy/react-file-browser/adapters/r2` | `R2FileBrowserAdapter`. |
261
+ | `@harryy/react-file-browser/adapters/supabase` | `SupabaseFileBrowserAdapter`. |
262
+ | `@harryy/react-file-browser/theme` | `FILE_BROWSER_THEME_CONTRACT`, `getFileBrowserDensityAttributes`. |
196
263
 
197
264
  ## Styling
198
265
 
@@ -216,17 +283,36 @@ documents every token and its default.
216
283
  - `readOnly` hides upload, create, rename, move, copy, and delete affordances while keeping browsing,
217
284
  preview, details, and download available.
218
285
  - `uploadPolicy` can reject files before enqueueing transfers by MIME type, extension, max file size,
219
- remaining quota, or a custom validator. Rejections render as an alert and valid files in the same
220
- batch still upload.
286
+ remaining quota, maximum files per batch, or a custom validator. A batch over `maxFilesPerBatch` is
287
+ rejected before folders are created or transfers enqueue. Other rejections render as an alert and
288
+ valid files in the same batch still upload.
221
289
  - Upload conflicts surface a replace / keep both / skip dialog with apply-to-all support.
222
290
  - Partial bulk failures can be reported with `FileBrowserBulkActionError`; successful paths stay
223
291
  applied and failed paths are surfaced in a dialog.
224
292
  - Single-file download uses `signedUrl`. Folder and multi-select bulk download uses `bulkDownloadUrl`
225
293
  when present, otherwise it builds a client zip from signed URLs after the configured size warning.
294
+ Set `allowClientZipFallback={false}` to require server ZIP support for folder and multi-file download.
226
295
  - Move-capable adapters enable the destination tree picker, Cut/Paste, and drag onto folders.
227
296
  - Keyboard shortcuts include Enter preview/open, F2 rename, Delete confirm, Cmd/Ctrl+A selection, and
228
297
  Cmd/Ctrl+C/X/V for adapter-gated copy, cut, and paste.
229
298
 
299
+ ### Transfer persistence and concurrency
300
+
301
+ Provider-owned managers use `window.localStorage` by default so resumable state can survive a refresh.
302
+ Set `options={{ storage: null }}` to keep transfer state in memory only. This preserves transfers across
303
+ SPA navigation and browser unmounts but writes no filenames, paths, results, or metadata to durable web
304
+ storage. Transfer persistence serializes only the fields needed to restore transfer status and resume
305
+ multipart work; arbitrary `FileNode.metadata` is never persisted.
306
+
307
+ Set `maxConcurrentUploads` in provider options to bound active uploads across every browser using that
308
+ provider. Queued, resumed, and restored uploads share the same limit:
309
+
310
+ ```tsx
311
+ <FileBrowserProvider options={{ maxConcurrentUploads: MAX_CONCURRENT_UPLOADS, storage: null }}>
312
+ <App />
313
+ </FileBrowserProvider>
314
+ ```
315
+
230
316
  ## Required backend lifecycle
231
317
 
232
318
  The package never creates server routes or lifecycle rules. Hosts must configure:
@@ -1,27 +1,27 @@
1
1
  import type { FileBrowserAdapter, FileBrowserListOptions, FileBrowserListResult, FileBrowserUploadOptions, FileNode } from '../core/types';
2
2
  export type CloudAdapterName = 'S3' | 'R2' | 'Supabase';
3
- export type CloudFileBrowserAdapterOptions = {
4
- implementation?: FileBrowserAdapter;
3
+ export type CloudFileBrowserAdapterOptions<TMetadata = unknown> = {
4
+ implementation?: FileBrowserAdapter<TMetadata>;
5
5
  };
6
- export declare class UnsupportedCloudFileBrowserAdapter implements FileBrowserAdapter {
6
+ export declare class UnsupportedCloudFileBrowserAdapter<TMetadata = unknown> implements FileBrowserAdapter<TMetadata> {
7
7
  private readonly adapterName;
8
- readonly rename?: NonNullable<FileBrowserAdapter['rename']>;
9
- readonly createFolder?: NonNullable<FileBrowserAdapter['createFolder']>;
10
- readonly move?: NonNullable<FileBrowserAdapter['move']>;
11
- readonly copy?: NonNullable<FileBrowserAdapter['copy']>;
12
- readonly stat?: NonNullable<FileBrowserAdapter['stat']>;
13
- readonly exists?: NonNullable<FileBrowserAdapter['exists']>;
14
- readonly createMultipartUpload?: NonNullable<FileBrowserAdapter['createMultipartUpload']>;
15
- readonly uploadPart?: NonNullable<FileBrowserAdapter['uploadPart']>;
16
- readonly completeMultipartUpload?: NonNullable<FileBrowserAdapter['completeMultipartUpload']>;
17
- readonly abortMultipartUpload?: NonNullable<FileBrowserAdapter['abortMultipartUpload']>;
18
- readonly bulkDownloadUrl?: NonNullable<FileBrowserAdapter['bulkDownloadUrl']>;
8
+ readonly rename?: NonNullable<FileBrowserAdapter<TMetadata>['rename']>;
9
+ readonly createFolder?: NonNullable<FileBrowserAdapter<TMetadata>['createFolder']>;
10
+ readonly move?: NonNullable<FileBrowserAdapter<TMetadata>['move']>;
11
+ readonly copy?: NonNullable<FileBrowserAdapter<TMetadata>['copy']>;
12
+ readonly stat?: NonNullable<FileBrowserAdapter<TMetadata>['stat']>;
13
+ readonly exists?: NonNullable<FileBrowserAdapter<TMetadata>['exists']>;
14
+ readonly createMultipartUpload?: NonNullable<FileBrowserAdapter<TMetadata>['createMultipartUpload']>;
15
+ readonly uploadPart?: NonNullable<FileBrowserAdapter<TMetadata>['uploadPart']>;
16
+ readonly completeMultipartUpload?: NonNullable<FileBrowserAdapter<TMetadata>['completeMultipartUpload']>;
17
+ readonly abortMultipartUpload?: NonNullable<FileBrowserAdapter<TMetadata>['abortMultipartUpload']>;
18
+ readonly bulkDownloadUrl?: NonNullable<FileBrowserAdapter<TMetadata>['bulkDownloadUrl']>;
19
19
  private readonly implementation?;
20
- constructor(adapterName: CloudAdapterName, options?: CloudFileBrowserAdapterOptions);
21
- list(path: string, opts?: FileBrowserListOptions): Promise<FileBrowserListResult>;
20
+ constructor(adapterName: CloudAdapterName, options?: CloudFileBrowserAdapterOptions<TMetadata>);
21
+ list(path: string, opts?: FileBrowserListOptions): Promise<FileBrowserListResult<TMetadata>>;
22
22
  delete(paths: string[]): Promise<void>;
23
23
  signedUrl(path: string): Promise<string>;
24
- upload(path: string, file: File, opts?: FileBrowserUploadOptions): Promise<FileNode>;
24
+ upload(path: string, file: File, opts?: FileBrowserUploadOptions): Promise<FileNode<TMetadata>>;
25
25
  private error;
26
26
  }
27
27
  //# sourceMappingURL=cloud-adapter-base.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"cloud-adapter-base.d.ts","sourceRoot":"","sources":["../../src/adapters/cloud-adapter-base.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACX,kBAAkB,EAClB,sBAAsB,EACtB,qBAAqB,EACrB,wBAAwB,EACxB,QAAQ,EACR,MAAM,eAAe,CAAA;AAEtB,MAAM,MAAM,gBAAgB,GAAG,IAAI,GAAG,IAAI,GAAG,UAAU,CAAA;AAEvD,MAAM,MAAM,8BAA8B,GAAG;IAC5C,cAAc,CAAC,EAAE,kBAAkB,CAAA;CACnC,CAAA;AAED,qBAAa,kCAAmC,YAAW,kBAAkB;IAgB3E,OAAO,CAAC,QAAQ,CAAC,WAAW;IAf7B,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,CAAC,kBAAkB,CAAC,QAAQ,CAAC,CAAC,CAAA;IAC3D,QAAQ,CAAC,YAAY,CAAC,EAAE,WAAW,CAAC,kBAAkB,CAAC,cAAc,CAAC,CAAC,CAAA;IACvE,QAAQ,CAAC,IAAI,CAAC,EAAE,WAAW,CAAC,kBAAkB,CAAC,MAAM,CAAC,CAAC,CAAA;IACvD,QAAQ,CAAC,IAAI,CAAC,EAAE,WAAW,CAAC,kBAAkB,CAAC,MAAM,CAAC,CAAC,CAAA;IACvD,QAAQ,CAAC,IAAI,CAAC,EAAE,WAAW,CAAC,kBAAkB,CAAC,MAAM,CAAC,CAAC,CAAA;IACvD,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,CAAC,kBAAkB,CAAC,QAAQ,CAAC,CAAC,CAAA;IAC3D,QAAQ,CAAC,qBAAqB,CAAC,EAAE,WAAW,CAAC,kBAAkB,CAAC,uBAAuB,CAAC,CAAC,CAAA;IACzF,QAAQ,CAAC,UAAU,CAAC,EAAE,WAAW,CAAC,kBAAkB,CAAC,YAAY,CAAC,CAAC,CAAA;IACnE,QAAQ,CAAC,uBAAuB,CAAC,EAAE,WAAW,CAAC,kBAAkB,CAAC,yBAAyB,CAAC,CAAC,CAAA;IAC7F,QAAQ,CAAC,oBAAoB,CAAC,EAAE,WAAW,CAAC,kBAAkB,CAAC,sBAAsB,CAAC,CAAC,CAAA;IACvF,QAAQ,CAAC,eAAe,CAAC,EAAE,WAAW,CAAC,kBAAkB,CAAC,iBAAiB,CAAC,CAAC,CAAA;IAE7E,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAC,CAAoB;gBAGlC,WAAW,EAAE,gBAAgB,EAC9C,OAAO,GAAE,8BAAmC;IAuC7C,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,sBAAsB,GAAG,OAAO,CAAC,qBAAqB,CAAC;IASjF,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAQtC,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAQxC,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,wBAAwB,GAAG,OAAO,CAAC,QAAQ,CAAC;IAUpF,OAAO,CAAC,KAAK;CAMb"}
1
+ {"version":3,"file":"cloud-adapter-base.d.ts","sourceRoot":"","sources":["../../src/adapters/cloud-adapter-base.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACX,kBAAkB,EAClB,sBAAsB,EACtB,qBAAqB,EACrB,wBAAwB,EACxB,QAAQ,EACR,MAAM,eAAe,CAAA;AAEtB,MAAM,MAAM,gBAAgB,GAAG,IAAI,GAAG,IAAI,GAAG,UAAU,CAAA;AAEvD,MAAM,MAAM,8BAA8B,CAAC,SAAS,GAAG,OAAO,IAAI;IACjE,cAAc,CAAC,EAAE,kBAAkB,CAAC,SAAS,CAAC,CAAA;CAC9C,CAAA;AAED,qBAAa,kCAAkC,CAAC,SAAS,GAAG,OAAO,CAAE,YAAW,kBAAkB,CAAC,SAAS,CAAC;IAgB3G,OAAO,CAAC,QAAQ,CAAC,WAAW;IAf7B,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,CAAC,kBAAkB,CAAC,SAAS,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAA;IACtE,QAAQ,CAAC,YAAY,CAAC,EAAE,WAAW,CAAC,kBAAkB,CAAC,SAAS,CAAC,CAAC,cAAc,CAAC,CAAC,CAAA;IAClF,QAAQ,CAAC,IAAI,CAAC,EAAE,WAAW,CAAC,kBAAkB,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,CAAC,CAAA;IAClE,QAAQ,CAAC,IAAI,CAAC,EAAE,WAAW,CAAC,kBAAkB,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,CAAC,CAAA;IAClE,QAAQ,CAAC,IAAI,CAAC,EAAE,WAAW,CAAC,kBAAkB,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,CAAC,CAAA;IAClE,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,CAAC,kBAAkB,CAAC,SAAS,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAA;IACtE,QAAQ,CAAC,qBAAqB,CAAC,EAAE,WAAW,CAAC,kBAAkB,CAAC,SAAS,CAAC,CAAC,uBAAuB,CAAC,CAAC,CAAA;IACpG,QAAQ,CAAC,UAAU,CAAC,EAAE,WAAW,CAAC,kBAAkB,CAAC,SAAS,CAAC,CAAC,YAAY,CAAC,CAAC,CAAA;IAC9E,QAAQ,CAAC,uBAAuB,CAAC,EAAE,WAAW,CAAC,kBAAkB,CAAC,SAAS,CAAC,CAAC,yBAAyB,CAAC,CAAC,CAAA;IACxG,QAAQ,CAAC,oBAAoB,CAAC,EAAE,WAAW,CAAC,kBAAkB,CAAC,SAAS,CAAC,CAAC,sBAAsB,CAAC,CAAC,CAAA;IAClG,QAAQ,CAAC,eAAe,CAAC,EAAE,WAAW,CAAC,kBAAkB,CAAC,SAAS,CAAC,CAAC,iBAAiB,CAAC,CAAC,CAAA;IAExF,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAC,CAA+B;gBAG7C,WAAW,EAAE,gBAAgB,EAC9C,OAAO,GAAE,8BAA8B,CAAC,SAAS,CAAM;IAuCxD,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,sBAAsB,GAAG,OAAO,CAAC,qBAAqB,CAAC,SAAS,CAAC,CAAC;IAS5F,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAQtC,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAQxC,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,wBAAwB,GAAG,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC;IAU/F,OAAO,CAAC,KAAK;CAMb"}
@@ -1,23 +1,24 @@
1
1
  import type { FileBrowserAdapter, FileBrowserListOptions, FileBrowserListResult, FileBrowserUploadOptions, FileNode } from '../../core/types';
2
2
  export type InMemoryFileBrowserCapability = 'createFolder' | 'rename' | 'move' | 'copy' | 'stat' | 'exists' | 'bulkDownloadUrl' | 'multipart';
3
- export type InMemoryFileBrowserAdapterOptions = {
3
+ export type InMemoryFileBrowserAdapterOptions<TMetadata = unknown> = {
4
4
  capabilities?: Partial<Record<InMemoryFileBrowserCapability, boolean>>;
5
+ initialEntries?: readonly FileNode<TMetadata>[];
5
6
  multipartPartSize?: number;
6
7
  pageSize?: number;
7
8
  now?: () => Date;
8
9
  };
9
- export declare class InMemoryFileBrowserAdapter implements FileBrowserAdapter {
10
- readonly createFolder?: NonNullable<FileBrowserAdapter['createFolder']>;
11
- readonly rename?: NonNullable<FileBrowserAdapter['rename']>;
12
- readonly move?: NonNullable<FileBrowserAdapter['move']>;
13
- readonly copy?: NonNullable<FileBrowserAdapter['copy']>;
14
- readonly stat?: NonNullable<FileBrowserAdapter['stat']>;
15
- readonly exists?: NonNullable<FileBrowserAdapter['exists']>;
16
- readonly bulkDownloadUrl?: NonNullable<FileBrowserAdapter['bulkDownloadUrl']>;
17
- readonly createMultipartUpload?: NonNullable<FileBrowserAdapter['createMultipartUpload']>;
18
- readonly uploadPart?: NonNullable<FileBrowserAdapter['uploadPart']>;
19
- readonly completeMultipartUpload?: NonNullable<FileBrowserAdapter['completeMultipartUpload']>;
20
- readonly abortMultipartUpload?: NonNullable<FileBrowserAdapter['abortMultipartUpload']>;
10
+ export declare class InMemoryFileBrowserAdapter<TMetadata = unknown> implements FileBrowserAdapter<TMetadata> {
11
+ readonly createFolder?: NonNullable<FileBrowserAdapter<TMetadata>['createFolder']>;
12
+ readonly rename?: NonNullable<FileBrowserAdapter<TMetadata>['rename']>;
13
+ readonly move?: NonNullable<FileBrowserAdapter<TMetadata>['move']>;
14
+ readonly copy?: NonNullable<FileBrowserAdapter<TMetadata>['copy']>;
15
+ readonly stat?: NonNullable<FileBrowserAdapter<TMetadata>['stat']>;
16
+ readonly exists?: NonNullable<FileBrowserAdapter<TMetadata>['exists']>;
17
+ readonly bulkDownloadUrl?: NonNullable<FileBrowserAdapter<TMetadata>['bulkDownloadUrl']>;
18
+ readonly createMultipartUpload?: NonNullable<FileBrowserAdapter<TMetadata>['createMultipartUpload']>;
19
+ readonly uploadPart?: NonNullable<FileBrowserAdapter<TMetadata>['uploadPart']>;
20
+ readonly completeMultipartUpload?: NonNullable<FileBrowserAdapter<TMetadata>['completeMultipartUpload']>;
21
+ readonly abortMultipartUpload?: NonNullable<FileBrowserAdapter<TMetadata>['abortMultipartUpload']>;
21
22
  private readonly entries;
22
23
  private readonly multipartUploads;
23
24
  private readonly multipartPartSize;
@@ -25,12 +26,12 @@ export declare class InMemoryFileBrowserAdapter implements FileBrowserAdapter {
25
26
  private readonly now;
26
27
  private etagSequence;
27
28
  private multipartSequence;
28
- constructor(options?: InMemoryFileBrowserAdapterOptions);
29
- list(path: string, opts?: FileBrowserListOptions): Promise<FileBrowserListResult>;
29
+ constructor(options?: InMemoryFileBrowserAdapterOptions<TMetadata>);
30
+ list(path: string, opts?: FileBrowserListOptions): Promise<FileBrowserListResult<TMetadata>>;
30
31
  private createFolderEntry;
31
32
  delete(paths: string[]): Promise<void>;
32
33
  signedUrl(path: string): Promise<string>;
33
- upload(path: string, file: File, opts?: FileBrowserUploadOptions): Promise<FileNode>;
34
+ upload(path: string, file: File, opts?: FileBrowserUploadOptions): Promise<FileNode<TMetadata>>;
34
35
  private nextAvailablePath;
35
36
  private renameEntry;
36
37
  private moveEntries;
@@ -49,5 +50,5 @@ export declare class InMemoryFileBrowserAdapter implements FileBrowserAdapter {
49
50
  private timestamp;
50
51
  private nextEtag;
51
52
  }
52
- export declare function createInMemoryFileBrowserAdapter(options?: InMemoryFileBrowserAdapterOptions): InMemoryFileBrowserAdapter;
53
+ export declare function createInMemoryFileBrowserAdapter<TMetadata = unknown>(options?: InMemoryFileBrowserAdapterOptions<TMetadata>): InMemoryFileBrowserAdapter<TMetadata>;
53
54
  //# sourceMappingURL=in-memory-file-browser-adapter.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"in-memory-file-browser-adapter.d.ts","sourceRoot":"","sources":["../../../src/adapters/in-memory/in-memory-file-browser-adapter.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"in-memory-file-browser-adapter.d.ts","sourceRoot":"","sources":["../../../src/adapters/in-memory/in-memory-file-browser-adapter.ts"],"names":[],"mappings":"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"}
@@ -39,7 +39,15 @@ var c = {
39
39
  name: "",
40
40
  kind: "folder",
41
41
  modifiedAt: this.timestamp()
42
- }), t.createFolder && (this.createFolder = this.createFolderEntry.bind(this)), t.rename && (this.rename = this.renameEntry.bind(this)), t.move && (this.move = this.moveEntries.bind(this)), t.copy && (this.copy = this.copyEntries.bind(this)), t.stat && (this.stat = this.statEntry.bind(this)), t.exists && (this.exists = this.existsEntries.bind(this)), t.bulkDownloadUrl && (this.bulkDownloadUrl = this.createBulkDownloadUrl.bind(this)), t.multipart && (this.createMultipartUpload = this.createMultipartUploadEntry.bind(this), this.uploadPart = this.uploadMultipartPart.bind(this), this.completeMultipartUpload = this.completeMultipartUploadEntry.bind(this), this.abortMultipartUpload = this.abortMultipartUploadEntry.bind(this));
42
+ });
43
+ for (let t of e.initialEntries ?? []) {
44
+ let e = i(t.path);
45
+ this.entries.set(e, {
46
+ ...t,
47
+ path: e
48
+ });
49
+ }
50
+ t.createFolder && (this.createFolder = this.createFolderEntry.bind(this)), t.rename && (this.rename = this.renameEntry.bind(this)), t.move && (this.move = this.moveEntries.bind(this)), t.copy && (this.copy = this.copyEntries.bind(this)), t.stat && (this.stat = this.statEntry.bind(this)), t.exists && (this.exists = this.existsEntries.bind(this)), t.bulkDownloadUrl && (this.bulkDownloadUrl = this.createBulkDownloadUrl.bind(this)), t.multipart && (this.createMultipartUpload = this.createMultipartUploadEntry.bind(this), this.uploadPart = this.uploadMultipartPart.bind(this), this.completeMultipartUpload = this.completeMultipartUploadEntry.bind(this), this.abortMultipartUpload = this.abortMultipartUploadEntry.bind(this));
43
51
  }
44
52
  list(e, n = {}) {
45
53
  p(n.signal);
@@ -250,7 +258,7 @@ function d(e) {
250
258
  name: e.name,
251
259
  kind: e.kind
252
260
  };
253
- return e.size !== void 0 && (t.size = e.size), e.mimeType !== void 0 && (t.mimeType = e.mimeType), e.modifiedAt !== void 0 && (t.modifiedAt = e.modifiedAt), e.etag !== void 0 && (t.etag = e.etag), e.thumbnailUrl !== void 0 && (t.thumbnailUrl = e.thumbnailUrl), t;
261
+ return e.id !== void 0 && (t.id = e.id), e.size !== void 0 && (t.size = e.size), e.mimeType !== void 0 && (t.mimeType = e.mimeType), e.modifiedAt !== void 0 && (t.modifiedAt = e.modifiedAt), e.etag !== void 0 && (t.etag = e.etag), e.thumbnailUrl !== void 0 && (t.thumbnailUrl = e.thumbnailUrl), e.metadata !== void 0 && (t.metadata = e.metadata), t;
254
262
  }
255
263
  function f(e, t) {
256
264
  return e.kind === t.kind ? e.name.localeCompare(t.name, void 0, {
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../../../src/adapters/in-memory/in-memory-file-browser-adapter.ts"],"sourcesContent":["import { zipSync } from 'fflate'\nimport type { Zippable } from 'fflate'\nimport { FileBrowserAdapterError } from '../../core/types'\nimport type {\n\tFileBrowserAdapter,\n\tFileBrowserListOptions,\n\tFileBrowserListResult,\n\tFileBrowserUploadOptions,\n\tFileNode\n} from '../../core/types'\nimport {\n\tROOT_PATH,\n\tgetFileBrowserBasename,\n\tgetFileBrowserDirname,\n\tisFileBrowserDescendantOrSelf,\n\tjoinFileBrowserPath,\n\tnormalizeFileBrowserPath,\n\treplaceFileBrowserPathPrefix\n} from '../../core/path'\n\nexport type InMemoryFileBrowserCapability =\n\t| 'createFolder'\n\t| 'rename'\n\t| 'move'\n\t| 'copy'\n\t| 'stat'\n\t| 'exists'\n\t| 'bulkDownloadUrl'\n\t| 'multipart'\n\nexport type InMemoryFileBrowserAdapterOptions = {\n\tcapabilities?: Partial<Record<InMemoryFileBrowserCapability, boolean>>\n\tmultipartPartSize?: number\n\tpageSize?: number\n\tnow?: () => Date\n}\n\ntype InMemoryEntry = FileNode & {\n\tblob?: Blob\n}\n\ntype InMemoryMultipartUpload = {\n\tpath: string\n\tsize: number\n\tpartSize: number\n\tparts: Map<number, { blob: Blob; etag: string }>\n}\n\nconst DEFAULT_CAPABILITIES: Record<InMemoryFileBrowserCapability, boolean> = {\n\tcreateFolder: true,\n\trename: true,\n\tmove: true,\n\tcopy: true,\n\tstat: true,\n\texists: true,\n\tbulkDownloadUrl: true,\n\tmultipart: false\n}\n\nexport class InMemoryFileBrowserAdapter implements FileBrowserAdapter {\n\treadonly createFolder?: NonNullable<FileBrowserAdapter['createFolder']>\n\treadonly rename?: NonNullable<FileBrowserAdapter['rename']>\n\treadonly move?: NonNullable<FileBrowserAdapter['move']>\n\treadonly copy?: NonNullable<FileBrowserAdapter['copy']>\n\treadonly stat?: NonNullable<FileBrowserAdapter['stat']>\n\treadonly exists?: NonNullable<FileBrowserAdapter['exists']>\n\treadonly bulkDownloadUrl?: NonNullable<FileBrowserAdapter['bulkDownloadUrl']>\n\treadonly createMultipartUpload?: NonNullable<FileBrowserAdapter['createMultipartUpload']>\n\treadonly uploadPart?: NonNullable<FileBrowserAdapter['uploadPart']>\n\treadonly completeMultipartUpload?: NonNullable<FileBrowserAdapter['completeMultipartUpload']>\n\treadonly abortMultipartUpload?: NonNullable<FileBrowserAdapter['abortMultipartUpload']>\n\n\tprivate readonly entries = new Map<string, InMemoryEntry>()\n\tprivate readonly multipartUploads = new Map<string, InMemoryMultipartUpload>()\n\tprivate readonly multipartPartSize: number\n\tprivate readonly pageSize?: number\n\tprivate readonly now: () => Date\n\tprivate etagSequence = 0\n\tprivate multipartSequence = 0\n\n\tconstructor(options: InMemoryFileBrowserAdapterOptions = {}) {\n\t\tconst capabilities = {\n\t\t\t...DEFAULT_CAPABILITIES,\n\t\t\t...options.capabilities\n\t\t}\n\n\t\tthis.pageSize = options.pageSize\n\t\tthis.multipartPartSize = Math.max(1, options.multipartPartSize ?? 5 * 1024 * 1024)\n\t\tthis.now = options.now ?? (() => new Date())\n\t\tthis.entries.set(ROOT_PATH, {\n\t\t\tpath: ROOT_PATH,\n\t\t\tname: '',\n\t\t\tkind: 'folder',\n\t\t\tmodifiedAt: this.timestamp()\n\t\t})\n\n\t\tif (capabilities.createFolder) {\n\t\t\tthis.createFolder = this.createFolderEntry.bind(this)\n\t\t}\n\n\t\tif (capabilities.rename) {\n\t\t\tthis.rename = this.renameEntry.bind(this)\n\t\t}\n\n\t\tif (capabilities.move) {\n\t\t\tthis.move = this.moveEntries.bind(this)\n\t\t}\n\n\t\tif (capabilities.copy) {\n\t\t\tthis.copy = this.copyEntries.bind(this)\n\t\t}\n\n\t\tif (capabilities.stat) {\n\t\t\tthis.stat = this.statEntry.bind(this)\n\t\t}\n\n\t\tif (capabilities.exists) {\n\t\t\tthis.exists = this.existsEntries.bind(this)\n\t\t}\n\n\t\tif (capabilities.bulkDownloadUrl) {\n\t\t\tthis.bulkDownloadUrl = this.createBulkDownloadUrl.bind(this)\n\t\t}\n\n\t\tif (capabilities.multipart) {\n\t\t\tthis.createMultipartUpload = this.createMultipartUploadEntry.bind(this)\n\t\t\tthis.uploadPart = this.uploadMultipartPart.bind(this)\n\t\t\tthis.completeMultipartUpload = this.completeMultipartUploadEntry.bind(this)\n\t\t\tthis.abortMultipartUpload = this.abortMultipartUploadEntry.bind(this)\n\t\t}\n\t}\n\n\tlist(path: string, opts: FileBrowserListOptions = {}): Promise<FileBrowserListResult> {\n\t\tthrowIfAborted(opts.signal)\n\t\tconst normalized = normalizeFileBrowserPath(path)\n\t\tconst folder = this.getEntry(normalized)\n\n\t\tif (folder.kind !== 'folder') {\n\t\t\tthrow new FileBrowserAdapterError('invalid_path', `Cannot list a file path: ${normalized}`)\n\t\t}\n\n\t\tconst allItems = Array.from(this.entries.values())\n\t\t\t.filter((entry) => entry.path !== ROOT_PATH)\n\t\t\t.filter((entry) => getFileBrowserDirname(entry.path) === normalized)\n\t\t\t.sort(compareEntries)\n\t\t\t.map(cloneNode)\n\n\t\tif (!this.pageSize) {\n\t\t\treturn Promise.resolve({ items: allItems })\n\t\t}\n\n\t\tconst start = opts.cursor ? Number.parseInt(opts.cursor, 10) : 0\n\t\tconst safeStart = Number.isFinite(start) && start > 0 ? start : 0\n\t\tconst items = allItems.slice(safeStart, safeStart + this.pageSize)\n\t\tconst next = safeStart + items.length\n\n\t\treturn Promise.resolve({\n\t\t\titems,\n\t\t\tcursor: next < allItems.length ? String(next) : undefined\n\t\t})\n\t}\n\n\tprivate createFolderEntry(path: string): Promise<FileNode> {\n\t\tconst normalized = normalizeFileBrowserPath(path)\n\n\t\tif (normalized === ROOT_PATH) {\n\t\t\treturn Promise.resolve(cloneNode(this.getEntry(ROOT_PATH)))\n\t\t}\n\n\t\tif (this.entries.has(normalized)) {\n\t\t\tthrow new FileBrowserAdapterError('conflict', `A file browser entry already exists at ${normalized}`)\n\t\t}\n\n\t\tthis.assertFolderExists(getFileBrowserDirname(normalized))\n\n\t\tconst entry: InMemoryEntry = {\n\t\t\tpath: normalized,\n\t\t\tname: getFileBrowserBasename(normalized),\n\t\t\tkind: 'folder',\n\t\t\tmodifiedAt: this.timestamp(),\n\t\t\tetag: this.nextEtag()\n\t\t}\n\n\t\tthis.entries.set(normalized, entry)\n\t\treturn Promise.resolve(cloneNode(entry))\n\t}\n\n\tdelete(paths: string[]): Promise<void> {\n\t\tfor (const path of paths.map(normalizeFileBrowserPath)) {\n\t\t\tif (path === ROOT_PATH) {\n\t\t\t\tthrow new FileBrowserAdapterError('invalid_path', 'Cannot delete the root folder')\n\t\t\t}\n\n\t\t\tthis.getEntry(path)\n\n\t\t\tfor (const candidate of Array.from(this.entries.keys())) {\n\t\t\t\tif (isFileBrowserDescendantOrSelf(path, candidate)) {\n\t\t\t\t\tthis.entries.delete(candidate)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn Promise.resolve()\n\t}\n\n\tsignedUrl(path: string): Promise<string> {\n\t\tconst entry = this.getEntry(path)\n\n\t\tif (entry.kind !== 'file' || !entry.blob) {\n\t\t\tthrow new FileBrowserAdapterError('invalid_path', `Cannot create a signed URL for a folder: ${entry.path}`)\n\t\t}\n\n\t\treturn Promise.resolve(URL.createObjectURL(entry.blob))\n\t}\n\n\tupload(path: string, file: File, opts: FileBrowserUploadOptions = {}): Promise<FileNode> {\n\t\tthrowIfAborted(opts.signal)\n\t\tlet normalized = normalizeFileBrowserPath(path)\n\t\tthis.assertFolderExists(getFileBrowserDirname(normalized))\n\n\t\tif (this.entries.has(normalized) && opts.onConflict !== 'replace') {\n\t\t\tif (opts.onConflict === 'keep-both') {\n\t\t\t\tnormalized = this.nextAvailablePath(normalized)\n\t\t\t} else {\n\t\t\t\tthrow new FileBrowserAdapterError('conflict', `A file browser entry already exists at ${normalized}`)\n\t\t\t}\n\t\t}\n\n\t\topts.onProgress?.(0, file.size)\n\t\tthrowIfAborted(opts.signal)\n\n\t\tconst entry: InMemoryEntry = {\n\t\t\tpath: normalized,\n\t\t\tname: getFileBrowserBasename(normalized) || file.name,\n\t\t\tkind: 'file',\n\t\t\tsize: file.size,\n\t\t\tmimeType: file.type || undefined,\n\t\t\tmodifiedAt: this.timestamp(),\n\t\t\tetag: this.nextEtag(),\n\t\t\tblob: file\n\t\t}\n\n\t\tthis.entries.set(normalized, entry)\n\t\topts.onProgress?.(file.size, file.size)\n\n\t\treturn Promise.resolve(cloneNode(entry))\n\t}\n\n\tprivate nextAvailablePath(path: string): string {\n\t\tconst dir = getFileBrowserDirname(path)\n\t\tconst basename = getFileBrowserBasename(path)\n\t\tconst dotIndex = basename.lastIndexOf('.')\n\t\tconst hasExtension = dotIndex > 0\n\t\tconst stem = hasExtension ? basename.slice(0, dotIndex) : basename\n\t\tconst extension = hasExtension ? basename.slice(dotIndex) : ''\n\n\t\tfor (let index = 1; index < Number.MAX_SAFE_INTEGER; index += 1) {\n\t\t\tconst candidate = joinFileBrowserPath(dir, `${stem} (${index})${extension}`)\n\t\t\tif (!this.entries.has(candidate)) {\n\t\t\t\treturn candidate\n\t\t\t}\n\t\t}\n\n\t\tthrow new FileBrowserAdapterError('conflict', `Could not allocate a unique file browser path for ${path}`)\n\t}\n\n\tprivate renameEntry(path: string, newName: string): Promise<FileNode> {\n\t\tconst normalized = normalizeFileBrowserPath(path)\n\t\tconst entry = this.getEntry(normalized)\n\t\tconst trimmedName = newName.trim()\n\n\t\tif (!trimmedName || trimmedName.includes('/') || trimmedName.includes('\\\\')) {\n\t\t\tthrow new FileBrowserAdapterError('invalid_path', `Invalid file browser name: ${newName}`)\n\t\t}\n\n\t\tconst updated: InMemoryEntry = {\n\t\t\t...entry,\n\t\t\tname: trimmedName,\n\t\t\tmodifiedAt: this.timestamp(),\n\t\t\tetag: this.nextEtag()\n\t\t}\n\n\t\tthis.entries.set(normalized, updated)\n\t\treturn Promise.resolve(cloneNode(updated))\n\t}\n\n\tprivate async moveEntries(from: string[], toDir: string): Promise<void> {\n\t\tawait this.copyEntries(from, toDir)\n\n\t\tfor (const path of from) {\n\t\t\tawait this.delete([path])\n\t\t}\n\t}\n\n\tprivate copyEntries(from: string[], toDir: string): Promise<void> {\n\t\tconst normalizedToDir = normalizeFileBrowserPath(toDir)\n\t\tthis.assertFolderExists(normalizedToDir)\n\n\t\tconst copies = new Map<string, InMemoryEntry>()\n\n\t\tfor (const sourcePath of from.map(normalizeFileBrowserPath)) {\n\t\t\tconst source = this.getEntry(sourcePath)\n\t\t\tconst destinationRoot = joinFileBrowserPath(normalizedToDir, getFileBrowserBasename(source.path))\n\n\t\t\tfor (const entry of this.collectTree(source.path)) {\n\t\t\t\tconst destinationPath = replaceFileBrowserPathPrefix(entry.path, source.path, destinationRoot)\n\n\t\t\t\tif (this.entries.has(destinationPath) || copies.has(destinationPath)) {\n\t\t\t\t\tthrow new FileBrowserAdapterError('conflict', `A file browser entry already exists at ${destinationPath}`)\n\t\t\t\t}\n\n\t\t\t\tcopies.set(destinationPath, {\n\t\t\t\t\t...entry,\n\t\t\t\t\tpath: destinationPath,\n\t\t\t\t\tname: entry.path === source.path ? getFileBrowserBasename(destinationPath) : entry.name,\n\t\t\t\t\tmodifiedAt: this.timestamp(),\n\t\t\t\t\tetag: this.nextEtag()\n\t\t\t\t})\n\t\t\t}\n\t\t}\n\n\t\tfor (const [path, entry] of copies) {\n\t\t\tthis.entries.set(path, entry)\n\t\t}\n\n\t\treturn Promise.resolve()\n\t}\n\n\tprivate statEntry(path: string): Promise<FileNode> {\n\t\treturn Promise.resolve(cloneNode(this.getEntry(path)))\n\t}\n\n\tprivate existsEntries(paths: string[]): Promise<Record<string, boolean>> {\n\t\treturn Promise.resolve(\n\t\t\tObject.fromEntries(\n\t\t\t\tpaths.map((path) => {\n\t\t\t\t\tconst normalized = normalizeFileBrowserPath(path)\n\t\t\t\t\treturn [normalized, this.entries.has(normalized)]\n\t\t\t\t})\n\t\t\t)\n\t\t)\n\t}\n\n\tprivate async createBulkDownloadUrl(paths: string[]): Promise<{ url: string; expiresAt: string }> {\n\t\tconst zippable: Zippable = {}\n\n\t\tfor (const path of paths) {\n\t\t\tthis.getEntry(path)\n\t\t\tconst tree = this.collectTree(path)\n\t\t\tfor (const entry of tree) {\n\t\t\t\tif (entry.kind === 'folder' || !entry.blob) {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tzippable[toArchivePath(entry.path)] = new Uint8Array(await entry.blob.arrayBuffer())\n\t\t\t}\n\t\t}\n\n\t\tconst archive = new Blob([zipSync(zippable)], {\n\t\t\ttype: 'application/zip'\n\t\t})\n\n\t\treturn {\n\t\t\turl: URL.createObjectURL(archive),\n\t\t\texpiresAt: new Date(this.now().getTime() + 4 * 60 * 60 * 1000).toISOString()\n\t\t}\n\t}\n\n\tprivate createMultipartUploadEntry(path: string, size: number): Promise<{ uploadId: string; partSize: number }> {\n\t\tconst normalized = normalizeFileBrowserPath(path)\n\t\tthis.assertFolderExists(getFileBrowserDirname(normalized))\n\n\t\tconst existing = this.entries.get(normalized)\n\t\tif (existing?.kind === 'folder') {\n\t\t\tthrow new FileBrowserAdapterError('conflict', `A file browser entry already exists at ${normalized}`)\n\t\t}\n\n\t\tthis.multipartSequence += 1\n\t\tconst uploadId = `memory-multipart-${this.multipartSequence}`\n\t\tthis.multipartUploads.set(uploadId, {\n\t\t\tpath: normalized,\n\t\t\tsize,\n\t\t\tpartSize: this.multipartPartSize,\n\t\t\tparts: new Map()\n\t\t})\n\n\t\treturn Promise.resolve({ uploadId, partSize: this.multipartPartSize })\n\t}\n\n\tprivate uploadMultipartPart({\n\t\tchunk,\n\t\tonProgress,\n\t\tpartNumber,\n\t\tsignal,\n\t\tuploadId\n\t}: Parameters<NonNullable<FileBrowserAdapter['uploadPart']>>[0]): Promise<{\n\t\tetag: string\n\t}> {\n\t\treturn Promise.resolve().then(() => {\n\t\t\tthrowIfAborted(signal)\n\t\t\tconst upload = this.getMultipartUpload(uploadId)\n\t\t\tconst etag = `memory-part-${partNumber}`\n\t\t\tupload.parts.set(partNumber, { blob: chunk, etag })\n\t\t\tonProgress?.(chunk.size)\n\t\t\tthrowIfAborted(signal)\n\n\t\t\treturn { etag }\n\t\t})\n\t}\n\n\tprivate completeMultipartUploadEntry({\n\t\tparts,\n\t\tuploadId\n\t}: Parameters<NonNullable<FileBrowserAdapter['completeMultipartUpload']>>[0]): Promise<FileNode> {\n\t\treturn Promise.resolve().then(() => {\n\t\t\tconst upload = this.getMultipartUpload(uploadId)\n\t\t\tconst blobs: Blob[] = []\n\n\t\t\tfor (const part of parts.sort((left, right) => left.partNumber - right.partNumber)) {\n\t\t\t\tconst uploaded = upload.parts.get(part.partNumber)\n\t\t\t\tif (!uploaded || uploaded.etag !== part.etag) {\n\t\t\t\t\tthrow new FileBrowserAdapterError('not_found', `No uploaded part ${part.partNumber} exists for ${uploadId}`)\n\t\t\t\t}\n\t\t\t\tblobs.push(uploaded.blob)\n\t\t\t}\n\n\t\t\tconst blob = new Blob(blobs)\n\t\t\tif (blob.size !== upload.size) {\n\t\t\t\tthrow new FileBrowserAdapterError('invalid_path', `Multipart upload ${uploadId} size mismatch`)\n\t\t\t}\n\n\t\t\tconst entry: InMemoryEntry = {\n\t\t\t\tpath: upload.path,\n\t\t\t\tname: getFileBrowserBasename(upload.path),\n\t\t\t\tkind: 'file',\n\t\t\t\tsize: blob.size,\n\t\t\t\tmodifiedAt: this.timestamp(),\n\t\t\t\tetag: this.nextEtag(),\n\t\t\t\tblob\n\t\t\t}\n\t\t\tthis.entries.set(upload.path, entry)\n\t\t\tthis.multipartUploads.delete(uploadId)\n\n\t\t\treturn cloneNode(entry)\n\t\t})\n\t}\n\n\tprivate abortMultipartUploadEntry(uploadId: string): Promise<void> {\n\t\treturn Promise.resolve().then(() => {\n\t\t\tthis.getMultipartUpload(uploadId)\n\t\t\tthis.multipartUploads.delete(uploadId)\n\t\t})\n\t}\n\n\tprivate getMultipartUpload(uploadId: string): InMemoryMultipartUpload {\n\t\tconst upload = this.multipartUploads.get(uploadId)\n\t\tif (!upload) {\n\t\t\tthrow new FileBrowserAdapterError('not_found', `No multipart upload exists for ${uploadId}`)\n\t\t}\n\t\treturn upload\n\t}\n\n\tprivate collectTree(path: string): InMemoryEntry[] {\n\t\tconst normalized = normalizeFileBrowserPath(path)\n\t\treturn Array.from(this.entries.values())\n\t\t\t.filter((entry) => isFileBrowserDescendantOrSelf(normalized, entry.path))\n\t\t\t.sort((left, right) => left.path.localeCompare(right.path))\n\t}\n\n\tprivate assertFolderExists(path: string): void {\n\t\tconst entry = this.getEntry(path)\n\n\t\tif (entry.kind !== 'folder') {\n\t\t\tthrow new FileBrowserAdapterError('invalid_path', `Expected a folder at ${entry.path}`)\n\t\t}\n\t}\n\n\tprivate getEntry(path: string): InMemoryEntry {\n\t\tconst normalized = normalizeFileBrowserPath(path)\n\t\tconst entry = this.entries.get(normalized)\n\n\t\tif (!entry) {\n\t\t\tthrow new FileBrowserAdapterError('not_found', `No file browser entry exists at ${normalized}`)\n\t\t}\n\n\t\treturn entry\n\t}\n\n\tprivate timestamp(): string {\n\t\treturn this.now().toISOString()\n\t}\n\n\tprivate nextEtag(): string {\n\t\tthis.etagSequence += 1\n\t\treturn `memory-${this.etagSequence}`\n\t}\n}\n\nexport function createInMemoryFileBrowserAdapter(\n\toptions?: InMemoryFileBrowserAdapterOptions\n): InMemoryFileBrowserAdapter {\n\treturn new InMemoryFileBrowserAdapter(options)\n}\n\nfunction cloneNode(entry: InMemoryEntry): FileNode {\n\tconst node: FileNode = {\n\t\tpath: entry.path,\n\t\tname: entry.name,\n\t\tkind: entry.kind\n\t}\n\n\tif (entry.size !== undefined) {\n\t\tnode.size = entry.size\n\t}\n\n\tif (entry.mimeType !== undefined) {\n\t\tnode.mimeType = entry.mimeType\n\t}\n\n\tif (entry.modifiedAt !== undefined) {\n\t\tnode.modifiedAt = entry.modifiedAt\n\t}\n\n\tif (entry.etag !== undefined) {\n\t\tnode.etag = entry.etag\n\t}\n\n\tif (entry.thumbnailUrl !== undefined) {\n\t\tnode.thumbnailUrl = entry.thumbnailUrl\n\t}\n\n\treturn node\n}\n\nfunction compareEntries(left: InMemoryEntry, right: InMemoryEntry): number {\n\tif (left.kind !== right.kind) {\n\t\treturn left.kind === 'folder' ? -1 : 1\n\t}\n\n\treturn left.name.localeCompare(right.name, undefined, {\n\t\tnumeric: true,\n\t\tsensitivity: 'base'\n\t})\n}\n\nfunction throwIfAborted(signal?: AbortSignal): void {\n\tif (signal?.aborted) {\n\t\tthrow new FileBrowserAdapterError('aborted', 'Operation was aborted')\n\t}\n}\n\nfunction toArchivePath(path: string): string {\n\treturn path.replace(/^\\/+/, '') || 'download'\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../../src/adapters/in-memory/in-memory-file-browser-adapter.ts"],"sourcesContent":["import { zipSync } from 'fflate'\nimport type { Zippable } from 'fflate'\nimport { FileBrowserAdapterError } from '../../core/types'\nimport type {\n\tFileBrowserAdapter,\n\tFileBrowserListOptions,\n\tFileBrowserListResult,\n\tFileBrowserUploadOptions,\n\tFileNode\n} from '../../core/types'\nimport {\n\tROOT_PATH,\n\tgetFileBrowserBasename,\n\tgetFileBrowserDirname,\n\tisFileBrowserDescendantOrSelf,\n\tjoinFileBrowserPath,\n\tnormalizeFileBrowserPath,\n\treplaceFileBrowserPathPrefix\n} from '../../core/path'\n\nexport type InMemoryFileBrowserCapability =\n\t| 'createFolder'\n\t| 'rename'\n\t| 'move'\n\t| 'copy'\n\t| 'stat'\n\t| 'exists'\n\t| 'bulkDownloadUrl'\n\t| 'multipart'\n\nexport type InMemoryFileBrowserAdapterOptions<TMetadata = unknown> = {\n\tcapabilities?: Partial<Record<InMemoryFileBrowserCapability, boolean>>\n\tinitialEntries?: readonly FileNode<TMetadata>[]\n\tmultipartPartSize?: number\n\tpageSize?: number\n\tnow?: () => Date\n}\n\ntype InMemoryEntry<TMetadata> = FileNode<TMetadata> & {\n\tblob?: Blob\n}\n\ntype InMemoryMultipartUpload = {\n\tpath: string\n\tsize: number\n\tpartSize: number\n\tparts: Map<number, { blob: Blob; etag: string }>\n}\n\nconst DEFAULT_CAPABILITIES: Record<InMemoryFileBrowserCapability, boolean> = {\n\tcreateFolder: true,\n\trename: true,\n\tmove: true,\n\tcopy: true,\n\tstat: true,\n\texists: true,\n\tbulkDownloadUrl: true,\n\tmultipart: false\n}\n\nexport class InMemoryFileBrowserAdapter<TMetadata = unknown> implements FileBrowserAdapter<TMetadata> {\n\treadonly createFolder?: NonNullable<FileBrowserAdapter<TMetadata>['createFolder']>\n\treadonly rename?: NonNullable<FileBrowserAdapter<TMetadata>['rename']>\n\treadonly move?: NonNullable<FileBrowserAdapter<TMetadata>['move']>\n\treadonly copy?: NonNullable<FileBrowserAdapter<TMetadata>['copy']>\n\treadonly stat?: NonNullable<FileBrowserAdapter<TMetadata>['stat']>\n\treadonly exists?: NonNullable<FileBrowserAdapter<TMetadata>['exists']>\n\treadonly bulkDownloadUrl?: NonNullable<FileBrowserAdapter<TMetadata>['bulkDownloadUrl']>\n\treadonly createMultipartUpload?: NonNullable<FileBrowserAdapter<TMetadata>['createMultipartUpload']>\n\treadonly uploadPart?: NonNullable<FileBrowserAdapter<TMetadata>['uploadPart']>\n\treadonly completeMultipartUpload?: NonNullable<FileBrowserAdapter<TMetadata>['completeMultipartUpload']>\n\treadonly abortMultipartUpload?: NonNullable<FileBrowserAdapter<TMetadata>['abortMultipartUpload']>\n\n\tprivate readonly entries = new Map<string, InMemoryEntry<TMetadata>>()\n\tprivate readonly multipartUploads = new Map<string, InMemoryMultipartUpload>()\n\tprivate readonly multipartPartSize: number\n\tprivate readonly pageSize?: number\n\tprivate readonly now: () => Date\n\tprivate etagSequence = 0\n\tprivate multipartSequence = 0\n\n\tconstructor(options: InMemoryFileBrowserAdapterOptions<TMetadata> = {}) {\n\t\tconst capabilities = {\n\t\t\t...DEFAULT_CAPABILITIES,\n\t\t\t...options.capabilities\n\t\t}\n\n\t\tthis.pageSize = options.pageSize\n\t\tthis.multipartPartSize = Math.max(1, options.multipartPartSize ?? 5 * 1024 * 1024)\n\t\tthis.now = options.now ?? (() => new Date())\n\t\tthis.entries.set(ROOT_PATH, {\n\t\t\tpath: ROOT_PATH,\n\t\t\tname: '',\n\t\t\tkind: 'folder',\n\t\t\tmodifiedAt: this.timestamp()\n\t\t})\n\t\tfor (const node of options.initialEntries ?? []) {\n\t\t\tconst normalized = normalizeFileBrowserPath(node.path)\n\t\t\tthis.entries.set(normalized, { ...node, path: normalized })\n\t\t}\n\n\t\tif (capabilities.createFolder) {\n\t\t\tthis.createFolder = this.createFolderEntry.bind(this)\n\t\t}\n\n\t\tif (capabilities.rename) {\n\t\t\tthis.rename = this.renameEntry.bind(this)\n\t\t}\n\n\t\tif (capabilities.move) {\n\t\t\tthis.move = this.moveEntries.bind(this)\n\t\t}\n\n\t\tif (capabilities.copy) {\n\t\t\tthis.copy = this.copyEntries.bind(this)\n\t\t}\n\n\t\tif (capabilities.stat) {\n\t\t\tthis.stat = this.statEntry.bind(this)\n\t\t}\n\n\t\tif (capabilities.exists) {\n\t\t\tthis.exists = this.existsEntries.bind(this)\n\t\t}\n\n\t\tif (capabilities.bulkDownloadUrl) {\n\t\t\tthis.bulkDownloadUrl = this.createBulkDownloadUrl.bind(this)\n\t\t}\n\n\t\tif (capabilities.multipart) {\n\t\t\tthis.createMultipartUpload = this.createMultipartUploadEntry.bind(this)\n\t\t\tthis.uploadPart = this.uploadMultipartPart.bind(this)\n\t\t\tthis.completeMultipartUpload = this.completeMultipartUploadEntry.bind(this)\n\t\t\tthis.abortMultipartUpload = this.abortMultipartUploadEntry.bind(this)\n\t\t}\n\t}\n\n\tlist(path: string, opts: FileBrowserListOptions = {}): Promise<FileBrowserListResult<TMetadata>> {\n\t\tthrowIfAborted(opts.signal)\n\t\tconst normalized = normalizeFileBrowserPath(path)\n\t\tconst folder = this.getEntry(normalized)\n\n\t\tif (folder.kind !== 'folder') {\n\t\t\tthrow new FileBrowserAdapterError('invalid_path', `Cannot list a file path: ${normalized}`)\n\t\t}\n\n\t\tconst allItems = Array.from(this.entries.values())\n\t\t\t.filter((entry) => entry.path !== ROOT_PATH)\n\t\t\t.filter((entry) => getFileBrowserDirname(entry.path) === normalized)\n\t\t\t.sort(compareEntries)\n\t\t\t.map(cloneNode)\n\n\t\tif (!this.pageSize) {\n\t\t\treturn Promise.resolve({ items: allItems })\n\t\t}\n\n\t\tconst start = opts.cursor ? Number.parseInt(opts.cursor, 10) : 0\n\t\tconst safeStart = Number.isFinite(start) && start > 0 ? start : 0\n\t\tconst items = allItems.slice(safeStart, safeStart + this.pageSize)\n\t\tconst next = safeStart + items.length\n\n\t\treturn Promise.resolve({\n\t\t\titems,\n\t\t\tcursor: next < allItems.length ? String(next) : undefined\n\t\t})\n\t}\n\n\tprivate createFolderEntry(path: string): Promise<FileNode<TMetadata>> {\n\t\tconst normalized = normalizeFileBrowserPath(path)\n\n\t\tif (normalized === ROOT_PATH) {\n\t\t\treturn Promise.resolve(cloneNode(this.getEntry(ROOT_PATH)))\n\t\t}\n\n\t\tif (this.entries.has(normalized)) {\n\t\t\tthrow new FileBrowserAdapterError('conflict', `A file browser entry already exists at ${normalized}`)\n\t\t}\n\n\t\tthis.assertFolderExists(getFileBrowserDirname(normalized))\n\n\t\tconst entry: InMemoryEntry<TMetadata> = {\n\t\t\tpath: normalized,\n\t\t\tname: getFileBrowserBasename(normalized),\n\t\t\tkind: 'folder',\n\t\t\tmodifiedAt: this.timestamp(),\n\t\t\tetag: this.nextEtag()\n\t\t}\n\n\t\tthis.entries.set(normalized, entry)\n\t\treturn Promise.resolve(cloneNode(entry))\n\t}\n\n\tdelete(paths: string[]): Promise<void> {\n\t\tfor (const path of paths.map(normalizeFileBrowserPath)) {\n\t\t\tif (path === ROOT_PATH) {\n\t\t\t\tthrow new FileBrowserAdapterError('invalid_path', 'Cannot delete the root folder')\n\t\t\t}\n\n\t\t\tthis.getEntry(path)\n\n\t\t\tfor (const candidate of Array.from(this.entries.keys())) {\n\t\t\t\tif (isFileBrowserDescendantOrSelf(path, candidate)) {\n\t\t\t\t\tthis.entries.delete(candidate)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn Promise.resolve()\n\t}\n\n\tsignedUrl(path: string): Promise<string> {\n\t\tconst entry = this.getEntry(path)\n\n\t\tif (entry.kind !== 'file' || !entry.blob) {\n\t\t\tthrow new FileBrowserAdapterError('invalid_path', `Cannot create a signed URL for a folder: ${entry.path}`)\n\t\t}\n\n\t\treturn Promise.resolve(URL.createObjectURL(entry.blob))\n\t}\n\n\tupload(path: string, file: File, opts: FileBrowserUploadOptions = {}): Promise<FileNode<TMetadata>> {\n\t\tthrowIfAborted(opts.signal)\n\t\tlet normalized = normalizeFileBrowserPath(path)\n\t\tthis.assertFolderExists(getFileBrowserDirname(normalized))\n\n\t\tif (this.entries.has(normalized) && opts.onConflict !== 'replace') {\n\t\t\tif (opts.onConflict === 'keep-both') {\n\t\t\t\tnormalized = this.nextAvailablePath(normalized)\n\t\t\t} else {\n\t\t\t\tthrow new FileBrowserAdapterError('conflict', `A file browser entry already exists at ${normalized}`)\n\t\t\t}\n\t\t}\n\n\t\topts.onProgress?.(0, file.size)\n\t\tthrowIfAborted(opts.signal)\n\n\t\tconst entry: InMemoryEntry<TMetadata> = {\n\t\t\tpath: normalized,\n\t\t\tname: getFileBrowserBasename(normalized) || file.name,\n\t\t\tkind: 'file',\n\t\t\tsize: file.size,\n\t\t\tmimeType: file.type || undefined,\n\t\t\tmodifiedAt: this.timestamp(),\n\t\t\tetag: this.nextEtag(),\n\t\t\tblob: file\n\t\t}\n\n\t\tthis.entries.set(normalized, entry)\n\t\topts.onProgress?.(file.size, file.size)\n\n\t\treturn Promise.resolve(cloneNode(entry))\n\t}\n\n\tprivate nextAvailablePath(path: string): string {\n\t\tconst dir = getFileBrowserDirname(path)\n\t\tconst basename = getFileBrowserBasename(path)\n\t\tconst dotIndex = basename.lastIndexOf('.')\n\t\tconst hasExtension = dotIndex > 0\n\t\tconst stem = hasExtension ? basename.slice(0, dotIndex) : basename\n\t\tconst extension = hasExtension ? basename.slice(dotIndex) : ''\n\n\t\tfor (let index = 1; index < Number.MAX_SAFE_INTEGER; index += 1) {\n\t\t\tconst candidate = joinFileBrowserPath(dir, `${stem} (${index})${extension}`)\n\t\t\tif (!this.entries.has(candidate)) {\n\t\t\t\treturn candidate\n\t\t\t}\n\t\t}\n\n\t\tthrow new FileBrowserAdapterError('conflict', `Could not allocate a unique file browser path for ${path}`)\n\t}\n\n\tprivate renameEntry(path: string, newName: string): Promise<FileNode<TMetadata>> {\n\t\tconst normalized = normalizeFileBrowserPath(path)\n\t\tconst entry = this.getEntry(normalized)\n\t\tconst trimmedName = newName.trim()\n\n\t\tif (!trimmedName || trimmedName.includes('/') || trimmedName.includes('\\\\')) {\n\t\t\tthrow new FileBrowserAdapterError('invalid_path', `Invalid file browser name: ${newName}`)\n\t\t}\n\n\t\tconst updated: InMemoryEntry<TMetadata> = {\n\t\t\t...entry,\n\t\t\tname: trimmedName,\n\t\t\tmodifiedAt: this.timestamp(),\n\t\t\tetag: this.nextEtag()\n\t\t}\n\n\t\tthis.entries.set(normalized, updated)\n\t\treturn Promise.resolve(cloneNode(updated))\n\t}\n\n\tprivate async moveEntries(from: string[], toDir: string): Promise<void> {\n\t\tawait this.copyEntries(from, toDir)\n\n\t\tfor (const path of from) {\n\t\t\tawait this.delete([path])\n\t\t}\n\t}\n\n\tprivate copyEntries(from: string[], toDir: string): Promise<void> {\n\t\tconst normalizedToDir = normalizeFileBrowserPath(toDir)\n\t\tthis.assertFolderExists(normalizedToDir)\n\n\t\tconst copies = new Map<string, InMemoryEntry<TMetadata>>()\n\n\t\tfor (const sourcePath of from.map(normalizeFileBrowserPath)) {\n\t\t\tconst source = this.getEntry(sourcePath)\n\t\t\tconst destinationRoot = joinFileBrowserPath(normalizedToDir, getFileBrowserBasename(source.path))\n\n\t\t\tfor (const entry of this.collectTree(source.path)) {\n\t\t\t\tconst destinationPath = replaceFileBrowserPathPrefix(entry.path, source.path, destinationRoot)\n\n\t\t\t\tif (this.entries.has(destinationPath) || copies.has(destinationPath)) {\n\t\t\t\t\tthrow new FileBrowserAdapterError('conflict', `A file browser entry already exists at ${destinationPath}`)\n\t\t\t\t}\n\n\t\t\t\tcopies.set(destinationPath, {\n\t\t\t\t\t...entry,\n\t\t\t\t\tpath: destinationPath,\n\t\t\t\t\tname: entry.path === source.path ? getFileBrowserBasename(destinationPath) : entry.name,\n\t\t\t\t\tmodifiedAt: this.timestamp(),\n\t\t\t\t\tetag: this.nextEtag()\n\t\t\t\t})\n\t\t\t}\n\t\t}\n\n\t\tfor (const [path, entry] of copies) {\n\t\t\tthis.entries.set(path, entry)\n\t\t}\n\n\t\treturn Promise.resolve()\n\t}\n\n\tprivate statEntry(path: string): Promise<FileNode<TMetadata>> {\n\t\treturn Promise.resolve(cloneNode(this.getEntry(path)))\n\t}\n\n\tprivate existsEntries(paths: string[]): Promise<Record<string, boolean>> {\n\t\treturn Promise.resolve(\n\t\t\tObject.fromEntries(\n\t\t\t\tpaths.map((path) => {\n\t\t\t\t\tconst normalized = normalizeFileBrowserPath(path)\n\t\t\t\t\treturn [normalized, this.entries.has(normalized)]\n\t\t\t\t})\n\t\t\t)\n\t\t)\n\t}\n\n\tprivate async createBulkDownloadUrl(paths: string[]): Promise<{ url: string; expiresAt: string }> {\n\t\tconst zippable: Zippable = {}\n\n\t\tfor (const path of paths) {\n\t\t\tthis.getEntry(path)\n\t\t\tconst tree = this.collectTree(path)\n\t\t\tfor (const entry of tree) {\n\t\t\t\tif (entry.kind === 'folder' || !entry.blob) {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tzippable[toArchivePath(entry.path)] = new Uint8Array(await entry.blob.arrayBuffer())\n\t\t\t}\n\t\t}\n\n\t\tconst archive = new Blob([zipSync(zippable)], {\n\t\t\ttype: 'application/zip'\n\t\t})\n\n\t\treturn {\n\t\t\turl: URL.createObjectURL(archive),\n\t\t\texpiresAt: new Date(this.now().getTime() + 4 * 60 * 60 * 1000).toISOString()\n\t\t}\n\t}\n\n\tprivate createMultipartUploadEntry(path: string, size: number): Promise<{ uploadId: string; partSize: number }> {\n\t\tconst normalized = normalizeFileBrowserPath(path)\n\t\tthis.assertFolderExists(getFileBrowserDirname(normalized))\n\n\t\tconst existing = this.entries.get(normalized)\n\t\tif (existing?.kind === 'folder') {\n\t\t\tthrow new FileBrowserAdapterError('conflict', `A file browser entry already exists at ${normalized}`)\n\t\t}\n\n\t\tthis.multipartSequence += 1\n\t\tconst uploadId = `memory-multipart-${this.multipartSequence}`\n\t\tthis.multipartUploads.set(uploadId, {\n\t\t\tpath: normalized,\n\t\t\tsize,\n\t\t\tpartSize: this.multipartPartSize,\n\t\t\tparts: new Map()\n\t\t})\n\n\t\treturn Promise.resolve({ uploadId, partSize: this.multipartPartSize })\n\t}\n\n\tprivate uploadMultipartPart({\n\t\tchunk,\n\t\tonProgress,\n\t\tpartNumber,\n\t\tsignal,\n\t\tuploadId\n\t}: Parameters<NonNullable<FileBrowserAdapter<TMetadata>['uploadPart']>>[0]): Promise<{\n\t\tetag: string\n\t}> {\n\t\treturn Promise.resolve().then(() => {\n\t\t\tthrowIfAborted(signal)\n\t\t\tconst upload = this.getMultipartUpload(uploadId)\n\t\t\tconst etag = `memory-part-${partNumber}`\n\t\t\tupload.parts.set(partNumber, { blob: chunk, etag })\n\t\t\tonProgress?.(chunk.size)\n\t\t\tthrowIfAborted(signal)\n\n\t\t\treturn { etag }\n\t\t})\n\t}\n\n\tprivate completeMultipartUploadEntry({\n\t\tparts,\n\t\tuploadId\n\t}: Parameters<NonNullable<FileBrowserAdapter<TMetadata>['completeMultipartUpload']>>[0]): Promise<\n\t\tFileNode<TMetadata>\n\t> {\n\t\treturn Promise.resolve().then(() => {\n\t\t\tconst upload = this.getMultipartUpload(uploadId)\n\t\t\tconst blobs: Blob[] = []\n\n\t\t\tfor (const part of parts.sort((left, right) => left.partNumber - right.partNumber)) {\n\t\t\t\tconst uploaded = upload.parts.get(part.partNumber)\n\t\t\t\tif (!uploaded || uploaded.etag !== part.etag) {\n\t\t\t\t\tthrow new FileBrowserAdapterError('not_found', `No uploaded part ${part.partNumber} exists for ${uploadId}`)\n\t\t\t\t}\n\t\t\t\tblobs.push(uploaded.blob)\n\t\t\t}\n\n\t\t\tconst blob = new Blob(blobs)\n\t\t\tif (blob.size !== upload.size) {\n\t\t\t\tthrow new FileBrowserAdapterError('invalid_path', `Multipart upload ${uploadId} size mismatch`)\n\t\t\t}\n\n\t\t\tconst entry: InMemoryEntry<TMetadata> = {\n\t\t\t\tpath: upload.path,\n\t\t\t\tname: getFileBrowserBasename(upload.path),\n\t\t\t\tkind: 'file',\n\t\t\t\tsize: blob.size,\n\t\t\t\tmodifiedAt: this.timestamp(),\n\t\t\t\tetag: this.nextEtag(),\n\t\t\t\tblob\n\t\t\t}\n\t\t\tthis.entries.set(upload.path, entry)\n\t\t\tthis.multipartUploads.delete(uploadId)\n\n\t\t\treturn cloneNode(entry)\n\t\t})\n\t}\n\n\tprivate abortMultipartUploadEntry(uploadId: string): Promise<void> {\n\t\treturn Promise.resolve().then(() => {\n\t\t\tthis.getMultipartUpload(uploadId)\n\t\t\tthis.multipartUploads.delete(uploadId)\n\t\t})\n\t}\n\n\tprivate getMultipartUpload(uploadId: string): InMemoryMultipartUpload {\n\t\tconst upload = this.multipartUploads.get(uploadId)\n\t\tif (!upload) {\n\t\t\tthrow new FileBrowserAdapterError('not_found', `No multipart upload exists for ${uploadId}`)\n\t\t}\n\t\treturn upload\n\t}\n\n\tprivate collectTree(path: string): InMemoryEntry<TMetadata>[] {\n\t\tconst normalized = normalizeFileBrowserPath(path)\n\t\treturn Array.from(this.entries.values())\n\t\t\t.filter((entry) => isFileBrowserDescendantOrSelf(normalized, entry.path))\n\t\t\t.sort((left, right) => left.path.localeCompare(right.path))\n\t}\n\n\tprivate assertFolderExists(path: string): void {\n\t\tconst entry = this.getEntry(path)\n\n\t\tif (entry.kind !== 'folder') {\n\t\t\tthrow new FileBrowserAdapterError('invalid_path', `Expected a folder at ${entry.path}`)\n\t\t}\n\t}\n\n\tprivate getEntry(path: string): InMemoryEntry<TMetadata> {\n\t\tconst normalized = normalizeFileBrowserPath(path)\n\t\tconst entry = this.entries.get(normalized)\n\n\t\tif (!entry) {\n\t\t\tthrow new FileBrowserAdapterError('not_found', `No file browser entry exists at ${normalized}`)\n\t\t}\n\n\t\treturn entry\n\t}\n\n\tprivate timestamp(): string {\n\t\treturn this.now().toISOString()\n\t}\n\n\tprivate nextEtag(): string {\n\t\tthis.etagSequence += 1\n\t\treturn `memory-${this.etagSequence}`\n\t}\n}\n\nexport function createInMemoryFileBrowserAdapter<TMetadata = unknown>(\n\toptions?: InMemoryFileBrowserAdapterOptions<TMetadata>\n): InMemoryFileBrowserAdapter<TMetadata> {\n\treturn new InMemoryFileBrowserAdapter<TMetadata>(options)\n}\n\nfunction cloneNode<TMetadata>(entry: InMemoryEntry<TMetadata>): FileNode<TMetadata> {\n\tconst node: FileNode<TMetadata> = {\n\t\tpath: entry.path,\n\t\tname: entry.name,\n\t\tkind: entry.kind\n\t}\n\n\tif (entry.id !== undefined) {\n\t\tnode.id = entry.id\n\t}\n\n\tif (entry.size !== undefined) {\n\t\tnode.size = entry.size\n\t}\n\n\tif (entry.mimeType !== undefined) {\n\t\tnode.mimeType = entry.mimeType\n\t}\n\n\tif (entry.modifiedAt !== undefined) {\n\t\tnode.modifiedAt = entry.modifiedAt\n\t}\n\n\tif (entry.etag !== undefined) {\n\t\tnode.etag = entry.etag\n\t}\n\n\tif (entry.thumbnailUrl !== undefined) {\n\t\tnode.thumbnailUrl = entry.thumbnailUrl\n\t}\n\n\tif (entry.metadata !== undefined) {\n\t\tnode.metadata = entry.metadata\n\t}\n\n\treturn node\n}\n\nfunction compareEntries<TMetadata>(left: InMemoryEntry<TMetadata>, right: InMemoryEntry<TMetadata>): number {\n\tif (left.kind !== right.kind) {\n\t\treturn left.kind === 'folder' ? -1 : 1\n\t}\n\n\treturn left.name.localeCompare(right.name, undefined, {\n\t\tnumeric: true,\n\t\tsensitivity: 'base'\n\t})\n}\n\nfunction throwIfAborted(signal?: AbortSignal): void {\n\tif (signal?.aborted) {\n\t\tthrow new FileBrowserAdapterError('aborted', 'Operation was aborted')\n\t}\n}\n\nfunction toArchivePath(path: string): string {\n\treturn path.replace(/^\\/+/, '') || 'download'\n}\n"],"mappings":";;;AAiDA,IAAM,IAAuE;CAC5E,cAAc;CACd,QAAQ;CACR,MAAM;CACN,MAAM;CACN,MAAM;CACN,QAAQ;CACR,iBAAiB;CACjB,WAAW;AACZ,GAEa,IAAb,MAAsG;CACrG;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CAEA,0BAA2B,IAAI,IAAsC;CACrE,mCAAoC,IAAI,IAAqC;CAC7E;CACA;CACA;CACA,eAAuB;CACvB,oBAA4B;CAE5B,YAAY,IAAwD,CAAC,GAAG;EACvE,IAAM,IAAe;GACpB,GAAG;GACH,GAAG,EAAQ;EACZ;EAKA,AAHA,KAAK,WAAW,EAAQ,UACxB,KAAK,oBAAoB,KAAK,IAAI,GAAG,EAAQ,qBAAqB,IAAI,OAAO,IAAI,GACjF,KAAK,MAAM,EAAQ,8BAAc,IAAI,KAAK,IAC1C,KAAK,QAAQ,IAAA,KAAe;GAC3B,MAAA;GACA,MAAM;GACN,MAAM;GACN,YAAY,KAAK,UAAU;EAC5B,CAAC;EACD,KAAK,IAAM,KAAQ,EAAQ,kBAAkB,CAAC,GAAG;GAChD,IAAM,IAAa,EAAyB,EAAK,IAAI;GACrD,KAAK,QAAQ,IAAI,GAAY;IAAE,GAAG;IAAM,MAAM;GAAW,CAAC;EAC3D;EA8BA,AA5BI,EAAa,iBAChB,KAAK,eAAe,KAAK,kBAAkB,KAAK,IAAI,IAGjD,EAAa,WAChB,KAAK,SAAS,KAAK,YAAY,KAAK,IAAI,IAGrC,EAAa,SAChB,KAAK,OAAO,KAAK,YAAY,KAAK,IAAI,IAGnC,EAAa,SAChB,KAAK,OAAO,KAAK,YAAY,KAAK,IAAI,IAGnC,EAAa,SAChB,KAAK,OAAO,KAAK,UAAU,KAAK,IAAI,IAGjC,EAAa,WAChB,KAAK,SAAS,KAAK,cAAc,KAAK,IAAI,IAGvC,EAAa,oBAChB,KAAK,kBAAkB,KAAK,sBAAsB,KAAK,IAAI,IAGxD,EAAa,cAChB,KAAK,wBAAwB,KAAK,2BAA2B,KAAK,IAAI,GACtE,KAAK,aAAa,KAAK,oBAAoB,KAAK,IAAI,GACpD,KAAK,0BAA0B,KAAK,6BAA6B,KAAK,IAAI,GAC1E,KAAK,uBAAuB,KAAK,0BAA0B,KAAK,IAAI;CAEtE;CAEA,KAAK,GAAc,IAA+B,CAAC,GAA8C;EAChG,EAAe,EAAK,MAAM;EAC1B,IAAM,IAAa,EAAyB,CAAI;EAGhD,IAFe,KAAK,SAAS,CAEzB,CAAA,CAAO,SAAS,UACnB,MAAM,IAAI,EAAwB,gBAAgB,4BAA4B,GAAY;EAG3F,IAAM,IAAW,MAAM,KAAK,KAAK,QAAQ,OAAO,CAAC,CAAC,CAChD,QAAQ,MAAU,EAAM,SAAA,GAAkB,CAAC,CAC3C,QAAQ,MAAU,EAAsB,EAAM,IAAI,MAAM,CAAU,CAAC,CACnE,KAAK,CAAc,CAAC,CACpB,IAAI,CAAS;EAEf,IAAI,CAAC,KAAK,UACT,OAAO,QAAQ,QAAQ,EAAE,OAAO,EAAS,CAAC;EAG3C,IAAM,IAAQ,EAAK,SAAS,OAAO,SAAS,EAAK,QAAQ,EAAE,IAAI,GACzD,IAAY,OAAO,SAAS,CAAK,KAAK,IAAQ,IAAI,IAAQ,GAC1D,IAAQ,EAAS,MAAM,GAAW,IAAY,KAAK,QAAQ,GAC3D,IAAO,IAAY,EAAM;EAE/B,OAAO,QAAQ,QAAQ;GACtB;GACA,QAAQ,IAAO,EAAS,SAAS,OAAO,CAAI,IAAI,KAAA;EACjD,CAAC;CACF;CAEA,kBAA0B,GAA4C;EACrE,IAAM,IAAa,EAAyB,CAAI;EAEhD,IAAI,MAAA,KACH,OAAO,QAAQ,QAAQ,EAAU,KAAK,SAAA,GAAkB,CAAC,CAAC;EAG3D,IAAI,KAAK,QAAQ,IAAI,CAAU,GAC9B,MAAM,IAAI,EAAwB,YAAY,0CAA0C,GAAY;EAGrG,KAAK,mBAAmB,EAAsB,CAAU,CAAC;EAEzD,IAAM,IAAkC;GACvC,MAAM;GACN,MAAM,EAAuB,CAAU;GACvC,MAAM;GACN,YAAY,KAAK,UAAU;GAC3B,MAAM,KAAK,SAAS;EACrB;EAGA,OADA,KAAK,QAAQ,IAAI,GAAY,CAAK,GAC3B,QAAQ,QAAQ,EAAU,CAAK,CAAC;CACxC;CAEA,OAAO,GAAgC;EACtC,KAAK,IAAM,KAAQ,EAAM,IAAI,CAAwB,GAAG;GACvD,IAAI,MAAA,KACH,MAAM,IAAI,EAAwB,gBAAgB,+BAA+B;GAGlF,KAAK,SAAS,CAAI;GAElB,KAAK,IAAM,KAAa,MAAM,KAAK,KAAK,QAAQ,KAAK,CAAC,GACrD,AAAI,EAA8B,GAAM,CAAS,KAChD,KAAK,QAAQ,OAAO,CAAS;EAGhC;EAEA,OAAO,QAAQ,QAAQ;CACxB;CAEA,UAAU,GAA+B;EACxC,IAAM,IAAQ,KAAK,SAAS,CAAI;EAEhC,IAAI,EAAM,SAAS,UAAU,CAAC,EAAM,MACnC,MAAM,IAAI,EAAwB,gBAAgB,4CAA4C,EAAM,MAAM;EAG3G,OAAO,QAAQ,QAAQ,IAAI,gBAAgB,EAAM,IAAI,CAAC;CACvD;CAEA,OAAO,GAAc,GAAY,IAAiC,CAAC,GAAiC;EACnG,EAAe,EAAK,MAAM;EAC1B,IAAI,IAAa,EAAyB,CAAI;EAG9C,IAFA,KAAK,mBAAmB,EAAsB,CAAU,CAAC,GAErD,KAAK,QAAQ,IAAI,CAAU,KAAK,EAAK,eAAe,WACvD,IAAI,EAAK,eAAe,aACvB,IAAa,KAAK,kBAAkB,CAAU;OAE9C,MAAM,IAAI,EAAwB,YAAY,0CAA0C,GAAY;EAKtG,AADA,EAAK,aAAa,GAAG,EAAK,IAAI,GAC9B,EAAe,EAAK,MAAM;EAE1B,IAAM,IAAkC;GACvC,MAAM;GACN,MAAM,EAAuB,CAAU,KAAK,EAAK;GACjD,MAAM;GACN,MAAM,EAAK;GACX,UAAU,EAAK,QAAQ,KAAA;GACvB,YAAY,KAAK,UAAU;GAC3B,MAAM,KAAK,SAAS;GACpB,MAAM;EACP;EAKA,OAHA,KAAK,QAAQ,IAAI,GAAY,CAAK,GAClC,EAAK,aAAa,EAAK,MAAM,EAAK,IAAI,GAE/B,QAAQ,QAAQ,EAAU,CAAK,CAAC;CACxC;CAEA,kBAA0B,GAAsB;EAC/C,IAAM,IAAM,EAAsB,CAAI,GAChC,IAAW,EAAuB,CAAI,GACtC,IAAW,EAAS,YAAY,GAAG,GACnC,IAAe,IAAW,GAC1B,IAAO,IAAe,EAAS,MAAM,GAAG,CAAQ,IAAI,GACpD,IAAY,IAAe,EAAS,MAAM,CAAQ,IAAI;EAE5D,KAAK,IAAI,IAAQ,GAAG,iBAAiC,KAAS,GAAG;GAChE,IAAM,IAAY,EAAoB,GAAK,GAAG,EAAK,IAAI,EAAM,GAAG,GAAW;GAC3E,IAAI,CAAC,KAAK,QAAQ,IAAI,CAAS,GAC9B,OAAO;EAET;EAEA,MAAM,IAAI,EAAwB,YAAY,qDAAqD,GAAM;CAC1G;CAEA,YAAoB,GAAc,GAA+C;EAChF,IAAM,IAAa,EAAyB,CAAI,GAC1C,IAAQ,KAAK,SAAS,CAAU,GAChC,IAAc,EAAQ,KAAK;EAEjC,IAAI,CAAC,KAAe,EAAY,SAAS,GAAG,KAAK,EAAY,SAAS,IAAI,GACzE,MAAM,IAAI,EAAwB,gBAAgB,8BAA8B,GAAS;EAG1F,IAAM,IAAoC;GACzC,GAAG;GACH,MAAM;GACN,YAAY,KAAK,UAAU;GAC3B,MAAM,KAAK,SAAS;EACrB;EAGA,OADA,KAAK,QAAQ,IAAI,GAAY,CAAO,GAC7B,QAAQ,QAAQ,EAAU,CAAO,CAAC;CAC1C;CAEA,MAAc,YAAY,GAAgB,GAA8B;EACvE,MAAM,KAAK,YAAY,GAAM,CAAK;EAElC,KAAK,IAAM,KAAQ,GAClB,MAAM,KAAK,OAAO,CAAC,CAAI,CAAC;CAE1B;CAEA,YAAoB,GAAgB,GAA8B;EACjE,IAAM,IAAkB,EAAyB,CAAK;EACtD,KAAK,mBAAmB,CAAe;EAEvC,IAAM,oBAAS,IAAI,IAAsC;EAEzD,KAAK,IAAM,KAAc,EAAK,IAAI,CAAwB,GAAG;GAC5D,IAAM,IAAS,KAAK,SAAS,CAAU,GACjC,IAAkB,EAAoB,GAAiB,EAAuB,EAAO,IAAI,CAAC;GAEhG,KAAK,IAAM,KAAS,KAAK,YAAY,EAAO,IAAI,GAAG;IAClD,IAAM,IAAkB,EAA6B,EAAM,MAAM,EAAO,MAAM,CAAe;IAE7F,IAAI,KAAK,QAAQ,IAAI,CAAe,KAAK,EAAO,IAAI,CAAe,GAClE,MAAM,IAAI,EAAwB,YAAY,0CAA0C,GAAiB;IAG1G,EAAO,IAAI,GAAiB;KAC3B,GAAG;KACH,MAAM;KACN,MAAM,EAAM,SAAS,EAAO,OAAO,EAAuB,CAAe,IAAI,EAAM;KACnF,YAAY,KAAK,UAAU;KAC3B,MAAM,KAAK,SAAS;IACrB,CAAC;GACF;EACD;EAEA,KAAK,IAAM,CAAC,GAAM,MAAU,GAC3B,KAAK,QAAQ,IAAI,GAAM,CAAK;EAG7B,OAAO,QAAQ,QAAQ;CACxB;CAEA,UAAkB,GAA4C;EAC7D,OAAO,QAAQ,QAAQ,EAAU,KAAK,SAAS,CAAI,CAAC,CAAC;CACtD;CAEA,cAAsB,GAAmD;EACxE,OAAO,QAAQ,QACd,OAAO,YACN,EAAM,KAAK,MAAS;GACnB,IAAM,IAAa,EAAyB,CAAI;GAChD,OAAO,CAAC,GAAY,KAAK,QAAQ,IAAI,CAAU,CAAC;EACjD,CAAC,CACF,CACD;CACD;CAEA,MAAc,sBAAsB,GAA8D;EACjG,IAAM,IAAqB,CAAC;EAE5B,KAAK,IAAM,KAAQ,GAAO;GACzB,KAAK,SAAS,CAAI;GAClB,IAAM,IAAO,KAAK,YAAY,CAAI;GAClC,KAAK,IAAM,KAAS,GACf,EAAM,SAAS,YAAY,CAAC,EAAM,SAGtC,EAAS,EAAc,EAAM,IAAI,KAAK,IAAI,WAAW,MAAM,EAAM,KAAK,YAAY,CAAC;EAErF;EAEA,IAAM,IAAU,IAAI,KAAK,CAAC,EAAQ,CAAQ,CAAC,GAAG,EAC7C,MAAM,kBACP,CAAC;EAED,OAAO;GACN,KAAK,IAAI,gBAAgB,CAAO;GAChC,WAAW,IAAI,KAAK,KAAK,IAAI,CAAC,CAAC,QAAQ,IAAI,QAAc,GAAI,CAAC,CAAC,YAAY;EAC5E;CACD;CAEA,2BAAmC,GAAc,GAA+D;EAC/G,IAAM,IAAa,EAAyB,CAAI;EAIhD,IAHA,KAAK,mBAAmB,EAAsB,CAAU,CAAC,GAExC,KAAK,QAAQ,IAAI,CAC9B,CAAA,EAAU,SAAS,UACtB,MAAM,IAAI,EAAwB,YAAY,0CAA0C,GAAY;EAGrG,KAAK,qBAAqB;EAC1B,IAAM,IAAW,oBAAoB,KAAK;EAQ1C,OAPA,KAAK,iBAAiB,IAAI,GAAU;GACnC,MAAM;GACN;GACA,UAAU,KAAK;GACf,uBAAO,IAAI,IAAI;EAChB,CAAC,GAEM,QAAQ,QAAQ;GAAE;GAAU,UAAU,KAAK;EAAkB,CAAC;CACtE;CAEA,oBAA4B,EAC3B,UACA,eACA,eACA,WACA,eAGE;EACF,OAAO,QAAQ,QAAQ,CAAC,CAAC,WAAW;GACnC,EAAe,CAAM;GACrB,IAAM,IAAS,KAAK,mBAAmB,CAAQ,GACzC,IAAO,eAAe;GAK5B,OAJA,EAAO,MAAM,IAAI,GAAY;IAAE,MAAM;IAAO;GAAK,CAAC,GAClD,IAAa,EAAM,IAAI,GACvB,EAAe,CAAM,GAEd,EAAE,QAAK;EACf,CAAC;CACF;CAEA,6BAAqC,EACpC,UACA,eAGC;EACD,OAAO,QAAQ,QAAQ,CAAC,CAAC,WAAW;GACnC,IAAM,IAAS,KAAK,mBAAmB,CAAQ,GACzC,IAAgB,CAAC;GAEvB,KAAK,IAAM,KAAQ,EAAM,MAAM,GAAM,MAAU,EAAK,aAAa,EAAM,UAAU,GAAG;IACnF,IAAM,IAAW,EAAO,MAAM,IAAI,EAAK,UAAU;IACjD,IAAI,CAAC,KAAY,EAAS,SAAS,EAAK,MACvC,MAAM,IAAI,EAAwB,aAAa,oBAAoB,EAAK,WAAW,cAAc,GAAU;IAE5G,EAAM,KAAK,EAAS,IAAI;GACzB;GAEA,IAAM,IAAO,IAAI,KAAK,CAAK;GAC3B,IAAI,EAAK,SAAS,EAAO,MACxB,MAAM,IAAI,EAAwB,gBAAgB,oBAAoB,EAAS,eAAe;GAG/F,IAAM,IAAkC;IACvC,MAAM,EAAO;IACb,MAAM,EAAuB,EAAO,IAAI;IACxC,MAAM;IACN,MAAM,EAAK;IACX,YAAY,KAAK,UAAU;IAC3B,MAAM,KAAK,SAAS;IACpB;GACD;GAIA,OAHA,KAAK,QAAQ,IAAI,EAAO,MAAM,CAAK,GACnC,KAAK,iBAAiB,OAAO,CAAQ,GAE9B,EAAU,CAAK;EACvB,CAAC;CACF;CAEA,0BAAkC,GAAiC;EAClE,OAAO,QAAQ,QAAQ,CAAC,CAAC,WAAW;GAEnC,AADA,KAAK,mBAAmB,CAAQ,GAChC,KAAK,iBAAiB,OAAO,CAAQ;EACtC,CAAC;CACF;CAEA,mBAA2B,GAA2C;EACrE,IAAM,IAAS,KAAK,iBAAiB,IAAI,CAAQ;EACjD,IAAI,CAAC,GACJ,MAAM,IAAI,EAAwB,aAAa,kCAAkC,GAAU;EAE5F,OAAO;CACR;CAEA,YAAoB,GAA0C;EAC7D,IAAM,IAAa,EAAyB,CAAI;EAChD,OAAO,MAAM,KAAK,KAAK,QAAQ,OAAO,CAAC,CAAC,CACtC,QAAQ,MAAU,EAA8B,GAAY,EAAM,IAAI,CAAC,CAAC,CACxE,MAAM,GAAM,MAAU,EAAK,KAAK,cAAc,EAAM,IAAI,CAAC;CAC5D;CAEA,mBAA2B,GAAoB;EAC9C,IAAM,IAAQ,KAAK,SAAS,CAAI;EAEhC,IAAI,EAAM,SAAS,UAClB,MAAM,IAAI,EAAwB,gBAAgB,wBAAwB,EAAM,MAAM;CAExF;CAEA,SAAiB,GAAwC;EACxD,IAAM,IAAa,EAAyB,CAAI,GAC1C,IAAQ,KAAK,QAAQ,IAAI,CAAU;EAEzC,IAAI,CAAC,GACJ,MAAM,IAAI,EAAwB,aAAa,mCAAmC,GAAY;EAG/F,OAAO;CACR;CAEA,YAA4B;EAC3B,OAAO,KAAK,IAAI,CAAC,CAAC,YAAY;CAC/B;CAEA,WAA2B;EAE1B,OADA,KAAK,gBAAgB,GACd,UAAU,KAAK;CACvB;AACD;AAEA,SAAgB,EACf,GACwC;CACxC,OAAO,IAAI,EAAsC,CAAO;AACzD;AAEA,SAAS,EAAqB,GAAsD;CACnF,IAAM,IAA4B;EACjC,MAAM,EAAM;EACZ,MAAM,EAAM;EACZ,MAAM,EAAM;CACb;CA8BA,OA5BI,EAAM,OAAO,KAAA,MAChB,EAAK,KAAK,EAAM,KAGb,EAAM,SAAS,KAAA,MAClB,EAAK,OAAO,EAAM,OAGf,EAAM,aAAa,KAAA,MACtB,EAAK,WAAW,EAAM,WAGnB,EAAM,eAAe,KAAA,MACxB,EAAK,aAAa,EAAM,aAGrB,EAAM,SAAS,KAAA,MAClB,EAAK,OAAO,EAAM,OAGf,EAAM,iBAAiB,KAAA,MAC1B,EAAK,eAAe,EAAM,eAGvB,EAAM,aAAa,KAAA,MACtB,EAAK,WAAW,EAAM,WAGhB;AACR;AAEA,SAAS,EAA0B,GAAgC,GAAyC;CAK3G,OAJI,EAAK,SAAS,EAAM,OAIjB,EAAK,KAAK,cAAc,EAAM,MAAM,KAAA,GAAW;EACrD,SAAS;EACT,aAAa;CACd,CAAC,IANO,EAAK,SAAS,WAAW,KAAK;AAOvC;AAEA,SAAS,EAAe,GAA4B;CACnD,IAAI,GAAQ,SACX,MAAM,IAAI,EAAwB,WAAW,uBAAuB;AAEtE;AAEA,SAAS,EAAc,GAAsB;CAC5C,OAAO,EAAK,QAAQ,QAAQ,EAAE,KAAK;AACpC"}
@@ -1,7 +1,7 @@
1
1
  import { S3CompatibleFileBrowserAdapter } from '../s3-compatible-adapter';
2
2
  import type { S3CompatibleFileBrowserAdapterOptions } from '../s3-compatible-adapter';
3
- export type R2FileBrowserAdapterOptions = S3CompatibleFileBrowserAdapterOptions;
4
- export declare class R2FileBrowserAdapter extends S3CompatibleFileBrowserAdapter {
5
- constructor(options?: R2FileBrowserAdapterOptions);
3
+ export type R2FileBrowserAdapterOptions<TMetadata = unknown> = S3CompatibleFileBrowserAdapterOptions<TMetadata>;
4
+ export declare class R2FileBrowserAdapter<TMetadata = unknown> extends S3CompatibleFileBrowserAdapter<TMetadata> {
5
+ constructor(options?: R2FileBrowserAdapterOptions<TMetadata>);
6
6
  }
7
7
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/adapters/r2/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,8BAA8B,EAAE,MAAM,0BAA0B,CAAA;AACzE,OAAO,KAAK,EAAE,qCAAqC,EAAE,MAAM,0BAA0B,CAAA;AAErF,MAAM,MAAM,2BAA2B,GAAG,qCAAqC,CAAA;AAE/E,qBAAa,oBAAqB,SAAQ,8BAA8B;gBAC3D,OAAO,CAAC,EAAE,2BAA2B;CAGjD"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/adapters/r2/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,8BAA8B,EAAE,MAAM,0BAA0B,CAAA;AACzE,OAAO,KAAK,EAAE,qCAAqC,EAAE,MAAM,0BAA0B,CAAA;AAErF,MAAM,MAAM,2BAA2B,CAAC,SAAS,GAAG,OAAO,IAAI,qCAAqC,CAAC,SAAS,CAAC,CAAA;AAE/G,qBAAa,oBAAoB,CAAC,SAAS,GAAG,OAAO,CAAE,SAAQ,8BAA8B,CAAC,SAAS,CAAC;gBAC3F,OAAO,CAAC,EAAE,2BAA2B,CAAC,SAAS,CAAC;CAG5D"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../../../src/adapters/r2/index.ts"],"sourcesContent":["import { S3CompatibleFileBrowserAdapter } from '../s3-compatible-adapter'\nimport type { S3CompatibleFileBrowserAdapterOptions } from '../s3-compatible-adapter'\n\nexport type R2FileBrowserAdapterOptions = S3CompatibleFileBrowserAdapterOptions\n\nexport class R2FileBrowserAdapter extends S3CompatibleFileBrowserAdapter {\n\tconstructor(options?: R2FileBrowserAdapterOptions) {\n\t\tsuper('R2', options)\n\t}\n}\n"],"mappings":";;AAKA,IAAa,IAAb,cAA0C,EAA+B;CACxE,YAAY,GAAuC;EAClD,MAAM,MAAM,CAAO;CACpB;AACD"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../../src/adapters/r2/index.ts"],"sourcesContent":["import { S3CompatibleFileBrowserAdapter } from '../s3-compatible-adapter'\nimport type { S3CompatibleFileBrowserAdapterOptions } from '../s3-compatible-adapter'\n\nexport type R2FileBrowserAdapterOptions<TMetadata = unknown> = S3CompatibleFileBrowserAdapterOptions<TMetadata>\n\nexport class R2FileBrowserAdapter<TMetadata = unknown> extends S3CompatibleFileBrowserAdapter<TMetadata> {\n\tconstructor(options?: R2FileBrowserAdapterOptions<TMetadata>) {\n\t\tsuper('R2', options)\n\t}\n}\n"],"mappings":";;AAKA,IAAa,IAAb,cAA+D,EAA0C;CACxG,YAAY,GAAkD;EAC7D,MAAM,MAAM,CAAO;CACpB;AACD"}
@@ -1,7 +1,7 @@
1
1
  import { S3CompatibleFileBrowserAdapter } from '../s3-compatible-adapter';
2
2
  import type { S3CompatibleFileBrowserAdapterOptions } from '../s3-compatible-adapter';
3
- export type S3FileBrowserAdapterOptions = S3CompatibleFileBrowserAdapterOptions;
4
- export declare class S3FileBrowserAdapter extends S3CompatibleFileBrowserAdapter {
5
- constructor(options?: S3FileBrowserAdapterOptions);
3
+ export type S3FileBrowserAdapterOptions<TMetadata = unknown> = S3CompatibleFileBrowserAdapterOptions<TMetadata>;
4
+ export declare class S3FileBrowserAdapter<TMetadata = unknown> extends S3CompatibleFileBrowserAdapter<TMetadata> {
5
+ constructor(options?: S3FileBrowserAdapterOptions<TMetadata>);
6
6
  }
7
7
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/adapters/s3/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,8BAA8B,EAAE,MAAM,0BAA0B,CAAA;AACzE,OAAO,KAAK,EAAE,qCAAqC,EAAE,MAAM,0BAA0B,CAAA;AAErF,MAAM,MAAM,2BAA2B,GAAG,qCAAqC,CAAA;AAE/E,qBAAa,oBAAqB,SAAQ,8BAA8B;gBAC3D,OAAO,CAAC,EAAE,2BAA2B;CAGjD"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/adapters/s3/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,8BAA8B,EAAE,MAAM,0BAA0B,CAAA;AACzE,OAAO,KAAK,EAAE,qCAAqC,EAAE,MAAM,0BAA0B,CAAA;AAErF,MAAM,MAAM,2BAA2B,CAAC,SAAS,GAAG,OAAO,IAAI,qCAAqC,CAAC,SAAS,CAAC,CAAA;AAE/G,qBAAa,oBAAoB,CAAC,SAAS,GAAG,OAAO,CAAE,SAAQ,8BAA8B,CAAC,SAAS,CAAC;gBAC3F,OAAO,CAAC,EAAE,2BAA2B,CAAC,SAAS,CAAC;CAG5D"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../../../src/adapters/s3/index.ts"],"sourcesContent":["import { S3CompatibleFileBrowserAdapter } from '../s3-compatible-adapter'\nimport type { S3CompatibleFileBrowserAdapterOptions } from '../s3-compatible-adapter'\n\nexport type S3FileBrowserAdapterOptions = S3CompatibleFileBrowserAdapterOptions\n\nexport class S3FileBrowserAdapter extends S3CompatibleFileBrowserAdapter {\n\tconstructor(options?: S3FileBrowserAdapterOptions) {\n\t\tsuper('S3', options)\n\t}\n}\n"],"mappings":";;AAKA,IAAa,IAAb,cAA0C,EAA+B;CACxE,YAAY,GAAuC;EAClD,MAAM,MAAM,CAAO;CACpB;AACD"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../../src/adapters/s3/index.ts"],"sourcesContent":["import { S3CompatibleFileBrowserAdapter } from '../s3-compatible-adapter'\nimport type { S3CompatibleFileBrowserAdapterOptions } from '../s3-compatible-adapter'\n\nexport type S3FileBrowserAdapterOptions<TMetadata = unknown> = S3CompatibleFileBrowserAdapterOptions<TMetadata>\n\nexport class S3FileBrowserAdapter<TMetadata = unknown> extends S3CompatibleFileBrowserAdapter<TMetadata> {\n\tconstructor(options?: S3FileBrowserAdapterOptions<TMetadata>) {\n\t\tsuper('S3', options)\n\t}\n}\n"],"mappings":";;AAKA,IAAa,IAAb,cAA+D,EAA0C;CACxG,YAAY,GAAkD;EAC7D,MAAM,MAAM,CAAO;CACpB;AACD"}