@shipfox/api-integration-jira 5.0.0 → 7.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.turbo/turbo-build.log +1 -1
- package/CHANGELOG.md +45 -0
- package/dist/presentation/routes/install.d.ts +5 -0
- package/dist/presentation/routes/install.d.ts.map +1 -1
- package/dist/presentation/routes/install.js +7 -4
- package/dist/presentation/routes/install.js.map +1 -1
- package/dist/tsconfig.test.tsbuildinfo +1 -1
- package/package.json +9 -10
- package/src/core/tokens.test.ts +16 -2
- package/src/presentation/routes/install.ts +18 -4
- package/test/globalSetup.ts +0 -9
- package/tsconfig.build.tsbuildinfo +1 -1
- package/turbo.json +1 -1
- package/test/api-secrets.d.ts +0 -26
package/.turbo/turbo-build.log
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
$ shipfox-swc
|
|
2
|
-
Successfully compiled: 20 files with swc (
|
|
2
|
+
Successfully compiled: 20 files with swc (421.57ms)
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,50 @@
|
|
|
1
1
|
# @shipfox/api-integration-jira
|
|
2
2
|
|
|
3
|
+
## 7.0.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- ffc7fc9: Republishes the affected release set after recovering package publication.
|
|
8
|
+
- Updated dependencies [ffc7fc9]
|
|
9
|
+
- @shipfox/api-workspaces@7.0.1
|
|
10
|
+
|
|
11
|
+
## 7.0.0
|
|
12
|
+
|
|
13
|
+
### Patch Changes
|
|
14
|
+
|
|
15
|
+
- @shipfox/api-workspaces@7.0.0
|
|
16
|
+
|
|
17
|
+
## 6.0.0
|
|
18
|
+
|
|
19
|
+
### Minor Changes
|
|
20
|
+
|
|
21
|
+
- a42b575: Exposes Secrets through its inter-module contract and migrates Agent, integrations, and Workflows consumers.
|
|
22
|
+
|
|
23
|
+
### Patch Changes
|
|
24
|
+
|
|
25
|
+
- f73da5d: Enforces bounded API context imports and routes inter-module consumers through producer contracts.
|
|
26
|
+
- 326f4c0: Exposes Workspaces inter-module operations and moves Auth and OAuth providers onto injected clients.
|
|
27
|
+
- Updated dependencies [0bb82a4]
|
|
28
|
+
- Updated dependencies [7366f04]
|
|
29
|
+
- Updated dependencies [7ac43a4]
|
|
30
|
+
- Updated dependencies [f262539]
|
|
31
|
+
- Updated dependencies [3bb4e26]
|
|
32
|
+
- Updated dependencies [c2db8c3]
|
|
33
|
+
- Updated dependencies [8bdc149]
|
|
34
|
+
- Updated dependencies [f73da5d]
|
|
35
|
+
- Updated dependencies [6bdf24b]
|
|
36
|
+
- Updated dependencies [b00ed29]
|
|
37
|
+
- Updated dependencies [8aa7cd3]
|
|
38
|
+
- Updated dependencies [326f4c0]
|
|
39
|
+
- Updated dependencies [1820feb]
|
|
40
|
+
- Updated dependencies [4604a06]
|
|
41
|
+
- @shipfox/api-integration-core-dto@6.0.0
|
|
42
|
+
- @shipfox/api-workspaces@6.0.0
|
|
43
|
+
- @shipfox/node-drizzle@0.3.2
|
|
44
|
+
- @shipfox/api-auth-context@6.0.0
|
|
45
|
+
- @shipfox/node-fastify@0.2.4
|
|
46
|
+
- @shipfox/api-integration-jira-dto@6.0.0
|
|
47
|
+
|
|
3
48
|
## 5.0.0
|
|
4
49
|
|
|
5
50
|
### 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;
|
|
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":"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"}
|
|
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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"}
|