@seifer-webapp-factory/authorization 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/README.md +17 -0
- package/backend/templates/cache/ttl-cache.ts +41 -0
- package/backend/templates/config/config-fragment.ts +41 -0
- package/backend/templates/nestjs/authz.controller.ts +253 -0
- package/backend/templates/nestjs/authz.module.ts +158 -0
- package/backend/templates/nestjs/tokens.ts +41 -0
- package/backend/templates/persistence/migrations/0001_authz.sql +45 -0
- package/backend/templates/persistence/migrations/index.ts +84 -0
- package/backend/templates/persistence/pg-policy-store.ts +193 -0
- package/backend/templates/persistence/seed.ts +60 -0
- package/dist/backend/src/index.d.ts +10 -0
- package/dist/backend/src/index.d.ts.map +1 -0
- package/dist/backend/src/index.js +9 -0
- package/dist/backend/src/index.js.map +1 -0
- package/dist/backend/src/policy.d.ts +13 -0
- package/dist/backend/src/policy.d.ts.map +1 -0
- package/dist/backend/src/policy.js +49 -0
- package/dist/backend/src/policy.js.map +1 -0
- package/dist/backend/src/ports.d.ts +90 -0
- package/dist/backend/src/ports.d.ts.map +1 -0
- package/dist/backend/src/ports.js +2 -0
- package/dist/backend/src/ports.js.map +1 -0
- package/dist/backend/src/services.d.ts +81 -0
- package/dist/backend/src/services.d.ts.map +1 -0
- package/dist/backend/src/services.js +234 -0
- package/dist/backend/src/services.js.map +1 -0
- package/dist/contract/endpoints.d.ts +433 -0
- package/dist/contract/endpoints.d.ts.map +1 -0
- package/dist/contract/endpoints.js +57 -0
- package/dist/contract/endpoints.js.map +1 -0
- package/dist/contract/errors.d.ts +33 -0
- package/dist/contract/errors.d.ts.map +1 -0
- package/dist/contract/errors.js +51 -0
- package/dist/contract/errors.js.map +1 -0
- package/dist/contract/events.d.ts +50 -0
- package/dist/contract/events.d.ts.map +1 -0
- package/dist/contract/events.js +13 -0
- package/dist/contract/events.js.map +1 -0
- package/dist/contract/index.d.ts +10 -0
- package/dist/contract/index.d.ts.map +1 -0
- package/dist/contract/index.js +10 -0
- package/dist/contract/index.js.map +1 -0
- package/dist/contract/permissions.d.ts +35 -0
- package/dist/contract/permissions.d.ts.map +1 -0
- package/dist/contract/permissions.js +37 -0
- package/dist/contract/permissions.js.map +1 -0
- package/dist/contract/schemas.d.ts +288 -0
- package/dist/contract/schemas.d.ts.map +1 -0
- package/dist/contract/schemas.js +91 -0
- package/dist/contract/schemas.js.map +1 -0
- package/dist/frontend/src/client.d.ts +31 -0
- package/dist/frontend/src/client.d.ts.map +1 -0
- package/dist/frontend/src/client.js +83 -0
- package/dist/frontend/src/client.js.map +1 -0
- package/dist/frontend/src/composables.d.ts +62 -0
- package/dist/frontend/src/composables.d.ts.map +1 -0
- package/dist/frontend/src/composables.js +170 -0
- package/dist/frontend/src/composables.js.map +1 -0
- package/dist/frontend/src/guards.d.ts +12 -0
- package/dist/frontend/src/guards.d.ts.map +1 -0
- package/dist/frontend/src/guards.js +10 -0
- package/dist/frontend/src/guards.js.map +1 -0
- package/dist/frontend/src/index.d.ts +12 -0
- package/dist/frontend/src/index.d.ts.map +1 -0
- package/dist/frontend/src/index.js +9 -0
- package/dist/frontend/src/index.js.map +1 -0
- package/dist/manifest.d.ts +56 -0
- package/dist/manifest.d.ts.map +1 -0
- package/dist/manifest.js +100 -0
- package/dist/manifest.js.map +1 -0
- package/dist/scaffolder/core/config.d.ts +86 -0
- package/dist/scaffolder/core/config.d.ts.map +1 -0
- package/dist/scaffolder/core/config.js +92 -0
- package/dist/scaffolder/core/config.js.map +1 -0
- package/dist/scaffolder/core/errors.d.ts +46 -0
- package/dist/scaffolder/core/errors.d.ts.map +1 -0
- package/dist/scaffolder/core/errors.js +60 -0
- package/dist/scaffolder/core/errors.js.map +1 -0
- package/dist/scaffolder/core/extend.d.ts +86 -0
- package/dist/scaffolder/core/extend.d.ts.map +1 -0
- package/dist/scaffolder/core/extend.js +94 -0
- package/dist/scaffolder/core/extend.js.map +1 -0
- package/dist/scaffolder/core/materialize.d.ts +71 -0
- package/dist/scaffolder/core/materialize.d.ts.map +1 -0
- package/dist/scaffolder/core/materialize.js +47 -0
- package/dist/scaffolder/core/materialize.js.map +1 -0
- package/dist/scaffolder/core/ports.d.ts +39 -0
- package/dist/scaffolder/core/ports.d.ts.map +1 -0
- package/dist/scaffolder/core/ports.js +33 -0
- package/dist/scaffolder/core/ports.js.map +1 -0
- package/dist/scaffolder/core/presence.d.ts +34 -0
- package/dist/scaffolder/core/presence.d.ts.map +1 -0
- package/dist/scaffolder/core/presence.js +29 -0
- package/dist/scaffolder/core/presence.js.map +1 -0
- package/dist/scaffolder/core/three-way-merge.d.ts +113 -0
- package/dist/scaffolder/core/three-way-merge.d.ts.map +1 -0
- package/dist/scaffolder/core/three-way-merge.js +184 -0
- package/dist/scaffolder/core/three-way-merge.js.map +1 -0
- package/dist/scaffolder/index.d.ts +25 -0
- package/dist/scaffolder/index.d.ts.map +1 -0
- package/dist/scaffolder/index.js +24 -0
- package/dist/scaffolder/index.js.map +1 -0
- package/frontend/templates/components/PermissionMatrix.vue +134 -0
- package/frontend/templates/i18n/en.json +61 -0
- package/frontend/templates/i18n/nl.json +61 -0
- package/frontend/templates/middleware/permission.ts +54 -0
- package/frontend/templates/pages/access-assignments.vue +151 -0
- package/frontend/templates/pages/role-editor.vue +169 -0
- package/frontend/templates/pages/roles-list.vue +84 -0
- package/frontend/templates/plugins/authz.client.ts +108 -0
- package/frontend/templates/runtime.ts +60 -0
- package/package.json +76 -0
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
/**
|
|
3
|
+
* US-Z0101 — DTO-schema's (de seam). Eén set Zod-schema's waaruit de backend valideert én de frontend
|
|
4
|
+
* zijn getypte client afleidt (`z.infer`). Rol-/permissie-namen zijn data; de vorm + minimale
|
|
5
|
+
* invarianten staan hier. Geen policy-logica — die zit in de `access-control`-kit.
|
|
6
|
+
*/
|
|
7
|
+
// --- Primitieven ---
|
|
8
|
+
/** Puntgescheiden sleutel-conventie (`authz.manage`, `article.write`), geen spaties. */
|
|
9
|
+
export const permissionKeySchema = z
|
|
10
|
+
.string()
|
|
11
|
+
.min(1)
|
|
12
|
+
.max(128)
|
|
13
|
+
.regex(/^[a-z0-9]+(?:[._-][a-z0-9]+)*$/, 'ongeldige permissie-sleutel');
|
|
14
|
+
/** Rol-sleutel: kleine letters/cijfers + scheidingstekens (`admin`, `content-editor`). */
|
|
15
|
+
export const roleKeySchema = z
|
|
16
|
+
.string()
|
|
17
|
+
.min(1)
|
|
18
|
+
.max(64)
|
|
19
|
+
.regex(/^[a-z0-9]+(?:[_-][a-z0-9]+)*$/, 'ongeldige rol-sleutel');
|
|
20
|
+
export const subjectIdSchema = z.string().min(1);
|
|
21
|
+
export const roleIdSchema = z.string().min(1);
|
|
22
|
+
// --- Rollen ---
|
|
23
|
+
export const roleSchema = z.object({
|
|
24
|
+
id: roleIdSchema,
|
|
25
|
+
key: roleKeySchema,
|
|
26
|
+
name: z.string().min(1).max(128),
|
|
27
|
+
permissions: z.array(permissionKeySchema),
|
|
28
|
+
/** Rol-hiërarchie: de bovenliggende rol waarvan deze rol de permissies erft; `null` = geen ouder. */
|
|
29
|
+
parentRoleId: roleIdSchema.nullable(),
|
|
30
|
+
});
|
|
31
|
+
export const roleListResponseSchema = z.object({ roles: z.array(roleSchema) });
|
|
32
|
+
export const createRoleRequestSchema = z.object({
|
|
33
|
+
key: roleKeySchema,
|
|
34
|
+
name: z.string().min(1).max(128),
|
|
35
|
+
permissions: z.array(permissionKeySchema).default([]),
|
|
36
|
+
parentRoleId: roleIdSchema.nullable().default(null),
|
|
37
|
+
});
|
|
38
|
+
/** Alle velden optioneel: een PATCH die alleen de aangeleverde velden wijzigt. */
|
|
39
|
+
export const updateRoleRequestSchema = z.object({
|
|
40
|
+
name: z.string().min(1).max(128).optional(),
|
|
41
|
+
permissions: z.array(permissionKeySchema).optional(),
|
|
42
|
+
parentRoleId: roleIdSchema.nullable().optional(),
|
|
43
|
+
});
|
|
44
|
+
// --- Permissie-catalogus ---
|
|
45
|
+
export const permissionSchema = z.object({
|
|
46
|
+
key: permissionKeySchema,
|
|
47
|
+
description: z.string(),
|
|
48
|
+
});
|
|
49
|
+
export const permissionListResponseSchema = z.object({ permissions: z.array(permissionSchema) });
|
|
50
|
+
// --- Toewijzingen ---
|
|
51
|
+
export const assignmentRequestSchema = z.object({
|
|
52
|
+
subjectId: subjectIdSchema,
|
|
53
|
+
roleId: roleIdSchema,
|
|
54
|
+
});
|
|
55
|
+
export const subjectRolesResponseSchema = z.object({
|
|
56
|
+
subjectId: subjectIdSchema,
|
|
57
|
+
roles: z.array(roleSchema),
|
|
58
|
+
});
|
|
59
|
+
// --- Resolutie / hydratie ---
|
|
60
|
+
export const mePermissionsResponseSchema = z.object({
|
|
61
|
+
subjectId: subjectIdSchema,
|
|
62
|
+
roles: z.array(roleKeySchema),
|
|
63
|
+
permissions: z.array(permissionKeySchema),
|
|
64
|
+
});
|
|
65
|
+
// --- Programmatic check ---
|
|
66
|
+
export const checkRequestSchema = z
|
|
67
|
+
.object({
|
|
68
|
+
/** RBAC-vorm: heeft het huidige subject deze permissie? */
|
|
69
|
+
permission: permissionKeySchema.optional(),
|
|
70
|
+
/** PDP-vorm: is deze action toegestaan (evt. tegen een resource, voor ReBAC/ownership)? */
|
|
71
|
+
action: z.string().min(1).optional(),
|
|
72
|
+
resource: z.object({ id: z.string().min(1), type: z.string().min(1).optional() }).optional(),
|
|
73
|
+
})
|
|
74
|
+
.refine((v) => Boolean(v.permission) || Boolean(v.action), {
|
|
75
|
+
message: 'permission of action is verplicht',
|
|
76
|
+
});
|
|
77
|
+
export const checkResponseSchema = z.object({
|
|
78
|
+
allowed: z.boolean(),
|
|
79
|
+
/** Veilige, niet-lekkende reden (geen policy-interne details). */
|
|
80
|
+
reason: z.string(),
|
|
81
|
+
});
|
|
82
|
+
// --- ReBAC-relaties (achter config-toggle) ---
|
|
83
|
+
export const relationRequestSchema = z.object({
|
|
84
|
+
subjectId: subjectIdSchema,
|
|
85
|
+
relation: z.string().min(1).max(64),
|
|
86
|
+
objectType: z.string().min(1).max(64),
|
|
87
|
+
objectId: z.string().min(1),
|
|
88
|
+
});
|
|
89
|
+
// --- Generieke bevestiging ---
|
|
90
|
+
export const acknowledgementSchema = z.object({ ok: z.literal(true) });
|
|
91
|
+
//# sourceMappingURL=schemas.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schemas.js","sourceRoot":"","sources":["../../contract/schemas.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { HttpClient } from '@seifer-webapp-factory/kits/frontend/http-client';
|
|
2
|
+
import type { Acknowledgement, AssignmentRequest, AuthzErrorCode, CheckRequest, CheckResponse, CreateRoleRequest, MePermissionsResponse, PermissionListResponse, RelationRequest, Role, RoleListResponse, SubjectRolesResponse, UpdateRoleRequest } from '../../contract/index.js';
|
|
3
|
+
/** Getypte fout bij een niet-2xx-respons: draagt de contract-`code` + `i18nKey`; nooit rauwe details. */
|
|
4
|
+
export declare class AuthzClientError extends Error {
|
|
5
|
+
readonly code: AuthzErrorCode;
|
|
6
|
+
readonly i18nKey: string;
|
|
7
|
+
readonly httpStatus: number;
|
|
8
|
+
readonly fields?: Readonly<Record<string, string[]>>;
|
|
9
|
+
constructor(code: AuthzErrorCode, i18nKey: string, httpStatus: number, fields?: Readonly<Record<string, string[]>>);
|
|
10
|
+
}
|
|
11
|
+
/** De publieke, getypte client-API (12 endpoints). */
|
|
12
|
+
export interface AuthzClient {
|
|
13
|
+
listRoles(): Promise<RoleListResponse>;
|
|
14
|
+
createRole(input: CreateRoleRequest): Promise<Role>;
|
|
15
|
+
updateRole(id: string, patch: UpdateRoleRequest): Promise<Role>;
|
|
16
|
+
deleteRole(id: string): Promise<Acknowledgement>;
|
|
17
|
+
listPermissions(): Promise<PermissionListResponse>;
|
|
18
|
+
subjectRoles(subjectId: string): Promise<SubjectRolesResponse>;
|
|
19
|
+
assignRole(input: AssignmentRequest): Promise<Acknowledgement>;
|
|
20
|
+
revokeRole(input: AssignmentRequest): Promise<Acknowledgement>;
|
|
21
|
+
mePermissions(): Promise<MePermissionsResponse>;
|
|
22
|
+
check(input: CheckRequest): Promise<CheckResponse>;
|
|
23
|
+
writeRelation(input: RelationRequest): Promise<Acknowledgement>;
|
|
24
|
+
removeRelation(input: RelationRequest): Promise<Acknowledgement>;
|
|
25
|
+
}
|
|
26
|
+
export interface CreateAuthzClientOptions {
|
|
27
|
+
readonly http: HttpClient;
|
|
28
|
+
}
|
|
29
|
+
/** Maakt een getypte authorization-client rond de geïnjecteerde kit-`HttpClient`. */
|
|
30
|
+
export declare function createAuthzClient(options: CreateAuthzClientOptions): AuthzClient;
|
|
31
|
+
//# sourceMappingURL=client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../../frontend/src/client.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kDAAkD,CAAC;AAMnF,OAAO,KAAK,EACV,eAAe,EACf,iBAAiB,EAEjB,cAAc,EACd,YAAY,EACZ,aAAa,EACb,iBAAiB,EACjB,qBAAqB,EACrB,sBAAsB,EACtB,eAAe,EACf,IAAI,EACJ,gBAAgB,EAChB,oBAAoB,EACpB,iBAAiB,EAClB,MAAM,yBAAyB,CAAC;AAEjC,yGAAyG;AACzG,qBAAa,gBAAiB,SAAQ,KAAK;IACzC,QAAQ,CAAC,IAAI,EAAE,cAAc,CAAC;IAC9B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,MAAM,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC;gBAEzC,IAAI,EAAE,cAAc,EAAE,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;CAQnH;AAED,sDAAsD;AACtD,MAAM,WAAW,WAAW;IAC1B,SAAS,IAAI,OAAO,CAAC,gBAAgB,CAAC,CAAC;IACvC,UAAU,CAAC,KAAK,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACpD,UAAU,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAChE,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC;IACjD,eAAe,IAAI,OAAO,CAAC,sBAAsB,CAAC,CAAC;IACnD,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,oBAAoB,CAAC,CAAC;IAC/D,UAAU,CAAC,KAAK,EAAE,iBAAiB,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC;IAC/D,UAAU,CAAC,KAAK,EAAE,iBAAiB,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC;IAC/D,aAAa,IAAI,OAAO,CAAC,qBAAqB,CAAC,CAAC;IAChD,KAAK,CAAC,KAAK,EAAE,YAAY,GAAG,OAAO,CAAC,aAAa,CAAC,CAAC;IACnD,aAAa,CAAC,KAAK,EAAE,eAAe,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC;IAChE,cAAc,CAAC,KAAK,EAAE,eAAe,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC;CAClE;AAED,MAAM,WAAW,wBAAwB;IACvC,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC;CAC3B;AAwBD,qFAAqF;AACrF,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,wBAAwB,GAAG,WAAW,CA8ChF"}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* US-Z0105 — De getypte authorization-client (het mechanisme). Leidt methoden, paden en foutcodes af
|
|
3
|
+
* uit het contract (`AUTHZ_ENDPOINTS` + `AUTHZ_ERROR_TAXONOMY`) — één bron, geen drift. Kent geen
|
|
4
|
+
* netwerk: krijgt de kit-`HttpClient` geïnjecteerd. Bij een niet-2xx-respons mapt hij de kit-`HttpError`
|
|
5
|
+
* (mét geparste body) naar een getypte `AuthzClientError` met de contract-`code` + `i18nKey`.
|
|
6
|
+
*/
|
|
7
|
+
import { HttpError } from '@seifer-webapp-factory/kits/frontend/http-client';
|
|
8
|
+
import { AUTHZ_ENDPOINTS, AUTHZ_ERROR_CODES, AUTHZ_ERROR_TAXONOMY, } from '../../contract/index.js';
|
|
9
|
+
/** Getypte fout bij een niet-2xx-respons: draagt de contract-`code` + `i18nKey`; nooit rauwe details. */
|
|
10
|
+
export class AuthzClientError extends Error {
|
|
11
|
+
code;
|
|
12
|
+
i18nKey;
|
|
13
|
+
httpStatus;
|
|
14
|
+
fields;
|
|
15
|
+
constructor(code, i18nKey, httpStatus, fields) {
|
|
16
|
+
super(`[authz] ${code} (HTTP ${httpStatus})`);
|
|
17
|
+
this.name = 'AuthzClientError';
|
|
18
|
+
this.code = code;
|
|
19
|
+
this.i18nKey = i18nKey;
|
|
20
|
+
this.httpStatus = httpStatus;
|
|
21
|
+
this.fields = fields;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
const ERROR_CODES = AUTHZ_ERROR_CODES;
|
|
25
|
+
/** Leidt de foutcode af: bij voorkeur uit de body (`code`), anders reverse-lookup op HTTP-status. */
|
|
26
|
+
function resolveErrorCode(status, body) {
|
|
27
|
+
const bodyCode = body?.code;
|
|
28
|
+
if (typeof bodyCode === 'string' && ERROR_CODES.includes(bodyCode))
|
|
29
|
+
return bodyCode;
|
|
30
|
+
const byStatus = AUTHZ_ERROR_CODES.find((code) => AUTHZ_ERROR_TAXONOMY[code].httpStatus === status);
|
|
31
|
+
return byStatus ?? 'validation_failed';
|
|
32
|
+
}
|
|
33
|
+
/** Vervangt `:param`-segmenten in een pad door concrete (ge-encodeerde) waarden. */
|
|
34
|
+
function buildPath(template, params) {
|
|
35
|
+
if (!params)
|
|
36
|
+
return template;
|
|
37
|
+
return template.replace(/:([A-Za-z0-9_]+)/g, (_, name) => encodeURIComponent(params[name] ?? ''));
|
|
38
|
+
}
|
|
39
|
+
/** Maakt een getypte authorization-client rond de geïnjecteerde kit-`HttpClient`. */
|
|
40
|
+
export function createAuthzClient(options) {
|
|
41
|
+
const { http } = options;
|
|
42
|
+
async function call(endpoint, opts = {}) {
|
|
43
|
+
let data;
|
|
44
|
+
let status;
|
|
45
|
+
try {
|
|
46
|
+
const res = await http.request({
|
|
47
|
+
method: endpoint.method,
|
|
48
|
+
path: buildPath(endpoint.path, opts.params),
|
|
49
|
+
body: opts.body,
|
|
50
|
+
});
|
|
51
|
+
data = res.data;
|
|
52
|
+
status = res.status;
|
|
53
|
+
}
|
|
54
|
+
catch (err) {
|
|
55
|
+
if (err instanceof HttpError && err.status !== undefined) {
|
|
56
|
+
const code = resolveErrorCode(err.status, err.body);
|
|
57
|
+
const errorBody = err.body;
|
|
58
|
+
throw new AuthzClientError(code, AUTHZ_ERROR_TAXONOMY[code].i18nKey, err.status, errorBody?.fields);
|
|
59
|
+
}
|
|
60
|
+
throw err;
|
|
61
|
+
}
|
|
62
|
+
const parsed = endpoint.response.safeParse(data);
|
|
63
|
+
if (!parsed.success) {
|
|
64
|
+
throw new AuthzClientError('validation_failed', AUTHZ_ERROR_TAXONOMY.validation_failed.i18nKey, status);
|
|
65
|
+
}
|
|
66
|
+
return parsed.data;
|
|
67
|
+
}
|
|
68
|
+
return {
|
|
69
|
+
listRoles: () => call(AUTHZ_ENDPOINTS.listRoles),
|
|
70
|
+
createRole: (input) => call(AUTHZ_ENDPOINTS.createRole, { body: input }),
|
|
71
|
+
updateRole: (id, patch) => call(AUTHZ_ENDPOINTS.updateRole, { body: patch, params: { id } }),
|
|
72
|
+
deleteRole: (id) => call(AUTHZ_ENDPOINTS.deleteRole, { params: { id } }),
|
|
73
|
+
listPermissions: () => call(AUTHZ_ENDPOINTS.listPermissions),
|
|
74
|
+
subjectRoles: (subjectId) => call(AUTHZ_ENDPOINTS.subjectRoles, { params: { id: subjectId } }),
|
|
75
|
+
assignRole: (input) => call(AUTHZ_ENDPOINTS.assignRole, { body: input }),
|
|
76
|
+
revokeRole: (input) => call(AUTHZ_ENDPOINTS.revokeRole, { body: input }),
|
|
77
|
+
mePermissions: () => call(AUTHZ_ENDPOINTS.mePermissions),
|
|
78
|
+
check: (input) => call(AUTHZ_ENDPOINTS.check, { body: input }),
|
|
79
|
+
writeRelation: (input) => call(AUTHZ_ENDPOINTS.writeRelation, { body: input }),
|
|
80
|
+
removeRelation: (input) => call(AUTHZ_ENDPOINTS.removeRelation, { body: input }),
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../../../frontend/src/client.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Vue-composables (het mechanisme, provide/inject). Een dunne, reactieve laag bovenop de getypte
|
|
3
|
+
* authorization-client. De client wordt per app-instance geprovide (`provideAuthzClient`), zodat
|
|
4
|
+
* SSR-render en client-hydratie per request geïsoleerd blijven — geen module-globale mutable state.
|
|
5
|
+
*
|
|
6
|
+
* Stories: US-Z0405 (usePermissions — hydratie van `can`), US-Z0201..0203 (useRoles),
|
|
7
|
+
* US-Z0301/0305 (useAssignments).
|
|
8
|
+
*/
|
|
9
|
+
import { type App, type InjectionKey, type Ref } from 'vue';
|
|
10
|
+
import { type AuthzClient } from './client.js';
|
|
11
|
+
import type { AssignmentRequest, CreateRoleRequest, Permission, Role, UpdateRoleRequest } from '../../contract/index.js';
|
|
12
|
+
/** De per-request client die op de app wordt geprovide. Symbool = module-constante (geen state). */
|
|
13
|
+
export declare const AUTHZ_CLIENT_KEY: InjectionKey<AuthzClient>;
|
|
14
|
+
/** Registreer de authorization-client op een app-instance (bij bootstrap). */
|
|
15
|
+
export declare function provideAuthzClient(app: App, client: AuthzClient): void;
|
|
16
|
+
/** Haal de getypte authorization-client op binnen setup(). Werpt als er niets geprovide is. */
|
|
17
|
+
export declare function useAuthzClient(): AuthzClient;
|
|
18
|
+
/** De reactieve vorm die elke actie-composable teruggeeft. `error` is een i18n-sleutel, geen detail. */
|
|
19
|
+
export interface UseAuthzAction<Input, Result> {
|
|
20
|
+
readonly pending: Ref<boolean>;
|
|
21
|
+
readonly error: Ref<string | null>;
|
|
22
|
+
readonly result: Ref<Result | null>;
|
|
23
|
+
submit(input: Input): Promise<Result | undefined>;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* US-Z0405 — hydrateert de effectieve permissies/rollen van het huidige subject uit
|
|
27
|
+
* `/authz/me/permissions` en biedt een reactieve `can(permission)`. Deze bron voedt de kit-evaluator
|
|
28
|
+
* (via `claimsPermissionSource`) zodat `<Can>`/`v-can`/de route-guard consistent gaten.
|
|
29
|
+
*/
|
|
30
|
+
export interface UsePermissions {
|
|
31
|
+
readonly permissions: Ref<string[]>;
|
|
32
|
+
readonly roles: Ref<string[]>;
|
|
33
|
+
readonly loaded: Ref<boolean>;
|
|
34
|
+
readonly pending: Ref<boolean>;
|
|
35
|
+
/** Reactieve permissie-check (default-deny: onbekend => false). */
|
|
36
|
+
can(permission: string): boolean;
|
|
37
|
+
/** (Her)laadt de permissies van de server. */
|
|
38
|
+
reload(): Promise<void>;
|
|
39
|
+
}
|
|
40
|
+
export declare function usePermissions(): UsePermissions;
|
|
41
|
+
/** US-Z0201..0203 — rollenbeheer-composables (lijst + mutaties). */
|
|
42
|
+
export interface UseRoles {
|
|
43
|
+
readonly roles: Ref<Role[]>;
|
|
44
|
+
readonly permissions: Ref<Permission[]>;
|
|
45
|
+
readonly pending: Ref<boolean>;
|
|
46
|
+
readonly error: Ref<string | null>;
|
|
47
|
+
refresh(): Promise<void>;
|
|
48
|
+
create: UseAuthzAction<CreateRoleRequest, Role>['submit'];
|
|
49
|
+
update: (id: string, patch: UpdateRoleRequest) => Promise<Role | undefined>;
|
|
50
|
+
remove: (id: string) => Promise<boolean>;
|
|
51
|
+
}
|
|
52
|
+
export declare function useRoles(): UseRoles;
|
|
53
|
+
/** US-Z0301/0305 — rol-toewijzing-composables (toekennen/intrekken + subject-rollen). */
|
|
54
|
+
export interface UseAssignments {
|
|
55
|
+
readonly subjectRoles: Ref<Role[]>;
|
|
56
|
+
readonly error: Ref<string | null>;
|
|
57
|
+
loadSubject(subjectId: string): Promise<void>;
|
|
58
|
+
assign(input: AssignmentRequest): Promise<boolean>;
|
|
59
|
+
revoke(input: AssignmentRequest): Promise<boolean>;
|
|
60
|
+
}
|
|
61
|
+
export declare function useAssignments(): UseAssignments;
|
|
62
|
+
//# sourceMappingURL=composables.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"composables.d.ts","sourceRoot":"","sources":["../../../frontend/src/composables.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Vue-composables (het mechanisme, provide/inject). Een dunne, reactieve laag bovenop de getypte
|
|
3
|
+
* authorization-client. De client wordt per app-instance geprovide (`provideAuthzClient`), zodat
|
|
4
|
+
* SSR-render en client-hydratie per request geïsoleerd blijven — geen module-globale mutable state.
|
|
5
|
+
*
|
|
6
|
+
* Stories: US-Z0405 (usePermissions — hydratie van `can`), US-Z0201..0203 (useRoles),
|
|
7
|
+
* US-Z0301/0305 (useAssignments).
|
|
8
|
+
*/
|
|
9
|
+
import { computed, inject, ref } from 'vue';
|
|
10
|
+
import { AuthzClientError } from './client.js';
|
|
11
|
+
/** De per-request client die op de app wordt geprovide. Symbool = module-constante (geen state). */
|
|
12
|
+
export const AUTHZ_CLIENT_KEY = Symbol('authz.client');
|
|
13
|
+
/** Registreer de authorization-client op een app-instance (bij bootstrap). */
|
|
14
|
+
export function provideAuthzClient(app, client) {
|
|
15
|
+
app.provide(AUTHZ_CLIENT_KEY, client);
|
|
16
|
+
}
|
|
17
|
+
/** Haal de getypte authorization-client op binnen setup(). Werpt als er niets geprovide is. */
|
|
18
|
+
export function useAuthzClient() {
|
|
19
|
+
const client = inject(AUTHZ_CLIENT_KEY);
|
|
20
|
+
if (client === undefined) {
|
|
21
|
+
throw new Error('[authz] useAuthzClient(): geen authorization-client geprovide. Roep provideAuthzClient(app, client) aan bij bootstrap.');
|
|
22
|
+
}
|
|
23
|
+
return client;
|
|
24
|
+
}
|
|
25
|
+
/** Vertaalt een gevangen fout naar een i18n-sleutel zonder details te lekken. */
|
|
26
|
+
function toI18nKey(cause) {
|
|
27
|
+
return cause instanceof AuthzClientError ? cause.i18nKey : 'authz.error.unknown';
|
|
28
|
+
}
|
|
29
|
+
function useAuthzAction(run) {
|
|
30
|
+
const pending = ref(false);
|
|
31
|
+
const error = ref(null);
|
|
32
|
+
const result = ref(null);
|
|
33
|
+
async function submit(input) {
|
|
34
|
+
pending.value = true;
|
|
35
|
+
error.value = null;
|
|
36
|
+
try {
|
|
37
|
+
const value = await run(input);
|
|
38
|
+
result.value = value;
|
|
39
|
+
return value;
|
|
40
|
+
}
|
|
41
|
+
catch (cause) {
|
|
42
|
+
error.value = toI18nKey(cause);
|
|
43
|
+
return undefined;
|
|
44
|
+
}
|
|
45
|
+
finally {
|
|
46
|
+
pending.value = false;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
return { pending, error, result, submit };
|
|
50
|
+
}
|
|
51
|
+
export function usePermissions() {
|
|
52
|
+
const client = useAuthzClient();
|
|
53
|
+
const permissions = ref([]);
|
|
54
|
+
const roles = ref([]);
|
|
55
|
+
const loaded = ref(false);
|
|
56
|
+
const pending = ref(false);
|
|
57
|
+
const permissionSet = computed(() => new Set(permissions.value));
|
|
58
|
+
async function reload() {
|
|
59
|
+
pending.value = true;
|
|
60
|
+
try {
|
|
61
|
+
const me = await client.mePermissions();
|
|
62
|
+
permissions.value = me.permissions;
|
|
63
|
+
roles.value = me.roles;
|
|
64
|
+
loaded.value = true;
|
|
65
|
+
}
|
|
66
|
+
finally {
|
|
67
|
+
pending.value = false;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
return {
|
|
71
|
+
permissions,
|
|
72
|
+
roles,
|
|
73
|
+
loaded,
|
|
74
|
+
pending,
|
|
75
|
+
can: (permission) => permissionSet.value.has(permission),
|
|
76
|
+
reload,
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
export function useRoles() {
|
|
80
|
+
const client = useAuthzClient();
|
|
81
|
+
const roles = ref([]);
|
|
82
|
+
const permissions = ref([]);
|
|
83
|
+
const pending = ref(false);
|
|
84
|
+
const error = ref(null);
|
|
85
|
+
async function refresh() {
|
|
86
|
+
pending.value = true;
|
|
87
|
+
error.value = null;
|
|
88
|
+
try {
|
|
89
|
+
const [roleList, permList] = await Promise.all([client.listRoles(), client.listPermissions()]);
|
|
90
|
+
roles.value = roleList.roles;
|
|
91
|
+
permissions.value = permList.permissions;
|
|
92
|
+
}
|
|
93
|
+
catch (cause) {
|
|
94
|
+
error.value = toI18nKey(cause);
|
|
95
|
+
}
|
|
96
|
+
finally {
|
|
97
|
+
pending.value = false;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
async function create(input) {
|
|
101
|
+
error.value = null;
|
|
102
|
+
try {
|
|
103
|
+
return await client.createRole(input);
|
|
104
|
+
}
|
|
105
|
+
catch (cause) {
|
|
106
|
+
error.value = toI18nKey(cause);
|
|
107
|
+
return undefined;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
async function update(id, patch) {
|
|
111
|
+
error.value = null;
|
|
112
|
+
try {
|
|
113
|
+
return await client.updateRole(id, patch);
|
|
114
|
+
}
|
|
115
|
+
catch (cause) {
|
|
116
|
+
error.value = toI18nKey(cause);
|
|
117
|
+
return undefined;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
async function remove(id) {
|
|
121
|
+
error.value = null;
|
|
122
|
+
try {
|
|
123
|
+
await client.deleteRole(id);
|
|
124
|
+
return true;
|
|
125
|
+
}
|
|
126
|
+
catch (cause) {
|
|
127
|
+
error.value = toI18nKey(cause);
|
|
128
|
+
return false;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
return { roles, permissions, pending, error, refresh, create, update, remove };
|
|
132
|
+
}
|
|
133
|
+
export function useAssignments() {
|
|
134
|
+
const client = useAuthzClient();
|
|
135
|
+
const subjectRoles = ref([]);
|
|
136
|
+
const error = ref(null);
|
|
137
|
+
async function loadSubject(subjectId) {
|
|
138
|
+
error.value = null;
|
|
139
|
+
try {
|
|
140
|
+
subjectRoles.value = (await client.subjectRoles(subjectId)).roles;
|
|
141
|
+
}
|
|
142
|
+
catch (cause) {
|
|
143
|
+
error.value = toI18nKey(cause);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
async function assign(input) {
|
|
147
|
+
error.value = null;
|
|
148
|
+
try {
|
|
149
|
+
await client.assignRole(input);
|
|
150
|
+
return true;
|
|
151
|
+
}
|
|
152
|
+
catch (cause) {
|
|
153
|
+
error.value = toI18nKey(cause);
|
|
154
|
+
return false;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
async function revoke(input) {
|
|
158
|
+
error.value = null;
|
|
159
|
+
try {
|
|
160
|
+
await client.revokeRole(input);
|
|
161
|
+
return true;
|
|
162
|
+
}
|
|
163
|
+
catch (cause) {
|
|
164
|
+
error.value = toI18nKey(cause);
|
|
165
|
+
return false;
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
return { subjectRoles, error, loadSubject, assign, revoke };
|
|
169
|
+
}
|
|
170
|
+
//# sourceMappingURL=composables.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"composables.js","sourceRoot":"","sources":["../../../frontend/src/composables.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Route-guards + gating (het mechanisme). De module levert kant-en-klare autorisatie-gating door de
|
|
3
|
+
* pure `access-control`-kit-adapters te composeren/her-exporteren: de `permissionGuard` (blokkeert
|
|
4
|
+
* routes zonder de vereiste permissie), de `<Can>`-component, de `v-can`-directive, `useCan()` en de
|
|
5
|
+
* evaluator-provider. De permissies komen via een geïnjecteerde bron (gehydrateerd uit
|
|
6
|
+
* `/authz/me/permissions`, US-Z0405) — geen module-globale state, SSR/hydratie-veilig.
|
|
7
|
+
*/
|
|
8
|
+
export { permissionGuard, createRedirectPolicy, Can, createCanDirective, providePermissions, useCan, PERMISSION_EVALUATOR_KEY, } from '@seifer-webapp-factory/kits/frontend/access-control/vue';
|
|
9
|
+
export type { RequiredPermissions, RedirectContext, RedirectPolicy, PermissionGuardOptions, RedirectTargets, } from '@seifer-webapp-factory/kits/frontend/access-control/vue';
|
|
10
|
+
export { createPermissionEvaluator, staticPermissionSource, claimsPermissionSource, } from '@seifer-webapp-factory/kits/frontend/access-control';
|
|
11
|
+
export type { PermissionEvaluator, PermissionSource, PermissionClaims, } from '@seifer-webapp-factory/kits/frontend/access-control';
|
|
12
|
+
//# sourceMappingURL=guards.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"guards.d.ts","sourceRoot":"","sources":["../../../frontend/src/guards.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,EACL,eAAe,EACf,oBAAoB,EACpB,GAAG,EACH,kBAAkB,EAClB,kBAAkB,EAClB,MAAM,EACN,wBAAwB,GACzB,MAAM,yDAAyD,CAAC;AACjE,YAAY,EACV,mBAAmB,EACnB,eAAe,EACf,cAAc,EACd,sBAAsB,EACtB,eAAe,GAChB,MAAM,yDAAyD,CAAC;AACjE,OAAO,EACL,yBAAyB,EACzB,sBAAsB,EACtB,sBAAsB,GACvB,MAAM,qDAAqD,CAAC;AAC7D,YAAY,EACV,mBAAmB,EACnB,gBAAgB,EAChB,gBAAgB,GACjB,MAAM,qDAAqD,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Route-guards + gating (het mechanisme). De module levert kant-en-klare autorisatie-gating door de
|
|
3
|
+
* pure `access-control`-kit-adapters te composeren/her-exporteren: de `permissionGuard` (blokkeert
|
|
4
|
+
* routes zonder de vereiste permissie), de `<Can>`-component, de `v-can`-directive, `useCan()` en de
|
|
5
|
+
* evaluator-provider. De permissies komen via een geïnjecteerde bron (gehydrateerd uit
|
|
6
|
+
* `/authz/me/permissions`, US-Z0405) — geen module-globale state, SSR/hydratie-veilig.
|
|
7
|
+
*/
|
|
8
|
+
export { permissionGuard, createRedirectPolicy, Can, createCanDirective, providePermissions, useCan, PERMISSION_EVALUATOR_KEY, } from '@seifer-webapp-factory/kits/frontend/access-control/vue';
|
|
9
|
+
export { createPermissionEvaluator, staticPermissionSource, claimsPermissionSource, } from '@seifer-webapp-factory/kits/frontend/access-control';
|
|
10
|
+
//# sourceMappingURL=guards.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"guards.js","sourceRoot":"","sources":["../../../frontend/src/guards.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,EACL,eAAe,EACf,oBAAoB,EACpB,GAAG,EACH,kBAAkB,EAClB,kBAAkB,EAClB,MAAM,EACN,wBAAwB,GACzB,MAAM,yDAAyD,CAAC;AAQjE,OAAO,EACL,yBAAyB,EACzB,sBAAsB,EACtB,sBAAsB,GACvB,MAAM,qDAAqD,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* authorization — de frontend-helft (het mechanisme). Barrel die de getypte client, de Vue-
|
|
3
|
+
* composables (provide/inject) en de gating/route-guards bundelt. Alle types leidt de consumer via het
|
|
4
|
+
* contract af; hier alleen het uitvoerbare mechanisme dat de frontend-kits samenbindt.
|
|
5
|
+
*/
|
|
6
|
+
export { createAuthzClient, AuthzClientError } from './client.js';
|
|
7
|
+
export type { AuthzClient, CreateAuthzClientOptions } from './client.js';
|
|
8
|
+
export { AUTHZ_CLIENT_KEY, provideAuthzClient, useAuthzClient, usePermissions, useRoles, useAssignments, } from './composables.js';
|
|
9
|
+
export type { UseAuthzAction, UsePermissions, UseRoles, UseAssignments } from './composables.js';
|
|
10
|
+
export { permissionGuard, createRedirectPolicy, Can, createCanDirective, providePermissions, useCan, createPermissionEvaluator, staticPermissionSource, claimsPermissionSource, PERMISSION_EVALUATOR_KEY, } from './guards.js';
|
|
11
|
+
export type { RequiredPermissions, RedirectContext, RedirectPolicy, PermissionGuardOptions, RedirectTargets, PermissionEvaluator, PermissionSource, PermissionClaims, } from './guards.js';
|
|
12
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../frontend/src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAClE,YAAY,EAAE,WAAW,EAAE,wBAAwB,EAAE,MAAM,aAAa,CAAC;AAEzE,OAAO,EACL,gBAAgB,EAChB,kBAAkB,EAClB,cAAc,EACd,cAAc,EACd,QAAQ,EACR,cAAc,GACf,MAAM,kBAAkB,CAAC;AAC1B,YAAY,EAAE,cAAc,EAAE,cAAc,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAEjG,OAAO,EACL,eAAe,EACf,oBAAoB,EACpB,GAAG,EACH,kBAAkB,EAClB,kBAAkB,EAClB,MAAM,EACN,yBAAyB,EACzB,sBAAsB,EACtB,sBAAsB,EACtB,wBAAwB,GACzB,MAAM,aAAa,CAAC;AACrB,YAAY,EACV,mBAAmB,EACnB,eAAe,EACf,cAAc,EACd,sBAAsB,EACtB,eAAe,EACf,mBAAmB,EACnB,gBAAgB,EAChB,gBAAgB,GACjB,MAAM,aAAa,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* authorization — de frontend-helft (het mechanisme). Barrel die de getypte client, de Vue-
|
|
3
|
+
* composables (provide/inject) en de gating/route-guards bundelt. Alle types leidt de consumer via het
|
|
4
|
+
* contract af; hier alleen het uitvoerbare mechanisme dat de frontend-kits samenbindt.
|
|
5
|
+
*/
|
|
6
|
+
export { createAuthzClient, AuthzClientError } from './client.js';
|
|
7
|
+
export { AUTHZ_CLIENT_KEY, provideAuthzClient, useAuthzClient, usePermissions, useRoles, useAssignments, } from './composables.js';
|
|
8
|
+
export { permissionGuard, createRedirectPolicy, Can, createCanDirective, providePermissions, useCan, createPermissionEvaluator, staticPermissionSource, claimsPermissionSource, PERMISSION_EVALUATOR_KEY, } from './guards.js';
|
|
9
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../frontend/src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAGlE,OAAO,EACL,gBAAgB,EAChB,kBAAkB,EAClB,cAAc,EACd,cAAc,EACd,QAAQ,EACR,cAAc,GACf,MAAM,kBAAkB,CAAC;AAG1B,OAAO,EACL,eAAe,EACf,oBAAoB,EACpB,GAAG,EACH,kBAAkB,EAClB,kBAAkB,EAClB,MAAM,EACN,yBAAyB,EACzB,sBAAsB,EACtB,sBAAsB,EACtB,wBAAwB,GACzB,MAAM,aAAa,CAAC"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/** De genormaliseerde vorm van een capability-module-manifest (identiek aan de authentication-tier). */
|
|
2
|
+
export interface CapabilityModuleManifest {
|
|
3
|
+
readonly name: string;
|
|
4
|
+
readonly version: string;
|
|
5
|
+
readonly templateVersion: string;
|
|
6
|
+
readonly provides: {
|
|
7
|
+
readonly routes: readonly string[];
|
|
8
|
+
readonly backendRoutes: readonly string[];
|
|
9
|
+
readonly capabilities: readonly string[];
|
|
10
|
+
};
|
|
11
|
+
readonly requires: {
|
|
12
|
+
readonly kits: {
|
|
13
|
+
readonly backend: readonly string[];
|
|
14
|
+
readonly frontend: readonly string[];
|
|
15
|
+
};
|
|
16
|
+
readonly ports: readonly string[];
|
|
17
|
+
/** Andere capability-modules waarvan deze afhangt (US-Z0803 presence-check). */
|
|
18
|
+
readonly modules?: readonly string[];
|
|
19
|
+
};
|
|
20
|
+
readonly contract: string;
|
|
21
|
+
readonly config: unknown;
|
|
22
|
+
readonly migrations: readonly string[];
|
|
23
|
+
readonly surface: readonly string[];
|
|
24
|
+
readonly mechanism: readonly string[];
|
|
25
|
+
}
|
|
26
|
+
/** De concrete manifest van de authorization-module. */
|
|
27
|
+
export declare const authorizationManifest: {
|
|
28
|
+
name: string;
|
|
29
|
+
version: string;
|
|
30
|
+
templateVersion: string;
|
|
31
|
+
provides: {
|
|
32
|
+
routes: string[];
|
|
33
|
+
backendRoutes: readonly string[];
|
|
34
|
+
capabilities: string[];
|
|
35
|
+
};
|
|
36
|
+
requires: {
|
|
37
|
+
kits: {
|
|
38
|
+
backend: string[];
|
|
39
|
+
frontend: string[];
|
|
40
|
+
};
|
|
41
|
+
ports: string[];
|
|
42
|
+
modules: string[];
|
|
43
|
+
};
|
|
44
|
+
contract: string;
|
|
45
|
+
config: undefined;
|
|
46
|
+
migrations: string[];
|
|
47
|
+
surface: string[];
|
|
48
|
+
mechanism: string[];
|
|
49
|
+
};
|
|
50
|
+
/**
|
|
51
|
+
* Valideert een capability-module-manifest. Naast de bekende checks (verplichte velden, geen dubbele
|
|
52
|
+
* kit binnen een stack) borgt deze variant dat een opgegeven `requires.modules` niet-leeg en uniek is
|
|
53
|
+
* (US-Z0801) — het is de basis voor de scaffolder-presence-check (US-Z0803).
|
|
54
|
+
*/
|
|
55
|
+
export declare function validateManifest(m: CapabilityModuleManifest): CapabilityModuleManifest;
|
|
56
|
+
//# sourceMappingURL=manifest.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manifest.d.ts","sourceRoot":"","sources":["../manifest.ts"],"names":[],"mappings":"AAUA,wGAAwG;AACxG,MAAM,WAAW,wBAAwB;IACvC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,QAAQ,EAAE;QACjB,QAAQ,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC;QACnC,QAAQ,CAAC,aAAa,EAAE,SAAS,MAAM,EAAE,CAAC;QAC1C,QAAQ,CAAC,YAAY,EAAE,SAAS,MAAM,EAAE,CAAC;KAC1C,CAAC;IACF,QAAQ,CAAC,QAAQ,EAAE;QACjB,QAAQ,CAAC,IAAI,EAAE;YACb,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;YACpC,QAAQ,CAAC,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAC;SACtC,CAAC;QACF,QAAQ,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;QAClC,gFAAgF;QAChF,QAAQ,CAAC,OAAO,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;KACtC,CAAC;IACF,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IACzB,QAAQ,CAAC,UAAU,EAAE,SAAS,MAAM,EAAE,CAAC;IACvC,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;IACpC,QAAQ,CAAC,SAAS,EAAE,SAAS,MAAM,EAAE,CAAC;CACvC;AAQD,wDAAwD;AACxD,eAAO,MAAM,qBAAqB;;;;;;;;;;;;;;;;;;;;;;CAsBE,CAAC;AAYrC;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,wBAAwB,GAAG,wBAAwB,CAmCtF"}
|