@wordrhyme/db 0.1.0-alpha.14
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 +66 -0
- package/dist/acl-policy.d.ts +86 -0
- package/dist/acl-policy.d.ts.map +1 -0
- package/dist/chunk-3TTVLSF5.js +3390 -0
- package/dist/chunk-3TTVLSF5.js.map +1 -0
- package/dist/chunk-DCJM6GN5.js +264 -0
- package/dist/chunk-DCJM6GN5.js.map +1 -0
- package/dist/chunk-KWWJRUIK.js +54 -0
- package/dist/chunk-KWWJRUIK.js.map +1 -0
- package/dist/chunk-XAIEVBMU.js +212 -0
- package/dist/chunk-XAIEVBMU.js.map +1 -0
- package/dist/delete-policy.d.ts +11 -0
- package/dist/delete-policy.d.ts.map +1 -0
- package/dist/index.d.ts +31 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +545 -0
- package/dist/index.js.map +1 -0
- package/dist/plugin.d.ts +110 -0
- package/dist/plugin.d.ts.map +1 -0
- package/dist/plugin.js +21 -0
- package/dist/plugin.js.map +1 -0
- package/dist/relations/index.d.ts +105 -0
- package/dist/relations/index.d.ts.map +1 -0
- package/dist/relations/index.js +9 -0
- package/dist/relations/index.js.map +1 -0
- package/dist/schema/action-journal.d.ts +386 -0
- package/dist/schema/action-journal.d.ts.map +1 -0
- package/dist/schema/audit-archive.d.ts +934 -0
- package/dist/schema/audit-archive.d.ts.map +1 -0
- package/dist/schema/audit-events.d.ts +502 -0
- package/dist/schema/audit-events.d.ts.map +1 -0
- package/dist/schema/audit-logs.d.ts +418 -0
- package/dist/schema/audit-logs.d.ts.map +1 -0
- package/dist/schema/auth.d.ts +2727 -0
- package/dist/schema/auth.d.ts.map +1 -0
- package/dist/schema/billing.d.ts +3969 -0
- package/dist/schema/billing.d.ts.map +1 -0
- package/dist/schema/common.d.ts +87 -0
- package/dist/schema/common.d.ts.map +1 -0
- package/dist/schema/currency.d.ts +791 -0
- package/dist/schema/currency.d.ts.map +1 -0
- package/dist/schema/entity-extensions.d.ts +314 -0
- package/dist/schema/entity-extensions.d.ts.map +1 -0
- package/dist/schema/entity-ownerships.d.ts +862 -0
- package/dist/schema/entity-ownerships.d.ts.map +1 -0
- package/dist/schema/feature-flags.d.ts +770 -0
- package/dist/schema/feature-flags.d.ts.map +1 -0
- package/dist/schema/geo.d.ts +824 -0
- package/dist/schema/geo.d.ts.map +1 -0
- package/dist/schema/i18n.d.ts +1109 -0
- package/dist/schema/i18n.d.ts.map +1 -0
- package/dist/schema/index.d.ts +43 -0
- package/dist/schema/index.d.ts.map +1 -0
- package/dist/schema/index.js +507 -0
- package/dist/schema/index.js.map +1 -0
- package/dist/schema/media.d.ts +1147 -0
- package/dist/schema/media.d.ts.map +1 -0
- package/dist/schema/menus.d.ts +636 -0
- package/dist/schema/menus.d.ts.map +1 -0
- package/dist/schema/notification-channels.d.ts +288 -0
- package/dist/schema/notification-channels.d.ts.map +1 -0
- package/dist/schema/notification-preferences.d.ts +300 -0
- package/dist/schema/notification-preferences.d.ts.map +1 -0
- package/dist/schema/notification-templates.d.ts +476 -0
- package/dist/schema/notification-templates.d.ts.map +1 -0
- package/dist/schema/notifications.d.ts +1139 -0
- package/dist/schema/notifications.d.ts.map +1 -0
- package/dist/schema/permission-fields.d.ts +96 -0
- package/dist/schema/permission-fields.d.ts.map +1 -0
- package/dist/schema/permissions.d.ts +173 -0
- package/dist/schema/permissions.d.ts.map +1 -0
- package/dist/schema/plugin-migrations.d.ts +204 -0
- package/dist/schema/plugin-migrations.d.ts.map +1 -0
- package/dist/schema/plugins.d.ts +1977 -0
- package/dist/schema/plugins.d.ts.map +1 -0
- package/dist/schema/relationships.d.ts +221 -0
- package/dist/schema/relationships.d.ts.map +1 -0
- package/dist/schema/role-permissions.d.ts +305 -0
- package/dist/schema/role-permissions.d.ts.map +1 -0
- package/dist/schema/roles.d.ts +260 -0
- package/dist/schema/roles.d.ts.map +1 -0
- package/dist/schema/scheduled-tasks.d.ts +1334 -0
- package/dist/schema/scheduled-tasks.d.ts.map +1 -0
- package/dist/schema/settings.d.ts +819 -0
- package/dist/schema/settings.d.ts.map +1 -0
- package/dist/schema/site-presentation.d.ts +1587 -0
- package/dist/schema/site-presentation.d.ts.map +1 -0
- package/dist/schema/teams.d.ts +381 -0
- package/dist/schema/teams.d.ts.map +1 -0
- package/dist/schema/web-design.d.ts +1542 -0
- package/dist/schema/web-design.d.ts.map +1 -0
- package/dist/schema/webhooks.d.ts +1016 -0
- package/dist/schema/webhooks.d.ts.map +1 -0
- package/dist/zod/index.d.ts +2 -0
- package/dist/zod/index.d.ts.map +1 -0
- package/dist/zod/index.js +6 -0
- package/dist/zod/index.js.map +1 -0
- package/package.json +63 -0
|
@@ -0,0 +1,264 @@
|
|
|
1
|
+
// src/plugin.ts
|
|
2
|
+
import { getTableName } from "drizzle-orm";
|
|
3
|
+
import {
|
|
4
|
+
pgTableCreator,
|
|
5
|
+
text,
|
|
6
|
+
timestamp
|
|
7
|
+
} from "drizzle-orm/pg-core";
|
|
8
|
+
import {
|
|
9
|
+
createInsertSchema as _drizzleCreateInsertSchema,
|
|
10
|
+
createSelectSchema as _drizzleCreateSelectSchema
|
|
11
|
+
} from "drizzle-orm/zod";
|
|
12
|
+
|
|
13
|
+
// src/acl-policy.ts
|
|
14
|
+
var ADMIN_ROLE_TAGS = ["role:owner", "role:admin", "role:super-admin"];
|
|
15
|
+
var ACL_POLICY_STATE_KEY = /* @__PURE__ */ Symbol.for("@wordrhyme/db/acl-policy-state");
|
|
16
|
+
function getAclPolicyRegistryState() {
|
|
17
|
+
const runtime = globalThis;
|
|
18
|
+
runtime[ACL_POLICY_STATE_KEY] ??= {
|
|
19
|
+
aclPolicyRegistry: /* @__PURE__ */ new Map(),
|
|
20
|
+
aclPolicyOverrideCache: /* @__PURE__ */ new Map()
|
|
21
|
+
};
|
|
22
|
+
return runtime[ACL_POLICY_STATE_KEY];
|
|
23
|
+
}
|
|
24
|
+
var aclPolicyRegistry = getAclPolicyRegistryState().aclPolicyRegistry;
|
|
25
|
+
function dedupePrincipals(policy) {
|
|
26
|
+
return Array.from(new Set(policy));
|
|
27
|
+
}
|
|
28
|
+
function normalizeDefaultAclPolicy(policy) {
|
|
29
|
+
if (typeof policy === "string") {
|
|
30
|
+
return [policy];
|
|
31
|
+
}
|
|
32
|
+
return dedupePrincipals(policy);
|
|
33
|
+
}
|
|
34
|
+
function setDeveloperAclPolicy(tableName, policy) {
|
|
35
|
+
aclPolicyRegistry.set(tableName, normalizeDefaultAclPolicy(policy));
|
|
36
|
+
}
|
|
37
|
+
var aclPolicyOverrideCache = getAclPolicyRegistryState().aclPolicyOverrideCache;
|
|
38
|
+
function overrideCacheKey(tableName, organizationId) {
|
|
39
|
+
return `${tableName}:${organizationId}`;
|
|
40
|
+
}
|
|
41
|
+
function setAclPolicyOverride(tableName, organizationId, policy) {
|
|
42
|
+
aclPolicyOverrideCache.set(overrideCacheKey(tableName, organizationId), normalizeDefaultAclPolicy(policy));
|
|
43
|
+
}
|
|
44
|
+
function removeAclPolicyOverride(tableName, organizationId) {
|
|
45
|
+
aclPolicyOverrideCache.delete(overrideCacheKey(tableName, organizationId));
|
|
46
|
+
}
|
|
47
|
+
function loadAclPolicyOverrides(overrides) {
|
|
48
|
+
for (const { tableName, organizationId, policy } of overrides) {
|
|
49
|
+
aclPolicyOverrideCache.set(overrideCacheKey(tableName, organizationId), normalizeDefaultAclPolicy(policy));
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
function clearAclPolicyOverrides() {
|
|
53
|
+
aclPolicyOverrideCache.clear();
|
|
54
|
+
}
|
|
55
|
+
function getEffectiveAclPolicy(tableName, organizationId) {
|
|
56
|
+
if (organizationId) {
|
|
57
|
+
const override = aclPolicyOverrideCache.get(overrideCacheKey(tableName, organizationId));
|
|
58
|
+
if (override) return override;
|
|
59
|
+
}
|
|
60
|
+
const devPolicy = aclPolicyRegistry.get(tableName);
|
|
61
|
+
if (devPolicy) return devPolicy;
|
|
62
|
+
return ["creator"];
|
|
63
|
+
}
|
|
64
|
+
function resolveAclTags(policy, ctx) {
|
|
65
|
+
const principals = normalizeDefaultAclPolicy(policy);
|
|
66
|
+
const tags = [];
|
|
67
|
+
for (const principal of principals) {
|
|
68
|
+
switch (principal) {
|
|
69
|
+
case "org":
|
|
70
|
+
if (ctx.organizationId) tags.push(`org:${ctx.organizationId}`);
|
|
71
|
+
break;
|
|
72
|
+
case "creator":
|
|
73
|
+
if (ctx.userId) tags.push(`user:${ctx.userId}`);
|
|
74
|
+
break;
|
|
75
|
+
case "admin":
|
|
76
|
+
tags.push(...ADMIN_ROLE_TAGS);
|
|
77
|
+
break;
|
|
78
|
+
case "public":
|
|
79
|
+
tags.push("public:all");
|
|
80
|
+
break;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
return Array.from(new Set(tags));
|
|
84
|
+
}
|
|
85
|
+
function getRegisteredAclPolicies() {
|
|
86
|
+
return Object.fromEntries(aclPolicyRegistry.entries());
|
|
87
|
+
}
|
|
88
|
+
var ACL_POLICY_SETTINGS_PREFIX = "lbac.defaultAclPolicy.";
|
|
89
|
+
|
|
90
|
+
// src/delete-policy.ts
|
|
91
|
+
var TABLE_SOFT_DELETE_CAPABILITY_KEY = /* @__PURE__ */ Symbol.for("@wordrhyme/db/table-soft-delete-capability");
|
|
92
|
+
var TABLE_SOFT_DELETE_CAPABILITY_PROPERTY = "__wordrhymeTableSoftDeleteCapability";
|
|
93
|
+
function setTableSoftDeleteCapability(table, enabled) {
|
|
94
|
+
Object.defineProperty(table, TABLE_SOFT_DELETE_CAPABILITY_KEY, {
|
|
95
|
+
value: enabled,
|
|
96
|
+
enumerable: false,
|
|
97
|
+
configurable: true
|
|
98
|
+
});
|
|
99
|
+
Object.defineProperty(table, TABLE_SOFT_DELETE_CAPABILITY_PROPERTY, {
|
|
100
|
+
value: enabled,
|
|
101
|
+
enumerable: false,
|
|
102
|
+
configurable: true
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
function getTableSoftDeleteCapability(table) {
|
|
106
|
+
if (!table || typeof table !== "object") {
|
|
107
|
+
return void 0;
|
|
108
|
+
}
|
|
109
|
+
const tableRecord = table;
|
|
110
|
+
const symbolValue = tableRecord[TABLE_SOFT_DELETE_CAPABILITY_KEY];
|
|
111
|
+
if (typeof symbolValue === "boolean") {
|
|
112
|
+
return symbolValue;
|
|
113
|
+
}
|
|
114
|
+
const propertyValue = tableRecord[TABLE_SOFT_DELETE_CAPABILITY_PROPERTY];
|
|
115
|
+
return typeof propertyValue === "boolean" ? propertyValue : void 0;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
// src/plugin.ts
|
|
119
|
+
var PLUGIN_AUDIT_ACTOR_TYPES = ["user", "system", "plugin", "api-token"];
|
|
120
|
+
function createPluginPolicyFields() {
|
|
121
|
+
return {
|
|
122
|
+
organizationId: text("organization_id").notNull(),
|
|
123
|
+
aclTags: text("acl_tags").array().notNull().default([]),
|
|
124
|
+
denyTags: text("deny_tags").array().notNull().default([])
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
function createPluginAuditFields() {
|
|
128
|
+
return {
|
|
129
|
+
createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
|
|
130
|
+
updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow().$onUpdate(() => /* @__PURE__ */ new Date()),
|
|
131
|
+
createdBy: text("created_by"),
|
|
132
|
+
createdByType: text("created_by_type").$type(),
|
|
133
|
+
updatedBy: text("updated_by"),
|
|
134
|
+
updatedByType: text("updated_by_type").$type()
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
function createPluginDeleteFields() {
|
|
138
|
+
return {
|
|
139
|
+
deletedAt: timestamp("deleted_at", { withTimezone: true }),
|
|
140
|
+
deletedBy: text("deleted_by"),
|
|
141
|
+
deletedByType: text("deleted_by_type").$type()
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
function resolvePluginId() {
|
|
145
|
+
const runtime = globalThis;
|
|
146
|
+
const envPluginId = runtime.process?.env?.WR_PLUGIN_ID;
|
|
147
|
+
const buildTimePluginId = typeof __WR_PLUGIN_ID__ === "undefined" ? void 0 : __WR_PLUGIN_ID__;
|
|
148
|
+
const pluginId = buildTimePluginId ?? envPluginId;
|
|
149
|
+
if (!pluginId) {
|
|
150
|
+
throw new Error(
|
|
151
|
+
"pluginTable() requires a plugin id. Configure __WR_PLUGIN_ID__ at build time or set process.env.WR_PLUGIN_ID before loading plugin schema files."
|
|
152
|
+
);
|
|
153
|
+
}
|
|
154
|
+
return pluginId;
|
|
155
|
+
}
|
|
156
|
+
function normalizePluginId(pluginId) {
|
|
157
|
+
return pluginId.replace(/[.\-]/g, "_");
|
|
158
|
+
}
|
|
159
|
+
function buildPluginTableName(shortName) {
|
|
160
|
+
return `plugin_${normalizePluginId(resolvePluginId())}_${shortName}`;
|
|
161
|
+
}
|
|
162
|
+
function createPluginPgTable() {
|
|
163
|
+
return pgTableCreator((shortName) => buildPluginTableName(shortName));
|
|
164
|
+
}
|
|
165
|
+
function isPluginTableOptions(value) {
|
|
166
|
+
return typeof value === "object" && value !== null;
|
|
167
|
+
}
|
|
168
|
+
function resolvePluginTableArgs(thirdArg, fourthArg) {
|
|
169
|
+
if (isPluginTableOptions(thirdArg)) {
|
|
170
|
+
return {
|
|
171
|
+
extraConfig: void 0,
|
|
172
|
+
options: thirdArg
|
|
173
|
+
};
|
|
174
|
+
}
|
|
175
|
+
return {
|
|
176
|
+
extraConfig: thirdArg,
|
|
177
|
+
options: fourthArg
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
function pluginTable(name, columns, thirdArg, fourthArg) {
|
|
181
|
+
const table = createPluginPgTable();
|
|
182
|
+
const { extraConfig, options } = resolvePluginTableArgs(thirdArg, fourthArg);
|
|
183
|
+
let pluginTableResult;
|
|
184
|
+
const lifecycleFields = {
|
|
185
|
+
...createPluginAuditFields(),
|
|
186
|
+
...options?.softDelete === true ? createPluginDeleteFields() : {}
|
|
187
|
+
};
|
|
188
|
+
if (typeof columns === "function") {
|
|
189
|
+
pluginTableResult = table(
|
|
190
|
+
name,
|
|
191
|
+
(columnTypes) => ({
|
|
192
|
+
...lifecycleFields,
|
|
193
|
+
...columns(columnTypes),
|
|
194
|
+
...createPluginPolicyFields()
|
|
195
|
+
}),
|
|
196
|
+
extraConfig
|
|
197
|
+
);
|
|
198
|
+
} else {
|
|
199
|
+
pluginTableResult = table(
|
|
200
|
+
name,
|
|
201
|
+
{
|
|
202
|
+
...lifecycleFields,
|
|
203
|
+
...columns,
|
|
204
|
+
...createPluginPolicyFields()
|
|
205
|
+
},
|
|
206
|
+
extraConfig
|
|
207
|
+
);
|
|
208
|
+
}
|
|
209
|
+
const softDeleteEnabled = options?.softDelete === true;
|
|
210
|
+
if (options?.acl?.defaultPolicy) {
|
|
211
|
+
setDeveloperAclPolicy(getTableName(pluginTableResult), options.acl.defaultPolicy);
|
|
212
|
+
}
|
|
213
|
+
setTableSoftDeleteCapability(pluginTableResult, softDeleteEnabled);
|
|
214
|
+
return pluginTableResult;
|
|
215
|
+
}
|
|
216
|
+
var MANAGED_FIELD_OMIT = {
|
|
217
|
+
organizationId: true,
|
|
218
|
+
aclTags: true,
|
|
219
|
+
denyTags: true,
|
|
220
|
+
createdAt: true,
|
|
221
|
+
updatedAt: true,
|
|
222
|
+
createdBy: true,
|
|
223
|
+
createdByType: true,
|
|
224
|
+
updatedBy: true,
|
|
225
|
+
updatedByType: true,
|
|
226
|
+
deletedAt: true,
|
|
227
|
+
deletedBy: true,
|
|
228
|
+
deletedByType: true
|
|
229
|
+
};
|
|
230
|
+
function omitManagedFields(schema) {
|
|
231
|
+
const omitExistingManagedFields = Object.fromEntries(
|
|
232
|
+
Object.keys(MANAGED_FIELD_OMIT).filter((key) => key in schema.shape).map((key) => [key, true])
|
|
233
|
+
);
|
|
234
|
+
return schema.omit(omitExistingManagedFields);
|
|
235
|
+
}
|
|
236
|
+
function createPluginInsertSchema(...args) {
|
|
237
|
+
const schema = _drizzleCreateInsertSchema(...args);
|
|
238
|
+
return omitManagedFields(schema);
|
|
239
|
+
}
|
|
240
|
+
function createPluginSelectSchema(...args) {
|
|
241
|
+
const createSelect = _drizzleCreateSelectSchema;
|
|
242
|
+
const schema = createSelect(...args);
|
|
243
|
+
return omitManagedFields(schema);
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
export {
|
|
247
|
+
setAclPolicyOverride,
|
|
248
|
+
removeAclPolicyOverride,
|
|
249
|
+
loadAclPolicyOverrides,
|
|
250
|
+
clearAclPolicyOverrides,
|
|
251
|
+
getEffectiveAclPolicy,
|
|
252
|
+
resolveAclTags,
|
|
253
|
+
getRegisteredAclPolicies,
|
|
254
|
+
ACL_POLICY_SETTINGS_PREFIX,
|
|
255
|
+
setTableSoftDeleteCapability,
|
|
256
|
+
getTableSoftDeleteCapability,
|
|
257
|
+
PLUGIN_AUDIT_ACTOR_TYPES,
|
|
258
|
+
normalizePluginId,
|
|
259
|
+
buildPluginTableName,
|
|
260
|
+
pluginTable,
|
|
261
|
+
createPluginInsertSchema,
|
|
262
|
+
createPluginSelectSchema
|
|
263
|
+
};
|
|
264
|
+
//# sourceMappingURL=chunk-DCJM6GN5.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/plugin.ts","../src/acl-policy.ts","../src/delete-policy.ts"],"sourcesContent":["import { type InferInsertModel, type InferSelectModel, type Table, getTableName } from \"drizzle-orm\";\nimport {\n type AnyPgColumnBuilder,\n type PgBuildColumns,\n type PgBuildExtraConfigColumns,\n type PgTableExtraConfig,\n type PgTableExtraConfigValue,\n type PgTableWithColumns,\n pgTableCreator,\n text,\n timestamp,\n} from \"drizzle-orm/pg-core\";\nimport type { PgColumnsBuilders } from \"drizzle-orm/pg-core/columns/all\";\nimport {\n type BuildRefine,\n type BuildSchema,\n type NoUnknownKeys,\n createInsertSchema as _drizzleCreateInsertSchema,\n createSelectSchema as _drizzleCreateSelectSchema,\n} from \"drizzle-orm/zod\";\nimport type { z } from \"zod/v4\";\nimport { type DefaultAclPolicy, setDeveloperAclPolicy } from \"./acl-policy\";\nimport { setTableSoftDeleteCapability } from \"./delete-policy\";\n\nexport type { DefaultAclPolicy };\nexport { TagPrefix, type TagPrefixType } from \"./schema/permission-fields\";\n\nexport const PLUGIN_AUDIT_ACTOR_TYPES = [\"user\", \"system\", \"plugin\", \"api-token\"] as const;\nexport type PluginAuditActorType = (typeof PLUGIN_AUDIT_ACTOR_TYPES)[number];\n\ndeclare const __WR_PLUGIN_ID__: string | undefined;\n\ntype PluginProcess = typeof globalThis & {\n process?: {\n env?: Record<string, string | undefined> & {\n WR_PLUGIN_ID?: string;\n };\n };\n};\n\nfunction createPluginPolicyFields() {\n return {\n organizationId: text(\"organization_id\").notNull(),\n aclTags: text(\"acl_tags\").array().notNull().default([]),\n denyTags: text(\"deny_tags\").array().notNull().default([]),\n };\n}\n\nfunction createPluginAuditFields() {\n return {\n createdAt: timestamp(\"created_at\", { withTimezone: true }).notNull().defaultNow(),\n updatedAt: timestamp(\"updated_at\", { withTimezone: true })\n .notNull()\n .defaultNow()\n .$onUpdate(() => new Date()),\n createdBy: text(\"created_by\"),\n createdByType: text(\"created_by_type\").$type<PluginAuditActorType>(),\n updatedBy: text(\"updated_by\"),\n updatedByType: text(\"updated_by_type\").$type<PluginAuditActorType>(),\n };\n}\n\nfunction createPluginDeleteFields() {\n return {\n deletedAt: timestamp(\"deleted_at\", { withTimezone: true }),\n deletedBy: text(\"deleted_by\"),\n deletedByType: text(\"deleted_by_type\").$type<PluginAuditActorType>(),\n };\n}\n\ntype PluginPolicyFieldBuilders = ReturnType<typeof createPluginPolicyFields>;\ntype PluginAuditFieldBuilders = ReturnType<typeof createPluginAuditFields>;\ntype PluginDeleteFieldBuilders = ReturnType<typeof createPluginDeleteFields>;\ntype NoPluginDeleteFields = Record<never, never>;\ntype PluginColumnMap<\n TColumnsMap extends Record<string, AnyPgColumnBuilder>,\n TSoftDelete extends boolean = false,\n> = Omit<PluginAuditFieldBuilders, keyof TColumnsMap> &\n (TSoftDelete extends true ? Omit<PluginDeleteFieldBuilders, keyof TColumnsMap> : NoPluginDeleteFields) &\n Omit<TColumnsMap, keyof PluginPolicyFieldBuilders> &\n PluginPolicyFieldBuilders;\ntype PluginTableResult<\n TTableName extends string,\n TColumnsMap extends Record<string, AnyPgColumnBuilder>,\n TSoftDelete extends boolean = false,\n> = PgTableWithColumns<{\n name: TTableName;\n schema: undefined;\n columns: PgBuildColumns<TTableName, PluginColumnMap<TColumnsMap, TSoftDelete>>;\n dialect: \"pg\";\n}>;\ntype PluginExtraConfig<TColumnsMap extends Record<string, AnyPgColumnBuilder>, TSoftDelete extends boolean = false> = (\n self: PgBuildExtraConfigColumns<PluginColumnMap<TColumnsMap, TSoftDelete>>,\n) => PgTableExtraConfig | PgTableExtraConfigValue[];\n\nexport interface PluginTableOptions {\n acl?: {\n defaultPolicy: DefaultAclPolicy;\n };\n softDelete?: boolean;\n}\n\nfunction resolvePluginId(): string {\n const runtime = globalThis as PluginProcess;\n const envPluginId = runtime.process?.env?.WR_PLUGIN_ID;\n const buildTimePluginId = typeof __WR_PLUGIN_ID__ === \"undefined\" ? undefined : __WR_PLUGIN_ID__;\n const pluginId = buildTimePluginId ?? envPluginId;\n\n if (!pluginId) {\n throw new Error(\n \"pluginTable() requires a plugin id. Configure __WR_PLUGIN_ID__ at build time \" +\n \"or set process.env.WR_PLUGIN_ID before loading plugin schema files.\",\n );\n }\n\n return pluginId;\n}\n\nexport function normalizePluginId(pluginId: string): string {\n return pluginId.replace(/[.\\-]/g, \"_\");\n}\n\nexport function buildPluginTableName(shortName: string): string {\n return `plugin_${normalizePluginId(resolvePluginId())}_${shortName}`;\n}\n\nfunction createPluginPgTable() {\n return pgTableCreator((shortName) => buildPluginTableName(shortName));\n}\n\nfunction isPluginTableOptions<TColumnsMap extends Record<string, AnyPgColumnBuilder>>(\n value: PluginExtraConfig<TColumnsMap> | PluginTableOptions | undefined,\n): value is PluginTableOptions {\n return typeof value === \"object\" && value !== null;\n}\n\nfunction resolvePluginTableArgs<TColumnsMap extends Record<string, AnyPgColumnBuilder>>(\n thirdArg?: PluginExtraConfig<TColumnsMap> | PluginTableOptions,\n fourthArg?: PluginTableOptions,\n): {\n extraConfig: PluginExtraConfig<TColumnsMap> | undefined;\n options: PluginTableOptions | undefined;\n} {\n if (isPluginTableOptions(thirdArg)) {\n return {\n extraConfig: undefined,\n options: thirdArg,\n };\n }\n\n return {\n extraConfig: thirdArg,\n options: fourthArg,\n };\n}\n\nexport function pluginTable<TTableName extends string, TColumnsMap extends Record<string, AnyPgColumnBuilder>>(\n name: TTableName,\n columns: TColumnsMap,\n options: PluginTableOptions & { softDelete: true },\n): PluginTableResult<TTableName, TColumnsMap, true>;\nexport function pluginTable<TTableName extends string, TColumnsMap extends Record<string, AnyPgColumnBuilder>>(\n name: TTableName,\n columns: TColumnsMap,\n extraConfig?: PluginExtraConfig<TColumnsMap>,\n): PluginTableResult<TTableName, TColumnsMap>;\nexport function pluginTable<TTableName extends string, TColumnsMap extends Record<string, AnyPgColumnBuilder>>(\n name: TTableName,\n columns: TColumnsMap,\n options?: PluginTableOptions,\n): PluginTableResult<TTableName, TColumnsMap>;\nexport function pluginTable<TTableName extends string, TColumnsMap extends Record<string, AnyPgColumnBuilder>>(\n name: TTableName,\n columns: TColumnsMap,\n extraConfig: PluginExtraConfig<TColumnsMap, true>,\n options: PluginTableOptions & { softDelete: true },\n): PluginTableResult<TTableName, TColumnsMap, true>;\nexport function pluginTable<TTableName extends string, TColumnsMap extends Record<string, AnyPgColumnBuilder>>(\n name: TTableName,\n columns: TColumnsMap,\n extraConfig: PluginExtraConfig<TColumnsMap>,\n options?: PluginTableOptions,\n): PluginTableResult<TTableName, TColumnsMap>;\nexport function pluginTable<TTableName extends string, TColumnsMap extends Record<string, AnyPgColumnBuilder>>(\n name: TTableName,\n columns: (columnTypes: PgColumnsBuilders) => TColumnsMap,\n options: PluginTableOptions & { softDelete: true },\n): PluginTableResult<TTableName, TColumnsMap, true>;\nexport function pluginTable<TTableName extends string, TColumnsMap extends Record<string, AnyPgColumnBuilder>>(\n name: TTableName,\n columns: (columnTypes: PgColumnsBuilders) => TColumnsMap,\n extraConfig?: PluginExtraConfig<TColumnsMap>,\n): PluginTableResult<TTableName, TColumnsMap>;\nexport function pluginTable<TTableName extends string, TColumnsMap extends Record<string, AnyPgColumnBuilder>>(\n name: TTableName,\n columns: (columnTypes: PgColumnsBuilders) => TColumnsMap,\n options?: PluginTableOptions,\n): PluginTableResult<TTableName, TColumnsMap>;\nexport function pluginTable<TTableName extends string, TColumnsMap extends Record<string, AnyPgColumnBuilder>>(\n name: TTableName,\n columns: (columnTypes: PgColumnsBuilders) => TColumnsMap,\n extraConfig: PluginExtraConfig<TColumnsMap, true>,\n options: PluginTableOptions & { softDelete: true },\n): PluginTableResult<TTableName, TColumnsMap, true>;\nexport function pluginTable<TTableName extends string, TColumnsMap extends Record<string, AnyPgColumnBuilder>>(\n name: TTableName,\n columns: (columnTypes: PgColumnsBuilders) => TColumnsMap,\n extraConfig: PluginExtraConfig<TColumnsMap>,\n options?: PluginTableOptions,\n): PluginTableResult<TTableName, TColumnsMap>;\nexport function pluginTable<TTableName extends string, TColumnsMap extends Record<string, AnyPgColumnBuilder>>(\n name: TTableName,\n columns: TColumnsMap | ((columnTypes: PgColumnsBuilders) => TColumnsMap),\n thirdArg?: PluginExtraConfig<TColumnsMap> | PluginTableOptions,\n fourthArg?: PluginTableOptions,\n): PluginTableResult<TTableName, TColumnsMap> {\n const table = createPluginPgTable();\n const { extraConfig, options } = resolvePluginTableArgs(thirdArg, fourthArg);\n let pluginTableResult: PluginTableResult<TTableName, TColumnsMap>;\n const lifecycleFields = {\n ...createPluginAuditFields(),\n ...(options?.softDelete === true ? createPluginDeleteFields() : {}),\n };\n\n if (typeof columns === \"function\") {\n pluginTableResult = table(\n name,\n (columnTypes) => ({\n ...lifecycleFields,\n ...columns(columnTypes),\n ...createPluginPolicyFields(),\n }),\n extraConfig as never,\n ) as unknown as PluginTableResult<TTableName, TColumnsMap>;\n } else {\n pluginTableResult = table(\n name,\n {\n ...lifecycleFields,\n ...columns,\n ...createPluginPolicyFields(),\n },\n extraConfig as never,\n ) as unknown as PluginTableResult<TTableName, TColumnsMap>;\n }\n\n const softDeleteEnabled = options?.softDelete === true;\n\n if (options?.acl?.defaultPolicy) {\n setDeveloperAclPolicy(getTableName(pluginTableResult), options.acl.defaultPolicy);\n }\n setTableSoftDeleteCapability(pluginTableResult, softDeleteEnabled);\n\n return pluginTableResult;\n}\n\n// ============================================================\n// Plugin Zod Schema Helpers\n// ============================================================\n\n/**\n * Platform-managed fields automatically injected by `pluginTable()`.\n * These are managed by ScopedDb at runtime and must never appear in API inputs.\n */\nconst MANAGED_FIELD_OMIT = {\n organizationId: true,\n aclTags: true,\n denyTags: true,\n createdAt: true,\n updatedAt: true,\n createdBy: true,\n createdByType: true,\n updatedBy: true,\n updatedByType: true,\n deletedAt: true,\n deletedBy: true,\n deletedByType: true,\n} as const;\ntype ManagedFieldKey = keyof typeof MANAGED_FIELD_OMIT;\ntype OmitManagedFields<TSchema> = TSchema extends z.ZodObject<infer TShape, infer TConfig>\n ? z.ZodObject<Omit<TShape, ManagedFieldKey>, TConfig>\n : TSchema;\n\nfunction omitManagedFields<TSchema extends z.ZodObject>(schema: TSchema): OmitManagedFields<TSchema> {\n const omitExistingManagedFields = Object.fromEntries(\n Object.keys(MANAGED_FIELD_OMIT)\n .filter((key) => key in schema.shape)\n .map((key) => [key, true as const]),\n );\n\n return schema.omit(omitExistingManagedFields as Parameters<typeof schema.omit>[0]) as OmitManagedFields<TSchema>;\n}\n\n/**\n * Create a Zod insert schema for a plugin table, automatically omitting\n * platform-managed fields such as tenant policy and audit columns.\n *\n * Drop-in replacement for `createInsertSchema()` from `drizzle-orm/zod`.\n * Plugin developers should use this instead to avoid leaking infra concerns.\n *\n * @example\n * ```ts\n * import { pluginTable, createPluginInsertSchema } from '@wordrhyme/db/plugin';\n *\n * export const myTable = pluginTable('items', { ... });\n * export const insertItemSchema = createPluginInsertSchema(myTable);\n * ```\n */\nexport function createPluginInsertSchema<TTable extends Table>(\n table: TTable,\n): OmitManagedFields<BuildSchema<\"insert\", TTable[\"_\"][\"columns\"], undefined, undefined>>;\nexport function createPluginInsertSchema<\n TTable extends Table,\n TRefine extends BuildRefine<Pick<TTable[\"_\"][\"columns\"], keyof InferInsertModel<TTable>>, undefined>,\n>(\n table: TTable,\n refine?: NoUnknownKeys<TRefine, InferInsertModel<TTable>>,\n): OmitManagedFields<BuildSchema<\"insert\", TTable[\"_\"][\"columns\"], TRefine, undefined>>;\nexport function createPluginInsertSchema(...args: Parameters<typeof _drizzleCreateInsertSchema>) {\n const schema = _drizzleCreateInsertSchema(...args);\n return omitManagedFields(schema);\n}\n\n/**\n * Create a Zod select schema for public plugin API contracts. Host-managed\n * policy, audit, and deletion fields stay internal to ScopedDb and the Host.\n */\nexport function createPluginSelectSchema<TTable extends Table>(\n table: TTable,\n): OmitManagedFields<BuildSchema<\"select\", TTable[\"_\"][\"columns\"], undefined, undefined>>;\nexport function createPluginSelectSchema<\n TTable extends Table,\n TRefine extends BuildRefine<TTable[\"_\"][\"columns\"], undefined>,\n>(\n table: TTable,\n refine?: NoUnknownKeys<TRefine, InferSelectModel<TTable>>,\n): OmitManagedFields<BuildSchema<\"select\", TTable[\"_\"][\"columns\"], TRefine, undefined>>;\nexport function createPluginSelectSchema(...args: unknown[]) {\n const createSelect = _drizzleCreateSelectSchema as unknown as (...params: unknown[]) => z.ZodObject;\n const schema = createSelect(...args);\n return omitManagedFields(schema);\n}\n","/**\n * ACL Policy Registry\n *\n * Allows plugin developers to declare default ACL policies per table via `pluginTable(..., { acl })`.\n * ScopedDb reads from this registry when inserting rows without explicit aclTags.\n *\n * Priority chain (highest → lowest):\n * 1. Admin override (via Settings, cached in-memory per org+table)\n * 2. Developer declaration (via `pluginTable(..., { acl: { defaultPolicy } })`)\n * 3. System fallback (\"creator\")\n *\n * @example\n * ```ts\n * import { pluginTable } from '@wordrhyme/db/plugin';\n *\n * export const shopProducts = pluginTable('products', { ... }, {\n * acl: { defaultPolicy: ['org'] },\n * }); // org-visible by default\n * ```\n */\n\n// ============================================================\n// Types\n// ============================================================\n\n/**\n * Default ACL policy for a table\n *\n * Principals:\n * - 'org': Organization-visible → ['org:{orgId}']\n * - 'creator': Creator-only → ['user:{userId}'] (system default)\n * - 'admin': Org admins → ['role:owner', 'role:admin', 'role:super-admin']\n * - 'public': Public → ['public:all']\n *\n * Policies can be composed as an array, e.g.:\n * - ['org', 'creator']\n * - ['admin', 'creator']\n */\nexport type DefaultAclPolicyPrincipal = \"org\" | \"creator\" | \"admin\" | \"public\";\nexport type DefaultAclPolicy = DefaultAclPolicyPrincipal | readonly DefaultAclPolicyPrincipal[];\n\nconst ADMIN_ROLE_TAGS = [\"role:owner\", \"role:admin\", \"role:super-admin\"] as const;\nconst ACL_POLICY_STATE_KEY = Symbol.for(\"@wordrhyme/db/acl-policy-state\");\n\n// ============================================================\n// Developer Declaration Registry (sync, populated at module load)\n// ============================================================\n\ntype AclPolicyRegistryState = {\n aclPolicyRegistry: Map<string, readonly DefaultAclPolicyPrincipal[]>;\n aclPolicyOverrideCache: Map<string, readonly DefaultAclPolicyPrincipal[]>;\n};\n\ntype AclPolicyGlobal = typeof globalThis & {\n [ACL_POLICY_STATE_KEY]?: AclPolicyRegistryState;\n};\n\nfunction getAclPolicyRegistryState(): AclPolicyRegistryState {\n const runtime = globalThis as AclPolicyGlobal;\n runtime[ACL_POLICY_STATE_KEY] ??= {\n aclPolicyRegistry: new Map<string, readonly DefaultAclPolicyPrincipal[]>(),\n aclPolicyOverrideCache: new Map<string, readonly DefaultAclPolicyPrincipal[]>(),\n };\n return runtime[ACL_POLICY_STATE_KEY];\n}\n\nconst aclPolicyRegistry = getAclPolicyRegistryState().aclPolicyRegistry;\n\nfunction dedupePrincipals(policy: readonly DefaultAclPolicyPrincipal[]): readonly DefaultAclPolicyPrincipal[] {\n return Array.from(new Set(policy));\n}\n\nfunction normalizeDefaultAclPolicy(policy: DefaultAclPolicy): readonly DefaultAclPolicyPrincipal[] {\n if (typeof policy === \"string\") {\n return [policy];\n }\n\n return dedupePrincipals(policy);\n}\n\nexport function setDeveloperAclPolicy(tableName: string, policy: DefaultAclPolicy): void {\n aclPolicyRegistry.set(tableName, normalizeDefaultAclPolicy(policy));\n}\n\n// ============================================================\n// Admin Override Cache (sync lookup, async population)\n// ============================================================\n\nconst aclPolicyOverrideCache = getAclPolicyRegistryState().aclPolicyOverrideCache;\n\nfunction overrideCacheKey(tableName: string, organizationId: string): string {\n return `${tableName}:${organizationId}`;\n}\n\n/**\n * Set an admin override for a table's default ACL policy.\n *\n * Called by the platform's settings service when an admin configures\n * a table-level ACL policy override via the admin UI.\n */\nexport function setAclPolicyOverride(tableName: string, organizationId: string, policy: DefaultAclPolicy): void {\n aclPolicyOverrideCache.set(overrideCacheKey(tableName, organizationId), normalizeDefaultAclPolicy(policy));\n}\n\n/**\n * Remove an admin override.\n */\nexport function removeAclPolicyOverride(tableName: string, organizationId: string): void {\n aclPolicyOverrideCache.delete(overrideCacheKey(tableName, organizationId));\n}\n\n/**\n * Batch-load admin overrides (called on startup or cache refresh).\n *\n * @param overrides - Array of { tableName, organizationId, policy }\n */\nexport function loadAclPolicyOverrides(\n overrides: Array<{ tableName: string; organizationId: string; policy: DefaultAclPolicy }>,\n): void {\n for (const { tableName, organizationId, policy } of overrides) {\n aclPolicyOverrideCache.set(overrideCacheKey(tableName, organizationId), normalizeDefaultAclPolicy(policy));\n }\n}\n\n/**\n * Clear all admin overrides (for testing or full refresh).\n */\nexport function clearAclPolicyOverrides(): void {\n aclPolicyOverrideCache.clear();\n}\n\n// ============================================================\n// Effective Policy Resolution\n// ============================================================\n\n/**\n * Get the effective ACL policy for a table + org combination.\n *\n * Priority: admin override > developer declaration > system default ('creator')\n *\n * This is a **sync** function — safe to call from wrapInsert's values() builder.\n */\nexport function getEffectiveAclPolicy(tableName: string, organizationId?: string): readonly DefaultAclPolicyPrincipal[] {\n // 1. Admin override (org-specific)\n if (organizationId) {\n const override = aclPolicyOverrideCache.get(overrideCacheKey(tableName, organizationId));\n if (override) return override;\n }\n\n // 2. Developer declaration\n const devPolicy = aclPolicyRegistry.get(tableName);\n if (devPolicy) return devPolicy;\n\n // 3. System default\n return [\"creator\"];\n}\n\n/**\n * Resolve a policy to concrete aclTags.\n */\nexport function resolveAclTags(\n policy: DefaultAclPolicy,\n ctx: { userId: string | undefined; organizationId: string | undefined },\n): string[] {\n const principals = normalizeDefaultAclPolicy(policy);\n const tags: string[] = [];\n\n for (const principal of principals) {\n switch (principal) {\n case \"org\":\n if (ctx.organizationId) tags.push(`org:${ctx.organizationId}`);\n break;\n case \"creator\":\n if (ctx.userId) tags.push(`user:${ctx.userId}`);\n break;\n case \"admin\":\n tags.push(...ADMIN_ROLE_TAGS);\n break;\n case \"public\":\n tags.push(\"public:all\");\n break;\n }\n }\n\n return Array.from(new Set(tags));\n}\n\n// ============================================================\n// Debug / Admin UI helpers\n// ============================================================\n\n/**\n * Get all registered developer policies (for admin UI / debugging).\n */\nexport function getRegisteredAclPolicies(): Record<string, readonly DefaultAclPolicyPrincipal[]> {\n return Object.fromEntries(aclPolicyRegistry.entries());\n}\n\n/**\n * Settings key pattern for admin overrides.\n * Used by the settings router to store/retrieve overrides.\n */\nexport const ACL_POLICY_SETTINGS_PREFIX = \"lbac.defaultAclPolicy.\";\n","/**\n * Plugin table soft-delete capability metadata.\n *\n * `pluginTable(..., { softDelete: true })` marks the Drizzle table object\n * explicitly. ScopedDb reads this metadata to decide whether ordinary\n * `ctx.db.delete(table).where(...)` should become an UPDATE that writes the\n * delete lifecycle fields.\n */\n\nconst TABLE_SOFT_DELETE_CAPABILITY_KEY = Symbol.for(\"@wordrhyme/db/table-soft-delete-capability\");\nconst TABLE_SOFT_DELETE_CAPABILITY_PROPERTY = \"__wordrhymeTableSoftDeleteCapability\";\n\nexport function setTableSoftDeleteCapability(table: object, enabled: boolean): void {\n Object.defineProperty(table, TABLE_SOFT_DELETE_CAPABILITY_KEY, {\n value: enabled,\n enumerable: false,\n configurable: true,\n });\n Object.defineProperty(table, TABLE_SOFT_DELETE_CAPABILITY_PROPERTY, {\n value: enabled,\n enumerable: false,\n configurable: true,\n });\n}\n\nexport function getTableSoftDeleteCapability(table: unknown): boolean | undefined {\n if (!table || typeof table !== \"object\") {\n return undefined;\n }\n\n const tableRecord = table as Record<PropertyKey, unknown>;\n const symbolValue = tableRecord[TABLE_SOFT_DELETE_CAPABILITY_KEY];\n if (typeof symbolValue === \"boolean\") {\n return symbolValue;\n }\n\n const propertyValue = tableRecord[TABLE_SOFT_DELETE_CAPABILITY_PROPERTY];\n return typeof propertyValue === \"boolean\" ? propertyValue : undefined;\n}\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __export = (target, all) => {
|
|
3
|
+
for (var name in all)
|
|
4
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
5
|
+
};
|
|
6
|
+
|
|
7
|
+
// src/schema/permission-fields.ts
|
|
8
|
+
import { text } from "drizzle-orm/pg-core";
|
|
9
|
+
var scopeFields = {
|
|
10
|
+
/** Resource space ID (used by Space plugin, reserved by Core) */
|
|
11
|
+
spaceId: text("space_id"),
|
|
12
|
+
/** Team ID (used by Team feature) */
|
|
13
|
+
teamId: text("team_id")
|
|
14
|
+
};
|
|
15
|
+
var ownerFields = {
|
|
16
|
+
/** Current owner ID */
|
|
17
|
+
ownerId: text("owner_id"),
|
|
18
|
+
/** Original creator ID (for audit, preserved after ownership transfer) */
|
|
19
|
+
creatorId: text("creator_id")
|
|
20
|
+
};
|
|
21
|
+
var lbacFields = {
|
|
22
|
+
/** Allow list - match any tag to grant access */
|
|
23
|
+
aclTags: text("acl_tags").array().notNull().default([]),
|
|
24
|
+
/** Deny list - match any tag to deny access (higher priority than allow) */
|
|
25
|
+
denyTags: text("deny_tags").array().notNull().default([])
|
|
26
|
+
};
|
|
27
|
+
var permissionFields = {
|
|
28
|
+
...scopeFields,
|
|
29
|
+
...ownerFields,
|
|
30
|
+
...lbacFields
|
|
31
|
+
};
|
|
32
|
+
var createLbacIndexes = (tableName) => `
|
|
33
|
+
CREATE INDEX IF NOT EXISTS idx_${tableName}_acl_tags ON "${tableName}" USING GIN(acl_tags);
|
|
34
|
+
CREATE INDEX IF NOT EXISTS idx_${tableName}_deny_tags ON "${tableName}" USING GIN(deny_tags);
|
|
35
|
+
`;
|
|
36
|
+
var TagPrefix = {
|
|
37
|
+
USER: "user",
|
|
38
|
+
ORG: "org",
|
|
39
|
+
TEAM: "team",
|
|
40
|
+
SPACE: "space",
|
|
41
|
+
ROLE: "role",
|
|
42
|
+
PUBLIC: "public"
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
export {
|
|
46
|
+
__export,
|
|
47
|
+
scopeFields,
|
|
48
|
+
ownerFields,
|
|
49
|
+
lbacFields,
|
|
50
|
+
permissionFields,
|
|
51
|
+
createLbacIndexes,
|
|
52
|
+
TagPrefix
|
|
53
|
+
};
|
|
54
|
+
//# sourceMappingURL=chunk-KWWJRUIK.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/schema/permission-fields.ts"],"sourcesContent":["/**\n * Permission Fields Database Schema\n *\n * Predefined fields for business tables that support LBAC.\n * Core may not use all fields, but plugins can extend them.\n *\n * Usage:\n * ```typescript\n * export const articles = pgTable('articles', {\n * id: text('id').primaryKey(),\n * organizationId: text('organization_id').notNull(),\n * title: text('title').notNull(),\n * ...permissionFields, // Spread permission fields\n * });\n * ```\n */\n\nimport { text } from 'drizzle-orm/pg-core';\n\n// ============================================================\n// Scope Fields\n// ============================================================\n\n/**\n * Scope ownership fields\n * - spaceId: Resource space (used by Space plugin)\n * - teamId: Team ownership\n */\nexport const scopeFields = {\n /** Resource space ID (used by Space plugin, reserved by Core) */\n spaceId: text('space_id'),\n\n /** Team ID (used by Team feature) */\n teamId: text('team_id'),\n};\n\n// ============================================================\n// Owner Fields\n// ============================================================\n\n/**\n * Person ownership fields\n * - ownerId: Current owner (transferable)\n * - creatorId: Original creator (immutable, for audit)\n */\nexport const ownerFields = {\n /** Current owner ID */\n ownerId: text('owner_id'),\n\n /** Original creator ID (for audit, preserved after ownership transfer) */\n creatorId: text('creator_id'),\n};\n\n// ============================================================\n// LBAC Fields\n// ============================================================\n\n/**\n * LBAC fields\n * - aclTags: List of tags that allow access\n * - denyTags: List of tags that deny access (higher priority than aclTags)\n *\n * Tag format: '{prefix}:{id}'\n * Examples: 'user:123', 'org:456', 'team:tech', 'space:marketing'\n */\nexport const lbacFields = {\n /** Allow list - match any tag to grant access */\n aclTags: text('acl_tags').array().notNull().default([]),\n\n /** Deny list - match any tag to deny access (higher priority than allow) */\n denyTags: text('deny_tags').array().notNull().default([]),\n};\n\n// ============================================================\n// Combined Permission Fields\n// ============================================================\n\n/**\n * Complete permission fields (recommended for business tables)\n *\n * Includes:\n * - spaceId, teamId (scope ownership)\n * - ownerId, creatorId (person ownership)\n * - aclTags, denyTags (LBAC)\n */\nexport const permissionFields = {\n ...scopeFields,\n ...ownerFields,\n ...lbacFields,\n};\n\n// ============================================================\n// Utilities\n// ============================================================\n\n/**\n * LBAC index SQL generator\n *\n * Creates GIN indexes for aclTags and denyTags to accelerate queries\n *\n * @param tableName - Table name\n * @returns SQL statement\n */\nexport const createLbacIndexes = (tableName: string) => `\nCREATE INDEX IF NOT EXISTS idx_${tableName}_acl_tags ON \"${tableName}\" USING GIN(acl_tags);\nCREATE INDEX IF NOT EXISTS idx_${tableName}_deny_tags ON \"${tableName}\" USING GIN(deny_tags);\n`;\n\n/**\n * Tag prefix constants\n */\nexport const TagPrefix = {\n USER: 'user',\n ORG: 'org',\n TEAM: 'team',\n SPACE: 'space',\n ROLE: 'role',\n PUBLIC: 'public',\n} as const;\n\nexport type TagPrefixType = (typeof TagPrefix)[keyof typeof TagPrefix];\n"],"mappings":";;;;;;;AAiBA,SAAS,YAAY;AAWd,IAAM,cAAc;AAAA;AAAA,EAEzB,SAAS,KAAK,UAAU;AAAA;AAAA,EAGxB,QAAQ,KAAK,SAAS;AACxB;AAWO,IAAM,cAAc;AAAA;AAAA,EAEzB,SAAS,KAAK,UAAU;AAAA;AAAA,EAGxB,WAAW,KAAK,YAAY;AAC9B;AAcO,IAAM,aAAa;AAAA;AAAA,EAExB,SAAS,KAAK,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC;AAAA;AAAA,EAGtD,UAAU,KAAK,WAAW,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC;AAC1D;AAcO,IAAM,mBAAmB;AAAA,EAC9B,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AACL;AAcO,IAAM,oBAAoB,CAAC,cAAsB;AAAA,iCACvB,SAAS,iBAAiB,SAAS;AAAA,iCACnC,SAAS,kBAAkB,SAAS;AAAA;AAM9D,IAAM,YAAY;AAAA,EACvB,MAAM;AAAA,EACN,KAAK;AAAA,EACL,MAAM;AAAA,EACN,OAAO;AAAA,EACP,MAAM;AAAA,EACN,QAAQ;AACV;","names":[]}
|
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
import {
|
|
2
|
+
schema_exports
|
|
3
|
+
} from "./chunk-3TTVLSF5.js";
|
|
4
|
+
|
|
5
|
+
// src/relations/index.ts
|
|
6
|
+
import { defineRelations } from "drizzle-orm";
|
|
7
|
+
var relations = defineRelations(schema_exports, (r) => ({
|
|
8
|
+
// ============================================
|
|
9
|
+
// Auth & User Relations
|
|
10
|
+
// ============================================
|
|
11
|
+
account: {
|
|
12
|
+
user: r.one.user({
|
|
13
|
+
from: r.account.userId,
|
|
14
|
+
to: r.user.id
|
|
15
|
+
})
|
|
16
|
+
},
|
|
17
|
+
user: {
|
|
18
|
+
accounts: r.many.account(),
|
|
19
|
+
organizationsViaInvitation: r.many.organization({
|
|
20
|
+
from: r.user.id.through(r.invitation.inviterId),
|
|
21
|
+
to: r.organization.id.through(r.invitation.organizationId),
|
|
22
|
+
alias: "user_id_organization_id_via_invitation"
|
|
23
|
+
}),
|
|
24
|
+
organizationsViaMember: r.many.organization({
|
|
25
|
+
alias: "organization_id_user_id_via_member"
|
|
26
|
+
}),
|
|
27
|
+
sessions: r.many.session(),
|
|
28
|
+
teams: r.many.team()
|
|
29
|
+
},
|
|
30
|
+
session: {
|
|
31
|
+
user: r.one.user({
|
|
32
|
+
from: r.session.userId,
|
|
33
|
+
to: r.user.id
|
|
34
|
+
})
|
|
35
|
+
},
|
|
36
|
+
// ============================================
|
|
37
|
+
// Organization Relations
|
|
38
|
+
// ============================================
|
|
39
|
+
organization: {
|
|
40
|
+
entityOwnerships: r.many.entityOwnerships(),
|
|
41
|
+
i18nLanguages: r.many.i18nLanguages(),
|
|
42
|
+
i18nMessages: r.many.i18nMessages(),
|
|
43
|
+
usersViaInvitation: r.many.user({
|
|
44
|
+
alias: "user_id_organization_id_via_invitation"
|
|
45
|
+
}),
|
|
46
|
+
usersViaMember: r.many.user({
|
|
47
|
+
from: r.organization.id.through(r.member.organizationId),
|
|
48
|
+
to: r.user.id.through(r.member.userId),
|
|
49
|
+
alias: "organization_id_user_id_via_member"
|
|
50
|
+
}),
|
|
51
|
+
relationships: r.many.relationship(),
|
|
52
|
+
roles: r.many.roles(),
|
|
53
|
+
teams: r.many.team()
|
|
54
|
+
},
|
|
55
|
+
// ============================================
|
|
56
|
+
// Team Relations
|
|
57
|
+
// ============================================
|
|
58
|
+
team: {
|
|
59
|
+
organization: r.one.organization({
|
|
60
|
+
from: r.team.organizationId,
|
|
61
|
+
to: r.organization.id
|
|
62
|
+
}),
|
|
63
|
+
users: r.many.user({
|
|
64
|
+
from: r.team.id.through(r.teamMember.teamId),
|
|
65
|
+
to: r.user.id.through(r.teamMember.userId)
|
|
66
|
+
})
|
|
67
|
+
},
|
|
68
|
+
// ============================================
|
|
69
|
+
// RBAC Relations
|
|
70
|
+
// ============================================
|
|
71
|
+
roles: {
|
|
72
|
+
organization: r.one.organization({
|
|
73
|
+
from: r.roles.organizationId,
|
|
74
|
+
to: r.organization.id
|
|
75
|
+
}),
|
|
76
|
+
rolePermissions: r.many.rolePermissions()
|
|
77
|
+
},
|
|
78
|
+
rolePermissions: {
|
|
79
|
+
role: r.one.roles({
|
|
80
|
+
from: r.rolePermissions.roleId,
|
|
81
|
+
to: r.roles.id
|
|
82
|
+
})
|
|
83
|
+
},
|
|
84
|
+
menus: {},
|
|
85
|
+
// ============================================
|
|
86
|
+
// Entity Ownership Relations
|
|
87
|
+
// ============================================
|
|
88
|
+
entityOwnerships: {
|
|
89
|
+
organization: r.one.organization({
|
|
90
|
+
from: r.entityOwnerships.organizationId,
|
|
91
|
+
to: r.organization.id
|
|
92
|
+
})
|
|
93
|
+
},
|
|
94
|
+
relationship: {
|
|
95
|
+
organization: r.one.organization({
|
|
96
|
+
from: r.relationship.organizationId,
|
|
97
|
+
to: r.organization.id
|
|
98
|
+
})
|
|
99
|
+
},
|
|
100
|
+
// ============================================
|
|
101
|
+
// Media Relations (unified replacement)
|
|
102
|
+
// ============================================
|
|
103
|
+
media: {
|
|
104
|
+
parent: r.one.media({
|
|
105
|
+
from: r.media.parentId,
|
|
106
|
+
to: r.media.id,
|
|
107
|
+
alias: "media_parent"
|
|
108
|
+
}),
|
|
109
|
+
variants: r.many.media({
|
|
110
|
+
alias: "media_parent"
|
|
111
|
+
})
|
|
112
|
+
},
|
|
113
|
+
// ============================================
|
|
114
|
+
// i18n Relations
|
|
115
|
+
// ============================================
|
|
116
|
+
i18nLanguages: {
|
|
117
|
+
organization: r.one.organization({
|
|
118
|
+
from: r.i18nLanguages.organizationId,
|
|
119
|
+
to: r.organization.id
|
|
120
|
+
})
|
|
121
|
+
},
|
|
122
|
+
i18nMessages: {
|
|
123
|
+
organization: r.one.organization({
|
|
124
|
+
from: r.i18nMessages.organizationId,
|
|
125
|
+
to: r.organization.id
|
|
126
|
+
})
|
|
127
|
+
},
|
|
128
|
+
// ============================================
|
|
129
|
+
// Feature Flag Relations
|
|
130
|
+
// ============================================
|
|
131
|
+
featureFlagOverrides: {
|
|
132
|
+
featureFlag: r.one.featureFlags({
|
|
133
|
+
from: r.featureFlagOverrides.flagId,
|
|
134
|
+
to: r.featureFlags.id
|
|
135
|
+
})
|
|
136
|
+
},
|
|
137
|
+
featureFlags: {
|
|
138
|
+
featureFlagOverrides: r.many.featureFlagOverrides()
|
|
139
|
+
},
|
|
140
|
+
// ============================================
|
|
141
|
+
// Billing Relations
|
|
142
|
+
// ============================================
|
|
143
|
+
planItems: {
|
|
144
|
+
plan: r.one.plans({
|
|
145
|
+
from: r.planItems.planId,
|
|
146
|
+
to: r.plans.id
|
|
147
|
+
})
|
|
148
|
+
},
|
|
149
|
+
plans: {
|
|
150
|
+
planItems: r.many.planItems(),
|
|
151
|
+
planSubscriptionsPlanId: r.many.planSubscriptions({
|
|
152
|
+
alias: "planSubscriptions_planId_plans_id"
|
|
153
|
+
}),
|
|
154
|
+
planSubscriptionsScheduledPlanId: r.many.planSubscriptions({
|
|
155
|
+
alias: "planSubscriptions_scheduledPlanId_plans_id"
|
|
156
|
+
})
|
|
157
|
+
},
|
|
158
|
+
planSubscriptions: {
|
|
159
|
+
transactionInitialTransactionId: r.one.transactions({
|
|
160
|
+
from: r.planSubscriptions.initialTransactionId,
|
|
161
|
+
to: r.transactions.id,
|
|
162
|
+
alias: "planSubscriptions_initialTransactionId_transactions_id"
|
|
163
|
+
}),
|
|
164
|
+
transactionLatestTransactionId: r.one.transactions({
|
|
165
|
+
from: r.planSubscriptions.latestTransactionId,
|
|
166
|
+
to: r.transactions.id,
|
|
167
|
+
alias: "planSubscriptions_latestTransactionId_transactions_id"
|
|
168
|
+
}),
|
|
169
|
+
planPlanId: r.one.plans({
|
|
170
|
+
from: r.planSubscriptions.planId,
|
|
171
|
+
to: r.plans.id,
|
|
172
|
+
alias: "planSubscriptions_planId_plans_id"
|
|
173
|
+
}),
|
|
174
|
+
planScheduledPlanId: r.one.plans({
|
|
175
|
+
from: r.planSubscriptions.scheduledPlanId,
|
|
176
|
+
to: r.plans.id,
|
|
177
|
+
alias: "planSubscriptions_scheduledPlanId_plans_id"
|
|
178
|
+
})
|
|
179
|
+
},
|
|
180
|
+
transactions: {
|
|
181
|
+
planSubscriptionsInitialTransactionId: r.many.planSubscriptions({
|
|
182
|
+
alias: "planSubscriptions_initialTransactionId_transactions_id"
|
|
183
|
+
}),
|
|
184
|
+
planSubscriptionsLatestTransactionId: r.many.planSubscriptions({
|
|
185
|
+
alias: "planSubscriptions_latestTransactionId_transactions_id"
|
|
186
|
+
})
|
|
187
|
+
},
|
|
188
|
+
// ============================================
|
|
189
|
+
// Webhook Relations
|
|
190
|
+
// ============================================
|
|
191
|
+
webhookDeliveries: {
|
|
192
|
+
webhookEndpoint: r.one.webhookEndpoints({
|
|
193
|
+
from: r.webhookDeliveries.endpointId,
|
|
194
|
+
to: r.webhookEndpoints.id
|
|
195
|
+
})
|
|
196
|
+
},
|
|
197
|
+
webhookEndpoints: {
|
|
198
|
+
webhookDeliveries: r.many.webhookDeliveries(),
|
|
199
|
+
webhookOutboxes: r.many.webhookOutbox()
|
|
200
|
+
},
|
|
201
|
+
webhookOutbox: {
|
|
202
|
+
webhookEndpoint: r.one.webhookEndpoints({
|
|
203
|
+
from: r.webhookOutbox.endpointId,
|
|
204
|
+
to: r.webhookEndpoints.id
|
|
205
|
+
})
|
|
206
|
+
}
|
|
207
|
+
}));
|
|
208
|
+
|
|
209
|
+
export {
|
|
210
|
+
relations
|
|
211
|
+
};
|
|
212
|
+
//# sourceMappingURL=chunk-XAIEVBMU.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/relations/index.ts"],"sourcesContent":["/**\n * Drizzle Relations Definitions\n *\n * Defines relationships between tables for use with Drizzle's relational queries.\n * These relations enable .with() queries and type-safe joins.\n *\n * @example\n * ```typescript\n * import { db } from './db';\n * import { relations } from '@wordrhyme/db/relations';\n *\n * const userWithOrgs = await db.query.user.findFirst({\n * with: { organizationsViaMember: true }\n * });\n * ```\n */\n\nimport { defineRelations } from 'drizzle-orm';\nimport * as schema from '../schema';\n\nexport const relations = defineRelations(schema, (r) => ({\n // ============================================\n // Auth & User Relations\n // ============================================\n account: {\n user: r.one.user({\n from: r.account.userId,\n to: r.user.id,\n }),\n },\n\n user: {\n accounts: r.many.account(),\n organizationsViaInvitation: r.many.organization({\n from: r.user.id.through(r.invitation.inviterId),\n to: r.organization.id.through(r.invitation.organizationId),\n alias: 'user_id_organization_id_via_invitation',\n }),\n organizationsViaMember: r.many.organization({\n alias: 'organization_id_user_id_via_member',\n }),\n sessions: r.many.session(),\n teams: r.many.team(),\n },\n\n session: {\n user: r.one.user({\n from: r.session.userId,\n to: r.user.id,\n }),\n },\n\n // ============================================\n // Organization Relations\n // ============================================\n organization: {\n entityOwnerships: r.many.entityOwnerships(),\n i18nLanguages: r.many.i18nLanguages(),\n i18nMessages: r.many.i18nMessages(),\n usersViaInvitation: r.many.user({\n alias: 'user_id_organization_id_via_invitation',\n }),\n usersViaMember: r.many.user({\n from: r.organization.id.through(r.member.organizationId),\n to: r.user.id.through(r.member.userId),\n alias: 'organization_id_user_id_via_member',\n }),\n relationships: r.many.relationship(),\n roles: r.many.roles(),\n teams: r.many.team(),\n },\n\n // ============================================\n // Team Relations\n // ============================================\n team: {\n organization: r.one.organization({\n from: r.team.organizationId,\n to: r.organization.id,\n }),\n users: r.many.user({\n from: r.team.id.through(r.teamMember.teamId),\n to: r.user.id.through(r.teamMember.userId),\n }),\n },\n\n // ============================================\n // RBAC Relations\n // ============================================\n roles: {\n organization: r.one.organization({\n from: r.roles.organizationId,\n to: r.organization.id,\n }),\n rolePermissions: r.many.rolePermissions(),\n },\n\n rolePermissions: {\n role: r.one.roles({\n from: r.rolePermissions.roleId,\n to: r.roles.id,\n }),\n },\n\n menus: {},\n\n // ============================================\n // Entity Ownership Relations\n // ============================================\n entityOwnerships: {\n organization: r.one.organization({\n from: r.entityOwnerships.organizationId,\n to: r.organization.id,\n }),\n },\n\n relationship: {\n organization: r.one.organization({\n from: r.relationship.organizationId,\n to: r.organization.id,\n }),\n },\n\n // ============================================\n // Media Relations (unified replacement)\n // ============================================\n media: {\n parent: r.one.media({\n from: r.media.parentId,\n to: r.media.id,\n alias: 'media_parent',\n }),\n variants: r.many.media({\n alias: 'media_parent',\n }),\n },\n\n // ============================================\n // i18n Relations\n // ============================================\n i18nLanguages: {\n organization: r.one.organization({\n from: r.i18nLanguages.organizationId,\n to: r.organization.id,\n }),\n },\n\n i18nMessages: {\n organization: r.one.organization({\n from: r.i18nMessages.organizationId,\n to: r.organization.id,\n }),\n },\n\n // ============================================\n // Feature Flag Relations\n // ============================================\n featureFlagOverrides: {\n featureFlag: r.one.featureFlags({\n from: r.featureFlagOverrides.flagId,\n to: r.featureFlags.id,\n }),\n },\n\n featureFlags: {\n featureFlagOverrides: r.many.featureFlagOverrides(),\n },\n\n // ============================================\n // Billing Relations\n // ============================================\n planItems: {\n plan: r.one.plans({\n from: r.planItems.planId,\n to: r.plans.id,\n }),\n },\n\n plans: {\n planItems: r.many.planItems(),\n planSubscriptionsPlanId: r.many.planSubscriptions({\n alias: 'planSubscriptions_planId_plans_id',\n }),\n planSubscriptionsScheduledPlanId: r.many.planSubscriptions({\n alias: 'planSubscriptions_scheduledPlanId_plans_id',\n }),\n },\n\n planSubscriptions: {\n transactionInitialTransactionId: r.one.transactions({\n from: r.planSubscriptions.initialTransactionId,\n to: r.transactions.id,\n alias: 'planSubscriptions_initialTransactionId_transactions_id',\n }),\n transactionLatestTransactionId: r.one.transactions({\n from: r.planSubscriptions.latestTransactionId,\n to: r.transactions.id,\n alias: 'planSubscriptions_latestTransactionId_transactions_id',\n }),\n planPlanId: r.one.plans({\n from: r.planSubscriptions.planId,\n to: r.plans.id,\n alias: 'planSubscriptions_planId_plans_id',\n }),\n planScheduledPlanId: r.one.plans({\n from: r.planSubscriptions.scheduledPlanId,\n to: r.plans.id,\n alias: 'planSubscriptions_scheduledPlanId_plans_id',\n }),\n },\n\n transactions: {\n planSubscriptionsInitialTransactionId: r.many.planSubscriptions({\n alias: 'planSubscriptions_initialTransactionId_transactions_id',\n }),\n planSubscriptionsLatestTransactionId: r.many.planSubscriptions({\n alias: 'planSubscriptions_latestTransactionId_transactions_id',\n }),\n },\n\n // ============================================\n // Webhook Relations\n // ============================================\n webhookDeliveries: {\n webhookEndpoint: r.one.webhookEndpoints({\n from: r.webhookDeliveries.endpointId,\n to: r.webhookEndpoints.id,\n }),\n },\n\n webhookEndpoints: {\n webhookDeliveries: r.many.webhookDeliveries(),\n webhookOutboxes: r.many.webhookOutbox(),\n },\n\n webhookOutbox: {\n webhookEndpoint: r.one.webhookEndpoints({\n from: r.webhookOutbox.endpointId,\n to: r.webhookEndpoints.id,\n }),\n },\n}));\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Plugin table soft-delete capability metadata.
|
|
3
|
+
*
|
|
4
|
+
* `pluginTable(..., { softDelete: true })` marks the Drizzle table object
|
|
5
|
+
* explicitly. ScopedDb reads this metadata to decide whether ordinary
|
|
6
|
+
* `ctx.db.delete(table).where(...)` should become an UPDATE that writes the
|
|
7
|
+
* delete lifecycle fields.
|
|
8
|
+
*/
|
|
9
|
+
export declare function setTableSoftDeleteCapability(table: object, enabled: boolean): void;
|
|
10
|
+
export declare function getTableSoftDeleteCapability(table: unknown): boolean | undefined;
|
|
11
|
+
//# sourceMappingURL=delete-policy.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"delete-policy.d.ts","sourceRoot":"","sources":["../src/delete-policy.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAKH,wBAAgB,4BAA4B,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,IAAI,CAWlF;AAED,wBAAgB,4BAA4B,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,GAAG,SAAS,CAahF"}
|