@octabits-io/nuxt-ui-kit 0.14.2 → 0.15.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 -10
- package/dist/api/index.d.ts +1 -39
- package/dist/api/index.js +1 -30
- package/dist/index.d.ts +1 -1
- package/dist/index.js +4 -1
- package/package.json +3 -13
package/README.md
CHANGED
|
@@ -26,16 +26,17 @@ itself, so it has no Nuxt dependency, only `vue`.
|
|
|
26
26
|
- **Route guard builder** — `createAuthGuard` returns a handler yielding a
|
|
27
27
|
redirect target or `undefined`; per-app policy (org validation, role gates)
|
|
28
28
|
goes in the `afterAuthenticated` hook
|
|
29
|
-
- **
|
|
30
|
-
`
|
|
31
|
-
|
|
32
|
-
|
|
29
|
+
- **API-client seams** (`./api`, transport-agnostic) —
|
|
30
|
+
`resolveApiBaseUrl` (configured URL → page origin in production → localhost
|
|
31
|
+
dev port) and `createAccessTokenProvider` (bearer from the OIDC session).
|
|
32
|
+
Build the client with Hono's `hc` and inject the token through its own async
|
|
33
|
+
`headers` thunk
|
|
33
34
|
- **Org store core** — `createOrgStoreCore<TOrg>` (granted orgs, slug-keyed
|
|
34
35
|
selection, persistence, lost-access revocation) for the app's own store
|
|
35
36
|
- **API error → i18n** — `createApiErrorMessenger({ t, te })`: maps
|
|
36
37
|
`{ key, message }` bodies and validation errors to user-facing strings via
|
|
37
38
|
the `errors.*` / `validation.fields.*` / `validation.messages.*` key
|
|
38
|
-
convention; unwraps
|
|
39
|
+
convention; unwraps `{ value }` error envelopes
|
|
39
40
|
- **Confirm dialog** — promise-based `useConfirm()` + singleton state, with a
|
|
40
41
|
`./components/ConfirmDialog.vue` renderer (`common.cancel`/`common.confirm`
|
|
41
42
|
i18n defaults, `zIndexClass` prop for stacking above slideovers)
|
|
@@ -113,11 +114,17 @@ export default defineNuxtPlugin((nuxtApp) => {
|
|
|
113
114
|
})
|
|
114
115
|
})
|
|
115
116
|
|
|
116
|
-
// app/composables/useApi.ts
|
|
117
|
-
const
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
117
|
+
// app/composables/useApi.ts — `hcWithType` is the API package's pre-compiled client type
|
|
118
|
+
const getAccessToken = createAccessTokenProvider(getUserManager)
|
|
119
|
+
const client = hcWithType(
|
|
120
|
+
resolveApiBaseUrl({ configuredUrl, isProductionBuild: import.meta.env.PROD, devFallbackPort: 3002 }),
|
|
121
|
+
{
|
|
122
|
+
headers: async () => {
|
|
123
|
+
const token = await getAccessToken()
|
|
124
|
+
return token ? { authorization: `Bearer ${token}` } : {}
|
|
125
|
+
},
|
|
126
|
+
},
|
|
127
|
+
)
|
|
121
128
|
|
|
122
129
|
// app/stores/auth.ts
|
|
123
130
|
export const useAuthStore = defineStore('auth', () =>
|
package/dist/api/index.d.ts
CHANGED
|
@@ -1,8 +1,5 @@
|
|
|
1
1
|
import { UserManager } from "oidc-client-ts";
|
|
2
|
-
import { Treaty } from "@elysiajs/eden";
|
|
3
|
-
import { Elysia } from "elysia";
|
|
4
2
|
//#region src/api/client.d.ts
|
|
5
|
-
type AnyElysia = Elysia<any, any, any, any, any, any, any>;
|
|
6
3
|
interface ResolveApiBaseUrlOptions {
|
|
7
4
|
/**
|
|
8
5
|
* The explicitly configured URL, first-match-wins — e.g.
|
|
@@ -26,40 +23,5 @@ declare function resolveApiBaseUrl(options: ResolveApiBaseUrlOptions): string;
|
|
|
26
23
|
* access token, or `null` when there is no non-expired session.
|
|
27
24
|
*/
|
|
28
25
|
declare function createAccessTokenProvider(getUserManager: () => UserManager): () => Promise<string | null>;
|
|
29
|
-
interface TreatyClientFactoryOptions {
|
|
30
|
-
/** Resolve (and memoize, if desired) the base URL at first client use. */
|
|
31
|
-
getBaseUrl: () => string;
|
|
32
|
-
/** Bearer token per request; `null` sends no Authorization header. */
|
|
33
|
-
getAccessToken: () => Promise<string | null>;
|
|
34
|
-
/**
|
|
35
|
-
* Eden Treaty's auto-Date parsing on responses. Default `false`: with the
|
|
36
|
-
* default `true`, any `YYYY-MM-DD` string in a response is silently
|
|
37
|
-
* converted to a `Date` object, which then JSON-serializes back as a full
|
|
38
|
-
* ISO datetime on the next request — breaking server-side "plain ISO date
|
|
39
|
-
* string" validation. Keep the wire contract string-typed unless the API
|
|
40
|
-
* genuinely round-trips Date objects.
|
|
41
|
-
*/
|
|
42
|
-
parseDate?: boolean;
|
|
43
|
-
/**
|
|
44
|
-
* Additional header source(s), applied after the bearer injector — a later
|
|
45
|
-
* entry wins on key collision, so consumers can add or override headers
|
|
46
|
-
* without losing the Authorization injection.
|
|
47
|
-
*/
|
|
48
|
-
headers?: Treaty.Config['headers'];
|
|
49
|
-
/** Extra Treaty config (fetcher, onRequest, …), applied last. */
|
|
50
|
-
treatyConfig?: Omit<Treaty.Config, 'headers' | 'parseDate'>;
|
|
51
|
-
}
|
|
52
|
-
/**
|
|
53
|
-
* Lazily-created Eden Treaty client singleton with OIDC bearer injection.
|
|
54
|
-
*
|
|
55
|
-
* ```ts
|
|
56
|
-
* const getClient = createTreatyClientFactory<App>({ getBaseUrl, getAccessToken })
|
|
57
|
-
* export function useApi() {
|
|
58
|
-
* const client = getClient()
|
|
59
|
-
* return { api: client.api, client }
|
|
60
|
-
* }
|
|
61
|
-
* ```
|
|
62
|
-
*/
|
|
63
|
-
declare function createTreatyClientFactory<App extends AnyElysia>(options: TreatyClientFactoryOptions): () => Treaty.Create<App>;
|
|
64
26
|
//#endregion
|
|
65
|
-
export { type ResolveApiBaseUrlOptions,
|
|
27
|
+
export { type ResolveApiBaseUrlOptions, createAccessTokenProvider, resolveApiBaseUrl };
|
package/dist/api/index.js
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { treaty } from "@elysiajs/eden";
|
|
2
1
|
//#region src/api/client.ts
|
|
3
2
|
/**
|
|
4
3
|
* Resolve the API base URL: configured value, else the page origin in
|
|
@@ -19,33 +18,5 @@ function createAccessTokenProvider(getUserManager) {
|
|
|
19
18
|
return user.access_token;
|
|
20
19
|
};
|
|
21
20
|
}
|
|
22
|
-
/**
|
|
23
|
-
* Lazily-created Eden Treaty client singleton with OIDC bearer injection.
|
|
24
|
-
*
|
|
25
|
-
* ```ts
|
|
26
|
-
* const getClient = createTreatyClientFactory<App>({ getBaseUrl, getAccessToken })
|
|
27
|
-
* export function useApi() {
|
|
28
|
-
* const client = getClient()
|
|
29
|
-
* return { api: client.api, client }
|
|
30
|
-
* }
|
|
31
|
-
* ```
|
|
32
|
-
*/
|
|
33
|
-
function createTreatyClientFactory(options) {
|
|
34
|
-
let client = null;
|
|
35
|
-
return function getClient() {
|
|
36
|
-
if (client) return client;
|
|
37
|
-
const bearerInjector = async () => {
|
|
38
|
-
const token = await options.getAccessToken();
|
|
39
|
-
if (token) return { authorization: `Bearer ${token}` };
|
|
40
|
-
};
|
|
41
|
-
const extraHeaders = options.headers === void 0 ? [] : Array.isArray(options.headers) ? options.headers : [options.headers];
|
|
42
|
-
client = treaty(options.getBaseUrl(), {
|
|
43
|
-
parseDate: options.parseDate ?? false,
|
|
44
|
-
headers: [bearerInjector, ...extraHeaders],
|
|
45
|
-
...options.treatyConfig
|
|
46
|
-
});
|
|
47
|
-
return client;
|
|
48
|
-
};
|
|
49
|
-
}
|
|
50
21
|
//#endregion
|
|
51
|
-
export { createAccessTokenProvider,
|
|
22
|
+
export { createAccessTokenProvider, resolveApiBaseUrl };
|
package/dist/index.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ import { Component, ComputedRef, InjectionKey, Ref } from "vue";
|
|
|
2
2
|
import { RouteLocationRaw } from "vue-router";
|
|
3
3
|
//#region src/org/orgStore.d.ts
|
|
4
4
|
type OrgStorage = Pick<Storage, 'getItem' | 'setItem' | 'removeItem'>;
|
|
5
|
-
/** Result seam for the org fetch —
|
|
5
|
+
/** Result seam for the org fetch — a `{ data, error }` pair, whatever the client. */
|
|
6
6
|
type FetchOrganizationsResult<TOrg> = {
|
|
7
7
|
items: TOrg[];
|
|
8
8
|
error?: undefined;
|
package/dist/index.js
CHANGED
|
@@ -120,7 +120,10 @@ function useConfirmState() {
|
|
|
120
120
|
*
|
|
121
121
|
* Framework-free: pass `t`/`te` from your i18n instance (the app-side
|
|
122
122
|
* composable is typically `const { t, te } = useI18n()` + this factory).
|
|
123
|
-
*
|
|
123
|
+
* Errors wrapped in a `{ value }` envelope are unwrapped automatically — Eden
|
|
124
|
+
* Treaty's error shape originally, kept because it costs nothing and any
|
|
125
|
+
* client that boxes the body the same way gets the same handling. Hono's `hc`
|
|
126
|
+
* hands back the parsed body directly, so it takes the unwrapped path.
|
|
124
127
|
*/
|
|
125
128
|
/** Lowercase + collapse every non-alphanumeric run to `_` (trimmed) — a flat, definable vue-i18n key segment. */
|
|
126
129
|
function i18nSlug(value) {
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@octabits-io/nuxt-ui-kit",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "Frontend kit for Nuxt/Vue admin SPAs: OIDC session harness (oidc-client-ts),
|
|
3
|
+
"version": "0.15.0",
|
|
4
|
+
"description": "Frontend kit for Nuxt/Vue admin SPAs: OIDC session harness (oidc-client-ts), API-client seams (base URL + OIDC bearer), auth/org store cores, and a route-guard builder — factory-style seams the app wires into its own plugins, stores, and middleware",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"exports": {
|
|
@@ -73,22 +73,18 @@
|
|
|
73
73
|
"url": "https://github.com/octabits-io/platform/issues"
|
|
74
74
|
},
|
|
75
75
|
"devDependencies": {
|
|
76
|
-
"@elysiajs/eden": "^1.4.9",
|
|
77
76
|
"date-fns": "^4.4.0",
|
|
78
|
-
"elysia": "^1.4.29",
|
|
79
77
|
"oidc-client-ts": "^3.5.0",
|
|
80
78
|
"vitest": "^4.1.10",
|
|
81
79
|
"vue": "^3.5.41",
|
|
82
80
|
"zod": "^4.4.3",
|
|
83
|
-
"@octabits-io/framework": "^0.
|
|
81
|
+
"@octabits-io/framework": "^0.23.0"
|
|
84
82
|
},
|
|
85
83
|
"peerDependencies": {
|
|
86
|
-
"@elysiajs/eden": "^1.4.0",
|
|
87
84
|
"@internationalized/date": "^3",
|
|
88
85
|
"@nuxt/ui": "^4",
|
|
89
86
|
"@octabits-io/framework": ">=0.4.0 <1",
|
|
90
87
|
"date-fns": "^3 || ^4",
|
|
91
|
-
"elysia": ">=1.4 <3",
|
|
92
88
|
"oidc-client-ts": "^3.3.0",
|
|
93
89
|
"typescript": "^5 || ^6 || ^7",
|
|
94
90
|
"vue": "^3.5.0",
|
|
@@ -97,9 +93,6 @@
|
|
|
97
93
|
"zod": "^4"
|
|
98
94
|
},
|
|
99
95
|
"peerDependenciesMeta": {
|
|
100
|
-
"@elysiajs/eden": {
|
|
101
|
-
"optional": true
|
|
102
|
-
},
|
|
103
96
|
"@octabits-io/framework": {
|
|
104
97
|
"optional": true
|
|
105
98
|
},
|
|
@@ -112,9 +105,6 @@
|
|
|
112
105
|
"date-fns": {
|
|
113
106
|
"optional": true
|
|
114
107
|
},
|
|
115
|
-
"elysia": {
|
|
116
|
-
"optional": true
|
|
117
|
-
},
|
|
118
108
|
"oidc-client-ts": {
|
|
119
109
|
"optional": true
|
|
120
110
|
},
|