@palbase/backend 23.0.0 → 23.1.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/dist/bin/palbase-backend.cjs +313 -24
- package/dist/bin/palbase-backend.cjs.map +1 -1
- package/dist/bin/palbase-backend.js +5 -5
- package/dist/{chunk-Y5HXVUMP.js → chunk-HQRJDARQ.js} +2 -2
- package/dist/{chunk-REZU6UKT.js → chunk-M5MCBWJI.js} +296 -25
- package/dist/chunk-M5MCBWJI.js.map +1 -0
- package/dist/{chunk-W5ODXPY3.js → chunk-NS5V43YQ.js} +14 -1
- package/dist/chunk-NS5V43YQ.js.map +1 -0
- package/dist/{chunk-FSGSB42K.js → chunk-OHALWEOG.js} +9 -4
- package/dist/chunk-OHALWEOG.js.map +1 -0
- package/dist/{chunk-HAF67F2H.js → chunk-PY7YJDCT.js} +57 -3
- package/dist/chunk-PY7YJDCT.js.map +1 -0
- package/dist/{chunk-ZC6Q2BRD.js → chunk-R3KN6RHD.js} +2 -2
- package/dist/{chunk-OMRTHM4X.js → chunk-RCLNBJCM.js} +1 -1
- package/dist/chunk-RCLNBJCM.js.map +1 -0
- package/dist/db/index.cjs +68 -1
- package/dist/db/index.cjs.map +1 -1
- package/dist/db/index.d.cts +2 -2
- package/dist/db/index.d.ts +2 -2
- package/dist/db/index.js +2 -2
- package/dist/{endpoint-BavvbW4P.d.ts → endpoint-CVWXh6oG.d.ts} +70 -8
- package/dist/{endpoint-i8TTCohk.d.cts → endpoint-c9h5jriX.d.cts} +70 -8
- package/dist/engine/index.cjs +313 -24
- package/dist/engine/index.cjs.map +1 -1
- package/dist/engine/index.d.cts +4 -4
- package/dist/engine/index.d.ts +4 -4
- package/dist/engine/index.js +4 -4
- package/dist/{index-B7YBEG5w.d.ts → index-BZrJXnVh.d.ts} +49 -4
- package/dist/{index-Bmvx1EvJ.d.cts → index-By8Dle5U.d.cts} +86 -17
- package/dist/{index-B3jmmItD.d.ts → index-CwAJ7HEe.d.ts} +86 -17
- package/dist/{index-E7OscPJT.d.cts → index-CxeQSfJP.d.cts} +49 -4
- package/dist/index.cjs +104 -3
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +8 -8
- package/dist/index.d.ts +8 -8
- package/dist/index.js +32 -6
- package/dist/index.js.map +1 -1
- package/dist/openapi/index.cjs +29 -4
- package/dist/openapi/index.cjs.map +1 -1
- package/dist/openapi/index.d.cts +5 -2
- package/dist/openapi/index.d.ts +5 -2
- package/dist/openapi/index.js +32 -7
- package/dist/openapi/index.js.map +1 -1
- package/dist/{registry-DY3d9l1k.d.ts → registry-B3niOVYp.d.ts} +101 -7
- package/dist/{registry-C3H2uPeZ.d.cts → registry-CqPK2Qby.d.cts} +101 -7
- package/dist/test/index.cjs +482 -9
- package/dist/test/index.cjs.map +1 -1
- package/dist/test/index.d.cts +35 -3
- package/dist/test/index.d.ts +35 -3
- package/dist/test/index.js +480 -8
- package/dist/test/index.js.map +1 -1
- package/package.json +4 -3
- package/stager/return_types.js +23 -0
- package/dist/chunk-FSGSB42K.js.map +0 -1
- package/dist/chunk-HAF67F2H.js.map +0 -1
- package/dist/chunk-OMRTHM4X.js.map +0 -1
- package/dist/chunk-REZU6UKT.js.map +0 -1
- package/dist/chunk-W5ODXPY3.js.map +0 -1
- /package/dist/{chunk-Y5HXVUMP.js.map → chunk-HQRJDARQ.js.map} +0 -0
- /package/dist/{chunk-ZC6Q2BRD.js.map → chunk-R3KN6RHD.js.map} +0 -0
package/dist/index.cjs
CHANGED
|
@@ -57,6 +57,9 @@ __export(src_exports, {
|
|
|
57
57
|
Req: () => Req,
|
|
58
58
|
RequestId: () => RequestId,
|
|
59
59
|
Secrets: () => Secrets,
|
|
60
|
+
Signal: () => Signal,
|
|
61
|
+
Sse: () => Sse,
|
|
62
|
+
SseOut: () => SseOut,
|
|
60
63
|
Storage: () => Storage,
|
|
61
64
|
TooManyRequests: () => TooManyRequests,
|
|
62
65
|
TraceId: () => TraceId,
|
|
@@ -354,6 +357,19 @@ var TxPlanBuilder = class {
|
|
|
354
357
|
}
|
|
355
358
|
return this.push({ op: "insert", table: name, values: encoded }, `${name}.insert()`);
|
|
356
359
|
},
|
|
360
|
+
upsert: (values, options) => {
|
|
361
|
+
const encoded = encodeMap(values, false);
|
|
362
|
+
if (Object.keys(encoded).length === 0) {
|
|
363
|
+
throw new TxPlanError(`${name}.upsert() needs at least one column`);
|
|
364
|
+
}
|
|
365
|
+
if (options.onConflict.length === 0) {
|
|
366
|
+
throw new TxPlanError(`${name}.upsert() needs at least one onConflict column`);
|
|
367
|
+
}
|
|
368
|
+
return this.push(
|
|
369
|
+
{ op: "upsert", table: name, values: encoded, onConflict: options.onConflict },
|
|
370
|
+
`${name}.upsert()`
|
|
371
|
+
);
|
|
372
|
+
},
|
|
357
373
|
insertMany: (rows) => {
|
|
358
374
|
if (rows.length === 0) {
|
|
359
375
|
return new TxRowsImpl(this, SKIPPED_OP, `${name}.insertMany()`);
|
|
@@ -564,7 +580,8 @@ function makeTablesAccessor(ops) {
|
|
|
564
580
|
update: (id, data) => ops().update(name, id, data),
|
|
565
581
|
delete: (id) => ops().delete(name, id),
|
|
566
582
|
findById: (id) => ops().findById(name, id),
|
|
567
|
-
findMany: (query) => ops().findMany(name, query),
|
|
583
|
+
findMany: (query, opts) => ops().findMany(name, query, opts),
|
|
584
|
+
upsert: (data, opts) => ops().upsert(name, data, opts),
|
|
568
585
|
search: (params) => ops().search(name, params),
|
|
569
586
|
similar: (id, params) => ops().similar(name, id, params),
|
|
570
587
|
recommend: (params) => ops().recommend(name, params),
|
|
@@ -584,13 +601,17 @@ function makeTypedSurface(raw2) {
|
|
|
584
601
|
update: (table, id, data) => raw2.update(table, id, data),
|
|
585
602
|
delete: (table, id) => raw2.delete(table, id),
|
|
586
603
|
findById: (table, id) => raw2.findById(table, id),
|
|
587
|
-
findMany: (table, query) => raw2.findMany(table, query),
|
|
604
|
+
findMany: (table, query, opts) => raw2.findMany(table, query, opts),
|
|
605
|
+
upsert: (table, data, opts) => raw2.upsert(table, data, opts),
|
|
588
606
|
search: (table, params) => raw2.search(table, params),
|
|
589
607
|
similar: (table, id, params) => reco.similar(table, id, params),
|
|
590
608
|
recommend: (table, params) => reco.recommend(table, params),
|
|
591
609
|
supersede: (table, id, row) => raw2.supersede(table, id, row)
|
|
592
610
|
};
|
|
593
611
|
return Object.assign(ops, {
|
|
612
|
+
// Both surfaces get it: a savepoint on the service transaction is as useful
|
|
613
|
+
// as one on the request's, and each is bound to its own connection.
|
|
614
|
+
attempt: (fn) => raw2.attempt(fn),
|
|
594
615
|
tables: makeTablesAccessor(() => reco),
|
|
595
616
|
transaction(fn) {
|
|
596
617
|
const builder = new TxPlanBuilder();
|
|
@@ -1573,6 +1594,9 @@ function buildModuleClients(cfg) {
|
|
|
1573
1594
|
}
|
|
1574
1595
|
|
|
1575
1596
|
// src/db/policy.ts
|
|
1597
|
+
function quote(name) {
|
|
1598
|
+
return `"${name.replace(/"/g, '""')}"`;
|
|
1599
|
+
}
|
|
1576
1600
|
var PolicyBuilder = class {
|
|
1577
1601
|
_def;
|
|
1578
1602
|
constructor(name) {
|
|
@@ -1608,6 +1632,41 @@ var PolicyBuilder = class {
|
|
|
1608
1632
|
this._def.using = sqlExpr;
|
|
1609
1633
|
return this;
|
|
1610
1634
|
}
|
|
1635
|
+
/**
|
|
1636
|
+
* "Rows of THIS table whose owner the caller is a member of" — the membership
|
|
1637
|
+
* pattern, written so it cannot recurse.
|
|
1638
|
+
*
|
|
1639
|
+
* THE TRAP IT EXISTS FOR. Written by hand, membership policies point at each
|
|
1640
|
+
* other: `channels` is visible to members, so its policy reads
|
|
1641
|
+
* `channel_members`; `channel_members` is visible to members, so its policy
|
|
1642
|
+
* reads `channels`. Postgres refuses the pair at query time with `infinite
|
|
1643
|
+
* recursion detected in policy for relation ...`, and the error names the
|
|
1644
|
+
* relation but not the cycle. The way out is asymmetry — the MEMBERSHIP table
|
|
1645
|
+
* is protected by `user_id = auth.uid()` and nothing else, and every other
|
|
1646
|
+
* table subqueries INTO it. That shape was in the platform's own schema and
|
|
1647
|
+
* written down nowhere; a customer recovered it by reading that schema.
|
|
1648
|
+
*
|
|
1649
|
+
* `(select auth.uid())` rather than a bare call: the scalar subquery is
|
|
1650
|
+
* evaluated ONCE per statement instead of per row.
|
|
1651
|
+
*
|
|
1652
|
+
* @example
|
|
1653
|
+
* // channels: visible to members. The membership table gets the simple one.
|
|
1654
|
+
* policy("member_read").for("select").to("authenticated")
|
|
1655
|
+
* .memberOf("channel_members", "channel_id")
|
|
1656
|
+
* // → id IN (SELECT "channel_id" FROM "channel_members"
|
|
1657
|
+
* // WHERE "user_id" = (select auth.uid()))
|
|
1658
|
+
*/
|
|
1659
|
+
memberOf(membershipTable, foreignKey, options = {}) {
|
|
1660
|
+
if (this._def.using !== null) {
|
|
1661
|
+
throw new Error(
|
|
1662
|
+
`policy(${this._def.name}).memberOf(): this policy already has a using() expression. Write one or the other \u2014 memberOf IS the using expression.`
|
|
1663
|
+
);
|
|
1664
|
+
}
|
|
1665
|
+
const column = options.column ?? "id";
|
|
1666
|
+
const userColumn = options.userColumn ?? "user_id";
|
|
1667
|
+
this._def.using = `${quote(column)} IN (SELECT ${quote(foreignKey)} FROM ${quote(membershipTable)} WHERE ${quote(userColumn)} = (select auth.uid()))`;
|
|
1668
|
+
return this;
|
|
1669
|
+
}
|
|
1611
1670
|
/** Set the `WITH CHECK (...)` write-validation expression (raw SQL). */
|
|
1612
1671
|
withCheck(sqlExpr) {
|
|
1613
1672
|
this._def.withCheck = sqlExpr;
|
|
@@ -2033,6 +2092,21 @@ var ColumnBuilder = class _ColumnBuilder {
|
|
|
2033
2092
|
this._def.defaultNow = true;
|
|
2034
2093
|
return new _ColumnBuilder(this._def.type, this._def);
|
|
2035
2094
|
}
|
|
2095
|
+
/**
|
|
2096
|
+
* The DATABASE assigns this column's value — a trigger, a rule, an identity.
|
|
2097
|
+
*
|
|
2098
|
+
* The column becomes optional on INSERT (the author has nothing to send) while
|
|
2099
|
+
* the DDL stays free of a DEFAULT this schema would not honour. It is NOT
|
|
2100
|
+
* `default()`: that declares a value the schema promises to write.
|
|
2101
|
+
*
|
|
2102
|
+
* Naming: deliberately not `generated()`. Postgres has GENERATED columns and
|
|
2103
|
+
* they are a different thing; borrowing the word would send a reader — or a
|
|
2104
|
+
* model writing a schema — to the wrong feature.
|
|
2105
|
+
*/
|
|
2106
|
+
dbAssigned() {
|
|
2107
|
+
this._def.dbAssigned = true;
|
|
2108
|
+
return new _ColumnBuilder(this._def.type, this._def);
|
|
2109
|
+
}
|
|
2036
2110
|
/** Add a foreign key reference. */
|
|
2037
2111
|
/**
|
|
2038
2112
|
* Declares that this column used to be called `previous`.
|
|
@@ -2180,10 +2254,11 @@ var openai = {
|
|
|
2180
2254
|
function makeTypedTable(name, raw2) {
|
|
2181
2255
|
return {
|
|
2182
2256
|
insert: (data) => raw2.insert(name, data),
|
|
2257
|
+
upsert: (data, opts) => raw2.upsert(name, data, opts),
|
|
2183
2258
|
update: (id, data) => raw2.update(name, id, data),
|
|
2184
2259
|
delete: (id) => raw2.delete(name, id),
|
|
2185
2260
|
findById: (id) => raw2.findById(name, id),
|
|
2186
|
-
findMany: (query) => raw2.findMany(name, query)
|
|
2261
|
+
findMany: (query, opts) => raw2.findMany(name, query, opts)
|
|
2187
2262
|
};
|
|
2188
2263
|
}
|
|
2189
2264
|
function makeTypedDB(schema, raw2) {
|
|
@@ -2750,6 +2825,29 @@ function validateUploadConfigShape(c) {
|
|
|
2750
2825
|
}
|
|
2751
2826
|
}
|
|
2752
2827
|
|
|
2828
|
+
// src/decorators/sse.ts
|
|
2829
|
+
function Sse(subpath = "", config) {
|
|
2830
|
+
const { auth, rateLimit, ...sseConfig } = config;
|
|
2831
|
+
const options = {
|
|
2832
|
+
sseConfig,
|
|
2833
|
+
...auth !== void 0 ? { auth } : {},
|
|
2834
|
+
...rateLimit !== void 0 ? { rateLimit } : {}
|
|
2835
|
+
};
|
|
2836
|
+
return function(target, propertyKey) {
|
|
2837
|
+
recordRoute(target, String(propertyKey), "POST", subpath, options);
|
|
2838
|
+
};
|
|
2839
|
+
}
|
|
2840
|
+
function SseOut() {
|
|
2841
|
+
return function(target, propertyKey, parameterIndex) {
|
|
2842
|
+
recordParam(target, String(propertyKey), { index: parameterIndex, kind: "sseOut" });
|
|
2843
|
+
};
|
|
2844
|
+
}
|
|
2845
|
+
function Signal() {
|
|
2846
|
+
return function(target, propertyKey, parameterIndex) {
|
|
2847
|
+
recordParam(target, String(propertyKey), { index: parameterIndex, kind: "signal" });
|
|
2848
|
+
};
|
|
2849
|
+
}
|
|
2850
|
+
|
|
2753
2851
|
// src/decorators/params.ts
|
|
2754
2852
|
function makeParamDecorator(kind, extra) {
|
|
2755
2853
|
return function(target, propertyKey, parameterIndex) {
|
|
@@ -3156,6 +3254,9 @@ var import_zod2 = require("zod");
|
|
|
3156
3254
|
Req,
|
|
3157
3255
|
RequestId,
|
|
3158
3256
|
Secrets,
|
|
3257
|
+
Signal,
|
|
3258
|
+
Sse,
|
|
3259
|
+
SseOut,
|
|
3159
3260
|
Storage,
|
|
3160
3261
|
TooManyRequests,
|
|
3161
3262
|
TraceId,
|