@ingram-tech/nk-db 0.6.0 → 0.8.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.
package/README.md CHANGED
@@ -54,6 +54,11 @@ same pool: `betterAuth({ database: pool, … })`.
54
54
  - **`configureTimestampsAsStrings()`** — opt-in, for legacy row types that expect
55
55
  `timestamptz` as ISO strings (on the golden path, prefer Drizzle's
56
56
  `timestamp(..., { mode: "string" })` per column).
57
+ - **`pgTimestampToIso(value)` / `pgNumericToNumber(value)`** — response-boundary
58
+ coercions for schemas written against supabase-js. `pg`/Drizzle return
59
+ `numeric` as a string and `timestamp(..., { mode: "string" })` as Postgres'
60
+ text form; these convert to the `z.number()` / strict `z.iso.datetime()` shapes
61
+ those schemas expect. Presentation only — keep money math on the decimal value.
57
62
 
58
63
  ## Keeping RLS on a direct connection (`withRls` / `withRlsTransaction`)
59
64
 
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Normalize a Postgres timestamp string to a strict ISO-8601 UTC string
3
+ * ("2026-06-21T18:22:08.331Z"), the form `z.iso.datetime()` (no offset) accepts.
4
+ *
5
+ * `Date` parses both Postgres' space-separated form and supabase-js's `+00:00`
6
+ * offset form to the same instant, and `.toISOString()` emits the canonical
7
+ * `T…Z`. `null` passes through.
8
+ */
9
+ export declare function pgTimestampToIso(value: string): string;
10
+ export declare function pgTimestampToIso(value: null): null;
11
+ export declare function pgTimestampToIso(value: string | null): string | null;
12
+ /**
13
+ * Coerce a Postgres `numeric` value (which `pg`/Drizzle return as a string to
14
+ * preserve arbitrary precision) to a JS number, for schemas that expect
15
+ * `z.number()`. `null` passes through.
16
+ *
17
+ * Lossy for values outside `Number`'s safe range — only use at the response
18
+ * boundary, never for money math (keep that on the string/decimal value).
19
+ */
20
+ export declare function pgNumericToNumber(value: string): number;
21
+ export declare function pgNumericToNumber(value: null): null;
22
+ export declare function pgNumericToNumber(value: string | null): number | null;
23
+ //# sourceMappingURL=coerce.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"coerce.d.ts","sourceRoot":"","sources":["../src/coerce.ts"],"names":[],"mappings":"AAcA;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAAC;AACxD,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,IAAI,GAAG,IAAI,CAAC;AACpD,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,GAAG,IAAI,CAAC;AAKtE;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAAC;AACzD,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,IAAI,GAAG,IAAI,CAAC;AACrD,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,GAAG,IAAI,CAAC"}
package/dist/coerce.js ADDED
@@ -0,0 +1,20 @@
1
+ // Coerce Postgres value representations back to the JS types app code expects.
2
+ //
3
+ // Why these exist: response/validation schemas in nextkit sites are typically
4
+ // written against supabase-js / PostgREST, which parsed `timestamptz` into ISO
5
+ // strings and `numeric` into JS numbers. Direct `pg` (and Drizzle on top of it)
6
+ // surfaces those columns differently — `numeric` as a string (to avoid losing
7
+ // precision), and `timestamp(..., { mode: "string" })` as Postgres' own text
8
+ // form ("2026-06-21 18:22:08.331494+00", space separator, short offset). Neither
9
+ // satisfies a schema expecting `z.number()` / strict `z.iso.datetime()`.
10
+ //
11
+ // Use these at the read/response boundary when handing Drizzle/`pg` rows to such
12
+ // a schema. They are presentation coercions, not domain math — keep money
13
+ // arithmetic on the string/decimal value, and only convert for output.
14
+ export function pgTimestampToIso(value) {
15
+ return value === null ? null : new Date(value).toISOString();
16
+ }
17
+ export function pgNumericToNumber(value) {
18
+ return value === null ? null : Number(value);
19
+ }
20
+ //# sourceMappingURL=coerce.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"coerce.js","sourceRoot":"","sources":["../src/coerce.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,EAAE;AACF,8EAA8E;AAC9E,+EAA+E;AAC/E,gFAAgF;AAChF,8EAA8E;AAC9E,6EAA6E;AAC7E,iFAAiF;AACjF,yEAAyE;AACzE,EAAE;AACF,iFAAiF;AACjF,0EAA0E;AAC1E,uEAAuE;AAavE,MAAM,UAAU,gBAAgB,CAAC,KAAoB;IACpD,OAAO,KAAK,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC,WAAW,EAAE,CAAC;AAC9D,CAAC;AAaD,MAAM,UAAU,iBAAiB,CAAC,KAAoB;IACrD,OAAO,KAAK,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AAC9C,CAAC"}
package/dist/index.d.ts CHANGED
@@ -1,3 +1,4 @@
1
+ export { pgNumericToNumber, pgTimestampToIso } from "./coerce.js";
1
2
  export { createDb, withRlsTransaction } from "./drizzle.js";
2
3
  export { type DbEnv, dbEnv, getDatabaseUrl, isConfigured } from "./keys.js";
3
4
  export { type CreatePoolConfig, createPool } from "./pool.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,QAAQ,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAC5D,OAAO,EAAE,KAAK,KAAK,EAAE,KAAK,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAC5E,OAAO,EAAE,KAAK,gBAAgB,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAC9D,OAAO,EAAE,aAAa,EAAE,KAAK,WAAW,EAAE,KAAK,OAAO,EAAE,MAAM,cAAc,CAAC;AAC7E,OAAO,EACN,kBAAkB,EAClB,gBAAgB,EAChB,KAAK,iBAAiB,EACtB,KAAK,SAAS,EACd,KAAK,UAAU,EACf,gBAAgB,EAChB,WAAW,GACX,MAAM,UAAU,CAAC;AAClB,OAAO,EAAE,4BAA4B,EAAE,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAClE,OAAO,EAAE,QAAQ,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAC5D,OAAO,EAAE,KAAK,KAAK,EAAE,KAAK,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAC5E,OAAO,EAAE,KAAK,gBAAgB,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAC9D,OAAO,EAAE,aAAa,EAAE,KAAK,WAAW,EAAE,KAAK,OAAO,EAAE,MAAM,cAAc,CAAC;AAC7E,OAAO,EACN,kBAAkB,EAClB,gBAAgB,EAChB,KAAK,iBAAiB,EACtB,KAAK,SAAS,EACd,KAAK,UAAU,EACf,gBAAgB,EAChB,WAAW,GACX,MAAM,UAAU,CAAC;AAClB,OAAO,EAAE,4BAA4B,EAAE,MAAM,YAAY,CAAC"}
package/dist/index.js CHANGED
@@ -1,6 +1,7 @@
1
1
  // The Ingram Postgres data layer. The PGlite dev/test harness lives behind the
2
2
  // "@ingram-tech/nk-db/pglite" subpath so its WASM/dev-only deps never reach a
3
3
  // production bundle.
4
+ export { pgNumericToNumber, pgTimestampToIso } from "./coerce.js";
4
5
  export { createDb, withRlsTransaction } from "./drizzle.js";
5
6
  export { dbEnv, getDatabaseUrl, isConfigured } from "./keys.js";
6
7
  export { createPool } from "./pool.js";
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,8EAA8E;AAC9E,qBAAqB;AAErB,OAAO,EAAE,QAAQ,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAC5D,OAAO,EAAc,KAAK,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAC5E,OAAO,EAAyB,UAAU,EAAE,MAAM,WAAW,CAAC;AAC9D,OAAO,EAAE,aAAa,EAAkC,MAAM,cAAc,CAAC;AAC7E,OAAO,EACN,kBAAkB,EAClB,gBAAgB,EAIhB,gBAAgB,EAChB,WAAW,GACX,MAAM,UAAU,CAAC;AAClB,OAAO,EAAE,4BAA4B,EAAE,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,8EAA8E;AAC9E,qBAAqB;AAErB,OAAO,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAClE,OAAO,EAAE,QAAQ,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAC5D,OAAO,EAAc,KAAK,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAC5E,OAAO,EAAyB,UAAU,EAAE,MAAM,WAAW,CAAC;AAC9D,OAAO,EAAE,aAAa,EAAkC,MAAM,cAAc,CAAC;AAC7E,OAAO,EACN,kBAAkB,EAClB,gBAAgB,EAIhB,gBAAgB,EAChB,WAAW,GACX,MAAM,UAAU,CAAC;AAClB,OAAO,EAAE,4BAA4B,EAAE,MAAM,YAAY,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ingram-tech/nk-db",
3
- "version": "0.6.0",
3
+ "version": "0.8.0",
4
4
  "description": "The Ingram Postgres data layer: one TLS-aware pg pool, raw-SQL helpers, Drizzle wiring, and a PGlite (no-Docker) dev/test harness for Next.js sites.",
5
5
  "license": "MIT",
6
6
  "type": "module",