Skip to content

Commit b56fb0a

Browse files
committed
chore(changeset): declare the driver-sql / driver-turso door narrowing (#15267)
Both graded `minor` and marked `type-surface-only` under ADR-0087, matching the landed precedent PR #15280 for `update()` on the same classes. Claude-Session: https://claude.ai/code/session_01XTBcV7zZHmokdyQgXjbyEU Co-authored-by: Claude <noreply@anthropic.com>
1 parent cb1bd40 commit b56fb0a

2 files changed

Lines changed: 28 additions & 0 deletions

File tree

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
---
2+
'@objectstack/driver-sql': minor
3+
---
4+
5+
feat(driver-sql): the five remaining `IDataDriver` doors publish their honest types — the contract's own, not `any` (#15267)
6+
7+
**BREAKING** for TypeScript consumers — a published TYPE-surface narrowing, shipped as `minor` under the launch-window convention (the one PR #14434 set for the same class of change on `@objectstack/driver-memory`, and PR #15280 followed for `update()` on this very class). `SqlDriver` carried an EXPLICIT `Promise<any>` on five doors that `IDataDriver` had already declared narrower: `findOne()` (`Record<string, unknown> | null` — it has always answered `results[0] || null`), `create()` (`Record<string, unknown>`), `bulkCreate()` (`Record<string, unknown>[]`), `execute()` (`unknown`) and `explain()` (`unknown`). An explicit `any` satisfies all five structurally, so `tsc` said nothing while the emitted `.d.ts` told every consumer that `findOne()` never returns `null` and that `create()` returns whatever they like. #15280 un-masked `update()` and filed the census of what was left; this is that remainder.
8+
9+
Each door is now declared as the contract declares it. A caller that read fields off `findOne()` through the `any` now narrows the `null` arm first; a caller that leaned on `any` to read undeclared members off `create()` / `bulkCreate()`, or to dereference a raw `execute()` / `explain()` result, now types what it reads. No runtime behaviour changes.
10+
11+
`@objectstack/driver-sqlite-wasm` overrides none of these five and re-declares no member of its own, so it carries no entry: the narrowing reaches its consumers through this package's `.d.ts`. `@objectstack/driver-turso` overrides four of the five and carries its own entry.
12+
13+
Out of scope and deliberately unmoved: `analyzeQuery()` (not an `IDataDriver` member) and `aggregate()` keep their annotations.
14+
15+
<!-- adr-0087: not-required (type-surface-only packages/drivers/driver-sql/src/sql-driver.ts#findOne, packages/drivers/driver-sql/src/sql-driver.ts#create, packages/drivers/driver-sql/src/sql-driver.ts#bulkCreate, packages/drivers/driver-sql/src/sql-driver.ts#execute, packages/drivers/driver-sql/src/sql-driver.ts#explain) Five published driver methods' declared returns move off an explicit `any` onto the contract's own shapes. No metadata key is removed, renamed or re-shaped, `packages/spec` is untouched, and nothing exists for `objectstack migrate meta`, `spec-changes.json` or the upgrade guide to rewrite; the obligation is a TypeScript narrowing at the consumer's own call site, delivered by the compiler. -->
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
---
2+
'@objectstack/driver-turso': minor
3+
---
4+
5+
feat(driver-turso): the overridden `IDataDriver` doors publish their honest types, not `any` (#15267)
6+
7+
**BREAKING** for TypeScript consumers — a published TYPE-surface narrowing, shipped as `minor` under the launch-window convention. `TursoDriver` does not merely inherit these doors from `SqlDriver` — it OVERRIDES `findOne()`, `create()`, `bulkCreate()` and `execute()`, and each override was written out with its own explicit `Promise<any>`. So this package's emitted `.d.ts` re-declared four of the five doors as `any` on its own and would NOT have picked up the `@objectstack/driver-sql` narrowing — the same shape PR #15280 had to fix separately for `update()`.
8+
9+
Both branches of every one of the four already answered the contract's type: the local branch forwards to `SqlDriver`'s door (narrowed alongside, #15267) and the remote branch passes `RemoteTransport`'s result — already declared `Record<string, unknown> | null`, `Record<string, unknown>`, `Record<string, unknown>[]` and `unknown` respectively — through the generic `formatRemoteRow` / `formatRemoteRows`. Each override now declares what it has always answered. A caller that read fields off `findOne()` through the `any` now narrows the `null` arm first. No runtime behaviour changes.
10+
11+
`explain()` is not overridden here and reaches these consumers through `@objectstack/driver-sql`. Out of scope and deliberately unmoved: `upsert()`, `aggregate()` and `beginTransaction()` keep their annotations.
12+
13+
<!-- adr-0087: not-required (type-surface-only packages/drivers/driver-turso/src/turso-driver.ts#findOne, packages/drivers/driver-turso/src/turso-driver.ts#create, packages/drivers/driver-turso/src/turso-driver.ts#bulkCreate, packages/drivers/driver-turso/src/turso-driver.ts#execute) Four published driver method overrides' declared returns move off an explicit `any` onto the contract's own shapes; no metadata key moves, `packages/spec` is untouched, and the obligation is a TypeScript narrowing at the consumer's own call site, delivered by the compiler. -->

0 commit comments

Comments
 (0)