@navios/react-query 0.1.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.
@@ -0,0 +1,61 @@
1
+ import type { AnyEndpointConfig, UrlHasParams, UrlParams } from '@navios/common'
2
+ import type { DataTag } from '@tanstack/react-query'
3
+
4
+ import type { BaseQueryParams } from '../types.mjs'
5
+
6
+ import { queryKeyCreator } from './query-key-creator.mjs'
7
+
8
+ /**
9
+ * Creates a mutation key for a given endpoint configuration and options.
10
+ *
11
+ * @param {config: Config } config - The endpoint object containing the configuration.
12
+ * @param {Options} [options] - Optional query parameters with a default `processResponse` function that processes the response data.
13
+ *
14
+ * @returns {Object} An object containing the `mutationKey` function.
15
+ *
16
+ * The `mutationKey` function generates a mutation key based on the provided parameters:
17
+ * - If the URL has parameters (`HasParams` is `true`), it expects an object with `urlParams`.
18
+ * - The return type of the `mutationKey` function depends on the `processResponse` function in `options`.
19
+ * If `processResponse` is defined, the return type is a `DataTag` containing the processed result and an error type.
20
+ *
21
+ * @example Example usage:
22
+ * ```typescript
23
+ * const createMutationKey = mutationKeyCreator(endpoint.config);
24
+ * const mutationKey = createMutationKey({ urlParams: { id: 123 } });
25
+ * ```
26
+ *
27
+ * @example Advanced usage:
28
+ * ```ts
29
+ * const createMutationKey = mutationKeyCreator(endpoint.config, {
30
+ * processResponse: (data) => {
31
+ * if (!data.success) {
32
+ * throw new Error(data.message);
33
+ * }
34
+ * return data.data;
35
+ * },
36
+ * });
37
+ * // We create a mutation that will be shared across the project for all passed userId
38
+ * const mutationKey = createMutationKey({ urlParams: { projectId: 123, userId: 'wildcard' } });
39
+ */
40
+ export function mutationKeyCreator<
41
+ Config extends AnyEndpointConfig,
42
+ Options extends BaseQueryParams<Config>,
43
+ Url extends Config['url'] = Config['url'],
44
+ HasParams extends UrlHasParams<Url> = UrlHasParams<Url>,
45
+ >(
46
+ config: Config,
47
+ options: Options = {
48
+ processResponse: (data) => data,
49
+ } as Options,
50
+ ): (
51
+ params: HasParams extends true ? { urlParams: UrlParams<Url> } : {},
52
+ ) => Options['processResponse'] extends (...args: any[]) => infer Result
53
+ ? DataTag<[Config['url']], Result, Error>
54
+ : never {
55
+ const queryKey = queryKeyCreator(config, options, false)
56
+
57
+ // @ts-expect-error We have correct types in return type
58
+ return (params) => {
59
+ return queryKey.filterKey(params)
60
+ }
61
+ }
@@ -0,0 +1,125 @@
1
+ import type { AnyEndpointConfig, UrlHasParams, UrlParams } from '@navios/common'
2
+ import type { DataTag, InfiniteData } from '@tanstack/react-query'
3
+ import type { AnyZodObject, z } from 'zod'
4
+
5
+ import { bindUrlParams } from '@navios/common'
6
+
7
+ import type { BaseQueryParams } from '../types.mjs'
8
+
9
+ type Split<S extends string, D extends string> = string extends S
10
+ ? string[]
11
+ : S extends ''
12
+ ? []
13
+ : S extends `${infer T}${D}${infer U}`
14
+ ? [T, ...Split<U, D>]
15
+ : [S]
16
+
17
+ export type QueryKeyCreatorResult<
18
+ QuerySchema = undefined,
19
+ Url extends string = string,
20
+ Result = unknown,
21
+ IsInfinite extends boolean = false,
22
+ HasParams extends UrlHasParams<Url> = UrlHasParams<Url>,
23
+ > = {
24
+ template: Split<Url, '/'>
25
+ dataTag: (
26
+ params: (HasParams extends true ? { urlParams: UrlParams<Url> } : {}) &
27
+ (QuerySchema extends AnyZodObject
28
+ ? { params: z.input<QuerySchema> }
29
+ : {}),
30
+ ) => DataTag<
31
+ Split<Url, '/'>,
32
+ IsInfinite extends true ? InfiniteData<Result> : Result,
33
+ Error
34
+ >
35
+ filterKey: (
36
+ params: HasParams extends true ? { urlParams: UrlParams<Url> } : {},
37
+ ) => DataTag<
38
+ Split<Url, '/'>,
39
+ IsInfinite extends true ? InfiniteData<Result> : Result,
40
+ Error
41
+ >
42
+ bindToUrl: (
43
+ params: (HasParams extends true ? { urlParams: UrlParams<Url> } : {}) &
44
+ (QuerySchema extends AnyZodObject
45
+ ? { params: z.infer<QuerySchema> }
46
+ : {}),
47
+ ) => string
48
+ }
49
+
50
+ export function queryKeyCreator<
51
+ Config extends AnyEndpointConfig,
52
+ Options extends BaseQueryParams<Config>,
53
+ IsInfinite extends boolean,
54
+ Url extends Config['url'] = Config['url'],
55
+ HasParams extends UrlHasParams<Url> = UrlHasParams<Url>,
56
+ >(
57
+ config: Config,
58
+ options: Options,
59
+ isInfinite: IsInfinite,
60
+ ): QueryKeyCreatorResult<
61
+ Config['querySchema'],
62
+ Url,
63
+ Options['processResponse'] extends (...args: any[]) => infer Result
64
+ ? Result
65
+ : never,
66
+ IsInfinite,
67
+ HasParams
68
+ > {
69
+ const url = config.url as Url
70
+ const urlParts = url.split('/').filter(Boolean) as Split<Url, '/'>
71
+ return {
72
+ template: urlParts,
73
+ // @ts-expect-error We have correct types in return type
74
+ dataTag: (params) => {
75
+ const queryParams =
76
+ params && 'querySchema' in config && 'params' in params
77
+ ? config.querySchema?.parse(params.params)
78
+ : []
79
+ return [
80
+ ...(options.keyPrefix ?? []),
81
+ ...urlParts.map((part) =>
82
+ part.startsWith('$')
83
+ ? // @ts-expect-error TS2339 We know that the urlParams are defined only if the url has params
84
+ params.urlParams[part.slice(1)].toString()
85
+ : part,
86
+ ),
87
+ ...(options.keySuffix ?? []),
88
+ queryParams ?? [],
89
+ ] as unknown as DataTag<
90
+ Split<Url, '/'>,
91
+ Options['processResponse'] extends (...args: any[]) => infer Result
92
+ ? IsInfinite extends true
93
+ ? InfiniteData<Result>
94
+ : Result
95
+ : never,
96
+ Error
97
+ >
98
+ },
99
+ // @ts-expect-error We have correct types in return type
100
+ filterKey: (params) => {
101
+ return [
102
+ ...(options.keyPrefix ?? []),
103
+ ...urlParts.map((part) =>
104
+ part.startsWith('$')
105
+ ? // @ts-expect-error TS2339 We know that the urlParams are defined only if the url has params
106
+ params.urlParams[part.slice(1)].toString()
107
+ : part,
108
+ ),
109
+ ...(options.keySuffix ?? []),
110
+ ] as unknown as DataTag<
111
+ Split<Url, '/'>,
112
+ Options['processResponse'] extends (...args: any[]) => infer Result
113
+ ? IsInfinite extends true
114
+ ? InfiniteData<Result>
115
+ : Result
116
+ : never,
117
+ Error
118
+ >
119
+ },
120
+
121
+ bindToUrl: (params) => {
122
+ return bindUrlParams<Url>(url, params ?? ({} as any))
123
+ },
124
+ }
125
+ }