postgrejs 3.8.0 → 3.10.0

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 (67) hide show
  1. package/CHANGELOG.md +59 -1
  2. package/README.md +50 -0
  3. package/connection/connection.d.ts +14 -2
  4. package/connection/connection.js +63 -11
  5. package/connection/intl-connection.d.ts +164 -6
  6. package/connection/intl-connection.js +558 -37
  7. package/connection/pool.d.ts +30 -6
  8. package/connection/pool.js +22 -3
  9. package/connection/prepared-statement.js +22 -2
  10. package/data-type-map.d.ts +16 -0
  11. package/data-type-map.js +56 -12
  12. package/data-types/circle-type.js +5 -2
  13. package/data-types/classes/geometric.d.ts +49 -7
  14. package/data-types/classes/geometric.js +59 -11
  15. package/data-types/classes/interval.d.ts +40 -16
  16. package/data-types/classes/interval.js +68 -40
  17. package/data-types/classes/numeric.d.ts +6 -0
  18. package/data-types/classes/numeric.js +8 -0
  19. package/data-types/classes/range.d.ts +6 -1
  20. package/data-types/classes/range.js +6 -1
  21. package/data-types/date-type.js +2 -2
  22. package/data-types/interval-type.js +1 -1
  23. package/data-types/money-type.d.ts +38 -0
  24. package/data-types/money-type.js +212 -0
  25. package/data-types/numeric-type.d.ts +2 -0
  26. package/data-types/numeric-type.js +22 -11
  27. package/data-types/temporal-types.d.ts +19 -0
  28. package/data-types/temporal-types.js +520 -0
  29. package/data-types/timestamp-type.js +2 -2
  30. package/data-types/timestamptz-type.js +2 -2
  31. package/index.d.ts +3 -0
  32. package/index.js +3 -0
  33. package/interfaces/data-mapping-options.d.ts +126 -4
  34. package/interfaces/database-connection-params.d.ts +32 -5
  35. package/interfaces/query-options.d.ts +32 -0
  36. package/interfaces/script-execute-options.d.ts +32 -0
  37. package/interfaces/transaction-options.d.ts +27 -0
  38. package/interfaces/transaction-options.js +1 -0
  39. package/package.json +1 -1
  40. package/protocol/database-error.d.ts +15 -0
  41. package/protocol/database-error.js +19 -0
  42. package/protocol/frontend.js +1 -1
  43. package/protocol/pg-socket.js +7 -10
  44. package/util/array-leaf.d.ts +10 -0
  45. package/util/array-leaf.js +22 -0
  46. package/util/connection-config.js +11 -1
  47. package/util/date-style.d.ts +47 -0
  48. package/util/date-style.js +123 -0
  49. package/util/decimal-as-string.d.ts +11 -0
  50. package/util/decimal-as-string.js +30 -0
  51. package/util/fetch-as-string.d.ts +33 -0
  52. package/util/fetch-as-string.js +122 -0
  53. package/util/get-parsers.js +18 -1
  54. package/util/parse-datetime.d.ts +4 -3
  55. package/util/parse-datetime.js +34 -9
  56. package/util/resolve-column-formats.d.ts +5 -11
  57. package/util/resolve-column-formats.js +28 -24
  58. package/util/row-decoder.d.ts +24 -4
  59. package/util/row-decoder.js +25 -10
  60. package/util/sql-tag.js +2 -1
  61. package/util/stringify-for-sql.js +6 -5
  62. package/util/temporal.d.ts +47 -0
  63. package/util/temporal.js +61 -0
  64. package/util/transaction-command.d.ts +7 -0
  65. package/util/transaction-command.js +32 -0
  66. package/util/unspecified-param.d.ts +18 -8
  67. package/util/unspecified-param.js +22 -14
@@ -0,0 +1,61 @@
1
+ /**
2
+ * Reaching the `Temporal` the application provides, without depending on
3
+ * one.
4
+ *
5
+ * No runtime ships Temporal yet - Node 24.15 and Bun 1.3.10 both answer
6
+ * `undefined`, with or without `--harmony` - so today every caller that
7
+ * turns `temporalTypes` on has installed a polyfill. That is why this is
8
+ * read off `globalThis` when it is needed rather than imported: this
9
+ * package takes no dependency, a polyfill loaded after this module is
10
+ * still seen, and the day a runtime ships Temporal nothing here changes.
11
+ */
12
+ let _systemTimeZone;
13
+ const _knownZones = new Set();
14
+ /**
15
+ * The runtime's `Temporal`, or an error saying how to get one.
16
+ *
17
+ * Called when a type map is built - which for a connection is while it
18
+ * is being constructed - so a missing Temporal is reported before any
19
+ * I/O rather than in the middle of decoding a row.
20
+ */
21
+ export function getTemporal() {
22
+ const t = globalThis.Temporal;
23
+ if (!t || !t.ZonedDateTime)
24
+ throw new Error('Temporal is not available in this runtime. postgrejs reads ' +
25
+ 'globalThis.Temporal and takes no dependency of its own: install ' +
26
+ '`temporal-polyfill` and import it before connecting, or leave ' +
27
+ '`temporalTypes` off.');
28
+ return t;
29
+ }
30
+ /**
31
+ * The zone a `timestamptz` is printed in when the caller named none.
32
+ *
33
+ * Only the printing: a timestamptz is an absolute instant and arrives as
34
+ * one, so the zone decides what wall clock the ZonedDateTime shows and
35
+ * nothing about which moment it is.
36
+ */
37
+ export function systemTimeZone() {
38
+ if (_systemTimeZone === undefined)
39
+ _systemTimeZone = Intl.DateTimeFormat().resolvedOptions().timeZone;
40
+ return _systemTimeZone;
41
+ }
42
+ /**
43
+ * Checks a zone name before it is handed to Temporal, so the complaint
44
+ * names the setting it came from instead of surfacing from inside a
45
+ * decode. `Intl` accepts exactly what Temporal does and is here whether
46
+ * Temporal is or not.
47
+ */
48
+ export function requireTimeZone(zone, where) {
49
+ if (_knownZones.has(zone))
50
+ return zone;
51
+ try {
52
+ new Intl.DateTimeFormat('en-US', { timeZone: zone });
53
+ }
54
+ catch {
55
+ throw new Error(`"${zone}" (${where}) is not a time zone this runtime knows, so a ` +
56
+ 'timestamptz cannot be given one. Pass `timeZone` in the mapping ' +
57
+ 'options to name one yourself.');
58
+ }
59
+ _knownZones.add(zone);
60
+ return zone;
61
+ }
@@ -0,0 +1,7 @@
1
+ /** Whether `sql` opens or closes a transaction. */
2
+ export declare function isTransactionCommand(sql: string): boolean;
3
+ /**
4
+ * Whether `sql` must not run inside a savepoint - it is a transaction
5
+ * command, or it configures the transaction.
6
+ */
7
+ export declare function refusesSavepoint(sql: string): boolean;
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Statements that open or close a transaction, and so manage their own
3
+ * boundaries: an implicit BEGIN or COMMIT around one would be wrong, and
4
+ * wrapping one in a savepoint - COMMIT, say - is nonsense.
5
+ */
6
+ const TRANSACTION_COMMAND_PATTERN = /^(\bBEGIN\b|\bCOMMIT\b|\bSTART\b|\bROLLBACK|SAVEPOINT|RELEASE\b)/i;
7
+ /**
8
+ * `SET TRANSACTION`, which configures the transaction it runs in rather
9
+ * than opening or closing one.
10
+ *
11
+ * It needs an answer of its own because the two are not the same
12
+ * question. PostgreSQL refuses two of its forms inside a subtransaction
13
+ * - `SET TRANSACTION ISOLATION LEVEL` and `SET TRANSACTION [NOT]
14
+ * DEFERRABLE`, both 25001 - so the savepoint `rollbackOnError` puts
15
+ * around every statement in a transaction made them impossible to run
16
+ * at all. But the implicit BEGIN that `autoCommit: false` adds is
17
+ * exactly what they need, so answering "transaction command" for them
18
+ * and suppressing both would trade one failure for another.
19
+ */
20
+ const CONFIGURES_TRANSACTION_PATTERN = /^\bSET\s+TRANSACTION\b/i;
21
+ /** Whether `sql` opens or closes a transaction. */
22
+ export function isTransactionCommand(sql) {
23
+ return TRANSACTION_COMMAND_PATTERN.test(sql);
24
+ }
25
+ /**
26
+ * Whether `sql` must not run inside a savepoint - it is a transaction
27
+ * command, or it configures the transaction.
28
+ */
29
+ export function refusesSavepoint(sql) {
30
+ return (TRANSACTION_COMMAND_PATTERN.test(sql) ||
31
+ CONFIGURES_TRANSACTION_PATTERN.test(sql));
32
+ }
@@ -1,8 +1,3 @@
1
- /**
2
- * The first value inside `v` that is not itself an array - what an array
3
- * parameter's element type would be read from. A scalar answers itself.
4
- */
5
- export declare function arrayLeaf(v: any): any;
6
1
  /**
7
2
  * Whether a parameter goes out with no declared type (OID 0), as text,
8
3
  * for the server to resolve from wherever it lands.
@@ -25,8 +20,23 @@ export declare function arrayLeaf(v: any): any;
25
20
  * as it does under `pg`. A cast (`$1::text`) or a named type
26
21
  * (`new BindParam(DataTypeOIDs.varchar, v)`) says which type is meant.
27
22
  *
28
- * Numbers, booleans and Buffers keep their declared types: they are
29
- * already right nearly everywhere, and sending them as text would give
30
- * up the binary encoding for no correctness gain.
23
+ * - An array of numbers is the same question, and the answer matters
24
+ * more: `[1, 2]` is `int2[]`, `int4[]`, `int8[]`, `numeric[]`,
25
+ * `float4[]` or `float8[]` depending on where it lands, and unlike
26
+ * their scalars those types have no operators or implicit casts
27
+ * between them. A declared `int4[]` is therefore not merely a guess
28
+ * but a wrong answer wherever the column is one of the other five:
29
+ * `array[1,2]::int8[] = $1` is `42883 operator does not exist:
30
+ * bigint[] = integer[]`, and `numeric[] = double precision[]` the
31
+ * same. The scalars are left declared because they do have those
32
+ * operators - `1::int8 = $1` and `1.5::numeric = $1` both resolve.
33
+ *
34
+ * A scalar number, a boolean, a Buffer, and an array of anything but
35
+ * numbers keep their declared types: an array of booleans, of Buffers
36
+ * or of one of this client's own classes has one type it can be, so
37
+ * naming it says nothing the server would have decided differently -
38
+ * and it keeps the binary encoding, which the text literal gives up.
39
+ * A caller who wants that back for a large numeric array names the type
40
+ * with `new BindParam(DataTypeOIDs._float8, v)`.
31
41
  */
32
42
  export declare function isUnspecifiedParam(v: any): boolean;
@@ -1,13 +1,4 @@
1
- /**
2
- * The first value inside `v` that is not itself an array - what an array
3
- * parameter's element type would be read from. A scalar answers itself.
4
- */
5
- export function arrayLeaf(v) {
6
- let x = v;
7
- while (Array.isArray(x))
8
- x = x[0];
9
- return x;
10
- }
1
+ import { arrayLeaf } from './array-leaf.js';
11
2
  /**
12
3
  * Whether a parameter goes out with no declared type (OID 0), as text,
13
4
  * for the server to resolve from wherever it lands.
@@ -30,11 +21,28 @@ export function arrayLeaf(v) {
30
21
  * as it does under `pg`. A cast (`$1::text`) or a named type
31
22
  * (`new BindParam(DataTypeOIDs.varchar, v)`) says which type is meant.
32
23
  *
33
- * Numbers, booleans and Buffers keep their declared types: they are
34
- * already right nearly everywhere, and sending them as text would give
35
- * up the binary encoding for no correctness gain.
24
+ * - An array of numbers is the same question, and the answer matters
25
+ * more: `[1, 2]` is `int2[]`, `int4[]`, `int8[]`, `numeric[]`,
26
+ * `float4[]` or `float8[]` depending on where it lands, and unlike
27
+ * their scalars those types have no operators or implicit casts
28
+ * between them. A declared `int4[]` is therefore not merely a guess
29
+ * but a wrong answer wherever the column is one of the other five:
30
+ * `array[1,2]::int8[] = $1` is `42883 operator does not exist:
31
+ * bigint[] = integer[]`, and `numeric[] = double precision[]` the
32
+ * same. The scalars are left declared because they do have those
33
+ * operators - `1::int8 = $1` and `1.5::numeric = $1` both resolve.
34
+ *
35
+ * A scalar number, a boolean, a Buffer, and an array of anything but
36
+ * numbers keep their declared types: an array of booleans, of Buffers
37
+ * or of one of this client's own classes has one type it can be, so
38
+ * naming it says nothing the server would have decided differently -
39
+ * and it keeps the binary encoding, which the text literal gives up.
40
+ * A caller who wants that back for a large numeric array names the type
41
+ * with `new BindParam(DataTypeOIDs._float8, v)`.
36
42
  */
37
43
  export function isUnspecifiedParam(v) {
38
44
  const x = arrayLeaf(v);
39
- return typeof x === 'string' || x instanceof Date;
45
+ if (typeof x === 'string' || x instanceof Date)
46
+ return true;
47
+ return Array.isArray(v) && (typeof x === 'number' || typeof x === 'bigint');
40
48
  }