@merkaly/nuxt 0.2.5 → 0.3.1
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/module.json +1 -1
- package/dist/runtime/components/app.vue +6 -1
- package/dist/runtime/components/auth.vue +4 -1
- package/dist/runtime/components/input/InputAddress.d.vue.ts +1 -1
- package/dist/runtime/components/input/InputAddress.vue.d.ts +1 -1
- package/dist/runtime/components/input/InputMoney.d.vue.ts +1 -1
- package/dist/runtime/components/input/InputMoney.vue.d.ts +1 -1
- package/dist/runtime/components/table/TableDatagrid.d.vue.ts +80 -0
- package/dist/runtime/components/table/TableDatagrid.vue +23 -21
- package/dist/runtime/components/table/TableDatagrid.vue.d.ts +80 -0
- package/dist/runtime/composables/useDatagrid.d.ts +1 -1
- package/dist/runtime/composables/useNavigation.d.ts +10 -5
- package/dist/runtime/composables/useNavigation.js +33 -28
- package/dist/runtime/composables/useValidator.d.ts +16 -0
- package/dist/runtime/composables/useValidator.js +59 -0
- package/dist/runtime/middleware/auth.js +3 -1
- package/dist/runtime/plugins/auth0.client.js +5 -1
- package/dist/runtime/utils/withAdapter.js +3 -0
- package/package.json +17 -14
package/dist/module.json
CHANGED
|
@@ -1,10 +1,15 @@
|
|
|
1
1
|
<script setup>
|
|
2
2
|
import { useRoute } from "#app";
|
|
3
|
-
import { useAuth, watchOnce } from "#imports";
|
|
3
|
+
import { useAuth, watchOnce, addRouteMiddleware, useNuxtApp } from "#imports";
|
|
4
4
|
import AuthMiddleware from "../middleware/auth";
|
|
5
|
+
import { useNavigation } from "../composables/useNavigation";
|
|
5
6
|
const $route = useRoute();
|
|
6
7
|
const { isLoading } = useAuth();
|
|
8
|
+
const { hook } = useNuxtApp();
|
|
7
9
|
watchOnce(isLoading, () => AuthMiddleware($route, $route));
|
|
10
|
+
const { defer, regenerate } = useNavigation();
|
|
11
|
+
addRouteMiddleware("navigation", (to) => defer(to), { global: true });
|
|
12
|
+
hook("page:finish", () => regenerate());
|
|
8
13
|
</script>
|
|
9
14
|
|
|
10
15
|
<template>
|
|
@@ -8,6 +8,7 @@ const code = params.get("code");
|
|
|
8
8
|
const error = params.get("error");
|
|
9
9
|
const invitation = params.get("invitation");
|
|
10
10
|
const organization = params.get("organization");
|
|
11
|
+
const redirect = params.get("redirect");
|
|
11
12
|
function handleInvite() {
|
|
12
13
|
return $auth0.loginWithRedirect({ authorizationParams: { organization, invitation } });
|
|
13
14
|
}
|
|
@@ -32,7 +33,9 @@ callOnce(async () => {
|
|
|
32
33
|
if (code) {
|
|
33
34
|
return handleCode();
|
|
34
35
|
}
|
|
35
|
-
return $auth0.loginWithRedirect(
|
|
36
|
+
return $auth0.loginWithRedirect({
|
|
37
|
+
appState: { target: redirect || "/" }
|
|
38
|
+
});
|
|
36
39
|
});
|
|
37
40
|
</script>
|
|
38
41
|
|
|
@@ -81,8 +81,8 @@ declare const __VLS_export: import("vue").DefineComponent<import("vue").ExtractP
|
|
|
81
81
|
}>, {
|
|
82
82
|
mode: PlaceTypes;
|
|
83
83
|
disabled: boolean;
|
|
84
|
-
countries: string[];
|
|
85
84
|
placeholder: string;
|
|
85
|
+
countries: string[];
|
|
86
86
|
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
|
87
87
|
declare const _default: typeof __VLS_export;
|
|
88
88
|
export default _default;
|
|
@@ -81,8 +81,8 @@ declare const __VLS_export: import("vue").DefineComponent<import("vue").ExtractP
|
|
|
81
81
|
}>, {
|
|
82
82
|
mode: PlaceTypes;
|
|
83
83
|
disabled: boolean;
|
|
84
|
-
countries: string[];
|
|
85
84
|
placeholder: string;
|
|
85
|
+
countries: string[];
|
|
86
86
|
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
|
87
87
|
declare const _default: typeof __VLS_export;
|
|
88
88
|
export default _default;
|
|
@@ -76,9 +76,9 @@ declare const __VLS_export: import("vue").DefineComponent<import("vue").ExtractP
|
|
|
76
76
|
}>, {
|
|
77
77
|
prefix: string;
|
|
78
78
|
decimal: string;
|
|
79
|
-
placeholder: string;
|
|
80
79
|
max: number;
|
|
81
80
|
min: number;
|
|
81
|
+
placeholder: string;
|
|
82
82
|
precision: number;
|
|
83
83
|
suffix: string;
|
|
84
84
|
thousands: string;
|
|
@@ -76,9 +76,9 @@ declare const __VLS_export: import("vue").DefineComponent<import("vue").ExtractP
|
|
|
76
76
|
}>, {
|
|
77
77
|
prefix: string;
|
|
78
78
|
decimal: string;
|
|
79
|
-
placeholder: string;
|
|
80
79
|
max: number;
|
|
81
80
|
min: number;
|
|
81
|
+
placeholder: string;
|
|
82
82
|
precision: number;
|
|
83
83
|
suffix: string;
|
|
84
84
|
thousands: string;
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import type { DataGrid } from '../../composables/useDatagrid.js';
|
|
2
|
+
declare const __VLS_export: <G>(__VLS_props: NonNullable<Awaited<typeof __VLS_setup>>["props"], __VLS_ctx?: __VLS_PrettifyLocal<Pick<NonNullable<Awaited<typeof __VLS_setup>>, "attrs" | "emit" | "slots">>, __VLS_exposed?: NonNullable<Awaited<typeof __VLS_setup>>["expose"], __VLS_setup?: Promise<{
|
|
3
|
+
props: import("vue").PublicProps & __VLS_PrettifyLocal<{
|
|
4
|
+
modelValue: DataGrid<G>;
|
|
5
|
+
} & import("vue").ExtractPublicPropTypes<{
|
|
6
|
+
emptyText: {
|
|
7
|
+
type: StringConstructor;
|
|
8
|
+
default: () => string;
|
|
9
|
+
};
|
|
10
|
+
hideFooter: {
|
|
11
|
+
type: BooleanConstructor;
|
|
12
|
+
default: boolean;
|
|
13
|
+
};
|
|
14
|
+
hidePagination: {
|
|
15
|
+
type: BooleanConstructor;
|
|
16
|
+
default: boolean;
|
|
17
|
+
};
|
|
18
|
+
hideSelect: {
|
|
19
|
+
type: BooleanConstructor;
|
|
20
|
+
default: boolean;
|
|
21
|
+
};
|
|
22
|
+
}> & {
|
|
23
|
+
"onUpdate:modelValue"?: ((value: DataGrid<G>) => any) | undefined;
|
|
24
|
+
onFetch?: ((reason: "sort" | "filter" | "search" | "paginate" | "refresh") => any) | undefined;
|
|
25
|
+
"onToggle:item"?: ((item: G, expanded: boolean) => any) | undefined;
|
|
26
|
+
}> & (typeof globalThis extends {
|
|
27
|
+
__VLS_PROPS_FALLBACK: infer P;
|
|
28
|
+
} ? P : {});
|
|
29
|
+
expose: (exposed: {}) => void;
|
|
30
|
+
attrs: any;
|
|
31
|
+
slots: {
|
|
32
|
+
[x: `head[${string}]`]: ((props: {
|
|
33
|
+
column: import("../../composables/useDatagrid.js").ColumnDefinition<G>;
|
|
34
|
+
key: string;
|
|
35
|
+
}) => any) | undefined;
|
|
36
|
+
} & {
|
|
37
|
+
[x: `row[${string}]`]: ((props: {
|
|
38
|
+
column: import("../../composables/useDatagrid.js").ColumnDefinition<G>;
|
|
39
|
+
idx: number;
|
|
40
|
+
item: G;
|
|
41
|
+
key: string;
|
|
42
|
+
}) => any) | undefined;
|
|
43
|
+
} & {
|
|
44
|
+
search?: (props: {}) => any;
|
|
45
|
+
} & {
|
|
46
|
+
toolbar?: (props: {}) => any;
|
|
47
|
+
} & {
|
|
48
|
+
filters?: (props: {}) => any;
|
|
49
|
+
} & {
|
|
50
|
+
empty?: (props: {}) => any;
|
|
51
|
+
} & {
|
|
52
|
+
actions?: (props: {
|
|
53
|
+
index: number;
|
|
54
|
+
item: G;
|
|
55
|
+
}) => any;
|
|
56
|
+
} & {
|
|
57
|
+
details?: (props: {
|
|
58
|
+
index: number;
|
|
59
|
+
item: G;
|
|
60
|
+
toggleDetails: () => void;
|
|
61
|
+
}) => any;
|
|
62
|
+
} & {
|
|
63
|
+
tfoot?: (props: {}) => any;
|
|
64
|
+
} & {
|
|
65
|
+
footer?: (props: {}) => any;
|
|
66
|
+
};
|
|
67
|
+
emit: {
|
|
68
|
+
(e: "fetch", reason: "sort" | "filter" | "search" | "paginate" | "refresh"): void;
|
|
69
|
+
(e: "toggle:item", item: G, expanded: boolean): void;
|
|
70
|
+
} & ((evt: "update:modelValue", value: DataGrid<G>) => void);
|
|
71
|
+
}>) => import("vue").VNode & {
|
|
72
|
+
__ctx?: Awaited<typeof __VLS_setup>;
|
|
73
|
+
};
|
|
74
|
+
declare const _default: typeof __VLS_export;
|
|
75
|
+
export default _default;
|
|
76
|
+
type __VLS_PrettifyLocal<T> = (T extends any ? {
|
|
77
|
+
[K in keyof T]: T[K];
|
|
78
|
+
} : {
|
|
79
|
+
[K in keyof T as K]: T[K];
|
|
80
|
+
}) & {};
|
|
@@ -236,29 +236,31 @@ function toggleDetails(item) {
|
|
|
236
236
|
<BCardFooter v-if="!props.hideFooter" class="p-4">
|
|
237
237
|
<slot name="footer" />
|
|
238
238
|
|
|
239
|
-
<
|
|
240
|
-
<
|
|
241
|
-
<
|
|
242
|
-
<
|
|
243
|
-
|
|
244
|
-
|
|
239
|
+
<template v-if="!props.hidePagination">
|
|
240
|
+
<BRow align-h="between" align-v="center" class="w-100">
|
|
241
|
+
<BCol cols="auto">
|
|
242
|
+
<select v-model="$datagrid.limit" class="form-select form-select-sm form-select-solid" disabled>
|
|
243
|
+
<BFormSelectOption :value="10">10</BFormSelectOption>
|
|
244
|
+
</select>
|
|
245
|
+
</BCol>
|
|
245
246
|
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
247
|
+
<BCol v-show="!$datagrid.loading" cols="auto">
|
|
248
|
+
<BPagination
|
|
249
|
+
v-model="$datagrid.page"
|
|
250
|
+
:disabled="$datagrid.loading"
|
|
251
|
+
:per-page="$datagrid.limit"
|
|
252
|
+
:total-rows="$datagrid.total"
|
|
253
|
+
class="mb-0"
|
|
254
|
+
no-goto-end-buttons
|
|
255
|
+
@update:model-value="emit('fetch', 'paginate')" />
|
|
256
|
+
</BCol>
|
|
256
257
|
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
258
|
+
<BCol class="fs-7 text-muted" cols="auto">
|
|
259
|
+
<span v-if="$datagrid.loading">Loading...</span>
|
|
260
|
+
<FormatText v-else :template="paginationText.template" :values="paginationText.values" />
|
|
261
|
+
</BCol>
|
|
262
|
+
</BRow>
|
|
263
|
+
</template>
|
|
262
264
|
</BCardFooter>
|
|
263
265
|
</BCard>
|
|
264
266
|
</template>
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import type { DataGrid } from '../../composables/useDatagrid.js';
|
|
2
|
+
declare const __VLS_export: <G>(__VLS_props: NonNullable<Awaited<typeof __VLS_setup>>["props"], __VLS_ctx?: __VLS_PrettifyLocal<Pick<NonNullable<Awaited<typeof __VLS_setup>>, "attrs" | "emit" | "slots">>, __VLS_exposed?: NonNullable<Awaited<typeof __VLS_setup>>["expose"], __VLS_setup?: Promise<{
|
|
3
|
+
props: import("vue").PublicProps & __VLS_PrettifyLocal<{
|
|
4
|
+
modelValue: DataGrid<G>;
|
|
5
|
+
} & import("vue").ExtractPublicPropTypes<{
|
|
6
|
+
emptyText: {
|
|
7
|
+
type: StringConstructor;
|
|
8
|
+
default: () => string;
|
|
9
|
+
};
|
|
10
|
+
hideFooter: {
|
|
11
|
+
type: BooleanConstructor;
|
|
12
|
+
default: boolean;
|
|
13
|
+
};
|
|
14
|
+
hidePagination: {
|
|
15
|
+
type: BooleanConstructor;
|
|
16
|
+
default: boolean;
|
|
17
|
+
};
|
|
18
|
+
hideSelect: {
|
|
19
|
+
type: BooleanConstructor;
|
|
20
|
+
default: boolean;
|
|
21
|
+
};
|
|
22
|
+
}> & {
|
|
23
|
+
"onUpdate:modelValue"?: ((value: DataGrid<G>) => any) | undefined;
|
|
24
|
+
onFetch?: ((reason: "sort" | "filter" | "search" | "paginate" | "refresh") => any) | undefined;
|
|
25
|
+
"onToggle:item"?: ((item: G, expanded: boolean) => any) | undefined;
|
|
26
|
+
}> & (typeof globalThis extends {
|
|
27
|
+
__VLS_PROPS_FALLBACK: infer P;
|
|
28
|
+
} ? P : {});
|
|
29
|
+
expose: (exposed: {}) => void;
|
|
30
|
+
attrs: any;
|
|
31
|
+
slots: {
|
|
32
|
+
[x: `head[${string}]`]: ((props: {
|
|
33
|
+
column: import("../../composables/useDatagrid.js").ColumnDefinition<G>;
|
|
34
|
+
key: string;
|
|
35
|
+
}) => any) | undefined;
|
|
36
|
+
} & {
|
|
37
|
+
[x: `row[${string}]`]: ((props: {
|
|
38
|
+
column: import("../../composables/useDatagrid.js").ColumnDefinition<G>;
|
|
39
|
+
idx: number;
|
|
40
|
+
item: G;
|
|
41
|
+
key: string;
|
|
42
|
+
}) => any) | undefined;
|
|
43
|
+
} & {
|
|
44
|
+
search?: (props: {}) => any;
|
|
45
|
+
} & {
|
|
46
|
+
toolbar?: (props: {}) => any;
|
|
47
|
+
} & {
|
|
48
|
+
filters?: (props: {}) => any;
|
|
49
|
+
} & {
|
|
50
|
+
empty?: (props: {}) => any;
|
|
51
|
+
} & {
|
|
52
|
+
actions?: (props: {
|
|
53
|
+
index: number;
|
|
54
|
+
item: G;
|
|
55
|
+
}) => any;
|
|
56
|
+
} & {
|
|
57
|
+
details?: (props: {
|
|
58
|
+
index: number;
|
|
59
|
+
item: G;
|
|
60
|
+
toggleDetails: () => void;
|
|
61
|
+
}) => any;
|
|
62
|
+
} & {
|
|
63
|
+
tfoot?: (props: {}) => any;
|
|
64
|
+
} & {
|
|
65
|
+
footer?: (props: {}) => any;
|
|
66
|
+
};
|
|
67
|
+
emit: {
|
|
68
|
+
(e: "fetch", reason: "sort" | "filter" | "search" | "paginate" | "refresh"): void;
|
|
69
|
+
(e: "toggle:item", item: G, expanded: boolean): void;
|
|
70
|
+
} & ((evt: "update:modelValue", value: DataGrid<G>) => void);
|
|
71
|
+
}>) => import("vue").VNode & {
|
|
72
|
+
__ctx?: Awaited<typeof __VLS_setup>;
|
|
73
|
+
};
|
|
74
|
+
declare const _default: typeof __VLS_export;
|
|
75
|
+
export default _default;
|
|
76
|
+
type __VLS_PrettifyLocal<T> = (T extends any ? {
|
|
77
|
+
[K in keyof T]: T[K];
|
|
78
|
+
} : {
|
|
79
|
+
[K in keyof T as K]: T[K];
|
|
80
|
+
}) & {};
|
|
@@ -1,18 +1,23 @@
|
|
|
1
|
-
|
|
2
|
-
interface INavigationItem {
|
|
1
|
+
interface NavigationItem {
|
|
3
2
|
text: string | null;
|
|
4
3
|
path: string;
|
|
4
|
+
loading?: boolean;
|
|
5
5
|
}
|
|
6
|
-
|
|
6
|
+
type NavigationItemOrGetter = NavigationItem | (() => NavigationItem);
|
|
7
|
+
export declare function useNavigation(page?: NavigationItemOrGetter): {
|
|
7
8
|
current: import("vue").ComputedRef<{
|
|
8
9
|
path: string;
|
|
9
10
|
text: string | null;
|
|
11
|
+
loading: boolean;
|
|
10
12
|
} | undefined>;
|
|
11
13
|
items: import("vue").ComputedRef<{
|
|
12
14
|
path: string;
|
|
13
15
|
text: string | null;
|
|
16
|
+
loading: boolean;
|
|
14
17
|
}[]>;
|
|
15
|
-
|
|
16
|
-
|
|
18
|
+
defer: (route: {
|
|
19
|
+
path: string;
|
|
20
|
+
}) => void;
|
|
21
|
+
regenerate: () => void;
|
|
17
22
|
};
|
|
18
23
|
export {};
|
|
@@ -2,45 +2,50 @@ import { computed } from "vue";
|
|
|
2
2
|
import { useState } from "#imports";
|
|
3
3
|
export function useNavigation(page) {
|
|
4
4
|
const list = useState("breadcrumbs", () => []);
|
|
5
|
+
const pendingRoute = useState("breadcrumbs:pending", () => null);
|
|
5
6
|
function normalizePath(base, path) {
|
|
6
|
-
|
|
7
|
-
if (!path.startsWith("/")) {
|
|
8
|
-
path = "/" + path;
|
|
9
|
-
}
|
|
10
|
-
if (base.endsWith("/")) {
|
|
11
|
-
base = base.slice(0, -1);
|
|
12
|
-
}
|
|
13
|
-
return base + path;
|
|
7
|
+
return `${base.replace(/\/$/, "")}/${path.replace(/^\//, "")}`;
|
|
14
8
|
}
|
|
15
|
-
|
|
9
|
+
function resolve(item) {
|
|
10
|
+
return typeof item === "function" ? item() : item;
|
|
11
|
+
}
|
|
12
|
+
const resolved = computed(() => {
|
|
16
13
|
let uri = "";
|
|
17
|
-
return list.value.map((
|
|
14
|
+
return list.value.map((item) => {
|
|
15
|
+
const { text, path = "", loading } = resolve(item);
|
|
18
16
|
uri = normalizePath(uri, path);
|
|
19
|
-
return { path: uri, text };
|
|
20
|
-
})
|
|
17
|
+
return { path: uri, text, loading: !!loading };
|
|
18
|
+
});
|
|
19
|
+
});
|
|
20
|
+
const items = computed(() => {
|
|
21
|
+
return resolved.value.filter(({ text, loading }) => text != null && !loading);
|
|
21
22
|
});
|
|
22
23
|
const current = computed(() => {
|
|
23
|
-
|
|
24
|
-
return items.value.at(length - 1);
|
|
24
|
+
return resolved.value.at(-1);
|
|
25
25
|
});
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
const
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
}
|
|
32
|
-
return list.value.push(item);
|
|
33
|
-
};
|
|
34
|
-
if (page) {
|
|
35
|
-
setPage(page);
|
|
36
|
-
}
|
|
37
|
-
function regenerate(route) {
|
|
38
|
-
const itemIndex = items.value.findLastIndex((value) => route.path.startsWith(value.path));
|
|
26
|
+
function regenerate() {
|
|
27
|
+
if (!pendingRoute.value) return;
|
|
28
|
+
const route = pendingRoute.value;
|
|
29
|
+
pendingRoute.value = null;
|
|
30
|
+
const itemIndex = resolved.value.findLastIndex((value) => route.startsWith(value.path));
|
|
39
31
|
if (itemIndex >= 0) {
|
|
40
32
|
list.value = list.value.slice(0, itemIndex + 1);
|
|
41
33
|
return;
|
|
42
34
|
}
|
|
43
35
|
list.value = [];
|
|
44
36
|
}
|
|
45
|
-
|
|
37
|
+
if (page) {
|
|
38
|
+
regenerate();
|
|
39
|
+
const { path } = resolve(page);
|
|
40
|
+
const existingIndex = list.value.findIndex((i) => resolve(i).path === path);
|
|
41
|
+
if (existingIndex >= 0) {
|
|
42
|
+
list.value[existingIndex] = page;
|
|
43
|
+
} else {
|
|
44
|
+
list.value.push(page);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
function defer(route) {
|
|
48
|
+
pendingRoute.value = route.path;
|
|
49
|
+
}
|
|
50
|
+
return { current, items, defer, regenerate };
|
|
46
51
|
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
type FieldConstraints = {
|
|
2
|
+
maxlength?: number;
|
|
3
|
+
minlength?: number;
|
|
4
|
+
required?: boolean;
|
|
5
|
+
};
|
|
6
|
+
type FieldAttrs = FieldConstraints & {
|
|
7
|
+
state?: boolean | null;
|
|
8
|
+
};
|
|
9
|
+
export declare function useValidator<T extends object>(instance: T): {
|
|
10
|
+
form: T;
|
|
11
|
+
attrs: import("vue").ComputedRef<{ [K in keyof T]?: FieldAttrs | undefined; }>;
|
|
12
|
+
valid: import("vue").ComputedRef<boolean>;
|
|
13
|
+
errors: Record<keyof T, string>;
|
|
14
|
+
validate: () => Promise<boolean>;
|
|
15
|
+
};
|
|
16
|
+
export {};
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { reactive, computed, ref } from "vue";
|
|
2
|
+
import { validate as classValidate, getMetadataStorage } from "class-validator";
|
|
3
|
+
const handlers = {
|
|
4
|
+
isLength(entry, [min, max]) {
|
|
5
|
+
if (min > 0) entry.minlength = min;
|
|
6
|
+
if (max != null) entry.maxlength = max;
|
|
7
|
+
},
|
|
8
|
+
isNotEmpty(entry) {
|
|
9
|
+
entry.required = true;
|
|
10
|
+
}
|
|
11
|
+
};
|
|
12
|
+
function extractConstraints(constructor) {
|
|
13
|
+
const metadata = getMetadataStorage().getTargetValidationMetadatas(constructor, "", false, false);
|
|
14
|
+
const constraints = {};
|
|
15
|
+
for (const meta of metadata) {
|
|
16
|
+
const prop = meta.propertyName;
|
|
17
|
+
if (!constraints[prop]) constraints[prop] = {};
|
|
18
|
+
const handler = handlers[meta.name];
|
|
19
|
+
if (handler) handler(constraints[prop], meta.constraints ?? []);
|
|
20
|
+
}
|
|
21
|
+
return constraints;
|
|
22
|
+
}
|
|
23
|
+
function applyErrors(result, errors, state) {
|
|
24
|
+
for (const key of Object.keys(errors)) {
|
|
25
|
+
errors[key] = "";
|
|
26
|
+
state[key] = true;
|
|
27
|
+
}
|
|
28
|
+
for (const error of result) {
|
|
29
|
+
const messages = error.constraints ? Object.values(error.constraints) : [];
|
|
30
|
+
errors[error.property] = messages[0] || "Invalid";
|
|
31
|
+
state[error.property] = false;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
function mergeAttrs(constraints, state) {
|
|
35
|
+
const result = {};
|
|
36
|
+
const keys = /* @__PURE__ */ new Set([...Object.keys(constraints), ...Object.keys(state)]);
|
|
37
|
+
for (const key of keys) {
|
|
38
|
+
const prop = key;
|
|
39
|
+
result[prop] = { ...constraints[prop], state: state[key] ?? null };
|
|
40
|
+
}
|
|
41
|
+
return result;
|
|
42
|
+
}
|
|
43
|
+
export function useValidator(instance) {
|
|
44
|
+
const form = reactive(instance);
|
|
45
|
+
const constraints = extractConstraints(instance.constructor);
|
|
46
|
+
const errors = reactive({});
|
|
47
|
+
const state = reactive({});
|
|
48
|
+
const validated = ref(false);
|
|
49
|
+
const valid = computed(() => validated.value && !Object.values(errors).some((v) => v));
|
|
50
|
+
const attrs = computed(() => mergeAttrs(constraints, state));
|
|
51
|
+
async function validate() {
|
|
52
|
+
const plain = Object.assign(Object.create(Object.getPrototypeOf(instance)), form);
|
|
53
|
+
const result = await classValidate(plain);
|
|
54
|
+
applyErrors(result, errors, state);
|
|
55
|
+
validated.value = true;
|
|
56
|
+
return result.length === 0;
|
|
57
|
+
}
|
|
58
|
+
return { form, attrs, valid, errors, validate };
|
|
59
|
+
}
|
|
@@ -16,5 +16,7 @@ export default defineNuxtRouteMiddleware((to) => {
|
|
|
16
16
|
if (isAuthenticated.value) {
|
|
17
17
|
return;
|
|
18
18
|
}
|
|
19
|
-
|
|
19
|
+
const redirect = to.fullPath;
|
|
20
|
+
const callbackUrl = redirect === "/" ? merkaly.auth0.callbackUrl : `${merkaly.auth0.callbackUrl}?redirect=${encodeURIComponent(redirect)}`;
|
|
21
|
+
return navigateTo(callbackUrl);
|
|
20
22
|
});
|
|
@@ -51,6 +51,10 @@ export default defineNuxtPlugin(async ({ callHook, hook }) => {
|
|
|
51
51
|
return $api("/identities", { method: "POST", prefix: "/", body });
|
|
52
52
|
});
|
|
53
53
|
};
|
|
54
|
-
|
|
54
|
+
const isAuthCallback = window.location.pathname === $config.merkaly.auth0.callbackUrl;
|
|
55
|
+
if (!isAuthCallback) {
|
|
56
|
+
await Promise.allSettled([auth0.getUser(), auth0.getTokenSilently()]).then(() => hook("app:created", () => callHook("merkaly:auth", user.value))).catch(() => void 0);
|
|
57
|
+
}
|
|
58
|
+
isLoading.value = false;
|
|
55
59
|
return { provide: { auth0 } };
|
|
56
60
|
});
|
|
@@ -6,6 +6,9 @@ export const withAdapter = (callback) => (args) => {
|
|
|
6
6
|
const { params: initialParams = {}, ...hooks } = config;
|
|
7
7
|
const mergedParams = defu(executionParams, { ...initialParams });
|
|
8
8
|
const adapterResult = callback(mergedParams);
|
|
9
|
+
if (adapterResult.body && typeof adapterResult.body === "object" && !(adapterResult.body instanceof FormData)) {
|
|
10
|
+
adapterResult.body = { ...adapterResult.body };
|
|
11
|
+
}
|
|
9
12
|
return defu(hooks, adapterResult);
|
|
10
13
|
});
|
|
11
14
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@merkaly/nuxt",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.1",
|
|
4
4
|
"repository": {
|
|
5
5
|
"type": "git",
|
|
6
6
|
"url": "git+https://github.com/merkaly-io/nuxt.git"
|
|
@@ -27,6 +27,20 @@
|
|
|
27
27
|
"files": [
|
|
28
28
|
"dist"
|
|
29
29
|
],
|
|
30
|
+
"scripts": {
|
|
31
|
+
"build": "nuxt-module-build build",
|
|
32
|
+
"build:stub": "nuxt-module-build build --stub",
|
|
33
|
+
"dev": "pnpm dev:prepare && cd playground && pnpm storybook",
|
|
34
|
+
"dev:build": "nuxi build playground",
|
|
35
|
+
"dev:prepare": "pnpm build:stub && nuxi prepare playground",
|
|
36
|
+
"lint": "eslint .",
|
|
37
|
+
"prepack": "pnpm build",
|
|
38
|
+
"prepare": "nuxt-module-build prepare",
|
|
39
|
+
"release": "pnpm lint && pnpm test && pnpm build && changelogen --release && npm publish --access public && git push --follow-tags",
|
|
40
|
+
"test": "vitest run",
|
|
41
|
+
"test:types": "vue-tsc --noEmit && cd playground && vue-tsc --noEmit",
|
|
42
|
+
"test:watch": "vitest watch"
|
|
43
|
+
},
|
|
30
44
|
"dependencies": {
|
|
31
45
|
"@auth0/auth0-spa-js": "^2.14.0",
|
|
32
46
|
"@bootstrap-vue-next/nuxt": "^0.43.0",
|
|
@@ -46,6 +60,7 @@
|
|
|
46
60
|
"bootstrap": "^5.3.8",
|
|
47
61
|
"bootstrap-vue-next": "^0.43.0",
|
|
48
62
|
"change-case": "^5",
|
|
63
|
+
"class-validator": "^0.14.3",
|
|
49
64
|
"eslint": "^9.39.1",
|
|
50
65
|
"filesize": "^11.0.2",
|
|
51
66
|
"nuxt": "^4.3.0",
|
|
@@ -72,17 +87,5 @@
|
|
|
72
87
|
},
|
|
73
88
|
"engines": {
|
|
74
89
|
"node": ">=20.0.0"
|
|
75
|
-
},
|
|
76
|
-
"scripts": {
|
|
77
|
-
"build": "nuxt-module-build build",
|
|
78
|
-
"build:stub": "nuxt-module-build build --stub",
|
|
79
|
-
"dev": "pnpm dev:prepare && cd playground && pnpm storybook",
|
|
80
|
-
"dev:build": "nuxi build playground",
|
|
81
|
-
"dev:prepare": "pnpm build:stub && nuxi prepare playground",
|
|
82
|
-
"lint": "eslint .",
|
|
83
|
-
"release": "pnpm lint && pnpm test && pnpm build && changelogen --release && npm publish --access public && git push --follow-tags",
|
|
84
|
-
"test": "vitest run",
|
|
85
|
-
"test:types": "vue-tsc --noEmit && cd playground && vue-tsc --noEmit",
|
|
86
|
-
"test:watch": "vitest watch"
|
|
87
90
|
}
|
|
88
|
-
}
|
|
91
|
+
}
|