From c3101e2900925c5ac90bf3ae1e594716370b859a Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 5 Nov 2026 21:44:07 +0000 Subject: [PATCH 1/2] refactor(core)!: retire forty-two zero-consumer entry exports The @object-ui/core entry stops exporting 42 names nothing outside the package imports (tests and prose counted, hotcrm included). buildQueryAST and defaultQueryASTBuilder had no reader inside the package either and are deleted; the other 40 stay in their modules and only leave the entry. The export-star lines over those modules become named lists, in the entry and in the unpublished evaluator, actions, theme and data-scope sub-barrels. Claude-Session: https://claude.ai/code/session_01L6bhgXepjCvAfm5dmHYdrX Co-authored-by: Claude --- .../25921-core-zero-consumer-exports.md | 41 +++++ ui/packages/core/src/actions/index.ts | 33 +++- ui/packages/core/src/data-scope/index.ts | 3 +- .../__tests__/rowPredicateCanon.test.ts | 6 +- ui/packages/core/src/evaluator/index.ts | 18 +- ui/packages/core/src/index.ts | 158 ++++++++++++++++-- ui/packages/core/src/query/query-ast.ts | 6 - ui/packages/core/src/theme/index.ts | 7 +- 8 files changed, 233 insertions(+), 39 deletions(-) create mode 100644 .changeset/25921-core-zero-consumer-exports.md diff --git a/.changeset/25921-core-zero-consumer-exports.md b/.changeset/25921-core-zero-consumer-exports.md new file mode 100644 index 00000000000..74fef54be24 --- /dev/null +++ b/.changeset/25921-core-zero-consumer-exports.md @@ -0,0 +1,41 @@ +--- +'@object-ui/core': patch +--- + +refactor(core)!: retire forty-two zero-consumer entry exports, and delete the query-AST convenience pair nothing reads + +Clause-②: no (narrowing) +Metadata-protocol: none + + + +**BREAKING** for a host that imports any of these forty-two names from `@object-ui/core`. None had an importer anywhere in the workspace or in hotcrm, so the Console and every `@object-ui/*` package are unaffected. + +Two of them are **gone from the package, not only from the entry**, because nothing inside the package read them either: `buildQueryAST` and the `defaultQueryASTBuilder` instance it wrapped are deleted from `query/query-ast.ts`. + +The other forty stay in their modules for the code and tests that read them and only leave the entry. Every other name the entry exported stays exported unchanged, among them `QueryASTBuilder`, `columnIdentity`, `columnHeader`, `normalizeColumnIdentity`, `toDomProps`, `pickDomProps`, `AFFORDANCE_GRANTS`, `attachObjectSortability`, `readObjectSortability`, `markSwitchedOffActions`, `isActionSwitchedOff`, `attachCascadeDeleteObjects`, `readCascadeDeleteObjects`, `getSortValue`, `compareSortValues`, `bindSubjectPermissions`, `subjectPermissionsOf`, `bindSubjectCapabilities`, `subjectCapabilitiesOf`, `detectNonCanonicalRowSpelling`, `ACTION_DEF_KEYS`, `SPEC_ACTION_KEYS`, `RETIRED_ACTION_KEYS`, `warnOnUnknownActionKeys`, `interpretActionResponse`, `readActionPayload`, `actionCopySource`, `fillTemplateHoles`, `generateThemeVars`, `generateColorVars`, `elementDataSourceBlock`, `ERROR_CODES`, `createError`, `ObjectUIError` with all its subclasses, `debugLog`, `parseDebugFlags`, `CONTEXT_TOKENS`, `resolveFilterPlaceholders`, `buildChartSeries`, `isIntegerAggregate`, `resolveDimensionFieldMeta` and `createFieldColorResolver`. + +What leaves, and what to write instead: + +- FROM `buildQueryAST(query)`, `defaultQueryASTBuilder` TO `new QueryASTBuilder().build(query)`. +- FROM `CANONICAL_COLUMN_IDENTITY_KEY`, `LEGACY_COLUMN_IDENTITY_KEYS`, `CANONICAL_COLUMN_LABEL_KEY` TO `columnIdentity(column)` / `columnHeader(column)`, which read the canonical key and its legacy spellings; FROM `normalizeColumnIdentities(columns)` TO `columns.map(normalizeColumnIdentity)`. +- FROM `isOpenDomAttributeFamily` TO `toDomProps` / `pickDomProps`, which already pass every `data-*` and `aria-*` key. +- FROM `AffordanceGrantRow` TO `AffordanceGrant`, or `(typeof AFFORDANCE_GRANTS)[ConsoleAffordance]` for one row. +- FROM `normalizeObjectSortability`, `OBJECT_SORTABILITY_KEY` TO `attachObjectSortability` / `readObjectSortability`. +- FROM `ACTION_SWITCHED_OFF_KEY` TO `markSwitchedOffActions` / `markSwitchedOffActionsByObject` / `isActionSwitchedOff`. +- FROM `CASCADE_DELETE_OBJECTS_KEY` TO `attachCascadeDeleteObjects` / `readCascadeDeleteObjects`. +- FROM `compareCellValues(a, b, options)` TO `compareSortValues(getSortValue(a, options), getSortValue(b, options))`. +- FROM `SUBJECT_PERMISSIONS`, `SUBJECT_CAPABILITIES` TO `bindSubjectPermissions` / `subjectPermissionsOf` and `bindSubjectCapabilities` / `subjectCapabilitiesOf`. +- FROM `ROW_PREDICATE_CANONICAL_ROOT` TO the literal `'record'`, or `detectNonCanonicalRowSpelling` to check a predicate. +- FROM `NAVIGATION_ALIAS_KEYS`, `HOST_DISPATCH_ACTION_KEYS`, `KNOWN_ACTION_KEYS`, `classifyActionKeys` TO `warnOnUnknownActionKeys`, which classifies an action against the same vocabulary, or `ACTION_DEF_KEYS` / `SPEC_ACTION_KEYS` for the authored key lists. +- FROM `hasDeprecatedObjectParams`, `warnOnDeprecatedObjectParams` TO nothing: `ActionRunner` warns about deprecated object params itself when it runs the action. +- FROM `isLegacyActionEnvelope` TO `interpretActionResponse` / `readActionPayload`, which unwrap the legacy envelope. +- FROM `actionCopyText`, `fillTransitionalCopy` TO `actionCopySource` with `hasTemplateHoles` / `fillTemplateHoles`. +- FROM `toCSSColor`, `generateTypographyVars`, `generateBorderRadiusVars`, `generateShadowVars` TO `generateThemeVars(theme)`, which emits all of those variables, or `generateColorVars` for the colour block alone. +- FROM `isElementDataSourceBlock` TO nothing a host needs: the component registry reads it when `elementDataSourceBlock` marks a renderer. +- FROM `isErrorCode(code)` TO `code in ERROR_CODES`; FROM `formatErrorMessage(error)` TO `error.message` with `ERROR_CODES[error.code]` for the suggestion and doc link. +- FROM `isDebugEnabled` TO `debugLog` / `debugTime`, which are no-ops when debug mode is off. +- FROM `ContextTokenName` TO `(typeof CONTEXT_TOKENS)[number]`. +- FROM `isBuiltinAggregate`, `resolveMeasureLabel` TO `buildChartSeries` with `builtinAggregateLabels`, which labels a built-in aggregate measure the same way; FROM `INTEGER_AGGREGATES` TO `isIntegerAggregate`. +- FROM `resolveDimensionFieldOptions(...)` TO `resolveDimensionFieldMeta(...)`, the same walk, reading each entry's `options`; FROM `resolveRelationshipTarget` TO `resolveDimensionFieldMeta`, which follows the relationship for a dotted path. +- FROM `isColorLiteral`, `buildFieldColorMap`, `FieldColorOption` TO `createFieldColorResolver(fieldDef)`, which builds the colour map and accepts colour literals as-is. diff --git a/ui/packages/core/src/actions/index.ts b/ui/packages/core/src/actions/index.ts index dce6d6ab302..c9e74de6915 100644 --- a/ui/packages/core/src/actions/index.ts +++ b/ui/packages/core/src/actions/index.ts @@ -11,23 +11,38 @@ export * from './ActionEngine.js'; export { ACTION_DEF_KEYS, SPEC_ACTION_KEYS, - NAVIGATION_ALIAS_KEYS, - HOST_DISPATCH_ACTION_KEYS, RETIRED_ACTION_KEYS, - KNOWN_ACTION_KEYS, - classifyActionKeys, warnOnUnknownActionKeys, - hasDeprecatedObjectParams, - warnOnDeprecatedObjectParams, - // `resetActionKeyWarnings` is test-only and stays off the barrel + // `resetActionKeyWarnings` is test-only and stays off the barrel; + // `NAVIGATION_ALIAS_KEYS`, `HOST_DISPATCH_ACTION_KEYS`, `KNOWN_ACTION_KEYS`, + // `classifyActionKeys`, `hasDeprecatedObjectParams` and + // `warnOnDeprecatedObjectParams` stay in the module for `ActionRunner` and + // its pins, off the public entry (objectstack#25921: zero consumers) } from './actionKeys.js'; export * from './TransactionManager.js'; export * from './UndoManager.js'; export * from './bulkFastPath.js'; export * from './actionErrorDetail.js'; -export * from './actionResponse.js'; +// Named, not `export *`: `isLegacyActionEnvelope` stays in the module for its +// in-package readers and off the public entry (objectstack#25921: zero +// consumers). +export { + readActionPayload, + interpretActionResponse, + refusalFieldErrors, + type ActionResponseOutcome, +} from './actionResponse.js'; export * from './serverActionHandler.js'; export * from './recordIdParam.js'; export * from './recordDelete.js'; export * from './navigationTarget.js'; -export * from './actionCopyTemplate.js'; +// Named, not `export *`: `actionCopyText`, `fillTransitionalCopy` stay in the +// module for its in-package readers and off the public entry +// (objectstack#25921: zero consumers). +export { + isActionCopyEnvelope, + actionCopySource, + hasTemplateHoles, + fillTemplateHoles, + type ActionCopyTemplate, +} from './actionCopyTemplate.js'; diff --git a/ui/packages/core/src/data-scope/index.ts b/ui/packages/core/src/data-scope/index.ts index 577ff32d372..229ad78ec21 100644 --- a/ui/packages/core/src/data-scope/index.ts +++ b/ui/packages/core/src/data-scope/index.ts @@ -29,7 +29,8 @@ export { elementDataSourceBlock, elementDataSourceRefusedLimitMessage, elementDataSourceViewNotFoundMessage, - isElementDataSourceBlock, + // `isElementDataSourceBlock` stays in the module for the registry and off + // the public entry (objectstack#25921: zero consumers). isElementDataSourceConfig, resolveSavedView, type ComposedElementDataSource, diff --git a/ui/packages/core/src/evaluator/__tests__/rowPredicateCanon.test.ts b/ui/packages/core/src/evaluator/__tests__/rowPredicateCanon.test.ts index add813aed45..4ad83204d22 100644 --- a/ui/packages/core/src/evaluator/__tests__/rowPredicateCanon.test.ts +++ b/ui/packages/core/src/evaluator/__tests__/rowPredicateCanon.test.ts @@ -33,10 +33,10 @@ import { describe, it, expect, vi, beforeEach, afterEach, type MockInstance } fr import * as core from '../index.js'; import { detectNonCanonicalRowSpelling, - ROW_PREDICATE_CANONICAL_ROOT, evalRowPredicate, partitionRowsByPredicate, } from '../index.js'; +import { ROW_PREDICATE_CANONICAL_ROOT } from '../rowPredicateCanon.js'; const row = { status: 'in_review', amount: 10 }; const other = { status: 'draft', amount: 1 }; @@ -165,7 +165,9 @@ describe('[#5741] `evalRowPredicate` — the row is bound as `record.*` only', ( expect('warnNonCanonicalRowSpelling' in core).toBe(false); expect('resetRowPredicateCanonWarnings' in core).toBe(false); expect(typeof core.detectNonCanonicalRowSpelling).toBe('function'); - expect(core.ROW_PREDICATE_CANONICAL_ROOT).toBe('record'); + // The canonical-root constant stays in the module, off the barrel + // (objectstack#25921: zero consumers outside the package). + expect('ROW_PREDICATE_CANONICAL_ROOT' in core).toBe(false); }); it('`partitionRowsByPredicate`: `record.*` still partitions; a retired spelling excludes EVERY row', () => { diff --git a/ui/packages/core/src/evaluator/index.ts b/ui/packages/core/src/evaluator/index.ts index 782ec769cd9..3e7ea30558c 100644 --- a/ui/packages/core/src/evaluator/index.ts +++ b/ui/packages/core/src/evaluator/index.ts @@ -11,8 +11,22 @@ export * from './ExpressionEvaluator.js'; export * from './predicateInput.js'; export * from './declaredPredicate.js'; export * from './fieldRules.js'; -export * from './subjectPermissions.js'; -export * from './rowPredicateCanon.js'; +// Named, not `export *`: `SUBJECT_PERMISSIONS`, `SUBJECT_CAPABILITIES` stay in +// the module for its in-package readers and off the public entry +// (objectstack#25921: zero consumers). +export { + bindSubjectPermissions, + subjectPermissionsOf, + bindSubjectCapabilities, + subjectCapabilitiesOf, +} from './subjectPermissions.js'; +// Named, not `export *`: `ROW_PREDICATE_CANONICAL_ROOT` stays in the module for +// its in-package readers and off the public entry (objectstack#25921: zero +// consumers). +export { + detectNonCanonicalRowSpelling, + type NonCanonicalRowSpelling, +} from './rowPredicateCanon.js'; export * from './listConditional.js'; export * from './deadlineSettled.js'; export * from './optionRules.js'; diff --git a/ui/packages/core/src/index.ts b/ui/packages/core/src/index.ts index ae558e8e3dc..ad021768149 100644 --- a/ui/packages/core/src/index.ts +++ b/ui/packages/core/src/index.ts @@ -21,12 +21,37 @@ export * from './validation/index.js'; // what `toDomProps` passes — everything else is consumed or dropped. // `@object-ui/fields` executes the SAME mechanism against its own declared key // list (`pickDomProps`), so there is one judge, not two. -export * from './utils/dom-props.js'; +// Named, not `export *`: `isOpenDomAttributeFamily` stays in the module for its +// in-package readers and off the public entry (objectstack#25921: zero +// consumers). +export { + pickDomProps, + toDomProps, + SDUI_DOM_PASS_THROUGH_KEYS, + type SduiDomPassThroughKey, + type DomProps, +} from './utils/dom-props.js'; export * from './utils/filter-converter.js'; export * from './utils/managedBy.js'; // The affordance-to-grant map (objectui#12082): every console affordance that // offers a write reads the grant it exercises from this one table. -export * from './utils/affordanceGrants.js'; +// Named, not `export *`: `AffordanceGrantRow` stays in the module for its +// in-package readers and off the public entry (objectstack#25921: zero +// consumers). +export { + resolveAffordance, + resolveFieldAffordance, + formFieldsAffordance, + type AffordanceGrant, + type FieldAffordanceGrant, + AFFORDANCE_GRANTS, + type ConsoleAffordance, + type FieldAffordance, + type AffordanceGrantPrincipal, + type FieldAffordancePrincipal, + type AffordanceSource, + type AffordanceVerdict, +} from './utils/affordanceGrants.js'; export * from './utils/extract-records.js'; // The non-grid row ceiling (objectui#7210), homed beside the `extractRecords` // it wraps by objectui#7508's ruling A′. `@object-ui/react` re-exports three of @@ -56,32 +81,61 @@ export * from './utils/unmaterialized-fields.js'; // (`entry exists && sortable: true`). Homed beside the storage-fact set above // because a consumer that reaches for one must be able to see the other and // know which one the platform actually served. -export * from './utils/column-sortability.js'; +// Named, not `export *`: `normalizeObjectSortability`, `OBJECT_SORTABILITY_KEY` +// stay in the module for its in-package readers and off the public entry +// (objectstack#25921: zero consumers). +export { + attachObjectSortability, + readObjectSortability, + isPlatformSortableField, + filterPlatformSortableSort, +} from './utils/column-sortability.js'; // [objectstack#27504] The served packaged-action activation: which declared // actions the installation switched off, stamped by the data layer and asked // by every action gate beside the capability check. -export * from './utils/action-activation.js'; +// Named, not `export *`: `ACTION_SWITCHED_OFF_KEY` stays in the module for its +// in-package readers and off the public entry (objectstack#25921: zero +// consumers). +export { + markSwitchedOffActions, + markSwitchedOffActionsByObject, + isActionSwitchedOff, +} from './utils/action-activation.js'; // [objectstack#28472] The served delete cascade: the objects a delete of this // object also deletes, carried by the data layer to the delete confirmation. -export * from './utils/cascade-delete-objects.js'; +// Named, not `export *`: `CASCADE_DELETE_OBJECTS_KEY` stays in the module for +// its in-package readers and off the public entry (objectstack#25921: zero +// consumers). +export { + attachCascadeDeleteObjects, + readCascadeDeleteObjects, +} from './utils/cascade-delete-objects.js'; // [objectstack#28211] A list view's `kanban.lanes` as the `object-kanban` // node's `columns`: the one mapping both producers of that node share. export * from './utils/kanban-declared-lanes.js'; // Named, not `export *`: the module's `reset*` helper is test-only and stays off // the public barrel (objectui#13453); in-repo tests import it from the module. +// `CANONICAL_COLUMN_IDENTITY_KEY`, `LEGACY_COLUMN_IDENTITY_KEYS`, +// `normalizeColumnIdentities` and `CANONICAL_COLUMN_LABEL_KEY` stay in the +// module for its in-package readers and off the public entry +// (objectstack#25921: zero consumers). export { - CANONICAL_COLUMN_IDENTITY_KEY, - LEGACY_COLUMN_IDENTITY_KEYS, TABLE_ADAPTER_COLUMN_KEY, columnIdentity, hasConflictingColumnIdentity, normalizeColumnIdentity, - normalizeColumnIdentities, - CANONICAL_COLUMN_LABEL_KEY, TABLE_ADAPTER_HEADER_KEY, columnHeader, } from './utils/column-identity.js'; -export * from './utils/sort-values.js'; +// Named, not `export *`: `compareCellValues` stays in the module for its +// in-package readers and off the public entry (objectstack#25921: zero +// consumers). +export { + getSortValue, + compareSortValues, + type SortValue, + type SortValueOptions, +} from './utils/sort-values.js'; // Named, not `export *`: the module's `reset*` helper is test-only and stays off // the public barrel (objectui#13453); in-repo tests import it from the module. export { @@ -100,8 +154,32 @@ export * from './query/index.js'; export * from './adapters/index.js'; export * from './theme/index.js'; export * from './data-scope/index.js'; -export * from './errors/index.js'; -export * from './utils/debug.js'; +// Named, not `export *`: `isErrorCode`, `formatErrorMessage` stay in the module +// for its in-package readers and off the public entry (objectstack#25921: zero +// consumers). +export { + isObjectUIError, + createError, + type ErrorCodeEntry, + ERROR_CODES, + ObjectUIError, + SchemaError, + RegistryError, + ExpressionError, + PluginError, + FieldValidationError, +} from './errors/index.js'; +// Named, not `export *`: `isDebugEnabled` stays in the module for its +// in-package readers and off the public entry (objectstack#25921: zero +// consumers). +export { + parseDebugFlags, + debugLog, + debugTime, + debugTimeEnd, + type DebugCategory, + type DebugFlags, +} from './utils/debug.js'; export * from './utils/debug-collector.js'; export * from './utils/freeze-schema.js'; // The shared key/value-bag check (objectui#13458); locals switch to it when touched. @@ -126,7 +204,14 @@ export * from './utils/date-macros.js'; // the record-scoped `{record_id}` (objectui#7297), // plus `resolveFilterPlaceholders`, the single entry point every surface // should call so no vocabulary is silently skipped (objectstack-ai/objectstack#3574). -export * from './utils/filter-tokens.js'; +// Named, not `export *`: `ContextTokenName` stays in the module for its +// in-package readers and off the public entry (objectstack#25921: zero +// consumers). +export { + resolveContextTokens, + resolveFilterPlaceholders, + type FilterTokenScope, +} from './utils/filter-tokens.js'; // Named, not `export *`: the module's `reset*` helper is test-only and stays off // the public barrel (objectui#13453); in-repo tests import it from the module. export { @@ -141,7 +226,44 @@ export { } from './utils/dashboard-filters.js'; export * from './utils/merge-filters.js'; export * from './utils/compare-to.js'; -export * from './utils/chart-series.js'; +// Named, not `export *`: `isBuiltinAggregate`, `resolveMeasureLabel`, +// `resolveRelationshipTarget`, `resolveDimensionFieldOptions`, +// `INTEGER_AGGREGATES` stay in the module for its in-package readers and off +// the public entry (objectstack#25921: zero consumers). +export { + isIntegerAggregate, + chartBucketId, + chartRowBucketId, + buildChartSeries, + relabelDimensions, + findChartSeriesRow, + buildOptionColorMap, + buildCategoryOrder, + buildCategoryRank, + localizeFieldOptions, + buildDimensionLabelMap, + resolveDimensionFieldMeta, + dimensionOptionTranslator, + deriveDimensionLabelMaps, + loadDimensionFieldMeta, + type ChartResultField, + type BuiltinAggregateCarrier, + type ChartMeasureField, + type ChartSeriesBinding, + type ChartSeriesResult, + BUILTIN_AGGREGATES, + type BuiltinAggregate, + type BuiltinAggregateLabels, + NULL_CATEGORY_LABEL, + CHART_BUCKET_ID_KEY, + type ChartSeriesOptions, + type ChartDrillLookupOptions, + type ChartSegmentClickEvent, + type OptionLabelTranslator, + type DimensionFieldMeta, + type FieldOptionLabelResolver, + type DimensionRelabelTarget, +} from './utils/chart-series.js'; // "Which result column carries the measure?" — one answer for the row // projection and the series binding alike, delegated to the spec's own // derivation so the two cannot drift (objectui#8266). @@ -199,7 +321,13 @@ export { // The one `colorField` ladder every record view shares (objectui#7243) — the // gantt, calendar and timeline all resolve an authored option colour here // instead of each guessing at the raw stored value. -export * from './utils/record-color.js'; +// Named, not `export *`: `isColorLiteral`, `buildFieldColorMap`, +// `FieldColorOption` stay in the module for its in-package readers and off the +// public entry (objectstack#25921: zero consumers). +export { + createFieldColorResolver, + type FieldColorDefinition, +} from './utils/record-color.js'; export * from './utils/export-filename.js'; // Named, not `export *`: the module's `reset*` helper is test-only and stays off // the public barrel (objectui#13453); in-repo tests import it from the module. diff --git a/ui/packages/core/src/query/query-ast.ts b/ui/packages/core/src/query/query-ast.ts index c20aefa2814..6a61a36f27d 100644 --- a/ui/packages/core/src/query/query-ast.ts +++ b/ui/packages/core/src/query/query-ast.ts @@ -331,9 +331,3 @@ export class QueryASTBuilder { return ast; } } - -export const defaultQueryASTBuilder = new QueryASTBuilder(); - -export function buildQueryAST(query: DriverQueryConfig): SqlQueryAST { - return defaultQueryASTBuilder.build(query); -} diff --git a/ui/packages/core/src/theme/index.ts b/ui/packages/core/src/theme/index.ts index c54bfb77dbe..1ae8f47409d 100644 --- a/ui/packages/core/src/theme/index.ts +++ b/ui/packages/core/src/theme/index.ts @@ -8,11 +8,10 @@ export { hexToHSL, - toCSSColor, generateColorVars, - generateTypographyVars, - generateBorderRadiusVars, - generateShadowVars, + // `toCSSColor`, `generateTypographyVars`, `generateBorderRadiusVars` and + // `generateShadowVars` stay in the module for `generateThemeVars` and off + // the public entry (objectstack#25921: zero consumers). // `generateAnimationVars` / `generateZIndexVars` removed with the // `theme.animation` / `theme.zIndex` tombstones in @objectstack/spec // 17.0.0-rc.3 (objectstack#5021) — see ThemeEngine's RETIRED THEME BLOCKS From c21d361f698e9ac05f89cfa6b229756c687449ff Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 5 Nov 2026 21:46:19 +0000 Subject: [PATCH 2/2] fix(core): keep the spec names the filter-tokens and column-sortability modules re-export on the entry The reverse probe over all 518 former entry names caught five names the named lists dropped: CONTEXT_TOKENS, FIELD_UNSORTABLE_VIRTUAL_TYPE, FIELD_SORTABLE_UNPROVISIONED_ANCHOR, FieldSortability and ObjectSortability, which those modules re-export from @objectstack/spec. Claude-Session: https://claude.ai/code/session_01L6bhgXepjCvAfm5dmHYdrX Co-authored-by: Claude --- ui/packages/core/src/index.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/ui/packages/core/src/index.ts b/ui/packages/core/src/index.ts index ad021768149..98fdb9f08a9 100644 --- a/ui/packages/core/src/index.ts +++ b/ui/packages/core/src/index.ts @@ -81,10 +81,14 @@ export * from './utils/unmaterialized-fields.js'; // (`entry exists && sortable: true`). Homed beside the storage-fact set above // because a consumer that reaches for one must be able to see the other and // know which one the platform actually served. -// Named, not `export *`: `normalizeObjectSortability`, `OBJECT_SORTABILITY_KEY` +// Named, not `export *`: `normalizeObjectSortability` and `OBJECT_SORTABILITY_KEY` // stay in the module for its in-package readers and off the public entry // (objectstack#25921: zero consumers). export { + FIELD_UNSORTABLE_VIRTUAL_TYPE, + FIELD_SORTABLE_UNPROVISIONED_ANCHOR, + type FieldSortability, + type ObjectSortability, attachObjectSortability, readObjectSortability, isPlatformSortableField, @@ -208,6 +212,7 @@ export * from './utils/date-macros.js'; // in-package readers and off the public entry (objectstack#25921: zero // consumers). export { + CONTEXT_TOKENS, resolveContextTokens, resolveFilterPlaceholders, type FilterTokenScope,