@finueva/drive 0.5.0 → 0.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # @finueva/drive
2
2
 
3
+ ## 0.5.1
4
+
5
+ ### Patch Changes
6
+
7
+ - b54eff9: Bind the default Fetch implementation to its global receiver so browser requests do not fail with an illegal invocation. Custom Fetch implementations and request policies are unchanged.
8
+
3
9
  ## 0.5.0
4
10
 
5
11
  ### Minor Changes
package/README.md CHANGED
@@ -6,13 +6,13 @@ The package is ESM-only. Node.js 22 is the exact minimum; package CI qualifies N
6
6
 
7
7
  ## Exports
8
8
 
9
- | Import | Runtime |
10
- | ----------------------- | ---------------------------------------------------------------------- |
11
- | `@finueva/drive` | Browser-safe client factory, errors, and curated types |
12
- | `@finueva/drive/client` | Browser-safe client factory |
13
- | `@finueva/drive/server` | Request-scoped Worker and Node low-level client factory |
14
- | `@finueva/drive/core` | Reviewed error values only |
15
- | `@finueva/drive/types` | Curated workspace, search, item, version, permission, and upload types |
9
+ | Import | Runtime |
10
+ | ----------------------- | --------------------------------- |
11
+ | `@finueva/drive` | Browser client, errors, types |
12
+ | `@finueva/drive/client` | Browser client |
13
+ | `@finueva/drive/server` | Request-scoped Worker/Node client |
14
+ | `@finueva/drive/core` | Error values |
15
+ | `@finueva/drive/types` | Public operation types |
16
16
 
17
17
  ## Browser
18
18
 
@@ -21,7 +21,12 @@ import { createDriveClient } from "@finueva/drive";
21
21
 
22
22
  const drive = createDriveClient({
23
23
  baseUrl: "https://drive.example.com",
24
- getCredential: ({ signal }) => auth.getDriveCredential({ signal }),
24
+ getCredential: async ({ signal }) => {
25
+ signal.throwIfAborted();
26
+ const credential = await auth.getDriveCredential({ workspace: { type: "personal" } });
27
+ signal.throwIfAborted();
28
+ return credential.token;
29
+ },
25
30
  timeoutMilliseconds: 30_000,
26
31
  });
27
32
 
@@ -53,6 +58,10 @@ const uploaded = await drive.uploadFile({
53
58
 
54
59
  The provider runs once for every request. The SDK sends its result only as `Authorization: Bearer`, always sets `credentials: "omit"` and `cache: "no-store"`, and never reads cookies. Configuration does not accept default headers. Credential acquisition, Fetch, and response handling share one bounded request deadline: 30 seconds by default, configurable from 1 millisecond through 120 seconds.
55
60
 
61
+ `auth` is a configured `@finueva/auth` client. Select the exact personal or organization workspace. Native Fetch needs no wrapper.
62
+
63
+ Approve the exact application origin in Drive's `DRIVE_BROWSER_ORIGINS` policy and configure archive CORS separately. API responses must expose `X-Request-ID` and `ETag`. See [browser setup](https://github.com/Ifkafin/drive/blob/main/apps/developer/docs/architecture/configuration.md#native-api-browser-origins).
64
+
56
65
  ## Worker And Node
57
66
 
58
67
  ```ts
@@ -101,9 +110,9 @@ Methods use the Native API operation IDs:
101
110
 
102
111
  `getCurrentWorkspace` maps the credential's selected Auth context to the provisioned Drive workspace and canonical managed root. It accepts only an optional `{ signal }` input, never provisions as a side effect, and returns no entitlement, credential, or private persistence fields.
103
112
 
104
- `getItem` reads one active managed item under exact `items:metadata:read` authority. It conceals absent, cross-workspace, unauthorized, tombstoned, ancestor-tombstoned, and unpublished file items as not found. Results expose exact `workspaceId`, `itemId`, nullable `parentId`, `type`, `name`, `lifecycleState`, `revision`, and `currentVersion`. Folder metadata returns `currentVersion: null`; published files return only the current immutable version ID, state, byte length, untrusted media type, and untrusted protection classification. The strong item ETag matches the returned item revision. Digests, archive/cache state, provider keys, upload state, and content authority are not exposed.
113
+ `getItem` requires `items:metadata:read`. Absent, unauthorized, tombstoned, or unpublished items are concealed. Folders have `currentVersion: null`; files expose their current version. The strong ETag matches the item revision. Media type and protection classification are untrusted metadata, not content authority. Internal storage/provider state is never exposed.
105
114
 
106
- `searchWorkspaceItems` searches active managed metadata in one workspace by a required NFC, case-sensitive name prefix. The prefix is 1 through 64 Unicode code points, at most 255 UTF-8 bytes, and excludes C0/C1 controls plus U+2028/U+2029. Results are exact frozen `{ items, nextCursor }` pages of at most the requested limit or 50 by default, in binary name then item-ID order. Each item adds exact `volumeId` and `provider: "managed"` fields to the `getItem` metadata shape; folders require `currentVersion: null` and files require current-version metadata. Cursors use the existing opaque syntax and an empty page cannot carry a continuation.
115
+ `searchWorkspaceItems` matches NFC, case-sensitive name prefixes: 1-64 Unicode code points, at most 255 UTF-8 bytes, without C0/C1 controls or U+2028/U+2029. Frozen `{ items, nextCursor }` pages default to 50 rows ordered by binary name then item ID. Results add `volumeId` and `provider: "managed"` to item metadata. An empty page cannot have a cursor.
107
116
 
108
117
  Every mutation requires the API's explicit idempotency key when the operation defines one. Item lifecycle mutations also require the current strong item ETag as `ifMatch`; grant mutations use their documented collection or grant precondition. Mutations are never retried automatically. Sparse updates omit `undefined` properties and preserve explicit `null` expiry.
109
118
 
@@ -111,7 +120,7 @@ Successful calls return `{ data, status, requestId, validators }`. A successful
111
120
 
112
121
  `updateItem` renames and moves one stable item ID. A move immediately changes inherited-grant ancestry; Drive does not copy grants to the item. `trashItem` retains a 30-day tombstone, `restoreItem` requires the original parent to remain active, and `deleteItem` starts permanent archive cleanup only after retention expires and no hold applies. Permanent deletion is currently bounded to at most 25 subtree items and 25 total versions; larger trees fail unavailable until a durable workflow exists. Exact retries resume retained deletion checkpoints and never trigger blind provider duplication.
113
122
 
114
- `listItemVersions` returns only immutable `current` and `superseded` managed version projections in pages of at most 50 using an opaque encrypted cursor. `getItemVersion` returns a strict frozen `ManagedItemVersionResource` containing the requested `workspaceId`, `itemId`, and `versionId` plus those version fields; all three response IDs must match the request. It conceals clean absence, valid wrong-item identity, unpublished history, and deleting or deleted history, while malformed retained state is unavailable. `restoreItemVersion` atomically makes one selected superseded version current, demotes the previous current version, advances the item revision, and never copies or overwrites archive bytes.
123
+ `listItemVersions` pages immutable current/superseded versions, at most 50 per page. `getItemVersion` verifies all three workspace/item/version IDs and conceals unavailable history. Malformed retained state fails unavailable. `restoreItemVersion` atomically changes the current version and item revision without copying or overwriting archive bytes.
115
124
 
116
125
  `createDownload` returns a short-lived archive descriptor for the current or an explicit immutable version, one visible `restore-pending` result for cold content, or a no-body `304` operation result whose validators retain the source ETag. Full, closed, open, and suffix ranges use the selected archive object's strong ETag; malformed or multiple ranges are served as full representations, while valid non-overlapping ranges fail with `range_not_satisfiable`. `downloadItem` follows a descriptor with no Drive credential, ambient browser credentials, or referrer and returns the provider body as a backpressured `Response`; it preserves the same `304` and cold-restore results without a provider request. It validates exact status, ETag, identity encoding, length, and `Content-Range`, cancels malformed upstream bodies, and keeps caller cancellation/deadline authority active until the stream closes or is cancelled. It never returns Blob, ArrayBuffer, text, or base64 whole-file convenience values.
117
126
 
package/dist/client.js CHANGED
@@ -1780,7 +1780,7 @@ function createClientRuntime(config) {
1780
1780
  try {
1781
1781
  runtime = Object.freeze({
1782
1782
  baseUrl: parseBaseUrl(config.baseUrl),
1783
- fetchImplementation: config.fetch ?? globalThis.fetch,
1783
+ fetchImplementation: config.fetch ?? globalThis.fetch.bind(globalThis),
1784
1784
  getCredential: config.getCredential,
1785
1785
  timeoutMilliseconds: parseTimeoutMilliseconds(config.timeoutMilliseconds)
1786
1786
  });
package/dist/index.js CHANGED
@@ -1780,7 +1780,7 @@ function createClientRuntime(config) {
1780
1780
  try {
1781
1781
  runtime = Object.freeze({
1782
1782
  baseUrl: parseBaseUrl(config.baseUrl),
1783
- fetchImplementation: config.fetch ?? globalThis.fetch,
1783
+ fetchImplementation: config.fetch ?? globalThis.fetch.bind(globalThis),
1784
1784
  getCredential: config.getCredential,
1785
1785
  timeoutMilliseconds: parseTimeoutMilliseconds(config.timeoutMilliseconds)
1786
1786
  });
package/dist/server.js CHANGED
@@ -1738,7 +1738,7 @@ function createClientRuntime(config) {
1738
1738
  try {
1739
1739
  runtime = Object.freeze({
1740
1740
  baseUrl: parseBaseUrl(config.baseUrl),
1741
- fetchImplementation: config.fetch ?? globalThis.fetch,
1741
+ fetchImplementation: config.fetch ?? globalThis.fetch.bind(globalThis),
1742
1742
  getCredential: config.getCredential,
1743
1743
  timeoutMilliseconds: parseTimeoutMilliseconds(config.timeoutMilliseconds)
1744
1744
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@finueva/drive",
3
- "version": "0.5.0",
3
+ "version": "0.5.1",
4
4
  "description": "Public browser, Worker, and Node client for Finueva Drive",
5
5
  "type": "module",
6
6
  "types": "./dist/index.d.ts",
@@ -65,6 +65,7 @@
65
65
  "openapi-fetch": "0.17.0",
66
66
  "openapi-typescript": "7.13.0",
67
67
  "playwright": "1.62.1",
68
+ "prettier": "^3.9.6",
68
69
  "rolldown": "1.2.0",
69
70
  "rolldown-plugin-dts": "0.27.14",
70
71
  "typescript": "5.9.3",