@shipfox/api-integration-core 11.0.0 → 12.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. package/.turbo/turbo-build.log +4 -4
  2. package/CHANGELOG.md +62 -0
  3. package/dist/core/providers/source-control.d.ts +1 -1
  4. package/dist/core/providers/source-control.d.ts.map +1 -1
  5. package/dist/core/providers/source-control.js.map +1 -1
  6. package/dist/core/source-control-service.d.ts +7 -1
  7. package/dist/core/source-control-service.d.ts.map +1 -1
  8. package/dist/core/source-control-service.js +11 -0
  9. package/dist/core/source-control-service.js.map +1 -1
  10. package/dist/db/connections.d.ts +6 -0
  11. package/dist/db/connections.d.ts.map +1 -1
  12. package/dist/db/connections.js +6 -0
  13. package/dist/db/connections.js.map +1 -1
  14. package/dist/db/webhook-deliveries.d.ts +18 -1
  15. package/dist/db/webhook-deliveries.d.ts.map +1 -1
  16. package/dist/db/webhook-deliveries.js +65 -19
  17. package/dist/db/webhook-deliveries.js.map +1 -1
  18. package/dist/index.d.ts +5 -5
  19. package/dist/index.d.ts.map +1 -1
  20. package/dist/index.js +2 -2
  21. package/dist/index.js.map +1 -1
  22. package/dist/presentation/inter-module.d.ts.map +1 -1
  23. package/dist/presentation/inter-module.js +10 -1
  24. package/dist/presentation/inter-module.js.map +1 -1
  25. package/dist/providers/github.d.ts.map +1 -1
  26. package/dist/providers/github.js +2 -1
  27. package/dist/providers/github.js.map +1 -1
  28. package/dist/providers/jira.d.ts.map +1 -1
  29. package/dist/providers/jira.js +35 -12
  30. package/dist/providers/jira.js.map +1 -1
  31. package/dist/providers/types.d.ts +1 -1
  32. package/dist/providers/types.js.map +1 -1
  33. package/dist/tsconfig.test.tsbuildinfo +1 -1
  34. package/package.json +20 -20
  35. package/src/core/agent-tool-selection.test.ts +1 -0
  36. package/src/core/providers/registry.test.ts +1 -0
  37. package/src/core/providers/source-control.ts +1 -0
  38. package/src/core/source-control-service.test.ts +25 -0
  39. package/src/core/source-control-service.ts +21 -0
  40. package/src/db/connections.test.ts +18 -0
  41. package/src/db/connections.ts +25 -0
  42. package/src/db/webhook-deliveries.test.ts +77 -0
  43. package/src/db/webhook-deliveries.ts +110 -21
  44. package/src/index.ts +13 -3
  45. package/src/presentation/inter-module.ts +11 -1
  46. package/src/presentation/routes/list-repositories.test.ts +1 -0
  47. package/src/providers/github.ts +2 -0
  48. package/src/providers/jira.test.ts +2 -0
  49. package/src/providers/jira.ts +38 -12
  50. package/src/providers/types.ts +1 -1
  51. package/test/env.ts +0 -1
  52. package/test/route-utils.ts +1 -0
  53. package/tsconfig.build.tsbuildinfo +1 -1
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts"],"sourcesContent":["import {dirname, resolve} from 'node:path';\nimport {fileURLToPath} from 'node:url';\nimport {\n integrationsEventSchemas,\n type StoredWebhookRequest,\n type WebhookProcessingResult,\n type WebhookRequestProcessor,\n type WebhookRouteId,\n} from '@shipfox/api-integration-spi';\nimport type {WorkflowsModuleClient} from '@shipfox/api-workflows-dto/inter-module';\nimport type {WorkspacesInterModuleClient} from '@shipfox/api-workspaces-dto/inter-module';\nimport {reportError} from '@shipfox/node-error-monitoring';\nimport type {ModuleService, ShipfoxModule} from '@shipfox/node-module';\nimport {logger} from '@shipfox/node-opentelemetry';\nimport type {IntegrationProvider} from '#core/entities/provider.js';\nimport {WebhookProcessorNotConfiguredError} from '#core/errors.js';\nimport {\n createIntegrationProviderRegistry,\n type IntegrationProviderRegistry,\n} from '#core/providers/registry.js';\nimport {\n createSourceControlIntegrationService,\n type IntegrationSourceControlService,\n} from '#core/source-control-service.js';\nimport {getIntegrationConnectionById} from '#db/connections.js';\nimport {db} from '#db/db.js';\nimport {migrationsPath} from '#db/migrations.js';\nimport {integrationsOutbox} from '#db/schema/outbox.js';\nimport {createIntegrationsInterModulePresentation} from '#presentation/inter-module.js';\nimport {createIntegrationRoutes} from '#presentation/routes/index.js';\nimport {loadEnabledProviderModules} from '#providers/modules.js';\nimport type {\n IntegrationModuleParts,\n IntegrationProviderSecrets,\n WebhookProcessorRegistration,\n} from '#providers/types.js';\nimport {createIntegrationsMaintenanceActivities} from '#temporal/activities/index.js';\nimport {INTEGRATIONS_MAINTENANCE_TASK_QUEUE} from '#temporal/constants.js';\n\nconst packageRoot = resolve(dirname(fileURLToPath(import.meta.url)), '..');\nconst maintenanceWorkflowsPath = resolve(packageRoot, 'dist/temporal/workflows/index.js');\n\nexport type {\n StoredWebhookRequest,\n WebhookProcessingResult,\n WebhookRequestProcessor,\n WebhookRouteId,\n} from '@shipfox/api-integration-spi';\nexport {\n buildProviderRepositoryId,\n MAX_REPOSITORY_FILE_BYTES,\n parseProviderRepositoryId,\n} from '@shipfox/api-integration-spi';\nexport type {\n AgentToolCatalogs,\n AgentToolSelectionCatalogs,\n LoadWorkspaceConnectionSnapshot,\n WorkspaceConnectionSnapshot,\n WorkspaceConnectionSnapshotEntry,\n} from '#core/agent-tool-selection.js';\nexport {\n buildAgentToolCatalogs,\n buildAgentToolSelectionCatalogs,\n createWorkspaceConnectionSnapshotLoader,\n} from '#core/agent-tool-selection.js';\nexport type {\n IntegrationConnection,\n IntegrationConnectionLifecycleStatus,\n} from '#core/entities/connection.js';\nexport type {\n IntegrationCapability,\n IntegrationProvider,\n IntegrationProviderAdapters,\n IntegrationProviderKind,\n RegisteredIntegrationProvider,\n} from '#core/entities/provider.js';\nexport type {IntegrationProviderErrorReason} from '#core/errors.js';\nexport {\n ConnectionSlugConflictError,\n IntegrationCapabilityUnavailableError,\n IntegrationCheckoutUnsupportedError,\n IntegrationConnectionInactiveError,\n IntegrationConnectionNotFoundError,\n IntegrationConnectionWorkspaceMismatchError,\n IntegrationProviderError,\n IntegrationProviderUnavailableError,\n WebhookProcessorNotConfiguredError,\n} from '#core/errors.js';\nexport type {\n AgentToolCallInput,\n AgentToolCatalogEntry,\n AgentToolCatalogMethod,\n AgentToolJsonSchema,\n AgentToolSensitivity,\n AgentToolSession,\n AgentToolsProvider,\n OpenAgentToolsSessionInput,\n} from '#core/providers/agent-tools.js';\nexport {redactCheckoutSpec} from '#core/providers/redact-checkout-spec.js';\nexport type {IntegrationProviderRegistry} from '#core/providers/registry.js';\nexport type {\n CheckoutCredentials,\n CheckoutPermissions,\n CheckoutSpec,\n CreateCheckoutSpecInput,\n FetchFileInput,\n FileEntry,\n FilePage,\n FileSnapshot,\n ListFilesInput,\n ListRepositoriesInput,\n RepositoryPage,\n RepositorySnapshot,\n RepositoryVisibility,\n ResolveRepositoryInput,\n SourceControlProvider,\n} from '#core/providers/source-control.js';\nexport type {IntegrationSourceControlService} from '#core/source-control-service.js';\nexport {createSourceControlIntegrationService} from '#core/source-control-service.js';\nexport type {GetIntegrationConnectionByIdFn} from '#db/connections.js';\nexport {getIntegrationConnectionById} from '#db/connections.js';\nexport type {\n ClaimWebhookDeliveryFn,\n PublishIntegrationEventReceivedFn,\n PublishIntegrationEventReceivedParams,\n PublishIntegrationEventReceivedResult,\n PublishSourcePushFn,\n PublishSourcePushParams,\n RecordDeliveryOnlyFn,\n RecordDeliveryOnlyParams,\n} from '#db/webhook-deliveries.js';\nexport {claimWebhookDelivery, pruneWebhookDeliveries} from '#db/webhook-deliveries.js';\nexport {integrationRouteErrorHandler} from '#presentation/routes/errors.js';\n\nexport interface CreateIntegrationsModuleOptions {\n providers?: IntegrationProvider[] | undefined;\n /**\n * Pre-built module parts, bypassing config-gated provider loading. Test-only seam\n * for exercising a provider's database, workers, or startup tasks directly. Takes\n * precedence over `providers`.\n */\n parts?: IntegrationModuleParts[] | undefined;\n secrets?: IntegrationProviderSecrets | undefined;\n workspaces?: WorkspacesInterModuleClient | undefined;\n agentTools?:\n | {\n workflows: WorkflowsModuleClient;\n }\n | undefined;\n webhookDeliverySource?: WebhookDeliverySource | undefined;\n}\n\n/**\n * Hosted runtimes implement this port to receive stored webhook requests. The\n * integration module starts its returned service after migrations complete.\n */\nexport interface WebhookDeliverySource {\n createService(processor: WebhookRequestProcessor): ModuleService;\n}\n\nexport interface IntegrationsContext {\n module: ShipfoxModule;\n registry: IntegrationProviderRegistry;\n capabilities: {\n sourceControl: IntegrationSourceControlService;\n };\n sourceControl: IntegrationSourceControlService;\n webhookProcessor: WebhookRequestProcessor;\n /**\n * Runs every enabled provider's one-shot boot-time tasks, after modules are initialized\n * (migrations done). Failures are isolated and logged, never rethrown, so a provider task\n * can never gate API boot. No-op when no enabled provider contributes a task.\n */\n runStartupTasks: () => Promise<void>;\n}\n\nexport async function createIntegrationsModule(\n options: CreateIntegrationsModuleOptions = {},\n): Promise<ShipfoxModule> {\n return (await createIntegrationsContext(options)).module;\n}\n\nexport async function createIntegrationsContext(\n options: CreateIntegrationsModuleOptions = {},\n): Promise<IntegrationsContext> {\n const workspaces = options.workspaces;\n const parts: IntegrationModuleParts[] =\n options.parts ??\n (options.providers\n ? options.providers.map((provider) => ({\n provider,\n webhookProcessors: provider.webhookProcessors,\n }))\n : await loadEnabledProviderModules({\n secrets: options.secrets,\n ...(workspaces\n ? {\n requireActiveWorkspaceMembership: (input: {\n workspaceId: string;\n userId: string;\n memberships: ReadonlyArray<\n import('@shipfox/api-auth-context').UserContextMembership\n >;\n }) =>\n workspaces.requireActiveMembership({\n ...input,\n memberships: [...input.memberships],\n }),\n }\n : {}),\n }));\n\n const registry = createIntegrationProviderRegistry(parts.map((part) => part.provider));\n const sourceControl = createSourceControlIntegrationService({\n registry,\n getIntegrationConnectionById,\n });\n const webhookProcessor = createComposedWebhookProcessor(\n parts.flatMap((part) => part.webhookProcessors ?? []),\n );\n\n async function runStartupTasks(): Promise<void> {\n for (const task of parts.flatMap((part) => part.startupTasks ?? [])) {\n // A provider convenience must never gate API boot.\n try {\n await task();\n } catch (error) {\n logger().error({err: error}, 'Integration startup task failed, continuing boot');\n reportError(error, {boundary: 'integration.startup'});\n }\n }\n }\n\n const module: ShipfoxModule = {\n name: 'integrations',\n interModulePresentations: [\n createIntegrationsInterModulePresentation({registry, sourceControl}),\n ],\n startupTasks: runStartupTasks,\n database: [\n {db, migrationsPath, databaseNamespace: 'integrations'},\n ...parts.flatMap((part) => (part.database ? [part.database] : [])),\n ],\n routes: createIntegrationRoutes(registry, sourceControl, {\n agentTools: options.agentTools\n ? {\n workflows: options.agentTools.workflows,\n getIntegrationConnectionById,\n }\n : undefined,\n }),\n e2eRoutes: parts.flatMap((part) => part.e2eRoutes ?? []),\n publishers: [\n {name: 'integrations', table: integrationsOutbox, db, eventSchemas: integrationsEventSchemas},\n ],\n workers: [\n {\n taskQueue: INTEGRATIONS_MAINTENANCE_TASK_QUEUE,\n workflowsPath: maintenanceWorkflowsPath,\n activities: createIntegrationsMaintenanceActivities,\n workflows: [\n {\n name: 'pruneWebhookDeliveriesCron',\n id: 'integrations-prune-webhook-deliveries',\n cronSchedule: '0 3 * * *',\n },\n ],\n },\n ...parts.flatMap((part) => part.workers ?? []),\n ],\n ...(options.webhookDeliverySource\n ? {services: [options.webhookDeliverySource.createService(webhookProcessor)]}\n : {}),\n };\n\n return {\n module,\n registry,\n capabilities: {sourceControl},\n sourceControl,\n webhookProcessor,\n runStartupTasks,\n };\n}\n\nfunction createComposedWebhookProcessor(\n registrations: WebhookProcessorRegistration[],\n): WebhookRequestProcessor {\n const processors = new Map<WebhookRouteId, WebhookRequestProcessor>();\n for (const registration of registrations) {\n for (const routeId of registration.routeIds) {\n if (processors.has(routeId)) {\n throw new Error(`Webhook processor is registered more than once for ${routeId}`);\n }\n processors.set(routeId, registration.processor);\n }\n }\n\n return {\n async process(request: StoredWebhookRequest): Promise<WebhookProcessingResult> {\n const processor = processors.get(request.route_id);\n if (!processor) {\n throw new WebhookProcessorNotConfiguredError(request.route_id);\n }\n return await processor.process(request);\n },\n };\n}\n"],"names":["dirname","resolve","fileURLToPath","integrationsEventSchemas","reportError","logger","WebhookProcessorNotConfiguredError","createIntegrationProviderRegistry","createSourceControlIntegrationService","getIntegrationConnectionById","db","migrationsPath","integrationsOutbox","createIntegrationsInterModulePresentation","createIntegrationRoutes","loadEnabledProviderModules","createIntegrationsMaintenanceActivities","INTEGRATIONS_MAINTENANCE_TASK_QUEUE","packageRoot","url","maintenanceWorkflowsPath","buildProviderRepositoryId","MAX_REPOSITORY_FILE_BYTES","parseProviderRepositoryId","buildAgentToolCatalogs","buildAgentToolSelectionCatalogs","createWorkspaceConnectionSnapshotLoader","ConnectionSlugConflictError","IntegrationCapabilityUnavailableError","IntegrationCheckoutUnsupportedError","IntegrationConnectionInactiveError","IntegrationConnectionNotFoundError","IntegrationConnectionWorkspaceMismatchError","IntegrationProviderError","IntegrationProviderUnavailableError","redactCheckoutSpec","claimWebhookDelivery","pruneWebhookDeliveries","integrationRouteErrorHandler","createIntegrationsModule","options","createIntegrationsContext","module","workspaces","parts","providers","map","provider","webhookProcessors","secrets","requireActiveWorkspaceMembership","input","requireActiveMembership","memberships","registry","part","sourceControl","webhookProcessor","createComposedWebhookProcessor","flatMap","runStartupTasks","task","startupTasks","error","err","boundary","name","interModulePresentations","database","databaseNamespace","routes","agentTools","workflows","undefined","e2eRoutes","publishers","table","eventSchemas","workers","taskQueue","workflowsPath","activities","id","cronSchedule","webhookDeliverySource","services","createService","capabilities","registrations","processors","Map","registration","routeId","routeIds","has","Error","set","processor","process","request","get","route_id"],"mappings":"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"}
1
+ {"version":3,"sources":["../src/index.ts"],"sourcesContent":["import {dirname, resolve} from 'node:path';\nimport {fileURLToPath} from 'node:url';\nimport {\n integrationsEventSchemas,\n type StoredWebhookRequest,\n type WebhookProcessingResult,\n type WebhookRequestProcessor,\n type WebhookRouteId,\n} from '@shipfox/api-integration-spi';\nimport type {WorkflowsModuleClient} from '@shipfox/api-workflows-dto/inter-module';\nimport type {WorkspacesInterModuleClient} from '@shipfox/api-workspaces-dto/inter-module';\nimport {reportError} from '@shipfox/node-error-monitoring';\nimport type {ModuleService, ShipfoxModule} from '@shipfox/node-module';\nimport {logger} from '@shipfox/node-opentelemetry';\nimport type {IntegrationProvider} from '#core/entities/provider.js';\nimport {WebhookProcessorNotConfiguredError} from '#core/errors.js';\nimport {\n createIntegrationProviderRegistry,\n type IntegrationProviderRegistry,\n} from '#core/providers/registry.js';\nimport {\n createSourceControlIntegrationService,\n type IntegrationSourceControlService,\n} from '#core/source-control-service.js';\nimport {getIntegrationConnectionById} from '#db/connections.js';\nimport {db} from '#db/db.js';\nimport {migrationsPath} from '#db/migrations.js';\nimport {integrationsOutbox} from '#db/schema/outbox.js';\nimport {createIntegrationsInterModulePresentation} from '#presentation/inter-module.js';\nimport {createIntegrationRoutes} from '#presentation/routes/index.js';\nimport {loadEnabledProviderModules} from '#providers/modules.js';\nimport type {\n IntegrationModuleParts,\n IntegrationProviderSecrets,\n WebhookProcessorRegistration,\n} from '#providers/types.js';\nimport {createIntegrationsMaintenanceActivities} from '#temporal/activities/index.js';\nimport {INTEGRATIONS_MAINTENANCE_TASK_QUEUE} from '#temporal/constants.js';\n\nconst packageRoot = resolve(dirname(fileURLToPath(import.meta.url)), '..');\nconst maintenanceWorkflowsPath = resolve(packageRoot, 'dist/temporal/workflows/index.js');\n\nexport type {\n StoredWebhookRequest,\n WebhookProcessingResult,\n WebhookRequestProcessor,\n WebhookRouteId,\n} from '@shipfox/api-integration-spi';\nexport {\n buildProviderRepositoryId,\n MAX_REPOSITORY_FILE_BYTES,\n parseProviderRepositoryId,\n} from '@shipfox/api-integration-spi';\nexport type {\n AgentToolCatalogs,\n AgentToolSelectionCatalogs,\n LoadWorkspaceConnectionSnapshot,\n WorkspaceConnectionSnapshot,\n WorkspaceConnectionSnapshotEntry,\n} from '#core/agent-tool-selection.js';\nexport {\n buildAgentToolCatalogs,\n buildAgentToolSelectionCatalogs,\n createWorkspaceConnectionSnapshotLoader,\n} from '#core/agent-tool-selection.js';\nexport type {\n IntegrationConnection,\n IntegrationConnectionLifecycleStatus,\n} from '#core/entities/connection.js';\nexport type {\n IntegrationCapability,\n IntegrationProvider,\n IntegrationProviderAdapters,\n IntegrationProviderKind,\n RegisteredIntegrationProvider,\n} from '#core/entities/provider.js';\nexport type {IntegrationProviderErrorReason} from '#core/errors.js';\nexport {\n ConnectionSlugConflictError,\n IntegrationCapabilityUnavailableError,\n IntegrationCheckoutUnsupportedError,\n IntegrationConnectionInactiveError,\n IntegrationConnectionNotFoundError,\n IntegrationConnectionWorkspaceMismatchError,\n IntegrationProviderError,\n IntegrationProviderUnavailableError,\n WebhookProcessorNotConfiguredError,\n} from '#core/errors.js';\nexport type {\n AgentToolCallInput,\n AgentToolCatalogEntry,\n AgentToolCatalogMethod,\n AgentToolJsonSchema,\n AgentToolSensitivity,\n AgentToolSession,\n AgentToolsProvider,\n OpenAgentToolsSessionInput,\n} from '#core/providers/agent-tools.js';\nexport {redactCheckoutSpec} from '#core/providers/redact-checkout-spec.js';\nexport type {IntegrationProviderRegistry} from '#core/providers/registry.js';\nexport type {\n CheckoutCredentials,\n CheckoutPermissions,\n CheckoutSpec,\n CreateCheckoutSpecInput,\n FetchFileInput,\n FileEntry,\n FilePage,\n FileSnapshot,\n ListFilesInput,\n ListRepositoriesInput,\n RepositoryPage,\n RepositorySnapshot,\n RepositoryVisibility,\n ResolveRepositoryInput,\n SourceControlProvider,\n TriggerReference,\n} from '#core/providers/source-control.js';\nexport type {IntegrationSourceControlService} from '#core/source-control-service.js';\nexport {createSourceControlIntegrationService} from '#core/source-control-service.js';\nexport type {\n GetIntegrationConnectionByIdFn,\n GetIntegrationConnectionBySlugFn,\n} from '#db/connections.js';\nexport {getIntegrationConnectionById, getIntegrationConnectionBySlug} from '#db/connections.js';\nexport type {\n ClaimWebhookDeliveryFn,\n PublishIntegrationEventReceivedFn,\n PublishIntegrationEventReceivedParams,\n PublishIntegrationEventReceivedResult,\n PublishSourcePushFn,\n PublishSourcePushParams,\n PublishSourceRepositoryUpdatedFn,\n PublishSourceRepositoryUpdatedParams,\n RecordDeliveryOnlyFn,\n RecordDeliveryOnlyParams,\n} from '#db/webhook-deliveries.js';\nexport {\n claimWebhookDelivery,\n pruneWebhookDeliveries,\n publishSourceRepositoryUpdated,\n} from '#db/webhook-deliveries.js';\nexport {integrationRouteErrorHandler} from '#presentation/routes/errors.js';\n\nexport interface CreateIntegrationsModuleOptions {\n providers?: IntegrationProvider[] | undefined;\n /**\n * Pre-built module parts, bypassing config-gated provider loading. Test-only seam\n * for exercising a provider's database, workers, or startup tasks directly. Takes\n * precedence over `providers`.\n */\n parts?: IntegrationModuleParts[] | undefined;\n secrets?: IntegrationProviderSecrets | undefined;\n workspaces?: WorkspacesInterModuleClient | undefined;\n agentTools?:\n | {\n workflows: WorkflowsModuleClient;\n }\n | undefined;\n webhookDeliverySource?: WebhookDeliverySource | undefined;\n}\n\n/**\n * Hosted runtimes implement this port to receive stored webhook requests. The\n * integration module starts its returned service after migrations complete.\n */\nexport interface WebhookDeliverySource {\n createService(processor: WebhookRequestProcessor): ModuleService;\n}\n\nexport interface IntegrationsContext {\n module: ShipfoxModule;\n registry: IntegrationProviderRegistry;\n capabilities: {\n sourceControl: IntegrationSourceControlService;\n };\n sourceControl: IntegrationSourceControlService;\n webhookProcessor: WebhookRequestProcessor;\n /**\n * Runs every enabled provider's one-shot boot-time tasks, after modules are initialized\n * (migrations done). Failures are isolated and logged, never rethrown, so a provider task\n * can never gate API boot. No-op when no enabled provider contributes a task.\n */\n runStartupTasks: () => Promise<void>;\n}\n\nexport async function createIntegrationsModule(\n options: CreateIntegrationsModuleOptions = {},\n): Promise<ShipfoxModule> {\n return (await createIntegrationsContext(options)).module;\n}\n\nexport async function createIntegrationsContext(\n options: CreateIntegrationsModuleOptions = {},\n): Promise<IntegrationsContext> {\n const workspaces = options.workspaces;\n const parts: IntegrationModuleParts[] =\n options.parts ??\n (options.providers\n ? options.providers.map((provider) => ({\n provider,\n webhookProcessors: provider.webhookProcessors,\n }))\n : await loadEnabledProviderModules({\n secrets: options.secrets,\n ...(workspaces\n ? {\n requireActiveWorkspaceMembership: (input: {\n workspaceId: string;\n userId: string;\n memberships: ReadonlyArray<\n import('@shipfox/api-auth-context').UserContextMembership\n >;\n }) =>\n workspaces.requireActiveMembership({\n ...input,\n memberships: [...input.memberships],\n }),\n }\n : {}),\n }));\n\n const registry = createIntegrationProviderRegistry(parts.map((part) => part.provider));\n const sourceControl = createSourceControlIntegrationService({\n registry,\n getIntegrationConnectionById,\n });\n const webhookProcessor = createComposedWebhookProcessor(\n parts.flatMap((part) => part.webhookProcessors ?? []),\n );\n\n async function runStartupTasks(): Promise<void> {\n for (const task of parts.flatMap((part) => part.startupTasks ?? [])) {\n // A provider convenience must never gate API boot.\n try {\n await task();\n } catch (error) {\n logger().error({err: error}, 'Integration startup task failed, continuing boot');\n reportError(error, {boundary: 'integration.startup'});\n }\n }\n }\n\n const module: ShipfoxModule = {\n name: 'integrations',\n interModulePresentations: [\n createIntegrationsInterModulePresentation({registry, sourceControl}),\n ],\n startupTasks: runStartupTasks,\n database: [\n {db, migrationsPath, databaseNamespace: 'integrations'},\n ...parts.flatMap((part) => (part.database ? [part.database] : [])),\n ],\n routes: createIntegrationRoutes(registry, sourceControl, {\n agentTools: options.agentTools\n ? {\n workflows: options.agentTools.workflows,\n getIntegrationConnectionById,\n }\n : undefined,\n }),\n e2eRoutes: parts.flatMap((part) => part.e2eRoutes ?? []),\n publishers: [\n {name: 'integrations', table: integrationsOutbox, db, eventSchemas: integrationsEventSchemas},\n ],\n workers: [\n {\n taskQueue: INTEGRATIONS_MAINTENANCE_TASK_QUEUE,\n workflowsPath: maintenanceWorkflowsPath,\n activities: createIntegrationsMaintenanceActivities,\n workflows: [\n {\n name: 'pruneWebhookDeliveriesCron',\n id: 'integrations-prune-webhook-deliveries',\n cronSchedule: '0 3 * * *',\n },\n ],\n },\n ...parts.flatMap((part) => part.workers ?? []),\n ],\n ...(options.webhookDeliverySource\n ? {services: [options.webhookDeliverySource.createService(webhookProcessor)]}\n : {}),\n };\n\n return {\n module,\n registry,\n capabilities: {sourceControl},\n sourceControl,\n webhookProcessor,\n runStartupTasks,\n };\n}\n\nfunction createComposedWebhookProcessor(\n registrations: WebhookProcessorRegistration[],\n): WebhookRequestProcessor {\n const processors = new Map<WebhookRouteId, WebhookRequestProcessor>();\n for (const registration of registrations) {\n for (const routeId of registration.routeIds) {\n if (processors.has(routeId)) {\n throw new Error(`Webhook processor is registered more than once for ${routeId}`);\n }\n processors.set(routeId, registration.processor);\n }\n }\n\n return {\n async process(request: StoredWebhookRequest): Promise<WebhookProcessingResult> {\n const processor = processors.get(request.route_id);\n if (!processor) {\n throw new WebhookProcessorNotConfiguredError(request.route_id);\n }\n return await processor.process(request);\n },\n };\n}\n"],"names":["dirname","resolve","fileURLToPath","integrationsEventSchemas","reportError","logger","WebhookProcessorNotConfiguredError","createIntegrationProviderRegistry","createSourceControlIntegrationService","getIntegrationConnectionById","db","migrationsPath","integrationsOutbox","createIntegrationsInterModulePresentation","createIntegrationRoutes","loadEnabledProviderModules","createIntegrationsMaintenanceActivities","INTEGRATIONS_MAINTENANCE_TASK_QUEUE","packageRoot","url","maintenanceWorkflowsPath","buildProviderRepositoryId","MAX_REPOSITORY_FILE_BYTES","parseProviderRepositoryId","buildAgentToolCatalogs","buildAgentToolSelectionCatalogs","createWorkspaceConnectionSnapshotLoader","ConnectionSlugConflictError","IntegrationCapabilityUnavailableError","IntegrationCheckoutUnsupportedError","IntegrationConnectionInactiveError","IntegrationConnectionNotFoundError","IntegrationConnectionWorkspaceMismatchError","IntegrationProviderError","IntegrationProviderUnavailableError","redactCheckoutSpec","getIntegrationConnectionBySlug","claimWebhookDelivery","pruneWebhookDeliveries","publishSourceRepositoryUpdated","integrationRouteErrorHandler","createIntegrationsModule","options","createIntegrationsContext","module","workspaces","parts","providers","map","provider","webhookProcessors","secrets","requireActiveWorkspaceMembership","input","requireActiveMembership","memberships","registry","part","sourceControl","webhookProcessor","createComposedWebhookProcessor","flatMap","runStartupTasks","task","startupTasks","error","err","boundary","name","interModulePresentations","database","databaseNamespace","routes","agentTools","workflows","undefined","e2eRoutes","publishers","table","eventSchemas","workers","taskQueue","workflowsPath","activities","id","cronSchedule","webhookDeliverySource","services","createService","capabilities","registrations","processors","Map","registration","routeId","routeIds","has","Error","set","processor","process","request","get","route_id"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"inter-module.d.ts","sourceRoot":"","sources":["../../src/presentation/inter-module.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,+BAA+B,EAAC,MAAM,gDAAgD,CAAC;AAC/F,OAAO,EAIL,KAAK,uBAAuB,EAC7B,MAAM,uBAAuB,CAAC;AAe/B,OAAO,KAAK,EAAC,2BAA2B,EAAC,MAAM,6BAA6B,CAAC;AAC7E,OAAO,KAAK,EAAC,+BAA+B,EAAC,MAAM,iCAAiC,CAAC;AAGrF,wBAAgB,yCAAyC,CAAC,MAAM,EAAE;IAChE,QAAQ,EAAE,2BAA2B,CAAC;IACtC,aAAa,EAAE,+BAA+B,CAAC;CAChD,GAAG,uBAAuB,CAAC,OAAO,+BAA+B,CAAC,CA+ElE"}
1
+ {"version":3,"file":"inter-module.d.ts","sourceRoot":"","sources":["../../src/presentation/inter-module.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,+BAA+B,EAAC,MAAM,gDAAgD,CAAC;AAC/F,OAAO,EAIL,KAAK,uBAAuB,EAC7B,MAAM,uBAAuB,CAAC;AAe/B,OAAO,KAAK,EAAC,2BAA2B,EAAC,MAAM,6BAA6B,CAAC;AAC7E,OAAO,KAAK,EAAC,+BAA+B,EAAC,MAAM,iCAAiC,CAAC;AAGrF,wBAAgB,yCAAyC,CAAC,MAAM,EAAE;IAChE,QAAQ,EAAE,2BAA2B,CAAC;IACtC,aAAa,EAAE,+BAA+B,CAAC;CAChD,GAAG,uBAAuB,CAAC,OAAO,+BAA+B,CAAC,CAyFlE"}
@@ -2,7 +2,7 @@ import { integrationsInterModuleContract } from '@shipfox/api-integration-core-d
2
2
  import { createInterModuleKnownError, defineInterModulePresentation } from '@shipfox/inter-module';
3
3
  import { buildAgentToolCatalogs, buildAgentToolSelectionCatalogs, createWorkspaceConnectionSnapshotLoader } from '#core/agent-tool-selection.js';
4
4
  import { IntegrationCapabilityUnavailableError, IntegrationCheckoutUnsupportedError, IntegrationConnectionInactiveError, IntegrationConnectionNotFoundError, IntegrationConnectionWorkspaceMismatchError, IntegrationProviderError, IntegrationProviderUnavailableError } from '#core/errors.js';
5
- import { getIntegrationConnectionById } from '#db/connections.js';
5
+ import { getIntegrationConnectionById, getIntegrationConnectionBySlug } from '#db/connections.js';
6
6
  export function createIntegrationsInterModulePresentation(params) {
7
7
  const contract = integrationsInterModuleContract;
8
8
  return defineInterModulePresentation(contract, {
@@ -17,6 +17,15 @@ export function createIntegrationsInterModulePresentation(params) {
17
17
  repository: resolved.repository
18
18
  };
19
19
  }),
20
+ resolveConnection: async (input)=>{
21
+ const resolved = await getIntegrationConnectionBySlug(input);
22
+ return resolved ? {
23
+ id: resolved.id,
24
+ provider: resolved.provider,
25
+ slug: resolved.slug
26
+ } : null;
27
+ },
28
+ resolveTriggerReference: async (input)=>await known(contract.methods.resolveTriggerReference, input, async ()=>await params.sourceControl.resolveTriggerReference(input)),
20
29
  listSourceFiles: async (input)=>await known(contract.methods.listSourceFiles, input, async ()=>await params.sourceControl.listFiles(input)),
21
30
  fetchSourceFile: async (input)=>await known(contract.methods.fetchSourceFile, input, async ()=>await params.sourceControl.fetchFile(input)),
22
31
  createCheckoutSpec: async (input)=>await known(contract.methods.createCheckoutSpec, input, async ()=>{
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/presentation/inter-module.ts"],"sourcesContent":["import {integrationsInterModuleContract} from '@shipfox/api-integration-core-dto/inter-module';\nimport {\n createInterModuleKnownError,\n defineInterModulePresentation,\n type InterModuleMethodContract,\n type InterModulePresentation,\n} from '@shipfox/inter-module';\nimport {\n buildAgentToolCatalogs,\n buildAgentToolSelectionCatalogs,\n createWorkspaceConnectionSnapshotLoader,\n} from '#core/agent-tool-selection.js';\nimport {\n IntegrationCapabilityUnavailableError,\n IntegrationCheckoutUnsupportedError,\n IntegrationConnectionInactiveError,\n IntegrationConnectionNotFoundError,\n IntegrationConnectionWorkspaceMismatchError,\n IntegrationProviderError,\n IntegrationProviderUnavailableError,\n} from '#core/errors.js';\nimport type {IntegrationProviderRegistry} from '#core/providers/registry.js';\nimport type {IntegrationSourceControlService} from '#core/source-control-service.js';\nimport {getIntegrationConnectionById} from '#db/connections.js';\n\nexport function createIntegrationsInterModulePresentation(params: {\n registry: IntegrationProviderRegistry;\n sourceControl: IntegrationSourceControlService;\n}): InterModulePresentation<typeof integrationsInterModuleContract> {\n const contract = integrationsInterModuleContract;\n return defineInterModulePresentation(contract, {\n resolveSourceRepository: async (input) =>\n await known(contract.methods.resolveSourceRepository, input, async () => {\n const resolved = await params.sourceControl.resolveRepository(input);\n return {\n connection: {\n id: resolved.connection.id,\n provider: resolved.connection.provider,\n slug: resolved.connection.slug,\n },\n repository: resolved.repository,\n };\n }),\n listSourceFiles: async (input) =>\n await known(\n contract.methods.listSourceFiles,\n input,\n async () => await params.sourceControl.listFiles(input),\n ),\n fetchSourceFile: async (input) =>\n await known(\n contract.methods.fetchSourceFile,\n input,\n async () => await params.sourceControl.fetchFile(input),\n ),\n createCheckoutSpec: async (input) =>\n await known(contract.methods.createCheckoutSpec, input, async () => {\n const spec = await params.sourceControl.createCheckoutSpec(input);\n return {\n repositoryUrl: spec.repositoryUrl,\n ref: spec.ref,\n ...(spec.credentials\n ? {\n credentials: {\n ...spec.credentials,\n expiresAt: spec.credentials.expiresAt.toISOString(),\n },\n }\n : {}),\n ...(spec.gitAuthor === undefined ? {} : {gitAuthor: spec.gitAuthor}),\n };\n }),\n getAgentToolsContext: async (input) =>\n await known(contract.methods.getAgentToolsContext, input, async () => {\n const [selectionCatalogs, catalogs, snapshot, defaultConnection] = await Promise.all([\n buildAgentToolSelectionCatalogs(params.registry),\n buildAgentToolCatalogs(params.registry),\n createWorkspaceConnectionSnapshotLoader(params.registry)(input.workspaceId),\n getIntegrationConnectionById(input.defaultConnectionId),\n ]);\n return {\n selectionCatalogs: [...selectionCatalogs].map(([provider, value]) => ({\n provider,\n selectors: value.selectors.map((selector) => ({...selector})),\n })),\n catalogs: [...catalogs].map(([provider, tools]) => ({\n provider,\n tools: tools.map(({methods, ...tool}) => ({\n ...tool,\n ...(methods === undefined ? {} : {methods: methods.map((method) => ({...method}))}),\n })),\n })),\n workspaceConnections: [...snapshot].map(([slug, value]) => ({\n slug,\n ...value,\n capabilities: [...value.capabilities],\n })),\n defaultConnection: defaultConnection\n ? {\n id: defaultConnection.id,\n slug: defaultConnection.slug,\n provider: defaultConnection.provider,\n }\n : null,\n };\n }),\n });\n}\n\nasync function known<Output>(\n method: InterModuleMethodContract,\n input: {connectionId?: string; defaultConnectionId?: string},\n operation: () => Promise<Output>,\n): Promise<Output> {\n try {\n return await operation();\n } catch (error) {\n throw mapError(method, input, error);\n }\n}\nfunction mapError(\n method: InterModuleMethodContract,\n input: {connectionId?: string; defaultConnectionId?: string},\n error: unknown,\n): unknown {\n if (error instanceof IntegrationConnectionNotFoundError)\n return createInterModuleKnownError(method, 'connection-not-found', {\n connectionId: input.connectionId ?? input.defaultConnectionId,\n });\n if (error instanceof IntegrationConnectionInactiveError)\n return createInterModuleKnownError(method, 'connection-inactive', {\n connectionId: input.connectionId,\n });\n if (error instanceof IntegrationConnectionWorkspaceMismatchError)\n return createInterModuleKnownError(method, 'connection-workspace-mismatch', {\n connectionId: input.connectionId,\n });\n if (error instanceof IntegrationProviderUnavailableError)\n return createInterModuleKnownError(method, 'provider-unavailable', {provider: error.provider});\n if (error instanceof IntegrationCapabilityUnavailableError)\n return createInterModuleKnownError(method, 'capability-unavailable', {\n provider: error.provider,\n capability: error.capability,\n });\n if (error instanceof IntegrationCheckoutUnsupportedError)\n return createInterModuleKnownError(method, 'checkout-unsupported', {provider: error.provider});\n if (error instanceof IntegrationProviderError)\n return createInterModuleKnownError(method, 'provider-failure', {\n reason: error.reason,\n ...(error.retryAfterSeconds === undefined\n ? {}\n : {retryAfterSeconds: error.retryAfterSeconds}),\n });\n return error;\n}\n"],"names":["integrationsInterModuleContract","createInterModuleKnownError","defineInterModulePresentation","buildAgentToolCatalogs","buildAgentToolSelectionCatalogs","createWorkspaceConnectionSnapshotLoader","IntegrationCapabilityUnavailableError","IntegrationCheckoutUnsupportedError","IntegrationConnectionInactiveError","IntegrationConnectionNotFoundError","IntegrationConnectionWorkspaceMismatchError","IntegrationProviderError","IntegrationProviderUnavailableError","getIntegrationConnectionById","createIntegrationsInterModulePresentation","params","contract","resolveSourceRepository","input","known","methods","resolved","sourceControl","resolveRepository","connection","id","provider","slug","repository","listSourceFiles","listFiles","fetchSourceFile","fetchFile","createCheckoutSpec","spec","repositoryUrl","ref","credentials","expiresAt","toISOString","gitAuthor","undefined","getAgentToolsContext","selectionCatalogs","catalogs","snapshot","defaultConnection","Promise","all","registry","workspaceId","defaultConnectionId","map","value","selectors","selector","tools","tool","method","workspaceConnections","capabilities","operation","error","mapError","connectionId","capability","reason","retryAfterSeconds"],"mappings":"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"}
1
+ {"version":3,"sources":["../../src/presentation/inter-module.ts"],"sourcesContent":["import {integrationsInterModuleContract} from '@shipfox/api-integration-core-dto/inter-module';\nimport {\n createInterModuleKnownError,\n defineInterModulePresentation,\n type InterModuleMethodContract,\n type InterModulePresentation,\n} from '@shipfox/inter-module';\nimport {\n buildAgentToolCatalogs,\n buildAgentToolSelectionCatalogs,\n createWorkspaceConnectionSnapshotLoader,\n} from '#core/agent-tool-selection.js';\nimport {\n IntegrationCapabilityUnavailableError,\n IntegrationCheckoutUnsupportedError,\n IntegrationConnectionInactiveError,\n IntegrationConnectionNotFoundError,\n IntegrationConnectionWorkspaceMismatchError,\n IntegrationProviderError,\n IntegrationProviderUnavailableError,\n} from '#core/errors.js';\nimport type {IntegrationProviderRegistry} from '#core/providers/registry.js';\nimport type {IntegrationSourceControlService} from '#core/source-control-service.js';\nimport {getIntegrationConnectionById, getIntegrationConnectionBySlug} from '#db/connections.js';\n\nexport function createIntegrationsInterModulePresentation(params: {\n registry: IntegrationProviderRegistry;\n sourceControl: IntegrationSourceControlService;\n}): InterModulePresentation<typeof integrationsInterModuleContract> {\n const contract = integrationsInterModuleContract;\n return defineInterModulePresentation(contract, {\n resolveSourceRepository: async (input) =>\n await known(contract.methods.resolveSourceRepository, input, async () => {\n const resolved = await params.sourceControl.resolveRepository(input);\n return {\n connection: {\n id: resolved.connection.id,\n provider: resolved.connection.provider,\n slug: resolved.connection.slug,\n },\n repository: resolved.repository,\n };\n }),\n resolveConnection: async (input) => {\n const resolved = await getIntegrationConnectionBySlug(input);\n return resolved ? {id: resolved.id, provider: resolved.provider, slug: resolved.slug} : null;\n },\n resolveTriggerReference: async (input) =>\n await known(\n contract.methods.resolveTriggerReference,\n input,\n async () => await params.sourceControl.resolveTriggerReference(input),\n ),\n listSourceFiles: async (input) =>\n await known(\n contract.methods.listSourceFiles,\n input,\n async () => await params.sourceControl.listFiles(input),\n ),\n fetchSourceFile: async (input) =>\n await known(\n contract.methods.fetchSourceFile,\n input,\n async () => await params.sourceControl.fetchFile(input),\n ),\n createCheckoutSpec: async (input) =>\n await known(contract.methods.createCheckoutSpec, input, async () => {\n const spec = await params.sourceControl.createCheckoutSpec(input);\n return {\n repositoryUrl: spec.repositoryUrl,\n ref: spec.ref,\n ...(spec.credentials\n ? {\n credentials: {\n ...spec.credentials,\n expiresAt: spec.credentials.expiresAt.toISOString(),\n },\n }\n : {}),\n ...(spec.gitAuthor === undefined ? {} : {gitAuthor: spec.gitAuthor}),\n };\n }),\n getAgentToolsContext: async (input) =>\n await known(contract.methods.getAgentToolsContext, input, async () => {\n const [selectionCatalogs, catalogs, snapshot, defaultConnection] = await Promise.all([\n buildAgentToolSelectionCatalogs(params.registry),\n buildAgentToolCatalogs(params.registry),\n createWorkspaceConnectionSnapshotLoader(params.registry)(input.workspaceId),\n getIntegrationConnectionById(input.defaultConnectionId),\n ]);\n return {\n selectionCatalogs: [...selectionCatalogs].map(([provider, value]) => ({\n provider,\n selectors: value.selectors.map((selector) => ({...selector})),\n })),\n catalogs: [...catalogs].map(([provider, tools]) => ({\n provider,\n tools: tools.map(({methods, ...tool}) => ({\n ...tool,\n ...(methods === undefined ? {} : {methods: methods.map((method) => ({...method}))}),\n })),\n })),\n workspaceConnections: [...snapshot].map(([slug, value]) => ({\n slug,\n ...value,\n capabilities: [...value.capabilities],\n })),\n defaultConnection: defaultConnection\n ? {\n id: defaultConnection.id,\n slug: defaultConnection.slug,\n provider: defaultConnection.provider,\n }\n : null,\n };\n }),\n });\n}\n\nasync function known<Output>(\n method: InterModuleMethodContract,\n input: {connectionId?: string; defaultConnectionId?: string},\n operation: () => Promise<Output>,\n): Promise<Output> {\n try {\n return await operation();\n } catch (error) {\n throw mapError(method, input, error);\n }\n}\nfunction mapError(\n method: InterModuleMethodContract,\n input: {connectionId?: string; defaultConnectionId?: string},\n error: unknown,\n): unknown {\n if (error instanceof IntegrationConnectionNotFoundError)\n return createInterModuleKnownError(method, 'connection-not-found', {\n connectionId: input.connectionId ?? input.defaultConnectionId,\n });\n if (error instanceof IntegrationConnectionInactiveError)\n return createInterModuleKnownError(method, 'connection-inactive', {\n connectionId: input.connectionId,\n });\n if (error instanceof IntegrationConnectionWorkspaceMismatchError)\n return createInterModuleKnownError(method, 'connection-workspace-mismatch', {\n connectionId: input.connectionId,\n });\n if (error instanceof IntegrationProviderUnavailableError)\n return createInterModuleKnownError(method, 'provider-unavailable', {provider: error.provider});\n if (error instanceof IntegrationCapabilityUnavailableError)\n return createInterModuleKnownError(method, 'capability-unavailable', {\n provider: error.provider,\n capability: error.capability,\n });\n if (error instanceof IntegrationCheckoutUnsupportedError)\n return createInterModuleKnownError(method, 'checkout-unsupported', {provider: error.provider});\n if (error instanceof IntegrationProviderError)\n return createInterModuleKnownError(method, 'provider-failure', {\n reason: error.reason,\n ...(error.retryAfterSeconds === undefined\n ? {}\n : {retryAfterSeconds: error.retryAfterSeconds}),\n });\n return error;\n}\n"],"names":["integrationsInterModuleContract","createInterModuleKnownError","defineInterModulePresentation","buildAgentToolCatalogs","buildAgentToolSelectionCatalogs","createWorkspaceConnectionSnapshotLoader","IntegrationCapabilityUnavailableError","IntegrationCheckoutUnsupportedError","IntegrationConnectionInactiveError","IntegrationConnectionNotFoundError","IntegrationConnectionWorkspaceMismatchError","IntegrationProviderError","IntegrationProviderUnavailableError","getIntegrationConnectionById","getIntegrationConnectionBySlug","createIntegrationsInterModulePresentation","params","contract","resolveSourceRepository","input","known","methods","resolved","sourceControl","resolveRepository","connection","id","provider","slug","repository","resolveConnection","resolveTriggerReference","listSourceFiles","listFiles","fetchSourceFile","fetchFile","createCheckoutSpec","spec","repositoryUrl","ref","credentials","expiresAt","toISOString","gitAuthor","undefined","getAgentToolsContext","selectionCatalogs","catalogs","snapshot","defaultConnection","Promise","all","registry","workspaceId","defaultConnectionId","map","value","selectors","selector","tools","tool","method","workspaceConnections","capabilities","operation","error","mapError","connectionId","capability","reason","retryAfterSeconds"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"github.d.ts","sourceRoot":"","sources":["../../src/providers/github.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAEV,yBAAyB,EAE1B,MAAM,qBAAqB,CAAC;AA2H7B,eAAO,MAAM,oBAAoB,EAAE,yBAIlC,CAAC"}
1
+ {"version":3,"file":"github.d.ts","sourceRoot":"","sources":["../../src/providers/github.ts"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EAEV,yBAAyB,EAE1B,MAAM,qBAAqB,CAAC;AA4H7B,eAAO,MAAM,oBAAoB,EAAE,yBAIlC,CAAC"}
@@ -1,7 +1,7 @@
1
1
  import { config } from '#config.js';
2
2
  import { getIntegrationConnectionById, resolveUniqueConnectionSlug, upsertIntegrationConnection } from '#db/connections.js';
3
3
  import { db } from '#db/db.js';
4
- import { publishIntegrationEventReceived, publishSourcePush, recordDeliveryOnly } from '#db/webhook-deliveries.js';
4
+ import { publishIntegrationEventReceived, publishSourcePush, publishSourceRepositoryUpdated, recordDeliveryOnly } from '#db/webhook-deliveries.js';
5
5
  import { retryConnectionSlugCollision, slugifyConnectionSlug } from '#providers/connection-slug.js';
6
6
  async function loadGithubModuleParts(options = {}) {
7
7
  const { createGithubInstallationTokenProvider, createGithubE2eRoutes, encodeInstallationTokenEnvelope, createGithubIntegrationProvider, getGithubInstallationByInstallationId, githubInstallationTokenNamespace, db: githubDb, migrationsPath: githubMigrationsPath, upsertGithubInstallation } = await import('@shipfox/api-integration-github');
@@ -67,6 +67,7 @@ async function loadGithubModuleParts(options = {}) {
67
67
  getExistingGithubConnection,
68
68
  connectGithubInstallation,
69
69
  publishIntegrationEventReceived,
70
+ publishSourceRepositoryUpdated,
70
71
  publishSourcePush,
71
72
  recordDeliveryOnly,
72
73
  getIntegrationConnectionById,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/providers/github.ts"],"sourcesContent":["import type {ConnectGithubInstallationInput} from '@shipfox/api-integration-github';\nimport type {IntegrationConnection as CoreIntegrationConnection} from '@shipfox/api-integration-spi';\nimport {config} from '#config.js';\nimport {\n getIntegrationConnectionById,\n resolveUniqueConnectionSlug,\n upsertIntegrationConnection,\n} from '#db/connections.js';\nimport {db} from '#db/db.js';\nimport {\n publishIntegrationEventReceived,\n publishSourcePush,\n recordDeliveryOnly,\n} from '#db/webhook-deliveries.js';\nimport {retryConnectionSlugCollision, slugifyConnectionSlug} from '#providers/connection-slug.js';\nimport type {\n IntegrationModuleParts,\n IntegrationProviderModule,\n IntegrationProviderModuleLoadOptions,\n} from '#providers/types.js';\n\nasync function loadGithubModuleParts(\n options: IntegrationProviderModuleLoadOptions = {},\n): Promise<IntegrationModuleParts> {\n const {\n createGithubInstallationTokenProvider,\n createGithubE2eRoutes,\n encodeInstallationTokenEnvelope,\n createGithubIntegrationProvider,\n getGithubInstallationByInstallationId,\n githubInstallationTokenNamespace,\n db: githubDb,\n migrationsPath: githubMigrationsPath,\n upsertGithubInstallation,\n } = await import('@shipfox/api-integration-github');\n\n const tokenProvider = createGithubInstallationTokenProvider({\n getIntegrationConnectionById,\n secretStore: options.secrets?.github\n ? {\n read: async (workspaceId, installationId) =>\n (await options.secrets?.github?.getSecret({\n workspaceId,\n namespace: githubInstallationTokenNamespace(installationId),\n key: 'envelope',\n })) ?? null,\n write: async (workspaceId, installationId, envelope) => {\n await options.secrets?.github?.setSecrets({\n workspaceId,\n namespace: githubInstallationTokenNamespace(installationId),\n values: {envelope: encodeInstallationTokenEnvelope(envelope)},\n });\n },\n }\n : undefined,\n });\n\n async function getExistingGithubConnection(input: {\n installationId: string;\n }): Promise<CoreIntegrationConnection<'github'> | undefined> {\n const installation = await getGithubInstallationByInstallationId(input.installationId);\n if (!installation) return undefined;\n const connection = await getIntegrationConnectionById(installation.connectionId);\n if (!connection) return undefined;\n return connection as CoreIntegrationConnection<'github'>;\n }\n\n async function connectGithubInstallation(\n input: ConnectGithubInstallationInput,\n ): Promise<CoreIntegrationConnection<'github'>> {\n return await retryConnectionSlugCollision(() =>\n db().transaction(async (tx) => {\n const baseSlug = slugifyConnectionSlug(`github_${input.installation.accountLogin}`, {\n fallback: 'github',\n });\n const slug = await resolveUniqueConnectionSlug(\n {\n workspaceId: input.workspaceId,\n provider: 'github',\n externalAccountId: input.installationId,\n baseSlug,\n },\n {tx},\n );\n const connection = await upsertIntegrationConnection(\n {\n workspaceId: input.workspaceId,\n provider: 'github',\n externalAccountId: input.installationId,\n slug,\n displayName: input.displayName,\n lifecycleStatus: 'active',\n },\n {tx},\n );\n\n await upsertGithubInstallation(\n {\n connectionId: connection.id,\n ...input.installation,\n },\n {tx},\n );\n\n return connection as CoreIntegrationConnection<'github'>;\n }),\n );\n }\n\n const integrationProvider = createGithubIntegrationProvider({\n getExistingGithubConnection,\n connectGithubInstallation,\n publishIntegrationEventReceived,\n publishSourcePush,\n recordDeliveryOnly,\n getIntegrationConnectionById,\n coreDb: db,\n deleteSecrets: options.secrets?.deleteSecrets,\n agentTools: {tokenProvider},\n ...(options.requireActiveWorkspaceMembership\n ? {requireActiveWorkspaceMembership: options.requireActiveWorkspaceMembership}\n : {}),\n });\n\n return {\n provider: integrationProvider,\n webhookProcessors: integrationProvider.webhookProcessors,\n e2eRoutes: [\n createGithubE2eRoutes({\n getExistingGithubConnection,\n connectGithubInstallation,\n connectionCapabilities: ['source_control', 'agent_tools'],\n }),\n ],\n database: {\n db: githubDb,\n migrationsPath: githubMigrationsPath,\n databaseNamespace: 'integrations_github',\n },\n };\n}\n\nexport const githubProviderModule: IntegrationProviderModule = {\n id: 'github',\n enabled: config.INTEGRATIONS_ENABLE_GITHUB_PROVIDER,\n load: loadGithubModuleParts,\n};\n"],"names":["config","getIntegrationConnectionById","resolveUniqueConnectionSlug","upsertIntegrationConnection","db","publishIntegrationEventReceived","publishSourcePush","recordDeliveryOnly","retryConnectionSlugCollision","slugifyConnectionSlug","loadGithubModuleParts","options","createGithubInstallationTokenProvider","createGithubE2eRoutes","encodeInstallationTokenEnvelope","createGithubIntegrationProvider","getGithubInstallationByInstallationId","githubInstallationTokenNamespace","githubDb","migrationsPath","githubMigrationsPath","upsertGithubInstallation","tokenProvider","secretStore","secrets","github","read","workspaceId","installationId","getSecret","namespace","key","write","envelope","setSecrets","values","undefined","getExistingGithubConnection","input","installation","connection","connectionId","connectGithubInstallation","transaction","tx","baseSlug","accountLogin","fallback","slug","provider","externalAccountId","displayName","lifecycleStatus","id","integrationProvider","coreDb","deleteSecrets","agentTools","requireActiveWorkspaceMembership","webhookProcessors","e2eRoutes","connectionCapabilities","database","databaseNamespace","githubProviderModule","enabled","INTEGRATIONS_ENABLE_GITHUB_PROVIDER","load"],"mappings":"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"}
1
+ {"version":3,"sources":["../../src/providers/github.ts"],"sourcesContent":["import type {ConnectGithubInstallationInput} from '@shipfox/api-integration-github';\nimport type {IntegrationConnection as CoreIntegrationConnection} from '@shipfox/api-integration-spi';\nimport {config} from '#config.js';\nimport {\n getIntegrationConnectionById,\n resolveUniqueConnectionSlug,\n upsertIntegrationConnection,\n} from '#db/connections.js';\nimport {db} from '#db/db.js';\nimport {\n publishIntegrationEventReceived,\n publishSourcePush,\n publishSourceRepositoryUpdated,\n recordDeliveryOnly,\n} from '#db/webhook-deliveries.js';\nimport {retryConnectionSlugCollision, slugifyConnectionSlug} from '#providers/connection-slug.js';\nimport type {\n IntegrationModuleParts,\n IntegrationProviderModule,\n IntegrationProviderModuleLoadOptions,\n} from '#providers/types.js';\n\nasync function loadGithubModuleParts(\n options: IntegrationProviderModuleLoadOptions = {},\n): Promise<IntegrationModuleParts> {\n const {\n createGithubInstallationTokenProvider,\n createGithubE2eRoutes,\n encodeInstallationTokenEnvelope,\n createGithubIntegrationProvider,\n getGithubInstallationByInstallationId,\n githubInstallationTokenNamespace,\n db: githubDb,\n migrationsPath: githubMigrationsPath,\n upsertGithubInstallation,\n } = await import('@shipfox/api-integration-github');\n\n const tokenProvider = createGithubInstallationTokenProvider({\n getIntegrationConnectionById,\n secretStore: options.secrets?.github\n ? {\n read: async (workspaceId, installationId) =>\n (await options.secrets?.github?.getSecret({\n workspaceId,\n namespace: githubInstallationTokenNamespace(installationId),\n key: 'envelope',\n })) ?? null,\n write: async (workspaceId, installationId, envelope) => {\n await options.secrets?.github?.setSecrets({\n workspaceId,\n namespace: githubInstallationTokenNamespace(installationId),\n values: {envelope: encodeInstallationTokenEnvelope(envelope)},\n });\n },\n }\n : undefined,\n });\n\n async function getExistingGithubConnection(input: {\n installationId: string;\n }): Promise<CoreIntegrationConnection<'github'> | undefined> {\n const installation = await getGithubInstallationByInstallationId(input.installationId);\n if (!installation) return undefined;\n const connection = await getIntegrationConnectionById(installation.connectionId);\n if (!connection) return undefined;\n return connection as CoreIntegrationConnection<'github'>;\n }\n\n async function connectGithubInstallation(\n input: ConnectGithubInstallationInput,\n ): Promise<CoreIntegrationConnection<'github'>> {\n return await retryConnectionSlugCollision(() =>\n db().transaction(async (tx) => {\n const baseSlug = slugifyConnectionSlug(`github_${input.installation.accountLogin}`, {\n fallback: 'github',\n });\n const slug = await resolveUniqueConnectionSlug(\n {\n workspaceId: input.workspaceId,\n provider: 'github',\n externalAccountId: input.installationId,\n baseSlug,\n },\n {tx},\n );\n const connection = await upsertIntegrationConnection(\n {\n workspaceId: input.workspaceId,\n provider: 'github',\n externalAccountId: input.installationId,\n slug,\n displayName: input.displayName,\n lifecycleStatus: 'active',\n },\n {tx},\n );\n\n await upsertGithubInstallation(\n {\n connectionId: connection.id,\n ...input.installation,\n },\n {tx},\n );\n\n return connection as CoreIntegrationConnection<'github'>;\n }),\n );\n }\n\n const integrationProvider = createGithubIntegrationProvider({\n getExistingGithubConnection,\n connectGithubInstallation,\n publishIntegrationEventReceived,\n publishSourceRepositoryUpdated,\n publishSourcePush,\n recordDeliveryOnly,\n getIntegrationConnectionById,\n coreDb: db,\n deleteSecrets: options.secrets?.deleteSecrets,\n agentTools: {tokenProvider},\n ...(options.requireActiveWorkspaceMembership\n ? {requireActiveWorkspaceMembership: options.requireActiveWorkspaceMembership}\n : {}),\n });\n\n return {\n provider: integrationProvider,\n webhookProcessors: integrationProvider.webhookProcessors,\n e2eRoutes: [\n createGithubE2eRoutes({\n getExistingGithubConnection,\n connectGithubInstallation,\n connectionCapabilities: ['source_control', 'agent_tools'],\n }),\n ],\n database: {\n db: githubDb,\n migrationsPath: githubMigrationsPath,\n databaseNamespace: 'integrations_github',\n },\n };\n}\n\nexport const githubProviderModule: IntegrationProviderModule = {\n id: 'github',\n enabled: config.INTEGRATIONS_ENABLE_GITHUB_PROVIDER,\n load: loadGithubModuleParts,\n};\n"],"names":["config","getIntegrationConnectionById","resolveUniqueConnectionSlug","upsertIntegrationConnection","db","publishIntegrationEventReceived","publishSourcePush","publishSourceRepositoryUpdated","recordDeliveryOnly","retryConnectionSlugCollision","slugifyConnectionSlug","loadGithubModuleParts","options","createGithubInstallationTokenProvider","createGithubE2eRoutes","encodeInstallationTokenEnvelope","createGithubIntegrationProvider","getGithubInstallationByInstallationId","githubInstallationTokenNamespace","githubDb","migrationsPath","githubMigrationsPath","upsertGithubInstallation","tokenProvider","secretStore","secrets","github","read","workspaceId","installationId","getSecret","namespace","key","write","envelope","setSecrets","values","undefined","getExistingGithubConnection","input","installation","connection","connectionId","connectGithubInstallation","transaction","tx","baseSlug","accountLogin","fallback","slug","provider","externalAccountId","displayName","lifecycleStatus","id","integrationProvider","coreDb","deleteSecrets","agentTools","requireActiveWorkspaceMembership","webhookProcessors","e2eRoutes","connectionCapabilities","database","databaseNamespace","githubProviderModule","enabled","INTEGRATIONS_ENABLE_GITHUB_PROVIDER","load"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"jira.d.ts","sourceRoot":"","sources":["../../src/providers/jira.ts"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EAAyB,yBAAyB,EAAC,MAAM,qBAAqB,CAAC;AA+I3F,eAAO,MAAM,kBAAkB,EAAE,yBAIhC,CAAC"}
1
+ {"version":3,"file":"jira.d.ts","sourceRoot":"","sources":["../../src/providers/jira.ts"],"names":[],"mappings":"AAiBA,OAAO,KAAK,EAAyB,yBAAyB,EAAC,MAAM,qBAAqB,CAAC;AAwK3F,eAAO,MAAM,kBAAkB,EAAE,yBAIhC,CAAC"}
@@ -1,6 +1,7 @@
1
1
  import { config } from '#config.js';
2
2
  import { deleteIntegrationConnection, getIntegrationConnectionById, resolveUniqueConnectionSlug, updateIntegrationConnectionLifecycleStatus, upsertIntegrationConnection } from '#db/connections.js';
3
3
  import { db } from '#db/db.js';
4
+ import { publishIntegrationEventReceived, recordDeliveryOnly } from '#db/webhook-deliveries.js';
4
5
  import { retryConnectionSlugCollision, slugifyConnectionSlug } from '#providers/connection-slug.js';
5
6
  const JIRA_SECRETS_NAMESPACE_PREFIX = 'system/integrations/jira/';
6
7
  async function loadJiraModuleParts(options = {}) {
@@ -93,19 +94,41 @@ async function loadJiraModuleParts(options = {}) {
93
94
  const pendingStore = createJiraPendingSelectionStore({
94
95
  secrets
95
96
  });
97
+ const integrationProvider = createJiraIntegrationProvider({
98
+ routes: {
99
+ tokenStore,
100
+ pendingStore,
101
+ getExistingJiraConnection,
102
+ connectJiraInstallation,
103
+ disconnectJiraInstallation,
104
+ coreDb: db,
105
+ publishIntegrationEventReceived,
106
+ recordDeliveryOnly,
107
+ getIntegrationConnectionById,
108
+ markConnectionActive: async ({ connectionId, tx })=>{
109
+ await updateIntegrationConnectionLifecycleStatus({
110
+ id: connectionId,
111
+ lifecycleStatus: 'active'
112
+ }, tx === undefined ? {} : {
113
+ tx: tx
114
+ });
115
+ },
116
+ markConnectionError: async ({ connectionId, tx })=>{
117
+ await updateIntegrationConnectionLifecycleStatus({
118
+ id: connectionId,
119
+ lifecycleStatus: 'error'
120
+ }, tx === undefined ? {} : {
121
+ tx: tx
122
+ });
123
+ },
124
+ ...options.requireActiveWorkspaceMembership ? {
125
+ requireActiveWorkspaceMembership: options.requireActiveWorkspaceMembership
126
+ } : {}
127
+ }
128
+ });
96
129
  return {
97
- provider: createJiraIntegrationProvider({
98
- routes: {
99
- tokenStore,
100
- pendingStore,
101
- getExistingJiraConnection,
102
- connectJiraInstallation,
103
- disconnectJiraInstallation,
104
- ...options.requireActiveWorkspaceMembership ? {
105
- requireActiveWorkspaceMembership: options.requireActiveWorkspaceMembership
106
- } : {}
107
- }
108
- }),
130
+ provider: integrationProvider,
131
+ webhookProcessors: integrationProvider.webhookProcessors,
109
132
  database: {
110
133
  db: jiraDb,
111
134
  migrationsPath,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/providers/jira.ts"],"sourcesContent":["import type {\n ConnectJiraInstallationInput,\n JiraPendingSelectionSecretsStore,\n JiraSecretsStore,\n} from '@shipfox/api-integration-jira';\nimport type {IntegrationConnection as CoreIntegrationConnection} from '@shipfox/api-integration-spi';\nimport {config} from '#config.js';\nimport {\n deleteIntegrationConnection,\n getIntegrationConnectionById,\n resolveUniqueConnectionSlug,\n updateIntegrationConnectionLifecycleStatus,\n upsertIntegrationConnection,\n} from '#db/connections.js';\nimport {db} from '#db/db.js';\nimport {retryConnectionSlugCollision, slugifyConnectionSlug} from '#providers/connection-slug.js';\nimport type {IntegrationModuleParts, IntegrationProviderModule} from '#providers/types.js';\n\nconst JIRA_SECRETS_NAMESPACE_PREFIX = 'system/integrations/jira/';\ntype IntegrationDb = ReturnType<typeof db>;\ntype IntegrationTx = Parameters<Parameters<IntegrationDb['transaction']>[0]>[0];\n\nasync function loadJiraModuleParts(\n options: Parameters<IntegrationProviderModule['load']>[0] = {},\n): Promise<IntegrationModuleParts> {\n const {\n createJiraIntegrationProvider,\n createJiraPendingSelectionStore,\n createJiraTokenStore,\n db: jiraDb,\n disconnectJiraInstallation: disconnectJiraInstallationRecords,\n getJiraInstallationByCloudId,\n migrationsPath,\n upsertJiraInstallation,\n } = await import('@shipfox/api-integration-jira');\n\n async function getExistingJiraConnection(input: {\n cloudId: string;\n }): Promise<CoreIntegrationConnection<'jira'> | undefined> {\n const installation = await getJiraInstallationByCloudId(input.cloudId);\n if (!installation) return undefined;\n return (await getIntegrationConnectionById(installation.connectionId)) as\n | CoreIntegrationConnection<'jira'>\n | undefined;\n }\n\n function connectJiraInstallation(\n input: ConnectJiraInstallationInput,\n ): Promise<CoreIntegrationConnection<'jira'>> {\n return retryConnectionSlugCollision(() =>\n db().transaction(async (tx) => {\n const slug = await resolveUniqueConnectionSlug(\n {\n workspaceId: input.workspaceId,\n provider: 'jira',\n externalAccountId: input.cloudId,\n baseSlug: slugifyConnectionSlug(`jira_${input.siteName || input.cloudId}`, {\n fallback: 'jira',\n }),\n },\n {tx},\n );\n const connection = await upsertIntegrationConnection(\n {\n workspaceId: input.workspaceId,\n provider: 'jira',\n externalAccountId: input.cloudId,\n slug,\n displayName: input.displayName,\n lifecycleStatus: 'active',\n },\n {tx},\n );\n await upsertJiraInstallation(\n {\n connectionId: connection.id,\n cloudId: input.cloudId,\n siteUrl: input.siteUrl,\n siteName: input.siteName,\n authorizingAccountId: input.authorizingAccountId,\n scopes: input.scopes,\n status: 'installed',\n tokenExpiresAt: input.tokenExpiresAt,\n },\n {tx},\n );\n return connection as CoreIntegrationConnection<'jira'>;\n }),\n );\n }\n\n async function disconnectJiraInstallation(input: {connectionId: string}): Promise<void> {\n await disconnectJiraInstallationRecords<IntegrationTx>({\n connectionId: input.connectionId,\n getConnection: getIntegrationConnectionById,\n deleteSecrets: (params) =>\n options.secrets?.jira?.deleteSecrets({\n ...params,\n namespace: jiraNamespaceSuffix(params.namespace),\n }) ?? Promise.resolve(0),\n transaction: (fn) => db().transaction((tx) => fn(tx)),\n deleteConnection: (params, transactionOptions) =>\n deleteIntegrationConnection({id: params.connectionId}, transactionOptions),\n });\n }\n\n const fallbackSecrets: JiraSecretsStore & JiraPendingSelectionSecretsStore = {\n getSecret: () => Promise.resolve(null),\n setSecrets: () => Promise.reject(new Error('Jira token storage is not configured')),\n deleteSecrets: () => Promise.resolve(0),\n };\n const secrets: JiraSecretsStore & JiraPendingSelectionSecretsStore = options.secrets?.jira\n ? {\n getSecret: (params) =>\n options.secrets?.jira?.getSecret({\n ...params,\n namespace: jiraNamespaceSuffix(params.namespace),\n }) ?? Promise.resolve(null),\n setSecrets: (params) =>\n options.secrets?.jira?.setSecrets({\n ...params,\n namespace: jiraNamespaceSuffix(params.namespace),\n }) ?? Promise.resolve(),\n deleteSecrets: (params) =>\n options.secrets?.jira?.deleteSecrets({\n ...params,\n namespace: jiraNamespaceSuffix(params.namespace),\n }) ?? Promise.resolve(0),\n }\n : fallbackSecrets;\n const tokenStore = createJiraTokenStore({\n resolveConnection: getIntegrationConnectionById,\n secrets,\n markConnectionError: async ({connectionId}) => {\n await updateIntegrationConnectionLifecycleStatus({\n id: connectionId,\n lifecycleStatus: 'error',\n });\n },\n });\n const pendingStore = createJiraPendingSelectionStore({secrets});\n\n return {\n provider: createJiraIntegrationProvider({\n routes: {\n tokenStore,\n pendingStore,\n getExistingJiraConnection,\n connectJiraInstallation,\n disconnectJiraInstallation,\n ...(options.requireActiveWorkspaceMembership\n ? {requireActiveWorkspaceMembership: options.requireActiveWorkspaceMembership}\n : {}),\n },\n }),\n database: {db: jiraDb, migrationsPath, databaseNamespace: 'integrations_jira'},\n };\n}\n\nexport const jiraProviderModule: IntegrationProviderModule = {\n id: 'jira',\n enabled: config.INTEGRATIONS_ENABLE_JIRA_PROVIDER,\n load: loadJiraModuleParts,\n};\n\nfunction jiraNamespaceSuffix(namespace: string): string {\n if (!namespace.startsWith(JIRA_SECRETS_NAMESPACE_PREFIX)) {\n throw new Error('Jira provider attempted to access an unscoped secret namespace');\n }\n return namespace.slice(JIRA_SECRETS_NAMESPACE_PREFIX.length);\n}\n"],"names":["config","deleteIntegrationConnection","getIntegrationConnectionById","resolveUniqueConnectionSlug","updateIntegrationConnectionLifecycleStatus","upsertIntegrationConnection","db","retryConnectionSlugCollision","slugifyConnectionSlug","JIRA_SECRETS_NAMESPACE_PREFIX","loadJiraModuleParts","options","createJiraIntegrationProvider","createJiraPendingSelectionStore","createJiraTokenStore","jiraDb","disconnectJiraInstallation","disconnectJiraInstallationRecords","getJiraInstallationByCloudId","migrationsPath","upsertJiraInstallation","getExistingJiraConnection","input","installation","cloudId","undefined","connectionId","connectJiraInstallation","transaction","tx","slug","workspaceId","provider","externalAccountId","baseSlug","siteName","fallback","connection","displayName","lifecycleStatus","id","siteUrl","authorizingAccountId","scopes","status","tokenExpiresAt","getConnection","deleteSecrets","params","secrets","jira","namespace","jiraNamespaceSuffix","Promise","resolve","fn","deleteConnection","transactionOptions","fallbackSecrets","getSecret","setSecrets","reject","Error","tokenStore","resolveConnection","markConnectionError","pendingStore","routes","requireActiveWorkspaceMembership","database","databaseNamespace","jiraProviderModule","enabled","INTEGRATIONS_ENABLE_JIRA_PROVIDER","load","startsWith","slice","length"],"mappings":"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"}
1
+ {"version":3,"sources":["../../src/providers/jira.ts"],"sourcesContent":["import type {\n ConnectJiraInstallationInput,\n JiraPendingSelectionSecretsStore,\n JiraSecretsStore,\n} from '@shipfox/api-integration-jira';\nimport type {IntegrationConnection as CoreIntegrationConnection} from '@shipfox/api-integration-spi';\nimport {config} from '#config.js';\nimport {\n deleteIntegrationConnection,\n getIntegrationConnectionById,\n resolveUniqueConnectionSlug,\n updateIntegrationConnectionLifecycleStatus,\n upsertIntegrationConnection,\n} from '#db/connections.js';\nimport {db} from '#db/db.js';\nimport {publishIntegrationEventReceived, recordDeliveryOnly} from '#db/webhook-deliveries.js';\nimport {retryConnectionSlugCollision, slugifyConnectionSlug} from '#providers/connection-slug.js';\nimport type {IntegrationModuleParts, IntegrationProviderModule} from '#providers/types.js';\n\nconst JIRA_SECRETS_NAMESPACE_PREFIX = 'system/integrations/jira/';\ntype IntegrationDb = ReturnType<typeof db>;\ntype IntegrationTx = Parameters<Parameters<IntegrationDb['transaction']>[0]>[0];\n\nasync function loadJiraModuleParts(\n options: Parameters<IntegrationProviderModule['load']>[0] = {},\n): Promise<IntegrationModuleParts> {\n const {\n createJiraIntegrationProvider,\n createJiraPendingSelectionStore,\n createJiraTokenStore,\n db: jiraDb,\n disconnectJiraInstallation: disconnectJiraInstallationRecords,\n getJiraInstallationByCloudId,\n migrationsPath,\n upsertJiraInstallation,\n } = await import('@shipfox/api-integration-jira');\n\n async function getExistingJiraConnection(input: {\n cloudId: string;\n }): Promise<CoreIntegrationConnection<'jira'> | undefined> {\n const installation = await getJiraInstallationByCloudId(input.cloudId);\n if (!installation) return undefined;\n return (await getIntegrationConnectionById(installation.connectionId)) as\n | CoreIntegrationConnection<'jira'>\n | undefined;\n }\n\n function connectJiraInstallation(\n input: ConnectJiraInstallationInput,\n ): Promise<CoreIntegrationConnection<'jira'>> {\n return retryConnectionSlugCollision(() =>\n db().transaction(async (tx) => {\n const slug = await resolveUniqueConnectionSlug(\n {\n workspaceId: input.workspaceId,\n provider: 'jira',\n externalAccountId: input.cloudId,\n baseSlug: slugifyConnectionSlug(`jira_${input.siteName || input.cloudId}`, {\n fallback: 'jira',\n }),\n },\n {tx},\n );\n const connection = await upsertIntegrationConnection(\n {\n workspaceId: input.workspaceId,\n provider: 'jira',\n externalAccountId: input.cloudId,\n slug,\n displayName: input.displayName,\n lifecycleStatus: 'active',\n },\n {tx},\n );\n await upsertJiraInstallation(\n {\n connectionId: connection.id,\n cloudId: input.cloudId,\n siteUrl: input.siteUrl,\n siteName: input.siteName,\n authorizingAccountId: input.authorizingAccountId,\n scopes: input.scopes,\n status: 'installed',\n tokenExpiresAt: input.tokenExpiresAt,\n },\n {tx},\n );\n return connection as CoreIntegrationConnection<'jira'>;\n }),\n );\n }\n\n async function disconnectJiraInstallation(input: {connectionId: string}): Promise<void> {\n await disconnectJiraInstallationRecords<IntegrationTx>({\n connectionId: input.connectionId,\n getConnection: getIntegrationConnectionById,\n deleteSecrets: (params) =>\n options.secrets?.jira?.deleteSecrets({\n ...params,\n namespace: jiraNamespaceSuffix(params.namespace),\n }) ?? Promise.resolve(0),\n transaction: (fn) => db().transaction((tx) => fn(tx)),\n deleteConnection: (params, transactionOptions) =>\n deleteIntegrationConnection({id: params.connectionId}, transactionOptions),\n });\n }\n\n const fallbackSecrets: JiraSecretsStore & JiraPendingSelectionSecretsStore = {\n getSecret: () => Promise.resolve(null),\n setSecrets: () => Promise.reject(new Error('Jira token storage is not configured')),\n deleteSecrets: () => Promise.resolve(0),\n };\n const secrets: JiraSecretsStore & JiraPendingSelectionSecretsStore = options.secrets?.jira\n ? {\n getSecret: (params) =>\n options.secrets?.jira?.getSecret({\n ...params,\n namespace: jiraNamespaceSuffix(params.namespace),\n }) ?? Promise.resolve(null),\n setSecrets: (params) =>\n options.secrets?.jira?.setSecrets({\n ...params,\n namespace: jiraNamespaceSuffix(params.namespace),\n }) ?? Promise.resolve(),\n deleteSecrets: (params) =>\n options.secrets?.jira?.deleteSecrets({\n ...params,\n namespace: jiraNamespaceSuffix(params.namespace),\n }) ?? Promise.resolve(0),\n }\n : fallbackSecrets;\n const tokenStore = createJiraTokenStore({\n resolveConnection: getIntegrationConnectionById,\n secrets,\n markConnectionError: async ({connectionId}) => {\n await updateIntegrationConnectionLifecycleStatus({\n id: connectionId,\n lifecycleStatus: 'error',\n });\n },\n });\n const pendingStore = createJiraPendingSelectionStore({secrets});\n\n const integrationProvider = createJiraIntegrationProvider({\n routes: {\n tokenStore,\n pendingStore,\n getExistingJiraConnection,\n connectJiraInstallation,\n disconnectJiraInstallation,\n coreDb: db,\n publishIntegrationEventReceived,\n recordDeliveryOnly,\n getIntegrationConnectionById,\n markConnectionActive: async ({connectionId, tx}) => {\n await updateIntegrationConnectionLifecycleStatus(\n {\n id: connectionId,\n lifecycleStatus: 'active',\n },\n tx === undefined ? {} : {tx: tx as IntegrationTx},\n );\n },\n markConnectionError: async ({connectionId, tx}) => {\n await updateIntegrationConnectionLifecycleStatus(\n {\n id: connectionId,\n lifecycleStatus: 'error',\n },\n tx === undefined ? {} : {tx: tx as IntegrationTx},\n );\n },\n ...(options.requireActiveWorkspaceMembership\n ? {requireActiveWorkspaceMembership: options.requireActiveWorkspaceMembership}\n : {}),\n },\n });\n\n return {\n provider: integrationProvider,\n webhookProcessors: integrationProvider.webhookProcessors,\n database: {db: jiraDb, migrationsPath, databaseNamespace: 'integrations_jira'},\n };\n}\n\nexport const jiraProviderModule: IntegrationProviderModule = {\n id: 'jira',\n enabled: config.INTEGRATIONS_ENABLE_JIRA_PROVIDER,\n load: loadJiraModuleParts,\n};\n\nfunction jiraNamespaceSuffix(namespace: string): string {\n if (!namespace.startsWith(JIRA_SECRETS_NAMESPACE_PREFIX)) {\n throw new Error('Jira provider attempted to access an unscoped secret namespace');\n }\n return namespace.slice(JIRA_SECRETS_NAMESPACE_PREFIX.length);\n}\n"],"names":["config","deleteIntegrationConnection","getIntegrationConnectionById","resolveUniqueConnectionSlug","updateIntegrationConnectionLifecycleStatus","upsertIntegrationConnection","db","publishIntegrationEventReceived","recordDeliveryOnly","retryConnectionSlugCollision","slugifyConnectionSlug","JIRA_SECRETS_NAMESPACE_PREFIX","loadJiraModuleParts","options","createJiraIntegrationProvider","createJiraPendingSelectionStore","createJiraTokenStore","jiraDb","disconnectJiraInstallation","disconnectJiraInstallationRecords","getJiraInstallationByCloudId","migrationsPath","upsertJiraInstallation","getExistingJiraConnection","input","installation","cloudId","undefined","connectionId","connectJiraInstallation","transaction","tx","slug","workspaceId","provider","externalAccountId","baseSlug","siteName","fallback","connection","displayName","lifecycleStatus","id","siteUrl","authorizingAccountId","scopes","status","tokenExpiresAt","getConnection","deleteSecrets","params","secrets","jira","namespace","jiraNamespaceSuffix","Promise","resolve","fn","deleteConnection","transactionOptions","fallbackSecrets","getSecret","setSecrets","reject","Error","tokenStore","resolveConnection","markConnectionError","pendingStore","integrationProvider","routes","coreDb","markConnectionActive","requireActiveWorkspaceMembership","webhookProcessors","database","databaseNamespace","jiraProviderModule","enabled","INTEGRATIONS_ENABLE_JIRA_PROVIDER","load","startsWith","slice","length"],"mappings":"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"}
@@ -9,7 +9,7 @@ import type { IntegrationProvider } from '#core/entities/provider.js';
9
9
  * and one-shot boot-time tasks. Providers that own none of these simply omit them.
10
10
  *
11
11
  * A startup task is run once after modules are initialized (migrations done). The
12
- * provider owns its own wiring core runs each task generically and isolates
12
+ * provider owns its own wiring: core runs each task generically and isolates
13
13
  * failures so a task can never gate API boot.
14
14
  */
15
15
  export interface IntegrationModuleParts {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/providers/types.ts"],"sourcesContent":["import type {UserContextMembership} from '@shipfox/api-auth-context';\nimport type {WebhookRequestProcessor, WebhookRouteId} from '@shipfox/api-integration-spi';\nimport type {RouteExport} from '@shipfox/node-fastify';\nimport type {ModuleDatabase, ModuleWorker} from '@shipfox/node-module';\nimport type {IntegrationProvider} from '#core/entities/provider.js';\n\n/**\n * Everything one integration contributes to the composed integrations module:\n * a registry provider, plus an optional dedicated database, background workers,\n * and one-shot boot-time tasks. Providers that own none of these simply omit them.\n *\n * A startup task is run once after modules are initialized (migrations done). The\n * provider owns its own wiring core runs each task generically and isolates\n * failures so a task can never gate API boot.\n */\nexport interface IntegrationModuleParts {\n provider: IntegrationProvider;\n database?: ModuleDatabase | undefined;\n e2eRoutes?: RouteExport[] | undefined;\n workers?: ModuleWorker[] | undefined;\n startupTasks?: Array<() => Promise<void>> | undefined;\n webhookProcessors?: WebhookProcessorRegistration[] | undefined;\n}\n\nexport interface WebhookProcessorRegistration {\n routeIds: readonly WebhookRouteId[];\n processor: WebhookRequestProcessor;\n}\n\n/**\n * A config-gated integration, registered once in `providerModules`. `load` is\n * called lazily and only when `enabled`, so a disabled provider never imports\n * its (potentially heavy) implementation package.\n */\nexport interface IntegrationProviderModule {\n id: string;\n enabled: boolean;\n load(options?: IntegrationProviderModuleLoadOptions): Promise<IntegrationModuleParts>;\n}\n\nexport interface IntegrationProviderModuleLoadOptions {\n secrets?: IntegrationProviderSecrets | undefined;\n requireActiveWorkspaceMembership?:\n | ((input: {\n workspaceId: string;\n userId: string;\n memberships: ReadonlyArray<UserContextMembership>;\n }) => Promise<unknown>)\n | undefined;\n}\n\nexport interface IntegrationProviderSecrets {\n github?: IntegrationProviderScopedSecrets | undefined;\n jira?: IntegrationProviderScopedSecrets | undefined;\n linear?: IntegrationProviderScopedSecrets | undefined;\n slack?: IntegrationProviderScopedSecrets | undefined;\n deleteSecrets(params: {workspaceId: string; namespace: string}): Promise<number>;\n}\n\nexport interface IntegrationProviderScopedSecrets {\n getSecret(params: {workspaceId: string; namespace: string; key: string}): Promise<string | null>;\n setSecrets(params: {\n workspaceId: string;\n namespace: string;\n values: Record<string, string>;\n editedBy?: string | null | undefined;\n }): Promise<void>;\n deleteSecrets(params: {workspaceId: string; namespace: string}): Promise<number>;\n}\n"],"names":[],"mappings":"AA2DA,WASC"}
1
+ {"version":3,"sources":["../../src/providers/types.ts"],"sourcesContent":["import type {UserContextMembership} from '@shipfox/api-auth-context';\nimport type {WebhookRequestProcessor, WebhookRouteId} from '@shipfox/api-integration-spi';\nimport type {RouteExport} from '@shipfox/node-fastify';\nimport type {ModuleDatabase, ModuleWorker} from '@shipfox/node-module';\nimport type {IntegrationProvider} from '#core/entities/provider.js';\n\n/**\n * Everything one integration contributes to the composed integrations module:\n * a registry provider, plus an optional dedicated database, background workers,\n * and one-shot boot-time tasks. Providers that own none of these simply omit them.\n *\n * A startup task is run once after modules are initialized (migrations done). The\n * provider owns its own wiring: core runs each task generically and isolates\n * failures so a task can never gate API boot.\n */\nexport interface IntegrationModuleParts {\n provider: IntegrationProvider;\n database?: ModuleDatabase | undefined;\n e2eRoutes?: RouteExport[] | undefined;\n workers?: ModuleWorker[] | undefined;\n startupTasks?: Array<() => Promise<void>> | undefined;\n webhookProcessors?: WebhookProcessorRegistration[] | undefined;\n}\n\nexport interface WebhookProcessorRegistration {\n routeIds: readonly WebhookRouteId[];\n processor: WebhookRequestProcessor;\n}\n\n/**\n * A config-gated integration, registered once in `providerModules`. `load` is\n * called lazily and only when `enabled`, so a disabled provider never imports\n * its (potentially heavy) implementation package.\n */\nexport interface IntegrationProviderModule {\n id: string;\n enabled: boolean;\n load(options?: IntegrationProviderModuleLoadOptions): Promise<IntegrationModuleParts>;\n}\n\nexport interface IntegrationProviderModuleLoadOptions {\n secrets?: IntegrationProviderSecrets | undefined;\n requireActiveWorkspaceMembership?:\n | ((input: {\n workspaceId: string;\n userId: string;\n memberships: ReadonlyArray<UserContextMembership>;\n }) => Promise<unknown>)\n | undefined;\n}\n\nexport interface IntegrationProviderSecrets {\n github?: IntegrationProviderScopedSecrets | undefined;\n jira?: IntegrationProviderScopedSecrets | undefined;\n linear?: IntegrationProviderScopedSecrets | undefined;\n slack?: IntegrationProviderScopedSecrets | undefined;\n deleteSecrets(params: {workspaceId: string; namespace: string}): Promise<number>;\n}\n\nexport interface IntegrationProviderScopedSecrets {\n getSecret(params: {workspaceId: string; namespace: string; key: string}): Promise<string | null>;\n setSecrets(params: {\n workspaceId: string;\n namespace: string;\n values: Record<string, string>;\n editedBy?: string | null | undefined;\n }): Promise<void>;\n deleteSecrets(params: {workspaceId: string; namespace: string}): Promise<number>;\n}\n"],"names":[],"mappings":"AA2DA,WASC"}