neon 8.4.5 → 8.6.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.
Files changed (79) hide show
  1. package/README.md +18 -9
  2. package/dist/_chunks/{env-4WGRW2nw.js → env-BNm69Qh8.js} +2 -5
  3. package/dist/commands/config.js +11 -28
  4. package/dist/commands/dev.js +93 -27
  5. package/dist/commands/env.js +2 -3
  6. package/dist/commands/init.js +1 -2
  7. package/dist/commands/link.js +1 -1
  8. package/dist/commands/manifest.js +1 -3
  9. package/dist/commands/subscribe.js +16 -16
  10. package/dist/credential_io.js +1 -2
  11. package/dist/dev/env.js +1 -2
  12. package/dist/dev/runtime.js +8 -0
  13. package/dist/env_file.js +9 -1
  14. package/dist/index.js +1 -1
  15. package/dist/init/auth.js +1 -4
  16. package/dist/init/choices.js +21 -7
  17. package/dist/init/copy.js +21 -7
  18. package/dist/init/run.js +25 -16
  19. package/dist/plugins/run.js +2 -1
  20. package/dist/psql/command/cmd_io.js +1 -2
  21. package/dist/psql/command/cmd_pipeline.js +1 -2
  22. package/dist/psql/core/common.js +1 -2
  23. package/dist/psql/core/startup.js +1 -2
  24. package/dist/psql/index.js +1 -2
  25. package/dist/psql/types/index.js +1 -2
  26. package/dist/skills/catalog.js +5 -0
  27. package/dist/utils/hooks.js +0 -2
  28. package/dist/utils/staging.js +1 -14
  29. package/{LICENSE → dist/vendor/postgres-meta/LICENSE} +0 -1
  30. package/dist/vendor/postgres-meta/constants.js +14 -0
  31. package/dist/vendor/postgres-meta/lib/PostgresMeta.js +49 -0
  32. package/dist/vendor/postgres-meta/lib/PostgresMetaColumnPrivileges.js +85 -0
  33. package/dist/vendor/postgres-meta/lib/PostgresMetaColumns.js +235 -0
  34. package/dist/vendor/postgres-meta/lib/PostgresMetaConfig.js +16 -0
  35. package/dist/vendor/postgres-meta/lib/PostgresMetaExtensions.js +79 -0
  36. package/dist/vendor/postgres-meta/lib/PostgresMetaForeignTables.js +81 -0
  37. package/dist/vendor/postgres-meta/lib/PostgresMetaFunctions.js +173 -0
  38. package/dist/vendor/postgres-meta/lib/PostgresMetaIndexes.js +42 -0
  39. package/dist/vendor/postgres-meta/lib/PostgresMetaMaterializedViews.js +84 -0
  40. package/dist/vendor/postgres-meta/lib/PostgresMetaPolicies.js +120 -0
  41. package/dist/vendor/postgres-meta/lib/PostgresMetaPublications.js +193 -0
  42. package/dist/vendor/postgres-meta/lib/PostgresMetaRelationships.js +87 -0
  43. package/dist/vendor/postgres-meta/lib/PostgresMetaRoles.js +203 -0
  44. package/dist/vendor/postgres-meta/lib/PostgresMetaSchemas.js +105 -0
  45. package/dist/vendor/postgres-meta/lib/PostgresMetaTablePrivileges.js +91 -0
  46. package/dist/vendor/postgres-meta/lib/PostgresMetaTables.js +183 -0
  47. package/dist/vendor/postgres-meta/lib/PostgresMetaTriggers.js +156 -0
  48. package/dist/vendor/postgres-meta/lib/PostgresMetaTypes.js +22 -0
  49. package/dist/vendor/postgres-meta/lib/PostgresMetaVersion.js +20 -0
  50. package/dist/vendor/postgres-meta/lib/PostgresMetaViews.js +83 -0
  51. package/dist/vendor/postgres-meta/lib/constants.js +8 -0
  52. package/dist/vendor/postgres-meta/lib/db.js +147 -0
  53. package/dist/vendor/postgres-meta/lib/generators.js +106 -0
  54. package/dist/vendor/postgres-meta/lib/helpers.js +26 -0
  55. package/dist/vendor/postgres-meta/lib/index.js +1 -0
  56. package/dist/vendor/postgres-meta/lib/sql/column_privileges.sql.js +154 -0
  57. package/dist/vendor/postgres-meta/lib/sql/columns.sql.js +123 -0
  58. package/dist/vendor/postgres-meta/lib/sql/common.js +1 -0
  59. package/dist/vendor/postgres-meta/lib/sql/config.sql.js +32 -0
  60. package/dist/vendor/postgres-meta/lib/sql/extensions.sql.js +20 -0
  61. package/dist/vendor/postgres-meta/lib/sql/foreign_tables.sql.js +20 -0
  62. package/dist/vendor/postgres-meta/lib/sql/functions.sql.js +141 -0
  63. package/dist/vendor/postgres-meta/lib/sql/indexes.sql.js +51 -0
  64. package/dist/vendor/postgres-meta/lib/sql/materialized_views.sql.js +21 -0
  65. package/dist/vendor/postgres-meta/lib/sql/policies.sql.js +53 -0
  66. package/dist/vendor/postgres-meta/lib/sql/publications.sql.js +46 -0
  67. package/dist/vendor/postgres-meta/lib/sql/roles.sql.js +40 -0
  68. package/dist/vendor/postgres-meta/lib/sql/schemas.sql.js +26 -0
  69. package/dist/vendor/postgres-meta/lib/sql/table.sql.js +109 -0
  70. package/dist/vendor/postgres-meta/lib/sql/table_privileges.sql.js +85 -0
  71. package/dist/vendor/postgres-meta/lib/sql/table_relationships.sql.js +52 -0
  72. package/dist/vendor/postgres-meta/lib/sql/triggers.sql.js +64 -0
  73. package/dist/vendor/postgres-meta/lib/sql/types.sql.js +65 -0
  74. package/dist/vendor/postgres-meta/lib/sql/version.sql.js +15 -0
  75. package/dist/vendor/postgres-meta/lib/sql/views.sql.js +22 -0
  76. package/dist/vendor/postgres-meta/lib/sql/views_key_dependencies.sql.js +198 -0
  77. package/dist/vendor/postgres-meta/lib/types.js +1 -0
  78. package/dist/vendor/postgres-meta/templates/typescript.js +608 -0
  79. package/package.json +12 -5
@@ -0,0 +1,84 @@
1
+ import { coalesceRowsToArray, filterByList, filterByValue } from "./helpers.js";
2
+ import { COLUMNS_SQL } from "./sql/columns.sql.js";
3
+ import { MATERIALIZED_VIEWS_SQL } from "./sql/materialized_views.sql.js";
4
+ //#region src/vendor/postgres-meta/lib/PostgresMetaMaterializedViews.ts
5
+ var PostgresMetaMaterializedViews = class {
6
+ constructor(query) {
7
+ this.query = query;
8
+ }
9
+ async list({ includedSchemas, excludedSchemas, limit, offset, includeColumns = false } = {}) {
10
+ const schemaFilter = filterByList(includedSchemas, excludedSchemas, void 0);
11
+ let sql = generateEnrichedMaterializedViewsSql({
12
+ includeColumns,
13
+ schemaFilter,
14
+ limit,
15
+ offset
16
+ });
17
+ return await this.query(sql);
18
+ }
19
+ async retrieve({ id, name, schema = "public" }) {
20
+ if (id) {
21
+ const idsFilter = filterByValue([id]);
22
+ const sql = generateEnrichedMaterializedViewsSql({
23
+ includeColumns: true,
24
+ idsFilter
25
+ });
26
+ const { data, error } = await this.query(sql);
27
+ if (error) return {
28
+ data,
29
+ error
30
+ };
31
+ else if (data.length === 0) return {
32
+ data: null,
33
+ error: { message: `Cannot find a materialized view with ID ${id}` }
34
+ };
35
+ else return {
36
+ data: data[0],
37
+ error
38
+ };
39
+ } else if (name) {
40
+ const materializedViewIdentifierFilter = filterByValue([`${schema}.${name}`]);
41
+ const sql = generateEnrichedMaterializedViewsSql({
42
+ includeColumns: true,
43
+ materializedViewIdentifierFilter
44
+ });
45
+ const { data, error } = await this.query(sql);
46
+ if (error) return {
47
+ data,
48
+ error
49
+ };
50
+ else if (data.length === 0) return {
51
+ data: null,
52
+ error: { message: `Cannot find a materialized view named ${name} in schema ${schema}` }
53
+ };
54
+ else return {
55
+ data: data[0],
56
+ error
57
+ };
58
+ } else return {
59
+ data: null,
60
+ error: { message: "Invalid parameters on materialized view retrieve" }
61
+ };
62
+ }
63
+ };
64
+ const generateEnrichedMaterializedViewsSql = ({ includeColumns, schemaFilter, materializedViewIdentifierFilter, idsFilter, limit, offset }) => `
65
+ with materialized_views as (${MATERIALIZED_VIEWS_SQL({
66
+ schemaFilter,
67
+ limit,
68
+ offset,
69
+ materializedViewIdentifierFilter,
70
+ idsFilter
71
+ })})
72
+ ${includeColumns ? `, columns as (${COLUMNS_SQL({
73
+ schemaFilter,
74
+ limit,
75
+ offset,
76
+ tableIdentifierFilter: materializedViewIdentifierFilter,
77
+ tableIdFilter: idsFilter
78
+ })})` : ""}
79
+ select
80
+ *
81
+ ${includeColumns ? `, ${coalesceRowsToArray("columns", "columns.table_id = materialized_views.id")}` : ""}
82
+ from materialized_views`;
83
+ //#endregion
84
+ export { PostgresMetaMaterializedViews as default };
@@ -0,0 +1,120 @@
1
+ import { DEFAULT_SYSTEM_SCHEMAS } from "./constants.js";
2
+ import { filterByList, filterByValue } from "./helpers.js";
3
+ import { POLICIES_SQL } from "./sql/policies.sql.js";
4
+ import { ident } from "pg-format";
5
+ //#region src/vendor/postgres-meta/lib/PostgresMetaPolicies.ts
6
+ var PostgresMetaPolicies = class {
7
+ constructor(query) {
8
+ this.query = query;
9
+ }
10
+ async list({ includeSystemSchemas = false, includedSchemas, excludedSchemas, limit, offset } = {}) {
11
+ const schemaFilter = filterByList(includedSchemas, excludedSchemas, !includeSystemSchemas ? DEFAULT_SYSTEM_SCHEMAS : void 0);
12
+ let sql = POLICIES_SQL({
13
+ schemaFilter,
14
+ limit,
15
+ offset
16
+ });
17
+ return await this.query(sql);
18
+ }
19
+ async retrieve({ id, name, table, schema = "public" }) {
20
+ const schemaFilter = schema ? filterByList([schema], []) : void 0;
21
+ if (id) {
22
+ const idsFilter = filterByValue([`${id}`]);
23
+ const sql = POLICIES_SQL({ idsFilter });
24
+ const { data, error } = await this.query(sql);
25
+ if (error) return {
26
+ data,
27
+ error
28
+ };
29
+ else if (data.length === 0) return {
30
+ data: null,
31
+ error: { message: `Cannot find a policy with ID ${id}` }
32
+ };
33
+ else return {
34
+ data: data[0],
35
+ error
36
+ };
37
+ } else if (name && table) {
38
+ const functionNameIdentifierFilter = filterByValue([`${table}.${name}`]);
39
+ const sql = POLICIES_SQL({
40
+ schemaFilter,
41
+ functionNameIdentifierFilter
42
+ });
43
+ const { data, error } = await this.query(sql);
44
+ if (error) return {
45
+ data,
46
+ error
47
+ };
48
+ else if (data.length === 0) return {
49
+ data: null,
50
+ error: { message: `Cannot find a policy named ${name} for table ${schema}.${table}` }
51
+ };
52
+ else return {
53
+ data: data[0],
54
+ error
55
+ };
56
+ } else return {
57
+ data: null,
58
+ error: { message: "Invalid parameters on policy retrieve" }
59
+ };
60
+ }
61
+ async create({ name, table, schema = "public", definition, check, action = "PERMISSIVE", command = "ALL", roles = ["public"] }) {
62
+ const definitionClause = definition === void 0 ? "" : `USING (${definition})`;
63
+ const checkClause = check === void 0 ? "" : `WITH CHECK (${check})`;
64
+ const sql = `
65
+ CREATE POLICY ${ident(name)} ON ${ident(schema)}.${ident(table)}
66
+ AS ${action}
67
+ FOR ${command}
68
+ TO ${roles.map(ident).join(",")}
69
+ ${definitionClause} ${checkClause};`;
70
+ const { error } = await this.query(sql);
71
+ if (error) return {
72
+ data: null,
73
+ error
74
+ };
75
+ return await this.retrieve({
76
+ name,
77
+ table,
78
+ schema
79
+ });
80
+ }
81
+ async update(id, { name, definition, check, roles }) {
82
+ const { data: old, error } = await this.retrieve({ id });
83
+ if (error) return {
84
+ data: null,
85
+ error
86
+ };
87
+ const alter = `ALTER POLICY ${ident(old.name)} ON ${ident(old.schema)}.${ident(old.table)}`;
88
+ const nameSql = name === void 0 ? "" : `${alter} RENAME TO ${ident(name)};`;
89
+ const sql = `BEGIN; ${definition === void 0 ? "" : `${alter} USING (${definition});`} ${check === void 0 ? "" : `${alter} WITH CHECK (${check});`} ${roles === void 0 ? "" : `${alter} TO ${roles.map(ident).join(",")};`} ${nameSql} COMMIT;`;
90
+ {
91
+ const { error } = await this.query(sql);
92
+ if (error) return {
93
+ data: null,
94
+ error
95
+ };
96
+ }
97
+ return await this.retrieve({ id });
98
+ }
99
+ async remove(id) {
100
+ const { data: policy, error } = await this.retrieve({ id });
101
+ if (error) return {
102
+ data: null,
103
+ error
104
+ };
105
+ const sql = `DROP POLICY ${ident(policy.name)} ON ${ident(policy.schema)}.${ident(policy.table)};`;
106
+ {
107
+ const { error } = await this.query(sql);
108
+ if (error) return {
109
+ data: null,
110
+ error
111
+ };
112
+ }
113
+ return {
114
+ data: policy,
115
+ error: null
116
+ };
117
+ }
118
+ };
119
+ //#endregion
120
+ export { PostgresMetaPolicies as default };
@@ -0,0 +1,193 @@
1
+ import { filterByValue } from "./helpers.js";
2
+ import { PUBLICATIONS_SQL } from "./sql/publications.sql.js";
3
+ import { ident, literal } from "pg-format";
4
+ //#region src/vendor/postgres-meta/lib/PostgresMetaPublications.ts
5
+ var PostgresMetaPublications = class {
6
+ constructor(query) {
7
+ this.query = query;
8
+ }
9
+ async list({ limit, offset }) {
10
+ let sql = PUBLICATIONS_SQL({
11
+ limit,
12
+ offset
13
+ });
14
+ return await this.query(sql);
15
+ }
16
+ async retrieve({ id, name }) {
17
+ if (id) {
18
+ const idsFilter = filterByValue([id]);
19
+ const sql = PUBLICATIONS_SQL({ idsFilter });
20
+ const { data, error } = await this.query(sql);
21
+ if (error) return {
22
+ data,
23
+ error
24
+ };
25
+ else if (data.length === 0) return {
26
+ data: null,
27
+ error: { message: `Cannot find a publication with ID ${id}` }
28
+ };
29
+ else return {
30
+ data: data[0],
31
+ error
32
+ };
33
+ } else if (name) {
34
+ const nameFilter = filterByValue([name]);
35
+ const sql = PUBLICATIONS_SQL({ nameFilter });
36
+ const { data, error } = await this.query(sql);
37
+ if (error) return {
38
+ data,
39
+ error
40
+ };
41
+ else if (data.length === 0) return {
42
+ data: null,
43
+ error: { message: `Cannot find a publication named ${name}` }
44
+ };
45
+ else return {
46
+ data: data[0],
47
+ error
48
+ };
49
+ } else return {
50
+ data: null,
51
+ error: { message: "Invalid parameters on publication retrieve" }
52
+ };
53
+ }
54
+ async create({ name, publish_insert = false, publish_update = false, publish_delete = false, publish_truncate = false, tables = null }) {
55
+ let tableClause;
56
+ if (tables === void 0 || tables === null) tableClause = "FOR ALL TABLES";
57
+ else if (tables.length === 0) tableClause = "";
58
+ else tableClause = `FOR TABLE ${tables.map((t) => {
59
+ if (!t.includes(".")) return ident(t);
60
+ const [schema, ...rest] = t.split(".");
61
+ const table = rest.join(".");
62
+ return `${ident(schema)}.${ident(table)}`;
63
+ }).join(",")}`;
64
+ let publishOps = [];
65
+ if (publish_insert) publishOps.push("insert");
66
+ if (publish_update) publishOps.push("update");
67
+ if (publish_delete) publishOps.push("delete");
68
+ if (publish_truncate) publishOps.push("truncate");
69
+ const sql = `
70
+ CREATE PUBLICATION ${ident(name)} ${tableClause}
71
+ WITH (publish = '${publishOps.join(",")}');`;
72
+ const { error } = await this.query(sql);
73
+ if (error) return {
74
+ data: null,
75
+ error
76
+ };
77
+ return await this.retrieve({ name });
78
+ }
79
+ async update(id, { name, owner, publish_insert, publish_update, publish_delete, publish_truncate, tables }) {
80
+ const sql = `
81
+ do $$
82
+ declare
83
+ id oid := ${literal(id)};
84
+ old record;
85
+ new_name text := ${name === void 0 ? null : literal(name)};
86
+ new_owner text := ${owner === void 0 ? null : literal(owner)};
87
+ new_publish_insert bool := ${publish_insert ?? null};
88
+ new_publish_update bool := ${publish_update ?? null};
89
+ new_publish_delete bool := ${publish_delete ?? null};
90
+ new_publish_truncate bool := ${publish_truncate ?? null};
91
+ new_tables text := ${tables === void 0 ? null : literal(tables === null ? "all tables" : tables.map((t) => {
92
+ if (!t.includes(".")) return ident(t);
93
+ const [schema, ...rest] = t.split(".");
94
+ const table = rest.join(".");
95
+ return `${ident(schema)}.${ident(table)}`;
96
+ }).join(","))};
97
+ begin
98
+ select * into old from pg_publication where oid = id;
99
+ if old is null then
100
+ raise exception 'Cannot find publication with id %', id;
101
+ end if;
102
+
103
+ if new_tables is null then
104
+ null;
105
+ elsif new_tables = 'all tables' then
106
+ if old.puballtables then
107
+ null;
108
+ else
109
+ -- Need to recreate because going from list of tables <-> all tables with alter is not possible.
110
+ execute(format('drop publication %1$I; create publication %1$I for all tables;', old.pubname));
111
+ end if;
112
+ else
113
+ if old.puballtables then
114
+ -- Need to recreate because going from list of tables <-> all tables with alter is not possible.
115
+ execute(format('drop publication %1$I; create publication %1$I;', old.pubname));
116
+ elsif exists(select from pg_publication_rel where prpubid = id) then
117
+ execute(
118
+ format(
119
+ 'alter publication %I drop table %s',
120
+ old.pubname,
121
+ (select string_agg(prrelid::regclass::text, ', ') from pg_publication_rel where prpubid = id)
122
+ )
123
+ );
124
+ end if;
125
+
126
+ -- At this point the publication must have no tables.
127
+
128
+ if new_tables != '' then
129
+ execute(format('alter publication %I add table %s', old.pubname, new_tables));
130
+ end if;
131
+ end if;
132
+
133
+ execute(
134
+ format(
135
+ 'alter publication %I set (publish = %L);',
136
+ old.pubname,
137
+ concat_ws(
138
+ ', ',
139
+ case when coalesce(new_publish_insert, old.pubinsert) then 'insert' end,
140
+ case when coalesce(new_publish_update, old.pubupdate) then 'update' end,
141
+ case when coalesce(new_publish_delete, old.pubdelete) then 'delete' end,
142
+ case when coalesce(new_publish_truncate, old.pubtruncate) then 'truncate' end
143
+ )
144
+ )
145
+ );
146
+
147
+ execute(format('alter publication %I owner to %I;', old.pubname, coalesce(new_owner, old.pubowner::regrole::name)));
148
+
149
+ -- Using the same name in the rename clause gives an error, so only do it if the new name is different.
150
+ if new_name is not null and new_name != old.pubname then
151
+ execute(format('alter publication %I rename to %I;', old.pubname, coalesce(new_name, old.pubname)));
152
+ end if;
153
+
154
+ -- We need to retrieve the publication later, so we need a way to uniquely identify which publication this is.
155
+ -- We can't rely on id because it gets changed if it got recreated.
156
+ -- We use a temp table to store the unique name - DO blocks can't return a value.
157
+ create temp table pg_meta_publication_tmp (name) on commit drop as values (coalesce(new_name, old.pubname));
158
+ end $$;
159
+
160
+ with publications as (${PUBLICATIONS_SQL({})}) select * from publications where name = (select name from pg_meta_publication_tmp);
161
+ `;
162
+ const { data, error } = await this.query(sql);
163
+ if (error) return {
164
+ data: null,
165
+ error
166
+ };
167
+ return {
168
+ data: data[0],
169
+ error
170
+ };
171
+ }
172
+ async remove(id) {
173
+ const { data: publication, error } = await this.retrieve({ id });
174
+ if (error) return {
175
+ data: null,
176
+ error
177
+ };
178
+ const sql = `DROP PUBLICATION IF EXISTS ${ident(publication.name)};`;
179
+ {
180
+ const { error } = await this.query(sql);
181
+ if (error) return {
182
+ data: null,
183
+ error
184
+ };
185
+ }
186
+ return {
187
+ data: publication,
188
+ error: null
189
+ };
190
+ }
191
+ };
192
+ //#endregion
193
+ export { PostgresMetaPublications as default };
@@ -0,0 +1,87 @@
1
+ import { DEFAULT_SYSTEM_SCHEMAS } from "./constants.js";
2
+ import { filterByList } from "./helpers.js";
3
+ import { TABLE_RELATIONSHIPS_SQL } from "./sql/table_relationships.sql.js";
4
+ import { VIEWS_KEY_DEPENDENCIES_SQL } from "./sql/views_key_dependencies.sql.js";
5
+ //#region src/vendor/postgres-meta/lib/PostgresMetaRelationships.ts
6
+ var PostgresMetaRelationships = class {
7
+ constructor(query) {
8
+ this.query = query;
9
+ }
10
+ async list({ includeSystemSchemas = false, includedSchemas, excludedSchemas } = {}) {
11
+ const schemaFilter = filterByList(includedSchemas, excludedSchemas, !includeSystemSchemas ? DEFAULT_SYSTEM_SCHEMAS : void 0);
12
+ let allTableM2oAndO2oRelationships;
13
+ {
14
+ const sql = TABLE_RELATIONSHIPS_SQL({ schemaFilter });
15
+ const { data, error } = await this.query(sql);
16
+ if (error) return {
17
+ data: null,
18
+ error
19
+ };
20
+ allTableM2oAndO2oRelationships = data;
21
+ }
22
+ let allViewM2oAndO2oRelationships;
23
+ {
24
+ const viewsKeyDependenciesSql = VIEWS_KEY_DEPENDENCIES_SQL({ schemaFilter });
25
+ const { data: viewsKeyDependencies, error } = await this.query(viewsKeyDependenciesSql);
26
+ if (error) return {
27
+ data: null,
28
+ error
29
+ };
30
+ allViewM2oAndO2oRelationships = allTableM2oAndO2oRelationships.flatMap((r) => {
31
+ const expandKeyDepCols = (colDeps) => {
32
+ const tableColumns = colDeps.map(({ table_column }) => table_column);
33
+ const cartesianProduct = (allEntries) => {
34
+ return allEntries.reduce((results, entries) => results.map((result) => entries.map((entry) => result.concat(entry))).reduce((subResults, result) => subResults.concat(result), []), [[]]);
35
+ };
36
+ return cartesianProduct(colDeps.map((cd) => cd.view_columns)).map((viewColumns) => ({
37
+ tableColumns,
38
+ viewColumns
39
+ }));
40
+ };
41
+ const viewToTableKeyDeps = viewsKeyDependencies.filter((vkd) => vkd.table_schema === r.schema && vkd.table_name === r.relation && vkd.constraint_name === r.foreign_key_name && vkd.constraint_type === "f");
42
+ const tableToViewKeyDeps = viewsKeyDependencies.filter((vkd) => vkd.table_schema === r.referenced_schema && vkd.table_name === r.referenced_relation && vkd.constraint_name === r.foreign_key_name && vkd.constraint_type === "f_ref");
43
+ const viewToTableRelationships = viewToTableKeyDeps.flatMap((vtkd) => expandKeyDepCols(vtkd.column_dependencies).map(({ viewColumns }) => ({
44
+ foreign_key_name: r.foreign_key_name,
45
+ schema: vtkd.view_schema,
46
+ relation: vtkd.view_name,
47
+ columns: viewColumns,
48
+ is_one_to_one: r.is_one_to_one,
49
+ referenced_schema: r.referenced_schema,
50
+ referenced_relation: r.referenced_relation,
51
+ referenced_columns: r.referenced_columns
52
+ })));
53
+ const tableToViewRelationships = tableToViewKeyDeps.flatMap((tvkd) => expandKeyDepCols(tvkd.column_dependencies).map(({ viewColumns }) => ({
54
+ foreign_key_name: r.foreign_key_name,
55
+ schema: r.schema,
56
+ relation: r.relation,
57
+ columns: r.columns,
58
+ is_one_to_one: r.is_one_to_one,
59
+ referenced_schema: tvkd.view_schema,
60
+ referenced_relation: tvkd.view_name,
61
+ referenced_columns: viewColumns
62
+ })));
63
+ const viewToViewRelationships = viewToTableKeyDeps.flatMap((vtkd) => expandKeyDepCols(vtkd.column_dependencies).flatMap(({ viewColumns }) => tableToViewKeyDeps.flatMap((tvkd) => expandKeyDepCols(tvkd.column_dependencies).map(({ viewColumns: referencedViewColumns }) => ({
64
+ foreign_key_name: r.foreign_key_name,
65
+ schema: vtkd.view_schema,
66
+ relation: vtkd.view_name,
67
+ columns: viewColumns,
68
+ is_one_to_one: r.is_one_to_one,
69
+ referenced_schema: tvkd.view_schema,
70
+ referenced_relation: tvkd.view_name,
71
+ referenced_columns: referencedViewColumns
72
+ })))));
73
+ return [
74
+ ...viewToTableRelationships,
75
+ ...tableToViewRelationships,
76
+ ...viewToViewRelationships
77
+ ];
78
+ });
79
+ }
80
+ return {
81
+ data: allTableM2oAndO2oRelationships.concat(allViewM2oAndO2oRelationships),
82
+ error: null
83
+ };
84
+ }
85
+ };
86
+ //#endregion
87
+ export { PostgresMetaRelationships as default };
@@ -0,0 +1,203 @@
1
+ import { filterByValue } from "./helpers.js";
2
+ import { ROLES_SQL } from "./sql/roles.sql.js";
3
+ import { ident, literal } from "pg-format";
4
+ //#region src/vendor/postgres-meta/lib/PostgresMetaRoles.ts
5
+ function changeRoleConfig2Object(config) {
6
+ if (!config) return null;
7
+ return config.reduce((acc, cur) => {
8
+ const [key, value] = cur.split("=");
9
+ acc[key] = value;
10
+ return acc;
11
+ }, {});
12
+ }
13
+ var PostgresMetaRoles = class {
14
+ constructor(query) {
15
+ this.query = query;
16
+ }
17
+ async list({ includeDefaultRoles = false, limit, offset } = {}) {
18
+ const sql = ROLES_SQL({
19
+ limit,
20
+ offset,
21
+ includeDefaultRoles
22
+ });
23
+ const result = await this.query(sql);
24
+ if (result.data) result.data = result.data.map((role) => {
25
+ role.config = changeRoleConfig2Object(role.config);
26
+ return role;
27
+ });
28
+ return result;
29
+ }
30
+ async retrieve({ id, name }) {
31
+ if (id) {
32
+ const idsFilter = filterByValue([id]);
33
+ const sql = ROLES_SQL({ idsFilter });
34
+ const { data, error } = await this.query(sql);
35
+ if (error) return {
36
+ data,
37
+ error
38
+ };
39
+ else if (data.length === 0) return {
40
+ data: null,
41
+ error: { message: `Cannot find a role with ID ${id}` }
42
+ };
43
+ else {
44
+ data[0].config = changeRoleConfig2Object(data[0].config);
45
+ return {
46
+ data: data[0],
47
+ error
48
+ };
49
+ }
50
+ } else if (name) {
51
+ const nameFilter = filterByValue([name]);
52
+ const sql = ROLES_SQL({ nameFilter });
53
+ const { data, error } = await this.query(sql);
54
+ if (error) return {
55
+ data,
56
+ error
57
+ };
58
+ else if (data.length === 0) return {
59
+ data: null,
60
+ error: { message: `Cannot find a role named ${name}` }
61
+ };
62
+ else {
63
+ data[0].config = changeRoleConfig2Object(data[0].config);
64
+ return {
65
+ data: data[0],
66
+ error
67
+ };
68
+ }
69
+ } else return {
70
+ data: null,
71
+ error: { message: "Invalid parameters on role retrieve" }
72
+ };
73
+ }
74
+ async create({ name, is_superuser = false, can_create_db = false, can_create_role = false, inherit_role = true, can_login = false, is_replication_role = false, can_bypass_rls = false, connection_limit = -1, password, valid_until, member_of, members, admins, config }) {
75
+ const isSuperuserClause = is_superuser ? "SUPERUSER" : "NOSUPERUSER";
76
+ const canCreateDbClause = can_create_db ? "CREATEDB" : "NOCREATEDB";
77
+ const canCreateRoleClause = can_create_role ? "CREATEROLE" : "NOCREATEROLE";
78
+ const inheritRoleClause = inherit_role ? "INHERIT" : "NOINHERIT";
79
+ const canLoginClause = can_login ? "LOGIN" : "NOLOGIN";
80
+ const isReplicationRoleClause = is_replication_role ? "REPLICATION" : "NOREPLICATION";
81
+ const canBypassRlsClause = can_bypass_rls ? "BYPASSRLS" : "NOBYPASSRLS";
82
+ const connectionLimitClause = `CONNECTION LIMIT ${connection_limit}`;
83
+ const passwordClause = password === void 0 ? "" : `PASSWORD ${literal(password)}`;
84
+ const validUntilClause = valid_until === void 0 ? "" : `VALID UNTIL ${literal(valid_until)}`;
85
+ const memberOfClause = member_of === void 0 ? "" : `IN ROLE ${member_of.join(",")}`;
86
+ const membersClause = members === void 0 ? "" : `ROLE ${members.join(",")}`;
87
+ const adminsClause = admins === void 0 ? "" : `ADMIN ${admins.join(",")}`;
88
+ let configClause = "";
89
+ if (config !== void 0) configClause = Object.keys(config).map((k) => {
90
+ const v = config[k];
91
+ if (!k || !v) return "";
92
+ return `ALTER ROLE ${name} SET ${k} = ${v};`;
93
+ }).join("\n");
94
+ const sql = `
95
+ BEGIN;
96
+ CREATE ROLE ${ident(name)}
97
+ WITH
98
+ ${isSuperuserClause}
99
+ ${canCreateDbClause}
100
+ ${canCreateRoleClause}
101
+ ${inheritRoleClause}
102
+ ${canLoginClause}
103
+ ${isReplicationRoleClause}
104
+ ${canBypassRlsClause}
105
+ ${connectionLimitClause}
106
+ ${passwordClause}
107
+ ${validUntilClause}
108
+ ${memberOfClause}
109
+ ${membersClause}
110
+ ${adminsClause};
111
+ ${configClause ? configClause : ""}
112
+ COMMIT;`;
113
+ const { error } = await this.query(sql);
114
+ if (error) return {
115
+ data: null,
116
+ error
117
+ };
118
+ return await this.retrieve({ name });
119
+ }
120
+ async update(id, { name, is_superuser, can_create_db, can_create_role, inherit_role, can_login, is_replication_role, can_bypass_rls, connection_limit, password, valid_until, config }) {
121
+ const { data: old, error } = await this.retrieve({ id });
122
+ if (error) return {
123
+ data: null,
124
+ error
125
+ };
126
+ const nameSql = name === void 0 ? "" : `ALTER ROLE ${ident(old.name)} RENAME TO ${ident(name)};`;
127
+ let isSuperuserClause = "";
128
+ if (is_superuser !== void 0) isSuperuserClause = is_superuser ? "SUPERUSER" : "NOSUPERUSER";
129
+ let canCreateDbClause = "";
130
+ if (can_create_db !== void 0) canCreateDbClause = can_create_db ? "CREATEDB" : "NOCREATEDB";
131
+ let canCreateRoleClause = "";
132
+ if (can_create_role !== void 0) canCreateRoleClause = can_create_role ? "CREATEROLE" : "NOCREATEROLE";
133
+ let inheritRoleClause = "";
134
+ if (inherit_role !== void 0) inheritRoleClause = inherit_role ? "INHERIT" : "NOINHERIT";
135
+ let canLoginClause = "";
136
+ if (can_login !== void 0) canLoginClause = can_login ? "LOGIN" : "NOLOGIN";
137
+ let isReplicationRoleClause = "";
138
+ if (is_replication_role !== void 0) isReplicationRoleClause = is_replication_role ? "REPLICATION" : "NOREPLICATION";
139
+ let canBypassRlsClause = "";
140
+ if (can_bypass_rls !== void 0) canBypassRlsClause = can_bypass_rls ? "BYPASSRLS" : "NOBYPASSRLS";
141
+ const connectionLimitClause = connection_limit === void 0 ? "" : `CONNECTION LIMIT ${connection_limit}`;
142
+ const passwordClause = password === void 0 ? "" : `PASSWORD ${literal(password)}`;
143
+ const validUntilClause = valid_until === void 0 ? "" : `VALID UNTIL ${literal(valid_until)}`;
144
+ let configClause = "";
145
+ if (config !== void 0) configClause = config.map((c) => {
146
+ const { op, path, value } = c;
147
+ const k = path;
148
+ const v = value || null;
149
+ if (!k) throw new Error(`Invalid config value ${value}`);
150
+ switch (op) {
151
+ case "add":
152
+ case "replace": return `ALTER ROLE ${ident(old.name)} SET ${ident(k)} = ${literal(v)};`;
153
+ case "remove": return `ALTER ROLE ${ident(old.name)} RESET ${ident(k)};`;
154
+ default: throw new Error(`Invalid config op ${op}`);
155
+ }
156
+ }).filter(Boolean).join("");
157
+ const sql = `
158
+ BEGIN;
159
+ ALTER ROLE ${ident(old.name)}
160
+ ${isSuperuserClause}
161
+ ${canCreateDbClause}
162
+ ${canCreateRoleClause}
163
+ ${inheritRoleClause}
164
+ ${canLoginClause}
165
+ ${isReplicationRoleClause}
166
+ ${canBypassRlsClause}
167
+ ${connectionLimitClause}
168
+ ${passwordClause}
169
+ ${validUntilClause};
170
+ ${configClause ? configClause : ""}
171
+ ${nameSql}
172
+ COMMIT;`;
173
+ {
174
+ const { error } = await this.query(sql);
175
+ if (error) return {
176
+ data: null,
177
+ error
178
+ };
179
+ }
180
+ return await this.retrieve({ id });
181
+ }
182
+ async remove(id) {
183
+ const { data: role, error } = await this.retrieve({ id });
184
+ if (error) return {
185
+ data: null,
186
+ error
187
+ };
188
+ const sql = `DROP ROLE ${ident(role.name)};`;
189
+ {
190
+ const { error } = await this.query(sql);
191
+ if (error) return {
192
+ data: null,
193
+ error
194
+ };
195
+ }
196
+ return {
197
+ data: role,
198
+ error: null
199
+ };
200
+ }
201
+ };
202
+ //#endregion
203
+ export { changeRoleConfig2Object, PostgresMetaRoles as default };