Skip to content

Commit a63b2a0

Browse files
committed
refactor(types)!: delete nine Spec Report Bridge names nothing reads
Nine names of ui/packages/types/src/spec-report.ts leave the package: the chart re-export trio, SpecReportTypeEnum, the aggregate-mapping trio and the joined-report wrapper type with its guard. Their in-package test pins go with them; the JoinedReportBlock pins and SpecReportSchema control stay. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01L9qibyCtmv9kCQuHZPh6eW
1 parent 0306761 commit a63b2a0

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)