joist-orm 2.3.0-next.41 → 2.3.0-next.43

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.
Files changed (95) hide show
  1. package/build/_virtual/_rolldown/runtime.cjs +23 -0
  2. package/build/_virtual/_rolldown/runtime.js +5 -0
  3. package/build/codegen.cjs +19 -0
  4. package/build/codegen.cjs.map +1 -0
  5. package/build/codegen.d.cts +1 -0
  6. package/build/codegen.d.mts +1 -0
  7. package/build/codegen.js +11 -28
  8. package/build/codegen.js.map +1 -1
  9. package/build/drivers/PostgresDriver.cjs +290 -0
  10. package/build/drivers/PostgresDriver.cjs.map +1 -0
  11. package/build/drivers/PostgresDriver.d.cts +77 -0
  12. package/build/drivers/PostgresDriver.d.cts.map +1 -0
  13. package/build/drivers/PostgresDriver.d.mts +77 -0
  14. package/build/drivers/PostgresDriver.d.mts.map +1 -0
  15. package/build/drivers/PostgresDriver.js +249 -325
  16. package/build/drivers/PostgresDriver.js.map +1 -1
  17. package/build/drivers/WireRowData.cjs +374 -0
  18. package/build/drivers/WireRowData.cjs.map +1 -0
  19. package/build/drivers/WireRowData.d.cts +111 -0
  20. package/build/drivers/WireRowData.d.cts.map +1 -0
  21. package/build/drivers/WireRowData.d.mts +111 -0
  22. package/build/drivers/WireRowData.d.mts.map +1 -0
  23. package/build/drivers/WireRowData.js +352 -412
  24. package/build/drivers/WireRowData.js.map +1 -1
  25. package/build/drivers/binaryParsers.cjs +422 -0
  26. package/build/drivers/binaryParsers.cjs.map +1 -0
  27. package/build/drivers/{binaryParsers.d.ts → binaryParsers.d.cts} +18 -14
  28. package/build/drivers/binaryParsers.d.cts.map +1 -0
  29. package/build/drivers/binaryParsers.d.mts +80 -0
  30. package/build/drivers/binaryParsers.d.mts.map +1 -0
  31. package/build/drivers/binaryParsers.js +315 -385
  32. package/build/drivers/binaryParsers.js.map +1 -1
  33. package/build/drivers/patchPgProtocol.cjs +255 -0
  34. package/build/drivers/patchPgProtocol.cjs.map +1 -0
  35. package/build/drivers/{patchPgProtocol.d.ts → patchPgProtocol.d.cts} +18 -14
  36. package/build/drivers/patchPgProtocol.d.cts.map +1 -0
  37. package/build/drivers/patchPgProtocol.d.mts +47 -0
  38. package/build/drivers/patchPgProtocol.d.mts.map +1 -0
  39. package/build/drivers/patchPgProtocol.js +211 -232
  40. package/build/drivers/patchPgProtocol.js.map +1 -1
  41. package/build/graphql-codegen-export.cjs +10 -0
  42. package/build/graphql-codegen-export.d.cts +1 -0
  43. package/build/graphql-codegen-export.d.mts +1 -0
  44. package/build/graphql-codegen-export.js +2 -19
  45. package/build/graphql-export.cjs +10 -0
  46. package/build/graphql-export.d.cts +1 -0
  47. package/build/graphql-export.d.mts +1 -0
  48. package/build/graphql-export.js +2 -19
  49. package/build/index.cjs +41 -0
  50. package/build/index.d.cts +3 -0
  51. package/build/index.d.mts +3 -0
  52. package/build/index.js +3 -27
  53. package/build/knex-export.cjs +10 -0
  54. package/build/knex-export.d.cts +1 -0
  55. package/build/knex-export.d.mts +1 -0
  56. package/build/knex-export.js +2 -19
  57. package/build/pg-export.cjs +13 -0
  58. package/build/pg-export.d.cts +4 -0
  59. package/build/pg-export.d.mts +4 -0
  60. package/build/pg-export.js +4 -20
  61. package/build/pg-migrate.cjs +22 -0
  62. package/build/pg-migrate.cjs.map +1 -0
  63. package/build/pg-migrate.d.cts +1 -0
  64. package/build/pg-migrate.d.mts +1 -0
  65. package/build/pg-migrate.js +13 -28
  66. package/build/pg-migrate.js.map +1 -1
  67. package/build/seed.cjs +49 -0
  68. package/build/seed.cjs.map +1 -0
  69. package/build/{seed.d.ts → seed.d.cts} +5 -1
  70. package/build/seed.d.cts.map +1 -0
  71. package/build/seed.d.mts +24 -0
  72. package/build/seed.d.mts.map +1 -0
  73. package/build/seed.js +39 -45
  74. package/build/seed.js.map +1 -1
  75. package/build/tests-export.cjs +10 -0
  76. package/build/tests-export.d.cts +1 -0
  77. package/build/tests-export.d.mts +1 -0
  78. package/build/tests-export.js +2 -19
  79. package/package.json +150 -28
  80. package/build/codegen.d.ts +0 -2
  81. package/build/drivers/PostgresDriver.d.ts +0 -73
  82. package/build/drivers/WireRowData.d.ts +0 -107
  83. package/build/graphql-codegen-export.d.ts +0 -1
  84. package/build/graphql-codegen-export.js.map +0 -1
  85. package/build/graphql-export.d.ts +0 -1
  86. package/build/graphql-export.js.map +0 -1
  87. package/build/index.d.ts +0 -3
  88. package/build/index.js.map +0 -1
  89. package/build/knex-export.d.ts +0 -1
  90. package/build/knex-export.js.map +0 -1
  91. package/build/pg-export.d.ts +0 -3
  92. package/build/pg-export.js.map +0 -1
  93. package/build/pg-migrate.d.ts +0 -2
  94. package/build/tests-export.d.ts +0 -1
  95. package/build/tests-export.js.map +0 -1
@@ -1,253 +1,204 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.setBinaryTypeParser = setBinaryTypeParser;
4
- exports.getBinaryTypeParser = getBinaryTypeParser;
5
- exports.registerDatabaseBinaryParsers = registerDatabaseBinaryParsers;
6
- exports.setSessionTimeZone = setSessionTimeZone;
7
- exports.binaryTextParser = binaryTextParser;
8
- exports.binaryArrayParser = binaryArrayParser;
9
- exports.binaryDateToDate = binaryDateToDate;
10
- exports.binaryTimestampToDate = binaryTimestampToDate;
11
- exports.binaryTimestamptzToDate = binaryTimestamptzToDate;
12
- exports.registerTemporalBinaryParsers = registerTemporalBinaryParsers;
13
- const joist_core_1 = require("joist-core");
1
+ import { requireTemporal } from "joist-core";
2
+ //#region src/drivers/binaryParsers.ts
14
3
  /**
15
- * Joist's registry of PostgreSQL *binary-format* cell parsers, used by `WireRowData` for lazy
16
- * `em.find`/`em.load` results (which request binary output; see `executeRowDataQuery`).
17
- *
18
- * This registry is deliberately **separate from `pg.types`**: `pg.types.setTypeParser` and
19
- * pool/client `TypeOverrides` continue to govern classic *text* results (knex, `pool.query`,
20
- * non-lazy drivers), while binary cells decode wire-bytes -> values directly — ints via
21
- * `readInt32BE`, timestamps via µs arithmetic, Temporal values constructed without ever
22
- * materializing a string. There is no fallback from one registry to the other:
23
- *
24
- * - Built-in parsers cover the standard scalar/array types below; `setupLatestPgTypes`
25
- * registers the date/time parsers appropriate to Date-vs-Temporal mode.
26
- * - Custom/extension types (native enums, citext, domains, hstore, ...) must be registered
27
- * explicitly with {@link setBinaryTypeParser} — text-like types can use
28
- * {@link binaryTextParser}, arrays of registered elements can use {@link binaryArrayParser}.
29
- * - A query selecting a column whose oid has no registered parser **fails** with a descriptive
30
- * error (see `WireRowData.setRowDescription`), rather than guessing at a lossy decoding.
31
- *
32
- * Values produced here should match what the classic text path produces for the same column
33
- * (i.e. `numeric` stays a string, `int8` stays a string, Date-mode timestamps become `Date`s),
34
- * so entities hydrate identically in either mode; Temporal-mode parsers construct
35
- * `Temporal.PlainDate`/`ZonedDateTime`/etc. directly, and the temporal mappers pass
36
- * already-constructed instances through.
37
- */
4
+ * Joist's registry of PostgreSQL *binary-format* cell parsers, used by `WireRowData` for lazy
5
+ * `em.find`/`em.load` results (which request binary output; see `executeRowDataQuery`).
6
+ *
7
+ * This registry is deliberately **separate from `pg.types`**: `pg.types.setTypeParser` and
8
+ * pool/client `TypeOverrides` continue to govern classic *text* results (knex, `pool.query`,
9
+ * non-lazy drivers), while binary cells decode wire-bytes -> values directly — ints via
10
+ * `readInt32BE`, timestamps via µs arithmetic, Temporal values constructed without ever
11
+ * materializing a string. There is no fallback from one registry to the other:
12
+ *
13
+ * - Built-in parsers cover the standard scalar/array types below; `setupLatestPgTypes`
14
+ * registers the date/time parsers appropriate to Date-vs-Temporal mode.
15
+ * - Custom/extension types (native enums, citext, domains, hstore, ...) must be registered
16
+ * explicitly with {@link setBinaryTypeParser} — text-like types can use
17
+ * {@link binaryTextParser}, arrays of registered elements can use {@link binaryArrayParser}.
18
+ * - A query selecting a column whose oid has no registered parser **fails** with a descriptive
19
+ * error (see `WireRowData.setRowDescription`), rather than guessing at a lossy decoding.
20
+ *
21
+ * Values produced here should match what the classic text path produces for the same column
22
+ * (i.e. `numeric` stays a string, `int8` stays a string, Date-mode timestamps become `Date`s),
23
+ * so entities hydrate identically in either mode; Temporal-mode parsers construct
24
+ * `Temporal.PlainDate`/`ZonedDateTime`/etc. directly, and the temporal mappers pass
25
+ * already-constructed instances through.
26
+ */
38
27
  function setBinaryTypeParser(oid, parse) {
39
- parsers.set(oid, parse);
28
+ parsers.set(oid, parse);
40
29
  }
41
30
  /** Returns the registered binary parser for `oid`, i.e. for tests to save/restore. */
42
31
  function getBinaryTypeParser(oid) {
43
- return parsers.get(oid);
32
+ return parsers.get(oid);
44
33
  }
45
34
  /**
46
- * Auto-registers binary parsers for the database's text-like dynamic-oid types — native enums
47
- * and citext, plus their array types — so apps get those for free.
48
- *
49
- * `PostgresDriver` calls this lazily before its first lazy query; apps can also call it
50
- * directly (i.e. at boot) if they want the registrations eagerly. Explicit
51
- * `setBinaryTypeParser` registrations are never overwritten.
52
- */
35
+ * Auto-registers binary parsers for the database's text-like dynamic-oid types — native enums
36
+ * and citext, plus their array types — so apps get those for free.
37
+ *
38
+ * `PostgresDriver` calls this lazily before its first lazy query; apps can also call it
39
+ * directly (i.e. at boot) if they want the registrations eagerly. Explicit
40
+ * `setBinaryTypeParser` registrations are never overwritten.
41
+ */
53
42
  async function registerDatabaseBinaryParsers(pool) {
54
- // Also capture the session's TimeZone, which zones temporal-mode timestamptz loads to match
55
- // what classic text parsing would have produced (pg renders timestamps in the session zone)
56
- const [{ rows: settings }, { rows }] = await Promise.all([
57
- pool.query(`select current_setting('TimeZone') as tz`),
58
- pool.query(`select t.oid, t.typarray
43
+ const [{ rows: settings }, { rows }] = await Promise.all([pool.query(`select current_setting('TimeZone') as tz`), pool.query(`select t.oid, t.typarray
59
44
  from pg_type t
60
45
  where t.typtype = 'e'
61
46
  or t.typname = 'citext'
62
- or (t.typtype = 'd' and (select b.typcategory from pg_type b where b.oid = t.typbasetype) = 'S')`),
63
- ]);
64
- setSessionTimeZone(settings[0].tz);
65
- for (const row of rows) {
66
- const oid = Number(row.oid);
67
- if (getBinaryTypeParser(oid) === undefined)
68
- setBinaryTypeParser(oid, binaryTextParser);
69
- const arrayOid = Number(row.typarray);
70
- if (arrayOid !== 0 && getBinaryTypeParser(arrayOid) === undefined) {
71
- setBinaryTypeParser(arrayOid, binaryArrayParser);
72
- }
73
- }
47
+ or (t.typtype = 'd' and (select b.typcategory from pg_type b where b.oid = t.typbasetype) = 'S')`)]);
48
+ setSessionTimeZone(settings[0].tz);
49
+ for (const row of rows) {
50
+ const oid = Number(row.oid);
51
+ if (getBinaryTypeParser(oid) === void 0) setBinaryTypeParser(oid, binaryTextParser);
52
+ const arrayOid = Number(row.typarray);
53
+ if (arrayOid !== 0 && getBinaryTypeParser(arrayOid) === void 0) setBinaryTypeParser(arrayOid, binaryArrayParser);
54
+ }
74
55
  }
75
56
  /**
76
- * Sets the session `TimeZone` used to zone temporal-mode `timestamptz` loads; normally captured
77
- * automatically by {@link registerDatabaseBinaryParsers}. One zone per process — pools with
78
- * differing session TimeZones are not supported by the binary path.
79
- */
57
+ * Sets the session `TimeZone` used to zone temporal-mode `timestamptz` loads; normally captured
58
+ * automatically by {@link registerDatabaseBinaryParsers}. One zone per process — pools with
59
+ * differing session TimeZones are not supported by the binary path.
60
+ */
80
61
  function setSessionTimeZone(timeZone) {
81
- sessionTimeZone = timeZone === "Etc/UTC" ? "UTC" : timeZone;
62
+ sessionTimeZone = timeZone === "Etc/UTC" ? "UTC" : timeZone;
82
63
  }
83
64
  let sessionTimeZone = "UTC";
84
65
  /** Decodes a cell's bytes as utf8 text, i.e. for text-like custom types (enums, citext, domains). */
85
66
  function binaryTextParser(chunk, start, length) {
86
- return chunk.toString("utf8", start, start + length);
67
+ return chunk.toString("utf8", start, start + length);
87
68
  }
88
69
  /**
89
- * Decodes a binary array cell into a JS array of element values.
90
- *
91
- * The element oid is embedded in the wire format, and each element decodes through this
92
- * registry — so arrays of any registered type (including custom-registered oids and the
93
- * mode-appropriate temporal types) work without separate element wiring. Registered for the
94
- * standard `_type` oids below; register it for custom array oids as needed.
95
- */
70
+ * Decodes a binary array cell into a JS array of element values.
71
+ *
72
+ * The element oid is embedded in the wire format, and each element decodes through this
73
+ * registry — so arrays of any registered type (including custom-registered oids and the
74
+ * mode-appropriate temporal types) work without separate element wiring. Registered for the
75
+ * standard `_type` oids below; register it for custom array oids as needed.
76
+ */
96
77
  function binaryArrayParser(chunk, start, length) {
97
- const nDims = chunk.readInt32BE(start);
98
- if (nDims === 0)
99
- return [];
100
- const elemOid = chunk.readInt32BE(start + 8);
101
- const parse = parsers.get(elemOid) ??
102
- fail(`joist-orm: no binary type parser registered for array element oid ${elemOid}; see setBinaryTypeParser`);
103
- const dims = [];
104
- for (let d = 0; d < nDims; d++)
105
- dims.push(chunk.readInt32BE(start + 12 + d * 8));
106
- let pos = start + 12 + nDims * 8;
107
- function readDim(dim) {
108
- const values = [];
109
- for (let i = 0; i < dims[dim]; i++) {
110
- if (dim < nDims - 1) {
111
- values.push(readDim(dim + 1));
112
- }
113
- else {
114
- const len = chunk.readInt32BE(pos);
115
- pos += 4;
116
- if (len === -1) {
117
- values.push(null);
118
- }
119
- else {
120
- values.push(parse(chunk, pos, len));
121
- pos += len;
122
- }
123
- }
124
- }
125
- return values;
126
- }
127
- return readDim(0);
78
+ const nDims = chunk.readInt32BE(start);
79
+ if (nDims === 0) return [];
80
+ const elemOid = chunk.readInt32BE(start + 8);
81
+ const parse = parsers.get(elemOid) ?? fail$1(`joist-orm: no binary type parser registered for array element oid ${elemOid}; see setBinaryTypeParser`);
82
+ const dims = [];
83
+ for (let d = 0; d < nDims; d++) dims.push(chunk.readInt32BE(start + 12 + d * 8));
84
+ let pos = start + 12 + nDims * 8;
85
+ function readDim(dim) {
86
+ const values = [];
87
+ for (let i = 0; i < dims[dim]; i++) if (dim < nDims - 1) values.push(readDim(dim + 1));
88
+ else {
89
+ const len = chunk.readInt32BE(pos);
90
+ pos += 4;
91
+ if (len === -1) values.push(null);
92
+ else {
93
+ values.push(parse(chunk, pos, len));
94
+ pos += len;
95
+ }
96
+ }
97
+ return values;
98
+ }
99
+ return readDim(0);
128
100
  }
129
101
  /** Decodes binary `date` cells to `Date`s, matching postgres-date's text semantics; Date mode. */
130
102
  function binaryDateToDate(chunk, start) {
131
- const days = chunk.readInt32BE(start);
132
- if (days === INFINITY_DAYS)
133
- return Infinity;
134
- if (days === NEG_INFINITY_DAYS)
135
- return -Infinity;
136
- const [year, month, day] = civilFromDays(days + PG_EPOCH_DAYS);
137
- const date = new Date(year, month - 1, day);
138
- // Mirror postgres-date's fixup for years 0-99 being interpreted as 1900-1999
139
- if (year < 100)
140
- date.setFullYear(year);
141
- return date;
103
+ const days = chunk.readInt32BE(start);
104
+ if (days === INFINITY_DAYS) return Infinity;
105
+ if (days === NEG_INFINITY_DAYS) return -Infinity;
106
+ const [year, month, day] = civilFromDays(days + PG_EPOCH_DAYS);
107
+ const date = new Date(year, month - 1, day);
108
+ if (year < 100) date.setFullYear(year);
109
+ return date;
142
110
  }
143
111
  /** Decodes binary `timestamp` (without zone) cells to local-time `Date`s; Date mode. */
144
112
  function binaryTimestampToDate(chunk, start) {
145
- const pgMicros = chunk.readBigInt64BE(start);
146
- if (pgMicros === INFINITY_US)
147
- return Infinity;
148
- if (pgMicros === NEG_INFINITY_US)
149
- return -Infinity;
150
- const { days, us } = splitPgMicros(pgMicros);
151
- const [year, month, day] = civilFromDays(days);
152
- const seconds = Math.floor(us / 1_000_000);
153
- const date = new Date(year, month - 1, day, Math.floor(seconds / 3600), Math.floor((seconds / 60) % 60), seconds % 60, Math.floor((us % 1_000_000) / 1000));
154
- if (year < 100)
155
- date.setFullYear(year);
156
- return date;
113
+ const pgMicros = chunk.readBigInt64BE(start);
114
+ if (pgMicros === INFINITY_US) return Infinity;
115
+ if (pgMicros === NEG_INFINITY_US) return -Infinity;
116
+ const { days, us } = splitPgMicros(pgMicros);
117
+ const [year, month, day] = civilFromDays(days);
118
+ const seconds = Math.floor(us / 1e6);
119
+ const date = new Date(year, month - 1, day, Math.floor(seconds / 3600), Math.floor(seconds / 60 % 60), seconds % 60, Math.floor(us % 1e6 / 1e3));
120
+ if (year < 100) date.setFullYear(year);
121
+ return date;
157
122
  }
158
123
  /** Decodes binary `timestamptz` cells to `Date`s (µs floor to ms, like the text parse); Date mode. */
159
124
  function binaryTimestamptzToDate(chunk, start) {
160
- const pgMicros = chunk.readBigInt64BE(start);
161
- if (pgMicros === INFINITY_US)
162
- return Infinity;
163
- if (pgMicros === NEG_INFINITY_US)
164
- return -Infinity;
165
- const epochMicros = pgMicros + PG_EPOCH_US;
166
- let ms = epochMicros / 1000n;
167
- if (epochMicros % 1000n < 0n)
168
- ms -= 1n;
169
- return new Date(Number(ms));
125
+ const pgMicros = chunk.readBigInt64BE(start);
126
+ if (pgMicros === INFINITY_US) return Infinity;
127
+ if (pgMicros === NEG_INFINITY_US) return -Infinity;
128
+ const epochMicros = pgMicros + PG_EPOCH_US;
129
+ let ms = epochMicros / 1000n;
130
+ if (epochMicros % 1000n < 0n) ms -= 1n;
131
+ return new Date(Number(ms));
170
132
  }
171
133
  /**
172
- * Registers the Temporal-mode binary parsers: date/time/timestamp/timestamptz cells construct
173
- * `Temporal` values *directly* from the wire µs/days — no intermediate strings, no
174
- * `temporalMappers.fromDb` parsing (the mappers pass already-constructed instances through).
175
- *
176
- * `timestamptz` matches the text path's zoning exactly: classic parsing zones the value by the
177
- * offset the session's `TimeZone` rendered (normalizing `+00` to `UTC`), so we compute the
178
- * session zone's offset at each instant (see `setSessionTimeZone`; the configured
179
- * `temporal.timeZone` only governs `now`-conversions, not loads).
180
- */
134
+ * Registers the Temporal-mode binary parsers: date/time/timestamp/timestamptz cells construct
135
+ * `Temporal` values *directly* from the wire µs/days — no intermediate strings, no
136
+ * `temporalMappers.fromDb` parsing (the mappers pass already-constructed instances through).
137
+ *
138
+ * `timestamptz` matches the text path's zoning exactly: classic parsing zones the value by the
139
+ * offset the session's `TimeZone` rendered (normalizing `+00` to `UTC`), so we compute the
140
+ * session zone's offset at each instant (see `setSessionTimeZone`; the configured
141
+ * `temporal.timeZone` only governs `now`-conversions, not loads).
142
+ */
181
143
  function registerTemporalBinaryParsers() {
182
- const { Temporal: t } = (0, joist_core_1.requireTemporal)();
183
- setBinaryTypeParser(oids.DATE, (chunk, start) => {
184
- const days = chunk.readInt32BE(start);
185
- if (days === INFINITY_DAYS || days === NEG_INFINITY_DAYS)
186
- failTemporalInfinity("date");
187
- const [year, month, day] = civilFromDays(days + PG_EPOCH_DAYS);
188
- return new t.PlainDate(year, month, day);
189
- });
190
- setBinaryTypeParser(1083 /* time */, (chunk, start) => {
191
- const us = Number(chunk.readBigInt64BE(start));
192
- const seconds = Math.floor(us / 1_000_000);
193
- return new t.PlainTime(Math.floor(seconds / 3600), Math.floor((seconds / 60) % 60), seconds % 60, Math.floor((us % 1_000_000) / 1000), us % 1000);
194
- });
195
- setBinaryTypeParser(oids.TIMESTAMP, (chunk, start) => {
196
- const pgMicros = chunk.readBigInt64BE(start);
197
- if (pgMicros === INFINITY_US || pgMicros === NEG_INFINITY_US)
198
- failTemporalInfinity("timestamp");
199
- const { days, us } = splitPgMicros(pgMicros);
200
- const [year, month, day] = civilFromDays(days);
201
- const seconds = Math.floor(us / 1_000_000);
202
- return new t.PlainDateTime(year, month, day, Math.floor(seconds / 3600), Math.floor((seconds / 60) % 60), seconds % 60, Math.floor((us % 1_000_000) / 1000), us % 1000);
203
- });
204
- setBinaryTypeParser(oids.TIMESTAMPTZ, (chunk, start) => {
205
- const pgMicros = chunk.readBigInt64BE(start);
206
- if (pgMicros === INFINITY_US || pgMicros === NEG_INFINITY_US)
207
- failTemporalInfinity("timestamptz");
208
- const instant = t.Instant.fromEpochNanoseconds((pgMicros + PG_EPOCH_US) * 1000n);
209
- if (sessionTimeZone === "UTC")
210
- return instant.toZonedDateTimeISO("UTC");
211
- // Zone by the session zone's offset at this instant, i.e. what pg's text rendering carries
212
- const zoned = instant.toZonedDateTimeISO(sessionTimeZone);
213
- const { offset } = zoned;
214
- return offset === "+00:00" ? zoned.withTimeZone("UTC") : zoned.withTimeZone(offset);
215
- });
144
+ const { Temporal: t } = requireTemporal();
145
+ setBinaryTypeParser(oids.DATE, (chunk, start) => {
146
+ const days = chunk.readInt32BE(start);
147
+ if (days === INFINITY_DAYS || days === NEG_INFINITY_DAYS) failTemporalInfinity("date");
148
+ const [year, month, day] = civilFromDays(days + PG_EPOCH_DAYS);
149
+ return new t.PlainDate(year, month, day);
150
+ });
151
+ setBinaryTypeParser(1083, (chunk, start) => {
152
+ const us = Number(chunk.readBigInt64BE(start));
153
+ const seconds = Math.floor(us / 1e6);
154
+ return new t.PlainTime(Math.floor(seconds / 3600), Math.floor(seconds / 60 % 60), seconds % 60, Math.floor(us % 1e6 / 1e3), us % 1e3);
155
+ });
156
+ setBinaryTypeParser(oids.TIMESTAMP, (chunk, start) => {
157
+ const pgMicros = chunk.readBigInt64BE(start);
158
+ if (pgMicros === INFINITY_US || pgMicros === NEG_INFINITY_US) failTemporalInfinity("timestamp");
159
+ const { days, us } = splitPgMicros(pgMicros);
160
+ const [year, month, day] = civilFromDays(days);
161
+ const seconds = Math.floor(us / 1e6);
162
+ return new t.PlainDateTime(year, month, day, Math.floor(seconds / 3600), Math.floor(seconds / 60 % 60), seconds % 60, Math.floor(us % 1e6 / 1e3), us % 1e3);
163
+ });
164
+ setBinaryTypeParser(oids.TIMESTAMPTZ, (chunk, start) => {
165
+ const pgMicros = chunk.readBigInt64BE(start);
166
+ if (pgMicros === INFINITY_US || pgMicros === NEG_INFINITY_US) failTemporalInfinity("timestamptz");
167
+ const instant = t.Instant.fromEpochNanoseconds((pgMicros + PG_EPOCH_US) * 1000n);
168
+ if (sessionTimeZone === "UTC") return instant.toZonedDateTimeISO("UTC");
169
+ const zoned = instant.toZonedDateTimeISO(sessionTimeZone);
170
+ const { offset } = zoned;
171
+ return offset === "+00:00" ? zoned.withTimeZone("UTC") : zoned.withTimeZone(offset);
172
+ });
216
173
  }
217
- // Microseconds between the Postgres epoch (2000-01-01) and the Unix epoch (1970-01-01)
218
174
  const PG_EPOCH_US = 946684800000000n;
219
- const PG_EPOCH_DAYS = 10_957;
175
+ const PG_EPOCH_DAYS = 10957;
220
176
  const US_PER_DAY = 86400000000n;
221
- // The wire sentinels for `infinity` / `-infinity` timestamps and dates
222
- const INFINITY_US = 0x7fffffffffffffffn;
223
- const NEG_INFINITY_US = -0x8000000000000000n;
224
- const INFINITY_DAYS = 0x7fffffff;
225
- const NEG_INFINITY_DAYS = -0x80000000;
226
- // pg's builtin oids, inlined to avoid importing pg here (these are protocol constants)
177
+ const INFINITY_US = 9223372036854775807n;
178
+ const NEG_INFINITY_US = -9223372036854775808n;
179
+ const INFINITY_DAYS = 2147483647;
180
+ const NEG_INFINITY_DAYS = -2147483648;
227
181
  const oids = {
228
- BOOL: 16,
229
- BYTEA: 17,
230
- INT8: 20,
231
- INT2: 21,
232
- INT4: 23,
233
- TEXT: 25,
234
- OID: 26,
235
- JSON: 114,
236
- FLOAT4: 700,
237
- FLOAT8: 701,
238
- BPCHAR: 1042,
239
- VARCHAR: 1043,
240
- DATE: 1082,
241
- TIMESTAMP: 1114,
242
- TIMESTAMPTZ: 1184,
243
- NUMERIC: 1700,
244
- UUID: 2950,
245
- JSONB: 3802,
182
+ BOOL: 16,
183
+ BYTEA: 17,
184
+ INT8: 20,
185
+ INT2: 21,
186
+ INT4: 23,
187
+ TEXT: 25,
188
+ OID: 26,
189
+ JSON: 114,
190
+ FLOAT4: 700,
191
+ FLOAT8: 701,
192
+ BPCHAR: 1042,
193
+ VARCHAR: 1043,
194
+ DATE: 1082,
195
+ TIMESTAMP: 1114,
196
+ TIMESTAMPTZ: 1184,
197
+ NUMERIC: 1700,
198
+ UUID: 2950,
199
+ JSONB: 3802
246
200
  };
247
- const parsers = new Map();
248
- // The standard scalar builtins; values match what the classic text path produces for the same
249
- // column, i.e. int8/numeric stay strings, bytea stays a Buffer (byte-exact, where classic pg's
250
- // binary handling is utf8-lossy)
201
+ const parsers = /* @__PURE__ */ new Map();
251
202
  setBinaryTypeParser(oids.BOOL, (chunk, start) => chunk[start] !== 0);
252
203
  setBinaryTypeParser(oids.INT2, (chunk, start) => chunk.readInt16BE(start));
253
204
  setBinaryTypeParser(oids.INT4, (chunk, start) => chunk.readInt32BE(start));
@@ -258,225 +209,204 @@ setBinaryTypeParser(oids.FLOAT8, (chunk, start) => chunk.readDoubleBE(start));
258
209
  setBinaryTypeParser(oids.TEXT, binaryTextParser);
259
210
  setBinaryTypeParser(oids.VARCHAR, binaryTextParser);
260
211
  setBinaryTypeParser(oids.BPCHAR, binaryTextParser);
261
- setBinaryTypeParser(19 /* name */, binaryTextParser);
212
+ setBinaryTypeParser(19, binaryTextParser);
262
213
  setBinaryTypeParser(oids.UUID, (chunk, start) => renderUuid(chunk, start));
263
214
  setBinaryTypeParser(oids.BYTEA, copyBytes);
264
215
  setBinaryTypeParser(oids.JSON, (chunk, start, length) => JSON.parse(chunk.toString("utf8", start, start + length)));
265
- // jsonb payloads have a 1-byte version prefix before the JSON text
266
216
  setBinaryTypeParser(oids.JSONB, (chunk, start, length) => JSON.parse(chunk.toString("utf8", start + 1, start + length)));
267
217
  setBinaryTypeParser(oids.NUMERIC, renderNumeric);
268
- setBinaryTypeParser(3614 /* tsvector */, renderTsVector);
269
- setBinaryTypeParser(3910 /* tstzrange */, (chunk, start) => renderRange(chunk, start, (c, s) => {
270
- // pg quotes finite bounds (they contain spaces) but renders infinity bounds bare
271
- const text = renderTimestamp(c.readBigInt64BE(s), "+00");
272
- return text === "infinity" || text === "-infinity" ? text : `"${text}"`;
218
+ setBinaryTypeParser(3614, renderTsVector);
219
+ setBinaryTypeParser(3910, (chunk, start) => renderRange(chunk, start, (c, s) => {
220
+ const text = renderTimestamp(c.readBigInt64BE(s), "+00");
221
+ return text === "infinity" || text === "-infinity" ? text : `"${text}"`;
273
222
  }));
274
- // Rendered like pg's text output, which is also what the classic text path yields (no parser)
275
- setBinaryTypeParser(1083 /* time */, (chunk, start) => renderTimeOfDay(Number(chunk.readBigInt64BE(start))));
276
- // The standard `_type` array oids; elements decode through the registry (see binaryArrayParser)
223
+ setBinaryTypeParser(1083, (chunk, start) => renderTimeOfDay(Number(chunk.readBigInt64BE(start))));
277
224
  for (const arrayOid of [
278
- 1000, // bool[]
279
- 1001, // bytea[]
280
- 1005, // int2[]
281
- 1007, // int4[]
282
- 1009, // text[]
283
- 1014, // bpchar[]
284
- 1015, // varchar[]
285
- 1016, // int8[]
286
- 1021, // float4[]
287
- 1022, // float8[]
288
- 1182, // date[]
289
- 1183, // time[]
290
- 1115, // timestamp[]
291
- 1185, // timestamptz[]
292
- 1231, // numeric[]
293
- 2951, // uuid[]
294
- 199, // json[]
295
- 3807, // jsonb[]
296
- 3643, // tsvector[]
297
- 3911, // tstzrange[]
298
- ]) {
299
- setBinaryTypeParser(arrayOid, binaryArrayParser);
300
- }
301
- // Default the date/time oids to Date-mode semantics; `setupLatestPgTypes` re-registers the
302
- // Temporal-mode parsers when the app runs with `temporal` configured
225
+ 1e3,
226
+ 1001,
227
+ 1005,
228
+ 1007,
229
+ 1009,
230
+ 1014,
231
+ 1015,
232
+ 1016,
233
+ 1021,
234
+ 1022,
235
+ 1182,
236
+ 1183,
237
+ 1115,
238
+ 1185,
239
+ 1231,
240
+ 2951,
241
+ 199,
242
+ 3807,
243
+ 3643,
244
+ 3911
245
+ ]) setBinaryTypeParser(arrayOid, binaryArrayParser);
303
246
  setBinaryTypeParser(oids.DATE, binaryDateToDate);
304
247
  setBinaryTypeParser(oids.TIMESTAMP, binaryTimestampToDate);
305
248
  setBinaryTypeParser(oids.TIMESTAMPTZ, binaryTimestamptzToDate);
306
249
  /** Splits pg timestamp µs into days-since-1970 and µs-within-day, flooring correctly pre-epoch. */
307
250
  function splitPgMicros(pgMicros) {
308
- const epochMicros = pgMicros + PG_EPOCH_US;
309
- let days = epochMicros / US_PER_DAY;
310
- let micros = epochMicros % US_PER_DAY;
311
- if (micros < 0n) {
312
- days -= 1n;
313
- micros += US_PER_DAY;
314
- }
315
- return { days: Number(days), us: Number(micros) };
251
+ const epochMicros = pgMicros + PG_EPOCH_US;
252
+ let days = epochMicros / US_PER_DAY;
253
+ let micros = epochMicros % US_PER_DAY;
254
+ if (micros < 0n) {
255
+ days -= 1n;
256
+ micros += US_PER_DAY;
257
+ }
258
+ return {
259
+ days: Number(days),
260
+ us: Number(micros)
261
+ };
316
262
  }
317
263
  /** Fails on the ±infinity wire sentinels, which have no Temporal representation. */
318
264
  function failTemporalInfinity(type) {
319
- return fail(`joist-orm: cannot represent an 'infinity' ${type} as a Temporal value`);
265
+ return fail$1(`joist-orm: cannot represent an 'infinity' ${type} as a Temporal value`);
320
266
  }
321
267
  /** Reads a float4 as its shortest round-trip decimal, matching pg's shortest text output. */
322
268
  function readFloat4(chunk, start) {
323
- const value = chunk.readFloatBE(start);
324
- if (!Number.isFinite(value))
325
- return value;
326
- // ±0 as-is: toPrecision would drop -0's sign, and === cannot tell the zeros apart
327
- if (value === 0)
328
- return value;
329
- // The raw float32 -> float64 widening (i.e. 0.1f -> 0.10000000149...) diverges from the text
330
- // path, which parses pg's shortest repr; find the shortest decimal that round-trips instead
331
- // (binary32 needs at most 9 significant decimal digits)
332
- for (let precision = 1; precision <= 9; precision++) {
333
- const shortest = Number(value.toPrecision(precision));
334
- if (Math.fround(shortest) === value)
335
- return shortest;
336
- }
337
- return value;
269
+ const value = chunk.readFloatBE(start);
270
+ if (!Number.isFinite(value)) return value;
271
+ if (value === 0) return value;
272
+ for (let precision = 1; precision <= 9; precision++) {
273
+ const shortest = Number(value.toPrecision(precision));
274
+ if (Math.fround(shortest) === value) return shortest;
275
+ }
276
+ return value;
338
277
  }
339
278
  /** Copies the exact cell bytes, i.e. for bytea values. */
340
279
  function copyBytes(chunk, start, length) {
341
- const cell = Buffer.allocUnsafe(length);
342
- chunk.copy(cell, 0, start, start + length);
343
- return cell;
280
+ const cell = Buffer.allocUnsafe(length);
281
+ chunk.copy(cell, 0, start, start + length);
282
+ return cell;
344
283
  }
345
284
  /** Renders a binary uuid (16 bytes) as the canonical dashed-hex string. */
346
285
  function renderUuid(chunk, start) {
347
- const hex = chunk.toString("hex", start, start + 16);
348
- return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20)}`;
286
+ const hex = chunk.toString("hex", start, start + 16);
287
+ return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20)}`;
349
288
  }
350
289
  /** Renders a binary numeric (base-10000 digit groups) to pg's text form, i.e. `-12.340`. */
351
290
  function renderNumeric(chunk, start) {
352
- const nDigits = chunk.readInt16BE(start);
353
- const weight = chunk.readInt16BE(start + 2);
354
- const sign = chunk.readUInt16BE(start + 4);
355
- const dscale = chunk.readUInt16BE(start + 6);
356
- if (sign === 0xc000)
357
- return "NaN";
358
- if (sign === 0xd000)
359
- return "Infinity";
360
- if (sign === 0xf000)
361
- return "-Infinity";
362
- // Integer part: digit groups from `weight` down to 0 (missing groups are zero)
363
- let integer = "";
364
- for (let w = weight, i = 0; w >= 0; w--, i++) {
365
- const group = i < nDigits ? chunk.readUInt16BE(start + 8 + i * 2) : 0;
366
- integer += integer === "" ? String(group) : String(group).padStart(4, "0");
367
- }
368
- if (integer === "")
369
- integer = "0";
370
- if (dscale === 0)
371
- return sign === 0x4000 ? `-${integer}` : integer;
372
- // Fraction part: the group at weight -k is digits[weight + k]; pad/trim to exactly `dscale` digits
373
- let fraction = "";
374
- for (let k = 1; fraction.length < dscale; k++) {
375
- const i = weight + k;
376
- const group = i >= 0 && i < nDigits ? chunk.readUInt16BE(start + 8 + i * 2) : 0;
377
- fraction += String(group).padStart(4, "0");
378
- }
379
- fraction = fraction.slice(0, dscale);
380
- return `${sign === 0x4000 ? "-" : ""}${integer}.${fraction}`;
291
+ const nDigits = chunk.readInt16BE(start);
292
+ const weight = chunk.readInt16BE(start + 2);
293
+ const sign = chunk.readUInt16BE(start + 4);
294
+ const dscale = chunk.readUInt16BE(start + 6);
295
+ if (sign === 49152) return "NaN";
296
+ if (sign === 53248) return "Infinity";
297
+ if (sign === 61440) return "-Infinity";
298
+ let integer = "";
299
+ for (let w = weight, i = 0; w >= 0; w--, i++) {
300
+ const group = i < nDigits ? chunk.readUInt16BE(start + 8 + i * 2) : 0;
301
+ integer += integer === "" ? String(group) : String(group).padStart(4, "0");
302
+ }
303
+ if (integer === "") integer = "0";
304
+ if (dscale === 0) return sign === 16384 ? `-${integer}` : integer;
305
+ let fraction = "";
306
+ for (let k = 1; fraction.length < dscale; k++) {
307
+ const i = weight + k;
308
+ const group = i >= 0 && i < nDigits ? chunk.readUInt16BE(start + 8 + i * 2) : 0;
309
+ fraction += String(group).padStart(4, "0");
310
+ }
311
+ fraction = fraction.slice(0, dscale);
312
+ return `${sign === 16384 ? "-" : ""}${integer}.${fraction}`;
381
313
  }
382
314
  /** Renders a binary tsvector (lexeme cstrings + position/weight words) to pg's text form, i.e. `'new':2A`. */
383
315
  function renderTsVector(chunk, start) {
384
- const count = chunk.readInt32BE(start);
385
- let pos = start + 4;
386
- const lexemes = [];
387
- for (let i = 0; i < count; i++) {
388
- const end = chunk.indexOf(0, pos);
389
- // pg's output doubles both backslashes and quotes inside lexemes
390
- const word = chunk.toString("utf8", pos, end).replace(/\\/g, "\\\\").replace(/'/g, "''");
391
- pos = end + 1;
392
- const nPositions = chunk.readUInt16BE(pos);
393
- pos += 2;
394
- const positions = [];
395
- for (let p = 0; p < nPositions; p++) {
396
- // Each word entry packs the weight in the top 2 bits (3=A, 2=B, 1=C, 0=D/default)
397
- const entry = chunk.readUInt16BE(pos);
398
- pos += 2;
399
- positions.push(`${entry & 0x3fff}${weightSuffixes[entry >> 14]}`);
400
- }
401
- lexemes.push(positions.length > 0 ? `'${word}':${positions.join(",")}` : `'${word}'`);
402
- }
403
- return lexemes.join(" ");
316
+ const count = chunk.readInt32BE(start);
317
+ let pos = start + 4;
318
+ const lexemes = [];
319
+ for (let i = 0; i < count; i++) {
320
+ const end = chunk.indexOf(0, pos);
321
+ const word = chunk.toString("utf8", pos, end).replace(/\\/g, "\\\\").replace(/'/g, "''");
322
+ pos = end + 1;
323
+ const nPositions = chunk.readUInt16BE(pos);
324
+ pos += 2;
325
+ const positions = [];
326
+ for (let p = 0; p < nPositions; p++) {
327
+ const entry = chunk.readUInt16BE(pos);
328
+ pos += 2;
329
+ positions.push(`${entry & 16383}${weightSuffixes[entry >> 14]}`);
330
+ }
331
+ lexemes.push(positions.length > 0 ? `'${word}':${positions.join(",")}` : `'${word}'`);
332
+ }
333
+ return lexemes.join(" ");
404
334
  }
405
- const weightSuffixes = ["", "C", "B", "A"];
335
+ const weightSuffixes = [
336
+ "",
337
+ "C",
338
+ "B",
339
+ "A"
340
+ ];
406
341
  /** Renders a binary range (flags byte + length-prefixed bounds) to pg's text form, i.e. `["a","b")`. */
407
342
  function renderRange(chunk, start, bound) {
408
- const flags = chunk[start];
409
- if (flags & 0x01)
410
- return "empty";
411
- let pos = start + 1;
412
- let lower = "";
413
- let upper = "";
414
- if (!(flags & 0x08)) {
415
- const len = chunk.readInt32BE(pos);
416
- lower = bound(chunk, pos + 4);
417
- pos += 4 + len;
418
- }
419
- if (!(flags & 0x10)) {
420
- upper = bound(chunk, pos + 4);
421
- }
422
- return `${flags & 0x02 ? "[" : "("}${lower},${upper}${flags & 0x04 ? "]" : ")"}`;
423
- }
424
- /** Renders days-since-1970 as pg's date text, i.e. `2020-01-02` or `0001-01-01 BC`. */
425
- function renderDate(epochDays) {
426
- const { text, bc } = renderDatePart(epochDays);
427
- return bc ? `${text} BC` : text;
343
+ const flags = chunk[start];
344
+ if (flags & 1) return "empty";
345
+ let pos = start + 1;
346
+ let lower = "";
347
+ let upper = "";
348
+ if (!(flags & 8)) {
349
+ const len = chunk.readInt32BE(pos);
350
+ lower = bound(chunk, pos + 4);
351
+ pos += 4 + len;
352
+ }
353
+ if (!(flags & 16)) upper = bound(chunk, pos + 4);
354
+ return `${flags & 2 ? "[" : "("}${lower},${upper}${flags & 4 ? "]" : ")"}`;
428
355
  }
429
356
  /**
430
- * Renders the `YYYY-MM-DD` part, converting astronomical years to pg's BC numbering
431
- * (astronomical year 0 = `0001 BC`); timestamps append the ` BC` marker after the time/zone.
432
- */
357
+ * Renders the `YYYY-MM-DD` part, converting astronomical years to pg's BC numbering
358
+ * (astronomical year 0 = `0001 BC`); timestamps append the ` BC` marker after the time/zone.
359
+ */
433
360
  function renderDatePart(epochDays) {
434
- const [year, month, day] = civilFromDays(epochDays);
435
- const bc = year <= 0;
436
- const displayYear = bc ? 1 - year : year;
437
- return {
438
- text: `${String(displayYear).padStart(4, "0")}-${String(month).padStart(2, "0")}-${String(day).padStart(2, "0")}`,
439
- bc,
440
- };
361
+ const [year, month, day] = civilFromDays(epochDays);
362
+ const bc = year <= 0;
363
+ const displayYear = bc ? 1 - year : year;
364
+ return {
365
+ text: `${String(displayYear).padStart(4, "0")}-${String(month).padStart(2, "0")}-${String(day).padStart(2, "0")}`,
366
+ bc
367
+ };
441
368
  }
442
369
  /** Renders a binary timestamp (µs since 2000-01-01) to pg's text form, i.e. `2020-01-02 03:04:05.678+00`. */
443
370
  function renderTimestamp(pgMicros, suffix) {
444
- if (pgMicros === INFINITY_US)
445
- return "infinity";
446
- if (pgMicros === NEG_INFINITY_US)
447
- return "-infinity";
448
- const { days, us } = splitPgMicros(pgMicros);
449
- const { text: date, bc } = renderDatePart(days);
450
- return `${date} ${renderTimeOfDay(us)}${suffix}${bc ? " BC" : ""}`;
371
+ if (pgMicros === INFINITY_US) return "infinity";
372
+ if (pgMicros === NEG_INFINITY_US) return "-infinity";
373
+ const { days, us } = splitPgMicros(pgMicros);
374
+ const { text: date, bc } = renderDatePart(days);
375
+ return `${date} ${renderTimeOfDay(us)}${suffix}${bc ? " BC" : ""}`;
451
376
  }
452
377
  /** Renders µs-since-midnight to pg's time text, i.e. `03:04:05.678` with trailing zeros trimmed. */
453
378
  function renderTimeOfDay(us) {
454
- const seconds = Math.floor(us / 1_000_000);
455
- const hh = String(Math.floor(seconds / 3600)).padStart(2, "0");
456
- const mm = String(Math.floor((seconds / 60) % 60)).padStart(2, "0");
457
- const ss = String(seconds % 60).padStart(2, "0");
458
- // pg renders up to 6 fractional digits with trailing zeros trimmed, and no "." when zero
459
- let fraction = "";
460
- const usPart = us % 1_000_000;
461
- if (usPart > 0)
462
- fraction = `.${String(usPart).padStart(6, "0")}`.replace(/0+$/, "");
463
- return `${hh}:${mm}:${ss}${fraction}`;
379
+ const seconds = Math.floor(us / 1e6);
380
+ const hh = String(Math.floor(seconds / 3600)).padStart(2, "0");
381
+ const mm = String(Math.floor(seconds / 60 % 60)).padStart(2, "0");
382
+ const ss = String(seconds % 60).padStart(2, "0");
383
+ let fraction = "";
384
+ const usPart = us % 1e6;
385
+ if (usPart > 0) fraction = `.${String(usPart).padStart(6, "0")}`.replace(/0+$/, "");
386
+ return `${hh}:${mm}:${ss}${fraction}`;
464
387
  }
465
388
  /** Converts days-since-1970 to a civil [year, month, day], i.e. Howard Hinnant's algorithm. */
466
389
  function civilFromDays(epochDays) {
467
- const z = epochDays + 719_468;
468
- const era = Math.floor(z / 146_097);
469
- const doe = z - era * 146_097;
470
- const yoe = Math.floor((doe - Math.floor(doe / 1460) + Math.floor(doe / 36524) - Math.floor(doe / 146096)) / 365);
471
- const y = yoe + era * 400;
472
- const doy = doe - (365 * yoe + Math.floor(yoe / 4) - Math.floor(yoe / 100));
473
- const mp = Math.floor((5 * doy + 2) / 153);
474
- const d = doy - Math.floor((153 * mp + 2) / 5) + 1;
475
- const m = mp < 10 ? mp + 3 : mp - 9;
476
- return [m <= 2 ? y + 1 : y, m, d];
390
+ const z = epochDays + 719468;
391
+ const era = Math.floor(z / 146097);
392
+ const doe = z - era * 146097;
393
+ const yoe = Math.floor((doe - Math.floor(doe / 1460) + Math.floor(doe / 36524) - Math.floor(doe / 146096)) / 365);
394
+ const y = yoe + era * 400;
395
+ const doy = doe - (365 * yoe + Math.floor(yoe / 4) - Math.floor(yoe / 100));
396
+ const mp = Math.floor((5 * doy + 2) / 153);
397
+ const d = doy - Math.floor((153 * mp + 2) / 5) + 1;
398
+ const m = mp < 10 ? mp + 3 : mp - 9;
399
+ return [
400
+ m <= 2 ? y + 1 : y,
401
+ m,
402
+ d
403
+ ];
477
404
  }
478
405
  /** Throws an `Error` with `message`. */
479
- function fail(message) {
480
- throw new Error(message);
406
+ function fail$1(message) {
407
+ throw new Error(message);
481
408
  }
409
+ //#endregion
410
+ export { binaryArrayParser, binaryDateToDate, binaryTextParser, binaryTimestampToDate, binaryTimestamptzToDate, getBinaryTypeParser, registerDatabaseBinaryParsers, registerTemporalBinaryParsers, setBinaryTypeParser, setSessionTimeZone };
411
+
482
412
  //# sourceMappingURL=binaryParsers.js.map