@kequtech/tenon-orm 0.4.4 → 0.4.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +9 -0
- package/dist/generation/render.js +5 -4
- package/docs/connections.md +13 -4
- package/docs/reference.md +1 -1
- package/docs/schema-types.md +21 -18
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.4.5
|
|
4
|
+
|
|
5
|
+
- Preserve generated enum and enum-domain label unions when unrelated codecs change, including
|
|
6
|
+
Date and bigint decoding. Custom enum decoders retain their declared output types; unidentified
|
|
7
|
+
decoders still warn and generate `unknown`. Enum write inputs retain catalog choices.
|
|
8
|
+
- Require pgclear `^0.3.3` for per-type default-decoder metadata and dynamic notification
|
|
9
|
+
subscriptions. Native listeners can add and remove channels on one dedicated connection; see
|
|
10
|
+
[notifications](docs/connections.md#listen-for-notifications) for ownership and recovery.
|
|
11
|
+
|
|
3
12
|
## 0.4.4
|
|
4
13
|
|
|
5
14
|
- Pass the shared `TenonConfig` directly to `createTenon`, including its connection, codecs, and
|
|
@@ -6,12 +6,13 @@ function columnTypes(column, codecs, path, warn) {
|
|
|
6
6
|
warn(`Column ${path} uses a custom decoder without a known TypeScript representation; generated as unknown.`);
|
|
7
7
|
read = 'unknown';
|
|
8
8
|
}
|
|
9
|
-
const choices = column.choices?.map((choice) => JSON.stringify(choice)).join(' | ') || 'never';
|
|
10
|
-
if (column.typeKind === 'e' && codecs === defaultCodecs && read === 'string')
|
|
11
|
-
read = choices;
|
|
12
9
|
let write = defaultCodecs.typescript(oid);
|
|
13
|
-
if (column.typeKind === 'e')
|
|
10
|
+
if (column.typeKind === 'e') {
|
|
11
|
+
const choices = column.choices?.map((choice) => JSON.stringify(choice)).join(' | ') || 'never';
|
|
12
|
+
if (read === 'string' && codecs.isDefaultDecoder(oid))
|
|
13
|
+
read = choices;
|
|
14
14
|
write = choices;
|
|
15
|
+
}
|
|
15
16
|
if (write === 'unknown' || write.startsWith('PgArray<'))
|
|
16
17
|
write = 'string';
|
|
17
18
|
if ([20, 1700].includes(oid))
|
package/docs/connections.md
CHANGED
|
@@ -181,20 +181,29 @@ During application startup, pass a validated PostgreSQL URI (`connection` below)
|
|
|
181
181
|
import { listen } from '@kequtech/pgclear';
|
|
182
182
|
|
|
183
183
|
const listener = await listen(connection, {
|
|
184
|
-
channels: [
|
|
184
|
+
channels: [],
|
|
185
185
|
onNotification: ({ payload }) => console.log(payload),
|
|
186
186
|
reconnect: true,
|
|
187
187
|
});
|
|
188
|
+
// Membership can change on this same connection. Await server registration:
|
|
189
|
+
await listener.subscribe('users_changed');
|
|
190
|
+
// When the channel is no longer needed:
|
|
191
|
+
await listener.unsubscribe('users_changed');
|
|
188
192
|
// At shutdown:
|
|
189
193
|
await listener.close();
|
|
190
194
|
```
|
|
191
195
|
|
|
192
|
-
A listener has a separate lifetime and is not closed by `db.close()`.
|
|
193
|
-
|
|
196
|
+
A listener has a separate lifetime and is not closed by `db.close()`. Subscription changes share its
|
|
197
|
+
dedicated connection; reconnect restores the last acknowledged channel set. Subscriptions are set
|
|
198
|
+
operations: repeated subscribes do not add reference counts. Applications own subscriber counts,
|
|
199
|
+
authorization, and routing. Notifications are not replayed after a disconnection; use the listener's
|
|
200
|
+
status/generation changes to detect a possible gap and reconcile persistent state. See
|
|
201
|
+
[pgclear's notification guide](https://github.com/kequtech/pgclear/blob/main/docs/notifications.md)
|
|
202
|
+
for deadlines, cancellation, and changes queued during reconnect.
|
|
194
203
|
|
|
195
204
|
## Update the driver
|
|
196
205
|
|
|
197
|
-
Tenon depends on `@kequtech/pgclear: ^0.3.
|
|
206
|
+
Tenon depends on `@kequtech/pgclear: ^0.3.3`, which permits compatible 0.3.x patch updates. With npm:
|
|
198
207
|
|
|
199
208
|
```sh
|
|
200
209
|
npm update @kequtech/pgclear
|
package/docs/reference.md
CHANGED
|
@@ -44,7 +44,7 @@ handling, timeout bounds, and lifecycle examples. Runtime `search_path` is indep
|
|
|
44
44
|
|
|
45
45
|
### Driver updates
|
|
46
46
|
|
|
47
|
-
The dependency range is `@kequtech/pgclear: ^0.3.
|
|
47
|
+
The dependency range is `@kequtech/pgclear: ^0.3.3`. Compatible patches may be updated independently;
|
|
48
48
|
see [driver updates](connections.md#update-the-driver). Tenon re-exports `builtin`, `json`, `param`,
|
|
49
49
|
`defaultCodecs`, and `createTemporalCodecs`, with the driver's `Codec`, `CodecRegistry`, `Parameter`,
|
|
50
50
|
`PgArray`, `TemporalConstructors`, and `TemporalInput` types.
|
package/docs/schema-types.md
CHANGED
|
@@ -131,22 +131,22 @@ well typed; PostgreSQL still enforces constraints.
|
|
|
131
131
|
These are the default driver representations. SQL NULL is `null`; nullable generated columns add
|
|
132
132
|
null to their type. Input encoding and output decoding are separate choices.
|
|
133
133
|
|
|
134
|
-
| PostgreSQL value | Default read
|
|
135
|
-
| ----------------------------------------------------------- |
|
|
136
|
-
| smallint, integer, serial, oid | `number`
|
|
137
|
-
| bigint, bigserial, `count(*)` | Exact `string`
|
|
138
|
-
| numeric/decimal | `string`
|
|
139
|
-
| real, double precision | `number`
|
|
140
|
-
| boolean | `boolean`
|
|
141
|
-
| text, UUID, other textual types | `string`
|
|
142
|
-
| enum | Catalog label union
|
|
143
|
-
| date, timestamp, timestamptz | `string`
|
|
144
|
-
| time, interval | `string`
|
|
145
|
-
| timetz | `string`
|
|
146
|
-
| json/jsonb | `unknown`
|
|
147
|
-
| bytea | `Uint8Array`
|
|
148
|
-
| Supported built-in arrays | Recursive readonly `PgArray<T>`
|
|
149
|
-
| Unrecognized types and dynamic enum/domain/extension arrays | Wire-text `string`
|
|
134
|
+
| PostgreSQL value | Default read | Plain write input |
|
|
135
|
+
| ----------------------------------------------------------- | ---------------------------------------------------- | ------------------------------------------------------------- |
|
|
136
|
+
| smallint, integer, serial, oid | `number` | `number` |
|
|
137
|
+
| bigint, bigserial, `count(*)` | Exact `string` | Exact string or bigint |
|
|
138
|
+
| numeric/decimal | `string` | String or bigint |
|
|
139
|
+
| real, double precision | `number` | Finite number |
|
|
140
|
+
| boolean | `boolean` | Boolean |
|
|
141
|
+
| text, UUID, other textual types | `string` | String |
|
|
142
|
+
| enum | Catalog label union when its decoder remains default | Label union |
|
|
143
|
+
| date, timestamp, timestamptz | `string` | String, Date, or supported Temporal value |
|
|
144
|
+
| time, interval | `string` | String or supported Temporal value |
|
|
145
|
+
| timetz | `string` | String |
|
|
146
|
+
| json/jsonb | `unknown` | Encoded JSON string; use `json(value)` for a parameter |
|
|
147
|
+
| bytea | `Uint8Array` | Uint8Array |
|
|
148
|
+
| Supported built-in arrays | Recursive readonly `PgArray<T>` | Encoded PostgreSQL array text; use `param` for an array value |
|
|
149
|
+
| Unrecognized types and dynamic enum/domain/extension arrays | Wire-text `string` | Encoded string or explicit parameter |
|
|
150
150
|
|
|
151
151
|
Generated inputs conservatively describe column-compatible representations; an explicit `Parameter`
|
|
152
152
|
is accepted for every writable column. PostgreSQL checks ranges and text formats. Plain undefined,
|
|
@@ -200,8 +200,11 @@ configuration needs the corresponding Temporal library declarations.
|
|
|
200
200
|
|
|
201
201
|
A custom text codec can declare `text.typescript` to describe its non-NULL output. Generation and
|
|
202
202
|
checking consume the registry's metadata. An unidentified decoder warns and becomes `unknown`;
|
|
203
|
-
a declared representation is trusted, not runtime validation.
|
|
204
|
-
|
|
203
|
+
a declared representation is trusted, not runtime validation. Generated enum rows retain catalog label
|
|
204
|
+
unions when that enum's decoder remains default, including when unrelated Date, bigint, or other
|
|
205
|
+
codecs change. A custom enum decoder uses its own declared output type, or `unknown` with a warning
|
|
206
|
+
when unidentified; declaring `string` does not establish that it preserves catalog labels. Enum write
|
|
207
|
+
inputs retain catalog choices regardless of the output decoder.
|
|
205
208
|
|
|
206
209
|
Place the registry in shared `connection.codecs` so runtime, CLI generation, inspection, and source
|
|
207
210
|
checking use it consistently. Programmatic inspection/checking inherit `connection.codecs` too. Relative type-import
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kequtech/tenon-orm",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.5",
|
|
4
4
|
"license": "ISC",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"description": "A PostgreSQL ORM designed for coding agents, with explicit SQL, typed queries, and migrations",
|
|
@@ -71,7 +71,7 @@
|
|
|
71
71
|
"printWidth": 100
|
|
72
72
|
},
|
|
73
73
|
"dependencies": {
|
|
74
|
-
"@kequtech/pgclear": "^0.3.
|
|
74
|
+
"@kequtech/pgclear": "^0.3.3",
|
|
75
75
|
"typescript": "~6.0.2"
|
|
76
76
|
}
|
|
77
77
|
}
|