Skip to content

Commit e396095

Browse files
refactor(types)!: delete nine Spec Report Bridge names nothing reads (#31038)
<!-- claude-projects-attribution: {"github_login":"os-tesla"} --> _Requested by **Tesla** · [project thread](https://claude.ai/code/project/chan_01AXsQkLFKRdQCqQ3RTr6Jao?thread=cmsg_01AXsQkLFKRdQCqQ3RTr6JaoDjfmEr3MKz1q8Xz5W6ZahJ)_ Part of #25921 (batch 10, claim 6691851032 with amendments 6691892486 naming the branch and 6691972228 naming the batch; the card's other open items stay on it) Clause-②: no (narrowing) Metadata-protocol: none ## 维护者速读 - 改了什么:从 `@object-ui/types` 的 `spec-report.ts`(入口上的 "Spec Report Bridge" 一组)删除 9 个没人读的名字:`SpecReportChart`、`SpecReportChartInput`、`SpecReportChartSchema`、`SpecReportTypeEnum`、`SpecReportAggregate`、`QLAggregationFunction`、`mapAggregateToQL`、`JoinedSpecReport`、`isJoinedSpecReport`。 - 为什么改:#25921 清理零消费者公开面;这 9 个名字在仓内与 hotcrm 都没有任何引用(只剩 CHANGELOG 记录行),其中 4 个只是 `@objectstack/spec/ui` 已有符号的改名转出,留着会被当成 UI 协议包的公开承诺。 - 风险与回滚:其中 `mapAggregateToQL`、`isJoinedSpecReport` 是运行时函数,dist 也随之删除;仓内无调用方,Console 与各 `@object-ui/*` 包不受影响。对外部 npm 使用者是破坏性变更,带一个 `!` patch changeset(BREAKING、FROM/TO、ADR-0087 `runtime-export-retired` 9 个)。回滚即 revert 本 PR。 - 先看:`ui/packages/types/src/spec-report.ts`(删掉的声明与两条 spec 导入)、`.changeset/25921-types-spec-report-bridge.md`(迁移说明)、`ui/packages/types/src/__tests__/report-chart-query-spec-parity.test.ts`(按席位裁决 A 删掉两条 `JoinedSpecReport.blocks` 派生钉子,`JoinedReportBlock` 的钉子全部保留)。 - 两分钟验证:`git grep -lw -e mapAggregateToQL -e JoinedSpecReport -- ui/packages` 预期只命中 `ui/packages/types/src/index.ts` 的退役注释(及 CHANGELOG);`pnpm --dir ui exec vitest run packages/types/` 预期全绿。 - 需要你做的:无,席位落地。 ## What changes `@object-ui/types` (its `.` entry) loses 9 names of `src/spec-report.ts`, the entry's "Spec Report Bridge" block. They are deleted from the module, not only from the entry: `SpecReportChart`, `SpecReportChartInput`, `SpecReportChartSchema`, `SpecReportTypeEnum`, `SpecReportAggregate`, `QLAggregationFunction`, `mapAggregateToQL`, `JoinedSpecReport`, `isJoinedSpecReport`. - `src/spec-report.ts`: the chart type pair and the `SpecReportChartSchema` / `SpecReportTypeEnum` constants go, with the four `@objectstack/spec/ui` imports only they read (`ReportChartParsed`, `ReportChart`, `ReportChartSchema`, `ReportType`); the "Aggregate mapping" section (`QLAggregationFunction`, `mapAggregateToQL`) and `SpecReportAggregate` go, with the header's "Aggregation naming" paragraph that pointed at them; `JoinedSpecReport` and `isJoinedSpecReport` go. The rest of the module stays as it was: `SpecReport`, `SpecReportInput`, `SpecReportTypeName`, `SpecReportDateGranularity`, `SpecReportSchema`, the `SpecReport` factory, `LegacyReportPresentationLike`, `specReportToPresentation`, `isSpecReport`, `JoinedReportBlock`. - `src/index.ts`: the block's two named lists lose the 9 names; a comment names them (#25921) and where the four spec re-exports' originals live. - `.changeset/25921-types-spec-report-bridge.md`: one `!` patch changeset, BREAKING, FROM/TO per name (the chart trio and `SpecReportTypeEnum` → `ReportChartParsed` / `ReportChart` / `ReportChartSchema` / `ReportType` of `@objectstack/spec/ui`; the aggregate trio and the joined pair → no replacement, with the one-line rewrite for the guard), and the ADR-0087 `runtime-export-retired` marker naming all 9. `spec-report.ts` is reached only through the `.` entry; no subpath entry of the package exports it. ## Tests Seat ruling A (amendment 6691972228): only what pins a retired name goes; every other row stays. - `src/__tests__/spec-report.test.ts`: the `describe('mapAggregateToQL')` block (2 tests) and its import go with the function; the schema, adapter and `isSpecReport` blocks stay. - `src/__tests__/spec-ui-schema-reexports.test.ts`: the `SpecReportTypeEnum` `toBeDefined` line goes; the `SpecReportSchema` line stays as the control for the same assertion. - `src/__tests__/report-chart-query-spec-parity.test.ts`: the two derivation pins on `JoinedSpecReport.blocks` (`_joinedReportBlocksAreTheSpecReportBlocks`, `_joinedReportBlocksAreParsedTier`, their `PublishedJoinedBlocks` alias and `void` lines), the `JoinedSpecReport` import, the `JoinedReportBlockParsed` import only they used, and the header prose naming them. Every `JoinedReportBlock` pin (state, derivation, member) stays. The file is compiled by the package's `type-check` (`tsc -p tsconfig.test.json` lists it). - No ablation: a deletion of exports with no tested behaviour left behind. The reverse probe below is the proof that the built `.d.ts` is the one read. ## Verification <details><summary>Census (read-only, before any edit; origin/main 0306761, hotcrm 6961ab1)</summary> - Tool: the batch 8 census (TS AST of every published `ui/packages/*` main entry; identifier-token index over every tracked file of both repositories minus CHANGELOGs, changesets, the lockfile and release notes; prose and tests count as consumers; then not taught in README/demo/docs and not named by a kept export's declaration). `@object-ui/types`: 716 entry names, 156 zero-outside, 54 candidates; `spec-report.ts` 10 of them. Note: this project's files `ui-seat-3/r2026-11-06/25921-b10-census.md`. - `git grep -lw` per name: every hit outside `ui/packages/types/` is a CHANGELOG record line (types, ui, app-shell, components, core); hotcrm 0 for all 9. - Readers among the 9 are each other only (`mapAggregateToQL`'s signature names `SpecReportAggregate` / `QLAggregationFunction`; `isJoinedSpecReport` names `JoinedSpecReport`). No zod twin, not an arm of `AnySchema`, no subpath entry, not taught. - Kept on rule 3 although the tool listed it: `SpecReportDateGranularity`, reached through `specReportToPresentation` → `LegacyReportPresentationLike.groupBy[].dateGranularity` (the tool's one-level proxy does not see the transitive reach). - Positive controls, same module, same tool: `specReportToPresentation` (4 files outside the package), `isSpecReport` (1). - No pending changeset names any of the 9; none of the 29 open PRs touches `ui/packages/types/`. </details> <details><summary>Local runs on head 6db3704 (base 0306761)</summary> - `env -u OS_SKIP_DTS pnpm --filter '@object-ui/types...' build` (fresh worktree, no prior `dist`): VERDICT command-exit 0. Built `dist`: 0 files name `mapAggregateToQL`, `isJoinedSpecReport` or `SpecReportChartSchema`; the control `specReportToPresentation` is in 5. - `pnpm --filter @object-ui/types run type-check` (src, examples, and `tsconfig.test.json`, which lists `report-chart-query-spec-parity.test.ts`) and `pnpm --dir ui exec vitest run packages/types/`: VERDICT command-exit 0; Test Files 387 passed (387), Tests 10460 passed (10460) (batch 9's 10462 minus the two `mapAggregateToQL` tests). - Reverse probe against the built `dist/index.d.ts`: a scratch file importing the 9 names plus the controls `isSpecReport` and `specReportToPresentation`, `tsc --noEmit --module nodenext`: 9 errors (TS2305 / TS2724, one per retired name), 0 on the control line. - `node scripts/pm/dispatch-gates.mjs --commands` on a63b2a0: 36 derived families, every line run with stdin closed, all exit 0 (`pnpm --dir ui exec vitest run scripts/`: Test Files 170 passed, 2 skipped (172), after building `@objectstack/client...` and `@objectstack/formula...` in this fresh worktree first); `--ran` reconciliation: 36 run, 0 NOT-MEASURED, 0 UNRUN. - `origin/main` merged (9 commits, none under `ui/packages/types/`) → head 6db3704; the derivation is byte-identical. Re-run there with stdin closed, all exit 0: `check-adr-0087-registration --base origin/main`, `check-changeset-no-major`, `check-empty-changeset`, `check:type-check-coverage`, `check:type-check-debt` (first attempt exit 3 while the dogfood build held the verify lock; rerun after it: exit 0, "0 raw tsc error(s) total"), `check:test-source-alias`, `check:cross-package-test-inputs`, `check-sdui-manifest`, `check:nul-bytes`. - `node scripts/check-platform-checklist.mjs --changed-from origin/main`: exit 0 (0 anchored files). `pnpm --dir ui run check:new-line-citations`: 0 new citations. - Full dogfood (owed by the `(narrowing)` arm), head 6db3704: `bash scripts/pm/os-verify-lock.sh -c "env -u OS_SKIP_DTS pnpm --filter '@objectstack/dogfood^...' build && pnpm --filter @objectstack/dogfood test"`: VERDICT command-exit 0; Test Files 428 passed, 3 skipped (431); Tests 3562 passed, 41 skipped (3603). - Records: this project's files `ui-seat-3/r2026-11-06/25921-b10/` (`gates-ran-a63b2a0f.list`, `gates-ran-6db37048.list`, `reverse-probe.txt`). </details> ## Acceptance notes - Still open on #25921 after this batch: `clearSharedDiscoveryCache` (needs a test-support home first) and the other barrel batches. `@object-ui/types` keeps about 45 more candidates (`product-blocks.ts` / `designer.ts` whose census hits are reached through kept unions, `data-protocol.ts` 6, `ui-action.ts` 4, the `@objectstack/spec/ui` re-exports 7 and others). Census and tools: this project's files `ui-seat-3/r2026-11-06/25921-b10-census.md`. - `types/src/ai.ts` keeps its `never` tombstones until the sunset rule of #25912; not touched here. --- _Generated by [Claude Code](https://claude.ai/code/session_01L9qibyCtmv9kCQuHZPh6eW)_ 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_01L9qibyCtmv9kCQuHZPh6eW Co-authored-by: Claude <noreply@anthropic.com>
1 parent 9d939c5 commit e396095

6 files changed

Lines changed: 43 additions & 156 deletions

File tree

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
---
2+
'@object-ui/types': patch
3+
---
4+
5+
refactor(types)!: delete nine Spec Report Bridge names nothing reads
6+
7+
Clause-②: no (narrowing)
8+
Metadata-protocol: none
9+
10+
<!-- adr-0087: not-required (runtime-export-retired @object-ui/types#SpecReportChart, @object-ui/types#SpecReportChartInput, @object-ui/types#SpecReportChartSchema, @object-ui/types#SpecReportTypeEnum, @object-ui/types#SpecReportAggregate, @object-ui/types#QLAggregationFunction, @object-ui/types#mapAggregateToQL, @object-ui/types#JoinedSpecReport, @object-ui/types#isJoinedSpecReport) the retired operands are package re-exports of `@objectstack/spec/ui` symbols, two string unions, a helper function and a type guard that no renderer, adapter or host reads; nothing in the workspace or in hotcrm imports any of them from the package entry, they are not arms of `AnySchema`, and the spec schemas they re-exported stay where they are in `@objectstack/spec/ui`, so no stored shape, registered node type or conversion surface changes and there is nothing for `objectstack migrate meta` to rewrite -->
11+
12+
**BREAKING** for a host that imports any of these nine names from `@object-ui/types`. None had an importer anywhere in the workspace or in hotcrm, so the Console and every `@object-ui/*` package are unaffected.
13+
14+
They are **gone from the package, not only from the entry**: `src/spec-report.ts` no longer declares them. Two of them, `mapAggregateToQL` and `isJoinedSpecReport`, are runtime values, so the built `dist` loses them too. The rest of the Spec Report Bridge stays: `SpecReport`, `SpecReportInput`, `SpecReportTypeName`, `SpecReportDateGranularity`, `SpecReportSchema`, `LegacyReportPresentationLike`, `specReportToPresentation`, `isSpecReport` and `JoinedReportBlock`.
15+
16+
What leaves, and what to write instead:
17+
18+
- FROM `SpecReportChart` TO `ReportChartParsed` from `@objectstack/spec/ui`.
19+
- FROM `SpecReportChartInput` TO `ReportChart` from `@objectstack/spec/ui`.
20+
- FROM `SpecReportChartSchema` TO `ReportChartSchema` from `@objectstack/spec/ui`.
21+
- FROM `SpecReportTypeEnum` TO `ReportType` from `@objectstack/spec/ui`.
22+
- FROM `SpecReportAggregate`, `QLAggregationFunction`, `mapAggregateToQL` TO no replacement. A spec report is dataset-bound: its `values` name measures whose aggregation the dataset declares, so there is no per-column aggregate left to translate.
23+
- FROM `JoinedSpecReport`, `isJoinedSpecReport` TO no replacement in this package. Test `isSpecReport(value) && value.type === 'joined'` and read `value.blocks`, each a `JoinedReportBlock`.

‎ui/packages/types/src/__tests__/report-chart-query-spec-parity.test.ts‎

Lines changed: 7 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -42,11 +42,8 @@ import {
4242
ChartTypeSchema as SpecChartTypeSchema,
4343
DashboardWidgetSchema as SpecDashboardWidgetSchema,
4444
} from '@objectstack/spec/ui';
45-
import type {
46-
JoinedReportBlock as SpecJoinedReportBlock,
47-
JoinedReportBlockParsed as SpecJoinedReportBlockParsed,
48-
} from '@objectstack/spec/ui';
49-
import type { JoinedReportBlock as PublishedJoinedReportBlock, JoinedSpecReport } from '../spec-report.js';
45+
import type { JoinedReportBlock as SpecJoinedReportBlock } from '@objectstack/spec/ui';
46+
import type { JoinedReportBlock as PublishedJoinedReportBlock } from '../spec-report.js';
5047
import { AppContextSelectorSchema } from '../zod/app.zod.js';
5148
import { DashboardWidgetSchema, DashboardWidgetTypeSchema, GlobalFilterSchema } from '../zod/complex.zod.js';
5249
import { DASHBOARD_COMPONENT_WIDGET_TYPES, DASHBOARD_WIDGET_TYPE_EXTENSIONS } from '../complex.js';
@@ -790,10 +787,10 @@ describe('renamed local dialects do not collide with a spec export (objectui#307
790787
* `groupingsAcross`, `filter`, `chart` — plus an index signature; the spec's
791788
* schema refuses all five of those keys, `chart` by name since objectstack#20161.
792789
*
793-
* objectui#10940 REPLACED the published `JoinedReportBlock` with the spec's type,
794-
* and `JoinedSpecReport.blocks` with the spec's own `Report.blocks`: a
795-
* published-type change, narrowing and widening, stated member by member in its
796-
* changeset. The divergence probes that stood here — local interface against
790+
* objectui#10940 REPLACED the published `JoinedReportBlock` with the spec's type:
791+
* a published-type change, narrowing and widening, stated member by member in
792+
* its changeset. (The joined-report wrapper type it also re-derived left the
793+
* package with objectstack#25921, read by nothing; its pins went with it.) The divergence probes that stood here — local interface against
797794
* spec, each written to stop compiling the day its difference moved — are
798795
* answered by that replacement and are deleted with the interface.
799796
*
@@ -807,8 +804,7 @@ describe('renamed local dialects do not collide with a spec export (objectui#307
807804
* probe on an erased spec is deleted, so every probe below is asked on every
808805
* compile and an erasure, on either spec, stops compiling. `any` is refused
809806
* as before.
810-
* - THE DERIVATION PINS: the published block IS the spec's block, and the
811-
* published joined report's `blocks` ARE the spec's report blocks. Re-forking
807+
* - THE DERIVATION PIN: the published block IS the spec's block. Re-forking
812808
* the block by hand under the spec's name is also refused by
813809
* `check:spec-symbols`, whose ALLOW row for this symbol retired with the
814810
* burn-down.
@@ -861,27 +857,6 @@ const _publishedBlockIsTheSpecBlock = true satisfies (
861857
? SameType<DeclaredBlockKeys<PublishedJoinedReportBlock>, DeclaredBlockKeys<SpecJoinedReportBlock>>
862858
: false
863859
);
864-
// …and a published joined report's `blocks` are the spec's own report blocks,
865-
// on the PARSED tier of `SpecReport`: required, each element the spec's parsed
866-
// block, assignable to the authoring-tier block but not the other way round
867-
// (`type` and `order[].direction` are defaulted on the parsed side).
868-
type PublishedJoinedBlocks = BlockMember<JoinedSpecReport, 'blocks'>;
869-
const _joinedReportBlocksAreTheSpecReportBlocks = true satisfies (
870-
[PublishedJoinedBlocks] extends [never]
871-
? false
872-
: undefined extends PublishedJoinedBlocks
873-
? false
874-
: SameType<PublishedJoinedBlocks, SpecJoinedReportBlockParsed[]>
875-
);
876-
const _joinedReportBlocksAreParsedTier = true satisfies (
877-
[PublishedJoinedBlocks] extends [never]
878-
? false
879-
: [SpecJoinedReportBlockParsed] extends [PublishedJoinedReportBlock]
880-
? [PublishedJoinedReportBlock] extends [SpecJoinedReportBlockParsed]
881-
? false
882-
: true
883-
: false
884-
);
885860

886861
// 1. NARROWED: the legacy inline-query keys are gone from the published block,
887862
// and so is the index signature that let any other key through.
@@ -958,8 +933,6 @@ void _specJoinedReportBlockTyping;
958933
void _specJoinedReportBlockIsNotEvenAny;
959934
void _publishedBlockTyping;
960935
void _publishedBlockIsTheSpecBlock;
961-
void _joinedReportBlocksAreTheSpecReportBlocks;
962-
void _joinedReportBlocksAreParsedTier;
963936
void _legacyBlockKeysAreGone;
964937
void _publishedBlockHasNoIndexSignature;
965938
void _datasetBoundBlockKeysArrived;

‎ui/packages/types/src/__tests__/spec-report.test.ts‎

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -4,35 +4,19 @@
44
*
55
* Tests for the Spec Report bridge (spec 9.0, dataset-bound — ADR-0021):
66
* - Re-exports compile and match the spec shape.
7-
* - Aggregate mapping handles the `unique → count_distinct` translation.
87
* - The presentation adapter maps the dataset `rows` / `values` names through.
98
*/
109

1110
import { describe, it, expect } from 'vitest';
1211
import {
1312
SpecReport,
1413
SpecReportSchema,
15-
mapAggregateToQL,
1614
specReportToPresentation,
1715
isSpecReport,
1816
} from '../spec-report';
1917
import type { SpecReportInput } from '../spec-report';
2018

2119
describe('SpecReport bridge', () => {
22-
describe('mapAggregateToQL', () => {
23-
it('translates unique to count_distinct', () => {
24-
expect(mapAggregateToQL('unique')).toBe('count_distinct');
25-
});
26-
27-
it('passes through standard aggregates', () => {
28-
expect(mapAggregateToQL('sum')).toBe('sum');
29-
expect(mapAggregateToQL('avg')).toBe('avg');
30-
expect(mapAggregateToQL('min')).toBe('min');
31-
expect(mapAggregateToQL('max')).toBe('max');
32-
expect(mapAggregateToQL('count')).toBe('count');
33-
});
34-
});
35-
3620
describe('SpecReportSchema parsing', () => {
3721
it('accepts a minimal tabular report (dataset + values)', () => {
3822
const input: SpecReportInput = {

‎ui/packages/types/src/__tests__/spec-ui-schema-reexports.test.ts‎

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,6 @@ describe('spec/ui …Schema re-exports (#2561, decision (a))', () => {
184184
expect(typeof Types.defineStack).toBe('function');
185185
expect(Types.ObjectStackSchema).toBeDefined();
186186
expect(Types.SpecReportSchema).toBeDefined();
187-
expect(Types.SpecReportTypeEnum).toBeDefined();
188187
expect(Types.ACTION_LOCATIONS).toBeDefined();
189188
expect(Types.ActionLocationSchema).toBeDefined();
190189
});

‎ui/packages/types/src/index.ts‎

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -960,29 +960,28 @@ export type {
960960
// Authoritative report protocol from @objectstack/spec, re-exported under
961961
// `Spec*` names so they coexist with the legacy presentation `ReportComponentSchema`.
962962
// See `./spec-report.ts` for the layering rationale.
963+
//
964+
// #25921 (batch 10): nine names of this block are DELETED, nothing in this
965+
// workspace or in hotcrm read them: `SpecReportChart`, `SpecReportChartInput`,
966+
// `SpecReportChartSchema` and `SpecReportTypeEnum` (import `ReportChartParsed`,
967+
// `ReportChart`, `ReportChartSchema` and `ReportType` from `@objectstack/spec/ui`),
968+
// and `SpecReportAggregate`, `QLAggregationFunction`, `mapAggregateToQL`,
969+
// `JoinedSpecReport` and `isJoinedSpecReport` (no replacement). The changeset
970+
// carries the FROM/TO.
963971
// ---------------------------------------------------------------------------
964972
export type {
965973
SpecReportInput,
966-
SpecReportChart,
967-
SpecReportChartInput,
968974
SpecReportTypeName,
969-
SpecReportAggregate,
970975
SpecReportDateGranularity,
971-
QLAggregationFunction,
972976
LegacyReportPresentationLike,
973977
JoinedReportBlock,
974-
JoinedSpecReport,
975978
} from './spec-report.js';
976979

977980
export {
978981
SpecReportSchema,
979-
SpecReportChartSchema,
980-
SpecReportTypeEnum,
981982
SpecReport,
982-
mapAggregateToQL,
983983
specReportToPresentation,
984984
isSpecReport,
985-
isJoinedSpecReport,
986985
} from './spec-report.js';
987986

988987
// Workflow / Flow Designer schemas removed in 9.0 — they backed the retired

‎ui/packages/types/src/spec-report.ts‎

Lines changed: 5 additions & 96 deletions
Original file line numberDiff line numberDiff line change
@@ -32,34 +32,24 @@
3232
* without polluting the protocol.
3333
* - A converter (`specReportToPresentation`) lets the legacy renderer keep
3434
* working while we migrate to spec-native rendering.
35-
*
36-
* ## Aggregation naming
37-
*
38-
* The UI spec uses `aggregate: 'unique'` while the data layer (ObjectQL,
39-
* `@objectstack/spec/data`) uses `count_distinct`. Use {@link mapAggregateToQL}
40-
* when translating a Report column into an ObjectQL `AggregationNode`.
4135
*/
4236

4337
// `@objectstack/spec` 17.0.0-rc.6 retired every `…Input` alias and moved the
4438
// bare name onto the `z.input` side: `Report`/`ReportChart` are now
4539
// `z.input<typeof …Schema>` and `ReportParsed`/`ReportChartParsed` carry the
46-
// `z.infer` shape these bindings used to read under the bare name. Both pairs
47-
// below are therefore re-pointed so that each local alias keeps the meaning it
48-
// had at rc.5 — `SpecReport`/`SpecReportChart` stay PARSED, `SpecReportInput`/
49-
// `SpecReportChartInput` stay INPUT. Following the rename by name alone (`X` →
50-
// `X`) would have silently swapped the two.
40+
// `z.infer` shape these bindings used to read under the bare name. The pair
41+
// below is therefore re-pointed so that each local alias keeps the meaning it
42+
// had at rc.5 — `SpecReport` stays PARSED, `SpecReportInput` stays INPUT.
43+
// Following the rename by name alone (`X` → `X`) would have silently swapped
44+
// the two.
5145
import type {
5246
ReportParsed as SpecReportType_,
5347
Report as SpecReportInputType_,
54-
ReportChartParsed as SpecReportChartType_,
55-
ReportChart as SpecReportChartInputType_,
5648
JoinedReportBlock as SpecJoinedReportBlockType_,
5749
} from '@objectstack/spec/ui';
5850

5951
import {
6052
ReportSchema as SpecReportSchema_,
61-
ReportChartSchema as SpecReportChartSchema_,
62-
ReportType as SpecReportTypeEnum_,
6353
Report as SpecReportFactory_,
6454
} from '@objectstack/spec/ui';
6555

@@ -69,8 +59,6 @@ import {
6959

7060
export type SpecReport = SpecReportType_;
7161
export type SpecReportInput = SpecReportInputType_;
72-
export type SpecReportChart = SpecReportChartType_;
73-
export type SpecReportChartInput = SpecReportChartInputType_;
7462

7563
/**
7664
* The four report types defined by the UI Protocol.
@@ -82,15 +70,6 @@ export type SpecReportChartInput = SpecReportChartInputType_;
8270
*/
8371
export type SpecReportTypeName = 'tabular' | 'summary' | 'matrix' | 'joined';
8472

85-
/**
86-
* Aggregation enum as it appears in the *UI* Report spec
87-
* (`@objectstack/spec/ui` Report.columns[].aggregate).
88-
*
89-
* Note that this intentionally differs from the data-layer `AggregationFunction`
90-
* enum used in ObjectQL — see {@link mapAggregateToQL}.
91-
*/
92-
export type SpecReportAggregate = 'sum' | 'avg' | 'max' | 'min' | 'count' | 'unique';
93-
9473
/**
9574
* Date granularity for time-based grouping
9675
* (`Report.groupingsDown[].dateGranularity`).
@@ -102,61 +81,13 @@ export type SpecReportDateGranularity = 'day' | 'week' | 'month' | 'quarter' | '
10281
// ---------------------------------------------------------------------------
10382

10483
export const SpecReportSchema = SpecReportSchema_;
105-
export const SpecReportChartSchema = SpecReportChartSchema_;
106-
export const SpecReportTypeEnum = SpecReportTypeEnum_;
10784

10885
/**
10986
* Spec factory helper (`Report.create`).
11087
* Validates the input against the spec and returns a typed `SpecReport`.
11188
*/
11289
export const SpecReport = SpecReportFactory_;
11390

114-
// ---------------------------------------------------------------------------
115-
// Aggregate mapping: UI spec → data layer (ObjectQL)
116-
// ---------------------------------------------------------------------------
117-
118-
/**
119-
* The aggregation enum used by the ObjectQL data layer.
120-
* Kept as a string union (rather than importing the value from
121-
* `@objectstack/spec/data`) so this types-only package stays
122-
* runtime-dependency-free.
123-
*/
124-
export type QLAggregationFunction =
125-
| 'count'
126-
| 'sum'
127-
| 'avg'
128-
| 'min'
129-
| 'max'
130-
| 'count_distinct'
131-
| 'array_agg'
132-
| 'string_agg';
133-
134-
/**
135-
* Translate a UI-layer aggregate name into the corresponding ObjectQL
136-
* `AggregationFunction`. The only non-trivial mapping is `unique → count_distinct`.
137-
*
138-
* @example
139-
* mapAggregateToQL('unique') // 'count_distinct'
140-
* mapAggregateToQL('sum') // 'sum'
141-
*/
142-
export function mapAggregateToQL(aggregate: SpecReportAggregate): QLAggregationFunction {
143-
switch (aggregate) {
144-
case 'unique': return 'count_distinct';
145-
case 'sum':
146-
case 'avg':
147-
case 'min':
148-
case 'max':
149-
case 'count':
150-
return aggregate;
151-
default: {
152-
// Exhaustiveness check
153-
const _exhaustive: never = aggregate;
154-
void _exhaustive;
155-
return 'count';
156-
}
157-
}
158-
}
159-
16091
// ---------------------------------------------------------------------------
16192
// Adapter: spec Report → legacy presentation ReportComponentSchema
16293
// ---------------------------------------------------------------------------
@@ -282,25 +213,3 @@ export function isSpecReport(value: unknown): value is SpecReport {
282213
* rather than kept beside it.
283214
*/
284215
export type JoinedReportBlock = SpecJoinedReportBlockType_;
285-
286-
/**
287-
* A `SpecReport` of `type: 'joined'` carrying its constituent blocks.
288-
* Use this as the schema input to `ReportRenderer` (dataset-bound blocks render
289-
* through `DatasetReportRenderer`).
290-
*
291-
* `blocks` is the spec's own `Report.blocks`, made required. It is on the
292-
* PARSED tier, like `SpecReport` itself (`type` and each `order[].direction`
293-
* are defaulted), so each element is assignable to the authoring-tier
294-
* {@link JoinedReportBlock}, but not the other way round.
295-
*/
296-
export type JoinedSpecReport = SpecReport & {
297-
type: 'joined';
298-
blocks: NonNullable<SpecReport['blocks']>;
299-
};
300-
301-
/** Type guard for joined reports with a `blocks` array. */
302-
export function isJoinedSpecReport(value: unknown): value is JoinedSpecReport {
303-
if (!isSpecReport(value)) return false;
304-
const v = value as Record<string, unknown>;
305-
return v.type === 'joined' && Array.isArray((v as { blocks?: unknown }).blocks);
306-
}

0 commit comments

Comments
 (0)