[PLT-106969]feat(buckets): accept bucket id or name on file ops; add folderKey/folderPath to getAll#607
[PLT-106969]feat(buckets): accept bucket id or name on file ops; add folderKey/folderPath to getAll#607deepeshrai-tech wants to merge 2 commits into
Conversation
…lderPath to getAll Extends 5 BucketService file-operation methods so their first parameter accepts `bucket: number | string` — either a numeric bucket Id or a bucket Name. When a name is supplied the SDK resolves it to an Id via an OData `$filter=Name eq '…'&$select=Id&$top=1` lookup on the folder-scoped Buckets collection. Methods updated: - `deleteFile` - `getFileMetaData` - `getFiles` - `getReadUri` - `uploadFile` Also extends `BucketGetAllOptions` with `folderKey?: string` and `folderPath?: string` so `getAll()` can be scoped by any of the three folder refs. `getAll()` with no folder options deliberately remains a cross-folder query — it does not fall back to the SDK init-time meta-tag folderKey (documented, non-breaking). Shared name-lookup logic (name validation + folder header resolution + OData filter + empty-result → NotFoundError) is extracted into a private `findByNameInFolder` helper on `FolderScopedService`; both `getByNameLookup` (full-resource fetch) and the new `resolveIdByName` (Id-only projection) delegate to it. Unit and integration coverage added for all name-path scenarios and for `folderKey` / `folderPath` on `getAll()`. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Review findingsThree issues found this run: 1. Regression in coerceBucketId — invalid Id escapes validation (link) 2. Missing regression guard for 4 of 5 sibling methods (link) 3. |
- `coerceBucketId`: reject `NaN` / `Infinity` via `Number.isFinite`, not
just `<= 0`. `parseInt('bad', 10)` and similar no longer leak into the
API URL.
- Add "numeric id skips name lookup" regression guard for all four
sibling methods (`uploadFile`, `getReadUri`, `getFileMetaData`,
`getFiles`) — previously only `deleteFile` was covered.
- Widen the NaN/Infinity validation test alongside the existing 0/-5
cases.
- Type integration-test callbacks as `BlobItem` instead of `any`.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
|
✅ No issues found. Checked for bugs and CLAUDE.md compliance. |
| * Uploads a file to a bucket — options-only form. | ||
| * | ||
| * @deprecated Use the positional form: `uploadFile(bucketId, path, content, options?)`. See {@link BucketUploadFileRequestOptions} for the supported options. | ||
| * @deprecated Use the positional form: `uploadFile(bucket, path, content, options?)`. See {@link BucketUploadFileRequestOptions} for the supported options. |
There was a problem hiding this comment.
This shouldnt be changing right?
| ({ folderId, folderKey, folderPath, ...restOptions } = opts); | ||
| } | ||
|
|
||
| const bucketId = await this.coerceBucketId( |
There was a problem hiding this comment.
this extra would need OR.Buckets.Read. Pls update oauth-scopes.md
|
|
||
| const { folderId, folderKey, folderPath } = options ?? {}; | ||
|
|
||
| const bucketId = await this.coerceBucketId( |
There was a problem hiding this comment.
This would require OR.Buckets.Read permission. Pls verify/update oauth-scopes.md
| throw new ValidationError({ message: `bucket is required for ${callerLabel}` }); | ||
| } | ||
| if (typeof bucket === 'number') { | ||
| if (!Number.isFinite(bucket) || bucket <= 0) { |
There was a problem hiding this comment.
| if (!Number.isFinite(bucket) || bucket <= 0) { | |
| if (!Number.isInteger(bucket) || bucket <= 0) { |



Summary
BucketServicefile-op methods (deleteFile,getFileMetaData,getFiles,getReadUri,uploadFile) to acceptbucket: number | string— either a numeric Id or a bucket Name. Names are resolved via a lean OData$filter=Name eq '…'&$select=Id&$top=1lookup on the folder-scoped Buckets collection.BucketGetAllOptionswithfolderKey?: stringandfolderPath?: stringsogetAll()can be scoped by any of the three folder refs.getAll()with no folder options remains a cross-folder query — deliberately does not fall back to the SDK init-time meta-tag folderKey (non-breaking).findByNameInFolderhelper onFolderScopedService; bothgetByNameLookup(full-resource fetch) and the newresolveIdByName(Id-only projection) delegate to it.Public API surface
Positional forms are the primary API. Deprecated options-only overloads (
uploadFile({ bucketId, ... }),getReadUri({ bucketId, ... })) remain numeric-only forbucketId— they're already on the way out.Design notes
folderId/folderKey/folderPath); missing name →NotFoundErrorwith folder hint.@track-decorated; the outer public method's@trackfires once (avoids the delegation double-telemetry anti-pattern).coerceBucketIddistinguishes missing-value from invalid-value error messages (bucket is requiredvsbucket must be a positive numeric Id).getAll()picks the endpoint based on whether any folder ref is in options — not onfolderIdalone — sofolderKey/folderPathcorrectly trigger the folder-scoped endpoint. Endpoint constants unchanged.Test plan
buckets.test.ts(all passing). New coverage: bucket-name resolution for all 5 methods,NotFoundErrorpropagation,numeric id skips name lookupregression guard, positive-Id validation,folderKey/folderPathongetAll, cross-folder-default preserved when SDK has init-time folderKey.File operations - by bucket nameblock exercising all 5 methods end-to-end + folderKey scoping on the by-name path; added folderKey/folderPath cases to thegetAlldescribe.dist/cleanly.🤖 Generated with Claude Code