nfx-ui 0.26.0 → 0.28.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/apis/authRefresh.js.map +1 -1
- package/dist/apis/clients.js.map +1 -1
- package/dist/apis/ip.d.ts.map +1 -1
- package/dist/apis/ip.js.map +1 -1
- package/dist/apis/repositories/AssetRepository.d.ts.map +1 -1
- package/dist/apis/repositories/AssetRepository.js.map +1 -1
- package/dist/apis/repositories/AuthRepository.d.ts.map +1 -1
- package/dist/apis/repositories/AuthRepository.js.map +1 -1
- package/dist/config/env.js.map +1 -1
- package/dist/constants/index.js +5 -5
- package/dist/constants/key.d.ts +4 -0
- package/dist/constants/key.d.ts.map +1 -1
- package/dist/constants/key.js +23 -1
- package/dist/constants/key.js.map +1 -1
- package/dist/constants/querykeys.js.map +1 -1
- package/dist/enums/auth.d.ts.map +1 -1
- package/dist/enums/auth.js.map +1 -1
- package/dist/enums/dashboard.d.ts.map +1 -1
- package/dist/enums/dashboard.js.map +1 -1
- package/dist/enums/language.d.ts.map +1 -1
- package/dist/enums/language.js.map +1 -1
- package/dist/enums/layout.d.ts.map +1 -1
- package/dist/enums/layout.js.map +1 -1
- package/dist/enums/theme.d.ts.map +1 -1
- package/dist/enums/theme.js.map +1 -1
- package/dist/events/EventEmitter.d.ts.map +1 -1
- package/dist/events/EventEmitter.js.map +1 -1
- package/dist/events/auth.d.ts +4 -0
- package/dist/events/auth.d.ts.map +1 -1
- package/dist/events/auth.js +9 -1
- package/dist/events/auth.js.map +1 -1
- package/dist/events/query.d.ts.map +1 -1
- package/dist/events/query.js.map +1 -1
- package/dist/events/system.d.ts.map +1 -1
- package/dist/events/system.js.map +1 -1
- package/dist/hooks/asset.d.ts +1 -0
- package/dist/hooks/asset.d.ts.map +1 -1
- package/dist/hooks/asset.js +10 -7
- package/dist/hooks/asset.js.map +1 -1
- package/dist/hooks/auth.d.ts +27 -0
- package/dist/hooks/auth.d.ts.map +1 -1
- package/dist/hooks/auth.js +256 -111
- package/dist/hooks/auth.js.map +1 -1
- package/dist/hooks/index.d.ts.map +1 -1
- package/dist/hooks/index.js +9 -9
- package/dist/hooks/preference.d.ts.map +1 -1
- package/dist/hooks/preference.js.map +1 -1
- package/dist/languages/hooks/useLanguageLabel.d.ts.map +1 -1
- package/dist/languages/hooks/useLanguageLabel.js.map +1 -1
- package/dist/languages/hooks/useLayoutLabel.d.ts.map +1 -1
- package/dist/languages/hooks/useLayoutLabel.js.map +1 -1
- package/dist/languages/hooks/usePreferenceLabel.d.ts.map +1 -1
- package/dist/languages/hooks/usePreferenceLabel.js.map +1 -1
- package/dist/languages/hooks/useThemeLabel.d.ts.map +1 -1
- package/dist/languages/hooks/useThemeLabel.js.map +1 -1
- package/dist/languages/languages/i18n.d.ts.map +1 -1
- package/dist/languages/languages/i18n.js.map +1 -1
- package/dist/languages/languages/i18nResources.js.map +1 -1
- package/dist/languages/types/components.d.ts.map +1 -1
- package/dist/languages/types/language.d.ts.map +1 -1
- package/dist/languages/utils/getLocalLanguage.d.ts.map +1 -1
- package/dist/languages/utils/getLocalLanguage.js.map +1 -1
- package/dist/languages/utils/languageStorage.d.ts.map +1 -1
- package/dist/languages/utils/languageStorage.js.map +1 -1
- package/dist/navigations/GuestRoute.js.map +1 -1
- package/dist/navigations/ProtectedRoute.js.map +1 -1
- package/dist/providers/DataProvider/index.d.ts.map +1 -1
- package/dist/providers/DataProvider/index.js.map +1 -1
- package/dist/providers/LanguageProvider/index.d.ts.map +1 -1
- package/dist/providers/LanguageProvider/index.js.map +1 -1
- package/dist/providers/ThemeProvider/index.d.ts.map +1 -1
- package/dist/providers/ThemeProvider/index.js.map +1 -1
- package/dist/schemas/index.js +4 -4
- package/dist/schemas/loginSchema.d.ts +15 -0
- package/dist/schemas/loginSchema.d.ts.map +1 -1
- package/dist/schemas/loginSchema.js +20 -1
- package/dist/schemas/loginSchema.js.map +1 -1
- package/dist/schemas/profileEditSchema.d.ts.map +1 -1
- package/dist/schemas/profileEditSchema.js.map +1 -1
- package/dist/schemas/signupSchema.js.map +1 -1
- package/dist/stores/auth.d.ts.map +1 -1
- package/dist/stores/auth.js.map +1 -1
- package/dist/stores/index.d.ts.map +1 -1
- package/dist/stores/layout.js.map +1 -1
- package/dist/stores/preference.d.ts.map +1 -1
- package/dist/stores/preference.js.map +1 -1
- package/dist/themes/hooks/index.d.ts.map +1 -1
- package/dist/themes/hooks/useTheme.d.ts.map +1 -1
- package/dist/themes/hooks/useTheme.js.map +1 -1
- package/dist/themes/index.d.ts.map +1 -1
- package/dist/themes/radix/mappings.d.ts.map +1 -1
- package/dist/themes/radix/mappings.js.map +1 -1
- package/dist/themes/types/components.d.ts.map +1 -1
- package/dist/themes/types/context.d.ts.map +1 -1
- package/dist/themes/types/index.d.ts.map +1 -1
- package/dist/themes/types/theme.d.ts.map +1 -1
- package/dist/types/domain/auth/login.d.ts.map +1 -1
- package/dist/types/domain/auth/profile.d.ts.map +1 -1
- package/dist/types/domain/auth/signup.d.ts.map +1 -1
- package/dist/utils/apiError.d.ts.map +1 -1
- package/dist/utils/apiError.js.map +1 -1
- package/dist/utils/array.d.ts.map +1 -1
- package/dist/utils/array.js.map +1 -1
- package/dist/utils/domain/account.d.ts.map +1 -1
- package/dist/utils/domain/account.js.map +1 -1
- package/dist/utils/domain/buildProfilePatch.d.ts.map +1 -1
- package/dist/utils/domain/buildProfilePatch.js.map +1 -1
- package/dist/utils/domain/images.js.map +1 -1
- package/dist/utils/factory/hooks.d.ts.map +1 -1
- package/dist/utils/factory/hooks.js.map +1 -1
- package/dist/utils/lstorage.d.ts.map +1 -1
- package/dist/utils/lstorage.js.map +1 -1
- package/dist/utils/safe.d.ts.map +1 -1
- package/dist/utils/safe.js.map +1 -1
- package/dist/utils/suspense.d.ts.map +1 -1
- package/dist/utils/suspense.js.map +1 -1
- package/package.json +1 -1
- package/src/apis/authRefresh.ts +4 -4
- package/src/apis/clients.ts +5 -5
- package/src/apis/ip.ts +1 -1
- package/src/apis/repositories/AssetRepository.ts +1 -1
- package/src/apis/repositories/AuthRepository.ts +2 -2
- package/src/config/env.ts +1 -1
- package/src/constants/key.ts +5 -1
- package/src/constants/querykeys.ts +1 -1
- package/src/enums/auth.ts +2 -2
- package/src/enums/dashboard.ts +2 -2
- package/src/enums/language.ts +2 -2
- package/src/enums/layout.ts +2 -2
- package/src/enums/theme.ts +2 -2
- package/src/events/EventEmitter.ts +1 -1
- package/src/events/auth.ts +14 -4
- package/src/events/query.ts +3 -3
- package/src/events/system.ts +3 -3
- package/src/hooks/asset.ts +12 -7
- package/src/hooks/auth.ts +238 -12
- package/src/hooks/index.ts +1 -1
- package/src/hooks/preference.ts +5 -5
- package/src/languages/hooks/useLanguageLabel.ts +1 -1
- package/src/languages/hooks/useLayoutLabel.ts +1 -1
- package/src/languages/hooks/usePreferenceLabel.ts +1 -1
- package/src/languages/hooks/useThemeLabel.ts +1 -1
- package/src/languages/languages/i18n.ts +3 -3
- package/src/languages/languages/i18nResources.ts +1 -1
- package/src/languages/types/components.ts +1 -1
- package/src/languages/types/language.ts +1 -1
- package/src/languages/utils/getLocalLanguage.ts +2 -2
- package/src/languages/utils/languageStorage.ts +3 -3
- package/src/navigations/GuestRoute.tsx +1 -1
- package/src/navigations/ProtectedRoute.tsx +1 -1
- package/src/providers/DataProvider/index.tsx +7 -7
- package/src/providers/LanguageProvider/index.tsx +6 -6
- package/src/providers/ThemeProvider/index.tsx +4 -4
- package/src/schemas/loginSchema.ts +25 -0
- package/src/schemas/profileEditSchema.ts +4 -4
- package/src/schemas/signupSchema.ts +1 -1
- package/src/stores/auth.ts +3 -3
- package/src/stores/index.ts +1 -1
- package/src/stores/layout.ts +1 -1
- package/src/stores/preference.ts +5 -5
- package/src/themes/hooks/index.ts +1 -1
- package/src/themes/hooks/useTheme.ts +4 -4
- package/src/themes/index.ts +2 -2
- package/src/themes/radix/mappings.ts +2 -2
- package/src/themes/types/components.ts +1 -1
- package/src/themes/types/context.ts +2 -2
- package/src/themes/types/index.ts +1 -1
- package/src/themes/types/theme.ts +1 -1
- package/src/types/domain/auth/login.ts +2 -2
- package/src/types/domain/auth/profile.ts +1 -1
- package/src/types/domain/auth/signup.ts +1 -1
- package/src/utils/apiError.ts +2 -2
- package/src/utils/array.ts +1 -1
- package/src/utils/domain/account.ts +2 -2
- package/src/utils/domain/buildProfilePatch.ts +6 -6
- package/src/utils/domain/images.ts +1 -1
- package/src/utils/factory/hooks.ts +1 -1
- package/src/utils/lstorage.ts +1 -1
- package/src/utils/safe.ts +1 -1
- package/src/utils/suspense.ts +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hooks.js","names":[],"sources":["../../../src/utils/factory/hooks.ts"],"sourcesContent":["/**\n * Hooks 模块:分页 fetch 与统一 React Query hooks(稳定身份,可在业务 hook body 内直接调用)。\n */\nimport type {\n InfiniteData,\n QueryKey,\n UseInfiniteQueryOptions,\n UseInfiniteQueryResult,\n UseQueryOptions,\n UseQueryResult,\n UseSuspenseInfiniteQueryOptions,\n UseSuspenseInfiniteQueryResult,\n UseSuspenseQueryOptions,\n UseSuspenseQueryResult,\n} from \"@tanstack/react-query\";\nimport type { AxiosError } from \"axios\";\nimport type { ListDTOWithNextCursor, ListDTOWithTotalNumber, OffsetLimitNumber, OffsetLimitString } from \"@/types/api\";\n\nimport { useMemo } from \"react\";\nimport { useInfiniteQuery, useQuery, useSuspenseInfiniteQuery, useSuspenseQuery } from \"@tanstack/react-query\";\n\ntype InfiniteListFilter = Partial<OffsetLimitNumber>;\n\ntype FetchNumberListParams<F extends InfiniteListFilter = InfiniteListFilter> = F & OffsetLimitNumber;\n\ntype FetchStringListParams<F extends object = Record<string, unknown>> = F & OffsetLimitString;\n\ntype MutationCtx = {\n prev?: unknown;\n};\n\ntype InfiniteQueryOptions<T> = Omit<UseInfiniteQueryOptions<ListDTOWithTotalNumber<T>, AxiosError, T[]>, \"queryKey\" | \"queryFn\" | \"getNextPageParam\" | \"initialPageParam\"> & {\n postProcess?: (data: T[]) => void;\n};\n\ntype StringInfiniteQueryOptions<T> = Omit<UseInfiniteQueryOptions<ListDTOWithNextCursor<T>, AxiosError, T[]>, \"queryKey\" | \"queryFn\" | \"getNextPageParam\" | \"initialPageParam\"> & {\n postProcess?: (data: T[]) => void;\n};\n\ntype SuspenseInfiniteQueryOptions<T> = Omit<\n UseSuspenseInfiniteQueryOptions<ListDTOWithTotalNumber<T>, AxiosError, T[]>,\n \"queryKey\" | \"queryFn\" | \"getNextPageParam\" | \"initialPageParam\"\n> & {\n postProcess?: (data: T[]) => void;\n};\n\ntype InfiniteQueryOptionsUnion<T> = InfiniteQueryOptions<T> | SuspenseInfiniteQueryOptions<T>;\n\ntype SuspenseUnifiedQueryOptions<T> = Omit<UseSuspenseQueryOptions<T, AxiosError, T>, \"queryKey\" | \"queryFn\"> & {\n postProcess?: (data: T) => void;\n};\n\ntype NormalUnifiedQueryOptions<T> = Omit<UseQueryOptions<T, AxiosError, T>, \"queryKey\" | \"queryFn\"> & {\n postProcess?: (data: T) => void;\n};\n\ntype UnifiedQueryParams<T> = {\n options?: SuspenseUnifiedQueryOptions<T>;\n postProcess?: (data: T) => void;\n} & Record<string, unknown>;\n\ntype QueryOptions<T> = NormalUnifiedQueryOptions<T>;\ntype SuspenseQueryOptions<T> = SuspenseUnifiedQueryOptions<T>;\n\nconst DEFAULT_PAGE_SIZE = 20;\n\nexport type {\n FetchNumberListParams,\n FetchStringListParams,\n InfiniteListFilter,\n InfiniteQueryOptions,\n InfiniteQueryOptionsUnion,\n MutationCtx,\n NormalUnifiedQueryOptions,\n StringInfiniteQueryOptions,\n SuspenseInfiniteQueryOptions,\n SuspenseUnifiedQueryOptions,\n UnifiedQueryParams,\n};\n\nfunction resolvePageSize(filter?: InfiniteListFilter): number {\n return filter?.limit ?? DEFAULT_PAGE_SIZE;\n}\n\nfunction resolveBaseOffset(filter?: InfiniteListFilter): number {\n return filter?.offset ?? 0;\n}\n\nfunction makeCursorFetchFunction<T, F extends InfiniteListFilter = InfiniteListFilter>(\n fetchFunc: (params: F) => Promise<ListDTOWithTotalNumber<T>>,\n postProcess?: (data: T[]) => void,\n) {\n return async (pageParam: number = 0, filter?: F): Promise<ListDTOWithTotalNumber<T>> => {\n const pageSize = resolvePageSize(filter);\n const baseOffset = resolveBaseOffset(filter);\n const payload = {\n ...filter,\n offset: baseOffset + pageParam * pageSize,\n limit: pageSize,\n } as F;\n const { items, total } = await fetchFunc(payload);\n if (items?.length) postProcess?.(items);\n return { items, total };\n };\n}\n\nfunction makeStringCursorFetchFunction<T, F extends Partial<Pick<OffsetLimitString, \"limit\">> & object = Partial<Pick<OffsetLimitString, \"limit\">>>(\n fetchFunc: (params: FetchStringListParams<F>) => Promise<ListDTOWithNextCursor<T>>,\n postProcess?: (data: T[]) => void,\n) {\n return async (pageParam: string = \"\", filter?: F): Promise<ListDTOWithNextCursor<T>> => {\n const pageSize = filter?.limit ?? DEFAULT_PAGE_SIZE;\n const payload = {\n ...filter,\n offset: pageParam,\n limit: pageSize,\n } as FetchStringListParams<F>;\n const { items, nextCursor } = await fetchFunc(payload);\n if (items?.length) postProcess?.(items);\n return { items, nextCursor };\n };\n}\n\nexport { makeCursorFetchFunction, makeStringCursorFetchFunction };\n\nfunction buildInfiniteCommonOptions<T, F extends InfiniteListFilter = InfiniteListFilter>(\n queryKey: QueryKey,\n fetchFunction: (pageParam: number, filter?: F) => Promise<ListDTOWithTotalNumber<T>>,\n filter: F,\n options: Omit<InfiniteQueryOptionsUnion<T>, \"postProcess\"> | undefined,\n) {\n const pageSize = resolvePageSize(filter);\n const baseOffset = resolveBaseOffset(filter);\n return {\n // eslint-disable-next-line @tanstack/query/exhaustive-deps\n queryKey: [...queryKey, filter],\n queryFn: ({ pageParam }: { pageParam: number }) => fetchFunction(pageParam, filter),\n initialPageParam: 0,\n getNextPageParam: (lastPage: ListDTOWithTotalNumber<T>, allPages: ListDTOWithTotalNumber<T>[]) =>\n baseOffset + allPages.length * pageSize < lastPage.total ? allPages.length : undefined,\n select: (d: InfiniteData<ListDTOWithTotalNumber<T>>) => d.pages.flatMap((p) => p.items),\n retry: (failureCount: number, error: AxiosError) => {\n const transient = (error?.status && error.status >= 500) || error?.code === \"NETWORK_ERROR\";\n const retryMax = typeof options?.retry === \"number\" ? options.retry : 3;\n return transient && failureCount < retryMax;\n },\n ...(options as Partial<ReturnType<typeof useInfiniteQuery>>),\n };\n}\n\nfunction buildQueryCommonOptions<T, F extends object = Record<string, unknown>>(\n fetchRemote: (params: F) => Promise<T>,\n queryKey: QueryKey,\n filter: F | undefined,\n options: QueryOptions<T> | SuspenseQueryOptions<T> | undefined,\n) {\n const { postProcess, ...queryOptions } = options ?? {};\n return {\n queryKey: filter !== undefined ? [...queryKey, filter] : queryKey,\n queryFn: async () => {\n const data = await fetchRemote(filter || ({} as F));\n postProcess?.(data);\n return data;\n },\n select: (data: T) => data,\n retry: (failureCount: number, error: AxiosError) => {\n const status = error?.status ?? error?.response?.status;\n const transient = (typeof status === \"number\" && status >= 500) || error?.code === \"NETWORK_ERROR\";\n const retryMax = typeof queryOptions?.retry === \"number\" ? queryOptions.retry : 3;\n return transient && failureCount < retryMax;\n },\n ...(queryOptions as object),\n };\n}\n\nfunction useUnifiedQuery<T, F extends object = Record<string, unknown>>(\n fetchRemote: (params: F) => Promise<T>,\n queryKey: QueryKey,\n filter?: F,\n options?: QueryOptions<T>,\n): UseQueryResult<T, AxiosError> {\n return useQuery(buildQueryCommonOptions(fetchRemote, queryKey, filter, options));\n}\n\nfunction useUnifiedSuspenseQuery<T, F extends object = Record<string, unknown>>(\n fetchRemote: (params: F) => Promise<T>,\n queryKey: QueryKey,\n filter?: F,\n options?: SuspenseQueryOptions<T>,\n): UseSuspenseQueryResult<T, AxiosError> {\n return useSuspenseQuery(buildQueryCommonOptions(fetchRemote, queryKey, filter, options));\n}\n\nfunction useUnifiedInfiniteQuery<T, F extends InfiniteListFilter = InfiniteListFilter>(\n fetchRemote: (params: F) => Promise<ListDTOWithTotalNumber<T>>,\n queryKey: QueryKey,\n filter?: F,\n options?: InfiniteQueryOptions<T>,\n): UseInfiniteQueryResult<T[], AxiosError> {\n const resolvedFilter = (filter ?? {}) as F;\n const { postProcess, ...queryOptions } = options ?? {};\n const fetchFunction = useMemo(() => makeCursorFetchFunction(fetchRemote, postProcess), [fetchRemote, postProcess]);\n return useInfiniteQuery(buildInfiniteCommonOptions(queryKey, fetchFunction, resolvedFilter, queryOptions));\n}\n\nfunction useUnifiedSuspenseInfiniteQuery<T, F extends InfiniteListFilter = InfiniteListFilter>(\n fetchRemote: (params: F) => Promise<ListDTOWithTotalNumber<T>>,\n queryKey: QueryKey,\n filter?: F,\n options?: SuspenseInfiniteQueryOptions<T>,\n): UseSuspenseInfiniteQueryResult<T[], AxiosError> {\n const resolvedFilter = (filter ?? {}) as F;\n const { postProcess, ...queryOptions } = options ?? {};\n const fetchFunction = useMemo(() => makeCursorFetchFunction(fetchRemote, postProcess), [fetchRemote, postProcess]);\n return useSuspenseInfiniteQuery(buildInfiniteCommonOptions(queryKey, fetchFunction, resolvedFilter, queryOptions));\n}\n\nexport { useUnifiedInfiniteQuery, useUnifiedQuery, useUnifiedSuspenseInfiniteQuery, useUnifiedSuspenseQuery };\n"],"mappings":";;;AAgEA,IAAM,IAAoB;AAgB1B,SAAS,EAAgB,GAAqC;CAC5D,OAAO,GAAQ,SAAS;AAC1B;AAEA,SAAS,EAAkB,GAAqC;CAC9D,OAAO,GAAQ,UAAU;AAC3B;AAEA,SAAS,EACP,GACA,GACA;CACA,OAAO,OAAO,IAAoB,GAAG,MAAmD;EACtF,IAAM,IAAW,EAAgB,CAAM,GACjC,IAAa,EAAkB,CAAM,GAMrC,EAAE,UAAO,aAAU,MAAM,EAAU;GAJvC,GAAG;GACH,QAAQ,IAAa,IAAY;GACjC,OAAO;EAEgC,CAAO;EAEhD,OADI,GAAO,UAAQ,IAAc,CAAK,GAC/B;GAAE;GAAO;EAAM;CACxB;AACF;AAEA,SAAS,EACP,GACA,GACA;CACA,OAAO,OAAO,IAAoB,IAAI,MAAkD;EACtF,IAAM,IAAW,GAAQ,SAAS,GAM5B,EAAE,UAAO,kBAAe,MAAM,EAAU;GAJ5C,GAAG;GACH,QAAQ;GACR,OAAO;EAEqC,CAAO;EAErD,OADI,GAAO,UAAQ,IAAc,CAAK,GAC/B;GAAE;GAAO;EAAW;CAC7B;AACF;AAIA,SAAS,EACP,GACA,GACA,GACA,GACA;CACA,IAAM,IAAW,EAAgB,CAAM,GACjC,IAAa,EAAkB,CAAM;CAC3C,OAAO;EAEL,UAAU,CAAC,GAAG,GAAU,CAAM;EAC9B,UAAU,EAAE,mBAAuC,EAAc,GAAW,CAAM;EAClF,kBAAkB;EAClB,mBAAmB,GAAqC,MACtD,IAAa,EAAS,SAAS,IAAW,EAAS,QAAQ,EAAS,SAAS,KAAA;EAC/E,SAAS,MAA+C,EAAE,MAAM,SAAS,MAAM,EAAE,KAAK;EACtF,QAAQ,GAAsB,MAAsB;GAClD,IAAM,IAAa,GAAO,UAAU,EAAM,UAAU,OAAQ,GAAO,SAAS,iBACtE,IAAW,OAAO,GAAS,SAAU,WAAW,EAAQ,QAAQ;GACtE,OAAO,KAAa,IAAe;EACrC;EACA,GAAI;CACN;AACF;AAEA,SAAS,EACP,GACA,GACA,GACA,GACA;CACA,IAAM,EAAE,gBAAa,GAAG,MAAiB,KAAW,CAAC;CACrD,OAAO;EACL,UAAU,MAAW,KAAA,IAAoC,IAAxB,CAAC,GAAG,GAAU,CAAM;EACrD,SAAS,YAAY;GACnB,IAAM,IAAO,MAAM,EAAY,KAAW,CAAC,CAAO;GAElD,OADA,IAAc,CAAI,GACX;EACT;EACA,SAAS,MAAY;EACrB,QAAQ,GAAsB,MAAsB;GAClD,IAAM,IAAS,GAAO,UAAU,GAAO,UAAU,QAC3C,IAAa,OAAO,KAAW,YAAY,KAAU,OAAQ,GAAO,SAAS,iBAC7E,IAAW,OAAO,GAAc,SAAU,WAAW,EAAa,QAAQ;GAChF,OAAO,KAAa,IAAe;EACrC;EACA,GAAI;CACN;AACF;AAEA,SAAS,EACP,GACA,GACA,GACA,GAC+B;CAC/B,OAAO,EAAS,EAAwB,GAAa,GAAU,GAAQ,CAAO,CAAC;AACjF;AAEA,SAAS,EACP,GACA,GACA,GACA,GACuC;CACvC,OAAO,EAAiB,EAAwB,GAAa,GAAU,GAAQ,CAAO,CAAC;AACzF;AAEA,SAAS,EACP,GACA,GACA,GACA,GACyC;CACzC,IAAM,IAAkB,KAAU,CAAC,GAC7B,EAAE,gBAAa,GAAG,MAAiB,KAAW,CAAC,GAC/C,IAAgB,QAAc,EAAwB,GAAa,CAAW,GAAG,CAAC,GAAa,CAAW,CAAC;CACjH,OAAO,EAAiB,EAA2B,GAAU,GAAe,GAAgB,CAAY,CAAC;AAC3G;AAEA,SAAS,EACP,GACA,GACA,GACA,GACiD;CACjD,IAAM,IAAkB,KAAU,CAAC,GAC7B,EAAE,gBAAa,GAAG,MAAiB,KAAW,CAAC,GAC/C,IAAgB,QAAc,EAAwB,GAAa,CAAW,GAAG,CAAC,GAAa,CAAW,CAAC;CACjH,OAAO,EAAyB,EAA2B,GAAU,GAAe,GAAgB,CAAY,CAAC;AACnH"}
|
|
1
|
+
{"version":3,"file":"hooks.js","names":[],"sources":["../../../src/utils/factory/hooks.ts"],"sourcesContent":["/**\n * Hooks 模块:分页 fetch 与统一 React Query hooks(稳定身份,可在业务 hook body 内直接调用)。\n */\nimport type {\n InfiniteData,\n QueryKey,\n UseInfiniteQueryOptions,\n UseInfiniteQueryResult,\n UseQueryOptions,\n UseQueryResult,\n UseSuspenseInfiniteQueryOptions,\n UseSuspenseInfiniteQueryResult,\n UseSuspenseQueryOptions,\n UseSuspenseQueryResult,\n} from \"@tanstack/react-query\";\nimport type { AxiosError } from \"axios\";\nimport type { ListDTOWithNextCursor, ListDTOWithTotalNumber, OffsetLimitNumber, OffsetLimitString } from \"nfx-ui/types/api\";\n\nimport { useMemo } from \"react\";\nimport { useInfiniteQuery, useQuery, useSuspenseInfiniteQuery, useSuspenseQuery } from \"@tanstack/react-query\";\n\ntype InfiniteListFilter = Partial<OffsetLimitNumber>;\n\ntype FetchNumberListParams<F extends InfiniteListFilter = InfiniteListFilter> = F & OffsetLimitNumber;\n\ntype FetchStringListParams<F extends object = Record<string, unknown>> = F & OffsetLimitString;\n\ntype MutationCtx = {\n prev?: unknown;\n};\n\ntype InfiniteQueryOptions<T> = Omit<UseInfiniteQueryOptions<ListDTOWithTotalNumber<T>, AxiosError, T[]>, \"queryKey\" | \"queryFn\" | \"getNextPageParam\" | \"initialPageParam\"> & {\n postProcess?: (data: T[]) => void;\n};\n\ntype StringInfiniteQueryOptions<T> = Omit<UseInfiniteQueryOptions<ListDTOWithNextCursor<T>, AxiosError, T[]>, \"queryKey\" | \"queryFn\" | \"getNextPageParam\" | \"initialPageParam\"> & {\n postProcess?: (data: T[]) => void;\n};\n\ntype SuspenseInfiniteQueryOptions<T> = Omit<\n UseSuspenseInfiniteQueryOptions<ListDTOWithTotalNumber<T>, AxiosError, T[]>,\n \"queryKey\" | \"queryFn\" | \"getNextPageParam\" | \"initialPageParam\"\n> & {\n postProcess?: (data: T[]) => void;\n};\n\ntype InfiniteQueryOptionsUnion<T> = InfiniteQueryOptions<T> | SuspenseInfiniteQueryOptions<T>;\n\ntype SuspenseUnifiedQueryOptions<T> = Omit<UseSuspenseQueryOptions<T, AxiosError, T>, \"queryKey\" | \"queryFn\"> & {\n postProcess?: (data: T) => void;\n};\n\ntype NormalUnifiedQueryOptions<T> = Omit<UseQueryOptions<T, AxiosError, T>, \"queryKey\" | \"queryFn\"> & {\n postProcess?: (data: T) => void;\n};\n\ntype UnifiedQueryParams<T> = {\n options?: SuspenseUnifiedQueryOptions<T>;\n postProcess?: (data: T) => void;\n} & Record<string, unknown>;\n\ntype QueryOptions<T> = NormalUnifiedQueryOptions<T>;\ntype SuspenseQueryOptions<T> = SuspenseUnifiedQueryOptions<T>;\n\nconst DEFAULT_PAGE_SIZE = 20;\n\nexport type {\n FetchNumberListParams,\n FetchStringListParams,\n InfiniteListFilter,\n InfiniteQueryOptions,\n InfiniteQueryOptionsUnion,\n MutationCtx,\n NormalUnifiedQueryOptions,\n StringInfiniteQueryOptions,\n SuspenseInfiniteQueryOptions,\n SuspenseUnifiedQueryOptions,\n UnifiedQueryParams,\n};\n\nfunction resolvePageSize(filter?: InfiniteListFilter): number {\n return filter?.limit ?? DEFAULT_PAGE_SIZE;\n}\n\nfunction resolveBaseOffset(filter?: InfiniteListFilter): number {\n return filter?.offset ?? 0;\n}\n\nfunction makeCursorFetchFunction<T, F extends InfiniteListFilter = InfiniteListFilter>(\n fetchFunc: (params: F) => Promise<ListDTOWithTotalNumber<T>>,\n postProcess?: (data: T[]) => void,\n) {\n return async (pageParam: number = 0, filter?: F): Promise<ListDTOWithTotalNumber<T>> => {\n const pageSize = resolvePageSize(filter);\n const baseOffset = resolveBaseOffset(filter);\n const payload = {\n ...filter,\n offset: baseOffset + pageParam * pageSize,\n limit: pageSize,\n } as F;\n const { items, total } = await fetchFunc(payload);\n if (items?.length) postProcess?.(items);\n return { items, total };\n };\n}\n\nfunction makeStringCursorFetchFunction<T, F extends Partial<Pick<OffsetLimitString, \"limit\">> & object = Partial<Pick<OffsetLimitString, \"limit\">>>(\n fetchFunc: (params: FetchStringListParams<F>) => Promise<ListDTOWithNextCursor<T>>,\n postProcess?: (data: T[]) => void,\n) {\n return async (pageParam: string = \"\", filter?: F): Promise<ListDTOWithNextCursor<T>> => {\n const pageSize = filter?.limit ?? DEFAULT_PAGE_SIZE;\n const payload = {\n ...filter,\n offset: pageParam,\n limit: pageSize,\n } as FetchStringListParams<F>;\n const { items, nextCursor } = await fetchFunc(payload);\n if (items?.length) postProcess?.(items);\n return { items, nextCursor };\n };\n}\n\nexport { makeCursorFetchFunction, makeStringCursorFetchFunction };\n\nfunction buildInfiniteCommonOptions<T, F extends InfiniteListFilter = InfiniteListFilter>(\n queryKey: QueryKey,\n fetchFunction: (pageParam: number, filter?: F) => Promise<ListDTOWithTotalNumber<T>>,\n filter: F,\n options: Omit<InfiniteQueryOptionsUnion<T>, \"postProcess\"> | undefined,\n) {\n const pageSize = resolvePageSize(filter);\n const baseOffset = resolveBaseOffset(filter);\n return {\n // eslint-disable-next-line @tanstack/query/exhaustive-deps\n queryKey: [...queryKey, filter],\n queryFn: ({ pageParam }: { pageParam: number }) => fetchFunction(pageParam, filter),\n initialPageParam: 0,\n getNextPageParam: (lastPage: ListDTOWithTotalNumber<T>, allPages: ListDTOWithTotalNumber<T>[]) =>\n baseOffset + allPages.length * pageSize < lastPage.total ? allPages.length : undefined,\n select: (d: InfiniteData<ListDTOWithTotalNumber<T>>) => d.pages.flatMap((p) => p.items),\n retry: (failureCount: number, error: AxiosError) => {\n const transient = (error?.status && error.status >= 500) || error?.code === \"NETWORK_ERROR\";\n const retryMax = typeof options?.retry === \"number\" ? options.retry : 3;\n return transient && failureCount < retryMax;\n },\n ...(options as Partial<ReturnType<typeof useInfiniteQuery>>),\n };\n}\n\nfunction buildQueryCommonOptions<T, F extends object = Record<string, unknown>>(\n fetchRemote: (params: F) => Promise<T>,\n queryKey: QueryKey,\n filter: F | undefined,\n options: QueryOptions<T> | SuspenseQueryOptions<T> | undefined,\n) {\n const { postProcess, ...queryOptions } = options ?? {};\n return {\n queryKey: filter !== undefined ? [...queryKey, filter] : queryKey,\n queryFn: async () => {\n const data = await fetchRemote(filter || ({} as F));\n postProcess?.(data);\n return data;\n },\n select: (data: T) => data,\n retry: (failureCount: number, error: AxiosError) => {\n const status = error?.status ?? error?.response?.status;\n const transient = (typeof status === \"number\" && status >= 500) || error?.code === \"NETWORK_ERROR\";\n const retryMax = typeof queryOptions?.retry === \"number\" ? queryOptions.retry : 3;\n return transient && failureCount < retryMax;\n },\n ...(queryOptions as object),\n };\n}\n\nfunction useUnifiedQuery<T, F extends object = Record<string, unknown>>(\n fetchRemote: (params: F) => Promise<T>,\n queryKey: QueryKey,\n filter?: F,\n options?: QueryOptions<T>,\n): UseQueryResult<T, AxiosError> {\n return useQuery(buildQueryCommonOptions(fetchRemote, queryKey, filter, options));\n}\n\nfunction useUnifiedSuspenseQuery<T, F extends object = Record<string, unknown>>(\n fetchRemote: (params: F) => Promise<T>,\n queryKey: QueryKey,\n filter?: F,\n options?: SuspenseQueryOptions<T>,\n): UseSuspenseQueryResult<T, AxiosError> {\n return useSuspenseQuery(buildQueryCommonOptions(fetchRemote, queryKey, filter, options));\n}\n\nfunction useUnifiedInfiniteQuery<T, F extends InfiniteListFilter = InfiniteListFilter>(\n fetchRemote: (params: F) => Promise<ListDTOWithTotalNumber<T>>,\n queryKey: QueryKey,\n filter?: F,\n options?: InfiniteQueryOptions<T>,\n): UseInfiniteQueryResult<T[], AxiosError> {\n const resolvedFilter = (filter ?? {}) as F;\n const { postProcess, ...queryOptions } = options ?? {};\n const fetchFunction = useMemo(() => makeCursorFetchFunction(fetchRemote, postProcess), [fetchRemote, postProcess]);\n return useInfiniteQuery(buildInfiniteCommonOptions(queryKey, fetchFunction, resolvedFilter, queryOptions));\n}\n\nfunction useUnifiedSuspenseInfiniteQuery<T, F extends InfiniteListFilter = InfiniteListFilter>(\n fetchRemote: (params: F) => Promise<ListDTOWithTotalNumber<T>>,\n queryKey: QueryKey,\n filter?: F,\n options?: SuspenseInfiniteQueryOptions<T>,\n): UseSuspenseInfiniteQueryResult<T[], AxiosError> {\n const resolvedFilter = (filter ?? {}) as F;\n const { postProcess, ...queryOptions } = options ?? {};\n const fetchFunction = useMemo(() => makeCursorFetchFunction(fetchRemote, postProcess), [fetchRemote, postProcess]);\n return useSuspenseInfiniteQuery(buildInfiniteCommonOptions(queryKey, fetchFunction, resolvedFilter, queryOptions));\n}\n\nexport { useUnifiedInfiniteQuery, useUnifiedQuery, useUnifiedSuspenseInfiniteQuery, useUnifiedSuspenseQuery };\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lstorage.d.ts","sourceRoot":"","sources":["../../src/utils/lstorage.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAS,OAAO,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"lstorage.d.ts","sourceRoot":"","sources":["../../src/utils/lstorage.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAS,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAUzD,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAI5C;AAED,wBAAgB,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAEpD;AAED,wBAAgB,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAIxD"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lstorage.js","names":[],"sources":["../../src/utils/lstorage.ts"],"sourcesContent":["/**\n * localStorage 安全封装,避免隐私模式等场景抛错。\n * Safe localStorage wrapper; avoids throwing in private mode etc.\n */\n\nimport type { Maybe, Nilable } from \"
|
|
1
|
+
{"version":3,"file":"lstorage.js","names":[],"sources":["../../src/utils/lstorage.ts"],"sourcesContent":["/**\n * localStorage 安全封装,避免隐私模式等场景抛错。\n * Safe localStorage wrapper; avoids throwing in private mode etc.\n */\n\nimport type { Maybe, Nilable } from \"nfx-ui/types/utils\";\n\nfunction safe<T>(fn: () => T): Maybe<T> {\n try {\n return fn();\n } catch {\n return undefined;\n }\n}\n\nexport function removeItem(key: string): void {\n safe(() => {\n localStorage.removeItem(key);\n });\n}\n\nexport function getItem(key: string): Nilable<string> {\n return safe(() => localStorage.getItem(key));\n}\n\nexport function setItem(key: string, value: string): void {\n safe(() => {\n localStorage.setItem(key, value);\n });\n}\n"],"mappings":";AAOA,SAAS,EAAQ,GAAuB;CACtC,IAAI;EACF,OAAO,EAAG;CACZ,QAAQ;EACN;CACF;AACF;AAEA,SAAgB,EAAW,GAAmB;CAC5C,QAAW;EACT,aAAa,WAAW,CAAG;CAC7B,CAAC;AACH;AAEA,SAAgB,EAAQ,GAA8B;CACpD,OAAO,QAAW,aAAa,QAAQ,CAAG,CAAC;AAC7C;AAEA,SAAgB,EAAQ,GAAa,GAAqB;CACxD,QAAW;EACT,aAAa,QAAQ,GAAK,CAAK;CACjC,CAAC;AACH"}
|
package/dist/utils/safe.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"safe.d.ts","sourceRoot":"","sources":["../../src/utils/safe.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"safe.d.ts","sourceRoot":"","sources":["../../src/utils/safe.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,cAAc,CAAC;AAErG;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,CAE9D;AAED;;;;;;GAMG;AACH,wBAAgB,SAAS,CAAC,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,CAExD;AAED;;;;;;GAMG;AACH,wBAAgB,WAAW,CAAC,CAAC,SAAS,MAAM,EAAE,KAAK,EAAE,SAAS,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAE7E;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,SAAS,CAAC,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC,EAAE,CAAC,EAAE,YAAY,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,CAMvG;AAED;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,CAAC,MAAM,CAAC,GAAG,QAAQ,CAAC,MAAM,CAAC,CAErE;AAED;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,CAAC,SAAS,MAAM,EAAE,KAAK,EAAE,SAAS,CAAC,CAAC,CAAC,GAAG,UAAU,CAAC,CAAC,CAAC,CAGnF;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,MAAM,CAAC,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,YAAY,EAAE,CAAC,GAAG,CAAC,CAAC;AACjE,wBAAgB,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,YAAY,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;AAKxE;;GAEG;AACH,wBAAgB,QAAQ,CAAC,CAAC,SAAS,MAAM,EAAE,KAAK,EAAE,OAAO,CAAC,MAAM,CAAC,EAAE,OAAO,EAAE,SAAS,CAAC,EAAE,EAAE,YAAY,EAAE,CAAC,GAAG,CAAC,CAE5G;AAED;;;;;;GAMG;AACH,wBAAgB,OAAO,CAAC,KAAK,EAAE,OAAO,CAAC,MAAM,CAAC,GAAG,KAAK,CAAC,MAAM,CAAC,CAI7D"}
|
package/dist/utils/safe.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"safe.js","names":[],"sources":["../../src/utils/safe.ts"],"sourcesContent":["/**\n * Safe 工具:将 Nilable / Emptyable / Array 等规范为 Nullable、Maybe、Zeroable、Stringable、Array,避免到处写 ?? undefined / ?? null / ?? 0 / ?? \"\" / ?? []。\n * Safe utils: normalize Nilable/Emptyable/array to Nullable, Maybe, Zeroable, Stringable, Array.\n */\n\nimport type { Nullable, Maybe, Nilable, Emptyable, Zeroable, Stringable, Array } from \"
|
|
1
|
+
{"version":3,"file":"safe.js","names":[],"sources":["../../src/utils/safe.ts"],"sourcesContent":["/**\n * Safe 工具:将 Nilable / Emptyable / Array 等规范为 Nullable、Maybe、Zeroable、Stringable、Array,避免到处写 ?? undefined / ?? null / ?? 0 / ?? \"\" / ?? []。\n * Safe utils: normalize Nilable/Emptyable/array to Nullable, Maybe, Zeroable, Stringable, Array.\n */\n\nimport type { Nullable, Maybe, Nilable, Emptyable, Zeroable, Stringable, Array } from \"nfx-ui/types\";\n\n/**\n * 将 Nilable 规范为 Nullable:undefined 转为 null,null 与 T 原样返回。返回类型 Nullable<T>。\n * Normalize Nilable to Nullable: convert undefined to null; null and T unchanged. Returns Nullable<T>.\n * @param value - 可能为 null 或 undefined 的值 (value that may be null or undefined)\n * @returns 若为 undefined 则 null,否则原值 (null if undefined, otherwise value)\n * @example safeNullable(apiResponse.data) // undefined → null,便于区分「未设置」与「空」\n */\nexport function safeNullable<T>(value: Nilable<T>): Nullable<T> {\n return (value === undefined ? null : value) as Nullable<T>;\n}\n\n/**\n * 将 Nilable 规范为 Maybe:null 转为 undefined,undefined 与 T 原样返回。返回类型 Maybe<T>。等同 value ?? undefined。\n * Normalize Nilable to Maybe: convert null to undefined; undefined and T unchanged. Returns Maybe<T>. Same as value ?? undefined.\n * @param value - 可能为 null 或 undefined 的值 (value that may be null or undefined)\n * @returns 若为 null 或 undefined 则 undefined,否则原值 (undefined if null/undefined, otherwise value)\n * @example safeMaybe(product.price) // 代替 product.price ?? undefined\n */\nexport function safeMaybe<T>(value: Nilable<T>): Maybe<T> {\n return value ?? undefined;\n}\n\n/**\n * 将 Emptyable 字符串规范为 Nilable:空字符串转为 undefined,null/undefined/非空串原样。返回类型 Nilable<T>。常用于表单、接口字段。\n * Normalize Emptyable string to Nilable: \"\" to undefined; null, undefined, non-empty string unchanged. Returns Nilable<T>. For form/API fields.\n * @param value - 可能为 null、undefined 或空字符串 (value that may be null, undefined or \"\")\n * @returns 若为 \"\" 则 undefined,否则原值 (undefined if \"\", otherwise value)\n * @example safeNilable(product.remark) // \"\" 也视为「无值」\n */\nexport function safeNilable<T extends string>(value: Emptyable<T>): Nilable<T> {\n return (value === \"\" ? undefined : value) as Nilable<T>;\n}\n\n/**\n * 将 Nilable 数组规范为数组:null/undefined 转为 [] 或 defaultValue。返回类型 Array<T>(即 T[])。\n * Normalize Nilable array to array: null/undefined to [] or defaultValue. Returns Array<T> (i.e. T[]).\n * @param value - 可能为 null 或 undefined 的数组 (array that may be null or undefined)\n * @param defaultValue - 可选,当 value 为 null/undefined 时使用;缺省为 [] (optional default when value is null/undefined; default is [])\n * @returns value ?? defaultValue ?? [] (never null/undefined)\n * @example safeArray(product.tags) // product.tags ?? []\n * @example safeArray(product.tags, ['default'])\n *\n * 参数使用 `Array<T>`(即 `T[]`,见 `@/types`)与全库类型别名一致;入参也接受 `readonly T[]`,便于兼容只读数组来源。\n */\nexport function safeArray<T>(value: Nilable<Array<T> | readonly T[]>, defaultValue?: Array<T>): Array<T> {\n const resolved = value ?? defaultValue;\n if (resolved === undefined) {\n return [] as Array<T>;\n }\n return resolved as Array<T>;\n}\n\n/**\n * 将 Nilable 数值规范为 Zeroable:null/undefined 转为 0。返回类型 Zeroable<number>(即 number,0 为兜底)。\n * Normalize Nilable number to Zeroable: null/undefined to 0. Returns Zeroable<number> (number with 0 as fallback).\n * @param value - 可能为 null 或 undefined 的数值 (number that may be null or undefined)\n * @returns value ?? 0 (never null/undefined)\n * @example safeZeroable(product.stock) // 代替 product.stock ?? 0\n */\nexport function safeZeroable(value: Nilable<number>): Zeroable<number> {\n return (value ?? 0) as Zeroable<number>;\n}\n\n/**\n * 将 Emptyable 字符串规范为 Stringable:null/undefined/\"\" 转为 \"\"。返回类型 Stringable<string>(即 string,\"\" 为兜底)。\n * Normalize Emptyable string to Stringable: null/undefined/\"\" to \"\". Returns Stringable<string> (string with \"\" as fallback).\n * @param value - 可能为 null、undefined 或空字符串 (value that may be null, undefined or \"\")\n * @returns 若为 null、undefined 或 \"\" 则 \"\",否则原值 (\"\" if null/undefined/\"\", otherwise value)\n * @example safeStringable(product.name) // 代替 product.name ?? \"\"\n */\nexport function safeStringable<T extends string>(value: Emptyable<T>): Stringable<T> {\n if (value === null || value === undefined || value === \"\") return \"\" as Stringable<T>;\n return value as Stringable<T>;\n}\n\n/**\n * 若值为 null/undefined 则返回默认值,否则返回原值。等同 value ?? defaultValue。\n * Return defaultValue when value is null/undefined, otherwise value. Same as value ?? defaultValue.\n * @param value - 可能为 null 或 undefined 的值 (value that may be null or undefined)\n * @param defaultValue - 默认值 (default value)\n * @returns value ?? defaultValue\n * @example safeOr(product.stock, 0)\n * @example safeOr(product.name, '')\n *\n * 使用两个类型参数时,若第一个实参无法收窄(例如索引访问、宽泛的 Record),`T` 可能被推断为 `unknown`,结果变成 `unknown`。\n * 因此提供**单类型**重载:当 `defaultValue` 与「有值时」的类型一致时,应写 `safeOr(x, fallback)` 且两者同型,返回即为 `T`。\n */\nexport function safeOr<T>(value: Nilable<T>, defaultValue: T): T;\nexport function safeOr<T, D>(value: Nilable<T>, defaultValue: D): T | D;\nexport function safeOr<T, D>(value: Nilable<T>, defaultValue: D): T | D {\n return value ?? defaultValue;\n}\n\n/**\n * 将字符串规范为允许的枚举成员;非法或缺省时回落 defaultValue。\n */\nexport function safeEnum<T extends string>(value: Nilable<string>, allowed: readonly T[], defaultValue: T): T {\n return typeof value === \"string\" && allowed.includes(value as T) ? (value as T) : defaultValue;\n}\n\n/**\n * 安全取数字:null/undefined/NaN 转为 undefined,合法数字原样。返回类型 Maybe<number>。\n * Safe number: null/undefined/NaN to undefined; valid number unchanged. Returns Maybe<number>.\n * @param value - 可能为 null、undefined 或非数字 (value that may be null, undefined or NaN)\n * @returns 若为 null、undefined 或 NaN 则 undefined,否则数字 (undefined if null/undefined/NaN, otherwise number)\n * @example safeNum(product.price) // 用于严格「有值才用」的场景\n */\nexport function safeNum(value: Nilable<number>): Maybe<number> {\n if (value === null || value === undefined) return undefined;\n const n = Number(value);\n return Number.isNaN(n) ? undefined : n;\n}\n"],"mappings":";AAcA,SAAgB,EAAgB,GAAgC;CAC9D,OAAQ,MAAU,KAAA,IAAY,OAAO;AACvC;AASA,SAAgB,EAAa,GAA6B;CACxD,OAAO,KAAS,KAAA;AAClB;AASA,SAAgB,EAA8B,GAAiC;CAC7E,OAAQ,MAAU,KAAK,KAAA,IAAY;AACrC;AAaA,SAAgB,EAAa,GAAyC,GAAmC;CACvG,IAAM,IAAW,KAAS;CAI1B,OAHI,MAAa,KAAA,IACR,CAAC,IAEH;AACT;AASA,SAAgB,EAAa,GAA0C;CACrE,OAAQ,KAAS;AACnB;AASA,SAAgB,EAAiC,GAAoC;CAEnF,OADI,KAAU,QAA+B,MAAU,KAAW,KAC3D;AACT;AAgBA,SAAgB,EAAa,GAAmB,GAAwB;CACtE,OAAO,KAAS;AAClB;AAKA,SAAgB,EAA2B,GAAwB,GAAuB,GAAoB;CAC5G,OAAO,OAAO,KAAU,YAAY,EAAQ,SAAS,CAAU,IAAK,IAAc;AACpF;AASA,SAAgB,EAAQ,GAAuC;CAC7D,IAAI,KAAU,MAA6B;CAC3C,IAAM,IAAI,OAAO,CAAK;CACtB,OAAO,OAAO,MAAM,CAAC,IAAI,KAAA,IAAY;AACvC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"suspense.d.ts","sourceRoot":"","sources":["../../src/utils/suspense.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"suspense.d.ts","sourceRoot":"","sources":["../../src/utils/suspense.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAE5C;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAAC,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,KAAK,SAAM,GAAG,CAAC,CAKnE"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"suspense.js","names":[],"sources":["../../src/utils/suspense.ts"],"sourcesContent":["import type { Nilable } from \"
|
|
1
|
+
{"version":3,"file":"suspense.js","names":[],"sources":["../../src/utils/suspense.ts"],"sourcesContent":["import type { Nilable } from \"nfx-ui/types\";\n\n/**\n * 若值为 null/undefined 则抛出 Promise 使 React Suspense 挂起,否则返回该值。\n * If value is null/undefined, throw a promise to suspend (React Suspense); otherwise return value.\n * @param value - 待检查的值。Value to check.\n * @param delay - 重试前的延迟(毫秒)。Delay in ms before retry.\n * @returns 非空时的 value。Value when non-null.\n * @example const data = suspenseIfNull(resource); // 在 Suspense 边界内,data 非空时才渲染\n */\nexport function suspenseIfNull<T>(value: Nilable<T>, delay = 100): T {\n if (value == null) {\n throw new Promise<void>((resolve) => setTimeout(resolve, delay));\n }\n return value;\n}\n"],"mappings":";AAUA,SAAgB,EAAkB,GAAmB,IAAQ,KAAQ;CACnE,IAAI,KAAS,MACX,MAAM,IAAI,SAAe,MAAY,WAAW,GAAS,CAAK,CAAC;CAEjE,OAAO;AACT"}
|
package/package.json
CHANGED
package/src/apis/authRefresh.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { AxiosError } from "axios";
|
|
2
|
-
import { AuthStore, clearAuth, isRejectedRefreshToken, markRejectedRefreshToken, setTokens } from "
|
|
3
|
-
import { ensureDeviceIdStorage } from "
|
|
4
|
-
import { getApiError } from "
|
|
5
|
-
import { getJwtExpiresAtMs, getJwtIssuedAtMs } from "
|
|
2
|
+
import { AuthStore, clearAuth, isRejectedRefreshToken, markRejectedRefreshToken, setTokens } from "nfx-ui/stores/auth";
|
|
3
|
+
import { ensureDeviceIdStorage } from "nfx-ui/stores/system";
|
|
4
|
+
import { getApiError } from "nfx-ui/utils/apiError";
|
|
5
|
+
import { getJwtExpiresAtMs, getJwtIssuedAtMs } from "nfx-ui/utils/jwt";
|
|
6
6
|
|
|
7
7
|
import { getIdentityRepositories } from "./activeIdentityRepositories";
|
|
8
8
|
|
package/src/apis/clients.ts
CHANGED
|
@@ -3,14 +3,14 @@
|
|
|
3
3
|
* publicClient: login / refresh. protectedClient: Bearer + 401 → refreshAuthTokens.
|
|
4
4
|
*/
|
|
5
5
|
import type { InternalAxiosRequestConfig } from "axios";
|
|
6
|
-
import type { ApiErrorBody } from "
|
|
6
|
+
import type { ApiErrorBody } from "nfx-ui/types";
|
|
7
7
|
|
|
8
8
|
import axios, { AxiosError } from "axios";
|
|
9
9
|
import applyCaseMiddleware from "axios-case-converter";
|
|
10
|
-
import { authEventEmitter, authEvents } from "
|
|
11
|
-
import { AuthStore, clearAuth, hasSelectedProfile } from "
|
|
12
|
-
import { shouldForceLogoutAfterAuthRetry, shouldImmediateForceLogoutOnApiError } from "
|
|
13
|
-
import { safeOr } from "
|
|
10
|
+
import { authEventEmitter, authEvents } from "nfx-ui/events/auth";
|
|
11
|
+
import { AuthStore, clearAuth, hasSelectedProfile } from "nfx-ui/stores/auth";
|
|
12
|
+
import { shouldForceLogoutAfterAuthRetry, shouldImmediateForceLogoutOnApiError } from "nfx-ui/utils/sessionErrors";
|
|
13
|
+
import { safeOr } from "nfx-ui/utils/safe";
|
|
14
14
|
|
|
15
15
|
import { refreshAuthTokens } from "./authRefresh";
|
|
16
16
|
import { API_ENDPOINTS } from "./ip";
|
package/src/apis/ip.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import type { DataResponse, FullAccountInfoByKind, ListDTOWithTotalNumber, Login, Profile, ProfileItemsByKind, Signup, Tokens } from "
|
|
1
|
+
import type { DataResponse, FullAccountInfoByKind, ListDTOWithTotalNumber, Login, Profile, ProfileItemsByKind, Signup, Tokens } from "nfx-ui/types";
|
|
2
2
|
|
|
3
|
-
import { ProfileKindEnum } from "
|
|
3
|
+
import { ProfileKindEnum } from "nfx-ui/enums";
|
|
4
4
|
|
|
5
5
|
import { protectedClient, publicClient, publicClientWithoutTransform } from "../clients";
|
|
6
6
|
import { dataFromResponse, URL_PATHS } from "../ip";
|
package/src/config/env.ts
CHANGED
package/src/constants/key.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { QueryKey } from "@tanstack/react-query";
|
|
2
2
|
|
|
3
|
-
import { ProfileKindEnum } from "
|
|
3
|
+
import { ProfileKindEnum } from "nfx-ui/enums";
|
|
4
4
|
|
|
5
5
|
const DOMAIN_AUTH = "auth";
|
|
6
6
|
|
|
@@ -13,3 +13,7 @@ export const AUTH_ME = (aID: string, pID: string): QueryKey => [aID, pID, DOMAIN
|
|
|
13
13
|
export const AUTH_PROFILES = (aID: string, kind: ProfileKindEnum): QueryKey => [aID, DOMAIN_AUTH, kind, "list", "profiles"];
|
|
14
14
|
export const AUTH_EMAILS = (aID: string): QueryKey => [aID, DOMAIN_AUTH, "list", "emails"];
|
|
15
15
|
export const AUTH_PHONES = (aID: string): QueryKey => [aID, DOMAIN_AUTH, "list", "phones"];
|
|
16
|
+
export const AUTH_OWNER_FORGERS = (aID: string): QueryKey => [aID, DOMAIN_AUTH, "list", "owner-forgers"];
|
|
17
|
+
export const AUTH_OWNER_AUTHORITIES = (aID: string): QueryKey => [aID, DOMAIN_AUTH, "list", "owner-authorities"];
|
|
18
|
+
export const AUTH_PUBLIC_CARD = (profileId: string): QueryKey => [DOMAIN_AUTH, "item", "public-card", profileId];
|
|
19
|
+
export const AUTH_PROFILE_SEARCH = (aID: string, kind: ProfileKindEnum, query: string): QueryKey => [aID, DOMAIN_AUTH, kind, "list", "profile-search", query];
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
*
|
|
5
5
|
* @example
|
|
6
6
|
* ```ts
|
|
7
|
-
* import { createListKey, createItemKey } from "
|
|
7
|
+
* import { createListKey, createItemKey } from "nfx-ui/constants";
|
|
8
8
|
*
|
|
9
9
|
* const CATALOG_CATEGORY_LIST = createListKey("catalog", "category");
|
|
10
10
|
* const CATALOG_CATEGORY = createItemKey("catalog", "category");
|
package/src/enums/auth.ts
CHANGED
|
@@ -4,9 +4,9 @@
|
|
|
4
4
|
* 角色不在 JWT;能力门控按纯成员判定(hasRole / hasAnyRole)。
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
import type { Nilable } from "
|
|
7
|
+
import type { Nilable } from "nfx-ui/types";
|
|
8
8
|
|
|
9
|
-
import { safeArray, safeEnum } from "
|
|
9
|
+
import { safeArray, safeEnum } from "nfx-ui/utils/safe";
|
|
10
10
|
|
|
11
11
|
export function hasRole<T>(role: T, roles: Nilable<readonly T[]>): boolean {
|
|
12
12
|
return safeArray(roles).includes(role);
|
package/src/enums/dashboard.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import type { Array, Nilable } from "
|
|
1
|
+
import type { Array, Nilable } from "nfx-ui/types";
|
|
2
2
|
|
|
3
|
-
import { safeEnum } from "
|
|
3
|
+
import { safeEnum } from "nfx-ui/utils/safe";
|
|
4
4
|
|
|
5
5
|
/** 仪表盘背景。Dashboard background. */
|
|
6
6
|
export enum DashboardBackgroundEnum {
|
package/src/enums/language.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* 语言枚举与常量,不引用任何 JSON,供需要轻量引用的模块使用。
|
|
3
3
|
*/
|
|
4
|
-
import type { Nilable } from "
|
|
4
|
+
import type { Nilable } from "nfx-ui/types";
|
|
5
5
|
|
|
6
|
-
import { safeEnum } from "
|
|
6
|
+
import { safeEnum } from "nfx-ui/utils/safe";
|
|
7
7
|
|
|
8
8
|
export enum LanguageEnum {
|
|
9
9
|
EN = "en",
|
package/src/enums/layout.ts
CHANGED
package/src/enums/theme.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { safeEnum } from "
|
|
1
|
+
import { safeEnum } from "nfx-ui/utils/safe";
|
|
2
2
|
|
|
3
|
-
import type { Nilable } from "
|
|
3
|
+
import type { Nilable } from "nfx-ui/types";
|
|
4
4
|
|
|
5
5
|
/** 基础主题枚举(平台/圆角等,如 iOS 24 / Android|Windows 6 / Linux 4) */
|
|
6
6
|
export enum BaseEnum {
|
package/src/events/auth.ts
CHANGED
|
@@ -1,15 +1,17 @@
|
|
|
1
|
-
import type { ProfileKindEnum } from "
|
|
2
|
-
import type { EventNamesOf } from "
|
|
1
|
+
import type { ProfileKindEnum } from "nfx-ui/enums";
|
|
2
|
+
import type { EventNamesOf } from "nfx-ui/events/EventEmitter";
|
|
3
3
|
|
|
4
|
-
import { defineEvents, EventEmitter } from "
|
|
5
|
-
import { singleton } from "
|
|
4
|
+
import { defineEvents, EventEmitter } from "nfx-ui/events/EventEmitter";
|
|
5
|
+
import { singleton } from "nfx-ui/utils/singleton";
|
|
6
6
|
|
|
7
7
|
export const authEvents = defineEvents({
|
|
8
8
|
UPDATE_ACCOUNT_SUCCESS: "AUTH:UPDATE_ACCOUNT_SUCCESS",
|
|
9
9
|
LOGIN_SUCCESS: "AUTH:LOGIN_SUCCESS",
|
|
10
10
|
LOGOUT: "AUTH:LOGOUT",
|
|
11
11
|
INVALIDATE_EMAILS: "AUTH:INVALIDATE_EMAILS",
|
|
12
|
+
INVALIDATE_PHONES: "AUTH:INVALIDATE_PHONES",
|
|
12
13
|
INVALIDATE_PROFILES: "AUTH:INVALIDATE_PROFILES",
|
|
14
|
+
INVALIDATE_OWNER: "AUTH:INVALIDATE_OWNER",
|
|
13
15
|
});
|
|
14
16
|
|
|
15
17
|
type AuthEvent = EventNamesOf<typeof authEvents>;
|
|
@@ -28,10 +30,18 @@ class AuthEventEmitter extends EventEmitter<AuthEvent> {
|
|
|
28
30
|
this.emit(authEvents.INVALIDATE_EMAILS, aID);
|
|
29
31
|
}
|
|
30
32
|
|
|
33
|
+
invalidatePhones(aID?: string) {
|
|
34
|
+
this.emit(authEvents.INVALIDATE_PHONES, aID);
|
|
35
|
+
}
|
|
36
|
+
|
|
31
37
|
invalidateProfiles(payload: InvalidateProfilesPayload) {
|
|
32
38
|
this.emit(authEvents.INVALIDATE_PROFILES, payload);
|
|
33
39
|
}
|
|
34
40
|
|
|
41
|
+
invalidateOwner(aID?: string) {
|
|
42
|
+
this.emit(authEvents.INVALIDATE_OWNER, aID);
|
|
43
|
+
}
|
|
44
|
+
|
|
35
45
|
logout() {
|
|
36
46
|
this.emit(authEvents.LOGOUT);
|
|
37
47
|
}
|
package/src/events/query.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import type { EventNamesOf } from "
|
|
1
|
+
import type { EventNamesOf } from "nfx-ui/events/EventEmitter";
|
|
2
2
|
|
|
3
|
-
import { defineEvents, EventEmitter } from "
|
|
4
|
-
import { singleton } from "
|
|
3
|
+
import { defineEvents, EventEmitter } from "nfx-ui/events/EventEmitter";
|
|
4
|
+
import { singleton } from "nfx-ui/utils/singleton";
|
|
5
5
|
|
|
6
6
|
export const queryEvents = defineEvents({
|
|
7
7
|
RESET_ACTIVE_QUERIES: "QUERY:RESET_ACTIVE_QUERIES",
|
package/src/events/system.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import type { EventNamesOf } from "
|
|
1
|
+
import type { EventNamesOf } from "nfx-ui/events/EventEmitter";
|
|
2
2
|
|
|
3
|
-
import { defineEvents, EventEmitter } from "
|
|
4
|
-
import { singleton } from "
|
|
3
|
+
import { defineEvents, EventEmitter } from "nfx-ui/events/EventEmitter";
|
|
4
|
+
import { singleton } from "nfx-ui/utils/singleton";
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* Host-agnostic UI feedback. Package emits; WEB ModalProvider listens.
|
package/src/hooks/asset.ts
CHANGED
|
@@ -2,20 +2,25 @@
|
|
|
2
2
|
* Asset upload hooks — 组件勿直接调 apis/asset
|
|
3
3
|
*/
|
|
4
4
|
import type { AxiosError } from "axios";
|
|
5
|
-
import type { Asset } from "
|
|
5
|
+
import type { Asset } from "nfx-ui/types";
|
|
6
6
|
|
|
7
7
|
import { useMutation } from "@tanstack/react-query";
|
|
8
|
-
import { useAssetRepository } from "
|
|
9
|
-
import { authEventEmitter, authEvents } from "
|
|
10
|
-
import { systemEventEmitter } from "
|
|
11
|
-
import { AuthStore } from "
|
|
12
|
-
import { getApiErrorMessage } from "
|
|
13
|
-
import { useUnifiedQuery } from "
|
|
8
|
+
import { useAssetRepository } from "nfx-ui/apis/repositories";
|
|
9
|
+
import { authEventEmitter, authEvents } from "nfx-ui/events/auth";
|
|
10
|
+
import { systemEventEmitter } from "nfx-ui/events/system";
|
|
11
|
+
import { AuthStore } from "nfx-ui/stores/auth";
|
|
12
|
+
import { getApiErrorMessage } from "nfx-ui/utils/apiError";
|
|
13
|
+
import { useUnifiedQuery } from "nfx-ui/utils/factory";
|
|
14
14
|
|
|
15
15
|
export type UseDeleteImageOptions = {
|
|
16
16
|
ifShowError?: boolean;
|
|
17
17
|
};
|
|
18
18
|
|
|
19
|
+
export const useAssetFileURL = () => {
|
|
20
|
+
const asset = useAssetRepository();
|
|
21
|
+
return (kind: Asset.Kind, id: string) => asset.FileURL(kind, id);
|
|
22
|
+
};
|
|
23
|
+
|
|
19
24
|
export const usePrepareUpload = () => {
|
|
20
25
|
const asset = useAssetRepository();
|
|
21
26
|
return useMutation({
|