Repository navigation
fix(providers): type the upload adapter's scope from the spec's UploadScope (objectui#12055) - #12428
Conversation
…dScope (objectui#12055) `ObjectStackUploadAdapterOptions.scope` was an open `string`, so an author could name a scope the storage service refuses with 400. It is now the spec's upload-scope vocabulary, `UploadScope` from `@objectstack/spec/api`, reached through the `API` namespace `@object-ui/types` already re-exports: no hand copy, no new dependency, no new export. Pins: the option type equals the spec type and is not an open string; a `@ts-expect-error` refuses `scope: 'avatars'`; the existing forwarding and no-scope pins stay as they were. Claude-Session: https://claude.ai/code/session_01JZnppgHRp4sREcouhkQYDB Co-authored-by: Claude <noreply@anthropic.com>
…i#12055) Claude-Session: https://claude.ai/code/session_01JZnppgHRp4sREcouhkQYDB Co-authored-by: Claude <noreply@anthropic.com>
✅ Console Performance Budget
The eager closure is every chunk the entry reaches through static imports — what the browser fetches and parses before the app renders. The entry chunk on its own is a small fraction of it. 📦 Bundle Size Report
Size Limits
|
…(objectui#12055) The pending entry from the shared half said the scope option's type is unchanged (`string`); the type half narrows it, and both entries publish in one release. Delete that sentence, and the newer entry's sentence that superseded it. Claim amendment 1 on objectui#12055 authorises the edit. Claude-Session: https://claude.ai/code/session_01JZnppgHRp4sREcouhkQYDB Co-authored-by: Claude <noreply@anthropic.com>
✅ Console Performance Budget
The eager closure is every chunk the entry reaches through static imports — what the browser fetches and parses before the app renders. The entry chunk on its own is a small fraction of it. 📦 Bundle Size Report
Size Limits
|
|
Contract reviewServed-tier: Read, read-only: card #12055 (body and every comment, rulings and earlier records included), PR #12428 (body, file list, net diff against ① Derived judgmentsThe file list is four paths:
② Semver level
③ Boundary flagsDev flags (report 6184802562), each answered:
The out-of-scope finding (the pending-changeset sentence) was taken up by claim amendment 1 (6184832958) and landed in the amendment round (report 6184856123) as the head's last commit; verified in the diff.
File surface: every changed path is on the claim's surface or the amendment's rider; Gate verdicts on this head
Implemented-by: VERDICT: PASS |
Seat ACCEPT: objectui PR #12428 at
|
Fixes #12055
Clause-②: no (narrowing)
What changes
createObjectStackUploadAdapter'sscopeoption (ObjectStackUploadAdapterOptions.scopein@object-ui/providers) was an openstring. It is nowAPI.UploadScope: the spec's upload-scope vocabulary,UploadScopefrom@objectstack/spec/api, reached through theAPInamespace that@object-ui/typesalready re-exports (export type * as API from '@objectstack/spec/api'). This is the type half triage's answer C left on the card; the shared half (thepathfallback removed) landed as PR #12058.@object-ui/providersalready depends on@object-ui/types, and@object-ui/typesdepends on@objectstack/spec, sopackage.jsonand the lockfile do not change. The emittedUploadProvider.d.tsgains one type-only line,import type { API } from '@object-ui/types', and the emitted JS is unchanged (the import is erased: 0 hits indist/UploadProvider.js). Named here for the contract review, as the dispatch asked.400, and says an omitted scope sends none, so the server applies the default the spec's upload request declares. It no longer points at thesys_fileselect in@objectstack/service-storageas the authority.RecordAttachmentsPanel(scope: 'attachments'), which is in the vocabulary and still compiles. The console's app-wide adapter passes none. Neither source file changes.Measured before editing (installed
@objectstack/spec18.0.0-next.1)UploadScopeSchemaandtype UploadScope = z.input of UploadScopeSchemaare exported from the./apisubpath; the package root does not export them. Members:tenant,user,private,temp,attachments(publicis not one). The card body's list still namespublic; the type follows the spec, so it does not apply.GetPresignedUrlRequestSchema.scopeisUploadScopeSchema.default("user")in the installed JS.Pins (
packages/providers/src/__tests__/objectstack-upload-scope-12055.test.ts)tsconfig.test.json(chained after the source program intype-check):undefined, is exactlyAPI.UploadScope, andAPI.UploadScopeis notany;stringis not assignable to it;@ts-expect-erroron{ scope: 'avatars' }typed asObjectStackUploadAdapterOptions.scope: 'attachments'is forwarded unchanged, an adapter built without a scope sends none (with or without apath).Evidence (head
7d5d8f2dd, every run after the last commit)pnpm --filter @object-ui/providers type-check(echoestsc --noEmit && tsc -p tsconfig.test.json): VERDICT command-exit 0.tsc -p tsconfig.test.json --listFileslists the test file once, and lists the spec'sdist/api/index.d.mts.pnpm exec vitest run packages/providers/plus the two adapter-factory suites (RecordAttachmentsPanel.affordanceGrant-12047,App.uploadAltitude-10131):Test Files 5 passed (5),Tests 23 passed (23); the 12055 file runs 6 tests, all passed.pnpm --filter @object-ui/app-shell type-check, after building its 29-package dependency closure at this branch: VERDICT command-exit 0.ablation-replace.mjswith an exit/int/term trap):scope?: API.UploadScope;widened toscope?: string;(anchor 1 to 0, blob changed).tsc -p tsconfig.test.jsonthen fails with exit 2: two TS2344 (the identity pin and the not-an-open-string pin) and TS2578 (unused@ts-expect-erroron'avatars'). Restored: blob equal to HEAD,git diff HEADempty.RecordAttachmentsPanel'sscope: 'attachments'changed to'avatars', then app-shelltsc --noEmitfails with exit 2: TS2322,Type '"avatars"' is not assignable to type '"tenant" | "user" | "private" | "temp" | "attachments" | undefined'. Restored: blob equal to HEAD,git diff HEADempty.check-changeset-presence(1 changeset declared),check-changeset-no-major,check-changeset-fixed,check-changeset-overwrite(0 modified),check-changeset-claims,check-control-bytes,check-new-cross-file-line-citations(0 new),check-test-path-roots,check-vi-mock-specifiers,check-phantom-dependencies;check-governed-queue-guard --teston the 3 paths: NOT GOVERNED. ESLint on the 2 touched files: 0 errors, 7 warnings (react-refresh/only-export-componentsandreact-hooks/refs), none on a line this PR changes. Repo-wide lint and the rest of the farm are CI's.check:spec-floors,check:self-import(nopackage.jsonchanges).Changeset
.changeset/12055-upload-scope-type.md:@object-ui/providersminor, with the breaking meaning (TypeScript only: a scope outside the vocabulary no longer compiles; the server already refused it) and the remedy, andClause-②: no (narrowing).Acceptance notes
.changeset/12055-upload-path-not-scope.md(from PR fix(providers): the ObjectStack upload adapter never sends an upload path as the storage scope (objectui#12055) #12058, not yet released) says "The option's type is unchanged (string)." This PR makes that sentence false before it ships. It is left untouched because the claim's file surface names one changeset; the new changeset says it supersedes that note. If the seat prefers one coherent CHANGELOG entry, the remedy is to delete that one sentence.Clause-②: no; this body carriesClause-②: no (narrowing)as the dispatch asked. No objectui gate reads the line.Session:
https://claude.ai/code/session_01JZnppgHRp4sREcouhkQYDBGenerated by Claude Code