neon 8.4.5 → 8.5.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/README.md +7 -7
- package/dist/_chunks/{env-4WGRW2nw.js → env-BNm69Qh8.js} +2 -5
- package/dist/commands/config.js +11 -28
- package/dist/commands/dev.js +1 -1
- package/dist/commands/env.js +2 -3
- package/dist/commands/init.js +1 -2
- package/dist/commands/manifest.js +1 -3
- package/dist/commands/subscribe.js +16 -16
- package/dist/credential_io.js +1 -2
- package/dist/dev/env.js +1 -2
- package/dist/index.js +1 -1
- package/dist/init/run.js +1 -2
- package/dist/plugins/run.js +2 -1
- package/dist/psql/command/cmd_io.js +1 -2
- package/dist/psql/command/cmd_pipeline.js +1 -2
- package/dist/psql/core/common.js +1 -2
- package/dist/psql/core/startup.js +1 -2
- package/dist/psql/index.js +1 -2
- package/dist/psql/types/index.js +1 -2
- package/dist/skills/catalog.js +5 -0
- package/dist/utils/hooks.js +0 -2
- package/dist/utils/staging.js +1 -14
- package/{LICENSE → dist/vendor/postgres-meta/LICENSE} +0 -1
- package/dist/vendor/postgres-meta/constants.js +14 -0
- package/dist/vendor/postgres-meta/lib/PostgresMeta.js +49 -0
- package/dist/vendor/postgres-meta/lib/PostgresMetaColumnPrivileges.js +85 -0
- package/dist/vendor/postgres-meta/lib/PostgresMetaColumns.js +235 -0
- package/dist/vendor/postgres-meta/lib/PostgresMetaConfig.js +16 -0
- package/dist/vendor/postgres-meta/lib/PostgresMetaExtensions.js +79 -0
- package/dist/vendor/postgres-meta/lib/PostgresMetaForeignTables.js +81 -0
- package/dist/vendor/postgres-meta/lib/PostgresMetaFunctions.js +173 -0
- package/dist/vendor/postgres-meta/lib/PostgresMetaIndexes.js +42 -0
- package/dist/vendor/postgres-meta/lib/PostgresMetaMaterializedViews.js +84 -0
- package/dist/vendor/postgres-meta/lib/PostgresMetaPolicies.js +120 -0
- package/dist/vendor/postgres-meta/lib/PostgresMetaPublications.js +193 -0
- package/dist/vendor/postgres-meta/lib/PostgresMetaRelationships.js +87 -0
- package/dist/vendor/postgres-meta/lib/PostgresMetaRoles.js +203 -0
- package/dist/vendor/postgres-meta/lib/PostgresMetaSchemas.js +105 -0
- package/dist/vendor/postgres-meta/lib/PostgresMetaTablePrivileges.js +91 -0
- package/dist/vendor/postgres-meta/lib/PostgresMetaTables.js +183 -0
- package/dist/vendor/postgres-meta/lib/PostgresMetaTriggers.js +156 -0
- package/dist/vendor/postgres-meta/lib/PostgresMetaTypes.js +22 -0
- package/dist/vendor/postgres-meta/lib/PostgresMetaVersion.js +20 -0
- package/dist/vendor/postgres-meta/lib/PostgresMetaViews.js +83 -0
- package/dist/vendor/postgres-meta/lib/constants.js +8 -0
- package/dist/vendor/postgres-meta/lib/db.js +147 -0
- package/dist/vendor/postgres-meta/lib/generators.js +106 -0
- package/dist/vendor/postgres-meta/lib/helpers.js +26 -0
- package/dist/vendor/postgres-meta/lib/index.js +1 -0
- package/dist/vendor/postgres-meta/lib/sql/column_privileges.sql.js +154 -0
- package/dist/vendor/postgres-meta/lib/sql/columns.sql.js +123 -0
- package/dist/vendor/postgres-meta/lib/sql/common.js +1 -0
- package/dist/vendor/postgres-meta/lib/sql/config.sql.js +32 -0
- package/dist/vendor/postgres-meta/lib/sql/extensions.sql.js +20 -0
- package/dist/vendor/postgres-meta/lib/sql/foreign_tables.sql.js +20 -0
- package/dist/vendor/postgres-meta/lib/sql/functions.sql.js +141 -0
- package/dist/vendor/postgres-meta/lib/sql/indexes.sql.js +51 -0
- package/dist/vendor/postgres-meta/lib/sql/materialized_views.sql.js +21 -0
- package/dist/vendor/postgres-meta/lib/sql/policies.sql.js +53 -0
- package/dist/vendor/postgres-meta/lib/sql/publications.sql.js +46 -0
- package/dist/vendor/postgres-meta/lib/sql/roles.sql.js +40 -0
- package/dist/vendor/postgres-meta/lib/sql/schemas.sql.js +26 -0
- package/dist/vendor/postgres-meta/lib/sql/table.sql.js +109 -0
- package/dist/vendor/postgres-meta/lib/sql/table_privileges.sql.js +85 -0
- package/dist/vendor/postgres-meta/lib/sql/table_relationships.sql.js +52 -0
- package/dist/vendor/postgres-meta/lib/sql/triggers.sql.js +64 -0
- package/dist/vendor/postgres-meta/lib/sql/types.sql.js +65 -0
- package/dist/vendor/postgres-meta/lib/sql/version.sql.js +15 -0
- package/dist/vendor/postgres-meta/lib/sql/views.sql.js +22 -0
- package/dist/vendor/postgres-meta/lib/sql/views_key_dependencies.sql.js +198 -0
- package/dist/vendor/postgres-meta/lib/types.js +1 -0
- package/dist/vendor/postgres-meta/templates/typescript.js +608 -0
- package/package.json +13 -6
|
@@ -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 };
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import { DEFAULT_SYSTEM_SCHEMAS } from "./constants.js";
|
|
2
|
+
import { filterByList, filterByValue } from "./helpers.js";
|
|
3
|
+
import { SCHEMAS_SQL } from "./sql/schemas.sql.js";
|
|
4
|
+
import { ident } from "pg-format";
|
|
5
|
+
//#region src/vendor/postgres-meta/lib/PostgresMetaSchemas.ts
|
|
6
|
+
var PostgresMetaSchemas = class {
|
|
7
|
+
constructor(query) {
|
|
8
|
+
this.query = query;
|
|
9
|
+
}
|
|
10
|
+
async list({ includedSchemas, excludedSchemas, includeSystemSchemas = false, limit, offset } = {}) {
|
|
11
|
+
const schemaFilter = filterByList(includedSchemas, excludedSchemas, !includeSystemSchemas ? DEFAULT_SYSTEM_SCHEMAS : void 0);
|
|
12
|
+
const sql = SCHEMAS_SQL({
|
|
13
|
+
limit,
|
|
14
|
+
offset,
|
|
15
|
+
includeSystemSchemas,
|
|
16
|
+
nameFilter: schemaFilter
|
|
17
|
+
});
|
|
18
|
+
return await this.query(sql);
|
|
19
|
+
}
|
|
20
|
+
async retrieve({ id, name }) {
|
|
21
|
+
if (id) {
|
|
22
|
+
const idsFilter = filterByValue([id]);
|
|
23
|
+
const sql = SCHEMAS_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 schema with ID ${id}` }
|
|
32
|
+
};
|
|
33
|
+
else return {
|
|
34
|
+
data: data[0],
|
|
35
|
+
error
|
|
36
|
+
};
|
|
37
|
+
} else if (name) {
|
|
38
|
+
const nameFilter = filterByValue([name]);
|
|
39
|
+
const sql = SCHEMAS_SQL({ nameFilter });
|
|
40
|
+
const { data, error } = await this.query(sql);
|
|
41
|
+
if (error) return {
|
|
42
|
+
data,
|
|
43
|
+
error
|
|
44
|
+
};
|
|
45
|
+
else if (data.length === 0) return {
|
|
46
|
+
data: null,
|
|
47
|
+
error: { message: `Cannot find a schema named ${name}` }
|
|
48
|
+
};
|
|
49
|
+
else return {
|
|
50
|
+
data: data[0],
|
|
51
|
+
error
|
|
52
|
+
};
|
|
53
|
+
} else return {
|
|
54
|
+
data: null,
|
|
55
|
+
error: { message: "Invalid parameters on schema retrieve" }
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
async create({ name, owner = "postgres" }) {
|
|
59
|
+
const sql = `CREATE SCHEMA ${ident(name)} AUTHORIZATION ${ident(owner)};`;
|
|
60
|
+
const { error } = await this.query(sql);
|
|
61
|
+
if (error) return {
|
|
62
|
+
data: null,
|
|
63
|
+
error
|
|
64
|
+
};
|
|
65
|
+
return await this.retrieve({ name });
|
|
66
|
+
}
|
|
67
|
+
async update(id, { name, owner }) {
|
|
68
|
+
const { data: old, error } = await this.retrieve({ id });
|
|
69
|
+
if (error) return {
|
|
70
|
+
data: null,
|
|
71
|
+
error
|
|
72
|
+
};
|
|
73
|
+
const nameSql = name === void 0 ? "" : `ALTER SCHEMA ${ident(old.name)} RENAME TO ${ident(name)};`;
|
|
74
|
+
const sql = `BEGIN; ${owner === void 0 ? "" : `ALTER SCHEMA ${ident(old.name)} OWNER TO ${ident(owner)};`} ${nameSql} COMMIT;`;
|
|
75
|
+
{
|
|
76
|
+
const { error } = await this.query(sql);
|
|
77
|
+
if (error) return {
|
|
78
|
+
data: null,
|
|
79
|
+
error
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
return await this.retrieve({ id });
|
|
83
|
+
}
|
|
84
|
+
async remove(id, { cascade = false } = {}) {
|
|
85
|
+
const { data: schema, error } = await this.retrieve({ id });
|
|
86
|
+
if (error) return {
|
|
87
|
+
data: null,
|
|
88
|
+
error
|
|
89
|
+
};
|
|
90
|
+
const sql = `DROP SCHEMA ${ident(schema.name)} ${cascade ? "CASCADE" : "RESTRICT"};`;
|
|
91
|
+
{
|
|
92
|
+
const { error } = await this.query(sql);
|
|
93
|
+
if (error) return {
|
|
94
|
+
data: null,
|
|
95
|
+
error
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
return {
|
|
99
|
+
data: schema,
|
|
100
|
+
error: null
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
};
|
|
104
|
+
//#endregion
|
|
105
|
+
export { PostgresMetaSchemas as default };
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { DEFAULT_SYSTEM_SCHEMAS } from "./constants.js";
|
|
2
|
+
import { filterByList, filterByValue } from "./helpers.js";
|
|
3
|
+
import { TABLE_PRIVILEGES_SQL } from "./sql/table_privileges.sql.js";
|
|
4
|
+
import { ident } from "pg-format";
|
|
5
|
+
//#region src/vendor/postgres-meta/lib/PostgresMetaTablePrivileges.ts
|
|
6
|
+
var PostgresMetaTablePrivileges = 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
|
+
const sql = TABLE_PRIVILEGES_SQL({
|
|
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 = TABLE_PRIVILEGES_SQL({ idsFilter });
|
|
23
|
+
const { data, error } = await this.query(sql);
|
|
24
|
+
if (error) return {
|
|
25
|
+
data,
|
|
26
|
+
error
|
|
27
|
+
};
|
|
28
|
+
else if (data.length === 0) return {
|
|
29
|
+
data: null,
|
|
30
|
+
error: { message: `Cannot find a relation with ID ${id}` }
|
|
31
|
+
};
|
|
32
|
+
else return {
|
|
33
|
+
data: data[0],
|
|
34
|
+
error
|
|
35
|
+
};
|
|
36
|
+
} else if (name) {
|
|
37
|
+
const nameIdentifierFilter = filterByValue([`${schema}.${name}`]);
|
|
38
|
+
const sql = TABLE_PRIVILEGES_SQL({ nameIdentifierFilter });
|
|
39
|
+
const { data, error } = await this.query(sql);
|
|
40
|
+
if (error) return {
|
|
41
|
+
data,
|
|
42
|
+
error
|
|
43
|
+
};
|
|
44
|
+
else if (data.length === 0) return {
|
|
45
|
+
data: null,
|
|
46
|
+
error: { message: `Cannot find a relation named ${name} in schema ${schema}` }
|
|
47
|
+
};
|
|
48
|
+
else return {
|
|
49
|
+
data: data[0],
|
|
50
|
+
error
|
|
51
|
+
};
|
|
52
|
+
} else return {
|
|
53
|
+
data: null,
|
|
54
|
+
error: { message: "Invalid parameters on retrieving table privileges" }
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
async grant(grants) {
|
|
58
|
+
let sql = `
|
|
59
|
+
do $$
|
|
60
|
+
begin
|
|
61
|
+
${grants.map(({ privilege_type, relation_id, grantee, is_grantable }) => `execute format('grant ${privilege_type} on table %s to ${grantee.toLowerCase() === "public" ? "public" : ident(grantee)} ${is_grantable ? "with grant option" : ""}', ${relation_id}::regclass);`).join("\n")}
|
|
62
|
+
end $$;
|
|
63
|
+
`;
|
|
64
|
+
const { data, error } = await this.query(sql);
|
|
65
|
+
if (error) return {
|
|
66
|
+
data,
|
|
67
|
+
error
|
|
68
|
+
};
|
|
69
|
+
const relationIds = [...new Set(grants.map(({ relation_id }) => relation_id))];
|
|
70
|
+
sql = TABLE_PRIVILEGES_SQL({ idsFilter: filterByList(relationIds) });
|
|
71
|
+
return await this.query(sql);
|
|
72
|
+
}
|
|
73
|
+
async revoke(revokes) {
|
|
74
|
+
let sql = `
|
|
75
|
+
do $$
|
|
76
|
+
begin
|
|
77
|
+
${revokes.map((revoke) => `execute format('revoke ${revoke.privilege_type} on table %s from ${revoke.grantee}', ${revoke.relation_id}::regclass);`).join("\n")}
|
|
78
|
+
end $$;
|
|
79
|
+
`;
|
|
80
|
+
const { data, error } = await this.query(sql);
|
|
81
|
+
if (error) return {
|
|
82
|
+
data,
|
|
83
|
+
error
|
|
84
|
+
};
|
|
85
|
+
const relationIds = [...new Set(revokes.map(({ relation_id }) => relation_id))];
|
|
86
|
+
sql = TABLE_PRIVILEGES_SQL({ idsFilter: filterByList(relationIds) });
|
|
87
|
+
return await this.query(sql);
|
|
88
|
+
}
|
|
89
|
+
};
|
|
90
|
+
//#endregion
|
|
91
|
+
export { PostgresMetaTablePrivileges as default };
|
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
import { DEFAULT_SYSTEM_SCHEMAS } from "./constants.js";
|
|
2
|
+
import { coalesceRowsToArray, filterByList, filterByValue } from "./helpers.js";
|
|
3
|
+
import { TABLES_SQL } from "./sql/table.sql.js";
|
|
4
|
+
import { COLUMNS_SQL } from "./sql/columns.sql.js";
|
|
5
|
+
import { ident, literal } from "pg-format";
|
|
6
|
+
//#region src/vendor/postgres-meta/lib/PostgresMetaTables.ts
|
|
7
|
+
var PostgresMetaTables = class {
|
|
8
|
+
constructor(query) {
|
|
9
|
+
this.query = query;
|
|
10
|
+
}
|
|
11
|
+
async list({ includeSystemSchemas = false, includedSchemas, excludedSchemas, limit, offset, includeColumns = true } = {}) {
|
|
12
|
+
const schemaFilter = filterByList(includedSchemas, excludedSchemas, !includeSystemSchemas ? DEFAULT_SYSTEM_SCHEMAS : void 0);
|
|
13
|
+
const sql = generateEnrichedTablesSql({
|
|
14
|
+
includeColumns,
|
|
15
|
+
schemaFilter,
|
|
16
|
+
limit,
|
|
17
|
+
offset
|
|
18
|
+
});
|
|
19
|
+
return await this.query(sql);
|
|
20
|
+
}
|
|
21
|
+
async retrieve({ id, name, schema = "public" }) {
|
|
22
|
+
const schemaFilter = schema ? filterByList([schema], []) : void 0;
|
|
23
|
+
if (id) {
|
|
24
|
+
const idsFilter = filterByValue([id]);
|
|
25
|
+
const sql = generateEnrichedTablesSql({
|
|
26
|
+
schemaFilter,
|
|
27
|
+
includeColumns: true,
|
|
28
|
+
idsFilter
|
|
29
|
+
});
|
|
30
|
+
const { data, error } = await this.query(sql);
|
|
31
|
+
if (error) return {
|
|
32
|
+
data,
|
|
33
|
+
error
|
|
34
|
+
};
|
|
35
|
+
else if (data.length === 0) return {
|
|
36
|
+
data: null,
|
|
37
|
+
error: { message: `Cannot find a table with ID ${id}` }
|
|
38
|
+
};
|
|
39
|
+
else return {
|
|
40
|
+
data: data[0],
|
|
41
|
+
error
|
|
42
|
+
};
|
|
43
|
+
} else if (name) {
|
|
44
|
+
const tableIdentifierFilter = filterByValue([`${schema}.${name}`]);
|
|
45
|
+
const sql = generateEnrichedTablesSql({
|
|
46
|
+
schemaFilter,
|
|
47
|
+
includeColumns: true,
|
|
48
|
+
tableIdentifierFilter
|
|
49
|
+
});
|
|
50
|
+
const { data, error } = await this.query(sql);
|
|
51
|
+
if (error) return {
|
|
52
|
+
data,
|
|
53
|
+
error
|
|
54
|
+
};
|
|
55
|
+
else if (data.length === 0) return {
|
|
56
|
+
data: null,
|
|
57
|
+
error: { message: `Cannot find a table named ${name} in schema ${schema}` }
|
|
58
|
+
};
|
|
59
|
+
else return {
|
|
60
|
+
data: data[0],
|
|
61
|
+
error
|
|
62
|
+
};
|
|
63
|
+
} else return {
|
|
64
|
+
data: null,
|
|
65
|
+
error: { message: "Invalid parameters on table retrieve" }
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
async create({ name, schema = "public", comment }) {
|
|
69
|
+
const sql = `BEGIN; ${`CREATE TABLE ${ident(schema)}.${ident(name)} ();`} ${comment === void 0 ? "" : `COMMENT ON TABLE ${ident(schema)}.${ident(name)} IS ${literal(comment)};`} COMMIT;`;
|
|
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
|
+
schema
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
async update(id, { name, schema, rls_enabled, rls_forced, replica_identity, replica_identity_index, primary_keys, comment }) {
|
|
81
|
+
const { data: old, error } = await this.retrieve({ id });
|
|
82
|
+
if (error) return {
|
|
83
|
+
data: null,
|
|
84
|
+
error
|
|
85
|
+
};
|
|
86
|
+
const alter = `ALTER TABLE ${ident(old.schema)}.${ident(old.name)}`;
|
|
87
|
+
const schemaSql = schema === void 0 ? "" : `${alter} SET SCHEMA ${ident(schema)};`;
|
|
88
|
+
let nameSql = "";
|
|
89
|
+
if (name !== void 0 && name !== old.name) {
|
|
90
|
+
const currentSchema = schema === void 0 ? old.schema : schema;
|
|
91
|
+
nameSql = `ALTER TABLE ${ident(currentSchema)}.${ident(old.name)} RENAME TO ${ident(name)};`;
|
|
92
|
+
}
|
|
93
|
+
let enableRls = "";
|
|
94
|
+
if (rls_enabled !== void 0) {
|
|
95
|
+
const enable = `${alter} ENABLE ROW LEVEL SECURITY;`;
|
|
96
|
+
const disable = `${alter} DISABLE ROW LEVEL SECURITY;`;
|
|
97
|
+
enableRls = rls_enabled ? enable : disable;
|
|
98
|
+
}
|
|
99
|
+
let forceRls = "";
|
|
100
|
+
if (rls_forced !== void 0) {
|
|
101
|
+
const enable = `${alter} FORCE ROW LEVEL SECURITY;`;
|
|
102
|
+
const disable = `${alter} NO FORCE ROW LEVEL SECURITY;`;
|
|
103
|
+
forceRls = rls_forced ? enable : disable;
|
|
104
|
+
}
|
|
105
|
+
let replicaSql = "";
|
|
106
|
+
if (replica_identity === void 0) {} else if (replica_identity === "INDEX") replicaSql = `${alter} REPLICA IDENTITY USING INDEX ${replica_identity_index};`;
|
|
107
|
+
else replicaSql = `${alter} REPLICA IDENTITY ${replica_identity};`;
|
|
108
|
+
let primaryKeysSql = "";
|
|
109
|
+
if (primary_keys === void 0) {} else {
|
|
110
|
+
if (old.primary_keys.length !== 0) primaryKeysSql += `
|
|
111
|
+
DO $$
|
|
112
|
+
DECLARE
|
|
113
|
+
r record;
|
|
114
|
+
BEGIN
|
|
115
|
+
SELECT conname
|
|
116
|
+
INTO r
|
|
117
|
+
FROM pg_constraint
|
|
118
|
+
WHERE contype = 'p' AND conrelid = ${literal(id)};
|
|
119
|
+
EXECUTE ${literal(`${alter} DROP CONSTRAINT `)} || quote_ident(r.conname);
|
|
120
|
+
END
|
|
121
|
+
$$;
|
|
122
|
+
`;
|
|
123
|
+
if (primary_keys.length === 0) {} else primaryKeysSql += `${alter} ADD PRIMARY KEY (${primary_keys.map((x) => ident(x.name)).join(",")});`;
|
|
124
|
+
}
|
|
125
|
+
const commentSql = comment === void 0 ? "" : `COMMENT ON TABLE ${ident(old.schema)}.${ident(old.name)} IS ${literal(comment)};`;
|
|
126
|
+
const sql = `
|
|
127
|
+
BEGIN;
|
|
128
|
+
${enableRls}
|
|
129
|
+
${forceRls}
|
|
130
|
+
${replicaSql}
|
|
131
|
+
${primaryKeysSql}
|
|
132
|
+
${commentSql}
|
|
133
|
+
${schemaSql}
|
|
134
|
+
${nameSql}
|
|
135
|
+
COMMIT;`;
|
|
136
|
+
{
|
|
137
|
+
const { error } = await this.query(sql);
|
|
138
|
+
if (error) return {
|
|
139
|
+
data: null,
|
|
140
|
+
error
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
return await this.retrieve({ id });
|
|
144
|
+
}
|
|
145
|
+
async remove(id, { cascade = false } = {}) {
|
|
146
|
+
const { data: table, error } = await this.retrieve({ id });
|
|
147
|
+
if (error) return {
|
|
148
|
+
data: null,
|
|
149
|
+
error
|
|
150
|
+
};
|
|
151
|
+
const sql = `DROP TABLE ${ident(table.schema)}.${ident(table.name)} ${cascade ? "CASCADE" : "RESTRICT"};`;
|
|
152
|
+
{
|
|
153
|
+
const { error } = await this.query(sql);
|
|
154
|
+
if (error) return {
|
|
155
|
+
data: null,
|
|
156
|
+
error
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
return {
|
|
160
|
+
data: table,
|
|
161
|
+
error: null
|
|
162
|
+
};
|
|
163
|
+
}
|
|
164
|
+
};
|
|
165
|
+
const generateEnrichedTablesSql = ({ includeColumns, schemaFilter, tableIdentifierFilter, idsFilter, limit, offset }) => `
|
|
166
|
+
with tables as (${TABLES_SQL({
|
|
167
|
+
schemaFilter,
|
|
168
|
+
tableIdentifierFilter,
|
|
169
|
+
idsFilter,
|
|
170
|
+
limit,
|
|
171
|
+
offset
|
|
172
|
+
})})
|
|
173
|
+
${includeColumns ? `, columns as (${COLUMNS_SQL({
|
|
174
|
+
schemaFilter,
|
|
175
|
+
tableIdFilter: idsFilter,
|
|
176
|
+
tableIdentifierFilter
|
|
177
|
+
})})` : ""}
|
|
178
|
+
select
|
|
179
|
+
*
|
|
180
|
+
${includeColumns ? `, ${coalesceRowsToArray("columns", "columns.table_id = tables.id")}` : ""}
|
|
181
|
+
from tables`;
|
|
182
|
+
//#endregion
|
|
183
|
+
export { PostgresMetaTables as default };
|