@protobase/cli 0.66.11 → 0.66.12
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/cli/package.js +1 -1
- package/dist/doctor/built-in-models.js +10 -1
- package/dist/doctor/run.js +2 -2
- package/package.json +7 -7
- package/skills/protobase/references/reference/cli.md +1 -1
- package/skills/protobase/references/reference/comments.md +1 -1
- package/skills/protobase/references/reference/history.md +1 -1
- package/skills/protobase/references/reference/webhooks.md +1 -1
package/dist/cli/package.js
CHANGED
|
@@ -22,5 +22,14 @@ const builtInModels = (config, models) => {
|
|
|
22
22
|
views: [...webhooks.views, ...added.views].map((view) => view.toModel())
|
|
23
23
|
};
|
|
24
24
|
};
|
|
25
|
+
/**
|
|
26
|
+
* A missing index on a built-in table as a recommendation: the app owns its schema, so a database migrated by an earlier
|
|
27
|
+
* version still serves, and only the reads that need the index are refused until `protobase migration` writes it.
|
|
28
|
+
*/
|
|
29
|
+
const builtInIndexIssues = (issues) => issues.map((issue) => ({
|
|
30
|
+
...issue,
|
|
31
|
+
severity: "warning",
|
|
32
|
+
suggestion: `write it as a migration with \`protobase migration\` (${issue.suggestion})`
|
|
33
|
+
}));
|
|
25
34
|
//#endregion
|
|
26
|
-
export { builtInModels };
|
|
35
|
+
export { builtInIndexIssues, builtInModels };
|
package/dist/doctor/run.js
CHANGED
|
@@ -3,7 +3,7 @@ import { connect } from "../db/connect.js";
|
|
|
3
3
|
import { introspect } from "../db/introspect.js";
|
|
4
4
|
import { loadDataConfig } from "../project/load-data-config.js";
|
|
5
5
|
import { readOnlyDb } from "../db/read-only-db.js";
|
|
6
|
-
import { builtInModels } from "./built-in-models.js";
|
|
6
|
+
import { builtInIndexIssues, builtInModels } from "./built-in-models.js";
|
|
7
7
|
import { checkResource } from "./check.js";
|
|
8
8
|
import { indexIssues } from "./index-issues.js";
|
|
9
9
|
import { readShapes } from "./read-shapes.js";
|
|
@@ -28,7 +28,7 @@ const runDoctor = async (options, out) => {
|
|
|
28
28
|
views: [...builtIn.views, ...config.views],
|
|
29
29
|
pages: config.pages
|
|
30
30
|
});
|
|
31
|
-
const indexes = await Promise.all(models.map(async (model) => indexIssues(model, await tableIndexes(db, model), shapes))).finally(() => db.destroy());
|
|
31
|
+
const indexes = await Promise.all(models.map(async (model) => indexIssues(model, await tableIndexes(db, model), shapes))).then((found) => found.map((issues, i) => i < builtIn.models.length ? builtInIndexIssues(issues) : issues)).finally(() => db.destroy());
|
|
32
32
|
const issues = models.flatMap((model, i) => [
|
|
33
33
|
...checkResource(model, tables),
|
|
34
34
|
...relationIssues(model, models),
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@protobase/cli",
|
|
3
|
-
"version": "0.66.
|
|
3
|
+
"version": "0.66.12",
|
|
4
4
|
"description": "The protobase command: scaffold, doctor, dev, build and serve a Protobase project.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"repository": {
|
|
@@ -43,12 +43,12 @@
|
|
|
43
43
|
"dependencies": {
|
|
44
44
|
"@better-auth/core": "^1.7.12",
|
|
45
45
|
"@hono/node-server": "^2.1.3",
|
|
46
|
-
"@protobase/config": "0.66.
|
|
47
|
-
"@protobase/layout": "0.66.
|
|
48
|
-
"@protobase/query": "0.66.
|
|
49
|
-
"@protobase/schema": "0.66.
|
|
50
|
-
"@protobase/server": "0.66.
|
|
51
|
-
"@protobase/ui": "0.66.
|
|
46
|
+
"@protobase/config": "0.66.12",
|
|
47
|
+
"@protobase/layout": "0.66.12",
|
|
48
|
+
"@protobase/query": "0.66.12",
|
|
49
|
+
"@protobase/schema": "0.66.12",
|
|
50
|
+
"@protobase/server": "0.66.12",
|
|
51
|
+
"@protobase/ui": "0.66.12",
|
|
52
52
|
"@react-email/render": "^2.1.0",
|
|
53
53
|
"@scalar/hono-api-reference": "^0.12.10",
|
|
54
54
|
"@sentry/vite-plugin": "^11.10.0",
|
|
@@ -107,7 +107,7 @@ protobase doctor [connection string | --env VAR] [--config <dir>]
|
|
|
107
107
|
|
|
108
108
|
The URL comes as for [`scaffold`](#scaffold): the connection string, the variable `--env` names, or `DATABASE_URL`, each also read from the nearest `.env`.
|
|
109
109
|
|
|
110
|
-
Imports `config/index.ts` and the views of `config/*/ui.ts`, as the config module has them by convention, and checks every exported resource against the database, with the resources Protobase adds by what `protobase.config.ts` (read with `command: 'tool'`) and the resources enable: the [webhook](webhooks.md#subscriptions-in-the-admin-app) ones of `webhooks`, Failed jobs, [Activity](history.md) and [Comments](comments.md). The tables [`migration`](#migration) writes for those have every index their reads need, so after the project's migrations they pass:
|
|
110
|
+
Imports `config/index.ts` and the views of `config/*/ui.ts`, as the config module has them by convention, and checks every exported resource against the database, with the resources Protobase adds by what `protobase.config.ts` (read with `command: 'tool'`) and the resources enable: the [webhook](webhooks.md#subscriptions-in-the-admin-app) ones of `webhooks`, Failed jobs, [Activity](history.md) and [Comments](comments.md). The tables [`migration`](#migration) writes for those have every index their reads need, so after the project's migrations they pass; a read of theirs that lacks an index, as on a table an earlier version wrote, is a warning to run `migration`, since the app owns its schema:
|
|
111
111
|
|
|
112
112
|
- error: missing table or column, field type that does not fit the column (a file field needs a text column), table without a usable key, configured key not backed by a unique index, `.openExisting()` fields that are not the columns of a unique index, relation to a resource the config does not declare
|
|
113
113
|
- error: a read the [scan guard](api.md#safety) refuses, because no index serves a column it filters, sorts, searches or counts by. Doctor reads each table's indexes from the catalog, as the server does, and judges with the scan guard's own rule every read the API takes and the app makes: a filter on each `.filterable()` field, a sort by each `.sortable()` one, `search()` over the search fields, a role's own records (`.owner()`) and the names a relation shows; each view's list in its order and with the filter it opens with, its filter widgets and their counts, its chart, its map, board, calendar and timeline, its card photos, its order by hand, its related sections, galleries and charts, its named lists, its recent records and a saved search's new records; and each block of a [composed page](layouts.md) that lists records, and each `Chart` block's grouped and split fields. Each error is an index to add, with every request that needs it and where it comes from:
|
|
@@ -64,7 +64,7 @@ Once a resource takes comments, admins get **Comments** (the built-in resource `
|
|
|
64
64
|
|
|
65
65
|
## The table
|
|
66
66
|
|
|
67
|
-
[`protobase migration`](cli.md#migration) adds the schema `comments` with the table `comments.comments`; apply it with the project's other migrations. It has an index for each column the Comments list filters on, and the next migration adds one an earlier version's table lacks. `protobase dev` and `protobase serve` do not start while a resource has comments and the table
|
|
67
|
+
[`protobase migration`](cli.md#migration) adds the schema `comments` with the table `comments.comments`; apply it with the project's other migrations. It has an index for each column the Comments list filters on, and the next migration adds one an earlier version's table lacks. `protobase dev` and `protobase serve` do not start while a resource has comments and the table is missing; without an index added since, they start, and only the Comments list's reads that need it are refused. A deleted record's comments stay in the table.
|
|
68
68
|
|
|
69
69
|
| Column | |
|
|
70
70
|
| --- | --- |
|
|
@@ -71,7 +71,7 @@ Once a resource has history, admins get **Activity** (the built-in resource `rec
|
|
|
71
71
|
|
|
72
72
|
## The table
|
|
73
73
|
|
|
74
|
-
[`protobase migration`](cli.md#migration) adds the table `changes.history` to the `changes` schema of the event capture (renamed with `events: { schema }`), and the capture triggers of each resource with history; apply it with the project's other migrations. It has an index for each column the Activity list filters on, and the next migration adds one an earlier version's table lacks. `protobase dev` and `protobase serve` do not start while the table,
|
|
74
|
+
[`protobase migration`](cli.md#migration) adds the table `changes.history` to the `changes` schema of the event capture (renamed with `events: { schema }`), and the capture triggers of each resource with history; apply it with the project's other migrations. It has an index for each column the Activity list filters on, and the next migration adds one an earlier version's table lacks. `protobase dev` and `protobase serve` do not start while the table or a trigger is missing; without an index added since, they start, and only the Activity list's reads that need it are refused. A resource that drops `.history()` loses its triggers, unless it has events, at the next migration; its changes stay in the table.
|
|
75
75
|
|
|
76
76
|
| Column | |
|
|
77
77
|
| --- | --- |
|
|
@@ -116,7 +116,7 @@ It adds two pages, over a `webhooks` schema that [`protobase migration`](cli.md#
|
|
|
116
116
|
- **Webhook subscriptions** (`webhook_subscriptions`, the table `webhooks.subscriptions`): a name, the events (`orders.created orders.large`, or `orders.*`), the URL, a filter, extra headers, full or thin payload, and whether it is enabled. The server sets the tenant and the owner, the person who made it, and makes the secret, which only a [reveal](api.md#sensitive-fields-and-audit) shows. Saving checks the events and the filter against the resources, and refuses a URL whose host is a private, loopback or link-local address.
|
|
117
117
|
- **Webhook deliveries** (`webhook_deliveries`, a view over the delivery jobs): the deliveries that wait for their next try or failed for good, with their last error. A delivery leaves the list once it succeeds.
|
|
118
118
|
|
|
119
|
-
The migration gives the subscriptions table an index for each sort, filter and search of its list, and creates the `pg_trgm` extension the search's indexes need (`create extension if not exists pg_trgm`, a trusted extension since Postgres 13, so any role that may create in the database can). A database that has an earlier version's schema gets the indexes from the next `protobase migration`; the server
|
|
119
|
+
The migration gives the subscriptions table an index for each sort, filter and search of its list, and creates the `pg_trgm` extension the search's indexes need (`create extension if not exists pg_trgm`, a trusted extension since Postgres 13, so any role that may create in the database can). A database that has an earlier version's schema gets the indexes from the next `protobase migration`; until it is applied the server still starts, and refuses only the list's reads that need them.
|
|
120
120
|
|
|
121
121
|
Both are scoped to the tenant like any resource with `.tenant()`, and their access decides who may do what: `webhook_subscriptions.create`, `webhook_deliveries.update` and so on, as for the app's own resources. A role's wildcard over resources, such as `*.read`, grants none of them: their URLs and secrets let whoever reads them call the receivers, so with roles only admins (`*`) and roles that [name them](access.md#resources-that-need-named-grants) manage webhook subscriptions.
|
|
122
122
|
|