You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit 1be8953
Browse filesBrowse the repository at this point in the historyBrowse files
changeset: state the SDK narrowing in the disposition its three siblings use
#8140 / #11925 / #12034 are the same class — a published `@objectstack/client`
return-type narrowing with no metadata surface behind it — and all three record
the no-ADR-0087-entry disposition as prose rather than as a `**BREAKING**`
declaration, which in this repo is the token that routes a change at the
metadata migration ledger. The consumer impact is stated in full (FROM/TO per
method, and the exact reads that stop compiling); what is dropped is a token
that would have claimed a ledger relevance this change does not have.
Recorded on the PR: the ADR-0087 gate has no honest disposition for a published
TYPE-surface narrowing that carries a consumer source-edit prescription and no
metadata migration — filed separately.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UjujZN219uFzBhSYfMykCd
|`analytics.meta`|`AnalyticsMetadataResponse`| same envelope; `data` is the bare `CubeMeta[]` projection |
30
-
|`analytics.explain`|`AnalyticsSqlResponse`| same envelope; `data` is `{ sql, params }`|
31
-
|`automation.trigger`|`BaseResponse & { data: AutomationResult }`| same envelope; the payload its sibling `automation.execute` unwraps |
32
-
|`analytics.queryDataset`|`AnalyticsResult`| served by `@objectstack/rest`, which answers `res.json(result)` — no envelope |
33
-
34
-
**What breaks.** Nothing that was already reading these correctly. `any`
35
-
accepted every read, so code that treated `analytics.query(...)` as if it were
36
-
the payload — `(await client.analytics.query(q)).rows` — compiled and was
37
-
`undefined` at runtime; it is now a compile error naming the envelope. The
38
-
remedy is the read the wire always required: `.data.rows`. The one method that
39
-
moves the other way is `queryDataset`, which is served BARE — a caller reading
40
-
`.data` off it was likewise reading `undefined`, and that read is now refused
41
-
too.
42
-
43
-
Every shape above was measured by driving the real producers (a real
44
-
`AnalyticsService`, a real `AutomationEngine`, the real `HttpDispatcher` and the
45
-
real `RestServer`, with only the socket stood in for), not by reading source or
46
-
asserting against a mock.
47
-
48
-
Scope: the five families whose producers live in this repo. The 38
49
-
better-auth-backed `auth.*` / `organizations.*` / `oauth.*` methods of the same
50
-
class are untouched and remain ledgered.
51
-
52
-
<!-- adr-0087: not-required (no-migration-prescription) A TypeScript return-type narrowing on five runtime SDK methods. No authorable key, schema property or metadata shape is removed, renamed or re-shaped anywhere — `packages/spec` is untouched — so there is no tombstone and nothing mechanical for `objectstack migrate meta` to rewrite; a ledger entry would have no artifact to project into. The channel that reaches an affected caller is the compile error at their own call site, which names the envelope and is why the change is worth shipping: the remedy (`.data.rows` instead of `.rows`) is a source edit in consumer code, which no migration entry can perform on an upgrader's behalf. -->
|`client.analytics.meta`|`any`|`AnalyticsMetadataResponse`| same envelope; `data` is the bare `CubeMeta[]` projection |
28
+
|`client.analytics.explain`|`any`|`AnalyticsSqlResponse`| same envelope; `data` is `{ sql, params }`|
29
+
|`client.automation.trigger`|`any`|`BaseResponse & { data: AutomationResult }`| same envelope, over the payload its sibling `automation.execute` unwraps |
30
+
|`client.analytics.queryDataset`|`any`|`AnalyticsResult`| served by `@objectstack/rest`, which ends `res.json(result)` — no envelope |
31
+
32
+
`any` is assignable to everything and admits every property read, so a
33
+
consumer's code can stop compiling where it previously did not. Concretely:
34
+
35
+
-**Reading a payload key off one of the four ENVELOPED results.**
36
+
`(await client.analytics.query(q)).rows` compiled and was `undefined` at
37
+
runtime; the read the wire always required is `.data.rows`. Same for
38
+
`.data` on `meta` / `explain`, and `.data.runId` / `.data.screen` on
39
+
`automation.trigger`.
40
+
-**Reading `.data` off `queryDataset`**, which is served bare — likewise
41
+
`undefined` today, likewise refused now.
42
+
- Assigning any of the five results to an unrelated annotation, or forwarding
43
+
one to a differently-typed parameter.
44
+
45
+
That break is the point: those call sites are already wrong at runtime and the
46
+
`any` is what hid it. The compiler is the channel that reaches every affected
47
+
consumer, and it is strictly more precise than a release note.
48
+
49
+
## How the shapes were established
50
+
51
+
By DRIVING the real producers — a real `AnalyticsService`, a real
52
+
`AutomationEngine`, the real `HttpDispatcher` and the real `RestServer`, with
53
+
only the socket stood in for — not by reading source and not by asserting
54
+
against a mock. Two spec response types that look like the right binding are
55
+
NARROWER than the contract their route relays
56
+
(`AnalyticsResultResponseSchema.data.fields` and
57
+
`TriggerFlowResponseSchema.data`), so those two annotations bind the producer's
58
+
contract instead; the near-miss is pinned so a later sweep cannot retarget them.
59
+
60
+
## Scope
61
+
62
+
The five families whose producers live in this repo. The 38 better-auth-backed
63
+
`auth.*` / `organizations.*` / `oauth.*` methods of the same class are untouched
64
+
and keep their erased `any` — they are exactly as permissive as before, and no
65
+
consumer loses anything by that.
66
+
67
+
No ADR-0087 ledger entry: nothing here is a metadata surface. No Zod schema, no
68
+
`packages/spec` declaration and no stored representation changed — the erasure
69
+
lived only in a TypeScript return annotation — so `objectstack migrate meta` has
70
+
nothing to rewrite and an entry would have no artifact to project into. This is
71
+
the disposition #8140, #11925 and #12034 recorded for the same class of SDK
0 commit comments