rake-db 2.33.4 → 2.33.6
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/index.d.ts +17 -1
- package/dist/index.js +62 -2
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +62 -2
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
package/dist/index.d.ts
CHANGED
|
@@ -5,10 +5,15 @@ declare namespace DbStructure {
|
|
|
5
5
|
schemaName: string;
|
|
6
6
|
tableName: string;
|
|
7
7
|
}
|
|
8
|
+
interface TableRls {
|
|
9
|
+
enable: boolean;
|
|
10
|
+
force: boolean;
|
|
11
|
+
}
|
|
8
12
|
interface Table {
|
|
9
13
|
schemaName: string;
|
|
10
14
|
name: string;
|
|
11
15
|
comment?: string;
|
|
16
|
+
rls?: TableRls;
|
|
12
17
|
columns: Column[];
|
|
13
18
|
}
|
|
14
19
|
interface View {
|
|
@@ -194,6 +199,7 @@ interface IntrospectedStructure {
|
|
|
194
199
|
managedRolesSql?: string;
|
|
195
200
|
}
|
|
196
201
|
interface IntrospectDbStructureParams {
|
|
202
|
+
rls?: boolean;
|
|
197
203
|
roles?: {
|
|
198
204
|
whereSql?: string;
|
|
199
205
|
};
|
|
@@ -201,7 +207,7 @@ interface IntrospectDbStructureParams {
|
|
|
201
207
|
}
|
|
202
208
|
declare function getDbVersion(db: Adapter): Promise<number>;
|
|
203
209
|
declare function introspectDbSchema(db: Adapter, params?: IntrospectDbStructureParams): Promise<IntrospectedStructure>;
|
|
204
|
-
type RakeDbAst = RakeDbAst.Table | RakeDbAst.ChangeTable | RakeDbAst.RenameType | RakeDbAst.Schema | RakeDbAst.RenameSchema | RakeDbAst.Extension | RakeDbAst.Enum | RakeDbAst.EnumValues | RakeDbAst.RenameEnumValues | RakeDbAst.ChangeEnumValues | RakeDbAst.Domain | RakeDbAst.Collation | RakeDbAst.Constraint | RakeDbAst.RenameTableItem | RakeDbAst.View | RakeDbAst.Role | RakeDbAst.RenameRole | RakeDbAst.ChangeRole | RakeDbAst.DefaultPrivilege;
|
|
210
|
+
type RakeDbAst = RakeDbAst.Table | RakeDbAst.ChangeTable | RakeDbAst.RenameType | RakeDbAst.Schema | RakeDbAst.RenameSchema | RakeDbAst.Extension | RakeDbAst.Enum | RakeDbAst.EnumValues | RakeDbAst.RenameEnumValues | RakeDbAst.ChangeEnumValues | RakeDbAst.Domain | RakeDbAst.Collation | RakeDbAst.Constraint | RakeDbAst.RenameTableItem | RakeDbAst.View | RakeDbAst.Role | RakeDbAst.RenameRole | RakeDbAst.ChangeRole | RakeDbAst.DefaultPrivilege | RakeDbAst.TableRls;
|
|
205
211
|
declare namespace RakeDbAst {
|
|
206
212
|
export interface Table extends TableData {
|
|
207
213
|
type: 'table';
|
|
@@ -427,6 +433,12 @@ declare namespace RakeDbAst {
|
|
|
427
433
|
grant?: DefaultPrivilegeObjectConfig;
|
|
428
434
|
revoke?: DefaultPrivilegeObjectConfig;
|
|
429
435
|
}
|
|
436
|
+
export interface TableRls {
|
|
437
|
+
type: 'tableRls';
|
|
438
|
+
action: 'enable' | 'disable' | 'force' | 'noForce';
|
|
439
|
+
schema?: string;
|
|
440
|
+
table: string;
|
|
441
|
+
}
|
|
430
442
|
export {};
|
|
431
443
|
}
|
|
432
444
|
interface TableMethods {
|
|
@@ -1441,6 +1453,10 @@ declare class Migration<CT = unknown> {
|
|
|
1441
1453
|
to: Partial<DbStructure.Role>;
|
|
1442
1454
|
}): Promise<void>;
|
|
1443
1455
|
changeDefaultPrivileges(params: ChangeDefaultPrivilegesArg): Promise<void>;
|
|
1456
|
+
enableRls(tableName: string): Promise<void>;
|
|
1457
|
+
disableRls(tableName: string): Promise<void>;
|
|
1458
|
+
forceRls(tableName: string): Promise<void>;
|
|
1459
|
+
noForceRls(tableName: string): Promise<void>;
|
|
1444
1460
|
}
|
|
1445
1461
|
interface AddEnumValueOptions {
|
|
1446
1462
|
ifNotExists?: boolean;
|
package/dist/index.js
CHANGED
|
@@ -1226,6 +1226,22 @@ const buildQuery = (ast, objectType, privileges, grantable, action) => {
|
|
|
1226
1226
|
} else parts.push(`REVOKE ${privilegeList} ON ${objectTypeToSql[objectType]} FROM "${ast.grantee}"`);
|
|
1227
1227
|
return parts.join(" ");
|
|
1228
1228
|
};
|
|
1229
|
+
const actionToSql = {
|
|
1230
|
+
enable: "ENABLE ROW LEVEL SECURITY",
|
|
1231
|
+
disable: "DISABLE ROW LEVEL SECURITY",
|
|
1232
|
+
force: "FORCE ROW LEVEL SECURITY",
|
|
1233
|
+
noForce: "NO FORCE ROW LEVEL SECURITY"
|
|
1234
|
+
};
|
|
1235
|
+
const setRls = async (migration, tableName, action) => {
|
|
1236
|
+
const [schema, table] = getSchemaAndTableFromName(migration.adapter.getSchema(), tableName);
|
|
1237
|
+
await migration.adapter.arrays(`ALTER TABLE ${quoteTable(schema, table)} ${actionToSql[action]}`);
|
|
1238
|
+
};
|
|
1239
|
+
const enableOrDisableRls = (migration, up, tableName) => {
|
|
1240
|
+
return setRls(migration, tableName, up ? "enable" : "disable");
|
|
1241
|
+
};
|
|
1242
|
+
const forceOrNoForceRls = (migration, up, tableName) => {
|
|
1243
|
+
return setRls(migration, tableName, up ? "force" : "noForce");
|
|
1244
|
+
};
|
|
1229
1245
|
/**
|
|
1230
1246
|
* Creates a new `db` instance that is an instance of `pqb` with mixed in migration methods from the `Migration` class.
|
|
1231
1247
|
* It overrides `query` and `array` db adapter methods to intercept SQL for the logging.
|
|
@@ -2087,6 +2103,18 @@ var Migration = class {
|
|
|
2087
2103
|
changeDefaultPrivileges(params) {
|
|
2088
2104
|
return changeDefaultPrivileges(this, this.up, params);
|
|
2089
2105
|
}
|
|
2106
|
+
enableRls(tableName) {
|
|
2107
|
+
return enableOrDisableRls(this, this.up, tableName);
|
|
2108
|
+
}
|
|
2109
|
+
disableRls(tableName) {
|
|
2110
|
+
return enableOrDisableRls(this, !this.up, tableName);
|
|
2111
|
+
}
|
|
2112
|
+
forceRls(tableName) {
|
|
2113
|
+
return forceOrNoForceRls(this, this.up, tableName);
|
|
2114
|
+
}
|
|
2115
|
+
noForceRls(tableName) {
|
|
2116
|
+
return forceOrNoForceRls(this, !this.up, tableName);
|
|
2117
|
+
}
|
|
2090
2118
|
};
|
|
2091
2119
|
const wrapWithEnhancingError = async (text, values, promise) => {
|
|
2092
2120
|
try {
|
|
@@ -3431,6 +3459,11 @@ const astToGenerateItem = (config, ast, currentSchema) => {
|
|
|
3431
3459
|
if (ast.owner) deps.push(`role:${ast.owner}`);
|
|
3432
3460
|
deps.push(`role:${ast.grantee}`);
|
|
3433
3461
|
break;
|
|
3462
|
+
case "tableRls": {
|
|
3463
|
+
const { schema = currentSchema } = ast;
|
|
3464
|
+
deps.push(schema, `${schema}.${ast.table}`);
|
|
3465
|
+
break;
|
|
3466
|
+
}
|
|
3434
3467
|
default: (0, pqb_internal.exhaustive)(ast);
|
|
3435
3468
|
}
|
|
3436
3469
|
return {
|
|
@@ -3896,6 +3929,13 @@ const astEncoders = {
|
|
|
3896
3929
|
code.push(props);
|
|
3897
3930
|
(0, pqb_internal.addCode)(code, "});");
|
|
3898
3931
|
return code;
|
|
3932
|
+
},
|
|
3933
|
+
tableRls(ast, _config, currentSchema) {
|
|
3934
|
+
const table = quoteSchemaTable({
|
|
3935
|
+
schema: ast.schema,
|
|
3936
|
+
name: ast.table
|
|
3937
|
+
}, currentSchema);
|
|
3938
|
+
return `await db.${ast.action === "enable" ? "enableRls" : ast.action === "disable" ? "disableRls" : ast.action === "force" ? "forceRls" : "noForceRls"}(${table});`;
|
|
3899
3939
|
}
|
|
3900
3940
|
};
|
|
3901
3941
|
const roleParams = (name, ast, compare, to) => {
|
|
@@ -4028,10 +4068,18 @@ ORDER BY a.attnum`;
|
|
|
4028
4068
|
const schemasSql = `SELECT coalesce(json_agg(nspname ORDER BY nspname), '[]')
|
|
4029
4069
|
FROM pg_catalog.pg_namespace n
|
|
4030
4070
|
WHERE ${filterSchema("nspname")}`;
|
|
4031
|
-
const tablesSql = `SELECT
|
|
4071
|
+
const tablesSql = (rls) => `SELECT
|
|
4032
4072
|
nspname AS "schemaName",
|
|
4033
4073
|
relname AS "name",
|
|
4034
4074
|
obj_description(c.oid) AS comment,
|
|
4075
|
+
${rls ? `(SELECT json_build_object(
|
|
4076
|
+
'enable', rc.relrowsecurity,
|
|
4077
|
+
'force', rc.relforcerowsecurity
|
|
4078
|
+
)
|
|
4079
|
+
FROM pg_class rc
|
|
4080
|
+
JOIN pg_namespace nr ON nr.oid = rc.relnamespace
|
|
4081
|
+
WHERE rc.relname = c.relname
|
|
4082
|
+
AND nr.nspname = n.nspname) AS "rls",` : ""}
|
|
4035
4083
|
(SELECT coalesce(json_agg(t), '[]') FROM (${columnsSql({
|
|
4036
4084
|
schema: "n",
|
|
4037
4085
|
table: "c",
|
|
@@ -4351,7 +4399,7 @@ const defaultPrivilegesSql = `SELECT COALESCE(json_agg(t.*), '[]') FROM (
|
|
|
4351
4399
|
JOIN LATERAL aclexplode(d.defaclacl) ae ON true
|
|
4352
4400
|
GROUP BY "grantor", "grantee", "schema", "object"
|
|
4353
4401
|
) t`;
|
|
4354
|
-
const sql = (version, params) => `SELECT (${schemasSql}) AS "schemas", ${jsonAgg(tablesSql, "tables")}, ${jsonAgg(viewsSql, "views")}, ${jsonAgg(indexesSql, "indexes")}, ${jsonAgg(constraintsSql, "constraints")}, ${jsonAgg(triggersSql, "triggers")}, ${jsonAgg(extensionsSql, "extensions")}, ${jsonAgg(enumsSql, "enums")}, ${jsonAgg(domainsSql, "domains")}, ${jsonAgg(collationsSql(version), "collations")}${params?.roles ? `, (${roleSql(params.roles)}) AS "roles"` : ""}${params?.loadDefaultPrivileges ? `, (${defaultPrivilegesSql}) AS "defaultPrivileges"` : ""}`;
|
|
4402
|
+
const sql = (version, params) => `SELECT (${schemasSql}) AS "schemas", ${jsonAgg(tablesSql(params?.rls), "tables")}, ${jsonAgg(viewsSql, "views")}, ${jsonAgg(indexesSql, "indexes")}, ${jsonAgg(constraintsSql, "constraints")}, ${jsonAgg(triggersSql, "triggers")}, ${jsonAgg(extensionsSql, "extensions")}, ${jsonAgg(enumsSql, "enums")}, ${jsonAgg(domainsSql, "domains")}, ${jsonAgg(collationsSql(version), "collations")}${params?.roles ? `, (${roleSql(params.roles)}) AS "roles"` : ""}${params?.loadDefaultPrivileges ? `, (${defaultPrivilegesSql}) AS "defaultPrivileges"` : ""}`;
|
|
4355
4403
|
async function getDbVersion(db) {
|
|
4356
4404
|
const { rows: [{ version: versionString }] } = await db.query("SELECT version()");
|
|
4357
4405
|
return +versionString.match(/\d+/)[0];
|
|
@@ -4498,6 +4546,18 @@ const structureToAst = async (ctx, adapter, config) => {
|
|
|
4498
4546
|
for (const table of data.tables) {
|
|
4499
4547
|
if (table.name === migrationsTable && table.schemaName === migrationsSchema) continue;
|
|
4500
4548
|
ast.push(tableToAst(ctx, data, table, "create", domains));
|
|
4549
|
+
if (table.rls?.enable) ast.push({
|
|
4550
|
+
type: "tableRls",
|
|
4551
|
+
action: "enable",
|
|
4552
|
+
schema: table.schemaName === ctx.currentSchema ? void 0 : table.schemaName,
|
|
4553
|
+
table: table.name
|
|
4554
|
+
});
|
|
4555
|
+
if (table.rls?.force) ast.push({
|
|
4556
|
+
type: "tableRls",
|
|
4557
|
+
action: "force",
|
|
4558
|
+
schema: table.schemaName === ctx.currentSchema ? void 0 : table.schemaName,
|
|
4559
|
+
table: table.name
|
|
4560
|
+
});
|
|
4501
4561
|
}
|
|
4502
4562
|
for (const it of data.extensions) ast.push({
|
|
4503
4563
|
type: "extension",
|