@assemora/auth 0.1.0
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/LICENSE +202 -0
- package/README.md +69 -0
- package/dist/actors.d.ts +20 -0
- package/dist/actors.d.ts.map +1 -0
- package/dist/actors.js +37 -0
- package/dist/actors.js.map +1 -0
- package/dist/authorization.d.ts +36 -0
- package/dist/authorization.d.ts.map +1 -0
- package/dist/authorization.js +93 -0
- package/dist/authorization.js.map +1 -0
- package/dist/commands.d.ts +232 -0
- package/dist/commands.d.ts.map +1 -0
- package/dist/commands.js +390 -0
- package/dist/commands.js.map +1 -0
- package/dist/credentials.d.ts +16 -0
- package/dist/credentials.d.ts.map +1 -0
- package/dist/credentials.js +43 -0
- package/dist/credentials.js.map +1 -0
- package/dist/index.d.ts +35 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +35 -0
- package/dist/index.js.map +1 -0
- package/dist/models.d.ts +136 -0
- package/dist/models.d.ts.map +1 -0
- package/dist/models.js +92 -0
- package/dist/models.js.map +1 -0
- package/dist/module.d.ts +39 -0
- package/dist/module.d.ts.map +1 -0
- package/dist/module.js +95 -0
- package/dist/module.js.map +1 -0
- package/dist/ownership.d.ts +67 -0
- package/dist/ownership.d.ts.map +1 -0
- package/dist/ownership.js +51 -0
- package/dist/ownership.js.map +1 -0
- package/dist/permissions.d.ts +40 -0
- package/dist/permissions.d.ts.map +1 -0
- package/dist/permissions.js +86 -0
- package/dist/permissions.js.map +1 -0
- package/dist/policies.d.ts +120 -0
- package/dist/policies.d.ts.map +1 -0
- package/dist/policies.js +92 -0
- package/dist/policies.js.map +1 -0
- package/dist/queries.d.ts +166 -0
- package/dist/queries.d.ts.map +1 -0
- package/dist/queries.js +236 -0
- package/dist/queries.js.map +1 -0
- package/dist/sessions.d.ts +40 -0
- package/dist/sessions.d.ts.map +1 -0
- package/dist/sessions.js +39 -0
- package/dist/sessions.js.map +1 -0
- package/dist/tokens.d.ts +40 -0
- package/dist/tokens.d.ts.map +1 -0
- package/dist/tokens.js +60 -0
- package/dist/tokens.js.map +1 -0
- package/package.json +42 -0
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The sections whose entry names *are* subjects.
|
|
3
|
+
*
|
|
4
|
+
* A model is registered under its table and a resource under its name, and both of
|
|
5
|
+
* those are what a subject is spelled as — `articles`, `pages`, `media`.
|
|
6
|
+
*/
|
|
7
|
+
const NAMING_SECTIONS = ['resources', 'models', 'singletons'];
|
|
8
|
+
/**
|
|
9
|
+
* The sections whose entry names *contain* a subject.
|
|
10
|
+
*
|
|
11
|
+
* A command or a query is `menu.list`, and the subject the authorizer takes from it is
|
|
12
|
+
* everything before the last dot. These carry the registering module in the descriptor
|
|
13
|
+
* itself, so they are read rather than attributed.
|
|
14
|
+
*/
|
|
15
|
+
const GROUPING_SECTIONS = ['commands', 'queries'];
|
|
16
|
+
/** What `subjectOf` takes as the subject of `menu.list`. Kept identical to it. */
|
|
17
|
+
const groupOf = (name) => name.slice(0, Math.max(name.lastIndexOf('.'), 0));
|
|
18
|
+
/**
|
|
19
|
+
* Whether `module` declared `subject`, and may therefore write a policy for it.
|
|
20
|
+
*
|
|
21
|
+
* @param registry the application's, for the attribution — the module that registered
|
|
22
|
+
* each entry, which is what `forModule` records.
|
|
23
|
+
*/
|
|
24
|
+
export const ownsSubject = (registry, module, subject) => {
|
|
25
|
+
if (subject === module || subject.startsWith(`${module}.`))
|
|
26
|
+
return true;
|
|
27
|
+
if (NAMING_SECTIONS.some((section) => registry.registeredBy(section, subject) === module)) {
|
|
28
|
+
return true;
|
|
29
|
+
}
|
|
30
|
+
return GROUPING_SECTIONS.some((section) => registry
|
|
31
|
+
.section(section)
|
|
32
|
+
.some((entry) => entry.module === module && groupOf(entry.name) === subject));
|
|
33
|
+
};
|
|
34
|
+
/**
|
|
35
|
+
* Why a subject was refused, in the terms the person reading it can act on.
|
|
36
|
+
*
|
|
37
|
+
* It names all three things the refusal is about — who asked, for what, and what would
|
|
38
|
+
* have had to be true — because a configuration error read at boot is read once, by
|
|
39
|
+
* somebody who did not write the module that caused it.
|
|
40
|
+
*/
|
|
41
|
+
export const foreignSubject = (module, subject) => `Module "${module}" registered a policy for "${subject}", which it does not declare. ` +
|
|
42
|
+
`A policy is a grant: it lets a caller through where a permission would have been ` +
|
|
43
|
+
`required, so a module may only write one for a subject of its own. "${module}" would ` +
|
|
44
|
+
`have to name "${subject}" as a model or a resource, declare a command or query in the "${subject}." group, or be named "${subject}" itself. ` +
|
|
45
|
+
`If this policy belongs to the application rather than to a module, pass it as ` +
|
|
46
|
+
`auth({ policies: [...] }) at the composition root, where the application speaks for itself.`;
|
|
47
|
+
/** The same, for a policy that reached the registry through no module at all. */
|
|
48
|
+
export const unattributedSubject = (subject) => `A policy for "${subject}" was registered outside any module, so nothing declares it ` +
|
|
49
|
+
`and nothing answers for it. Register it on the module that owns the subject with ` +
|
|
50
|
+
`.policies(...), or — if it is the application's — pass it as auth({ policies: [...] }).`;
|
|
51
|
+
//# sourceMappingURL=ownership.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ownership.js","sourceRoot":"","sources":["../src/ownership.ts"],"names":[],"mappings":"AAkDA;;;;;GAKG;AACH,MAAM,eAAe,GAAG,CAAC,WAAW,EAAE,QAAQ,EAAE,YAAY,CAAU,CAAA;AAEtE;;;;;;GAMG;AACH,MAAM,iBAAiB,GAAG,CAAC,UAAU,EAAE,SAAS,CAAU,CAAA;AAE1D,kFAAkF;AAClF,MAAM,OAAO,GAAG,CAAC,IAAY,EAAU,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;AAE3F;;;;;GAKG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,QAAwB,EAAE,MAAc,EAAE,OAAe,EAAW,EAAE;IAChG,IAAI,OAAO,KAAK,MAAM,IAAI,OAAO,CAAC,UAAU,CAAC,GAAG,MAAM,GAAG,CAAC;QAAE,OAAO,IAAI,CAAA;IAEvE,IAAI,eAAe,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,QAAQ,CAAC,YAAY,CAAC,OAAO,EAAE,OAAO,CAAC,KAAK,MAAM,CAAC,EAAE,CAAC;QAC1F,OAAO,IAAI,CAAA;IACb,CAAC;IAED,OAAO,iBAAiB,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CACxC,QAAQ;SACL,OAAO,CAAC,OAAO,CAAC;SAChB,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,MAAM,KAAK,MAAM,IAAI,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,OAAO,CAAC,CAC/E,CAAA;AACH,CAAC,CAAA;AAED;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,MAAc,EAAE,OAAe,EAAU,EAAE,CACxE,WAAW,MAAM,8BAA8B,OAAO,gCAAgC;IACtF,mFAAmF;IACnF,uEAAuE,MAAM,UAAU;IACvF,iBAAiB,OAAO,kEAAkE,OAAO,0BAA0B,OAAO,YAAY;IAC9I,gFAAgF;IAChF,6FAA6F,CAAA;AAE/F,iFAAiF;AACjF,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,OAAe,EAAU,EAAE,CAC7D,iBAAiB,OAAO,8DAA8D;IACtF,mFAAmF;IACnF,yFAAyF,CAAA"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What an actor is allowed to do (SPEC.md §50).
|
|
3
|
+
*
|
|
4
|
+
* A user's permissions come from the roles they hold; an API token and an agent
|
|
5
|
+
* carry their own list. All three answer the same question the same way, which is
|
|
6
|
+
* why a policy never has to know which kind of actor it is looking at.
|
|
7
|
+
*
|
|
8
|
+
* All three are also asked a question before that one: whether this is still an
|
|
9
|
+
* actor at all. It is asked *here* rather than where a credential is accepted,
|
|
10
|
+
* because not every path presents a credential. A session is checked when the cookie
|
|
11
|
+
* is read (`sessionActor`) and a bearer token when the header is (`tokenActor`), but
|
|
12
|
+
* a job carries an actor sealed into an envelope and is replayed by a worker hours
|
|
13
|
+
* later with nothing to present — as does anything else that stores an identity and
|
|
14
|
+
* acts on it afterwards. This function is the one narrow place every one of those
|
|
15
|
+
* paths goes through, so this is where liveness has to be decided (ADR-0023).
|
|
16
|
+
*
|
|
17
|
+
* The cost is a row read: resolving a user's permissions is four queries rather than
|
|
18
|
+
* three, and the command pipeline resolves them twice — once for the permission
|
|
19
|
+
* check and once for the policy rule (ADR-0015). It buys the only revocation the
|
|
20
|
+
* framework has, so it is paid on every command. A deactivated actor short-circuits
|
|
21
|
+
* to one query, which is the case where it matters that it is cheap.
|
|
22
|
+
*/
|
|
23
|
+
import type { Actor } from '@assemora/core';
|
|
24
|
+
/** Grants everything. Given to the first administrator, and to nobody casually. */
|
|
25
|
+
export declare const WILDCARD = "*";
|
|
26
|
+
export type PermissionSet = ReadonlySet<string>;
|
|
27
|
+
/** Everything this actor may do, whoever they are. */
|
|
28
|
+
export declare const permissionsOf: (actor: Actor | undefined) => Promise<PermissionSet>;
|
|
29
|
+
/**
|
|
30
|
+
* Whether a permission is held, exactly or by a wildcard above it.
|
|
31
|
+
*
|
|
32
|
+
* `articles.update` is held by `articles.update`, by `articles.*`, and by `*`. The
|
|
33
|
+
* grouped form is what makes a role like "editor" writable at all — `content.*` says
|
|
34
|
+
* something a list of forty names does not — and it matches how the names themselves
|
|
35
|
+
* are built, since a command name *is* a permission name (ADR-0015).
|
|
36
|
+
*
|
|
37
|
+
* Only whole segments match: `articles.*` does not grant `articlesecret.read`.
|
|
38
|
+
*/
|
|
39
|
+
export declare const holds: (permissions: PermissionSet, permission: string) => boolean;
|
|
40
|
+
//# sourceMappingURL=permissions.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"permissions.d.ts","sourceRoot":"","sources":["../src/permissions.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAA;AAK3C,mFAAmF;AACnF,eAAO,MAAM,QAAQ,MAAM,CAAA;AAE3B,MAAM,MAAM,aAAa,GAAG,WAAW,CAAC,MAAM,CAAC,CAAA;AAmE/C,sDAAsD;AACtD,eAAO,MAAM,aAAa,UAAiB,KAAK,GAAG,SAAS,KAAG,OAAO,CAAC,aAAa,CAWnF,CAAA;AAED;;;;;;;;;GASG;AACH,eAAO,MAAM,KAAK,gBAAiB,aAAa,cAAc,MAAM,KAAG,OAUtE,CAAA"}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { Agent, ApiToken, Permission, RolePermission, User, UserRole } from './models.js';
|
|
2
|
+
import { isLive } from './tokens.js';
|
|
3
|
+
/** Grants everything. Given to the first administrator, and to nobody casually. */
|
|
4
|
+
export const WILDCARD = '*';
|
|
5
|
+
const EMPTY = new Set();
|
|
6
|
+
/**
|
|
7
|
+
* Whether the person behind an actor may still act.
|
|
8
|
+
*
|
|
9
|
+
* An absent row is deliberately *not* a revocation. The framework has no user
|
|
10
|
+
* deletion — `active: false` is the whole of how a person is cut off — so an absence
|
|
11
|
+
* is never something this system decided; it is an application whose identities live
|
|
12
|
+
* in an SSO directory and whose roles are assigned here, and denying on absence
|
|
13
|
+
* would make `assemora_user_roles` unusable for it. `active: false` is a statement,
|
|
14
|
+
* and it is the one that binds.
|
|
15
|
+
*/
|
|
16
|
+
const userIsLive = async (userId) => {
|
|
17
|
+
const user = await User.find(userId);
|
|
18
|
+
return user === null || user.active;
|
|
19
|
+
};
|
|
20
|
+
const permissionsOfUser = async (userId) => {
|
|
21
|
+
// Asked first, so a user who may not act costs one read instead of four.
|
|
22
|
+
if (!(await userIsLive(userId)))
|
|
23
|
+
return EMPTY;
|
|
24
|
+
const roles = await UserRole.where('userId', userId);
|
|
25
|
+
if (roles.length === 0)
|
|
26
|
+
return EMPTY;
|
|
27
|
+
const links = await RolePermission.whereIn('roleId', roles.map((role) => role.roleId));
|
|
28
|
+
if (links.length === 0)
|
|
29
|
+
return EMPTY;
|
|
30
|
+
const permissions = await Permission.whereIn('id', links.map((link) => link.permissionId));
|
|
31
|
+
return new Set(permissions.map((permission) => permission.name));
|
|
32
|
+
};
|
|
33
|
+
const permissionsOfAgent = async (agentId) => {
|
|
34
|
+
const agent = await Agent.find(agentId);
|
|
35
|
+
if (agent === null || !agent.enabled)
|
|
36
|
+
return EMPTY;
|
|
37
|
+
return new Set(agent.permissions);
|
|
38
|
+
};
|
|
39
|
+
const permissionsOfApiToken = async (tokenId) => {
|
|
40
|
+
const token = await ApiToken.find(tokenId);
|
|
41
|
+
// `tokenActor` refuses an expired token at the header, but a token id restored
|
|
42
|
+
// from anywhere else — a queue, a stored context — never passes that check, and a
|
|
43
|
+
// token whose expiry has come and gone is not a credential any more.
|
|
44
|
+
if (token === null || !isLive(token.expiresAt))
|
|
45
|
+
return EMPTY;
|
|
46
|
+
// A token issued *for* a person is that person's access under another name.
|
|
47
|
+
// Deactivating them has to take it with it, or the one revocation gesture the
|
|
48
|
+
// framework has quietly leaves a door open (SPEC.md §49).
|
|
49
|
+
if (token.userId !== null && !(await userIsLive(token.userId)))
|
|
50
|
+
return EMPTY;
|
|
51
|
+
return new Set(token.permissions);
|
|
52
|
+
};
|
|
53
|
+
/** Everything this actor may do, whoever they are. */
|
|
54
|
+
export const permissionsOf = async (actor) => {
|
|
55
|
+
if (actor === undefined)
|
|
56
|
+
return EMPTY;
|
|
57
|
+
switch (actor.type) {
|
|
58
|
+
case 'user':
|
|
59
|
+
return permissionsOfUser(actor.id);
|
|
60
|
+
case 'agent':
|
|
61
|
+
return permissionsOfAgent(actor.id);
|
|
62
|
+
case 'api':
|
|
63
|
+
return permissionsOfApiToken(actor.id);
|
|
64
|
+
}
|
|
65
|
+
};
|
|
66
|
+
/**
|
|
67
|
+
* Whether a permission is held, exactly or by a wildcard above it.
|
|
68
|
+
*
|
|
69
|
+
* `articles.update` is held by `articles.update`, by `articles.*`, and by `*`. The
|
|
70
|
+
* grouped form is what makes a role like "editor" writable at all — `content.*` says
|
|
71
|
+
* something a list of forty names does not — and it matches how the names themselves
|
|
72
|
+
* are built, since a command name *is* a permission name (ADR-0015).
|
|
73
|
+
*
|
|
74
|
+
* Only whole segments match: `articles.*` does not grant `articlesecret.read`.
|
|
75
|
+
*/
|
|
76
|
+
export const holds = (permissions, permission) => {
|
|
77
|
+
if (permissions.has(WILDCARD) || permissions.has(permission))
|
|
78
|
+
return true;
|
|
79
|
+
const segments = permission.split('.');
|
|
80
|
+
for (let depth = segments.length - 1; depth > 0; depth -= 1) {
|
|
81
|
+
if (permissions.has(`${segments.slice(0, depth).join('.')}.*`))
|
|
82
|
+
return true;
|
|
83
|
+
}
|
|
84
|
+
return false;
|
|
85
|
+
};
|
|
86
|
+
//# sourceMappingURL=permissions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"permissions.js","sourceRoot":"","sources":["../src/permissions.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Policies (SPEC.md §51).
|
|
3
|
+
*
|
|
4
|
+
* A policy answers one question — may this actor do this to this thing — and the
|
|
5
|
+
* same answer is given to Studio, REST, the SDK, the CLI and MCP, because they all
|
|
6
|
+
* arrive through the same Command Bus and the same Query Bus.
|
|
7
|
+
*/
|
|
8
|
+
import { type Actor, type AssemoraContext } from '@assemora/core';
|
|
9
|
+
export type PolicyActor = Actor | undefined;
|
|
10
|
+
export type PolicyContext<R = unknown> = {
|
|
11
|
+
readonly actor: PolicyActor;
|
|
12
|
+
/** The row being acted on, once it has been read. `undefined` before that. */
|
|
13
|
+
readonly record: R;
|
|
14
|
+
readonly context: AssemoraContext;
|
|
15
|
+
/** Whether the actor holds a named permission (SPEC.md §50). */
|
|
16
|
+
can(permission: string): boolean;
|
|
17
|
+
};
|
|
18
|
+
export type PolicyRule<R = unknown> = (context: PolicyContext<R>) => boolean | Promise<boolean>;
|
|
19
|
+
/**
|
|
20
|
+
* Rules by action. `read`, `create`, `update` and `delete` are the ones the CRUD
|
|
21
|
+
* commands ask about; any other name is asked for by whoever defines it.
|
|
22
|
+
*/
|
|
23
|
+
export type PolicyRules<R = unknown> = Readonly<Record<string, PolicyRule<R>>>;
|
|
24
|
+
export type Policy<R = unknown> = {
|
|
25
|
+
readonly node: 'policy';
|
|
26
|
+
readonly subject: string;
|
|
27
|
+
readonly rules: PolicyRules<R>;
|
|
28
|
+
};
|
|
29
|
+
/**
|
|
30
|
+
* ```ts
|
|
31
|
+
* export const ArticlePolicy = policy('articles', {
|
|
32
|
+
* read: () => true,
|
|
33
|
+
* update: ({ actor, record }) => actor?.id === record.authorId,
|
|
34
|
+
* delete: ({ can }) => can('articles.delete'),
|
|
35
|
+
* })
|
|
36
|
+
* ```
|
|
37
|
+
*
|
|
38
|
+
* SPEC.md §51 spells the record argument after the model — `{ actor, article }`.
|
|
39
|
+
* It is named `record` here because the key would have to be derived from a literal
|
|
40
|
+
* table name that `model()` does not preserve; naming it after the subject would be
|
|
41
|
+
* a runtime-only convenience with no type behind it.
|
|
42
|
+
*/
|
|
43
|
+
export declare const policy: <R = Record<string, unknown>>(subject: string, rules: PolicyRules<R>) => Policy<R>;
|
|
44
|
+
/**
|
|
45
|
+
* What the Schema Registry is told about a policy (SPEC.md §51, ADR-0002).
|
|
46
|
+
*
|
|
47
|
+
* The rules themselves are functions and stay here: a function does not survive
|
|
48
|
+
* `JSON.stringify`, so a descriptor that carried one would arrive at Studio as an empty
|
|
49
|
+
* object and be worse than saying nothing (ADR-0027). What travels is the shape of the
|
|
50
|
+
* thing — which subject, which actions it answers for, and which module put it there.
|
|
51
|
+
*
|
|
52
|
+
* That last field is the reason this section exists at all. `registerPolicy` grants
|
|
53
|
+
* access, and until now it wrote nothing anywhere: an installed package could open
|
|
54
|
+
* `pages.create` to everybody in twelve lines and the application's single source of
|
|
55
|
+
* truth described the rest of the system perfectly while saying nothing about that.
|
|
56
|
+
*/
|
|
57
|
+
export type PolicyDescriptor = {
|
|
58
|
+
/** The subject the policy is about, which is what it is addressed by. */
|
|
59
|
+
readonly name: string;
|
|
60
|
+
/** The actions it answers for, in declaration order. */
|
|
61
|
+
readonly actions: readonly string[];
|
|
62
|
+
/**
|
|
63
|
+
* The module that registered it, when a module did.
|
|
64
|
+
*
|
|
65
|
+
* Absent means `registerPolicy` was called outside module registration — which is
|
|
66
|
+
* legal, and is exactly the case worth being able to see.
|
|
67
|
+
*/
|
|
68
|
+
readonly module?: string;
|
|
69
|
+
};
|
|
70
|
+
declare module '@assemora/core' {
|
|
71
|
+
interface RegistrySections {
|
|
72
|
+
policies: PolicyDescriptor;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
export declare const describePolicy: (definition: Policy<never>, module?: string) => PolicyDescriptor;
|
|
76
|
+
/**
|
|
77
|
+
* What the application's own policies are attributed to.
|
|
78
|
+
*
|
|
79
|
+
* A policy passed as `auth({ policies: [...] })` is written at the composition root by
|
|
80
|
+
* the person who assembled the application, so it speaks for the whole of it and is
|
|
81
|
+
* held to no ownership rule — the application *is* the trust boundary the rule exists
|
|
82
|
+
* to protect. A symbol rather than a name so that no module can be called this, and so
|
|
83
|
+
* that a descriptor never carries it: the section shows such a policy with no `module`,
|
|
84
|
+
* which is what "the application, not a package" has looked like since #5.
|
|
85
|
+
*/
|
|
86
|
+
export declare const APPLICATION: unique symbol;
|
|
87
|
+
export type PolicySource = string | typeof APPLICATION;
|
|
88
|
+
/**
|
|
89
|
+
* Puts a rule in the map, attributed to whoever is registering it.
|
|
90
|
+
*
|
|
91
|
+
* Deliberately *not* exported from this package. The source is what the ownership rule
|
|
92
|
+
* is checked against, so a caller able to supply one is a caller able to claim to be
|
|
93
|
+
* `pages` — and a package outside this file cannot reach this function to try
|
|
94
|
+
* (ADR-0027). The two callers are the module facet, which passes the module the
|
|
95
|
+
* builder is registering, and `auth({ policies })`, which passes `APPLICATION`.
|
|
96
|
+
*/
|
|
97
|
+
export declare const registerModulePolicy: (definition: Policy<never>, module: PolicySource) => void;
|
|
98
|
+
/**
|
|
99
|
+
* Puts a rule in the map, attributed to nobody.
|
|
100
|
+
*
|
|
101
|
+
* Exported, because a test of the authorization port needs a policy in front of it and
|
|
102
|
+
* never boots an application. An application *does* boot, and refuses to start on a
|
|
103
|
+
* policy nothing declares — so this is a harness seam rather than a way in: a package
|
|
104
|
+
* that calls it at import time takes the application down at boot, naming the subject
|
|
105
|
+
* and itself (`ownership.ts`).
|
|
106
|
+
*/
|
|
107
|
+
export declare const registerPolicy: (definition: Policy<never>) => void;
|
|
108
|
+
/**
|
|
109
|
+
* Who registered each policy, including the ones the application registered itself.
|
|
110
|
+
*
|
|
111
|
+
* `describedPolicies` cannot answer this: a descriptor carries a module *name*, and
|
|
112
|
+
* the application is deliberately not one. The check at boot needs the difference.
|
|
113
|
+
*/
|
|
114
|
+
export declare const policySources: () => ReadonlyMap<string, PolicySource>;
|
|
115
|
+
export declare const policyFor: (subject: string) => Policy<never> | undefined;
|
|
116
|
+
export declare const registeredPolicies: () => readonly Policy<never>[];
|
|
117
|
+
/** Every policy as the registry describes it, whoever registered it and however. */
|
|
118
|
+
export declare const describedPolicies: () => readonly PolicyDescriptor[];
|
|
119
|
+
export declare const clearPolicies: () => void;
|
|
120
|
+
//# sourceMappingURL=policies.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"policies.d.ts","sourceRoot":"","sources":["../src/policies.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,EAAE,KAAK,KAAK,EAAE,KAAK,eAAe,EAAiB,MAAM,gBAAgB,CAAA;AAEhF,MAAM,MAAM,WAAW,GAAG,KAAK,GAAG,SAAS,CAAA;AAE3C,MAAM,MAAM,aAAa,CAAC,CAAC,GAAG,OAAO,IAAI;IACvC,QAAQ,CAAC,KAAK,EAAE,WAAW,CAAA;IAC3B,8EAA8E;IAC9E,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAA;IAClB,QAAQ,CAAC,OAAO,EAAE,eAAe,CAAA;IACjC,gEAAgE;IAChE,GAAG,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAA;CACjC,CAAA;AAED,MAAM,MAAM,UAAU,CAAC,CAAC,GAAG,OAAO,IAAI,CAAC,OAAO,EAAE,aAAa,CAAC,CAAC,CAAC,KAAK,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAA;AAE/F;;;GAGG;AACH,MAAM,MAAM,WAAW,CAAC,CAAC,GAAG,OAAO,IAAI,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;AAE9E,MAAM,MAAM,MAAM,CAAC,CAAC,GAAG,OAAO,IAAI;IAChC,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAA;IACvB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,KAAK,EAAE,WAAW,CAAC,CAAC,CAAC,CAAA;CAC/B,CAAA;AAED;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,MAAM,GAAI,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,WACvC,MAAM,SACR,WAAW,CAAC,CAAC,CAAC,KACpB,MAAM,CAAC,CAAC,CAAyC,CAAA;AAEpD;;;;;;;;;;;;GAYG;AACH,MAAM,MAAM,gBAAgB,GAAG;IAC7B,yEAAyE;IACzE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,wDAAwD;IACxD,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAA;IACnC;;;;;OAKG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CACzB,CAAA;AAED,OAAO,QAAQ,gBAAgB,CAAC;IAC9B,UAAU,gBAAgB;QACxB,QAAQ,EAAE,gBAAgB,CAAA;KAC3B;CACF;AAED,eAAO,MAAM,cAAc,eAAgB,MAAM,CAAC,KAAK,CAAC,WAAW,MAAM,KAAG,gBAI1E,CAAA;AAOF;;;;;;;;;GASG;AACH,eAAO,MAAM,WAAW,EAAE,OAAO,MAAuC,CAAA;AAExE,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG,OAAO,WAAW,CAAA;AAEtD;;;;;;;;GAQG;AACH,eAAO,MAAM,oBAAoB,eAAgB,MAAM,CAAC,KAAK,CAAC,UAAU,YAAY,KAAG,IAGtF,CAAA;AAED;;;;;;;;GAQG;AACH,eAAO,MAAM,cAAc,eAAgB,MAAM,CAAC,KAAK,CAAC,KAAG,IAU1D,CAAA;AAED;;;;;GAKG;AACH,eAAO,MAAM,aAAa,QAAO,WAAW,CAAC,MAAM,EAAE,YAAY,CAAY,CAAA;AAE7E,eAAO,MAAM,SAAS,YAAa,MAAM,KAAG,MAAM,CAAC,KAAK,CAAC,GAAG,SAAoC,CAAA;AAEhG,eAAO,MAAM,kBAAkB,QAAO,SAAS,MAAM,CAAC,KAAK,CAAC,EAA8B,CAAA;AAE1F,oFAAoF;AACpF,eAAO,MAAM,iBAAiB,QAAO,SAAS,gBAAgB,EAQ1D,CAAA;AAEJ,eAAO,MAAM,aAAa,QAAO,IAGhC,CAAA"}
|
package/dist/policies.js
ADDED
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Policies (SPEC.md §51).
|
|
3
|
+
*
|
|
4
|
+
* A policy answers one question — may this actor do this to this thing — and the
|
|
5
|
+
* same answer is given to Studio, REST, the SDK, the CLI and MCP, because they all
|
|
6
|
+
* arrive through the same Command Bus and the same Query Bus.
|
|
7
|
+
*/
|
|
8
|
+
import { AssemoraError } from '@assemora/core';
|
|
9
|
+
/**
|
|
10
|
+
* ```ts
|
|
11
|
+
* export const ArticlePolicy = policy('articles', {
|
|
12
|
+
* read: () => true,
|
|
13
|
+
* update: ({ actor, record }) => actor?.id === record.authorId,
|
|
14
|
+
* delete: ({ can }) => can('articles.delete'),
|
|
15
|
+
* })
|
|
16
|
+
* ```
|
|
17
|
+
*
|
|
18
|
+
* SPEC.md §51 spells the record argument after the model — `{ actor, article }`.
|
|
19
|
+
* It is named `record` here because the key would have to be derived from a literal
|
|
20
|
+
* table name that `model()` does not preserve; naming it after the subject would be
|
|
21
|
+
* a runtime-only convenience with no type behind it.
|
|
22
|
+
*/
|
|
23
|
+
export const policy = (subject, rules) => ({ node: 'policy', subject, rules });
|
|
24
|
+
export const describePolicy = (definition, module) => ({
|
|
25
|
+
name: definition.subject,
|
|
26
|
+
actions: Object.keys(definition.rules),
|
|
27
|
+
...(module === undefined ? {} : { module }),
|
|
28
|
+
});
|
|
29
|
+
const registered = new Map();
|
|
30
|
+
/** Which module registered which subject, for the check at boot to be able to say. */
|
|
31
|
+
const sources = new Map();
|
|
32
|
+
/**
|
|
33
|
+
* What the application's own policies are attributed to.
|
|
34
|
+
*
|
|
35
|
+
* A policy passed as `auth({ policies: [...] })` is written at the composition root by
|
|
36
|
+
* the person who assembled the application, so it speaks for the whole of it and is
|
|
37
|
+
* held to no ownership rule — the application *is* the trust boundary the rule exists
|
|
38
|
+
* to protect. A symbol rather than a name so that no module can be called this, and so
|
|
39
|
+
* that a descriptor never carries it: the section shows such a policy with no `module`,
|
|
40
|
+
* which is what "the application, not a package" has looked like since #5.
|
|
41
|
+
*/
|
|
42
|
+
export const APPLICATION = Symbol('assemora.application');
|
|
43
|
+
/**
|
|
44
|
+
* Puts a rule in the map, attributed to whoever is registering it.
|
|
45
|
+
*
|
|
46
|
+
* Deliberately *not* exported from this package. The source is what the ownership rule
|
|
47
|
+
* is checked against, so a caller able to supply one is a caller able to claim to be
|
|
48
|
+
* `pages` — and a package outside this file cannot reach this function to try
|
|
49
|
+
* (ADR-0027). The two callers are the module facet, which passes the module the
|
|
50
|
+
* builder is registering, and `auth({ policies })`, which passes `APPLICATION`.
|
|
51
|
+
*/
|
|
52
|
+
export const registerModulePolicy = (definition, module) => {
|
|
53
|
+
registerPolicy(definition);
|
|
54
|
+
sources.set(definition.subject, module);
|
|
55
|
+
};
|
|
56
|
+
/**
|
|
57
|
+
* Puts a rule in the map, attributed to nobody.
|
|
58
|
+
*
|
|
59
|
+
* Exported, because a test of the authorization port needs a policy in front of it and
|
|
60
|
+
* never boots an application. An application *does* boot, and refuses to start on a
|
|
61
|
+
* policy nothing declares — so this is a harness seam rather than a way in: a package
|
|
62
|
+
* that calls it at import time takes the application down at boot, naming the subject
|
|
63
|
+
* and itself (`ownership.ts`).
|
|
64
|
+
*/
|
|
65
|
+
export const registerPolicy = (definition) => {
|
|
66
|
+
if (registered.has(definition.subject)) {
|
|
67
|
+
throw new AssemoraError('CONFIGURATION_ERROR', `A policy for "${definition.subject}" is already registered`, { status: 500 });
|
|
68
|
+
}
|
|
69
|
+
registered.set(definition.subject, definition);
|
|
70
|
+
};
|
|
71
|
+
/**
|
|
72
|
+
* Who registered each policy, including the ones the application registered itself.
|
|
73
|
+
*
|
|
74
|
+
* `describedPolicies` cannot answer this: a descriptor carries a module *name*, and
|
|
75
|
+
* the application is deliberately not one. The check at boot needs the difference.
|
|
76
|
+
*/
|
|
77
|
+
export const policySources = () => sources;
|
|
78
|
+
export const policyFor = (subject) => registered.get(subject);
|
|
79
|
+
export const registeredPolicies = () => [...registered.values()];
|
|
80
|
+
/** Every policy as the registry describes it, whoever registered it and however. */
|
|
81
|
+
export const describedPolicies = () => [...registered.values()].map((definition) => {
|
|
82
|
+
const source = sources.get(definition.subject);
|
|
83
|
+
// The application's policies are described with no module, which is the shape a
|
|
84
|
+
// registration outside any module has always had — and the right one: naming a
|
|
85
|
+
// module there would claim a package wrote what the application wrote.
|
|
86
|
+
return describePolicy(definition, typeof source === 'string' ? source : undefined);
|
|
87
|
+
});
|
|
88
|
+
export const clearPolicies = () => {
|
|
89
|
+
registered.clear();
|
|
90
|
+
sources.clear();
|
|
91
|
+
};
|
|
92
|
+
//# sourceMappingURL=policies.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"policies.js","sourceRoot":"","sources":["../src/policies.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,EAAoC,aAAa,EAAE,MAAM,gBAAgB,CAAA;AA2BhF;;;;;;;;;;;;;GAaG;AACH,MAAM,CAAC,MAAM,MAAM,GAAG,CACpB,OAAe,EACf,KAAqB,EACV,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAA;AAmCpD,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,UAAyB,EAAE,MAAe,EAAoB,EAAE,CAAC,CAAC;IAC/F,IAAI,EAAE,UAAU,CAAC,OAAO;IACxB,OAAO,EAAE,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC;IACtC,GAAG,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC;CAC5C,CAAC,CAAA;AAEF,MAAM,UAAU,GAAG,IAAI,GAAG,EAAyB,CAAA;AAEnD,sFAAsF;AACtF,MAAM,OAAO,GAAG,IAAI,GAAG,EAAwB,CAAA;AAE/C;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,WAAW,GAAkB,MAAM,CAAC,sBAAsB,CAAC,CAAA;AAIxE;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,UAAyB,EAAE,MAAoB,EAAQ,EAAE;IAC5F,cAAc,CAAC,UAAU,CAAC,CAAA;IAC1B,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,OAAO,EAAE,MAAM,CAAC,CAAA;AACzC,CAAC,CAAA;AAED;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,UAAyB,EAAQ,EAAE;IAChE,IAAI,UAAU,CAAC,GAAG,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;QACvC,MAAM,IAAI,aAAa,CACrB,qBAAqB,EACrB,iBAAiB,UAAU,CAAC,OAAO,yBAAyB,EAC5D,EAAE,MAAM,EAAE,GAAG,EAAE,CAChB,CAAA;IACH,CAAC;IAED,UAAU,CAAC,GAAG,CAAC,UAAU,CAAC,OAAO,EAAE,UAAU,CAAC,CAAA;AAChD,CAAC,CAAA;AAED;;;;;GAKG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,GAAsC,EAAE,CAAC,OAAO,CAAA;AAE7E,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC,OAAe,EAA6B,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC,OAAO,CAAC,CAAA;AAEhG,MAAM,CAAC,MAAM,kBAAkB,GAAG,GAA6B,EAAE,CAAC,CAAC,GAAG,UAAU,CAAC,MAAM,EAAE,CAAC,CAAA;AAE1F,oFAAoF;AACpF,MAAM,CAAC,MAAM,iBAAiB,GAAG,GAAgC,EAAE,CACjE,CAAC,GAAG,UAAU,CAAC,MAAM,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,UAAU,EAAE,EAAE;IAC1C,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,OAAO,CAAC,CAAA;IAE9C,gFAAgF;IAChF,+EAA+E;IAC/E,uEAAuE;IACvE,OAAO,cAAc,CAAC,UAAU,EAAE,OAAO,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,CAAA;AACpF,CAAC,CAAC,CAAA;AAEJ,MAAM,CAAC,MAAM,aAAa,GAAG,GAAS,EAAE;IACtC,UAAU,CAAC,KAAK,EAAE,CAAA;IAClB,OAAO,CAAC,KAAK,EAAE,CAAA;AACjB,CAAC,CAAA"}
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
export declare const ListUsers: import("@assemora/core").QueryDefinition<{
|
|
2
|
+
page: import("@assemora/schema").OptionalSchema<number>;
|
|
3
|
+
perPage: import("@assemora/schema").OptionalSchema<number>;
|
|
4
|
+
search: import("@assemora/schema").OptionalSchema<string>;
|
|
5
|
+
active: import("@assemora/schema").OptionalSchema<boolean>;
|
|
6
|
+
}, {
|
|
7
|
+
readonly data: readonly {
|
|
8
|
+
readonly active: boolean;
|
|
9
|
+
readonly createdAt: Date;
|
|
10
|
+
readonly email: string;
|
|
11
|
+
readonly id: string;
|
|
12
|
+
readonly name: string;
|
|
13
|
+
readonly roles: readonly string[];
|
|
14
|
+
readonly version: number;
|
|
15
|
+
}[];
|
|
16
|
+
readonly lastPage: number;
|
|
17
|
+
readonly page: number;
|
|
18
|
+
readonly perPage: number;
|
|
19
|
+
readonly total: number;
|
|
20
|
+
}>;
|
|
21
|
+
export declare const GetUser: import("@assemora/core").QueryDefinition<{
|
|
22
|
+
id: import("@assemora/schema").StringSchema;
|
|
23
|
+
}, {
|
|
24
|
+
readonly active: boolean;
|
|
25
|
+
readonly createdAt: Date;
|
|
26
|
+
readonly email: string;
|
|
27
|
+
readonly id: string;
|
|
28
|
+
readonly name: string;
|
|
29
|
+
readonly permissions: readonly string[];
|
|
30
|
+
readonly roles: readonly string[];
|
|
31
|
+
readonly updatedAt: Date;
|
|
32
|
+
readonly version: number;
|
|
33
|
+
}>;
|
|
34
|
+
export declare const ListRoles: import("@assemora/core").QueryDefinition<{}, {
|
|
35
|
+
readonly data: readonly {
|
|
36
|
+
readonly id: string;
|
|
37
|
+
readonly label: string;
|
|
38
|
+
readonly name: string;
|
|
39
|
+
readonly permissions: readonly string[];
|
|
40
|
+
readonly version: number;
|
|
41
|
+
}[];
|
|
42
|
+
}>;
|
|
43
|
+
export declare const ListPermissions: import("@assemora/core").QueryDefinition<{}, {
|
|
44
|
+
readonly data: readonly {
|
|
45
|
+
readonly description: string | null;
|
|
46
|
+
readonly id: string;
|
|
47
|
+
readonly name: string;
|
|
48
|
+
}[];
|
|
49
|
+
}>;
|
|
50
|
+
export declare const ListApiTokens: import("@assemora/core").QueryDefinition<{
|
|
51
|
+
page: import("@assemora/schema").OptionalSchema<number>;
|
|
52
|
+
perPage: import("@assemora/schema").OptionalSchema<number>;
|
|
53
|
+
userId: import("@assemora/schema").OptionalSchema<string>;
|
|
54
|
+
}, {
|
|
55
|
+
readonly data: readonly {
|
|
56
|
+
readonly createdAt: Date;
|
|
57
|
+
readonly expiresAt: Date | null;
|
|
58
|
+
readonly id: string;
|
|
59
|
+
readonly lastUsedAt: Date | null;
|
|
60
|
+
readonly name: string;
|
|
61
|
+
readonly permissions: readonly string[];
|
|
62
|
+
readonly userId: string | null;
|
|
63
|
+
}[];
|
|
64
|
+
readonly lastPage: number;
|
|
65
|
+
readonly page: number;
|
|
66
|
+
readonly perPage: number;
|
|
67
|
+
readonly total: number;
|
|
68
|
+
}>;
|
|
69
|
+
export declare const ListAgents: import("@assemora/core").QueryDefinition<{
|
|
70
|
+
page: import("@assemora/schema").OptionalSchema<number>;
|
|
71
|
+
perPage: import("@assemora/schema").OptionalSchema<number>;
|
|
72
|
+
}, {
|
|
73
|
+
readonly data: readonly {
|
|
74
|
+
readonly createdAt: Date;
|
|
75
|
+
readonly description: string | null;
|
|
76
|
+
readonly enabled: boolean;
|
|
77
|
+
readonly id: string;
|
|
78
|
+
readonly name: string;
|
|
79
|
+
readonly permissions: readonly string[];
|
|
80
|
+
}[];
|
|
81
|
+
readonly lastPage: number;
|
|
82
|
+
readonly page: number;
|
|
83
|
+
readonly perPage: number;
|
|
84
|
+
readonly total: number;
|
|
85
|
+
}>;
|
|
86
|
+
export declare const authQueries: readonly [import("@assemora/core").QueryDefinition<{
|
|
87
|
+
page: import("@assemora/schema").OptionalSchema<number>;
|
|
88
|
+
perPage: import("@assemora/schema").OptionalSchema<number>;
|
|
89
|
+
search: import("@assemora/schema").OptionalSchema<string>;
|
|
90
|
+
active: import("@assemora/schema").OptionalSchema<boolean>;
|
|
91
|
+
}, {
|
|
92
|
+
readonly data: readonly {
|
|
93
|
+
readonly active: boolean;
|
|
94
|
+
readonly createdAt: Date;
|
|
95
|
+
readonly email: string;
|
|
96
|
+
readonly id: string;
|
|
97
|
+
readonly name: string;
|
|
98
|
+
readonly roles: readonly string[];
|
|
99
|
+
readonly version: number;
|
|
100
|
+
}[];
|
|
101
|
+
readonly lastPage: number;
|
|
102
|
+
readonly page: number;
|
|
103
|
+
readonly perPage: number;
|
|
104
|
+
readonly total: number;
|
|
105
|
+
}>, import("@assemora/core").QueryDefinition<{
|
|
106
|
+
id: import("@assemora/schema").StringSchema;
|
|
107
|
+
}, {
|
|
108
|
+
readonly active: boolean;
|
|
109
|
+
readonly createdAt: Date;
|
|
110
|
+
readonly email: string;
|
|
111
|
+
readonly id: string;
|
|
112
|
+
readonly name: string;
|
|
113
|
+
readonly permissions: readonly string[];
|
|
114
|
+
readonly roles: readonly string[];
|
|
115
|
+
readonly updatedAt: Date;
|
|
116
|
+
readonly version: number;
|
|
117
|
+
}>, import("@assemora/core").QueryDefinition<{}, {
|
|
118
|
+
readonly data: readonly {
|
|
119
|
+
readonly id: string;
|
|
120
|
+
readonly label: string;
|
|
121
|
+
readonly name: string;
|
|
122
|
+
readonly permissions: readonly string[];
|
|
123
|
+
readonly version: number;
|
|
124
|
+
}[];
|
|
125
|
+
}>, import("@assemora/core").QueryDefinition<{}, {
|
|
126
|
+
readonly data: readonly {
|
|
127
|
+
readonly description: string | null;
|
|
128
|
+
readonly id: string;
|
|
129
|
+
readonly name: string;
|
|
130
|
+
}[];
|
|
131
|
+
}>, import("@assemora/core").QueryDefinition<{
|
|
132
|
+
page: import("@assemora/schema").OptionalSchema<number>;
|
|
133
|
+
perPage: import("@assemora/schema").OptionalSchema<number>;
|
|
134
|
+
userId: import("@assemora/schema").OptionalSchema<string>;
|
|
135
|
+
}, {
|
|
136
|
+
readonly data: readonly {
|
|
137
|
+
readonly createdAt: Date;
|
|
138
|
+
readonly expiresAt: Date | null;
|
|
139
|
+
readonly id: string;
|
|
140
|
+
readonly lastUsedAt: Date | null;
|
|
141
|
+
readonly name: string;
|
|
142
|
+
readonly permissions: readonly string[];
|
|
143
|
+
readonly userId: string | null;
|
|
144
|
+
}[];
|
|
145
|
+
readonly lastPage: number;
|
|
146
|
+
readonly page: number;
|
|
147
|
+
readonly perPage: number;
|
|
148
|
+
readonly total: number;
|
|
149
|
+
}>, import("@assemora/core").QueryDefinition<{
|
|
150
|
+
page: import("@assemora/schema").OptionalSchema<number>;
|
|
151
|
+
perPage: import("@assemora/schema").OptionalSchema<number>;
|
|
152
|
+
}, {
|
|
153
|
+
readonly data: readonly {
|
|
154
|
+
readonly createdAt: Date;
|
|
155
|
+
readonly description: string | null;
|
|
156
|
+
readonly enabled: boolean;
|
|
157
|
+
readonly id: string;
|
|
158
|
+
readonly name: string;
|
|
159
|
+
readonly permissions: readonly string[];
|
|
160
|
+
}[];
|
|
161
|
+
readonly lastPage: number;
|
|
162
|
+
readonly page: number;
|
|
163
|
+
readonly perPage: number;
|
|
164
|
+
readonly total: number;
|
|
165
|
+
}>];
|
|
166
|
+
//# sourceMappingURL=queries.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"queries.d.ts","sourceRoot":"","sources":["../src/queries.ts"],"names":[],"mappings":"AAgEA,eAAO,MAAM,SAAS;;;;;;;;;;;;;;;;;;;EA4CpB,CAAA;AAEF,eAAO,MAAM,OAAO;;;;;;;;;;;;EAiClB,CAAA;AAEF,eAAO,MAAM,SAAS;;;;;;;;EAuCpB,CAAA;AAEF,eAAO,MAAM,eAAe;;;;;;EAa1B,CAAA;AAEF,eAAO,MAAM,aAAa;;;;;;;;;;;;;;;;;;EAsCxB,CAAA;AAEF,eAAO,MAAM,UAAU;;;;;;;;;;;;;;;;EA+BrB,CAAA;AAEF,eAAO,MAAM,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAOd,CAAA"}
|