@bg-dev/nuxt-zenstack 0.0.3 → 0.0.4
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/module.mjs +21 -8
- package/dist/runtime/composables/common.d.ts +0 -8
- package/dist/runtime/composables/useZenstackCreate/index.d.ts +3 -3
- package/dist/runtime/composables/useZenstackDelete/index.d.ts +3 -3
- package/dist/runtime/composables/useZenstackRead/index.d.ts +4 -4
- package/dist/runtime/composables/useZenstackRead/index.js +8 -7
- package/dist/runtime/composables/useZenstackReadMany/index.d.ts +4 -3
- package/dist/runtime/composables/useZenstackReadMany/index.js +21 -8
- package/dist/runtime/composables/useZenstackReadMany/orderBy.d.ts +5 -0
- package/dist/runtime/composables/useZenstackReadMany/orderBy.js +25 -0
- package/dist/runtime/composables/useZenstackReadMany/where.d.ts +2 -0
- package/dist/runtime/composables/useZenstackReadMany/where.js +235 -0
- package/dist/runtime/composables/useZenstackStore/index.d.ts +6 -2
- package/dist/runtime/composables/useZenstackStore/index.js +3 -4
- package/dist/runtime/composables/useZenstackStore/normalization.d.ts +16 -3
- package/dist/runtime/composables/useZenstackStore/normalization.js +16 -3
- package/dist/runtime/composables/useZenstackUpdate/index.d.ts +2 -2
- package/dist/runtime/server/api/models/[model]/[id].delete.js +4 -1
- package/dist/runtime/server/api/models/[model]/[id].get.js +4 -1
- package/dist/runtime/server/api/models/[model]/[id].patch.js +7 -4
- package/dist/runtime/server/api/models/[model]/index.get.js +4 -1
- package/dist/runtime/server/api/models/[model]/index.post.js +7 -4
- package/dist/runtime/server/utils/error.d.ts +9 -0
- package/dist/runtime/server/utils/error.js +49 -0
- package/dist/runtime/server/utils/index.d.ts +3 -7
- package/dist/runtime/server/utils/index.js +5 -9
- package/dist/runtime/server/utils/parsers.d.ts +2 -2
- package/dist/runtime/server/utils/parsers.js +2 -2
- package/package.json +3 -1
package/dist/module.json
CHANGED
package/dist/module.mjs
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { defineNuxtModule, createResolver,
|
|
1
|
+
import { defineNuxtModule, createResolver, addTemplate, addServerTemplate, addTypeTemplate, addServerHandler, addImportsDir } from '@nuxt/kit';
|
|
2
2
|
import { joinURL } from 'ufo';
|
|
3
3
|
import { defu } from 'defu';
|
|
4
4
|
|
|
5
5
|
const name = "@bg-dev/nuxt-zenstack";
|
|
6
|
-
const version = "0.0.
|
|
6
|
+
const version = "0.0.4";
|
|
7
7
|
|
|
8
8
|
const module$1 = defineNuxtModule({
|
|
9
9
|
meta: {
|
|
@@ -24,11 +24,6 @@ const module$1 = defineNuxtModule({
|
|
|
24
24
|
}
|
|
25
25
|
});
|
|
26
26
|
const resolver = createResolver(import.meta.url);
|
|
27
|
-
addServerImports({
|
|
28
|
-
from: resolver.resolve("./runtime/server/utils"),
|
|
29
|
-
name: "provideClient",
|
|
30
|
-
as: "provideZenstackClient"
|
|
31
|
-
});
|
|
32
27
|
addTemplate({
|
|
33
28
|
write: true,
|
|
34
29
|
filename: "nuxt-zenstack.mjs",
|
|
@@ -45,9 +40,11 @@ export { schema as zenstackSchema } from '~~/zenstack/schema'
|
|
|
45
40
|
addTypeTemplate({
|
|
46
41
|
filename: "types/nuxt-zenstack.d.ts",
|
|
47
42
|
getContents: () => `
|
|
48
|
-
import type { ModelOperations, ModelResult, IncludeInput, WhereInput, FindManyArgs, SimplifiedPlainResult, SelectIncludeOmit, QueryOptions, CreateArgs, UpdateArgs } from '@zenstackhq/orm'
|
|
43
|
+
import type { ClientContract, ModelOperations, ModelResult, IncludeInput, WhereInput, FindManyArgs, SimplifiedPlainResult, SelectIncludeOmit, QueryOptions, CreateArgs, UpdateArgs } from '@zenstackhq/orm'
|
|
49
44
|
import type { SchemaType } from '~~/zenstack/schema'
|
|
50
45
|
import type { ModelDef } from '@zenstackhq/orm/schema'
|
|
46
|
+
import type { H3Error } from 'h3'
|
|
47
|
+
import { ORMError, RejectedByPolicyReason, ORMErrorReason } from '@zenstackhq/orm'
|
|
51
48
|
|
|
52
49
|
type ItemGetPayload<Zmodel extends $Zmodel, Args extends SelectIncludeOmit<SchemaType, Zmodel, true>, Options extends QueryOptions<SchemaType> = QueryOptions<SchemaType>> = SimplifiedPlainResult<SchemaType, Zmodel, Args, Options>
|
|
53
50
|
|
|
@@ -62,6 +59,22 @@ export type $Zwhere<Zmodel extends $Zmodel> = WhereInput<SchemaType, Zmodel> | u
|
|
|
62
59
|
export type $ZorderBy<Zmodel extends $Zmodel> = FindManyArgs<SchemaType, Zmodel>['orderBy'] | undefined
|
|
63
60
|
export type $ZcreateData<Zmodel extends $Zmodel> = CreateArgs<SchemaType, Zmodel>['data']
|
|
64
61
|
export type $ZupdateData<Zmodel extends $Zmodel> = UpdateArgs<SchemaType, Zmodel>['data']
|
|
62
|
+
export type $ZormError = ORMError
|
|
63
|
+
export type $Zerror = H3Error<{
|
|
64
|
+
ormErrorReason: ORMErrorReason
|
|
65
|
+
dbErrorCode?: unknown
|
|
66
|
+
dbErrorMessage?: string
|
|
67
|
+
model?: string
|
|
68
|
+
rejectedByPolicyReason?: RejectedByPolicyReason
|
|
69
|
+
}>
|
|
70
|
+
|
|
71
|
+
declare module 'h3' {
|
|
72
|
+
interface H3EventContext {
|
|
73
|
+
zenstack: {
|
|
74
|
+
client: ClientContract<SchemaType>
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
65
78
|
`
|
|
66
79
|
});
|
|
67
80
|
addServerHandler({
|
|
@@ -1,13 +1,5 @@
|
|
|
1
1
|
export type Status = 'idle' | 'pending' | 'success' | 'error';
|
|
2
2
|
export type FetchPolicy = 'cache-first' | 'fetch-only' | 'cache-only' | 'cache-and-fetch';
|
|
3
|
-
export type Error = {
|
|
4
|
-
error: boolean;
|
|
5
|
-
url: string;
|
|
6
|
-
statusCode: number;
|
|
7
|
-
statusMessage: string;
|
|
8
|
-
message: string;
|
|
9
|
-
stack?: string[];
|
|
10
|
-
};
|
|
11
3
|
export declare function getConfig(): {
|
|
12
4
|
apiPath: string;
|
|
13
5
|
fetchPolicy: FetchPolicy;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import type { $Zmodel, $Zitem, $ZcreateData } from '#build/types/nuxt-zenstack';
|
|
2
|
-
import type { Status
|
|
1
|
+
import type { $Zmodel, $Zitem, $ZcreateData, $Zerror } from '#build/types/nuxt-zenstack';
|
|
2
|
+
import type { Status } from '../common.js';
|
|
3
3
|
import { type Ref } from '#imports';
|
|
4
4
|
export declare function useZenstackCreate<Zmodel extends $Zmodel, Zitem extends $Zitem<Zmodel>>(model: Zmodel): {
|
|
5
5
|
data: Ref<Zitem | null>;
|
|
6
|
-
error: Ref
|
|
6
|
+
error: Ref<$Zerror | null>;
|
|
7
7
|
status: Ref<Status>;
|
|
8
8
|
mutate: (input: $ZcreateData<Zmodel>) => Promise<void>;
|
|
9
9
|
reset: () => void;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import type { $Zmodel, $Zitem, $Zid } from '#build/types/nuxt-zenstack';
|
|
2
|
-
import type { Status
|
|
1
|
+
import type { $Zmodel, $Zitem, $Zid, $Zerror } from '#build/types/nuxt-zenstack';
|
|
2
|
+
import type { Status } from '../common.js';
|
|
3
3
|
import { type Ref } from '#imports';
|
|
4
4
|
export declare function useZenstackDelete<Zmodel extends $Zmodel, Zitem extends $Zitem<Zmodel>>(model: Zmodel): {
|
|
5
5
|
data: Ref<Zitem | null>;
|
|
6
|
-
error: Ref
|
|
6
|
+
error: Ref<$Zerror | null>;
|
|
7
7
|
status: Ref<Status>;
|
|
8
8
|
mutate: (id: $Zid<Zmodel>) => Promise<void>;
|
|
9
9
|
reset: () => void;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import type { $Zmodel, $Zitem, $Zid, $Zinclude } from '#build/types/nuxt-zenstack';
|
|
1
|
+
import type { $Zmodel, $Zitem, $Zid, $Zinclude, $Zerror } from '#build/types/nuxt-zenstack';
|
|
2
2
|
import type { Status, FetchPolicy } from '../common.js';
|
|
3
|
-
import type { Ref
|
|
3
|
+
import type { Ref } from '#imports';
|
|
4
4
|
type Options<Zinclude> = {
|
|
5
5
|
/**
|
|
6
6
|
* - `cache-first` means that the query will first try to fetch the data from the store. If the data is not found in the store, it will fetch the data from the server and update the store.
|
|
@@ -19,11 +19,11 @@ type Options<Zinclude> = {
|
|
|
19
19
|
* The relations to include in the query.
|
|
20
20
|
* @default undefined
|
|
21
21
|
*/
|
|
22
|
-
include?:
|
|
22
|
+
include?: Zinclude;
|
|
23
23
|
};
|
|
24
24
|
export declare function useZenstackRead<Zmodel extends $Zmodel, Zinclude extends $Zinclude<Zmodel>, Zitem extends $Zitem<Zmodel, Zinclude>>(model: Zmodel, id: $Zid<Zmodel>, opts?: Options<Zinclude>): Promise<{
|
|
25
25
|
data: Ref<Zitem | null>;
|
|
26
|
-
error: Ref
|
|
26
|
+
error: Ref<$Zerror | null>;
|
|
27
27
|
status: Ref<Status>;
|
|
28
28
|
refetch: () => Promise<void>;
|
|
29
29
|
}>;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ref,
|
|
1
|
+
import { ref, watch, useNuxtApp } from "#imports";
|
|
2
2
|
import { joinURL } from "ufo";
|
|
3
3
|
import { useZenstackStore } from "../useZenstackStore/index.js";
|
|
4
4
|
import { stringify } from "superjson";
|
|
@@ -10,19 +10,15 @@ export async function useZenstackRead(model, id, opts = {}) {
|
|
|
10
10
|
const store = useZenstackStore();
|
|
11
11
|
const config = getConfig();
|
|
12
12
|
const nuxtApp = useNuxtApp();
|
|
13
|
-
const watchedOptions = [opts.include].filter((option) => isRef(option) || typeof option === "function");
|
|
14
13
|
const method = "GET";
|
|
15
14
|
opts.fetchPolicy ??= config.fetchPolicy;
|
|
16
15
|
opts.immediate ??= true;
|
|
17
16
|
if (opts.fetchPolicy !== "fetch-only")
|
|
18
17
|
updateData();
|
|
19
18
|
watch(store.state, () => updateData());
|
|
20
|
-
watch(watchedOptions, () => refetch());
|
|
21
19
|
if (shouldFetchInitially())
|
|
22
20
|
await refetch();
|
|
23
|
-
function
|
|
24
|
-
if (opts.immediate === false)
|
|
25
|
-
return false;
|
|
21
|
+
function canFetchAutomatically() {
|
|
26
22
|
const entry = store.fetchHistory.value.find((entry2) => entry2.model === model && entry2.id === id && entry2.method === method && entry2.query === JSON.stringify(getQuery()));
|
|
27
23
|
if (entry?.ssr && nuxtApp.isHydrating)
|
|
28
24
|
return false;
|
|
@@ -30,12 +26,17 @@ export async function useZenstackRead(model, id, opts = {}) {
|
|
|
30
26
|
return false;
|
|
31
27
|
return true;
|
|
32
28
|
}
|
|
29
|
+
function shouldFetchInitially() {
|
|
30
|
+
if (opts.immediate === false)
|
|
31
|
+
return false;
|
|
32
|
+
return canFetchAutomatically();
|
|
33
|
+
}
|
|
33
34
|
function updateData() {
|
|
34
35
|
data.value = store.getOne(model, id);
|
|
35
36
|
}
|
|
36
37
|
function getQuery() {
|
|
37
38
|
const json = stringify({
|
|
38
|
-
include:
|
|
39
|
+
include: opts.include
|
|
39
40
|
});
|
|
40
41
|
return { q: json };
|
|
41
42
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { $Zmodel, $Zitem, $Zinclude, $Zwhere, $ZorderBy } from '#build/types/nuxt-zenstack';
|
|
1
|
+
import type { $Zmodel, $Zitem, $Zinclude, $Zwhere, $ZorderBy, $Zerror } from '#build/types/nuxt-zenstack';
|
|
2
2
|
import type { Status, FetchPolicy } from '../common.js';
|
|
3
3
|
import type { MaybeRefOrGetter, Ref } from '#imports';
|
|
4
4
|
type Options<Zinclude, Zwhere, ZorderBy> = {
|
|
@@ -19,7 +19,7 @@ type Options<Zinclude, Zwhere, ZorderBy> = {
|
|
|
19
19
|
* The relations to include in the query.
|
|
20
20
|
* @default undefined
|
|
21
21
|
*/
|
|
22
|
-
include?:
|
|
22
|
+
include?: Zinclude;
|
|
23
23
|
/**
|
|
24
24
|
* The filter to apply to the query.
|
|
25
25
|
* @default undefined
|
|
@@ -43,8 +43,9 @@ type Options<Zinclude, Zwhere, ZorderBy> = {
|
|
|
43
43
|
};
|
|
44
44
|
export declare function useZenstackReadMany<Zmodel extends $Zmodel, Zinclude extends $Zinclude<Zmodel>, Zitem extends $Zitem<Zmodel, Zinclude>, Zwhere extends $Zwhere<Zmodel>, ZorderBy extends $ZorderBy<Zmodel>>(model: Zmodel, opts?: Options<Zinclude, Zwhere, ZorderBy>): Promise<{
|
|
45
45
|
data: Ref<Zitem[] | null>;
|
|
46
|
-
error: Ref
|
|
46
|
+
error: Ref<$Zerror | null>;
|
|
47
47
|
status: Ref<Status>;
|
|
48
|
+
canFetchMore: Ref<boolean>;
|
|
48
49
|
refetch: () => Promise<void>;
|
|
49
50
|
}>;
|
|
50
51
|
export {};
|
|
@@ -3,14 +3,17 @@ import { joinURL } from "ufo";
|
|
|
3
3
|
import { useZenstackStore } from "../useZenstackStore/index.js";
|
|
4
4
|
import { stringify } from "superjson";
|
|
5
5
|
import { getConfig, getFetch } from "../common.js";
|
|
6
|
+
import { sort } from "./orderBy.js";
|
|
7
|
+
import { matchesWhere } from "./where.js";
|
|
6
8
|
export async function useZenstackReadMany(model, opts = {}) {
|
|
7
9
|
const data = ref(null);
|
|
8
10
|
const error = ref(null);
|
|
9
11
|
const status = ref("idle");
|
|
12
|
+
const canFetchMore = ref(true);
|
|
10
13
|
const store = useZenstackStore();
|
|
11
14
|
const config = getConfig();
|
|
12
15
|
const nuxtApp = useNuxtApp();
|
|
13
|
-
const watchedOptions = [opts.
|
|
16
|
+
const watchedOptions = [opts.where, opts.orderBy, opts.skip, opts.take].filter((option) => isRef(option) || typeof option === "function");
|
|
14
17
|
const method = "GET";
|
|
15
18
|
opts.fetchPolicy ??= config.fetchPolicy;
|
|
16
19
|
opts.immediate ??= true;
|
|
@@ -21,13 +24,12 @@ export async function useZenstackReadMany(model, opts = {}) {
|
|
|
21
24
|
watch(store.state, () => updateData());
|
|
22
25
|
watch(watchedOptions, () => {
|
|
23
26
|
updateData();
|
|
24
|
-
|
|
27
|
+
if (canFetchAutomatically())
|
|
28
|
+
refetch();
|
|
25
29
|
});
|
|
26
30
|
if (shouldFetchInitially())
|
|
27
31
|
await refetch();
|
|
28
|
-
function
|
|
29
|
-
if (opts.immediate === false)
|
|
30
|
-
return false;
|
|
32
|
+
function canFetchAutomatically() {
|
|
31
33
|
const entry = store.fetchHistory.value.find((entry2) => entry2.model === model && entry2.method === method && entry2.query === JSON.stringify(getQuery()));
|
|
32
34
|
if (entry?.ssr && nuxtApp.isHydrating)
|
|
33
35
|
return false;
|
|
@@ -35,12 +37,20 @@ export async function useZenstackReadMany(model, opts = {}) {
|
|
|
35
37
|
return false;
|
|
36
38
|
return true;
|
|
37
39
|
}
|
|
40
|
+
function shouldFetchInitially() {
|
|
41
|
+
if (opts.immediate === false)
|
|
42
|
+
return false;
|
|
43
|
+
return canFetchAutomatically();
|
|
44
|
+
}
|
|
38
45
|
function updateData() {
|
|
39
|
-
|
|
46
|
+
const items = store.getMany(model);
|
|
47
|
+
const filteredItems = items.filter((el) => matchesWhere(el, toValue(opts.where)));
|
|
48
|
+
const orderedFilteredItems = sort(filteredItems, toValue(opts.orderBy));
|
|
49
|
+
data.value = orderedFilteredItems;
|
|
40
50
|
}
|
|
41
51
|
function getQuery() {
|
|
42
52
|
const json = stringify({
|
|
43
|
-
include:
|
|
53
|
+
include: opts.include,
|
|
44
54
|
where: toValue(opts.where),
|
|
45
55
|
orderBy: toValue(opts.orderBy),
|
|
46
56
|
skip: toValue(opts.skip),
|
|
@@ -61,15 +71,18 @@ export async function useZenstackReadMany(model, opts = {}) {
|
|
|
61
71
|
});
|
|
62
72
|
error.value = null;
|
|
63
73
|
status.value = "pending";
|
|
74
|
+
canFetchMore.value = false;
|
|
64
75
|
try {
|
|
65
76
|
const res = await _fetch(url, { method, query });
|
|
66
77
|
store.setMany(model, res.data);
|
|
67
78
|
updateData();
|
|
68
79
|
status.value = "success";
|
|
80
|
+
canFetchMore.value = res.data.length === toValue(opts.take);
|
|
69
81
|
} catch (err) {
|
|
70
82
|
error.value = err.data;
|
|
71
83
|
status.value = "error";
|
|
84
|
+
canFetchMore.value = true;
|
|
72
85
|
}
|
|
73
86
|
}
|
|
74
|
-
return { data, error, status, refetch };
|
|
87
|
+
return { data, error, status, canFetchMore, refetch };
|
|
75
88
|
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { $Zitem, $ZorderBy, $Zinclude, $Zmodel } from '#build/types/nuxt-zenstack';
|
|
2
|
+
/**
|
|
3
|
+
* @note Sort by relational fields not supported
|
|
4
|
+
*/
|
|
5
|
+
export declare function sort<Zmodel extends $Zmodel, Zinclude extends $Zinclude<Zmodel>, Zitem extends $Zitem<Zmodel, Zinclude>>(items: Zitem[], orderBy: $ZorderBy<Zmodel>): Zitem[];
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
export function sort(items, orderBy) {
|
|
2
|
+
if (!items.length || !orderBy)
|
|
3
|
+
return items;
|
|
4
|
+
return items.sort((a, b) => {
|
|
5
|
+
const orderByArray = Array.isArray(orderBy) ? orderBy : [orderBy];
|
|
6
|
+
for (const orderByObj of orderByArray) {
|
|
7
|
+
const orderByEntries = Object.entries(orderByObj);
|
|
8
|
+
for (const [field, direction] of orderByEntries) {
|
|
9
|
+
if (direction !== "asc" && direction !== "desc") continue;
|
|
10
|
+
const aValue = a[field];
|
|
11
|
+
const bValue = b[field];
|
|
12
|
+
if (aValue == null && bValue == null) continue;
|
|
13
|
+
if (aValue == null) return 1;
|
|
14
|
+
if (bValue == null) return -1;
|
|
15
|
+
let comparison = 0;
|
|
16
|
+
if (aValue < bValue) comparison = -1;
|
|
17
|
+
else if (aValue > bValue) comparison = 1;
|
|
18
|
+
if (comparison !== 0) {
|
|
19
|
+
return direction === "asc" ? comparison : -comparison;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
return 0;
|
|
24
|
+
});
|
|
25
|
+
}
|
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
export function matchesWhere(item, where) {
|
|
2
|
+
if (!where) return true;
|
|
3
|
+
if (!item) return false;
|
|
4
|
+
const itemRecord = item;
|
|
5
|
+
const whereRecord = where;
|
|
6
|
+
for (const key of Object.keys(whereRecord)) {
|
|
7
|
+
if (whereRecord[key] === void 0) continue;
|
|
8
|
+
const filter = whereRecord[key];
|
|
9
|
+
if (key === "AND") {
|
|
10
|
+
if (Array.isArray(filter)) {
|
|
11
|
+
if (!filter.every((cond) => matchesWhere(item, cond))) return false;
|
|
12
|
+
} else {
|
|
13
|
+
if (!matchesWhere(item, filter)) return false;
|
|
14
|
+
}
|
|
15
|
+
continue;
|
|
16
|
+
}
|
|
17
|
+
if (key === "OR") {
|
|
18
|
+
if (Array.isArray(filter)) {
|
|
19
|
+
if (!filter.some((cond) => matchesWhere(item, cond))) return false;
|
|
20
|
+
} else {
|
|
21
|
+
if (!matchesWhere(item, filter)) return false;
|
|
22
|
+
}
|
|
23
|
+
continue;
|
|
24
|
+
}
|
|
25
|
+
if (key === "NOT") {
|
|
26
|
+
if (Array.isArray(filter)) {
|
|
27
|
+
if (filter.some((cond) => matchesWhere(item, cond))) return false;
|
|
28
|
+
} else {
|
|
29
|
+
if (matchesWhere(item, filter)) return false;
|
|
30
|
+
}
|
|
31
|
+
continue;
|
|
32
|
+
}
|
|
33
|
+
const value = itemRecord[key];
|
|
34
|
+
if (!checkCondition(value, filter)) {
|
|
35
|
+
return false;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
return true;
|
|
39
|
+
}
|
|
40
|
+
function checkCondition(value, filter) {
|
|
41
|
+
if (filter === null) {
|
|
42
|
+
return value === null;
|
|
43
|
+
}
|
|
44
|
+
if (filter === void 0) {
|
|
45
|
+
return true;
|
|
46
|
+
}
|
|
47
|
+
if (typeof filter !== "object" && typeof filter !== "function") {
|
|
48
|
+
if (value instanceof Date && typeof filter === "string") {
|
|
49
|
+
return value.toISOString() === filter;
|
|
50
|
+
}
|
|
51
|
+
return value === filter;
|
|
52
|
+
}
|
|
53
|
+
if (value instanceof Date && filter instanceof Date) {
|
|
54
|
+
return value.getTime() === filter.getTime();
|
|
55
|
+
}
|
|
56
|
+
const filterRecord = filter;
|
|
57
|
+
const keys = Object.keys(filterRecord);
|
|
58
|
+
if (keys.length === 0) return true;
|
|
59
|
+
let caseInsensitive = false;
|
|
60
|
+
if (filterRecord.mode === "insensitive") {
|
|
61
|
+
caseInsensitive = true;
|
|
62
|
+
}
|
|
63
|
+
for (const op of keys) {
|
|
64
|
+
if (op === "mode") continue;
|
|
65
|
+
let expected = filterRecord[op];
|
|
66
|
+
let actual = value;
|
|
67
|
+
if (["lt", "lte", "gt", "gte", "equals", "not"].includes(op)) {
|
|
68
|
+
if (actual instanceof Date && typeof expected === "string") {
|
|
69
|
+
const d = new Date(expected);
|
|
70
|
+
if (!Number.isNaN(d.getTime())) expected = d;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
if (caseInsensitive && typeof actual === "string" && typeof expected === "string") {
|
|
74
|
+
if (["equals", "not", "contains", "startsWith", "endsWith"].includes(op)) {
|
|
75
|
+
actual = actual.toLowerCase();
|
|
76
|
+
expected = expected.toLowerCase();
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
switch (op) {
|
|
80
|
+
case "equals":
|
|
81
|
+
if (actual instanceof Date && expected instanceof Date) {
|
|
82
|
+
if (actual.getTime() !== expected.getTime()) return false;
|
|
83
|
+
} else if (actual !== expected) {
|
|
84
|
+
return false;
|
|
85
|
+
}
|
|
86
|
+
break;
|
|
87
|
+
case "not":
|
|
88
|
+
if (typeof expected === "object" && expected !== null && !Array.isArray(expected) && !(expected instanceof Date)) {
|
|
89
|
+
if (checkCondition(value, expected)) return false;
|
|
90
|
+
} else {
|
|
91
|
+
if (actual instanceof Date && expected instanceof Date) {
|
|
92
|
+
if (actual.getTime() === expected.getTime()) return false;
|
|
93
|
+
} else if (actual === expected) {
|
|
94
|
+
return false;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
break;
|
|
98
|
+
case "in":
|
|
99
|
+
if (!Array.isArray(expected)) return false;
|
|
100
|
+
if (caseInsensitive && typeof actual === "string") {
|
|
101
|
+
const lowerVal = actual.toLowerCase();
|
|
102
|
+
const lowerList = expected.map((e) => typeof e === "string" ? e.toLowerCase() : e);
|
|
103
|
+
if (!lowerList.includes(lowerVal)) return false;
|
|
104
|
+
} else {
|
|
105
|
+
if (actual instanceof Date) {
|
|
106
|
+
const time = actual.getTime();
|
|
107
|
+
if (!expected.some((e) => e instanceof Date && e.getTime() === time || e === actual)) return false;
|
|
108
|
+
} else {
|
|
109
|
+
if (!expected.includes(actual)) return false;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
break;
|
|
113
|
+
case "notIn":
|
|
114
|
+
if (!Array.isArray(expected)) return false;
|
|
115
|
+
if (caseInsensitive && typeof actual === "string") {
|
|
116
|
+
const lowerVal = actual.toLowerCase();
|
|
117
|
+
const lowerList = expected.map((e) => typeof e === "string" ? e.toLowerCase() : e);
|
|
118
|
+
if (lowerList.includes(lowerVal)) return false;
|
|
119
|
+
} else {
|
|
120
|
+
if (actual instanceof Date) {
|
|
121
|
+
const time = actual.getTime();
|
|
122
|
+
if (expected.some((e) => e instanceof Date && e.getTime() === time || e === actual)) return false;
|
|
123
|
+
} else {
|
|
124
|
+
if (expected.includes(actual)) return false;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
break;
|
|
128
|
+
case "lt":
|
|
129
|
+
if (typeof actual === "number" && typeof expected === "number") {
|
|
130
|
+
if (!(actual < expected)) return false;
|
|
131
|
+
} else if (actual instanceof Date && expected instanceof Date) {
|
|
132
|
+
if (!(actual < expected)) return false;
|
|
133
|
+
} else if (typeof actual === "string" && typeof expected === "string") {
|
|
134
|
+
if (!(actual < expected)) return false;
|
|
135
|
+
} else {
|
|
136
|
+
if (!(actual < expected)) return false;
|
|
137
|
+
}
|
|
138
|
+
break;
|
|
139
|
+
case "lte":
|
|
140
|
+
if (!(actual <= expected)) return false;
|
|
141
|
+
break;
|
|
142
|
+
case "gt":
|
|
143
|
+
if (!(actual > expected)) return false;
|
|
144
|
+
break;
|
|
145
|
+
case "gte":
|
|
146
|
+
if (!(actual >= expected)) return false;
|
|
147
|
+
break;
|
|
148
|
+
case "contains":
|
|
149
|
+
if (typeof actual !== "string" || typeof expected !== "string" || !actual.includes(expected)) return false;
|
|
150
|
+
break;
|
|
151
|
+
case "startsWith":
|
|
152
|
+
if (typeof actual !== "string" || typeof expected !== "string" || !actual.startsWith(expected)) return false;
|
|
153
|
+
break;
|
|
154
|
+
case "endsWith":
|
|
155
|
+
if (typeof actual !== "string" || typeof expected !== "string" || !actual.endsWith(expected)) return false;
|
|
156
|
+
break;
|
|
157
|
+
// Relations
|
|
158
|
+
case "some":
|
|
159
|
+
if (!Array.isArray(value)) return false;
|
|
160
|
+
if (!value.some((v) => checkInternal(v, expected))) return false;
|
|
161
|
+
break;
|
|
162
|
+
case "every":
|
|
163
|
+
if (!Array.isArray(value)) return false;
|
|
164
|
+
if (!value.every((v) => checkInternal(v, expected))) return false;
|
|
165
|
+
break;
|
|
166
|
+
case "none":
|
|
167
|
+
if (!Array.isArray(value)) return false;
|
|
168
|
+
if (value.some((v) => checkInternal(v, expected))) return false;
|
|
169
|
+
break;
|
|
170
|
+
case "is":
|
|
171
|
+
if (expected === null) {
|
|
172
|
+
if (value != null) return false;
|
|
173
|
+
} else {
|
|
174
|
+
if (value == null) return false;
|
|
175
|
+
if (!checkInternal(value, expected)) return false;
|
|
176
|
+
}
|
|
177
|
+
break;
|
|
178
|
+
case "isNot":
|
|
179
|
+
if (expected === null) {
|
|
180
|
+
if (value == null) return false;
|
|
181
|
+
} else {
|
|
182
|
+
if (value == null) break;
|
|
183
|
+
if (checkInternal(value, expected)) return false;
|
|
184
|
+
}
|
|
185
|
+
break;
|
|
186
|
+
default:
|
|
187
|
+
if (value && typeof value === "object" && !Array.isArray(value) && !(value instanceof Date)) {
|
|
188
|
+
if (!checkCondition(value[op], expected)) return false;
|
|
189
|
+
} else {
|
|
190
|
+
return false;
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
return true;
|
|
195
|
+
}
|
|
196
|
+
function checkInternal(item, where) {
|
|
197
|
+
return matchesWhereInternal(item, where);
|
|
198
|
+
}
|
|
199
|
+
function matchesWhereInternal(item, where) {
|
|
200
|
+
if (!where) return true;
|
|
201
|
+
if (!item) return false;
|
|
202
|
+
for (const key of Object.keys(where)) {
|
|
203
|
+
if (where[key] === void 0) continue;
|
|
204
|
+
const filter = where[key];
|
|
205
|
+
if (key === "AND") {
|
|
206
|
+
if (Array.isArray(filter)) {
|
|
207
|
+
if (!filter.every((cond) => matchesWhereInternal(item, cond))) return false;
|
|
208
|
+
} else {
|
|
209
|
+
if (!matchesWhereInternal(item, filter)) return false;
|
|
210
|
+
}
|
|
211
|
+
continue;
|
|
212
|
+
}
|
|
213
|
+
if (key === "OR") {
|
|
214
|
+
if (Array.isArray(filter)) {
|
|
215
|
+
if (!filter.some((cond) => matchesWhereInternal(item, cond))) return false;
|
|
216
|
+
} else {
|
|
217
|
+
if (!matchesWhereInternal(item, filter)) return false;
|
|
218
|
+
}
|
|
219
|
+
continue;
|
|
220
|
+
}
|
|
221
|
+
if (key === "NOT") {
|
|
222
|
+
if (Array.isArray(filter)) {
|
|
223
|
+
if (filter.some((cond) => matchesWhereInternal(item, cond))) return false;
|
|
224
|
+
} else {
|
|
225
|
+
if (matchesWhereInternal(item, filter)) return false;
|
|
226
|
+
}
|
|
227
|
+
continue;
|
|
228
|
+
}
|
|
229
|
+
const value = item[key];
|
|
230
|
+
if (!checkCondition(value, filter)) {
|
|
231
|
+
return false;
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
return true;
|
|
235
|
+
}
|
|
@@ -11,11 +11,15 @@ type FetchEntry = {
|
|
|
11
11
|
export declare function useZenstackStore(): {
|
|
12
12
|
state: Readonly<import("vue").Ref<{
|
|
13
13
|
readonly [x: string]: {
|
|
14
|
-
readonly [x: string]:
|
|
14
|
+
readonly [x: string]: {
|
|
15
|
+
readonly [x: string]: string | number | boolean | readonly string[] | null;
|
|
16
|
+
};
|
|
15
17
|
};
|
|
16
18
|
}, {
|
|
17
19
|
readonly [x: string]: {
|
|
18
|
-
readonly [x: string]:
|
|
20
|
+
readonly [x: string]: {
|
|
21
|
+
readonly [x: string]: string | number | boolean | readonly string[] | null;
|
|
22
|
+
};
|
|
19
23
|
};
|
|
20
24
|
}>>;
|
|
21
25
|
fetchHistory: Readonly<import("vue").Ref<readonly {
|
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import { generateNormalizrSchema, getNormalizrSchema } from "./normalization.js";
|
|
1
|
+
import { generateNormalizrSchema, getNormalizrSchema, mergeNormalizedData } from "./normalization.js";
|
|
2
2
|
import { normalize, denormalize } from "normalizr";
|
|
3
|
-
import { defu } from "defu";
|
|
4
3
|
import { readonly, useState } from "#imports";
|
|
5
4
|
generateNormalizrSchema();
|
|
6
5
|
export function useZenstackStore() {
|
|
@@ -9,12 +8,12 @@ export function useZenstackStore() {
|
|
|
9
8
|
function setOne(model, input) {
|
|
10
9
|
const schema = getNormalizrSchema(model);
|
|
11
10
|
const res = normalize(input, schema);
|
|
12
|
-
state.value =
|
|
11
|
+
state.value = mergeNormalizedData(res.entities, state.value);
|
|
13
12
|
}
|
|
14
13
|
function setMany(model, input) {
|
|
15
14
|
const schema = [getNormalizrSchema(model)];
|
|
16
15
|
const res = normalize(input, schema);
|
|
17
|
-
state.value =
|
|
16
|
+
state.value = mergeNormalizedData(res.entities, state.value);
|
|
18
17
|
}
|
|
19
18
|
function getOne(model, input) {
|
|
20
19
|
const schema = getNormalizrSchema(model);
|
|
@@ -1,5 +1,18 @@
|
|
|
1
1
|
import { schema as normalizrSchema } from 'normalizr';
|
|
2
2
|
import type { $Zmodel } from '#build/types/nuxt-zenstack';
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
type NormalizedDataField = number | string | boolean | null | string[];
|
|
4
|
+
/**
|
|
5
|
+
* Normalized data structure
|
|
6
|
+
* {
|
|
7
|
+
* model: {
|
|
8
|
+
* id: {
|
|
9
|
+
* field: NormalizedDataField
|
|
10
|
+
* }
|
|
11
|
+
* }
|
|
12
|
+
* }
|
|
13
|
+
*/
|
|
14
|
+
export type NormalizedData = Record<string, Record<string, Record<string, NormalizedDataField>>>;
|
|
15
|
+
export declare function getNormalizrSchema(model: $Zmodel): normalizrSchema.Entity<any>;
|
|
16
|
+
export declare function generateNormalizrSchema(): void;
|
|
17
|
+
export declare function mergeNormalizedData(newData: NormalizedData, currentData: NormalizedData): NormalizedData;
|
|
18
|
+
export {};
|
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
import { schema as normalizrSchema } from "normalizr";
|
|
2
2
|
import { getModelDef, getModels, isValidModel } from "./helpers.js";
|
|
3
|
+
import { defu } from "defu";
|
|
3
4
|
const NORMALIZR_SCHEMA = /* @__PURE__ */ new Map();
|
|
4
|
-
function getNormalizrSchema(model) {
|
|
5
|
+
export function getNormalizrSchema(model) {
|
|
5
6
|
const schema = NORMALIZR_SCHEMA.get(model);
|
|
6
7
|
if (!schema)
|
|
7
8
|
throw new Error(`Model ${model.toString()} not defined`);
|
|
8
9
|
return schema;
|
|
9
10
|
}
|
|
10
|
-
function generateNormalizrSchema() {
|
|
11
|
+
export function generateNormalizrSchema() {
|
|
11
12
|
const models = getModels();
|
|
12
13
|
for (const model of models) {
|
|
13
14
|
NORMALIZR_SCHEMA.set(model, new normalizrSchema.Entity(model.toString()));
|
|
@@ -28,4 +29,16 @@ function generateNormalizrSchema() {
|
|
|
28
29
|
}
|
|
29
30
|
}
|
|
30
31
|
}
|
|
31
|
-
export
|
|
32
|
+
export function mergeNormalizedData(newData, currentData) {
|
|
33
|
+
const merged = defu(newData, currentData);
|
|
34
|
+
for (const model in merged) {
|
|
35
|
+
for (const id in merged[model]) {
|
|
36
|
+
for (const field in merged[model][id]) {
|
|
37
|
+
if (Array.isArray(merged[model][id][field])) {
|
|
38
|
+
merged[model][id][field] = Array.from(new Set(merged[model][id][field]));
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
return merged;
|
|
44
|
+
}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import type { $Zmodel, $Zitem, $ZupdateData, $Zid } from '#build/types/nuxt-zenstack';
|
|
1
|
+
import type { $Zmodel, $Zitem, $ZupdateData, $Zid, $Zerror } from '#build/types/nuxt-zenstack';
|
|
2
2
|
import type { Status } from '../common.js';
|
|
3
3
|
import type { Ref } from '#imports';
|
|
4
4
|
export declare function useZenstackUpdate<Zmodel extends $Zmodel, Zitem extends $Zitem<Zmodel>>(model: Zmodel): {
|
|
5
5
|
data: Ref<Zitem | null>;
|
|
6
|
-
error: Ref
|
|
6
|
+
error: Ref<$Zerror | null>;
|
|
7
7
|
status: Ref<Status>;
|
|
8
8
|
mutate: (id: $Zid<Zmodel>, input: $ZupdateData<Zmodel>) => Promise<void>;
|
|
9
9
|
reset: () => void;
|
|
@@ -1,14 +1,17 @@
|
|
|
1
1
|
import { defineEventHandler } from "h3";
|
|
2
2
|
import { parseModel, parseId } from "../../../utils/parsers.js";
|
|
3
3
|
import { getModelOperations } from "../../../utils/index.js";
|
|
4
|
+
import { createError } from "../../../utils/error.js";
|
|
4
5
|
export default defineEventHandler(async (event) => {
|
|
5
6
|
const model = parseModel(event);
|
|
6
7
|
const id = parseId(event, model);
|
|
7
|
-
const operations = getModelOperations(model);
|
|
8
|
+
const operations = getModelOperations(event, model);
|
|
8
9
|
const data = await operations.delete({
|
|
9
10
|
where: {
|
|
10
11
|
id
|
|
11
12
|
}
|
|
13
|
+
}).catch((err) => {
|
|
14
|
+
throw createError(err);
|
|
12
15
|
});
|
|
13
16
|
return { data };
|
|
14
17
|
});
|
|
@@ -1,16 +1,19 @@
|
|
|
1
1
|
import { parseModel, parseId, parseReadArgs } from "../../../utils/parsers.js";
|
|
2
2
|
import { defineEventHandler } from "h3";
|
|
3
3
|
import { getModelOperations } from "../../../utils/index.js";
|
|
4
|
+
import { createError } from "../../../utils/error.js";
|
|
4
5
|
export default defineEventHandler(async (event) => {
|
|
5
6
|
const model = parseModel(event);
|
|
6
7
|
const id = parseId(event, model);
|
|
7
8
|
const readArgs = parseReadArgs(event, model);
|
|
8
|
-
const operations = getModelOperations(model);
|
|
9
|
+
const operations = getModelOperations(event, model);
|
|
9
10
|
const data = await operations.findUnique({
|
|
10
11
|
include: readArgs.include,
|
|
11
12
|
where: {
|
|
12
13
|
id
|
|
13
14
|
}
|
|
15
|
+
}).catch((err) => {
|
|
16
|
+
throw createError(err);
|
|
14
17
|
});
|
|
15
18
|
return { data };
|
|
16
19
|
});
|
|
@@ -1,18 +1,21 @@
|
|
|
1
|
-
import { parseModel, parseId,
|
|
1
|
+
import { parseModel, parseId, parseUpdateArgs } from "../../../utils/parsers.js";
|
|
2
2
|
import { defineEventHandler } from "h3";
|
|
3
3
|
import { getModelOperations, includeAll } from "../../../utils/index.js";
|
|
4
|
+
import { createError } from "../../../utils/error.js";
|
|
4
5
|
export default defineEventHandler(async (event) => {
|
|
5
6
|
const model = parseModel(event);
|
|
6
7
|
const id = parseId(event, model);
|
|
7
|
-
const
|
|
8
|
-
const operations = getModelOperations(model);
|
|
8
|
+
const updateArgs = await parseUpdateArgs(event, model);
|
|
9
|
+
const operations = getModelOperations(event, model);
|
|
9
10
|
const include = includeAll(model);
|
|
10
11
|
const data = await operations.update({
|
|
11
|
-
data:
|
|
12
|
+
data: updateArgs.data,
|
|
12
13
|
include,
|
|
13
14
|
where: {
|
|
14
15
|
id
|
|
15
16
|
}
|
|
17
|
+
}).catch((err) => {
|
|
18
|
+
throw createError(err);
|
|
16
19
|
});
|
|
17
20
|
return { data };
|
|
18
21
|
});
|
|
@@ -1,16 +1,19 @@
|
|
|
1
1
|
import { parseModel, parseReadArgs } from "../../../utils/parsers.js";
|
|
2
2
|
import { defineEventHandler } from "h3";
|
|
3
3
|
import { getModelOperations } from "../../../utils/index.js";
|
|
4
|
+
import { createError } from "../../../utils/error.js";
|
|
4
5
|
export default defineEventHandler(async (event) => {
|
|
5
6
|
const model = parseModel(event);
|
|
6
7
|
const readArgs = parseReadArgs(event, model);
|
|
7
|
-
const operations = getModelOperations(model);
|
|
8
|
+
const operations = getModelOperations(event, model);
|
|
8
9
|
const data = await operations.findMany({
|
|
9
10
|
orderBy: readArgs.orderBy,
|
|
10
11
|
include: readArgs.include,
|
|
11
12
|
skip: readArgs.skip,
|
|
12
13
|
take: readArgs.take,
|
|
13
14
|
where: readArgs.where
|
|
15
|
+
}).catch((err) => {
|
|
16
|
+
throw createError(err);
|
|
14
17
|
});
|
|
15
18
|
return { data };
|
|
16
19
|
});
|
|
@@ -1,14 +1,17 @@
|
|
|
1
|
-
import { parseModel,
|
|
1
|
+
import { parseModel, parseCreateArgs } from "../../../utils/parsers.js";
|
|
2
2
|
import { defineEventHandler } from "h3";
|
|
3
3
|
import { getModelOperations, includeAll } from "../../../utils/index.js";
|
|
4
|
+
import { createError } from "../../../utils/error.js";
|
|
4
5
|
export default defineEventHandler(async (event) => {
|
|
5
6
|
const model = parseModel(event);
|
|
6
|
-
const
|
|
7
|
-
const operations = getModelOperations(model);
|
|
7
|
+
const createArgs = await parseCreateArgs(event, model);
|
|
8
|
+
const operations = getModelOperations(event, model);
|
|
8
9
|
const include = includeAll(model);
|
|
9
10
|
const data = await operations.create({
|
|
10
|
-
data:
|
|
11
|
+
data: createArgs.data,
|
|
11
12
|
include
|
|
13
|
+
}).catch((err) => {
|
|
14
|
+
throw createError(err);
|
|
12
15
|
});
|
|
13
16
|
return { data };
|
|
14
17
|
});
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { $ZormError } from '#build/types/nuxt-zenstack';
|
|
2
|
+
import { ORMErrorReason } from '@zenstackhq/orm';
|
|
3
|
+
export declare function createError(ormError: $ZormError): import("h3").H3Error<{
|
|
4
|
+
ormErrorReason: ORMErrorReason;
|
|
5
|
+
dbErrorCode?: unknown;
|
|
6
|
+
dbErrorMessage?: string;
|
|
7
|
+
model?: string;
|
|
8
|
+
rejectedByPolicyReason?: import("@zenstackhq/orm").RejectedByPolicyReason;
|
|
9
|
+
}>;
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { ORMErrorReason } from "@zenstackhq/orm";
|
|
2
|
+
import { createError as createH3Error } from "h3";
|
|
3
|
+
export function createError(ormError) {
|
|
4
|
+
let statusCode = 500;
|
|
5
|
+
switch (ormError.reason) {
|
|
6
|
+
case ORMErrorReason.CONFIG_ERROR:
|
|
7
|
+
statusCode = 500;
|
|
8
|
+
break;
|
|
9
|
+
case ORMErrorReason.DB_QUERY_ERROR:
|
|
10
|
+
statusCode = 409;
|
|
11
|
+
break;
|
|
12
|
+
case ORMErrorReason.INTERNAL_ERROR:
|
|
13
|
+
statusCode = 500;
|
|
14
|
+
break;
|
|
15
|
+
case ORMErrorReason.NOT_FOUND:
|
|
16
|
+
statusCode = 404;
|
|
17
|
+
break;
|
|
18
|
+
case ORMErrorReason.INVALID_INPUT:
|
|
19
|
+
statusCode = 400;
|
|
20
|
+
break;
|
|
21
|
+
case ORMErrorReason.NOT_SUPPORTED:
|
|
22
|
+
statusCode = 501;
|
|
23
|
+
break;
|
|
24
|
+
case ORMErrorReason.REJECTED_BY_POLICY:
|
|
25
|
+
statusCode = 401;
|
|
26
|
+
break;
|
|
27
|
+
default:
|
|
28
|
+
statusCode = 500;
|
|
29
|
+
}
|
|
30
|
+
const error = {
|
|
31
|
+
name: "Zenstack Error",
|
|
32
|
+
cause: ormError.cause,
|
|
33
|
+
message: ormError.message,
|
|
34
|
+
statusCode,
|
|
35
|
+
statusMessage: ormError.reason,
|
|
36
|
+
stack: ormError.stack,
|
|
37
|
+
fatal: false,
|
|
38
|
+
unhandled: false,
|
|
39
|
+
toJSON: () => error,
|
|
40
|
+
data: {
|
|
41
|
+
ormErrorReason: ormError.reason,
|
|
42
|
+
dbErrorCode: ormError.dbErrorCode,
|
|
43
|
+
dbErrorMessage: ormError.dbErrorMessage,
|
|
44
|
+
model: ormError.model,
|
|
45
|
+
rejectedByPolicyReason: ormError.rejectedByPolicyReason
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
return createH3Error(error);
|
|
49
|
+
}
|
|
@@ -1,12 +1,8 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import type {
|
|
3
|
-
declare
|
|
4
|
-
export declare function provideClient(client: typeof _client): void;
|
|
5
|
-
export declare function getClient(): ClientContract<SchemaType>;
|
|
6
|
-
export declare function getModelOperations<Zmodel extends $Zmodel>(model: Zmodel): $Zoperations<Zmodel>;
|
|
1
|
+
import type { $Zmodel, $Zoperations, $Zdef } from '#build/types/nuxt-zenstack';
|
|
2
|
+
import type { H3Event } from 'h3';
|
|
3
|
+
export declare function getModelOperations<Zmodel extends $Zmodel>(event: H3Event, model: Zmodel): $Zoperations<Zmodel>;
|
|
7
4
|
export declare function getModelDef(model: $Zmodel): $Zdef;
|
|
8
5
|
export declare function isIdString(model: $Zmodel): boolean;
|
|
9
6
|
export declare function getModels(): $Zmodel[];
|
|
10
7
|
export declare function isValidModel(model: $Zmodel): boolean;
|
|
11
8
|
export declare function includeAll<Zmodel extends $Zmodel>(model: Zmodel): boolean | import("@zenstackhq/orm").SelectIncludeOmit<SchemaType, any, boolean, true>;
|
|
12
|
-
export {};
|
|
@@ -1,16 +1,12 @@
|
|
|
1
1
|
import { zenstackSchema } from "nuxt-zenstack-server.mjs";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
}
|
|
6
|
-
export function getClient() {
|
|
7
|
-
if (_client) {
|
|
8
|
-
return _client;
|
|
2
|
+
function getClient(event) {
|
|
3
|
+
if (event.context.zenstack?.client) {
|
|
4
|
+
return event.context.zenstack.client;
|
|
9
5
|
}
|
|
10
6
|
throw new Error("ZenStack client not provided");
|
|
11
7
|
}
|
|
12
|
-
export function getModelOperations(model) {
|
|
13
|
-
const db = getClient();
|
|
8
|
+
export function getModelOperations(event, model) {
|
|
9
|
+
const db = getClient(event);
|
|
14
10
|
return db[model.toString().toLocaleLowerCase()];
|
|
15
11
|
}
|
|
16
12
|
export function getModelDef(model) {
|
|
@@ -10,10 +10,10 @@ type ReadArgs<Zmodel extends $Zmodel> = {
|
|
|
10
10
|
export declare function parseModel(event: H3Event): string | number | symbol;
|
|
11
11
|
export declare function parseId(event: H3Event, model: $Zmodel): string | number;
|
|
12
12
|
export declare function parseReadArgs<Zmodel extends $Zmodel>(event: H3Event, _model: Zmodel): ReadArgs<Zmodel>;
|
|
13
|
-
export declare function
|
|
13
|
+
export declare function parseCreateArgs<Zmodel extends $Zmodel>(event: H3Event, _model: Zmodel): Promise<{
|
|
14
14
|
data: $ZcreateData<Zmodel>;
|
|
15
15
|
}>;
|
|
16
|
-
export declare function
|
|
16
|
+
export declare function parseUpdateArgs<Zmodel extends $Zmodel>(event: H3Event, _model: Zmodel): Promise<{
|
|
17
17
|
data: $ZupdateData<Zmodel>;
|
|
18
18
|
}>;
|
|
19
19
|
export {};
|
|
@@ -20,9 +20,9 @@ export function parseReadArgs(event, _model) {
|
|
|
20
20
|
const query = getQuery(event);
|
|
21
21
|
return query?.q ? parse(query.q) : {};
|
|
22
22
|
}
|
|
23
|
-
export async function
|
|
23
|
+
export async function parseCreateArgs(event, _model) {
|
|
24
24
|
return readBody(event);
|
|
25
25
|
}
|
|
26
|
-
export async function
|
|
26
|
+
export async function parseUpdateArgs(event, _model) {
|
|
27
27
|
return readBody(event);
|
|
28
28
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bg-dev/nuxt-zenstack",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.4",
|
|
4
4
|
"description": "ZenStack integration for Nuxt",
|
|
5
5
|
"repository": {
|
|
6
6
|
"url": "https://github.com/becem-gharbi/nuxt-zenstack"
|
|
@@ -66,7 +66,9 @@
|
|
|
66
66
|
"@nuxt/test-utils": "^3.23.0",
|
|
67
67
|
"@nuxt/ui": "^4.3.0",
|
|
68
68
|
"@types/node": "latest",
|
|
69
|
+
"@vueuse/core": "^14.1.0",
|
|
69
70
|
"@zenstackhq/cli": "3.2.1",
|
|
71
|
+
"@zenstackhq/plugin-policy": "^3.2.1",
|
|
70
72
|
"changelogen": "^0.6.2",
|
|
71
73
|
"eslint": "^9.39.2",
|
|
72
74
|
"libsql": "^0.5.22",
|