@owlmeans/postgres-resource 0.1.18-rc.40 → 0.1.18-rc.42

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 (89) hide show
  1. package/README.md +2 -2
  2. package/agent-meta/manifest.json +2 -2
  3. package/agent-meta/skills/postgres-resource/SKILL.md +2 -2
  4. package/build/declarations.d.ts +1 -8
  5. package/build/declarations.d.ts.map +1 -1
  6. package/build/declarations.js.map +1 -1
  7. package/build/errors.d.ts +3 -1
  8. package/build/errors.d.ts.map +1 -1
  9. package/build/errors.js +4 -2
  10. package/build/errors.js.map +1 -1
  11. package/build/resource.d.ts +1 -1
  12. package/build/resource.d.ts.map +1 -1
  13. package/build/resource.js.map +1 -1
  14. package/build/types.d.ts +6 -1
  15. package/build/types.d.ts.map +1 -1
  16. package/build/types.local.d.ts +14 -0
  17. package/build/types.local.d.ts.map +1 -0
  18. package/build/types.local.js +2 -0
  19. package/build/types.local.js.map +1 -0
  20. package/build/utils/consts.local.d.ts +33 -0
  21. package/build/utils/consts.local.d.ts.map +1 -0
  22. package/build/utils/consts.local.js +61 -0
  23. package/build/utils/consts.local.js.map +1 -0
  24. package/build/utils/criteria.d.ts +2 -2
  25. package/build/utils/criteria.d.ts.map +1 -1
  26. package/build/utils/criteria.js +2 -3
  27. package/build/utils/criteria.js.map +1 -1
  28. package/build/utils/diff.d.ts.map +1 -1
  29. package/build/utils/diff.js +5 -3
  30. package/build/utils/diff.js.map +1 -1
  31. package/build/utils/index.d.ts +1 -0
  32. package/build/utils/index.d.ts.map +1 -1
  33. package/build/utils/index.js.map +1 -1
  34. package/build/utils/introspect.d.ts.map +1 -1
  35. package/build/utils/introspect.js +1 -29
  36. package/build/utils/introspect.js.map +1 -1
  37. package/build/utils/life-cycle.d.ts +3 -8
  38. package/build/utils/life-cycle.d.ts.map +1 -1
  39. package/build/utils/life-cycle.js +5 -2
  40. package/build/utils/life-cycle.js.map +1 -1
  41. package/build/utils/marshal.d.ts.map +1 -1
  42. package/build/utils/marshal.js +11 -5
  43. package/build/utils/marshal.js.map +1 -1
  44. package/build/utils/migrations.d.ts.map +1 -1
  45. package/build/utils/migrations.js +9 -6
  46. package/build/utils/migrations.js.map +1 -1
  47. package/build/utils/name.d.ts.map +1 -1
  48. package/build/utils/name.js +2 -2
  49. package/build/utils/name.js.map +1 -1
  50. package/build/utils/schema.d.ts.map +1 -1
  51. package/build/utils/schema.js +6 -4
  52. package/build/utils/schema.js.map +1 -1
  53. package/build/utils/sql.d.ts +1 -9
  54. package/build/utils/sql.d.ts.map +1 -1
  55. package/build/utils/sql.js +0 -0
  56. package/build/utils/sql.js.map +1 -1
  57. package/build/utils/sync.d.ts.map +1 -1
  58. package/build/utils/sync.js +6 -16
  59. package/build/utils/sync.js.map +1 -1
  60. package/build/utils/types.d.ts +18 -0
  61. package/build/utils/types.d.ts.map +1 -0
  62. package/build/utils/types.js +2 -0
  63. package/build/utils/types.js.map +1 -0
  64. package/build/utils/types.local.d.ts +33 -0
  65. package/build/utils/types.local.d.ts.map +1 -0
  66. package/build/utils/types.local.js +2 -0
  67. package/build/utils/types.local.js.map +1 -0
  68. package/package.json +14 -13
  69. package/src/declarations.ts +1 -9
  70. package/src/errors.ts +5 -13
  71. package/src/resource.ts +3 -11
  72. package/src/types.local.ts +16 -0
  73. package/src/types.ts +7 -4
  74. package/src/utils/consts.local.ts +68 -0
  75. package/src/utils/criteria.ts +4 -19
  76. package/src/utils/diff.ts +5 -4
  77. package/src/utils/index.ts +1 -0
  78. package/src/utils/introspect.ts +1 -32
  79. package/src/utils/life-cycle.ts +8 -15
  80. package/src/utils/marshal.ts +12 -7
  81. package/src/utils/migrations.ts +9 -6
  82. package/src/utils/name.ts +2 -3
  83. package/src/utils/schema.ts +8 -32
  84. package/src/utils/sql.ts +0 -0
  85. package/src/utils/sync.ts +6 -18
  86. package/src/utils/types.local.ts +35 -0
  87. package/src/utils/types.ts +19 -0
  88. package/tests/diff.spec.ts +24 -0
  89. package/tests/errors.spec.ts +11 -0
@@ -1 +1 @@
1
- {"version":3,"file":"sync.js","sourceRoot":"","sources":["../../src/utils/sync.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"sync.js","sourceRoot":"","sources":["../../src/utils/sync.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ import type { PgRuntimeTable, TableSpec } from '../types.js';
2
+ import type { MigrationReport } from '@owlmeans/resource';
3
+ import type { BasicContext } from '@owlmeans/context';
4
+ export interface TableInit {
5
+ spec: TableSpec;
6
+ /** The Drizzle table CRUD is built against. */
7
+ entity: PgRuntimeTable;
8
+ reports: MigrationReport[];
9
+ }
10
+ /**
11
+ * The context a placeholder resolves through.
12
+ *
13
+ * Resolution reads exactly one thing — `context.resource(alias).table` — so the config a context
14
+ * carries is irrelevant here, and pinning one would force every caller holding a server context
15
+ * to cast its way in. Deliberately open, and named so callers pass what they already have.
16
+ */
17
+ export type PlaceholderContext = BasicContext<any>;
18
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/utils/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,aAAa,CAAA;AAC5D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAA;AACzD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAErD,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,SAAS,CAAA;IACf,+CAA+C;IAC/C,MAAM,EAAE,cAAc,CAAA;IACtB,OAAO,EAAE,eAAe,EAAE,CAAA;CAC3B;AAED;;;;;;GAMG;AACH,MAAM,MAAM,kBAAkB,GAAG,YAAY,CAAC,GAAG,CAAC,CAAA"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/utils/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,33 @@
1
+ import type { SQL } from 'drizzle-orm';
2
+ import { PG_KEYWORD } from '../consts.js';
3
+ import type { PgPropertyOverride, PgRootOverride } from '../types.js';
4
+ /**
5
+ * A value at a path, as the jsonb it is (`#>`) and as text (`#>>`). The path is ONE bound `text[]`
6
+ * parameter, so a segment holding a comma or a brace stays one segment.
7
+ */
8
+ export interface PathTarget {
9
+ value: SQL;
10
+ text: SQL;
11
+ /** Absent, or a JSON `null` — what every other store reads as "no value". */
12
+ missing: SQL;
13
+ }
14
+ export interface RawProperty {
15
+ type?: string | string[];
16
+ format?: string;
17
+ enum?: unknown[];
18
+ items?: RawProperty;
19
+ maxLength?: number;
20
+ maximum?: number;
21
+ minimum?: number;
22
+ default?: unknown;
23
+ nullable?: boolean;
24
+ secure?: boolean;
25
+ [PG_KEYWORD]?: PgPropertyOverride;
26
+ }
27
+ export interface RawSchema {
28
+ properties?: Record<string, RawProperty>;
29
+ required?: string[];
30
+ allOf?: RawSchema[];
31
+ [PG_KEYWORD]?: PgRootOverride;
32
+ }
33
+ //# sourceMappingURL=types.local.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.local.d.ts","sourceRoot":"","sources":["../../src/utils/types.local.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,aAAa,CAAA;AACtC,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAA;AACzC,OAAO,KAAK,EAAE,kBAAkB,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;AAErE;;;GAGG;AACH,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,GAAG,CAAA;IACV,IAAI,EAAE,GAAG,CAAA;IACT,6EAA6E;IAC7E,OAAO,EAAE,GAAG,CAAA;CACb;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAA;IACxB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,IAAI,CAAC,EAAE,OAAO,EAAE,CAAA;IAChB,KAAK,CAAC,EAAE,WAAW,CAAA;IACnB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB,CAAC,UAAU,CAAC,CAAC,EAAE,kBAAkB,CAAA;CAClC;AAED,MAAM,WAAW,SAAS;IACxB,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAA;IACxC,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAA;IACnB,KAAK,CAAC,EAAE,SAAS,EAAE,CAAA;IACnB,CAAC,UAAU,CAAC,CAAC,EAAE,cAAc,CAAA;CAC9B"}
@@ -0,0 +1,2 @@
1
+ import { PG_KEYWORD } from '../consts.js';
2
+ //# sourceMappingURL=types.local.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.local.js","sourceRoot":"","sources":["../../src/utils/types.local.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAA"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@owlmeans/postgres-resource",
3
- "version": "0.1.18-rc.40",
3
+ "version": "0.1.18-rc.42",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "scripts": {
@@ -26,22 +26,23 @@
26
26
  "pg": "*"
27
27
  },
28
28
  "dependencies": {
29
- "@noble/hashes": "^1.5.0",
30
- "@owlmeans/basic-ids": "^0.1.18-rc.34",
31
- "@owlmeans/context": "^0.1.18-rc.32",
32
- "@owlmeans/resource": "^0.1.18-rc.37",
33
- "@owlmeans/server-context": "^0.1.18-rc.40",
34
- "@scure/base": "^2.3.0",
35
- "drizzle-orm": "~0.45.2"
29
+ "@noble/hashes": "^2.4.0",
30
+ "@owlmeans/basic-ids": "^0.1.18-rc.36",
31
+ "@owlmeans/context": "^0.1.18-rc.33",
32
+ "@owlmeans/log": "^0.1.18-rc.1",
33
+ "@owlmeans/resource": "^0.1.18-rc.39",
34
+ "@owlmeans/server-context": "^0.1.18-rc.42",
35
+ "@scure/base": "^2.4.0",
36
+ "drizzle-orm": "~0.45.3"
36
37
  },
37
38
  "devDependencies": {
38
39
  "@owlmeans/dep-config": "workspace:*",
39
- "@owlmeans/test-integration": "^0.1.18-rc.30",
40
- "@types/bun": "^1.4.0",
41
- "@types/node": "^26.1.0",
42
- "@types/pg": "^8.20.4",
40
+ "@owlmeans/test-integration": "^0.1.18-rc.32",
41
+ "@types/bun": "^1.4.2",
42
+ "@types/node": "^26.6.4",
43
+ "@types/pg": "^8.23.1",
43
44
  "nodemon": "^3.1.14",
44
- "pg": "^8.22.0",
45
+ "pg": "^8.23.1",
45
46
  "typescript": "^7.0.2"
46
47
  },
47
48
  "publishConfig": {
@@ -1,14 +1,6 @@
1
1
  import { createMigrationRegistry } from '@owlmeans/resource'
2
- import type { MigrationRegistry } from '@owlmeans/resource'
3
- import type { AnySchema } from 'ajv'
4
2
 
5
- import type { PgIndexSpec, PostgresTx } from './types.js'
6
-
7
- export interface PostgresDeclaration {
8
- schema?: AnySchema
9
- indexes: PgIndexSpec[]
10
- migrations: MigrationRegistry<PostgresTx>
11
- }
3
+ import type { PostgresTx, PostgresDeclaration } from './types.js'
12
4
 
13
5
  /**
14
6
  * Per-alias declaration store, held at module scope rather than on the resource object.
package/src/errors.ts CHANGED
@@ -4,6 +4,7 @@ import {
4
4
  } from '@owlmeans/resource'
5
5
 
6
6
  import { PgErrorCode } from './consts.js'
7
+ import type { PgDriverError } from './types.local.js'
7
8
 
8
9
  export class PostgresError extends ResourceError {
9
10
  public static override typeName = `${ResourceError.typeName}PostgresError`
@@ -106,17 +107,6 @@ export class PostgresBootstrapError extends PostgresError {
106
107
  }
107
108
  }
108
109
 
109
- interface PgDriverError {
110
- code?: string
111
- detail?: string
112
- hint?: string
113
- severity?: string
114
- constraint?: string
115
- table?: string
116
- column?: string
117
- message?: string
118
- }
119
-
120
110
  const isDriverError = (error: unknown): error is PgDriverError =>
121
111
  error != null && typeof error === 'object' && 'code' in error
122
112
 
@@ -183,8 +173,10 @@ const describe = (error: PgDriverError): string => {
183
173
  * Translate a raw `pg` driver error into the framework's error vocabulary, so a driver
184
174
  * type never escapes the package. Errors that already are `ResilientError`s pass through
185
175
  * untouched — the reconciler and the migration runner raise their own.
176
+ * A migration may supply its resolved SQL; placeholders stay intact and parameter values
177
+ * are never added. The statement travels in the message so error marshalling preserves it.
186
178
  */
187
- export const pgErrorToResourceError = (error: unknown): Error => {
179
+ export const pgErrorToResourceError = (error: unknown, query?: string): Error => {
188
180
  if (error instanceof ResilientError) {
189
181
  return error
190
182
  }
@@ -193,7 +185,7 @@ export const pgErrorToResourceError = (error: unknown): Error => {
193
185
  return error instanceof Error ? error : new PostgresError(`${error}`)
194
186
  }
195
187
 
196
- const message = describe(driver)
188
+ const message = describe(driver) + (query == null ? '' : `\nSQL: ${query}`)
197
189
  const produce = (): Error => {
198
190
  switch (driver.code) {
199
191
  case PgErrorCode.UniqueViolation:
package/src/resource.ts CHANGED
@@ -1,14 +1,7 @@
1
1
  import { appendContextual, assertContext } from '@owlmeans/context'
2
- import {
3
- MisshapedRecord, RecordExists, RecordUpdateFailed, UnknownRecordError, UnsupportedArgumentError
4
- } from '@owlmeans/resource'
5
- import type {
6
- Criteria, FirstOptions, ListOptions, ListResult, MigrationStage, ResourceRecord, WriteOptions
7
- } from '@owlmeans/resource'
8
- import type { ServerConfig, ServerContext } from '@owlmeans/server-context'
2
+ import { MisshapedRecord, RecordExists, RecordUpdateFailed, UnknownRecordError, UnsupportedArgumentError, type Criteria, type FirstOptions, type ListOptions, type ListResult, type MigrationStage, type ResourceRecord, type WriteOptions } from '@owlmeans/resource'
9
3
  import type { AnySchema, JSONSchemaType } from 'ajv'
10
- import { eq, sql } from 'drizzle-orm'
11
- import type { SQL } from 'drizzle-orm'
4
+ import { eq, sql, type SQL } from 'drizzle-orm'
12
5
  import type { PoolClient, QueryResultRow } from 'pg'
13
6
 
14
7
  import { DEFAULT_DB_ALIAS, DEFAULT_PAGE_SIZE, ID_FIELD } from './consts.js'
@@ -24,9 +17,8 @@ import { initializeTable } from './utils/life-cycle.js'
24
17
  import { recordToFullValues, recordToValues, resultToRecord, rowToRecord } from './utils/marshal.js'
25
18
  import { makeTx } from './utils/migrations.js'
26
19
  import { refOf, resolvePlaceholders } from './utils/sql.js'
20
+ import type { Config, Context } from './types.local.js'
27
21
 
28
- type Config = ServerConfig
29
- type Context<C extends Config = Config> = ServerContext<C>
30
22
 
31
23
  /** Postgres has no row expiry — silently ignoring a TTL would lose data. */
32
24
  const refuseTtl = (opts?: WriteOptions): void => {
@@ -0,0 +1,16 @@
1
+ import type { ServerConfig, ServerContext } from '@owlmeans/server-context'
2
+
3
+ export interface PgDriverError {
4
+ code?: string
5
+ detail?: string
6
+ hint?: string
7
+ severity?: string
8
+ constraint?: string
9
+ table?: string
10
+ column?: string
11
+ message?: string
12
+ }
13
+
14
+ export type Config = ServerConfig
15
+
16
+ export type Context<C extends Config = Config> = ServerContext<C>
package/src/types.ts CHANGED
@@ -1,7 +1,4 @@
1
- import type {
2
- Criteria, DbLocker, LockableResource, MigratableResource, Resource,
3
- ResourceDbService, ResourceRecord, WriteOptions
4
- } from '@owlmeans/resource'
1
+ import type { Criteria, DbLocker, LockableResource, MigratableResource, Resource, ResourceDbService, ResourceRecord, WriteOptions, MigrationRegistry } from '@owlmeans/resource'
5
2
  import type { AnySchema } from 'ajv'
6
3
  import type { Pool, PoolClient, QueryResultRow } from 'pg'
7
4
  import type { NodePgDatabase } from 'drizzle-orm/node-postgres'
@@ -321,3 +318,9 @@ export interface DdlPlan {
321
318
  fresh: boolean
322
319
  statements: DdlStatement[]
323
320
  }
321
+
322
+ export interface PostgresDeclaration {
323
+ schema?: AnySchema
324
+ indexes: PgIndexSpec[]
325
+ migrations: MigrationRegistry<PostgresTx>
326
+ }
@@ -0,0 +1,68 @@
1
+ import { PgErrorCode } from '../consts.js'
2
+
3
+ export const COMPARISON: Record<string, string> = {
4
+ $eq: '=', $ne: '<>', $gt: '>', $gte: '>=', $lt: '<', $lte: '<='
5
+ }
6
+
7
+ /** A type cast as `pg_get_expr` / `pg_get_indexdef` print one: `::text`, `::character varying(64)[]`. */
8
+ export const CAST = /::(?:character varying|double precision|bit varying|timestamp with(?:out)? time zone|time with(?:out)? time zone|[a-z_][a-z0-9_]*)(?:\(\d+(?:\s*,\s*\d+)?\))?(?:\[\])?/g
9
+
10
+ /**
11
+ * `pg_attribute` + `format_type` rather than `information_schema.columns`, because it
12
+ * returns one canonical type string with the typmod already baked in
13
+ * (`character varying(320)`). `information_schema` splits the same information across
14
+ * four columns and reports every array as `ARRAY`, which no comparison can use.
15
+ */
16
+ export const COLUMNS = `
17
+ SELECT a.attname AS name,
18
+ format_type(a.atttypid, a.atttypmod) AS type,
19
+ a.attnotnull AS not_null,
20
+ pg_get_expr(d.adbin, d.adrelid) AS default_expr,
21
+ a.attidentity AS identity,
22
+ a.attgenerated AS generated,
23
+ a.attnum AS ordinal
24
+ FROM pg_attribute a
25
+ LEFT JOIN pg_attrdef d ON d.adrelid = a.attrelid AND d.adnum = a.attnum
26
+ WHERE a.attrelid = to_regclass($1) AND a.attnum > 0 AND NOT a.attisdropped
27
+ ORDER BY a.attnum
28
+ `
29
+
30
+ export const INDEXES = `
31
+ SELECT indexname AS name, indexdef AS definition
32
+ FROM pg_indexes
33
+ WHERE schemaname = $1 AND tablename = $2
34
+ `
35
+
36
+ export const CONSTRAINTS = `
37
+ SELECT c.conname AS name, c.contype AS type, pg_get_constraintdef(c.oid) AS definition
38
+ FROM pg_constraint c
39
+ WHERE c.conrelid = to_regclass($1)
40
+ AND c.contype <> 'n'
41
+ `
42
+
43
+ export const SAFE_IDENTIFIER = /^[A-Za-z_][A-Za-z0-9_$]*$/
44
+
45
+ /**
46
+ * `{{ }}` / `{{self}}` — the owning resource's qualified table
47
+ * `{{alias}}` — another registered postgres resource's qualified table
48
+ * `{{alias.property}}` — a qualified column of that resource
49
+ * `{{#alias}}` — the bare quoted table name, for `ON CONFLICT ON CONSTRAINT`
50
+ * `{{$}}` — the owning resource's quoted schema
51
+ *
52
+ * Resource aliases in this codebase use `-` and `:` but never `.`, so `.` is unambiguous
53
+ * as the column separator.
54
+ */
55
+ export const PLACEHOLDER = /\{\{\s*([#$]?)([A-Za-z0-9_:-]*)(?:\.([A-Za-z0-9_]+))?\s*\}\}/g
56
+
57
+ /**
58
+ * Codes that mean "the cast is legal, the data isn't": a `text` column holding `'a'` retyped to
59
+ * `integer`, a value too wide for the new length, a number past the new range. Postgres refuses
60
+ * each of these rather than truncating, and the remedy is the same one a refused cast needs — so
61
+ * they are only read as a cast problem here, inside DDL. On the CRUD path the identical code means
62
+ * a caller passed a bad value, which is a different bug with a different fix.
63
+ */
64
+ export const CAST_DATA_CODES: string[] = [
65
+ PgErrorCode.InvalidTextRepresentation,
66
+ PgErrorCode.StringDataRightTruncation,
67
+ PgErrorCode.NumericValueOutOfRange
68
+ ]
@@ -1,13 +1,9 @@
1
- import { UnsupportedArgumentError } from '@owlmeans/resource'
2
- import type { Criteria, FieldOperators, Sort } from '@owlmeans/resource'
3
- import { and, asc, desc, or, param, sql } from 'drizzle-orm'
4
- import type { SQL } from 'drizzle-orm'
1
+ import { UnsupportedArgumentError, type Criteria, type FieldOperators, type Sort } from '@owlmeans/resource'
2
+ import { and, asc, desc, or, param, sql, type SQL } from 'drizzle-orm'
5
3
 
6
4
  import type { ColumnSpec, PgRuntimeTable, TableSpec } from '../types.js'
7
-
8
- const COMPARISON: Record<string, string> = {
9
- $eq: '=', $ne: '<>', $gt: '>', $gte: '>=', $lt: '<', $lte: '<='
10
- }
5
+ import { COMPARISON } from './consts.local.js'
6
+ import type { PathTarget } from './types.local.js'
11
7
 
12
8
  const columnRef = (table: PgRuntimeTable, column: ColumnSpec): SQL => sql`${table[column.property]}`
13
9
 
@@ -166,17 +162,6 @@ const escapeLike = (value: string): string => value.replace(/[\\%_]/g, match =>
166
162
 
167
163
  // ─── Dotted paths into a jsonb column ────────────────────────────────────────────────────────────
168
164
 
169
- /**
170
- * A value at a path, as the jsonb it is (`#>`) and as text (`#>>`). The path is ONE bound `text[]`
171
- * parameter, so a segment holding a comma or a brace stays one segment.
172
- */
173
- interface PathTarget {
174
- value: SQL
175
- text: SQL
176
- /** Absent, or a JSON `null` — what every other store reads as "no value". */
177
- missing: SQL
178
- }
179
-
180
165
  const pathTarget = (table: PgRuntimeTable, column: ColumnSpec, path: string[]): PathTarget => {
181
166
  const value = sql`(${columnRef(table, column)} #> ${param(path)}::text[])`
182
167
 
package/src/utils/diff.ts CHANGED
@@ -7,6 +7,7 @@ import type {
7
7
  ColumnSpec, DdlPlan, DdlStatement, LiveTable, PgIndexSpec, PostgresResource, TableSpec
8
8
  } from '../types.js'
9
9
  import { qualify, quoteIdent } from './name.js'
10
+ import { CAST } from './consts.local.js'
10
11
 
11
12
  const literal = (value: string | number | boolean | null): string => {
12
13
  if (value === null) return 'NULL'
@@ -23,9 +24,6 @@ const defaultExpression = (column: ColumnSpec): string | undefined => {
23
24
  return undefined
24
25
  }
25
26
 
26
- /** A type cast as `pg_get_expr` / `pg_get_indexdef` print one: `::text`, `::character varying(64)[]`. */
27
- const CAST = /::(?:character varying|double precision|bit varying|timestamp with(?:out)? time zone|time with(?:out)? time zone|[a-z_][a-z0-9_]*)(?:\(\d+(?:\s*,\s*\d+)?\))?(?:\[\])?/g
28
-
29
27
  /**
30
28
  * Postgres echoes defaults back with explicit casts — a declared `'active'` comes back as
31
29
  * `'active'::text`. Compare without them, so an unchanged default doesn't look like drift on
@@ -303,7 +301,10 @@ export const planSync = (
303
301
  }
304
302
  const liveConstraints: Record<string, string> = {}
305
303
  for (const constraint of live.constraints) {
306
- if (constraint.type === 'p' || constraint.type === 'f') {
304
+ // Primary and foreign keys have their own paths. A NOT NULL (`n`) is a constraint row since
305
+ // Postgres 18 (`<table>_<column>_not_null`) and is owned by the column step above: dropping it by
306
+ // name is refused on a primary key column, and on any other it would undo a `required` property.
307
+ if (constraint.type === 'p' || constraint.type === 'f' || constraint.type === 'n') {
307
308
  continue
308
309
  }
309
310
  liveConstraints[constraint.name] = constraint.definition
@@ -2,6 +2,7 @@ export * from './criteria.js'
2
2
  export * from './diff.js'
3
3
  export * from './introspect.js'
4
4
  export * from './life-cycle.js'
5
+ export type * from './types.js'
5
6
  export * from './marshal.js'
6
7
  export * from './migrations.js'
7
8
  export * from './name.js'
@@ -1,38 +1,7 @@
1
1
  import type { PoolClient } from 'pg'
2
2
 
3
3
  import type { LiveColumn, LiveConstraint, LiveIndex, LiveTable } from '../types.js'
4
-
5
- /**
6
- * `pg_attribute` + `format_type` rather than `information_schema.columns`, because it
7
- * returns one canonical type string with the typmod already baked in
8
- * (`character varying(320)`). `information_schema` splits the same information across
9
- * four columns and reports every array as `ARRAY`, which no comparison can use.
10
- */
11
- const COLUMNS = `
12
- SELECT a.attname AS name,
13
- format_type(a.atttypid, a.atttypmod) AS type,
14
- a.attnotnull AS not_null,
15
- pg_get_expr(d.adbin, d.adrelid) AS default_expr,
16
- a.attidentity AS identity,
17
- a.attgenerated AS generated,
18
- a.attnum AS ordinal
19
- FROM pg_attribute a
20
- LEFT JOIN pg_attrdef d ON d.adrelid = a.attrelid AND d.adnum = a.attnum
21
- WHERE a.attrelid = to_regclass($1) AND a.attnum > 0 AND NOT a.attisdropped
22
- ORDER BY a.attnum
23
- `
24
-
25
- const INDEXES = `
26
- SELECT indexname AS name, indexdef AS definition
27
- FROM pg_indexes
28
- WHERE schemaname = $1 AND tablename = $2
29
- `
30
-
31
- const CONSTRAINTS = `
32
- SELECT c.conname AS name, c.contype AS type, pg_get_constraintdef(c.oid) AS definition
33
- FROM pg_constraint c
34
- WHERE c.conrelid = to_regclass($1)
35
- `
4
+ import { COLUMNS, CONSTRAINTS, INDEXES } from './consts.local.js'
36
5
 
37
6
  /** Read the table exactly as Postgres currently holds it. */
38
7
  export const introspectTable = async (
@@ -1,14 +1,12 @@
1
1
  import type { BasicContext } from '@owlmeans/context'
2
- import { MigrationStage, runMigrations } from '@owlmeans/resource'
3
- import type { DbConfig, MigrationReport, ResourceRecord } from '@owlmeans/resource'
2
+ import { MigrationStage, runMigrations, type DbConfig, type MigrationReport, type ResourceRecord } from '@owlmeans/resource'
3
+ import { logger } from '@owlmeans/log'
4
4
  import type { PoolClient } from 'pg'
5
5
 
6
6
  import { DEF_MIGRATIONS_TABLE, PgAutoSync } from '../consts.js'
7
7
  import { getDeclaration } from '../declarations.js'
8
8
  import { describePgError, pgErrorToResourceError } from '../errors.js'
9
- import type {
10
- PgRuntimeTable, PostgresDb, PostgresMeta, PostgresResource, TableSpec
11
- } from '../types.js'
9
+ import type { PostgresDb, PostgresMeta, PostgresResource, TableSpec } from '../types.js'
12
10
  import { planForeignKeys, planSync } from './diff.js'
13
11
  import { introspectTable } from './introspect.js'
14
12
  import { makeMigrationStore } from './migrations.js'
@@ -17,13 +15,9 @@ import { schemaToTableSpec } from './schema.js'
17
15
  import { refOf, resolvePlaceholders } from './sql.js'
18
16
  import { acquireLock, applyPlan, ensureSchema, releaseLock } from './sync.js'
19
17
  import { specToTable } from './table.js'
18
+ import type { TableInit } from './types.js'
20
19
 
21
- export interface TableInit {
22
- spec: TableSpec
23
- /** The Drizzle table CRUD is built against. */
24
- entity: PgRuntimeTable
25
- reports: MigrationReport[]
26
- }
20
+ const log = logger('postgres-resource')
27
21
 
28
22
  /**
29
23
  * Bring a resource's table to the shape its schema declares, then hand back everything the
@@ -90,10 +84,9 @@ export const initializeTable = async (
90
84
 
91
85
  for (const report of reports) {
92
86
  if (report.applied.length > 0) {
93
- console.log(
94
- `@owlmeans/postgres-resource: ${spec.qualified} applied ${report.stage} migrations —`
95
- + ` ${report.applied.join(', ')}`
96
- )
87
+ log.info('Migrations applied', {
88
+ resource: resource.alias, table: spec.qualified, stage: report.stage, applied: report.applied,
89
+ }, { event: 'migration.applied' })
97
90
  }
98
91
  }
99
92
  } finally {
@@ -1,9 +1,12 @@
1
1
  import type { ResourceRecord } from '@owlmeans/resource'
2
+ import { logThrottle, logger } from '@owlmeans/log'
2
3
  import { types as pgTypes } from 'pg'
3
4
 
4
5
  import { ID_FIELD, PgTypeOid } from '../consts.js'
5
6
  import type { ColumnSpec, TableSpec } from '../types.js'
6
7
 
8
+ const log = logger('postgres-resource')
9
+
7
10
  /**
8
11
  * Parse a temporal value the way the driver would have.
9
12
  *
@@ -23,7 +26,7 @@ const toDate = (value: string, column: ColumnSpec): unknown => {
23
26
  return (pgTypes.getTypeParser(oid as never) as (raw: string) => unknown)(value)
24
27
  }
25
28
 
26
- const fromDriver = (value: unknown, column: ColumnSpec): unknown => {
29
+ const fromDriver = (value: unknown, column: ColumnSpec, table?: string): unknown => {
27
30
  if (value == null) {
28
31
  return value
29
32
  }
@@ -44,10 +47,12 @@ const fromDriver = (value: unknown, column: ColumnSpec): unknown => {
44
47
  }
45
48
  const parsed = Number(value)
46
49
  if (!Number.isSafeInteger(parsed)) {
47
- console.warn(
48
- `@owlmeans/postgres-resource: "${column.column}" holds ${value}, which exceeds the safe`
49
- + ' integer range — the value read back is imprecise.'
50
- )
50
+ // Fires per row read: one line per window per column is enough.
51
+ if (logThrottle(`postgres-resource:${table ?? ''}:${column.column}:unsafe-bigint`, 300_000)) {
52
+ log.warn('Bigint column value exceeds the safe integer range; the value read back is imprecise', {
53
+ table, column: column.column,
54
+ })
55
+ }
51
56
  }
52
57
 
53
58
  return parsed
@@ -100,7 +105,7 @@ export const rowToRecord = <T extends ResourceRecord>(row: Record<string, unknow
100
105
  record[key] = value
101
106
  continue
102
107
  }
103
- record[column.property] = fromDriver(value, column)
108
+ record[column.property] = fromDriver(value, column, spec.qualified)
104
109
  }
105
110
  if (record[ID_FIELD] != null) {
106
111
  record[ID_FIELD] = `${record[ID_FIELD]}`
@@ -123,7 +128,7 @@ export const resultToRecord = <T extends ResourceRecord>(
123
128
  const record: Record<string, unknown> = {}
124
129
  for (const [key, value] of Object.entries(row)) {
125
130
  const column = spec.byProperty[key]
126
- record[key] = column == null ? value : fromDriver(value, column)
131
+ record[key] = column == null ? value : fromDriver(value, column, spec.qualified)
127
132
  }
128
133
  if (record[ID_FIELD] != null) {
129
134
  record[ID_FIELD] = `${record[ID_FIELD]}`
@@ -15,29 +15,32 @@ export const makeTx = (
15
15
  client,
16
16
 
17
17
  query: async <Row extends QueryResultRow = QueryResultRow>(text: string, params?: unknown[]) => {
18
+ const query = resolve(text)
18
19
  try {
19
- const result = await client.query<Row>(resolve(text), params as never[])
20
+ const result = await client.query<Row>(query, params as never[])
20
21
  return result.rows
21
22
  } catch (error) {
22
- throw pgErrorToResourceError(error)
23
+ throw pgErrorToResourceError(error, query)
23
24
  }
24
25
  },
25
26
 
26
27
  queryOne: async <Row extends QueryResultRow = QueryResultRow>(text: string, params?: unknown[]) => {
28
+ const query = resolve(text)
27
29
  try {
28
- const result = await client.query<Row>(resolve(text), params as never[])
30
+ const result = await client.query<Row>(query, params as never[])
29
31
  return result.rows[0] ?? null
30
32
  } catch (error) {
31
- throw pgErrorToResourceError(error)
33
+ throw pgErrorToResourceError(error, query)
32
34
  }
33
35
  },
34
36
 
35
37
  execute: async (text: string, params?: unknown[]) => {
38
+ const query = resolve(text)
36
39
  try {
37
- const result = await client.query(resolve(text), params as never[])
40
+ const result = await client.query(query, params as never[])
38
41
  return result.rowCount ?? 0
39
42
  } catch (error) {
40
- throw pgErrorToResourceError(error)
43
+ throw pgErrorToResourceError(error, query)
41
44
  }
42
45
  },
43
46
 
package/src/utils/name.ts CHANGED
@@ -1,11 +1,10 @@
1
- import { sha256 } from '@noble/hashes/sha2'
1
+ import { sha256 } from '@noble/hashes/sha2.js'
2
2
  import { hex } from '@scure/base'
3
3
  import type { DbConfig, ResourceRecord } from '@owlmeans/resource'
4
4
 
5
5
  import { PG_MAX_IDENTIFIER } from '../consts.js'
6
6
  import type { PostgresResource } from '../types.js'
7
-
8
- const SAFE_IDENTIFIER = /^[A-Za-z_][A-Za-z0-9_$]*$/
7
+ import { SAFE_IDENTIFIER } from './consts.local.js'
9
8
 
10
9
  /**
11
10
  * Coerce an arbitrary name into a legal Postgres identifier of at most 63 bytes.