pipework 0.189.0 → 0.191.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/CHANGELOG.md +33 -0
- package/dist/REFERENCE.md +10 -131
- package/dist/auth/tenant/scoped-db.d.ts.map +1 -1
- package/dist/auth/tenant/scoped-db.js +349 -186
- package/dist/auth/tenant/scoped-db.js.map +1 -1
- package/dist/data/db/aggregates.d.ts.map +1 -1
- package/dist/data/db/aggregates.js +1 -6
- package/dist/data/db/aggregates.js.map +1 -1
- package/dist/data/db/db.d.ts +3 -7
- package/dist/data/db/db.d.ts.map +1 -1
- package/dist/data/db/db.js +3 -7
- package/dist/data/db/db.js.map +1 -1
- package/dist/data/query/pg-core/columns/common.js +1 -1
- package/dist/data/query/pg-core/columns/common.js.map +1 -1
- package/dist/data/query/pg-core/utils/array.js +1 -1
- package/dist/data/query/pg-core/utils/array.js.map +1 -1
- package/dist/data/query/postgres-js/array-parser.d.ts +7 -0
- package/dist/data/query/postgres-js/array-parser.d.ts.map +1 -0
- package/dist/data/query/postgres-js/array-parser.js +49 -0
- package/dist/data/query/postgres-js/array-parser.js.map +1 -0
- package/dist/data/query/postgres-js/driver.d.ts.map +1 -1
- package/dist/data/query/postgres-js/driver.js +31 -1
- package/dist/data/query/postgres-js/driver.js.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,38 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.191.0
|
|
4
|
+
|
|
5
|
+
- **Added: `$with` on a tenant-scoped connection** (#748). `db.$with('m').materialized().as(db.select(…).from(tenantTable))` followed by `db.with(m).select().from(m)` returns only the context tenant's rows, the same as an inline subquery.
|
|
6
|
+
- A CTE body must be built by the same scoped connection. The callback form `(qb) => …` gets a scoped query builder.
|
|
7
|
+
- A raw `sql` body, or a builder from `pipe.system()` or another connection, is refused with a message saying why.
|
|
8
|
+
- `db.with(…)` accepts only this connection's CTEs and scopes what follows it.
|
|
9
|
+
- **Fixed: the tenant-scoped connection let other tenants' rows through on several paths** (#748). Postgres row-level security still applied wherever it was configured, but pipework's own tenant filter was missing on these:
|
|
10
|
+
- A scoped select used as a subquery, through `inArray(…)`, `.as()`, `getSQL()` or `toSQL()`, had no tenant filter. The filter used to be added only when the query was awaited. It is now in the SQL as soon as the table is named.
|
|
11
|
+
- A joined tenant table (inner, left, right, full or cross) wasn't filtered. Its condition now goes in the join's ON clause, so a left join keeps its unmatched rows. Right and full joins also keep the tables before them to the tenant.
|
|
12
|
+
- `db.with(x)` passed straight through to the unscoped connection.
|
|
13
|
+
- `db.transaction(cb)` handed `cb` an unscoped `tx`.
|
|
14
|
+
- `$count` counted every tenant's rows.
|
|
15
|
+
- `update().from(tenantTable)` read every tenant's rows.
|
|
16
|
+
- A `union` (or other set operation) accepted an operand built elsewhere.
|
|
17
|
+
- An `onConflictDoUpdate` upsert on a unique key that excludes the tenant column could overwrite another tenant's row. Its update is now limited to the tenant's own rows, and a conflict with another tenant's row updates nothing and returns no row. `pipe.upsert` and audited upserts are covered.
|
|
18
|
+
- The no-tenant guard connection refuses a tenant table on all of the same paths.
|
|
19
|
+
- **Changed:**
|
|
20
|
+
- `insert().select()` into a tenant table is refused on a scoped connection, because the tenant column can't be set from a select.
|
|
21
|
+
- `db.query` (relational queries) is refused on a scoped connection that has tables.
|
|
22
|
+
|
|
23
|
+
## 0.190.0
|
|
24
|
+
|
|
25
|
+
- **Fixed: a NULL element in an array read back wrong** (#747). On every path (column selects, `db.execute`, `arrayAgg`) an unquoted NULL element now reads as `null`, for every array type:
|
|
26
|
+
- Numeric arrays used to give `NaN`, and bigint arrays threw `Cannot convert NULL to a BigInt`.
|
|
27
|
+
- `text[]`, `uuid[]` and enum arrays gave the string `'NULL'`, which a real `'NULL'` string couldn't be told apart from.
|
|
28
|
+
- `bool[]` gave `false`.
|
|
29
|
+
- `jsonb[]` threw on parse.
|
|
30
|
+
- Date and timestamp array columns gave `Invalid Date`.
|
|
31
|
+
|
|
32
|
+
A quoted `"NULL"` string stays a string, and a float `NaN` stays `NaN`.
|
|
33
|
+
- The fix replaces the driver's array parser for every array type it learns at connect, enums and domains included. An enum created after a connection opened is learned by connections opened after it.
|
|
34
|
+
- `db.execute` now returns a `numeric[]` as an array of strings (`['1.5', null]`) instead of the text `'{1.5,NULL}'`.
|
|
35
|
+
|
|
3
36
|
## 0.189.0
|
|
4
37
|
|
|
5
38
|
- **Added: a step's own priority** (#744). `steps: { shadow: { priority: -100, … } }` queues that step's jobs at its own priority instead of the run's, in every run and for every fan-out instance. Higher priorities are claimed first, across runs, per worker class. A measurement step set below every run priority waits behind every other step on its workers, and its run still finishes and records as before. The steps it needs, the steps that need it and the run's finish job keep the run's priority.
|
package/dist/REFERENCE.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# Pipework API Reference
|
|
2
2
|
|
|
3
3
|
> Auto-generated from source JSDoc. Do not edit manually.
|
|
4
|
-
> Generated: 2026-10-
|
|
4
|
+
> Generated: 2026-10-20
|
|
5
5
|
|
|
6
6
|
## Contents
|
|
7
7
|
|
|
@@ -816,10 +816,6 @@ Acquires a transaction-scoped advisory lock. Released at commit/rollback.
|
|
|
816
816
|
|
|
817
817
|
Runs a function in a SERIALIZABLE transaction with automatic retry on serialization failures and deadlocks.
|
|
818
818
|
|
|
819
|
-
### `pipe.withTimeouts`
|
|
820
|
-
|
|
821
|
-
Sets statement_timeout and/or lock_timeout for the current transaction in one statement, then runs fn; a statement cancelled for them rejects with StatementTimeoutError or LockTimeoutError.
|
|
822
|
-
|
|
823
819
|
### `pipe.bulkSet`
|
|
824
820
|
|
|
825
821
|
Bulk UPDATE ... FROM (VALUES ...) — updates multiple rows with per-row values in a single statement.
|
|
@@ -828,10 +824,6 @@ Bulk UPDATE ... FROM (VALUES ...) — updates multiple rows with per-row values
|
|
|
828
824
|
|
|
829
825
|
Produces a typed VALUES clause for bulk operations — the base primitive for bulkSet and bulkUpsert.
|
|
830
826
|
|
|
831
|
-
### `pipe.fn`
|
|
832
|
-
|
|
833
|
-
A set-returning SQL function as a typed source for `.from()` and joins — `pipe.fn('schema.f', { args: [field.uuid()], columns: { path: field.text() } })`. Arguments are bound and cast to their declared types.
|
|
834
|
-
|
|
835
827
|
### `pipe.field`
|
|
836
828
|
|
|
837
829
|
Field builders for domain definitions — uuid(), text(), integer(), etc.
|
|
@@ -844,10 +836,6 @@ Registers a domain definition with table, validators, and factory projections. T
|
|
|
844
836
|
|
|
845
837
|
Returns the global registry of all domain definitions.
|
|
846
838
|
|
|
847
|
-
### `pipe.external`
|
|
848
|
-
|
|
849
|
-
Declares a table or view another service owns (`pipe.external(name, fields, { schema, table? })`): typed columns and every query operator, read-only, never migrated, not tenant-scoped.
|
|
850
|
-
|
|
851
839
|
### `pipe.update`
|
|
852
840
|
|
|
853
841
|
Pipework-owned UPDATE builder — the only consumer-facing way to update pipework-managed tables (Q8).
|
|
@@ -878,54 +866,12 @@ interface WindowSpec
|
|
|
878
866
|
interface ValueColumnDef
|
|
879
867
|
```
|
|
880
868
|
|
|
881
|
-
**`JsonbElements`** — A jsonb array read as its elements' text. Produced by {@link jsonbElements}.
|
|
882
|
-
|
|
883
|
-
```typescript
|
|
884
|
-
interface JsonbElements
|
|
885
|
-
```
|
|
886
|
-
|
|
887
|
-
**`ArraySource`** — Something whose elements `arrayAny` / `arrayAll` can test.
|
|
888
|
-
|
|
889
|
-
```typescript
|
|
890
|
-
type ArraySource =
|
|
891
|
-
```
|
|
892
|
-
|
|
893
|
-
**`ElementOf`** — The element type of an {@link ArraySource}.
|
|
894
|
-
|
|
895
|
-
```typescript
|
|
896
|
-
type ElementOf<S> =
|
|
897
|
-
```
|
|
898
|
-
|
|
899
|
-
**`FunctionSpec`** — Declares a SQL function's argument and result-column shapes. See {@link fn}.
|
|
900
|
-
|
|
901
|
-
```typescript
|
|
902
|
-
interface FunctionSpec<TArgs extends readonly AnyField[], TColumns extends Record<string, AnyField>>
|
|
903
|
-
```
|
|
904
|
-
|
|
905
|
-
**`FunctionSourceFields`** — The selected fields of a function source: each result column as a typed SQL expression.
|
|
906
|
-
|
|
907
|
-
```typescript
|
|
908
|
-
type FunctionSourceFields<TColumns extends Record<string, AnyField>> =
|
|
909
|
-
```
|
|
910
|
-
|
|
911
|
-
**`FunctionSource`** — A function call usable in `.from()` and joins; its result columns are properties of it.
|
|
912
|
-
|
|
913
|
-
```typescript
|
|
914
|
-
type FunctionSource<TAlias extends string, TColumns extends Record<string, AnyField>> =
|
|
915
|
-
```
|
|
916
|
-
|
|
917
869
|
**`SerializableOptions`** — Retry policy for {@link serializable}: how many attempts on a serialization failure / deadlock, and the base backoff between them.
|
|
918
870
|
|
|
919
871
|
```typescript
|
|
920
872
|
interface SerializableOptions
|
|
921
873
|
```
|
|
922
874
|
|
|
923
|
-
**`TimeoutOptions`** — Which timeouts {@link withTimeouts} sets; each a positive integer number of milliseconds.
|
|
924
|
-
|
|
925
|
-
```typescript
|
|
926
|
-
interface TimeoutOptions
|
|
927
|
-
```
|
|
928
|
-
|
|
929
875
|
**`ManagedConnection`** — A standalone pooled connection: the raw postgres.js client, its drizzle handle, and a `close()` that ends the pool.
|
|
930
876
|
|
|
931
877
|
```typescript
|
|
@@ -946,10 +892,6 @@ JSONB query operators — typed helpers for PostgreSQL JSONB containment, key ch
|
|
|
946
892
|
|
|
947
893
|
The @> containment operator — tests whether a JSONB column contains the given value.
|
|
948
894
|
|
|
949
|
-
### `jsonb.merge`
|
|
950
|
-
|
|
951
|
-
Merges an object into a JSONB column in `.set()`: `coalesce(col, '{}') || value`. Top-level keys overwrite; others are kept.
|
|
952
|
-
|
|
953
895
|
### `jsonb.containedBy`
|
|
954
896
|
|
|
955
897
|
The <@ contained-by operator — tests whether a JSONB column is contained by the given value.
|
|
@@ -1016,60 +958,6 @@ type Schema<T = unknown> = z.ZodType<T>
|
|
|
1016
958
|
type Infer<T extends Schema> = z.infer<T>
|
|
1017
959
|
```
|
|
1018
960
|
|
|
1019
|
-
**`StringSchema`** — A string validator — what check.string() returns, nameable without importing zod.
|
|
1020
|
-
|
|
1021
|
-
```typescript
|
|
1022
|
-
interface StringSchema extends z.ZodString
|
|
1023
|
-
```
|
|
1024
|
-
|
|
1025
|
-
**`NumberSchema`** — A number validator — what check.number() returns.
|
|
1026
|
-
|
|
1027
|
-
```typescript
|
|
1028
|
-
interface NumberSchema extends z.ZodNumber
|
|
1029
|
-
```
|
|
1030
|
-
|
|
1031
|
-
**`BooleanSchema`** — A boolean validator — what check.boolean() returns.
|
|
1032
|
-
|
|
1033
|
-
```typescript
|
|
1034
|
-
interface BooleanSchema extends z.ZodBoolean
|
|
1035
|
-
```
|
|
1036
|
-
|
|
1037
|
-
**`EnumSchema`** — An enum validator over string literals — what check.enum([...]) returns.
|
|
1038
|
-
|
|
1039
|
-
```typescript
|
|
1040
|
-
interface EnumSchema<V extends string = string> extends z.ZodEnum<
|
|
1041
|
-
```
|
|
1042
|
-
|
|
1043
|
-
**`LiteralSchema`** — A literal validator — what check.literal(v) returns.
|
|
1044
|
-
|
|
1045
|
-
```typescript
|
|
1046
|
-
interface LiteralSchema<V extends string | number | boolean | null = string> extends z.ZodLiteral<V>
|
|
1047
|
-
```
|
|
1048
|
-
|
|
1049
|
-
**`ArraySchema`** — An array validator — what check.array(item) returns.
|
|
1050
|
-
|
|
1051
|
-
```typescript
|
|
1052
|
-
interface ArraySchema<Item extends z.core.SomeType = z.core.SomeType> extends z.ZodArray<Item>
|
|
1053
|
-
```
|
|
1054
|
-
|
|
1055
|
-
**`OptionalSchema`** — An optional validator — what check.optional(inner) returns.
|
|
1056
|
-
|
|
1057
|
-
```typescript
|
|
1058
|
-
interface OptionalSchema<Inner extends z.core.SomeType = z.core.SomeType> extends z.ZodOptional<Inner>
|
|
1059
|
-
```
|
|
1060
|
-
|
|
1061
|
-
**`NullableSchema`** — A nullable validator — what check.nullable(inner) returns.
|
|
1062
|
-
|
|
1063
|
-
```typescript
|
|
1064
|
-
interface NullableSchema<Inner extends z.core.SomeType = z.core.SomeType> extends z.ZodNullable<Inner>
|
|
1065
|
-
```
|
|
1066
|
-
|
|
1067
|
-
**`ObjectSchema`** — An object validator whose .extend, .pick, .omit and .partial results stay ObjectSchema — what check.object({...}) returns.
|
|
1068
|
-
|
|
1069
|
-
```typescript
|
|
1070
|
-
type ObjectSchema<S extends Shape = Shape> =
|
|
1071
|
-
```
|
|
1072
|
-
|
|
1073
961
|
## temporal — Bitemporal Data
|
|
1074
962
|
|
|
1075
963
|
Temporal (bitemporal) data namespace — version history with effective date ranges.
|
|
@@ -1586,11 +1474,7 @@ interface RateLimitConfig
|
|
|
1586
1474
|
interface RateLimitWindow
|
|
1587
1475
|
```
|
|
1588
1476
|
|
|
1589
|
-
**`RateLimitClass`**
|
|
1590
|
-
|
|
1591
|
-
A named limit class: any of a per-user, per-tenant, per-address and total window, each counted on its own.
|
|
1592
|
-
Each key takes one window or an array of windows (distinct `windowSeconds`); a request is counted against
|
|
1593
|
-
all of a key's windows and refused if any is over.
|
|
1477
|
+
**`RateLimitClass`** — A named limit class: any of a per-user, per-tenant and per-address window, each counted on its own.
|
|
1594
1478
|
|
|
1595
1479
|
```typescript
|
|
1596
1480
|
interface RateLimitClass
|
|
@@ -1606,8 +1490,8 @@ interface RateLimitRefusal
|
|
|
1606
1490
|
|
|
1607
1491
|
Named limit classes, checked after auth and counted in Postgres (`pipework_rate_limit_counts`, opted in
|
|
1608
1492
|
with the blueprint's `rateLimits: {}`), so every server process on the same database shares one count.
|
|
1609
|
-
|
|
1610
|
-
refused requests don't spend the tenant's budget.
|
|
1493
|
+
Windows are counted perUser, perTenant, perAddress in turn, up to the first one over its max, so one user's
|
|
1494
|
+
refused requests don't spend the tenant's budget. A route is in `signedIn` (auth required, or optional with
|
|
1611
1495
|
a user), `public` (no auth, or optional without a user) or the class its fitting names with `.rateLimit(name)`.
|
|
1612
1496
|
|
|
1613
1497
|
```typescript
|
|
@@ -1759,20 +1643,15 @@ interface TraceTree
|
|
|
1759
1643
|
|
|
1760
1644
|
## data
|
|
1761
1645
|
|
|
1762
|
-
### `
|
|
1763
|
-
|
|
1764
|
-
A statement was cancelled by Postgres for running past the statement timeout a {@link withTimeouts} call set. `cause` is the driver error.
|
|
1765
|
-
|
|
1766
|
-
```typescript
|
|
1767
|
-
class StatementTimeoutError extends Error constructor(readonly statementTimeoutMs: number, cause: unknown)
|
|
1768
|
-
```
|
|
1769
|
-
|
|
1770
|
-
### `LockTimeoutError`
|
|
1646
|
+
### `tap`
|
|
1771
1647
|
|
|
1772
|
-
|
|
1648
|
+
Opens a standalone managed connection outside the manifold's pools — the
|
|
1649
|
+
sanctioned door for contexts where `pipe()` structurally cannot resolve:
|
|
1650
|
+
`worker_threads`, detached monitors, one-off scripts. Callers own the
|
|
1651
|
+
lifecycle: always `await conn.close()`.
|
|
1773
1652
|
|
|
1774
1653
|
```typescript
|
|
1775
|
-
|
|
1654
|
+
function tap(url: string, options?: ConnectOptions): ManagedConnection
|
|
1776
1655
|
```
|
|
1777
1656
|
|
|
1778
1657
|
## request
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scoped-db.d.ts","sourceRoot":"","sources":["../../../src/auth/tenant/scoped-db.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"scoped-db.d.ts","sourceRoot":"","sources":["../../../src/auth/tenant/scoped-db.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,wBAAwB,CAAA;AAichD,wBAAgB,mBAAmB,CAAC,EAAE,EAAE,EAAE,GAAG,EAAE,CAE9C;AAED,wBAAgB,cAAc,CAAC,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE,MAAM,GAAG,EAAE,CAE3D"}
|