@shipfox/api-integration-jira 12.0.0 → 12.1.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.
- package/.turbo/turbo-build.log +17 -2
- package/CHANGELOG.md +10 -0
- package/README.md +58 -2
- package/dist/api/client.d.ts +19 -0
- package/dist/api/client.d.ts.map +1 -1
- package/dist/api/client.js +78 -0
- package/dist/api/client.js.map +1 -1
- package/dist/core/agent-tools-provider.d.ts +26 -0
- package/dist/core/agent-tools-provider.d.ts.map +1 -0
- package/dist/core/agent-tools-provider.js +130 -0
- package/dist/core/agent-tools-provider.js.map +1 -0
- package/dist/core/agent-tools.d.ts +16 -0
- package/dist/core/agent-tools.d.ts.map +1 -0
- package/dist/core/agent-tools.js +441 -0
- package/dist/core/agent-tools.js.map +1 -0
- package/dist/core/tokens.d.ts +2 -0
- package/dist/core/tokens.d.ts.map +1 -1
- package/dist/core/tokens.js +129 -37
- package/dist/core/tokens.js.map +1 -1
- package/dist/db/db.d.ts +68 -0
- package/dist/db/db.d.ts.map +1 -1
- package/dist/db/installations.d.ts +23 -7
- package/dist/db/installations.d.ts.map +1 -1
- package/dist/db/installations.js +42 -19
- package/dist/db/installations.js.map +1 -1
- package/dist/db/schema/installations.d.ts +34 -0
- package/dist/db/schema/installations.d.ts.map +1 -1
- package/dist/db/schema/installations.js +12 -2
- package/dist/db/schema/installations.js.map +1 -1
- package/dist/index.d.ts +20 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +17 -5
- package/dist/index.js.map +1 -1
- package/dist/temporal/activities/index.d.ts +2 -0
- package/dist/temporal/activities/index.d.ts.map +1 -0
- package/dist/temporal/activities/index.js +3 -0
- package/dist/temporal/activities/index.js.map +1 -0
- package/dist/temporal/activities/refresh-jira-tokens.d.ts +20 -0
- package/dist/temporal/activities/refresh-jira-tokens.d.ts.map +1 -0
- package/dist/temporal/activities/refresh-jira-tokens.js +58 -0
- package/dist/temporal/activities/refresh-jira-tokens.js.map +1 -0
- package/dist/temporal/constants.d.ts +6 -0
- package/dist/temporal/constants.d.ts.map +1 -0
- package/dist/temporal/constants.js +8 -0
- package/dist/temporal/constants.js.map +1 -0
- package/dist/temporal/worker.d.ts +9 -0
- package/dist/temporal/worker.d.ts.map +1 -0
- package/dist/temporal/worker.js +26 -0
- package/dist/temporal/worker.js.map +1 -0
- package/dist/temporal/workflows/index.bundle.js +25225 -0
- package/dist/temporal/workflows/index.bundle.meta.json +1 -0
- package/dist/temporal/workflows/index.d.ts +2 -0
- package/dist/temporal/workflows/index.d.ts.map +1 -0
- package/dist/temporal/workflows/index.js +3 -0
- package/dist/temporal/workflows/index.js.map +1 -0
- package/dist/temporal/workflows/refresh-jira-tokens-cron.d.ts +2 -0
- package/dist/temporal/workflows/refresh-jira-tokens-cron.d.ts.map +1 -0
- package/dist/temporal/workflows/refresh-jira-tokens-cron.js +20 -0
- package/dist/temporal/workflows/refresh-jira-tokens-cron.js.map +1 -0
- package/dist/tsconfig.test.tsbuildinfo +1 -1
- package/drizzle/0001_jira-token-refresh-state.sql +12 -0
- package/drizzle/meta/0001_snapshot.json +245 -0
- package/drizzle/meta/_journal.json +7 -0
- package/package.json +12 -5
- package/src/api/client.test.ts +133 -12
- package/src/api/client.ts +107 -0
- package/src/core/agent-tools-provider.test.ts +299 -0
- package/src/core/agent-tools-provider.ts +175 -0
- package/src/core/agent-tools.ts +450 -0
- package/src/core/tokens-refresh.test.ts +221 -4
- package/src/core/tokens.test.ts +1 -1
- package/src/core/tokens.ts +153 -33
- package/src/db/installations.test.ts +84 -2
- package/src/db/installations.ts +81 -21
- package/src/db/schema/installations.ts +21 -1
- package/src/index.test.ts +34 -0
- package/src/index.ts +47 -3
- package/src/temporal/activities/index.ts +5 -0
- package/src/temporal/activities/refresh-jira-tokens.test.ts +156 -0
- package/src/temporal/activities/refresh-jira-tokens.ts +88 -0
- package/src/temporal/constants.ts +8 -0
- package/src/temporal/worker.ts +39 -0
- package/src/temporal/workflows/index.ts +1 -0
- package/src/temporal/workflows/refresh-jira-tokens-cron.ts +19 -0
- package/test/factories/jira-installation.ts +4 -0
- package/tsconfig.build.tsbuildinfo +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/db/installations.ts"],"sourcesContent":["import {isUniqueViolation} from '@shipfox/node-drizzle';\nimport {pgClient, withPostgresSession} from '@shipfox/node-postgres';\nimport {eq, sql} from 'drizzle-orm';\nimport {\n JiraConnectionAlreadyLinkedError,\n JiraInstallationAlreadyLinkedError,\n JiraInstallationSiteMismatchError,\n} from '#core/errors.js';\nimport {db} from './db.js';\nimport {jiraInstallations, toJiraInstallation} from './schema/installations.js';\n\nexport type JiraInstallationLock = <T>(lockKey: string, fn: () => Promise<T>) => Promise<T>;\n\nconst JIRA_INSTALLATION_LOCK_RETRY_DELAY_MS = 100;\nconst JIRA_INSTALLATION_LOCK_MAX_RETRY_DELAY_MS = 1_000;\nconst JIRA_INSTALLATION_LOCK_TIMEOUT_MS = 30_000;\n\nexport async function withJiraInstallationLock<T>(lockKey: string, fn: () => Promise<T>) {\n const advisoryKey = `jira-installation:${lockKey}`;\n const deadline = Date.now() + JIRA_INSTALLATION_LOCK_TIMEOUT_MS;\n let retryDelayMs = JIRA_INSTALLATION_LOCK_RETRY_DELAY_MS;\n\n while (true) {\n const attempt = await withPostgresSession(async (client) => {\n const lock = await client.query<{acquired: boolean}>(\n 'SELECT pg_try_advisory_lock(hashtext($1)) AS acquired',\n [advisoryKey],\n );\n if (lock.rows[0]?.acquired !== true) return {acquired: false as const};\n\n try {\n return {acquired: true as const, value: await fn()};\n } finally {\n await client.query('SELECT pg_advisory_unlock(hashtext($1))', [advisoryKey]);\n }\n });\n\n if (attempt.acquired) return attempt.value;\n if (Date.now() >= deadline) {\n throw new Error(`Timed out waiting for Jira installation lock: ${lockKey}`);\n }\n await new Promise((resolve) => setTimeout(resolve, retryDelayMs));\n retryDelayMs = Math.min(retryDelayMs * 2, JIRA_INSTALLATION_LOCK_MAX_RETRY_DELAY_MS);\n }\n}\n\nexport type JiraInstallationStatus = 'installed' | 'revoked';\n\nexport interface JiraInstallation {\n id: string;\n connectionId: string;\n cloudId: string;\n siteUrl: string;\n siteName: string;\n authorizingAccountId: string;\n scopes: string[];\n webhookIds: number[];\n webhookExpiresAt: Date | null;\n status: JiraInstallationStatus;\n tokenExpiresAt: Date | null;\n createdAt: Date;\n updatedAt: Date;\n}\n\nexport interface UpsertJiraInstallationParams {\n connectionId: string;\n cloudId: string;\n siteUrl: string;\n siteName: string;\n authorizingAccountId: string;\n scopes: string[];\n webhookIds?: number[] | undefined;\n webhookExpiresAt?: Date | null | undefined;\n status: JiraInstallationStatus;\n tokenExpiresAt?: Date | null | undefined;\n}\n\nexport interface UpdateJiraInstallationTokenExpiryParams {\n connectionId: string;\n tokenExpiresAt: Date | null;\n scopes?: string[] | undefined;\n}\n\nexport interface UpdateJiraInstallationWebhookParams {\n connectionId: string;\n webhookIds: number[];\n webhookExpiresAt: Date | null;\n}\n\ntype JiraDb = ReturnType<typeof db>;\ntype JiraTx = Parameters<Parameters<JiraDb['transaction']>[0]>[0];\n\nexport async function upsertJiraInstallation(\n params: UpsertJiraInstallationParams,\n options: {tx?: unknown} = {},\n): Promise<JiraInstallation> {\n const executor = (options.tx ?? db()) as JiraDb | JiraTx;\n const now = new Date();\n let row: typeof jiraInstallations.$inferSelect | undefined;\n try {\n [row] = await executor\n .insert(jiraInstallations)\n .values({\n connectionId: params.connectionId,\n cloudId: params.cloudId,\n siteUrl: params.siteUrl,\n siteName: params.siteName,\n authorizingAccountId: params.authorizingAccountId,\n scopes: params.scopes,\n webhookIds: params.webhookIds ?? [],\n webhookExpiresAt: params.webhookExpiresAt ?? null,\n status: params.status,\n tokenExpiresAt: params.tokenExpiresAt ?? null,\n })\n .onConflictDoUpdate({\n target: jiraInstallations.connectionId,\n setWhere: eq(jiraInstallations.cloudId, params.cloudId),\n set: {\n cloudId: params.cloudId,\n siteUrl: params.siteUrl,\n siteName: params.siteName,\n authorizingAccountId: params.authorizingAccountId,\n scopes: params.scopes,\n ...(params.webhookIds === undefined ? {} : {webhookIds: params.webhookIds}),\n ...(params.webhookExpiresAt === undefined\n ? {}\n : {webhookExpiresAt: params.webhookExpiresAt}),\n status: params.status,\n tokenExpiresAt: params.tokenExpiresAt ?? null,\n updatedAt: now,\n },\n })\n .returning();\n } catch (error) {\n if (isUniqueViolation(error, 'integrations_jira_installations_connection_unique')) {\n throw new JiraConnectionAlreadyLinkedError(params.connectionId);\n }\n if (isUniqueViolation(error, 'integrations_jira_installations_cloud_id_unique')) {\n throw new JiraInstallationAlreadyLinkedError(params.cloudId);\n }\n throw error;\n }\n\n if (!row) throw new JiraInstallationSiteMismatchError(params.connectionId, params.cloudId);\n return toJiraInstallation(row);\n}\n\nexport async function getJiraInstallationByCloudId(\n cloudId: string,\n options: {tx?: unknown} = {},\n): Promise<JiraInstallation | undefined> {\n const executor = (options.tx ?? db()) as JiraDb | JiraTx;\n const rows = await executor\n .select()\n .from(jiraInstallations)\n .where(eq(jiraInstallations.cloudId, cloudId))\n .limit(1);\n const row = rows[0];\n return row ? toJiraInstallation(row) : undefined;\n}\n\nexport async function updateJiraInstallationTokenExpiry(\n params: UpdateJiraInstallationTokenExpiryParams,\n options: {tx?: unknown} = {},\n): Promise<JiraInstallation | undefined> {\n const executor = (options.tx ?? db()) as JiraDb | JiraTx;\n const [row] = await executor\n .update(jiraInstallations)\n .set({\n tokenExpiresAt: params.tokenExpiresAt,\n ...(params.scopes === undefined ? {} : {scopes: params.scopes}),\n updatedAt: new Date(),\n })\n .where(eq(jiraInstallations.connectionId, params.connectionId))\n .returning();\n return row ? toJiraInstallation(row) : undefined;\n}\n\nexport async function updateJiraInstallationWebhook(\n params: UpdateJiraInstallationWebhookParams,\n options: {tx?: unknown} = {},\n): Promise<JiraInstallation | undefined> {\n const executor = (options.tx ?? db()) as JiraDb | JiraTx;\n const [row] = await executor\n .update(jiraInstallations)\n .set({\n webhookIds: params.webhookIds,\n webhookExpiresAt: params.webhookExpiresAt,\n updatedAt: new Date(),\n })\n .where(eq(jiraInstallations.connectionId, params.connectionId))\n .returning();\n return row ? toJiraInstallation(row) : undefined;\n}\n\nexport async function deleteJiraInstallationByConnectionId(\n connectionId: string,\n options: {tx?: unknown} = {},\n): Promise<boolean> {\n const executor = (options.tx ?? db()) as JiraDb | JiraTx;\n const result = await executor\n .delete(jiraInstallations)\n .where(eq(jiraInstallations.connectionId, connectionId));\n return (result.rowCount ?? 0) > 0;\n}\n\nexport type JiraRefreshLockResult<T> = {acquired: true; value: T} | {acquired: false};\n\nexport function withJiraRefreshLock<T>(\n connectionId: string,\n fn: () => Promise<T>,\n): Promise<JiraRefreshLockResult<T>> {\n return withJiraRefreshLockClient(connectionId, fn);\n}\n\nexport function withJiraWebhookRegistrationLock<T>(\n lockKey: string,\n fn: (tx?: unknown) => Promise<T>,\n): Promise<T> {\n return withJiraInstallationLock(lockKey, () => fn());\n}\n\nasync function withJiraRefreshLockClient<T>(\n connectionId: string,\n fn: () => Promise<T>,\n): Promise<JiraRefreshLockResult<T>> {\n const client = await pgClient().connect();\n let acquired = false;\n try {\n const lock = await client.query<{acquired: boolean}>(\n 'SELECT pg_try_advisory_lock(hashtext($1)) AS acquired',\n [connectionId],\n );\n acquired = lock.rows[0]?.acquired === true;\n if (!acquired) return {acquired: false};\n return {acquired: true, value: await fn()};\n } finally {\n try {\n if (acquired) await client.query('SELECT pg_advisory_unlock(hashtext($1))', [connectionId]);\n } finally {\n client.release();\n }\n }\n}\n\nexport async function getJiraInstallationByConnectionId(\n connectionId: string,\n options: {tx?: unknown} = {},\n): Promise<JiraInstallation | undefined> {\n const executor = (options.tx ?? db()) as JiraDb | JiraTx;\n const rows = await executor\n .select()\n .from(jiraInstallations)\n .where(eq(jiraInstallations.connectionId, connectionId))\n .limit(1);\n const row = rows[0];\n if (!row) return undefined;\n return toJiraInstallation(row);\n}\n\nexport async function getJiraInstallationByWebhookId(\n webhookId: number,\n options: {tx?: unknown} = {},\n): Promise<JiraInstallation | undefined> {\n const executor = (options.tx ?? db()) as JiraDb | JiraTx;\n const rows = await executor\n .select()\n .from(jiraInstallations)\n .where(sql`${jiraInstallations.webhookIds} @> ${JSON.stringify([webhookId])}::jsonb`)\n .limit(1);\n const row = rows[0];\n if (!row) return undefined;\n return toJiraInstallation(row);\n}\n\nexport async function markJiraInstallationRevoked(\n connectionId: string,\n options: {tx?: unknown} = {},\n): Promise<JiraInstallation | undefined> {\n const executor = (options.tx ?? db()) as JiraDb | JiraTx;\n const [row] = await executor\n .update(jiraInstallations)\n .set({status: 'revoked', updatedAt: new Date()})\n .where(eq(jiraInstallations.connectionId, connectionId))\n .returning();\n if (!row) return undefined;\n return toJiraInstallation(row);\n}\n"],"names":["isUniqueViolation","pgClient","withPostgresSession","eq","sql","JiraConnectionAlreadyLinkedError","JiraInstallationAlreadyLinkedError","JiraInstallationSiteMismatchError","db","jiraInstallations","toJiraInstallation","JIRA_INSTALLATION_LOCK_RETRY_DELAY_MS","JIRA_INSTALLATION_LOCK_MAX_RETRY_DELAY_MS","JIRA_INSTALLATION_LOCK_TIMEOUT_MS","withJiraInstallationLock","lockKey","fn","advisoryKey","deadline","Date","now","retryDelayMs","attempt","client","lock","query","rows","acquired","value","Error","Promise","resolve","setTimeout","Math","min","upsertJiraInstallation","params","options","executor","tx","row","insert","values","connectionId","cloudId","siteUrl","siteName","authorizingAccountId","scopes","webhookIds","webhookExpiresAt","status","tokenExpiresAt","onConflictDoUpdate","target","setWhere","set","undefined","updatedAt","returning","error","getJiraInstallationByCloudId","select","from","where","limit","updateJiraInstallationTokenExpiry","update","updateJiraInstallationWebhook","deleteJiraInstallationByConnectionId","result","delete","rowCount","withJiraRefreshLock","withJiraRefreshLockClient","withJiraWebhookRegistrationLock","connect","release","getJiraInstallationByConnectionId","getJiraInstallationByWebhookId","webhookId","JSON","stringify","markJiraInstallationRevoked"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../src/db/installations.ts"],"sourcesContent":["import {isUniqueViolation} from '@shipfox/node-drizzle';\nimport {pgClient, withPostgresSession} from '@shipfox/node-postgres';\nimport {and, asc, eq, lte, sql} from 'drizzle-orm';\nimport {\n JiraConnectionAlreadyLinkedError,\n JiraInstallationAlreadyLinkedError,\n JiraInstallationSiteMismatchError,\n} from '#core/errors.js';\nimport {db} from './db.js';\nimport {jiraInstallations, toJiraInstallation} from './schema/installations.js';\n\nexport type JiraInstallationLock = <T>(lockKey: string, fn: () => Promise<T>) => Promise<T>;\n\nconst JIRA_ADVISORY_LOCK_RETRY_DELAY_MS = 100;\nconst JIRA_ADVISORY_LOCK_MAX_RETRY_DELAY_MS = 1_000;\nconst JIRA_ADVISORY_LOCK_TIMEOUT_MS = 30_000;\n\ntype JiraAdvisoryLockAttempt<T> = {acquired: true; value: T} | {acquired: false};\n\nexport function withJiraInstallationLock<T>(lockKey: string, fn: () => Promise<T>) {\n const advisoryKey = `jira-installation:${lockKey}`;\n return withJiraAdvisoryLockWait(`Jira installation lock: ${lockKey}`, () =>\n withPostgresSession(async (client) => {\n const lock = await client.query<{acquired: boolean}>(\n 'SELECT pg_try_advisory_lock(hashtext($1)) AS acquired',\n [advisoryKey],\n );\n if (lock.rows[0]?.acquired !== true) return {acquired: false as const};\n\n try {\n return {acquired: true as const, value: await fn()};\n } finally {\n await client.query('SELECT pg_advisory_unlock(hashtext($1))', [advisoryKey]);\n }\n }),\n );\n}\n\nexport type JiraInstallationStatus = 'installed' | 'revoked';\n\nexport interface JiraInstallation {\n id: string;\n connectionId: string;\n cloudId: string;\n siteUrl: string;\n siteName: string;\n authorizingAccountId: string;\n scopes: string[];\n webhookIds: number[];\n webhookExpiresAt: Date | null;\n status: JiraInstallationStatus;\n tokenExpiresAt: Date | null;\n refreshTokenLastUsedAt: Date;\n refreshTokenLastAttemptedAt: Date;\n createdAt: Date;\n updatedAt: Date;\n}\n\nexport interface UpsertJiraInstallationParams {\n connectionId: string;\n cloudId: string;\n siteUrl: string;\n siteName: string;\n authorizingAccountId: string;\n scopes: string[];\n webhookIds?: number[] | undefined;\n webhookExpiresAt?: Date | null | undefined;\n status: JiraInstallationStatus;\n tokenExpiresAt?: Date | null | undefined;\n refreshTokenLastUsedAt?: Date | undefined;\n refreshTokenLastAttemptedAt?: Date | undefined;\n}\n\nexport interface UpdateJiraInstallationTokenExpiryParams {\n connectionId: string;\n tokenExpiresAt: Date | null;\n scopes?: string[] | undefined;\n}\n\nexport interface UpdateJiraInstallationWebhookParams {\n connectionId: string;\n webhookIds: number[];\n webhookExpiresAt: Date | null;\n}\n\ntype JiraDb = ReturnType<typeof db>;\ntype JiraTx = Parameters<Parameters<JiraDb['transaction']>[0]>[0];\n\nexport async function upsertJiraInstallation(\n params: UpsertJiraInstallationParams,\n options: {tx?: unknown} = {},\n): Promise<JiraInstallation> {\n const executor = (options.tx ?? db()) as JiraDb | JiraTx;\n const now = new Date();\n let row: typeof jiraInstallations.$inferSelect | undefined;\n try {\n [row] = await executor\n .insert(jiraInstallations)\n .values({\n connectionId: params.connectionId,\n cloudId: params.cloudId,\n siteUrl: params.siteUrl,\n siteName: params.siteName,\n authorizingAccountId: params.authorizingAccountId,\n scopes: params.scopes,\n webhookIds: params.webhookIds ?? [],\n webhookExpiresAt: params.webhookExpiresAt ?? null,\n status: params.status,\n tokenExpiresAt: params.tokenExpiresAt ?? null,\n refreshTokenLastUsedAt: params.refreshTokenLastUsedAt ?? now,\n refreshTokenLastAttemptedAt: params.refreshTokenLastAttemptedAt ?? now,\n })\n .onConflictDoUpdate({\n target: jiraInstallations.connectionId,\n setWhere: eq(jiraInstallations.cloudId, params.cloudId),\n set: {\n cloudId: params.cloudId,\n siteUrl: params.siteUrl,\n siteName: params.siteName,\n authorizingAccountId: params.authorizingAccountId,\n scopes: params.scopes,\n ...(params.webhookIds === undefined ? {} : {webhookIds: params.webhookIds}),\n ...(params.webhookExpiresAt === undefined\n ? {}\n : {webhookExpiresAt: params.webhookExpiresAt}),\n status: params.status,\n tokenExpiresAt: params.tokenExpiresAt ?? null,\n refreshTokenLastUsedAt: params.refreshTokenLastUsedAt ?? now,\n refreshTokenLastAttemptedAt: params.refreshTokenLastAttemptedAt ?? now,\n updatedAt: now,\n },\n })\n .returning();\n } catch (error) {\n if (isUniqueViolation(error, 'integrations_jira_installations_connection_unique')) {\n throw new JiraConnectionAlreadyLinkedError(params.connectionId);\n }\n if (isUniqueViolation(error, 'integrations_jira_installations_cloud_id_unique')) {\n throw new JiraInstallationAlreadyLinkedError(params.cloudId);\n }\n throw error;\n }\n\n if (!row) throw new JiraInstallationSiteMismatchError(params.connectionId, params.cloudId);\n return toJiraInstallation(row);\n}\n\nexport async function getJiraInstallationByCloudId(\n cloudId: string,\n options: {tx?: unknown} = {},\n): Promise<JiraInstallation | undefined> {\n const executor = (options.tx ?? db()) as JiraDb | JiraTx;\n const rows = await executor\n .select()\n .from(jiraInstallations)\n .where(eq(jiraInstallations.cloudId, cloudId))\n .limit(1);\n const row = rows[0];\n return row ? toJiraInstallation(row) : undefined;\n}\n\nexport async function updateJiraInstallationTokenExpiry(\n params: UpdateJiraInstallationTokenExpiryParams,\n options: {tx?: unknown} = {},\n): Promise<JiraInstallation | undefined> {\n const executor = (options.tx ?? db()) as JiraDb | JiraTx;\n const now = new Date();\n const [row] = await executor\n .update(jiraInstallations)\n .set({\n tokenExpiresAt: params.tokenExpiresAt,\n refreshTokenLastUsedAt: now,\n refreshTokenLastAttemptedAt: now,\n ...(params.scopes === undefined ? {} : {scopes: params.scopes}),\n updatedAt: now,\n })\n .where(eq(jiraInstallations.connectionId, params.connectionId))\n .returning();\n return row ? toJiraInstallation(row) : undefined;\n}\n\nexport async function markJiraInstallationTokenRefreshAttempt(\n connectionId: string,\n options: {tx?: unknown} = {},\n): Promise<JiraInstallation | undefined> {\n const executor = (options.tx ?? db()) as JiraDb | JiraTx;\n const [row] = await executor\n .update(jiraInstallations)\n .set({refreshTokenLastAttemptedAt: new Date()})\n .where(eq(jiraInstallations.connectionId, connectionId))\n .returning();\n return row ? toJiraInstallation(row) : undefined;\n}\n\nexport async function listJiraInstallationsDueForTokenRefresh(\n params: {before: Date; limit?: number | undefined},\n options: {tx?: unknown} = {},\n): Promise<JiraInstallation[]> {\n const executor = (options.tx ?? db()) as JiraDb | JiraTx;\n const rows = await executor\n .select()\n .from(jiraInstallations)\n .where(\n and(\n eq(jiraInstallations.status, 'installed'),\n lte(jiraInstallations.refreshTokenLastUsedAt, params.before),\n ),\n )\n .orderBy(asc(jiraInstallations.refreshTokenLastAttemptedAt))\n .limit(params.limit ?? 100);\n return rows.map(toJiraInstallation);\n}\n\nexport async function updateJiraInstallationWebhook(\n params: UpdateJiraInstallationWebhookParams,\n options: {tx?: unknown} = {},\n): Promise<JiraInstallation | undefined> {\n const executor = (options.tx ?? db()) as JiraDb | JiraTx;\n const [row] = await executor\n .update(jiraInstallations)\n .set({\n webhookIds: params.webhookIds,\n webhookExpiresAt: params.webhookExpiresAt,\n updatedAt: new Date(),\n })\n .where(eq(jiraInstallations.connectionId, params.connectionId))\n .returning();\n return row ? toJiraInstallation(row) : undefined;\n}\n\nexport async function deleteJiraInstallationByConnectionId(\n connectionId: string,\n options: {tx?: unknown} = {},\n): Promise<boolean> {\n const executor = (options.tx ?? db()) as JiraDb | JiraTx;\n const result = await executor\n .delete(jiraInstallations)\n .where(eq(jiraInstallations.connectionId, connectionId));\n return (result.rowCount ?? 0) > 0;\n}\n\nexport type JiraRefreshLockResult<T> = JiraAdvisoryLockAttempt<T>;\n\nexport function withJiraRefreshLock<T>(\n connectionId: string,\n fn: () => Promise<T>,\n): Promise<JiraRefreshLockResult<T>> {\n return withJiraRefreshLockClient(connectionId, fn);\n}\n\nexport function withJiraRefreshLockAndWait<T>(\n connectionId: string,\n fn: () => Promise<T>,\n): Promise<T> {\n return withJiraAdvisoryLockWait(`Jira refresh lock: ${connectionId}`, () =>\n withJiraRefreshLock(connectionId, fn),\n );\n}\n\nexport function withJiraWebhookRegistrationLock<T>(\n lockKey: string,\n fn: (tx?: unknown) => Promise<T>,\n): Promise<T> {\n return withJiraInstallationLock(lockKey, () => fn());\n}\n\nasync function withJiraRefreshLockClient<T>(\n connectionId: string,\n fn: () => Promise<T>,\n): Promise<JiraRefreshLockResult<T>> {\n const client = await pgClient().connect();\n let acquired = false;\n try {\n const lock = await client.query<{acquired: boolean}>(\n 'SELECT pg_try_advisory_lock(hashtext($1)) AS acquired',\n [connectionId],\n );\n acquired = lock.rows[0]?.acquired === true;\n if (!acquired) return {acquired: false};\n return {acquired: true, value: await fn()};\n } finally {\n try {\n if (acquired) await client.query('SELECT pg_advisory_unlock(hashtext($1))', [connectionId]);\n } finally {\n client.release();\n }\n }\n}\n\nasync function withJiraAdvisoryLockWait<T>(\n lockDescription: string,\n attemptLock: () => Promise<JiraAdvisoryLockAttempt<T>>,\n): Promise<T> {\n const deadline = Date.now() + JIRA_ADVISORY_LOCK_TIMEOUT_MS;\n let retryDelayMs = JIRA_ADVISORY_LOCK_RETRY_DELAY_MS;\n\n while (true) {\n const attempt = await attemptLock();\n if (attempt.acquired) return attempt.value;\n if (Date.now() >= deadline) throw new Error(`Timed out waiting for ${lockDescription}`);\n await new Promise((resolve) => setTimeout(resolve, retryDelayMs));\n retryDelayMs = Math.min(retryDelayMs * 2, JIRA_ADVISORY_LOCK_MAX_RETRY_DELAY_MS);\n }\n}\n\nexport async function getJiraInstallationByConnectionId(\n connectionId: string,\n options: {tx?: unknown} = {},\n): Promise<JiraInstallation | undefined> {\n const executor = (options.tx ?? db()) as JiraDb | JiraTx;\n const rows = await executor\n .select()\n .from(jiraInstallations)\n .where(eq(jiraInstallations.connectionId, connectionId))\n .limit(1);\n const row = rows[0];\n if (!row) return undefined;\n return toJiraInstallation(row);\n}\n\nexport async function getJiraInstallationByWebhookId(\n webhookId: number,\n options: {tx?: unknown} = {},\n): Promise<JiraInstallation | undefined> {\n const executor = (options.tx ?? db()) as JiraDb | JiraTx;\n const rows = await executor\n .select()\n .from(jiraInstallations)\n .where(sql`${jiraInstallations.webhookIds} @> ${JSON.stringify([webhookId])}::jsonb`)\n .limit(1);\n const row = rows[0];\n if (!row) return undefined;\n return toJiraInstallation(row);\n}\n\nexport async function markJiraInstallationRevoked(\n connectionId: string,\n options: {tx?: unknown} = {},\n): Promise<JiraInstallation | undefined> {\n const executor = (options.tx ?? db()) as JiraDb | JiraTx;\n const [row] = await executor\n .update(jiraInstallations)\n .set({status: 'revoked', updatedAt: new Date()})\n .where(eq(jiraInstallations.connectionId, connectionId))\n .returning();\n if (!row) return undefined;\n return toJiraInstallation(row);\n}\n"],"names":["isUniqueViolation","pgClient","withPostgresSession","and","asc","eq","lte","sql","JiraConnectionAlreadyLinkedError","JiraInstallationAlreadyLinkedError","JiraInstallationSiteMismatchError","db","jiraInstallations","toJiraInstallation","JIRA_ADVISORY_LOCK_RETRY_DELAY_MS","JIRA_ADVISORY_LOCK_MAX_RETRY_DELAY_MS","JIRA_ADVISORY_LOCK_TIMEOUT_MS","withJiraInstallationLock","lockKey","fn","advisoryKey","withJiraAdvisoryLockWait","client","lock","query","rows","acquired","value","upsertJiraInstallation","params","options","executor","tx","now","Date","row","insert","values","connectionId","cloudId","siteUrl","siteName","authorizingAccountId","scopes","webhookIds","webhookExpiresAt","status","tokenExpiresAt","refreshTokenLastUsedAt","refreshTokenLastAttemptedAt","onConflictDoUpdate","target","setWhere","set","undefined","updatedAt","returning","error","getJiraInstallationByCloudId","select","from","where","limit","updateJiraInstallationTokenExpiry","update","markJiraInstallationTokenRefreshAttempt","listJiraInstallationsDueForTokenRefresh","before","orderBy","map","updateJiraInstallationWebhook","deleteJiraInstallationByConnectionId","result","delete","rowCount","withJiraRefreshLock","withJiraRefreshLockClient","withJiraRefreshLockAndWait","withJiraWebhookRegistrationLock","connect","release","lockDescription","attemptLock","deadline","retryDelayMs","attempt","Error","Promise","resolve","setTimeout","Math","min","getJiraInstallationByConnectionId","getJiraInstallationByWebhookId","webhookId","JSON","stringify","markJiraInstallationRevoked"],"mappings":"AAAA,SAAQA,iBAAiB,QAAO,wBAAwB;AACxD,SAAQC,QAAQ,EAAEC,mBAAmB,QAAO,yBAAyB;AACrE,SAAQC,GAAG,EAAEC,GAAG,EAAEC,EAAE,EAAEC,GAAG,EAAEC,GAAG,QAAO,cAAc;AACnD,SACEC,gCAAgC,EAChCC,kCAAkC,EAClCC,iCAAiC,QAC5B,kBAAkB;AACzB,SAAQC,EAAE,QAAO,UAAU;AAC3B,SAAQC,iBAAiB,EAAEC,kBAAkB,QAAO,4BAA4B;AAIhF,MAAMC,oCAAoC;AAC1C,MAAMC,wCAAwC;AAC9C,MAAMC,gCAAgC;AAItC,OAAO,SAASC,yBAA4BC,OAAe,EAAEC,EAAoB;IAC/E,MAAMC,cAAc,CAAC,kBAAkB,EAAEF,SAAS;IAClD,OAAOG,yBAAyB,CAAC,wBAAwB,EAAEH,SAAS,EAAE,IACpEhB,oBAAoB,OAAOoB;YACzB,MAAMC,OAAO,MAAMD,OAAOE,KAAK,CAC7B,yDACA;gBAACJ;aAAY;YAEf,IAAIG,KAAKE,IAAI,CAAC,EAAE,EAAEC,aAAa,MAAM,OAAO;gBAACA,UAAU;YAAc;YAErE,IAAI;gBACF,OAAO;oBAACA,UAAU;oBAAeC,OAAO,MAAMR;gBAAI;YACpD,SAAU;gBACR,MAAMG,OAAOE,KAAK,CAAC,2CAA2C;oBAACJ;iBAAY;YAC7E;QACF;AAEJ;AAoDA,OAAO,eAAeQ,uBACpBC,MAAoC,EACpCC,UAA0B,CAAC,CAAC;IAE5B,MAAMC,WAAYD,QAAQE,EAAE,IAAIrB;IAChC,MAAMsB,MAAM,IAAIC;IAChB,IAAIC;IACJ,IAAI;QACF,CAACA,IAAI,GAAG,MAAMJ,SACXK,MAAM,CAACxB,mBACPyB,MAAM,CAAC;YACNC,cAAcT,OAAOS,YAAY;YACjCC,SAASV,OAAOU,OAAO;YACvBC,SAASX,OAAOW,OAAO;YACvBC,UAAUZ,OAAOY,QAAQ;YACzBC,sBAAsBb,OAAOa,oBAAoB;YACjDC,QAAQd,OAAOc,MAAM;YACrBC,YAAYf,OAAOe,UAAU,IAAI,EAAE;YACnCC,kBAAkBhB,OAAOgB,gBAAgB,IAAI;YAC7CC,QAAQjB,OAAOiB,MAAM;YACrBC,gBAAgBlB,OAAOkB,cAAc,IAAI;YACzCC,wBAAwBnB,OAAOmB,sBAAsB,IAAIf;YACzDgB,6BAA6BpB,OAAOoB,2BAA2B,IAAIhB;QACrE,GACCiB,kBAAkB,CAAC;YAClBC,QAAQvC,kBAAkB0B,YAAY;YACtCc,UAAU/C,GAAGO,kBAAkB2B,OAAO,EAAEV,OAAOU,OAAO;YACtDc,KAAK;gBACHd,SAASV,OAAOU,OAAO;gBACvBC,SAASX,OAAOW,OAAO;gBACvBC,UAAUZ,OAAOY,QAAQ;gBACzBC,sBAAsBb,OAAOa,oBAAoB;gBACjDC,QAAQd,OAAOc,MAAM;gBACrB,GAAId,OAAOe,UAAU,KAAKU,YAAY,CAAC,IAAI;oBAACV,YAAYf,OAAOe,UAAU;gBAAA,CAAC;gBAC1E,GAAIf,OAAOgB,gBAAgB,KAAKS,YAC5B,CAAC,IACD;oBAACT,kBAAkBhB,OAAOgB,gBAAgB;gBAAA,CAAC;gBAC/CC,QAAQjB,OAAOiB,MAAM;gBACrBC,gBAAgBlB,OAAOkB,cAAc,IAAI;gBACzCC,wBAAwBnB,OAAOmB,sBAAsB,IAAIf;gBACzDgB,6BAA6BpB,OAAOoB,2BAA2B,IAAIhB;gBACnEsB,WAAWtB;YACb;QACF,GACCuB,SAAS;IACd,EAAE,OAAOC,OAAO;QACd,IAAIzD,kBAAkByD,OAAO,sDAAsD;YACjF,MAAM,IAAIjD,iCAAiCqB,OAAOS,YAAY;QAChE;QACA,IAAItC,kBAAkByD,OAAO,oDAAoD;YAC/E,MAAM,IAAIhD,mCAAmCoB,OAAOU,OAAO;QAC7D;QACA,MAAMkB;IACR;IAEA,IAAI,CAACtB,KAAK,MAAM,IAAIzB,kCAAkCmB,OAAOS,YAAY,EAAET,OAAOU,OAAO;IACzF,OAAO1B,mBAAmBsB;AAC5B;AAEA,OAAO,eAAeuB,6BACpBnB,OAAe,EACfT,UAA0B,CAAC,CAAC;IAE5B,MAAMC,WAAYD,QAAQE,EAAE,IAAIrB;IAChC,MAAMc,OAAO,MAAMM,SAChB4B,MAAM,GACNC,IAAI,CAAChD,mBACLiD,KAAK,CAACxD,GAAGO,kBAAkB2B,OAAO,EAAEA,UACpCuB,KAAK,CAAC;IACT,MAAM3B,MAAMV,IAAI,CAAC,EAAE;IACnB,OAAOU,MAAMtB,mBAAmBsB,OAAOmB;AACzC;AAEA,OAAO,eAAeS,kCACpBlC,MAA+C,EAC/CC,UAA0B,CAAC,CAAC;IAE5B,MAAMC,WAAYD,QAAQE,EAAE,IAAIrB;IAChC,MAAMsB,MAAM,IAAIC;IAChB,MAAM,CAACC,IAAI,GAAG,MAAMJ,SACjBiC,MAAM,CAACpD,mBACPyC,GAAG,CAAC;QACHN,gBAAgBlB,OAAOkB,cAAc;QACrCC,wBAAwBf;QACxBgB,6BAA6BhB;QAC7B,GAAIJ,OAAOc,MAAM,KAAKW,YAAY,CAAC,IAAI;YAACX,QAAQd,OAAOc,MAAM;QAAA,CAAC;QAC9DY,WAAWtB;IACb,GACC4B,KAAK,CAACxD,GAAGO,kBAAkB0B,YAAY,EAAET,OAAOS,YAAY,GAC5DkB,SAAS;IACZ,OAAOrB,MAAMtB,mBAAmBsB,OAAOmB;AACzC;AAEA,OAAO,eAAeW,wCACpB3B,YAAoB,EACpBR,UAA0B,CAAC,CAAC;IAE5B,MAAMC,WAAYD,QAAQE,EAAE,IAAIrB;IAChC,MAAM,CAACwB,IAAI,GAAG,MAAMJ,SACjBiC,MAAM,CAACpD,mBACPyC,GAAG,CAAC;QAACJ,6BAA6B,IAAIf;IAAM,GAC5C2B,KAAK,CAACxD,GAAGO,kBAAkB0B,YAAY,EAAEA,eACzCkB,SAAS;IACZ,OAAOrB,MAAMtB,mBAAmBsB,OAAOmB;AACzC;AAEA,OAAO,eAAeY,wCACpBrC,MAAkD,EAClDC,UAA0B,CAAC,CAAC;IAE5B,MAAMC,WAAYD,QAAQE,EAAE,IAAIrB;IAChC,MAAMc,OAAO,MAAMM,SAChB4B,MAAM,GACNC,IAAI,CAAChD,mBACLiD,KAAK,CACJ1D,IACEE,GAAGO,kBAAkBkC,MAAM,EAAE,cAC7BxC,IAAIM,kBAAkBoC,sBAAsB,EAAEnB,OAAOsC,MAAM,IAG9DC,OAAO,CAAChE,IAAIQ,kBAAkBqC,2BAA2B,GACzDa,KAAK,CAACjC,OAAOiC,KAAK,IAAI;IACzB,OAAOrC,KAAK4C,GAAG,CAACxD;AAClB;AAEA,OAAO,eAAeyD,8BACpBzC,MAA2C,EAC3CC,UAA0B,CAAC,CAAC;IAE5B,MAAMC,WAAYD,QAAQE,EAAE,IAAIrB;IAChC,MAAM,CAACwB,IAAI,GAAG,MAAMJ,SACjBiC,MAAM,CAACpD,mBACPyC,GAAG,CAAC;QACHT,YAAYf,OAAOe,UAAU;QAC7BC,kBAAkBhB,OAAOgB,gBAAgB;QACzCU,WAAW,IAAIrB;IACjB,GACC2B,KAAK,CAACxD,GAAGO,kBAAkB0B,YAAY,EAAET,OAAOS,YAAY,GAC5DkB,SAAS;IACZ,OAAOrB,MAAMtB,mBAAmBsB,OAAOmB;AACzC;AAEA,OAAO,eAAeiB,qCACpBjC,YAAoB,EACpBR,UAA0B,CAAC,CAAC;IAE5B,MAAMC,WAAYD,QAAQE,EAAE,IAAIrB;IAChC,MAAM6D,SAAS,MAAMzC,SAClB0C,MAAM,CAAC7D,mBACPiD,KAAK,CAACxD,GAAGO,kBAAkB0B,YAAY,EAAEA;IAC5C,OAAO,AAACkC,CAAAA,OAAOE,QAAQ,IAAI,CAAA,IAAK;AAClC;AAIA,OAAO,SAASC,oBACdrC,YAAoB,EACpBnB,EAAoB;IAEpB,OAAOyD,0BAA0BtC,cAAcnB;AACjD;AAEA,OAAO,SAAS0D,2BACdvC,YAAoB,EACpBnB,EAAoB;IAEpB,OAAOE,yBAAyB,CAAC,mBAAmB,EAAEiB,cAAc,EAAE,IACpEqC,oBAAoBrC,cAAcnB;AAEtC;AAEA,OAAO,SAAS2D,gCACd5D,OAAe,EACfC,EAAgC;IAEhC,OAAOF,yBAAyBC,SAAS,IAAMC;AACjD;AAEA,eAAeyD,0BACbtC,YAAoB,EACpBnB,EAAoB;IAEpB,MAAMG,SAAS,MAAMrB,WAAW8E,OAAO;IACvC,IAAIrD,WAAW;IACf,IAAI;QACF,MAAMH,OAAO,MAAMD,OAAOE,KAAK,CAC7B,yDACA;YAACc;SAAa;QAEhBZ,WAAWH,KAAKE,IAAI,CAAC,EAAE,EAAEC,aAAa;QACtC,IAAI,CAACA,UAAU,OAAO;YAACA,UAAU;QAAK;QACtC,OAAO;YAACA,UAAU;YAAMC,OAAO,MAAMR;QAAI;IAC3C,SAAU;QACR,IAAI;YACF,IAAIO,UAAU,MAAMJ,OAAOE,KAAK,CAAC,2CAA2C;gBAACc;aAAa;QAC5F,SAAU;YACRhB,OAAO0D,OAAO;QAChB;IACF;AACF;AAEA,eAAe3D,yBACb4D,eAAuB,EACvBC,WAAsD;IAEtD,MAAMC,WAAWjD,KAAKD,GAAG,KAAKjB;IAC9B,IAAIoE,eAAetE;IAEnB,MAAO,KAAM;QACX,MAAMuE,UAAU,MAAMH;QACtB,IAAIG,QAAQ3D,QAAQ,EAAE,OAAO2D,QAAQ1D,KAAK;QAC1C,IAAIO,KAAKD,GAAG,MAAMkD,UAAU,MAAM,IAAIG,MAAM,CAAC,sBAAsB,EAAEL,iBAAiB;QACtF,MAAM,IAAIM,QAAQ,CAACC,UAAYC,WAAWD,SAASJ;QACnDA,eAAeM,KAAKC,GAAG,CAACP,eAAe,GAAGrE;IAC5C;AACF;AAEA,OAAO,eAAe6E,kCACpBtD,YAAoB,EACpBR,UAA0B,CAAC,CAAC;IAE5B,MAAMC,WAAYD,QAAQE,EAAE,IAAIrB;IAChC,MAAMc,OAAO,MAAMM,SAChB4B,MAAM,GACNC,IAAI,CAAChD,mBACLiD,KAAK,CAACxD,GAAGO,kBAAkB0B,YAAY,EAAEA,eACzCwB,KAAK,CAAC;IACT,MAAM3B,MAAMV,IAAI,CAAC,EAAE;IACnB,IAAI,CAACU,KAAK,OAAOmB;IACjB,OAAOzC,mBAAmBsB;AAC5B;AAEA,OAAO,eAAe0D,+BACpBC,SAAiB,EACjBhE,UAA0B,CAAC,CAAC;IAE5B,MAAMC,WAAYD,QAAQE,EAAE,IAAIrB;IAChC,MAAMc,OAAO,MAAMM,SAChB4B,MAAM,GACNC,IAAI,CAAChD,mBACLiD,KAAK,CAACtD,GAAG,CAAC,EAAEK,kBAAkBgC,UAAU,CAAC,IAAI,EAAEmD,KAAKC,SAAS,CAAC;QAACF;KAAU,EAAE,OAAO,CAAC,EACnFhC,KAAK,CAAC;IACT,MAAM3B,MAAMV,IAAI,CAAC,EAAE;IACnB,IAAI,CAACU,KAAK,OAAOmB;IACjB,OAAOzC,mBAAmBsB;AAC5B;AAEA,OAAO,eAAe8D,4BACpB3D,YAAoB,EACpBR,UAA0B,CAAC,CAAC;IAE5B,MAAMC,WAAYD,QAAQE,EAAE,IAAIrB;IAChC,MAAM,CAACwB,IAAI,GAAG,MAAMJ,SACjBiC,MAAM,CAACpD,mBACPyC,GAAG,CAAC;QAACP,QAAQ;QAAWS,WAAW,IAAIrB;IAAM,GAC7C2B,KAAK,CAACxD,GAAGO,kBAAkB0B,YAAY,EAAEA,eACzCkB,SAAS;IACZ,IAAI,CAACrB,KAAK,OAAOmB;IACjB,OAAOzC,mBAAmBsB;AAC5B"}
|
|
@@ -196,6 +196,40 @@ export declare const jiraInstallations: import("drizzle-orm/pg-core").PgTableWit
|
|
|
196
196
|
identity: undefined;
|
|
197
197
|
generated: undefined;
|
|
198
198
|
}, {}, {}>;
|
|
199
|
+
refreshTokenLastUsedAt: import("drizzle-orm/pg-core").PgColumn<{
|
|
200
|
+
name: "refresh_token_last_used_at";
|
|
201
|
+
tableName: "installations";
|
|
202
|
+
dataType: "date";
|
|
203
|
+
columnType: "PgTimestamp";
|
|
204
|
+
data: Date;
|
|
205
|
+
driverParam: string;
|
|
206
|
+
notNull: true;
|
|
207
|
+
hasDefault: true;
|
|
208
|
+
isPrimaryKey: false;
|
|
209
|
+
isAutoincrement: false;
|
|
210
|
+
hasRuntimeDefault: false;
|
|
211
|
+
enumValues: undefined;
|
|
212
|
+
baseColumn: never;
|
|
213
|
+
identity: undefined;
|
|
214
|
+
generated: undefined;
|
|
215
|
+
}, {}, {}>;
|
|
216
|
+
refreshTokenLastAttemptedAt: import("drizzle-orm/pg-core").PgColumn<{
|
|
217
|
+
name: "refresh_token_last_attempted_at";
|
|
218
|
+
tableName: "installations";
|
|
219
|
+
dataType: "date";
|
|
220
|
+
columnType: "PgTimestamp";
|
|
221
|
+
data: Date;
|
|
222
|
+
driverParam: string;
|
|
223
|
+
notNull: true;
|
|
224
|
+
hasDefault: true;
|
|
225
|
+
isPrimaryKey: false;
|
|
226
|
+
isAutoincrement: false;
|
|
227
|
+
hasRuntimeDefault: false;
|
|
228
|
+
enumValues: undefined;
|
|
229
|
+
baseColumn: never;
|
|
230
|
+
identity: undefined;
|
|
231
|
+
generated: undefined;
|
|
232
|
+
}, {}, {}>;
|
|
199
233
|
createdAt: import("drizzle-orm/pg-core").PgColumn<{
|
|
200
234
|
name: "created_at";
|
|
201
235
|
tableName: "installations";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"installations.d.ts","sourceRoot":"","sources":["../../../src/db/schema/installations.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAC,gBAAgB,EAAC,MAAM,sBAAsB,CAAC;AAG3D,eAAO,MAAM,iBAAiB
|
|
1
|
+
{"version":3,"file":"installations.d.ts","sourceRoot":"","sources":["../../../src/db/schema/installations.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAC,gBAAgB,EAAC,MAAM,sBAAsB,CAAC;AAG3D,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAuC7B,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG,OAAO,iBAAiB,CAAC,YAAY,CAAC;AACvE,MAAM,MAAM,wBAAwB,GAAG,OAAO,iBAAiB,CAAC,YAAY,CAAC;AAE7E,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,kBAAkB,GAAG,gBAAgB,CAkB5E"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { uuidv7PrimaryKey } from '@shipfox/node-drizzle';
|
|
2
|
-
import { jsonb, text, timestamp, uniqueIndex, uuid } from 'drizzle-orm/pg-core';
|
|
2
|
+
import { index, jsonb, text, timestamp, uniqueIndex, uuid } from 'drizzle-orm/pg-core';
|
|
3
3
|
import { pgTable } from './common.js';
|
|
4
4
|
export const jiraInstallations = pgTable('installations', {
|
|
5
5
|
id: uuidv7PrimaryKey(),
|
|
@@ -17,6 +17,12 @@ export const jiraInstallations = pgTable('installations', {
|
|
|
17
17
|
tokenExpiresAt: timestamp('token_expires_at', {
|
|
18
18
|
withTimezone: true
|
|
19
19
|
}),
|
|
20
|
+
refreshTokenLastUsedAt: timestamp('refresh_token_last_used_at', {
|
|
21
|
+
withTimezone: true
|
|
22
|
+
}).notNull().defaultNow(),
|
|
23
|
+
refreshTokenLastAttemptedAt: timestamp('refresh_token_last_attempted_at', {
|
|
24
|
+
withTimezone: true
|
|
25
|
+
}).notNull().defaultNow(),
|
|
20
26
|
createdAt: timestamp('created_at', {
|
|
21
27
|
withTimezone: true
|
|
22
28
|
}).notNull().defaultNow(),
|
|
@@ -25,7 +31,9 @@ export const jiraInstallations = pgTable('installations', {
|
|
|
25
31
|
}).notNull().defaultNow()
|
|
26
32
|
}, (table)=>[
|
|
27
33
|
uniqueIndex('integrations_jira_installations_connection_unique').on(table.connectionId),
|
|
28
|
-
uniqueIndex('integrations_jira_installations_cloud_id_unique').on(table.cloudId)
|
|
34
|
+
uniqueIndex('integrations_jira_installations_cloud_id_unique').on(table.cloudId),
|
|
35
|
+
index('integrations_jira_installations_token_refresh_due_idx').on(table.status, table.refreshTokenLastUsedAt),
|
|
36
|
+
index('integrations_jira_installations_token_refresh_attempt_idx').on(table.status, table.refreshTokenLastAttemptedAt)
|
|
29
37
|
]);
|
|
30
38
|
export function toJiraInstallation(row) {
|
|
31
39
|
return {
|
|
@@ -40,6 +48,8 @@ export function toJiraInstallation(row) {
|
|
|
40
48
|
webhookExpiresAt: row.webhookExpiresAt,
|
|
41
49
|
status: row.status,
|
|
42
50
|
tokenExpiresAt: row.tokenExpiresAt,
|
|
51
|
+
refreshTokenLastUsedAt: row.refreshTokenLastUsedAt,
|
|
52
|
+
refreshTokenLastAttemptedAt: row.refreshTokenLastAttemptedAt,
|
|
43
53
|
createdAt: row.createdAt,
|
|
44
54
|
updatedAt: row.updatedAt
|
|
45
55
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/db/schema/installations.ts"],"sourcesContent":["import {uuidv7PrimaryKey} from '@shipfox/node-drizzle';\nimport {jsonb, text, timestamp, uniqueIndex, uuid} from 'drizzle-orm/pg-core';\nimport type {JiraInstallation} from '#db/installations.js';\nimport {pgTable} from './common.js';\n\nexport const jiraInstallations = pgTable(\n 'installations',\n {\n id: uuidv7PrimaryKey(),\n connectionId: uuid('connection_id').notNull(),\n cloudId: text('cloud_id').notNull(),\n siteUrl: text('site_url').notNull(),\n siteName: text('site_name').notNull(),\n authorizingAccountId: text('authorizing_account_id').notNull(),\n scopes: jsonb('scopes').$type<string[]>().notNull(),\n webhookIds: jsonb('webhook_ids').$type<number[]>().notNull().default([]),\n webhookExpiresAt: timestamp('webhook_expires_at', {withTimezone: true}),\n status: text('status').notNull().$type<JiraInstallation['status']>(),\n tokenExpiresAt: timestamp('token_expires_at', {withTimezone: true}),\n createdAt: timestamp('created_at', {withTimezone: true}).notNull().defaultNow(),\n updatedAt: timestamp('updated_at', {withTimezone: true}).notNull().defaultNow(),\n },\n (table) => [\n uniqueIndex('integrations_jira_installations_connection_unique').on(table.connectionId),\n uniqueIndex('integrations_jira_installations_cloud_id_unique').on(table.cloudId),\n ],\n);\n\nexport type JiraInstallationDb = typeof jiraInstallations.$inferSelect;\nexport type JiraInstallationCreateDb = typeof jiraInstallations.$inferInsert;\n\nexport function toJiraInstallation(row: JiraInstallationDb): JiraInstallation {\n return {\n id: row.id,\n connectionId: row.connectionId,\n cloudId: row.cloudId,\n siteUrl: row.siteUrl,\n siteName: row.siteName,\n authorizingAccountId: row.authorizingAccountId,\n scopes: row.scopes,\n webhookIds: row.webhookIds,\n webhookExpiresAt: row.webhookExpiresAt,\n status: row.status,\n tokenExpiresAt: row.tokenExpiresAt,\n createdAt: row.createdAt,\n updatedAt: row.updatedAt,\n };\n}\n"],"names":["uuidv7PrimaryKey","jsonb","text","timestamp","uniqueIndex","uuid","pgTable","jiraInstallations","id","connectionId","notNull","cloudId","siteUrl","siteName","authorizingAccountId","scopes","$type","webhookIds","default","webhookExpiresAt","withTimezone","status","tokenExpiresAt","
|
|
1
|
+
{"version":3,"sources":["../../../src/db/schema/installations.ts"],"sourcesContent":["import {uuidv7PrimaryKey} from '@shipfox/node-drizzle';\nimport {index, jsonb, text, timestamp, uniqueIndex, uuid} from 'drizzle-orm/pg-core';\nimport type {JiraInstallation} from '#db/installations.js';\nimport {pgTable} from './common.js';\n\nexport const jiraInstallations = pgTable(\n 'installations',\n {\n id: uuidv7PrimaryKey(),\n connectionId: uuid('connection_id').notNull(),\n cloudId: text('cloud_id').notNull(),\n siteUrl: text('site_url').notNull(),\n siteName: text('site_name').notNull(),\n authorizingAccountId: text('authorizing_account_id').notNull(),\n scopes: jsonb('scopes').$type<string[]>().notNull(),\n webhookIds: jsonb('webhook_ids').$type<number[]>().notNull().default([]),\n webhookExpiresAt: timestamp('webhook_expires_at', {withTimezone: true}),\n status: text('status').notNull().$type<JiraInstallation['status']>(),\n tokenExpiresAt: timestamp('token_expires_at', {withTimezone: true}),\n refreshTokenLastUsedAt: timestamp('refresh_token_last_used_at', {\n withTimezone: true,\n })\n .notNull()\n .defaultNow(),\n refreshTokenLastAttemptedAt: timestamp('refresh_token_last_attempted_at', {\n withTimezone: true,\n })\n .notNull()\n .defaultNow(),\n createdAt: timestamp('created_at', {withTimezone: true}).notNull().defaultNow(),\n updatedAt: timestamp('updated_at', {withTimezone: true}).notNull().defaultNow(),\n },\n (table) => [\n uniqueIndex('integrations_jira_installations_connection_unique').on(table.connectionId),\n uniqueIndex('integrations_jira_installations_cloud_id_unique').on(table.cloudId),\n index('integrations_jira_installations_token_refresh_due_idx').on(\n table.status,\n table.refreshTokenLastUsedAt,\n ),\n index('integrations_jira_installations_token_refresh_attempt_idx').on(\n table.status,\n table.refreshTokenLastAttemptedAt,\n ),\n ],\n);\n\nexport type JiraInstallationDb = typeof jiraInstallations.$inferSelect;\nexport type JiraInstallationCreateDb = typeof jiraInstallations.$inferInsert;\n\nexport function toJiraInstallation(row: JiraInstallationDb): JiraInstallation {\n return {\n id: row.id,\n connectionId: row.connectionId,\n cloudId: row.cloudId,\n siteUrl: row.siteUrl,\n siteName: row.siteName,\n authorizingAccountId: row.authorizingAccountId,\n scopes: row.scopes,\n webhookIds: row.webhookIds,\n webhookExpiresAt: row.webhookExpiresAt,\n status: row.status,\n tokenExpiresAt: row.tokenExpiresAt,\n refreshTokenLastUsedAt: row.refreshTokenLastUsedAt,\n refreshTokenLastAttemptedAt: row.refreshTokenLastAttemptedAt,\n createdAt: row.createdAt,\n updatedAt: row.updatedAt,\n };\n}\n"],"names":["uuidv7PrimaryKey","index","jsonb","text","timestamp","uniqueIndex","uuid","pgTable","jiraInstallations","id","connectionId","notNull","cloudId","siteUrl","siteName","authorizingAccountId","scopes","$type","webhookIds","default","webhookExpiresAt","withTimezone","status","tokenExpiresAt","refreshTokenLastUsedAt","defaultNow","refreshTokenLastAttemptedAt","createdAt","updatedAt","table","on","toJiraInstallation","row"],"mappings":"AAAA,SAAQA,gBAAgB,QAAO,wBAAwB;AACvD,SAAQC,KAAK,EAAEC,KAAK,EAAEC,IAAI,EAAEC,SAAS,EAAEC,WAAW,EAAEC,IAAI,QAAO,sBAAsB;AAErF,SAAQC,OAAO,QAAO,cAAc;AAEpC,OAAO,MAAMC,oBAAoBD,QAC/B,iBACA;IACEE,IAAIT;IACJU,cAAcJ,KAAK,iBAAiBK,OAAO;IAC3CC,SAAST,KAAK,YAAYQ,OAAO;IACjCE,SAASV,KAAK,YAAYQ,OAAO;IACjCG,UAAUX,KAAK,aAAaQ,OAAO;IACnCI,sBAAsBZ,KAAK,0BAA0BQ,OAAO;IAC5DK,QAAQd,MAAM,UAAUe,KAAK,GAAaN,OAAO;IACjDO,YAAYhB,MAAM,eAAee,KAAK,GAAaN,OAAO,GAAGQ,OAAO,CAAC,EAAE;IACvEC,kBAAkBhB,UAAU,sBAAsB;QAACiB,cAAc;IAAI;IACrEC,QAAQnB,KAAK,UAAUQ,OAAO,GAAGM,KAAK;IACtCM,gBAAgBnB,UAAU,oBAAoB;QAACiB,cAAc;IAAI;IACjEG,wBAAwBpB,UAAU,8BAA8B;QAC9DiB,cAAc;IAChB,GACGV,OAAO,GACPc,UAAU;IACbC,6BAA6BtB,UAAU,mCAAmC;QACxEiB,cAAc;IAChB,GACGV,OAAO,GACPc,UAAU;IACbE,WAAWvB,UAAU,cAAc;QAACiB,cAAc;IAAI,GAAGV,OAAO,GAAGc,UAAU;IAC7EG,WAAWxB,UAAU,cAAc;QAACiB,cAAc;IAAI,GAAGV,OAAO,GAAGc,UAAU;AAC/E,GACA,CAACI,QAAU;QACTxB,YAAY,qDAAqDyB,EAAE,CAACD,MAAMnB,YAAY;QACtFL,YAAY,mDAAmDyB,EAAE,CAACD,MAAMjB,OAAO;QAC/EX,MAAM,yDAAyD6B,EAAE,CAC/DD,MAAMP,MAAM,EACZO,MAAML,sBAAsB;QAE9BvB,MAAM,6DAA6D6B,EAAE,CACnED,MAAMP,MAAM,EACZO,MAAMH,2BAA2B;KAEpC,EACD;AAKF,OAAO,SAASK,mBAAmBC,GAAuB;IACxD,OAAO;QACLvB,IAAIuB,IAAIvB,EAAE;QACVC,cAAcsB,IAAItB,YAAY;QAC9BE,SAASoB,IAAIpB,OAAO;QACpBC,SAASmB,IAAInB,OAAO;QACpBC,UAAUkB,IAAIlB,QAAQ;QACtBC,sBAAsBiB,IAAIjB,oBAAoB;QAC9CC,QAAQgB,IAAIhB,MAAM;QAClBE,YAAYc,IAAId,UAAU;QAC1BE,kBAAkBY,IAAIZ,gBAAgB;QACtCE,QAAQU,IAAIV,MAAM;QAClBC,gBAAgBS,IAAIT,cAAc;QAClCC,wBAAwBQ,IAAIR,sBAAsB;QAClDE,6BAA6BM,IAAIN,2BAA2B;QAC5DC,WAAWK,IAAIL,SAAS;QACxBC,WAAWI,IAAIJ,SAAS;IAC1B;AACF"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,13 +1,19 @@
|
|
|
1
|
-
import { type JiraApiClient } from '#api/client.js';
|
|
1
|
+
import { type JiraAgentToolsClient, type JiraApiClient } from '#api/client.js';
|
|
2
2
|
import { config } from '#config.js';
|
|
3
|
+
import { JiraAgentToolsProvider } from '#core/agent-tools-provider.js';
|
|
4
|
+
import type { JiraTokenStore } from '#core/tokens.js';
|
|
3
5
|
import { closeDb, db } from '#db/db.js';
|
|
4
6
|
import { getJiraInstallationByConnectionId } from '#db/installations.js';
|
|
5
7
|
import { migrationsPath } from '#db/migrations.js';
|
|
6
8
|
import { type CreateJiraIntegrationRoutesOptions } from '#presentation/routes/install.js';
|
|
7
9
|
import { type CreateJiraWebhookRoutesOptions } from '#presentation/routes/webhooks.js';
|
|
8
10
|
export type { JiraProvider } from '@shipfox/api-integration-jira-dto';
|
|
9
|
-
export type { JiraAccessibleResource, JiraApiClient, JiraAuthorization, JiraDynamicWebhookRegistration, JiraIdentity, } from '#api/client.js';
|
|
10
|
-
export { createJiraApiClient, JIRA_DYNAMIC_WEBHOOK_EVENTS, JIRA_DYNAMIC_WEBHOOK_JQL, mapJiraError, } from '#api/client.js';
|
|
11
|
+
export type { JiraAccessibleResource, JiraAgentToolHttpMethod, JiraAgentToolQueryValue, JiraAgentToolRequest, JiraAgentToolResponse, JiraAgentToolsClient, JiraApiClient, JiraAuthorization, JiraDynamicWebhookRegistration, JiraIdentity, } from '#api/client.js';
|
|
12
|
+
export { createJiraAgentToolsClient, createJiraApiClient, JIRA_DYNAMIC_WEBHOOK_EVENTS, JIRA_DYNAMIC_WEBHOOK_JQL, mapJiraError, } from '#api/client.js';
|
|
13
|
+
export type { JiraAgentToolCatalogEntry, JiraAgentToolId, JiraAgentToolRequiredScope, } from '#core/agent-tools.js';
|
|
14
|
+
export { jiraAgentToolCatalog, jiraAgentToolSelectionCatalog, jiraPlainTextToAdf, } from '#core/agent-tools.js';
|
|
15
|
+
export type { JiraAgentToolsProviderOptions, JiraToolCallResult, } from '#core/agent-tools-provider.js';
|
|
16
|
+
export { JiraAgentToolsProvider } from '#core/agent-tools-provider.js';
|
|
11
17
|
export type { DisconnectJiraInstallationParams } from '#core/disconnect.js';
|
|
12
18
|
export { disconnectJiraInstallation } from '#core/disconnect.js';
|
|
13
19
|
export { JiraAccessTokenMissingError, JiraAuthorizationScopeMismatchError, JiraConnectionAlreadyLinkedError, JiraConnectionNotFoundError, JiraInstallationAlreadyLinkedError, JiraInstallationSiteMismatchError, JiraInstallStateActorMismatchError, JiraInstallStateError, JiraIntegrationProviderError, JiraOAuthCallbackError, JiraOfflineAccessNotGrantedError, JiraPendingSelectionNotFoundError, JiraSiteSelectionMismatchError, JiraTokenUnrefreshableError, } from '#core/errors.js';
|
|
@@ -24,12 +30,17 @@ export { createJiraWebhookProcessor } from '#core/webhook-processor.js';
|
|
|
24
30
|
export type { RegisterJiraWebhookParams } from '#core/webhook-registration.js';
|
|
25
31
|
export { JIRA_WEBHOOK_TTL_MS, registerJiraWebhook } from '#core/webhook-registration.js';
|
|
26
32
|
export type { JiraInstallation, JiraInstallationLock, JiraInstallationStatus, UpdateJiraInstallationWebhookParams, UpsertJiraInstallationParams, } from '#db/installations.js';
|
|
27
|
-
export { deleteJiraInstallationByConnectionId, getJiraInstallationByCloudId, getJiraInstallationByConnectionId, getJiraInstallationByWebhookId, markJiraInstallationRevoked, updateJiraInstallationTokenExpiry, updateJiraInstallationWebhook, upsertJiraInstallation, withJiraRefreshLock, withJiraWebhookRegistrationLock, } from '#db/installations.js';
|
|
33
|
+
export { deleteJiraInstallationByConnectionId, getJiraInstallationByCloudId, getJiraInstallationByConnectionId, getJiraInstallationByWebhookId, listJiraInstallationsDueForTokenRefresh, markJiraInstallationRevoked, updateJiraInstallationTokenExpiry, updateJiraInstallationWebhook, upsertJiraInstallation, withJiraRefreshLock, withJiraWebhookRegistrationLock, } from '#db/installations.js';
|
|
28
34
|
export type { CreateJiraWebhookRoutesOptions } from '#presentation/routes/webhooks.js';
|
|
29
35
|
export { createJiraWebhookRoutes } from '#presentation/routes/webhooks.js';
|
|
36
|
+
export { createJiraMaintenanceWorker } from '#temporal/worker.js';
|
|
30
37
|
export { closeDb, config, db, migrationsPath };
|
|
31
38
|
export interface CreateJiraIntegrationProviderOptions {
|
|
32
39
|
jira?: JiraApiClient | undefined;
|
|
40
|
+
agentTools?: {
|
|
41
|
+
tokenStore: Pick<JiraTokenStore, 'getAccessToken'>;
|
|
42
|
+
jira?: JiraAgentToolsClient | undefined;
|
|
43
|
+
} | undefined;
|
|
33
44
|
getJiraInstallationByConnectionId?: typeof getJiraInstallationByConnectionId | undefined;
|
|
34
45
|
routes?: JiraIntegrationProviderRoutesOptions | undefined;
|
|
35
46
|
}
|
|
@@ -37,7 +48,11 @@ type JiraIntegrationProviderRoutesOptions = Omit<CreateJiraIntegrationRoutesOpti
|
|
|
37
48
|
export declare function createJiraIntegrationProvider(options?: CreateJiraIntegrationProviderOptions): {
|
|
38
49
|
provider: string;
|
|
39
50
|
displayName: string;
|
|
40
|
-
adapters: {
|
|
51
|
+
adapters: {
|
|
52
|
+
agent_tools: JiraAgentToolsProvider;
|
|
53
|
+
} | {
|
|
54
|
+
agent_tools?: never;
|
|
55
|
+
};
|
|
41
56
|
connectionExternalUrl(connection: {
|
|
42
57
|
id: string;
|
|
43
58
|
}): Promise<string | undefined>;
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { JIRA_PROVIDER } from '@shipfox/api-integration-jira-dto';
|
|
2
|
-
import { createJiraApiClient } from '#api/client.js';
|
|
2
|
+
import { createJiraAgentToolsClient, createJiraApiClient } from '#api/client.js';
|
|
3
3
|
import { config } from '#config.js';
|
|
4
|
+
import { JiraAgentToolsProvider } from '#core/agent-tools-provider.js';
|
|
4
5
|
import { createJiraWebhookProcessor } from '#core/webhook-processor.js';
|
|
5
6
|
import { registerJiraWebhook } from '#core/webhook-registration.js';
|
|
6
7
|
import { closeDb, db } from '#db/db.js';
|
|
@@ -9,7 +10,9 @@ import { migrationsPath } from '#db/migrations.js';
|
|
|
9
10
|
import { createJiraIntegrationRoutes } from '#presentation/routes/install.js';
|
|
10
11
|
import { createJiraWebhookRoutes, JIRA_WEBHOOK_ROUTE_PREFIX } from '#presentation/routes/webhooks.js';
|
|
11
12
|
const TRAILING_SLASHES_RE = /\/+$/;
|
|
12
|
-
export { createJiraApiClient, JIRA_DYNAMIC_WEBHOOK_EVENTS, JIRA_DYNAMIC_WEBHOOK_JQL, mapJiraError } from '#api/client.js';
|
|
13
|
+
export { createJiraAgentToolsClient, createJiraApiClient, JIRA_DYNAMIC_WEBHOOK_EVENTS, JIRA_DYNAMIC_WEBHOOK_JQL, mapJiraError } from '#api/client.js';
|
|
14
|
+
export { jiraAgentToolCatalog, jiraAgentToolSelectionCatalog, jiraPlainTextToAdf } from '#core/agent-tools.js';
|
|
15
|
+
export { JiraAgentToolsProvider } from '#core/agent-tools-provider.js';
|
|
13
16
|
export { disconnectJiraInstallation } from '#core/disconnect.js';
|
|
14
17
|
export { JiraAccessTokenMissingError, JiraAuthorizationScopeMismatchError, JiraConnectionAlreadyLinkedError, JiraConnectionNotFoundError, JiraInstallationAlreadyLinkedError, JiraInstallationSiteMismatchError, JiraInstallStateActorMismatchError, JiraInstallStateError, JiraIntegrationProviderError, JiraOAuthCallbackError, JiraOfflineAccessNotGrantedError, JiraPendingSelectionNotFoundError, JiraSiteSelectionMismatchError, JiraTokenUnrefreshableError } from '#core/errors.js';
|
|
15
18
|
export { handleJiraCallback, handleJiraOAuthCallbackError, handleJiraSiteSelection } from '#core/install.js';
|
|
@@ -19,12 +22,19 @@ export { signJiraInstallState, verifyJiraInstallState } from '#core/state.js';
|
|
|
19
22
|
export { createJiraTokenStore, jiraSecretsNamespace } from '#core/tokens.js';
|
|
20
23
|
export { createJiraWebhookProcessor } from '#core/webhook-processor.js';
|
|
21
24
|
export { JIRA_WEBHOOK_TTL_MS, registerJiraWebhook } from '#core/webhook-registration.js';
|
|
22
|
-
export { deleteJiraInstallationByConnectionId, getJiraInstallationByCloudId, getJiraInstallationByConnectionId, getJiraInstallationByWebhookId, markJiraInstallationRevoked, updateJiraInstallationTokenExpiry, updateJiraInstallationWebhook, upsertJiraInstallation, withJiraRefreshLock, withJiraWebhookRegistrationLock } from '#db/installations.js';
|
|
25
|
+
export { deleteJiraInstallationByConnectionId, getJiraInstallationByCloudId, getJiraInstallationByConnectionId, getJiraInstallationByWebhookId, listJiraInstallationsDueForTokenRefresh, markJiraInstallationRevoked, updateJiraInstallationTokenExpiry, updateJiraInstallationWebhook, upsertJiraInstallation, withJiraRefreshLock, withJiraWebhookRegistrationLock } from '#db/installations.js';
|
|
23
26
|
export { createJiraWebhookRoutes } from '#presentation/routes/webhooks.js';
|
|
27
|
+
export { createJiraMaintenanceWorker } from '#temporal/worker.js';
|
|
24
28
|
export { closeDb, config, db, migrationsPath };
|
|
25
29
|
export function createJiraIntegrationProvider(options = {}) {
|
|
26
30
|
const jira = options.jira ?? createJiraApiClient();
|
|
27
31
|
const getInstallationByConnectionId = options.getJiraInstallationByConnectionId ?? getJiraInstallationByConnectionId;
|
|
32
|
+
const adapters = options.agentTools ? {
|
|
33
|
+
agent_tools: new JiraAgentToolsProvider({
|
|
34
|
+
jira: options.agentTools.jira ?? createJiraAgentToolsClient(),
|
|
35
|
+
tokenStore: options.agentTools.tokenStore
|
|
36
|
+
})
|
|
37
|
+
} : {};
|
|
28
38
|
const webhookOptions = toJiraWebhookOptions(options.routes);
|
|
29
39
|
const webhookProcessor = webhookOptions ? createJiraWebhookProcessor(webhookOptions) : undefined;
|
|
30
40
|
const webhookRoutes = webhookOptions ? [
|
|
@@ -39,7 +49,9 @@ export function createJiraIntegrationProvider(options = {}) {
|
|
|
39
49
|
const routes = options.routes ? [
|
|
40
50
|
createJiraIntegrationRoutes({
|
|
41
51
|
jira,
|
|
42
|
-
connectionCapabilities: [
|
|
52
|
+
connectionCapabilities: adapters.agent_tools ? [
|
|
53
|
+
'agent_tools'
|
|
54
|
+
] : [],
|
|
43
55
|
...options.routes,
|
|
44
56
|
registerJiraWebhook: (input)=>registerJiraWebhook({
|
|
45
57
|
jira,
|
|
@@ -63,7 +75,7 @@ export function createJiraIntegrationProvider(options = {}) {
|
|
|
63
75
|
return {
|
|
64
76
|
provider: JIRA_PROVIDER,
|
|
65
77
|
displayName: 'Jira',
|
|
66
|
-
adapters
|
|
78
|
+
adapters,
|
|
67
79
|
async connectionExternalUrl (connection) {
|
|
68
80
|
return (await getInstallationByConnectionId(connection.id))?.siteUrl;
|
|
69
81
|
},
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["import {JIRA_PROVIDER} from '@shipfox/api-integration-jira-dto';\nimport {createJiraApiClient, type JiraApiClient} from '#api/client.js';\nimport {config} from '#config.js';\nimport {createJiraWebhookProcessor} from '#core/webhook-processor.js';\nimport {registerJiraWebhook} from '#core/webhook-registration.js';\nimport {closeDb, db} from '#db/db.js';\nimport {getJiraInstallationByConnectionId} from '#db/installations.js';\nimport {migrationsPath} from '#db/migrations.js';\nimport {\n type CreateJiraIntegrationRoutesOptions,\n createJiraIntegrationRoutes,\n} from '#presentation/routes/install.js';\nimport {\n type CreateJiraWebhookRoutesOptions,\n createJiraWebhookRoutes,\n JIRA_WEBHOOK_ROUTE_PREFIX,\n} from '#presentation/routes/webhooks.js';\n\nconst TRAILING_SLASHES_RE = /\\/+$/;\n\nexport type {JiraProvider} from '@shipfox/api-integration-jira-dto';\nexport type {\n JiraAccessibleResource,\n JiraApiClient,\n JiraAuthorization,\n JiraDynamicWebhookRegistration,\n JiraIdentity,\n} from '#api/client.js';\nexport {\n createJiraApiClient,\n JIRA_DYNAMIC_WEBHOOK_EVENTS,\n JIRA_DYNAMIC_WEBHOOK_JQL,\n mapJiraError,\n} from '#api/client.js';\nexport type {DisconnectJiraInstallationParams} from '#core/disconnect.js';\nexport {disconnectJiraInstallation} from '#core/disconnect.js';\nexport {\n JiraAccessTokenMissingError,\n JiraAuthorizationScopeMismatchError,\n JiraConnectionAlreadyLinkedError,\n JiraConnectionNotFoundError,\n JiraInstallationAlreadyLinkedError,\n JiraInstallationSiteMismatchError,\n JiraInstallStateActorMismatchError,\n JiraInstallStateError,\n JiraIntegrationProviderError,\n JiraOAuthCallbackError,\n JiraOfflineAccessNotGrantedError,\n JiraPendingSelectionNotFoundError,\n JiraSiteSelectionMismatchError,\n JiraTokenUnrefreshableError,\n} from '#core/errors.js';\nexport type {ConnectJiraInstallationInput, HandleJiraCallbackParams} from '#core/install.js';\nexport {\n handleJiraCallback,\n handleJiraOAuthCallbackError,\n handleJiraSiteSelection,\n} from '#core/install.js';\nexport type {JiraPendingSelectionSecretsStore, JiraPendingSelectionStore} from '#core/pending.js';\nexport {createJiraPendingSelectionStore, jiraPendingSecretsNamespace} from '#core/pending.js';\nexport {\n assertJiraAuthorizationScopes,\n formatJiraOAuthScopes,\n JIRA_OAUTH_SCOPES,\n} from '#core/scopes.js';\nexport {signJiraInstallState, verifyJiraInstallState} from '#core/state.js';\nexport type {\n CreateJiraTokenStoreParams,\n GetJiraAccessTokenParams,\n JiraConnectionResolverResult,\n JiraSecretsStore,\n JiraTokenStore,\n StoreJiraTokensParams,\n} from '#core/tokens.js';\nexport {createJiraTokenStore, jiraSecretsNamespace} from '#core/tokens.js';\nexport type {\n CreateJiraWebhookProcessorOptions,\n JiraWebhookProcessor,\n} from '#core/webhook-processor.js';\nexport {createJiraWebhookProcessor} from '#core/webhook-processor.js';\nexport type {RegisterJiraWebhookParams} from '#core/webhook-registration.js';\nexport {JIRA_WEBHOOK_TTL_MS, registerJiraWebhook} from '#core/webhook-registration.js';\nexport type {\n JiraInstallation,\n JiraInstallationLock,\n JiraInstallationStatus,\n UpdateJiraInstallationWebhookParams,\n UpsertJiraInstallationParams,\n} from '#db/installations.js';\nexport {\n deleteJiraInstallationByConnectionId,\n getJiraInstallationByCloudId,\n getJiraInstallationByConnectionId,\n getJiraInstallationByWebhookId,\n markJiraInstallationRevoked,\n updateJiraInstallationTokenExpiry,\n updateJiraInstallationWebhook,\n upsertJiraInstallation,\n withJiraRefreshLock,\n withJiraWebhookRegistrationLock,\n} from '#db/installations.js';\nexport type {CreateJiraWebhookRoutesOptions} from '#presentation/routes/webhooks.js';\nexport {createJiraWebhookRoutes} from '#presentation/routes/webhooks.js';\nexport {closeDb, config, db, migrationsPath};\n\nexport interface CreateJiraIntegrationProviderOptions {\n jira?: JiraApiClient | undefined;\n getJiraInstallationByConnectionId?: typeof getJiraInstallationByConnectionId | undefined;\n routes?: JiraIntegrationProviderRoutesOptions | undefined;\n}\n\ntype JiraIntegrationProviderRoutesOptions = Omit<\n CreateJiraIntegrationRoutesOptions,\n 'jira' | 'connectionCapabilities' | 'registerJiraWebhook'\n> &\n Omit<CreateJiraWebhookRoutesOptions, 'processor'>;\n\nexport function createJiraIntegrationProvider(options: CreateJiraIntegrationProviderOptions = {}) {\n const jira = options.jira ?? createJiraApiClient();\n const getInstallationByConnectionId =\n options.getJiraInstallationByConnectionId ?? getJiraInstallationByConnectionId;\n const webhookOptions = toJiraWebhookOptions(options.routes);\n const webhookProcessor = webhookOptions ? createJiraWebhookProcessor(webhookOptions) : undefined;\n const webhookRoutes = webhookOptions\n ? [\n createJiraWebhookRoutes({\n coreDb: webhookOptions.coreDb,\n publishIntegrationEventReceived: webhookOptions.publishIntegrationEventReceived,\n recordDeliveryOnly: webhookOptions.recordDeliveryOnly,\n getIntegrationConnectionById: webhookOptions.getIntegrationConnectionById,\n processor: webhookProcessor,\n }),\n ]\n : [];\n const routes = options.routes\n ? [\n createJiraIntegrationRoutes({\n jira,\n connectionCapabilities: [],\n ...options.routes,\n registerJiraWebhook: (input) =>\n registerJiraWebhook({\n jira,\n connectionId: input.connectionId,\n cloudId: input.cloudId,\n accessToken: input.accessToken,\n webhookUrl: jiraWebhookUrl(input.connectionId),\n ...(input.withRegistrationLock\n ? {withRegistrationLock: input.withRegistrationLock}\n : {}),\n ...(input.onRegistrationSuccess\n ? {onRegistrationSuccess: input.onRegistrationSuccess}\n : {}),\n ...(input.onRegistrationFailure\n ? {onRegistrationFailure: input.onRegistrationFailure}\n : {}),\n }).then(() => undefined),\n }),\n ...webhookRoutes,\n ]\n : [];\n return {\n provider: JIRA_PROVIDER,\n displayName: 'Jira',\n adapters: {},\n async connectionExternalUrl(connection: {id: string}): Promise<string | undefined> {\n return (await getInstallationByConnectionId(connection.id))?.siteUrl;\n },\n routes,\n webhookProcessors: webhookProcessor\n ? [{routeIds: ['jira'] as const, processor: webhookProcessor}]\n : undefined,\n };\n}\n\nfunction jiraWebhookUrl(connectionId: string): string {\n return `${config.JIRA_WEBHOOK_BASE_URL.replace(TRAILING_SLASHES_RE, '')}${JIRA_WEBHOOK_ROUTE_PREFIX}/${connectionId}`;\n}\n\nfunction toJiraWebhookOptions(\n routes: CreateJiraIntegrationProviderOptions['routes'],\n): CreateJiraWebhookRoutesOptions | undefined {\n if (!routes) return undefined;\n if (\n routes.coreDb === undefined ||\n routes.publishIntegrationEventReceived === undefined ||\n routes.recordDeliveryOnly === undefined ||\n routes.getIntegrationConnectionById === undefined\n )\n throw new Error(\n 'Jira integration provider requires all webhook receiver dependencies: coreDb, publishIntegrationEventReceived, recordDeliveryOnly, and getIntegrationConnectionById',\n );\n return {\n coreDb: routes.coreDb,\n publishIntegrationEventReceived: routes.publishIntegrationEventReceived,\n recordDeliveryOnly: routes.recordDeliveryOnly,\n getIntegrationConnectionById: routes.getIntegrationConnectionById,\n };\n}\n"],"names":["JIRA_PROVIDER","createJiraApiClient","config","createJiraWebhookProcessor","registerJiraWebhook","closeDb","db","getJiraInstallationByConnectionId","migrationsPath","createJiraIntegrationRoutes","createJiraWebhookRoutes","JIRA_WEBHOOK_ROUTE_PREFIX","TRAILING_SLASHES_RE","JIRA_DYNAMIC_WEBHOOK_EVENTS","JIRA_DYNAMIC_WEBHOOK_JQL","mapJiraError","disconnectJiraInstallation","JiraAccessTokenMissingError","JiraAuthorizationScopeMismatchError","JiraConnectionAlreadyLinkedError","JiraConnectionNotFoundError","JiraInstallationAlreadyLinkedError","JiraInstallationSiteMismatchError","JiraInstallStateActorMismatchError","JiraInstallStateError","JiraIntegrationProviderError","JiraOAuthCallbackError","JiraOfflineAccessNotGrantedError","JiraPendingSelectionNotFoundError","JiraSiteSelectionMismatchError","JiraTokenUnrefreshableError","handleJiraCallback","handleJiraOAuthCallbackError","handleJiraSiteSelection","createJiraPendingSelectionStore","jiraPendingSecretsNamespace","assertJiraAuthorizationScopes","formatJiraOAuthScopes","JIRA_OAUTH_SCOPES","signJiraInstallState","verifyJiraInstallState","createJiraTokenStore","jiraSecretsNamespace","JIRA_WEBHOOK_TTL_MS","deleteJiraInstallationByConnectionId","getJiraInstallationByCloudId","getJiraInstallationByWebhookId","markJiraInstallationRevoked","updateJiraInstallationTokenExpiry","updateJiraInstallationWebhook","upsertJiraInstallation","withJiraRefreshLock","withJiraWebhookRegistrationLock","createJiraIntegrationProvider","options","jira","getInstallationByConnectionId","webhookOptions","toJiraWebhookOptions","routes","webhookProcessor","undefined","webhookRoutes","coreDb","publishIntegrationEventReceived","recordDeliveryOnly","getIntegrationConnectionById","processor","connectionCapabilities","input","connectionId","cloudId","accessToken","webhookUrl","jiraWebhookUrl","withRegistrationLock","onRegistrationSuccess","onRegistrationFailure","then","provider","displayName","adapters","connectionExternalUrl","connection","id","siteUrl","webhookProcessors","routeIds","JIRA_WEBHOOK_BASE_URL","replace","Error"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["import {JIRA_PROVIDER} from '@shipfox/api-integration-jira-dto';\nimport {\n createJiraAgentToolsClient,\n createJiraApiClient,\n type JiraAgentToolsClient,\n type JiraApiClient,\n} from '#api/client.js';\nimport {config} from '#config.js';\nimport {JiraAgentToolsProvider} from '#core/agent-tools-provider.js';\nimport type {JiraTokenStore} from '#core/tokens.js';\nimport {createJiraWebhookProcessor} from '#core/webhook-processor.js';\nimport {registerJiraWebhook} from '#core/webhook-registration.js';\nimport {closeDb, db} from '#db/db.js';\nimport {getJiraInstallationByConnectionId} from '#db/installations.js';\nimport {migrationsPath} from '#db/migrations.js';\nimport {\n type CreateJiraIntegrationRoutesOptions,\n createJiraIntegrationRoutes,\n} from '#presentation/routes/install.js';\nimport {\n type CreateJiraWebhookRoutesOptions,\n createJiraWebhookRoutes,\n JIRA_WEBHOOK_ROUTE_PREFIX,\n} from '#presentation/routes/webhooks.js';\n\nconst TRAILING_SLASHES_RE = /\\/+$/;\n\nexport type {JiraProvider} from '@shipfox/api-integration-jira-dto';\nexport type {\n JiraAccessibleResource,\n JiraAgentToolHttpMethod,\n JiraAgentToolQueryValue,\n JiraAgentToolRequest,\n JiraAgentToolResponse,\n JiraAgentToolsClient,\n JiraApiClient,\n JiraAuthorization,\n JiraDynamicWebhookRegistration,\n JiraIdentity,\n} from '#api/client.js';\nexport {\n createJiraAgentToolsClient,\n createJiraApiClient,\n JIRA_DYNAMIC_WEBHOOK_EVENTS,\n JIRA_DYNAMIC_WEBHOOK_JQL,\n mapJiraError,\n} from '#api/client.js';\nexport type {\n JiraAgentToolCatalogEntry,\n JiraAgentToolId,\n JiraAgentToolRequiredScope,\n} from '#core/agent-tools.js';\nexport {\n jiraAgentToolCatalog,\n jiraAgentToolSelectionCatalog,\n jiraPlainTextToAdf,\n} from '#core/agent-tools.js';\nexport type {\n JiraAgentToolsProviderOptions,\n JiraToolCallResult,\n} from '#core/agent-tools-provider.js';\nexport {JiraAgentToolsProvider} from '#core/agent-tools-provider.js';\nexport type {DisconnectJiraInstallationParams} from '#core/disconnect.js';\nexport {disconnectJiraInstallation} from '#core/disconnect.js';\nexport {\n JiraAccessTokenMissingError,\n JiraAuthorizationScopeMismatchError,\n JiraConnectionAlreadyLinkedError,\n JiraConnectionNotFoundError,\n JiraInstallationAlreadyLinkedError,\n JiraInstallationSiteMismatchError,\n JiraInstallStateActorMismatchError,\n JiraInstallStateError,\n JiraIntegrationProviderError,\n JiraOAuthCallbackError,\n JiraOfflineAccessNotGrantedError,\n JiraPendingSelectionNotFoundError,\n JiraSiteSelectionMismatchError,\n JiraTokenUnrefreshableError,\n} from '#core/errors.js';\nexport type {ConnectJiraInstallationInput, HandleJiraCallbackParams} from '#core/install.js';\nexport {\n handleJiraCallback,\n handleJiraOAuthCallbackError,\n handleJiraSiteSelection,\n} from '#core/install.js';\nexport type {JiraPendingSelectionSecretsStore, JiraPendingSelectionStore} from '#core/pending.js';\nexport {createJiraPendingSelectionStore, jiraPendingSecretsNamespace} from '#core/pending.js';\nexport {\n assertJiraAuthorizationScopes,\n formatJiraOAuthScopes,\n JIRA_OAUTH_SCOPES,\n} from '#core/scopes.js';\nexport {signJiraInstallState, verifyJiraInstallState} from '#core/state.js';\nexport type {\n CreateJiraTokenStoreParams,\n GetJiraAccessTokenParams,\n JiraConnectionResolverResult,\n JiraSecretsStore,\n JiraTokenStore,\n StoreJiraTokensParams,\n} from '#core/tokens.js';\nexport {createJiraTokenStore, jiraSecretsNamespace} from '#core/tokens.js';\nexport type {\n CreateJiraWebhookProcessorOptions,\n JiraWebhookProcessor,\n} from '#core/webhook-processor.js';\nexport {createJiraWebhookProcessor} from '#core/webhook-processor.js';\nexport type {RegisterJiraWebhookParams} from '#core/webhook-registration.js';\nexport {JIRA_WEBHOOK_TTL_MS, registerJiraWebhook} from '#core/webhook-registration.js';\nexport type {\n JiraInstallation,\n JiraInstallationLock,\n JiraInstallationStatus,\n UpdateJiraInstallationWebhookParams,\n UpsertJiraInstallationParams,\n} from '#db/installations.js';\nexport {\n deleteJiraInstallationByConnectionId,\n getJiraInstallationByCloudId,\n getJiraInstallationByConnectionId,\n getJiraInstallationByWebhookId,\n listJiraInstallationsDueForTokenRefresh,\n markJiraInstallationRevoked,\n updateJiraInstallationTokenExpiry,\n updateJiraInstallationWebhook,\n upsertJiraInstallation,\n withJiraRefreshLock,\n withJiraWebhookRegistrationLock,\n} from '#db/installations.js';\nexport type {CreateJiraWebhookRoutesOptions} from '#presentation/routes/webhooks.js';\nexport {createJiraWebhookRoutes} from '#presentation/routes/webhooks.js';\nexport {createJiraMaintenanceWorker} from '#temporal/worker.js';\nexport {closeDb, config, db, migrationsPath};\n\nexport interface CreateJiraIntegrationProviderOptions {\n jira?: JiraApiClient | undefined;\n agentTools?:\n | {\n tokenStore: Pick<JiraTokenStore, 'getAccessToken'>;\n jira?: JiraAgentToolsClient | undefined;\n }\n | undefined;\n getJiraInstallationByConnectionId?: typeof getJiraInstallationByConnectionId | undefined;\n routes?: JiraIntegrationProviderRoutesOptions | undefined;\n}\n\ntype JiraIntegrationProviderRoutesOptions = Omit<\n CreateJiraIntegrationRoutesOptions,\n 'jira' | 'connectionCapabilities' | 'registerJiraWebhook'\n> &\n Omit<CreateJiraWebhookRoutesOptions, 'processor'>;\n\nexport function createJiraIntegrationProvider(options: CreateJiraIntegrationProviderOptions = {}) {\n const jira = options.jira ?? createJiraApiClient();\n const getInstallationByConnectionId =\n options.getJiraInstallationByConnectionId ?? getJiraInstallationByConnectionId;\n const adapters = options.agentTools\n ? {\n agent_tools: new JiraAgentToolsProvider({\n jira: options.agentTools.jira ?? createJiraAgentToolsClient(),\n tokenStore: options.agentTools.tokenStore,\n }),\n }\n : {};\n const webhookOptions = toJiraWebhookOptions(options.routes);\n const webhookProcessor = webhookOptions ? createJiraWebhookProcessor(webhookOptions) : undefined;\n const webhookRoutes = webhookOptions\n ? [\n createJiraWebhookRoutes({\n coreDb: webhookOptions.coreDb,\n publishIntegrationEventReceived: webhookOptions.publishIntegrationEventReceived,\n recordDeliveryOnly: webhookOptions.recordDeliveryOnly,\n getIntegrationConnectionById: webhookOptions.getIntegrationConnectionById,\n processor: webhookProcessor,\n }),\n ]\n : [];\n const routes = options.routes\n ? [\n createJiraIntegrationRoutes({\n jira,\n connectionCapabilities: adapters.agent_tools ? ['agent_tools'] : [],\n ...options.routes,\n registerJiraWebhook: (input) =>\n registerJiraWebhook({\n jira,\n connectionId: input.connectionId,\n cloudId: input.cloudId,\n accessToken: input.accessToken,\n webhookUrl: jiraWebhookUrl(input.connectionId),\n ...(input.withRegistrationLock\n ? {withRegistrationLock: input.withRegistrationLock}\n : {}),\n ...(input.onRegistrationSuccess\n ? {onRegistrationSuccess: input.onRegistrationSuccess}\n : {}),\n ...(input.onRegistrationFailure\n ? {onRegistrationFailure: input.onRegistrationFailure}\n : {}),\n }).then(() => undefined),\n }),\n ...webhookRoutes,\n ]\n : [];\n return {\n provider: JIRA_PROVIDER,\n displayName: 'Jira',\n adapters,\n async connectionExternalUrl(connection: {id: string}): Promise<string | undefined> {\n return (await getInstallationByConnectionId(connection.id))?.siteUrl;\n },\n routes,\n webhookProcessors: webhookProcessor\n ? [{routeIds: ['jira'] as const, processor: webhookProcessor}]\n : undefined,\n };\n}\n\nfunction jiraWebhookUrl(connectionId: string): string {\n return `${config.JIRA_WEBHOOK_BASE_URL.replace(TRAILING_SLASHES_RE, '')}${JIRA_WEBHOOK_ROUTE_PREFIX}/${connectionId}`;\n}\n\nfunction toJiraWebhookOptions(\n routes: CreateJiraIntegrationProviderOptions['routes'],\n): CreateJiraWebhookRoutesOptions | undefined {\n if (!routes) return undefined;\n if (\n routes.coreDb === undefined ||\n routes.publishIntegrationEventReceived === undefined ||\n routes.recordDeliveryOnly === undefined ||\n routes.getIntegrationConnectionById === undefined\n )\n throw new Error(\n 'Jira integration provider requires all webhook receiver dependencies: coreDb, publishIntegrationEventReceived, recordDeliveryOnly, and getIntegrationConnectionById',\n );\n return {\n coreDb: routes.coreDb,\n publishIntegrationEventReceived: routes.publishIntegrationEventReceived,\n recordDeliveryOnly: routes.recordDeliveryOnly,\n getIntegrationConnectionById: routes.getIntegrationConnectionById,\n };\n}\n"],"names":["JIRA_PROVIDER","createJiraAgentToolsClient","createJiraApiClient","config","JiraAgentToolsProvider","createJiraWebhookProcessor","registerJiraWebhook","closeDb","db","getJiraInstallationByConnectionId","migrationsPath","createJiraIntegrationRoutes","createJiraWebhookRoutes","JIRA_WEBHOOK_ROUTE_PREFIX","TRAILING_SLASHES_RE","JIRA_DYNAMIC_WEBHOOK_EVENTS","JIRA_DYNAMIC_WEBHOOK_JQL","mapJiraError","jiraAgentToolCatalog","jiraAgentToolSelectionCatalog","jiraPlainTextToAdf","disconnectJiraInstallation","JiraAccessTokenMissingError","JiraAuthorizationScopeMismatchError","JiraConnectionAlreadyLinkedError","JiraConnectionNotFoundError","JiraInstallationAlreadyLinkedError","JiraInstallationSiteMismatchError","JiraInstallStateActorMismatchError","JiraInstallStateError","JiraIntegrationProviderError","JiraOAuthCallbackError","JiraOfflineAccessNotGrantedError","JiraPendingSelectionNotFoundError","JiraSiteSelectionMismatchError","JiraTokenUnrefreshableError","handleJiraCallback","handleJiraOAuthCallbackError","handleJiraSiteSelection","createJiraPendingSelectionStore","jiraPendingSecretsNamespace","assertJiraAuthorizationScopes","formatJiraOAuthScopes","JIRA_OAUTH_SCOPES","signJiraInstallState","verifyJiraInstallState","createJiraTokenStore","jiraSecretsNamespace","JIRA_WEBHOOK_TTL_MS","deleteJiraInstallationByConnectionId","getJiraInstallationByCloudId","getJiraInstallationByWebhookId","listJiraInstallationsDueForTokenRefresh","markJiraInstallationRevoked","updateJiraInstallationTokenExpiry","updateJiraInstallationWebhook","upsertJiraInstallation","withJiraRefreshLock","withJiraWebhookRegistrationLock","createJiraMaintenanceWorker","createJiraIntegrationProvider","options","jira","getInstallationByConnectionId","adapters","agentTools","agent_tools","tokenStore","webhookOptions","toJiraWebhookOptions","routes","webhookProcessor","undefined","webhookRoutes","coreDb","publishIntegrationEventReceived","recordDeliveryOnly","getIntegrationConnectionById","processor","connectionCapabilities","input","connectionId","cloudId","accessToken","webhookUrl","jiraWebhookUrl","withRegistrationLock","onRegistrationSuccess","onRegistrationFailure","then","provider","displayName","connectionExternalUrl","connection","id","siteUrl","webhookProcessors","routeIds","JIRA_WEBHOOK_BASE_URL","replace","Error"],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/temporal/activities/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,sCAAsC,EAC3C,+BAA+B,EAC/B,KAAK,8BAA8B,GACpC,MAAM,0BAA0B,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/temporal/activities/index.ts"],"sourcesContent":["export {\n type CreateJiraMaintenanceActivitiesOptions,\n createJiraMaintenanceActivities,\n type JiraTokenRefreshActivityResult,\n} from './refresh-jira-tokens.js';\n"],"names":["createJiraMaintenanceActivities"],"mappings":"AAAA,SAEEA,+BAA+B,QAE1B,2BAA2B"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { IntegrationConnection } from '@shipfox/api-integration-spi';
|
|
2
|
+
import type { JiraTokenStore } from '#core/tokens.js';
|
|
3
|
+
import { listJiraInstallationsDueForTokenRefresh, markJiraInstallationTokenRefreshAttempt } from '#db/installations.js';
|
|
4
|
+
export interface JiraTokenRefreshActivityResult {
|
|
5
|
+
refreshed: number;
|
|
6
|
+
skipped: number;
|
|
7
|
+
failed: number;
|
|
8
|
+
}
|
|
9
|
+
export interface CreateJiraMaintenanceActivitiesOptions {
|
|
10
|
+
tokenStore: Pick<JiraTokenStore, 'getAccessToken'>;
|
|
11
|
+
resolveConnection(connectionId: string): Promise<Pick<IntegrationConnection, 'lifecycleStatus'> | undefined>;
|
|
12
|
+
listInstallations?: typeof listJiraInstallationsDueForTokenRefresh | undefined;
|
|
13
|
+
markAttempted?: typeof markJiraInstallationTokenRefreshAttempt | undefined;
|
|
14
|
+
now?: (() => Date) | undefined;
|
|
15
|
+
heartbeat?: (() => void) | undefined;
|
|
16
|
+
}
|
|
17
|
+
export declare function createJiraMaintenanceActivities(options: CreateJiraMaintenanceActivitiesOptions): {
|
|
18
|
+
refreshJiraTokensActivity(): Promise<JiraTokenRefreshActivityResult>;
|
|
19
|
+
};
|
|
20
|
+
//# sourceMappingURL=refresh-jira-tokens.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"refresh-jira-tokens.d.ts","sourceRoot":"","sources":["../../../src/temporal/activities/refresh-jira-tokens.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,qBAAqB,EAAC,MAAM,8BAA8B,CAAC;AAExE,OAAO,KAAK,EAAC,cAAc,EAAC,MAAM,iBAAiB,CAAC;AACpD,OAAO,EAEL,uCAAuC,EACvC,uCAAuC,EACxC,MAAM,sBAAsB,CAAC;AAQ9B,MAAM,WAAW,8BAA8B;IAC7C,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,sCAAsC;IACrD,UAAU,EAAE,IAAI,CAAC,cAAc,EAAE,gBAAgB,CAAC,CAAC;IACnD,iBAAiB,CACf,YAAY,EAAE,MAAM,GACnB,OAAO,CAAC,IAAI,CAAC,qBAAqB,EAAE,iBAAiB,CAAC,GAAG,SAAS,CAAC,CAAC;IACvE,iBAAiB,CAAC,EAAE,OAAO,uCAAuC,GAAG,SAAS,CAAC;IAC/E,aAAa,CAAC,EAAE,OAAO,uCAAuC,GAAG,SAAS,CAAC;IAC3E,GAAG,CAAC,EAAE,CAAC,MAAM,IAAI,CAAC,GAAG,SAAS,CAAC;IAC/B,SAAS,CAAC,EAAE,CAAC,MAAM,IAAI,CAAC,GAAG,SAAS,CAAC;CACtC;AAED,wBAAgB,+BAA+B,CAAC,OAAO,EAAE,sCAAsC;iCAOxD,OAAO,CAAC,8BAA8B,CAAC;EAsC7E"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { logger } from '@shipfox/node-opentelemetry';
|
|
2
|
+
import { listJiraInstallationsDueForTokenRefresh, markJiraInstallationTokenRefreshAttempt } from '#db/installations.js';
|
|
3
|
+
import { JIRA_REFRESH_TOKEN_PROACTIVE_REFRESH_AFTER_MS, JIRA_REFRESH_TOKEN_SWEEP_BATCH_SIZE } from '#temporal/constants.js';
|
|
4
|
+
const JIRA_REFRESH_TOKEN_HEARTBEAT_INTERVAL_MS = 15_000;
|
|
5
|
+
export function createJiraMaintenanceActivities(options) {
|
|
6
|
+
const listInstallations = options.listInstallations ?? listJiraInstallationsDueForTokenRefresh;
|
|
7
|
+
const markAttempted = options.markAttempted ?? markJiraInstallationTokenRefreshAttempt;
|
|
8
|
+
const now = options.now ?? (()=>new Date());
|
|
9
|
+
const heartbeat = options.heartbeat ?? (()=>undefined);
|
|
10
|
+
return {
|
|
11
|
+
async refreshJiraTokensActivity () {
|
|
12
|
+
const before = new Date(now().getTime() - JIRA_REFRESH_TOKEN_PROACTIVE_REFRESH_AFTER_MS);
|
|
13
|
+
const installations = await listInstallations({
|
|
14
|
+
before,
|
|
15
|
+
limit: JIRA_REFRESH_TOKEN_SWEEP_BATCH_SIZE
|
|
16
|
+
});
|
|
17
|
+
let refreshed = 0;
|
|
18
|
+
let skipped = 0;
|
|
19
|
+
let failed = 0;
|
|
20
|
+
for (const installation of installations){
|
|
21
|
+
const heartbeatInterval = setInterval(heartbeat, JIRA_REFRESH_TOKEN_HEARTBEAT_INTERVAL_MS);
|
|
22
|
+
try {
|
|
23
|
+
heartbeat();
|
|
24
|
+
await markAttempted(installation.connectionId);
|
|
25
|
+
const connection = await options.resolveConnection(installation.connectionId);
|
|
26
|
+
if (connection?.lifecycleStatus !== 'active') {
|
|
27
|
+
skipped += 1;
|
|
28
|
+
continue;
|
|
29
|
+
}
|
|
30
|
+
await options.tokenStore.getAccessToken({
|
|
31
|
+
connectionId: installation.connectionId,
|
|
32
|
+
forceRefresh: true
|
|
33
|
+
});
|
|
34
|
+
refreshed += 1;
|
|
35
|
+
} catch (error) {
|
|
36
|
+
failed += 1;
|
|
37
|
+
logRefreshFailure(installation, error);
|
|
38
|
+
} finally{
|
|
39
|
+
clearInterval(heartbeatInterval);
|
|
40
|
+
heartbeat();
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
return {
|
|
44
|
+
refreshed,
|
|
45
|
+
skipped,
|
|
46
|
+
failed
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
function logRefreshFailure(installation, error) {
|
|
52
|
+
logger().warn({
|
|
53
|
+
connectionId: installation.connectionId,
|
|
54
|
+
err: error
|
|
55
|
+
}, 'Jira proactive token refresh failed');
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
//# sourceMappingURL=refresh-jira-tokens.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/temporal/activities/refresh-jira-tokens.ts"],"sourcesContent":["import type {IntegrationConnection} from '@shipfox/api-integration-spi';\nimport {logger} from '@shipfox/node-opentelemetry';\nimport type {JiraTokenStore} from '#core/tokens.js';\nimport {\n type JiraInstallation,\n listJiraInstallationsDueForTokenRefresh,\n markJiraInstallationTokenRefreshAttempt,\n} from '#db/installations.js';\nimport {\n JIRA_REFRESH_TOKEN_PROACTIVE_REFRESH_AFTER_MS,\n JIRA_REFRESH_TOKEN_SWEEP_BATCH_SIZE,\n} from '#temporal/constants.js';\n\nconst JIRA_REFRESH_TOKEN_HEARTBEAT_INTERVAL_MS = 15_000;\n\nexport interface JiraTokenRefreshActivityResult {\n refreshed: number;\n skipped: number;\n failed: number;\n}\n\nexport interface CreateJiraMaintenanceActivitiesOptions {\n tokenStore: Pick<JiraTokenStore, 'getAccessToken'>;\n resolveConnection(\n connectionId: string,\n ): Promise<Pick<IntegrationConnection, 'lifecycleStatus'> | undefined>;\n listInstallations?: typeof listJiraInstallationsDueForTokenRefresh | undefined;\n markAttempted?: typeof markJiraInstallationTokenRefreshAttempt | undefined;\n now?: (() => Date) | undefined;\n heartbeat?: (() => void) | undefined;\n}\n\nexport function createJiraMaintenanceActivities(options: CreateJiraMaintenanceActivitiesOptions) {\n const listInstallations = options.listInstallations ?? listJiraInstallationsDueForTokenRefresh;\n const markAttempted = options.markAttempted ?? markJiraInstallationTokenRefreshAttempt;\n const now = options.now ?? (() => new Date());\n const heartbeat = options.heartbeat ?? (() => undefined);\n\n return {\n async refreshJiraTokensActivity(): Promise<JiraTokenRefreshActivityResult> {\n const before = new Date(now().getTime() - JIRA_REFRESH_TOKEN_PROACTIVE_REFRESH_AFTER_MS);\n const installations = await listInstallations({\n before,\n limit: JIRA_REFRESH_TOKEN_SWEEP_BATCH_SIZE,\n });\n let refreshed = 0;\n let skipped = 0;\n let failed = 0;\n\n for (const installation of installations) {\n const heartbeatInterval = setInterval(heartbeat, JIRA_REFRESH_TOKEN_HEARTBEAT_INTERVAL_MS);\n try {\n heartbeat();\n await markAttempted(installation.connectionId);\n const connection = await options.resolveConnection(installation.connectionId);\n if (connection?.lifecycleStatus !== 'active') {\n skipped += 1;\n continue;\n }\n\n await options.tokenStore.getAccessToken({\n connectionId: installation.connectionId,\n forceRefresh: true,\n });\n refreshed += 1;\n } catch (error) {\n failed += 1;\n logRefreshFailure(installation, error);\n } finally {\n clearInterval(heartbeatInterval);\n heartbeat();\n }\n }\n\n return {refreshed, skipped, failed};\n },\n };\n}\n\nfunction logRefreshFailure(installation: JiraInstallation, error: unknown): void {\n logger().warn(\n {\n connectionId: installation.connectionId,\n err: error,\n },\n 'Jira proactive token refresh failed',\n );\n}\n"],"names":["logger","listJiraInstallationsDueForTokenRefresh","markJiraInstallationTokenRefreshAttempt","JIRA_REFRESH_TOKEN_PROACTIVE_REFRESH_AFTER_MS","JIRA_REFRESH_TOKEN_SWEEP_BATCH_SIZE","JIRA_REFRESH_TOKEN_HEARTBEAT_INTERVAL_MS","createJiraMaintenanceActivities","options","listInstallations","markAttempted","now","Date","heartbeat","undefined","refreshJiraTokensActivity","before","getTime","installations","limit","refreshed","skipped","failed","installation","heartbeatInterval","setInterval","connectionId","connection","resolveConnection","lifecycleStatus","tokenStore","getAccessToken","forceRefresh","error","logRefreshFailure","clearInterval","warn","err"],"mappings":"AACA,SAAQA,MAAM,QAAO,8BAA8B;AAEnD,SAEEC,uCAAuC,EACvCC,uCAAuC,QAClC,uBAAuB;AAC9B,SACEC,6CAA6C,EAC7CC,mCAAmC,QAC9B,yBAAyB;AAEhC,MAAMC,2CAA2C;AAmBjD,OAAO,SAASC,gCAAgCC,OAA+C;IAC7F,MAAMC,oBAAoBD,QAAQC,iBAAiB,IAAIP;IACvD,MAAMQ,gBAAgBF,QAAQE,aAAa,IAAIP;IAC/C,MAAMQ,MAAMH,QAAQG,GAAG,IAAK,CAAA,IAAM,IAAIC,MAAK;IAC3C,MAAMC,YAAYL,QAAQK,SAAS,IAAK,CAAA,IAAMC,SAAQ;IAEtD,OAAO;QACL,MAAMC;YACJ,MAAMC,SAAS,IAAIJ,KAAKD,MAAMM,OAAO,KAAKb;YAC1C,MAAMc,gBAAgB,MAAMT,kBAAkB;gBAC5CO;gBACAG,OAAOd;YACT;YACA,IAAIe,YAAY;YAChB,IAAIC,UAAU;YACd,IAAIC,SAAS;YAEb,KAAK,MAAMC,gBAAgBL,cAAe;gBACxC,MAAMM,oBAAoBC,YAAYZ,WAAWP;gBACjD,IAAI;oBACFO;oBACA,MAAMH,cAAca,aAAaG,YAAY;oBAC7C,MAAMC,aAAa,MAAMnB,QAAQoB,iBAAiB,CAACL,aAAaG,YAAY;oBAC5E,IAAIC,YAAYE,oBAAoB,UAAU;wBAC5CR,WAAW;wBACX;oBACF;oBAEA,MAAMb,QAAQsB,UAAU,CAACC,cAAc,CAAC;wBACtCL,cAAcH,aAAaG,YAAY;wBACvCM,cAAc;oBAChB;oBACAZ,aAAa;gBACf,EAAE,OAAOa,OAAO;oBACdX,UAAU;oBACVY,kBAAkBX,cAAcU;gBAClC,SAAU;oBACRE,cAAcX;oBACdX;gBACF;YACF;YAEA,OAAO;gBAACO;gBAAWC;gBAASC;YAAM;QACpC;IACF;AACF;AAEA,SAASY,kBAAkBX,YAA8B,EAAEU,KAAc;IACvEhC,SAASmC,IAAI,CACX;QACEV,cAAcH,aAAaG,YAAY;QACvCW,KAAKJ;IACP,GACA;AAEJ"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export declare const JIRA_REFRESH_TOKEN_IDLE_WINDOW_MS: number;
|
|
2
|
+
export declare const JIRA_REFRESH_TOKEN_REFRESH_LEAD_TIME_MS: number;
|
|
3
|
+
export declare const JIRA_REFRESH_TOKEN_PROACTIVE_REFRESH_AFTER_MS: number;
|
|
4
|
+
export declare const JIRA_REFRESH_TOKEN_SWEEP_BATCH_SIZE = 20;
|
|
5
|
+
export declare const JIRA_MAINTENANCE_TASK_QUEUE = "integrations-jira-maintenance";
|
|
6
|
+
//# sourceMappingURL=constants.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../src/temporal/constants.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,iCAAiC,QAAkB,CAAC;AACjE,eAAO,MAAM,uCAAuC,QAAkB,CAAC;AACvE,eAAO,MAAM,6CAA6C,QACmB,CAAC;AAC9E,eAAO,MAAM,mCAAmC,KAAK,CAAC;AACtD,eAAO,MAAM,2BAA2B,kCAAkC,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
const MS_PER_DAY = 24 * 60 * 60 * 1000;
|
|
2
|
+
export const JIRA_REFRESH_TOKEN_IDLE_WINDOW_MS = 90 * MS_PER_DAY;
|
|
3
|
+
export const JIRA_REFRESH_TOKEN_REFRESH_LEAD_TIME_MS = 14 * MS_PER_DAY;
|
|
4
|
+
export const JIRA_REFRESH_TOKEN_PROACTIVE_REFRESH_AFTER_MS = JIRA_REFRESH_TOKEN_IDLE_WINDOW_MS - JIRA_REFRESH_TOKEN_REFRESH_LEAD_TIME_MS;
|
|
5
|
+
export const JIRA_REFRESH_TOKEN_SWEEP_BATCH_SIZE = 20;
|
|
6
|
+
export const JIRA_MAINTENANCE_TASK_QUEUE = 'integrations-jira-maintenance';
|
|
7
|
+
|
|
8
|
+
//# sourceMappingURL=constants.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/temporal/constants.ts"],"sourcesContent":["const MS_PER_DAY = 24 * 60 * 60 * 1000;\n\nexport const JIRA_REFRESH_TOKEN_IDLE_WINDOW_MS = 90 * MS_PER_DAY;\nexport const JIRA_REFRESH_TOKEN_REFRESH_LEAD_TIME_MS = 14 * MS_PER_DAY;\nexport const JIRA_REFRESH_TOKEN_PROACTIVE_REFRESH_AFTER_MS =\n JIRA_REFRESH_TOKEN_IDLE_WINDOW_MS - JIRA_REFRESH_TOKEN_REFRESH_LEAD_TIME_MS;\nexport const JIRA_REFRESH_TOKEN_SWEEP_BATCH_SIZE = 20;\nexport const JIRA_MAINTENANCE_TASK_QUEUE = 'integrations-jira-maintenance';\n"],"names":["MS_PER_DAY","JIRA_REFRESH_TOKEN_IDLE_WINDOW_MS","JIRA_REFRESH_TOKEN_REFRESH_LEAD_TIME_MS","JIRA_REFRESH_TOKEN_PROACTIVE_REFRESH_AFTER_MS","JIRA_REFRESH_TOKEN_SWEEP_BATCH_SIZE","JIRA_MAINTENANCE_TASK_QUEUE"],"mappings":"AAAA,MAAMA,aAAa,KAAK,KAAK,KAAK;AAElC,OAAO,MAAMC,oCAAoC,KAAKD,WAAW;AACjE,OAAO,MAAME,0CAA0C,KAAKF,WAAW;AACvE,OAAO,MAAMG,gDACXF,oCAAoCC,wCAAwC;AAC9E,OAAO,MAAME,sCAAsC,GAAG;AACtD,OAAO,MAAMC,8BAA8B,gCAAgC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { IntegrationConnection } from '@shipfox/api-integration-spi';
|
|
2
|
+
import type { ModuleWorker } from '@shipfox/node-module';
|
|
3
|
+
import type { JiraTokenStore } from '#core/tokens.js';
|
|
4
|
+
export interface CreateJiraMaintenanceWorkerOptions {
|
|
5
|
+
tokenStore: Pick<JiraTokenStore, 'getAccessToken'>;
|
|
6
|
+
resolveConnection(connectionId: string): Promise<Pick<IntegrationConnection, 'lifecycleStatus'> | undefined>;
|
|
7
|
+
}
|
|
8
|
+
export declare function createJiraMaintenanceWorker(options: CreateJiraMaintenanceWorkerOptions): ModuleWorker;
|
|
9
|
+
//# sourceMappingURL=worker.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"worker.d.ts","sourceRoot":"","sources":["../../src/temporal/worker.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAC,qBAAqB,EAAC,MAAM,8BAA8B,CAAC;AACxE,OAAO,KAAK,EAAC,YAAY,EAAC,MAAM,sBAAsB,CAAC;AAEvD,OAAO,KAAK,EAAC,cAAc,EAAC,MAAM,iBAAiB,CAAC;AAOpD,MAAM,WAAW,kCAAkC;IACjD,UAAU,EAAE,IAAI,CAAC,cAAc,EAAE,gBAAgB,CAAC,CAAC;IACnD,iBAAiB,CACf,YAAY,EAAE,MAAM,GACnB,OAAO,CAAC,IAAI,CAAC,qBAAqB,EAAE,iBAAiB,CAAC,GAAG,SAAS,CAAC,CAAC;CACxE;AAED,wBAAgB,2BAA2B,CACzC,OAAO,EAAE,kCAAkC,GAC1C,YAAY,CAiBd"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { dirname, resolve } from 'node:path';
|
|
2
|
+
import { fileURLToPath } from 'node:url';
|
|
3
|
+
import { Context } from '@temporalio/activity';
|
|
4
|
+
import { createJiraMaintenanceActivities } from '#temporal/activities/index.js';
|
|
5
|
+
import { JIRA_MAINTENANCE_TASK_QUEUE } from '#temporal/constants.js';
|
|
6
|
+
const packageRoot = resolve(dirname(fileURLToPath(import.meta.url)), '../..');
|
|
7
|
+
const workflowsPath = resolve(packageRoot, 'dist/temporal/workflows/index.js');
|
|
8
|
+
export function createJiraMaintenanceWorker(options) {
|
|
9
|
+
return {
|
|
10
|
+
taskQueue: JIRA_MAINTENANCE_TASK_QUEUE,
|
|
11
|
+
workflowsPath,
|
|
12
|
+
activities: ()=>createJiraMaintenanceActivities({
|
|
13
|
+
...options,
|
|
14
|
+
heartbeat: ()=>Context.current().heartbeat()
|
|
15
|
+
}),
|
|
16
|
+
workflows: [
|
|
17
|
+
{
|
|
18
|
+
name: 'refreshJiraTokensCron',
|
|
19
|
+
id: 'jira-refresh-tokens',
|
|
20
|
+
cronSchedule: '0 */6 * * *'
|
|
21
|
+
}
|
|
22
|
+
]
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
//# sourceMappingURL=worker.js.map
|