Skip to content

fix(plugin-list): 删掉 UserFilters 的私有算子表,tab preset 走 spec 单一出口 (#3470) - #3483

Merged
yinlianghui merged 2 commits into
mainfrom
claude/issue-3470-userfilters-operator-table
Aug 6, 2026
Merged

fix(plugin-list): 删掉 UserFilters 的私有算子表,tab preset 走 spec 单一出口 (#3470)#3483
yinlianghui merged 2 commits into
mainfrom
claude/issue-3470-userfilters-operator-table

Conversation

@yinlianghui

@yinlianghui yinlianghui commented Aug 6, 2026

Copy link
Copy Markdown
Collaborator

Fixes #3470

先说 before/after 的实测裁决:IDENTICAL —— 这部分是纯修复,不是行为变更

issue 的 ⚠️ 差异点要求先测量再决定:旧表把 before/after 改写成 </>,而这两个词本身也是 VALID_AST_OPERATORS 成员,所以「直接透传」到底是不是纯修复,取决于服务端对它们的日期语义。按裁决用实测回答,没有假设。

独立测试栈(#3431 同法):e2e/live/ci/start-backend.sh,已发布 @objectstack/*@17.0.0-rc.2 + examples/app-showcase,objectstack dev --seed-admin --fresh -p 4093;对象 showcase_task(due_datedate,created_atdatetime)。原始 payload:

["due_date","before","2026-08-01"]                  -> 200  n=2
["due_date","<","2026-08-01"]                       -> 200  n=2   同一批 id
["due_date","after","2026-08-01"]                   -> 200  n=8
["due_date",">","2026-08-01"]                       -> 200  n=8   同一批 id
["created_at","before","2026-08-01T00:00:00.000Z"]  -> 200  n=6
["created_at","<","2026-08-01T00:00:00.000Z"]       -> 200  n=6   同一批 id
["created_at","after","2026-08-01T00:00:00.000Z"]   -> 200  n=3
["created_at",">","2026-08-01T00:00:00.000Z"]       -> 200  n=3   同一批 id

比对不只看行数,连返回的 record id 集合都逐个比过(探针里 same() 在双 200 时比较排序后的 id 数组)。datedatetime 两种字段类型、两个方向,状态码与结果集完全一致。所以旧表那次改写是个 no-op,去掉它是纯修复。spec 自己也独立印证了同一结论:canonicalAstOperator('before') === '<'

整表替换的实测:19 个算子里只有 not_in 的答案变了(400 → 正确的行)

把「canonical 拼法」与「旧 specOperatorToAst 的输出」逐一对打:

作者写的算子 canonical 直发 旧表映射后 判定
equals 200 n=2 = 200 n=2 same
not_equals 200 n=8 != 200 n=8 same
contains 200 n=1 contains 200 n=1 same
not_contains 200 n=9 notcontains 200 n=9 same
starts_with 200 n=1 startswith 200 n=1 same
ends_with 200 n=1 ends_with 200 n=1 same
greater_than 200 n=10 &gt; 200 n=10 same
less_than 200 n=0 &lt; 200 n=0 same
greater_than_or_equal 200 n=10 &gt;= 200 n=10 same
less_than_or_equal 200 n=0 &lt;= 200 n=0 same
in 200 n=4 in 200 n=4 same
not_in 200 n=8 not in 400 INVALID_FILTER DIFF
is_empty / is_not_empty 200 n=10 / n=0 same
is_null / is_not_null 200 n=10 / n=0 same
before / after 200 n=2 / n=8 &lt; / &gt; same
between 200 n=1 between 200 n=1 same

not_in 那 8 行与基线 ["status","!=","done"] 的 8 行是同一批。也就是说:整表替换对 18 个算子是无差别的,唯一变化正是被修的那个缺陷。

⚠️ 唯一一处「不是纯修复」的行为变更:规则缺省 operator

上表是按 19 个 canonical 算子测的,不覆盖「作者根本没写 operator」这一格。旧表的第一行是 case undefined: … return '=':一条 {field, value} 没有 operator 的规则,会被凭空补成等值谓词 ['status','=','x'],isFilterAST 放行、服务端当真答一批行。

改后它走 normalizeFilterOperator(非字符串原样返回)→ [field, undefined, value] → isFilterAST 判否 → 与其它 off-spec 拼法一样的响亮 400。

这个方向是对的,而且有 spec 背书:ViewFilterRuleSchema.operatorz.enum、没有 default,缺省 operator 的规则 safeParse 直接 invalid_value(已断言),即这类 metadata 根本发布不上去 —— 旧的 = 补齐是消费侧替契约做主,正是 #0.1 要拆掉的宽容消费者。但它确实是本 PR 里唯一「改前 200、改后 400」的一格,所以单独点名、单独一条测试钉住,不并进上面的 same 表里蒙混过去。

改了什么

specOperatorToAst 整个删掉,normalizeTabPresets 改走 spec 自己的 normalizeFilterOperator

删表而不是补表,是因为根本不需要表:19 个 VIEW_FILTER_OPERATORS 全部已经是 VALID_AST_OPERATORS 成员,rule → AST 的下降纯结构性,没有任何东西需要翻译;真正需要折叠的只有存量 metadata 里的旧拼法(gt / eq / nin / notEquals …),而那正是 normalizeFilterOperator 的职责。这也是写入侧 app-shell/views/viewFilterFold.ts 和 core 侧 saved-view fold(#3431)用的同一个出口 —— 一个出口,两个方向就不可能各自漂成一种方言。

未知拼法原样透传,让 isFilterAST 继续判否、服务端继续响亮 400(AGENTS.md #0.1):把 bfore 悄悄读成 before,换来的是一个看着合理的错误结果集,而不是作者能看见的错误。

反向验证(方向先预测,再运行)

预测:把私有表放回去,新增断言里钉 canonical 拼法的那些应该转红,而读 spec 词表 / 旧三元组透传 / 未知拼法透传这几条应该保持绿(旧表的 default: 分支本来就透传未知拼法)。实测与预测一致:

(表放回去)Tests  41 failed | 22 passed (63)
AssertionError: expected [ [ 'status', 'not in', [ 'done' ] ] ]
              to deeply equal [ [ 'status', 'not_in', [ 'done' ] ] ]

(表删掉)  Tests  64 passed (64)

诚实标注:「未知拼法原样透传」那条改前改后都是绿的,它钉的是契约不是变化,测试注释里写明了这一点 —— 不把一条不会翻转的断言粉饰成回归证据。

新断言用 spec 自己的 isFilterAST(就是服务端那道闸)在离线把验收事实钉死,和 #3431 一致,以后不需要真后端也能守住。

夹具清扫(按规则的消费半径,不是按包)

全仓搜过 'not in' 字面量与 tab preset 夹具。受影响的只有一处:UserFilters.test.tsx 里那条「从 initialSelections._tab 恢复 tab」的用例,它顺手钉了旧映射的 ['priority','=','urgent']。它测的是 tab 恢复、不是算子翻译,所以按「重新拼写」处置,改成 canonical 的 equals 并加注说明。phase2-schemas.test.ts 用的是已下降的 filters: triplet[] 旧形状,不走这条路径,未受影响(本 PR 另加了一条断言把「旧形状不许开始被翻译」钉住)。

验证

pnpm exec vitest run --maxWorkers=2 packages/plugin-list
  Test Files  23 passed (23)
  Tests  363 passed (363)

pnpm --filter @object-ui/plugin-list type-check     -> tsc --noEmit && tsc -p tsconfig.typetests.json,0 error
pnpm --filter @object-ui/plugin-list lint           -> 0 errors(warning 为仓库既有)
node scripts/check-control-bytes.mjs                -> OK(3675 个文件)
node scripts/check-changeset-no-major.mjs           -> 无 major

changeset:patch(@object-ui/plugin-list)。

范围外发现(已另立,不在本 PR 修)

objectstack-ai/objectstack#5869 —— 同一轮探针发现:集合算子的比较值是标量时(["status","not_in","done"],而这是 spec 合法的 ViewFilterRule,value 未按算子约束形状)服务端答 500 DATABASE_ERROR,而不是带 ADR-0112 信封的 400。与 #5234(静默零行)同轴不同格,已在正文里说明为何先立独立条目、是否并入请对面 PM 裁决。本 PR 不在消费侧加任何形状兜底 —— 那正是 #0.1 要避免的宽容消费者。

… presets through the spec (#3470)

`UserFilters.specOperatorToAst` was the second hand-kept operator map in this
package, and it had drifted: it lowered `not_in` — the spec's OWN canonical
spelling — and the legacy `nin` to the spaced `'not in'`, which appears in no
spec vocabulary. `isFilterAST` refuses it, so a `ViewTab.filter` preset written
the canonical way produced an empty list plus 400 the moment its tab was
clicked.

Measured against a real backend (published @objectstack/*@17.0.0-rc.2 +
app-showcase, showcase_task):

  $filter=[["status","not in",["done"]]]  -> 400 {"code":"INVALID_FILTER"}
  $filter=[["status","not_in",["done"]]]  -> 200, 8 rows
  $filter=[["status","!=","done"]]        -> 200, the same 8 rows

The table is deleted rather than repaired: all 19 VIEW_FILTER_OPERATORS are
already members of VALID_AST_OPERATORS, so the rule -> AST lowering is purely
structural and needs no translation. Only the legacy spellings stored metadata
still carries need folding, and the spec's own `normalizeFilterOperator` does
that — the same single exit the write side (viewFilterFold) and core's saved-view
fold (#3431) use, so the directions cannot drift into two dialects. An unknown
spelling is passed through verbatim so the server still refuses it loudly.

before/after are now passed through instead of being rewritten to `<`/`>`. That
was the one judgement call and it was settled by measurement, not assumption: on
the same live backend the word and the symbol return identical status and
identical record ids, on a `date` field and a `datetime` field, both directions.
The other 18 operators were measured the same way and are unchanged in what the
server answers; not_in is the only one whose answer changes, 400 -> the rows.

Reverse-verified: with the table restored, 41 of the 63 new assertions go red,
including the headline `isFilterAST` one. The 22 that stay green are the ones
that should — the spec-vocabulary reads, the legacy triplet passthrough, and the
unknown-spelling contract pin, whose behaviour the old table's `default:` branch
already had.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GTRjn8xBqp75dk7kFupVRt
@vercel

vercel Bot commented Aug 6, 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 Aug 6, 2026 10:04am

Request Review

@github-actions

github-actions Bot commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

✅ Console Performance Budget

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

📦 Bundle Size Report

Package Size Gzipped
app-shell (index.js) 8.47KB 3.09KB
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.21KB 3.45KB
auth (LoginForm.js) 18.13KB 5.39KB
auth (PreviewBanner.js) 0.90KB 0.50KB
auth (RegisterForm.js) 6.64KB 2.21KB
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.35KB 1.07KB
auth (org-roles.js) 6.66KB 2.78KB
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) 21.35KB 5.70KB
collaboration (LiveCursors.js) 3.17KB 1.27KB
collaboration (PresenceAvatars.js) 6.49KB 2.64KB
collaboration (PresenceProvider.js) 2.79KB 1.13KB
collaboration (index.js) 1.65KB 0.73KB
collaboration (useCollaborationTranslation.js) 5.30KB 2.24KB
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) 479.63KB 105.43KB
core (index.js) 2.47KB 0.91KB
create-plugin (index.js) 9.28KB 2.98KB
data-objectstack (index.js) 136.30KB 34.76KB
fields (index.js) 229.92KB 56.48KB
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.65KB 1.06KB
i18n (pickLocalized.js) 1.70KB 0.83KB
i18n (provider.js) 9.48KB 3.27KB
i18n (useObjectLabel.js) 26.14KB 6.07KB
i18n (useSafeTranslation.js) 3.26KB 1.44KB
layout (index.js) 38.53KB 10.71KB
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) 6.96KB 1.98KB
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) 4.05KB 1.53KB
mobile (useTouchTarget.js) 1.01KB 0.54KB
permissions (MePermissionsProvider.js) 8.75KB 3.06KB
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.41KB 1.44KB
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.98KB 12.37KB
plugin-charts (index.js) 61.04KB 17.31KB
plugin-chatbot (index.js) 180.09KB 42.72KB
plugin-dashboard (index.js) 112.03KB 28.88KB
plugin-designer (index.js) 210.51KB 42.51KB
plugin-detail (index.js) 232.53KB 57.37KB
plugin-editor (index.js) 2.46KB 1.10KB
plugin-form (index.js) 111.54KB 26.97KB
plugin-gantt (index.js) 162.55KB 39.57KB
plugin-grid (index.js) 185.25KB 49.08KB
plugin-kanban (index.js) 48.03KB 13.22KB
plugin-list (index.js) 104.72KB 25.36KB
plugin-map (index.js) 16.81KB 5.24KB
plugin-markdown (index.js) 13.72KB 4.69KB
plugin-report (index.js) 40.58KB 10.58KB
plugin-timeline (index.js) 25.76KB 7.33KB
plugin-tree (index.js) 8.50KB 2.88KB
plugin-view (index.js) 84.03KB 20.55KB
providers (DataSourceProvider.js) 0.75KB 0.39KB
providers (MetadataProvider.js) 1.37KB 0.59KB
providers (ThemeProvider.js) 1.90KB 0.85KB
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) 5.67KB 2.37KB
react (LazyPluginLoader.js) 3.77KB 1.33KB
react (SchemaRenderer.js) 19.28KB 6.38KB
react (data-invalidation.js) 5.05KB 2.08KB
react (index.js) 1.02KB 0.55KB
react (spec-input.js) 0.20KB 0.18KB
sdui-parser (codegen.js) 4.09KB 1.74KB
sdui-parser (index.js) 4.47KB 2.03KB
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) 1.87KB 0.85KB
types (disclosure.js) 0.20KB 0.18KB
types (error-code.js) 1.54KB 0.88KB
types (feedback.js) 0.20KB 0.18KB
types (field-types.js) 0.20KB 0.18KB
types (form.js) 0.20KB 0.18KB
types (http-retry.js) 4.32KB 2.02KB
types (index.js) 2.46KB 1.21KB
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.05KB 1.93KB
types (system-fields.js) 3.33KB 1.54KB
types (theme.js) 0.20KB 0.18KB
types (ui-action.js) 3.40KB 1.71KB
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

…ith no operator (#3470)

The deleted table opened with `case undefined: … return '='`, so a tab-preset
rule carrying `{field, value}` and NO operator lowered to `['status','=','x']`:
accepted by isFilterAST and answered by the server as a real equality predicate.
Through the spec's `normalizeFilterOperator` (which returns non-strings
untouched) it now lowers to `[field, undefined, value]`, which isFilterAST
refuses — the same loud 400 every other off-spec spelling gets.

That is the ONLY sub-case in this change whose "before" was a passing 200 rather
than a 400, so it is called out rather than folded into the pure-fix claim.
It is nonetheless the correct direction: `ViewFilterRuleSchema.operator` is a
bare `z.enum` with no default, so an operator-less rule fails `safeParse` with
`invalid_value` and cannot be published — inventing `=` for it was a lenient
consumer standing in for the contract (AGENTS.md #0.1). Both facts (the spec's
refusal and the emitted node's) are asserted, so the claim cannot rot.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GTRjn8xBqp75dk7kFupVRt
@github-actions

github-actions Bot commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

✅ Console Performance Budget

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

📦 Bundle Size Report

Package Size Gzipped
app-shell (index.js) 8.47KB 3.09KB
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.21KB 3.45KB
auth (LoginForm.js) 18.13KB 5.39KB
auth (PreviewBanner.js) 0.90KB 0.50KB
auth (RegisterForm.js) 6.64KB 2.21KB
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.35KB 1.07KB
auth (org-roles.js) 6.66KB 2.78KB
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) 21.35KB 5.70KB
collaboration (LiveCursors.js) 3.17KB 1.27KB
collaboration (PresenceAvatars.js) 6.49KB 2.64KB
collaboration (PresenceProvider.js) 2.79KB 1.13KB
collaboration (index.js) 1.65KB 0.73KB
collaboration (useCollaborationTranslation.js) 5.30KB 2.24KB
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) 479.63KB 105.43KB
core (index.js) 2.47KB 0.91KB
create-plugin (index.js) 9.28KB 2.98KB
data-objectstack (index.js) 136.30KB 34.76KB
fields (index.js) 229.92KB 56.48KB
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.65KB 1.06KB
i18n (pickLocalized.js) 1.70KB 0.83KB
i18n (provider.js) 9.48KB 3.27KB
i18n (useObjectLabel.js) 26.14KB 6.07KB
i18n (useSafeTranslation.js) 3.26KB 1.44KB
layout (index.js) 38.53KB 10.71KB
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) 6.96KB 1.98KB
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) 4.05KB 1.53KB
mobile (useTouchTarget.js) 1.01KB 0.54KB
permissions (MePermissionsProvider.js) 8.75KB 3.06KB
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.41KB 1.44KB
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.98KB 12.37KB
plugin-charts (index.js) 61.04KB 17.31KB
plugin-chatbot (index.js) 180.09KB 42.72KB
plugin-dashboard (index.js) 112.03KB 28.88KB
plugin-designer (index.js) 210.51KB 42.51KB
plugin-detail (index.js) 232.53KB 57.37KB
plugin-editor (index.js) 2.46KB 1.10KB
plugin-form (index.js) 111.54KB 26.97KB
plugin-gantt (index.js) 162.55KB 39.57KB
plugin-grid (index.js) 185.25KB 49.08KB
plugin-kanban (index.js) 48.03KB 13.22KB
plugin-list (index.js) 104.72KB 25.36KB
plugin-map (index.js) 16.81KB 5.24KB
plugin-markdown (index.js) 13.72KB 4.69KB
plugin-report (index.js) 40.58KB 10.58KB
plugin-timeline (index.js) 25.76KB 7.33KB
plugin-tree (index.js) 8.50KB 2.88KB
plugin-view (index.js) 84.03KB 20.55KB
providers (DataSourceProvider.js) 0.75KB 0.39KB
providers (MetadataProvider.js) 1.37KB 0.59KB
providers (ThemeProvider.js) 1.90KB 0.85KB
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) 5.67KB 2.37KB
react (LazyPluginLoader.js) 3.77KB 1.33KB
react (SchemaRenderer.js) 19.28KB 6.38KB
react (data-invalidation.js) 5.05KB 2.08KB
react (index.js) 1.02KB 0.55KB
react (spec-input.js) 0.20KB 0.18KB
sdui-parser (codegen.js) 4.09KB 1.74KB
sdui-parser (index.js) 4.47KB 2.03KB
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) 1.87KB 0.85KB
types (disclosure.js) 0.20KB 0.18KB
types (error-code.js) 1.54KB 0.88KB
types (feedback.js) 0.20KB 0.18KB
types (field-types.js) 0.20KB 0.18KB
types (form.js) 0.20KB 0.18KB
types (http-retry.js) 4.32KB 2.02KB
types (index.js) 2.46KB 1.21KB
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.05KB 1.93KB
types (system-fields.js) 3.33KB 1.54KB
types (theme.js) 0.20KB 0.18KB
types (ui-action.js) 3.40KB 1.71KB
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

@yinlianghui
yinlianghui marked this pull request as ready for review August 6, 2026 13:51
@yinlianghui
yinlianghui added this pull request to the merge queue Aug 6, 2026
Merged via the queue into main with commit d7f350a Aug 6, 2026
19 checks passed
@yinlianghui
yinlianghui deleted the claude/issue-3470-userfilters-operator-table branch August 6, 2026 13:52
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.

UserFilters 的私有 specOperatorToAst 把 not_in/nin 译成 not in(带空格),服务端 400;且它是第二张手工算子表

2 participants