@stack-spot/portal-network 0.3.1 → 0.4.0-beta.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.
Files changed (66) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/dist/api/secrets.d.ts +100 -0
  3. package/dist/api/secrets.d.ts.map +1 -0
  4. package/dist/api/secrets.js +101 -0
  5. package/dist/api/secrets.js.map +1 -0
  6. package/dist/apis.json +8 -0
  7. package/dist/client/account.d.ts +232 -0
  8. package/dist/client/account.d.ts.map +1 -1
  9. package/dist/client/account.js +226 -1
  10. package/dist/client/account.js.map +1 -1
  11. package/dist/client/secrets.d.ts +50 -0
  12. package/dist/client/secrets.d.ts.map +1 -0
  13. package/dist/client/secrets.js +78 -0
  14. package/dist/client/secrets.js.map +1 -0
  15. package/dist/error/DefaultAPIError.js +3 -3
  16. package/dist/error/DefaultAPIError.js.map +1 -1
  17. package/dist/error/dictionary/account.d.ts +2 -0
  18. package/dist/error/dictionary/account.d.ts.map +1 -1
  19. package/dist/error/dictionary/account.js +2 -0
  20. package/dist/error/dictionary/account.js.map +1 -1
  21. package/dist/error/dictionary/secrets.d.ts +13 -0
  22. package/dist/error/dictionary/secrets.d.ts.map +1 -0
  23. package/dist/error/dictionary/secrets.js +13 -0
  24. package/dist/error/dictionary/secrets.js.map +1 -0
  25. package/dist/index.d.ts +1 -0
  26. package/dist/index.d.ts.map +1 -1
  27. package/dist/index.js +1 -0
  28. package/dist/index.js.map +1 -1
  29. package/dist/network/AutoQuery.d.ts +1 -1
  30. package/dist/network/AutoQuery.d.ts.map +1 -1
  31. package/dist/network/AutoQuery.js +4 -1
  32. package/dist/network/AutoQuery.js.map +1 -1
  33. package/dist/network/ManualInfiniteQuery.d.ts +1 -0
  34. package/dist/network/ManualInfiniteQuery.d.ts.map +1 -1
  35. package/dist/network/ManualInfiniteQuery.js.map +1 -1
  36. package/dist/network/ManualMutation.d.ts.map +1 -1
  37. package/dist/network/ManualMutation.js +3 -0
  38. package/dist/network/ManualMutation.js.map +1 -1
  39. package/dist/network/ManualOperation.d.ts +1 -0
  40. package/dist/network/ManualOperation.d.ts.map +1 -1
  41. package/dist/network/ManualOperation.js +16 -5
  42. package/dist/network/ManualOperation.js.map +1 -1
  43. package/dist/network/ManualQuery.d.ts.map +1 -1
  44. package/dist/network/ManualQuery.js +3 -0
  45. package/dist/network/ManualQuery.js.map +1 -1
  46. package/dist/network/ReactQueryNetworkClient.d.ts.map +1 -1
  47. package/dist/network/ReactQueryNetworkClient.js +11 -21
  48. package/dist/network/ReactQueryNetworkClient.js.map +1 -1
  49. package/dist/network/types.d.ts +1 -0
  50. package/dist/network/types.d.ts.map +1 -1
  51. package/package.json +2 -3
  52. package/src/api/secrets.ts +279 -0
  53. package/src/apis.json +8 -0
  54. package/src/client/account.ts +124 -3
  55. package/src/client/secrets.ts +56 -0
  56. package/src/error/DefaultAPIError.ts +3 -3
  57. package/src/error/dictionary/account.ts +2 -0
  58. package/src/error/dictionary/secrets.ts +14 -0
  59. package/src/index.ts +1 -0
  60. package/src/network/AutoQuery.ts +3 -1
  61. package/src/network/ManualInfiniteQuery.ts +4 -1
  62. package/src/network/ManualMutation.ts +2 -0
  63. package/src/network/ManualOperation.ts +16 -5
  64. package/src/network/ManualQuery.ts +2 -0
  65. package/src/network/ReactQueryNetworkClient.ts +9 -16
  66. package/src/network/types.ts +1 -0
@@ -1,18 +1,36 @@
1
1
  import { HttpError } from '@oazapfts/runtime'
2
2
  import {
3
3
  accountDataIsAvailable,
4
- bindToGroups, bindToRoles, create, createPartner,
4
+ addResourcesToGroup,
5
+ addRoleToMember,
6
+ bindGroupMembers,
7
+ bindRoleGroups,
8
+ bindRoles,
9
+ bindToGroups, bindToRoles, create, createAccountRole, createPartner,
5
10
  createUser,
6
11
  deactivateFidoCredentials,
7
12
  defaults,
13
+ deleteAccountRole,
8
14
  deleteMember,
9
- deletePartner, enableFidoCredentials, getAccountMembers1, getAllMemberFidoCredentials, getFeatures,
15
+ deletePartner, deleteResourceFromGroup, deleteRole, deleteV1GroupsByGroupId, enableFidoCredentials, getAccountMembers1,
16
+ getAllMemberFidoCredentials, getFeatures,
17
+ getGroupById,
18
+ getGroupResources,
19
+ getGroups,
10
20
  getMemberById,
11
21
  getMemberGroups,
22
+ getMembers,
12
23
  getPartnerAccount, getPartnersSharingAllowed,
13
24
  getPersonalClientCredentials,
14
25
  getResources1,
15
- getRoles1, removeRoleFromMember, resetPassword, updatePartnerAccountAdminData, updatePartnerAccountData, updateUser,
26
+ getResourcesAndActionsWithStatus,
27
+ getRoleGroups,
28
+ getRoleMembers,
29
+ getRoles,
30
+ getRoles1, getRoles2, removeRoleFromMember, resetPassword, save, update1, updateAccountRole, updatePartnerAccountAdminData,
31
+ updatePartnerAccountData,
32
+ updateRoleWithNewActions,
33
+ updateUser,
16
34
  validateNewPartnerData,
17
35
  validatePartnerAssociationLimit,
18
36
  } from '../api/account'
@@ -150,10 +168,113 @@ class AccountClient extends ReactQueryNetworkClient {
150
168
  * Disables Fido credentials for the given member.
151
169
  */
152
170
  disableFidoCredentials = this.mutation(deactivateFidoCredentials)
171
+ /**
172
+ * Gets group by id.
173
+ */
174
+ group = this.query(getGroupById)
175
+ /**
176
+ * Get all groups (paginated).
177
+ */
178
+ allGroups = this.infiniteQuery(getGroups)
179
+ /**
180
+ * Creates a group.
181
+ */
182
+ createGroup = this.mutation(save)
183
+ /**
184
+ * Updates a group.
185
+ */
186
+ updateGroup = this.mutation(update1)
187
+ /**
188
+ * Deletes a group.
189
+ */
190
+ deleteGroup = this.mutation(deleteV1GroupsByGroupId)
191
+ /**
192
+ * Gets all members in a group (paginated).
193
+ */
194
+ groupMembers = this.infiniteQuery(getMembers)
195
+ /**
196
+ * Adds several members to a group
197
+ */
198
+ addMembersToGroup = this.mutation(bindGroupMembers)
153
199
  /**
154
200
  * Removes a member from a group
155
201
  */
156
202
  removeMemberFromGroup = this.mutation(deleteMember)
203
+ /**
204
+ * Gets all roles of a group.
205
+ */
206
+ groupRoles = this.infiniteQuery(getRoles2)
207
+ /**
208
+ * Adds several roles to a group.
209
+ */
210
+ addRolesToGroup = this.mutation(bindRoles)
211
+ /**
212
+ * Removes a role from a group.
213
+ */
214
+ removeRoleFromGroup = this.mutation(deleteRole)
215
+ /**
216
+ * Gets all resources of a group (paginated).
217
+ */
218
+ groupResources = this.infiniteQuery(getGroupResources)
219
+ /**
220
+ * Adds several resources to a group.
221
+ */
222
+ addResourcesToGroup = this.mutation(addResourcesToGroup)
223
+ /**
224
+ * Removes a resource from a group.
225
+ */
226
+ removeResourceFromGroup = this.mutation(deleteResourceFromGroup)
227
+ /**
228
+ * Gets all roles in the account (paginated)
229
+ */
230
+ allRoles = this.infiniteQuery(getRoles)
231
+ /**
232
+ * Get a role by id
233
+ */
234
+ role = this.query({
235
+ name: 'account.role',
236
+ request: async (signal, { id }: { id: string }) => {
237
+ const roles = await getRoles({ filterBy: 'id', filterValue: id }, { signal })
238
+ if (!roles.length) throw new StackspotAPIError({ status: 404 })
239
+ return roles[0]
240
+ },
241
+ })
242
+ /**
243
+ * Gets all members with the provided role (paginated)
244
+ */
245
+ roleMembers = this.infiniteQuery(getRoleMembers)
246
+ /**
247
+ * Creates a role
248
+ */
249
+ createRole = this.mutation(createAccountRole)
250
+ /**
251
+ * Updates a role
252
+ */
253
+ updateRole = this.mutation(updateAccountRole)
254
+ /**
255
+ * Deletes a role
256
+ */
257
+ deleteRole = this.mutation(deleteAccountRole)
258
+ /**
259
+ * Adds a role to several members
260
+ */
261
+ addRoleToMembers = this.mutation(addRoleToMember)
262
+ /**
263
+ * Gets all groups with the provided role (paginated)
264
+ */
265
+ roleGroups = this.infiniteQuery(getRoleGroups)
266
+ /**
267
+ * Adds a role to several groups
268
+ */
269
+ addRoleToGroups = this.mutation(bindRoleGroups)
270
+ /**
271
+ * Get the actions a role is allowed to perform
272
+ */
273
+ rolePermissions = this.infiniteQuery(getResourcesAndActionsWithStatus)
274
+ /**
275
+ * Updates a role with new actions
276
+ */
277
+ updateRolePermissions = this.mutation(updateRoleWithNewActions)
157
278
  }
158
279
 
159
280
  export const accountClient = new AccountClient()
@@ -0,0 +1,56 @@
1
+ import { HttpError } from '@oazapfts/runtime'
2
+
3
+ import { createKey, defaults, deleteKey, deleteSecretValue, editKey, getAll1, getAvailability, updateSecretValue } from '../api/secrets'
4
+ import apis from '../apis.json'
5
+ import { DefaultAPIError } from '../error/DefaultAPIError'
6
+ import { secretsDictionary } from '../error/dictionary/secrets'
7
+ import { StackspotAPIError } from '../error/StackspotAPIError'
8
+ import { ReactQueryNetworkClient } from '../network/ReactQueryNetworkClient'
9
+
10
+ class SecretClient extends ReactQueryNetworkClient {
11
+ constructor() {
12
+ super(apis.secrets.url, defaults)
13
+ }
14
+
15
+ protected buildStackSpotError(error: HttpError): StackspotAPIError {
16
+ return new DefaultAPIError(error.data, error.status, secretsDictionary, error.headers)
17
+ }
18
+
19
+ /**
20
+ * Create a key
21
+ */
22
+ createKey = this.mutation(createKey)
23
+
24
+ /**
25
+ * Get all keys
26
+ */
27
+ getAllKeys = this.query(getAll1)
28
+
29
+ /**
30
+ * Delete a key
31
+ */
32
+ deleteKey = this.mutation(deleteKey)
33
+
34
+ /**
35
+ * Update a key's description
36
+ */
37
+ updateKey = this.mutation(editKey)
38
+
39
+ /**
40
+ * Get which secrets are defined or undefined for a user
41
+ */
42
+ getAvailability = this.query(getAvailability)
43
+
44
+ /**
45
+ * Update a secret's value
46
+ */
47
+ updateSecretValue = this.mutation(updateSecretValue)
48
+
49
+ /**
50
+ * Delete a secret's value
51
+ */
52
+ deleteSecretValue = this.mutation(deleteSecretValue)
53
+
54
+ }
55
+
56
+ export const secretsClient = new SecretClient()
@@ -27,10 +27,10 @@ function createMessage(raw: ErrorResponse, dictionary: Dictionary, language: Lan
27
27
  const api = raw.code?.split(/[-_]/)[0]
28
28
  const details = raw.validationDetails?.map((detail) => {
29
29
  const dict: Record<string, string> = (fieldDictionary[api?.toLowerCase() as keyof typeof fieldDictionary] ?? {})[language] ?? {}
30
- const name = dict[detail.code] || detail.field || (raw.code !== detail.code && dictionary[language][detail.code]) || ''
31
- return name ? `${name}${detail.values ? `\n${detail.values.join('\n')}` : ''}` : undefined
30
+ const name = dict[detail.code] || detail.field || (raw.code !== detail.code && dictionary[language][detail.code]) || detail.code
31
+ return detail.values?.length ? `${name}${detail.values ? `\n${detail.values.join('\n')}` : ''}` : name
32
32
  })?.filter(d => !!d)
33
- return `${title}\n${details?.join('\n')}`
33
+ return details?.length === 1 ? details[0] : `${title}\n${details?.join('\n')}`
34
34
  }
35
35
 
36
36
  /**
@@ -26,6 +26,7 @@ export const accountDictionary = {
26
26
  ACC_ACCOUNT_PARTNER_CANT_BE_INACTIVATED: 'This partner cannot be deactivated due to associated APIs or products.',
27
27
  ACC_ACCOUNT_CREATION_PARTNER_ASSOCIATION_LIMIT: 'Your account has reached the limit of associations with partner accounts.',
28
28
  ACC_INVALID_PASSWORD: "Invalid password. Please make sure it meets the requirements and hasn't been used before.",
29
+ ROLES_ALREADY_EXISTS: 'A role with this name already exists.',
29
30
  },
30
31
  pt: {
31
32
  ACC_BAD_REQUEST_ERROR: 'Os dados informados estão inválidos ou inconsistentes.',
@@ -52,5 +53,6 @@ export const accountDictionary = {
52
53
  ACC_ACCOUNT_PARTNER_CANT_BE_INACTIVATED: 'Este Parceiro não pode ser inativado devido a APIs ou produtos associados.',
53
54
  ACC_ACCOUNT_CREATION_PARTNER_ASSOCIATION_LIMIT: 'Sua conta atingiu o limite de associações com Contas de Parceiros.',
54
55
  ACC_INVALID_PASSWORD: 'Senha inválida. Verifique se ela atende aos requisitos e não foi usada anteriormente.',
56
+ ROLES_ALREADY_EXISTS: 'Já existe um papel com esse nome.',
55
57
  },
56
58
  } satisfies Dictionary
@@ -0,0 +1,14 @@
1
+ import { Dictionary } from '@stack-spot/portal-translate'
2
+
3
+ export const secretsDictionary = {
4
+ en: {
5
+ WSA_SECRET_KEY_ALREADY_EXISTS: 'Secret Key already exists.',
6
+ WSA_SECRET_KEY_NOT_FOUND: 'Secret Key not found.',
7
+ WSA_SECRET_VALUE_NOT_FOUND: 'Secret Value not found.',
8
+ },
9
+ pt: {
10
+ WSA_SECRET_KEY_ALREADY_EXISTS: 'Secret Key já existe.',
11
+ WSA_SECRET_KEY_NOT_FOUND: 'Secret Key não encontrada.',
12
+ WSA_SECRET_VALUE_NOT_FOUND: 'Valor da Secret não encontrado.',
13
+ },
14
+ } satisfies Dictionary
package/src/index.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  export { accountClient } from './client/account'
2
+ export { secretsClient } from './client/secrets'
2
3
  export { DefaultAPIError } from './error/DefaultAPIError'
3
4
  export { StackspotAPIError } from './error/StackspotAPIError'
4
5
  export { NetworkClient } from './network/NetworkClient'
@@ -76,6 +76,8 @@ export class AutoQuery<Variables, Result> extends AutoOperation<Variables> imple
76
76
  }
77
77
 
78
78
  getKey(variables?: Partial<Variables>) {
79
- return [this.apiName, this.fn.name, variables]
79
+ const key: any[] = [this.apiName, this.fn.name]
80
+ if (variables) key.push(variables)
81
+ return key
80
82
  }
81
83
  }
@@ -12,7 +12,10 @@ export class ManualInfiniteQuery<
12
12
  PageParamName extends keyof Variables,
13
13
  Accumulator extends keyof Result | ''
14
14
  > extends ManualQuery<Variables, Result> implements InfiniteQueryObject<Variables, Result, Accumulator> {
15
- constructor(config: InfiniteQueryConfig<Variables, Result, PageParamName, Accumulator> & { apiName: string }) {
15
+ constructor(
16
+ config: InfiniteQueryConfig<Variables, Result, PageParamName, Accumulator>
17
+ & { apiName: string, transformError: (error: any) => StackspotAPIError },
18
+ ) {
16
19
  super(config as FullOperationConfig<any, any>)
17
20
  }
18
21
 
@@ -22,6 +22,8 @@ export class ManualMutation<
22
22
  return await this.config.request(
23
23
  ...[abortController.signal, variables] as Variables extends void ? [AbortSignal] : [AbortSignal, Variables],
24
24
  )
25
+ } catch (error) {
26
+ throw this.config.transformError(error)
25
27
  } finally {
26
28
  this.abortMap.delete(variables)
27
29
  }
@@ -14,11 +14,19 @@ export abstract class ManualOperation<Variables extends Record<string, any> | vo
14
14
  this.config = config
15
15
  }
16
16
 
17
+ private async makePermissionRequest(variables: Partial<Record<string, any>> | undefined) {
18
+ try {
19
+ // @ts-ignore the following is correct. TS can't correctly infer the conditional type here =(
20
+ return await this.config.permission(variables)
21
+ } catch (error) {
22
+ throw this.config.transformError(error)
23
+ }
24
+ }
25
+
17
26
  isAllowed(...[variables]: Variables extends void ? [] : [variables?: Partial<Variables>]) {
18
27
  return queryClient.fetchQuery({
19
28
  queryKey: this.getPermissionKey(variables as Variables),
20
- // @ts-ignore the following is correct. TS can't correctly infer the conditional type here =(
21
- queryFn: () => this.config.permission(variables),
29
+ queryFn: () => this.makePermissionRequest(variables),
22
30
  })
23
31
  }
24
32
 
@@ -27,12 +35,15 @@ export abstract class ManualOperation<Variables extends Record<string, any> | vo
27
35
  ? [options?: Omit<UseQueryOptions, 'queryFn' | 'queryKey'>]
28
36
  : [variables?: Partial<Variables>, options?: Omit<UseQueryOptions, 'queryFn' | 'queryKey'>]
29
37
  ) {
30
- const [variables, options] = args.length === 2 ? args : [undefined, args[0]]
38
+ /* `this.config.permission` is a function with arity 0 or 1. If it accepts variables, its arity is 1. If it doesn't accept variables,
39
+ its arity is zero. We can use this information to determine what the type of `args` actually is at runtime. If variables are accepted,
40
+ than the 1st argument is the variables and the 2nd is the query options, otherwise, it has a single argument, which is the query
41
+ options. */
42
+ const [variables, options] = this.config.permission.length === 2 ? args : [undefined, args[0]]
31
43
  const result = useQuery({
32
44
  ...options,
33
45
  queryKey: this.getPermissionKey(variables as Variables),
34
- // @ts-ignore the following is correct. TS can't correctly infer the conditional type here =(
35
- queryFn: () => this.config.permission(variables),
46
+ queryFn: () => this.makePermissionRequest(variables),
36
47
  }, queryClient) as UseQueryResult<boolean, StackspotAPIError>
37
48
  return [result.data, result.isPending, result.error, result] as const
38
49
  }
@@ -26,6 +26,8 @@ export class ManualQuery<
26
26
  return await this.config.request(
27
27
  ...[abortController.signal, variables] as Variables extends void ? [AbortSignal] : [AbortSignal, Variables],
28
28
  )
29
+ } catch (error) {
30
+ throw this.config.transformError(error)
29
31
  } finally {
30
32
  this.abortMap.delete(variables)
31
33
  this.currentRequests.delete(variables)
@@ -55,16 +55,6 @@ export abstract class ReactQueryNetworkClient extends NetworkClient {
55
55
  return this.buildStackSpotError(error)
56
56
  }
57
57
 
58
- #withErrorTreatment = <Args extends any[], Result>(block: (...args: Args) => Promise<Result>): ((...args: Args) => Promise<Result>) => (
59
- async (...args) => {
60
- try {
61
- return await block(...args)
62
- } catch (error: any) {
63
- throw this.#transformError(error)
64
- }
65
- }
66
- )
67
-
68
58
  /**
69
59
  * Receives an HttpError and returns a StackspotAPIError.
70
60
  * @param error the original HttpError created by oazapfts.
@@ -120,8 +110,9 @@ export abstract class ReactQueryNetworkClient extends NetworkClient {
120
110
  : new ManualQuery({
121
111
  ...fnOrConfig,
122
112
  apiName: this.constructor.name,
123
- request: this.#withErrorTreatment(fnOrConfig.request),
124
- permission: fnOrConfig.permission ? this.#withErrorTreatment(fnOrConfig.permission) : undefined,
113
+ request: fnOrConfig.request,
114
+ permission: fnOrConfig.permission,
115
+ transformError: error => this.#transformError(error),
125
116
  })
126
117
  }
127
118
 
@@ -205,8 +196,9 @@ export abstract class ReactQueryNetworkClient extends NetworkClient {
205
196
  : new ManualInfiniteQuery({
206
197
  ...fnOrConfig,
207
198
  apiName: this.constructor.name,
208
- request: this.#withErrorTreatment(fnOrConfig.request),
209
- permission: fnOrConfig.permission ? this.#withErrorTreatment(fnOrConfig.permission) : undefined,
199
+ request: fnOrConfig.request,
200
+ permission: fnOrConfig.permission,
201
+ transformError: error => this.#transformError(error),
210
202
  })
211
203
  }
212
204
 
@@ -245,8 +237,9 @@ export abstract class ReactQueryNetworkClient extends NetworkClient {
245
237
  return new ManualMutation({
246
238
  ...fnOrConfig,
247
239
  apiName: this.constructor.name,
248
- request: this.#withErrorTreatment(fnOrConfig.request),
249
- permission: fnOrConfig.permission ? this.#withErrorTreatment(fnOrConfig.permission) : undefined,
240
+ request: fnOrConfig.request,
241
+ permission: fnOrConfig.permission,
242
+ transformError: error => this.#transformError(error),
250
243
  })
251
244
  }
252
245
  }
@@ -88,6 +88,7 @@ export interface FullOperationConfig<
88
88
  * The name of the API where this operation is called: used for composing a query key.
89
89
  */
90
90
  apiName: string,
91
+ transformError: (error: any) => StackspotAPIError,
91
92
  }
92
93
 
93
94
  export type InfiniteQueryConfig<