@anweb/nuxt-ancore 1.9.3 → 1.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/module.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "AnCore",
3
3
  "configKey": "ancore",
4
- "version": "1.9.3",
4
+ "version": "1.10.0",
5
5
  "builder": {
6
6
  "@nuxt/module-builder": "1.0.2",
7
7
  "unbuild": "3.6.1"
@@ -1,19 +1,19 @@
1
1
  import type { NitroFetchOptions, NitroFetchRequest } from 'nitropack';
2
2
  import { type Ref, type ComputedRef } from 'vue';
3
- import type { KeysOf, PickFrom } from '#app/composables/asyncData';
4
- import { useAsyncData } from '#app';
3
+ import { type AsyncDataRequestStatus } from '#app';
5
4
  interface TConfig {
6
5
  request: NitroFetchRequest;
7
6
  apiConfig?: NitroFetchOptions<string>;
7
+ params?: Record<string, unknown>;
8
8
  }
9
9
  interface TUseAnData<TData, TError> {
10
10
  init: () => Promise<void>;
11
11
  set: (data: TData) => void;
12
+ config: Ref<TConfig>;
13
+ data: ComputedRef<TData | undefined>;
14
+ status: ComputedRef<AsyncDataRequestStatus>;
12
15
  loading: ComputedRef<boolean>;
13
- request: Ref<NitroFetchRequest>;
14
- data: Ref<PickFrom<TData, KeysOf<TData>> | undefined, PickFrom<TData, KeysOf<TData>> | undefined>;
15
- error: ComputedRef<TError>;
16
- status: ReturnType<typeof useAsyncData>['status'];
16
+ error: ComputedRef<TError | undefined>;
17
17
  }
18
- export declare const useAnData: <TData = unknown, TError = unknown>(config: TConfig) => TUseAnData<TData, TError>;
18
+ export declare const useAnData: <TData = unknown, TError = unknown>(initConfig: TConfig) => TUseAnData<TData, TError>;
19
19
  export {};
@@ -1,34 +1,45 @@
1
- import { computed, ref } from "vue";
1
+ import { computed, ref, watch } from "vue";
2
2
  import { useAsyncData } from "#app";
3
- import { userApi } from "../utils/index.js";
4
- export const useAnData = (config) => {
5
- const request = ref(config.request);
3
+ import { toQuery, userApi } from "../utils/index.js";
4
+ export const useAnData = (initConfig) => {
5
+ const config = ref({ ...initConfig });
6
+ const data = ref(void 0);
7
+ const error = ref(void 0);
8
+ const status = ref("idle");
9
+ const init = async () => {
10
+ const Data = await useAsyncData(
11
+ key,
12
+ () => userApi(
13
+ config.value.request,
14
+ { method: "GET", ...config.value.apiConfig || {} }
15
+ )
16
+ );
17
+ watch(Data.data, () => data.value = Data.data.value, { immediate: true });
18
+ watch(Data.error, () => error.value = Data.error.value, { immediate: true });
19
+ watch(Data.status, () => error.value = Data.status.value, { immediate: true });
20
+ };
6
21
  const set = (value) => {
7
22
  data.value = value;
8
23
  };
9
- const loading = computed(() => {
10
- return status.value === "pending";
11
- });
12
24
  const key = computed(() => {
13
- return request.value.toString();
25
+ let url = config.value.request.toString();
26
+ for (const key2 in config.value.params) {
27
+ url.replace(`:${key2}`, encodeURIComponent(String(config.value.params[key2])));
28
+ }
29
+ let query = "";
30
+ if (config.value.apiConfig?.query) {
31
+ query = "?" + toQuery(config.value.apiConfig.query);
32
+ }
33
+ return url + query;
14
34
  });
15
- const {
16
- data,
17
- error,
18
- execute,
19
- status
20
- } = useAsyncData(
21
- key,
22
- () => userApi(request.value, { method: "GET", ...config.apiConfig || {} }),
23
- { immediate: false }
24
- );
35
+ const loading = computed(() => status.value === "pending");
25
36
  return {
26
- init: execute,
37
+ init,
27
38
  set,
28
- loading,
29
- request,
30
39
  data,
31
- error,
32
- status
40
+ config,
41
+ status,
42
+ loading,
43
+ error
33
44
  };
34
45
  };
@@ -1,16 +1,19 @@
1
- import type { Rules } from 'async-validator';
1
+ import type { RuleItem } from 'async-validator';
2
2
  import { type UseAsyncValidatorExecuteReturn } from '@vueuse/integrations/useAsyncValidator';
3
- interface TFormParams<T> {
4
- rules?: Rules;
5
- empty: Record<keyof T, unknown>;
6
- data?: Partial<T> | null;
3
+ interface TStructureItem<TData> {
4
+ default: TData;
5
+ rules?: RuleItem[];
7
6
  }
8
- declare const _default: <T = unknown>(params: TFormParams<T>) => {
9
- state: [T] extends [import("vue").Ref<any, any>] ? import("@vue/shared").IfAny<T, import("vue").Ref<T, T>, T> : import("vue").Ref<import("vue").UnwrapRef<T>, T | import("vue").UnwrapRef<T>>;
10
- merge: (data: T) => void;
7
+ interface TFormParams<TForm> {
8
+ structure: Record<keyof TForm, TStructureItem<TForm[keyof TForm]>>;
9
+ data?: Partial<TForm> | null;
10
+ }
11
+ export declare const useAnForm: <TForm extends Record<string, unknown>>(params: TFormParams<TForm>) => {
12
+ state: [TForm] extends [import("vue").Ref<any, any>] ? import("@vue/shared").IfAny<TForm, import("vue").Ref<TForm, TForm>, TForm> : import("vue").Ref<import("vue").UnwrapRef<TForm>, TForm | import("vue").UnwrapRef<TForm>>;
13
+ merge: (data: TForm) => void;
11
14
  validator: {
12
15
  check: () => Promise<UseAsyncValidatorExecuteReturn>;
13
- errors: import("vue").Ref<Record<string, import("async-validator").ValidateError[]> | undefined, Record<string, import("async-validator").ValidateError[]> | undefined>;
16
+ errors: [Partial<Record<keyof TForm, string>>] extends [import("vue").Ref<any, any>] ? import("@vue/shared").IfAny<import("vue").Ref<any, any> & Partial<Record<keyof TForm, string>>, import("vue").Ref<import("vue").Ref<any, any> & Partial<Record<keyof TForm, string>>, import("vue").Ref<any, any> & Partial<Record<keyof TForm, string>>>, import("vue").Ref<any, any> & Partial<Record<keyof TForm, string>>> : import("vue").Ref<import("vue").UnwrapRef<Partial<Record<keyof TForm, string>>>, Partial<Record<keyof TForm, string>> | import("vue").UnwrapRef<Partial<Record<keyof TForm, string>>>>;
14
17
  };
15
18
  history: {
16
19
  isChanged: import("vue").ComputedRef<boolean>;
@@ -18,4 +21,4 @@ declare const _default: <T = unknown>(params: TFormParams<T>) => {
18
21
  commit: () => void;
19
22
  };
20
23
  };
21
- export default _default;
24
+ export {};
@@ -1,17 +1,17 @@
1
+ import { computed, ref, nextTick, watch } from "vue";
2
+ import { useRefHistory } from "@vueuse/core";
1
3
  import {
2
4
  useAsyncValidator
3
5
  } from "@vueuse/integrations/useAsyncValidator";
4
- import { useRefHistory } from "@vueuse/core";
5
- import { computed, ref, nextTick, watchEffect, watch } from "vue";
6
- export default (params) => {
7
- const state = ref(params.empty ? { ...params.empty } : {});
8
- const keys = Object.keys(params.empty);
6
+ export const useAnForm = (params) => {
7
+ const state = ref(Object.fromEntries(Object.entries(params.structure).map(([k, v]) => [k, params.data?.[k] ?? v.default])));
8
+ const keys = Object.keys(state.value);
9
9
  let validatorExecute;
10
- const validatorErrors = ref();
11
10
  const History = useRefHistory(state, { deep: true });
11
+ const errors = ref({});
12
12
  const init = () => {
13
13
  if (params.data) merge(params.data);
14
- if (params.rules) initValidate();
14
+ initValidate();
15
15
  void nextTick(History.clear);
16
16
  };
17
17
  const merge = (data) => {
@@ -20,15 +20,25 @@ export default (params) => {
20
20
  }
21
21
  };
22
22
  const initValidate = () => {
23
- if (!params.rules) return;
23
+ const rules = {};
24
+ for (const key of keys) {
25
+ if (!params.structure[key].rules) continue;
26
+ rules[key] = params.structure[key].rules;
27
+ }
24
28
  const validator = useAsyncValidator(
25
29
  state,
26
- params.rules,
30
+ rules,
27
31
  { manual: true }
28
32
  );
29
33
  validatorExecute = validator.execute;
30
- watchEffect(() => {
31
- validatorErrors.value = validator.errorFields.value;
34
+ watch(validator.errorFields, () => {
35
+ errors.value = {};
36
+ for (const key in validator.errorFields.value) {
37
+ const fieldErrors = validator.errorFields.value[key];
38
+ if (fieldErrors?.[0]) {
39
+ errors.value[key] = fieldErrors[0].message;
40
+ }
41
+ }
32
42
  });
33
43
  };
34
44
  const first = computed(() => {
@@ -41,9 +51,7 @@ export default (params) => {
41
51
  return firstOne !== last;
42
52
  });
43
53
  watch(state, () => {
44
- if (validatorErrors.value) {
45
- validatorErrors.value = void 0;
46
- }
54
+ errors.value = {};
47
55
  }, { deep: true });
48
56
  init();
49
57
  return {
@@ -55,7 +63,7 @@ export default (params) => {
55
63
  check: () => {
56
64
  return validatorExecute();
57
65
  },
58
- errors: validatorErrors
66
+ errors
59
67
  },
60
68
  history: {
61
69
  isChanged,
@@ -1,6 +1,5 @@
1
- declare const _default: (resources?: Record<string, any>) => {
1
+ export declare const useAnI18n: (resources?: Record<string, any>) => {
2
2
  t: import("i18next").TFunction<["translation", ...string[]], undefined>;
3
3
  } | {
4
4
  t: (key: string, options?: {}) => string;
5
5
  };
6
- export default _default;
@@ -1,6 +1,6 @@
1
1
  import i18next from "i18next";
2
2
  import { getJSONHash } from "../utils/index.js";
3
- export default (resources) => {
3
+ export const useAnI18n = (resources) => {
4
4
  if (!resources) return { t: i18next.t };
5
5
  const ns = getJSONHash(resources);
6
6
  for (const lang in resources) {
@@ -1,18 +1,21 @@
1
1
  import type { NitroFetchOptions, NitroFetchRequest } from 'nitropack';
2
2
  interface TConfig<TFilter> {
3
3
  request: NitroFetchRequest;
4
+ apiConfig?: NitroFetchOptions<string>;
4
5
  filter?: TFilter;
6
+ params?: Record<string, unknown>;
7
+ skipField?: string;
5
8
  reverse?: boolean;
6
- apiConfig?: NitroFetchOptions<string>;
7
9
  }
8
- declare const _default: <TData, TFilter = unknown>(config: TConfig<TFilter>) => {
9
- init: (newFilter?: TFilter) => Promise<void>;
10
- inited: import("vue").Ref<boolean, boolean>;
11
- filter: [Partial<TFilter>] extends [import("vue").Ref<any, any>] ? import("@vue/shared").IfAny<import("vue").Ref<any, any> & Partial<TFilter>, import("vue").Ref<import("vue").Ref<any, any> & Partial<TFilter>, import("vue").Ref<any, any> & Partial<TFilter>>, import("vue").Ref<any, any> & Partial<TFilter>> : import("vue").Ref<import("vue").UnwrapRef<Partial<TFilter>>, Partial<TFilter> | import("vue").UnwrapRef<Partial<TFilter>>>;
12
- loading: import("vue").ComputedRef<boolean>;
10
+ export declare const useAnList: <TData, TFilter extends object = {}>(initConfig: TConfig<TFilter>) => {
11
+ init: () => Promise<void>;
12
+ filter: TFilter;
13
+ params: Record<string, unknown> | undefined;
13
14
  items: TData[];
14
15
  count: import("vue").Ref<number | null, number | null>;
15
- error: import("vue").Ref<import("#app").NuxtError<unknown> | undefined, import("#app").NuxtError<unknown> | undefined>;
16
- status: import("vue").Ref<import("#app").AsyncDataRequestStatus, import("#app").AsyncDataRequestStatus>;
16
+ inited: import("vue").ComputedRef<boolean>;
17
+ status: import("vue").ComputedRef<import("nuxt/app").AsyncDataRequestStatus>;
18
+ loading: import("vue").ComputedRef<boolean>;
19
+ error: import("vue").ComputedRef<unknown>;
17
20
  };
18
- export default _default;
21
+ export {};
@@ -1,65 +1,49 @@
1
- import { computed, ref, reactive, watch } from "vue";
2
- import { useAsyncData } from "#app";
3
- import { userApi, toQuery } from "../utils/index.js";
4
- export default (config) => {
5
- const inited = ref(false);
6
- const filter = ref(config.filter || {});
1
+ import { ref, reactive, watch, computed } from "vue";
2
+ import { useAnData } from "./useAnData.js";
3
+ export const useAnList = (initConfig) => {
4
+ const config = ref(initConfig);
7
5
  const items = reactive([]);
8
6
  const count = ref(null);
9
- const init = async (newFilter) => {
10
- if (newFilter) {
11
- filter.value = { ...newFilter };
12
- } else if (config.filter) {
13
- filter.value = { ...config.filter };
14
- }
15
- await execute();
7
+ const init = async () => {
8
+ await data.init();
16
9
  refresh();
17
- inited.value = true;
18
10
  };
19
11
  const refresh = () => {
20
- if (!data.value) return;
21
- if (!filter.value.skip) {
12
+ if (!data.data.value) return;
13
+ if (!config.value.apiConfig?.query?.[config.value.skipField || "skip"]) {
22
14
  setCount(null);
23
15
  items.length = 0;
24
16
  }
25
- if (config.reverse) {
26
- items.unshift(...data.value.items);
17
+ if (config.value.reverse) {
18
+ items.unshift(...data.data.value.items);
27
19
  } else {
28
- items.push(...data.value.items);
20
+ items.push(...data.data.value.items);
29
21
  }
30
- setCount(data.value.count);
22
+ setCount(data.data.value.count);
31
23
  };
32
24
  const setCount = (value) => {
33
25
  count.value = value;
34
26
  };
35
- const key = computed(() => {
36
- return config.request + "?" + toQuery(filter.value);
37
- });
38
- const loading = computed(() => {
39
- return status.value === "pending";
27
+ const inited = computed(() => data.status.value !== "idle");
28
+ if (!config.value.apiConfig) {
29
+ config.value.apiConfig = {};
30
+ }
31
+ config.value.apiConfig.query = config.value.filter;
32
+ const data = useAnData({
33
+ request: config.value.request,
34
+ apiConfig: config.value.apiConfig,
35
+ params: config.value.params
40
36
  });
41
- const {
42
- data,
43
- error,
44
- execute,
45
- status
46
- } = useAsyncData(
47
- key,
48
- () => userApi(
49
- config.request,
50
- { method: "GET", query: filter.value, ...config.apiConfig || {} }
51
- ),
52
- { immediate: false }
53
- );
54
- watch(data, refresh);
37
+ watch(data.data, refresh);
55
38
  return {
56
39
  init,
57
- inited,
58
- filter,
59
- loading,
40
+ filter: config.value.filter,
41
+ params: config.value.params,
60
42
  items,
61
43
  count,
62
- error,
63
- status
44
+ inited,
45
+ status: data.status,
46
+ loading: data.loading,
47
+ error: data.error
64
48
  };
65
49
  };
@@ -1,4 +1,8 @@
1
- import { sha256 } from "js-sha256";
1
+ import { sha256 } from "@noble/hashes/sha2";
2
+ import { utf8ToBytes, bytesToHex } from "@noble/hashes/utils";
2
3
  export const getJSONHash = (obj) => {
3
- return sha256(JSON.stringify(obj));
4
+ const s = JSON.stringify(obj);
5
+ const bytes = utf8ToBytes(s);
6
+ const digest = sha256(bytes);
7
+ return bytesToHex(digest);
4
8
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@anweb/nuxt-ancore",
3
- "version": "1.9.3",
3
+ "version": "1.10.0",
4
4
  "description": "AnCore Nuxt module",
5
5
  "repository": "https://github.com/ANLTD/ancore",
6
6
  "license": "MIT",
@@ -27,25 +27,25 @@
27
27
  "dev": "npm run dev:prepare && nuxi dev playground",
28
28
  "dev:build": "nuxi build playground",
29
29
  "dev:prepare": "nuxt-module-build build --stub && nuxt-module-build prepare && nuxi prepare playground",
30
- "release:patch": "npm run prepack && changelogen --bump patch --release && npm publish --access public && git push --follow-tags",
31
- "release:minor": "npm run prepack && changelogen --bump minor --release && npm publish --access public && git push --follow-tags",
32
- "release:major": "npm run prepack && changelogen --bump major --release && npm publish --access public && git push --follow-tags"
30
+ "release:patch": "npm run prepack && changelogen --patch --release && npm publish --access public && git push --follow-tags",
31
+ "release:minor": "npm run prepack && changelogen --minor --release && npm publish --access public && git push --follow-tags",
32
+ "release:major": "npm run prepack && changelogen --major --release && npm publish --access public && git push --follow-tags"
33
33
  },
34
34
  "dependencies": {
35
- "@nuxt/kit": "^4.1.0",
35
+ "@noble/hashes": "^2.0.0",
36
+ "@nuxt/kit": "^4.1.2",
36
37
  "@vueuse/core": "^13.9.0",
37
38
  "@vueuse/integrations": "^13.9.0",
38
39
  "async-validator": "^4.2.5",
39
- "i18next": "^25.5.0",
40
- "js-sha256": "^0.11.1"
40
+ "i18next": "^25.5.2"
41
41
  },
42
42
  "devDependencies": {
43
43
  "@nuxt/devtools": "^2.6.3",
44
44
  "@nuxt/module-builder": "^1.0.2",
45
- "@nuxt/schema": "^4.1.0",
45
+ "@nuxt/schema": "^4.1.2",
46
46
  "@types/node": "latest",
47
47
  "changelogen": "^0.6.2",
48
- "nuxt": "^4.1.0",
48
+ "nuxt": "^4.1.2",
49
49
  "typescript": "~5.9.2"
50
50
  }
51
51
  }