@constructive-io/seeder 0.5.0 → 0.5.2
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/bin.js +669 -2
- package/dist/bin.js.map +1 -1
- package/dist/index.cjs +700 -33
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +669 -2
- package/dist/index.js.map +1 -1
- package/package.json +5 -4
package/dist/index.cjs
CHANGED
|
@@ -7,7 +7,14 @@ var graphqlRequest = require('graphql-request');
|
|
|
7
7
|
var crypto = require('crypto');
|
|
8
8
|
var index_js = require('inquirerer/cli/index.js');
|
|
9
9
|
var faker = require('@faker-js/faker');
|
|
10
|
-
|
|
10
|
+
require('@constructive-io/graphql-query/client/index.js');
|
|
11
|
+
var index_js$1 = require('@constructive-io/graphql-query/generators/index.js');
|
|
12
|
+
require('@constructive-io/graphql-query/query-builder.js');
|
|
13
|
+
require('@constructive-io/graphql-query/types/core.js');
|
|
14
|
+
require('@constructive-io/graphql-query/ast.js');
|
|
15
|
+
require('@constructive-io/graphql-query/custom-ast.js');
|
|
16
|
+
require('@constructive-io/graphql-query/meta-object/convert.js');
|
|
17
|
+
require('@constructive-io/graphql-query/meta-object/validate.js');
|
|
11
18
|
var promises = require('fs/promises');
|
|
12
19
|
var path = require('path');
|
|
13
20
|
var url = require('url');
|
|
@@ -18023,7 +18030,7 @@ function getBlueprintNames() {
|
|
|
18023
18030
|
|
|
18024
18031
|
// package.json
|
|
18025
18032
|
var package_default = {
|
|
18026
|
-
version: "0.5.
|
|
18033
|
+
version: "0.5.2"};
|
|
18027
18034
|
|
|
18028
18035
|
// src/templates/blog/generators.ts
|
|
18029
18036
|
var POST_STATUSES = ["draft", "published", "archived"];
|
|
@@ -20305,20 +20312,680 @@ async function provisionDatabase(db, options) {
|
|
|
20305
20312
|
function buildProvisionedEndpoint(domain, subdomain, apiPrefix = "public", port = 3e3) {
|
|
20306
20313
|
return `http://${apiPrefix}-${subdomain}.${domain}:${port}/graphql`;
|
|
20307
20314
|
}
|
|
20315
|
+
function pgFieldToCamelCase(str) {
|
|
20316
|
+
return str.replace(/_([a-z0-9])/g, (_, c) => c.toUpperCase());
|
|
20317
|
+
}
|
|
20318
|
+
function convertInflection(inflection) {
|
|
20319
|
+
if (!inflection) return void 0;
|
|
20320
|
+
return {
|
|
20321
|
+
allRows: inflection.allRows ?? "",
|
|
20322
|
+
allRowsSimple: inflection.allRowsSimple ?? "",
|
|
20323
|
+
conditionType: inflection.conditionType ?? "",
|
|
20324
|
+
connection: inflection.connection ?? "",
|
|
20325
|
+
createField: inflection.createField ?? "",
|
|
20326
|
+
createInputType: inflection.createInputType ?? "",
|
|
20327
|
+
createPayloadType: inflection.createPayloadType ?? "",
|
|
20328
|
+
deleteByPrimaryKey: inflection.deleteByPrimaryKey ?? null,
|
|
20329
|
+
deletePayloadType: inflection.deletePayloadType ?? "",
|
|
20330
|
+
edge: inflection.edge ?? "",
|
|
20331
|
+
edgeField: inflection.edgeField ?? "",
|
|
20332
|
+
enumType: inflection.enumType ?? "",
|
|
20333
|
+
filterType: inflection.filterType ?? null,
|
|
20334
|
+
inputType: inflection.inputType ?? "",
|
|
20335
|
+
orderByType: inflection.orderByType ?? "",
|
|
20336
|
+
patchField: inflection.patchField ?? "",
|
|
20337
|
+
patchType: inflection.patchType ?? null,
|
|
20338
|
+
tableFieldName: inflection.tableFieldName ?? "",
|
|
20339
|
+
tableType: inflection.tableType ?? "",
|
|
20340
|
+
typeName: inflection.typeName ?? "",
|
|
20341
|
+
updateByPrimaryKey: inflection.updateByPrimaryKey ?? null,
|
|
20342
|
+
updatePayloadType: inflection.updatePayloadType ?? null
|
|
20343
|
+
};
|
|
20344
|
+
}
|
|
20345
|
+
function convertQueryNames(query) {
|
|
20346
|
+
if (!query) return void 0;
|
|
20347
|
+
return {
|
|
20348
|
+
all: query.all,
|
|
20349
|
+
one: query.one ?? null,
|
|
20350
|
+
create: query.create ?? "",
|
|
20351
|
+
update: query.update ?? null,
|
|
20352
|
+
delete: query.delete ?? null
|
|
20353
|
+
};
|
|
20354
|
+
}
|
|
20355
|
+
function cleanTable(metaTable) {
|
|
20356
|
+
const relations = metaTable.relations;
|
|
20357
|
+
return {
|
|
20358
|
+
name: metaTable.name,
|
|
20359
|
+
inflection: convertInflection(metaTable.inflection),
|
|
20360
|
+
query: convertQueryNames(metaTable.query),
|
|
20361
|
+
fields: (metaTable.fields || []).filter((f) => f != null).map((field2) => ({
|
|
20362
|
+
name: pgFieldToCamelCase(field2.name),
|
|
20363
|
+
type: {
|
|
20364
|
+
gqlType: field2.type.gqlType,
|
|
20365
|
+
isArray: field2.type.isArray,
|
|
20366
|
+
modifier: field2.type.modifier,
|
|
20367
|
+
pgAlias: field2.type.pgAlias,
|
|
20368
|
+
pgType: field2.type.pgType,
|
|
20369
|
+
subtype: field2.type.subtype,
|
|
20370
|
+
typmod: field2.type.typmod
|
|
20371
|
+
},
|
|
20372
|
+
isNotNull: field2.isNotNull ?? field2.type.isNotNull ?? null,
|
|
20373
|
+
hasDefault: field2.hasDefault ?? field2.type.hasDefault ?? null
|
|
20374
|
+
})),
|
|
20375
|
+
relations: {
|
|
20376
|
+
belongsTo: (relations?.belongsTo || []).filter((r) => r != null).map((relation) => ({
|
|
20377
|
+
fieldName: relation.fieldName ?? null,
|
|
20378
|
+
isUnique: relation.isUnique,
|
|
20379
|
+
referencesTable: relation.references?.name || "",
|
|
20380
|
+
type: relation.type ?? null,
|
|
20381
|
+
keys: (relation.keys || []).filter((k) => k != null).map((key) => ({
|
|
20382
|
+
name: pgFieldToCamelCase(key.name),
|
|
20383
|
+
type: {
|
|
20384
|
+
gqlType: key.type?.gqlType || "",
|
|
20385
|
+
isArray: key.type?.isArray || false,
|
|
20386
|
+
modifier: key.type?.modifier,
|
|
20387
|
+
pgAlias: key.type?.pgAlias,
|
|
20388
|
+
pgType: key.type?.pgType,
|
|
20389
|
+
subtype: key.type?.subtype,
|
|
20390
|
+
typmod: key.type?.typmod
|
|
20391
|
+
}
|
|
20392
|
+
}))
|
|
20393
|
+
})),
|
|
20394
|
+
hasOne: (relations?.hasOne || []).filter((r) => r != null).map((relation) => ({
|
|
20395
|
+
fieldName: relation.fieldName ?? null,
|
|
20396
|
+
isUnique: relation.isUnique,
|
|
20397
|
+
referencedByTable: relation.referencedBy?.name || "",
|
|
20398
|
+
type: relation.type ?? null,
|
|
20399
|
+
keys: (relation.keys || []).filter((k) => k != null).map((key) => ({
|
|
20400
|
+
name: pgFieldToCamelCase(key.name),
|
|
20401
|
+
type: {
|
|
20402
|
+
gqlType: key.type?.gqlType || "",
|
|
20403
|
+
isArray: key.type?.isArray || false,
|
|
20404
|
+
modifier: key.type?.modifier,
|
|
20405
|
+
pgAlias: key.type?.pgAlias,
|
|
20406
|
+
pgType: key.type?.pgType,
|
|
20407
|
+
subtype: key.type?.subtype,
|
|
20408
|
+
typmod: key.type?.typmod
|
|
20409
|
+
}
|
|
20410
|
+
}))
|
|
20411
|
+
})),
|
|
20412
|
+
hasMany: (relations?.hasMany || []).filter((r) => r != null).map((relation) => ({
|
|
20413
|
+
fieldName: relation.fieldName ?? null,
|
|
20414
|
+
isUnique: relation.isUnique,
|
|
20415
|
+
referencedByTable: relation.referencedBy?.name || "",
|
|
20416
|
+
type: relation.type ?? null,
|
|
20417
|
+
keys: (relation.keys || []).filter((k) => k != null).map((key) => ({
|
|
20418
|
+
name: pgFieldToCamelCase(key.name),
|
|
20419
|
+
type: {
|
|
20420
|
+
gqlType: key.type?.gqlType || "",
|
|
20421
|
+
isArray: key.type?.isArray || false,
|
|
20422
|
+
modifier: key.type?.modifier,
|
|
20423
|
+
pgAlias: key.type?.pgAlias,
|
|
20424
|
+
pgType: key.type?.pgType,
|
|
20425
|
+
subtype: key.type?.subtype,
|
|
20426
|
+
typmod: key.type?.typmod
|
|
20427
|
+
}
|
|
20428
|
+
}))
|
|
20429
|
+
})),
|
|
20430
|
+
manyToMany: (relations?.manyToMany || []).filter((r) => r != null).map((relation) => ({
|
|
20431
|
+
fieldName: relation.fieldName ?? null,
|
|
20432
|
+
rightTable: relation.rightTable?.name || "",
|
|
20433
|
+
junctionTable: relation.junctionTable?.name || "",
|
|
20434
|
+
type: relation.type ?? null
|
|
20435
|
+
}))
|
|
20436
|
+
}
|
|
20437
|
+
};
|
|
20438
|
+
}
|
|
20439
|
+
function isPlainObject(value) {
|
|
20440
|
+
return typeof value === "object" && value !== null && !Array.isArray(value) && Object.prototype.toString.call(value) === "[object Object]";
|
|
20441
|
+
}
|
|
20442
|
+
function hasNestedDirtyFields(dirtyFields, prefix) {
|
|
20443
|
+
for (const field2 of dirtyFields) {
|
|
20444
|
+
if (field2 === prefix || field2.startsWith(`${prefix}.`)) {
|
|
20445
|
+
return true;
|
|
20446
|
+
}
|
|
20447
|
+
}
|
|
20448
|
+
return false;
|
|
20449
|
+
}
|
|
20450
|
+
function isFieldOrAncestorDirty(dirtyFields, path2) {
|
|
20451
|
+
if (dirtyFields.has(path2)) return true;
|
|
20452
|
+
const parts = path2.split(".");
|
|
20453
|
+
for (let i = 1; i < parts.length; i++) {
|
|
20454
|
+
const ancestorPath = parts.slice(0, i).join(".");
|
|
20455
|
+
if (dirtyFields.has(ancestorPath)) return true;
|
|
20456
|
+
}
|
|
20457
|
+
return false;
|
|
20458
|
+
}
|
|
20459
|
+
function getNestedValue(obj, path2) {
|
|
20460
|
+
const parts = path2.split(".");
|
|
20461
|
+
let current = obj;
|
|
20462
|
+
for (const part of parts) {
|
|
20463
|
+
if (current === null || current === void 0) return void 0;
|
|
20464
|
+
if (typeof current !== "object") return void 0;
|
|
20465
|
+
current = current[part];
|
|
20466
|
+
}
|
|
20467
|
+
return current;
|
|
20468
|
+
}
|
|
20469
|
+
function prepareMutationInput(input, options) {
|
|
20470
|
+
const { operation, dirtyFields, defaultValues, alwaysInclude = [], exclude = [], _pathPrefix = "" } = options;
|
|
20471
|
+
const result = {};
|
|
20472
|
+
const alwaysIncludeSet = new Set(alwaysInclude);
|
|
20473
|
+
const excludeSet = new Set(exclude);
|
|
20474
|
+
for (const [key, value] of Object.entries(input)) {
|
|
20475
|
+
const fullPath = _pathPrefix ? `${_pathPrefix}.${key}` : key;
|
|
20476
|
+
const isDirty = dirtyFields ? isFieldOrAncestorDirty(dirtyFields, fullPath) : true;
|
|
20477
|
+
const hasDirtyTracking = !!dirtyFields;
|
|
20478
|
+
if (excludeSet.has(key) || excludeSet.has(fullPath)) continue;
|
|
20479
|
+
if (alwaysIncludeSet.has(key) || alwaysIncludeSet.has(fullPath)) {
|
|
20480
|
+
result[key] = value;
|
|
20481
|
+
continue;
|
|
20482
|
+
}
|
|
20483
|
+
if (value === void 0) continue;
|
|
20484
|
+
if (value === null) {
|
|
20485
|
+
if (operation === "create") {
|
|
20486
|
+
if (hasDirtyTracking && isDirty) {
|
|
20487
|
+
result[key] = null;
|
|
20488
|
+
}
|
|
20489
|
+
} else {
|
|
20490
|
+
if (isDirty) {
|
|
20491
|
+
result[key] = null;
|
|
20492
|
+
}
|
|
20493
|
+
}
|
|
20494
|
+
continue;
|
|
20495
|
+
}
|
|
20496
|
+
if (value === "") {
|
|
20497
|
+
if (operation === "create") {
|
|
20498
|
+
if (hasDirtyTracking && isDirty) {
|
|
20499
|
+
result[key] = "";
|
|
20500
|
+
}
|
|
20501
|
+
} else {
|
|
20502
|
+
if (isDirty) {
|
|
20503
|
+
result[key] = "";
|
|
20504
|
+
}
|
|
20505
|
+
}
|
|
20506
|
+
continue;
|
|
20507
|
+
}
|
|
20508
|
+
if (Array.isArray(value)) {
|
|
20509
|
+
if (hasDirtyTracking && !isDirty && !hasNestedDirtyFields(dirtyFields, fullPath)) {
|
|
20510
|
+
continue;
|
|
20511
|
+
}
|
|
20512
|
+
result[key] = value;
|
|
20513
|
+
continue;
|
|
20514
|
+
}
|
|
20515
|
+
if (isPlainObject(value)) {
|
|
20516
|
+
const hasRelevantDirtyFields = !hasDirtyTracking || isDirty || hasNestedDirtyFields(dirtyFields, fullPath);
|
|
20517
|
+
if (!hasRelevantDirtyFields) {
|
|
20518
|
+
continue;
|
|
20519
|
+
}
|
|
20520
|
+
const nestedResult = prepareMutationInput(value, {
|
|
20521
|
+
...options,
|
|
20522
|
+
_pathPrefix: fullPath
|
|
20523
|
+
});
|
|
20524
|
+
if (Object.keys(nestedResult).length > 0) {
|
|
20525
|
+
result[key] = nestedResult;
|
|
20526
|
+
}
|
|
20527
|
+
continue;
|
|
20528
|
+
}
|
|
20529
|
+
if (hasDirtyTracking && !isDirty) {
|
|
20530
|
+
continue;
|
|
20531
|
+
}
|
|
20532
|
+
if (defaultValues) {
|
|
20533
|
+
const defaultValue = getNestedValue(defaultValues, fullPath);
|
|
20534
|
+
if (value === defaultValue && !isDirty) {
|
|
20535
|
+
continue;
|
|
20536
|
+
}
|
|
20537
|
+
}
|
|
20538
|
+
result[key] = value;
|
|
20539
|
+
}
|
|
20540
|
+
return result;
|
|
20541
|
+
}
|
|
20542
|
+
function prepareCreateInput(input, options) {
|
|
20543
|
+
return prepareMutationInput(input, { ...options, operation: "create" });
|
|
20544
|
+
}
|
|
20545
|
+
var MEMBERSHIP_TYPES = {
|
|
20546
|
+
APP: 1,
|
|
20547
|
+
ORGANIZATION: 2};
|
|
20548
|
+
var CRUD_OPERATIONS = ["create", "read", "update", "delete"];
|
|
20549
|
+
var CRUD_TO_PRIVILEGE = {
|
|
20550
|
+
create: "INSERT",
|
|
20551
|
+
read: "SELECT",
|
|
20552
|
+
update: "UPDATE",
|
|
20553
|
+
delete: "DELETE"
|
|
20554
|
+
};
|
|
20555
|
+
var DEFAULT_CRUD_GRANT_PRIVILEGES = [
|
|
20556
|
+
["select", "*"],
|
|
20557
|
+
["insert", "*"],
|
|
20558
|
+
["update", "*"],
|
|
20559
|
+
["delete", "*"]
|
|
20560
|
+
];
|
|
20561
|
+
var POLICY_PROVISIONING_CONFIG = {
|
|
20562
|
+
AuthzDirectOwner: {
|
|
20563
|
+
category: "has-module",
|
|
20564
|
+
hasDataNode: true,
|
|
20565
|
+
dataNodeType: "DataDirectOwner",
|
|
20566
|
+
fieldOverrides: {
|
|
20567
|
+
entity_field: {
|
|
20568
|
+
type: "string",
|
|
20569
|
+
required: true,
|
|
20570
|
+
label: "Owner Field Name",
|
|
20571
|
+
placeholder: "owner_id",
|
|
20572
|
+
description: "Column that stores the owner user ID",
|
|
20573
|
+
defaultValue: "owner_id"
|
|
20574
|
+
}
|
|
20575
|
+
}
|
|
20576
|
+
},
|
|
20577
|
+
AuthzEntityMembership: {
|
|
20578
|
+
category: "has-module",
|
|
20579
|
+
hasDataNode: true,
|
|
20580
|
+
dataNodeType: "DataEntityMembership",
|
|
20581
|
+
fieldOverrides: {
|
|
20582
|
+
entity_field: {
|
|
20583
|
+
type: "string",
|
|
20584
|
+
required: true,
|
|
20585
|
+
label: "Entity Field Name",
|
|
20586
|
+
placeholder: "entity_id",
|
|
20587
|
+
description: "Column referencing the org/group",
|
|
20588
|
+
defaultValue: "entity_id"
|
|
20589
|
+
},
|
|
20590
|
+
membership_type: {
|
|
20591
|
+
type: "integer",
|
|
20592
|
+
hidden: true,
|
|
20593
|
+
defaultValue: MEMBERSHIP_TYPES.ORGANIZATION
|
|
20594
|
+
},
|
|
20595
|
+
permission: {
|
|
20596
|
+
type: "string",
|
|
20597
|
+
component: "permission-select",
|
|
20598
|
+
label: "Required Permission",
|
|
20599
|
+
description: "Optional permission the user must have"
|
|
20600
|
+
},
|
|
20601
|
+
is_admin: {
|
|
20602
|
+
type: "boolean",
|
|
20603
|
+
label: "Admins",
|
|
20604
|
+
description: "People with admin access can view this."
|
|
20605
|
+
},
|
|
20606
|
+
is_owner: {
|
|
20607
|
+
type: "boolean",
|
|
20608
|
+
label: "Owners",
|
|
20609
|
+
description: "People who own the membership can view this."
|
|
20610
|
+
}
|
|
20611
|
+
}
|
|
20612
|
+
},
|
|
20613
|
+
AuthzDirectOwnerAny: {
|
|
20614
|
+
category: "needs-fields",
|
|
20615
|
+
hasDataNode: false,
|
|
20616
|
+
fieldOverrides: {
|
|
20617
|
+
entity_fields: {
|
|
20618
|
+
type: "uuid[]",
|
|
20619
|
+
required: true,
|
|
20620
|
+
label: "Owner Fields",
|
|
20621
|
+
description: "UUID columns to check for ownership (OR logic)",
|
|
20622
|
+
defaultValue: ["owner_id"],
|
|
20623
|
+
pgType: "uuid"
|
|
20624
|
+
}
|
|
20625
|
+
}
|
|
20626
|
+
},
|
|
20627
|
+
AuthzMembership: {
|
|
20628
|
+
category: "no-fields",
|
|
20629
|
+
hasDataNode: false,
|
|
20630
|
+
fieldOverrides: {
|
|
20631
|
+
membership_type: {
|
|
20632
|
+
type: "integer",
|
|
20633
|
+
required: true,
|
|
20634
|
+
component: "membership-type-select",
|
|
20635
|
+
label: "Membership Scope",
|
|
20636
|
+
description: "Which type of membership to check against",
|
|
20637
|
+
defaultValue: MEMBERSHIP_TYPES.APP
|
|
20638
|
+
},
|
|
20639
|
+
permission: {
|
|
20640
|
+
type: "string",
|
|
20641
|
+
component: "permission-select",
|
|
20642
|
+
label: "Required Permission",
|
|
20643
|
+
description: "Optional permission the user must have"
|
|
20644
|
+
},
|
|
20645
|
+
is_admin: {
|
|
20646
|
+
type: "boolean",
|
|
20647
|
+
label: "Admins",
|
|
20648
|
+
description: "People with admin access can view this."
|
|
20649
|
+
},
|
|
20650
|
+
is_owner: {
|
|
20651
|
+
type: "boolean",
|
|
20652
|
+
label: "Owners",
|
|
20653
|
+
description: "People who own the membership can view this."
|
|
20654
|
+
}
|
|
20655
|
+
}
|
|
20656
|
+
},
|
|
20657
|
+
AuthzPublishable: {
|
|
20658
|
+
category: "has-module",
|
|
20659
|
+
hasDataNode: true,
|
|
20660
|
+
dataNodeType: "DataPublishable",
|
|
20661
|
+
fieldOverrides: {
|
|
20662
|
+
is_published_field: {
|
|
20663
|
+
type: "string",
|
|
20664
|
+
label: "Published Flag Field",
|
|
20665
|
+
placeholder: "is_published",
|
|
20666
|
+
defaultValue: "is_published"
|
|
20667
|
+
},
|
|
20668
|
+
published_at_field: {
|
|
20669
|
+
type: "string",
|
|
20670
|
+
label: "Published At Field",
|
|
20671
|
+
placeholder: "published_at",
|
|
20672
|
+
defaultValue: "published_at"
|
|
20673
|
+
},
|
|
20674
|
+
require_published_at: {
|
|
20675
|
+
type: "boolean",
|
|
20676
|
+
label: "Require Published At",
|
|
20677
|
+
description: "Also require that the publish date has passed",
|
|
20678
|
+
defaultValue: true
|
|
20679
|
+
}
|
|
20680
|
+
}
|
|
20681
|
+
},
|
|
20682
|
+
AuthzTemporal: {
|
|
20683
|
+
category: "needs-fields",
|
|
20684
|
+
hasDataNode: false,
|
|
20685
|
+
fieldOverrides: {
|
|
20686
|
+
valid_from_field: {
|
|
20687
|
+
type: "string",
|
|
20688
|
+
required: true,
|
|
20689
|
+
label: "Valid From Field",
|
|
20690
|
+
placeholder: "valid_from",
|
|
20691
|
+
description: "Column for start time",
|
|
20692
|
+
defaultValue: "valid_from",
|
|
20693
|
+
pgType: "timestamptz"
|
|
20694
|
+
},
|
|
20695
|
+
valid_until_field: {
|
|
20696
|
+
type: "string",
|
|
20697
|
+
required: true,
|
|
20698
|
+
label: "Valid Until Field",
|
|
20699
|
+
placeholder: "valid_until",
|
|
20700
|
+
description: "Column for end time",
|
|
20701
|
+
defaultValue: "valid_until",
|
|
20702
|
+
pgType: "timestamptz"
|
|
20703
|
+
},
|
|
20704
|
+
valid_from_inclusive: {
|
|
20705
|
+
type: "boolean",
|
|
20706
|
+
label: "Include Start",
|
|
20707
|
+
description: "Include start boundary",
|
|
20708
|
+
defaultValue: true
|
|
20709
|
+
},
|
|
20710
|
+
valid_until_inclusive: {
|
|
20711
|
+
type: "boolean",
|
|
20712
|
+
label: "Include End",
|
|
20713
|
+
description: "Include end boundary",
|
|
20714
|
+
defaultValue: false
|
|
20715
|
+
}
|
|
20716
|
+
}
|
|
20717
|
+
},
|
|
20718
|
+
AuthzMemberList: {
|
|
20719
|
+
category: "needs-fields",
|
|
20720
|
+
hasDataNode: false,
|
|
20721
|
+
fieldOverrides: {
|
|
20722
|
+
array_field: {
|
|
20723
|
+
type: "string",
|
|
20724
|
+
required: true,
|
|
20725
|
+
label: "Member List Field",
|
|
20726
|
+
placeholder: "allowed_users",
|
|
20727
|
+
description: "Column containing list of user IDs",
|
|
20728
|
+
defaultValue: "allowed_users",
|
|
20729
|
+
pgType: "uuid[]"
|
|
20730
|
+
}
|
|
20731
|
+
}
|
|
20732
|
+
},
|
|
20733
|
+
AuthzRelatedMemberList: {
|
|
20734
|
+
category: "needs-table",
|
|
20735
|
+
hasDataNode: false,
|
|
20736
|
+
fieldOverrides: {
|
|
20737
|
+
owned_schema: {
|
|
20738
|
+
hidden: true
|
|
20739
|
+
},
|
|
20740
|
+
owned_table: {
|
|
20741
|
+
type: "string",
|
|
20742
|
+
required: true,
|
|
20743
|
+
component: "table-select",
|
|
20744
|
+
label: "Related Table",
|
|
20745
|
+
placeholder: "groups",
|
|
20746
|
+
description: "Table containing the member list"
|
|
20747
|
+
},
|
|
20748
|
+
owned_table_key: {
|
|
20749
|
+
type: "uuid",
|
|
20750
|
+
required: true,
|
|
20751
|
+
label: "Member List Column",
|
|
20752
|
+
placeholder: "member_ids",
|
|
20753
|
+
description: "List column in related table",
|
|
20754
|
+
dependsOn: "owned_table"
|
|
20755
|
+
},
|
|
20756
|
+
owned_table_ref_key: {
|
|
20757
|
+
type: "uuid",
|
|
20758
|
+
required: true,
|
|
20759
|
+
label: "Reference Key",
|
|
20760
|
+
placeholder: "id",
|
|
20761
|
+
description: "FK column in related table",
|
|
20762
|
+
dependsOn: "owned_table"
|
|
20763
|
+
},
|
|
20764
|
+
this_object_key: {
|
|
20765
|
+
type: "uuid",
|
|
20766
|
+
required: true,
|
|
20767
|
+
label: "Foreign Key",
|
|
20768
|
+
placeholder: "group_id",
|
|
20769
|
+
description: "FK on this table to related table"
|
|
20770
|
+
}
|
|
20771
|
+
}
|
|
20772
|
+
},
|
|
20773
|
+
AuthzRelatedEntityMembership: {
|
|
20774
|
+
category: "needs-table",
|
|
20775
|
+
hasDataNode: false,
|
|
20776
|
+
fieldOverrides: {
|
|
20777
|
+
entity_field: {
|
|
20778
|
+
type: "uuid",
|
|
20779
|
+
required: true,
|
|
20780
|
+
label: "Foreign Key Field",
|
|
20781
|
+
description: "Field on this table referencing the linked table"
|
|
20782
|
+
},
|
|
20783
|
+
membership_type: {
|
|
20784
|
+
type: "integer",
|
|
20785
|
+
required: true,
|
|
20786
|
+
component: "membership-type-select",
|
|
20787
|
+
label: "Membership Scope"
|
|
20788
|
+
},
|
|
20789
|
+
obj_schema: {
|
|
20790
|
+
hidden: true
|
|
20791
|
+
},
|
|
20792
|
+
obj_table: {
|
|
20793
|
+
type: "string",
|
|
20794
|
+
required: true,
|
|
20795
|
+
component: "table-select",
|
|
20796
|
+
label: "Linked Table",
|
|
20797
|
+
description: "Table to check for membership"
|
|
20798
|
+
},
|
|
20799
|
+
obj_field: {
|
|
20800
|
+
type: "uuid",
|
|
20801
|
+
required: true,
|
|
20802
|
+
label: "Entity Field on Linked Table",
|
|
20803
|
+
description: "Field containing entity ID for membership check",
|
|
20804
|
+
dependsOn: "obj_table"
|
|
20805
|
+
},
|
|
20806
|
+
permission: {
|
|
20807
|
+
type: "string",
|
|
20808
|
+
component: "permission-select",
|
|
20809
|
+
label: "Required Permission"
|
|
20810
|
+
},
|
|
20811
|
+
is_admin: {
|
|
20812
|
+
type: "boolean",
|
|
20813
|
+
label: "Admins",
|
|
20814
|
+
description: "People with admin access can view this."
|
|
20815
|
+
},
|
|
20816
|
+
is_owner: {
|
|
20817
|
+
type: "boolean",
|
|
20818
|
+
label: "Owners",
|
|
20819
|
+
description: "People who own the membership can view this."
|
|
20820
|
+
}
|
|
20821
|
+
}
|
|
20822
|
+
},
|
|
20823
|
+
AuthzOrgHierarchy: {
|
|
20824
|
+
category: "has-module",
|
|
20825
|
+
hasDataNode: true,
|
|
20826
|
+
dataNodeType: "DataOwnershipInEntity",
|
|
20827
|
+
disabled: true,
|
|
20828
|
+
fieldOverrides: {
|
|
20829
|
+
direction: {
|
|
20830
|
+
type: "string",
|
|
20831
|
+
required: true,
|
|
20832
|
+
label: "Direction",
|
|
20833
|
+
description: "Which direction to traverse the org hierarchy",
|
|
20834
|
+
defaultValue: "down",
|
|
20835
|
+
options: [
|
|
20836
|
+
{ value: "down", label: "Down", description: "Managers can see their subordinates" },
|
|
20837
|
+
{ value: "up", label: "Up", description: "Subordinates can see their managers" }
|
|
20838
|
+
]
|
|
20839
|
+
},
|
|
20840
|
+
entity_field: {
|
|
20841
|
+
type: "string",
|
|
20842
|
+
label: "Entity Field Name",
|
|
20843
|
+
placeholder: "entity_id",
|
|
20844
|
+
description: "Field referencing the org entity",
|
|
20845
|
+
defaultValue: "entity_id"
|
|
20846
|
+
},
|
|
20847
|
+
anchor_field: {
|
|
20848
|
+
type: "string",
|
|
20849
|
+
required: true,
|
|
20850
|
+
label: "Anchor Field",
|
|
20851
|
+
placeholder: "owner_id",
|
|
20852
|
+
description: "Field referencing the user (e.g., owner_id)"
|
|
20853
|
+
},
|
|
20854
|
+
max_depth: {
|
|
20855
|
+
type: "integer",
|
|
20856
|
+
label: "Max Depth",
|
|
20857
|
+
description: "Optional max depth to limit visibility"
|
|
20858
|
+
}
|
|
20859
|
+
}
|
|
20860
|
+
},
|
|
20861
|
+
AuthzAllowAll: {
|
|
20862
|
+
category: "no-fields",
|
|
20863
|
+
hasDataNode: false
|
|
20864
|
+
},
|
|
20865
|
+
AuthzDenyAll: {
|
|
20866
|
+
category: "no-fields",
|
|
20867
|
+
hasDataNode: false
|
|
20868
|
+
},
|
|
20869
|
+
AuthzComposite: {
|
|
20870
|
+
category: "no-fields",
|
|
20871
|
+
hasDataNode: false
|
|
20872
|
+
}
|
|
20873
|
+
};
|
|
20874
|
+
var AUTO_INJECT_SCHEMA_FIELDS = /* @__PURE__ */ new Set(["owned_schema", "obj_schema"]);
|
|
20875
|
+
function getPolicyCategory(policyType) {
|
|
20876
|
+
return POLICY_PROVISIONING_CONFIG[policyType]?.category ?? "no-fields";
|
|
20877
|
+
}
|
|
20878
|
+
function getDataNodeForPolicy(policyType) {
|
|
20879
|
+
return POLICY_PROVISIONING_CONFIG[policyType]?.dataNodeType;
|
|
20880
|
+
}
|
|
20881
|
+
function getPolicyFieldDefaults(policyType) {
|
|
20882
|
+
const config = POLICY_PROVISIONING_CONFIG[policyType];
|
|
20883
|
+
if (!config?.fieldOverrides) {
|
|
20884
|
+
return {};
|
|
20885
|
+
}
|
|
20886
|
+
const defaults = {};
|
|
20887
|
+
for (const [key, override] of Object.entries(config.fieldOverrides)) {
|
|
20888
|
+
if (override.defaultValue !== void 0) {
|
|
20889
|
+
defaults[key] = override.defaultValue;
|
|
20890
|
+
}
|
|
20891
|
+
}
|
|
20892
|
+
return defaults;
|
|
20893
|
+
}
|
|
20894
|
+
function getFieldsRequiringColumns(policyType) {
|
|
20895
|
+
const config = POLICY_PROVISIONING_CONFIG[policyType];
|
|
20896
|
+
if (!config?.fieldOverrides) {
|
|
20897
|
+
return [];
|
|
20898
|
+
}
|
|
20899
|
+
const result = [];
|
|
20900
|
+
for (const [key, override] of Object.entries(config.fieldOverrides)) {
|
|
20901
|
+
if (!override.pgType) {
|
|
20902
|
+
continue;
|
|
20903
|
+
}
|
|
20904
|
+
const defaultName = Array.isArray(override.defaultValue) ? override.defaultValue : typeof override.defaultValue === "string" ? override.defaultValue : key;
|
|
20905
|
+
result.push({
|
|
20906
|
+
key,
|
|
20907
|
+
defaultName,
|
|
20908
|
+
pgType: override.pgType
|
|
20909
|
+
});
|
|
20910
|
+
}
|
|
20911
|
+
return result;
|
|
20912
|
+
}
|
|
20913
|
+
function sanitizePolicyData(data) {
|
|
20914
|
+
const sanitized = {};
|
|
20915
|
+
for (const [key, value] of Object.entries(data)) {
|
|
20916
|
+
if (value === void 0 || value === null) {
|
|
20917
|
+
continue;
|
|
20918
|
+
}
|
|
20919
|
+
if (typeof value === "string" && value.trim() === "") {
|
|
20920
|
+
continue;
|
|
20921
|
+
}
|
|
20922
|
+
if (Array.isArray(value) && value.length === 0) {
|
|
20923
|
+
continue;
|
|
20924
|
+
}
|
|
20925
|
+
sanitized[key] = value;
|
|
20926
|
+
}
|
|
20927
|
+
return sanitized;
|
|
20928
|
+
}
|
|
20929
|
+
function injectSchemaFields(policyData, schemaId, policyType) {
|
|
20930
|
+
const config = POLICY_PROVISIONING_CONFIG[policyType];
|
|
20931
|
+
if (!config?.fieldOverrides) {
|
|
20932
|
+
return policyData;
|
|
20933
|
+
}
|
|
20934
|
+
const next = { ...policyData };
|
|
20935
|
+
for (const [key, override] of Object.entries(config.fieldOverrides)) {
|
|
20936
|
+
if (!AUTO_INJECT_SCHEMA_FIELDS.has(key)) {
|
|
20937
|
+
continue;
|
|
20938
|
+
}
|
|
20939
|
+
if (override.hidden && next[key] === void 0) {
|
|
20940
|
+
next[key] = schemaId;
|
|
20941
|
+
}
|
|
20942
|
+
}
|
|
20943
|
+
return next;
|
|
20944
|
+
}
|
|
20945
|
+
function buildNodeDataForDataNodeType(dataNodeType, policyData) {
|
|
20946
|
+
if (!dataNodeType) {
|
|
20947
|
+
return {};
|
|
20948
|
+
}
|
|
20949
|
+
const data = {};
|
|
20950
|
+
if (dataNodeType === "DataDirectOwner") {
|
|
20951
|
+
if (policyData.entity_field && policyData.entity_field !== "owner_id") {
|
|
20952
|
+
data.owner_field_name = policyData.entity_field;
|
|
20953
|
+
}
|
|
20954
|
+
}
|
|
20955
|
+
if (dataNodeType === "DataEntityMembership") {
|
|
20956
|
+
if (policyData.entity_field && policyData.entity_field !== "entity_id") {
|
|
20957
|
+
data.entity_field_name = policyData.entity_field;
|
|
20958
|
+
}
|
|
20959
|
+
}
|
|
20960
|
+
if (dataNodeType === "DataOwnershipInEntity") {
|
|
20961
|
+
if (policyData.entity_field && policyData.entity_field !== "entity_id") {
|
|
20962
|
+
data.entity_field_name = policyData.entity_field;
|
|
20963
|
+
}
|
|
20964
|
+
if (policyData.anchor_field && policyData.anchor_field !== "owner_id") {
|
|
20965
|
+
data.owner_field_name = policyData.anchor_field;
|
|
20966
|
+
}
|
|
20967
|
+
}
|
|
20968
|
+
return data;
|
|
20969
|
+
}
|
|
20970
|
+
function buildNodeData(policyType, policyData) {
|
|
20971
|
+
return buildNodeDataForDataNodeType(getDataNodeForPolicy(policyType), policyData);
|
|
20972
|
+
}
|
|
20973
|
+
|
|
20974
|
+
// src/tables.ts
|
|
20308
20975
|
function assert2(condition, message) {
|
|
20309
20976
|
if (!condition) {
|
|
20310
20977
|
throw new Error(message);
|
|
20311
20978
|
}
|
|
20312
20979
|
}
|
|
20313
20980
|
function getPolicyPrivileges(policy) {
|
|
20314
|
-
const operations = policy.operations?.length ? policy.operations :
|
|
20315
|
-
return operations.map((operation) =>
|
|
20981
|
+
const operations = policy.operations?.length ? policy.operations : CRUD_OPERATIONS;
|
|
20982
|
+
return operations.map((operation) => CRUD_TO_PRIVILEGE[operation]);
|
|
20316
20983
|
}
|
|
20317
20984
|
function getResolvedPolicyData(policy, schemaId) {
|
|
20318
|
-
return
|
|
20319
|
-
|
|
20985
|
+
return sanitizePolicyData(
|
|
20986
|
+
injectSchemaFields(
|
|
20320
20987
|
{
|
|
20321
|
-
...
|
|
20988
|
+
...getPolicyFieldDefaults(policy.policyType),
|
|
20322
20989
|
...policy.policyData ?? {}
|
|
20323
20990
|
},
|
|
20324
20991
|
schemaId,
|
|
@@ -20380,7 +21047,7 @@ async function ensureBaseTable(db, databaseId, schemaId, tableName, grantRoles,
|
|
|
20380
21047
|
tableName,
|
|
20381
21048
|
useRls,
|
|
20382
21049
|
grantRoles,
|
|
20383
|
-
grantPrivileges:
|
|
21050
|
+
grantPrivileges: DEFAULT_CRUD_GRANT_PRIVILEGES
|
|
20384
21051
|
};
|
|
20385
21052
|
if (inlinePolicy) {
|
|
20386
21053
|
provisionInput.policyType = inlinePolicy.policyType;
|
|
@@ -20479,7 +21146,7 @@ async function createPrimaryKey(db, databaseId, tableId, fieldIds) {
|
|
|
20479
21146
|
}
|
|
20480
21147
|
async function ensurePolicyFields(db, databaseId, tableId, policy, schemaId) {
|
|
20481
21148
|
const resolvedPolicyData = getResolvedPolicyData(policy, schemaId);
|
|
20482
|
-
const helperFields =
|
|
21149
|
+
const helperFields = getFieldsRequiringColumns(policy.policyType);
|
|
20483
21150
|
let createdFields = 0;
|
|
20484
21151
|
for (const helperField of helperFields) {
|
|
20485
21152
|
const overrideValue = resolvedPolicyData[helperField.key];
|
|
@@ -20501,8 +21168,8 @@ async function attachPolicyToTable(db, databaseId, schemaId, tableId, policy, no
|
|
|
20501
21168
|
throw new Error("AuthzComposite is not supported in seeder blueprints yet");
|
|
20502
21169
|
}
|
|
20503
21170
|
const resolvedPolicyData = getResolvedPolicyData(policy, schemaId);
|
|
20504
|
-
const nodeType =
|
|
20505
|
-
const nodeData =
|
|
21171
|
+
const nodeType = getDataNodeForPolicy(policy.policyType);
|
|
21172
|
+
const nodeData = buildNodeData(policy.policyType, resolvedPolicyData);
|
|
20506
21173
|
const provisionInput = {
|
|
20507
21174
|
databaseId,
|
|
20508
21175
|
schemaId,
|
|
@@ -20537,10 +21204,10 @@ async function provisionTable(db, databaseId, schemaId, table, grantRoles) {
|
|
|
20537
21204
|
return ensureBaseTable(db, databaseId, schemaId, table.name, grantRoles, false);
|
|
20538
21205
|
}
|
|
20539
21206
|
const [firstPolicy, ...remainingPolicies] = policies;
|
|
20540
|
-
const firstPolicyCategory =
|
|
21207
|
+
const firstPolicyCategory = getPolicyCategory(firstPolicy.policyType);
|
|
20541
21208
|
const firstPolicyData = getResolvedPolicyData(firstPolicy, schemaId);
|
|
20542
|
-
const firstNodeType =
|
|
20543
|
-
const firstNodeData =
|
|
21209
|
+
const firstNodeType = getDataNodeForPolicy(firstPolicy.policyType);
|
|
21210
|
+
const firstNodeData = buildNodeData(firstPolicy.policyType, firstPolicyData);
|
|
20544
21211
|
const nodeTypesSeen = /* @__PURE__ */ new Set();
|
|
20545
21212
|
const inlinePolicy = firstPolicyCategory === "has-module" || firstPolicyCategory === "no-fields" || firstPolicyCategory === "needs-table" ? {
|
|
20546
21213
|
policyType: firstPolicy.policyType,
|
|
@@ -20569,7 +21236,7 @@ async function provisionTable(db, databaseId, schemaId, table, grantRoles) {
|
|
|
20569
21236
|
outcome.tableModulesCreated += attachResult.tableModulesCreated;
|
|
20570
21237
|
}
|
|
20571
21238
|
for (const policy of remainingPolicies) {
|
|
20572
|
-
if (
|
|
21239
|
+
if (getPolicyCategory(policy.policyType) === "needs-fields") {
|
|
20573
21240
|
await ensurePolicyFields(db, databaseId, outcome.tableId, policy, schemaId);
|
|
20574
21241
|
}
|
|
20575
21242
|
const attachResult = await attachPolicyToTable(db, databaseId, schemaId, outcome.tableId, policy, nodeTypesSeen);
|
|
@@ -20614,51 +21281,51 @@ async function provisionManyToManyRelation(db, databaseId, schemaId, sourceTable
|
|
|
20614
21281
|
throw new Error(`Relation ${relation.junctionTableName} supports at most one junction-table policy`);
|
|
20615
21282
|
}
|
|
20616
21283
|
const junctionPolicy = relation.policies?.[0];
|
|
20617
|
-
if (junctionPolicy?.policyType === "AuthzComposite" ||
|
|
21284
|
+
if (junctionPolicy?.policyType === "AuthzComposite" || getPolicyCategory(junctionPolicy?.policyType ?? "AuthzAllowAll") === "needs-fields") {
|
|
20618
21285
|
throw new Error(`Relation ${relation.junctionTableName} uses an unsupported junction-table policy`);
|
|
20619
21286
|
}
|
|
20620
21287
|
const resolvedPolicy = junctionPolicy ?? {
|
|
20621
21288
|
policyType: "AuthzAllowAll"};
|
|
20622
21289
|
const policyData = getResolvedPolicyData(resolvedPolicy, schemaId);
|
|
20623
|
-
const derivedNodeType =
|
|
20624
|
-
const baseNodeData =
|
|
20625
|
-
const data
|
|
21290
|
+
const derivedNodeType = getDataNodeForPolicy(resolvedPolicy.policyType);
|
|
21291
|
+
const baseNodeData = buildNodeData(resolvedPolicy.policyType, policyData);
|
|
21292
|
+
const data = {
|
|
20626
21293
|
databaseId,
|
|
20627
21294
|
relationType: "RelationManyToMany",
|
|
20628
21295
|
sourceTableId,
|
|
20629
21296
|
targetTableId,
|
|
20630
21297
|
junctionTableName: relation.junctionTableName,
|
|
20631
21298
|
grantRoles: ["authenticated"],
|
|
20632
|
-
grantPrivileges:
|
|
21299
|
+
grantPrivileges: DEFAULT_CRUD_GRANT_PRIVILEGES,
|
|
20633
21300
|
policyType: resolvedPolicy.policyType,
|
|
20634
21301
|
policyPermissive: resolvedPolicy.isPermissive ?? true,
|
|
20635
21302
|
policyData,
|
|
20636
21303
|
policyRole: resolvedPolicy.roleName?.trim() || "authenticated"
|
|
20637
21304
|
};
|
|
20638
21305
|
if (relation.deleteAction) {
|
|
20639
|
-
data
|
|
21306
|
+
data.deleteAction = relation.deleteAction;
|
|
20640
21307
|
}
|
|
20641
21308
|
if (relation.useCompositeKey !== void 0) {
|
|
20642
|
-
data
|
|
21309
|
+
data.useCompositeKey = relation.useCompositeKey;
|
|
20643
21310
|
}
|
|
20644
21311
|
if (relation.sourceFieldName) {
|
|
20645
|
-
data
|
|
21312
|
+
data.sourceFieldName = relation.sourceFieldName;
|
|
20646
21313
|
}
|
|
20647
21314
|
if (relation.targetFieldName) {
|
|
20648
|
-
data
|
|
21315
|
+
data.targetFieldName = relation.targetFieldName;
|
|
20649
21316
|
}
|
|
20650
21317
|
if (derivedNodeType) {
|
|
20651
|
-
data
|
|
21318
|
+
data.nodeType = derivedNodeType;
|
|
20652
21319
|
const derivedNodeData = relation.useCompositeKey ? { ...baseNodeData, include_id: false } : baseNodeData;
|
|
20653
21320
|
if (Object.keys(derivedNodeData).length > 0) {
|
|
20654
|
-
data
|
|
21321
|
+
data.nodeData = derivedNodeData;
|
|
20655
21322
|
}
|
|
20656
21323
|
} else if (!relation.useCompositeKey) {
|
|
20657
|
-
data
|
|
21324
|
+
data.nodeType = "DataId";
|
|
20658
21325
|
}
|
|
20659
21326
|
try {
|
|
20660
21327
|
const result = await db.relationProvision.create({
|
|
20661
|
-
data
|
|
21328
|
+
data,
|
|
20662
21329
|
select: { id: true, outJunctionTableId: true }
|
|
20663
21330
|
}).execute();
|
|
20664
21331
|
if (!result.ok) {
|
|
@@ -20922,7 +21589,7 @@ function getTableLookupVariants(value) {
|
|
|
20922
21589
|
async function loadMetaTables(client) {
|
|
20923
21590
|
const response = await client.request(META_QUERY);
|
|
20924
21591
|
const rawTables = response._meta?.tables?.filter((table) => Boolean(table)) ?? [];
|
|
20925
|
-
const allTables = rawTables.map((table) =>
|
|
21592
|
+
const allTables = rawTables.map((table) => cleanTable(table));
|
|
20926
21593
|
const byName = /* @__PURE__ */ new Map();
|
|
20927
21594
|
for (let index = 0; index < rawTables.length; index++) {
|
|
20928
21595
|
const rawTable = rawTables[index];
|
|
@@ -21011,16 +21678,16 @@ async function executeSeedNode(client, node, meta, ctx) {
|
|
|
21011
21678
|
ids: []
|
|
21012
21679
|
};
|
|
21013
21680
|
}
|
|
21014
|
-
const mutation =
|
|
21681
|
+
const mutation = index_js$1.buildPostGraphileCreate(table, meta.allTables, {
|
|
21015
21682
|
fieldSelection: { select: ["id"] }
|
|
21016
21683
|
});
|
|
21017
|
-
const singularName =
|
|
21018
|
-
const mutationName =
|
|
21684
|
+
const singularName = index_js$1.toCamelCaseSingular(node.table, table);
|
|
21685
|
+
const mutationName = index_js$1.toCreateMutationName(node.table, table);
|
|
21019
21686
|
const results = await batchedAll(generatedRows, async (row) => {
|
|
21020
21687
|
const input = node.mapInput ? node.mapInput(row, ctx) : row;
|
|
21021
21688
|
const variables = {
|
|
21022
21689
|
input: {
|
|
21023
|
-
[singularName]:
|
|
21690
|
+
[singularName]: prepareCreateInput(input)
|
|
21024
21691
|
}
|
|
21025
21692
|
};
|
|
21026
21693
|
try {
|