@rebasepro/server-postgres 0.24.0 → 0.24.1-canary.g19596ef
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 +16 -0
- package/dist/{BranchService-BRt78gfa.js → BranchService-UgKa416x.js} +14 -3
- package/dist/BranchService-UgKa416x.js.map +1 -0
- package/dist/PostgresBackendDriver.d.ts +104 -2
- package/dist/PostgresBootstrapper.d.ts +101 -2
- package/dist/auth/ensure-tables.d.ts +12 -0
- package/dist/auth/services.d.ts +6 -0
- package/dist/backup/backup-cli.d.ts +75 -2
- package/dist/backup/backup-service.d.ts +2 -2
- package/dist/backup/pg-binary.d.ts +5 -0
- package/dist/{backup-cli-DW5p9_zv.js → backup-cli-yiKd1GsC.js} +168 -75
- package/dist/backup-cli-yiKd1GsC.js.map +1 -0
- package/dist/{backup-service-EwcDVG-8.js → backup-service-AZWc2wvI.js} +99 -28
- package/dist/backup-service-AZWc2wvI.js.map +1 -0
- package/dist/boot-ddl-B9ZmBJ75.js +105 -0
- package/dist/boot-ddl-B9ZmBJ75.js.map +1 -0
- package/dist/cli-console-DGee3Zl7.js +225 -0
- package/dist/cli-console-DGee3Zl7.js.map +1 -0
- package/dist/cli-console.d.ts +39 -0
- package/dist/cli-errors-oVUuD8k0.js +2180 -0
- package/dist/cli-errors-oVUuD8k0.js.map +1 -0
- package/dist/cli-errors.d.ts +91 -9
- package/dist/{cli-flags-BglvpjHv.js → cli-flags-DnPHXjRH.js} +56 -6
- package/dist/cli-flags-DnPHXjRH.js.map +1 -0
- package/dist/cli-flags.d.ts +15 -0
- package/dist/cli-helpers.d.ts +76 -22
- package/dist/cli-output.d.ts +16 -28
- package/dist/{arg-Dni7MzLB.js → cli-prompt-egtNKkZl.js} +49 -3
- package/dist/cli-prompt-egtNKkZl.js.map +1 -0
- package/dist/cli-prompt.d.ts +19 -0
- package/dist/cli-push.d.ts +87 -0
- package/dist/cli-scratch-database.d.ts +33 -8
- package/dist/cli.js +764 -222
- package/dist/cli.js.map +1 -1
- package/dist/{column-plan-helpers-1-LQD0yI.js → column-plan-helpers-D_V4oaZh.js} +11 -5
- package/dist/{column-plan-helpers-1-LQD0yI.js.map → column-plan-helpers-D_V4oaZh.js.map} +1 -1
- package/dist/{databasePoolManager-Bj5FbeAs.js → connection-C938nR3E.js} +25 -113
- package/dist/connection-C938nR3E.js.map +1 -0
- package/dist/connection.d.ts +13 -2
- package/dist/databasePoolManager-DZgnBOgj.js +119 -0
- package/dist/databasePoolManager-DZgnBOgj.js.map +1 -0
- package/dist/{ensure-collection-tables-kkkHk8oo.js → deferred-index-build-BqmEHGaD.js} +485 -347
- package/dist/deferred-index-build-BqmEHGaD.js.map +1 -0
- package/dist/{doctor-C-sYWbmt.js → doctor-CUAAOFZm.js} +65 -54
- package/dist/doctor-CUAAOFZm.js.map +1 -0
- package/dist/ensure-collection-policies-Bb51V2OV.js +541 -0
- package/dist/ensure-collection-policies-Bb51V2OV.js.map +1 -0
- package/dist/ensure-collection-tables-egjGBjhv.js +532 -0
- package/dist/ensure-collection-tables-egjGBjhv.js.map +1 -0
- package/dist/{ensure-tables-BmI_tRxc.js → ensure-tables-DMPWhJ6R.js} +174 -78
- package/dist/ensure-tables-DMPWhJ6R.js.map +1 -0
- package/dist/enum-labels-kept-Msq5gMcb.js +56 -0
- package/dist/enum-labels-kept-Msq5gMcb.js.map +1 -0
- package/dist/generate-drizzle-schema-DrA-YgXv.js +57 -0
- package/dist/generate-drizzle-schema-DrA-YgXv.js.map +1 -0
- package/dist/{generate-drizzle-schema-logic-sSFDp6LR.js → generate-drizzle-schema-logic-BaT0H7Gq.js} +6 -6
- package/dist/generate-drizzle-schema-logic-BaT0H7Gq.js.map +1 -0
- package/dist/generate-files-OoRJLEdk.js +199 -0
- package/dist/generate-files-OoRJLEdk.js.map +1 -0
- package/dist/{generate-postgres-ddl-logic-BJsLaVNX.js → generate-postgres-ddl-logic-B4k9djAV.js} +4 -4
- package/dist/{generate-postgres-ddl-logic-BJsLaVNX.js.map → generate-postgres-ddl-logic-B4k9djAV.js.map} +1 -1
- package/dist/{generated-schema-staleness-Di9c4ZxN.js → generated-schema-staleness-BWN_PsMi.js} +2 -2
- package/dist/{generated-schema-staleness-Di9c4ZxN.js.map → generated-schema-staleness-BWN_PsMi.js.map} +1 -1
- package/dist/generated-sql.d.ts +8 -2
- package/dist/history/HistoryService.d.ts +64 -5
- package/dist/history/ensure-history-table.d.ts +63 -4
- package/dist/index.d.ts +1 -0
- package/dist/index.es.js +139 -19236
- package/dist/index.es.js.map +1 -1
- package/dist/{introspect-db-logic-kCETE8TY.js → introspect-db-logic-BCc1Jym2.js} +136 -9
- package/dist/introspect-db-logic-BCc1Jym2.js.map +1 -0
- package/dist/{introspect-db-queries-C_Q5VgQw.js → introspect-db-queries-BhhJg0b8.js} +48 -1
- package/dist/introspect-db-queries-BhhJg0b8.js.map +1 -0
- package/dist/open-rebase-CAjWpPjs.js +20895 -0
- package/dist/open-rebase-CAjWpPjs.js.map +1 -0
- package/dist/open-rebase.d.ts +94 -0
- package/dist/pg-error-utils-Bs_Ue4wn.js +395 -0
- package/dist/pg-error-utils-Bs_Ue4wn.js.map +1 -0
- package/dist/{plan-schema-DU9exq6C.js → plan-schema-CsNgK0qi.js} +152 -42
- package/dist/plan-schema-CsNgK0qi.js.map +1 -0
- package/dist/{policy-drift-B-J2hhm0.js → policy-drift-BKC50y2p.js} +32 -8
- package/dist/policy-drift-BKC50y2p.js.map +1 -0
- package/dist/push-index-prebuild-C_qhyoJa.js +45 -0
- package/dist/push-index-prebuild-C_qhyoJa.js.map +1 -0
- package/dist/push-legacy-renames-5g9h3HOa.js +34 -0
- package/dist/push-legacy-renames-5g9h3HOa.js.map +1 -0
- package/dist/{render-ddl-Ds2t_d9V.js → render-ddl-CrfEe__B.js} +15 -10
- package/dist/render-ddl-CrfEe__B.js.map +1 -0
- package/dist/{rls-bootstrap-sql-_KNnjanK.js → rls-bootstrap-sql-Bd-hJk08.js} +125 -1325
- package/dist/rls-bootstrap-sql-Bd-hJk08.js.map +1 -0
- package/dist/{rls-enforcement-CfXOJJaW.js → rls-enforcement-D7P4-ZYX.js} +130 -18
- package/dist/rls-enforcement-D7P4-ZYX.js.map +1 -0
- package/dist/{__vite-browser-external-BnuHet1e.js → rolldown-runtime-V7rFbMRe.js} +1 -8
- package/dist/schema/atlas-exclude.d.ts +42 -0
- package/dist/schema/auth-schema.d.ts +2 -2
- package/dist/schema/boot-ddl.d.ts +47 -0
- package/dist/schema/carved-out-migration.d.ts +5 -4
- package/dist/schema/collection-index.d.ts +45 -0
- package/dist/schema/column-plan-helpers.d.ts +5 -0
- package/dist/schema/deferred-index-build.d.ts +131 -0
- package/dist/schema/destructive-sql.d.ts +30 -1
- package/dist/schema/doctor-cli.js +110 -6
- package/dist/schema/doctor-cli.js.map +1 -1
- package/dist/schema/doctor-search-scale.d.ts +45 -0
- package/dist/schema/doctor.d.ts +20 -1
- package/dist/schema/ensure-collection-policies.d.ts +73 -35
- package/dist/schema/ensure-collection-tables.d.ts +56 -3
- package/dist/schema/enum-labels-kept.d.ts +26 -0
- package/dist/schema/generate-drizzle-schema.js +1 -1
- package/dist/schema/generate-files.d.ts +44 -0
- package/dist/schema/generate-next-step.d.ts +0 -13
- package/dist/schema/generate-postgres-ddl.js +10 -81
- package/dist/schema/generate-postgres-ddl.js.map +1 -1
- package/dist/schema/generated-schema-diff.d.ts +7 -0
- package/dist/schema/introspect-db-logic.d.ts +32 -0
- package/dist/schema/introspect-db-queries.d.ts +20 -1
- package/dist/schema/introspect-db-structure.d.ts +10 -0
- package/dist/schema/introspect-db.js +16 -20
- package/dist/schema/introspect-db.js.map +1 -1
- package/dist/schema/migrate-baseline.d.ts +33 -0
- package/dist/schema/migration-post-process.d.ts +34 -0
- package/dist/schema/plan/diff-plan.d.ts +126 -0
- package/dist/schema/plan/render-ddl.d.ts +2 -1
- package/dist/schema/plan/types.d.ts +8 -0
- package/dist/schema/push-index-prebuild.d.ts +25 -0
- package/dist/schema/push-legacy-renames.d.ts +20 -0
- package/dist/schema/rls-bootstrap-sql.d.ts +15 -0
- package/dist/schema/undeclarable-constraints.d.ts +59 -0
- package/dist/security/rls-enforcement.d.ts +32 -4
- package/dist/services/BranchService.d.ts +7 -0
- package/dist/services/FetchService.d.ts +58 -8
- package/dist/services/PersistService.d.ts +15 -0
- package/dist/services/RelationService.d.ts +88 -3
- package/dist/services/cdc/CdcListener.d.ts +17 -6
- package/dist/services/cdc/trigger-cdc.d.ts +151 -27
- package/dist/services/channel-bus/index.d.ts +1 -1
- package/dist/services/channel-history.d.ts +15 -4
- package/dist/services/collection-helpers.d.ts +15 -0
- package/dist/services/field-viewer.d.ts +15 -1
- package/dist/services/pg-notify-listener.d.ts +7 -0
- package/dist/services/realtimeService.d.ts +314 -14
- package/dist/services/row-pipeline.d.ts +16 -9
- package/dist/services/socket-liveness.d.ts +42 -2
- package/dist/services/sql-script.d.ts +207 -3
- package/dist/services/vector-iterative-scan.d.ts +40 -0
- package/dist/services/write-depth.d.ts +6 -0
- package/dist/services/write-transaction-scope.d.ts +9 -0
- package/dist/socket-opt-ins.d.ts +64 -0
- package/dist/source-DB6xJv3p.js +873 -0
- package/dist/source-DB6xJv3p.js.map +1 -0
- package/dist/tsx-loader.d.ts +14 -0
- package/dist/utils/connection-string.d.ts +31 -0
- package/dist/utils/drizzle-conditions.d.ts +21 -1
- package/dist/utils/error-cause.d.ts +7 -0
- package/dist/utils/pg-error-utils.d.ts +2 -4
- package/dist/utils/result-rows.d.ts +10 -0
- package/dist/{vector-index-CMJKb3C9.js → vector-index-BFhyEaiz.js} +2 -2
- package/dist/{vector-index-CMJKb3C9.js.map → vector-index-BFhyEaiz.js.map} +1 -1
- package/dist/websocket-DUiiwQd2.js +1632 -0
- package/dist/websocket-DUiiwQd2.js.map +1 -0
- package/dist/websocket.d.ts +13 -0
- package/package.json +7 -7
- package/dist/BranchService-BRt78gfa.js.map +0 -1
- package/dist/__vite-browser-external-BnuHet1e.js.map +0 -1
- package/dist/arg-Dni7MzLB.js.map +0 -1
- package/dist/backup-cli-DW5p9_zv.js.map +0 -1
- package/dist/backup-service-EwcDVG-8.js.map +0 -1
- package/dist/cli-errors-DsA-K9uP.js +0 -893
- package/dist/cli-errors-DsA-K9uP.js.map +0 -1
- package/dist/cli-flags-BglvpjHv.js.map +0 -1
- package/dist/cli-output-CNdMql-L.js +0 -47
- package/dist/cli-output-CNdMql-L.js.map +0 -1
- package/dist/collection-index-DdnsxiJ_.js +0 -286
- package/dist/collection-index-DdnsxiJ_.js.map +0 -1
- package/dist/databasePoolManager-Bj5FbeAs.js.map +0 -1
- package/dist/doctor-C-sYWbmt.js.map +0 -1
- package/dist/ensure-collection-policies-B1ureSIV.js +0 -160
- package/dist/ensure-collection-policies-B1ureSIV.js.map +0 -1
- package/dist/ensure-collection-tables-kkkHk8oo.js.map +0 -1
- package/dist/ensure-tables-BmI_tRxc.js.map +0 -1
- package/dist/generate-drizzle-schema-93M0lUxK.js +0 -123
- package/dist/generate-drizzle-schema-93M0lUxK.js.map +0 -1
- package/dist/generate-drizzle-schema-logic-sSFDp6LR.js.map +0 -1
- package/dist/introspect-db-logic-kCETE8TY.js.map +0 -1
- package/dist/introspect-db-queries-C_Q5VgQw.js.map +0 -1
- package/dist/plan-schema-DU9exq6C.js.map +0 -1
- package/dist/policy-drift-B-J2hhm0.js.map +0 -1
- package/dist/render-ddl-Ds2t_d9V.js.map +0 -1
- package/dist/rls-bootstrap-sql-_KNnjanK.js.map +0 -1
- package/dist/rls-enforcement-CfXOJJaW.js.map +0 -1
- package/dist/source-Br7L7GOI.js +0 -410
- package/dist/source-Br7L7GOI.js.map +0 -1
- package/dist/utils/sql-redaction.d.ts +0 -21
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { createRequire as __createRequire } from "module";
|
|
2
2
|
__createRequire(import.meta.url);
|
|
3
3
|
import { a as buildSearchColumnSpec, u as searchColumnStamps } from "./search-column-BM-GV6vH.js";
|
|
4
|
+
import { p as foreignKeyIndexSpec } from "./source-DB6xJv3p.js";
|
|
4
5
|
import { DEFAULT_SEARCH_COLUMN, DEFAULT_SEARCH_LANGUAGE } from "@rebasepro/types";
|
|
6
|
+
import { getGeneratedPolicyNames, policyToSecurityRule } from "@rebasepro/common";
|
|
5
7
|
import { firstFreeKey, toPostgresIdentifier, toWireKey } from "@rebasepro/utils";
|
|
6
8
|
//#region src/schema/introspect-db-naming.ts
|
|
7
9
|
/**
|
|
@@ -276,8 +278,8 @@ function stringStorage(col) {
|
|
|
276
278
|
case "character varying":
|
|
277
279
|
if (typeof col.character_maximum_length === "number" && col.character_maximum_length > 0) return { keys: [`columnType: ${literal("varchar")}`] };
|
|
278
280
|
return {
|
|
279
|
-
keys: [
|
|
280
|
-
note: `"${col.column_name}" is a varchar with no length
|
|
281
|
+
keys: [],
|
|
282
|
+
note: `"${col.column_name}" is a varchar with no length, declared as text: a push would plan converting it to text, which keeps every value.`
|
|
281
283
|
};
|
|
282
284
|
case "character": return { keys: [`columnType: ${literal("char")}`] };
|
|
283
285
|
case "uuid": return { keys: [`columnType: ${literal("uuid")}`] };
|
|
@@ -708,6 +710,41 @@ function classifyJunction(table, context) {
|
|
|
708
710
|
};
|
|
709
711
|
}
|
|
710
712
|
/**
|
|
713
|
+
* A policy expression that reads who is asking: the `app.uid` setting every
|
|
714
|
+
* request runs with, `rebase.uid()` (or the retired `auth.uid()`), the JWT,
|
|
715
|
+
* or the session's own role.
|
|
716
|
+
*/
|
|
717
|
+
var CALLER_IDENTITY = /current_setting\(\s*'app\.(uid|user_id|jwt)'|\b(rebase|auth)\.(uid|jwt)\s*\(|\bcurrent_user\b|\bsession_user\b/i;
|
|
718
|
+
/**
|
|
719
|
+
* The tables whose row-level security hands each caller rows of their own,
|
|
720
|
+
* with the policies that do it.
|
|
721
|
+
*
|
|
722
|
+
* Structure in the sense this module means: a policy is a rule the database
|
|
723
|
+
* enforces, and one that compares a row to the caller's identity says the rows
|
|
724
|
+
* belong to users. That is the app's data. A young database holds three
|
|
725
|
+
* customers and one order; by row count the customers are "a 3-row code list"
|
|
726
|
+
* and the orders a child reached only through them, and both go missing from
|
|
727
|
+
* the navigation of the app that owns them.
|
|
728
|
+
*/
|
|
729
|
+
function callerScopedTables(metadata) {
|
|
730
|
+
const scoped = /* @__PURE__ */ new Map();
|
|
731
|
+
for (const policy of metadata.policies ?? []) {
|
|
732
|
+
if (!CALLER_IDENTITY.test(policy.qual ?? "") && !CALLER_IDENTITY.test(policy.with_check ?? "")) continue;
|
|
733
|
+
scoped.set(policy.table_name, [...scoped.get(policy.table_name) ?? [], policy.policy_name]);
|
|
734
|
+
}
|
|
735
|
+
return scoped;
|
|
736
|
+
}
|
|
737
|
+
/** An entity because its policies give each user their own rows — see {@link callerScopedTables}. */
|
|
738
|
+
function classifyCallerScoped(table, perCaller) {
|
|
739
|
+
const policies = perCaller.get(table);
|
|
740
|
+
if (!policies) return null;
|
|
741
|
+
return {
|
|
742
|
+
table,
|
|
743
|
+
role: "entity",
|
|
744
|
+
reason: `its row-level security gives each user their own rows (${policies.join(", ")}), so they are the app's data`
|
|
745
|
+
};
|
|
746
|
+
}
|
|
747
|
+
/**
|
|
711
748
|
* A small, referenced, self-contained code list.
|
|
712
749
|
*
|
|
713
750
|
* Requires: something references it, it references nothing, it carries few and
|
|
@@ -833,8 +870,9 @@ function pickOwner(meta, constraints) {
|
|
|
833
870
|
function classifyTables(metadata, tables) {
|
|
834
871
|
const context = buildContext(metadata, tables);
|
|
835
872
|
const result = /* @__PURE__ */ new Map();
|
|
873
|
+
const perCaller = callerScopedTables(metadata);
|
|
836
874
|
for (const table of tables.keys()) {
|
|
837
|
-
const classification = classifyJunction(table, context) ?? classifyLookup(table, context) ?? classifyOwnedChild(table, context) ?? {
|
|
875
|
+
const classification = classifyJunction(table, context) ?? classifyCallerScoped(table, perCaller) ?? classifyLookup(table, context) ?? classifyOwnedChild(table, context) ?? {
|
|
838
876
|
table,
|
|
839
877
|
role: "entity",
|
|
840
878
|
reason: "no structural evidence that it is a join table, a code list, or owned by another table"
|
|
@@ -913,6 +951,32 @@ function deriveKanbanProperty(facts) {
|
|
|
913
951
|
return fact.column.column_name;
|
|
914
952
|
}
|
|
915
953
|
}
|
|
954
|
+
/** Names a string column goes by when it holds a board's card order (a fractional-indexing key). */
|
|
955
|
+
var ORDER_KEY_NAMES = /* @__PURE__ */ new Set([
|
|
956
|
+
"__order",
|
|
957
|
+
"order_key",
|
|
958
|
+
"sort_key",
|
|
959
|
+
"rank",
|
|
960
|
+
"lexorank",
|
|
961
|
+
"position_key"
|
|
962
|
+
]);
|
|
963
|
+
/**
|
|
964
|
+
* The string column that can hold a board's card order, or nothing.
|
|
965
|
+
*
|
|
966
|
+
* A board without `orderProperty` cannot keep a card's position within a
|
|
967
|
+
* column, and the config validator says so on every generate — so a board is
|
|
968
|
+
* emitted only when the table already has somewhere to store the order. A
|
|
969
|
+
* legacy table almost never does; asking its owner to add a hidden column
|
|
970
|
+
* just to satisfy generated output was the wrong way round.
|
|
971
|
+
*/
|
|
972
|
+
function deriveKanbanOrderProperty(facts) {
|
|
973
|
+
for (const fact of facts.values()) {
|
|
974
|
+
if (fact.isPk || fact.isFk || fact.isGenerated || fact.enumValues) continue;
|
|
975
|
+
if (fact.propType !== "string") continue;
|
|
976
|
+
if (!/^(text|character varying)$/.test(fact.column.data_type)) continue;
|
|
977
|
+
if (ORDER_KEY_NAMES.has(fact.column.column_name.toLowerCase())) return fact.column.column_name;
|
|
978
|
+
}
|
|
979
|
+
}
|
|
916
980
|
/**
|
|
917
981
|
* The column a list should be sorted by, newest first.
|
|
918
982
|
*
|
|
@@ -1302,6 +1366,57 @@ function sortPropertiesOrder(entries) {
|
|
|
1302
1366
|
var ADMIN_TYPES_PACKAGE = "@rebasepro/cms-types";
|
|
1303
1367
|
var COMMON_PACKAGE = "@rebasepro/common";
|
|
1304
1368
|
var TYPES_PACKAGE = "@rebasepro/types";
|
|
1369
|
+
/**
|
|
1370
|
+
* The table's row-level security policies, as the collection's `securityRules`.
|
|
1371
|
+
*
|
|
1372
|
+
* A table's policies are its access model, and a collection that describes
|
|
1373
|
+
* none leaves every one of them an "orphan": `doctor` fails on it, every push
|
|
1374
|
+
* warns about it, and a push drops one whose name has the shape an unnamed
|
|
1375
|
+
* rule compiles to (`<table>_<op>_<hash>`, which is every rule on a database
|
|
1376
|
+
* Rebase built). Described here, each is recreated from its rule as it was.
|
|
1377
|
+
*
|
|
1378
|
+
* Read back with `policyToSecurityRule` — what Studio's "Import from table"
|
|
1379
|
+
* and "Import to codebase" use — so the `TO` list, the mode and both clauses
|
|
1380
|
+
* come back as they are. The framework's own defaults
|
|
1381
|
+
* (`<table>_default_admin_read` and friends) are left out: every collection is
|
|
1382
|
+
* given them anyway, and described twice they would be written twice.
|
|
1383
|
+
*/
|
|
1384
|
+
function renderSecurityRules(tableName, policies) {
|
|
1385
|
+
const injected = getGeneratedPolicyNames({
|
|
1386
|
+
name: tableName,
|
|
1387
|
+
slug: tableName,
|
|
1388
|
+
table: tableName,
|
|
1389
|
+
properties: {}
|
|
1390
|
+
});
|
|
1391
|
+
const own = policies.filter((policy) => policy.table_name === tableName && !injected.has(policy.policy_name));
|
|
1392
|
+
if (own.length === 0) return "";
|
|
1393
|
+
return `
|
|
1394
|
+
// The table's row-level security policies, read from the database. \`rebase db push\`
|
|
1395
|
+
// recreates each from its rule, so a policy is changed here from now on.\n securityRules: [${own.map((policy) => {
|
|
1396
|
+
const rule = policyToSecurityRule({
|
|
1397
|
+
policyname: policy.policy_name,
|
|
1398
|
+
cmd: toPolicyCommand(policy.cmd),
|
|
1399
|
+
permissive: policy.permissive.toUpperCase() === "RESTRICTIVE" ? "RESTRICTIVE" : "PERMISSIVE",
|
|
1400
|
+
roles: policy.roles,
|
|
1401
|
+
qual: policy.qual,
|
|
1402
|
+
with_check: policy.with_check
|
|
1403
|
+
});
|
|
1404
|
+
return `\n {\n${Object.entries(rule).map(([key, value]) => {
|
|
1405
|
+
return ` ${key}: ${Array.isArray(value) ? `[${value.map((item) => quote(String(item))).join(", ")}]` : quote(String(value))}`;
|
|
1406
|
+
}).join(",\n")}\n },`;
|
|
1407
|
+
}).join("")}\n ],`;
|
|
1408
|
+
}
|
|
1409
|
+
/** `pg_policies.cmd`, narrowed to the commands a policy can have. */
|
|
1410
|
+
function toPolicyCommand(cmd) {
|
|
1411
|
+
switch (cmd.toUpperCase()) {
|
|
1412
|
+
case "SELECT": return "SELECT";
|
|
1413
|
+
case "INSERT": return "INSERT";
|
|
1414
|
+
case "UPDATE": return "UPDATE";
|
|
1415
|
+
case "DELETE": return "DELETE";
|
|
1416
|
+
case "ALL": return "ALL";
|
|
1417
|
+
default: return;
|
|
1418
|
+
}
|
|
1419
|
+
}
|
|
1305
1420
|
/** Adds entries to a property's `validation` block, creating it if absent. */
|
|
1306
1421
|
function withValidation(extra, entries) {
|
|
1307
1422
|
if (entries.length === 0) return extra;
|
|
@@ -1565,7 +1680,11 @@ function generateCollectionFile(tableName, meta, allFks, joinTables, tablesMap,
|
|
|
1565
1680
|
if (!hasGeneratedKey(extra, "autoValue") && !hasGeneratedKey(extra, "defaultValue")) {
|
|
1566
1681
|
const fallback = literalDefaultOf(col, finalPropType);
|
|
1567
1682
|
if (fallback && "source" in fallback) extra += `\n defaultValue: ${fallback.source},`;
|
|
1568
|
-
else if (fallback)
|
|
1683
|
+
else if (fallback) {
|
|
1684
|
+
const expression = col.column_default?.trim();
|
|
1685
|
+
if (col.is_nullable === "NO" && expression) extra += `\n databaseDefault: ${JSON.stringify(`sql\`${expression}\``)},`;
|
|
1686
|
+
else fileNotes.push(fallback.note);
|
|
1687
|
+
}
|
|
1569
1688
|
}
|
|
1570
1689
|
}
|
|
1571
1690
|
const declaredValidation = [];
|
|
@@ -1666,6 +1785,9 @@ function generateCollectionFile(tableName, meta, allFks, joinTables, tablesMap,
|
|
|
1666
1785
|
const onDelete = onDeleteOf(fk, required);
|
|
1667
1786
|
const requiredLine = required ? "\n validation: { required: true }," : "";
|
|
1668
1787
|
const onDeleteLine = onDelete ? `,\n onDelete: ${quote(onDelete)}` : "";
|
|
1788
|
+
const derivedIndex = foreignKeyIndexSpec(context.metadata?.schema ?? "public", tableName, fk.column_name);
|
|
1789
|
+
const indexLine = context.metadata?.indexes !== void 0 && meta.pks[0] !== fk.column_name && !context.metadata.indexes.some((i) => i.table_name === tableName && i.index_name === derivedIndex.indexName) ? `,\n // The database has no index of Rebase's on ${commentText(fk.column_name)}. Delete this line to have one built.
|
|
1790
|
+
index: false` : "";
|
|
1669
1791
|
propertyBlocks.set(relName, `
|
|
1670
1792
|
${propKey(relName)}: {
|
|
1671
1793
|
name: ${quote(relHumanName)},
|
|
@@ -1674,7 +1796,7 @@ function generateCollectionFile(tableName, meta, allFks, joinTables, tablesMap,
|
|
|
1674
1796
|
relation: {
|
|
1675
1797
|
kind: "belongsTo",
|
|
1676
1798
|
target: ${relationTarget(targetCollectionCamel)},
|
|
1677
|
-
localKey: ${quote(fk.column_name)}${onDeleteLine}
|
|
1799
|
+
localKey: ${quote(fk.column_name)}${onDeleteLine}${indexLine}
|
|
1678
1800
|
}
|
|
1679
1801
|
},`);
|
|
1680
1802
|
}
|
|
@@ -1769,6 +1891,7 @@ function generateCollectionFile(tableName, meta, allFks, joinTables, tablesMap,
|
|
|
1769
1891
|
if (search.note) fileNotes.push(search.note);
|
|
1770
1892
|
const searchBlock = search.block ?? "";
|
|
1771
1893
|
const relationsBlock = relationsOutput ? `\n relations: [${relationsOutput}\n ],` : "";
|
|
1894
|
+
const securityRulesBlock = renderSecurityRules(tableName, context.metadata?.policies ?? []);
|
|
1772
1895
|
const sortedPropertiesOrder = sortPropertiesOrder(orderEntries);
|
|
1773
1896
|
for (const key of sortedPropertiesOrder) propsOutput += propertyBlocks.get(key) || "";
|
|
1774
1897
|
const adminEntries = [`icon: ${quote(icon)}`];
|
|
@@ -1781,7 +1904,11 @@ function generateCollectionFile(tableName, meta, allFks, joinTables, tablesMap,
|
|
|
1781
1904
|
const titleProperty = deriveTitleProperty(derivedFacts);
|
|
1782
1905
|
if (titleProperty) adminEntries.push(`display: { title: ${quote(asProperty(titleProperty))} }`);
|
|
1783
1906
|
const kanbanProperty = deriveKanbanProperty(derivedFacts);
|
|
1784
|
-
|
|
1907
|
+
const orderProperty = kanbanProperty ? deriveKanbanOrderProperty(derivedFacts) : void 0;
|
|
1908
|
+
if (kanbanProperty && orderProperty) {
|
|
1909
|
+
adminEntries.push(`kanban: {\n columnProperty: ${quote(asProperty(kanbanProperty))}\n }`);
|
|
1910
|
+
adminEntries.push(`orderProperty: ${quote(asProperty(orderProperty))}`);
|
|
1911
|
+
} else if (kanbanProperty) adminEntries.push(`// A board over ${quote(asProperty(kanbanProperty))} fits this table, but a board needs a string column to keep each card's order in. Add one, then declare kanban: { columnProperty: ${quote(asProperty(kanbanProperty))} } and orderProperty: "<that property>".`);
|
|
1785
1912
|
const sort = deriveSort(derivedFacts);
|
|
1786
1913
|
if (sort) adminEntries.push(`sort: [${quote(asProperty(sort[0]))}, "desc"]`);
|
|
1787
1914
|
}
|
|
@@ -1793,7 +1920,7 @@ function generateCollectionFile(tableName, meta, allFks, joinTables, tablesMap,
|
|
|
1793
1920
|
const descriptionBlock = tableComment ? `\n description: ${quote(tableComment)},` : "";
|
|
1794
1921
|
const pgSchema = context.metadata?.schema;
|
|
1795
1922
|
const schemaBlock = pgSchema && pgSchema !== "public" ? `\n schema: ${quote(pgSchema)},` : "";
|
|
1796
|
-
const classificationNote = classification && classification.role !== "entity" ? `\n// Introspected as a ${commentText(classification.role)}: ${commentText(classification.reason)}.\n` : "";
|
|
1923
|
+
const classificationNote = classification && classification.role !== "entity" ? `\n// Introspected as ${/^[aeiou]/.test(classification.role) ? "an" : "a"} ${commentText(classification.role)}: ${commentText(classification.reason)}.\n` : "";
|
|
1797
1924
|
for (const note of fileNotes) context.notes?.push(`${tableName}: ${note}`);
|
|
1798
1925
|
const storageNote = fileNotes.length > 0 ? `\n// ⚠ Not reproduced exactly by \`rebase db push\` — read before pushing:\n${fileNotes.map((n) => `// - ${commentText(n)}`).join("\n")}\n` : "";
|
|
1799
1926
|
const collectionVarName = toCollectionVarName(tableName);
|
|
@@ -1807,7 +1934,7 @@ ${open}
|
|
|
1807
1934
|
slug: ${quote(tableName)},
|
|
1808
1935
|
table: ${quote(tableName)},${schemaBlock}${descriptionBlock}${searchBlock}
|
|
1809
1936
|
properties: {${propsOutput}
|
|
1810
|
-
},${relationsBlock}${adminBlock}
|
|
1937
|
+
},${relationsBlock}${securityRulesBlock}${adminBlock}
|
|
1811
1938
|
${close}
|
|
1812
1939
|
|
|
1813
1940
|
export default ${collectionVarName};
|
|
@@ -1868,4 +1995,4 @@ function safeHostFromUrl(url) {
|
|
|
1868
1995
|
//#endregion
|
|
1869
1996
|
export { compositeKeySkipReason as a, getIconForTable as c, safeHostFromUrl as d, singularize as f, humanize as g, mapPgType as h, buildTablesMap as i, identifyJoinTables as l, lookupCandidates as m, COMMON_PACKAGE as n, generateCollectionFile as o, classifyTables as p, buildEnumMap as r, generateIndexContent as s, ADMIN_TYPES_PACKAGE as t, mergeIndexContent as u };
|
|
1870
1997
|
|
|
1871
|
-
//# sourceMappingURL=introspect-db-logic-
|
|
1998
|
+
//# sourceMappingURL=introspect-db-logic-BCc1Jym2.js.map
|