@protobase/server 0.66.11 → 0.66.13
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/changes/capture-plan.js +3 -2
- package/dist/changes/capture-schema.js +5 -2
- package/dist/comments/comments-sql.d.ts +4 -1
- package/dist/comments/comments-sql.js +7 -4
- package/dist/package.js +1 -1
- package/dist/webhooks/table/schema-sql.js +6 -1
- package/dist/webhooks/table/schema.d.ts +4 -1
- package/dist/webhooks/table/schema.js +10 -4
- package/package.json +4 -4
|
@@ -35,7 +35,8 @@ const capturePlan = (schema, models, state) => {
|
|
|
35
35
|
const drop = state.triggers.filter((found) => found.function === capture?.oid).filter((found) => !wanted.some(({ trigger, table }) => table === found.table && trigger.name === found.name));
|
|
36
36
|
return {
|
|
37
37
|
setup: captured.length > 0 && (!state.outbox || !current),
|
|
38
|
-
history: models.some((model) => model.history) && !state.history,
|
|
38
|
+
history: models.some((model) => model.history) && (!state.history || !state.historyIndexed),
|
|
39
|
+
historyMissing: models.some((model) => model.history) && !state.history,
|
|
39
40
|
notices: models.some((model) => model.live) && !state.notices,
|
|
40
41
|
create: create.map(({ model, trigger }) => ({
|
|
41
42
|
model,
|
|
@@ -65,7 +66,7 @@ const planSql = (schema, plan) => {
|
|
|
65
66
|
/** The resources whose changes would not be captured or kept as the config declares: what a server refuses to start with. */
|
|
66
67
|
const uncaptured = (plan, models) => [...new Set([
|
|
67
68
|
...plan.setup ? models.filter(isCaptured) : plan.create.map(({ model }) => model),
|
|
68
|
-
...plan.
|
|
69
|
+
...plan.historyMissing ? models.filter((model) => model.history) : [],
|
|
69
70
|
...plan.notices ? models.filter((model) => model.live) : []
|
|
70
71
|
].map((model) => model.name))];
|
|
71
72
|
//#endregion
|
|
@@ -25,9 +25,12 @@ const readCaptureState = async (db, schema, models) => {
|
|
|
25
25
|
t.tgfoid::text as "function", t.tgtype::int as type, encode(t.tgargs, 'hex') as args
|
|
26
26
|
from pg_trigger t join pg_class c on c.oid = t.tgrelid join pg_namespace ns on ns.oid = c.relnamespace
|
|
27
27
|
where not t.tgisinternal and (t.tgfoid::text = ${capture?.oid ?? ""} or t.tgrelid::text = any(${oids}::text[]))`);
|
|
28
|
+
const outbox = await exists("outbox");
|
|
29
|
+
const history = await exists("history");
|
|
28
30
|
return {
|
|
29
|
-
outbox
|
|
30
|
-
history
|
|
31
|
+
outbox,
|
|
32
|
+
history,
|
|
33
|
+
historyIndexed: history && await hasIndexes(db, schema, "history", historyIndexes.map(([name]) => name)),
|
|
31
34
|
notices: await exists("notices"),
|
|
32
35
|
...capture && { capture },
|
|
33
36
|
triggers: triggers.map((trigger) => ({
|
|
@@ -6,6 +6,9 @@ import { Db } from "@protobase/query";
|
|
|
6
6
|
* table is never dropped.
|
|
7
7
|
*/
|
|
8
8
|
export declare const commentsMigration: (db: Db) => Promise<string | undefined>;
|
|
9
|
-
/**
|
|
9
|
+
/**
|
|
10
|
+
* Refuses to go on while a resource has `.comments()` and the database lacks their table; the project's migrations add
|
|
11
|
+
* it. An index added since only speeds reads up, so a table without it still serves and `protobase migration` adds it.
|
|
12
|
+
*/
|
|
10
13
|
export declare const checkComments: (db: Db, models: readonly ResourceModel[]) => Promise<void>;
|
|
11
14
|
//#endregion
|
|
@@ -27,20 +27,23 @@ const commentsTableSql = () => `create table if not exists ${commentsTable} (
|
|
|
27
27
|
"created_at" timestamptz not null default now()
|
|
28
28
|
);
|
|
29
29
|
${commentsIndexes.map(([name, columns]) => `create index if not exists "${name}" on ${commentsTable} (${columns})`).join(";\n")}`;
|
|
30
|
-
const hasCommentsTable = async (db) => (await sql`select to_regclass('comments.comments') is not null as found`.execute(db)).rows[0].found
|
|
30
|
+
const hasCommentsTable = async (db) => (await sql`select to_regclass('comments.comments') is not null as found`.execute(db)).rows[0].found;
|
|
31
31
|
/**
|
|
32
32
|
* The SQL that adds the `comments` schema and its table, or the indexes it lacks, `undefined` when it has them all. The
|
|
33
33
|
* table is never dropped.
|
|
34
34
|
*/
|
|
35
35
|
const commentsMigration = async (db) => {
|
|
36
|
-
if (await hasCommentsTable(db)) return void 0;
|
|
36
|
+
if (await hasCommentsTable(db) && await hasIndexes(db, "comments", "comments", commentsIndexes.map(([name]) => name))) return void 0;
|
|
37
37
|
return `create schema if not exists "comments";\n\n${commentsTableSql()};`;
|
|
38
38
|
};
|
|
39
|
-
/**
|
|
39
|
+
/**
|
|
40
|
+
* Refuses to go on while a resource has `.comments()` and the database lacks their table; the project's migrations add
|
|
41
|
+
* it. An index added since only speeds reads up, so a table without it still serves and `protobase migration` adds it.
|
|
42
|
+
*/
|
|
40
43
|
const checkComments = async (db, models) => {
|
|
41
44
|
if (!models.some((model) => model.comments)) return;
|
|
42
45
|
if (await hasCommentsTable(db)) return;
|
|
43
|
-
throw new Error(`The comments schema is missing
|
|
46
|
+
throw new Error(`The comments schema is missing, and resources with .comments() keep their comments in comments.comments. Write it as a migration with \`${migrationCommand}\`, apply it with the project's migrations, then start again.`);
|
|
44
47
|
};
|
|
45
48
|
//#endregion
|
|
46
49
|
export { checkComments, commentsMigration, commentsTable, commentsTableSql };
|
package/dist/package.js
CHANGED
|
@@ -2,6 +2,11 @@ import { jobsSchema } from "../../jobs/schema.js";
|
|
|
2
2
|
import { quoteIdent } from "../../changes/capture-sql.js";
|
|
3
3
|
/** The comment the schema's functions carry, which the startup check reads. */
|
|
4
4
|
const webhooksComment = `Protobase webhooks 2`;
|
|
5
|
+
/** The version a function's comment names, `undefined` when it is not one Protobase wrote. */
|
|
6
|
+
const commentVersion = (comment) => {
|
|
7
|
+
const match = comment?.match(/^Protobase webhooks (\d+)$/);
|
|
8
|
+
return match ? Number(match[1]) : void 0;
|
|
9
|
+
};
|
|
5
10
|
/** The delivery jobs, whose waiting and failed ones the deliveries view lists. */
|
|
6
11
|
const deliveryJobs = ["webhooks.deliver", "webhooks.deliver-ordered"];
|
|
7
12
|
/** The job that sends a subscription a test event. */
|
|
@@ -137,4 +142,4 @@ create index if not exists "delivery_log_status" on ${table} ("status");
|
|
|
137
142
|
create index if not exists "delivery_log_status_code" on ${table} ("status_code")`;
|
|
138
143
|
};
|
|
139
144
|
//#endregion
|
|
140
|
-
export { commandsSql, deliveriesSql, deliveryJobs, deliveryLogIndexesSql, deliveryLogSql, sendTestJob, subscriptionsIndexesSql, subscriptionsSql, webhooksComment };
|
|
145
|
+
export { commandsSql, commentVersion, deliveriesSql, deliveryJobs, deliveryLogIndexesSql, deliveryLogSql, sendTestJob, subscriptionsIndexesSql, subscriptionsSql, webhooksComment };
|
|
@@ -8,6 +8,9 @@ import { Db } from "@protobase/query";
|
|
|
8
8
|
* deliveries view reads. Tables are never dropped.
|
|
9
9
|
*/
|
|
10
10
|
export declare const webhooksMigration: (db: Db, options?: WebhooksOptions, events?: EventsOptions) => Promise<string | undefined>;
|
|
11
|
-
/**
|
|
11
|
+
/**
|
|
12
|
+
* Refuses to go on while the `webhooks` schema lacks what `webhooks` needs; the project's migrations add it. A schema
|
|
13
|
+
* written by an earlier version this one still serves on starts, and `protobase migration` brings it current.
|
|
14
|
+
*/
|
|
12
15
|
export declare const checkWebhooksSchema: (db: Db, options?: WebhooksOptions) => Promise<void>;
|
|
13
16
|
//#endregion
|
|
@@ -2,7 +2,7 @@ import { quoteIdent } from "../../changes/capture-sql.js";
|
|
|
2
2
|
import { changesSchema } from "../../changes/events-options.js";
|
|
3
3
|
import { migrationCommand } from "../../changes/capture-schema.js";
|
|
4
4
|
import { webhooksSchema } from "./options.js";
|
|
5
|
-
import { commandsSql, deliveriesSql, deliveryLogIndexesSql, deliveryLogSql, subscriptionsIndexesSql, subscriptionsSql
|
|
5
|
+
import { commandsSql, commentVersion, deliveriesSql, deliveryLogIndexesSql, deliveryLogSql, subscriptionsIndexesSql, subscriptionsSql } from "./schema-sql.js";
|
|
6
6
|
import { sql } from "kysely";
|
|
7
7
|
//#region src/webhooks/table/schema.ts
|
|
8
8
|
const functionNames = ["subscription_commands", "deliveries_resend"];
|
|
@@ -10,9 +10,12 @@ const readWebhooksSchema = async (db, schema) => {
|
|
|
10
10
|
const exists = async (table) => (await sql`select to_regclass(${`${quoteIdent(schema)}.${quoteIdent(table)}`}) is not null as found`.execute(db)).rows[0].found;
|
|
11
11
|
const { rows } = await sql`select p.proname as name, obj_description(p.oid, 'pg_proc') as comment
|
|
12
12
|
from pg_proc p join pg_namespace n on n.oid = p.pronamespace where n.nspname = ${schema} and p.proname = any(${functionNames}::text[]) order by p.proname`.execute(db);
|
|
13
|
+
const versions = functionNames.map((name) => commentVersion(rows.find((row) => row.name === name)?.comment ?? null));
|
|
14
|
+
const version = await exists("deliveries") && versions.every((found) => found !== void 0) ? Math.min(...versions) : void 0;
|
|
13
15
|
return {
|
|
14
16
|
subscriptions: await exists("subscriptions"),
|
|
15
|
-
current:
|
|
17
|
+
current: version === 2,
|
|
18
|
+
served: version !== void 0 && version >= 1,
|
|
16
19
|
deliveryLog: await exists("delivery_log")
|
|
17
20
|
};
|
|
18
21
|
};
|
|
@@ -39,11 +42,14 @@ const webhooksMigration = async (db, options = {}, events) => {
|
|
|
39
42
|
...needsLog || !current && found.deliveryLog ? [deliveryLogIndexesSql(schema)] : []
|
|
40
43
|
].join(";\n\n")};`;
|
|
41
44
|
};
|
|
42
|
-
/**
|
|
45
|
+
/**
|
|
46
|
+
* Refuses to go on while the `webhooks` schema lacks what `webhooks` needs; the project's migrations add it. A schema
|
|
47
|
+
* written by an earlier version this one still serves on starts, and `protobase migration` brings it current.
|
|
48
|
+
*/
|
|
43
49
|
const checkWebhooksSchema = async (db, options = {}) => {
|
|
44
50
|
const schema = webhooksSchema(options);
|
|
45
51
|
const found = await readWebhooksSchema(db, schema);
|
|
46
|
-
if (found.subscriptions && found.
|
|
52
|
+
if (found.subscriptions && found.served && (!options.deliveryLog || found.deliveryLog)) return;
|
|
47
53
|
throw new Error(`The ${schema} schema is missing or behind this version of Protobase. Write it as a migration with \`${migrationCommand}\`, apply it with the project's migrations, then start again.`);
|
|
48
54
|
};
|
|
49
55
|
//#endregion
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@protobase/server",
|
|
3
|
-
"version": "0.66.
|
|
3
|
+
"version": "0.66.13",
|
|
4
4
|
"description": "The Protobase REST API as a Hono app, with Better Auth sign-in.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"repository": {
|
|
@@ -43,9 +43,9 @@
|
|
|
43
43
|
"@better-auth/sso": "^1.7.12",
|
|
44
44
|
"@livekit/protocol": "1.53.1",
|
|
45
45
|
"@modelcontextprotocol/server": "^2.3.1",
|
|
46
|
-
"@protobase/layout": "0.66.
|
|
47
|
-
"@protobase/query": "0.66.
|
|
48
|
-
"@protobase/schema": "0.66.
|
|
46
|
+
"@protobase/layout": "0.66.13",
|
|
47
|
+
"@protobase/query": "0.66.13",
|
|
48
|
+
"@protobase/schema": "0.66.13",
|
|
49
49
|
"@react-email/render": "^2.1.0",
|
|
50
50
|
"@react-pdf/primitives": "^4.4.0",
|
|
51
51
|
"@react-pdf/renderer": "^4.9.0",
|