@shipfox/api-integration-jira 5.0.0 → 6.0.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.
@@ -1,2 +1,2 @@
1
1
  $ shipfox-swc
2
- Successfully compiled: 20 files with swc (321.85ms)
2
+ Successfully compiled: 20 files with swc (320.51ms)
package/CHANGELOG.md CHANGED
@@ -1,5 +1,36 @@
1
1
  # @shipfox/api-integration-jira
2
2
 
3
+ ## 6.0.0
4
+
5
+ ### Minor Changes
6
+
7
+ - a42b575: Exposes Secrets through its inter-module contract and migrates Agent, integrations, and Workflows consumers.
8
+
9
+ ### Patch Changes
10
+
11
+ - f73da5d: Enforces bounded API context imports and routes inter-module consumers through producer contracts.
12
+ - 326f4c0: Exposes Workspaces inter-module operations and moves Auth and OAuth providers onto injected clients.
13
+ - Updated dependencies [0bb82a4]
14
+ - Updated dependencies [7366f04]
15
+ - Updated dependencies [7ac43a4]
16
+ - Updated dependencies [f262539]
17
+ - Updated dependencies [3bb4e26]
18
+ - Updated dependencies [c2db8c3]
19
+ - Updated dependencies [8bdc149]
20
+ - Updated dependencies [f73da5d]
21
+ - Updated dependencies [6bdf24b]
22
+ - Updated dependencies [b00ed29]
23
+ - Updated dependencies [8aa7cd3]
24
+ - Updated dependencies [326f4c0]
25
+ - Updated dependencies [1820feb]
26
+ - Updated dependencies [4604a06]
27
+ - @shipfox/api-integration-core-dto@6.0.0
28
+ - @shipfox/api-workspaces@6.0.0
29
+ - @shipfox/node-drizzle@0.3.2
30
+ - @shipfox/api-auth-context@6.0.0
31
+ - @shipfox/node-fastify@0.2.4
32
+ - @shipfox/api-integration-jira-dto@6.0.0
33
+
3
34
  ## 5.0.0
4
35
 
5
36
  ### Patch Changes
@@ -16,6 +16,11 @@ export interface CreateJiraIntegrationRoutesOptions {
16
16
  connectionId: string;
17
17
  }): Promise<void>;
18
18
  connectionCapabilities: IntegrationCapability[];
19
+ requireActiveWorkspaceMembership?: (input: {
20
+ workspaceId: string;
21
+ userId: string;
22
+ memberships: ReadonlyArray<import('@shipfox/api-auth-context').UserContextMembership>;
23
+ }) => Promise<unknown>;
19
24
  }
20
25
  export declare function createJiraIntegrationRoutes(options: CreateJiraIntegrationRoutesOptions): RouteGroup;
21
26
  //# sourceMappingURL=install.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"install.d.ts","sourceRoot":"","sources":["../../../src/presentation/routes/install.ts"],"names":[],"mappings":"AACA,OAAO,EACL,KAAK,qBAAqB,EAC1B,KAAK,qBAAqB,EAE3B,MAAM,mCAAmC,CAAC;AAU3C,OAAO,EAAc,KAAK,UAAU,EAAC,MAAM,uBAAuB,CAAC;AACnE,OAAO,KAAK,EAAC,aAAa,EAAC,MAAM,gBAAgB,CAAC;AAElD,OAAO,EACL,KAAK,4BAA4B,EAIlC,MAAM,kBAAkB,CAAC;AAC1B,OAAO,KAAK,EAAC,yBAAyB,EAAC,MAAM,kBAAkB,CAAC;AAGhE,OAAO,KAAK,EAAC,cAAc,EAAC,MAAM,iBAAiB,CAAC;AAIpD,MAAM,WAAW,kCAAkC;IACjD,IAAI,EAAE,aAAa,CAAC;IACpB,UAAU,EAAE,IAAI,CAAC,cAAc,EAAE,aAAa,CAAC,CAAC;IAChD,YAAY,EAAE,IAAI,CAAC,yBAAyB,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,CAAC;IACzE,yBAAyB,CAAC,KAAK,EAAE;QAC/B,OAAO,EAAE,MAAM,CAAC;KACjB,GAAG,OAAO,CAAC,qBAAqB,CAAC,MAAM,CAAC,GAAG,SAAS,CAAC,CAAC;IACvD,uBAAuB,CACrB,KAAK,EAAE,4BAA4B,GAClC,OAAO,CAAC,qBAAqB,CAAC,MAAM,CAAC,CAAC,CAAC;IAC1C,0BAA0B,CAAC,KAAK,EAAE;QAAC,YAAY,EAAE,MAAM,CAAA;KAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACzE,sBAAsB,EAAE,qBAAqB,EAAE,CAAC;CACjD;AAED,wBAAgB,2BAA2B,CACzC,OAAO,EAAE,kCAAkC,GAC1C,UAAU,CA2FZ"}
1
+ {"version":3,"file":"install.d.ts","sourceRoot":"","sources":["../../../src/presentation/routes/install.ts"],"names":[],"mappings":"AACA,OAAO,EACL,KAAK,qBAAqB,EAC1B,KAAK,qBAAqB,EAE3B,MAAM,mCAAmC,CAAC;AAS3C,OAAO,EAAc,KAAK,UAAU,EAAC,MAAM,uBAAuB,CAAC;AACnE,OAAO,KAAK,EAAC,aAAa,EAAC,MAAM,gBAAgB,CAAC;AAElD,OAAO,EACL,KAAK,4BAA4B,EAIlC,MAAM,kBAAkB,CAAC;AAC1B,OAAO,KAAK,EAAC,yBAAyB,EAAC,MAAM,kBAAkB,CAAC;AAGhE,OAAO,KAAK,EAAC,cAAc,EAAC,MAAM,iBAAiB,CAAC;AAIpD,MAAM,WAAW,kCAAkC;IACjD,IAAI,EAAE,aAAa,CAAC;IACpB,UAAU,EAAE,IAAI,CAAC,cAAc,EAAE,aAAa,CAAC,CAAC;IAChD,YAAY,EAAE,IAAI,CAAC,yBAAyB,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,CAAC;IACzE,yBAAyB,CAAC,KAAK,EAAE;QAC/B,OAAO,EAAE,MAAM,CAAC;KACjB,GAAG,OAAO,CAAC,qBAAqB,CAAC,MAAM,CAAC,GAAG,SAAS,CAAC,CAAC;IACvD,uBAAuB,CACrB,KAAK,EAAE,4BAA4B,GAClC,OAAO,CAAC,qBAAqB,CAAC,MAAM,CAAC,CAAC,CAAC;IAC1C,0BAA0B,CAAC,KAAK,EAAE;QAAC,YAAY,EAAE,MAAM,CAAA;KAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACzE,sBAAsB,EAAE,qBAAqB,EAAE,CAAC;IAChD,gCAAgC,CAAC,EAAE,CAAC,KAAK,EAAE;QACzC,WAAW,EAAE,MAAM,CAAC;QACpB,MAAM,EAAE,MAAM,CAAC;QACf,WAAW,EAAE,aAAa,CAAC,OAAO,2BAA2B,EAAE,qBAAqB,CAAC,CAAC;KACvF,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;CACxB;AAED,wBAAgB,2BAA2B,CACzC,OAAO,EAAE,kCAAkC,GAC1C,UAAU,CA6FZ"}
@@ -1,7 +1,6 @@
1
1
  import { AUTH_USER, requireUserContext, requireWorkspaceAccess } from '@shipfox/api-auth-context';
2
2
  import { integrationConnectionDtoSchema } from '@shipfox/api-integration-core-dto';
3
3
  import { completeJiraSiteSelectionBodySchema, createJiraInstallBodySchema, createJiraInstallResponseSchema, jiraCallbackQuerySchema, jiraCallbackResponseSchema } from '@shipfox/api-integration-jira-dto';
4
- import { requireWorkspaceMembership } from '@shipfox/api-workspaces';
5
4
  import { defineRoute } from '@shipfox/node-fastify';
6
5
  import { config } from '#config.js';
7
6
  import { handleJiraCallback, handleJiraOAuthCallbackError, handleJiraSiteSelection } from '#core/install.js';
@@ -10,6 +9,7 @@ import { signJiraInstallState } from '#core/state.js';
10
9
  import { toIntegrationConnectionDto } from '#presentation/dto/integrations.js';
11
10
  import { jiraRouteErrorHandler } from './errors.js';
12
11
  export function createJiraIntegrationRoutes(options) {
12
+ const requireMembership = options.requireActiveWorkspaceMembership ?? unavailableWorkspaceMembershipCheck;
13
13
  const installRoute = defineRoute({
14
14
  method: 'POST',
15
15
  path: '/install',
@@ -65,7 +65,7 @@ export function createJiraIntegrationRoutes(options) {
65
65
  errorDescription: query.error_description,
66
66
  sessionUserId: actor.userId,
67
67
  sessionMemberships: actor.memberships,
68
- requireWorkspaceMembership
68
+ requireWorkspaceMembership: requireMembership
69
69
  });
70
70
  const result = await handleJiraCallback({
71
71
  ...options,
@@ -73,7 +73,7 @@ export function createJiraIntegrationRoutes(options) {
73
73
  state: query.state,
74
74
  sessionUserId: actor.userId,
75
75
  sessionMemberships: actor.memberships,
76
- requireWorkspaceMembership
76
+ requireWorkspaceMembership: requireMembership
77
77
  });
78
78
  return 'sites' in result ? {
79
79
  sites: result.sites.map((site)=>({
@@ -107,7 +107,7 @@ export function createJiraIntegrationRoutes(options) {
107
107
  state: request.body.state,
108
108
  sessionUserId: actor.userId,
109
109
  sessionMemberships: actor.memberships,
110
- requireWorkspaceMembership
110
+ requireWorkspaceMembership: requireMembership
111
111
  });
112
112
  return toIntegrationConnectionDto(connection, {
113
113
  capabilities: options.connectionCapabilities
@@ -123,6 +123,9 @@ export function createJiraIntegrationRoutes(options) {
123
123
  ]
124
124
  };
125
125
  }
126
+ function unavailableWorkspaceMembershipCheck(_input) {
127
+ return Promise.reject(new Error('Workspaces inter-module client is not configured'));
128
+ }
126
129
  function isJiraOAuthErrorCallback(query) {
127
130
  return 'error' in query && typeof query.error === 'string';
128
131
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/presentation/routes/install.ts"],"sourcesContent":["import {AUTH_USER, requireUserContext, requireWorkspaceAccess} from '@shipfox/api-auth-context';\nimport {\n type IntegrationCapability,\n type IntegrationConnection,\n integrationConnectionDtoSchema,\n} from '@shipfox/api-integration-core-dto';\nimport {\n completeJiraSiteSelectionBodySchema,\n createJiraInstallBodySchema,\n createJiraInstallResponseSchema,\n type JiraCallbackQueryDto,\n jiraCallbackQuerySchema,\n jiraCallbackResponseSchema,\n} from '@shipfox/api-integration-jira-dto';\nimport {requireWorkspaceMembership} from '@shipfox/api-workspaces';\nimport {defineRoute, type RouteGroup} from '@shipfox/node-fastify';\nimport type {JiraApiClient} from '#api/client.js';\nimport {config} from '#config.js';\nimport {\n type ConnectJiraInstallationInput,\n handleJiraCallback,\n handleJiraOAuthCallbackError,\n handleJiraSiteSelection,\n} from '#core/install.js';\nimport type {JiraPendingSelectionStore} from '#core/pending.js';\nimport {formatJiraOAuthScopes} from '#core/scopes.js';\nimport {signJiraInstallState} from '#core/state.js';\nimport type {JiraTokenStore} from '#core/tokens.js';\nimport {toIntegrationConnectionDto} from '#presentation/dto/integrations.js';\nimport {jiraRouteErrorHandler} from './errors.js';\n\nexport interface CreateJiraIntegrationRoutesOptions {\n jira: JiraApiClient;\n tokenStore: Pick<JiraTokenStore, 'storeTokens'>;\n pendingStore: Pick<JiraPendingSelectionStore, 'save' | 'load' | 'clear'>;\n getExistingJiraConnection(input: {\n cloudId: string;\n }): Promise<IntegrationConnection<'jira'> | undefined>;\n connectJiraInstallation(\n input: ConnectJiraInstallationInput,\n ): Promise<IntegrationConnection<'jira'>>;\n disconnectJiraInstallation(input: {connectionId: string}): Promise<void>;\n connectionCapabilities: IntegrationCapability[];\n}\n\nexport function createJiraIntegrationRoutes(\n options: CreateJiraIntegrationRoutesOptions,\n): RouteGroup {\n const installRoute = defineRoute({\n method: 'POST',\n path: '/install',\n auth: AUTH_USER,\n description: 'Create a Jira OAuth authorization URL for a workspace.',\n schema: {body: createJiraInstallBodySchema, response: {200: createJiraInstallResponseSchema}},\n handler: (request) => {\n const {workspace_id: workspaceId} = request.body;\n const actor = requireUserContext(request);\n requireWorkspaceAccess({request, workspaceId});\n const installUrl = new URL(`${config.JIRA_AUTH_BASE_URL}/authorize`);\n installUrl.searchParams.set('audience', 'api.atlassian.com');\n installUrl.searchParams.set('client_id', config.JIRA_OAUTH_CLIENT_ID);\n installUrl.searchParams.set('scope', formatJiraOAuthScopes());\n installUrl.searchParams.set('redirect_uri', config.JIRA_OAUTH_REDIRECT_URL);\n installUrl.searchParams.set(\n 'state',\n signJiraInstallState({workspaceId, userId: actor.userId}),\n );\n installUrl.searchParams.set('response_type', 'code');\n installUrl.searchParams.set('prompt', 'consent');\n return {install_url: installUrl.toString()};\n },\n });\n const callbackApiRoute = defineRoute({\n method: 'GET',\n path: '/callback/api',\n auth: AUTH_USER,\n description: 'Handle the Jira OAuth callback.',\n schema: {querystring: jiraCallbackQuerySchema, response: {200: jiraCallbackResponseSchema}},\n errorHandler: jiraRouteErrorHandler,\n handler: async (request) => {\n const actor = requireUserContext(request);\n const query = request.query;\n if (isJiraOAuthErrorCallback(query))\n return await handleJiraOAuthCallbackError({\n state: query.state,\n error: query.error,\n errorDescription: query.error_description,\n sessionUserId: actor.userId,\n sessionMemberships: actor.memberships,\n requireWorkspaceMembership,\n });\n const result = await handleJiraCallback({\n ...options,\n code: query.code,\n state: query.state,\n sessionUserId: actor.userId,\n sessionMemberships: actor.memberships,\n requireWorkspaceMembership,\n });\n return 'sites' in result\n ? {\n sites: result.sites.map((site) => ({\n cloud_id: site.cloudId,\n name: site.name,\n url: site.url,\n scopes: site.scopes,\n })),\n }\n : toIntegrationConnectionDto(result, {capabilities: options.connectionCapabilities});\n },\n });\n const siteSelectionRoute = defineRoute({\n method: 'POST',\n path: '/callback/site',\n auth: AUTH_USER,\n description: 'Complete Jira OAuth site selection.',\n schema: {\n body: completeJiraSiteSelectionBodySchema,\n response: {200: integrationConnectionDtoSchema},\n },\n errorHandler: jiraRouteErrorHandler,\n handler: async (request) => {\n const actor = requireUserContext(request);\n const connection = await handleJiraSiteSelection({\n ...options,\n cloudId: request.body.cloud_id,\n state: request.body.state,\n sessionUserId: actor.userId,\n sessionMemberships: actor.memberships,\n requireWorkspaceMembership,\n });\n return toIntegrationConnectionDto(connection, {capabilities: options.connectionCapabilities});\n },\n });\n return {\n prefix: '/integrations/jira',\n routes: [installRoute, callbackApiRoute, siteSelectionRoute],\n };\n}\n\nfunction isJiraOAuthErrorCallback(query: JiraCallbackQueryDto): query is JiraCallbackQueryDto & {\n error: string;\n error_description?: string | undefined;\n state: string;\n} {\n return 'error' in query && typeof query.error === 'string';\n}\n"],"names":["AUTH_USER","requireUserContext","requireWorkspaceAccess","integrationConnectionDtoSchema","completeJiraSiteSelectionBodySchema","createJiraInstallBodySchema","createJiraInstallResponseSchema","jiraCallbackQuerySchema","jiraCallbackResponseSchema","requireWorkspaceMembership","defineRoute","config","handleJiraCallback","handleJiraOAuthCallbackError","handleJiraSiteSelection","formatJiraOAuthScopes","signJiraInstallState","toIntegrationConnectionDto","jiraRouteErrorHandler","createJiraIntegrationRoutes","options","installRoute","method","path","auth","description","schema","body","response","handler","request","workspace_id","workspaceId","actor","installUrl","URL","JIRA_AUTH_BASE_URL","searchParams","set","JIRA_OAUTH_CLIENT_ID","JIRA_OAUTH_REDIRECT_URL","userId","install_url","toString","callbackApiRoute","querystring","errorHandler","query","isJiraOAuthErrorCallback","state","error","errorDescription","error_description","sessionUserId","sessionMemberships","memberships","result","code","sites","map","site","cloud_id","cloudId","name","url","scopes","capabilities","connectionCapabilities","siteSelectionRoute","connection","prefix","routes"],"mappings":"AAAA,SAAQA,SAAS,EAAEC,kBAAkB,EAAEC,sBAAsB,QAAO,4BAA4B;AAChG,SAGEC,8BAA8B,QACzB,oCAAoC;AAC3C,SACEC,mCAAmC,EACnCC,2BAA2B,EAC3BC,+BAA+B,EAE/BC,uBAAuB,EACvBC,0BAA0B,QACrB,oCAAoC;AAC3C,SAAQC,0BAA0B,QAAO,0BAA0B;AACnE,SAAQC,WAAW,QAAwB,wBAAwB;AAEnE,SAAQC,MAAM,QAAO,aAAa;AAClC,SAEEC,kBAAkB,EAClBC,4BAA4B,EAC5BC,uBAAuB,QAClB,mBAAmB;AAE1B,SAAQC,qBAAqB,QAAO,kBAAkB;AACtD,SAAQC,oBAAoB,QAAO,iBAAiB;AAEpD,SAAQC,0BAA0B,QAAO,oCAAoC;AAC7E,SAAQC,qBAAqB,QAAO,cAAc;AAgBlD,OAAO,SAASC,4BACdC,OAA2C;IAE3C,MAAMC,eAAeX,YAAY;QAC/BY,QAAQ;QACRC,MAAM;QACNC,MAAMxB;QACNyB,aAAa;QACbC,QAAQ;YAACC,MAAMtB;YAA6BuB,UAAU;gBAAC,KAAKtB;YAA+B;QAAC;QAC5FuB,SAAS,CAACC;YACR,MAAM,EAACC,cAAcC,WAAW,EAAC,GAAGF,QAAQH,IAAI;YAChD,MAAMM,QAAQhC,mBAAmB6B;YACjC5B,uBAAuB;gBAAC4B;gBAASE;YAAW;YAC5C,MAAME,aAAa,IAAIC,IAAI,GAAGxB,OAAOyB,kBAAkB,CAAC,UAAU,CAAC;YACnEF,WAAWG,YAAY,CAACC,GAAG,CAAC,YAAY;YACxCJ,WAAWG,YAAY,CAACC,GAAG,CAAC,aAAa3B,OAAO4B,oBAAoB;YACpEL,WAAWG,YAAY,CAACC,GAAG,CAAC,SAASvB;YACrCmB,WAAWG,YAAY,CAACC,GAAG,CAAC,gBAAgB3B,OAAO6B,uBAAuB;YAC1EN,WAAWG,YAAY,CAACC,GAAG,CACzB,SACAtB,qBAAqB;gBAACgB;gBAAaS,QAAQR,MAAMQ,MAAM;YAAA;YAEzDP,WAAWG,YAAY,CAACC,GAAG,CAAC,iBAAiB;YAC7CJ,WAAWG,YAAY,CAACC,GAAG,CAAC,UAAU;YACtC,OAAO;gBAACI,aAAaR,WAAWS,QAAQ;YAAE;QAC5C;IACF;IACA,MAAMC,mBAAmBlC,YAAY;QACnCY,QAAQ;QACRC,MAAM;QACNC,MAAMxB;QACNyB,aAAa;QACbC,QAAQ;YAACmB,aAAatC;YAAyBqB,UAAU;gBAAC,KAAKpB;YAA0B;QAAC;QAC1FsC,cAAc5B;QACdW,SAAS,OAAOC;YACd,MAAMG,QAAQhC,mBAAmB6B;YACjC,MAAMiB,QAAQjB,QAAQiB,KAAK;YAC3B,IAAIC,yBAAyBD,QAC3B,OAAO,MAAMlC,6BAA6B;gBACxCoC,OAAOF,MAAME,KAAK;gBAClBC,OAAOH,MAAMG,KAAK;gBAClBC,kBAAkBJ,MAAMK,iBAAiB;gBACzCC,eAAepB,MAAMQ,MAAM;gBAC3Ba,oBAAoBrB,MAAMsB,WAAW;gBACrC9C;YACF;YACF,MAAM+C,SAAS,MAAM5C,mBAAmB;gBACtC,GAAGQ,OAAO;gBACVqC,MAAMV,MAAMU,IAAI;gBAChBR,OAAOF,MAAME,KAAK;gBAClBI,eAAepB,MAAMQ,MAAM;gBAC3Ba,oBAAoBrB,MAAMsB,WAAW;gBACrC9C;YACF;YACA,OAAO,WAAW+C,SACd;gBACEE,OAAOF,OAAOE,KAAK,CAACC,GAAG,CAAC,CAACC,OAAU,CAAA;wBACjCC,UAAUD,KAAKE,OAAO;wBACtBC,MAAMH,KAAKG,IAAI;wBACfC,KAAKJ,KAAKI,GAAG;wBACbC,QAAQL,KAAKK,MAAM;oBACrB,CAAA;YACF,IACAhD,2BAA2BuC,QAAQ;gBAACU,cAAc9C,QAAQ+C,sBAAsB;YAAA;QACtF;IACF;IACA,MAAMC,qBAAqB1D,YAAY;QACrCY,QAAQ;QACRC,MAAM;QACNC,MAAMxB;QACNyB,aAAa;QACbC,QAAQ;YACNC,MAAMvB;YACNwB,UAAU;gBAAC,KAAKzB;YAA8B;QAChD;QACA2C,cAAc5B;QACdW,SAAS,OAAOC;YACd,MAAMG,QAAQhC,mBAAmB6B;YACjC,MAAMuC,aAAa,MAAMvD,wBAAwB;gBAC/C,GAAGM,OAAO;gBACV0C,SAAShC,QAAQH,IAAI,CAACkC,QAAQ;gBAC9BZ,OAAOnB,QAAQH,IAAI,CAACsB,KAAK;gBACzBI,eAAepB,MAAMQ,MAAM;gBAC3Ba,oBAAoBrB,MAAMsB,WAAW;gBACrC9C;YACF;YACA,OAAOQ,2BAA2BoD,YAAY;gBAACH,cAAc9C,QAAQ+C,sBAAsB;YAAA;QAC7F;IACF;IACA,OAAO;QACLG,QAAQ;QACRC,QAAQ;YAAClD;YAAcuB;YAAkBwB;SAAmB;IAC9D;AACF;AAEA,SAASpB,yBAAyBD,KAA2B;IAK3D,OAAO,WAAWA,SAAS,OAAOA,MAAMG,KAAK,KAAK;AACpD"}
1
+ {"version":3,"sources":["../../../src/presentation/routes/install.ts"],"sourcesContent":["import {AUTH_USER, requireUserContext, requireWorkspaceAccess} from '@shipfox/api-auth-context';\nimport {\n type IntegrationCapability,\n type IntegrationConnection,\n integrationConnectionDtoSchema,\n} from '@shipfox/api-integration-core-dto';\nimport {\n completeJiraSiteSelectionBodySchema,\n createJiraInstallBodySchema,\n createJiraInstallResponseSchema,\n type JiraCallbackQueryDto,\n jiraCallbackQuerySchema,\n jiraCallbackResponseSchema,\n} from '@shipfox/api-integration-jira-dto';\nimport {defineRoute, type RouteGroup} from '@shipfox/node-fastify';\nimport type {JiraApiClient} from '#api/client.js';\nimport {config} from '#config.js';\nimport {\n type ConnectJiraInstallationInput,\n handleJiraCallback,\n handleJiraOAuthCallbackError,\n handleJiraSiteSelection,\n} from '#core/install.js';\nimport type {JiraPendingSelectionStore} from '#core/pending.js';\nimport {formatJiraOAuthScopes} from '#core/scopes.js';\nimport {signJiraInstallState} from '#core/state.js';\nimport type {JiraTokenStore} from '#core/tokens.js';\nimport {toIntegrationConnectionDto} from '#presentation/dto/integrations.js';\nimport {jiraRouteErrorHandler} from './errors.js';\n\nexport interface CreateJiraIntegrationRoutesOptions {\n jira: JiraApiClient;\n tokenStore: Pick<JiraTokenStore, 'storeTokens'>;\n pendingStore: Pick<JiraPendingSelectionStore, 'save' | 'load' | 'clear'>;\n getExistingJiraConnection(input: {\n cloudId: string;\n }): Promise<IntegrationConnection<'jira'> | undefined>;\n connectJiraInstallation(\n input: ConnectJiraInstallationInput,\n ): Promise<IntegrationConnection<'jira'>>;\n disconnectJiraInstallation(input: {connectionId: string}): Promise<void>;\n connectionCapabilities: IntegrationCapability[];\n requireActiveWorkspaceMembership?: (input: {\n workspaceId: string;\n userId: string;\n memberships: ReadonlyArray<import('@shipfox/api-auth-context').UserContextMembership>;\n }) => Promise<unknown>;\n}\n\nexport function createJiraIntegrationRoutes(\n options: CreateJiraIntegrationRoutesOptions,\n): RouteGroup {\n const requireMembership =\n options.requireActiveWorkspaceMembership ?? unavailableWorkspaceMembershipCheck;\n const installRoute = defineRoute({\n method: 'POST',\n path: '/install',\n auth: AUTH_USER,\n description: 'Create a Jira OAuth authorization URL for a workspace.',\n schema: {body: createJiraInstallBodySchema, response: {200: createJiraInstallResponseSchema}},\n handler: (request) => {\n const {workspace_id: workspaceId} = request.body;\n const actor = requireUserContext(request);\n requireWorkspaceAccess({request, workspaceId});\n const installUrl = new URL(`${config.JIRA_AUTH_BASE_URL}/authorize`);\n installUrl.searchParams.set('audience', 'api.atlassian.com');\n installUrl.searchParams.set('client_id', config.JIRA_OAUTH_CLIENT_ID);\n installUrl.searchParams.set('scope', formatJiraOAuthScopes());\n installUrl.searchParams.set('redirect_uri', config.JIRA_OAUTH_REDIRECT_URL);\n installUrl.searchParams.set(\n 'state',\n signJiraInstallState({workspaceId, userId: actor.userId}),\n );\n installUrl.searchParams.set('response_type', 'code');\n installUrl.searchParams.set('prompt', 'consent');\n return {install_url: installUrl.toString()};\n },\n });\n const callbackApiRoute = defineRoute({\n method: 'GET',\n path: '/callback/api',\n auth: AUTH_USER,\n description: 'Handle the Jira OAuth callback.',\n schema: {querystring: jiraCallbackQuerySchema, response: {200: jiraCallbackResponseSchema}},\n errorHandler: jiraRouteErrorHandler,\n handler: async (request) => {\n const actor = requireUserContext(request);\n const query = request.query;\n if (isJiraOAuthErrorCallback(query))\n return await handleJiraOAuthCallbackError({\n state: query.state,\n error: query.error,\n errorDescription: query.error_description,\n sessionUserId: actor.userId,\n sessionMemberships: actor.memberships,\n requireWorkspaceMembership: requireMembership,\n });\n const result = await handleJiraCallback({\n ...options,\n code: query.code,\n state: query.state,\n sessionUserId: actor.userId,\n sessionMemberships: actor.memberships,\n requireWorkspaceMembership: requireMembership,\n });\n return 'sites' in result\n ? {\n sites: result.sites.map((site) => ({\n cloud_id: site.cloudId,\n name: site.name,\n url: site.url,\n scopes: site.scopes,\n })),\n }\n : toIntegrationConnectionDto(result, {capabilities: options.connectionCapabilities});\n },\n });\n const siteSelectionRoute = defineRoute({\n method: 'POST',\n path: '/callback/site',\n auth: AUTH_USER,\n description: 'Complete Jira OAuth site selection.',\n schema: {\n body: completeJiraSiteSelectionBodySchema,\n response: {200: integrationConnectionDtoSchema},\n },\n errorHandler: jiraRouteErrorHandler,\n handler: async (request) => {\n const actor = requireUserContext(request);\n const connection = await handleJiraSiteSelection({\n ...options,\n cloudId: request.body.cloud_id,\n state: request.body.state,\n sessionUserId: actor.userId,\n sessionMemberships: actor.memberships,\n requireWorkspaceMembership: requireMembership,\n });\n return toIntegrationConnectionDto(connection, {capabilities: options.connectionCapabilities});\n },\n });\n return {\n prefix: '/integrations/jira',\n routes: [installRoute, callbackApiRoute, siteSelectionRoute],\n };\n}\n\nfunction unavailableWorkspaceMembershipCheck(_input: {\n workspaceId: string;\n userId: string;\n memberships: ReadonlyArray<import('@shipfox/api-auth-context').UserContextMembership>;\n}): Promise<never> {\n return Promise.reject(new Error('Workspaces inter-module client is not configured'));\n}\n\nfunction isJiraOAuthErrorCallback(query: JiraCallbackQueryDto): query is JiraCallbackQueryDto & {\n error: string;\n error_description?: string | undefined;\n state: string;\n} {\n return 'error' in query && typeof query.error === 'string';\n}\n"],"names":["AUTH_USER","requireUserContext","requireWorkspaceAccess","integrationConnectionDtoSchema","completeJiraSiteSelectionBodySchema","createJiraInstallBodySchema","createJiraInstallResponseSchema","jiraCallbackQuerySchema","jiraCallbackResponseSchema","defineRoute","config","handleJiraCallback","handleJiraOAuthCallbackError","handleJiraSiteSelection","formatJiraOAuthScopes","signJiraInstallState","toIntegrationConnectionDto","jiraRouteErrorHandler","createJiraIntegrationRoutes","options","requireMembership","requireActiveWorkspaceMembership","unavailableWorkspaceMembershipCheck","installRoute","method","path","auth","description","schema","body","response","handler","request","workspace_id","workspaceId","actor","installUrl","URL","JIRA_AUTH_BASE_URL","searchParams","set","JIRA_OAUTH_CLIENT_ID","JIRA_OAUTH_REDIRECT_URL","userId","install_url","toString","callbackApiRoute","querystring","errorHandler","query","isJiraOAuthErrorCallback","state","error","errorDescription","error_description","sessionUserId","sessionMemberships","memberships","requireWorkspaceMembership","result","code","sites","map","site","cloud_id","cloudId","name","url","scopes","capabilities","connectionCapabilities","siteSelectionRoute","connection","prefix","routes","_input","Promise","reject","Error"],"mappings":"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"}