@octabits-io/nuxt-ui-kit 0.2.0 → 0.3.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/dist/api/index.d.ts +65 -0
- package/dist/api/index.js +51 -0
- package/dist/auth/index.d.ts +240 -0
- package/dist/auth/index.js +273 -0
- package/dist/i18n/index.d.ts +49 -0
- package/dist/i18n/index.js +80 -0
- package/dist/index.d.ts +65 -310
- package/dist/index.js +70 -325
- package/dist/locale/index.d.ts +140 -0
- package/dist/locale/index.js +140 -0
- package/dist/zod/index.d.ts +23 -1
- package/dist/zod/index.js +44 -1
- package/package.json +33 -2
- package/src/components/LocaleInput.vue +132 -0
- package/src/components/LocaleTab.vue +44 -0
- package/src/components/LocaleTextarea.vue +131 -0
- package/src/components/PageAction.vue +88 -0
- package/src/components/PageActionMenu.vue +34 -0
- package/src/components/PageHeader.vue +110 -0
- package/src/components/PageUtilityActions.vue +31 -0
- package/src/components/SubSidebar.vue +10 -1
- package/src/components/TranslationBadge.vue +65 -0
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
//#region src/i18n/index.ts
|
|
2
|
+
const kitMessagesEn = {
|
|
3
|
+
errors: {
|
|
4
|
+
internal_server_error: "An unexpected error occurred",
|
|
5
|
+
not_found: "Resource not found",
|
|
6
|
+
forbidden: "Permission denied",
|
|
7
|
+
validation_error: "Validation error",
|
|
8
|
+
unique_violation: "This value already exists",
|
|
9
|
+
foreign_key_violation: "Referenced record does not exist",
|
|
10
|
+
service_unavailable: "Service temporarily unavailable. Please try again later."
|
|
11
|
+
},
|
|
12
|
+
auth: {
|
|
13
|
+
sessionRenewFailedTitle: "Session refresh failed",
|
|
14
|
+
sessionRenewFailedDescription: "We couldn't refresh your session. You may need to sign in again.",
|
|
15
|
+
sessionExpiredTitle: "Session expired",
|
|
16
|
+
sessionExpiredDescription: "Your session has expired. Please sign in again.",
|
|
17
|
+
signingIn: "Completing sign in..."
|
|
18
|
+
},
|
|
19
|
+
localeField: {
|
|
20
|
+
translate: "Translate empty languages with AI",
|
|
21
|
+
translateDone: "No translations added | {count} translation added | {count} translations added",
|
|
22
|
+
inheritsBaseLocale: "Inherits the base locale",
|
|
23
|
+
translationStatus: {
|
|
24
|
+
complete: "All translations complete",
|
|
25
|
+
missing: "Missing translations — {details}"
|
|
26
|
+
}
|
|
27
|
+
},
|
|
28
|
+
pageChrome: {
|
|
29
|
+
back: "Back",
|
|
30
|
+
moreActions: "More actions",
|
|
31
|
+
help: "Help"
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
const kitMessagesDe = {
|
|
35
|
+
errors: {
|
|
36
|
+
internal_server_error: "Ein unerwarteter Fehler ist aufgetreten",
|
|
37
|
+
not_found: "Ressource nicht gefunden",
|
|
38
|
+
forbidden: "Zugriff verweigert",
|
|
39
|
+
validation_error: "Validierungsfehler",
|
|
40
|
+
unique_violation: "Dieser Wert existiert bereits",
|
|
41
|
+
foreign_key_violation: "Der referenzierte Datensatz existiert nicht",
|
|
42
|
+
service_unavailable: "Dienst vorübergehend nicht verfügbar. Bitte versuche es später erneut."
|
|
43
|
+
},
|
|
44
|
+
auth: {
|
|
45
|
+
sessionRenewFailedTitle: "Sitzung konnte nicht erneuert werden",
|
|
46
|
+
sessionRenewFailedDescription: "Wir konnten deine Sitzung nicht erneuern. Eventuell musst du dich neu anmelden.",
|
|
47
|
+
sessionExpiredTitle: "Sitzung abgelaufen",
|
|
48
|
+
sessionExpiredDescription: "Deine Sitzung ist abgelaufen. Bitte melde dich erneut an.",
|
|
49
|
+
signingIn: "Anmeldung wird abgeschlossen..."
|
|
50
|
+
},
|
|
51
|
+
localeField: {
|
|
52
|
+
translate: "Fehlende Sprachen mit KI übersetzen",
|
|
53
|
+
translateDone: "Keine Übersetzungen eingefügt | {count} Übersetzung eingefügt | {count} Übersetzungen eingefügt",
|
|
54
|
+
inheritsBaseLocale: "Übernimmt die Basissprache",
|
|
55
|
+
translationStatus: {
|
|
56
|
+
complete: "Alle Übersetzungen vollständig",
|
|
57
|
+
missing: "Fehlende Übersetzungen — {details}"
|
|
58
|
+
}
|
|
59
|
+
},
|
|
60
|
+
pageChrome: {
|
|
61
|
+
back: "Zurück",
|
|
62
|
+
moreActions: "Weitere Aktionen",
|
|
63
|
+
help: "Hilfe"
|
|
64
|
+
}
|
|
65
|
+
};
|
|
66
|
+
const kitMessagesDeFormal = {
|
|
67
|
+
errors: {
|
|
68
|
+
...kitMessagesDe.errors,
|
|
69
|
+
service_unavailable: "Dienst vorübergehend nicht verfügbar. Bitte versuchen Sie es später erneut."
|
|
70
|
+
},
|
|
71
|
+
auth: {
|
|
72
|
+
...kitMessagesDe.auth,
|
|
73
|
+
sessionRenewFailedDescription: "Wir konnten Ihre Sitzung nicht erneuern. Eventuell müssen Sie sich neu anmelden.",
|
|
74
|
+
sessionExpiredDescription: "Ihre Sitzung ist abgelaufen. Bitte melden Sie sich erneut an."
|
|
75
|
+
},
|
|
76
|
+
localeField: kitMessagesDe.localeField,
|
|
77
|
+
pageChrome: kitMessagesDe.pageChrome
|
|
78
|
+
};
|
|
79
|
+
//#endregion
|
|
80
|
+
export { kitMessagesDe, kitMessagesDeFormal, kitMessagesEn };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,299 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { ComputedRef, Ref } from "vue";
|
|
3
|
-
import { Treaty } from "@elysiajs/eden";
|
|
4
|
-
import { Elysia } from "elysia";
|
|
5
|
-
//#region src/auth/oidc.d.ts
|
|
6
|
-
/** Issuer + client id, resolved at first use (client-side runtime config). */
|
|
7
|
-
interface OidcClientConfig {
|
|
8
|
-
issuerUrl: string;
|
|
9
|
-
clientId: string;
|
|
10
|
-
}
|
|
11
|
-
interface UserManagerFactoryOptions {
|
|
12
|
-
/**
|
|
13
|
-
* Resolve the issuer/client pair lazily — typically from a runtime-injected
|
|
14
|
-
* config object (e.g. a K8s-entrypoint `window.__APP_CONFIG__`) falling back
|
|
15
|
-
* to the app's build-time config.
|
|
16
|
-
*/
|
|
17
|
-
getConfig: () => OidcClientConfig;
|
|
18
|
-
/** OAuth scopes requested on the initial signin. */
|
|
19
|
-
scope: string;
|
|
20
|
-
/**
|
|
21
|
-
* Scopes sent on the refresh-token grant when the IdP restricts them to a
|
|
22
|
-
* subset of the signin scopes (see `ZITADEL_REFRESH_TOKEN_ALLOWED_SCOPE`).
|
|
23
|
-
*/
|
|
24
|
-
refreshTokenAllowedScope?: string;
|
|
25
|
-
/** Path the IdP redirects back to after signin. Default `/auth/callback`. */
|
|
26
|
-
redirectPath?: string;
|
|
27
|
-
/** Path the IdP redirects to after logout. Default `/login`. */
|
|
28
|
-
postLogoutRedirectPath?: string;
|
|
29
|
-
/** Default `true`. */
|
|
30
|
-
automaticSilentRenew?: boolean;
|
|
31
|
-
/** Raw oidc-client-ts settings escape hatch, applied last. */
|
|
32
|
-
settings?: Partial<UserManagerSettings>;
|
|
33
|
-
/** Called when issuer/client resolve empty. Default `console.error`. */
|
|
34
|
-
onMissingConfig?: (message: string) => void;
|
|
35
|
-
}
|
|
36
|
-
/**
|
|
37
|
-
* Lazily-created `UserManager` singleton bound to `window.localStorage`.
|
|
38
|
-
* Call the returned getter from plugins/stores/composables — the manager is
|
|
39
|
-
* constructed on first call (client-side only; requires `window`).
|
|
40
|
-
*/
|
|
41
|
-
declare function createUserManagerFactory(options: UserManagerFactoryOptions): () => UserManager;
|
|
42
|
-
type StaleKeyStorage = Pick<Storage, 'length' | 'key' | 'removeItem'>;
|
|
43
|
-
/**
|
|
44
|
-
* Remove any `oidc.user:` storage keys that don't belong to the current
|
|
45
|
-
* authority+clientId — leftovers from environment switches would otherwise
|
|
46
|
-
* shadow or bloat the session storage.
|
|
47
|
-
*/
|
|
48
|
-
declare function removeStaleOidcKeys(authority: string, clientId: string, storage?: StaleKeyStorage): void;
|
|
49
|
-
/** Refresh tokens fail unrecoverably with these OIDC error codes — user must re-auth. */
|
|
50
|
-
declare function isUnrecoverableRenewError(message: string): boolean;
|
|
51
|
-
interface LoginRedirectorOptions {
|
|
52
|
-
getUserManager: () => UserManager;
|
|
53
|
-
/** Fallback login page for when `signinRedirect` itself fails. Default `/login`. */
|
|
54
|
-
loginPath?: string;
|
|
55
|
-
/**
|
|
56
|
-
* Paths where redirecting to login would loop (the login/callback pages
|
|
57
|
-
* themselves). Default: `loginPath` and anything under `/auth/`.
|
|
58
|
-
*/
|
|
59
|
-
isAuthRoute?: (path: string) => boolean;
|
|
60
|
-
/** Default `console.error`. */
|
|
61
|
-
log?: (message: string, detail?: unknown) => void;
|
|
62
|
-
}
|
|
63
|
-
/**
|
|
64
|
-
* Build a `redirectToLogin()` that starts an OIDC signin redirect carrying the
|
|
65
|
-
* current path as returnUrl state, with a plain `/login?redirect=` navigation
|
|
66
|
-
* fallback when the IdP redirect cannot even be started. No-ops on auth routes.
|
|
67
|
-
*/
|
|
68
|
-
declare function createLoginRedirector(options: LoginRedirectorOptions): () => Promise<void>;
|
|
69
|
-
/**
|
|
70
|
-
* A user-facing session event the app should surface (toast/banner). The kit
|
|
71
|
-
* classifies; presentation and copy stay in the app.
|
|
72
|
-
*
|
|
73
|
-
* - `renew-failed` — silent renew failed recoverably (next renew may succeed).
|
|
74
|
-
* - `session-expired` — the session is gone; a login redirect follows.
|
|
75
|
-
*/
|
|
76
|
-
type SessionNotice = {
|
|
77
|
-
kind: 'renew-failed';
|
|
78
|
-
error: Error;
|
|
79
|
-
} | {
|
|
80
|
-
kind: 'session-expired';
|
|
81
|
-
error?: Error;
|
|
82
|
-
};
|
|
83
|
-
interface SessionLifecycleHandlers {
|
|
84
|
-
/** Start re-authentication (typically from {@link createLoginRedirector}). */
|
|
85
|
-
redirectToLogin: () => void | Promise<void>;
|
|
86
|
-
/** Surface a notice to the user (toast). Optional — omit for headless use. */
|
|
87
|
-
notify?: (notice: SessionNotice) => void;
|
|
88
|
-
/** Clear app-side session state (e.g. reset the auth store's user). */
|
|
89
|
-
onSessionLost?: () => void;
|
|
90
|
-
/** Default `console.warn`. */
|
|
91
|
-
log?: (message: string, detail?: unknown) => void;
|
|
92
|
-
}
|
|
93
|
-
/**
|
|
94
|
-
* Wire oidc-client-ts session events to app callbacks:
|
|
95
|
-
*
|
|
96
|
-
* - silent-renew error → `notify` (`renew-failed`, or `session-expired` when the
|
|
97
|
-
* error is unrecoverable — see {@link isUnrecoverableRenewError}); an
|
|
98
|
-
* unrecoverable error also triggers the login redirect
|
|
99
|
-
* - access token expired without renewal → `notify(session-expired)` +
|
|
100
|
-
* `onSessionLost` + login redirect
|
|
101
|
-
* - back-channel signout at the IdP → `onSessionLost` + login redirect (no notice
|
|
102
|
-
* — the user initiated it elsewhere)
|
|
103
|
-
*
|
|
104
|
-
* Returns a detach function.
|
|
105
|
-
*/
|
|
106
|
-
declare function attachSessionLifecycleHandlers(userManager: UserManager, handlers: SessionLifecycleHandlers): () => void;
|
|
107
|
-
//#endregion
|
|
108
|
-
//#region src/auth/zitadel.d.ts
|
|
109
|
-
/**
|
|
110
|
-
* Zitadel scope presets for {@link createUserManagerFactory}.
|
|
111
|
-
*
|
|
112
|
-
* The URN scopes request the resource-owner (organization) claim and the
|
|
113
|
-
* project role grants; `offline_access` requests a refresh token.
|
|
114
|
-
*/
|
|
115
|
-
declare const ZITADEL_ORG_PROJECT_SCOPE = "openid profile email urn:zitadel:iam:user:resourceowner urn:zitadel:iam:org:project:roles offline_access";
|
|
116
|
-
/**
|
|
117
|
-
* Zitadel only accepts standard OIDC scopes on the refresh-token grant —
|
|
118
|
-
* sending `offline_access` or the `urn:zitadel:*` scopes returns
|
|
119
|
-
* `invalid_scope` even though they were granted at the initial auth. The
|
|
120
|
-
* URN-based claims still need to land in the refreshed access token; that
|
|
121
|
-
* depends on "Assert Roles on Authentication" being enabled at the Zitadel
|
|
122
|
-
* project level.
|
|
123
|
-
*/
|
|
124
|
-
declare const ZITADEL_REFRESH_TOKEN_ALLOWED_SCOPE = "openid profile email";
|
|
125
|
-
//#endregion
|
|
126
|
-
//#region src/auth/bypass.d.ts
|
|
127
|
-
type BypassStorage = Pick<Storage, 'getItem' | 'setItem'>;
|
|
128
|
-
interface AuthBypassProfile {
|
|
129
|
-
sub: string;
|
|
130
|
-
email: string;
|
|
131
|
-
name: string;
|
|
132
|
-
}
|
|
133
|
-
interface SeedAuthBypassOptions {
|
|
134
|
-
/** The shared secret the API accepts as a Bearer token. Falsy → no-op. */
|
|
135
|
-
bypassSecret: string | null | undefined;
|
|
136
|
-
issuerUrl: string;
|
|
137
|
-
clientId: string;
|
|
138
|
-
/**
|
|
139
|
-
* MUST be the build-time production flag (e.g. `import.meta.env.PROD`).
|
|
140
|
-
* When `true` the seed is refused unconditionally — a leaked runtime env var
|
|
141
|
-
* cannot enable the bypass in a production build.
|
|
142
|
-
*/
|
|
143
|
-
isProductionBuild: boolean;
|
|
144
|
-
/** Identity baked into the fake session. */
|
|
145
|
-
profile?: AuthBypassProfile;
|
|
146
|
-
/** Fake session lifetime. Default 86400 (24h). */
|
|
147
|
-
sessionTtlSeconds?: number;
|
|
148
|
-
storage?: BypassStorage;
|
|
149
|
-
/** Default `console.warn`. */
|
|
150
|
-
warn?: (message: string) => void;
|
|
151
|
-
}
|
|
152
|
-
/**
|
|
153
|
-
* Dev/E2E auth bypass: seed storage with a fake oidc-client-ts user whose
|
|
154
|
-
* `access_token` is the bypass secret, so the app considers the session
|
|
155
|
-
* authenticated and the API client sends the secret as Bearer.
|
|
156
|
-
*
|
|
157
|
-
* Call from a plugin that runs before the OIDC plugin. Skips seeding when a
|
|
158
|
-
* valid (non-expired) session already exists; overwrites corrupt entries.
|
|
159
|
-
* Returns whether a session was seeded.
|
|
160
|
-
*/
|
|
161
|
-
declare function seedAuthBypassSession(options: SeedAuthBypassOptions): boolean;
|
|
162
|
-
//#endregion
|
|
163
|
-
//#region src/auth/session.d.ts
|
|
164
|
-
/** Default mapped shape of the authenticated user. */
|
|
165
|
-
interface AuthSessionUser {
|
|
166
|
-
id: string;
|
|
167
|
-
email: string;
|
|
168
|
-
name: string | null;
|
|
169
|
-
picture: string | null;
|
|
170
|
-
}
|
|
171
|
-
interface AuthSessionCoreOptions<TUser> {
|
|
172
|
-
getUserManager: () => UserManager;
|
|
173
|
-
/** Map OIDC profile claims to the app's user shape. */
|
|
174
|
-
mapUser: (profile: UserProfile) => TUser;
|
|
175
|
-
/** Default `console.warn`. */
|
|
176
|
-
log?: (message: string, detail?: unknown) => void;
|
|
177
|
-
}
|
|
178
|
-
interface AuthSessionCore<TUser> {
|
|
179
|
-
user: Ref<TUser | null>;
|
|
180
|
-
initialized: Ref<boolean>;
|
|
181
|
-
loading: Ref<boolean>;
|
|
182
|
-
isAuthenticated: ComputedRef<boolean>;
|
|
183
|
-
/** Restore the session from storage, silently renewing an expired token. */
|
|
184
|
-
checkAuth: () => Promise<void>;
|
|
185
|
-
/** Start the signin redirect, carrying `returnUrl` as state. */
|
|
186
|
-
login: (returnUrl?: string) => Promise<void>;
|
|
187
|
-
/** Complete the signin redirect; returns the returnUrl state (default `/`). */
|
|
188
|
-
handleCallback: () => Promise<string>;
|
|
189
|
-
/** Clear the local session and redirect to the IdP's logout endpoint. */
|
|
190
|
-
logout: () => Promise<void>;
|
|
191
|
-
}
|
|
192
|
-
declare function defaultAuthUserMapper(profile: UserProfile): AuthSessionUser;
|
|
193
|
-
/**
|
|
194
|
-
* Reactive OIDC session state + actions — the setup body of an auth store.
|
|
195
|
-
* Wrap it in the app's own store so naming and registration stay app-owned:
|
|
196
|
-
*
|
|
197
|
-
* ```ts
|
|
198
|
-
* export const useAuthStore = defineStore('auth', () =>
|
|
199
|
-
* createAuthSessionCore({ getUserManager, mapUser: defaultAuthUserMapper }),
|
|
200
|
-
* )
|
|
201
|
-
* ```
|
|
202
|
-
*/
|
|
203
|
-
declare function createAuthSessionCore<TUser = AuthSessionUser>(options: AuthSessionCoreOptions<TUser>): AuthSessionCore<TUser>;
|
|
204
|
-
//#endregion
|
|
205
|
-
//#region src/auth/guard.d.ts
|
|
206
|
-
/** The route fields the guard needs — structurally satisfied by a Nuxt route. */
|
|
207
|
-
interface GuardRoute {
|
|
208
|
-
path: string;
|
|
209
|
-
fullPath: string;
|
|
210
|
-
}
|
|
211
|
-
interface AuthGuardOptions<TRoute extends GuardRoute = GuardRoute> {
|
|
212
|
-
/**
|
|
213
|
-
* Ensure the session is restored and report whether the user is
|
|
214
|
-
* authenticated — typically `checkAuth()` once, then `isAuthenticated`.
|
|
215
|
-
*/
|
|
216
|
-
ensureAuthenticated: () => Promise<boolean> | boolean;
|
|
217
|
-
/** Routes reachable without auth. Default: `/login` and `/auth/*`. */
|
|
218
|
-
isPublicRoute?: (to: TRoute) => boolean;
|
|
219
|
-
/** Build the login redirect target. Default `/login?redirect=<returnTo>`. */
|
|
220
|
-
loginRedirect?: (returnTo: string) => string;
|
|
221
|
-
/**
|
|
222
|
-
* Per-app policy hook that runs once the user is authenticated — tenant/org
|
|
223
|
-
* validation, role gates, acceptance gates. Return a path to redirect to,
|
|
224
|
-
* or nothing to let the navigation through.
|
|
225
|
-
*/
|
|
226
|
-
afterAuthenticated?: (to: TRoute) => Promise<string | undefined | void> | string | undefined | void;
|
|
227
|
-
}
|
|
228
|
-
/**
|
|
229
|
-
* Build the body of a global auth route-middleware. The returned handler
|
|
230
|
-
* yields a redirect target path or `undefined` to allow navigation; the app's
|
|
231
|
-
* middleware maps that onto its router:
|
|
232
|
-
*
|
|
233
|
-
* ```ts
|
|
234
|
-
* export default defineNuxtRouteMiddleware(async (to) => {
|
|
235
|
-
* const target = await guard(to)
|
|
236
|
-
* if (target) return navigateTo(target)
|
|
237
|
-
* })
|
|
238
|
-
* ```
|
|
239
|
-
*/
|
|
240
|
-
declare function createAuthGuard<TRoute extends GuardRoute = GuardRoute>(options: AuthGuardOptions<TRoute>): (to: TRoute) => Promise<string | undefined>;
|
|
241
|
-
//#endregion
|
|
242
|
-
//#region src/api/client.d.ts
|
|
243
|
-
type AnyElysia = Elysia<any, any, any, any, any, any, any>;
|
|
244
|
-
interface ResolveApiBaseUrlOptions {
|
|
245
|
-
/**
|
|
246
|
-
* The explicitly configured URL, first-match-wins — e.g.
|
|
247
|
-
* `__APP_CONFIG__.API_URL || runtimeConfig.public.apiUrl`. Falsy → fallback.
|
|
248
|
-
*/
|
|
249
|
-
configuredUrl: string | null | undefined;
|
|
250
|
-
/** Build-time production flag (`import.meta.env.PROD`). */
|
|
251
|
-
isProductionBuild: boolean;
|
|
252
|
-
/** Dev fallback becomes `http://localhost:<port>`. */
|
|
253
|
-
devFallbackPort: number;
|
|
254
|
-
/** Production fallback origin. Default `window.location.origin`. */
|
|
255
|
-
origin?: string;
|
|
256
|
-
}
|
|
257
|
-
/**
|
|
258
|
-
* Resolve the API base URL: configured value, else the page origin in
|
|
259
|
-
* production builds (same-host ingress), else a localhost dev port.
|
|
260
|
-
*/
|
|
261
|
-
declare function resolveApiBaseUrl(options: ResolveApiBaseUrlOptions): string;
|
|
262
|
-
/**
|
|
263
|
-
* Bearer-token provider backed by the OIDC session: resolves to the current
|
|
264
|
-
* access token, or `null` when there is no non-expired session.
|
|
265
|
-
*/
|
|
266
|
-
declare function createAccessTokenProvider(getUserManager: () => UserManager): () => Promise<string | null>;
|
|
267
|
-
interface TreatyClientFactoryOptions {
|
|
268
|
-
/** Resolve (and memoize, if desired) the base URL at first client use. */
|
|
269
|
-
getBaseUrl: () => string;
|
|
270
|
-
/** Bearer token per request; `null` sends no Authorization header. */
|
|
271
|
-
getAccessToken: () => Promise<string | null>;
|
|
272
|
-
/**
|
|
273
|
-
* Eden Treaty's auto-Date parsing on responses. Default `false`: with the
|
|
274
|
-
* default `true`, any `YYYY-MM-DD` string in a response is silently
|
|
275
|
-
* converted to a `Date` object, which then JSON-serializes back as a full
|
|
276
|
-
* ISO datetime on the next request — breaking server-side "plain ISO date
|
|
277
|
-
* string" validation. Keep the wire contract string-typed unless the API
|
|
278
|
-
* genuinely round-trips Date objects.
|
|
279
|
-
*/
|
|
280
|
-
parseDate?: boolean;
|
|
281
|
-
/** Extra Treaty config (fetcher, onRequest, …), applied last. */
|
|
282
|
-
treatyConfig?: Omit<Treaty.Config, 'headers' | 'parseDate'>;
|
|
283
|
-
}
|
|
284
|
-
/**
|
|
285
|
-
* Lazily-created Eden Treaty client singleton with OIDC bearer injection.
|
|
286
|
-
*
|
|
287
|
-
* ```ts
|
|
288
|
-
* const getClient = createTreatyClientFactory<App>({ getBaseUrl, getAccessToken })
|
|
289
|
-
* export function useApi() {
|
|
290
|
-
* const client = getClient()
|
|
291
|
-
* return { api: client.api, client }
|
|
292
|
-
* }
|
|
293
|
-
* ```
|
|
294
|
-
*/
|
|
295
|
-
declare function createTreatyClientFactory<App extends AnyElysia>(options: TreatyClientFactoryOptions): () => Treaty.Create<App>;
|
|
296
|
-
//#endregion
|
|
1
|
+
import { Component, ComputedRef, InjectionKey, Ref } from "vue";
|
|
297
2
|
//#region src/org/orgStore.d.ts
|
|
298
3
|
type OrgStorage = Pick<Storage, 'getItem' | 'setItem' | 'removeItem'>;
|
|
299
4
|
/** Result seam for the org fetch — mirrors an Eden Treaty `{ data, error }`. */
|
|
@@ -342,6 +47,16 @@ interface OrgStoreCore<TOrg> {
|
|
|
342
47
|
*/
|
|
343
48
|
declare function createOrgStoreCore<TOrg>(options: OrgStoreCoreOptions<TOrg>): OrgStoreCore<TOrg>;
|
|
344
49
|
//#endregion
|
|
50
|
+
//#region src/runtimeConfig.d.ts
|
|
51
|
+
/**
|
|
52
|
+
* Runtime-config lookup for SPAs deployed behind a static file server: an
|
|
53
|
+
* entrypoint script may define `window.__APP_CONFIG__` (values injected at
|
|
54
|
+
* deploy time), which takes precedence over the build-time fallback (e.g.
|
|
55
|
+
* Nuxt `runtimeConfig.public.*`).
|
|
56
|
+
*/
|
|
57
|
+
declare function resolveRuntimeConfigValue(appConfigKey: string, fallback: string): string;
|
|
58
|
+
declare function resolveRuntimeConfigValue(appConfigKey: string, fallback?: string): string | undefined;
|
|
59
|
+
//#endregion
|
|
345
60
|
//#region src/composables/useConfirm.d.ts
|
|
346
61
|
interface ConfirmOptions {
|
|
347
62
|
title: string;
|
|
@@ -397,24 +112,64 @@ interface ApiErrorMessengerOptions {
|
|
|
397
112
|
/** Default `console.error`. Pass `() => {}` to silence. */
|
|
398
113
|
log?: (message: string, error: unknown) => void;
|
|
399
114
|
}
|
|
400
|
-
/**
|
|
401
|
-
* Map API error bodies to user-facing i18n strings using a fixed key
|
|
402
|
-
* convention the consumer's locale files fulfil:
|
|
403
|
-
*
|
|
404
|
-
* - `errors.<key>` — one entry per API error key (fallback: the raw
|
|
405
|
-
* server `message`, and `errors.internal_server_error` for non-API errors)
|
|
406
|
-
* - `validation.fields.<path>` — display names for validated fields
|
|
407
|
-
* - `validation.messages.<snake_cased_message>` — validation message texts
|
|
408
|
-
*
|
|
409
|
-
* Framework-free: pass `t`/`te` from your i18n instance (the app-side
|
|
410
|
-
* composable is typically `const { t, te } = useI18n()` + this factory).
|
|
411
|
-
* Eden Treaty error envelopes (`{ value }`) are unwrapped automatically.
|
|
412
|
-
*/
|
|
413
115
|
declare function createApiErrorMessenger(options: ApiErrorMessengerOptions): {
|
|
414
116
|
getErrorMessage: (error: unknown) => string;
|
|
415
117
|
isValidationError: (error: unknown) => error is ValidationApiErrorLike;
|
|
416
118
|
};
|
|
417
119
|
//#endregion
|
|
120
|
+
//#region src/composables/useHelpPanel.d.ts
|
|
121
|
+
interface HelpPanelAction {
|
|
122
|
+
/** Unique key for this action within the tab */
|
|
123
|
+
key: string;
|
|
124
|
+
/** Display label */
|
|
125
|
+
label: string;
|
|
126
|
+
/** Icon name (e.g. i-lucide-circle-help) */
|
|
127
|
+
icon: string;
|
|
128
|
+
/** Raw Vue component to render in the panel */
|
|
129
|
+
component: Component;
|
|
130
|
+
/** Props to pass to the component (should be reactive) */
|
|
131
|
+
props: Record<string, unknown>;
|
|
132
|
+
}
|
|
133
|
+
interface HelpPanelRegistration {
|
|
134
|
+
actions: HelpPanelAction[];
|
|
135
|
+
}
|
|
136
|
+
interface HelpPanel {
|
|
137
|
+
/** Map of tab value -> registration */
|
|
138
|
+
registrations: Map<string, HelpPanelRegistration>;
|
|
139
|
+
/** Whether the panel is open */
|
|
140
|
+
isOpen: Ref<boolean>;
|
|
141
|
+
/** Currently active tab value */
|
|
142
|
+
activeTabValue: Ref<string>;
|
|
143
|
+
/** Actions for the currently active tab */
|
|
144
|
+
currentActions: ComputedRef<HelpPanelAction[]>;
|
|
145
|
+
/** Whether the active tab has any help actions */
|
|
146
|
+
hasActions: ComputedRef<boolean>;
|
|
147
|
+
/** Register help actions for a tab */
|
|
148
|
+
register(tabValue: string, actions: HelpPanelAction[]): void;
|
|
149
|
+
/** Unregister help actions for a tab */
|
|
150
|
+
unregister(tabValue: string): void;
|
|
151
|
+
/** Set the currently active tab */
|
|
152
|
+
setActiveTab(tabValue: string): void;
|
|
153
|
+
/** Toggle the panel open/closed */
|
|
154
|
+
toggle(): void;
|
|
155
|
+
}
|
|
156
|
+
declare const HELP_PANEL_KEY: InjectionKey<HelpPanel>;
|
|
157
|
+
interface HelpPanelOptions {
|
|
158
|
+
/** localStorage key persisting the open state. Default `help-panel-open`. */
|
|
159
|
+
storageKey?: string;
|
|
160
|
+
/** Storage override (tests). Default `globalThis.localStorage`. */
|
|
161
|
+
storage?: Pick<Storage, 'getItem' | 'setItem'>;
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* Provide/inject registry for a per-tab contextual help panel: pages register
|
|
165
|
+
* help actions keyed by tab, `PageUtilityActions` renders the toggle, and a
|
|
166
|
+
* panel component renders `currentActions`. Open state persists to
|
|
167
|
+
* localStorage; switching to a tab without actions auto-closes the panel.
|
|
168
|
+
*
|
|
169
|
+
* Provide it per page: `provide(HELP_PANEL_KEY, useHelpPanel())`.
|
|
170
|
+
*/
|
|
171
|
+
declare function useHelpPanel(options?: HelpPanelOptions): HelpPanel;
|
|
172
|
+
//#endregion
|
|
418
173
|
//#region src/composables/useDirtyTracking.d.ts
|
|
419
174
|
/**
|
|
420
175
|
* Form change-detection over a reactive state object via JSON deep-compare:
|
|
@@ -450,4 +205,4 @@ declare function usePagination(options?: {
|
|
|
450
205
|
resetPagination: () => void;
|
|
451
206
|
};
|
|
452
207
|
//#endregion
|
|
453
|
-
export { type ApiErrorLike, type ApiErrorMessengerOptions, type
|
|
208
|
+
export { type ApiErrorLike, type ApiErrorMessengerOptions, type ConfirmOptions, type FetchOrganizationsResult, HELP_PANEL_KEY, type HelpPanel, type HelpPanelAction, type HelpPanelOptions, type HelpPanelRegistration, type OrgStoreCore, type OrgStoreCoreOptions, type ValidationApiErrorLike, createApiErrorMessenger, createOrgStoreCore, resolveRuntimeConfigValue, useConfirm, useConfirmState, useDirtyTracking, useHelpPanel, usePagination };
|