@everystack/model 0.4.6 → 0.4.7
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/package.json +1 -1
- package/src/index.ts +1 -1
- package/src/module.ts +30 -0
package/package.json
CHANGED
package/src/index.ts
CHANGED
|
@@ -25,7 +25,7 @@ export type { Relation } from './relations';
|
|
|
25
25
|
export { defineModel, defineMaterializedTable } from './model';
|
|
26
26
|
export type { ModelDescriptor, ModelDefinition, ModelHooks, WrittenBy, MaterializedTableMarker, MaterializedTableDefinition } from './model';
|
|
27
27
|
|
|
28
|
-
export { defineModule, moduleModels, moduleExtensions, moduleFunctionSql, moduleSequences, moduleDerived } from './module';
|
|
28
|
+
export { defineModule, moduleModels, moduleExtensions, moduleFunctionSql, moduleSequences, moduleDerived, moduleGovernedRoles } from './module';
|
|
29
29
|
export type { Module, ModuleDefinition } from './module';
|
|
30
30
|
|
|
31
31
|
export {
|
package/src/module.ts
CHANGED
|
@@ -41,6 +41,28 @@ export interface ModuleDefinition {
|
|
|
41
41
|
* deployed by `db:reconcile`, never migrated. Supersedes the `functions` thunk.
|
|
42
42
|
*/
|
|
43
43
|
derived?: DerivedDescriptor[];
|
|
44
|
+
/**
|
|
45
|
+
* Roles this module's authz GOVERNS, beyond the ones its models already name.
|
|
46
|
+
*
|
|
47
|
+
* The reconciler treats declared authz as authoritative over the roles it governs and
|
|
48
|
+
* leaves every other grantee alone. Without that, a live role the model vocabulary
|
|
49
|
+
* cannot express — a migrator, an ETL account, a BI reader that predates everystack —
|
|
50
|
+
* has every privilege REVOKED the first time a plan is applied, because the reconciler
|
|
51
|
+
* unions declared ∪ live grantees and finds no declaration. On the first brownfield
|
|
52
|
+
* schema this was measured against, that was 32 revokes that would have broken the
|
|
53
|
+
* adopter's deploy pipeline mid-deploy.
|
|
54
|
+
*
|
|
55
|
+
* This list only ever WIDENS the governed set: `PUBLIC` and the fixed vocabulary
|
|
56
|
+
* (`anon`, `authenticated`, `admin`) plus every role the models name are always
|
|
57
|
+
* governed, and naming them here changes nothing. You cannot use this to stop the
|
|
58
|
+
* reconciler governing a role your models grant to — that would be a way to hide a
|
|
59
|
+
* grant from the very thing that audits it.
|
|
60
|
+
*
|
|
61
|
+
* An ungoverned grantee is NOT ignored: every plan, check and dry-run enumerates it by
|
|
62
|
+
* name with its exact privileges, and a grantee that is not in the stage's adoption
|
|
63
|
+
* baseline fails the gate. Exempt from reconciliation, never exempt from the report.
|
|
64
|
+
*/
|
|
65
|
+
governedRoles?: string[];
|
|
44
66
|
/**
|
|
45
67
|
* Package-owned SQL emitted after the tables — SECURITY DEFINER functions, triggers, etc.
|
|
46
68
|
* A thunk so it is generated lazily and can take run-specific input (the app's event-trigger
|
|
@@ -60,6 +82,8 @@ export interface Module {
|
|
|
60
82
|
sequences: SequenceDescriptor[];
|
|
61
83
|
/** Derived (compute) objects — reconciled, never migrated. */
|
|
62
84
|
derived: DerivedDescriptor[];
|
|
85
|
+
/** Roles this module's authz governs beyond the ones its models name. Widen-only. */
|
|
86
|
+
governedRoles: string[];
|
|
63
87
|
/** Function-SQL thunks, normalized to an array so composing modules just concatenates. */
|
|
64
88
|
functions: Array<() => string>;
|
|
65
89
|
}
|
|
@@ -95,6 +119,7 @@ export function defineModule(def: ModuleDefinition): Module {
|
|
|
95
119
|
extensions: def.extensions ?? [],
|
|
96
120
|
sequences: def.sequences ?? [],
|
|
97
121
|
derived: def.derived ?? [],
|
|
122
|
+
governedRoles: [...new Set(def.governedRoles ?? [])].sort(),
|
|
98
123
|
functions: def.functions ? [def.functions] : [],
|
|
99
124
|
};
|
|
100
125
|
}
|
|
@@ -124,3 +149,8 @@ export function moduleSequences(modules: Module[]): SequenceDescriptor[] {
|
|
|
124
149
|
export function moduleDerived(modules: Module[]): DerivedDescriptor[] {
|
|
125
150
|
return modules.flatMap((m) => m.derived);
|
|
126
151
|
}
|
|
152
|
+
|
|
153
|
+
/** The union of every module's governed roles — deduped and sorted. Widen-only by construction. */
|
|
154
|
+
export function moduleGovernedRoles(modules: Module[]): string[] {
|
|
155
|
+
return [...new Set(modules.flatMap((m) => m.governedRoles))].sort();
|
|
156
|
+
}
|