@finueva/drive 0.6.0 → 0.8.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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # @finueva/drive
2
2
 
3
+ ## 0.8.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 8809e4e: Add getCurrentWorkspaceSources, listWorkspaceItems, and getWorkspaceUsage for authorized Files discovery. List recently modified items, actual incoming user/team grants, and trash with authenticated pagination, nullable genuine creation/modification/creator metadata, published version details, and retained mutation ETags. Read exact managed quota byte strings including unresolved reservations. Separate actual managed volumes from known provider kinds without fabricated connections or health. Existing SDK operations retain their contracts. The backend requires generated migration 0010 before these discovery routes are deployed.
8
+
9
+ ## 0.7.0
10
+
11
+ ### Minor Changes
12
+
13
+ - 77546b2: Use portable S3 Content-MD5 transport with mandatory independent server-side whole-file and part SHA-256 verification for all uploads. Descriptor requests require `contentMd5`; there is no legacy transport or profile selector. `completeUpload` and `uploadFile` may return HTTP 202 with a `verifying` result; callers can inspect read-only progress and retry completion with the original idempotency key, or explicitly abort the retained upload. No automatic unbounded polling is performed.
14
+
3
15
  ## 0.6.0
4
16
 
5
17
  ### Minor Changes
package/README.md CHANGED
@@ -44,6 +44,7 @@ const matches = await drive.searchWorkspaceItems({
44
44
  limit: 50,
45
45
  });
46
46
 
47
+ const completionIdempotencyKey = crypto.randomUUID();
47
48
  const uploaded = await drive.uploadFile({
48
49
  workspaceId: workspace.workspaceId,
49
50
  parentItemId: workspace.rootItemId,
@@ -51,7 +52,7 @@ const uploaded = await drive.uploadFile({
51
52
  displayFilename: file.name,
52
53
  mediaType: file.type || "application/octet-stream",
53
54
  idempotencyKey: crypto.randomUUID(),
54
- completionIdempotencyKey: crypto.randomUUID(),
55
+ completionIdempotencyKey,
55
56
  onProgress: ({ phase, confirmedByteLength, totalByteLength }) => {
56
57
  renderProgress(phase, confirmedByteLength, totalByteLength);
57
58
  },
@@ -77,13 +78,39 @@ const drive = createDriveServerClient({
77
78
 
78
79
  Create a client per request when using user authority. A fixed `credential` string is accepted for an explicitly scoped credential, but the SDK does not create, refresh, persist, or infer sessions, cookies, provider tokens, or service authority.
79
80
 
80
- The server client exposes all 24 Native Drive operations plus streaming `downloadItem`, but intentionally has no Blob-only `uploadFile` method. The package root and browser client add `uploadFile`, for 26 methods total.
81
+ The server client exposes all 27 normal-user Native Drive operations plus streaming `downloadItem`, but intentionally has no Blob-only `uploadFile` method. The package root and browser client add `uploadFile`, for 29 methods total.
82
+
83
+ ## Workspace Discovery
84
+
85
+ `getCurrentWorkspaceSources()` returns the actual managed volume separately from
86
+ known provider kinds. It does not invent external connections or provider health.
87
+
88
+ ```ts
89
+ const recent = await drive.listWorkspaceItems({ workspaceId, view: "recent", limit: 25 });
90
+ const shared = await drive.listWorkspaceItems({ workspaceId, view: "shared" });
91
+ const trash = await drive.listWorkspaceItems({ workspaceId, view: "trash" });
92
+ const usage = await drive.getWorkspaceUsage({ workspaceId });
93
+ ```
94
+
95
+ Recent means recorded modification time, not viewing activity. Historical unknown
96
+ timestamps and creator user IDs stay null; unknown modification times are excluded
97
+ from recent results until a real mutation. Shared lists actual incoming direct
98
+ user/team grants, not inherited descendants or all workspace-visible items. Trash
99
+ requires delete authority and retains current ETags for the existing mutation
100
+ methods. Continuations are encrypted, principal/root/filter-bound and short-lived;
101
+ restart on stale-page errors. Optional `kind` and `creatorUserId` filters apply on
102
+ the service before pagination. Quota reads require `usage:read` and return exact
103
+ decimal byte strings, clamped availability and unresolved-reservation evidence.
104
+ These source additions require backend migration `0010`, deployment and SDK release.
81
105
 
82
106
  ## Operations
83
107
 
84
108
  Methods use the Native API operation IDs:
85
109
 
86
110
  - `getCurrentWorkspace`
111
+ - `getCurrentWorkspaceSources`
112
+ - `listWorkspaceItems`
113
+ - `getWorkspaceUsage`
87
114
  - `getItem`
88
115
  - `searchWorkspaceItems`
89
116
  - `listFolderChildren`
@@ -126,15 +153,15 @@ Successful calls return `{ data, status, requestId, validators }`. A successful
126
153
 
127
154
  `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.
128
155
 
129
- The six low-level upload methods map directly to the Native API. `createUpload` accepts `callerDeclaredContentDigest`, an ordinary whole-file `sha256:{64 lowercase hex}` value calculated or supplied by the caller. It is untrusted metadata, not provider verification evidence. `getUploadStatus` returns one bounded confirmed-part page and the current lifecycle/revision. Descriptor issuance accepts one base64 SHA-256 part checksum, `recordUploadPart` records exact provider ETag/checksum evidence and revision, `completeUpload` returns only a server-verified `ready` result, and `abortUpload` returns bodyless `204` success.
156
+ The six low-level upload methods map directly to the Native API. `createUpload` accepts a caller-declared whole-file `sha256:{64 lowercase hex}` digest. Portable S3 is the only supported upload transport, with no profile selector. Descriptor requests require `contentMd5` (canonical base64 MD5), and return a required `content-md5` header. Part SHA-256 declarations and opaque provider ETags remain separate callback fields; MD5 is transport error detection, not content identity.
130
157
 
131
- Provider part checksums and the provider's multipart composite checksum are verified server-side before publication. They are deliberately distinct from `callerDeclaredContentDigest`: multipart composite SHA-256 is not the ordinary SHA-256 of the complete file. Every low-level control obtains one credential, sends one request, validates exact IDs, checksums, ETags, and safe-integer bounds at runtime, and never retries automatically. `upload_recovery_required` is preserved as a canonical `DriveError` code.
158
+ Publication independently verifies archive bytes against both whole-file and part SHA-256 declarations. `getUploadStatus` exposes bounded confirmed-part pages and read-only verification progress once verification is admitted. `completeUpload` and `uploadFile` return `DriveOperationResult<UploadCompletion, 200 | 202>`: inspect `data.state` for `ready` versus `verifying`. A `202` is not publication. Retain its `uploadId` and the original completion idempotency key, inspect status, then call `completeUpload` again with that key when appropriate. The SDK does not start an unbounded polling loop. To cancel after a pending result, call `abortUpload({ workspaceId, uploadId })`, which returns bodyless `204`.
132
159
 
133
160
  `uploadFile` is the browser-safe direct-byte path for a Web `Blob` or `File`. It accepts zero-byte input, hashes the empty input correctly, accepts the server-mediated zero-byte mode, skips part transfer, and completes normally. Nonempty input is incrementally hashed in slices no larger than 32 MiB and is never materialized as a complete `ArrayBuffer`, Blob copy, base64 string, or SDK request body. The fixed policy permits at most 10,000 parts and 312.5 GiB.
134
161
 
135
- Each nonempty slice is sent directly to the exact descriptor URL. The request includes only descriptor-required headers, uses `credentials: "omit"`, `cache: "no-store"`, `redirect: "error"`, and `referrerPolicy: "no-referrer"`, and shares the configured cancellation/deadline bound. The archive CORS policy must expose both `ETag` and `x-amz-checksum-sha256`; missing, malformed, or mismatched values fail closed. Drive authorization, cookies, default headers, and file metadata never enter the archive request.
162
+ Each nonempty slice is sent directly to the exact descriptor URL. The SDK computes MD5 with the maintained Noble public API on the same bounded slice as SHA-256. Requests include only descriptor-required headers and use `credentials: "omit"`, `cache: "no-store"`, `redirect: "error"`, and `referrerPolicy: "no-referrer"`. Archive CORS must allow `content-md5` and expose `ETag`; no provider SHA response header is required, and ETags are never interpreted as hashes. If a Content-MD5 response header is exposed, it must match the request. Drive credentials, cookies and file metadata never enter the archive request.
136
163
 
137
- Repeating `uploadFile` with the same creation and completion idempotency keys explicitly resumes the retained session. After create/replay, the SDK reads status in pages of 100, bounded to 100 pages and 10,000 parts; validates session identity, mode, policy, lifecycle, revision, and pagination; re-hashes the supplied source; compares every confirmed part checksum; skips exact confirmed parts; and continues from the current revision. A matching `ready` status returns its exact ready projection. `completing` and `provider-completed` replay completion. Recovery-required and aborted states fail without pretending to resume.
164
+ Repeating `uploadFile` with the same creation and completion keys explicitly resumes the retained session when replay remains available. Status reads are bounded to 100 pages of 100 parts. The SDK checks session identity, policy, lifecycle, revisions and checksums, skips confirmed parts and never re-uploads a part merely because its callback response was lost. `completing`, `provider-completed` and `verifying` resume completion; failed/aborted/recovery-required states do not pretend to resume. After receiving pending, using its upload ID with low-level status/complete avoids re-hashing the source. Both normal and empty uploads may return pending, and progress observers can receive the `verifying` phase.
138
165
 
139
166
  There is no automatic network or provider retry. If a part-record callback response may have been lost, the SDK performs one bounded status reconciliation before either accepting the confirmed part or recording the same provider evidence once more; it never blindly re-uploads the bytes. If a completion response may have been lost, one status reconciliation returns success only when `ready` is proven. Other transient failures preserve the session for an explicit repeat until server expiry.
140
167
 
package/dist/client.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { $ as UpdateItemInput, A as ListItemVersionsInput, C as FolderPage, D as GetUploadStatusInput, E as GetItemVersionInput, F as ManagedItemVersionPage, I as ManagedItemVersionResource, J as RestoreItemInput, K as ReadyUpload, L as ManagedItemVersionRestoreResult, M as ManagedDownloadRestorePending, N as ManagedItemMetadata, O as ListFolderChildrenInput, P as ManagedItemVersion, Q as TrashItemInput, R as ManagedLifecycleItem, S as FolderItem, T as GetItemInput, W as ProtectionClassification, Y as RestoreItemVersionInput, Z as SearchWorkspaceItemsInput, at as UploadFileProgressCallback, c as CurrentWorkspace, ct as UploadSession, d as DriveClient, dt as WorkspaceItemSearchPage, f as DriveClientConfig, it as UploadFileProgress, j as ManagedDownloadDescriptor, l as DeleteItemInput, lt as UploadStatus, m as DriveCredentialProvider, n as CompleteUploadInput, nt as UploadFileInput, o as CreateUploadInput, ot as UploadPartDescriptor, q as RecordUploadPartInput, r as CreateDownloadInput, rt as UploadFilePhase, s as CreateUploadPartDescriptorInput, st as UploadPartResult, t as AbortUploadInput, tt as UploadConfirmedPart, u as DownloadItemResult, ut as WorkspaceItemSearchItem, w as GetCurrentWorkspaceInput } from "./contract.js";
1
+ import { $ as RestoreItemVersionInput, A as ListFolderChildrenInput, B as ManagedItemVersionRestoreResult, C as FolderItem, D as GetItemVersionInput, E as GetItemInput, F as ManagedDownloadRestorePending, H as PendingUpload, I as ManagedItemMetadata, J as ProtectionClassification, L as ManagedItemVersion, M as ListItemVersionsInput, N as ListWorkspaceItemsInput, O as GetUploadStatusInput, P as ManagedDownloadDescriptor, Q as RestoreItemInput, R as ManagedItemVersionPage, T as GetCurrentWorkspaceInput, V as ManagedLifecycleItem, X as ReadyUpload, Z as RecordUploadPartInput, _t as WorkspaceItemSearchItem, at as UploadCompletion, c as CurrentWorkspace, ct as UploadFilePhase, d as DownloadItemResult, dt as UploadPartDescriptor, f as DriveClient, ft as UploadPartResult, gt as WorkspaceDiscoveryPage, h as DriveCredentialProvider, ht as WorkspaceDiscoveryItem, k as GetWorkspaceUsageInput, l as CurrentWorkspaceSources, lt as UploadFileProgress, mt as UploadStatus, n as CompleteUploadInput, nt as TrashItemInput, o as CreateUploadInput, ot as UploadConfirmedPart, p as DriveClientConfig, pt as UploadSession, r as CreateDownloadInput, rt as UpdateItemInput, s as CreateUploadPartDescriptorInput, st as UploadFileInput, t as AbortUploadInput, tt as SearchWorkspaceItemsInput, u as DeleteItemInput, ut as UploadFileProgressCallback, vt as WorkspaceItemSearchPage, w as FolderPage, yt as WorkspaceUsage, z as ManagedItemVersionResource } from "./contract.js";
2
2
  //#region src/client.d.ts
3
3
  declare function createDriveClient(config: DriveClientConfig): DriveClient;
4
4
  //#endregion
5
- export { type AbortUploadInput, type CompleteUploadInput, type CreateDownloadInput, type CreateUploadInput, type CreateUploadPartDescriptorInput, type CurrentWorkspace, type DeleteItemInput, type DownloadItemResult, type DriveClient, type DriveClientConfig, type DriveCredentialProvider, type FolderItem, type FolderPage, type GetCurrentWorkspaceInput, type GetItemInput, type GetItemVersionInput, type GetUploadStatusInput, type ListFolderChildrenInput, type ListItemVersionsInput, type ManagedDownloadDescriptor, type ManagedDownloadRestorePending, type ManagedItemMetadata, type ManagedItemVersion, type ManagedItemVersionPage, type ManagedItemVersionResource, type ManagedItemVersionRestoreResult, type ManagedLifecycleItem, type ProtectionClassification, type ReadyUpload, type RecordUploadPartInput, type RestoreItemInput, type RestoreItemVersionInput, type SearchWorkspaceItemsInput, type TrashItemInput, type UpdateItemInput, type UploadConfirmedPart, type UploadFileInput, type UploadFilePhase, type UploadFileProgress, type UploadFileProgressCallback, type UploadPartDescriptor, type UploadPartResult, type UploadSession, type UploadStatus, type WorkspaceItemSearchItem, type WorkspaceItemSearchPage, createDriveClient };
5
+ export { type AbortUploadInput, type CompleteUploadInput, type CreateDownloadInput, type CreateUploadInput, type CreateUploadPartDescriptorInput, type CurrentWorkspace, type CurrentWorkspaceSources, type DeleteItemInput, type DownloadItemResult, type DriveClient, type DriveClientConfig, type DriveCredentialProvider, type FolderItem, type FolderPage, type GetCurrentWorkspaceInput, type GetItemInput, type GetItemVersionInput, type GetUploadStatusInput, type GetWorkspaceUsageInput, type ListFolderChildrenInput, type ListItemVersionsInput, type ListWorkspaceItemsInput, type ManagedDownloadDescriptor, type ManagedDownloadRestorePending, type ManagedItemMetadata, type ManagedItemVersion, type ManagedItemVersionPage, type ManagedItemVersionResource, type ManagedItemVersionRestoreResult, type ManagedLifecycleItem, type PendingUpload, type ProtectionClassification, type ReadyUpload, type RecordUploadPartInput, type RestoreItemInput, type RestoreItemVersionInput, type SearchWorkspaceItemsInput, type TrashItemInput, type UpdateItemInput, type UploadCompletion, type UploadConfirmedPart, type UploadFileInput, type UploadFilePhase, type UploadFileProgress, type UploadFileProgressCallback, type UploadPartDescriptor, type UploadPartResult, type UploadSession, type UploadStatus, type WorkspaceDiscoveryItem, type WorkspaceDiscoveryPage, type WorkspaceItemSearchItem, type WorkspaceItemSearchPage, type WorkspaceUsage, createDriveClient };