Repository navigation
Commit 7a5f73e
refactor(ui)!: fold the providers upload context into fields and data-objectstack, retire @object-ui/providers (#30550)
<!-- claude-projects-attribution: {"github_login":"os-sales"} -->
_Requested by **Sales** · [project
thread](https://claude.ai/code/project/chan_01D5bWFY3rFzgJcytD5gD4Uu?thread=cmsg_01D5bWFY3rFzgJcytD5gD4UuXx8nkFj47cDx3oQ4JtqdJS)_
Part of #25921 (the providers/upload fold only; the card's barrel
batches and `clearSharedDiscoveryCache` stay on it).
Clause-②: yes (narrowing)
Metadata-protocol: none
Skills-docs: follow-up #30559
## 维护者速读
- 改了什么:文件、图片、头像字段的上传上下文 `UploadProvider` / `useUpload` 搬进
`@object-ui/fields`,连 ObjectStack 存储服务的上传适配器搬进
`@object-ui/data-objectstack`,两边共用的上传契约类型放进
`@object-ui/types`,`@object-ui/providers` 整包退役。
- 为什么改:这个包只剩上传一件事,少一个要单独发布和维护的包;访问服务器的取数逻辑回到 data 包里,字段包不再依赖一个只为它存在的包。
- 风险与回滚:上传行为不变,预签名请求逐字节相同,控制台和附件面板照常上传;外部宿主若仍从 `@object-ui/providers`
导入,升级时编译报错,changeset 写了改从哪里导入。回滚就是 revert 本 PR。
- 先看:`ui/packages/fields/src/widgets/UploadProvider.tsx`(上下文与无 provider
时的本地回退),`ui/packages/data-objectstack/src/upload-adapter.ts`(三步上传,与原包代码相同),`.changeset/25921-providers-upload-fold.md`(BREAKING
说明与迁移行)。
- 两分钟验证:`pnpm --dir ui exec vitest run
packages/data-objectstack/src/objectstack-upload-scope-12055.test.ts
apps/console/src/__tests__/App.uploadAltitude-10131.test.tsx`,预期两个文件全部通过。
- 需要你做的:无,席位落地。PR 自身的改动行数(additions+deletions,GitHub 把两处搬移认作改名)是 2482
行,不到 3000 行。
## What changes
`@object-ui/providers` had one job left: the upload context the file,
image and avatar widgets of `@object-ui/fields` upload through, plus the
adapters that fill it. This PR moves each piece to the package that owns
it and retires the package.
- **`@object-ui/types`** gains `ui/packages/types/src/upload.ts`: the
`UploadAdapter`, `UploadOptions` and `UploadResult` interfaces,
unchanged in shape. They live here, as `DataSource` does, because
`@object-ui/fields` and `@object-ui/data-objectstack` do not depend on
each other and both need them.
- **`@object-ui/fields`** gains `src/widgets/UploadProvider.tsx`
(`UploadProvider`, `useUpload`, `UploadProviderProps`) and re-exports
the three contract types from its entry. `AvatarField`, `FileField` and
`ImageField` read it relatively. `createObjectUrlAdapter` moves in as a
module-private function: it is still the `blob:` fallback `useUpload`
answers with when no provider is mounted, and it is no longer exported.
- **`@object-ui/data-objectstack`** gains `src/upload-adapter.ts`
(`createObjectStackUploadAdapter`, `ObjectStackUploadAdapterOptions`):
fetch logic against an ObjectStack server, so it sits beside the other
fetch logic (ui/AGENTS.md section 3). The three-step presign, PUT and
complete flow is the original code. Its `scope` option stays typed as
`API.UploadScope`, and the objectui#12055 test moved with it.
- **Retired with no replacement:** `createS3Adapter`,
`createAzureBlobAdapter`, `S3AdapterOptions`, `AzureBlobAdapterOptions`.
They had zero consumers in the workspace and zero in
`objectstack-ai/hotcrm` (shallow clone at `6961ab1`; every upload name 0
hits, while a control name hits). A host that uploads to its own bucket
writes an `UploadAdapter` against `@object-ui/types`.
- **Importers re-pointed:** the console `App.tsx` (import only; the
`UploadProvider` wrap is unchanged), `ProfilePage.tsx`, app-shell's
`RecordAttachmentsPanel.tsx`, `SettingsPage.tsx` and one renderer
comment, and every test that imported or mocked the package. The
`@object-ui/providers` dependency leaves the console, app-shell and
fields manifests, its alias lines leave `ui/vitest.config.mts` and four
vite configs, and it leaves the `.changeset/config.json` fixed group,
the root `CONTRIBUTING.md` package table, two gate fixture lists and the
lockfile (regenerated with `pnpm install --lockfile-only`, deletions
only).
- **One gate floor moves:**
`ui/scripts/__tests__/check-doc-links.test.ts` counts the decidable
links in every package README, and the retired README carried 2 of them
(127 on the merge base, 125 here), so its floor moves from 126 to 125
with the measurement in its comment, as the `@object-ui/plugin-ai`
retirement did. The site-absolute floor is unchanged (48 measured, floor
39).
- **One PR, no re-export shim**, as the seat ruled. Two changesets:
`25921-providers-upload-fold.md` (fields and data-objectstack, patch,
`!`, BREAKING paragraph, one FROM line naming the package, ADR-0087
marker `runtime-export-retired @object-ui/providers#*`) and
`25921-upload-adapter-contract.md` (types, patch, widening).
**Changed lines: 2482 on the PR (+350 / −2132, 63 files; GitHub reads
the two moved files as renames), under the 3000-line threshold** (seat
correction; AGENTS.md reads the PR's `additions + deletions`).
`dispatch-gates` counts with `--no-renames`, so it counts the moved code
once as deleted and once as added and arrives at about 3,200 lines. 2386
of the deletions are the retired package's own nine files (its
`CHANGELOG.md` alone is 1524).
## Why
The package existed so the widgets and the console could share one
upload context. With the theme, data-source and metadata providers
retired earlier (objectui#13453), every remaining export belonged to
either the widgets or the ObjectStack data adapter.
## Tests
Behaviour is not changed, so the existing tests are the proof; they were
re-pointed, not rewritten. All runs on `4e1e0e0e` (the scripts/ run
first on `15c54522`, see Verification), under the shared verify lock:
- `pnpm --dir ui exec vitest run packages/fields/
packages/data-objectstack/ packages/types/
packages/cli/src/__tests__/workspace-vite.test.ts`: 801 files passed, 1
skipped; 16261 tests passed, 7 skipped. This includes the moved
objectui#12055 presign-body test and its compile-time pins.
- `pnpm --filter @object-ui/console test` (the whole console project,
since `App.tsx` changed): 298 files, 2939 tests passed, including
`App.uploadAltitude-10131`, the three `FormPage` upload tests and the
five `ProfilePage` tests.
- app-shell and plugin-form upload sites (every `views/__tests__/` file,
the `ActionParamDialog`, `RecordDetailView`, settings and chatbot files
that render an upload site, plus `WizardForm.nextMidUpload`,
`affordanceGrantMap-12082`, `uploadInFlightSave`): 104 files, 937 tests
passed.
- `pnpm --dir ui exec vitest run scripts/`: on `15c54522` 169 files
passed and 1 failed, the doc-links floor above (expected 125 to be at
least 126). With the floor moved, `check-doc-links.test.ts` alone passes
123/123; the full rerun on the final head is in the report.
No ablation: nothing tested changed behaviour.
## Acceptance notes
- Behaviour is unchanged: `UploadProvider`, `useUpload` and
`createObjectStackUploadAdapter` keep their signatures and bodies, and
the presign request body is pinned by the moved objectui#12055 test.
- The plugin-form `WizardForm.nextMidUpload` test used to mock the
`@object-ui/providers` module. A mock of the `@object-ui/fields` barrel
would not reach the widgets, which import `./UploadProvider.js`
relatively, so the test now mounts the real `UploadProvider` with a
deferred adapter. It drives the same pending upload.
- Mentions of `@object-ui/providers` this PR leaves alone, because they
are outside its file surface or are historical text that stays true:
- `skills/objectui/guides/project-setup.md:249` and `:307` (governed;
they still tell a reader to install `@object-ui/providers` for uploads,
a follow-up).
-
`ui/.claude/skills/objectui-contributor/guides/console-development.md:409`
(governed).
- `content/docs/releases/v18/18-2.mdx:374` (release text).
- The retired package's README held the `UploadProvider` usage guide. It
now lives in `ui/packages/fields/README.md` (an `UploadProvider`
section) and `ui/packages/data-objectstack/README.md` (a File Uploads
section), added in the patch round (seat correction).
- Historical comments that stay accurate:
`ui/packages/types/src/theme.ts:68,77`,
`ui/packages/types/src/__tests__/p2-spec-exports.test.ts:256`,
`ui/scripts/__tests__/one-authority-per-exported-name-6273.test.ts:616`,
the objectui#4194 error text quoted in
`ui/packages/plugin-editor/vite.config.ts:64` and
`ui/packages/plugin-markdown/vite.config.ts:64`, and
`ui/.changeset/13453-*`, `13464-*`, `13465-*`, `25685-*` (not read by
the root changeset config).
## Verification
- Build: `turbo run build --filter=@object-ui/console...
--filter='./packages/**' --filter='@objectstack/dogfood^...'`, 113/113
tasks, exit 0 (console `tsc` and `vite build` included).
- Type-check, each exit 0: `@object-ui/types`, `fields`,
`data-objectstack`, `app-shell`, `plugin-form`, `console`, `cli`,
`plugin-editor`, `plugin-markdown`, `runner` (`pnpm --filter PKG run
type-check`, which compiles each package's tests where it has a test
tsconfig).
- `dispatch-gates --commands`: 60 commands, all run. 59 exit 0; `pnpm
--dir ui exec vitest run scripts/` exited 1 on `15c54522` for the
doc-links floor above, and its rerun on the final head is in the report.
`check-adr-0087-registration --base origin/main` verifies
`@object-ui/providers#*` (package deleted, absent from the workspace and
the fixed group). `check:type-check-debt` exit 0 on the final head.
- Outside the derived list: `pnpm --dir ui run check:spec-symbols` exit
0; `check-platform-checklist --changed-from origin/main` exit 0 (0
anchored files); eslint on the 45 changed ui source files, 0 errors (the
one react-compiler ref warning in `UploadProvider.tsx` is the same
warning the original file carried).
- hotcrm census: shallow clone of `objectstack-ai/hotcrm` at `6961ab1`,
0 hits for `@object-ui/providers`, `UploadProvider`, `useUpload`,
`createObjectStackUploadAdapter`, `createS3Adapter`,
`createAzureBlobAdapter`, `createObjectUrlAdapter`, with a control name
hitting.
- The full dogfood battery (the title carries `!`) runs on the final
head under the lock; its count goes in the dev report on #25921.
- `origin/main` has moved 5 commits since the base; `git merge-tree
--write-tree HEAD origin/main` exits 0, and the one shared file
(`ui/packages/fields/src/index.tsx`) is changed in a different region.
## Human Minimum
- [x] 1. Schemas start as Zod; `packages/spec` holds no runtime logic.
(`packages/spec` untouched.)
- [x] 2. Every name I added uses the casing for its kind.
- [x] 3. No formatter ran; `pnpm lint` passes. (eslint on every changed
ui source file: 0 errors.)
- [x] 4. One issue, one branch off an up-to-date `main`, one pull
request.
- [x] 5. A change that publishes carries a changeset, and both
declaration lines are filled in here and in the changeset.
- [x] 6. `packages/spec` touched: not touched, nothing to regenerate.
- [x] 7. No hand edits to `content/docs/references/`,
`packages/*/CHANGELOG.md` or `content/docs/releases/`. (The retired
package's `CHANGELOG.md` is deleted with it, not edited.)
- [ ] 8. Title, body and comments are in English. (The body carries the
Chinese maintainer summary the dispatch rules require; everything else
is English.)
- [x] The *Before Submitting* list in CONTRIBUTING.md is done.
---
_Generated by [Claude
Code](https://claude.ai/code/session_01L6bhgWy2L8Kga6GXBtvjpK)_
<!-- signed: domain:ui#1 · os-sales · session_01L6bhgWn6zhNa4LL7VB1rtL
-->
---------
Co-authored-by: Claude <noreply@anthropic.com>1 parent a0c68ae commit 7a5f73e
63 files changed
Lines changed: 350 additions & 2132 deletions
File tree
- .changeset
- ui
- apps/console
- src
- __tests__
- components
- pages/system
- __tests__
- packages
- app-shell
- src
- console/organizations
- __tests__
- manage
- views
- __tests__
- cli/src/__tests__
- data-objectstack
- src
- fields
- src
- __tests__
- widgets
- plugin-editor
- plugin-form/src
- plugin-markdown
- providers
- src
- runner
- types/src
- scripts/__tests__
Some content is hidden
Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
114 | 114 | | |
115 | 115 | | |
116 | 116 | | |
117 | | - | |
118 | 117 | | |
119 | 118 | | |
120 | 119 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
467 | 467 | | |
468 | 468 | | |
469 | 469 | | |
470 | | - | |
471 | 470 | | |
472 | 471 | | |
473 | 472 | | |
| |||
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
84 | 84 | | |
85 | 85 | | |
86 | 86 | | |
87 | | - | |
88 | 87 | | |
89 | 88 | | |
90 | 89 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
16 | 16 | | |
17 | 17 | | |
18 | 18 | | |
19 | | - | |
| 19 | + | |
| 20 | + | |
20 | 21 | | |
21 | 22 | | |
22 | 23 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
81 | 81 | | |
82 | 82 | | |
83 | 83 | | |
84 | | - | |
85 | | - | |
86 | | - | |
87 | | - | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
88 | 88 | | |
89 | 89 | | |
90 | 90 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
30 | 30 | | |
31 | 31 | | |
32 | 32 | | |
33 | | - | |
| 33 | + | |
34 | 34 | | |
35 | 35 | | |
36 | 36 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
31 | 31 | | |
32 | 32 | | |
33 | 33 | | |
34 | | - | |
| 34 | + | |
35 | 35 | | |
36 | 36 | | |
37 | 37 | | |
| |||
0 commit comments