@shipfox/client-integrations 5.0.0 → 6.0.2

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 (187) hide show
  1. package/.turbo/turbo-build.log +1 -1
  2. package/CHANGELOG.md +84 -0
  3. package/dist/application/complete-integration-callback.d.ts +13 -0
  4. package/dist/application/complete-integration-callback.d.ts.map +1 -0
  5. package/dist/application/complete-integration-callback.js +26 -0
  6. package/dist/application/complete-integration-callback.js.map +1 -0
  7. package/dist/components/connection-picker.d.ts +2 -2
  8. package/dist/components/connection-picker.d.ts.map +1 -1
  9. package/dist/components/connection-picker.js +4 -4
  10. package/dist/components/connection-picker.js.map +1 -1
  11. package/dist/components/installed-integrations-section.d.ts +8 -6
  12. package/dist/components/installed-integrations-section.d.ts.map +1 -1
  13. package/dist/components/installed-integrations-section.js +22 -15
  14. package/dist/components/installed-integrations-section.js.map +1 -1
  15. package/dist/components/integration-gallery-for-workspace.d.ts +2 -2
  16. package/dist/components/integration-gallery-for-workspace.d.ts.map +1 -1
  17. package/dist/components/integration-gallery-for-workspace.js +14 -7
  18. package/dist/components/integration-gallery-for-workspace.js.map +1 -1
  19. package/dist/components/integration-gallery.d.ts +2 -2
  20. package/dist/components/integration-gallery.d.ts.map +1 -1
  21. package/dist/components/integration-gallery.js.map +1 -1
  22. package/dist/components/integration-usage-events.d.ts +1 -3
  23. package/dist/components/integration-usage-events.d.ts.map +1 -1
  24. package/dist/components/integration-usage-events.js +1 -125
  25. package/dist/components/integration-usage-events.js.map +1 -1
  26. package/dist/components/integration-usage-modal.d.ts +2 -2
  27. package/dist/components/integration-usage-modal.d.ts.map +1 -1
  28. package/dist/components/integration-usage-modal.js +2 -2
  29. package/dist/components/integration-usage-modal.js.map +1 -1
  30. package/dist/components/provider-grid.d.ts +7 -4
  31. package/dist/components/provider-grid.d.ts.map +1 -1
  32. package/dist/components/provider-grid.js +15 -10
  33. package/dist/components/provider-grid.js.map +1 -1
  34. package/dist/components/redirect-install-page.d.ts +2 -3
  35. package/dist/components/redirect-install-page.d.ts.map +1 -1
  36. package/dist/components/redirect-install-page.js +1 -1
  37. package/dist/components/redirect-install-page.js.map +1 -1
  38. package/dist/components/repository-picker.d.ts +2 -2
  39. package/dist/components/repository-picker.d.ts.map +1 -1
  40. package/dist/components/repository-picker.js +4 -4
  41. package/dist/components/repository-picker.js.map +1 -1
  42. package/dist/components/webhook/webhook-create-modal.d.ts +2 -2
  43. package/dist/components/webhook/webhook-create-modal.d.ts.map +1 -1
  44. package/dist/components/webhook/webhook-create-modal.js +8 -8
  45. package/dist/components/webhook/webhook-create-modal.js.map +1 -1
  46. package/dist/components/webhook/webhook-modals.stories.d.ts.map +1 -1
  47. package/dist/components/webhook/webhook-modals.stories.js +7 -7
  48. package/dist/components/webhook/webhook-modals.stories.js.map +1 -1
  49. package/dist/components/webhook/webhook-usage-details.d.ts.map +1 -1
  50. package/dist/components/webhook/webhook-usage-details.js +2 -2
  51. package/dist/components/webhook/webhook-usage-details.js.map +1 -1
  52. package/dist/connection-status-badge.d.ts +2 -2
  53. package/dist/connection-status-badge.d.ts.map +1 -1
  54. package/dist/connection-status-badge.js +11 -15
  55. package/dist/connection-status-badge.js.map +1 -1
  56. package/dist/core/models.d.ts +66 -0
  57. package/dist/core/models.d.ts.map +1 -0
  58. package/dist/core/models.js +156 -0
  59. package/dist/core/models.js.map +1 -0
  60. package/dist/feature.d.ts +7 -0
  61. package/dist/feature.d.ts.map +1 -1
  62. package/dist/feature.js +10 -9
  63. package/dist/feature.js.map +1 -1
  64. package/dist/hooks/api/integration-mapper.d.ts +11 -0
  65. package/dist/hooks/api/integration-mapper.d.ts.map +1 -0
  66. package/dist/hooks/api/integration-mapper.js +54 -0
  67. package/dist/hooks/api/integration-mapper.js.map +1 -0
  68. package/dist/hooks/api/integrations.d.ts +45 -240
  69. package/dist/hooks/api/integrations.d.ts.map +1 -1
  70. package/dist/hooks/api/integrations.js +78 -31
  71. package/dist/hooks/api/integrations.js.map +1 -1
  72. package/dist/hooks/api/webhook-connections.d.ts +12 -64
  73. package/dist/hooks/api/webhook-connections.d.ts.map +1 -1
  74. package/dist/hooks/api/webhook-connections.js +17 -9
  75. package/dist/hooks/api/webhook-connections.js.map +1 -1
  76. package/dist/index.d.ts +2 -1
  77. package/dist/index.d.ts.map +1 -1
  78. package/dist/index.js +2 -1
  79. package/dist/index.js.map +1 -1
  80. package/dist/linear-callback.d.ts +2 -1
  81. package/dist/linear-callback.d.ts.map +1 -1
  82. package/dist/linear-callback.js +17 -15
  83. package/dist/linear-callback.js.map +1 -1
  84. package/dist/pages/gitea-install-page.d.ts.map +1 -1
  85. package/dist/pages/gitea-install-page.js +1 -10
  86. package/dist/pages/gitea-install-page.js.map +1 -1
  87. package/dist/pages/linear-callback-page.d.ts.map +1 -1
  88. package/dist/pages/linear-callback-page.js +19 -32
  89. package/dist/pages/linear-callback-page.js.map +1 -1
  90. package/dist/pages/linear-install-page.d.ts.map +1 -1
  91. package/dist/pages/linear-install-page.js +2 -1
  92. package/dist/pages/linear-install-page.js.map +1 -1
  93. package/dist/pages/sentry-callback-page.d.ts.map +1 -1
  94. package/dist/pages/sentry-callback-page.js +22 -25
  95. package/dist/pages/sentry-callback-page.js.map +1 -1
  96. package/dist/pages/sentry-install-page.d.ts.map +1 -1
  97. package/dist/pages/sentry-install-page.js +2 -1
  98. package/dist/pages/sentry-install-page.js.map +1 -1
  99. package/dist/pages/slack-callback-page.d.ts.map +1 -1
  100. package/dist/pages/slack-callback-page.js +21 -28
  101. package/dist/pages/slack-callback-page.js.map +1 -1
  102. package/dist/pages/slack-install-page.d.ts.map +1 -1
  103. package/dist/pages/slack-install-page.js +2 -1
  104. package/dist/pages/slack-install-page.js.map +1 -1
  105. package/dist/pages/source-control-onboarding-page.d.ts.map +1 -1
  106. package/dist/pages/source-control-onboarding-page.js +5 -1
  107. package/dist/pages/source-control-onboarding-page.js.map +1 -1
  108. package/dist/provider-catalog.d.ts.map +1 -1
  109. package/dist/provider-catalog.js +7 -6
  110. package/dist/provider-catalog.js.map +1 -1
  111. package/dist/routes/github-callback.d.ts +16 -0
  112. package/dist/routes/github-callback.d.ts.map +1 -1
  113. package/dist/routes/github-callback.js +43 -21
  114. package/dist/routes/github-callback.js.map +1 -1
  115. package/dist/routes/linear-callback.d.ts +2 -0
  116. package/dist/routes/linear-callback.d.ts.map +1 -1
  117. package/dist/routes/linear-callback.js +2 -0
  118. package/dist/routes/linear-callback.js.map +1 -1
  119. package/dist/routes/sentry-callback.d.ts +2 -0
  120. package/dist/routes/sentry-callback.d.ts.map +1 -1
  121. package/dist/routes/sentry-callback.js +2 -0
  122. package/dist/routes/sentry-callback.js.map +1 -1
  123. package/dist/routes/slack-callback.d.ts +2 -0
  124. package/dist/routes/slack-callback.d.ts.map +1 -1
  125. package/dist/routes/slack-callback.js +2 -0
  126. package/dist/routes/slack-callback.js.map +1 -1
  127. package/dist/sentry-callback.d.ts +2 -1
  128. package/dist/sentry-callback.d.ts.map +1 -1
  129. package/dist/sentry-callback.js +18 -19
  130. package/dist/sentry-callback.js.map +1 -1
  131. package/dist/slack-callback.d.ts +2 -1
  132. package/dist/slack-callback.d.ts.map +1 -1
  133. package/dist/slack-callback.js +17 -15
  134. package/dist/slack-callback.js.map +1 -1
  135. package/dist/tsconfig.test.tsbuildinfo +1 -1
  136. package/package.json +17 -17
  137. package/src/application/complete-integration-callback.test.ts +41 -0
  138. package/src/application/complete-integration-callback.ts +39 -0
  139. package/src/components/connection-picker.tsx +7 -7
  140. package/src/components/installed-integrations-section.tsx +29 -24
  141. package/src/components/integration-gallery-for-workspace.tsx +23 -16
  142. package/src/components/integration-gallery.tsx +3 -3
  143. package/src/components/integration-usage-events.ts +1 -116
  144. package/src/components/integration-usage-modal.tsx +4 -4
  145. package/src/components/provider-grid.tsx +30 -18
  146. package/src/components/redirect-install-page.test.tsx +2 -6
  147. package/src/components/redirect-install-page.tsx +3 -2
  148. package/src/components/repository-picker.tsx +6 -6
  149. package/src/components/webhook/webhook-create-modal.tsx +12 -11
  150. package/src/components/webhook/webhook-modals.stories.tsx +10 -10
  151. package/src/components/webhook/webhook-usage-details.tsx +2 -4
  152. package/src/connection-status-badge.tsx +8 -14
  153. package/src/core/models.ts +200 -0
  154. package/src/feature.ts +12 -10
  155. package/src/hooks/api/integration-mapper.ts +64 -0
  156. package/src/hooks/api/integrations.test.ts +44 -22
  157. package/src/hooks/api/integrations.ts +229 -84
  158. package/src/hooks/api/webhook-connections.ts +58 -17
  159. package/src/index.ts +2 -1
  160. package/src/linear-callback.ts +24 -16
  161. package/src/pages/gitea-install-page.tsx +1 -10
  162. package/src/pages/linear-callback-page.tsx +18 -30
  163. package/src/pages/linear-install-page.tsx +2 -1
  164. package/src/pages/sentry-callback-page.test.tsx +5 -1
  165. package/src/pages/sentry-callback-page.tsx +28 -25
  166. package/src/pages/sentry-install-page.tsx +2 -1
  167. package/src/pages/slack-callback-page.tsx +20 -26
  168. package/src/pages/slack-install-page.tsx +2 -1
  169. package/src/pages/source-control-onboarding-page.tsx +5 -1
  170. package/src/provider-catalog.ts +7 -6
  171. package/src/routes/github-callback.test.ts +35 -1
  172. package/src/routes/github-callback.tsx +47 -21
  173. package/src/routes/linear-callback.tsx +5 -1
  174. package/src/routes/sentry-callback.tsx +5 -1
  175. package/src/routes/slack-callback.tsx +6 -1
  176. package/src/sentry-callback.test.ts +2 -1
  177. package/src/sentry-callback.ts +30 -20
  178. package/src/slack-callback.ts +24 -16
  179. package/tsconfig.build.tsbuildinfo +1 -1
  180. package/vercel.json +5 -0
  181. package/dist/integration-icon.d.ts +0 -17
  182. package/dist/integration-icon.d.ts.map +0 -1
  183. package/dist/integration-icon.js +0 -22
  184. package/dist/integration-icon.js.map +0 -1
  185. package/src/integration-icon.react.test.tsx +0 -40
  186. package/src/integration-icon.test.ts +0 -19
  187. package/src/integration-icon.tsx +0 -26
@@ -1,7 +1,15 @@
1
- import { apiRequest } from '@shipfox/client-api';
2
- import { queryOptions, useInfiniteQuery, useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
1
+ import { integrationConnectionDtoSchema, listIntegrationConnectionsResponseSchema, listIntegrationProvidersResponseSchema, listRepositoriesResponseSchema } from '@shipfox/api-integration-core-dto';
2
+ import { createGiteaConnectionResponseSchema } from '@shipfox/api-integration-gitea-dto';
3
+ import { createGithubInstallResponseSchema, githubCallbackResponseSchema } from '@shipfox/api-integration-github-dto';
4
+ import { createLinearInstallResponseSchema, linearCallbackResponseSchema } from '@shipfox/api-integration-linear-dto';
5
+ import { createSentryInstallResponseSchema, sentryConnectResponseSchema } from '@shipfox/api-integration-sentry-dto';
6
+ import { createSlackInstallResponseSchema, slackCallbackResponseSchema } from '@shipfox/api-integration-slack-dto';
7
+ import { checkedApiRequest, emptyResponseSchema } from '@shipfox/client-api';
8
+ import { infiniteQueryOptions, queryOptions, useInfiniteQuery, useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
9
+ import { isUsableConnection } from '#core/models.js';
3
10
  import { serializeLinearCallbackQuery } from '#linear-callback.js';
4
11
  import { serializeSlackCallbackQuery } from '#slack-callback.js';
12
+ import { toInstallRedirect, toIntegrationConnection, toIntegrationProvider, toRepository } from './integration-mapper.js';
5
13
  export const integrationsQueryKeys = {
6
14
  all: [
7
15
  'integrations'
@@ -38,21 +46,23 @@ export async function listIntegrationProviders({ capability, signal }) {
38
46
  if (capability) search.set('capability', capability);
39
47
  const query = search.toString();
40
48
  const path = query ? `/integration-providers?${query}` : '/integration-providers';
41
- return await apiRequest(path, {
49
+ const response = await checkedApiRequest(listIntegrationProvidersResponseSchema, path, {
42
50
  signal
43
51
  });
52
+ return response.providers.map(toIntegrationProvider);
44
53
  }
45
54
  export async function listIntegrationConnections({ workspaceId, capability, signal }) {
46
55
  const search = new URLSearchParams({
47
56
  workspace_id: workspaceId
48
57
  });
49
58
  if (capability) search.set('capability', capability);
50
- return await apiRequest(`/integration-connections?${search.toString()}`, {
59
+ const response = await checkedApiRequest(listIntegrationConnectionsResponseSchema, `/integration-connections?${search.toString()}`, {
51
60
  signal
52
61
  });
62
+ return response.connections.map(toIntegrationConnection);
53
63
  }
54
64
  export async function listSourceConnections({ workspaceId, signal }) {
55
- const result = await listIntegrationConnections({
65
+ const connections = await listIntegrationConnections({
56
66
  workspaceId,
57
67
  capability: 'source_control',
58
68
  signal
@@ -60,10 +70,7 @@ export async function listSourceConnections({ workspaceId, signal }) {
60
70
  // The endpoint returns every lifecycle status (the settings hub needs that),
61
71
  // but source-control consumers (onboarding redirect, project creation) only
62
72
  // act on usable connections — a disabled/error one must read as "not there".
63
- return {
64
- ...result,
65
- connections: result.connections.filter((connection)=>connection.lifecycle_status === 'active')
66
- };
73
+ return connections.filter(isUsableConnection);
67
74
  }
68
75
  export function sourceConnectionsQueryOptions(workspaceId) {
69
76
  return queryOptions({
@@ -79,59 +86,77 @@ export function sourceConnectionsQueryOptions(workspaceId) {
79
86
  });
80
87
  }
81
88
  export async function createGiteaConnection(body) {
82
- return await apiRequest('/integrations/gitea/connections', {
89
+ const response = await checkedApiRequest(createGiteaConnectionResponseSchema, '/integrations/gitea/connections', {
83
90
  method: 'POST',
84
91
  body
85
92
  });
93
+ return toIntegrationConnection(response);
86
94
  }
87
95
  export async function createGithubInstall(body) {
88
- return await apiRequest('/integrations/github/install', {
96
+ return toInstallRedirect(await checkedApiRequest(createGithubInstallResponseSchema, '/integrations/github/install', {
89
97
  method: 'POST',
90
98
  body
99
+ }));
100
+ }
101
+ export async function completeGithubCallback({ code, installationId, state, setupAction, token }) {
102
+ const query = new URLSearchParams({
103
+ code,
104
+ installation_id: String(installationId),
105
+ state
106
+ });
107
+ if (setupAction) query.set('setup_action', setupAction);
108
+ const response = await checkedApiRequest(githubCallbackResponseSchema, `/integrations/github/callback/api?${query.toString()}`, {
109
+ headers: {
110
+ authorization: `Bearer ${token}`
111
+ }
91
112
  });
113
+ return toIntegrationConnection(response);
92
114
  }
93
115
  export async function createSentryInstall(body) {
94
- return await apiRequest('/integrations/sentry/install', {
116
+ return toInstallRedirect(await checkedApiRequest(createSentryInstallResponseSchema, '/integrations/sentry/install', {
95
117
  method: 'POST',
96
118
  body
97
- });
119
+ }));
98
120
  }
99
121
  export async function createLinearInstall(body) {
100
- return await apiRequest('/integrations/linear/install', {
122
+ return toInstallRedirect(await checkedApiRequest(createLinearInstallResponseSchema, '/integrations/linear/install', {
101
123
  method: 'POST',
102
124
  body
103
- });
125
+ }));
104
126
  }
105
127
  export async function createSlackInstall(body) {
106
- return await apiRequest('/integrations/slack/install', {
128
+ return toInstallRedirect(await checkedApiRequest(createSlackInstallResponseSchema, '/integrations/slack/install', {
107
129
  method: 'POST',
108
130
  body
109
- });
131
+ }));
110
132
  }
111
133
  export async function completeLinearCallback({ query, token }) {
112
- return await apiRequest(`/integrations/linear/callback/api?${serializeLinearCallbackQuery(query)}`, {
134
+ const response = await checkedApiRequest(linearCallbackResponseSchema, `/integrations/linear/callback/api?${serializeLinearCallbackQuery(query)}`, {
113
135
  headers: {
114
136
  authorization: `Bearer ${token}`
115
137
  }
116
138
  });
139
+ return toIntegrationConnection(response);
117
140
  }
118
141
  export async function completeSlackCallback({ query, token }) {
119
- return await apiRequest(`/integrations/slack/callback/api?${serializeSlackCallbackQuery(query)}`, {
142
+ const response = await checkedApiRequest(slackCallbackResponseSchema, `/integrations/slack/callback/api?${serializeSlackCallbackQuery(query)}`, {
120
143
  headers: {
121
144
  authorization: `Bearer ${token}`
122
145
  }
123
146
  });
147
+ return toIntegrationConnection(response);
124
148
  }
125
149
  // Called from the callback route with an explicit bearer (same as the GitHub
126
150
  // callback): the route refreshes auth itself before forwarding the grant code.
127
151
  export async function connectSentry({ body, token }) {
128
- return await apiRequest('/integrations/sentry/connect', {
152
+ const response = await checkedApiRequest(sentryConnectResponseSchema, '/integrations/sentry/connect', {
129
153
  method: 'POST',
130
154
  body,
131
155
  headers: {
132
156
  authorization: `Bearer ${token}`
133
157
  }
134
158
  });
159
+ return toIntegrationConnection(response);
135
160
  }
136
161
  export async function listRepositories({ connectionId, cursor, search, signal }) {
137
162
  const params = new URLSearchParams();
@@ -139,24 +164,33 @@ export async function listRepositories({ connectionId, cursor, search, signal })
139
164
  if (search) params.set('search', search);
140
165
  const query = params.toString();
141
166
  const path = query ? `/integration-connections/${connectionId}/repositories?${query}` : `/integration-connections/${connectionId}/repositories`;
142
- return await apiRequest(path, {
167
+ const response = await checkedApiRequest(listRepositoriesResponseSchema, path, {
143
168
  signal
144
169
  });
170
+ return {
171
+ repositories: response.repositories.map(toRepository),
172
+ ...response.next_cursor == null ? {} : {
173
+ nextCursor: response.next_cursor
174
+ }
175
+ };
145
176
  }
146
177
  export async function updateIntegrationConnection({ connectionId, body }) {
147
- return await apiRequest(`/integration-connections/${encodeURIComponent(connectionId)}`, {
178
+ const response = await checkedApiRequest(integrationConnectionDtoSchema, `/integration-connections/${encodeURIComponent(connectionId)}`, {
148
179
  method: 'PATCH',
149
180
  body
150
181
  });
182
+ return toIntegrationConnection(response);
151
183
  }
152
184
  export async function deleteIntegrationConnection({ connectionId }) {
153
- await apiRequest(`/integration-connections/${encodeURIComponent(connectionId)}`, {
185
+ await checkedApiRequest(emptyResponseSchema, `/integration-connections/${encodeURIComponent(connectionId)}`, {
154
186
  method: 'DELETE'
155
187
  });
156
188
  }
157
189
  export function useIntegrationProvidersQuery(params) {
158
- const capability = params?.capability;
159
- return useQuery({
190
+ return useQuery(integrationProvidersQueryOptions(params?.capability));
191
+ }
192
+ export function integrationProvidersQueryOptions(capability) {
193
+ return queryOptions({
160
194
  queryKey: integrationsQueryKeys.providers(capability ?? 'all'),
161
195
  queryFn: ({ signal })=>listIntegrationProviders(capability ? {
162
196
  capability,
@@ -170,7 +204,10 @@ export function useSourceConnectionsQuery(workspaceId) {
170
204
  return useQuery(sourceConnectionsQueryOptions(workspaceId));
171
205
  }
172
206
  export function useIntegrationConnectionsQuery(workspaceId) {
173
- return useQuery({
207
+ return useQuery(integrationConnectionsQueryOptions(workspaceId));
208
+ }
209
+ export function integrationConnectionsQueryOptions(workspaceId) {
210
+ return queryOptions({
174
211
  queryKey: workspaceId ? integrationsQueryKeys.connections(workspaceId, 'all') : [
175
212
  ...integrationsQueryKeys.all,
176
213
  'connections'
@@ -182,9 +219,9 @@ export function useIntegrationConnectionsQuery(workspaceId) {
182
219
  })
183
220
  });
184
221
  }
185
- export function useRepositoriesInfiniteQuery(connectionId, options) {
222
+ export function repositoriesInfiniteQueryOptions(connectionId, options) {
186
223
  const trimmedSearch = options?.search?.trim() ?? '';
187
- return useInfiniteQuery({
224
+ return infiniteQueryOptions({
188
225
  queryKey: connectionId ? integrationsQueryKeys.repositories(connectionId, trimmedSearch) : [
189
226
  ...integrationsQueryKeys.all,
190
227
  'repositories'
@@ -200,12 +237,22 @@ export function useRepositoriesInfiniteQuery(connectionId, options) {
200
237
  if (trimmedSearch) args.search = trimmedSearch;
201
238
  return listRepositories(args);
202
239
  },
203
- getNextPageParam: (lastPage)=>lastPage.next_cursor ?? undefined
240
+ getNextPageParam: (lastPage)=>lastPage.nextCursor
204
241
  });
205
242
  }
243
+ export function useRepositoriesInfiniteQuery(connectionId, options) {
244
+ return useInfiniteQuery(repositoriesInfiniteQueryOptions(connectionId, options));
245
+ }
206
246
  export function useCreateGiteaConnectionMutation() {
247
+ const queryClient = useQueryClient();
207
248
  return useMutation({
208
- mutationFn: createGiteaConnection
249
+ mutationFn: createGiteaConnection,
250
+ onSuccess: async (connection)=>{
251
+ await queryClient.invalidateQueries({
252
+ queryKey: integrationsQueryKeys.connectionsByWorkspace(connection.workspaceId),
253
+ refetchType: 'all'
254
+ });
255
+ }
209
256
  });
210
257
  }
211
258
  export function useCreateLinearInstallMutation() {
@@ -234,7 +281,7 @@ export function useUpdateIntegrationConnectionMutation() {
234
281
  mutationFn: updateIntegrationConnection,
235
282
  onSuccess: async (connection)=>{
236
283
  await queryClient.invalidateQueries({
237
- queryKey: integrationsQueryKeys.connectionsByWorkspace(connection.workspace_id)
284
+ queryKey: integrationsQueryKeys.connectionsByWorkspace(connection.workspaceId)
238
285
  });
239
286
  }
240
287
  });
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/hooks/api/integrations.ts"],"sourcesContent":["import type {\n IntegrationCapabilityDto,\n IntegrationConnectionDto,\n ListIntegrationConnectionsResponseDto,\n ListIntegrationProvidersResponseDto,\n ListRepositoriesResponseDto,\n UpdateIntegrationConnectionBodyDto,\n} from '@shipfox/api-integration-core-dto';\nimport type {\n CreateGiteaConnectionBodyDto,\n CreateGiteaConnectionResponseDto,\n} from '@shipfox/api-integration-gitea-dto';\nimport type {\n CreateGithubInstallBodyDto,\n CreateGithubInstallResponseDto,\n} from '@shipfox/api-integration-github-dto';\nimport type {\n CreateLinearInstallBodyDto,\n CreateLinearInstallResponseDto,\n LinearCallbackQueryDto,\n LinearCallbackResponseDto,\n} from '@shipfox/api-integration-linear-dto';\nimport type {\n CreateSentryInstallBodyDto,\n CreateSentryInstallResponseDto,\n SentryConnectBodyDto,\n SentryConnectResponseDto,\n} from '@shipfox/api-integration-sentry-dto';\nimport type {\n CreateSlackInstallBodyDto,\n CreateSlackInstallResponseDto,\n SlackCallbackQueryDto,\n SlackCallbackResponseDto,\n} from '@shipfox/api-integration-slack-dto';\nimport {apiRequest} from '@shipfox/client-api';\nimport {\n type FetchQueryOptions,\n queryOptions,\n useInfiniteQuery,\n useMutation,\n useQuery,\n useQueryClient,\n} from '@tanstack/react-query';\nimport {serializeLinearCallbackQuery} from '#linear-callback.js';\nimport {serializeSlackCallbackQuery} from '#slack-callback.js';\n\nexport const integrationsQueryKeys = {\n all: ['integrations'] as const,\n providers: (capability: IntegrationCapabilityDto | 'all') =>\n [...integrationsQueryKeys.all, 'providers', capability] as const,\n connections: (workspaceId: string, capability: IntegrationCapabilityDto | 'all') =>\n [...integrationsQueryKeys.all, 'connections', workspaceId, capability] as const,\n // Prefix matching every per-capability connections query for a workspace, so\n // a mutation can refresh all connection views without touching providers or\n // repositories.\n connectionsByWorkspace: (workspaceId: string) =>\n [...integrationsQueryKeys.all, 'connections', workspaceId] as const,\n sourceConnections: (workspaceId: string) =>\n integrationsQueryKeys.connections(workspaceId, 'source_control'),\n repositories: (connectionId: string, search: string) =>\n [...integrationsQueryKeys.all, 'repositories', connectionId, search] as const,\n};\n\ntype SourceConnectionsQueryKey =\n | ReturnType<typeof integrationsQueryKeys.sourceConnections>\n | readonly ['integrations', 'source-connections'];\n\ntype SourceConnectionsQueryOptions = FetchQueryOptions<\n ListIntegrationConnectionsResponseDto,\n Error,\n ListIntegrationConnectionsResponseDto,\n SourceConnectionsQueryKey\n>;\n\nexport async function listIntegrationProviders({\n capability,\n signal,\n}: {\n capability?: IntegrationCapabilityDto;\n signal?: AbortSignal;\n}) {\n const search = new URLSearchParams();\n if (capability) search.set('capability', capability);\n const query = search.toString();\n const path = query ? `/integration-providers?${query}` : '/integration-providers';\n return await apiRequest<ListIntegrationProvidersResponseDto>(path, {signal});\n}\n\nexport async function listIntegrationConnections({\n workspaceId,\n capability,\n signal,\n}: {\n workspaceId: string;\n capability?: IntegrationCapabilityDto | undefined;\n signal?: AbortSignal | undefined;\n}) {\n const search = new URLSearchParams({workspace_id: workspaceId});\n if (capability) search.set('capability', capability);\n return await apiRequest<ListIntegrationConnectionsResponseDto>(\n `/integration-connections?${search.toString()}`,\n {signal},\n );\n}\n\nexport async function listSourceConnections({\n workspaceId,\n signal,\n}: {\n workspaceId: string;\n signal?: AbortSignal;\n}) {\n const result = await listIntegrationConnections({\n workspaceId,\n capability: 'source_control',\n signal,\n });\n // The endpoint returns every lifecycle status (the settings hub needs that),\n // but source-control consumers (onboarding redirect, project creation) only\n // act on usable connections — a disabled/error one must read as \"not there\".\n return {\n ...result,\n connections: result.connections.filter(\n (connection) => connection.lifecycle_status === 'active',\n ),\n };\n}\n\nexport function sourceConnectionsQueryOptions(\n workspaceId: string | undefined,\n): SourceConnectionsQueryOptions {\n return queryOptions({\n queryKey: workspaceId\n ? integrationsQueryKeys.sourceConnections(workspaceId)\n : ([...integrationsQueryKeys.all, 'source-connections'] as const),\n enabled: Boolean(workspaceId),\n queryFn: ({signal}) => listSourceConnections({workspaceId: workspaceId ?? '', signal}),\n });\n}\n\nexport async function createGiteaConnection(body: CreateGiteaConnectionBodyDto) {\n return await apiRequest<CreateGiteaConnectionResponseDto>('/integrations/gitea/connections', {\n method: 'POST',\n body,\n });\n}\n\nexport async function createGithubInstall(body: CreateGithubInstallBodyDto) {\n return await apiRequest<CreateGithubInstallResponseDto>('/integrations/github/install', {\n method: 'POST',\n body,\n });\n}\n\nexport async function createSentryInstall(body: CreateSentryInstallBodyDto) {\n return await apiRequest<CreateSentryInstallResponseDto>('/integrations/sentry/install', {\n method: 'POST',\n body,\n });\n}\n\nexport async function createLinearInstall(body: CreateLinearInstallBodyDto) {\n return await apiRequest<CreateLinearInstallResponseDto>('/integrations/linear/install', {\n method: 'POST',\n body,\n });\n}\n\nexport async function createSlackInstall(body: CreateSlackInstallBodyDto) {\n return await apiRequest<CreateSlackInstallResponseDto>('/integrations/slack/install', {\n method: 'POST',\n body,\n });\n}\n\nexport async function completeLinearCallback({\n query,\n token,\n}: {\n query: LinearCallbackQueryDto;\n token: string;\n}) {\n return await apiRequest<LinearCallbackResponseDto>(\n `/integrations/linear/callback/api?${serializeLinearCallbackQuery(query)}`,\n {headers: {authorization: `Bearer ${token}`}},\n );\n}\n\nexport async function completeSlackCallback({\n query,\n token,\n}: {\n query: SlackCallbackQueryDto;\n token: string;\n}) {\n return await apiRequest<SlackCallbackResponseDto>(\n `/integrations/slack/callback/api?${serializeSlackCallbackQuery(query)}`,\n {headers: {authorization: `Bearer ${token}`}},\n );\n}\n\n// Called from the callback route with an explicit bearer (same as the GitHub\n// callback): the route refreshes auth itself before forwarding the grant code.\nexport async function connectSentry({body, token}: {body: SentryConnectBodyDto; token: string}) {\n return await apiRequest<SentryConnectResponseDto>('/integrations/sentry/connect', {\n method: 'POST',\n body,\n headers: {authorization: `Bearer ${token}`},\n });\n}\n\nexport async function listRepositories({\n connectionId,\n cursor,\n search,\n signal,\n}: {\n connectionId: string;\n cursor?: string;\n search?: string;\n signal?: AbortSignal;\n}) {\n const params = new URLSearchParams();\n if (cursor) params.set('cursor', cursor);\n if (search) params.set('search', search);\n const query = params.toString();\n const path = query\n ? `/integration-connections/${connectionId}/repositories?${query}`\n : `/integration-connections/${connectionId}/repositories`;\n return await apiRequest<ListRepositoriesResponseDto>(path, {signal});\n}\n\nexport async function updateIntegrationConnection({\n connectionId,\n body,\n}: {\n connectionId: string;\n body: UpdateIntegrationConnectionBodyDto;\n}) {\n return await apiRequest<IntegrationConnectionDto>(\n `/integration-connections/${encodeURIComponent(connectionId)}`,\n {method: 'PATCH', body},\n );\n}\n\nexport async function deleteIntegrationConnection({connectionId}: {connectionId: string}) {\n await apiRequest<void>(`/integration-connections/${encodeURIComponent(connectionId)}`, {\n method: 'DELETE',\n });\n}\n\nexport function useIntegrationProvidersQuery(params?: {capability?: IntegrationCapabilityDto}) {\n const capability = params?.capability;\n return useQuery({\n queryKey: integrationsQueryKeys.providers(capability ?? 'all'),\n queryFn: ({signal}) => listIntegrationProviders(capability ? {capability, signal} : {signal}),\n });\n}\n\nexport function useSourceConnectionsQuery(workspaceId: string | undefined) {\n return useQuery(sourceConnectionsQueryOptions(workspaceId));\n}\n\nexport function useIntegrationConnectionsQuery(workspaceId: string | undefined) {\n return useQuery({\n queryKey: workspaceId\n ? integrationsQueryKeys.connections(workspaceId, 'all')\n : [...integrationsQueryKeys.all, 'connections'],\n enabled: Boolean(workspaceId),\n queryFn: ({signal}) => listIntegrationConnections({workspaceId: workspaceId ?? '', signal}),\n });\n}\n\nexport function useRepositoriesInfiniteQuery(\n connectionId: string | undefined,\n options?: {search?: string},\n) {\n const trimmedSearch = options?.search?.trim() ?? '';\n return useInfiniteQuery({\n queryKey: connectionId\n ? integrationsQueryKeys.repositories(connectionId, trimmedSearch)\n : [...integrationsQueryKeys.all, 'repositories'],\n enabled: Boolean(connectionId),\n initialPageParam: undefined as string | undefined,\n queryFn: ({pageParam, signal}) => {\n const args: {connectionId: string; cursor?: string; search?: string; signal: AbortSignal} = {\n connectionId: connectionId ?? '',\n signal,\n };\n if (pageParam) args.cursor = pageParam;\n if (trimmedSearch) args.search = trimmedSearch;\n return listRepositories(args);\n },\n getNextPageParam: (lastPage) => lastPage.next_cursor ?? undefined,\n });\n}\n\nexport function useCreateGiteaConnectionMutation() {\n return useMutation({mutationFn: createGiteaConnection});\n}\n\nexport function useCreateLinearInstallMutation() {\n return useMutation({mutationFn: createLinearInstall});\n}\n\nexport function useCreateSlackInstallMutation() {\n return useMutation({mutationFn: createSlackInstall});\n}\n\nexport function useCompleteLinearCallbackMutation() {\n return useMutation({mutationFn: completeLinearCallback});\n}\n\nexport function useCompleteSlackCallbackMutation() {\n return useMutation({mutationFn: completeSlackCallback});\n}\n\nexport function useUpdateIntegrationConnectionMutation() {\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: updateIntegrationConnection,\n onSuccess: async (connection) => {\n await queryClient.invalidateQueries({\n queryKey: integrationsQueryKeys.connectionsByWorkspace(connection.workspace_id),\n });\n },\n });\n}\n\nexport function useDeleteIntegrationConnectionMutation() {\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: ({\n workspaceId: _workspaceId,\n connectionId,\n }: {\n workspaceId: string;\n connectionId: string;\n }) => deleteIntegrationConnection({connectionId}),\n onSuccess: async (_result, variables) => {\n await queryClient.invalidateQueries({\n queryKey: integrationsQueryKeys.connectionsByWorkspace(variables.workspaceId),\n });\n },\n });\n}\n"],"names":["apiRequest","queryOptions","useInfiniteQuery","useMutation","useQuery","useQueryClient","serializeLinearCallbackQuery","serializeSlackCallbackQuery","integrationsQueryKeys","all","providers","capability","connections","workspaceId","connectionsByWorkspace","sourceConnections","repositories","connectionId","search","listIntegrationProviders","signal","URLSearchParams","set","query","toString","path","listIntegrationConnections","workspace_id","listSourceConnections","result","filter","connection","lifecycle_status","sourceConnectionsQueryOptions","queryKey","enabled","Boolean","queryFn","createGiteaConnection","body","method","createGithubInstall","createSentryInstall","createLinearInstall","createSlackInstall","completeLinearCallback","token","headers","authorization","completeSlackCallback","connectSentry","listRepositories","cursor","params","updateIntegrationConnection","encodeURIComponent","deleteIntegrationConnection","useIntegrationProvidersQuery","useSourceConnectionsQuery","useIntegrationConnectionsQuery","useRepositoriesInfiniteQuery","options","trimmedSearch","trim","initialPageParam","undefined","pageParam","args","getNextPageParam","lastPage","next_cursor","useCreateGiteaConnectionMutation","mutationFn","useCreateLinearInstallMutation","useCreateSlackInstallMutation","useCompleteLinearCallbackMutation","useCompleteSlackCallbackMutation","useUpdateIntegrationConnectionMutation","queryClient","onSuccess","invalidateQueries","useDeleteIntegrationConnectionMutation","_workspaceId","_result","variables"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../src/hooks/api/integrations.ts"],"sourcesContent":["import type {\n IntegrationCapabilityDto,\n UpdateIntegrationConnectionBodyDto,\n} from '@shipfox/api-integration-core-dto';\nimport {\n integrationConnectionDtoSchema,\n listIntegrationConnectionsResponseSchema,\n listIntegrationProvidersResponseSchema,\n listRepositoriesResponseSchema,\n} from '@shipfox/api-integration-core-dto';\nimport type {CreateGiteaConnectionBodyDto} from '@shipfox/api-integration-gitea-dto';\nimport {createGiteaConnectionResponseSchema} from '@shipfox/api-integration-gitea-dto';\nimport type {CreateGithubInstallBodyDto} from '@shipfox/api-integration-github-dto';\nimport {\n createGithubInstallResponseSchema,\n githubCallbackResponseSchema,\n} from '@shipfox/api-integration-github-dto';\nimport type {\n CreateLinearInstallBodyDto,\n LinearCallbackQueryDto,\n} from '@shipfox/api-integration-linear-dto';\nimport {\n createLinearInstallResponseSchema,\n linearCallbackResponseSchema,\n} from '@shipfox/api-integration-linear-dto';\nimport type {\n CreateSentryInstallBodyDto,\n SentryConnectBodyDto,\n} from '@shipfox/api-integration-sentry-dto';\nimport {\n createSentryInstallResponseSchema,\n sentryConnectResponseSchema,\n} from '@shipfox/api-integration-sentry-dto';\nimport type {\n CreateSlackInstallBodyDto,\n SlackCallbackQueryDto,\n} from '@shipfox/api-integration-slack-dto';\nimport {\n createSlackInstallResponseSchema,\n slackCallbackResponseSchema,\n} from '@shipfox/api-integration-slack-dto';\nimport {checkedApiRequest, emptyResponseSchema} from '@shipfox/client-api';\nimport {\n type FetchQueryOptions,\n type InfiniteData,\n infiniteQueryOptions,\n queryOptions,\n type UseInfiniteQueryOptions,\n useInfiniteQuery,\n useMutation,\n useQuery,\n useQueryClient,\n} from '@tanstack/react-query';\nimport {\n type InstallRedirect,\n type IntegrationConnection,\n type IntegrationProvider,\n isUsableConnection,\n type RepositoryPage,\n} from '#core/models.js';\nimport {serializeLinearCallbackQuery} from '#linear-callback.js';\nimport {serializeSlackCallbackQuery} from '#slack-callback.js';\nimport {\n toInstallRedirect,\n toIntegrationConnection,\n toIntegrationProvider,\n toRepository,\n} from './integration-mapper.js';\n\nexport const integrationsQueryKeys = {\n all: ['integrations'] as const,\n providers: (capability: IntegrationCapabilityDto | 'all') =>\n [...integrationsQueryKeys.all, 'providers', capability] as const,\n connections: (workspaceId: string, capability: IntegrationCapabilityDto | 'all') =>\n [...integrationsQueryKeys.all, 'connections', workspaceId, capability] as const,\n // Prefix matching every per-capability connections query for a workspace, so\n // a mutation can refresh all connection views without touching providers or\n // repositories.\n connectionsByWorkspace: (workspaceId: string) =>\n [...integrationsQueryKeys.all, 'connections', workspaceId] as const,\n sourceConnections: (workspaceId: string) =>\n integrationsQueryKeys.connections(workspaceId, 'source_control'),\n repositories: (connectionId: string, search: string) =>\n [...integrationsQueryKeys.all, 'repositories', connectionId, search] as const,\n};\n\ntype SourceConnectionsQueryKey =\n | ReturnType<typeof integrationsQueryKeys.sourceConnections>\n | readonly ['integrations', 'source-connections'];\n\ntype SourceConnectionsQueryOptions = FetchQueryOptions<\n IntegrationConnection[],\n Error,\n IntegrationConnection[],\n SourceConnectionsQueryKey\n>;\n\ntype ProvidersQueryKey = ReturnType<typeof integrationsQueryKeys.providers>;\n\ntype ProvidersQueryOptions = FetchQueryOptions<\n IntegrationProvider[],\n Error,\n IntegrationProvider[],\n ProvidersQueryKey\n>;\n\ntype ConnectionsQueryKey =\n | ReturnType<typeof integrationsQueryKeys.connections>\n | readonly ['integrations', 'connections'];\n\ntype ConnectionsQueryOptions = FetchQueryOptions<\n IntegrationConnection[],\n Error,\n IntegrationConnection[],\n ConnectionsQueryKey\n>;\n\ntype RepositoriesQueryKey =\n | ReturnType<typeof integrationsQueryKeys.repositories>\n | readonly ['integrations', 'repositories'];\n\ntype RepositoriesInfiniteQueryOptions = UseInfiniteQueryOptions<\n RepositoryPage,\n Error,\n InfiniteData<RepositoryPage, string | undefined>,\n RepositoriesQueryKey,\n string | undefined\n>;\n\nexport async function listIntegrationProviders({\n capability,\n signal,\n}: {\n capability?: IntegrationCapabilityDto;\n signal?: AbortSignal;\n}): Promise<IntegrationProvider[]> {\n const search = new URLSearchParams();\n if (capability) search.set('capability', capability);\n const query = search.toString();\n const path = query ? `/integration-providers?${query}` : '/integration-providers';\n const response = await checkedApiRequest(listIntegrationProvidersResponseSchema, path, {signal});\n return response.providers.map(toIntegrationProvider);\n}\n\nexport async function listIntegrationConnections({\n workspaceId,\n capability,\n signal,\n}: {\n workspaceId: string;\n capability?: IntegrationCapabilityDto | undefined;\n signal?: AbortSignal | undefined;\n}): Promise<IntegrationConnection[]> {\n const search = new URLSearchParams({workspace_id: workspaceId});\n if (capability) search.set('capability', capability);\n const response = await checkedApiRequest(\n listIntegrationConnectionsResponseSchema,\n `/integration-connections?${search.toString()}`,\n {signal},\n );\n return response.connections.map(toIntegrationConnection);\n}\n\nexport async function listSourceConnections({\n workspaceId,\n signal,\n}: {\n workspaceId: string;\n signal?: AbortSignal;\n}): Promise<IntegrationConnection[]> {\n const connections = await listIntegrationConnections({\n workspaceId,\n capability: 'source_control',\n signal,\n });\n // The endpoint returns every lifecycle status (the settings hub needs that),\n // but source-control consumers (onboarding redirect, project creation) only\n // act on usable connections — a disabled/error one must read as \"not there\".\n return connections.filter(isUsableConnection);\n}\n\nexport function sourceConnectionsQueryOptions(\n workspaceId: string | undefined,\n): SourceConnectionsQueryOptions {\n return queryOptions({\n queryKey: workspaceId\n ? integrationsQueryKeys.sourceConnections(workspaceId)\n : ([...integrationsQueryKeys.all, 'source-connections'] as const),\n enabled: Boolean(workspaceId),\n queryFn: ({signal}) => listSourceConnections({workspaceId: workspaceId ?? '', signal}),\n });\n}\n\nexport async function createGiteaConnection(\n body: CreateGiteaConnectionBodyDto,\n): Promise<IntegrationConnection> {\n const response = await checkedApiRequest(\n createGiteaConnectionResponseSchema,\n '/integrations/gitea/connections',\n {\n method: 'POST',\n body,\n },\n );\n return toIntegrationConnection(response);\n}\n\nexport async function createGithubInstall(\n body: CreateGithubInstallBodyDto,\n): Promise<InstallRedirect> {\n return toInstallRedirect(\n await checkedApiRequest(createGithubInstallResponseSchema, '/integrations/github/install', {\n method: 'POST',\n body,\n }),\n );\n}\n\nexport async function completeGithubCallback({\n code,\n installationId,\n state,\n setupAction,\n token,\n}: {\n code: string;\n installationId: number;\n state: string;\n setupAction?: string;\n token: string;\n}): Promise<IntegrationConnection> {\n const query = new URLSearchParams({code, installation_id: String(installationId), state});\n if (setupAction) query.set('setup_action', setupAction);\n const response = await checkedApiRequest(\n githubCallbackResponseSchema,\n `/integrations/github/callback/api?${query.toString()}`,\n {headers: {authorization: `Bearer ${token}`}},\n );\n return toIntegrationConnection(response);\n}\n\nexport async function createSentryInstall(\n body: CreateSentryInstallBodyDto,\n): Promise<InstallRedirect> {\n return toInstallRedirect(\n await checkedApiRequest(createSentryInstallResponseSchema, '/integrations/sentry/install', {\n method: 'POST',\n body,\n }),\n );\n}\n\nexport async function createLinearInstall(\n body: CreateLinearInstallBodyDto,\n): Promise<InstallRedirect> {\n return toInstallRedirect(\n await checkedApiRequest(createLinearInstallResponseSchema, '/integrations/linear/install', {\n method: 'POST',\n body,\n }),\n );\n}\n\nexport async function createSlackInstall(\n body: CreateSlackInstallBodyDto,\n): Promise<InstallRedirect> {\n return toInstallRedirect(\n await checkedApiRequest(createSlackInstallResponseSchema, '/integrations/slack/install', {\n method: 'POST',\n body,\n }),\n );\n}\n\nexport async function completeLinearCallback({\n query,\n token,\n}: {\n query: LinearCallbackQueryDto;\n token: string;\n}): Promise<IntegrationConnection> {\n const response = await checkedApiRequest(\n linearCallbackResponseSchema,\n `/integrations/linear/callback/api?${serializeLinearCallbackQuery(query)}`,\n {headers: {authorization: `Bearer ${token}`}},\n );\n return toIntegrationConnection(response);\n}\n\nexport async function completeSlackCallback({\n query,\n token,\n}: {\n query: SlackCallbackQueryDto;\n token: string;\n}): Promise<IntegrationConnection> {\n const response = await checkedApiRequest(\n slackCallbackResponseSchema,\n `/integrations/slack/callback/api?${serializeSlackCallbackQuery(query)}`,\n {headers: {authorization: `Bearer ${token}`}},\n );\n return toIntegrationConnection(response);\n}\n\n// Called from the callback route with an explicit bearer (same as the GitHub\n// callback): the route refreshes auth itself before forwarding the grant code.\nexport async function connectSentry({body, token}: {body: SentryConnectBodyDto; token: string}) {\n const response = await checkedApiRequest(\n sentryConnectResponseSchema,\n '/integrations/sentry/connect',\n {\n method: 'POST',\n body,\n headers: {authorization: `Bearer ${token}`},\n },\n );\n return toIntegrationConnection(response);\n}\n\nexport async function listRepositories({\n connectionId,\n cursor,\n search,\n signal,\n}: {\n connectionId: string;\n cursor?: string;\n search?: string;\n signal?: AbortSignal;\n}): Promise<RepositoryPage> {\n const params = new URLSearchParams();\n if (cursor) params.set('cursor', cursor);\n if (search) params.set('search', search);\n const query = params.toString();\n const path = query\n ? `/integration-connections/${connectionId}/repositories?${query}`\n : `/integration-connections/${connectionId}/repositories`;\n const response = await checkedApiRequest(listRepositoriesResponseSchema, path, {signal});\n return {\n repositories: response.repositories.map(toRepository),\n ...(response.next_cursor == null ? {} : {nextCursor: response.next_cursor}),\n };\n}\n\nexport async function updateIntegrationConnection({\n connectionId,\n body,\n}: {\n connectionId: string;\n body: UpdateIntegrationConnectionBodyDto;\n}): Promise<IntegrationConnection> {\n const response = await checkedApiRequest(\n integrationConnectionDtoSchema,\n `/integration-connections/${encodeURIComponent(connectionId)}`,\n {method: 'PATCH', body},\n );\n return toIntegrationConnection(response);\n}\n\nexport async function deleteIntegrationConnection({connectionId}: {connectionId: string}) {\n await checkedApiRequest(\n emptyResponseSchema,\n `/integration-connections/${encodeURIComponent(connectionId)}`,\n {\n method: 'DELETE',\n },\n );\n}\n\nexport function useIntegrationProvidersQuery(params?: {capability?: IntegrationCapabilityDto}) {\n return useQuery(integrationProvidersQueryOptions(params?.capability));\n}\n\nexport function integrationProvidersQueryOptions(\n capability?: IntegrationCapabilityDto,\n): ProvidersQueryOptions {\n return queryOptions({\n queryKey: integrationsQueryKeys.providers(capability ?? 'all'),\n queryFn: ({signal}) => listIntegrationProviders(capability ? {capability, signal} : {signal}),\n });\n}\n\nexport function useSourceConnectionsQuery(workspaceId: string | undefined) {\n return useQuery(sourceConnectionsQueryOptions(workspaceId));\n}\n\nexport function useIntegrationConnectionsQuery(workspaceId: string | undefined) {\n return useQuery(integrationConnectionsQueryOptions(workspaceId));\n}\n\nexport function integrationConnectionsQueryOptions(\n workspaceId: string | undefined,\n): ConnectionsQueryOptions {\n return queryOptions({\n queryKey: workspaceId\n ? integrationsQueryKeys.connections(workspaceId, 'all')\n : ([...integrationsQueryKeys.all, 'connections'] as const),\n enabled: Boolean(workspaceId),\n queryFn: ({signal}) => listIntegrationConnections({workspaceId: workspaceId ?? '', signal}),\n });\n}\n\nexport function repositoriesInfiniteQueryOptions(\n connectionId: string | undefined,\n options?: {search?: string},\n): RepositoriesInfiniteQueryOptions {\n const trimmedSearch = options?.search?.trim() ?? '';\n return infiniteQueryOptions({\n queryKey: connectionId\n ? integrationsQueryKeys.repositories(connectionId, trimmedSearch)\n : ([...integrationsQueryKeys.all, 'repositories'] as const),\n enabled: Boolean(connectionId),\n initialPageParam: undefined as string | undefined,\n queryFn: ({pageParam, signal}) => {\n const args: {connectionId: string; cursor?: string; search?: string; signal: AbortSignal} = {\n connectionId: connectionId ?? '',\n signal,\n };\n if (pageParam) args.cursor = pageParam;\n if (trimmedSearch) args.search = trimmedSearch;\n return listRepositories(args);\n },\n getNextPageParam: (lastPage) => lastPage.nextCursor,\n });\n}\n\nexport function useRepositoriesInfiniteQuery(\n connectionId: string | undefined,\n options?: {search?: string},\n) {\n return useInfiniteQuery(repositoriesInfiniteQueryOptions(connectionId, options));\n}\n\nexport function useCreateGiteaConnectionMutation() {\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: createGiteaConnection,\n onSuccess: async (connection) => {\n await queryClient.invalidateQueries({\n queryKey: integrationsQueryKeys.connectionsByWorkspace(connection.workspaceId),\n refetchType: 'all',\n });\n },\n });\n}\n\nexport function useCreateLinearInstallMutation() {\n return useMutation({mutationFn: createLinearInstall});\n}\n\nexport function useCreateSlackInstallMutation() {\n return useMutation({mutationFn: createSlackInstall});\n}\n\nexport function useCompleteLinearCallbackMutation() {\n return useMutation({mutationFn: completeLinearCallback});\n}\n\nexport function useCompleteSlackCallbackMutation() {\n return useMutation({mutationFn: completeSlackCallback});\n}\n\nexport function useUpdateIntegrationConnectionMutation() {\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: updateIntegrationConnection,\n onSuccess: async (connection) => {\n await queryClient.invalidateQueries({\n queryKey: integrationsQueryKeys.connectionsByWorkspace(connection.workspaceId),\n });\n },\n });\n}\n\nexport function useDeleteIntegrationConnectionMutation() {\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: ({\n workspaceId: _workspaceId,\n connectionId,\n }: {\n workspaceId: string;\n connectionId: string;\n }) => deleteIntegrationConnection({connectionId}),\n onSuccess: async (_result, variables) => {\n await queryClient.invalidateQueries({\n queryKey: integrationsQueryKeys.connectionsByWorkspace(variables.workspaceId),\n });\n },\n });\n}\n"],"names":["integrationConnectionDtoSchema","listIntegrationConnectionsResponseSchema","listIntegrationProvidersResponseSchema","listRepositoriesResponseSchema","createGiteaConnectionResponseSchema","createGithubInstallResponseSchema","githubCallbackResponseSchema","createLinearInstallResponseSchema","linearCallbackResponseSchema","createSentryInstallResponseSchema","sentryConnectResponseSchema","createSlackInstallResponseSchema","slackCallbackResponseSchema","checkedApiRequest","emptyResponseSchema","infiniteQueryOptions","queryOptions","useInfiniteQuery","useMutation","useQuery","useQueryClient","isUsableConnection","serializeLinearCallbackQuery","serializeSlackCallbackQuery","toInstallRedirect","toIntegrationConnection","toIntegrationProvider","toRepository","integrationsQueryKeys","all","providers","capability","connections","workspaceId","connectionsByWorkspace","sourceConnections","repositories","connectionId","search","listIntegrationProviders","signal","URLSearchParams","set","query","toString","path","response","map","listIntegrationConnections","workspace_id","listSourceConnections","filter","sourceConnectionsQueryOptions","queryKey","enabled","Boolean","queryFn","createGiteaConnection","body","method","createGithubInstall","completeGithubCallback","code","installationId","state","setupAction","token","installation_id","String","headers","authorization","createSentryInstall","createLinearInstall","createSlackInstall","completeLinearCallback","completeSlackCallback","connectSentry","listRepositories","cursor","params","next_cursor","nextCursor","updateIntegrationConnection","encodeURIComponent","deleteIntegrationConnection","useIntegrationProvidersQuery","integrationProvidersQueryOptions","useSourceConnectionsQuery","useIntegrationConnectionsQuery","integrationConnectionsQueryOptions","repositoriesInfiniteQueryOptions","options","trimmedSearch","trim","initialPageParam","undefined","pageParam","args","getNextPageParam","lastPage","useRepositoriesInfiniteQuery","useCreateGiteaConnectionMutation","queryClient","mutationFn","onSuccess","connection","invalidateQueries","refetchType","useCreateLinearInstallMutation","useCreateSlackInstallMutation","useCompleteLinearCallbackMutation","useCompleteSlackCallbackMutation","useUpdateIntegrationConnectionMutation","useDeleteIntegrationConnectionMutation","_workspaceId","_result","variables"],"mappings":"AAIA,SACEA,8BAA8B,EAC9BC,wCAAwC,EACxCC,sCAAsC,EACtCC,8BAA8B,QACzB,oCAAoC;AAE3C,SAAQC,mCAAmC,QAAO,qCAAqC;AAEvF,SACEC,iCAAiC,EACjCC,4BAA4B,QACvB,sCAAsC;AAK7C,SACEC,iCAAiC,EACjCC,4BAA4B,QACvB,sCAAsC;AAK7C,SACEC,iCAAiC,EACjCC,2BAA2B,QACtB,sCAAsC;AAK7C,SACEC,gCAAgC,EAChCC,2BAA2B,QACtB,qCAAqC;AAC5C,SAAQC,iBAAiB,EAAEC,mBAAmB,QAAO,sBAAsB;AAC3E,SAGEC,oBAAoB,EACpBC,YAAY,EAEZC,gBAAgB,EAChBC,WAAW,EACXC,QAAQ,EACRC,cAAc,QACT,wBAAwB;AAC/B,SAIEC,kBAAkB,QAEb,kBAAkB;AACzB,SAAQC,4BAA4B,QAAO,sBAAsB;AACjE,SAAQC,2BAA2B,QAAO,qBAAqB;AAC/D,SACEC,iBAAiB,EACjBC,uBAAuB,EACvBC,qBAAqB,EACrBC,YAAY,QACP,0BAA0B;AAEjC,OAAO,MAAMC,wBAAwB;IACnCC,KAAK;QAAC;KAAe;IACrBC,WAAW,CAACC,aACV;eAAIH,sBAAsBC,GAAG;YAAE;YAAaE;SAAW;IACzDC,aAAa,CAACC,aAAqBF,aACjC;eAAIH,sBAAsBC,GAAG;YAAE;YAAeI;YAAaF;SAAW;IACxE,6EAA6E;IAC7E,4EAA4E;IAC5E,gBAAgB;IAChBG,wBAAwB,CAACD,cACvB;eAAIL,sBAAsBC,GAAG;YAAE;YAAeI;SAAY;IAC5DE,mBAAmB,CAACF,cAClBL,sBAAsBI,WAAW,CAACC,aAAa;IACjDG,cAAc,CAACC,cAAsBC,SACnC;eAAIV,sBAAsBC,GAAG;YAAE;YAAgBQ;YAAcC;SAAO;AACxE,EAAE;AA6CF,OAAO,eAAeC,yBAAyB,EAC7CR,UAAU,EACVS,MAAM,EAIP;IACC,MAAMF,SAAS,IAAIG;IACnB,IAAIV,YAAYO,OAAOI,GAAG,CAAC,cAAcX;IACzC,MAAMY,QAAQL,OAAOM,QAAQ;IAC7B,MAAMC,OAAOF,QAAQ,CAAC,uBAAuB,EAAEA,OAAO,GAAG;IACzD,MAAMG,WAAW,MAAMjC,kBAAkBX,wCAAwC2C,MAAM;QAACL;IAAM;IAC9F,OAAOM,SAAShB,SAAS,CAACiB,GAAG,CAACrB;AAChC;AAEA,OAAO,eAAesB,2BAA2B,EAC/Cf,WAAW,EACXF,UAAU,EACVS,MAAM,EAKP;IACC,MAAMF,SAAS,IAAIG,gBAAgB;QAACQ,cAAchB;IAAW;IAC7D,IAAIF,YAAYO,OAAOI,GAAG,CAAC,cAAcX;IACzC,MAAMe,WAAW,MAAMjC,kBACrBZ,0CACA,CAAC,yBAAyB,EAAEqC,OAAOM,QAAQ,IAAI,EAC/C;QAACJ;IAAM;IAET,OAAOM,SAASd,WAAW,CAACe,GAAG,CAACtB;AAClC;AAEA,OAAO,eAAeyB,sBAAsB,EAC1CjB,WAAW,EACXO,MAAM,EAIP;IACC,MAAMR,cAAc,MAAMgB,2BAA2B;QACnDf;QACAF,YAAY;QACZS;IACF;IACA,6EAA6E;IAC7E,4EAA4E;IAC5E,6EAA6E;IAC7E,OAAOR,YAAYmB,MAAM,CAAC9B;AAC5B;AAEA,OAAO,SAAS+B,8BACdnB,WAA+B;IAE/B,OAAOjB,aAAa;QAClBqC,UAAUpB,cACNL,sBAAsBO,iBAAiB,CAACF,eACvC;eAAIL,sBAAsBC,GAAG;YAAE;SAAqB;QACzDyB,SAASC,QAAQtB;QACjBuB,SAAS,CAAC,EAAChB,MAAM,EAAC,GAAKU,sBAAsB;gBAACjB,aAAaA,eAAe;gBAAIO;YAAM;IACtF;AACF;AAEA,OAAO,eAAeiB,sBACpBC,IAAkC;IAElC,MAAMZ,WAAW,MAAMjC,kBACrBT,qCACA,mCACA;QACEuD,QAAQ;QACRD;IACF;IAEF,OAAOjC,wBAAwBqB;AACjC;AAEA,OAAO,eAAec,oBACpBF,IAAgC;IAEhC,OAAOlC,kBACL,MAAMX,kBAAkBR,mCAAmC,gCAAgC;QACzFsD,QAAQ;QACRD;IACF;AAEJ;AAEA,OAAO,eAAeG,uBAAuB,EAC3CC,IAAI,EACJC,cAAc,EACdC,KAAK,EACLC,WAAW,EACXC,KAAK,EAON;IACC,MAAMvB,QAAQ,IAAIF,gBAAgB;QAACqB;QAAMK,iBAAiBC,OAAOL;QAAiBC;IAAK;IACvF,IAAIC,aAAatB,MAAMD,GAAG,CAAC,gBAAgBuB;IAC3C,MAAMnB,WAAW,MAAMjC,kBACrBP,8BACA,CAAC,kCAAkC,EAAEqC,MAAMC,QAAQ,IAAI,EACvD;QAACyB,SAAS;YAACC,eAAe,CAAC,OAAO,EAAEJ,OAAO;QAAA;IAAC;IAE9C,OAAOzC,wBAAwBqB;AACjC;AAEA,OAAO,eAAeyB,oBACpBb,IAAgC;IAEhC,OAAOlC,kBACL,MAAMX,kBAAkBJ,mCAAmC,gCAAgC;QACzFkD,QAAQ;QACRD;IACF;AAEJ;AAEA,OAAO,eAAec,oBACpBd,IAAgC;IAEhC,OAAOlC,kBACL,MAAMX,kBAAkBN,mCAAmC,gCAAgC;QACzFoD,QAAQ;QACRD;IACF;AAEJ;AAEA,OAAO,eAAee,mBACpBf,IAA+B;IAE/B,OAAOlC,kBACL,MAAMX,kBAAkBF,kCAAkC,+BAA+B;QACvFgD,QAAQ;QACRD;IACF;AAEJ;AAEA,OAAO,eAAegB,uBAAuB,EAC3C/B,KAAK,EACLuB,KAAK,EAIN;IACC,MAAMpB,WAAW,MAAMjC,kBACrBL,8BACA,CAAC,kCAAkC,EAAEc,6BAA6BqB,QAAQ,EAC1E;QAAC0B,SAAS;YAACC,eAAe,CAAC,OAAO,EAAEJ,OAAO;QAAA;IAAC;IAE9C,OAAOzC,wBAAwBqB;AACjC;AAEA,OAAO,eAAe6B,sBAAsB,EAC1ChC,KAAK,EACLuB,KAAK,EAIN;IACC,MAAMpB,WAAW,MAAMjC,kBACrBD,6BACA,CAAC,iCAAiC,EAAEW,4BAA4BoB,QAAQ,EACxE;QAAC0B,SAAS;YAACC,eAAe,CAAC,OAAO,EAAEJ,OAAO;QAAA;IAAC;IAE9C,OAAOzC,wBAAwBqB;AACjC;AAEA,6EAA6E;AAC7E,+EAA+E;AAC/E,OAAO,eAAe8B,cAAc,EAAClB,IAAI,EAAEQ,KAAK,EAA8C;IAC5F,MAAMpB,WAAW,MAAMjC,kBACrBH,6BACA,gCACA;QACEiD,QAAQ;QACRD;QACAW,SAAS;YAACC,eAAe,CAAC,OAAO,EAAEJ,OAAO;QAAA;IAC5C;IAEF,OAAOzC,wBAAwBqB;AACjC;AAEA,OAAO,eAAe+B,iBAAiB,EACrCxC,YAAY,EACZyC,MAAM,EACNxC,MAAM,EACNE,MAAM,EAMP;IACC,MAAMuC,SAAS,IAAItC;IACnB,IAAIqC,QAAQC,OAAOrC,GAAG,CAAC,UAAUoC;IACjC,IAAIxC,QAAQyC,OAAOrC,GAAG,CAAC,UAAUJ;IACjC,MAAMK,QAAQoC,OAAOnC,QAAQ;IAC7B,MAAMC,OAAOF,QACT,CAAC,yBAAyB,EAAEN,aAAa,cAAc,EAAEM,OAAO,GAChE,CAAC,yBAAyB,EAAEN,aAAa,aAAa,CAAC;IAC3D,MAAMS,WAAW,MAAMjC,kBAAkBV,gCAAgC0C,MAAM;QAACL;IAAM;IACtF,OAAO;QACLJ,cAAcU,SAASV,YAAY,CAACW,GAAG,CAACpB;QACxC,GAAImB,SAASkC,WAAW,IAAI,OAAO,CAAC,IAAI;YAACC,YAAYnC,SAASkC,WAAW;QAAA,CAAC;IAC5E;AACF;AAEA,OAAO,eAAeE,4BAA4B,EAChD7C,YAAY,EACZqB,IAAI,EAIL;IACC,MAAMZ,WAAW,MAAMjC,kBACrBb,gCACA,CAAC,yBAAyB,EAAEmF,mBAAmB9C,eAAe,EAC9D;QAACsB,QAAQ;QAASD;IAAI;IAExB,OAAOjC,wBAAwBqB;AACjC;AAEA,OAAO,eAAesC,4BAA4B,EAAC/C,YAAY,EAAyB;IACtF,MAAMxB,kBACJC,qBACA,CAAC,yBAAyB,EAAEqE,mBAAmB9C,eAAe,EAC9D;QACEsB,QAAQ;IACV;AAEJ;AAEA,OAAO,SAAS0B,6BAA6BN,MAAgD;IAC3F,OAAO5D,SAASmE,iCAAiCP,QAAQhD;AAC3D;AAEA,OAAO,SAASuD,iCACdvD,UAAqC;IAErC,OAAOf,aAAa;QAClBqC,UAAUzB,sBAAsBE,SAAS,CAACC,cAAc;QACxDyB,SAAS,CAAC,EAAChB,MAAM,EAAC,GAAKD,yBAAyBR,aAAa;gBAACA;gBAAYS;YAAM,IAAI;gBAACA;YAAM;IAC7F;AACF;AAEA,OAAO,SAAS+C,0BAA0BtD,WAA+B;IACvE,OAAOd,SAASiC,8BAA8BnB;AAChD;AAEA,OAAO,SAASuD,+BAA+BvD,WAA+B;IAC5E,OAAOd,SAASsE,mCAAmCxD;AACrD;AAEA,OAAO,SAASwD,mCACdxD,WAA+B;IAE/B,OAAOjB,aAAa;QAClBqC,UAAUpB,cACNL,sBAAsBI,WAAW,CAACC,aAAa,SAC9C;eAAIL,sBAAsBC,GAAG;YAAE;SAAc;QAClDyB,SAASC,QAAQtB;QACjBuB,SAAS,CAAC,EAAChB,MAAM,EAAC,GAAKQ,2BAA2B;gBAACf,aAAaA,eAAe;gBAAIO;YAAM;IAC3F;AACF;AAEA,OAAO,SAASkD,iCACdrD,YAAgC,EAChCsD,OAA2B;IAE3B,MAAMC,gBAAgBD,SAASrD,QAAQuD,UAAU;IACjD,OAAO9E,qBAAqB;QAC1BsC,UAAUhB,eACNT,sBAAsBQ,YAAY,CAACC,cAAcuD,iBAChD;eAAIhE,sBAAsBC,GAAG;YAAE;SAAe;QACnDyB,SAASC,QAAQlB;QACjByD,kBAAkBC;QAClBvC,SAAS,CAAC,EAACwC,SAAS,EAAExD,MAAM,EAAC;YAC3B,MAAMyD,OAAsF;gBAC1F5D,cAAcA,gBAAgB;gBAC9BG;YACF;YACA,IAAIwD,WAAWC,KAAKnB,MAAM,GAAGkB;YAC7B,IAAIJ,eAAeK,KAAK3D,MAAM,GAAGsD;YACjC,OAAOf,iBAAiBoB;QAC1B;QACAC,kBAAkB,CAACC,WAAaA,SAASlB,UAAU;IACrD;AACF;AAEA,OAAO,SAASmB,6BACd/D,YAAgC,EAChCsD,OAA2B;IAE3B,OAAO1E,iBAAiByE,iCAAiCrD,cAAcsD;AACzE;AAEA,OAAO,SAASU;IACd,MAAMC,cAAclF;IACpB,OAAOF,YAAY;QACjBqF,YAAY9C;QACZ+C,WAAW,OAAOC;YAChB,MAAMH,YAAYI,iBAAiB,CAAC;gBAClCrD,UAAUzB,sBAAsBM,sBAAsB,CAACuE,WAAWxE,WAAW;gBAC7E0E,aAAa;YACf;QACF;IACF;AACF;AAEA,OAAO,SAASC;IACd,OAAO1F,YAAY;QAACqF,YAAY/B;IAAmB;AACrD;AAEA,OAAO,SAASqC;IACd,OAAO3F,YAAY;QAACqF,YAAY9B;IAAkB;AACpD;AAEA,OAAO,SAASqC;IACd,OAAO5F,YAAY;QAACqF,YAAY7B;IAAsB;AACxD;AAEA,OAAO,SAASqC;IACd,OAAO7F,YAAY;QAACqF,YAAY5B;IAAqB;AACvD;AAEA,OAAO,SAASqC;IACd,MAAMV,cAAclF;IACpB,OAAOF,YAAY;QACjBqF,YAAYrB;QACZsB,WAAW,OAAOC;YAChB,MAAMH,YAAYI,iBAAiB,CAAC;gBAClCrD,UAAUzB,sBAAsBM,sBAAsB,CAACuE,WAAWxE,WAAW;YAC/E;QACF;IACF;AACF;AAEA,OAAO,SAASgF;IACd,MAAMX,cAAclF;IACpB,OAAOF,YAAY;QACjBqF,YAAY,CAAC,EACXtE,aAAaiF,YAAY,EACzB7E,YAAY,EAIb,GAAK+C,4BAA4B;gBAAC/C;YAAY;QAC/CmE,WAAW,OAAOW,SAASC;YACzB,MAAMd,YAAYI,iBAAiB,CAAC;gBAClCrD,UAAUzB,sBAAsBM,sBAAsB,CAACkF,UAAUnF,WAAW;YAC9E;QACF;IACF;AACF"}
@@ -1,85 +1,32 @@
1
1
  import type { CreateWebhookConnectionBodyDto, UpdateWebhookConnectionBodyDto } from '@shipfox/api-integration-webhook-dto';
2
+ import { type FetchQueryOptions } from '@tanstack/react-query';
3
+ import type { WebhookConnection } from '#core/models.js';
2
4
  export declare const webhookConnectionsQueryKeys: {
3
5
  all: readonly ["webhook-connections"];
4
6
  list: (workspaceId: string) => readonly ["webhook-connections", "list", string];
5
7
  };
8
+ type WebhookConnectionsListQueryKey = ReturnType<typeof webhookConnectionsQueryKeys.list> | readonly ['webhook-connections', 'list'];
9
+ type WebhookConnectionsListQueryOptions = FetchQueryOptions<WebhookConnection[], Error, WebhookConnection[], WebhookConnectionsListQueryKey>;
6
10
  export declare function listWebhookConnections({ workspaceId, signal, }: {
7
11
  workspaceId: string;
8
12
  signal?: AbortSignal;
9
- }): Promise<{
10
- connections: {
11
- id: string;
12
- workspace_id: string;
13
- name: string;
14
- slug: string;
15
- lifecycle_status: "error" | "active" | "disabled";
16
- inbound_url: string;
17
- created_at: string;
18
- updated_at: string;
19
- }[];
20
- }>;
21
- export declare function createWebhookConnection(body: CreateWebhookConnectionBodyDto): Promise<{
22
- id: string;
23
- workspace_id: string;
24
- name: string;
25
- slug: string;
26
- lifecycle_status: "error" | "active" | "disabled";
27
- inbound_url: string;
28
- created_at: string;
29
- updated_at: string;
30
- }>;
13
+ }): Promise<WebhookConnection[]>;
14
+ export declare function createWebhookConnection(body: CreateWebhookConnectionBodyDto): Promise<WebhookConnection>;
31
15
  export declare function updateWebhookConnection({ connectionId, body, }: {
32
16
  connectionId: string;
33
17
  body: UpdateWebhookConnectionBodyDto;
34
- }): Promise<{
35
- id: string;
36
- workspace_id: string;
37
- name: string;
38
- slug: string;
39
- lifecycle_status: "error" | "active" | "disabled";
40
- inbound_url: string;
41
- created_at: string;
42
- updated_at: string;
43
- }>;
18
+ }): Promise<WebhookConnection>;
44
19
  export declare function deleteWebhookConnection({ connectionId }: {
45
20
  connectionId: string;
46
21
  }): Promise<void>;
47
- export declare function useWebhookConnectionsQuery(workspaceId: string | undefined): import("@tanstack/react-query").UseQueryResult<NoInfer<{
48
- connections: {
49
- id: string;
50
- workspace_id: string;
51
- name: string;
52
- slug: string;
53
- lifecycle_status: "error" | "active" | "disabled";
54
- inbound_url: string;
55
- created_at: string;
56
- updated_at: string;
57
- }[];
58
- }>, Error>;
59
- export declare function useCreateWebhookConnectionMutation(): import("@tanstack/react-query").UseMutationResult<{
60
- id: string;
61
- workspace_id: string;
62
- name: string;
63
- slug: string;
64
- lifecycle_status: "error" | "active" | "disabled";
65
- inbound_url: string;
66
- created_at: string;
67
- updated_at: string;
68
- }, Error, {
22
+ export declare function useWebhookConnectionsQuery(workspaceId: string | undefined): import("@tanstack/react-query").UseQueryResult<NoInfer<WebhookConnection[]>, Error>;
23
+ export declare function webhookConnectionsQueryOptions(workspaceId: string | undefined): WebhookConnectionsListQueryOptions;
24
+ export declare function useCreateWebhookConnectionMutation(): import("@tanstack/react-query").UseMutationResult<WebhookConnection, Error, {
69
25
  workspace_id: string;
70
26
  name: string;
71
27
  slug: string;
72
28
  }, unknown>;
73
- export declare function useUpdateWebhookConnectionMutation(): import("@tanstack/react-query").UseMutationResult<{
74
- id: string;
75
- workspace_id: string;
76
- name: string;
77
- slug: string;
78
- lifecycle_status: "error" | "active" | "disabled";
79
- inbound_url: string;
80
- created_at: string;
81
- updated_at: string;
82
- }, Error, {
29
+ export declare function useUpdateWebhookConnectionMutation(): import("@tanstack/react-query").UseMutationResult<WebhookConnection, Error, {
83
30
  workspaceId: string;
84
31
  connectionId: string;
85
32
  body: UpdateWebhookConnectionBodyDto;
@@ -88,4 +35,5 @@ export declare function useDeleteWebhookConnectionMutation(): import("@tanstack/
88
35
  workspaceId: string;
89
36
  connectionId: string;
90
37
  }, unknown>;
38
+ export {};
91
39
  //# sourceMappingURL=webhook-connections.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"webhook-connections.d.ts","sourceRoot":"","sources":["../../../src/hooks/api/webhook-connections.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,8BAA8B,EAE9B,8BAA8B,EAE/B,MAAM,sCAAsC,CAAC;AAK9C,eAAO,MAAM,2BAA2B;;wBAElB,MAAM;CAC3B,CAAC;AAEF,wBAAsB,sBAAsB,CAAC,EAC3C,WAAW,EACX,MAAM,GACP,EAAE;IACD,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB;;;;;;;;;;;GAMA;AAED,wBAAsB,uBAAuB,CAAC,IAAI,EAAE,8BAA8B;;;;;;;;;GAKjF;AAED,wBAAsB,uBAAuB,CAAC,EAC5C,YAAY,EACZ,IAAI,GACL,EAAE;IACD,YAAY,EAAE,MAAM,CAAC;IACrB,IAAI,EAAE,8BAA8B,CAAC;CACtC;;;;;;;;;GAKA;AAED,wBAAsB,uBAAuB,CAAC,EAAC,YAAY,EAAC,EAAE;IAAC,YAAY,EAAE,MAAM,CAAA;CAAC,iBAInF;AAED,wBAAgB,0BAA0B,CAAC,WAAW,EAAE,MAAM,GAAG,SAAS;;;;;;;;;;;WAQzE;AAED,wBAAgB,kCAAkC;;;;;;;;;;;;;YAQjD;AAED,wBAAgB,kCAAkC;;;;;;;;;;iBAO/B,MAAM;kBACL,MAAM;UACd,8BAA8B;YAMzC;AAED,wBAAgB,kCAAkC;iBAGH,MAAM;kBAAgB,MAAM;YAM1E"}
1
+ {"version":3,"file":"webhook-connections.d.ts","sourceRoot":"","sources":["../../../src/hooks/api/webhook-connections.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,8BAA8B,EAC9B,8BAA8B,EAC/B,MAAM,sCAAsC,CAAC;AAM9C,OAAO,EACL,KAAK,iBAAiB,EAMvB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,KAAK,EAAC,iBAAiB,EAAC,MAAM,iBAAiB,CAAC;AAIvD,eAAO,MAAM,2BAA2B;;wBAElB,MAAM;CAC3B,CAAC;AAEF,KAAK,8BAA8B,GAC/B,UAAU,CAAC,OAAO,2BAA2B,CAAC,IAAI,CAAC,GACnD,SAAS,CAAC,qBAAqB,EAAE,MAAM,CAAC,CAAC;AAE7C,KAAK,kCAAkC,GAAG,iBAAiB,CACzD,iBAAiB,EAAE,EACnB,KAAK,EACL,iBAAiB,EAAE,EACnB,8BAA8B,CAC/B,CAAC;AAEF,wBAAsB,sBAAsB,CAAC,EAC3C,WAAW,EACX,MAAM,GACP,EAAE;IACD,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB,gCAQA;AAED,wBAAsB,uBAAuB,CAAC,IAAI,EAAE,8BAA8B,8BAUjF;AAED,wBAAsB,uBAAuB,CAAC,EAC5C,YAAY,EACZ,IAAI,GACL,EAAE;IACD,YAAY,EAAE,MAAM,CAAC;IACrB,IAAI,EAAE,8BAA8B,CAAC;CACtC,8BAOA;AAED,wBAAsB,uBAAuB,CAAC,EAAC,YAAY,EAAC,EAAE;IAAC,YAAY,EAAE,MAAM,CAAA;CAAC,iBAQnF;AAED,wBAAgB,0BAA0B,CAAC,WAAW,EAAE,MAAM,GAAG,SAAS,uFAEzE;AAED,wBAAgB,8BAA8B,CAC5C,WAAW,EAAE,MAAM,GAAG,SAAS,GAC9B,kCAAkC,CAQpC;AAED,wBAAgB,kCAAkC;;;;YAQjD;AAED,wBAAgB,kCAAkC;iBAO/B,MAAM;kBACL,MAAM;UACd,8BAA8B;YAMzC;AAED,wBAAgB,kCAAkC;iBAGH,MAAM;kBAAgB,MAAM;YAM1E"}
@@ -1,5 +1,7 @@
1
- import { apiRequest } from '@shipfox/client-api';
2
- import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
1
+ import { listWebhookConnectionsResponseSchema, webhookConnectionDtoSchema } from '@shipfox/api-integration-webhook-dto';
2
+ import { checkedApiRequest, emptyResponseSchema } from '@shipfox/client-api';
3
+ import { queryOptions, useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
4
+ import { toWebhookConnection } from './integration-mapper.js';
3
5
  import { integrationsQueryKeys } from './integrations.js';
4
6
  export const webhookConnectionsQueryKeys = {
5
7
  all: [
@@ -15,29 +17,35 @@ export async function listWebhookConnections({ workspaceId, signal }) {
15
17
  const search = new URLSearchParams({
16
18
  workspace_id: workspaceId
17
19
  });
18
- return await apiRequest(`/integrations/webhook/connections?${search.toString()}`, {
20
+ const response = await checkedApiRequest(listWebhookConnectionsResponseSchema, `/integrations/webhook/connections?${search.toString()}`, {
19
21
  signal
20
22
  });
23
+ return response.connections.map(toWebhookConnection);
21
24
  }
22
25
  export async function createWebhookConnection(body) {
23
- return await apiRequest('/integrations/webhook/connections', {
26
+ const response = await checkedApiRequest(webhookConnectionDtoSchema, '/integrations/webhook/connections', {
24
27
  method: 'POST',
25
28
  body
26
29
  });
30
+ return toWebhookConnection(response);
27
31
  }
28
32
  export async function updateWebhookConnection({ connectionId, body }) {
29
- return await apiRequest(`/integrations/webhook/connections/${encodeURIComponent(connectionId)}`, {
33
+ const response = await checkedApiRequest(webhookConnectionDtoSchema, `/integrations/webhook/connections/${encodeURIComponent(connectionId)}`, {
30
34
  method: 'PATCH',
31
35
  body
32
36
  });
37
+ return toWebhookConnection(response);
33
38
  }
34
39
  export async function deleteWebhookConnection({ connectionId }) {
35
- await apiRequest(`/integrations/webhook/connections/${encodeURIComponent(connectionId)}`, {
40
+ await checkedApiRequest(emptyResponseSchema, `/integrations/webhook/connections/${encodeURIComponent(connectionId)}`, {
36
41
  method: 'DELETE'
37
42
  });
38
43
  }
39
44
  export function useWebhookConnectionsQuery(workspaceId) {
40
- return useQuery({
45
+ return useQuery(webhookConnectionsQueryOptions(workspaceId));
46
+ }
47
+ export function webhookConnectionsQueryOptions(workspaceId) {
48
+ return queryOptions({
41
49
  queryKey: workspaceId ? webhookConnectionsQueryKeys.list(workspaceId) : [
42
50
  ...webhookConnectionsQueryKeys.all,
43
51
  'list'
@@ -54,7 +62,7 @@ export function useCreateWebhookConnectionMutation() {
54
62
  return useMutation({
55
63
  mutationFn: createWebhookConnection,
56
64
  onSuccess: async (connection)=>{
57
- await invalidateWebhookConnectionViews(queryClient, connection.workspace_id);
65
+ await invalidateWebhookConnectionViews(queryClient, connection.workspaceId);
58
66
  }
59
67
  });
60
68
  }
@@ -66,7 +74,7 @@ export function useUpdateWebhookConnectionMutation() {
66
74
  body
67
75
  }),
68
76
  onSuccess: async (connection)=>{
69
- await invalidateWebhookConnectionViews(queryClient, connection.workspace_id);
77
+ await invalidateWebhookConnectionViews(queryClient, connection.workspaceId);
70
78
  }
71
79
  });
72
80
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/hooks/api/webhook-connections.ts"],"sourcesContent":["import type {\n CreateWebhookConnectionBodyDto,\n ListWebhookConnectionsResponseDto,\n UpdateWebhookConnectionBodyDto,\n WebhookConnectionDto,\n} from '@shipfox/api-integration-webhook-dto';\nimport {apiRequest} from '@shipfox/client-api';\nimport {type QueryClient, useMutation, useQuery, useQueryClient} from '@tanstack/react-query';\nimport {integrationsQueryKeys} from './integrations.js';\n\nexport const webhookConnectionsQueryKeys = {\n all: ['webhook-connections'] as const,\n list: (workspaceId: string) => [...webhookConnectionsQueryKeys.all, 'list', workspaceId] as const,\n};\n\nexport async function listWebhookConnections({\n workspaceId,\n signal,\n}: {\n workspaceId: string;\n signal?: AbortSignal;\n}) {\n const search = new URLSearchParams({workspace_id: workspaceId});\n return await apiRequest<ListWebhookConnectionsResponseDto>(\n `/integrations/webhook/connections?${search.toString()}`,\n {signal},\n );\n}\n\nexport async function createWebhookConnection(body: CreateWebhookConnectionBodyDto) {\n return await apiRequest<WebhookConnectionDto>('/integrations/webhook/connections', {\n method: 'POST',\n body,\n });\n}\n\nexport async function updateWebhookConnection({\n connectionId,\n body,\n}: {\n connectionId: string;\n body: UpdateWebhookConnectionBodyDto;\n}) {\n return await apiRequest<WebhookConnectionDto>(\n `/integrations/webhook/connections/${encodeURIComponent(connectionId)}`,\n {method: 'PATCH', body},\n );\n}\n\nexport async function deleteWebhookConnection({connectionId}: {connectionId: string}) {\n await apiRequest<void>(`/integrations/webhook/connections/${encodeURIComponent(connectionId)}`, {\n method: 'DELETE',\n });\n}\n\nexport function useWebhookConnectionsQuery(workspaceId: string | undefined) {\n return useQuery({\n queryKey: workspaceId\n ? webhookConnectionsQueryKeys.list(workspaceId)\n : [...webhookConnectionsQueryKeys.all, 'list'],\n enabled: Boolean(workspaceId),\n queryFn: ({signal}) => listWebhookConnections({workspaceId: workspaceId ?? '', signal}),\n });\n}\n\nexport function useCreateWebhookConnectionMutation() {\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: createWebhookConnection,\n onSuccess: async (connection) => {\n await invalidateWebhookConnectionViews(queryClient, connection.workspace_id);\n },\n });\n}\n\nexport function useUpdateWebhookConnectionMutation() {\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: ({\n connectionId,\n body,\n }: {\n workspaceId: string;\n connectionId: string;\n body: UpdateWebhookConnectionBodyDto;\n }) => updateWebhookConnection({connectionId, body}),\n onSuccess: async (connection) => {\n await invalidateWebhookConnectionViews(queryClient, connection.workspace_id);\n },\n });\n}\n\nexport function useDeleteWebhookConnectionMutation() {\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: ({connectionId}: {workspaceId: string; connectionId: string}) =>\n deleteWebhookConnection({connectionId}),\n onSuccess: async (_result, variables) => {\n await invalidateWebhookConnectionViews(queryClient, variables.workspaceId);\n },\n });\n}\n\nasync function invalidateWebhookConnectionViews(queryClient: QueryClient, workspaceId: string) {\n await Promise.all([\n queryClient.invalidateQueries({\n queryKey: webhookConnectionsQueryKeys.list(workspaceId),\n refetchType: 'all',\n }),\n queryClient.invalidateQueries({\n queryKey: integrationsQueryKeys.connectionsByWorkspace(workspaceId),\n refetchType: 'all',\n }),\n ]);\n}\n"],"names":["apiRequest","useMutation","useQuery","useQueryClient","integrationsQueryKeys","webhookConnectionsQueryKeys","all","list","workspaceId","listWebhookConnections","signal","search","URLSearchParams","workspace_id","toString","createWebhookConnection","body","method","updateWebhookConnection","connectionId","encodeURIComponent","deleteWebhookConnection","useWebhookConnectionsQuery","queryKey","enabled","Boolean","queryFn","useCreateWebhookConnectionMutation","queryClient","mutationFn","onSuccess","connection","invalidateWebhookConnectionViews","useUpdateWebhookConnectionMutation","useDeleteWebhookConnectionMutation","_result","variables","Promise","invalidateQueries","refetchType","connectionsByWorkspace"],"mappings":"AAMA,SAAQA,UAAU,QAAO,sBAAsB;AAC/C,SAA0BC,WAAW,EAAEC,QAAQ,EAAEC,cAAc,QAAO,wBAAwB;AAC9F,SAAQC,qBAAqB,QAAO,oBAAoB;AAExD,OAAO,MAAMC,8BAA8B;IACzCC,KAAK;QAAC;KAAsB;IAC5BC,MAAM,CAACC,cAAwB;eAAIH,4BAA4BC,GAAG;YAAE;YAAQE;SAAY;AAC1F,EAAE;AAEF,OAAO,eAAeC,uBAAuB,EAC3CD,WAAW,EACXE,MAAM,EAIP;IACC,MAAMC,SAAS,IAAIC,gBAAgB;QAACC,cAAcL;IAAW;IAC7D,OAAO,MAAMR,WACX,CAAC,kCAAkC,EAAEW,OAAOG,QAAQ,IAAI,EACxD;QAACJ;IAAM;AAEX;AAEA,OAAO,eAAeK,wBAAwBC,IAAoC;IAChF,OAAO,MAAMhB,WAAiC,qCAAqC;QACjFiB,QAAQ;QACRD;IACF;AACF;AAEA,OAAO,eAAeE,wBAAwB,EAC5CC,YAAY,EACZH,IAAI,EAIL;IACC,OAAO,MAAMhB,WACX,CAAC,kCAAkC,EAAEoB,mBAAmBD,eAAe,EACvE;QAACF,QAAQ;QAASD;IAAI;AAE1B;AAEA,OAAO,eAAeK,wBAAwB,EAACF,YAAY,EAAyB;IAClF,MAAMnB,WAAiB,CAAC,kCAAkC,EAAEoB,mBAAmBD,eAAe,EAAE;QAC9FF,QAAQ;IACV;AACF;AAEA,OAAO,SAASK,2BAA2Bd,WAA+B;IACxE,OAAON,SAAS;QACdqB,UAAUf,cACNH,4BAA4BE,IAAI,CAACC,eACjC;eAAIH,4BAA4BC,GAAG;YAAE;SAAO;QAChDkB,SAASC,QAAQjB;QACjBkB,SAAS,CAAC,EAAChB,MAAM,EAAC,GAAKD,uBAAuB;gBAACD,aAAaA,eAAe;gBAAIE;YAAM;IACvF;AACF;AAEA,OAAO,SAASiB;IACd,MAAMC,cAAczB;IACpB,OAAOF,YAAY;QACjB4B,YAAYd;QACZe,WAAW,OAAOC;YAChB,MAAMC,iCAAiCJ,aAAaG,WAAWlB,YAAY;QAC7E;IACF;AACF;AAEA,OAAO,SAASoB;IACd,MAAML,cAAczB;IACpB,OAAOF,YAAY;QACjB4B,YAAY,CAAC,EACXV,YAAY,EACZH,IAAI,EAKL,GAAKE,wBAAwB;gBAACC;gBAAcH;YAAI;QACjDc,WAAW,OAAOC;YAChB,MAAMC,iCAAiCJ,aAAaG,WAAWlB,YAAY;QAC7E;IACF;AACF;AAEA,OAAO,SAASqB;IACd,MAAMN,cAAczB;IACpB,OAAOF,YAAY;QACjB4B,YAAY,CAAC,EAACV,YAAY,EAA8C,GACtEE,wBAAwB;gBAACF;YAAY;QACvCW,WAAW,OAAOK,SAASC;YACzB,MAAMJ,iCAAiCJ,aAAaQ,UAAU5B,WAAW;QAC3E;IACF;AACF;AAEA,eAAewB,iCAAiCJ,WAAwB,EAAEpB,WAAmB;IAC3F,MAAM6B,QAAQ/B,GAAG,CAAC;QAChBsB,YAAYU,iBAAiB,CAAC;YAC5Bf,UAAUlB,4BAA4BE,IAAI,CAACC;YAC3C+B,aAAa;QACf;QACAX,YAAYU,iBAAiB,CAAC;YAC5Bf,UAAUnB,sBAAsBoC,sBAAsB,CAAChC;YACvD+B,aAAa;QACf;KACD;AACH"}
1
+ {"version":3,"sources":["../../../src/hooks/api/webhook-connections.ts"],"sourcesContent":["import type {\n CreateWebhookConnectionBodyDto,\n UpdateWebhookConnectionBodyDto,\n} from '@shipfox/api-integration-webhook-dto';\nimport {\n listWebhookConnectionsResponseSchema,\n webhookConnectionDtoSchema,\n} from '@shipfox/api-integration-webhook-dto';\nimport {checkedApiRequest, emptyResponseSchema} from '@shipfox/client-api';\nimport {\n type FetchQueryOptions,\n type QueryClient,\n queryOptions,\n useMutation,\n useQuery,\n useQueryClient,\n} from '@tanstack/react-query';\nimport type {WebhookConnection} from '#core/models.js';\nimport {toWebhookConnection} from './integration-mapper.js';\nimport {integrationsQueryKeys} from './integrations.js';\n\nexport const webhookConnectionsQueryKeys = {\n all: ['webhook-connections'] as const,\n list: (workspaceId: string) => [...webhookConnectionsQueryKeys.all, 'list', workspaceId] as const,\n};\n\ntype WebhookConnectionsListQueryKey =\n | ReturnType<typeof webhookConnectionsQueryKeys.list>\n | readonly ['webhook-connections', 'list'];\n\ntype WebhookConnectionsListQueryOptions = FetchQueryOptions<\n WebhookConnection[],\n Error,\n WebhookConnection[],\n WebhookConnectionsListQueryKey\n>;\n\nexport async function listWebhookConnections({\n workspaceId,\n signal,\n}: {\n workspaceId: string;\n signal?: AbortSignal;\n}) {\n const search = new URLSearchParams({workspace_id: workspaceId});\n const response = await checkedApiRequest(\n listWebhookConnectionsResponseSchema,\n `/integrations/webhook/connections?${search.toString()}`,\n {signal},\n );\n return response.connections.map(toWebhookConnection);\n}\n\nexport async function createWebhookConnection(body: CreateWebhookConnectionBodyDto) {\n const response = await checkedApiRequest(\n webhookConnectionDtoSchema,\n '/integrations/webhook/connections',\n {\n method: 'POST',\n body,\n },\n );\n return toWebhookConnection(response);\n}\n\nexport async function updateWebhookConnection({\n connectionId,\n body,\n}: {\n connectionId: string;\n body: UpdateWebhookConnectionBodyDto;\n}) {\n const response = await checkedApiRequest(\n webhookConnectionDtoSchema,\n `/integrations/webhook/connections/${encodeURIComponent(connectionId)}`,\n {method: 'PATCH', body},\n );\n return toWebhookConnection(response);\n}\n\nexport async function deleteWebhookConnection({connectionId}: {connectionId: string}) {\n await checkedApiRequest(\n emptyResponseSchema,\n `/integrations/webhook/connections/${encodeURIComponent(connectionId)}`,\n {\n method: 'DELETE',\n },\n );\n}\n\nexport function useWebhookConnectionsQuery(workspaceId: string | undefined) {\n return useQuery(webhookConnectionsQueryOptions(workspaceId));\n}\n\nexport function webhookConnectionsQueryOptions(\n workspaceId: string | undefined,\n): WebhookConnectionsListQueryOptions {\n return queryOptions({\n queryKey: workspaceId\n ? webhookConnectionsQueryKeys.list(workspaceId)\n : ([...webhookConnectionsQueryKeys.all, 'list'] as const),\n enabled: Boolean(workspaceId),\n queryFn: ({signal}) => listWebhookConnections({workspaceId: workspaceId ?? '', signal}),\n });\n}\n\nexport function useCreateWebhookConnectionMutation() {\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: createWebhookConnection,\n onSuccess: async (connection) => {\n await invalidateWebhookConnectionViews(queryClient, connection.workspaceId);\n },\n });\n}\n\nexport function useUpdateWebhookConnectionMutation() {\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: ({\n connectionId,\n body,\n }: {\n workspaceId: string;\n connectionId: string;\n body: UpdateWebhookConnectionBodyDto;\n }) => updateWebhookConnection({connectionId, body}),\n onSuccess: async (connection) => {\n await invalidateWebhookConnectionViews(queryClient, connection.workspaceId);\n },\n });\n}\n\nexport function useDeleteWebhookConnectionMutation() {\n const queryClient = useQueryClient();\n return useMutation({\n mutationFn: ({connectionId}: {workspaceId: string; connectionId: string}) =>\n deleteWebhookConnection({connectionId}),\n onSuccess: async (_result, variables) => {\n await invalidateWebhookConnectionViews(queryClient, variables.workspaceId);\n },\n });\n}\n\nasync function invalidateWebhookConnectionViews(queryClient: QueryClient, workspaceId: string) {\n await Promise.all([\n queryClient.invalidateQueries({\n queryKey: webhookConnectionsQueryKeys.list(workspaceId),\n refetchType: 'all',\n }),\n queryClient.invalidateQueries({\n queryKey: integrationsQueryKeys.connectionsByWorkspace(workspaceId),\n refetchType: 'all',\n }),\n ]);\n}\n"],"names":["listWebhookConnectionsResponseSchema","webhookConnectionDtoSchema","checkedApiRequest","emptyResponseSchema","queryOptions","useMutation","useQuery","useQueryClient","toWebhookConnection","integrationsQueryKeys","webhookConnectionsQueryKeys","all","list","workspaceId","listWebhookConnections","signal","search","URLSearchParams","workspace_id","response","toString","connections","map","createWebhookConnection","body","method","updateWebhookConnection","connectionId","encodeURIComponent","deleteWebhookConnection","useWebhookConnectionsQuery","webhookConnectionsQueryOptions","queryKey","enabled","Boolean","queryFn","useCreateWebhookConnectionMutation","queryClient","mutationFn","onSuccess","connection","invalidateWebhookConnectionViews","useUpdateWebhookConnectionMutation","useDeleteWebhookConnectionMutation","_result","variables","Promise","invalidateQueries","refetchType","connectionsByWorkspace"],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -1,10 +1,11 @@
1
+ export * from '@shipfox/integration-icons';
2
+ export * from '#core/models.js';
1
3
  export * from './components/connection-picker.js';
2
4
  export * from './components/integration-gallery.js';
3
5
  export * from './components/redirect-install-page.js';
4
6
  export * from './components/repository-picker.js';
5
7
  export * from './connection-status-badge.js';
6
8
  export * from './hooks/api/integrations.js';
7
- export * from './integration-icon.js';
8
9
  export * from './pages/gitea-install-page.js';
9
10
  export * from './pages/github-install-page.js';
10
11
  export * from './pages/linear-callback-page.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,mCAAmC,CAAC;AAClD,cAAc,qCAAqC,CAAC;AACpD,cAAc,uCAAuC,CAAC;AACtD,cAAc,mCAAmC,CAAC;AAClD,cAAc,8BAA8B,CAAC;AAC7C,cAAc,6BAA6B,CAAC;AAC5C,cAAc,uBAAuB,CAAC;AACtC,cAAc,+BAA+B,CAAC;AAC9C,cAAc,gCAAgC,CAAC;AAC/C,cAAc,iCAAiC,CAAC;AAChD,cAAc,gCAAgC,CAAC;AAC/C,cAAc,iCAAiC,CAAC;AAChD,cAAc,gCAAgC,CAAC;AAC/C,cAAc,gCAAgC,CAAC;AAC/C,cAAc,+BAA+B,CAAC;AAC9C,cAAc,2CAA2C,CAAC;AAC1D,cAAc,uBAAuB,CAAC;AACtC,cAAc,sBAAsB,CAAC;AACrC,cAAc,qBAAqB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,4BAA4B,CAAC;AAC3C,cAAc,iBAAiB,CAAC;AAChC,cAAc,mCAAmC,CAAC;AAClD,cAAc,qCAAqC,CAAC;AACpD,cAAc,uCAAuC,CAAC;AACtD,cAAc,mCAAmC,CAAC;AAClD,cAAc,8BAA8B,CAAC;AAC7C,cAAc,6BAA6B,CAAC;AAC5C,cAAc,+BAA+B,CAAC;AAC9C,cAAc,gCAAgC,CAAC;AAC/C,cAAc,iCAAiC,CAAC;AAChD,cAAc,gCAAgC,CAAC;AAC/C,cAAc,iCAAiC,CAAC;AAChD,cAAc,gCAAgC,CAAC;AAC/C,cAAc,gCAAgC,CAAC;AAC/C,cAAc,+BAA+B,CAAC;AAC9C,cAAc,2CAA2C,CAAC;AAC1D,cAAc,uBAAuB,CAAC;AACtC,cAAc,sBAAsB,CAAC;AACrC,cAAc,qBAAqB,CAAC"}
package/dist/index.js CHANGED
@@ -1,10 +1,11 @@
1
+ export * from '@shipfox/integration-icons';
2
+ export * from '#core/models.js';
1
3
  export * from './components/connection-picker.js';
2
4
  export * from './components/integration-gallery.js';
3
5
  export * from './components/redirect-install-page.js';
4
6
  export * from './components/repository-picker.js';
5
7
  export * from './connection-status-badge.js';
6
8
  export * from './hooks/api/integrations.js';
7
- export * from './integration-icon.js';
8
9
  export * from './pages/gitea-install-page.js';
9
10
  export * from './pages/github-install-page.js';
10
11
  export * from './pages/linear-callback-page.js';
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts"],"sourcesContent":["export * from './components/connection-picker.js';\nexport * from './components/integration-gallery.js';\nexport * from './components/redirect-install-page.js';\nexport * from './components/repository-picker.js';\nexport * from './connection-status-badge.js';\nexport * from './hooks/api/integrations.js';\nexport * from './integration-icon.js';\nexport * from './pages/gitea-install-page.js';\nexport * from './pages/github-install-page.js';\nexport * from './pages/linear-callback-page.js';\nexport * from './pages/linear-install-page.js';\nexport * from './pages/sentry-callback-page.js';\nexport * from './pages/sentry-install-page.js';\nexport * from './pages/slack-callback-page.js';\nexport * from './pages/slack-install-page.js';\nexport * from './pages/source-control-onboarding-page.js';\nexport * from './provider-catalog.js';\nexport * from './sentry-callback.js';\nexport * from './slack-callback.js';\n"],"names":[],"mappings":"AAAA,cAAc,oCAAoC;AAClD,cAAc,sCAAsC;AACpD,cAAc,wCAAwC;AACtD,cAAc,oCAAoC;AAClD,cAAc,+BAA+B;AAC7C,cAAc,8BAA8B;AAC5C,cAAc,wBAAwB;AACtC,cAAc,gCAAgC;AAC9C,cAAc,iCAAiC;AAC/C,cAAc,kCAAkC;AAChD,cAAc,iCAAiC;AAC/C,cAAc,kCAAkC;AAChD,cAAc,iCAAiC;AAC/C,cAAc,iCAAiC;AAC/C,cAAc,gCAAgC;AAC9C,cAAc,4CAA4C;AAC1D,cAAc,wBAAwB;AACtC,cAAc,uBAAuB;AACrC,cAAc,sBAAsB"}
1
+ {"version":3,"sources":["../src/index.ts"],"sourcesContent":["export * from '@shipfox/integration-icons';\nexport * from '#core/models.js';\nexport * from './components/connection-picker.js';\nexport * from './components/integration-gallery.js';\nexport * from './components/redirect-install-page.js';\nexport * from './components/repository-picker.js';\nexport * from './connection-status-badge.js';\nexport * from './hooks/api/integrations.js';\nexport * from './pages/gitea-install-page.js';\nexport * from './pages/github-install-page.js';\nexport * from './pages/linear-callback-page.js';\nexport * from './pages/linear-install-page.js';\nexport * from './pages/sentry-callback-page.js';\nexport * from './pages/sentry-install-page.js';\nexport * from './pages/slack-callback-page.js';\nexport * from './pages/slack-install-page.js';\nexport * from './pages/source-control-onboarding-page.js';\nexport * from './provider-catalog.js';\nexport * from './sentry-callback.js';\nexport * from './slack-callback.js';\n"],"names":[],"mappings":"AAAA,cAAc,6BAA6B;AAC3C,cAAc,kBAAkB;AAChC,cAAc,oCAAoC;AAClD,cAAc,sCAAsC;AACpD,cAAc,wCAAwC;AACtD,cAAc,oCAAoC;AAClD,cAAc,+BAA+B;AAC7C,cAAc,8BAA8B;AAC5C,cAAc,gCAAgC;AAC9C,cAAc,iCAAiC;AAC/C,cAAc,kCAAkC;AAChD,cAAc,iCAAiC;AAC/C,cAAc,kCAAkC;AAChD,cAAc,iCAAiC;AAC/C,cAAc,iCAAiC;AAC/C,cAAc,gCAAgC;AAC9C,cAAc,4CAA4C;AAC1D,cAAc,wBAAwB;AACtC,cAAc,uBAAuB;AACrC,cAAc,sBAAsB"}
@@ -1,6 +1,7 @@
1
1
  import type { LinearCallbackQueryDto } from '@shipfox/api-integration-linear-dto';
2
+ import { type BrowserStorage } from '@shipfox/client-ui';
2
3
  export declare const LINEAR_INSTALL_WORKSPACE_KEY = "shipfox.linear-install.workspace-id";
3
- type WorkspaceStorage = Pick<Storage, 'getItem' | 'setItem' | 'removeItem'>;
4
+ type WorkspaceStorage = BrowserStorage | undefined;
4
5
  export declare function saveLinearInstallWorkspace(storage: WorkspaceStorage, workspaceId: string): void;
5
6
  export declare function readLinearInstallWorkspace(storage: WorkspaceStorage): string | undefined;
6
7
  export declare function clearLinearInstallWorkspace(storage: WorkspaceStorage): void;