@stack-spot/portal-network 0.184.0 → 0.185.0-beta.1

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.
Files changed (142) hide show
  1. package/CHANGELOG.md +2444 -2412
  2. package/dist/api/account.js +1 -1
  3. package/dist/api/agent-tools.js +1 -1
  4. package/dist/api/agent.js +1 -1
  5. package/dist/api/ai.js +1 -1
  6. package/dist/api/apiManagement.js +1 -1
  7. package/dist/api/apiRuntime.js +1 -1
  8. package/dist/api/cloudAccount.js +1 -1
  9. package/dist/api/cloudPlatform.js +1 -1
  10. package/dist/api/cloudPlatformHorizon.js +1 -1
  11. package/dist/api/cloudRuntimes.js +1 -1
  12. package/dist/api/cloudServices.js +1 -1
  13. package/dist/api/codeShift.d.ts +63 -4
  14. package/dist/api/codeShift.d.ts.map +1 -1
  15. package/dist/api/codeShift.js +14 -1
  16. package/dist/api/codeShift.js.map +1 -1
  17. package/dist/api/content.js +1 -1
  18. package/dist/api/dataIntegration.js +1 -1
  19. package/dist/api/discover.js +1 -1
  20. package/dist/api/genAiInference.js +1 -1
  21. package/dist/api/insights.js +1 -1
  22. package/dist/api/notification.js +1 -1
  23. package/dist/api/secrets.js +1 -1
  24. package/dist/api/serviceCatalog.js +1 -1
  25. package/dist/api/workspace-ai.js +1 -1
  26. package/dist/api/workspace.js +1 -1
  27. package/dist/api/workspaceManager.js +1 -1
  28. package/dist/api/workspaceSearchEngine.js +1 -1
  29. package/dist/client/ai.d.ts.map +1 -1
  30. package/dist/client/ai.js +84 -14
  31. package/dist/client/ai.js.map +1 -1
  32. package/dist/client/code-shift.d.ts +30 -0
  33. package/dist/client/code-shift.d.ts.map +1 -1
  34. package/dist/client/code-shift.js +37 -1
  35. package/dist/client/code-shift.js.map +1 -1
  36. package/dist/client/types.d.ts +26 -6
  37. package/dist/client/types.d.ts.map +1 -1
  38. package/package.json +7 -7
  39. package/readme.md +1 -1
  40. package/scripts/generate-apis.ts +134 -134
  41. package/src/api/account.ts +8368 -8367
  42. package/src/api/agent-tools.ts +2172 -2169
  43. package/src/api/agent.ts +1085 -1083
  44. package/src/api/ai.ts +3388 -3388
  45. package/src/api/apiManagement.ts +570 -570
  46. package/src/api/apiRuntime.ts +2103 -2103
  47. package/src/api/cloudAccount.ts +1239 -1239
  48. package/src/api/cloudPlatform.ts +927 -927
  49. package/src/api/cloudPlatformHorizon.ts +2655 -2655
  50. package/src/api/cloudRuntimes.ts +2043 -2043
  51. package/src/api/cloudServices.ts +1445 -1445
  52. package/src/api/codeShift.ts +3567 -3481
  53. package/src/api/content.ts +9785 -9785
  54. package/src/api/dataIntegration.ts +1657 -1657
  55. package/src/api/discover.ts +435 -435
  56. package/src/api/eventBus.ts +171 -171
  57. package/src/api/genAiInference.ts +603 -603
  58. package/src/api/insights.ts +310 -310
  59. package/src/api/notification.ts +336 -334
  60. package/src/api/secrets.ts +342 -342
  61. package/src/api/serviceCatalog.ts +2908 -2908
  62. package/src/api/workflows.ts +1669 -1669
  63. package/src/api/workspace-ai.ts +677 -677
  64. package/src/api/workspace.ts +5889 -5889
  65. package/src/api/workspaceManager.ts +2951 -2951
  66. package/src/api/workspaceSearchEngine.ts +153 -153
  67. package/src/api-addresses.ts +120 -120
  68. package/src/apis-itau.json +225 -225
  69. package/src/apis.json +225 -225
  70. package/src/client/account.ts +902 -902
  71. package/src/client/agent-tools.ts +210 -210
  72. package/src/client/agent.ts +81 -81
  73. package/src/client/ai.ts +469 -395
  74. package/src/client/api-management.ts +40 -40
  75. package/src/client/cloud-account.ts +70 -70
  76. package/src/client/cloud-platform-horizon.ts +113 -113
  77. package/src/client/cloud-platform.ts +163 -163
  78. package/src/client/cloud-runtimes.ts +129 -129
  79. package/src/client/cloud-services.ts +94 -94
  80. package/src/client/code-shift.ts +371 -349
  81. package/src/client/content.ts +538 -538
  82. package/src/client/data-integration.ts +191 -191
  83. package/src/client/discover.ts +89 -89
  84. package/src/client/event-bus.ts +84 -84
  85. package/src/client/gen-ai-inference.ts +65 -65
  86. package/src/client/insights.ts +28 -28
  87. package/src/client/notification.ts +32 -32
  88. package/src/client/runtime-manager.ts +76 -76
  89. package/src/client/secrets.ts +60 -60
  90. package/src/client/types.ts +398 -377
  91. package/src/client/workflow.ts +83 -83
  92. package/src/client/workspace-ai.ts +191 -191
  93. package/src/client/workspace-manager.ts +564 -564
  94. package/src/client/workspace-search.ts +39 -39
  95. package/src/client/workspace.ts +480 -480
  96. package/src/error/DefaultAPIError.ts +151 -151
  97. package/src/error/FileUploadError.ts +18 -18
  98. package/src/error/IgnoredErrorCodes.ts +3 -3
  99. package/src/error/StackspotAPIError.ts +101 -101
  100. package/src/error/StreamCanceledError.ts +10 -10
  101. package/src/error/StreamError.ts +7 -7
  102. package/src/error/StreamJsonError.ts +10 -10
  103. package/src/error/dictionary/account.ts +58 -58
  104. package/src/error/dictionary/action-details.ts +20 -20
  105. package/src/error/dictionary/action.ts +211 -211
  106. package/src/error/dictionary/agent-tools.ts +75 -75
  107. package/src/error/dictionary/ai-inference.ts +28 -28
  108. package/src/error/dictionary/base.ts +22 -22
  109. package/src/error/dictionary/cloud-platform.ts +82 -82
  110. package/src/error/dictionary/cnt-fields.ts +14 -14
  111. package/src/error/dictionary/cnt.ts +103 -103
  112. package/src/error/dictionary/code-shift.ts +12 -12
  113. package/src/error/dictionary/rte.ts +24 -24
  114. package/src/error/dictionary/rtm.ts +10 -10
  115. package/src/error/dictionary/secrets.ts +14 -14
  116. package/src/error/dictionary/workspace-ai.ts +10 -10
  117. package/src/error/dictionary/workspace-details.ts +15 -15
  118. package/src/error/dictionary/workspace-fields.ts +10 -10
  119. package/src/error/dictionary/workspace.ts +209 -209
  120. package/src/error/types.ts +21 -21
  121. package/src/index.ts +43 -43
  122. package/src/network/AutoInfiniteQuery.ts +115 -115
  123. package/src/network/AutoMutation.ts +27 -27
  124. package/src/network/AutoOperation.ts +73 -73
  125. package/src/network/AutoQuery.ts +75 -75
  126. package/src/network/ManualInfiniteQuery.ts +95 -95
  127. package/src/network/ManualMutation.ts +40 -40
  128. package/src/network/ManualOperation.ts +52 -52
  129. package/src/network/ManualQuery.ts +82 -82
  130. package/src/network/NetworkClient.ts +167 -167
  131. package/src/network/ReactQueryNetworkClient.ts +312 -312
  132. package/src/network/react-query-client.ts +14 -14
  133. package/src/network/types.ts +294 -294
  134. package/src/types.ts +1 -1
  135. package/src/utils/StreamedArray.tsx +146 -146
  136. package/src/utils/StreamedJson.tsx +166 -166
  137. package/src/utils/remove-authorization-param.ts +6 -6
  138. package/src/utils/string.ts +19 -19
  139. package/src/utils/use-extended-list.ts +80 -80
  140. package/src/utils/use-streamed-array.ts +17 -17
  141. package/tsconfig.build.json +4 -4
  142. package/tsconfig.json +10 -10
@@ -1,312 +1,312 @@
1
- /* eslint-disable react-hooks/rules-of-hooks */
2
-
3
- import { Defaults, HttpError, RequestOpts } from '@oazapfts/runtime'
4
- import { StackspotAPIError } from '../error/StackspotAPIError'
5
- import { AutoInfiniteQuery } from './AutoInfiniteQuery'
6
- import { AutoMutation } from './AutoMutation'
7
- import { AutoQuery } from './AutoQuery'
8
- import { ManualInfiniteQuery } from './ManualInfiniteQuery'
9
- import { ManualMutation } from './ManualMutation'
10
- import { ManualQuery } from './ManualQuery'
11
- import { NetworkClient } from './NetworkClient'
12
- import { Env, HTTPMethod, InfiniteQueryConfig, InfiniteQueryObject, InfiniteQueryOptions, MutationObject, OperationConfig, OperationObject, QueryObject } from './types'
13
-
14
- const DUMMY_ULID = '01HSTZ5471CBG4AW9BFJ0VTVG9'
15
- const PERMISSION_ERROR = 'permission-error'
16
- export const DEFAULT_PAGE_SIZE = 20
17
-
18
- /**
19
- * A Network Client that uses oazapfts for making requests and React Query for managing responses.
20
- */
21
- export abstract class ReactQueryNetworkClient extends NetworkClient {
22
- /**
23
- * @param baseURL An object with the keys "dev", "stg" and "prd". The values must be the url for each of these environments.
24
- * @param defaults the `default` object of the API this client is for (provided by the code generated by oazapfts).
25
- */
26
- constructor(baseURL: Record<Env, string>, defaults: Defaults<any>) {
27
- super(baseURL)
28
- defaults.baseUrl = ''
29
- defaults.fetch = (...args) => this.fetch(...args)
30
- }
31
-
32
- #parseErrorData(error: HttpError) {
33
- if (typeof error.data === 'string') {
34
- try {
35
- return JSON.parse(error.data)
36
- } catch { /* empty */ }
37
- }
38
- return error.data
39
- }
40
-
41
- #transformError(error: any): StackspotAPIError {
42
- if (error instanceof StackspotAPIError) return error
43
- if (!(error instanceof HttpError)) throw new StackspotAPIError({ status: 0, message: error?.message || `${error}`, stack: error.stack })
44
- const data = this.#parseErrorData(error)
45
- if (data.type === PERMISSION_ERROR) {
46
- // eslint-disable-next-line no-console
47
- console.error('Error while validating permissions:', data.message)
48
- return new StackspotAPIError({
49
- status: 500,
50
- stack: error.stack,
51
- message: language => language === 'pt'
52
- ? 'Ocorreu um erro ao validar as permissões.'
53
- : 'There was an error while validating permissions.',
54
- })
55
- }
56
- return this.buildStackSpotError(error)
57
- }
58
-
59
- /**
60
- * Receives an HttpError and returns a StackspotAPIError.
61
- * @param error the original HttpError created by oazapfts.
62
- */
63
- protected abstract buildStackSpotError(error: HttpError): StackspotAPIError
64
-
65
- /**
66
- * Creates a function that checks the permission for a request generated by an oazapfts function.
67
- *
68
- * This is intended to help creating a manual operation.
69
- *
70
- * @example
71
- * ```
72
- * myOperation = this.mutation({
73
- * // ...
74
- * permission: this.createPermissionFunctionFor(oazapftsFnForMyOperation)
75
- * })
76
- * ```
77
- * @param fn the function generated by oazapfts.
78
- * @returns a function that receives the variables of `fn` (if any) and returns a promise that resolves to true if the request is allowed
79
- * and false otherwise.
80
- */
81
- protected createPermissionFunctionFor<Args extends [variables: Record<string, any>, opts?: RequestOpts] | [opts?: RequestOpts]>(
82
- fn: (...args: Args) => Promise<any>,
83
- ): (...args: Args extends [opts?: RequestOpts] ? [] : [variables?: Partial<Args[0]>]) => Promise<boolean> {
84
- return (variables?: any) => fn.length === 2
85
- ? (fn as (variables: Record<string, any>, opts?: RequestOpts) => Promise<any>)(
86
- variables,
87
- { fetch: (...args) => this.#onFetchPermission(...args) },
88
- )
89
- : (fn as (opts?: RequestOpts) => Promise<any>)({ fetch: (...args) => this.#onFetchPermission(...args) })
90
- }
91
-
92
- /**
93
- * Creates a function that runs a oazapfts function with an abort signal.
94
- *
95
- * This is intended to help creating a manual operation.
96
- *
97
- * @example
98
- * ```
99
- * myOperation = this.mutation({
100
- * // ...
101
- * request: this.createRequestFunctionFor(oazapftsFnForMyOperation)
102
- * })
103
- * ```
104
- * @param fn the function generated by oazapfts.
105
- * @returns a function that receives a signal and the variables of `fn` (if any) and returns the same as `fn`.
106
- */
107
- protected createRequestFunctionFor<Args extends [variables: Record<string, any>, opts?: RequestOpts] | [opts?: RequestOpts], Result>(
108
- fn: (...args: Args) => Promise<Result>,
109
- ): (...args: Args extends [opts?: RequestOpts] ? [signal: AbortSignal] : [signal: AbortSignal, variables: Args[0]]) => Promise<Result> {
110
- return (signal, variables?: any) => fn.length === 2
111
- ? (fn as (variables: Record<string, any>, opts?: RequestOpts) => Promise<Result>)(variables, { signal })
112
- : (fn as (opts?: RequestOpts) => Promise<Result>)({ signal })
113
- }
114
-
115
- async #onFetchPermission(input: string | URL | Request, init?: RequestInit | undefined): Promise<Response> {
116
- const [path, method, body] = input instanceof Request
117
- ? [input.url, input.method as HTTPMethod, input.body]
118
- : [`${input}`, (init?.method?.toLowerCase() || 'get') as HTTPMethod, init?.body]
119
- try {
120
- /* We allow the dev not to pass any variable when validating a permission. For this reason, oazapfts might generate a path with
121
- "undefined". If this happens, we must replace the undefined text with a dummy ULID. */
122
- const fixedPath = path.replace(/\/undefined(\/|$)/g, `/${DUMMY_ULID}$1`)
123
- const isAllowed = await this.requestPermission(method, fixedPath, body as any)
124
- return new Response(`${isAllowed}`, { headers: { 'Content-Type': 'application/json' } })
125
- } catch (error: any) {
126
- return new Response(JSON.stringify({ type: PERMISSION_ERROR, message: error.message || `${error}` }), { status: 500 })
127
- }
128
- }
129
-
130
- /**
131
- * Builds a query manually by using a configuration object.
132
- * @param config the configuration object containing the name, a request function and a permission function.
133
- */
134
- protected query<Args extends [AbortSignal, Record<string, any>] | [AbortSignal], Result>(
135
- config: OperationConfig<Args, Result>,
136
- ): QueryObject<Args extends [AbortSignal] ? void : Args[1], Result>
137
- /**
138
- * Builds a query manually by using a configuration object.
139
- * @param config the configuration object containing the name and a request function.
140
- */
141
- protected query<Args extends [AbortSignal, Record<string, any>] | [AbortSignal], Result>(
142
- config: Omit<OperationConfig<Args, Result>, 'permission'>,
143
- ): Omit<QueryObject<Args extends [AbortSignal] ? void : Args[1], Result>, 'isAllowed' | 'useAllowed' | 'getPermissionKey'>
144
- /**
145
- * Builds a query automatically by using a function generated by oazapfts.
146
- * @param fn the oazapfts function.
147
- */
148
- protected query<Args extends [opts?: RequestOpts] | [variables: Record<string, any>, opts?: RequestOpts], Result>(
149
- fn: (...args: Args) => Promise<Result>
150
- ): Args extends [variables: infer Variables, opts?: RequestOpts] ? QueryObject<Variables, Result> : QueryObject<void, Result>
151
- protected query(fnOrConfig: any): QueryObject<any, any> {
152
- return typeof fnOrConfig === 'function'
153
- ? new AutoQuery(
154
- {
155
- apiName: this.constructor.name,
156
- fn: fnOrConfig,
157
- onFetchPermission: (...args) => this.#onFetchPermission(...args),
158
- transformError: error => this.#transformError(error),
159
- },
160
- )
161
- : new ManualQuery({
162
- ...fnOrConfig,
163
- apiName: this.constructor.name,
164
- request: fnOrConfig.request,
165
- permission: fnOrConfig.permission,
166
- transformError: error => this.#transformError(error),
167
- })
168
- }
169
-
170
- /**
171
- * Builds a query manually by using a configuration object.
172
- * @param config the configuration object containing the name, a request function and a permission function.
173
- */
174
- protected infiniteQuery<
175
- Variables extends Record<string, any>,
176
- Result,
177
- PageParamName extends keyof Variables,
178
- Accumulator extends keyof Result | '',
179
- >(config: InfiniteQueryConfig<Variables, Result, PageParamName, Accumulator>): InfiniteQueryObject<Variables, Result, Accumulator>
180
- /**
181
- * Builds a query manually by using a configuration object.
182
- * @param config the configuration object containing the name and a request function.
183
- */
184
- protected infiniteQuery<
185
- Variables extends Record<string, any>,
186
- Result,
187
- PageParamName extends keyof Variables,
188
- Accumulator extends keyof Result | '',
189
- >(
190
- config: Omit<InfiniteQueryConfig<Variables, Result, PageParamName, Accumulator>, 'permission'>,
191
- ): Omit<InfiniteQueryObject<Variables, Result, Accumulator>, 'isAllowed' | 'useAllowed' | 'getPermissionKey'>
192
- /**
193
- * Builds a query automatically by using a function generated by oazapfts.
194
- * @param fn the oazapfts function.
195
- * @param options the configuration for the infinite query.
196
- */
197
- protected infiniteQuery<
198
- Variables extends Record<string, any>,
199
- Result,
200
- PageParamName extends keyof Variables,
201
- Accumulator extends keyof Result,
202
- >(
203
- fn: (variables: Variables, opts?: RequestOpts) => Promise<Result>,
204
- options: Partial<InfiniteQueryOptions<Variables, Result, PageParamName, Accumulator>>,
205
- ): InfiniteQueryObject<Variables, Result, Accumulator>
206
- /**
207
- * Builds a query automatically by using a function generated by oazapfts with the variables `page` and `size`.
208
- * @param fn the oazapfts function that returns an array.
209
- * @param options optional configuration for the infinite query. By default, it will use the variables page and size of the function
210
- * passed in the first parameter.
211
- */
212
- protected infiniteQuery<
213
- Variables extends { page?: number | string, size?: number | string },
214
- Result extends any[],
215
- PageParamName extends keyof Variables = 'page',
216
- Accumulator extends keyof Result | '' = '',
217
- >(
218
- fn: (variables: Variables, opts?: RequestOpts) => Promise<Result>,
219
- options?: Partial<InfiniteQueryOptions<Variables, Result, PageParamName, Accumulator>>,
220
- ): InfiniteQueryObject<Variables, Result, Accumulator>
221
- /**
222
- * Builds a query automatically by using a function generated by oazapfts in which the variables `pageParamName` is a string
223
- * which can be used for dynamic indexing.
224
- * @param fn the oazapfts function that returns an array.
225
- * @param options optional configuration for the infinite query. By default, it will use the variables page and size of the function
226
- * passed in the first parameter.
227
- */
228
- protected infiniteQuery<
229
- Variables extends Record<string, any>,
230
- Result,
231
- PageParamName extends string,
232
- Accumulator extends keyof Result,
233
- >(
234
- fn: (variables: Variables, opts?: RequestOpts) => Promise<Result>,
235
- options: Partial<InfiniteQueryOptions<Variables, Result, PageParamName, Accumulator>>,
236
- ): InfiniteQueryObject<Variables, Result, Accumulator>
237
- protected infiniteQuery(
238
- fnOrConfig: any, options?: Partial<InfiniteQueryOptions<any, any, any, any>>,
239
- ): InfiniteQueryObject<any, any, any> {
240
- return typeof fnOrConfig === 'function'
241
- ? new AutoInfiniteQuery(
242
- {
243
- apiName: this.constructor.name,
244
- fn: fnOrConfig,
245
- onFetchPermission: (...args) => this.#onFetchPermission(...args),
246
- transformError: error => this.#transformError(error),
247
- },
248
- {
249
- accumulator: options?.accumulator ?? '',
250
- pageParamName: options?.pageParamName ?? 'page',
251
- initialPageParam: options?.initialPageParam ?? 1,
252
- defaultVariables: options?.defaultVariables ?? { size: DEFAULT_PAGE_SIZE },
253
- getNextPageParam: options?.getNextPageParam ?? (({ variables, lastPage, lastPageParam }) => {
254
- const size = variables.size ?? 1
255
- const isLastPageTheLast = lastPage && (
256
- (Array.isArray(lastPage) && lastPage.length < size)
257
- || (options?.accumulator !== undefined && options?.accumulator !== '' && lastPage[options?.accumulator]?.length < size)
258
- )
259
- return isLastPageTheLast ? undefined : parseInt(lastPageParam) + 1
260
- }),
261
- },
262
- )
263
- : new ManualInfiniteQuery({
264
- ...fnOrConfig,
265
- apiName: this.constructor.name,
266
- request: fnOrConfig.request,
267
- permission: fnOrConfig.permission,
268
- transformError: error => this.#transformError(error),
269
- })
270
- }
271
-
272
- /**
273
- * Builds a mutation manually by using a configuration object.
274
- * @param config the configuration object containing the name, a request function and a permission function.
275
- */
276
- protected mutation<Args extends [AbortSignal, Record<string, any>] | [AbortSignal], Result>(
277
- config: OperationConfig<Args, Result>,
278
- ): MutationObject<Args extends [AbortSignal] ? void : Args[1], Result>
279
- /**
280
- * Builds a mutation manually by using a configuration object.
281
- * @param config the configuration object containing the name and a request function.
282
- */
283
- protected mutation<Args extends [AbortSignal, Record<string, any>] | [AbortSignal], Result>(
284
- config: Omit<OperationConfig<Args, Result>, 'permission'>,
285
- ): Omit<MutationObject<Args extends [AbortSignal] ? void : Args[1], Result>, keyof OperationObject<any>>
286
- /**
287
- * Builds a mutation automatically by using a function generated by oazapfts.
288
- * @param fn the oazapfts function.
289
- */
290
- protected mutation<Args extends [opts?: RequestOpts] | [variables: Record<string, any>, opts?: RequestOpts], Result>(
291
- fn: (...args: Args) => Promise<Result>,
292
- ): Args extends [variables: infer Variables, opts?: RequestOpts] ? MutationObject<Variables, Result> : MutationObject<void, Result>
293
- protected mutation(fnOrConfig: any): MutationObject<any, any> {
294
- if (typeof fnOrConfig === 'function') {
295
- return new AutoMutation(
296
- {
297
- apiName: this.constructor.name,
298
- fn: fnOrConfig,
299
- onFetchPermission: (...args) => this.#onFetchPermission(...args),
300
- transformError: error => this.#transformError(error),
301
- },
302
- )
303
- }
304
- return new ManualMutation({
305
- ...fnOrConfig,
306
- apiName: this.constructor.name,
307
- request: fnOrConfig.request,
308
- permission: fnOrConfig.permission,
309
- transformError: error => this.#transformError(error),
310
- })
311
- }
312
- }
1
+ /* eslint-disable react-hooks/rules-of-hooks */
2
+
3
+ import { Defaults, HttpError, RequestOpts } from '@oazapfts/runtime'
4
+ import { StackspotAPIError } from '../error/StackspotAPIError'
5
+ import { AutoInfiniteQuery } from './AutoInfiniteQuery'
6
+ import { AutoMutation } from './AutoMutation'
7
+ import { AutoQuery } from './AutoQuery'
8
+ import { ManualInfiniteQuery } from './ManualInfiniteQuery'
9
+ import { ManualMutation } from './ManualMutation'
10
+ import { ManualQuery } from './ManualQuery'
11
+ import { NetworkClient } from './NetworkClient'
12
+ import { Env, HTTPMethod, InfiniteQueryConfig, InfiniteQueryObject, InfiniteQueryOptions, MutationObject, OperationConfig, OperationObject, QueryObject } from './types'
13
+
14
+ const DUMMY_ULID = '01HSTZ5471CBG4AW9BFJ0VTVG9'
15
+ const PERMISSION_ERROR = 'permission-error'
16
+ export const DEFAULT_PAGE_SIZE = 20
17
+
18
+ /**
19
+ * A Network Client that uses oazapfts for making requests and React Query for managing responses.
20
+ */
21
+ export abstract class ReactQueryNetworkClient extends NetworkClient {
22
+ /**
23
+ * @param baseURL An object with the keys "dev", "stg" and "prd". The values must be the url for each of these environments.
24
+ * @param defaults the `default` object of the API this client is for (provided by the code generated by oazapfts).
25
+ */
26
+ constructor(baseURL: Record<Env, string>, defaults: Defaults<any>) {
27
+ super(baseURL)
28
+ defaults.baseUrl = ''
29
+ defaults.fetch = (...args) => this.fetch(...args)
30
+ }
31
+
32
+ #parseErrorData(error: HttpError) {
33
+ if (typeof error.data === 'string') {
34
+ try {
35
+ return JSON.parse(error.data)
36
+ } catch { /* empty */ }
37
+ }
38
+ return error.data
39
+ }
40
+
41
+ #transformError(error: any): StackspotAPIError {
42
+ if (error instanceof StackspotAPIError) return error
43
+ if (!(error instanceof HttpError)) throw new StackspotAPIError({ status: 0, message: error?.message || `${error}`, stack: error.stack })
44
+ const data = this.#parseErrorData(error)
45
+ if (data.type === PERMISSION_ERROR) {
46
+ // eslint-disable-next-line no-console
47
+ console.error('Error while validating permissions:', data.message)
48
+ return new StackspotAPIError({
49
+ status: 500,
50
+ stack: error.stack,
51
+ message: language => language === 'pt'
52
+ ? 'Ocorreu um erro ao validar as permissões.'
53
+ : 'There was an error while validating permissions.',
54
+ })
55
+ }
56
+ return this.buildStackSpotError(error)
57
+ }
58
+
59
+ /**
60
+ * Receives an HttpError and returns a StackspotAPIError.
61
+ * @param error the original HttpError created by oazapfts.
62
+ */
63
+ protected abstract buildStackSpotError(error: HttpError): StackspotAPIError
64
+
65
+ /**
66
+ * Creates a function that checks the permission for a request generated by an oazapfts function.
67
+ *
68
+ * This is intended to help creating a manual operation.
69
+ *
70
+ * @example
71
+ * ```
72
+ * myOperation = this.mutation({
73
+ * // ...
74
+ * permission: this.createPermissionFunctionFor(oazapftsFnForMyOperation)
75
+ * })
76
+ * ```
77
+ * @param fn the function generated by oazapfts.
78
+ * @returns a function that receives the variables of `fn` (if any) and returns a promise that resolves to true if the request is allowed
79
+ * and false otherwise.
80
+ */
81
+ protected createPermissionFunctionFor<Args extends [variables: Record<string, any>, opts?: RequestOpts] | [opts?: RequestOpts]>(
82
+ fn: (...args: Args) => Promise<any>,
83
+ ): (...args: Args extends [opts?: RequestOpts] ? [] : [variables?: Partial<Args[0]>]) => Promise<boolean> {
84
+ return (variables?: any) => fn.length === 2
85
+ ? (fn as (variables: Record<string, any>, opts?: RequestOpts) => Promise<any>)(
86
+ variables,
87
+ { fetch: (...args) => this.#onFetchPermission(...args) },
88
+ )
89
+ : (fn as (opts?: RequestOpts) => Promise<any>)({ fetch: (...args) => this.#onFetchPermission(...args) })
90
+ }
91
+
92
+ /**
93
+ * Creates a function that runs a oazapfts function with an abort signal.
94
+ *
95
+ * This is intended to help creating a manual operation.
96
+ *
97
+ * @example
98
+ * ```
99
+ * myOperation = this.mutation({
100
+ * // ...
101
+ * request: this.createRequestFunctionFor(oazapftsFnForMyOperation)
102
+ * })
103
+ * ```
104
+ * @param fn the function generated by oazapfts.
105
+ * @returns a function that receives a signal and the variables of `fn` (if any) and returns the same as `fn`.
106
+ */
107
+ protected createRequestFunctionFor<Args extends [variables: Record<string, any>, opts?: RequestOpts] | [opts?: RequestOpts], Result>(
108
+ fn: (...args: Args) => Promise<Result>,
109
+ ): (...args: Args extends [opts?: RequestOpts] ? [signal: AbortSignal] : [signal: AbortSignal, variables: Args[0]]) => Promise<Result> {
110
+ return (signal, variables?: any) => fn.length === 2
111
+ ? (fn as (variables: Record<string, any>, opts?: RequestOpts) => Promise<Result>)(variables, { signal })
112
+ : (fn as (opts?: RequestOpts) => Promise<Result>)({ signal })
113
+ }
114
+
115
+ async #onFetchPermission(input: string | URL | Request, init?: RequestInit | undefined): Promise<Response> {
116
+ const [path, method, body] = input instanceof Request
117
+ ? [input.url, input.method as HTTPMethod, input.body]
118
+ : [`${input}`, (init?.method?.toLowerCase() || 'get') as HTTPMethod, init?.body]
119
+ try {
120
+ /* We allow the dev not to pass any variable when validating a permission. For this reason, oazapfts might generate a path with
121
+ "undefined". If this happens, we must replace the undefined text with a dummy ULID. */
122
+ const fixedPath = path.replace(/\/undefined(\/|$)/g, `/${DUMMY_ULID}$1`)
123
+ const isAllowed = await this.requestPermission(method, fixedPath, body as any)
124
+ return new Response(`${isAllowed}`, { headers: { 'Content-Type': 'application/json' } })
125
+ } catch (error: any) {
126
+ return new Response(JSON.stringify({ type: PERMISSION_ERROR, message: error.message || `${error}` }), { status: 500 })
127
+ }
128
+ }
129
+
130
+ /**
131
+ * Builds a query manually by using a configuration object.
132
+ * @param config the configuration object containing the name, a request function and a permission function.
133
+ */
134
+ protected query<Args extends [AbortSignal, Record<string, any>] | [AbortSignal], Result>(
135
+ config: OperationConfig<Args, Result>,
136
+ ): QueryObject<Args extends [AbortSignal] ? void : Args[1], Result>
137
+ /**
138
+ * Builds a query manually by using a configuration object.
139
+ * @param config the configuration object containing the name and a request function.
140
+ */
141
+ protected query<Args extends [AbortSignal, Record<string, any>] | [AbortSignal], Result>(
142
+ config: Omit<OperationConfig<Args, Result>, 'permission'>,
143
+ ): Omit<QueryObject<Args extends [AbortSignal] ? void : Args[1], Result>, 'isAllowed' | 'useAllowed' | 'getPermissionKey'>
144
+ /**
145
+ * Builds a query automatically by using a function generated by oazapfts.
146
+ * @param fn the oazapfts function.
147
+ */
148
+ protected query<Args extends [opts?: RequestOpts] | [variables: Record<string, any>, opts?: RequestOpts], Result>(
149
+ fn: (...args: Args) => Promise<Result>
150
+ ): Args extends [variables: infer Variables, opts?: RequestOpts] ? QueryObject<Variables, Result> : QueryObject<void, Result>
151
+ protected query(fnOrConfig: any): QueryObject<any, any> {
152
+ return typeof fnOrConfig === 'function'
153
+ ? new AutoQuery(
154
+ {
155
+ apiName: this.constructor.name,
156
+ fn: fnOrConfig,
157
+ onFetchPermission: (...args) => this.#onFetchPermission(...args),
158
+ transformError: error => this.#transformError(error),
159
+ },
160
+ )
161
+ : new ManualQuery({
162
+ ...fnOrConfig,
163
+ apiName: this.constructor.name,
164
+ request: fnOrConfig.request,
165
+ permission: fnOrConfig.permission,
166
+ transformError: error => this.#transformError(error),
167
+ })
168
+ }
169
+
170
+ /**
171
+ * Builds a query manually by using a configuration object.
172
+ * @param config the configuration object containing the name, a request function and a permission function.
173
+ */
174
+ protected infiniteQuery<
175
+ Variables extends Record<string, any>,
176
+ Result,
177
+ PageParamName extends keyof Variables,
178
+ Accumulator extends keyof Result | '',
179
+ >(config: InfiniteQueryConfig<Variables, Result, PageParamName, Accumulator>): InfiniteQueryObject<Variables, Result, Accumulator>
180
+ /**
181
+ * Builds a query manually by using a configuration object.
182
+ * @param config the configuration object containing the name and a request function.
183
+ */
184
+ protected infiniteQuery<
185
+ Variables extends Record<string, any>,
186
+ Result,
187
+ PageParamName extends keyof Variables,
188
+ Accumulator extends keyof Result | '',
189
+ >(
190
+ config: Omit<InfiniteQueryConfig<Variables, Result, PageParamName, Accumulator>, 'permission'>,
191
+ ): Omit<InfiniteQueryObject<Variables, Result, Accumulator>, 'isAllowed' | 'useAllowed' | 'getPermissionKey'>
192
+ /**
193
+ * Builds a query automatically by using a function generated by oazapfts.
194
+ * @param fn the oazapfts function.
195
+ * @param options the configuration for the infinite query.
196
+ */
197
+ protected infiniteQuery<
198
+ Variables extends Record<string, any>,
199
+ Result,
200
+ PageParamName extends keyof Variables,
201
+ Accumulator extends keyof Result,
202
+ >(
203
+ fn: (variables: Variables, opts?: RequestOpts) => Promise<Result>,
204
+ options: Partial<InfiniteQueryOptions<Variables, Result, PageParamName, Accumulator>>,
205
+ ): InfiniteQueryObject<Variables, Result, Accumulator>
206
+ /**
207
+ * Builds a query automatically by using a function generated by oazapfts with the variables `page` and `size`.
208
+ * @param fn the oazapfts function that returns an array.
209
+ * @param options optional configuration for the infinite query. By default, it will use the variables page and size of the function
210
+ * passed in the first parameter.
211
+ */
212
+ protected infiniteQuery<
213
+ Variables extends { page?: number | string, size?: number | string },
214
+ Result extends any[],
215
+ PageParamName extends keyof Variables = 'page',
216
+ Accumulator extends keyof Result | '' = '',
217
+ >(
218
+ fn: (variables: Variables, opts?: RequestOpts) => Promise<Result>,
219
+ options?: Partial<InfiniteQueryOptions<Variables, Result, PageParamName, Accumulator>>,
220
+ ): InfiniteQueryObject<Variables, Result, Accumulator>
221
+ /**
222
+ * Builds a query automatically by using a function generated by oazapfts in which the variables `pageParamName` is a string
223
+ * which can be used for dynamic indexing.
224
+ * @param fn the oazapfts function that returns an array.
225
+ * @param options optional configuration for the infinite query. By default, it will use the variables page and size of the function
226
+ * passed in the first parameter.
227
+ */
228
+ protected infiniteQuery<
229
+ Variables extends Record<string, any>,
230
+ Result,
231
+ PageParamName extends string,
232
+ Accumulator extends keyof Result,
233
+ >(
234
+ fn: (variables: Variables, opts?: RequestOpts) => Promise<Result>,
235
+ options: Partial<InfiniteQueryOptions<Variables, Result, PageParamName, Accumulator>>,
236
+ ): InfiniteQueryObject<Variables, Result, Accumulator>
237
+ protected infiniteQuery(
238
+ fnOrConfig: any, options?: Partial<InfiniteQueryOptions<any, any, any, any>>,
239
+ ): InfiniteQueryObject<any, any, any> {
240
+ return typeof fnOrConfig === 'function'
241
+ ? new AutoInfiniteQuery(
242
+ {
243
+ apiName: this.constructor.name,
244
+ fn: fnOrConfig,
245
+ onFetchPermission: (...args) => this.#onFetchPermission(...args),
246
+ transformError: error => this.#transformError(error),
247
+ },
248
+ {
249
+ accumulator: options?.accumulator ?? '',
250
+ pageParamName: options?.pageParamName ?? 'page',
251
+ initialPageParam: options?.initialPageParam ?? 1,
252
+ defaultVariables: options?.defaultVariables ?? { size: DEFAULT_PAGE_SIZE },
253
+ getNextPageParam: options?.getNextPageParam ?? (({ variables, lastPage, lastPageParam }) => {
254
+ const size = variables.size ?? 1
255
+ const isLastPageTheLast = lastPage && (
256
+ (Array.isArray(lastPage) && lastPage.length < size)
257
+ || (options?.accumulator !== undefined && options?.accumulator !== '' && lastPage[options?.accumulator]?.length < size)
258
+ )
259
+ return isLastPageTheLast ? undefined : parseInt(lastPageParam) + 1
260
+ }),
261
+ },
262
+ )
263
+ : new ManualInfiniteQuery({
264
+ ...fnOrConfig,
265
+ apiName: this.constructor.name,
266
+ request: fnOrConfig.request,
267
+ permission: fnOrConfig.permission,
268
+ transformError: error => this.#transformError(error),
269
+ })
270
+ }
271
+
272
+ /**
273
+ * Builds a mutation manually by using a configuration object.
274
+ * @param config the configuration object containing the name, a request function and a permission function.
275
+ */
276
+ protected mutation<Args extends [AbortSignal, Record<string, any>] | [AbortSignal], Result>(
277
+ config: OperationConfig<Args, Result>,
278
+ ): MutationObject<Args extends [AbortSignal] ? void : Args[1], Result>
279
+ /**
280
+ * Builds a mutation manually by using a configuration object.
281
+ * @param config the configuration object containing the name and a request function.
282
+ */
283
+ protected mutation<Args extends [AbortSignal, Record<string, any>] | [AbortSignal], Result>(
284
+ config: Omit<OperationConfig<Args, Result>, 'permission'>,
285
+ ): Omit<MutationObject<Args extends [AbortSignal] ? void : Args[1], Result>, keyof OperationObject<any>>
286
+ /**
287
+ * Builds a mutation automatically by using a function generated by oazapfts.
288
+ * @param fn the oazapfts function.
289
+ */
290
+ protected mutation<Args extends [opts?: RequestOpts] | [variables: Record<string, any>, opts?: RequestOpts], Result>(
291
+ fn: (...args: Args) => Promise<Result>,
292
+ ): Args extends [variables: infer Variables, opts?: RequestOpts] ? MutationObject<Variables, Result> : MutationObject<void, Result>
293
+ protected mutation(fnOrConfig: any): MutationObject<any, any> {
294
+ if (typeof fnOrConfig === 'function') {
295
+ return new AutoMutation(
296
+ {
297
+ apiName: this.constructor.name,
298
+ fn: fnOrConfig,
299
+ onFetchPermission: (...args) => this.#onFetchPermission(...args),
300
+ transformError: error => this.#transformError(error),
301
+ },
302
+ )
303
+ }
304
+ return new ManualMutation({
305
+ ...fnOrConfig,
306
+ apiName: this.constructor.name,
307
+ request: fnOrConfig.request,
308
+ permission: fnOrConfig.permission,
309
+ transformError: error => this.#transformError(error),
310
+ })
311
+ }
312
+ }
@@ -1,14 +1,14 @@
1
- import { QueryClient } from '@tanstack/react-query'
2
-
3
- /**
4
- * The global, unique, Query Client for React Query.
5
- */
6
- export const queryClient = new QueryClient({
7
- defaultOptions: {
8
- queries: {
9
- refetchOnWindowFocus: false,
10
- retry: false,
11
- staleTime: Infinity,
12
- },
13
- },
14
- })
1
+ import { QueryClient } from '@tanstack/react-query'
2
+
3
+ /**
4
+ * The global, unique, Query Client for React Query.
5
+ */
6
+ export const queryClient = new QueryClient({
7
+ defaultOptions: {
8
+ queries: {
9
+ refetchOnWindowFocus: false,
10
+ retry: false,
11
+ staleTime: Infinity,
12
+ },
13
+ },
14
+ })