@diphyx/harlemify 0.0.1 → 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/README.md CHANGED
@@ -9,7 +9,11 @@ API state management for Nuxt powered by [Harlem](https://harlemjs.com/)
9
9
  - Zod schema validation with field metadata
10
10
  - Automatic API client with runtime config
11
11
  - CRUD operations with endpoint status tracking
12
+ - Type-safe endpoint URL parameters
12
13
  - SSR support via Harlem SSR plugin
14
+ - Configurable primary key indicator
15
+ - Lifecycle hooks (before/after) for API operations
16
+ - Abort controller support for request cancellation
13
17
 
14
18
  ## Installation
15
19
 
@@ -40,20 +44,49 @@ const UserSchema = z.object({
40
44
  indicator: true,
41
45
  }),
42
46
  name: z.string().meta({
43
- actions: [ApiAction.POST, ApiAction.PUT],
47
+ actions: [ApiAction.POST, ApiAction.PATCH],
44
48
  }),
45
49
  });
46
50
 
47
- export const userStore = createStore("user", UserSchema, {
48
- [Endpoint.GET_UNITS]: {
49
- action: ApiAction.GET,
50
- url: "/users",
51
+ export type User = z.infer<typeof UserSchema>;
52
+
53
+ export const userStore = createStore(
54
+ "user",
55
+ UserSchema,
56
+ {
57
+ [Endpoint.GET_UNITS]: {
58
+ action: ApiAction.GET,
59
+ url: "/users",
60
+ },
61
+ [Endpoint.POST_UNITS]: {
62
+ action: ApiAction.POST,
63
+ url: "/users",
64
+ },
65
+ [Endpoint.PATCH_UNITS]: {
66
+ action: ApiAction.PATCH,
67
+ url: (params) => `/users/${params.id}`,
68
+ },
69
+ [Endpoint.DELETE_UNITS]: {
70
+ action: ApiAction.DELETE,
71
+ url: (params) => `/users/${params.id}`,
72
+ },
51
73
  },
52
- [Endpoint.POST_UNIT]: {
53
- action: ApiAction.POST,
54
- url: "/users",
74
+ {
75
+ indicator: "id",
76
+ hooks: {
77
+ before() {
78
+ console.log("Request starting...");
79
+ },
80
+ after(error) {
81
+ if (error) {
82
+ console.error("Request failed:", error);
83
+ } else {
84
+ console.log("Request completed");
85
+ }
86
+ },
87
+ },
55
88
  },
56
- });
89
+ );
57
90
  ```
58
91
 
59
92
  ## Documentation
package/dist/module.json CHANGED
@@ -4,7 +4,7 @@
4
4
  "compatibility": {
5
5
  "nuxt": ">=3.0.0 || >=4.0.0"
6
6
  },
7
- "version": "0.0.1",
7
+ "version": "0.0.3",
8
8
  "builder": {
9
9
  "@nuxt/module-builder": "0.8.4",
10
10
  "unbuild": "unknown"
@@ -24,10 +24,12 @@ export interface ApiRequestOptions<A extends ApiAction = ApiAction, H extends Ap
24
24
  headers?: H;
25
25
  query?: Q;
26
26
  body?: B;
27
+ timeout?: number;
27
28
  responseType?: ApiResponseType;
28
29
  retry?: number | false;
29
30
  retryDelay?: number;
30
31
  retryStatusCodes?: number[];
32
+ signal?: AbortSignal;
31
33
  }
32
34
  export interface ApiOptions {
33
35
  url?: string;
@@ -66,6 +66,7 @@ export function createApi(options) {
66
66
  retry: requestOptions?.retry,
67
67
  retryDelay: requestOptions?.retryDelay,
68
68
  retryStatusCodes: requestOptions?.retryStatusCodes,
69
+ signal: requestOptions?.signal,
69
70
  onRequestError({ request: request2, options: options2, error }) {
70
71
  throw new ApiRequestError({
71
72
  method: options2.method,
@@ -1,12 +1,26 @@
1
1
  import { z } from "zod";
2
2
  import { type Extension, type BaseState } from "@harlem/core";
3
3
  import { Endpoint, type EndpointDefinition, type EndpointMemory } from "../utils/endpoint.js";
4
+ export declare enum StoreMemoryPosition {
5
+ FIRST = "first",
6
+ LAST = "last"
7
+ }
4
8
  import { ApiAction, type ApiActionOptions, type ApiOptions } from "./api.js";
5
- export declare function createStore<T extends z.ZodRawShape>(name: string, schema: z.ZodObject<T>, endpoints?: Partial<Record<Endpoint, EndpointDefinition>>, options?: {
9
+ export declare class StoreConfigurationError extends Error {
10
+ constructor(message: string);
11
+ }
12
+ export interface StoreHooks {
13
+ before?: () => Promise<void> | void;
14
+ after?: (error?: Error) => Promise<void> | void;
15
+ }
16
+ export interface StoreOptions {
6
17
  api?: ApiOptions;
18
+ indicator?: string;
19
+ hooks?: StoreHooks;
7
20
  extensions?: Extension<BaseState>[];
8
- }): {
9
- api: {
21
+ }
22
+ export declare function createStore<T extends z.ZodRawShape, K extends keyof z.infer<z.ZodObject<T>> = "id" & keyof z.infer<z.ZodObject<T>>>(name: string, schema: z.ZodObject<T>, endpoints?: Partial<Record<Endpoint, EndpointDefinition<Partial<z.infer<z.ZodObject<T>>>>>>, options?: StoreOptions): {
23
+ api: () => {
10
24
  get: <T_1, H extends import("./api").ApiRequestHeader = import("./api").ApiRequestHeader, Q extends import("./api").ApiRequestQuery = import("./api").ApiRequestQuery>(url: string, options?: ApiActionOptions<ApiAction.GET, H, Q, never>) => Promise<T_1>;
11
25
  post: <T_1, H extends import("./api").ApiRequestHeader = import("./api").ApiRequestHeader, Q extends import("./api").ApiRequestQuery = import("./api").ApiRequestQuery, B extends import("./api").ApiRequestBody = import("./api").ApiRequestBody>(url: string, options?: ApiActionOptions<ApiAction.POST, H, Q, B>) => Promise<T_1>;
12
26
  put: <T_1, H extends import("./api").ApiRequestHeader = import("./api").ApiRequestHeader, Q extends import("./api").ApiRequestQuery = import("./api").ApiRequestQuery, B extends import("./api").ApiRequestBody = import("./api").ApiRequestBody>(url: string, options?: ApiActionOptions<ApiAction.PUT, H, Q, B>) => Promise<T_1>;
@@ -20,106 +34,42 @@ export declare function createStore<T extends z.ZodRawShape>(name: string, schem
20
34
  };
21
35
  endpoints: Record<Endpoint, EndpointMemory>;
22
36
  }>, never>;
23
- memorizedUnit: import("@vue/reactivity").ComputedRef<import("@vue/reactivity").DeepReadonly<z.core.$InferObjectOutput<T, {}>> | null>;
24
- memorizedUnits: import("@vue/reactivity").ComputedRef<readonly import("@vue/reactivity").DeepReadonly<z.core.$InferObjectOutput<T, {}>>[]>;
25
- hasMemorizedUnits: (...units: ({
26
- [x: string]: keyof z.core.$InferObjectOutput<T, {}>;
27
- } & Partial<z.core.$InferObjectOutput<T, {}>>)[]) => Record<keyof z.core.$InferObjectOutput<T, {}>, boolean>;
28
- endpointsStatus: {
29
- getUnitIsIdle: import("@vue/reactivity").ComputedRef<boolean>;
30
- getUnitIsPending: import("@vue/reactivity").ComputedRef<boolean>;
31
- getUnitIsSuccess: import("@vue/reactivity").ComputedRef<boolean>;
32
- getUnitIsFailed: import("@vue/reactivity").ComputedRef<boolean>;
33
- getUnitsIsIdle: import("@vue/reactivity").ComputedRef<boolean>;
34
- getUnitsIsPending: import("@vue/reactivity").ComputedRef<boolean>;
35
- getUnitsIsSuccess: import("@vue/reactivity").ComputedRef<boolean>;
36
- getUnitsIsFailed: import("@vue/reactivity").ComputedRef<boolean>;
37
- postUnitIsIdle: import("@vue/reactivity").ComputedRef<boolean>;
38
- postUnitIsPending: import("@vue/reactivity").ComputedRef<boolean>;
39
- postUnitIsSuccess: import("@vue/reactivity").ComputedRef<boolean>;
40
- postUnitIsFailed: import("@vue/reactivity").ComputedRef<boolean>;
41
- postUnitsIsIdle: import("@vue/reactivity").ComputedRef<boolean>;
42
- postUnitsIsPending: import("@vue/reactivity").ComputedRef<boolean>;
43
- postUnitsIsSuccess: import("@vue/reactivity").ComputedRef<boolean>;
44
- postUnitsIsFailed: import("@vue/reactivity").ComputedRef<boolean>;
45
- putUnitIsIdle: import("@vue/reactivity").ComputedRef<boolean>;
46
- putUnitIsPending: import("@vue/reactivity").ComputedRef<boolean>;
47
- putUnitIsSuccess: import("@vue/reactivity").ComputedRef<boolean>;
48
- putUnitIsFailed: import("@vue/reactivity").ComputedRef<boolean>;
49
- putUnitsIsIdle: import("@vue/reactivity").ComputedRef<boolean>;
50
- putUnitsIsPending: import("@vue/reactivity").ComputedRef<boolean>;
51
- putUnitsIsSuccess: import("@vue/reactivity").ComputedRef<boolean>;
52
- putUnitsIsFailed: import("@vue/reactivity").ComputedRef<boolean>;
53
- patchUnitIsIdle: import("@vue/reactivity").ComputedRef<boolean>;
54
- patchUnitIsPending: import("@vue/reactivity").ComputedRef<boolean>;
55
- patchUnitIsSuccess: import("@vue/reactivity").ComputedRef<boolean>;
56
- patchUnitIsFailed: import("@vue/reactivity").ComputedRef<boolean>;
57
- patchUnitsIsIdle: import("@vue/reactivity").ComputedRef<boolean>;
58
- patchUnitsIsPending: import("@vue/reactivity").ComputedRef<boolean>;
59
- patchUnitsIsSuccess: import("@vue/reactivity").ComputedRef<boolean>;
60
- patchUnitsIsFailed: import("@vue/reactivity").ComputedRef<boolean>;
61
- deleteUnitIsIdle: import("@vue/reactivity").ComputedRef<boolean>;
62
- deleteUnitIsPending: import("@vue/reactivity").ComputedRef<boolean>;
63
- deleteUnitIsSuccess: import("@vue/reactivity").ComputedRef<boolean>;
64
- deleteUnitIsFailed: import("@vue/reactivity").ComputedRef<boolean>;
65
- deleteUnitsIsIdle: import("@vue/reactivity").ComputedRef<boolean>;
66
- deleteUnitsIsPending: import("@vue/reactivity").ComputedRef<boolean>;
67
- deleteUnitsIsSuccess: import("@vue/reactivity").ComputedRef<boolean>;
68
- deleteUnitsIsFailed: import("@vue/reactivity").ComputedRef<boolean>;
69
- };
37
+ memorizedUnit: import("vue").ComputedRef<import("vue").DeepReadonly<z.core.$InferObjectOutput<T, {}>> | null>;
38
+ memorizedUnits: import("vue").ComputedRef<readonly import("vue").DeepReadonly<z.core.$InferObjectOutput<T, {}>>[]>;
39
+ hasMemorizedUnits: (...units: (Required<Pick<z.core.$InferObjectOutput<T, {}>, K>> & Partial<z.core.$InferObjectOutput<T, {}>>)[]) => Record<string | number, boolean>;
40
+ endpointsStatus: import("../utils/endpoint").EndpointsStatusMap<import("vue").ComputedRef<boolean>>;
70
41
  setMemorizedUnit: import("@harlem/core").Mutation<z.core.$InferObjectOutput<T, {}> | null, void>;
71
42
  setMemorizedUnits: (payload: z.core.$InferObjectOutput<T, {}>[]) => void;
72
- editMemorizedUnit: import("@harlem/core").Mutation<{
73
- [x: string]: keyof z.core.$InferObjectOutput<T, {}>;
74
- } & Partial<z.core.$InferObjectOutput<T, {}>>, void>;
75
- editMemorizedUnits: (payload: ({
76
- [x: string]: keyof z.core.$InferObjectOutput<T, {}>;
77
- } & Partial<z.core.$InferObjectOutput<T, {}>>)[]) => void;
78
- dropMemorizedUnit: import("@harlem/core").Mutation<{
79
- [x: string]: keyof z.core.$InferObjectOutput<T, {}>;
80
- } & Partial<z.core.$InferObjectOutput<T, {}>>, void>;
81
- dropMemorizedUnits: (payload: ({
82
- [x: string]: keyof z.core.$InferObjectOutput<T, {}>;
83
- } & Partial<z.core.$InferObjectOutput<T, {}>>)[]) => void;
43
+ editMemorizedUnit: import("@harlem/core").Mutation<Required<Pick<z.core.$InferObjectOutput<T, {}>, K>> & Partial<z.core.$InferObjectOutput<T, {}>>, void>;
44
+ editMemorizedUnits: (payload: (Required<Pick<z.core.$InferObjectOutput<T, {}>, K>> & Partial<z.core.$InferObjectOutput<T, {}>>)[]) => void;
45
+ dropMemorizedUnit: import("@harlem/core").Mutation<Required<Pick<z.core.$InferObjectOutput<T, {}>, K>> & Partial<z.core.$InferObjectOutput<T, {}>>, void>;
46
+ dropMemorizedUnits: (payload: (Required<Pick<z.core.$InferObjectOutput<T, {}>, K>> & Partial<z.core.$InferObjectOutput<T, {}>>)[]) => void;
84
47
  patchEndpointMemory: (payload: {
85
48
  key: Endpoint;
86
49
  memory: EndpointMemory;
87
50
  }) => void;
88
51
  purgeEndpointMemory: (payload?: unknown) => void;
89
- getUnit: (unit: {
90
- [x: string]: keyof z.core.$InferObjectOutput<T, {}>;
91
- } & Partial<z.core.$InferObjectOutput<T, {}>>, options?: Omit<ApiActionOptions<ApiAction.GET>, "body">) => Promise<z.core.$InferObjectOutput<T, {}>>;
52
+ getUnit: (unit?: Required<Pick<z.core.$InferObjectOutput<T, {}>, K>> & Partial<z.core.$InferObjectOutput<T, {}>>, options?: Omit<ApiActionOptions<ApiAction.GET>, "body">) => Promise<z.core.$InferObjectOutput<T, {}>>;
92
53
  getUnits: (options?: Omit<ApiActionOptions<ApiAction.GET>, "body">) => Promise<z.core.$InferObjectOutput<T, {}>[]>;
93
- postUnit: (unit: z.core.$InferObjectOutput<T, {}>, options?: ApiActionOptions<ApiAction.POST> & {
54
+ postUnit: (unit: Required<Pick<z.core.$InferObjectOutput<T, {}>, K>> & z.core.$InferObjectOutput<T, {}>, actionOptions?: ApiActionOptions<ApiAction.POST> & {
94
55
  validate?: boolean;
95
- }) => Promise<z.core.$InferObjectOutput<T, {}>>;
96
- postUnits: (units: z.core.$InferObjectOutput<T, {}>[], options?: ApiActionOptions<ApiAction.POST> & {
56
+ }) => Promise<Required<Pick<z.core.$InferObjectOutput<T, {}>, K>> & z.core.$InferObjectOutput<T, {}>>;
57
+ postUnits: (units: (Required<Pick<z.core.$InferObjectOutput<T, {}>, K>> & z.core.$InferObjectOutput<T, {}>)[], options?: ApiActionOptions<ApiAction.POST> & {
97
58
  validate?: boolean;
98
- }) => Promise<z.core.$InferObjectOutput<T, {}>[]>;
99
- putUnit: (unit: z.core.$InferObjectOutput<T, {}>, options?: ApiActionOptions<ApiAction.PUT> & {
59
+ position?: StoreMemoryPosition;
60
+ }) => Promise<(Required<Pick<z.core.$InferObjectOutput<T, {}>, K>> & z.core.$InferObjectOutput<T, {}>)[]>;
61
+ putUnit: (unit: Required<Pick<z.core.$InferObjectOutput<T, {}>, K>> & z.core.$InferObjectOutput<T, {}>, options?: ApiActionOptions<ApiAction.PUT> & {
100
62
  validate?: boolean;
101
- }) => Promise<z.core.$InferObjectOutput<T, {}>>;
102
- putUnits: (units: z.core.$InferObjectOutput<T, {}>[], options?: ApiActionOptions<ApiAction.PUT> & {
63
+ }) => Promise<Required<Pick<z.core.$InferObjectOutput<T, {}>, K>> & z.core.$InferObjectOutput<T, {}>>;
64
+ putUnits: (units: (Required<Pick<z.core.$InferObjectOutput<T, {}>, K>> & z.core.$InferObjectOutput<T, {}>)[], options?: ApiActionOptions<ApiAction.PUT> & {
103
65
  validate?: boolean;
104
- }) => Promise<z.core.$InferObjectOutput<T, {}>[]>;
105
- patchUnit: (unit: {
106
- [x: string]: keyof z.core.$InferObjectOutput<T, {}>;
107
- } & Partial<z.core.$InferObjectOutput<T, {}>>, options?: ApiActionOptions<ApiAction.PATCH> & {
66
+ }) => Promise<(Required<Pick<z.core.$InferObjectOutput<T, {}>, K>> & z.core.$InferObjectOutput<T, {}>)[]>;
67
+ patchUnit: (unit: Required<Pick<z.core.$InferObjectOutput<T, {}>, K>> & Partial<z.core.$InferObjectOutput<T, {}>>, options?: ApiActionOptions<ApiAction.PATCH> & {
108
68
  validate?: boolean;
109
- }) => Promise<{
110
- [x: string]: keyof z.core.$InferObjectOutput<T, {}>;
111
- } & Partial<z.core.$InferObjectOutput<T, {}>>>;
112
- patchUnits: (units: ({
113
- [x: string]: keyof z.core.$InferObjectOutput<T, {}>;
114
- } & Partial<z.core.$InferObjectOutput<T, {}>>)[], options?: ApiActionOptions<ApiAction.PATCH> & {
69
+ }) => Promise<Required<Pick<z.core.$InferObjectOutput<T, {}>, K>> & Partial<z.core.$InferObjectOutput<T, {}>>>;
70
+ patchUnits: (units: (Required<Pick<z.core.$InferObjectOutput<T, {}>, K>> & Partial<z.core.$InferObjectOutput<T, {}>>)[], options?: ApiActionOptions<ApiAction.PATCH> & {
115
71
  validate?: boolean;
116
- }) => Promise<({
117
- [x: string]: keyof z.core.$InferObjectOutput<T, {}>;
118
- } & Partial<z.core.$InferObjectOutput<T, {}>>)[]>;
119
- deleteUnit: (unit: {
120
- [x: string]: keyof z.core.$InferObjectOutput<T, {}>;
121
- } & Partial<z.core.$InferObjectOutput<T, {}>>, options?: Omit<ApiActionOptions<ApiAction.DELETE>, "body">) => Promise<boolean>;
122
- deleteUnits: (units: ({
123
- [x: string]: keyof z.core.$InferObjectOutput<T, {}>;
124
- } & Partial<z.core.$InferObjectOutput<T, {}>>)[], options?: Omit<ApiActionOptions<ApiAction.DELETE>, "body">) => Promise<boolean>;
72
+ }) => Promise<(Required<Pick<z.core.$InferObjectOutput<T, {}>, K>> & Partial<z.core.$InferObjectOutput<T, {}>>)[]>;
73
+ deleteUnit: (unit: Required<Pick<z.core.$InferObjectOutput<T, {}>, K>> & Partial<z.core.$InferObjectOutput<T, {}>>, options?: Omit<ApiActionOptions<ApiAction.DELETE>, "body">) => Promise<boolean>;
74
+ deleteUnits: (units: (Required<Pick<z.core.$InferObjectOutput<T, {}>, K>> & Partial<z.core.$InferObjectOutput<T, {}>>)[], options?: Omit<ApiActionOptions<ApiAction.DELETE>, "body">) => Promise<boolean>;
125
75
  };
@@ -11,16 +11,52 @@ import {
11
11
  Endpoint,
12
12
  EndpointStatus
13
13
  } from "../utils/endpoint.js";
14
+ export var StoreMemoryPosition = /* @__PURE__ */ ((StoreMemoryPosition2) => {
15
+ StoreMemoryPosition2["FIRST"] = "first";
16
+ StoreMemoryPosition2["LAST"] = "last";
17
+ return StoreMemoryPosition2;
18
+ })(StoreMemoryPosition || {});
14
19
  import {
15
20
  createApi
16
21
  } from "./api.js";
22
+ export class StoreConfigurationError extends Error {
23
+ constructor(message) {
24
+ super(message);
25
+ this.name = "StoreConfigurationError";
26
+ }
27
+ }
17
28
  export function createStore(name, schema, endpoints, options) {
18
- const config = useRuntimeConfig();
19
- const api = createApi({
20
- ...config.public.harlemify.api,
21
- ...options?.api
29
+ const { indicator } = resolveSchema(schema, {
30
+ indicator: options?.indicator
22
31
  });
23
- const { indicator } = resolveSchema(schema);
32
+ const hooks = options?.hooks;
33
+ let apiClient;
34
+ let apiInitError = null;
35
+ function api() {
36
+ if (apiInitError) {
37
+ throw apiInitError;
38
+ }
39
+ if (!apiClient) {
40
+ try {
41
+ const config = useRuntimeConfig();
42
+ if (!config) {
43
+ throw new StoreConfigurationError(
44
+ `Runtime config is not available. Ensure the store "${name}" is used within a Nuxt context.`
45
+ );
46
+ }
47
+ apiClient = createApi({
48
+ ...config.public.harlemify?.api,
49
+ ...options?.api
50
+ });
51
+ } catch (error) {
52
+ apiInitError = error instanceof Error ? error : new StoreConfigurationError(
53
+ `Failed to initialize API client for store "${name}": ${String(error)}`
54
+ );
55
+ throw apiInitError;
56
+ }
57
+ }
58
+ return apiClient;
59
+ }
24
60
  const store = createHarlemStore(
25
61
  name,
26
62
  {
@@ -138,278 +174,240 @@ export function createStore(name, schema, endpoints, options) {
138
174
  memory
139
175
  });
140
176
  }
141
- async function getUnit(unit, options2) {
142
- const endpoint = getEndpoint(endpoints, Endpoint.GET_UNIT);
143
- patchEndpointMemoryTo(Endpoint.GET_UNIT, {
177
+ async function withEndpointStatus(key, operation) {
178
+ await hooks?.before?.();
179
+ patchEndpointMemoryTo(key, {
144
180
  status: EndpointStatus.PENDING
145
181
  });
146
182
  try {
147
- const resolvedUrl = resolveEndpointUrl(endpoint.url, {
148
- [indicator]: unit[indicator]
149
- });
150
- const response = await api.get(resolvedUrl, options2);
151
- setMemorizedUnit(response);
152
- patchEndpointMemoryTo(Endpoint.GET_UNIT, {
183
+ const result = await operation();
184
+ patchEndpointMemoryTo(key, {
153
185
  status: EndpointStatus.SUCCESS
154
186
  });
155
- return response;
187
+ await hooks?.after?.();
188
+ return result;
156
189
  } catch (error) {
157
- patchEndpointMemoryTo(Endpoint.GET_UNIT, {
190
+ patchEndpointMemoryTo(key, {
158
191
  status: EndpointStatus.FAILED
159
192
  });
193
+ await hooks?.after?.(error);
160
194
  throw error;
161
195
  }
162
196
  }
197
+ async function getUnit(unit, options2) {
198
+ const endpoint = getEndpoint(endpoints, Endpoint.GET_UNIT);
199
+ return withEndpointStatus(Endpoint.GET_UNIT, async () => {
200
+ const response = await api().get(
201
+ resolveEndpointUrl(endpoint, unit),
202
+ options2
203
+ );
204
+ setMemorizedUnit(response);
205
+ return response;
206
+ });
207
+ }
163
208
  async function getUnits(options2) {
164
209
  const endpoint = getEndpoint(endpoints, Endpoint.GET_UNITS);
165
- patchEndpointMemoryTo(Endpoint.GET_UNITS, {
166
- status: EndpointStatus.PENDING
167
- });
168
- try {
169
- const resolvedUrl = resolveEndpointUrl(endpoint.url);
170
- const response = await api.get(resolvedUrl, options2);
210
+ return withEndpointStatus(Endpoint.GET_UNITS, async () => {
211
+ const response = await api().get(
212
+ resolveEndpointUrl(endpoint),
213
+ options2
214
+ );
171
215
  setMemorizedUnits(response);
172
- patchEndpointMemoryTo(Endpoint.GET_UNITS, {
173
- status: EndpointStatus.SUCCESS
174
- });
175
216
  return response;
176
- } catch (error) {
177
- patchEndpointMemoryTo(Endpoint.GET_UNITS, {
178
- status: EndpointStatus.FAILED
179
- });
180
- throw error;
181
- }
217
+ });
182
218
  }
183
- async function postUnit(unit, options2) {
219
+ async function postUnit(unit, actionOptions) {
184
220
  const endpoint = getEndpoint(endpoints, Endpoint.POST_UNIT);
185
- const resolvedSchema = resolveSchema(schema, endpoint.action, unit);
186
- if (options2?.validate) {
221
+ const resolvedSchema = resolveSchema(schema, {
222
+ indicator,
223
+ endpoint,
224
+ unit
225
+ });
226
+ if (actionOptions?.validate) {
187
227
  schema.pick(resolvedSchema.keys).parse(unit);
188
228
  }
189
- patchEndpointMemoryTo(Endpoint.POST_UNIT, {
190
- status: EndpointStatus.PENDING
191
- });
192
- try {
193
- const resolvedUrl = resolveEndpointUrl(endpoint.url, {
194
- [indicator]: unit[indicator]
195
- });
196
- const response = await api.post(resolvedUrl, {
197
- ...options2,
198
- body: options2?.body ?? resolvedSchema.values
199
- });
200
- setMemorizedUnit(response);
201
- patchEndpointMemoryTo(Endpoint.POST_UNIT, {
202
- status: EndpointStatus.SUCCESS
229
+ return withEndpointStatus(Endpoint.POST_UNIT, async () => {
230
+ const response = await api().post(
231
+ resolveEndpointUrl(endpoint, unit),
232
+ {
233
+ ...actionOptions,
234
+ body: actionOptions?.body ?? resolvedSchema.values
235
+ }
236
+ );
237
+ setMemorizedUnit({
238
+ ...unit,
239
+ ...response
203
240
  });
204
241
  return response;
205
- } catch (error) {
206
- patchEndpointMemoryTo(Endpoint.POST_UNIT, {
207
- status: EndpointStatus.FAILED
208
- });
209
- throw error;
210
- }
242
+ });
211
243
  }
212
244
  async function postUnits(units, options2) {
213
245
  const endpoint = getEndpoint(endpoints, Endpoint.POST_UNITS);
214
- const body = units.map((unit) => {
215
- const resolvedSchema = resolveSchema(schema, endpoint.action, unit);
216
- if (options2?.validate) {
217
- schema.pick(resolvedSchema.keys).parse(unit);
246
+ return withEndpointStatus(Endpoint.POST_UNITS, async () => {
247
+ const responses = [];
248
+ for (const unit of units) {
249
+ const resolvedSchema = resolveSchema(schema, {
250
+ indicator,
251
+ endpoint,
252
+ unit
253
+ });
254
+ if (options2?.validate) {
255
+ schema.pick(resolvedSchema.keys).parse(unit);
256
+ }
257
+ const response = await api().post(
258
+ resolveEndpointUrl(endpoint, unit),
259
+ {
260
+ ...options2,
261
+ body: options2?.body ?? resolvedSchema.values
262
+ }
263
+ );
264
+ const clonedUnits = [...memorizedUnits.value];
265
+ if (options2?.position === "last" /* LAST */) {
266
+ clonedUnits.push({
267
+ ...unit,
268
+ ...response
269
+ });
270
+ } else {
271
+ clonedUnits.unshift({
272
+ ...unit,
273
+ ...response
274
+ });
275
+ }
276
+ setMemorizedUnits(clonedUnits);
277
+ responses.push(response);
218
278
  }
219
- return resolvedSchema.values;
279
+ return responses;
220
280
  });
221
- patchEndpointMemoryTo(Endpoint.POST_UNITS, {
222
- status: EndpointStatus.PENDING
223
- });
224
- try {
225
- const resolvedUrl = resolveEndpointUrl(endpoint.url);
226
- const response = await api.post(resolvedUrl, {
227
- ...options2,
228
- body: options2?.body ?? body
229
- });
230
- setMemorizedUnits([
231
- ...memorizedUnits.value,
232
- ...response
233
- ]);
234
- patchEndpointMemoryTo(Endpoint.POST_UNITS, {
235
- status: EndpointStatus.SUCCESS
236
- });
237
- return response;
238
- } catch (error) {
239
- patchEndpointMemoryTo(Endpoint.POST_UNITS, {
240
- status: EndpointStatus.FAILED
241
- });
242
- throw error;
243
- }
244
281
  }
245
282
  async function putUnit(unit, options2) {
246
283
  const endpoint = getEndpoint(endpoints, Endpoint.PUT_UNIT);
247
- const resolvedSchema = resolveSchema(schema, endpoint.action, unit);
284
+ const resolvedSchema = resolveSchema(schema, {
285
+ indicator,
286
+ endpoint,
287
+ unit
288
+ });
248
289
  if (options2?.validate) {
249
290
  schema.pick(resolvedSchema.keys).parse(unit);
250
291
  }
251
- patchEndpointMemoryTo(Endpoint.PUT_UNIT, {
252
- status: EndpointStatus.PENDING
253
- });
254
- try {
255
- const resolvedUrl = resolveEndpointUrl(endpoint.url, {
256
- [indicator]: unit[indicator]
257
- });
258
- const response = await api.put(resolvedUrl, {
259
- ...options2,
260
- body: options2?.body ?? resolvedSchema.values
261
- });
262
- setMemorizedUnit(response);
263
- patchEndpointMemoryTo(Endpoint.PUT_UNIT, {
264
- status: EndpointStatus.SUCCESS
292
+ return withEndpointStatus(Endpoint.PUT_UNIT, async () => {
293
+ const response = await api().put(
294
+ resolveEndpointUrl(endpoint, unit),
295
+ {
296
+ ...options2,
297
+ body: options2?.body ?? resolvedSchema.values
298
+ }
299
+ );
300
+ setMemorizedUnit({
301
+ ...unit,
302
+ ...response
265
303
  });
266
304
  return response;
267
- } catch (error) {
268
- patchEndpointMemoryTo(Endpoint.PUT_UNIT, {
269
- status: EndpointStatus.FAILED
270
- });
271
- throw error;
272
- }
305
+ });
273
306
  }
274
307
  async function putUnits(units, options2) {
275
308
  const endpoint = getEndpoint(endpoints, Endpoint.PUT_UNITS);
276
- const body = units.map((unit) => {
277
- const resolvedSchema = resolveSchema(schema, endpoint.action, unit);
278
- if (options2?.validate) {
279
- schema.pick(resolvedSchema.keys).parse(unit);
309
+ return withEndpointStatus(Endpoint.PUT_UNITS, async () => {
310
+ const responses = [];
311
+ for (const unit of units) {
312
+ const resolvedSchema = resolveSchema(schema, {
313
+ indicator,
314
+ endpoint,
315
+ unit
316
+ });
317
+ if (options2?.validate) {
318
+ schema.pick(resolvedSchema.keys).parse(unit);
319
+ }
320
+ const response = await api().put(
321
+ resolveEndpointUrl(endpoint, unit),
322
+ {
323
+ ...options2,
324
+ body: options2?.body ?? resolvedSchema.values
325
+ }
326
+ );
327
+ editMemorizedUnits([
328
+ {
329
+ ...unit,
330
+ ...response
331
+ }
332
+ ]);
333
+ responses.push(response);
280
334
  }
281
- return resolvedSchema.values;
335
+ return responses;
282
336
  });
283
- patchEndpointMemoryTo(Endpoint.PUT_UNITS, {
284
- status: EndpointStatus.PENDING
285
- });
286
- try {
287
- const resolvedUrl = resolveEndpointUrl(endpoint.url);
288
- const response = await api.put(resolvedUrl, {
289
- ...options2,
290
- body: options2?.body ?? body
291
- });
292
- setMemorizedUnits(response);
293
- patchEndpointMemoryTo(Endpoint.PUT_UNITS, {
294
- status: EndpointStatus.SUCCESS
295
- });
296
- return response;
297
- } catch (error) {
298
- patchEndpointMemoryTo(Endpoint.PUT_UNITS, {
299
- status: EndpointStatus.FAILED
300
- });
301
- throw error;
302
- }
303
337
  }
304
338
  async function patchUnit(unit, options2) {
305
339
  const endpoint = getEndpoint(endpoints, Endpoint.PATCH_UNIT);
306
- const resolvedSchema = resolveSchema(schema, endpoint.action, unit);
340
+ const resolvedSchema = resolveSchema(schema, {
341
+ indicator,
342
+ endpoint,
343
+ unit
344
+ });
307
345
  if (options2?.validate) {
308
346
  schema.pick(resolvedSchema.keys).partial().parse(unit);
309
347
  }
310
- patchEndpointMemoryTo(Endpoint.PATCH_UNIT, {
311
- status: EndpointStatus.PENDING
312
- });
313
- try {
314
- const resolvedUrl = resolveEndpointUrl(endpoint.url, {
315
- [indicator]: unit[indicator]
348
+ return withEndpointStatus(Endpoint.PATCH_UNIT, async () => {
349
+ const response = await api().patch(resolveEndpointUrl(endpoint, unit), {
350
+ ...options2,
351
+ body: options2?.body ?? resolvedSchema.values
316
352
  });
317
- const response = await api.patch(
318
- resolvedUrl,
319
- {
320
- ...options2,
321
- body: options2?.body ?? resolvedSchema.values
322
- }
323
- );
324
- editMemorizedUnit(response);
325
- patchEndpointMemoryTo(Endpoint.PATCH_UNIT, {
326
- status: EndpointStatus.SUCCESS
353
+ editMemorizedUnit({
354
+ ...unit,
355
+ ...response
327
356
  });
328
357
  return response;
329
- } catch (error) {
330
- patchEndpointMemoryTo(Endpoint.PATCH_UNIT, {
331
- status: EndpointStatus.FAILED
332
- });
333
- throw error;
334
- }
358
+ });
335
359
  }
336
360
  async function patchUnits(units, options2) {
337
361
  const endpoint = getEndpoint(endpoints, Endpoint.PATCH_UNITS);
338
- const body = units.map((unit) => {
339
- const resolvedSchema = resolveSchema(schema, endpoint.action, unit);
340
- if (options2?.validate) {
341
- schema.pick(resolvedSchema.keys).partial().parse(unit);
362
+ return withEndpointStatus(Endpoint.PATCH_UNITS, async () => {
363
+ const responses = [];
364
+ for (const unit of units) {
365
+ const resolvedSchema = resolveSchema(schema, {
366
+ indicator,
367
+ endpoint,
368
+ unit
369
+ });
370
+ if (options2?.validate) {
371
+ schema.pick(resolvedSchema.keys).partial().parse(unit);
372
+ }
373
+ const response = await api().patch(resolveEndpointUrl(endpoint, unit), {
374
+ ...options2,
375
+ body: options2?.body ?? resolvedSchema.values
376
+ });
377
+ editMemorizedUnits([
378
+ {
379
+ ...unit,
380
+ ...response
381
+ }
382
+ ]);
383
+ responses.push(response);
342
384
  }
343
- return resolvedSchema.values;
344
- });
345
- patchEndpointMemoryTo(Endpoint.PATCH_UNITS, {
346
- status: EndpointStatus.PENDING
385
+ return responses;
347
386
  });
348
- try {
349
- const resolvedUrl = resolveEndpointUrl(endpoint.url);
350
- const response = await api.patch(resolvedUrl, {
351
- ...options2,
352
- body: options2?.body ?? body
353
- });
354
- editMemorizedUnits(response);
355
- patchEndpointMemoryTo(Endpoint.PATCH_UNITS, {
356
- status: EndpointStatus.SUCCESS
357
- });
358
- return response;
359
- } catch (error) {
360
- patchEndpointMemoryTo(Endpoint.PATCH_UNITS, {
361
- status: EndpointStatus.FAILED
362
- });
363
- throw error;
364
- }
365
387
  }
366
388
  async function deleteUnit(unit, options2) {
367
389
  const endpoint = getEndpoint(endpoints, Endpoint.DELETE_UNIT);
368
- patchEndpointMemoryTo(Endpoint.DELETE_UNIT, {
369
- status: EndpointStatus.PENDING
370
- });
371
- try {
372
- const resolvedUrl = resolveEndpointUrl(endpoint.url, {
373
- [indicator]: unit[indicator]
374
- });
375
- await api.del(
376
- resolvedUrl,
390
+ return withEndpointStatus(Endpoint.DELETE_UNIT, async () => {
391
+ await api().del(
392
+ resolveEndpointUrl(endpoint, unit),
377
393
  options2
378
394
  );
379
395
  dropMemorizedUnit(unit);
380
- patchEndpointMemoryTo(Endpoint.DELETE_UNIT, {
381
- status: EndpointStatus.SUCCESS
382
- });
383
396
  return true;
384
- } catch (error) {
385
- patchEndpointMemoryTo(Endpoint.DELETE_UNIT, {
386
- status: EndpointStatus.FAILED
387
- });
388
- throw error;
389
- }
397
+ });
390
398
  }
391
399
  async function deleteUnits(units, options2) {
392
400
  const endpoint = getEndpoint(endpoints, Endpoint.DELETE_UNITS);
393
- patchEndpointMemoryTo(Endpoint.DELETE_UNITS, {
394
- status: EndpointStatus.PENDING
395
- });
396
- try {
397
- const resolvedUrl = resolveEndpointUrl(endpoint.url);
398
- await api.del(
399
- resolvedUrl,
400
- options2
401
- );
402
- dropMemorizedUnits(units);
403
- patchEndpointMemoryTo(Endpoint.DELETE_UNITS, {
404
- status: EndpointStatus.SUCCESS
405
- });
401
+ return withEndpointStatus(Endpoint.DELETE_UNITS, async () => {
402
+ for (const unit of units) {
403
+ await api().del(
404
+ resolveEndpointUrl(endpoint, unit),
405
+ options2
406
+ );
407
+ dropMemorizedUnits([unit]);
408
+ }
406
409
  return true;
407
- } catch (error) {
408
- patchEndpointMemoryTo(Endpoint.DELETE_UNITS, {
409
- status: EndpointStatus.FAILED
410
- });
411
- throw error;
412
- }
410
+ });
413
411
  }
414
412
  return {
415
413
  api,
@@ -2,4 +2,4 @@ export { z } from "zod";
2
2
  export { ApiAction, ApiResponseType, ApiErrorSource, type ApiRequestHeader, type ApiRequestQuery, type ApiRequestBody, type ApiRequestOptions, type ApiOptions, type ApiActionOptions, type ApiErrorOptions, createApi, ApiError, ApiRequestError, ApiResponseError, } from "./core/api.js";
3
3
  export { Endpoint, EndpointStatus, type EndpointDefinition, type EndpointMemory, } from "./utils/endpoint.js";
4
4
  export { type SchemaMeta, getMeta, resolveSchema } from "./utils/schema.js";
5
- export { createStore } from "./core/store.js";
5
+ export { createStore, StoreMemoryPosition } from "./core/store.js";
@@ -13,4 +13,4 @@ export {
13
13
  EndpointStatus
14
14
  } from "./utils/endpoint.js";
15
15
  export { getMeta, resolveSchema } from "./utils/schema.js";
16
- export { createStore } from "./core/store.js";
16
+ export { createStore, StoreMemoryPosition } from "./core/store.js";
@@ -1,20 +1,26 @@
1
1
  import { createVuePlugin } from "@harlem/core";
2
2
  import {
3
+ createServerSSRPlugin,
3
4
  createClientSSRPlugin,
4
- createServerSSRPlugin
5
+ getBridgingScript
5
6
  } from "@harlem/plugin-ssr";
6
7
  export default defineNuxtPlugin((nuxtApp) => {
7
8
  const plugins = [];
8
- if (nuxtApp.payload.serverRendered) {
9
- if (import.meta.server) {
10
- plugins.push(createServerSSRPlugin());
11
- }
12
- if (import.meta.client) {
13
- plugins.push(createClientSSRPlugin());
14
- }
9
+ if (import.meta.server) {
10
+ plugins.push(createServerSSRPlugin());
11
+ }
12
+ if (import.meta.client) {
13
+ plugins.push(createClientSSRPlugin());
15
14
  }
16
15
  const harlem = createVuePlugin({
17
16
  plugins
18
17
  });
19
18
  nuxtApp.vueApp.use(harlem);
19
+ useHead({
20
+ script: [
21
+ {
22
+ innerHTML: getBridgingScript()
23
+ }
24
+ ]
25
+ });
20
26
  });
@@ -18,55 +18,22 @@ export declare enum EndpointStatus {
18
18
  SUCCESS = "success",
19
19
  FAILED = "failed"
20
20
  }
21
- export interface EndpointDefinition {
21
+ export interface EndpointDefinition<T = Record<string, unknown>> {
22
22
  action: ApiAction;
23
- url: string | ((keys: Record<PropertyKey, unknown>) => string);
23
+ url: string | ((params: T) => string);
24
24
  }
25
25
  export interface EndpointMemory {
26
26
  status: EndpointStatus;
27
27
  }
28
- export declare function makeEndpointStatusKey<K extends Endpoint, S extends EndpointStatus>(key: K, status: S): `${K}Is${Capitalize<S>}`;
29
- export declare function getEndpoint(endpoints: Partial<Record<Endpoint, EndpointDefinition>> | undefined, key: Endpoint): EndpointDefinition;
30
- export declare function resolveEndpointUrl<T extends Record<PropertyKey, unknown>>(url: string | ((parameters: T) => string), parameters?: T): string;
31
- export declare function makeEndpointsStatus<T>(getter: (name: string, fn: (state: BaseState) => boolean) => T): {
32
- getUnitIsIdle: T;
33
- getUnitIsPending: T;
34
- getUnitIsSuccess: T;
35
- getUnitIsFailed: T;
36
- getUnitsIsIdle: T;
37
- getUnitsIsPending: T;
38
- getUnitsIsSuccess: T;
39
- getUnitsIsFailed: T;
40
- postUnitIsIdle: T;
41
- postUnitIsPending: T;
42
- postUnitIsSuccess: T;
43
- postUnitIsFailed: T;
44
- postUnitsIsIdle: T;
45
- postUnitsIsPending: T;
46
- postUnitsIsSuccess: T;
47
- postUnitsIsFailed: T;
48
- putUnitIsIdle: T;
49
- putUnitIsPending: T;
50
- putUnitIsSuccess: T;
51
- putUnitIsFailed: T;
52
- putUnitsIsIdle: T;
53
- putUnitsIsPending: T;
54
- putUnitsIsSuccess: T;
55
- putUnitsIsFailed: T;
56
- patchUnitIsIdle: T;
57
- patchUnitIsPending: T;
58
- patchUnitIsSuccess: T;
59
- patchUnitIsFailed: T;
60
- patchUnitsIsIdle: T;
61
- patchUnitsIsPending: T;
62
- patchUnitsIsSuccess: T;
63
- patchUnitsIsFailed: T;
64
- deleteUnitIsIdle: T;
65
- deleteUnitIsPending: T;
66
- deleteUnitIsSuccess: T;
67
- deleteUnitIsFailed: T;
68
- deleteUnitsIsIdle: T;
69
- deleteUnitsIsPending: T;
70
- deleteUnitsIsSuccess: T;
71
- deleteUnitsIsFailed: T;
28
+ type CapitalizeString<S extends string> = S extends `${infer F}${infer R}` ? `${Uppercase<F>}${R}` : S;
29
+ export type EndpointStatusKey<K extends Endpoint = Endpoint, S extends EndpointStatus = EndpointStatus> = `${K}Is${CapitalizeString<S>}`;
30
+ export declare function makeEndpointStatusKey<K extends Endpoint, S extends EndpointStatus>(key: K, status: S): EndpointStatusKey<K, S>;
31
+ export declare function getEndpoint<T = Record<string, unknown>>(endpoints: Partial<Record<Endpoint, EndpointDefinition<T>>> | undefined, key: Endpoint): EndpointDefinition<T>;
32
+ export declare function resolveEndpointUrl<T>(endpoint: EndpointDefinition<T>, params?: {
33
+ [key: string]: unknown;
34
+ }): string;
35
+ export type EndpointsStatusMap<T> = {
36
+ [K in Endpoint as EndpointStatusKey<K, EndpointStatus>]: T;
72
37
  };
38
+ export declare function makeEndpointsStatus<T>(getter: (name: string, fn: (state: BaseState) => boolean) => T): EndpointsStatusMap<T>;
39
+ export {};
@@ -19,7 +19,8 @@ export var EndpointStatus = /* @__PURE__ */ ((EndpointStatus2) => {
19
19
  return EndpointStatus2;
20
20
  })(EndpointStatus || {});
21
21
  export function makeEndpointStatusKey(key, status) {
22
- return `${key}Is${status.charAt(0).toUpperCase() + status.slice(1)}`;
22
+ const capitalizedStatus = status.charAt(0).toUpperCase() + status.slice(1);
23
+ return `${key}Is${capitalizedStatus}`;
23
24
  }
24
25
  export function getEndpoint(endpoints, key) {
25
26
  const endpoint = endpoints?.[key];
@@ -28,11 +29,11 @@ export function getEndpoint(endpoints, key) {
28
29
  }
29
30
  return endpoint;
30
31
  }
31
- export function resolveEndpointUrl(url, parameters = {}) {
32
- if (typeof url === "function") {
33
- return url(parameters);
32
+ export function resolveEndpointUrl(endpoint, params) {
33
+ if (typeof endpoint.url === "function") {
34
+ return endpoint.url(params);
34
35
  }
35
- return url;
36
+ return endpoint.url;
36
37
  }
37
38
  export function makeEndpointsStatus(getter) {
38
39
  const output = {};
@@ -1,11 +1,17 @@
1
1
  import { z } from "zod";
2
2
  import type { ApiAction } from "../core/api.js";
3
+ import type { EndpointDefinition } from "./endpoint.js";
3
4
  export interface SchemaMeta {
4
5
  indicator?: boolean;
5
6
  actions?: ApiAction[];
6
7
  }
7
8
  export declare function getMeta(field: any): SchemaMeta | undefined;
8
- export declare function resolveSchema<T extends z.ZodRawShape, S extends z.infer<z.ZodObject<T>>>(schema: z.ZodObject<T>, action?: ApiAction, input?: Partial<S>): {
9
+ export interface ResolveSchemaOptions<S> {
10
+ indicator?: keyof S;
11
+ endpoint?: EndpointDefinition<Partial<S>>;
12
+ unit?: Partial<S>;
13
+ }
14
+ export declare function resolveSchema<T extends z.ZodRawShape, S extends z.infer<z.ZodObject<T>>>(schema: z.ZodObject<T>, options?: ResolveSchemaOptions<S>): {
9
15
  indicator: keyof S;
10
16
  keys: Record<keyof S, true>;
11
17
  values: Partial<S>;
@@ -1,9 +1,9 @@
1
1
  export function getMeta(field) {
2
2
  return field.meta();
3
3
  }
4
- export function resolveSchema(schema, action, input) {
4
+ export function resolveSchema(schema, options) {
5
5
  const output = {
6
- indicator: "id",
6
+ indicator: options?.indicator ?? "id",
7
7
  keys: {},
8
8
  values: {}
9
9
  };
@@ -12,13 +12,13 @@ export function resolveSchema(schema, action, input) {
12
12
  if (meta?.indicator) {
13
13
  output.indicator = key;
14
14
  }
15
- if (!action || !meta?.actions) {
15
+ if (!options?.endpoint?.action || !meta?.actions) {
16
16
  continue;
17
17
  }
18
- if (meta?.actions.includes(action)) {
18
+ if (meta?.actions.includes(options.endpoint.action)) {
19
19
  output.keys[key] = true;
20
- if (input && key in input) {
21
- output.values[key] = input[key];
20
+ if (options?.unit && key in options.unit) {
21
+ output.values[key] = options.unit[key];
22
22
  }
23
23
  }
24
24
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@diphyx/harlemify",
3
- "version": "0.0.1",
3
+ "version": "0.0.3",
4
4
  "description": "API state management for Nuxt powered by Harlem",
5
5
  "keywords": [
6
6
  "nuxt",
@@ -37,14 +37,13 @@
37
37
  "dist"
38
38
  ],
39
39
  "dependencies": {
40
- "@nuxt/kit": "^3.14.0",
41
40
  "@harlem/core": "^3.0.0",
42
41
  "@harlem/plugin-ssr": "^3.0.0",
42
+ "@nuxt/kit": "^3.14.0",
43
43
  "defu": "^6.0.0",
44
44
  "zod": "^4.0.0"
45
45
  },
46
46
  "devDependencies": {
47
- "@nuxt/devtools": "^1.6.0",
48
47
  "@nuxt/eslint-config": "^0.6.0",
49
48
  "@nuxt/module-builder": "^0.8.0",
50
49
  "@nuxt/schema": "^3.14.0",
@@ -53,12 +52,13 @@
53
52
  "eslint": "^9.0.0",
54
53
  "nuxt": "^3.14.0",
55
54
  "typescript": "^5.6.0",
56
- "vitest": "^2.0.0"
55
+ "vitest": "^2.0.0",
56
+ "vue": "^3.5.26"
57
57
  },
58
58
  "scripts": {
59
- "postinstall": "nuxi prepare playground",
59
+ "cleanup": "pnpm nuxt cleanup && pnpm nuxt cleanup playground",
60
+ "dev": "pnpm nuxt dev playground",
60
61
  "build": "nuxt-module-build build",
61
- "dev": "nuxi dev playground",
62
62
  "lint": "eslint . --fix",
63
63
  "test": "vitest run"
64
64
  }