Skip to content

fix(runner): type-check the package at all, fix the hidden DataSource violation (#2917) - #2922

Merged
os-zhuang merged 1 commit into
mainfrom
fix/2917-runner-typecheck
Jul 28, 2026
Merged

fix(runner): type-check the package at all, fix the hidden DataSource violation (#2917)#2922
os-zhuang merged 1 commit into
mainfrom
fix/2917-runner-typecheck

Conversation

@os-zhuang

Copy link
Copy Markdown
Contributor

Closes #2917. First follow-up off the #2915 sweep, taking the highest-risk item first.

It is not broken at runtime — #2917's risk assessment was wrong

I wrote that issue, and its "likely broken at runtime" claim does not survive contact with the code. Corrected in a comment there:

  • The line is import **type** { … } — erased before it can fail.
  • The one value import, emulateBatchTransaction, does exist (core/src/adapters/index.ts:16, re-exported via core/src/index.ts:24).
  • MockDataSource is unreferenced anywhere in the repo; App.tsx has no data-source wiring at all.

So this is a correctness and reference-quality fix, not an outage.

What the missing type-check actually hid

DataSource / BatchTransactionOperation were imported from @object-ui/core, which does not export them — they live in @object-ui/types. Because that import never resolved, class MockDataSource implements DataSource was silently a no-op.

Three separate commits then maintained the class as if it were verified — 62b9ab510 added batchTransaction, 09d9669c7 made getObjectSchema required, 5527388b0 added input validation. With the implements clause inert, a real contract violation survived all three:

async find(resource: string, params?: any): Promise<any[]> { return []; }

DataSource.find returns a QueryResult envelope, not a bare array. TS says it plainly once the import is fixed:

Property 'data' is missing in type 'any[]' but required in type 'QueryResult<any>'

The file's doc comment invites you to use it as the starting point for your own adapter ("在真实项目中,你会在这里使用 fetch/axios 调用你的 API"), so anyone who did would hand every consumer an array whose .data and .total are undefined. A wrong reference implementation is worse than none — that's the real defect.

The tsconfig, and a second correction

#2917 said to mirror packages/plugin-list. That's a library shape. runner is a Vite app, so apps/console is the right peer:

  • bundler resolution + allowImportingTsExtensions — for import App from './App.tsx'
  • types: ["vite/client"] — for import.meta.glob in MetadataLoader and the ./index.css side-effect import
  • standalone, not extending the root config — so the root paths are never inherited, workspace deps resolve through built .d.ts, and the TS6059 rootDir class of error cannot arise at all. No paths override needed, unlike the library packages in fix(plugin-map): drop the maplibre-gl@6 default import + gate type-check in CI (#2911) #2915.

With a tsconfig in place the real error count is 10, not 14 — four of the original were artifacts of having none.

Changes

packages/runner/tsconfig.json new, app-shaped (see above)
mockDataSource.ts types imported from @object-ui/types; find() returns Promise<QueryResult> as { data: [], total: 0 }; 6 unused params prefixed _
LayoutRenderer.tsx unused Circle icon import dropped
packages/runner/package.json "type-check": "tsc --noEmit"
scripts/check-type-check-coverage.mjs runner DEBT entry deleted

Coverage 35 → 36 of 45; outstanding errors 46 → 32.

Verification

Proven the gate genuinely covers the package rather than trusting the green — injecting a type error into runner/src/App.tsx:

Failed:    @object-ui/runner#type-check

That was impossible before this PR. Restored via cp (not git checkout, which would clobber uncommitted work) and confirmed no residual diff.

  • pnpm type-check --force71/71, zero cached (70 before; runner's task is new)
  • pnpm build — 43/43
  • pnpm test7847 passed, 24 skipped, 663 files, 0 failures
  • node scripts/check-type-check-coverage.mjs — green at 36/45

No changeset entry for a behaviour change to consumers: MockDataSource is unimported, so it is tree-shaken out of the app bundle and no published artifact changes shape.

🤖 Generated with Claude Code

… violation (#2917)

@object-ui/runner was the worst-covered package in the repo: `vite build`
(transpile only), no type-check script, and uniquely no tsconfig.json at all.
Nothing had ever type-checked it, despite it being published.

It was NOT broken at runtime — #2917's own risk assessment was wrong and is
corrected there. The two bad imports were `import type`, so they were erased
before they could fail; the one value import (emulateBatchTransaction) does
exist; and MockDataSource is unreferenced anywhere in the repo.

What the missing check hid: DataSource and BatchTransactionOperation were
imported from @object-ui/core, which does not export them (they live in
@object-ui/types). Because that import never resolved, `implements DataSource`
was silently a no-op, and three commits maintained the class as if it were
verified (62b9ab5, 09d9669, 5527388). A real contract violation survived
all three:

    async find(resource: string, params?: any): Promise<any[]> { return []; }

DataSource.find returns a QueryResult envelope, not a bare array. The file's doc
comment invites using it as the starting point for a real adapter, so anyone who
did would hand every consumer an array whose .data/.total are undefined.

- tsconfig.json added, mirroring apps/console (a Vite app) rather than a library:
  bundler resolution, allowImportingTsExtensions for ./App.tsx, and
  types: ["vite/client"] for import.meta.glob and the ./index.css import.
  Standalone, so the root `paths` are never inherited and TS6059 cannot arise.
- find() now returns Promise<QueryResult> as { data: [], total: 0 }.
- 6 unused params prefixed with _; unused Circle icon dropped from LayoutRenderer.
- type-check script added; DEBT entry deleted. Coverage 35 -> 36 of 45,
  outstanding errors 46 -> 32.

With a tsconfig the real count is 10, not 14 — four were artifacts of having none.

Proven the gate covers it rather than trusting the green: injecting an error into
runner/src/App.tsx yields `Failed: @object-ui/runner#type-check`, which was
impossible before.

Closes #2917

Co-Authored-By: Claude <noreply@anthropic.com>
@vercel

vercel Bot commented Jul 28, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
objectui Ignored Ignored Jul 28, 2026 12:00pm

Request Review

@github-actions

Copy link
Copy Markdown
Contributor

✅ Console Performance Budget

Metric Value Budget
Main entry (gzip) 27.9 KB 350 KB
Entry file index-B7cKRyXT.js
Status PASS

📦 Bundle Size Report

Package Size Gzipped
app-shell (index.js) 8.20KB 2.97KB
app-shell (runtime-config.js) 7.42KB 2.32KB
app-shell (types.js) 0.01KB 0.04KB
app-shell (urlParams.js) 7.57KB 2.97KB
auth (AuthContext.js) 0.31KB 0.24KB
auth (AuthGuard.js) 1.17KB 0.53KB
auth (AuthProvider.js) 22.10KB 4.37KB
auth (AuthShell.js) 3.49KB 1.40KB
auth (ForgotPasswordForm.js) 12.12KB 3.41KB
auth (LoginForm.js) 17.86KB 5.29KB
auth (PreviewBanner.js) 0.90KB 0.50KB
auth (RegisterForm.js) 6.43KB 2.09KB
auth (SocialSignInButtons.js) 9.60KB 3.89KB
auth (UserMenu.js) 3.40KB 1.22KB
auth (auth-gate-events.js) 1.29KB 0.66KB
auth (authStyles.js) 5.04KB 1.72KB
auth (createAuthClient.js) 35.76KB 9.11KB
auth (createAuthenticatedFetch.js) 4.37KB 1.69KB
auth (index.js) 2.25KB 1.01KB
auth (org-roles.js) 6.72KB 2.85KB
auth (phone-identifier.js) 1.11KB 0.66KB
auth (types.js) 0.59KB 0.35KB
auth (useAuth.js) 4.91KB 0.87KB
auth (useIsWorkspaceAdmin.js) 1.61KB 0.85KB
collaboration (CommentThread.js) 18.38KB 4.49KB
collaboration (LiveCursors.js) 3.17KB 1.27KB
collaboration (PresenceAvatars.js) 3.65KB 1.42KB
collaboration (PresenceProvider.js) 2.79KB 1.13KB
collaboration (index.js) 1.25KB 0.53KB
collaboration (useCommentSearch.js) 1.98KB 0.88KB
collaboration (useConflictResolution.js) 7.75KB 1.86KB
collaboration (useMentionNotifications.js) 1.81KB 0.68KB
collaboration (usePresence.js) 6.33KB 1.84KB
collaboration (useRealtimeSubscription.js) 7.91KB 2.01KB
components (index.js) 449.62KB 97.73KB
core (index.js) 2.12KB 0.77KB
create-plugin (index.js) 9.28KB 2.98KB
data-objectstack (index.js) 127.78KB 32.15KB
fields (index.js) 218.37KB 53.54KB
i18n (LocalizationContext.js) 1.76KB 0.96KB
i18n (currency.js) 1.22KB 0.64KB
i18n (i18n.js) 4.32KB 1.77KB
i18n (index.js) 2.46KB 0.96KB
i18n (pickLocalized.js) 1.70KB 0.83KB
i18n (provider.js) 5.37KB 1.72KB
i18n (useObjectLabel.js) 25.17KB 5.80KB
i18n (useSafeTranslation.js) 3.26KB 1.44KB
layout (index.js) 38.45KB 10.67KB
mobile (MobileProvider.js) 0.92KB 0.49KB
mobile (ResponsiveContainer.js) 0.94KB 0.38KB
mobile (breakpoints.js) 1.51KB 0.70KB
mobile (createOfflineDataSource.js) 5.61KB 1.74KB
mobile (index.js) 1.50KB 0.62KB
mobile (offlineQueue.js) 3.91KB 1.35KB
mobile (pwa.js) 0.97KB 0.49KB
mobile (serviceWorker.js) 1.48KB 0.62KB
mobile (serviceWorkerSource.js) 3.41KB 1.48KB
mobile (useBreakpoint.js) 1.54KB 0.65KB
mobile (useGesture.js) 4.42KB 1.27KB
mobile (useOfflineSync.js) 1.99KB 0.72KB
mobile (usePullToRefresh.js) 2.53KB 0.85KB
mobile (useResponsive.js) 0.71KB 0.42KB
mobile (useResponsiveConfig.js) 1.36KB 0.63KB
mobile (useSpecGesture.js) 1.77KB 0.77KB
mobile (useTouchTarget.js) 1.01KB 0.54KB
permissions (MePermissionsProvider.js) 6.84KB 2.42KB
permissions (PermissionContext.js) 0.31KB 0.25KB
permissions (PermissionGuard.js) 0.89KB 0.45KB
permissions (PermissionProvider.js) 3.67KB 1.12KB
permissions (evaluator.js) 4.00KB 1.23KB
permissions (index.js) 0.91KB 0.41KB
permissions (store.js) 0.91KB 0.42KB
permissions (useFieldPermissions.js) 1.28KB 0.52KB
permissions (usePermissions.js) 1.55KB 0.71KB
plugin-ai (index.js) 15.71KB 3.79KB
plugin-calendar (index.js) 44.90KB 12.35KB
plugin-charts (index.js) 57.26KB 16.24KB
plugin-chatbot (index.js) 179.93KB 42.67KB
plugin-dashboard (index.js) 109.60KB 28.33KB
plugin-designer (index.js) 210.56KB 42.56KB
plugin-detail (index.js) 214.86KB 52.39KB
plugin-editor (index.js) 2.46KB 1.10KB
plugin-form (index.js) 103.47KB 25.10KB
plugin-gantt (index.js) 162.26KB 39.53KB
plugin-grid (index.js) 179.25KB 46.97KB
plugin-kanban (index.js) 47.82KB 13.18KB
plugin-list (index.js) 98.67KB 23.35KB
plugin-map (index.js) 16.80KB 5.24KB
plugin-markdown (index.js) 13.65KB 4.67KB
plugin-report (index.js) 37.07KB 9.81KB
plugin-timeline (index.js) 25.03KB 7.11KB
plugin-tree (index.js) 8.36KB 2.81KB
plugin-view (index.js) 85.68KB 20.85KB
providers (DataSourceProvider.js) 0.75KB 0.39KB
providers (MetadataProvider.js) 1.37KB 0.59KB
providers (ThemeProvider.js) 1.55KB 0.67KB
providers (UploadProvider.js) 11.71KB 3.53KB
providers (index.js) 0.44KB 0.22KB
providers (types.js) 0.01KB 0.04KB
react-runtime (index.js) 3.19KB 1.38KB
react (LazyPluginLoader.js) 3.77KB 1.33KB
react (SchemaRenderer.js) 18.70KB 6.09KB
react (data-invalidation.js) 5.05KB 2.08KB
react (index.js) 1.00KB 0.55KB
sdui-parser (codegen.js) 4.09KB 1.74KB
sdui-parser (index.js) 2.16KB 0.94KB
sdui-parser (parse.js) 10.04KB 2.82KB
sdui-parser (types.js) 0.29KB 0.24KB
sdui-parser (validate.js) 4.69KB 1.48KB
types (ai.js) 0.20KB 0.17KB
types (api-types.js) 0.20KB 0.18KB
types (app.js) 2.87KB 0.99KB
types (base.js) 0.20KB 0.18KB
types (blocks.js) 0.20KB 0.18KB
types (complex.js) 0.20KB 0.18KB
types (crud.js) 0.20KB 0.18KB
types (data-display.js) 0.20KB 0.18KB
types (data-protocol.js) 0.20KB 0.19KB
types (data.js) 0.20KB 0.18KB
types (designer.js) 0.77KB 0.41KB
types (disclosure.js) 0.20KB 0.18KB
types (feedback.js) 0.20KB 0.18KB
types (field-types.js) 0.20KB 0.18KB
types (form.js) 0.20KB 0.18KB
types (index.js) 1.86KB 0.91KB
types (layout.js) 0.20KB 0.18KB
types (managed-by.js) 0.19KB 0.18KB
types (mobile.js) 0.20KB 0.18KB
types (navigation.js) 0.20KB 0.18KB
types (objectql.js) 0.20KB 0.18KB
types (overlay.js) 0.20KB 0.18KB
types (permissions.js) 0.20KB 0.18KB
types (plugin-scope.js) 0.20KB 0.18KB
types (record-components.js) 0.20KB 0.19KB
types (record-semantics.js) 1.28KB 0.67KB
types (registry.js) 0.20KB 0.18KB
types (reports.js) 0.20KB 0.18KB
types (spec-report.js) 5.04KB 1.93KB
types (system-fields.js) 2.39KB 1.17KB
types (theme.js) 0.20KB 0.18KB
types (ui-action.js) 0.75KB 0.46KB
types (views.js) 0.20KB 0.18KB
types (widget.js) 0.20KB 0.18KB

Size Limits

  • ✅ Core packages should be < 50KB gzipped
  • ✅ Component packages should be < 100KB gzipped
  • ⚠️ Plugin packages should be < 150KB gzipped

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

@object-ui/runner: has no tsconfig at all, and imports two exports @object-ui/core does not have

1 participant