orchid-orm 1.64.7 → 1.64.9
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.js +1 -3
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +2 -4
- package/dist/index.mjs.map +1 -1
- package/dist/migrations/index.js +441 -25
- package/dist/migrations/index.js.map +1 -1
- package/dist/migrations/index.mjs +443 -27
- package/dist/migrations/index.mjs.map +1 -1
- package/dist/migrations/node-postgres.js +441 -25
- package/dist/migrations/node-postgres.js.map +1 -1
- package/dist/migrations/node-postgres.mjs +443 -27
- package/dist/migrations/node-postgres.mjs.map +1 -1
- package/dist/migrations/postgres-js.js +441 -25
- package/dist/migrations/postgres-js.js.map +1 -1
- package/dist/migrations/postgres-js.mjs +443 -27
- package/dist/migrations/postgres-js.mjs.map +1 -1
- package/package.json +5 -5
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { promptSelect, getSchemaAndTableFromName, getDbTableColumnsChecks, dbColumnToAst, instantiateDbColumn, concatSchemaAndName, encodeColumnDefault, getIndexName, getExcludeName, getConstraintName, tableToAst, getMigrationsSchemaAndTable, getDbStructureTableData, makeDomainsMap, astToMigration, createMigrationInterface, introspectDbSchema, makeStructureToAstCtx, makeFileVersion, writeMigrationFile, migrateAndClose, migrate, structureToAst, saveMigratedVersion, rakeDbCommands } from 'rake-db';
|
|
1
|
+
import { promptSelect, getSchemaAndTableFromName, getDbTableColumnsChecks, dbColumnToAst, instantiateDbColumn, concatSchemaAndName, encodeColumnDefault, getIndexName, getExcludeName, getConstraintName, tableToAst, getMigrationsSchemaAndTable, getDbStructureTableData, makeDomainsMap, astToMigration, createMigrationInterface, introspectDbSchema, makeStructureToAstCtx, makeFileVersion, writeMigrationFile, migrateAndClose, getDbVersion, migrate, structureToAst, saveMigratedVersion, rakeDbCommands } from 'rake-db';
|
|
2
2
|
export * from 'rake-db';
|
|
3
|
-
import { colors, EnumColumn, ArrayColumn, toSnakeCase, getColumnBaseType, deepCompare, RawSql, emptyArray, toArray, getFreeSetAlias, VirtualColumn, exhaustive, toCamelCase, addCode, pluralize, codeToString, emptyObject, getQuerySchema, DomainColumn, UnknownColumn, defaultSchemaConfig, toPascalCase, getImportPath, singleQuote, columnsShapeToCode, pushTableDataCode, quoteObjectKey, pathToLog } from 'pqb';
|
|
3
|
+
import { colors, EnumColumn, ArrayColumn, toSnakeCase, getColumnBaseType, deepCompare, RawSql, emptyArray, toArray, getFreeSetAlias, VirtualColumn, getSupportedDefaultPrivileges, exhaustive, toCamelCase, addCode, pluralize, codeToString, emptyObject, getQuerySchema, DomainColumn, UnknownColumn, defaultSchemaConfig, toPascalCase, getImportPath, singleQuote, columnsShapeToCode, pushTableDataCode, quoteObjectKey, pathToLog } from 'pqb';
|
|
4
4
|
import path from 'node:path';
|
|
5
5
|
import { pathToFileURL } from 'url';
|
|
6
6
|
import fs from 'fs/promises';
|
|
@@ -2164,34 +2164,43 @@ const processTableChange = async (adapter, structureToAstCtx, dbStructure, domai
|
|
|
2164
2164
|
}
|
|
2165
2165
|
};
|
|
2166
2166
|
|
|
2167
|
+
const defaults = {
|
|
2168
|
+
super: false,
|
|
2169
|
+
inherit: false,
|
|
2170
|
+
createRole: false,
|
|
2171
|
+
createDb: false,
|
|
2172
|
+
canLogin: false,
|
|
2173
|
+
replication: false,
|
|
2174
|
+
connLimit: -1,
|
|
2175
|
+
bypassRls: false
|
|
2176
|
+
};
|
|
2167
2177
|
const processRoles = async (ast, dbStructure, { verifying, internal: { roles } }) => {
|
|
2168
2178
|
if (!dbStructure.roles || !roles) return;
|
|
2169
|
-
const codeRoles = roles.map(
|
|
2170
|
-
|
|
2171
|
-
|
|
2172
|
-
|
|
2173
|
-
|
|
2174
|
-
|
|
2175
|
-
|
|
2176
|
-
replication: false,
|
|
2177
|
-
connLimit: -1,
|
|
2178
|
-
bypassRls: false,
|
|
2179
|
-
...role
|
|
2180
|
-
})
|
|
2181
|
-
);
|
|
2179
|
+
const codeRoles = roles.map((role) => {
|
|
2180
|
+
const { defaultPrivileges: _, ...roleWithoutPrivileges } = role;
|
|
2181
|
+
return {
|
|
2182
|
+
...defaults,
|
|
2183
|
+
...roleWithoutPrivileges
|
|
2184
|
+
};
|
|
2185
|
+
});
|
|
2182
2186
|
const found = /* @__PURE__ */ new Set();
|
|
2183
2187
|
const dropRoles = [];
|
|
2184
2188
|
for (const dbRole of dbStructure.roles) {
|
|
2189
|
+
const {
|
|
2190
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
2191
|
+
defaultPrivileges: _,
|
|
2192
|
+
...dbRoleWithoutPrivileges
|
|
2193
|
+
} = dbRole;
|
|
2185
2194
|
const codeRole = codeRoles.find(
|
|
2186
2195
|
(codeRole2) => dbRole.name === codeRole2.name
|
|
2187
2196
|
);
|
|
2188
2197
|
if (codeRole) {
|
|
2189
2198
|
found.add(dbRole.name);
|
|
2190
|
-
if (!deepCompare(
|
|
2199
|
+
if (!deepCompare(dbRoleWithoutPrivileges, codeRole)) {
|
|
2191
2200
|
ast.push({
|
|
2192
2201
|
type: "changeRole",
|
|
2193
2202
|
name: dbRole.name,
|
|
2194
|
-
from:
|
|
2203
|
+
from: dbRoleWithoutPrivileges,
|
|
2195
2204
|
to: codeRole
|
|
2196
2205
|
});
|
|
2197
2206
|
}
|
|
@@ -2248,6 +2257,349 @@ const makeRenameOrChangeAst = (dbRole, codeRole) => {
|
|
|
2248
2257
|
}
|
|
2249
2258
|
};
|
|
2250
2259
|
|
|
2260
|
+
const ALL_OBJECT_TYPES = [
|
|
2261
|
+
"TABLES",
|
|
2262
|
+
"SEQUENCES",
|
|
2263
|
+
"FUNCTIONS",
|
|
2264
|
+
"TYPES",
|
|
2265
|
+
"SCHEMAS",
|
|
2266
|
+
"LARGE_OBJECTS"
|
|
2267
|
+
];
|
|
2268
|
+
const createAllObjectConfigs = (isGrantable, schema, supportedPrivileges) => {
|
|
2269
|
+
let types;
|
|
2270
|
+
if (schema) {
|
|
2271
|
+
types = ALL_OBJECT_TYPES.filter(
|
|
2272
|
+
(t) => t !== "SCHEMAS" && t !== "LARGE_OBJECTS"
|
|
2273
|
+
);
|
|
2274
|
+
} else {
|
|
2275
|
+
types = ALL_OBJECT_TYPES.filter((t) => {
|
|
2276
|
+
if (t === "LARGE_OBJECTS") {
|
|
2277
|
+
return supportedPrivileges.PRIVILEGES.LARGE_OBJECT !== void 0;
|
|
2278
|
+
}
|
|
2279
|
+
return true;
|
|
2280
|
+
});
|
|
2281
|
+
}
|
|
2282
|
+
return types.map((object) => ({
|
|
2283
|
+
object,
|
|
2284
|
+
privilegeConfigs: [{ privilege: "ALL", isGrantable }]
|
|
2285
|
+
}));
|
|
2286
|
+
};
|
|
2287
|
+
const objectTypeToKey = {
|
|
2288
|
+
TABLES: "tables",
|
|
2289
|
+
SEQUENCES: "sequences",
|
|
2290
|
+
FUNCTIONS: "functions",
|
|
2291
|
+
TYPES: "types",
|
|
2292
|
+
SCHEMAS: "schemas",
|
|
2293
|
+
LARGE_OBJECTS: "largeObjects"
|
|
2294
|
+
};
|
|
2295
|
+
const splitPrivilegeConfigs = (configs) => {
|
|
2296
|
+
const regular = [];
|
|
2297
|
+
const grantable = [];
|
|
2298
|
+
for (const p of configs) {
|
|
2299
|
+
if (p.isGrantable) {
|
|
2300
|
+
grantable.push(p.privilege);
|
|
2301
|
+
} else {
|
|
2302
|
+
regular.push(p.privilege);
|
|
2303
|
+
}
|
|
2304
|
+
}
|
|
2305
|
+
return { regular, grantable };
|
|
2306
|
+
};
|
|
2307
|
+
const createPrivilegeSetting = (regular, grantable) => {
|
|
2308
|
+
const setting = {};
|
|
2309
|
+
if (regular.length) setting.privileges = regular;
|
|
2310
|
+
if (grantable.length) setting.grantablePrivileges = grantable;
|
|
2311
|
+
return setting;
|
|
2312
|
+
};
|
|
2313
|
+
const collapsePrivileges = (privs, newPrivilegeConfigs, expectedPrivs, isGrantable) => {
|
|
2314
|
+
const hasAll = privs.some((p) => p.privilege === "ALL");
|
|
2315
|
+
const allPresent = hasAll || privs.length > 0 && privs.length === expectedPrivs.length && expectedPrivs.every((priv) => privs.some((p) => p.privilege === priv));
|
|
2316
|
+
if (allPresent) {
|
|
2317
|
+
newPrivilegeConfigs.push({ privilege: "ALL", isGrantable });
|
|
2318
|
+
} else if (privs.length > 0) {
|
|
2319
|
+
newPrivilegeConfigs.push(...privs);
|
|
2320
|
+
}
|
|
2321
|
+
};
|
|
2322
|
+
const collapsePrivilegesToAll = (privilege, objectTypeToAllPrivileges) => {
|
|
2323
|
+
const collapsedObjectConfigs = privilege.objectConfigs.map(
|
|
2324
|
+
(objConfig) => {
|
|
2325
|
+
const allPrivileges = objectTypeToAllPrivileges[objConfig.object];
|
|
2326
|
+
const expectedPrivs = allPrivileges.filter((p) => p !== "ALL");
|
|
2327
|
+
const regularPrivs = [];
|
|
2328
|
+
const grantablePrivs = [];
|
|
2329
|
+
for (const p of objConfig.privilegeConfigs) {
|
|
2330
|
+
if (p.isGrantable) {
|
|
2331
|
+
grantablePrivs.push(p);
|
|
2332
|
+
} else {
|
|
2333
|
+
regularPrivs.push(p);
|
|
2334
|
+
}
|
|
2335
|
+
}
|
|
2336
|
+
const newPrivilegeConfigs = [];
|
|
2337
|
+
collapsePrivileges(
|
|
2338
|
+
regularPrivs,
|
|
2339
|
+
newPrivilegeConfigs,
|
|
2340
|
+
expectedPrivs,
|
|
2341
|
+
false
|
|
2342
|
+
);
|
|
2343
|
+
collapsePrivileges(
|
|
2344
|
+
grantablePrivs,
|
|
2345
|
+
newPrivilegeConfigs,
|
|
2346
|
+
expectedPrivs,
|
|
2347
|
+
true
|
|
2348
|
+
);
|
|
2349
|
+
return {
|
|
2350
|
+
object: objConfig.object,
|
|
2351
|
+
privilegeConfigs: newPrivilegeConfigs
|
|
2352
|
+
};
|
|
2353
|
+
}
|
|
2354
|
+
);
|
|
2355
|
+
return {
|
|
2356
|
+
owner: privilege.owner,
|
|
2357
|
+
grantee: privilege.grantee,
|
|
2358
|
+
schema: privilege.schema,
|
|
2359
|
+
objectConfigs: collapsedObjectConfigs
|
|
2360
|
+
};
|
|
2361
|
+
};
|
|
2362
|
+
const privilegeConfigsMatch = (a, b, objectType, objectTypeToAllPrivileges) => {
|
|
2363
|
+
if (a.privilege === b.privilege && a.isGrantable === b.isGrantable) {
|
|
2364
|
+
return true;
|
|
2365
|
+
}
|
|
2366
|
+
const allPrivileges = objectTypeToAllPrivileges[objectType];
|
|
2367
|
+
const expectedPrivs = allPrivileges.filter((p) => p !== "ALL");
|
|
2368
|
+
if (a.privilege === "ALL" && a.isGrantable === b.isGrantable) {
|
|
2369
|
+
return expectedPrivs.includes(b.privilege);
|
|
2370
|
+
}
|
|
2371
|
+
if (b.privilege === "ALL" && a.isGrantable === b.isGrantable) {
|
|
2372
|
+
return expectedPrivs.includes(a.privilege);
|
|
2373
|
+
}
|
|
2374
|
+
return false;
|
|
2375
|
+
};
|
|
2376
|
+
const normalizeRoleName = (name) => {
|
|
2377
|
+
if (name.startsWith('"') && name.endsWith('"')) {
|
|
2378
|
+
return name.slice(1, -1);
|
|
2379
|
+
}
|
|
2380
|
+
return name;
|
|
2381
|
+
};
|
|
2382
|
+
const processPrivilegeConfig = (config, objectType) => {
|
|
2383
|
+
if (!config) return;
|
|
2384
|
+
const privilegeConfigs = [];
|
|
2385
|
+
if (config.privileges) {
|
|
2386
|
+
for (const p of config.privileges) {
|
|
2387
|
+
privilegeConfigs.push({ privilege: p, isGrantable: false });
|
|
2388
|
+
}
|
|
2389
|
+
}
|
|
2390
|
+
if (config.grantablePrivileges) {
|
|
2391
|
+
for (const p of config.grantablePrivileges) {
|
|
2392
|
+
privilegeConfigs.push({ privilege: p, isGrantable: true });
|
|
2393
|
+
}
|
|
2394
|
+
}
|
|
2395
|
+
if (privilegeConfigs.length) {
|
|
2396
|
+
return { object: objectType, privilegeConfigs };
|
|
2397
|
+
}
|
|
2398
|
+
return;
|
|
2399
|
+
};
|
|
2400
|
+
const hasAnyPrivilege = (obj) => {
|
|
2401
|
+
if (!obj) return false;
|
|
2402
|
+
for (const key of ALL_OBJECT_TYPES) {
|
|
2403
|
+
const setting = obj[objectTypeToKey[key]];
|
|
2404
|
+
if (setting?.privileges?.length || setting?.grantablePrivileges?.length) {
|
|
2405
|
+
return true;
|
|
2406
|
+
}
|
|
2407
|
+
}
|
|
2408
|
+
return false;
|
|
2409
|
+
};
|
|
2410
|
+
const processDefaultPrivileges = (ast, dbStructure, { internal: { roles } }) => {
|
|
2411
|
+
if (!dbStructure.defaultPrivileges || !roles) return;
|
|
2412
|
+
const supportedPrivileges = getSupportedDefaultPrivileges(
|
|
2413
|
+
dbStructure.version
|
|
2414
|
+
);
|
|
2415
|
+
const objectTypeToAllPrivileges = {};
|
|
2416
|
+
objectTypeToAllPrivileges.TABLES = supportedPrivileges.PRIVILEGES.TABLE;
|
|
2417
|
+
objectTypeToAllPrivileges.SEQUENCES = supportedPrivileges.PRIVILEGES.SEQUENCE;
|
|
2418
|
+
objectTypeToAllPrivileges.FUNCTIONS = supportedPrivileges.PRIVILEGES.FUNCTION;
|
|
2419
|
+
objectTypeToAllPrivileges.TYPES = supportedPrivileges.PRIVILEGES.TYPE;
|
|
2420
|
+
objectTypeToAllPrivileges.SCHEMAS = supportedPrivileges.PRIVILEGES.SCHEMA;
|
|
2421
|
+
if (supportedPrivileges.PRIVILEGES.LARGE_OBJECT) {
|
|
2422
|
+
objectTypeToAllPrivileges.LARGE_OBJECTS = supportedPrivileges.PRIVILEGES.LARGE_OBJECT;
|
|
2423
|
+
}
|
|
2424
|
+
const codePrivileges = /* @__PURE__ */ new Map();
|
|
2425
|
+
for (const role of roles) {
|
|
2426
|
+
if (!role.defaultPrivileges) continue;
|
|
2427
|
+
for (const privilege of role.defaultPrivileges) {
|
|
2428
|
+
const key = `${role.name}.${privilege.schema}`;
|
|
2429
|
+
const objectConfigs = [];
|
|
2430
|
+
if (privilege.allGrantable) {
|
|
2431
|
+
objectConfigs.push(
|
|
2432
|
+
...createAllObjectConfigs(
|
|
2433
|
+
true,
|
|
2434
|
+
privilege.schema,
|
|
2435
|
+
supportedPrivileges
|
|
2436
|
+
)
|
|
2437
|
+
);
|
|
2438
|
+
} else if (privilege.all) {
|
|
2439
|
+
objectConfigs.push(
|
|
2440
|
+
...createAllObjectConfigs(
|
|
2441
|
+
false,
|
|
2442
|
+
privilege.schema,
|
|
2443
|
+
supportedPrivileges
|
|
2444
|
+
)
|
|
2445
|
+
);
|
|
2446
|
+
}
|
|
2447
|
+
for (const objectType of ALL_OBJECT_TYPES) {
|
|
2448
|
+
if (privilege.schema && (objectType === "SCHEMAS" || objectType === "LARGE_OBJECTS")) {
|
|
2449
|
+
continue;
|
|
2450
|
+
}
|
|
2451
|
+
if (objectType === "LARGE_OBJECTS" && !supportedPrivileges.PRIVILEGES.LARGE_OBJECT) {
|
|
2452
|
+
continue;
|
|
2453
|
+
}
|
|
2454
|
+
const key2 = objectTypeToKey[objectType];
|
|
2455
|
+
if (key2 in privilege) {
|
|
2456
|
+
const config = privilege[key2];
|
|
2457
|
+
const processed = processPrivilegeConfig(config, objectType);
|
|
2458
|
+
if (processed) {
|
|
2459
|
+
const existingIndex = objectConfigs.findIndex(
|
|
2460
|
+
(o) => o.object === objectType
|
|
2461
|
+
);
|
|
2462
|
+
if (existingIndex >= 0) {
|
|
2463
|
+
objectConfigs[existingIndex] = processed;
|
|
2464
|
+
} else {
|
|
2465
|
+
objectConfigs.push(processed);
|
|
2466
|
+
}
|
|
2467
|
+
}
|
|
2468
|
+
}
|
|
2469
|
+
}
|
|
2470
|
+
if (objectConfigs.length) {
|
|
2471
|
+
codePrivileges.set(key, {
|
|
2472
|
+
owner: void 0,
|
|
2473
|
+
grantee: role.name,
|
|
2474
|
+
schema: privilege.schema,
|
|
2475
|
+
objectConfigs
|
|
2476
|
+
});
|
|
2477
|
+
}
|
|
2478
|
+
}
|
|
2479
|
+
}
|
|
2480
|
+
const found = /* @__PURE__ */ new Set();
|
|
2481
|
+
for (const dbPrivilege of dbStructure.defaultPrivileges) {
|
|
2482
|
+
const grantee = normalizeRoleName(dbPrivilege.grantee);
|
|
2483
|
+
if (grantee === "postgres") continue;
|
|
2484
|
+
const key = `${grantee}.${dbPrivilege.schema}`;
|
|
2485
|
+
const codePrivilege = codePrivileges.get(key);
|
|
2486
|
+
if (codePrivilege) {
|
|
2487
|
+
found.add(key);
|
|
2488
|
+
const grant = {};
|
|
2489
|
+
const revoke = {};
|
|
2490
|
+
for (const objectType of ALL_OBJECT_TYPES) {
|
|
2491
|
+
if (objectType === "LARGE_OBJECTS" && !supportedPrivileges.PRIVILEGES.LARGE_OBJECT) {
|
|
2492
|
+
continue;
|
|
2493
|
+
}
|
|
2494
|
+
const dbObj = dbPrivilege.objectConfigs.find(
|
|
2495
|
+
(o) => o.object === objectType
|
|
2496
|
+
);
|
|
2497
|
+
const codeObj = codePrivilege.objectConfigs.find(
|
|
2498
|
+
(o) => o.object === objectType
|
|
2499
|
+
);
|
|
2500
|
+
const dbPrivs = dbObj?.privilegeConfigs ?? [];
|
|
2501
|
+
const codePrivs = codeObj?.privilegeConfigs ?? [];
|
|
2502
|
+
const collapsedDbPrivilege = {
|
|
2503
|
+
owner: dbPrivilege.owner,
|
|
2504
|
+
grantee: dbPrivilege.grantee,
|
|
2505
|
+
schema: dbPrivilege.schema,
|
|
2506
|
+
objectConfigs: [{ object: objectType, privilegeConfigs: dbPrivs }]
|
|
2507
|
+
};
|
|
2508
|
+
const collapsedDbObj = collapsePrivilegesToAll(
|
|
2509
|
+
collapsedDbPrivilege,
|
|
2510
|
+
objectTypeToAllPrivileges
|
|
2511
|
+
).objectConfigs[0];
|
|
2512
|
+
const collapsedDbPrivs = collapsedDbObj?.privilegeConfigs ?? [];
|
|
2513
|
+
const toGrant = codePrivs.filter(
|
|
2514
|
+
(cp) => !collapsedDbPrivs.some(
|
|
2515
|
+
(dp) => privilegeConfigsMatch(
|
|
2516
|
+
cp,
|
|
2517
|
+
dp,
|
|
2518
|
+
objectType,
|
|
2519
|
+
objectTypeToAllPrivileges
|
|
2520
|
+
)
|
|
2521
|
+
)
|
|
2522
|
+
);
|
|
2523
|
+
const toRevoke = dbPrivs.filter(
|
|
2524
|
+
(dp) => !codePrivs.some(
|
|
2525
|
+
(cp) => privilegeConfigsMatch(
|
|
2526
|
+
cp,
|
|
2527
|
+
dp,
|
|
2528
|
+
objectType,
|
|
2529
|
+
objectTypeToAllPrivileges
|
|
2530
|
+
)
|
|
2531
|
+
)
|
|
2532
|
+
);
|
|
2533
|
+
if (toGrant.length) {
|
|
2534
|
+
const { regular, grantable } = splitPrivilegeConfigs(toGrant);
|
|
2535
|
+
const setting = createPrivilegeSetting(regular, grantable);
|
|
2536
|
+
if (setting.privileges || setting.grantablePrivileges) {
|
|
2537
|
+
grant[objectTypeToKey[objectType]] = setting;
|
|
2538
|
+
}
|
|
2539
|
+
}
|
|
2540
|
+
if (toRevoke.length) {
|
|
2541
|
+
const { regular, grantable } = splitPrivilegeConfigs(toRevoke);
|
|
2542
|
+
const setting = createPrivilegeSetting(regular, grantable);
|
|
2543
|
+
if (setting.privileges || setting.grantablePrivileges) {
|
|
2544
|
+
revoke[objectTypeToKey[objectType]] = setting;
|
|
2545
|
+
}
|
|
2546
|
+
}
|
|
2547
|
+
}
|
|
2548
|
+
const hasGrant = hasAnyPrivilege(grant);
|
|
2549
|
+
const hasRevoke = hasAnyPrivilege(revoke);
|
|
2550
|
+
if (hasGrant || hasRevoke) {
|
|
2551
|
+
ast.push({
|
|
2552
|
+
type: "defaultPrivilege",
|
|
2553
|
+
grantee,
|
|
2554
|
+
schema: dbPrivilege.schema,
|
|
2555
|
+
grant: hasGrant ? grant : void 0,
|
|
2556
|
+
revoke: hasRevoke ? revoke : void 0
|
|
2557
|
+
});
|
|
2558
|
+
}
|
|
2559
|
+
} else {
|
|
2560
|
+
const revoke = {};
|
|
2561
|
+
for (const obj of dbPrivilege.objectConfigs) {
|
|
2562
|
+
const { regular, grantable } = splitPrivilegeConfigs(
|
|
2563
|
+
obj.privilegeConfigs
|
|
2564
|
+
);
|
|
2565
|
+
const setting = createPrivilegeSetting(regular, grantable);
|
|
2566
|
+
if (setting.privileges || setting.grantablePrivileges) {
|
|
2567
|
+
revoke[objectTypeToKey[obj.object]] = setting;
|
|
2568
|
+
}
|
|
2569
|
+
}
|
|
2570
|
+
if (hasAnyPrivilege(revoke)) {
|
|
2571
|
+
ast.push({
|
|
2572
|
+
type: "defaultPrivilege",
|
|
2573
|
+
grantee,
|
|
2574
|
+
schema: dbPrivilege.schema,
|
|
2575
|
+
revoke
|
|
2576
|
+
});
|
|
2577
|
+
}
|
|
2578
|
+
}
|
|
2579
|
+
}
|
|
2580
|
+
for (const [key, codePrivilege] of codePrivileges) {
|
|
2581
|
+
if (found.has(key)) continue;
|
|
2582
|
+
const grant = {};
|
|
2583
|
+
for (const obj of codePrivilege.objectConfigs) {
|
|
2584
|
+
const { regular, grantable } = splitPrivilegeConfigs(
|
|
2585
|
+
obj.privilegeConfigs
|
|
2586
|
+
);
|
|
2587
|
+
const setting = createPrivilegeSetting(regular, grantable);
|
|
2588
|
+
if (setting.privileges || setting.grantablePrivileges) {
|
|
2589
|
+
grant[objectTypeToKey[obj.object]] = setting;
|
|
2590
|
+
}
|
|
2591
|
+
}
|
|
2592
|
+
if (hasAnyPrivilege(grant)) {
|
|
2593
|
+
ast.push({
|
|
2594
|
+
type: "defaultPrivilege",
|
|
2595
|
+
grantee: codePrivilege.grantee,
|
|
2596
|
+
schema: codePrivilege.schema,
|
|
2597
|
+
grant
|
|
2598
|
+
});
|
|
2599
|
+
}
|
|
2600
|
+
}
|
|
2601
|
+
};
|
|
2602
|
+
|
|
2251
2603
|
class PendingDbTypes {
|
|
2252
2604
|
constructor() {
|
|
2253
2605
|
this.set = /* @__PURE__ */ new Set();
|
|
@@ -2259,6 +2611,7 @@ class PendingDbTypes {
|
|
|
2259
2611
|
const composeMigration = async (adapter, config, ast, dbStructure, params) => {
|
|
2260
2612
|
const { structureToAstCtx, currentSchema } = params;
|
|
2261
2613
|
await processRoles(ast, dbStructure, params);
|
|
2614
|
+
processDefaultPrivileges(ast, dbStructure, params);
|
|
2262
2615
|
const domainsMap = makeDomainsMap(structureToAstCtx, dbStructure);
|
|
2263
2616
|
await processSchemas(ast, dbStructure, params);
|
|
2264
2617
|
processExtensions(ast, dbStructure, params);
|
|
@@ -2285,7 +2638,7 @@ const composeMigration = async (adapter, config, ast, dbStructure, params) => {
|
|
|
2285
2638
|
};
|
|
2286
2639
|
|
|
2287
2640
|
const rollbackErr = new Error("Rollback");
|
|
2288
|
-
const verifyMigration = async (adapter, config, migrationCode, generateMigrationParams, roles) => {
|
|
2641
|
+
const verifyMigration = async (adapter, config, migrationCode, generateMigrationParams, roles, defaultPrivileges) => {
|
|
2289
2642
|
const migrationFn = new Function("change", migrationCode);
|
|
2290
2643
|
let code;
|
|
2291
2644
|
try {
|
|
@@ -2302,7 +2655,8 @@ const verifyMigration = async (adapter, config, migrationCode, generateMigration
|
|
|
2302
2655
|
await changeFn(db, true);
|
|
2303
2656
|
}
|
|
2304
2657
|
const dbStructure = await introspectDbSchema(trx, {
|
|
2305
|
-
roles
|
|
2658
|
+
roles,
|
|
2659
|
+
loadDefaultPrivileges: defaultPrivileges?.loadDefaultPrivileges
|
|
2306
2660
|
});
|
|
2307
2661
|
generateMigrationParams.verifying = true;
|
|
2308
2662
|
try {
|
|
@@ -2631,12 +2985,59 @@ const report = (ast, config, currentSchema) => {
|
|
|
2631
2985
|
);
|
|
2632
2986
|
break;
|
|
2633
2987
|
case "renameRole":
|
|
2634
|
-
code.push(
|
|
2635
|
-
`${yellow("~ rename role")} ${a.from} ${yellow("=>")} ${a.to}`
|
|
2636
|
-
);
|
|
2637
|
-
break;
|
|
2638
2988
|
case "changeRole": {
|
|
2639
|
-
|
|
2989
|
+
if (a.type === "renameRole") {
|
|
2990
|
+
code.push(
|
|
2991
|
+
`${yellow("~ rename role")} ${a.from} ${yellow("=>")} ${a.to}`
|
|
2992
|
+
);
|
|
2993
|
+
} else {
|
|
2994
|
+
code.push(`${yellow("~ change role")} ${a.name}`);
|
|
2995
|
+
}
|
|
2996
|
+
break;
|
|
2997
|
+
}
|
|
2998
|
+
case "defaultPrivilege": {
|
|
2999
|
+
const mapPrivilege = (p) => p === "ALL" ? "ALL PRIVILEGES" : p;
|
|
3000
|
+
const schema = a.schema ? ` in schema ${colors.pale(a.schema)}` : ` ${colors.pale("in all schemas")}`;
|
|
3001
|
+
const parts = [];
|
|
3002
|
+
if (a.grant) {
|
|
3003
|
+
for (const [objType, config2] of Object.entries(a.grant)) {
|
|
3004
|
+
if (!config2) continue;
|
|
3005
|
+
const type = objType.replace(/([A-Z])/g, " $1").toLowerCase();
|
|
3006
|
+
if (config2.privileges?.length) {
|
|
3007
|
+
parts.push(
|
|
3008
|
+
`${green("+ grant default privileges")} ${config2.privileges.map(mapPrivilege).join(", ")} on ${type} to ${a.grantee}${schema}`
|
|
3009
|
+
);
|
|
3010
|
+
}
|
|
3011
|
+
if (config2.grantablePrivileges?.length) {
|
|
3012
|
+
parts.push(
|
|
3013
|
+
`${green(
|
|
3014
|
+
"+ grant default privileges"
|
|
3015
|
+
)} ${config2.grantablePrivileges.map(mapPrivilege).join(", ")} on ${type} with grant option to ${a.grantee}${schema}`
|
|
3016
|
+
);
|
|
3017
|
+
}
|
|
3018
|
+
}
|
|
3019
|
+
}
|
|
3020
|
+
if (a.revoke) {
|
|
3021
|
+
for (const [objType, config2] of Object.entries(a.revoke)) {
|
|
3022
|
+
if (!config2) continue;
|
|
3023
|
+
const type = objType.replace(/([A-Z])/g, " $1").toLowerCase();
|
|
3024
|
+
if (config2.privileges?.length) {
|
|
3025
|
+
parts.push(
|
|
3026
|
+
`${red("- revoke default privileges")} ${config2.privileges.map(mapPrivilege).join(", ")} on ${type} from ${a.grantee}${schema}`
|
|
3027
|
+
);
|
|
3028
|
+
}
|
|
3029
|
+
if (config2.grantablePrivileges?.length) {
|
|
3030
|
+
parts.push(
|
|
3031
|
+
`${red(
|
|
3032
|
+
"- revoke default privileges"
|
|
3033
|
+
)} ${config2.grantablePrivileges.map(mapPrivilege).join(", ")} on ${type} with grant option from ${a.grantee}${schema}`
|
|
3034
|
+
);
|
|
3035
|
+
}
|
|
3036
|
+
}
|
|
3037
|
+
}
|
|
3038
|
+
if (parts.length) {
|
|
3039
|
+
code.push(parts.join("\n"));
|
|
3040
|
+
}
|
|
2640
3041
|
break;
|
|
2641
3042
|
}
|
|
2642
3043
|
default:
|
|
@@ -2675,6 +3076,7 @@ const generate = async (adapters, config, args, afterPull) => {
|
|
|
2675
3076
|
adapters,
|
|
2676
3077
|
config,
|
|
2677
3078
|
rolesDbStructureParam,
|
|
3079
|
+
internal.roles ? { loadDefaultPrivileges: true } : void 0,
|
|
2678
3080
|
afterPull
|
|
2679
3081
|
);
|
|
2680
3082
|
const [adapter] = adapters;
|
|
@@ -2716,7 +3118,8 @@ const generate = async (adapters, config, args, afterPull) => {
|
|
|
2716
3118
|
config,
|
|
2717
3119
|
migrationCode,
|
|
2718
3120
|
generateMigrationParams,
|
|
2719
|
-
rolesDbStructureParam
|
|
3121
|
+
rolesDbStructureParam,
|
|
3122
|
+
internal.roles ? { loadDefaultPrivileges: true } : void 0
|
|
2720
3123
|
);
|
|
2721
3124
|
if (result !== void 0) {
|
|
2722
3125
|
throw new Error(
|
|
@@ -2774,10 +3177,12 @@ const getDbFromConfig = async (config, dbPath) => {
|
|
|
2774
3177
|
}
|
|
2775
3178
|
return db;
|
|
2776
3179
|
};
|
|
2777
|
-
const migrateAndPullStructures = async (adapters, config, roles, afterPull) => {
|
|
3180
|
+
const migrateAndPullStructures = async (adapters, config, roles, defaultPrivileges, afterPull) => {
|
|
2778
3181
|
if (afterPull) {
|
|
3182
|
+
const version = await getDbVersion(adapters[0]);
|
|
2779
3183
|
return {
|
|
2780
3184
|
dbStructure: {
|
|
3185
|
+
version,
|
|
2781
3186
|
schemas: [],
|
|
2782
3187
|
tables: [],
|
|
2783
3188
|
views: [],
|
|
@@ -2798,7 +3203,8 @@ const migrateAndPullStructures = async (adapters, config, roles, afterPull) => {
|
|
|
2798
3203
|
const dbStructures = await Promise.all(
|
|
2799
3204
|
adapters.map(
|
|
2800
3205
|
(adapter) => introspectDbSchema(adapter, {
|
|
2801
|
-
roles
|
|
3206
|
+
roles,
|
|
3207
|
+
loadDefaultPrivileges: defaultPrivileges?.loadDefaultPrivileges
|
|
2802
3208
|
})
|
|
2803
3209
|
)
|
|
2804
3210
|
);
|
|
@@ -2851,6 +3257,7 @@ const getActualItems = async (db, currentSchema, internal, columnTypes) => {
|
|
|
2851
3257
|
tables: [],
|
|
2852
3258
|
domains: []
|
|
2853
3259
|
};
|
|
3260
|
+
codeItems.schemas.add(currentSchema);
|
|
2854
3261
|
const domains = /* @__PURE__ */ new Map();
|
|
2855
3262
|
for (const key in db) {
|
|
2856
3263
|
if (key[0] === "$") continue;
|
|
@@ -2925,6 +3332,15 @@ const getActualItems = async (db, currentSchema, internal, columnTypes) => {
|
|
|
2925
3332
|
codeItems.schemas.add(domain.schemaName);
|
|
2926
3333
|
codeItems.domains.push(domain);
|
|
2927
3334
|
}
|
|
3335
|
+
if (internal.roles) {
|
|
3336
|
+
for (const role of internal.roles) {
|
|
3337
|
+
if (role.defaultPrivileges) {
|
|
3338
|
+
for (const privilege of role.defaultPrivileges) {
|
|
3339
|
+
if (privilege.schema) codeItems.schemas.add(privilege.schema);
|
|
3340
|
+
}
|
|
3341
|
+
}
|
|
3342
|
+
}
|
|
3343
|
+
}
|
|
2928
3344
|
return codeItems;
|
|
2929
3345
|
};
|
|
2930
3346
|
const processEnumColumn = (column, currentSchema, codeItems) => {
|