@bg-dev/nuxt-zenstack 0.0.2 → 0.0.3
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.d.mts +2 -0
- package/dist/module.json +1 -1
- package/dist/module.mjs +9 -7
- package/dist/runtime/composables/common.d.ts +6 -0
- package/dist/runtime/composables/common.js +7 -0
- package/dist/runtime/composables/index.d.ts +1 -0
- package/dist/runtime/composables/index.js +1 -0
- package/dist/runtime/composables/useZenstackCreate/index.js +10 -8
- package/dist/runtime/composables/useZenstackDelete/index.js +9 -4
- package/dist/runtime/composables/useZenstackRead/index.d.ts +4 -4
- package/dist/runtime/composables/useZenstackRead/index.js +36 -28
- package/dist/runtime/composables/useZenstackReadMany/index.d.ts +6 -6
- package/dist/runtime/composables/useZenstackReadMany/index.js +37 -30
- package/dist/runtime/composables/useZenstackStore/helpers.js +4 -4
- package/dist/runtime/composables/useZenstackStore/index.d.ts +28 -0
- package/dist/runtime/composables/useZenstackStore/index.js +24 -2
- package/dist/runtime/composables/useZenstackUpdate/index.js +10 -8
- package/dist/runtime/server/api/models/[model]/[id].patch.js +3 -1
- package/dist/runtime/server/api/models/[model]/index.post.js +4 -2
- package/dist/runtime/server/utils/index.d.ts +3 -2
- package/dist/runtime/server/utils/index.js +22 -1
- package/package.json +1 -1
package/dist/module.d.mts
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import * as _nuxt_schema from '@nuxt/schema';
|
|
2
|
+
import { FetchPolicy } from '../dist/runtime/composables/common.js';
|
|
2
3
|
|
|
3
4
|
interface ModuleOptions {
|
|
4
5
|
apiPath: string;
|
|
6
|
+
fetchPolicy: FetchPolicy;
|
|
5
7
|
}
|
|
6
8
|
declare const _default: _nuxt_schema.NuxtModule<ModuleOptions, ModuleOptions, false>;
|
|
7
9
|
|
package/dist/module.json
CHANGED
package/dist/module.mjs
CHANGED
|
@@ -3,7 +3,7 @@ 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.3";
|
|
7
7
|
|
|
8
8
|
const module$1 = defineNuxtModule({
|
|
9
9
|
meta: {
|
|
@@ -13,12 +13,14 @@ const module$1 = defineNuxtModule({
|
|
|
13
13
|
},
|
|
14
14
|
// Default configuration options of the Nuxt module
|
|
15
15
|
defaults: {
|
|
16
|
-
apiPath: "/api/_zenstack"
|
|
16
|
+
apiPath: "/api/_zenstack",
|
|
17
|
+
fetchPolicy: "cache-first"
|
|
17
18
|
},
|
|
18
19
|
setup(_options, _nuxt) {
|
|
19
20
|
_nuxt.options.runtimeConfig.public = defu(_nuxt.options.runtimeConfig.public, {
|
|
20
21
|
zenstack: {
|
|
21
|
-
apiPath: _options.apiPath
|
|
22
|
+
apiPath: _options.apiPath,
|
|
23
|
+
fetchPolicy: _options.fetchPolicy
|
|
22
24
|
}
|
|
23
25
|
});
|
|
24
26
|
const resolver = createResolver(import.meta.url);
|
|
@@ -54,10 +56,10 @@ export type $Zmodel = keyof SchemaType['models']
|
|
|
54
56
|
export type $Zdef = ModelDef
|
|
55
57
|
export type $Zoperations<Zmodel extends $Zmodel> = ModelOperations<SchemaType, Zmodel>
|
|
56
58
|
export type $Zid<Zmodel extends $Zmodel> = ModelResult<SchemaType, Zmodel> extends { id: infer Id } ? Id : never
|
|
57
|
-
export type $Zinclude<Zmodel extends $Zmodel> = IncludeInput<SchemaType, Zmodel>
|
|
58
|
-
export type $Zitem<Zmodel extends $Zmodel, Zinclude extends $Zinclude
|
|
59
|
-
export type $Zwhere<Zmodel extends $Zmodel> = WhereInput<SchemaType, Zmodel>
|
|
60
|
-
export type $ZorderBy<Zmodel extends $Zmodel> = FindManyArgs<SchemaType, Zmodel>['orderBy']
|
|
59
|
+
export type $Zinclude<Zmodel extends $Zmodel> = IncludeInput<SchemaType, Zmodel> | undefined
|
|
60
|
+
export type $Zitem<Zmodel extends $Zmodel, Zinclude extends $Zinclude = undefined> = ItemGetPayload<Zmodel, { include: Zinclude }>
|
|
61
|
+
export type $Zwhere<Zmodel extends $Zmodel> = WhereInput<SchemaType, Zmodel> | undefined
|
|
62
|
+
export type $ZorderBy<Zmodel extends $Zmodel> = FindManyArgs<SchemaType, Zmodel>['orderBy'] | undefined
|
|
61
63
|
export type $ZcreateData<Zmodel extends $Zmodel> = CreateArgs<SchemaType, Zmodel>['data']
|
|
62
64
|
export type $ZupdateData<Zmodel extends $Zmodel> = UpdateArgs<SchemaType, Zmodel>['data']
|
|
63
65
|
`
|
|
@@ -10,4 +10,10 @@ export type Error = {
|
|
|
10
10
|
};
|
|
11
11
|
export declare function getConfig(): {
|
|
12
12
|
apiPath: string;
|
|
13
|
+
fetchPolicy: FetchPolicy;
|
|
13
14
|
};
|
|
15
|
+
/**
|
|
16
|
+
* @param instance a custom fetch method created by `$fetch.create`
|
|
17
|
+
*/
|
|
18
|
+
export declare function provideFetch(instance: typeof $fetch): void;
|
|
19
|
+
export declare function getFetch(): import("nitropack/types").$Fetch<unknown, import("nitropack/types").NitroFetchRequest>;
|
|
@@ -3,3 +3,4 @@ export { useZenstackReadMany } from './useZenstackReadMany/index.js';
|
|
|
3
3
|
export { useZenstackRead } from './useZenstackRead/index.js';
|
|
4
4
|
export { useZenstackDelete } from './useZenstackDelete/index.js';
|
|
5
5
|
export { useZenstackUpdate } from './useZenstackUpdate/index.js';
|
|
6
|
+
export { provideFetch as provideZenstackFetch } from './common.js';
|
|
@@ -3,3 +3,4 @@ export { useZenstackReadMany } from "./useZenstackReadMany/index.js";
|
|
|
3
3
|
export { useZenstackRead } from "./useZenstackRead/index.js";
|
|
4
4
|
export { useZenstackDelete } from "./useZenstackDelete/index.js";
|
|
5
5
|
export { useZenstackUpdate } from "./useZenstackUpdate/index.js";
|
|
6
|
+
export { provideFetch as provideZenstackFetch } from "./common.js";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { getConfig } from "../common.js";
|
|
1
|
+
import { getConfig, getFetch } from "../common.js";
|
|
2
2
|
import { ref } from "#imports";
|
|
3
3
|
import { joinURL } from "ufo";
|
|
4
4
|
import { useZenstackStore } from "../useZenstackStore/index.js";
|
|
@@ -14,17 +14,19 @@ export function useZenstackCreate(model) {
|
|
|
14
14
|
status.value = "idle";
|
|
15
15
|
}
|
|
16
16
|
async function mutate(input) {
|
|
17
|
+
const _fetch = getFetch();
|
|
17
18
|
const url = joinURL(config.apiPath, `/models/${model.toString()}`);
|
|
19
|
+
const method = "POST";
|
|
20
|
+
const body = { data: input };
|
|
21
|
+
store.addToFetchHistory({
|
|
22
|
+
model: model.toString(),
|
|
23
|
+
method,
|
|
24
|
+
body: JSON.stringify(body)
|
|
25
|
+
});
|
|
18
26
|
reset();
|
|
19
27
|
status.value = "pending";
|
|
20
28
|
try {
|
|
21
|
-
const res = await
|
|
22
|
-
method: "POST",
|
|
23
|
-
body: {
|
|
24
|
-
data: input
|
|
25
|
-
// TODO: maybe include relations
|
|
26
|
-
}
|
|
27
|
-
});
|
|
29
|
+
const res = await _fetch(url, { method, body });
|
|
28
30
|
if (res.data)
|
|
29
31
|
store.setOne(model, res.data);
|
|
30
32
|
data.value = res.data;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { ref } from "#imports";
|
|
2
2
|
import { joinURL } from "ufo";
|
|
3
3
|
import { useZenstackStore } from "../useZenstackStore/index.js";
|
|
4
|
-
import { getConfig } from "../common.js";
|
|
4
|
+
import { getConfig, getFetch } from "../common.js";
|
|
5
5
|
export function useZenstackDelete(model) {
|
|
6
6
|
const data = ref(null);
|
|
7
7
|
const error = ref(null);
|
|
@@ -14,13 +14,18 @@ export function useZenstackDelete(model) {
|
|
|
14
14
|
status.value = "idle";
|
|
15
15
|
}
|
|
16
16
|
async function mutate(id) {
|
|
17
|
+
const _fetch = getFetch();
|
|
17
18
|
const url = joinURL(config.apiPath, `/models/${model.toString()}/${id}`);
|
|
19
|
+
const method = "DELETE";
|
|
20
|
+
store.addToFetchHistory({
|
|
21
|
+
model: model.toString(),
|
|
22
|
+
id,
|
|
23
|
+
method
|
|
24
|
+
});
|
|
18
25
|
reset();
|
|
19
26
|
status.value = "pending";
|
|
20
27
|
try {
|
|
21
|
-
const res = await
|
|
22
|
-
method: "DELETE"
|
|
23
|
-
});
|
|
28
|
+
const res = await _fetch(url, { method });
|
|
24
29
|
store.deleteOne(model, id);
|
|
25
30
|
data.value = res.data;
|
|
26
31
|
status.value = "success";
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { $Zmodel, $Zitem, $Zid, $Zinclude } from '#build/types/nuxt-zenstack';
|
|
2
2
|
import type { Status, FetchPolicy } from '../common.js';
|
|
3
3
|
import type { Ref, MaybeRefOrGetter } from '#imports';
|
|
4
|
-
type Options<
|
|
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.
|
|
7
7
|
* - `cache-and-fetch` means that the query will first try to fetch the data from the cache. It will then fetch the data from the server and update the cache.
|
|
@@ -19,12 +19,12 @@ type Options<Zmodel extends $Zmodel> = {
|
|
|
19
19
|
* The relations to include in the query.
|
|
20
20
|
* @default undefined
|
|
21
21
|
*/
|
|
22
|
-
include?: MaybeRefOrGetter
|
|
22
|
+
include?: MaybeRefOrGetter<Zinclude>;
|
|
23
23
|
};
|
|
24
|
-
export declare function useZenstackRead<Zmodel extends $Zmodel, Zitem extends $Zitem<Zmodel>>(model: Zmodel, id: $Zid<Zmodel>, opts?: Options<
|
|
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
26
|
error: Ref<Error | null>;
|
|
27
27
|
status: Ref<Status>;
|
|
28
28
|
refetch: () => Promise<void>;
|
|
29
|
-
}
|
|
29
|
+
}>;
|
|
30
30
|
export {};
|
|
@@ -1,57 +1,65 @@
|
|
|
1
|
-
import { ref, toValue, watch, isRef } from "#imports";
|
|
1
|
+
import { ref, toValue, watch, isRef, useNuxtApp } from "#imports";
|
|
2
2
|
import { joinURL } from "ufo";
|
|
3
3
|
import { useZenstackStore } from "../useZenstackStore/index.js";
|
|
4
4
|
import { stringify } from "superjson";
|
|
5
|
-
import { getConfig } from "../common.js";
|
|
6
|
-
export function useZenstackRead(model, id, opts = {}) {
|
|
5
|
+
import { getConfig, getFetch } from "../common.js";
|
|
6
|
+
export async function useZenstackRead(model, id, opts = {}) {
|
|
7
7
|
const data = ref(null);
|
|
8
8
|
const error = ref(null);
|
|
9
9
|
const status = ref("idle");
|
|
10
10
|
const store = useZenstackStore();
|
|
11
11
|
const config = getConfig();
|
|
12
|
-
|
|
13
|
-
opts.immediate ??= true;
|
|
14
|
-
switch (opts.fetchPolicy) {
|
|
15
|
-
case "cache-first":
|
|
16
|
-
updateData();
|
|
17
|
-
if (data.value) opts.immediate = false;
|
|
18
|
-
break;
|
|
19
|
-
case "cache-and-fetch":
|
|
20
|
-
updateData();
|
|
21
|
-
break;
|
|
22
|
-
case "cache-only":
|
|
23
|
-
updateData();
|
|
24
|
-
opts.immediate = false;
|
|
25
|
-
break;
|
|
26
|
-
}
|
|
12
|
+
const nuxtApp = useNuxtApp();
|
|
27
13
|
const watchedOptions = [opts.include].filter((option) => isRef(option) || typeof option === "function");
|
|
14
|
+
const method = "GET";
|
|
15
|
+
opts.fetchPolicy ??= config.fetchPolicy;
|
|
16
|
+
opts.immediate ??= true;
|
|
17
|
+
if (opts.fetchPolicy !== "fetch-only")
|
|
18
|
+
updateData();
|
|
28
19
|
watch(store.state, () => updateData());
|
|
29
20
|
watch(watchedOptions, () => refetch());
|
|
30
|
-
if (
|
|
31
|
-
refetch();
|
|
21
|
+
if (shouldFetchInitially())
|
|
22
|
+
await refetch();
|
|
23
|
+
function shouldFetchInitially() {
|
|
24
|
+
if (opts.immediate === false)
|
|
25
|
+
return false;
|
|
26
|
+
const entry = store.fetchHistory.value.find((entry2) => entry2.model === model && entry2.id === id && entry2.method === method && entry2.query === JSON.stringify(getQuery()));
|
|
27
|
+
if (entry?.ssr && nuxtApp.isHydrating)
|
|
28
|
+
return false;
|
|
29
|
+
if (opts.fetchPolicy === "cache-first" && entry)
|
|
30
|
+
return false;
|
|
31
|
+
return true;
|
|
32
|
+
}
|
|
32
33
|
function updateData() {
|
|
33
34
|
data.value = store.getOne(model, id);
|
|
34
35
|
}
|
|
36
|
+
function getQuery() {
|
|
37
|
+
const json = stringify({
|
|
38
|
+
include: toValue(opts.include)
|
|
39
|
+
});
|
|
40
|
+
return { q: json };
|
|
41
|
+
}
|
|
35
42
|
async function refetch() {
|
|
36
43
|
if (opts.fetchPolicy === "cache-only")
|
|
37
44
|
return;
|
|
45
|
+
const _fetch = getFetch();
|
|
38
46
|
const url = joinURL(config.apiPath, `/models/${model.toString()}/${id}`);
|
|
39
|
-
const
|
|
40
|
-
|
|
47
|
+
const query = getQuery();
|
|
48
|
+
store.addToFetchHistory({
|
|
49
|
+
model: model.toString(),
|
|
50
|
+
id,
|
|
51
|
+
method,
|
|
52
|
+
query: JSON.stringify(query)
|
|
41
53
|
});
|
|
42
54
|
error.value = null;
|
|
43
55
|
status.value = "pending";
|
|
44
56
|
try {
|
|
45
|
-
const res = await
|
|
46
|
-
method: "GET",
|
|
47
|
-
query: {
|
|
48
|
-
q: json
|
|
49
|
-
}
|
|
50
|
-
});
|
|
57
|
+
const res = await _fetch(url, { method, query });
|
|
51
58
|
if (res.data)
|
|
52
59
|
store.setOne(model, res.data);
|
|
53
60
|
else
|
|
54
61
|
store.deleteOne(model, id);
|
|
62
|
+
updateData();
|
|
55
63
|
status.value = "success";
|
|
56
64
|
} catch (err) {
|
|
57
65
|
error.value = err.data;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { $Zmodel, $Zitem, $Zinclude, $Zwhere, $ZorderBy } from '#build/types/nuxt-zenstack';
|
|
2
2
|
import type { Status, FetchPolicy } from '../common.js';
|
|
3
3
|
import type { MaybeRefOrGetter, Ref } from '#imports';
|
|
4
|
-
type Options<
|
|
4
|
+
type Options<Zinclude, Zwhere, ZorderBy> = {
|
|
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.
|
|
7
7
|
* - `cache-and-fetch` means that the query will first try to fetch the data from the cache. It will then fetch the data from the server and update the cache.
|
|
@@ -19,17 +19,17 @@ type Options<Zmodel extends $Zmodel> = {
|
|
|
19
19
|
* The relations to include in the query.
|
|
20
20
|
* @default undefined
|
|
21
21
|
*/
|
|
22
|
-
include?: MaybeRefOrGetter
|
|
22
|
+
include?: MaybeRefOrGetter<Zinclude>;
|
|
23
23
|
/**
|
|
24
24
|
* The filter to apply to the query.
|
|
25
25
|
* @default undefined
|
|
26
26
|
*/
|
|
27
|
-
where?: MaybeRefOrGetter
|
|
27
|
+
where?: MaybeRefOrGetter<Zwhere>;
|
|
28
28
|
/**
|
|
29
29
|
* The order to apply to the query.
|
|
30
30
|
* @default undefined
|
|
31
31
|
*/
|
|
32
|
-
orderBy?: MaybeRefOrGetter
|
|
32
|
+
orderBy?: MaybeRefOrGetter<ZorderBy>;
|
|
33
33
|
/**
|
|
34
34
|
* The number of items to skip.
|
|
35
35
|
* @default 0
|
|
@@ -41,10 +41,10 @@ type Options<Zmodel extends $Zmodel> = {
|
|
|
41
41
|
*/
|
|
42
42
|
take?: MaybeRefOrGetter<number>;
|
|
43
43
|
};
|
|
44
|
-
export declare function useZenstackReadMany<Zmodel extends $Zmodel, Zitem extends $Zitem<Zmodel>>(model: Zmodel, opts?: Options<
|
|
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
46
|
error: Ref<Error | null>;
|
|
47
47
|
status: Ref<Status>;
|
|
48
48
|
refetch: () => Promise<void>;
|
|
49
|
-
}
|
|
49
|
+
}>;
|
|
50
50
|
export {};
|
|
@@ -1,46 +1,44 @@
|
|
|
1
|
-
import { ref, toValue, watch, isRef } from "#imports";
|
|
1
|
+
import { ref, toValue, watch, isRef, useNuxtApp } from "#imports";
|
|
2
2
|
import { joinURL } from "ufo";
|
|
3
3
|
import { useZenstackStore } from "../useZenstackStore/index.js";
|
|
4
4
|
import { stringify } from "superjson";
|
|
5
|
-
import { getConfig } from "../common.js";
|
|
6
|
-
export function useZenstackReadMany(model, opts = {}) {
|
|
5
|
+
import { getConfig, getFetch } from "../common.js";
|
|
6
|
+
export async function useZenstackReadMany(model, opts = {}) {
|
|
7
7
|
const data = ref(null);
|
|
8
8
|
const error = ref(null);
|
|
9
9
|
const status = ref("idle");
|
|
10
10
|
const store = useZenstackStore();
|
|
11
11
|
const config = getConfig();
|
|
12
|
-
|
|
12
|
+
const nuxtApp = useNuxtApp();
|
|
13
|
+
const watchedOptions = [opts.include, opts.where, opts.orderBy, opts.skip, opts.take].filter((option) => isRef(option) || typeof option === "function");
|
|
14
|
+
const method = "GET";
|
|
15
|
+
opts.fetchPolicy ??= config.fetchPolicy;
|
|
13
16
|
opts.immediate ??= true;
|
|
14
17
|
opts.skip ??= 0;
|
|
15
18
|
opts.take ??= 1e3;
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
updateData();
|
|
19
|
-
if (data.value?.length) opts.immediate = false;
|
|
20
|
-
break;
|
|
21
|
-
case "cache-and-fetch":
|
|
22
|
-
updateData();
|
|
23
|
-
break;
|
|
24
|
-
case "cache-only":
|
|
25
|
-
updateData();
|
|
26
|
-
opts.immediate = false;
|
|
27
|
-
break;
|
|
28
|
-
}
|
|
29
|
-
const watchedOptions = [opts.include, opts.where, opts.orderBy, opts.skip, opts.take].filter((option) => isRef(option) || typeof option === "function");
|
|
19
|
+
if (opts.fetchPolicy !== "fetch-only")
|
|
20
|
+
updateData();
|
|
30
21
|
watch(store.state, () => updateData());
|
|
31
22
|
watch(watchedOptions, () => {
|
|
32
23
|
updateData();
|
|
33
24
|
refetch();
|
|
34
25
|
});
|
|
35
|
-
if (
|
|
36
|
-
refetch();
|
|
26
|
+
if (shouldFetchInitially())
|
|
27
|
+
await refetch();
|
|
28
|
+
function shouldFetchInitially() {
|
|
29
|
+
if (opts.immediate === false)
|
|
30
|
+
return false;
|
|
31
|
+
const entry = store.fetchHistory.value.find((entry2) => entry2.model === model && entry2.method === method && entry2.query === JSON.stringify(getQuery()));
|
|
32
|
+
if (entry?.ssr && nuxtApp.isHydrating)
|
|
33
|
+
return false;
|
|
34
|
+
if (opts.fetchPolicy === "cache-first" && entry)
|
|
35
|
+
return false;
|
|
36
|
+
return true;
|
|
37
|
+
}
|
|
37
38
|
function updateData() {
|
|
38
39
|
data.value = store.getMany(model);
|
|
39
40
|
}
|
|
40
|
-
|
|
41
|
-
if (opts.fetchPolicy === "cache-only")
|
|
42
|
-
return;
|
|
43
|
-
const url = joinURL(config.apiPath, `/models/${model.toString()}`);
|
|
41
|
+
function getQuery() {
|
|
44
42
|
const json = stringify({
|
|
45
43
|
include: toValue(opts.include),
|
|
46
44
|
where: toValue(opts.where),
|
|
@@ -48,16 +46,25 @@ export function useZenstackReadMany(model, opts = {}) {
|
|
|
48
46
|
skip: toValue(opts.skip),
|
|
49
47
|
take: toValue(opts.take)
|
|
50
48
|
});
|
|
49
|
+
return { q: json };
|
|
50
|
+
}
|
|
51
|
+
async function refetch() {
|
|
52
|
+
if (opts.fetchPolicy === "cache-only")
|
|
53
|
+
return;
|
|
54
|
+
const _fetch = getFetch();
|
|
55
|
+
const url = joinURL(config.apiPath, `/models/${model.toString()}`);
|
|
56
|
+
const query = getQuery();
|
|
57
|
+
store.addToFetchHistory({
|
|
58
|
+
model: model.toString(),
|
|
59
|
+
method,
|
|
60
|
+
query: JSON.stringify(query)
|
|
61
|
+
});
|
|
51
62
|
error.value = null;
|
|
52
63
|
status.value = "pending";
|
|
53
64
|
try {
|
|
54
|
-
const res = await
|
|
55
|
-
method: "GET",
|
|
56
|
-
query: {
|
|
57
|
-
q: json
|
|
58
|
-
}
|
|
59
|
-
});
|
|
65
|
+
const res = await _fetch(url, { method, query });
|
|
60
66
|
store.setMany(model, res.data);
|
|
67
|
+
updateData();
|
|
61
68
|
status.value = "success";
|
|
62
69
|
} catch (err) {
|
|
63
70
|
error.value = err.data;
|
|
@@ -3,10 +3,10 @@ export function getModelDef(model) {
|
|
|
3
3
|
return zenstackSchema.models[model];
|
|
4
4
|
}
|
|
5
5
|
export function isIdString(model) {
|
|
6
|
-
const
|
|
7
|
-
if (!
|
|
8
|
-
throw new Error(`
|
|
9
|
-
return
|
|
6
|
+
const modelDef = getModelDef(model);
|
|
7
|
+
if (!modelDef.uniqueFields.id)
|
|
8
|
+
throw new Error(`Model ${model.toString()} does not have an id as a unique field`);
|
|
9
|
+
return modelDef.uniqueFields.id.type === "String";
|
|
10
10
|
}
|
|
11
11
|
export function getModels() {
|
|
12
12
|
return Object.keys(zenstackSchema.models);
|
|
@@ -1,4 +1,13 @@
|
|
|
1
1
|
import type { $Zmodel, $Zid } from '#build/types/nuxt-zenstack';
|
|
2
|
+
type FetchEntry = {
|
|
3
|
+
model: string;
|
|
4
|
+
method: 'GET' | 'PATCH' | 'POST' | 'DELETE';
|
|
5
|
+
ssr: boolean;
|
|
6
|
+
timestamp: number;
|
|
7
|
+
id?: string | number;
|
|
8
|
+
query?: string;
|
|
9
|
+
body?: string;
|
|
10
|
+
};
|
|
2
11
|
export declare function useZenstackStore(): {
|
|
3
12
|
state: Readonly<import("vue").Ref<{
|
|
4
13
|
readonly [x: string]: {
|
|
@@ -9,10 +18,29 @@ export declare function useZenstackStore(): {
|
|
|
9
18
|
readonly [x: string]: object;
|
|
10
19
|
};
|
|
11
20
|
}>>;
|
|
21
|
+
fetchHistory: Readonly<import("vue").Ref<readonly {
|
|
22
|
+
readonly model: string;
|
|
23
|
+
readonly method: "GET" | "PATCH" | "POST" | "DELETE";
|
|
24
|
+
readonly ssr: boolean;
|
|
25
|
+
readonly timestamp: number;
|
|
26
|
+
readonly id?: string | number | undefined;
|
|
27
|
+
readonly query?: string | undefined;
|
|
28
|
+
readonly body?: string | undefined;
|
|
29
|
+
}[], readonly {
|
|
30
|
+
readonly model: string;
|
|
31
|
+
readonly method: "GET" | "PATCH" | "POST" | "DELETE";
|
|
32
|
+
readonly ssr: boolean;
|
|
33
|
+
readonly timestamp: number;
|
|
34
|
+
readonly id?: string | number | undefined;
|
|
35
|
+
readonly query?: string | undefined;
|
|
36
|
+
readonly body?: string | undefined;
|
|
37
|
+
}[]>>;
|
|
12
38
|
setOne: (model: $Zmodel, input: object) => void;
|
|
13
39
|
setMany: (model: $Zmodel, input: object[]) => void;
|
|
14
40
|
getOne: <Zmodel extends $Zmodel>(model: Zmodel, input: $Zid<Zmodel>) => any;
|
|
15
41
|
getMany: (model: $Zmodel) => any;
|
|
16
42
|
deleteOne: <Model extends $Zmodel>(model: Model, id: $Zid<Model>) => void;
|
|
17
43
|
deleteMany: (model: $Zmodel) => void;
|
|
44
|
+
addToFetchHistory: (entry: Omit<FetchEntry, "ssr" | "timestamp">) => void;
|
|
18
45
|
};
|
|
46
|
+
export {};
|
|
@@ -4,7 +4,8 @@ import { defu } from "defu";
|
|
|
4
4
|
import { readonly, useState } from "#imports";
|
|
5
5
|
generateNormalizrSchema();
|
|
6
6
|
export function useZenstackStore() {
|
|
7
|
-
const state = useState("zenstack-
|
|
7
|
+
const state = useState("zenstack-state", () => ({}));
|
|
8
|
+
const fetchHistory = useState("zenstack-fetch-history", () => []);
|
|
8
9
|
function setOne(model, input) {
|
|
9
10
|
const schema = getNormalizrSchema(model);
|
|
10
11
|
const res = normalize(input, schema);
|
|
@@ -45,5 +46,26 @@ export function useZenstackStore() {
|
|
|
45
46
|
}
|
|
46
47
|
state.value = newState;
|
|
47
48
|
}
|
|
48
|
-
|
|
49
|
+
function addToFetchHistory(entry) {
|
|
50
|
+
fetchHistory.value.push({
|
|
51
|
+
method: entry.method,
|
|
52
|
+
model: entry.model,
|
|
53
|
+
body: entry.body,
|
|
54
|
+
id: entry.id,
|
|
55
|
+
query: entry.query,
|
|
56
|
+
ssr: typeof window === "undefined",
|
|
57
|
+
timestamp: (/* @__PURE__ */ new Date()).getTime()
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
return {
|
|
61
|
+
state: readonly(state),
|
|
62
|
+
fetchHistory: readonly(fetchHistory),
|
|
63
|
+
setOne,
|
|
64
|
+
setMany,
|
|
65
|
+
getOne,
|
|
66
|
+
getMany,
|
|
67
|
+
deleteOne,
|
|
68
|
+
deleteMany,
|
|
69
|
+
addToFetchHistory
|
|
70
|
+
};
|
|
49
71
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { ref } from "#imports";
|
|
2
2
|
import { joinURL } from "ufo";
|
|
3
3
|
import { useZenstackStore } from "../useZenstackStore/index.js";
|
|
4
|
-
import { getConfig } from "../common.js";
|
|
4
|
+
import { getConfig, getFetch } from "../common.js";
|
|
5
5
|
export function useZenstackUpdate(model) {
|
|
6
6
|
const data = ref(null);
|
|
7
7
|
const error = ref(null);
|
|
@@ -14,17 +14,19 @@ export function useZenstackUpdate(model) {
|
|
|
14
14
|
status.value = "idle";
|
|
15
15
|
}
|
|
16
16
|
async function mutate(id, input) {
|
|
17
|
+
const _fetch = getFetch();
|
|
17
18
|
const url = joinURL(config.apiPath, `/models/${model.toString()}/${id}`);
|
|
19
|
+
const body = { data: input };
|
|
20
|
+
const method = "PATCH";
|
|
21
|
+
store.addToFetchHistory({
|
|
22
|
+
model: model.toString(),
|
|
23
|
+
method,
|
|
24
|
+
body: JSON.stringify(body)
|
|
25
|
+
});
|
|
18
26
|
reset();
|
|
19
27
|
status.value = "pending";
|
|
20
28
|
try {
|
|
21
|
-
const res = await
|
|
22
|
-
method: "PATCH",
|
|
23
|
-
body: {
|
|
24
|
-
data: input
|
|
25
|
-
// TODO: maybe include relations
|
|
26
|
-
}
|
|
27
|
-
});
|
|
29
|
+
const res = await _fetch(url, { method, body });
|
|
28
30
|
if (res.data)
|
|
29
31
|
store.setOne(model, res.data);
|
|
30
32
|
data.value = res.data;
|
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
import { parseModel, parseId, parseUpdateData } from "../../../utils/parsers.js";
|
|
2
2
|
import { defineEventHandler } from "h3";
|
|
3
|
-
import { getModelOperations } from "../../../utils/index.js";
|
|
3
|
+
import { getModelOperations, includeAll } from "../../../utils/index.js";
|
|
4
4
|
export default defineEventHandler(async (event) => {
|
|
5
5
|
const model = parseModel(event);
|
|
6
6
|
const id = parseId(event, model);
|
|
7
7
|
const updateData = await parseUpdateData(event, model);
|
|
8
8
|
const operations = getModelOperations(model);
|
|
9
|
+
const include = includeAll(model);
|
|
9
10
|
const data = await operations.update({
|
|
10
11
|
data: updateData.data,
|
|
12
|
+
include,
|
|
11
13
|
where: {
|
|
12
14
|
id
|
|
13
15
|
}
|
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
import { parseModel, parseCreateData } from "../../../utils/parsers.js";
|
|
2
2
|
import { defineEventHandler } from "h3";
|
|
3
|
-
import { getModelOperations } from "../../../utils/index.js";
|
|
3
|
+
import { getModelOperations, includeAll } from "../../../utils/index.js";
|
|
4
4
|
export default defineEventHandler(async (event) => {
|
|
5
5
|
const model = parseModel(event);
|
|
6
6
|
const createData = await parseCreateData(event, model);
|
|
7
7
|
const operations = getModelOperations(model);
|
|
8
|
+
const include = includeAll(model);
|
|
8
9
|
const data = await operations.create({
|
|
9
|
-
data: createData.data
|
|
10
|
+
data: createData.data,
|
|
11
|
+
include
|
|
10
12
|
});
|
|
11
13
|
return { data };
|
|
12
14
|
});
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import type { ClientContract } from '@zenstackhq/orm';
|
|
2
|
-
import type { $Zschema, $Zmodel, $Zoperations } from '#build/types/nuxt-zenstack';
|
|
2
|
+
import type { $Zschema, $Zmodel, $Zoperations, $Zdef } from '#build/types/nuxt-zenstack';
|
|
3
3
|
declare let _client: ClientContract<$Zschema> | null;
|
|
4
4
|
export declare function provideClient(client: typeof _client): void;
|
|
5
5
|
export declare function getClient(): ClientContract<SchemaType>;
|
|
6
6
|
export declare function getModelOperations<Zmodel extends $Zmodel>(model: Zmodel): $Zoperations<Zmodel>;
|
|
7
|
-
export declare function getModelDef(model: $Zmodel):
|
|
7
|
+
export declare function getModelDef(model: $Zmodel): $Zdef;
|
|
8
8
|
export declare function isIdString(model: $Zmodel): boolean;
|
|
9
9
|
export declare function getModels(): $Zmodel[];
|
|
10
10
|
export declare function isValidModel(model: $Zmodel): boolean;
|
|
11
|
+
export declare function includeAll<Zmodel extends $Zmodel>(model: Zmodel): boolean | import("@zenstackhq/orm").SelectIncludeOmit<SchemaType, any, boolean, true>;
|
|
11
12
|
export {};
|
|
@@ -17,7 +17,10 @@ export function getModelDef(model) {
|
|
|
17
17
|
return zenstackSchema.models[model];
|
|
18
18
|
}
|
|
19
19
|
export function isIdString(model) {
|
|
20
|
-
|
|
20
|
+
const modelDef = getModelDef(model);
|
|
21
|
+
if (!modelDef.uniqueFields.id)
|
|
22
|
+
throw new Error(`Model ${model.toString()} does not have an id as a unique field`);
|
|
23
|
+
return modelDef.uniqueFields.id.type === "String";
|
|
21
24
|
}
|
|
22
25
|
export function getModels() {
|
|
23
26
|
return Object.keys(zenstackSchema.models);
|
|
@@ -25,3 +28,21 @@ export function getModels() {
|
|
|
25
28
|
export function isValidModel(model) {
|
|
26
29
|
return getModels().includes(model);
|
|
27
30
|
}
|
|
31
|
+
export function includeAll(model) {
|
|
32
|
+
const include = {};
|
|
33
|
+
const modelSet = /* @__PURE__ */ new Set();
|
|
34
|
+
function iterate(_model, acc) {
|
|
35
|
+
const modelDef = getModelDef(_model);
|
|
36
|
+
for (const [field, fieldDef] of Object.entries(modelDef.fields)) {
|
|
37
|
+
if (isValidModel(fieldDef.type) && !modelSet.has(fieldDef.type)) {
|
|
38
|
+
acc["include"] ||= {};
|
|
39
|
+
acc["include"][field] = {};
|
|
40
|
+
modelSet.add(fieldDef.type);
|
|
41
|
+
iterate(fieldDef.type, acc["include"][field]);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
modelSet.add(model);
|
|
46
|
+
iterate(model, include);
|
|
47
|
+
return include["include"] ?? {};
|
|
48
|
+
}
|