@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,84 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
/**
|
|
3
|
+
* US-Z0204 — Roles-list-pagina (surface, gematerialiseerd, mag divergeren). Toont de rollen via de
|
|
4
|
+
* pinned `useRoles`-composable (mechanism) over de getypte contract-client (US-Z0105) tegen
|
|
5
|
+
* `GET /authz/roles`. De hele beheer-surface is gegate met `<Can permission="authz.manage">`
|
|
6
|
+
* (mechanism, default-deny aan de UI-kant, US-Z0405/US-Z0701): een subject zonder de beheer-
|
|
7
|
+
* permissie ziet de lijst en de "nieuwe rol"-affordance niet — en er lekt geen tekst of route die
|
|
8
|
+
* het bestaan ervan verraadt (no-catalog-leak, US-Z0703). Serverfouten uit de taxonomie (US-Z0102)
|
|
9
|
+
* worden via i18n vertaald en in een `aria-live`-regio getoond. Geen eigen transport.
|
|
10
|
+
*/
|
|
11
|
+
import { onMounted } from 'vue';
|
|
12
|
+
import { Can } from '../../src/index.js';
|
|
13
|
+
import { useRoles } from '../../src/composables.js';
|
|
14
|
+
import { useTranslate } from '../runtime.js';
|
|
15
|
+
|
|
16
|
+
const t = useTranslate();
|
|
17
|
+
const roles = useRoles();
|
|
18
|
+
|
|
19
|
+
onMounted(async () => {
|
|
20
|
+
await roles.refresh();
|
|
21
|
+
});
|
|
22
|
+
</script>
|
|
23
|
+
|
|
24
|
+
<template>
|
|
25
|
+
<Can permission="authz.manage">
|
|
26
|
+
<section class="authz-page authz-page--roles-list">
|
|
27
|
+
<header class="authz-page__header">
|
|
28
|
+
<h1 class="authz-page__title">{{ t('authz.roles.title') }}</h1>
|
|
29
|
+
<p class="authz-page__subtitle">{{ t('authz.roles.subtitle') }}</p>
|
|
30
|
+
<a class="authz-page__action" href="/admin/roles/new" data-testid="authz-roles-new">
|
|
31
|
+
{{ t('authz.roles.new') }}
|
|
32
|
+
</a>
|
|
33
|
+
</header>
|
|
34
|
+
|
|
35
|
+
<p
|
|
36
|
+
v-if="roles.error.value !== null"
|
|
37
|
+
class="authz-page__error"
|
|
38
|
+
role="alert"
|
|
39
|
+
aria-live="assertive"
|
|
40
|
+
data-testid="authz-roles-error"
|
|
41
|
+
>
|
|
42
|
+
{{ t(roles.error.value) }}
|
|
43
|
+
</p>
|
|
44
|
+
|
|
45
|
+
<p v-if="roles.pending.value" class="authz-page__status" role="status" aria-live="polite">
|
|
46
|
+
{{ t('authz.roles.loading') }}
|
|
47
|
+
</p>
|
|
48
|
+
|
|
49
|
+
<p v-else-if="roles.roles.value.length === 0" class="authz-page__empty">
|
|
50
|
+
{{ t('authz.roles.empty') }}
|
|
51
|
+
</p>
|
|
52
|
+
|
|
53
|
+
<table v-else class="authz-roles__table">
|
|
54
|
+
<thead>
|
|
55
|
+
<tr>
|
|
56
|
+
<th scope="col">{{ t('authz.roles.colKey') }}</th>
|
|
57
|
+
<th scope="col">{{ t('authz.roles.colName') }}</th>
|
|
58
|
+
<th scope="col">{{ t('authz.roles.colPermissions') }}</th>
|
|
59
|
+
<th scope="col">{{ t('authz.roles.colParent') }}</th>
|
|
60
|
+
</tr>
|
|
61
|
+
</thead>
|
|
62
|
+
<tbody>
|
|
63
|
+
<tr v-for="role in roles.roles.value" :key="role.id" class="authz-roles__row">
|
|
64
|
+
<th scope="row"><code>{{ role.key }}</code></th>
|
|
65
|
+
<td>
|
|
66
|
+
<a :href="`/admin/roles/${role.id}`">{{ role.name }}</a>
|
|
67
|
+
</td>
|
|
68
|
+
<td>
|
|
69
|
+
<span v-if="role.permissions.length === 0" class="authz-roles__muted">
|
|
70
|
+
{{ t('authz.roles.noPermissions') }}
|
|
71
|
+
</span>
|
|
72
|
+
<ul v-else class="authz-roles__permissions">
|
|
73
|
+
<li v-for="permission in role.permissions" :key="permission">
|
|
74
|
+
<code>{{ permission }}</code>
|
|
75
|
+
</li>
|
|
76
|
+
</ul>
|
|
77
|
+
</td>
|
|
78
|
+
<td>{{ role.parentRoleId ?? t('authz.roles.noParent') }}</td>
|
|
79
|
+
</tr>
|
|
80
|
+
</tbody>
|
|
81
|
+
</table>
|
|
82
|
+
</section>
|
|
83
|
+
</Can>
|
|
84
|
+
</template>
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* US-Z0405/US-Z0503 — Authz-bootstrap-plugin (surface, gematerialiseerd, Nuxt client-plugin). Bindt
|
|
3
|
+
* de frontend-kits en het mechanisme samen tot één per-app-instance geheel — géén module-globale
|
|
4
|
+
* mutable state:
|
|
5
|
+
*
|
|
6
|
+
* 1. `createHttpClient` met een `fetchTransport` die cookies meestuurt (`credentials: 'include'`),
|
|
7
|
+
* zodat de auth-sessie/CSRF-cookies automatisch meereizen (module→module op authentication).
|
|
8
|
+
* 2. `createAuthzClient` (het mechanisme) rond die http-client → `provideAuthzClient`.
|
|
9
|
+
* 3. De permissie-hydratie + evaluator: `usePermissions().reload()` haalt de effectieve permissies
|
|
10
|
+
* uit `/authz/me/permissions` (US-Z0405); een `claimsPermissionSource` leest die reactief uit en
|
|
11
|
+
* voedt een `createPermissionEvaluator` die via `providePermissions` de gating aandrijft
|
|
12
|
+
* (`<Can>`/`v-can`/`permissionGuard` — deny-by-default, US-Z0701).
|
|
13
|
+
* 4. i18n-, notifications- en navigate-providers voor de surface-pagina's.
|
|
14
|
+
*
|
|
15
|
+
* Dit bestand is een template dat in de host-Nuxt-app wordt gematerialiseerd; het draait niet in de
|
|
16
|
+
* vitest-render-tests (die injecteren een fake client + evaluator rechtstreeks).
|
|
17
|
+
*/
|
|
18
|
+
import { createHttpClient, fetchTransport } from '@seifer-webapp-factory/kits/frontend/http-client';
|
|
19
|
+
import {
|
|
20
|
+
createNotifications,
|
|
21
|
+
systemClock as notifyClock,
|
|
22
|
+
realScheduler as notifyScheduler,
|
|
23
|
+
} from '@seifer-webapp-factory/kits/frontend/notifications';
|
|
24
|
+
import { provideNotifications } from '@seifer-webapp-factory/kits/frontend/notifications/vue';
|
|
25
|
+
import { createI18n, provideI18n } from '@seifer-webapp-factory/kits/frontend/i18n/vue';
|
|
26
|
+
import { staticCatalogLoader } from '@seifer-webapp-factory/kits/frontend/i18n';
|
|
27
|
+
import { createAuthzClient } from '../../src/index.js';
|
|
28
|
+
import {
|
|
29
|
+
provideAuthzClient,
|
|
30
|
+
usePermissions,
|
|
31
|
+
} from '../../src/composables.js';
|
|
32
|
+
import {
|
|
33
|
+
claimsPermissionSource,
|
|
34
|
+
createPermissionEvaluator,
|
|
35
|
+
providePermissions,
|
|
36
|
+
} from '../../src/index.js';
|
|
37
|
+
import { provideNavigate } from '../runtime.js';
|
|
38
|
+
import nl from '../i18n/nl.json';
|
|
39
|
+
import en from '../i18n/en.json';
|
|
40
|
+
|
|
41
|
+
// `defineNuxtPlugin`, `navigateTo`, `useRuntimeConfig` zijn Nuxt auto-imports (host-context).
|
|
42
|
+
declare const defineNuxtPlugin: <T>(setup: (nuxtApp: NuxtAppLike) => T) => unknown;
|
|
43
|
+
declare const navigateTo: (to: string) => unknown;
|
|
44
|
+
declare const useRuntimeConfig: () => { public?: { authzBaseUrl?: string } };
|
|
45
|
+
|
|
46
|
+
interface NuxtAppLike {
|
|
47
|
+
readonly vueApp: import('vue').App;
|
|
48
|
+
provide(name: string, value: unknown): void;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export default defineNuxtPlugin(async (nuxtApp) => {
|
|
52
|
+
const app = nuxtApp.vueApp;
|
|
53
|
+
|
|
54
|
+
// 1. HTTP-client met cookie-transport (auth-sessie + CSRF via httpOnly-cookies reizen mee).
|
|
55
|
+
const baseUrl = useRuntimeConfig().public?.authzBaseUrl ?? '/api';
|
|
56
|
+
const credentialledFetch: typeof fetch = (input, init) =>
|
|
57
|
+
fetch(input, { ...init, credentials: 'include' });
|
|
58
|
+
const http = createHttpClient({
|
|
59
|
+
transport: fetchTransport(credentialledFetch),
|
|
60
|
+
baseUrl,
|
|
61
|
+
defaultHeaders: { accept: 'application/json' },
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
// 2. Het mechanisme: de getypte authorization-client.
|
|
65
|
+
const client = createAuthzClient({ http });
|
|
66
|
+
provideAuthzClient(app, client);
|
|
67
|
+
|
|
68
|
+
// 3. Permissie-hydratie + de deny-by-default evaluator die de gating aandrijft. `usePermissions`
|
|
69
|
+
// en `providePermissions` draaien binnen de app-context zodat `inject` de client vindt.
|
|
70
|
+
await app.runWithContext(async () => {
|
|
71
|
+
const permissions = usePermissions();
|
|
72
|
+
const evaluator = createPermissionEvaluator(
|
|
73
|
+
claimsPermissionSource(() => ({
|
|
74
|
+
roles: permissions.roles.value,
|
|
75
|
+
permissions: permissions.permissions.value,
|
|
76
|
+
})),
|
|
77
|
+
);
|
|
78
|
+
providePermissions(app, evaluator);
|
|
79
|
+
// Voor de route-middleware (US-Z0503): de evaluator op de Nuxt-app.
|
|
80
|
+
nuxtApp.provide('authzEvaluator', evaluator);
|
|
81
|
+
|
|
82
|
+
// Hydrateer de effectieve permissies. Anoniem/onvoldoende => stil deny-by-default (geen leak).
|
|
83
|
+
try {
|
|
84
|
+
await permissions.reload();
|
|
85
|
+
} catch {
|
|
86
|
+
// Geen (geldige) sessie: de claims blijven leeg; de evaluator weigert alles. Geen fout lekken.
|
|
87
|
+
}
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
// 4. Cross-cutting providers voor de surface-pagina's.
|
|
91
|
+
const i18n = await createI18n({
|
|
92
|
+
loader: staticCatalogLoader({ nl, en }),
|
|
93
|
+
supported: ['nl', 'en'],
|
|
94
|
+
defaultLocale: 'nl',
|
|
95
|
+
initialLocale: 'nl',
|
|
96
|
+
});
|
|
97
|
+
provideI18n(app, i18n);
|
|
98
|
+
|
|
99
|
+
const notifications = createNotifications({
|
|
100
|
+
clock: notifyClock(),
|
|
101
|
+
scheduler: notifyScheduler(),
|
|
102
|
+
});
|
|
103
|
+
provideNotifications(app, notifications);
|
|
104
|
+
|
|
105
|
+
provideNavigate(app, (to) => {
|
|
106
|
+
navigateTo(to);
|
|
107
|
+
});
|
|
108
|
+
});
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Kleine, test-veilige runtime-helpers voor de authorization-surface-pagina's. Géén mechanisme —
|
|
3
|
+
* puur glue die de pagina's los-koppelt van het host-framework (Nuxt) zodat ze óók bloot in vitest
|
|
4
|
+
* renderen. Alle helpers zijn per-instance / injectie-gebaseerd: geen module-globale mutable state.
|
|
5
|
+
*
|
|
6
|
+
* - `useTranslate()` — leest de i18n-kit-instance als die geprovide is, valt anders veilig terug op
|
|
7
|
+
* de sleutel zelf (zodat een pagina zonder i18n-provider tóch rendert; tests zien de sleutel).
|
|
8
|
+
* - `useNavigate()` / `provideNavigate()` — injecteerbare navigatie; de Nuxt-plugin wired hier
|
|
9
|
+
* `navigateTo`; zonder provider is het een no-op (tests hoeven geen router).
|
|
10
|
+
* - `readQueryParam()` — leest een query-parameter (bv. `id`, `subject`) uit `window.location`,
|
|
11
|
+
* test-veilig (happy-dom) en client-safe.
|
|
12
|
+
* - `useOptionalToasts()` — leest de notifications-toast-store als die geprovide is, anders `undefined`.
|
|
13
|
+
*/
|
|
14
|
+
import { inject, type App, type InjectionKey } from 'vue';
|
|
15
|
+
import { I18N_KEY } from '@seifer-webapp-factory/kits/frontend/i18n/vue';
|
|
16
|
+
import { TOAST_STORE_KEY } from '@seifer-webapp-factory/kits/frontend/notifications/vue';
|
|
17
|
+
import type { UseToasts } from '@seifer-webapp-factory/kits/frontend/notifications/vue';
|
|
18
|
+
|
|
19
|
+
/** Vertaal-functie: sleutel (+ optionele interpolatie-params) → gelokaliseerde tekst. */
|
|
20
|
+
export type TranslateFn = (key: string, params?: Readonly<Record<string, unknown>>) => string;
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Levert een vertaal-functie. Met geprovide i18n-kit: echte vertaling. Zonder: identiteit (de
|
|
24
|
+
* sleutel zelf), zodat een surface-pagina ook zonder i18n-provider rendert.
|
|
25
|
+
*/
|
|
26
|
+
export function useTranslate(): TranslateFn {
|
|
27
|
+
const i18n = inject(I18N_KEY, undefined);
|
|
28
|
+
return (key, params) => (i18n !== undefined ? i18n.t(key, params) : key);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/** Navigatie-functie: stuurt de gebruiker naar een pad (bv. naar de role-editor). */
|
|
32
|
+
export type NavigateFn = (to: string) => void;
|
|
33
|
+
|
|
34
|
+
/** Injectie-sleutel voor de navigator. Module-constante (geen mutable state). */
|
|
35
|
+
export const AUTHZ_NAVIGATE_KEY: InjectionKey<NavigateFn> = Symbol('authz.navigate');
|
|
36
|
+
|
|
37
|
+
/** Registreer de navigator op een app-instance (de Nuxt-plugin wired hier `navigateTo`). */
|
|
38
|
+
export function provideNavigate(app: App, navigate: NavigateFn): void {
|
|
39
|
+
app.provide(AUTHZ_NAVIGATE_KEY, navigate);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/** Haal de navigator op binnen setup(). Zonder provider: een veilige no-op. */
|
|
43
|
+
export function useNavigate(): NavigateFn {
|
|
44
|
+
return inject(AUTHZ_NAVIGATE_KEY, () => {});
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Lees een query-parameter uit de huidige URL. Test-veilig (happy-dom levert `window.location`) en
|
|
49
|
+
* client-safe. Zonder `window` (SSR): lege string.
|
|
50
|
+
*/
|
|
51
|
+
export function readQueryParam(name: string): string {
|
|
52
|
+
if (typeof window === 'undefined' || window.location == null) return '';
|
|
53
|
+
return new URLSearchParams(window.location.search).get(name) ?? '';
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/** Haal de (optionele) toast-store op; `undefined` als notifications niet geprovide is. */
|
|
57
|
+
export function useOptionalToasts(): UseToasts['success'] | undefined {
|
|
58
|
+
const store = inject(TOAST_STORE_KEY, undefined);
|
|
59
|
+
return store?.success;
|
|
60
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@seifer-webapp-factory/authorization",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "authorization — tweede capability-module: verticale, pluggable full-stack autorisatie-feature (RBAC + rol-hiërarchie, rol-toewijzing, default-deny-enforcement via een PDP-guard, optionele ReBAC, admin-UI) die de kits samenbindt via één contract. Eerste module met een module→module-afhankelijkheid op authentication.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"exports": {
|
|
8
|
+
"./contract": {
|
|
9
|
+
"types": "./dist/contract/index.d.ts",
|
|
10
|
+
"import": "./dist/contract/index.js"
|
|
11
|
+
},
|
|
12
|
+
"./backend": {
|
|
13
|
+
"types": "./dist/backend/src/index.d.ts",
|
|
14
|
+
"import": "./dist/backend/src/index.js"
|
|
15
|
+
},
|
|
16
|
+
"./frontend": {
|
|
17
|
+
"types": "./dist/frontend/src/index.d.ts",
|
|
18
|
+
"import": "./dist/frontend/src/index.js"
|
|
19
|
+
},
|
|
20
|
+
"./manifest": {
|
|
21
|
+
"types": "./dist/manifest.d.ts",
|
|
22
|
+
"import": "./dist/manifest.js"
|
|
23
|
+
},
|
|
24
|
+
"./scaffolder": {
|
|
25
|
+
"types": "./dist/scaffolder/index.d.ts",
|
|
26
|
+
"import": "./dist/scaffolder/index.js"
|
|
27
|
+
}
|
|
28
|
+
},
|
|
29
|
+
"scripts": {
|
|
30
|
+
"build": "tsc -p tsconfig.build.json",
|
|
31
|
+
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
32
|
+
"typecheck:backend": "tsc -p tsconfig.backend.json",
|
|
33
|
+
"test": "vitest run",
|
|
34
|
+
"test:e2e": "vitest run -c vitest.e2e.config.ts"
|
|
35
|
+
},
|
|
36
|
+
"peerDependencies": {
|
|
37
|
+
"vue": "^3.4.0",
|
|
38
|
+
"zod": "^3.23.0",
|
|
39
|
+
"@seifer-webapp-factory/kits": "^0.1.0"
|
|
40
|
+
},
|
|
41
|
+
"devDependencies": {
|
|
42
|
+
"@nestjs/common": "^10.4.22",
|
|
43
|
+
"@nestjs/core": "^10.4.22",
|
|
44
|
+
"@nestjs/platform-express": "^10.4.22",
|
|
45
|
+
"@nestjs/testing": "^10.4.22",
|
|
46
|
+
"@playwright/test": "^1.50.0",
|
|
47
|
+
"@types/pg": "^8.20.0",
|
|
48
|
+
"@types/supertest": "^6.0.0",
|
|
49
|
+
"@vitejs/plugin-vue": "^5.2.0",
|
|
50
|
+
"@vue/test-utils": "^2.4.0",
|
|
51
|
+
"express": "^4.21.0",
|
|
52
|
+
"happy-dom": "^15.0.0",
|
|
53
|
+
"pg": "^8.22.0",
|
|
54
|
+
"reflect-metadata": "^0.2.2",
|
|
55
|
+
"rxjs": "^7.8.2",
|
|
56
|
+
"supertest": "^7.0.0",
|
|
57
|
+
"testcontainers": "^10.28.0",
|
|
58
|
+
"tsx": "^4.23.0",
|
|
59
|
+
"typescript": "^5.7.0",
|
|
60
|
+
"vite": "^5.4.0",
|
|
61
|
+
"vitest": "^2.1.0",
|
|
62
|
+
"vue": "^3.4.0",
|
|
63
|
+
"vue-router": "^4.4.0",
|
|
64
|
+
"zod": "^3.24.0",
|
|
65
|
+
"@seifer-webapp-factory/kits": "^0.1.0"
|
|
66
|
+
},
|
|
67
|
+
"engines": {
|
|
68
|
+
"node": ">=20"
|
|
69
|
+
},
|
|
70
|
+
"files": [
|
|
71
|
+
"dist",
|
|
72
|
+
"backend/templates",
|
|
73
|
+
"frontend/templates",
|
|
74
|
+
"README.md"
|
|
75
|
+
]
|
|
76
|
+
}
|