@shipfox/client-integrations 0.2.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 (243) hide show
  1. package/.storybook/main.ts +1 -0
  2. package/.storybook/preview.css +4 -0
  3. package/.storybook/preview.tsx +56 -0
  4. package/.turbo/turbo-build.log +2 -0
  5. package/.turbo/turbo-type$colon$emit.log +1 -0
  6. package/.turbo/turbo-type.log +1 -0
  7. package/CHANGELOG.md +207 -0
  8. package/LICENSE +21 -0
  9. package/dist/components/connection-picker.d.ts +7 -0
  10. package/dist/components/connection-picker.d.ts.map +1 -0
  11. package/dist/components/connection-picker.js +98 -0
  12. package/dist/components/connection-picker.js.map +1 -0
  13. package/dist/components/installed-integrations-section.d.ts +14 -0
  14. package/dist/components/installed-integrations-section.d.ts.map +1 -0
  15. package/dist/components/installed-integrations-section.js +203 -0
  16. package/dist/components/installed-integrations-section.js.map +1 -0
  17. package/dist/components/integration-delete-confirm-modal.d.ts +10 -0
  18. package/dist/components/integration-delete-confirm-modal.d.ts.map +1 -0
  19. package/dist/components/integration-delete-confirm-modal.js +61 -0
  20. package/dist/components/integration-delete-confirm-modal.js.map +1 -0
  21. package/dist/components/integration-gallery-for-workspace.d.ts +9 -0
  22. package/dist/components/integration-gallery-for-workspace.d.ts.map +1 -0
  23. package/dist/components/integration-gallery-for-workspace.js +169 -0
  24. package/dist/components/integration-gallery-for-workspace.js.map +1 -0
  25. package/dist/components/integration-gallery.d.ts +8 -0
  26. package/dist/components/integration-gallery.d.ts.map +1 -0
  27. package/dist/components/integration-gallery.js +26 -0
  28. package/dist/components/integration-gallery.js.map +1 -0
  29. package/dist/components/integration-gallery.stories.d.ts +26 -0
  30. package/dist/components/integration-gallery.stories.d.ts.map +1 -0
  31. package/dist/components/integration-gallery.stories.js +335 -0
  32. package/dist/components/integration-gallery.stories.js.map +1 -0
  33. package/dist/components/integration-usage-events.d.ts +4 -0
  34. package/dist/components/integration-usage-events.d.ts.map +1 -0
  35. package/dist/components/integration-usage-events.js +127 -0
  36. package/dist/components/integration-usage-events.js.map +1 -0
  37. package/dist/components/integration-usage-modal.d.ts +16 -0
  38. package/dist/components/integration-usage-modal.d.ts.map +1 -0
  39. package/dist/components/integration-usage-modal.js +184 -0
  40. package/dist/components/integration-usage-modal.js.map +1 -0
  41. package/dist/components/provider-grid.d.ts +14 -0
  42. package/dist/components/provider-grid.d.ts.map +1 -0
  43. package/dist/components/provider-grid.js +152 -0
  44. package/dist/components/provider-grid.js.map +1 -0
  45. package/dist/components/redirect-install-page.d.ts +19 -0
  46. package/dist/components/redirect-install-page.d.ts.map +1 -0
  47. package/dist/components/redirect-install-page.js +68 -0
  48. package/dist/components/redirect-install-page.js.map +1 -0
  49. package/dist/components/repository-picker.d.ts +15 -0
  50. package/dist/components/repository-picker.d.ts.map +1 -0
  51. package/dist/components/repository-picker.js +78 -0
  52. package/dist/components/repository-picker.js.map +1 -0
  53. package/dist/components/webhook/copyable-value.d.ts +10 -0
  54. package/dist/components/webhook/copyable-value.d.ts.map +1 -0
  55. package/dist/components/webhook/copyable-value.js +65 -0
  56. package/dist/components/webhook/copyable-value.js.map +1 -0
  57. package/dist/components/webhook/webhook-create-modal.d.ts +10 -0
  58. package/dist/components/webhook/webhook-create-modal.d.ts.map +1 -0
  59. package/dist/components/webhook/webhook-create-modal.js +233 -0
  60. package/dist/components/webhook/webhook-create-modal.js.map +1 -0
  61. package/dist/components/webhook/webhook-form-errors.d.ts +11 -0
  62. package/dist/components/webhook/webhook-form-errors.d.ts.map +1 -0
  63. package/dist/components/webhook/webhook-form-errors.js +27 -0
  64. package/dist/components/webhook/webhook-form-errors.js.map +1 -0
  65. package/dist/components/webhook/webhook-modals.stories.d.ts +25 -0
  66. package/dist/components/webhook/webhook-modals.stories.d.ts.map +1 -0
  67. package/dist/components/webhook/webhook-modals.stories.js +222 -0
  68. package/dist/components/webhook/webhook-modals.stories.js.map +1 -0
  69. package/dist/components/webhook/webhook-public-endpoint-alert.d.ts +2 -0
  70. package/dist/components/webhook/webhook-public-endpoint-alert.d.ts.map +1 -0
  71. package/dist/components/webhook/webhook-public-endpoint-alert.js +20 -0
  72. package/dist/components/webhook/webhook-public-endpoint-alert.js.map +1 -0
  73. package/dist/components/webhook/webhook-usage-details.d.ts +7 -0
  74. package/dist/components/webhook/webhook-usage-details.d.ts.map +1 -0
  75. package/dist/components/webhook/webhook-usage-details.js +49 -0
  76. package/dist/components/webhook/webhook-usage-details.js.map +1 -0
  77. package/dist/connection-status-badge.d.ts +12 -0
  78. package/dist/connection-status-badge.d.ts.map +1 -0
  79. package/dist/connection-status-badge.js +34 -0
  80. package/dist/connection-status-badge.js.map +1 -0
  81. package/dist/feature.d.ts +37 -0
  82. package/dist/feature.d.ts.map +1 -0
  83. package/dist/feature.js +48 -0
  84. package/dist/feature.js.map +1 -0
  85. package/dist/hooks/api/integrations.d.ts +265 -0
  86. package/dist/hooks/api/integrations.d.ts.map +1 -0
  87. package/dist/hooks/api/integrations.js +229 -0
  88. package/dist/hooks/api/integrations.js.map +1 -0
  89. package/dist/hooks/api/webhook-connections.d.ts +91 -0
  90. package/dist/hooks/api/webhook-connections.d.ts.map +1 -0
  91. package/dist/hooks/api/webhook-connections.js +97 -0
  92. package/dist/hooks/api/webhook-connections.js.map +1 -0
  93. package/dist/index.d.ts +17 -0
  94. package/dist/index.d.ts.map +1 -0
  95. package/dist/index.js +18 -0
  96. package/dist/index.js.map +1 -0
  97. package/dist/integration-icon.d.ts +17 -0
  98. package/dist/integration-icon.d.ts.map +1 -0
  99. package/dist/integration-icon.js +22 -0
  100. package/dist/integration-icon.js.map +1 -0
  101. package/dist/linear-callback.d.ts +17 -0
  102. package/dist/linear-callback.d.ts.map +1 -0
  103. package/dist/linear-callback.js +113 -0
  104. package/dist/linear-callback.js.map +1 -0
  105. package/dist/pages/gitea-form-errors.d.ts +11 -0
  106. package/dist/pages/gitea-form-errors.d.ts.map +1 -0
  107. package/dist/pages/gitea-form-errors.js +35 -0
  108. package/dist/pages/gitea-form-errors.js.map +1 -0
  109. package/dist/pages/gitea-install-page.d.ts +2 -0
  110. package/dist/pages/gitea-install-page.d.ts.map +1 -0
  111. package/dist/pages/gitea-install-page.js +139 -0
  112. package/dist/pages/gitea-install-page.js.map +1 -0
  113. package/dist/pages/github-install-page.d.ts +2 -0
  114. package/dist/pages/github-install-page.d.ts.map +1 -0
  115. package/dist/pages/github-install-page.js +11 -0
  116. package/dist/pages/github-install-page.js.map +1 -0
  117. package/dist/pages/linear-callback-page.d.ts +2 -0
  118. package/dist/pages/linear-callback-page.d.ts.map +1 -0
  119. package/dist/pages/linear-callback-page.js +192 -0
  120. package/dist/pages/linear-callback-page.js.map +1 -0
  121. package/dist/pages/linear-install-page.d.ts +2 -0
  122. package/dist/pages/linear-install-page.d.ts.map +1 -0
  123. package/dist/pages/linear-install-page.js +24 -0
  124. package/dist/pages/linear-install-page.js.map +1 -0
  125. package/dist/pages/sentry-callback-page.d.ts +2 -0
  126. package/dist/pages/sentry-callback-page.d.ts.map +1 -0
  127. package/dist/pages/sentry-callback-page.js +256 -0
  128. package/dist/pages/sentry-callback-page.js.map +1 -0
  129. package/dist/pages/sentry-install-page.d.ts +2 -0
  130. package/dist/pages/sentry-install-page.d.ts.map +1 -0
  131. package/dist/pages/sentry-install-page.js +17 -0
  132. package/dist/pages/sentry-install-page.js.map +1 -0
  133. package/dist/pages/source-control-onboarding-page.d.ts +2 -0
  134. package/dist/pages/source-control-onboarding-page.d.ts.map +1 -0
  135. package/dist/pages/source-control-onboarding-page.js +37 -0
  136. package/dist/pages/source-control-onboarding-page.js.map +1 -0
  137. package/dist/provider-catalog.d.ts +15 -0
  138. package/dist/provider-catalog.d.ts.map +1 -0
  139. package/dist/provider-catalog.js +28 -0
  140. package/dist/provider-catalog.js.map +1 -0
  141. package/dist/routes/gitea.d.ts +6 -0
  142. package/dist/routes/gitea.d.ts.map +1 -0
  143. package/dist/routes/gitea.js +7 -0
  144. package/dist/routes/gitea.js.map +1 -0
  145. package/dist/routes/github-callback.d.ts +6 -0
  146. package/dist/routes/github-callback.d.ts.map +1 -0
  147. package/dist/routes/github-callback.js +129 -0
  148. package/dist/routes/github-callback.js.map +1 -0
  149. package/dist/routes/github.d.ts +6 -0
  150. package/dist/routes/github.d.ts.map +1 -0
  151. package/dist/routes/github.js +7 -0
  152. package/dist/routes/github.js.map +1 -0
  153. package/dist/routes/integrations.d.ts +6 -0
  154. package/dist/routes/integrations.d.ts.map +1 -0
  155. package/dist/routes/integrations.js +7 -0
  156. package/dist/routes/integrations.js.map +1 -0
  157. package/dist/routes/linear-callback.d.ts +6 -0
  158. package/dist/routes/linear-callback.d.ts.map +1 -0
  159. package/dist/routes/linear-callback.js +7 -0
  160. package/dist/routes/linear-callback.js.map +1 -0
  161. package/dist/routes/linear.d.ts +6 -0
  162. package/dist/routes/linear.d.ts.map +1 -0
  163. package/dist/routes/linear.js +7 -0
  164. package/dist/routes/linear.js.map +1 -0
  165. package/dist/routes/sentry-callback.d.ts +6 -0
  166. package/dist/routes/sentry-callback.d.ts.map +1 -0
  167. package/dist/routes/sentry-callback.js +7 -0
  168. package/dist/routes/sentry-callback.js.map +1 -0
  169. package/dist/routes/sentry.d.ts +6 -0
  170. package/dist/routes/sentry.d.ts.map +1 -0
  171. package/dist/routes/sentry.js +7 -0
  172. package/dist/routes/sentry.js.map +1 -0
  173. package/dist/sentry-callback.d.ts +35 -0
  174. package/dist/sentry-callback.d.ts.map +1 -0
  175. package/dist/sentry-callback.js +132 -0
  176. package/dist/sentry-callback.js.map +1 -0
  177. package/dist/tsconfig.test.tsbuildinfo +1 -0
  178. package/package.json +120 -0
  179. package/src/components/connection-picker.tsx +89 -0
  180. package/src/components/installed-integrations-section.tsx +198 -0
  181. package/src/components/integration-delete-confirm-modal.tsx +62 -0
  182. package/src/components/integration-gallery-for-workspace.tsx +193 -0
  183. package/src/components/integration-gallery.stories.tsx +302 -0
  184. package/src/components/integration-gallery.test.tsx +692 -0
  185. package/src/components/integration-gallery.tsx +49 -0
  186. package/src/components/integration-usage-events.test.ts +80 -0
  187. package/src/components/integration-usage-events.ts +116 -0
  188. package/src/components/integration-usage-modal.tsx +178 -0
  189. package/src/components/provider-grid.tsx +163 -0
  190. package/src/components/redirect-install-page.test.tsx +98 -0
  191. package/src/components/redirect-install-page.tsx +68 -0
  192. package/src/components/repository-picker.tsx +102 -0
  193. package/src/components/webhook/copyable-value.test.tsx +41 -0
  194. package/src/components/webhook/copyable-value.tsx +72 -0
  195. package/src/components/webhook/webhook-create-modal.tsx +247 -0
  196. package/src/components/webhook/webhook-form-errors.test.ts +45 -0
  197. package/src/components/webhook/webhook-form-errors.ts +32 -0
  198. package/src/components/webhook/webhook-modals.stories.tsx +225 -0
  199. package/src/components/webhook/webhook-public-endpoint-alert.tsx +15 -0
  200. package/src/components/webhook/webhook-usage-details.tsx +44 -0
  201. package/src/connection-status-badge.tsx +38 -0
  202. package/src/feature.ts +47 -0
  203. package/src/hooks/api/integrations.test.ts +105 -0
  204. package/src/hooks/api/integrations.ts +287 -0
  205. package/src/hooks/api/webhook-connections.ts +115 -0
  206. package/src/index.ts +16 -0
  207. package/src/integration-icon.react.test.tsx +40 -0
  208. package/src/integration-icon.test.ts +19 -0
  209. package/src/integration-icon.tsx +26 -0
  210. package/src/linear-callback.test.ts +227 -0
  211. package/src/linear-callback.ts +136 -0
  212. package/src/pages/gitea-form-errors.test.ts +55 -0
  213. package/src/pages/gitea-form-errors.ts +36 -0
  214. package/src/pages/gitea-install-page.tsx +108 -0
  215. package/src/pages/github-install-page.tsx +11 -0
  216. package/src/pages/linear-callback-page.test.tsx +157 -0
  217. package/src/pages/linear-callback-page.tsx +175 -0
  218. package/src/pages/linear-install-page.tsx +26 -0
  219. package/src/pages/sentry-callback-page.test.tsx +205 -0
  220. package/src/pages/sentry-callback-page.tsx +238 -0
  221. package/src/pages/sentry-install-page.tsx +17 -0
  222. package/src/pages/source-control-onboarding-page.test.tsx +46 -0
  223. package/src/pages/source-control-onboarding-page.tsx +26 -0
  224. package/src/provider-catalog.test.ts +42 -0
  225. package/src/provider-catalog.ts +49 -0
  226. package/src/routes/gitea.tsx +4 -0
  227. package/src/routes/github-callback.tsx +114 -0
  228. package/src/routes/github.tsx +4 -0
  229. package/src/routes/integrations.tsx +4 -0
  230. package/src/routes/linear-callback.tsx +4 -0
  231. package/src/routes/linear.tsx +4 -0
  232. package/src/routes/sentry-callback.tsx +4 -0
  233. package/src/routes/sentry.tsx +4 -0
  234. package/src/sentry-callback.test.ts +239 -0
  235. package/src/sentry-callback.ts +142 -0
  236. package/test/render.tsx +111 -0
  237. package/test/setup.ts +3 -0
  238. package/tsconfig.build.json +9 -0
  239. package/tsconfig.build.tsbuildinfo +1 -0
  240. package/tsconfig.json +3 -0
  241. package/tsconfig.test.json +8 -0
  242. package/vercel.json +8 -0
  243. package/vitest.config.ts +75 -0
@@ -0,0 +1,97 @@
1
+ import { apiRequest } from '@shipfox/client-api';
2
+ import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
3
+ import { integrationsQueryKeys } from './integrations.js';
4
+ export const webhookConnectionsQueryKeys = {
5
+ all: [
6
+ 'webhook-connections'
7
+ ],
8
+ list: (workspaceId)=>[
9
+ ...webhookConnectionsQueryKeys.all,
10
+ 'list',
11
+ workspaceId
12
+ ]
13
+ };
14
+ export async function listWebhookConnections({ workspaceId, signal }) {
15
+ const search = new URLSearchParams({
16
+ workspace_id: workspaceId
17
+ });
18
+ return await apiRequest(`/integrations/webhook/connections?${search.toString()}`, {
19
+ signal
20
+ });
21
+ }
22
+ export async function createWebhookConnection(body) {
23
+ return await apiRequest('/integrations/webhook/connections', {
24
+ method: 'POST',
25
+ body
26
+ });
27
+ }
28
+ export async function updateWebhookConnection({ connectionId, body }) {
29
+ return await apiRequest(`/integrations/webhook/connections/${encodeURIComponent(connectionId)}`, {
30
+ method: 'PATCH',
31
+ body
32
+ });
33
+ }
34
+ export async function deleteWebhookConnection({ connectionId }) {
35
+ await apiRequest(`/integrations/webhook/connections/${encodeURIComponent(connectionId)}`, {
36
+ method: 'DELETE'
37
+ });
38
+ }
39
+ export function useWebhookConnectionsQuery(workspaceId) {
40
+ return useQuery({
41
+ queryKey: workspaceId ? webhookConnectionsQueryKeys.list(workspaceId) : [
42
+ ...webhookConnectionsQueryKeys.all,
43
+ 'list'
44
+ ],
45
+ enabled: Boolean(workspaceId),
46
+ queryFn: ({ signal })=>listWebhookConnections({
47
+ workspaceId: workspaceId ?? '',
48
+ signal
49
+ })
50
+ });
51
+ }
52
+ export function useCreateWebhookConnectionMutation() {
53
+ const queryClient = useQueryClient();
54
+ return useMutation({
55
+ mutationFn: createWebhookConnection,
56
+ onSuccess: async (connection)=>{
57
+ await invalidateWebhookConnectionViews(queryClient, connection.workspace_id);
58
+ }
59
+ });
60
+ }
61
+ export function useUpdateWebhookConnectionMutation() {
62
+ const queryClient = useQueryClient();
63
+ return useMutation({
64
+ mutationFn: ({ connectionId, body })=>updateWebhookConnection({
65
+ connectionId,
66
+ body
67
+ }),
68
+ onSuccess: async (connection)=>{
69
+ await invalidateWebhookConnectionViews(queryClient, connection.workspace_id);
70
+ }
71
+ });
72
+ }
73
+ export function useDeleteWebhookConnectionMutation() {
74
+ const queryClient = useQueryClient();
75
+ return useMutation({
76
+ mutationFn: ({ connectionId })=>deleteWebhookConnection({
77
+ connectionId
78
+ }),
79
+ onSuccess: async (_result, variables)=>{
80
+ await invalidateWebhookConnectionViews(queryClient, variables.workspaceId);
81
+ }
82
+ });
83
+ }
84
+ async function invalidateWebhookConnectionViews(queryClient, workspaceId) {
85
+ await Promise.all([
86
+ queryClient.invalidateQueries({
87
+ queryKey: webhookConnectionsQueryKeys.list(workspaceId),
88
+ refetchType: 'all'
89
+ }),
90
+ queryClient.invalidateQueries({
91
+ queryKey: integrationsQueryKeys.connectionsByWorkspace(workspaceId),
92
+ refetchType: 'all'
93
+ })
94
+ ]);
95
+ }
96
+
97
+ //# sourceMappingURL=webhook-connections.js.map
@@ -0,0 +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"}
@@ -0,0 +1,17 @@
1
+ export * from './components/connection-picker.js';
2
+ export * from './components/integration-gallery.js';
3
+ export * from './components/redirect-install-page.js';
4
+ export * from './components/repository-picker.js';
5
+ export * from './connection-status-badge.js';
6
+ export * from './hooks/api/integrations.js';
7
+ export * from './integration-icon.js';
8
+ export * from './pages/gitea-install-page.js';
9
+ export * from './pages/github-install-page.js';
10
+ export * from './pages/linear-callback-page.js';
11
+ export * from './pages/linear-install-page.js';
12
+ export * from './pages/sentry-callback-page.js';
13
+ export * from './pages/sentry-install-page.js';
14
+ export * from './pages/source-control-onboarding-page.js';
15
+ export * from './provider-catalog.js';
16
+ export * from './sentry-callback.js';
17
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +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,2CAA2C,CAAC;AAC1D,cAAc,uBAAuB,CAAC;AACtC,cAAc,sBAAsB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,18 @@
1
+ export * from './components/connection-picker.js';
2
+ export * from './components/integration-gallery.js';
3
+ export * from './components/redirect-install-page.js';
4
+ export * from './components/repository-picker.js';
5
+ export * from './connection-status-badge.js';
6
+ export * from './hooks/api/integrations.js';
7
+ export * from './integration-icon.js';
8
+ export * from './pages/gitea-install-page.js';
9
+ export * from './pages/github-install-page.js';
10
+ export * from './pages/linear-callback-page.js';
11
+ export * from './pages/linear-install-page.js';
12
+ export * from './pages/sentry-callback-page.js';
13
+ export * from './pages/sentry-install-page.js';
14
+ export * from './pages/source-control-onboarding-page.js';
15
+ export * from './provider-catalog.js';
16
+ export * from './sentry-callback.js';
17
+
18
+ //# sourceMappingURL=index.js.map
@@ -0,0 +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/source-control-onboarding-page.js';\nexport * from './provider-catalog.js';\nexport * from './sentry-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,4CAA4C;AAC1D,cAAc,wBAAwB;AACtC,cAAc,uBAAuB"}
@@ -0,0 +1,17 @@
1
+ import { Icon, type IconName } from '@shipfox/react-ui/icon';
2
+ import type { ComponentProps } from 'react';
3
+ export declare const FALLBACK_INTEGRATION_ICON: IconName;
4
+ /**
5
+ * Accepts the source strings used by connections and events; unknown values use
6
+ * the neutral fallback icon.
7
+ */
8
+ export declare function getIntegrationIcon(source: string | null | undefined): IconName;
9
+ export interface IntegrationIconProps extends Omit<ComponentProps<typeof Icon>, 'name'> {
10
+ source: string | null | undefined;
11
+ }
12
+ /**
13
+ * Preserves the base icon props so callers can decide whether the glyph is
14
+ * decorative or labeled.
15
+ */
16
+ export declare function IntegrationIcon({ source, ...props }: IntegrationIconProps): import("react").JSX.Element;
17
+ //# sourceMappingURL=integration-icon.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"integration-icon.d.ts","sourceRoot":"","sources":["../src/integration-icon.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAC,IAAI,EAAE,KAAK,QAAQ,EAAC,MAAM,wBAAwB,CAAC;AAC3D,OAAO,KAAK,EAAC,cAAc,EAAC,MAAM,OAAO,CAAC;AAG1C,eAAO,MAAM,yBAAyB,EAAE,QAA0B,CAAC;AAEnE;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,QAAQ,CAG9E;AAED,MAAM,WAAW,oBAAqB,SAAQ,IAAI,CAAC,cAAc,CAAC,OAAO,IAAI,CAAC,EAAE,MAAM,CAAC;IACrF,MAAM,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;CACnC;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,EAAC,MAAM,EAAE,GAAG,KAAK,EAAC,EAAE,oBAAoB,+BAEvE"}
@@ -0,0 +1,22 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { Icon } from '@shipfox/react-ui/icon';
3
+ import { PROVIDER_CATALOG } from '#provider-catalog.js';
4
+ export const FALLBACK_INTEGRATION_ICON = 'componentLine';
5
+ /**
6
+ * Accepts the source strings used by connections and events; unknown values use
7
+ * the neutral fallback icon.
8
+ */ export function getIntegrationIcon(source) {
9
+ if (!source) return FALLBACK_INTEGRATION_ICON;
10
+ return PROVIDER_CATALOG[source]?.iconName ?? FALLBACK_INTEGRATION_ICON;
11
+ }
12
+ /**
13
+ * Preserves the base icon props so callers can decide whether the glyph is
14
+ * decorative or labeled.
15
+ */ export function IntegrationIcon({ source, ...props }) {
16
+ return /*#__PURE__*/ _jsx(Icon, {
17
+ name: getIntegrationIcon(source),
18
+ ...props
19
+ });
20
+ }
21
+
22
+ //# sourceMappingURL=integration-icon.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/integration-icon.tsx"],"sourcesContent":["import {Icon, type IconName} from '@shipfox/react-ui/icon';\nimport type {ComponentProps} from 'react';\nimport {PROVIDER_CATALOG} from '#provider-catalog.js';\n\nexport const FALLBACK_INTEGRATION_ICON: IconName = 'componentLine';\n\n/**\n * Accepts the source strings used by connections and events; unknown values use\n * the neutral fallback icon.\n */\nexport function getIntegrationIcon(source: string | null | undefined): IconName {\n if (!source) return FALLBACK_INTEGRATION_ICON;\n return PROVIDER_CATALOG[source]?.iconName ?? FALLBACK_INTEGRATION_ICON;\n}\n\nexport interface IntegrationIconProps extends Omit<ComponentProps<typeof Icon>, 'name'> {\n source: string | null | undefined;\n}\n\n/**\n * Preserves the base icon props so callers can decide whether the glyph is\n * decorative or labeled.\n */\nexport function IntegrationIcon({source, ...props}: IntegrationIconProps) {\n return <Icon name={getIntegrationIcon(source)} {...props} />;\n}\n"],"names":["Icon","PROVIDER_CATALOG","FALLBACK_INTEGRATION_ICON","getIntegrationIcon","source","iconName","IntegrationIcon","props","name"],"mappings":";AAAA,SAAQA,IAAI,QAAsB,yBAAyB;AAE3D,SAAQC,gBAAgB,QAAO,uBAAuB;AAEtD,OAAO,MAAMC,4BAAsC,gBAAgB;AAEnE;;;CAGC,GACD,OAAO,SAASC,mBAAmBC,MAAiC;IAClE,IAAI,CAACA,QAAQ,OAAOF;IACpB,OAAOD,gBAAgB,CAACG,OAAO,EAAEC,YAAYH;AAC/C;AAMA;;;CAGC,GACD,OAAO,SAASI,gBAAgB,EAACF,MAAM,EAAE,GAAGG,OAA4B;IACtE,qBAAO,KAACP;QAAKQ,MAAML,mBAAmBC;QAAU,GAAGG,KAAK;;AAC1D"}
@@ -0,0 +1,17 @@
1
+ import type { LinearCallbackQueryDto } from '@shipfox/api-integration-linear-dto';
2
+ export declare const LINEAR_INSTALL_WORKSPACE_KEY = "shipfox.linear-install.workspace-id";
3
+ type WorkspaceStorage = Pick<Storage, 'getItem' | 'setItem' | 'removeItem'>;
4
+ export declare function saveLinearInstallWorkspace(storage: WorkspaceStorage, workspaceId: string): void;
5
+ export declare function readLinearInstallWorkspace(storage: WorkspaceStorage): string | undefined;
6
+ export declare function clearLinearInstallWorkspace(storage: WorkspaceStorage): void;
7
+ export declare function parseLinearCallbackQuery(search: Record<string, unknown>): LinearCallbackQueryDto | undefined;
8
+ export declare function serializeLinearCallbackQuery(query: LinearCallbackQueryDto): string;
9
+ export type LinearCallbackFailure = {
10
+ title?: string;
11
+ message: string;
12
+ startOver: boolean;
13
+ signIn: boolean;
14
+ };
15
+ export declare function classifyLinearCallbackError(error: unknown): LinearCallbackFailure;
16
+ export {};
17
+ //# sourceMappingURL=linear-callback.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"linear-callback.d.ts","sourceRoot":"","sources":["../src/linear-callback.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,sBAAsB,EAAC,MAAM,qCAAqC,CAAC;AAGhF,eAAO,MAAM,4BAA4B,wCAAwC,CAAC;AAElF,KAAK,gBAAgB,GAAG,IAAI,CAAC,OAAO,EAAE,SAAS,GAAG,SAAS,GAAG,YAAY,CAAC,CAAC;AAE5E,wBAAgB,0BAA0B,CAAC,OAAO,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,GAAG,IAAI,CAM/F;AAED,wBAAgB,0BAA0B,CAAC,OAAO,EAAE,gBAAgB,GAAG,MAAM,GAAG,SAAS,CAMxF;AAED,wBAAgB,2BAA2B,CAAC,OAAO,EAAE,gBAAgB,GAAG,IAAI,CAM3E;AAED,wBAAgB,wBAAwB,CACtC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC9B,sBAAsB,GAAG,SAAS,CAWpC;AAED,wBAAgB,4BAA4B,CAAC,KAAK,EAAE,sBAAsB,GAAG,MAAM,CASlF;AAED,MAAM,MAAM,qBAAqB,GAAG;IAClC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,OAAO,CAAC;IACnB,MAAM,EAAE,OAAO,CAAC;CACjB,CAAC;AAEF,wBAAgB,2BAA2B,CAAC,KAAK,EAAE,OAAO,GAAG,qBAAqB,CAmEjF"}
@@ -0,0 +1,113 @@
1
+ import { ApiError } from '@shipfox/client-api';
2
+ export const LINEAR_INSTALL_WORKSPACE_KEY = 'shipfox.linear-install.workspace-id';
3
+ export function saveLinearInstallWorkspace(storage, workspaceId) {
4
+ try {
5
+ storage.setItem(LINEAR_INSTALL_WORKSPACE_KEY, workspaceId);
6
+ } catch {
7
+ // Storage only improves recovery navigation; callback input always comes from the URL.
8
+ }
9
+ }
10
+ export function readLinearInstallWorkspace(storage) {
11
+ try {
12
+ return storage.getItem(LINEAR_INSTALL_WORKSPACE_KEY) ?? undefined;
13
+ } catch {
14
+ return undefined;
15
+ }
16
+ }
17
+ export function clearLinearInstallWorkspace(storage) {
18
+ try {
19
+ storage.removeItem(LINEAR_INSTALL_WORKSPACE_KEY);
20
+ } catch {
21
+ // A stale navigation hint cannot alter the callback request or its response.
22
+ }
23
+ }
24
+ export function parseLinearCallbackQuery(search) {
25
+ const state = stringParam(search.state);
26
+ if (!state) return undefined;
27
+ const code = stringParam(search.code);
28
+ if (code) return {
29
+ code,
30
+ state
31
+ };
32
+ const error = stringParam(search.error);
33
+ if (!error) return undefined;
34
+ const errorDescription = stringParam(search.error_description);
35
+ return errorDescription ? {
36
+ error,
37
+ error_description: errorDescription,
38
+ state
39
+ } : {
40
+ error,
41
+ state
42
+ };
43
+ }
44
+ export function serializeLinearCallbackQuery(query) {
45
+ const params = new URLSearchParams();
46
+ if ('code' in query) params.set('code', query.code);
47
+ else {
48
+ params.set('error', query.error);
49
+ if (query.error_description) params.set('error_description', query.error_description);
50
+ }
51
+ params.set('state', query.state);
52
+ return params.toString();
53
+ }
54
+ export function classifyLinearCallbackError(error) {
55
+ if (error instanceof ApiError) {
56
+ if (error.code === 'invalid-linear-install-state') {
57
+ return {
58
+ title: 'Linear install link expired',
59
+ message: 'Linear install link expired. Start again from workspace settings.',
60
+ startOver: true,
61
+ signIn: false
62
+ };
63
+ }
64
+ if (error.code === 'linear-install-state-actor-mismatch' || error.code === 'unauthorized') {
65
+ return {
66
+ title: 'Different Shipfox account',
67
+ message: 'Different Shipfox account. Sign in with the account that started this install.',
68
+ startOver: true,
69
+ signIn: true
70
+ };
71
+ }
72
+ if (error.code === 'linear-installation-already-linked' || error.code === 'linear-connection-already-linked') {
73
+ return {
74
+ title: 'Linear already linked',
75
+ message: 'This Linear organization is already linked to another workspace.',
76
+ startOver: false,
77
+ signIn: false
78
+ };
79
+ }
80
+ if (error.code === 'linear-authorization-scope-mismatch' || error.code === 'linear-oauth-callback-error') {
81
+ return {
82
+ title: 'Linear permissions needed',
83
+ message: 'Linear did not authorize the permissions Shipfox needs. Review the Linear consent and start again.',
84
+ startOver: true,
85
+ signIn: false
86
+ };
87
+ }
88
+ if (error.status === 0 || error.code === 'network-error') {
89
+ return {
90
+ message: 'Could not reach Shipfox. Check your connection and start again.',
91
+ startOver: true,
92
+ signIn: false
93
+ };
94
+ }
95
+ if (error.status >= 500 || error.status === 429 || error.code === 'provider-unavailable' || error.code === 'timeout' || error.code === 'rate-limited') {
96
+ return {
97
+ message: 'Linear is temporarily unavailable. Start a new install when it is available.',
98
+ startOver: true,
99
+ signIn: false
100
+ };
101
+ }
102
+ }
103
+ return {
104
+ message: 'Could not complete the Linear install. Start again from workspace settings.',
105
+ startOver: true,
106
+ signIn: false
107
+ };
108
+ }
109
+ function stringParam(value) {
110
+ return typeof value === 'string' && value.length > 0 ? value : undefined;
111
+ }
112
+
113
+ //# sourceMappingURL=linear-callback.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/linear-callback.ts"],"sourcesContent":["import type {LinearCallbackQueryDto} from '@shipfox/api-integration-linear-dto';\nimport {ApiError} from '@shipfox/client-api';\n\nexport const LINEAR_INSTALL_WORKSPACE_KEY = 'shipfox.linear-install.workspace-id';\n\ntype WorkspaceStorage = Pick<Storage, 'getItem' | 'setItem' | 'removeItem'>;\n\nexport function saveLinearInstallWorkspace(storage: WorkspaceStorage, workspaceId: string): void {\n try {\n storage.setItem(LINEAR_INSTALL_WORKSPACE_KEY, workspaceId);\n } catch {\n // Storage only improves recovery navigation; callback input always comes from the URL.\n }\n}\n\nexport function readLinearInstallWorkspace(storage: WorkspaceStorage): string | undefined {\n try {\n return storage.getItem(LINEAR_INSTALL_WORKSPACE_KEY) ?? undefined;\n } catch {\n return undefined;\n }\n}\n\nexport function clearLinearInstallWorkspace(storage: WorkspaceStorage): void {\n try {\n storage.removeItem(LINEAR_INSTALL_WORKSPACE_KEY);\n } catch {\n // A stale navigation hint cannot alter the callback request or its response.\n }\n}\n\nexport function parseLinearCallbackQuery(\n search: Record<string, unknown>,\n): LinearCallbackQueryDto | undefined {\n const state = stringParam(search.state);\n if (!state) return undefined;\n\n const code = stringParam(search.code);\n if (code) return {code, state};\n\n const error = stringParam(search.error);\n if (!error) return undefined;\n const errorDescription = stringParam(search.error_description);\n return errorDescription ? {error, error_description: errorDescription, state} : {error, state};\n}\n\nexport function serializeLinearCallbackQuery(query: LinearCallbackQueryDto): string {\n const params = new URLSearchParams();\n if ('code' in query) params.set('code', query.code);\n else {\n params.set('error', query.error);\n if (query.error_description) params.set('error_description', query.error_description);\n }\n params.set('state', query.state);\n return params.toString();\n}\n\nexport type LinearCallbackFailure = {\n title?: string;\n message: string;\n startOver: boolean;\n signIn: boolean;\n};\n\nexport function classifyLinearCallbackError(error: unknown): LinearCallbackFailure {\n if (error instanceof ApiError) {\n if (error.code === 'invalid-linear-install-state') {\n return {\n title: 'Linear install link expired',\n message: 'Linear install link expired. Start again from workspace settings.',\n startOver: true,\n signIn: false,\n };\n }\n if (error.code === 'linear-install-state-actor-mismatch' || error.code === 'unauthorized') {\n return {\n title: 'Different Shipfox account',\n message: 'Different Shipfox account. Sign in with the account that started this install.',\n startOver: true,\n signIn: true,\n };\n }\n if (\n error.code === 'linear-installation-already-linked' ||\n error.code === 'linear-connection-already-linked'\n ) {\n return {\n title: 'Linear already linked',\n message: 'This Linear organization is already linked to another workspace.',\n startOver: false,\n signIn: false,\n };\n }\n if (\n error.code === 'linear-authorization-scope-mismatch' ||\n error.code === 'linear-oauth-callback-error'\n ) {\n return {\n title: 'Linear permissions needed',\n message:\n 'Linear did not authorize the permissions Shipfox needs. Review the Linear consent and start again.',\n startOver: true,\n signIn: false,\n };\n }\n if (error.status === 0 || error.code === 'network-error') {\n return {\n message: 'Could not reach Shipfox. Check your connection and start again.',\n startOver: true,\n signIn: false,\n };\n }\n if (\n error.status >= 500 ||\n error.status === 429 ||\n error.code === 'provider-unavailable' ||\n error.code === 'timeout' ||\n error.code === 'rate-limited'\n ) {\n return {\n message: 'Linear is temporarily unavailable. Start a new install when it is available.',\n startOver: true,\n signIn: false,\n };\n }\n }\n return {\n message: 'Could not complete the Linear install. Start again from workspace settings.',\n startOver: true,\n signIn: false,\n };\n}\n\nfunction stringParam(value: unknown): string | undefined {\n return typeof value === 'string' && value.length > 0 ? value : undefined;\n}\n"],"names":["ApiError","LINEAR_INSTALL_WORKSPACE_KEY","saveLinearInstallWorkspace","storage","workspaceId","setItem","readLinearInstallWorkspace","getItem","undefined","clearLinearInstallWorkspace","removeItem","parseLinearCallbackQuery","search","state","stringParam","code","error","errorDescription","error_description","serializeLinearCallbackQuery","query","params","URLSearchParams","set","toString","classifyLinearCallbackError","title","message","startOver","signIn","status","value","length"],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ export type GiteaConnectField = 'org';
2
+ export type GiteaConnectFormErrorMapping = {
3
+ kind: 'field';
4
+ field: GiteaConnectField;
5
+ message: string;
6
+ } | {
7
+ kind: 'form';
8
+ message: string;
9
+ };
10
+ export declare function giteaConnectErrorToFormError(error: unknown): GiteaConnectFormErrorMapping;
11
+ //# sourceMappingURL=gitea-form-errors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gitea-form-errors.d.ts","sourceRoot":"","sources":["../../src/pages/gitea-form-errors.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,iBAAiB,GAAG,KAAK,CAAC;AAEtC,MAAM,MAAM,4BAA4B,GACpC;IAAC,IAAI,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,iBAAiB,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAC,GAC1D;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAC,CAAC;AAEpC,wBAAgB,4BAA4B,CAAC,KAAK,EAAE,OAAO,GAAG,4BAA4B,CAezF"}
@@ -0,0 +1,35 @@
1
+ import { ApiError } from '@shipfox/client-api';
2
+ export function giteaConnectErrorToFormError(error) {
3
+ const code = error instanceof ApiError ? error.code : undefined;
4
+ if (code === 'gitea-organization-not-found') {
5
+ return {
6
+ kind: 'field',
7
+ field: 'org',
8
+ message: "We couldn't find that organization on Gitea. Check the name and try again."
9
+ };
10
+ }
11
+ if (code === 'gitea-org-already-linked') {
12
+ return {
13
+ kind: 'field',
14
+ field: 'org',
15
+ message: 'That organization is already installed.'
16
+ };
17
+ }
18
+ return {
19
+ kind: 'form',
20
+ message: giteaConnectErrorMessage(error)
21
+ };
22
+ }
23
+ function giteaConnectErrorMessage(error) {
24
+ if (error instanceof ApiError) {
25
+ // `network-error` carries the raw request URL in its message; never surface it.
26
+ if (error.code === 'network-error') {
27
+ return "We couldn't reach the server. Check your connection and try again.";
28
+ }
29
+ return error.message;
30
+ }
31
+ if (error instanceof Error) return error.message;
32
+ return 'Something went wrong. Try again.';
33
+ }
34
+
35
+ //# sourceMappingURL=gitea-form-errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/pages/gitea-form-errors.ts"],"sourcesContent":["import {ApiError} from '@shipfox/client-api';\n\nexport type GiteaConnectField = 'org';\n\nexport type GiteaConnectFormErrorMapping =\n | {kind: 'field'; field: GiteaConnectField; message: string}\n | {kind: 'form'; message: string};\n\nexport function giteaConnectErrorToFormError(error: unknown): GiteaConnectFormErrorMapping {\n const code = error instanceof ApiError ? error.code : undefined;\n\n if (code === 'gitea-organization-not-found') {\n return {\n kind: 'field',\n field: 'org',\n message: \"We couldn't find that organization on Gitea. Check the name and try again.\",\n };\n }\n if (code === 'gitea-org-already-linked') {\n return {kind: 'field', field: 'org', message: 'That organization is already installed.'};\n }\n\n return {kind: 'form', message: giteaConnectErrorMessage(error)};\n}\n\nfunction giteaConnectErrorMessage(error: unknown): string {\n if (error instanceof ApiError) {\n // `network-error` carries the raw request URL in its message; never surface it.\n if (error.code === 'network-error') {\n return \"We couldn't reach the server. Check your connection and try again.\";\n }\n return error.message;\n }\n if (error instanceof Error) return error.message;\n return 'Something went wrong. Try again.';\n}\n"],"names":["ApiError","giteaConnectErrorToFormError","error","code","undefined","kind","field","message","giteaConnectErrorMessage","Error"],"mappings":"AAAA,SAAQA,QAAQ,QAAO,sBAAsB;AAQ7C,OAAO,SAASC,6BAA6BC,KAAc;IACzD,MAAMC,OAAOD,iBAAiBF,WAAWE,MAAMC,IAAI,GAAGC;IAEtD,IAAID,SAAS,gCAAgC;QAC3C,OAAO;YACLE,MAAM;YACNC,OAAO;YACPC,SAAS;QACX;IACF;IACA,IAAIJ,SAAS,4BAA4B;QACvC,OAAO;YAACE,MAAM;YAASC,OAAO;YAAOC,SAAS;QAAyC;IACzF;IAEA,OAAO;QAACF,MAAM;QAAQE,SAASC,yBAAyBN;IAAM;AAChE;AAEA,SAASM,yBAAyBN,KAAc;IAC9C,IAAIA,iBAAiBF,UAAU;QAC7B,gFAAgF;QAChF,IAAIE,MAAMC,IAAI,KAAK,iBAAiB;YAClC,OAAO;QACT;QACA,OAAOD,MAAMK,OAAO;IACtB;IACA,IAAIL,iBAAiBO,OAAO,OAAOP,MAAMK,OAAO;IAChD,OAAO;AACT"}
@@ -0,0 +1,2 @@
1
+ export declare function GiteaInstallPage(): import("react").JSX.Element;
2
+ //# sourceMappingURL=gitea-install-page.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gitea-install-page.d.ts","sourceRoot":"","sources":["../../src/pages/gitea-install-page.tsx"],"names":[],"mappings":"AAaA,wBAAgB,gBAAgB,gCA8F/B"}
@@ -0,0 +1,139 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useActiveWorkspace } from '@shipfox/client-auth';
3
+ import { Button, ButtonLink } from '@shipfox/react-ui/button';
4
+ import { Callout } from '@shipfox/react-ui/callout';
5
+ import { FormField, FormFieldInput, fieldError } from '@shipfox/react-ui/form-field';
6
+ import { toast } from '@shipfox/react-ui/toast';
7
+ import { Header, Text } from '@shipfox/react-ui/typography';
8
+ import { useForm } from '@tanstack/react-form';
9
+ import { useQueryClient } from '@tanstack/react-query';
10
+ import { Link, useNavigate } from '@tanstack/react-router';
11
+ import { useState } from 'react';
12
+ import { integrationsQueryKeys, useCreateGiteaConnectionMutation } from '#hooks/api/integrations.js';
13
+ import { giteaConnectErrorToFormError } from './gitea-form-errors.js';
14
+ export function GiteaInstallPage() {
15
+ const workspace = useActiveWorkspace();
16
+ const connect = useCreateGiteaConnectionMutation();
17
+ const queryClient = useQueryClient();
18
+ const navigate = useNavigate();
19
+ const [formError, setFormError] = useState();
20
+ const form = useForm({
21
+ defaultValues: {
22
+ org: ''
23
+ },
24
+ onSubmit: async ({ value })=>{
25
+ setFormError(undefined);
26
+ const workspaceId = workspace.id;
27
+ try {
28
+ await connect.mutateAsync({
29
+ workspace_id: workspaceId,
30
+ org: value.org.trim()
31
+ });
32
+ await queryClient.invalidateQueries({
33
+ queryKey: integrationsQueryKeys.sourceConnections(workspaceId),
34
+ // The workspace home is the next active observer, not this page, so the
35
+ // default 'active' refetch would no-op and leave the cache stale until
36
+ // after the home redirects back here.
37
+ refetchType: 'all'
38
+ });
39
+ toast.success('Gitea organization installed.');
40
+ await navigate({
41
+ to: '/workspaces/$wid',
42
+ params: {
43
+ wid: workspaceId
44
+ }
45
+ });
46
+ } catch (error) {
47
+ const mapped = giteaConnectErrorToFormError(error);
48
+ if (mapped.kind === 'field') {
49
+ form.setFieldMeta(mapped.field, (prev)=>({
50
+ ...prev,
51
+ errorMap: {
52
+ ...prev.errorMap,
53
+ onServer: mapped.message
54
+ }
55
+ }));
56
+ } else {
57
+ setFormError(mapped.message);
58
+ }
59
+ }
60
+ }
61
+ });
62
+ return /*#__PURE__*/ _jsxs("div", {
63
+ className: "mx-auto flex w-full max-w-[480px] flex-col gap-20",
64
+ children: [
65
+ /*#__PURE__*/ _jsxs("header", {
66
+ className: "flex flex-col gap-8",
67
+ children: [
68
+ /*#__PURE__*/ _jsx(Header, {
69
+ variant: "h1",
70
+ children: "Install Gitea"
71
+ }),
72
+ /*#__PURE__*/ _jsx(Text, {
73
+ size: "md",
74
+ className: "text-foreground-neutral-muted",
75
+ children: "Enter the Gitea organization to install in this workspace."
76
+ })
77
+ ]
78
+ }),
79
+ /*#__PURE__*/ _jsxs("form", {
80
+ className: "flex flex-col gap-18",
81
+ noValidate: true,
82
+ onSubmit: (event)=>{
83
+ event.preventDefault();
84
+ event.stopPropagation();
85
+ void form.handleSubmit();
86
+ },
87
+ children: [
88
+ formError ? /*#__PURE__*/ _jsx(Callout, {
89
+ role: "alert",
90
+ type: "error",
91
+ children: formError
92
+ }) : null,
93
+ /*#__PURE__*/ _jsx(form.Field, {
94
+ name: "org",
95
+ validators: {
96
+ onBlur: ({ value })=>value.trim().length > 0 ? undefined : 'Enter your Gitea organization.',
97
+ onSubmit: ({ value })=>value.trim().length > 0 ? undefined : 'Enter your Gitea organization.'
98
+ },
99
+ children: (field)=>/*#__PURE__*/ _jsx(FormField, {
100
+ label: "Organization",
101
+ id: "gitea-org",
102
+ error: fieldError(field),
103
+ children: /*#__PURE__*/ _jsx(FormFieldInput, {
104
+ placeholder: "my-org",
105
+ autoComplete: "off",
106
+ value: field.state.value,
107
+ onChange: (event)=>field.handleChange(event.target.value),
108
+ onBlur: field.handleBlur
109
+ })
110
+ })
111
+ }),
112
+ /*#__PURE__*/ _jsxs("div", {
113
+ className: "flex items-center gap-12",
114
+ children: [
115
+ /*#__PURE__*/ _jsx(Button, {
116
+ type: "submit",
117
+ isLoading: connect.isPending,
118
+ children: "Install"
119
+ }),
120
+ /*#__PURE__*/ _jsx(ButtonLink, {
121
+ asChild: true,
122
+ variant: "muted",
123
+ children: /*#__PURE__*/ _jsx(Link, {
124
+ to: "/workspaces/$wid/integrations",
125
+ params: {
126
+ wid: workspace.id
127
+ },
128
+ children: "Cancel"
129
+ })
130
+ })
131
+ ]
132
+ })
133
+ ]
134
+ })
135
+ ]
136
+ });
137
+ }
138
+
139
+ //# sourceMappingURL=gitea-install-page.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/pages/gitea-install-page.tsx"],"sourcesContent":["import {useActiveWorkspace} from '@shipfox/client-auth';\nimport {Button, ButtonLink} from '@shipfox/react-ui/button';\nimport {Callout} from '@shipfox/react-ui/callout';\nimport {FormField, FormFieldInput, fieldError} from '@shipfox/react-ui/form-field';\nimport {toast} from '@shipfox/react-ui/toast';\nimport {Header, Text} from '@shipfox/react-ui/typography';\nimport {useForm} from '@tanstack/react-form';\nimport {useQueryClient} from '@tanstack/react-query';\nimport {Link, useNavigate} from '@tanstack/react-router';\nimport {useState} from 'react';\nimport {integrationsQueryKeys, useCreateGiteaConnectionMutation} from '#hooks/api/integrations.js';\nimport {giteaConnectErrorToFormError} from './gitea-form-errors.js';\n\nexport function GiteaInstallPage() {\n const workspace = useActiveWorkspace();\n const connect = useCreateGiteaConnectionMutation();\n const queryClient = useQueryClient();\n const navigate = useNavigate();\n const [formError, setFormError] = useState<string | undefined>();\n\n const form = useForm({\n defaultValues: {org: ''},\n onSubmit: async ({value}) => {\n setFormError(undefined);\n const workspaceId = workspace.id;\n try {\n await connect.mutateAsync({workspace_id: workspaceId, org: value.org.trim()});\n await queryClient.invalidateQueries({\n queryKey: integrationsQueryKeys.sourceConnections(workspaceId),\n // The workspace home is the next active observer, not this page, so the\n // default 'active' refetch would no-op and leave the cache stale until\n // after the home redirects back here.\n refetchType: 'all',\n });\n toast.success('Gitea organization installed.');\n await navigate({to: '/workspaces/$wid', params: {wid: workspaceId}});\n } catch (error) {\n const mapped = giteaConnectErrorToFormError(error);\n if (mapped.kind === 'field') {\n form.setFieldMeta(mapped.field, (prev) => ({\n ...prev,\n errorMap: {...prev.errorMap, onServer: mapped.message},\n }));\n } else {\n setFormError(mapped.message);\n }\n }\n },\n });\n\n return (\n <div className=\"mx-auto flex w-full max-w-[480px] flex-col gap-20\">\n <header className=\"flex flex-col gap-8\">\n <Header variant=\"h1\">Install Gitea</Header>\n <Text size=\"md\" className=\"text-foreground-neutral-muted\">\n Enter the Gitea organization to install in this workspace.\n </Text>\n </header>\n\n <form\n className=\"flex flex-col gap-18\"\n noValidate\n onSubmit={(event) => {\n event.preventDefault();\n event.stopPropagation();\n void form.handleSubmit();\n }}\n >\n {formError ? (\n <Callout role=\"alert\" type=\"error\">\n {formError}\n </Callout>\n ) : null}\n <form.Field\n name=\"org\"\n validators={{\n onBlur: ({value}) =>\n value.trim().length > 0 ? undefined : 'Enter your Gitea organization.',\n onSubmit: ({value}) =>\n value.trim().length > 0 ? undefined : 'Enter your Gitea organization.',\n }}\n >\n {(field) => (\n <FormField label=\"Organization\" id=\"gitea-org\" error={fieldError(field)}>\n <FormFieldInput\n placeholder=\"my-org\"\n autoComplete=\"off\"\n value={field.state.value}\n onChange={(event) => field.handleChange(event.target.value)}\n onBlur={field.handleBlur}\n />\n </FormField>\n )}\n </form.Field>\n <div className=\"flex items-center gap-12\">\n <Button type=\"submit\" isLoading={connect.isPending}>\n Install\n </Button>\n <ButtonLink asChild variant=\"muted\">\n <Link to=\"/workspaces/$wid/integrations\" params={{wid: workspace.id}}>\n Cancel\n </Link>\n </ButtonLink>\n </div>\n </form>\n </div>\n );\n}\n"],"names":["useActiveWorkspace","Button","ButtonLink","Callout","FormField","FormFieldInput","fieldError","toast","Header","Text","useForm","useQueryClient","Link","useNavigate","useState","integrationsQueryKeys","useCreateGiteaConnectionMutation","giteaConnectErrorToFormError","GiteaInstallPage","workspace","connect","queryClient","navigate","formError","setFormError","form","defaultValues","org","onSubmit","value","undefined","workspaceId","id","mutateAsync","workspace_id","trim","invalidateQueries","queryKey","sourceConnections","refetchType","success","to","params","wid","error","mapped","kind","setFieldMeta","field","prev","errorMap","onServer","message","div","className","header","variant","size","noValidate","event","preventDefault","stopPropagation","handleSubmit","role","type","Field","name","validators","onBlur","length","label","placeholder","autoComplete","state","onChange","handleChange","target","handleBlur","isLoading","isPending","asChild"],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare function GithubInstallPage(): import("react").JSX.Element;
2
+ //# sourceMappingURL=github-install-page.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"github-install-page.d.ts","sourceRoot":"","sources":["../../src/pages/github-install-page.tsx"],"names":[],"mappings":"AAGA,wBAAgB,iBAAiB,gCAOhC"}
@@ -0,0 +1,11 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { RedirectInstallPage } from '#components/redirect-install-page.js';
3
+ import { createGithubInstall } from '#hooks/api/integrations.js';
4
+ export function GithubInstallPage() {
5
+ return /*#__PURE__*/ _jsx(RedirectInstallPage, {
6
+ installRequest: createGithubInstall,
7
+ errorFallbackMessage: "Could not start GitHub install."
8
+ });
9
+ }
10
+
11
+ //# sourceMappingURL=github-install-page.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/pages/github-install-page.tsx"],"sourcesContent":["import {RedirectInstallPage} from '#components/redirect-install-page.js';\nimport {createGithubInstall} from '#hooks/api/integrations.js';\n\nexport function GithubInstallPage() {\n return (\n <RedirectInstallPage\n installRequest={createGithubInstall}\n errorFallbackMessage=\"Could not start GitHub install.\"\n />\n );\n}\n"],"names":["RedirectInstallPage","createGithubInstall","GithubInstallPage","installRequest","errorFallbackMessage"],"mappings":";AAAA,SAAQA,mBAAmB,QAAO,uCAAuC;AACzE,SAAQC,mBAAmB,QAAO,6BAA6B;AAE/D,OAAO,SAASC;IACd,qBACE,KAACF;QACCG,gBAAgBF;QAChBG,sBAAqB;;AAG3B"}
@@ -0,0 +1,2 @@
1
+ export declare function LinearCallbackPage(): import("react").JSX.Element;
2
+ //# sourceMappingURL=linear-callback-page.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"linear-callback-page.d.ts","sourceRoot":"","sources":["../../src/pages/linear-callback-page.tsx"],"names":[],"mappings":"AA8BA,wBAAgB,kBAAkB,gCAsFjC"}