@shipfox/api-integration-core 11.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.
Files changed (53) hide show
  1. package/.turbo/turbo-build.log +4 -4
  2. package/CHANGELOG.md +73 -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 +44 -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 +5 -0
  49. package/src/providers/jira.ts +45 -11
  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
@@ -1,6 +1,6 @@
1
1
  $ shipfox-swc && shipfox-temporal-bundle dist/temporal/workflows/index.js
2
- Successfully compiled: 50 files with swc (442.31ms)
3
- 2026-07-28T22:46:09.761Z [INFO] asset workflow-bundle-646aca428e9943f8cf17.js 3.17 MiB [emitted] [immutable] (name: main)
2
+ Successfully compiled: 50 files with swc (284.31ms)
3
+ 2026-08-04T14:51:43.676Z [INFO] asset workflow-bundle-646aca428e9943f8cf17.js 3.17 MiB [emitted] [immutable] (name: main)
4
4
  orphan modules 33.5 KiB [orphan] 21 modules
5
5
  runtime modules 1.13 KiB 5 modules
6
6
  modules by path ../../../../node_modules/.pnpm/ 970 KiB 196 modules
@@ -12,6 +12,6 @@ optional modules 30 bytes [optional]
12
12
  __temporal_custom_payload_converter (ignored) 15 bytes [optional] [built] [code generated]
13
13
  __temporal_custom_failure_converter (ignored) 15 bytes [optional] [built] [code generated]
14
14
  ../../../shared/node/temporal/dist/workflow-error-interceptor.js 1.21 KiB [built] [code generated]
15
- webpack 5.107.2 compiled successfully in 8531 ms
16
- 2026-07-28T22:46:09.772Z [INFO] Workflow bundle created { size: '3.17MB' }
15
+ webpack 5.107.2 compiled successfully in 5477 ms
16
+ 2026-08-04T14:51:43.698Z [INFO] Workflow bundle created { size: '3.17MB' }
17
17
  /home/runner/work/shipfox/shipfox/libs/api/integration/core/dist/temporal/workflows/index.js: 3323154 bytes
package/CHANGELOG.md CHANGED
@@ -1,5 +1,78 @@
1
1
  # @shipfox/api-integration-core
2
2
 
3
+ ## 12.1.0
4
+
5
+ ### Patch Changes
6
+
7
+ - 70e33c0: Adds the in-process Jira REST agent-tool catalog and write-selection support.
8
+ - Updated dependencies [70e33c0]
9
+ - Updated dependencies [312a137]
10
+ - Updated dependencies [af7adfc]
11
+ - @shipfox/api-integration-jira@12.1.0
12
+ - @shipfox/api-workflows-dto@12.1.0
13
+
14
+ ## 12.0.0
15
+
16
+ ### Minor Changes
17
+
18
+ - 032d316: Scope checkout credential minting to the currently running checkout step and return its fetch depth.
19
+
20
+ ### Patch Changes
21
+
22
+ - f78740d: Remove Unicode dash punctuation from package prose and source comments.
23
+ - 24ef475: Adds provider-normalized repository, ref, and commit extraction for source-control trigger payloads.
24
+ - f13e8bb: Add Jira dynamic webhook registration and authenticated event ingestion through
25
+ the shared stored-webhook workflow. Update the SPI webhook request exports and
26
+ serialize Jira installation replacement across API replicas. Preserve Jira
27
+ delivery identifiers and require lifecycle callbacks for registration. Remove
28
+ the unused Jira webhook signing-secret configuration and allow HS256 verification
29
+ at a supplied receipt time.
30
+ - 869a792: Refresh source-backed project repository identity from GitHub repository and installation-repository events.
31
+ - cb0abfa: Expose the normalized trigger project, repository, ref, and commit in workflow context.
32
+ - Updated dependencies [ee2ce67]
33
+ - Updated dependencies [f7939c7]
34
+ - Updated dependencies [f78740d]
35
+ - Updated dependencies [9dffe58]
36
+ - Updated dependencies [a018f92]
37
+ - Updated dependencies [dea1ffd]
38
+ - Updated dependencies [adf07e7]
39
+ - Updated dependencies [94aba88]
40
+ - Updated dependencies [24ef475]
41
+ - Updated dependencies [285fff2]
42
+ - Updated dependencies [e44a279]
43
+ - Updated dependencies [28daafe]
44
+ - Updated dependencies [f13e8bb]
45
+ - Updated dependencies [9ebc5b4]
46
+ - Updated dependencies [869a792]
47
+ - Updated dependencies [54c820e]
48
+ - Updated dependencies [35a42bd]
49
+ - Updated dependencies [d77baaa]
50
+ - Updated dependencies [032d316]
51
+ - Updated dependencies [c2a8e54]
52
+ - Updated dependencies [54c820e]
53
+ - Updated dependencies [cb0abfa]
54
+ - Updated dependencies [e1efaee]
55
+ - @shipfox/api-workflows-dto@12.0.0
56
+ - @shipfox/api-agent-dto@12.0.0
57
+ - @shipfox/api-integration-github@12.0.0
58
+ - @shipfox/api-integration-sentry@12.0.0
59
+ - @shipfox/api-integration-slack@12.0.0
60
+ - @shipfox/inter-module@0.2.3
61
+ - @shipfox/node-fastify@0.4.1
62
+ - @shipfox/node-module@1.0.5
63
+ - @shipfox/redact@0.2.6
64
+ - @shipfox/api-integration-linear@12.0.0
65
+ - @shipfox/api-workspaces-dto@12.0.0
66
+ - @shipfox/api-integration-spi@1.0.0
67
+ - @shipfox/api-integration-gitea@12.0.0
68
+ - @shipfox/api-integration-core-dto@12.0.0
69
+ - @shipfox/api-integration-jira@12.0.0
70
+ - @shipfox/node-postgres@0.5.0
71
+ - @shipfox/api-auth-context@12.0.0
72
+ - @shipfox/api-integration-webhook@12.0.0
73
+ - @shipfox/node-drizzle@0.3.5
74
+ - @shipfox/node-outbox@0.2.6
75
+
3
76
  ## 11.0.0
4
77
 
5
78
  ### Patch Changes
@@ -1,2 +1,2 @@
1
- export type { CheckoutCredentials, CheckoutPermissions, CheckoutSpec, CreateCheckoutSpecInput, FetchFileInput, FileEntry, FilePage, FileSnapshot, ListFilesInput, ListRepositoriesInput, RepositoryPage, RepositorySnapshot, RepositoryVisibility, ResolveRepositoryInput, SourceControlProvider, } from '@shipfox/api-integration-spi';
1
+ export type { CheckoutCredentials, CheckoutPermissions, CheckoutSpec, CreateCheckoutSpecInput, FetchFileInput, FileEntry, FilePage, FileSnapshot, ListFilesInput, ListRepositoriesInput, RepositoryPage, RepositorySnapshot, RepositoryVisibility, ResolveRepositoryInput, SourceControlProvider, TriggerReference, } from '@shipfox/api-integration-spi';
2
2
  //# sourceMappingURL=source-control.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"source-control.d.ts","sourceRoot":"","sources":["../../../src/core/providers/source-control.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,mBAAmB,EACnB,mBAAmB,EACnB,YAAY,EACZ,uBAAuB,EACvB,cAAc,EACd,SAAS,EACT,QAAQ,EACR,YAAY,EACZ,cAAc,EACd,qBAAqB,EACrB,cAAc,EACd,kBAAkB,EAClB,oBAAoB,EACpB,sBAAsB,EACtB,qBAAqB,GACtB,MAAM,8BAA8B,CAAC"}
1
+ {"version":3,"file":"source-control.d.ts","sourceRoot":"","sources":["../../../src/core/providers/source-control.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,mBAAmB,EACnB,mBAAmB,EACnB,YAAY,EACZ,uBAAuB,EACvB,cAAc,EACd,SAAS,EACT,QAAQ,EACR,YAAY,EACZ,cAAc,EACd,qBAAqB,EACrB,cAAc,EACd,kBAAkB,EAClB,oBAAoB,EACpB,sBAAsB,EACtB,qBAAqB,EACrB,gBAAgB,GACjB,MAAM,8BAA8B,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/core/providers/source-control.ts"],"sourcesContent":["export 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 '@shipfox/api-integration-spi';\n"],"names":[],"mappings":"AAAA,WAgBsC"}
1
+ {"version":3,"sources":["../../../src/core/providers/source-control.ts"],"sourcesContent":["export 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 '@shipfox/api-integration-spi';\n"],"names":[],"mappings":"AAAA,WAiBsC"}
@@ -1,10 +1,11 @@
1
1
  import type { IntegrationConnection } from './entities/connection.js';
2
2
  import type { IntegrationProviderRegistry } from './providers/registry.js';
3
- import type { CheckoutPermissions, CheckoutSpec, FilePage, FileSnapshot, RepositoryPage, RepositorySnapshot } from './providers/source-control.js';
3
+ import type { CheckoutPermissions, CheckoutSpec, FilePage, FileSnapshot, RepositoryPage, RepositorySnapshot, TriggerReference } from './providers/source-control.js';
4
4
  export interface IntegrationSourceControlService {
5
5
  getConnection(connectionId: string): Promise<IntegrationConnection>;
6
6
  listRepositories(input: ListSourceRepositoriesInput): Promise<RepositoryPage>;
7
7
  resolveRepository(input: ResolveSourceRepositoryInput): Promise<ResolvedSourceRepository>;
8
+ resolveTriggerReference(input: ResolveTriggerReferenceInput): Promise<TriggerReference | null>;
8
9
  listFiles(input: ListSourceFilesInput): Promise<FilePage>;
9
10
  fetchFile(input: FetchSourceFileInput): Promise<FileSnapshot>;
10
11
  createCheckoutSpec(input: CreateSourceCheckoutSpecInput): Promise<CheckoutSpec>;
@@ -20,6 +21,11 @@ export interface ResolveSourceRepositoryInput {
20
21
  connectionId: string;
21
22
  externalRepositoryId: string;
22
23
  }
24
+ export interface ResolveTriggerReferenceInput {
25
+ workspaceId: string;
26
+ connectionId: string;
27
+ payload: unknown;
28
+ }
23
29
  export interface ListSourceFilesInput extends ResolveSourceRepositoryInput {
24
30
  ref: string;
25
31
  prefix: string;
@@ -1 +1 @@
1
- {"version":3,"file":"source-control-service.d.ts","sourceRoot":"","sources":["../../src/core/source-control-service.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,qBAAqB,EAAC,MAAM,0BAA0B,CAAC;AAOpE,OAAO,KAAK,EAAC,2BAA2B,EAAC,MAAM,yBAAyB,CAAC;AACzE,OAAO,KAAK,EACV,mBAAmB,EACnB,YAAY,EACZ,QAAQ,EACR,YAAY,EACZ,cAAc,EACd,kBAAkB,EACnB,MAAM,+BAA+B,CAAC;AAEvC,MAAM,WAAW,+BAA+B;IAC9C,aAAa,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,qBAAqB,CAAC,CAAC;IACpE,gBAAgB,CAAC,KAAK,EAAE,2BAA2B,GAAG,OAAO,CAAC,cAAc,CAAC,CAAC;IAC9E,iBAAiB,CAAC,KAAK,EAAE,4BAA4B,GAAG,OAAO,CAAC,wBAAwB,CAAC,CAAC;IAC1F,SAAS,CAAC,KAAK,EAAE,oBAAoB,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;IAC1D,SAAS,CAAC,KAAK,EAAE,oBAAoB,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC;IAC9D,kBAAkB,CAAC,KAAK,EAAE,6BAA6B,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC;CACjF;AAED,MAAM,WAAW,2BAA2B;IAC1C,UAAU,EAAE,qBAAqB,CAAC;IAClC,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5B,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC7B;AAED,MAAM,WAAW,4BAA4B;IAC3C,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,oBAAoB,EAAE,MAAM,CAAC;CAC9B;AAED,MAAM,WAAW,oBAAqB,SAAQ,4BAA4B;IACxE,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC7B;AAED,MAAM,WAAW,oBAAqB,SAAQ,4BAA4B;IACxE,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,6BAA8B,SAAQ,4BAA4B;IACjF,GAAG,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACzB,WAAW,CAAC,EAAE,mBAAmB,GAAG,SAAS,CAAC;CAC/C;AAED,MAAM,WAAW,wBAAwB;IACvC,UAAU,EAAE,qBAAqB,CAAC;IAClC,UAAU,EAAE,kBAAkB,CAAC;CAChC;AAED,MAAM,WAAW,4CAA4C;IAC3D,QAAQ,EAAE,2BAA2B,CAAC;IACtC,4BAA4B,EAAE,CAC5B,YAAY,EAAE,MAAM,KACjB,OAAO,CAAC,qBAAqB,GAAG,SAAS,CAAC,CAAC;CACjD;AAED,wBAAgB,qCAAqC,CAAC,EACpD,QAAQ,EACR,4BAA4B,GAC7B,EAAE,4CAA4C,GAAG,+BAA+B,CAyFhF"}
1
+ {"version":3,"file":"source-control-service.d.ts","sourceRoot":"","sources":["../../src/core/source-control-service.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,qBAAqB,EAAC,MAAM,0BAA0B,CAAC;AAOpE,OAAO,KAAK,EAAC,2BAA2B,EAAC,MAAM,yBAAyB,CAAC;AACzE,OAAO,KAAK,EACV,mBAAmB,EACnB,YAAY,EACZ,QAAQ,EACR,YAAY,EACZ,cAAc,EACd,kBAAkB,EAClB,gBAAgB,EACjB,MAAM,+BAA+B,CAAC;AAEvC,MAAM,WAAW,+BAA+B;IAC9C,aAAa,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,qBAAqB,CAAC,CAAC;IACpE,gBAAgB,CAAC,KAAK,EAAE,2BAA2B,GAAG,OAAO,CAAC,cAAc,CAAC,CAAC;IAC9E,iBAAiB,CAAC,KAAK,EAAE,4BAA4B,GAAG,OAAO,CAAC,wBAAwB,CAAC,CAAC;IAC1F,uBAAuB,CAAC,KAAK,EAAE,4BAA4B,GAAG,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAAC;IAC/F,SAAS,CAAC,KAAK,EAAE,oBAAoB,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;IAC1D,SAAS,CAAC,KAAK,EAAE,oBAAoB,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC;IAC9D,kBAAkB,CAAC,KAAK,EAAE,6BAA6B,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC;CACjF;AAED,MAAM,WAAW,2BAA2B;IAC1C,UAAU,EAAE,qBAAqB,CAAC;IAClC,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5B,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC7B;AAED,MAAM,WAAW,4BAA4B;IAC3C,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,oBAAoB,EAAE,MAAM,CAAC;CAC9B;AAED,MAAM,WAAW,4BAA4B;IAC3C,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,oBAAqB,SAAQ,4BAA4B;IACxE,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC7B;AAED,MAAM,WAAW,oBAAqB,SAAQ,4BAA4B;IACxE,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,6BAA8B,SAAQ,4BAA4B;IACjF,GAAG,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACzB,WAAW,CAAC,EAAE,mBAAmB,GAAG,SAAS,CAAC;CAC/C;AAED,MAAM,WAAW,wBAAwB;IACvC,UAAU,EAAE,qBAAqB,CAAC;IAClC,UAAU,EAAE,kBAAkB,CAAC;CAChC;AAED,MAAM,WAAW,4CAA4C;IAC3D,QAAQ,EAAE,2BAA2B,CAAC;IACtC,4BAA4B,EAAE,CAC5B,YAAY,EAAE,MAAM,KACjB,OAAO,CAAC,qBAAqB,GAAG,SAAS,CAAC,CAAC;CACjD;AAED,wBAAgB,qCAAqC,CAAC,EACpD,QAAQ,EACR,4BAA4B,GAC7B,EAAE,4CAA4C,GAAG,+BAA+B,CAsGhF"}
@@ -34,6 +34,17 @@ export function createSourceControlIntegrationService({ registry, getIntegration
34
34
  repository
35
35
  };
36
36
  },
37
+ async resolveTriggerReference ({ workspaceId, connectionId, payload }) {
38
+ const connection = await getConnection(connectionId);
39
+ if (connection.workspaceId !== workspaceId) {
40
+ throw new IntegrationConnectionWorkspaceMismatchError(connectionId);
41
+ }
42
+ // Not every integration source names a repository (for example Linear),
43
+ // so a missing source-control adapter is a valid null reference rather
44
+ // than a failed run creation.
45
+ const sourceControl = registry.get(connection.provider).adapters.source_control;
46
+ return sourceControl?.resolveTriggerReference(payload) ?? null;
47
+ },
37
48
  async listFiles ({ workspaceId, connectionId, externalRepositoryId, ref, prefix, limit, cursor }) {
38
49
  const connection = await getConnection(connectionId);
39
50
  if (connection.workspaceId !== workspaceId) {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/core/source-control-service.ts"],"sourcesContent":["import type {IntegrationConnection} from './entities/connection.js';\nimport {\n IntegrationCheckoutUnsupportedError,\n IntegrationConnectionInactiveError,\n IntegrationConnectionNotFoundError,\n IntegrationConnectionWorkspaceMismatchError,\n} from './errors.js';\nimport type {IntegrationProviderRegistry} from './providers/registry.js';\nimport type {\n CheckoutPermissions,\n CheckoutSpec,\n FilePage,\n FileSnapshot,\n RepositoryPage,\n RepositorySnapshot,\n} from './providers/source-control.js';\n\nexport interface IntegrationSourceControlService {\n getConnection(connectionId: string): Promise<IntegrationConnection>;\n listRepositories(input: ListSourceRepositoriesInput): Promise<RepositoryPage>;\n resolveRepository(input: ResolveSourceRepositoryInput): Promise<ResolvedSourceRepository>;\n listFiles(input: ListSourceFilesInput): Promise<FilePage>;\n fetchFile(input: FetchSourceFileInput): Promise<FileSnapshot>;\n createCheckoutSpec(input: CreateSourceCheckoutSpecInput): Promise<CheckoutSpec>;\n}\n\nexport interface ListSourceRepositoriesInput {\n connection: IntegrationConnection;\n limit: number;\n cursor?: string | undefined;\n search?: string | undefined;\n}\n\nexport interface ResolveSourceRepositoryInput {\n workspaceId: string;\n connectionId: string;\n externalRepositoryId: string;\n}\n\nexport interface ListSourceFilesInput extends ResolveSourceRepositoryInput {\n ref: string;\n prefix: string;\n limit: number;\n cursor?: string | undefined;\n}\n\nexport interface FetchSourceFileInput extends ResolveSourceRepositoryInput {\n ref: string;\n path: string;\n}\n\nexport interface CreateSourceCheckoutSpecInput extends ResolveSourceRepositoryInput {\n ref?: string | undefined;\n permissions?: CheckoutPermissions | undefined;\n}\n\nexport interface ResolvedSourceRepository {\n connection: IntegrationConnection;\n repository: RepositorySnapshot;\n}\n\nexport interface CreateIntegrationSourceControlServiceOptions {\n registry: IntegrationProviderRegistry;\n getIntegrationConnectionById: (\n connectionId: string,\n ) => Promise<IntegrationConnection | undefined>;\n}\n\nexport function createSourceControlIntegrationService({\n registry,\n getIntegrationConnectionById,\n}: CreateIntegrationSourceControlServiceOptions): IntegrationSourceControlService {\n async function getConnection(connectionId: string): Promise<IntegrationConnection> {\n const connection = await getIntegrationConnectionById(connectionId);\n if (!connection) throw new IntegrationConnectionNotFoundError(connectionId);\n if (connection.lifecycleStatus !== 'active') {\n throw new IntegrationConnectionInactiveError(connection.id);\n }\n\n return connection;\n }\n\n return {\n getConnection,\n\n async listRepositories({connection, limit, cursor, search}) {\n const sourceControl = registry.getAdapter(connection.provider, 'source_control');\n return await sourceControl.listRepositories({\n connection,\n limit,\n cursor,\n search,\n });\n },\n\n async resolveRepository({workspaceId, connectionId, externalRepositoryId}) {\n const connection = await getConnection(connectionId);\n if (connection.workspaceId !== workspaceId) {\n throw new IntegrationConnectionWorkspaceMismatchError(connectionId);\n }\n const sourceControl = registry.getAdapter(connection.provider, 'source_control');\n\n const repository = await sourceControl.resolveRepository({\n connection,\n externalRepositoryId,\n });\n\n return {connection, repository};\n },\n\n async listFiles({workspaceId, connectionId, externalRepositoryId, ref, prefix, limit, cursor}) {\n const connection = await getConnection(connectionId);\n if (connection.workspaceId !== workspaceId) {\n throw new IntegrationConnectionWorkspaceMismatchError(connectionId);\n }\n const sourceControl = registry.getAdapter(connection.provider, 'source_control');\n\n return await sourceControl.listFiles({\n connection,\n externalRepositoryId,\n ref,\n prefix,\n limit,\n cursor,\n });\n },\n\n async fetchFile({workspaceId, connectionId, externalRepositoryId, ref, path}) {\n const connection = await getConnection(connectionId);\n if (connection.workspaceId !== workspaceId) {\n throw new IntegrationConnectionWorkspaceMismatchError(connectionId);\n }\n const sourceControl = registry.getAdapter(connection.provider, 'source_control');\n\n return await sourceControl.fetchFile({\n connection,\n externalRepositoryId,\n ref,\n path,\n });\n },\n\n async createCheckoutSpec({workspaceId, connectionId, externalRepositoryId, ref, permissions}) {\n const connection = await getConnection(connectionId);\n if (connection.workspaceId !== workspaceId) {\n throw new IntegrationConnectionWorkspaceMismatchError(connectionId);\n }\n const sourceControl = registry.getAdapter(connection.provider, 'source_control');\n if (!sourceControl.createCheckoutSpec) {\n throw new IntegrationCheckoutUnsupportedError(connection.provider);\n }\n\n return await sourceControl.createCheckoutSpec({\n connection,\n externalRepositoryId,\n ref,\n permissions,\n });\n },\n };\n}\n"],"names":["IntegrationCheckoutUnsupportedError","IntegrationConnectionInactiveError","IntegrationConnectionNotFoundError","IntegrationConnectionWorkspaceMismatchError","createSourceControlIntegrationService","registry","getIntegrationConnectionById","getConnection","connectionId","connection","lifecycleStatus","id","listRepositories","limit","cursor","search","sourceControl","getAdapter","provider","resolveRepository","workspaceId","externalRepositoryId","repository","listFiles","ref","prefix","fetchFile","path","createCheckoutSpec","permissions"],"mappings":"AACA,SACEA,mCAAmC,EACnCC,kCAAkC,EAClCC,kCAAkC,EAClCC,2CAA2C,QACtC,cAAc;AA8DrB,OAAO,SAASC,sCAAsC,EACpDC,QAAQ,EACRC,4BAA4B,EACiB;IAC7C,eAAeC,cAAcC,YAAoB;QAC/C,MAAMC,aAAa,MAAMH,6BAA6BE;QACtD,IAAI,CAACC,YAAY,MAAM,IAAIP,mCAAmCM;QAC9D,IAAIC,WAAWC,eAAe,KAAK,UAAU;YAC3C,MAAM,IAAIT,mCAAmCQ,WAAWE,EAAE;QAC5D;QAEA,OAAOF;IACT;IAEA,OAAO;QACLF;QAEA,MAAMK,kBAAiB,EAACH,UAAU,EAAEI,KAAK,EAAEC,MAAM,EAAEC,MAAM,EAAC;YACxD,MAAMC,gBAAgBX,SAASY,UAAU,CAACR,WAAWS,QAAQ,EAAE;YAC/D,OAAO,MAAMF,cAAcJ,gBAAgB,CAAC;gBAC1CH;gBACAI;gBACAC;gBACAC;YACF;QACF;QAEA,MAAMI,mBAAkB,EAACC,WAAW,EAAEZ,YAAY,EAAEa,oBAAoB,EAAC;YACvE,MAAMZ,aAAa,MAAMF,cAAcC;YACvC,IAAIC,WAAWW,WAAW,KAAKA,aAAa;gBAC1C,MAAM,IAAIjB,4CAA4CK;YACxD;YACA,MAAMQ,gBAAgBX,SAASY,UAAU,CAACR,WAAWS,QAAQ,EAAE;YAE/D,MAAMI,aAAa,MAAMN,cAAcG,iBAAiB,CAAC;gBACvDV;gBACAY;YACF;YAEA,OAAO;gBAACZ;gBAAYa;YAAU;QAChC;QAEA,MAAMC,WAAU,EAACH,WAAW,EAAEZ,YAAY,EAAEa,oBAAoB,EAAEG,GAAG,EAAEC,MAAM,EAAEZ,KAAK,EAAEC,MAAM,EAAC;YAC3F,MAAML,aAAa,MAAMF,cAAcC;YACvC,IAAIC,WAAWW,WAAW,KAAKA,aAAa;gBAC1C,MAAM,IAAIjB,4CAA4CK;YACxD;YACA,MAAMQ,gBAAgBX,SAASY,UAAU,CAACR,WAAWS,QAAQ,EAAE;YAE/D,OAAO,MAAMF,cAAcO,SAAS,CAAC;gBACnCd;gBACAY;gBACAG;gBACAC;gBACAZ;gBACAC;YACF;QACF;QAEA,MAAMY,WAAU,EAACN,WAAW,EAAEZ,YAAY,EAAEa,oBAAoB,EAAEG,GAAG,EAAEG,IAAI,EAAC;YAC1E,MAAMlB,aAAa,MAAMF,cAAcC;YACvC,IAAIC,WAAWW,WAAW,KAAKA,aAAa;gBAC1C,MAAM,IAAIjB,4CAA4CK;YACxD;YACA,MAAMQ,gBAAgBX,SAASY,UAAU,CAACR,WAAWS,QAAQ,EAAE;YAE/D,OAAO,MAAMF,cAAcU,SAAS,CAAC;gBACnCjB;gBACAY;gBACAG;gBACAG;YACF;QACF;QAEA,MAAMC,oBAAmB,EAACR,WAAW,EAAEZ,YAAY,EAAEa,oBAAoB,EAAEG,GAAG,EAAEK,WAAW,EAAC;YAC1F,MAAMpB,aAAa,MAAMF,cAAcC;YACvC,IAAIC,WAAWW,WAAW,KAAKA,aAAa;gBAC1C,MAAM,IAAIjB,4CAA4CK;YACxD;YACA,MAAMQ,gBAAgBX,SAASY,UAAU,CAACR,WAAWS,QAAQ,EAAE;YAC/D,IAAI,CAACF,cAAcY,kBAAkB,EAAE;gBACrC,MAAM,IAAI5B,oCAAoCS,WAAWS,QAAQ;YACnE;YAEA,OAAO,MAAMF,cAAcY,kBAAkB,CAAC;gBAC5CnB;gBACAY;gBACAG;gBACAK;YACF;QACF;IACF;AACF"}
1
+ {"version":3,"sources":["../../src/core/source-control-service.ts"],"sourcesContent":["import type {IntegrationConnection} from './entities/connection.js';\nimport {\n IntegrationCheckoutUnsupportedError,\n IntegrationConnectionInactiveError,\n IntegrationConnectionNotFoundError,\n IntegrationConnectionWorkspaceMismatchError,\n} from './errors.js';\nimport type {IntegrationProviderRegistry} from './providers/registry.js';\nimport type {\n CheckoutPermissions,\n CheckoutSpec,\n FilePage,\n FileSnapshot,\n RepositoryPage,\n RepositorySnapshot,\n TriggerReference,\n} from './providers/source-control.js';\n\nexport interface IntegrationSourceControlService {\n getConnection(connectionId: string): Promise<IntegrationConnection>;\n listRepositories(input: ListSourceRepositoriesInput): Promise<RepositoryPage>;\n resolveRepository(input: ResolveSourceRepositoryInput): Promise<ResolvedSourceRepository>;\n resolveTriggerReference(input: ResolveTriggerReferenceInput): Promise<TriggerReference | null>;\n listFiles(input: ListSourceFilesInput): Promise<FilePage>;\n fetchFile(input: FetchSourceFileInput): Promise<FileSnapshot>;\n createCheckoutSpec(input: CreateSourceCheckoutSpecInput): Promise<CheckoutSpec>;\n}\n\nexport interface ListSourceRepositoriesInput {\n connection: IntegrationConnection;\n limit: number;\n cursor?: string | undefined;\n search?: string | undefined;\n}\n\nexport interface ResolveSourceRepositoryInput {\n workspaceId: string;\n connectionId: string;\n externalRepositoryId: string;\n}\n\nexport interface ResolveTriggerReferenceInput {\n workspaceId: string;\n connectionId: string;\n payload: unknown;\n}\n\nexport interface ListSourceFilesInput extends ResolveSourceRepositoryInput {\n ref: string;\n prefix: string;\n limit: number;\n cursor?: string | undefined;\n}\n\nexport interface FetchSourceFileInput extends ResolveSourceRepositoryInput {\n ref: string;\n path: string;\n}\n\nexport interface CreateSourceCheckoutSpecInput extends ResolveSourceRepositoryInput {\n ref?: string | undefined;\n permissions?: CheckoutPermissions | undefined;\n}\n\nexport interface ResolvedSourceRepository {\n connection: IntegrationConnection;\n repository: RepositorySnapshot;\n}\n\nexport interface CreateIntegrationSourceControlServiceOptions {\n registry: IntegrationProviderRegistry;\n getIntegrationConnectionById: (\n connectionId: string,\n ) => Promise<IntegrationConnection | undefined>;\n}\n\nexport function createSourceControlIntegrationService({\n registry,\n getIntegrationConnectionById,\n}: CreateIntegrationSourceControlServiceOptions): IntegrationSourceControlService {\n async function getConnection(connectionId: string): Promise<IntegrationConnection> {\n const connection = await getIntegrationConnectionById(connectionId);\n if (!connection) throw new IntegrationConnectionNotFoundError(connectionId);\n if (connection.lifecycleStatus !== 'active') {\n throw new IntegrationConnectionInactiveError(connection.id);\n }\n\n return connection;\n }\n\n return {\n getConnection,\n\n async listRepositories({connection, limit, cursor, search}) {\n const sourceControl = registry.getAdapter(connection.provider, 'source_control');\n return await sourceControl.listRepositories({\n connection,\n limit,\n cursor,\n search,\n });\n },\n\n async resolveRepository({workspaceId, connectionId, externalRepositoryId}) {\n const connection = await getConnection(connectionId);\n if (connection.workspaceId !== workspaceId) {\n throw new IntegrationConnectionWorkspaceMismatchError(connectionId);\n }\n const sourceControl = registry.getAdapter(connection.provider, 'source_control');\n\n const repository = await sourceControl.resolveRepository({\n connection,\n externalRepositoryId,\n });\n\n return {connection, repository};\n },\n\n async resolveTriggerReference({workspaceId, connectionId, payload}) {\n const connection = await getConnection(connectionId);\n if (connection.workspaceId !== workspaceId) {\n throw new IntegrationConnectionWorkspaceMismatchError(connectionId);\n }\n\n // Not every integration source names a repository (for example Linear),\n // so a missing source-control adapter is a valid null reference rather\n // than a failed run creation.\n const sourceControl = registry.get(connection.provider).adapters.source_control;\n return sourceControl?.resolveTriggerReference(payload) ?? null;\n },\n\n async listFiles({workspaceId, connectionId, externalRepositoryId, ref, prefix, limit, cursor}) {\n const connection = await getConnection(connectionId);\n if (connection.workspaceId !== workspaceId) {\n throw new IntegrationConnectionWorkspaceMismatchError(connectionId);\n }\n const sourceControl = registry.getAdapter(connection.provider, 'source_control');\n\n return await sourceControl.listFiles({\n connection,\n externalRepositoryId,\n ref,\n prefix,\n limit,\n cursor,\n });\n },\n\n async fetchFile({workspaceId, connectionId, externalRepositoryId, ref, path}) {\n const connection = await getConnection(connectionId);\n if (connection.workspaceId !== workspaceId) {\n throw new IntegrationConnectionWorkspaceMismatchError(connectionId);\n }\n const sourceControl = registry.getAdapter(connection.provider, 'source_control');\n\n return await sourceControl.fetchFile({\n connection,\n externalRepositoryId,\n ref,\n path,\n });\n },\n\n async createCheckoutSpec({workspaceId, connectionId, externalRepositoryId, ref, permissions}) {\n const connection = await getConnection(connectionId);\n if (connection.workspaceId !== workspaceId) {\n throw new IntegrationConnectionWorkspaceMismatchError(connectionId);\n }\n const sourceControl = registry.getAdapter(connection.provider, 'source_control');\n if (!sourceControl.createCheckoutSpec) {\n throw new IntegrationCheckoutUnsupportedError(connection.provider);\n }\n\n return await sourceControl.createCheckoutSpec({\n connection,\n externalRepositoryId,\n ref,\n permissions,\n });\n },\n };\n}\n"],"names":["IntegrationCheckoutUnsupportedError","IntegrationConnectionInactiveError","IntegrationConnectionNotFoundError","IntegrationConnectionWorkspaceMismatchError","createSourceControlIntegrationService","registry","getIntegrationConnectionById","getConnection","connectionId","connection","lifecycleStatus","id","listRepositories","limit","cursor","search","sourceControl","getAdapter","provider","resolveRepository","workspaceId","externalRepositoryId","repository","resolveTriggerReference","payload","get","adapters","source_control","listFiles","ref","prefix","fetchFile","path","createCheckoutSpec","permissions"],"mappings":"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"}
@@ -41,6 +41,12 @@ export declare function getIntegrationConnectionById(id: string, options?: {
41
41
  tx?: IntegrationDb | IntegrationTx | undefined;
42
42
  }): Promise<IntegrationConnection | undefined>;
43
43
  export type GetIntegrationConnectionByIdFn = typeof getIntegrationConnectionById;
44
+ export interface GetIntegrationConnectionBySlugParams {
45
+ workspaceId: string;
46
+ slug: string;
47
+ }
48
+ export declare function getIntegrationConnectionBySlug(params: GetIntegrationConnectionBySlugParams): Promise<IntegrationConnection | undefined>;
49
+ export type GetIntegrationConnectionBySlugFn = typeof getIntegrationConnectionBySlug;
44
50
  export interface UpdateIntegrationConnectionLifecycleStatusParams {
45
51
  id: string;
46
52
  lifecycleStatus: IntegrationConnectionLifecycleStatus;
@@ -1 +1 @@
1
- {"version":3,"file":"connections.d.ts","sourceRoot":"","sources":["../../src/db/connections.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"connections.d.ts","sourceRoot":"","sources":["../../src/db/connections.ts"],"names":[],"mappings":"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"}
@@ -104,6 +104,12 @@ export async function getIntegrationConnectionById(id, options = {}) {
104
104
  if (!row) return undefined;
105
105
  return toIntegrationConnection(row);
106
106
  }
107
+ export async function getIntegrationConnectionBySlug(params) {
108
+ const rows = await db().select().from(integrationConnections).where(and(eq(integrationConnections.workspaceId, params.workspaceId), eq(integrationConnections.slug, params.slug))).limit(1);
109
+ const row = rows[0];
110
+ if (!row) return undefined;
111
+ return toIntegrationConnection(row);
112
+ }
107
113
  export async function updateIntegrationConnectionLifecycleStatus(params, options = {}) {
108
114
  const executor = options.tx ?? db();
109
115
  const [row] = await executor.update(integrationConnections).set({
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/db/connections.ts"],"sourcesContent":["import {CONNECTION_SLUG_MAX_LENGTH} from '@shipfox/api-integration-core-dto';\nimport {ConnectionSlugConflictError} from '@shipfox/api-integration-spi';\nimport {and, eq} from 'drizzle-orm';\nimport type {\n IntegrationConnection,\n IntegrationConnectionLifecycleStatus,\n} from '#core/entities/connection.js';\nimport type {IntegrationProviderKind} from '#core/entities/provider.js';\nimport {IntegrationConnectionAlreadyExistsError} from '#core/errors.js';\nimport {db} from './db.js';\nimport {integrationConnections, toIntegrationConnection} from './schema/connections.js';\n\ntype IntegrationDb = ReturnType<typeof db>;\ntype IntegrationTx = Parameters<Parameters<IntegrationDb['transaction']>[0]>[0];\n\nexport interface UpsertIntegrationConnectionParams {\n workspaceId: string;\n provider: IntegrationProviderKind;\n externalAccountId: string;\n slug: string;\n displayName: string;\n lifecycleStatus?: IntegrationConnectionLifecycleStatus | undefined;\n}\n\nexport async function upsertIntegrationConnection(\n params: UpsertIntegrationConnectionParams,\n options: {tx?: IntegrationDb | IntegrationTx | undefined} = {},\n): Promise<IntegrationConnection> {\n const executor = options.tx ?? db();\n const now = new Date();\n const [row] = await executor\n .insert(integrationConnections)\n .values({\n workspaceId: params.workspaceId,\n provider: params.provider,\n externalAccountId: params.externalAccountId,\n slug: params.slug,\n displayName: params.displayName,\n lifecycleStatus: params.lifecycleStatus ?? 'active',\n })\n .onConflictDoUpdate({\n target: [\n integrationConnections.workspaceId,\n integrationConnections.provider,\n integrationConnections.externalAccountId,\n ],\n set: {\n displayName: params.displayName,\n lifecycleStatus: params.lifecycleStatus ?? 'active',\n updatedAt: now,\n },\n })\n .returning();\n\n if (!row) throw new Error('Integration connection upsert returned no rows');\n return toIntegrationConnection(row);\n}\n\nexport interface CreateIntegrationConnectionParams {\n workspaceId: string;\n provider: IntegrationProviderKind;\n externalAccountId: string;\n slug: string;\n displayName: string;\n lifecycleStatus?: IntegrationConnectionLifecycleStatus | undefined;\n}\n\nconst INTEGRATION_CONNECTION_EXTERNAL_UNIQUE_CONSTRAINT =\n 'integrations_connections_workspace_external_unique';\nconst INTEGRATION_CONNECTION_SLUG_UNIQUE_CONSTRAINT =\n 'integrations_connections_workspace_slug_unique';\n\nexport function isIntegrationConnectionUniqueViolation(error: unknown): boolean {\n let current: unknown = error;\n for (let depth = 0; depth < 5 && current != null; depth += 1) {\n if (typeof current !== 'object') return false;\n const {code, constraint} = current as {code?: unknown; constraint?: unknown};\n if (code === '23505' && constraint === INTEGRATION_CONNECTION_EXTERNAL_UNIQUE_CONSTRAINT) {\n return true;\n }\n current = (current as {cause?: unknown}).cause;\n }\n return false;\n}\n\nexport function isIntegrationConnectionSlugUniqueViolation(error: unknown): boolean {\n let current: unknown = error;\n for (let depth = 0; depth < 5 && current != null; depth += 1) {\n if (typeof current !== 'object') return false;\n const {code, constraint} = current as {code?: unknown; constraint?: unknown};\n if (code === '23505' && constraint === INTEGRATION_CONNECTION_SLUG_UNIQUE_CONSTRAINT) {\n return true;\n }\n current = (current as {cause?: unknown}).cause;\n }\n return false;\n}\n\nexport async function createIntegrationConnection(\n params: CreateIntegrationConnectionParams,\n options: {tx?: IntegrationDb | IntegrationTx | undefined} = {},\n): Promise<IntegrationConnection> {\n const executor = options.tx ?? db();\n let rows: (typeof integrationConnections.$inferSelect)[];\n try {\n rows = await executor\n .insert(integrationConnections)\n .values({\n workspaceId: params.workspaceId,\n provider: params.provider,\n externalAccountId: params.externalAccountId,\n slug: params.slug,\n displayName: params.displayName,\n lifecycleStatus: params.lifecycleStatus ?? 'active',\n })\n .returning();\n } catch (error) {\n if (isIntegrationConnectionUniqueViolation(error)) {\n throw new IntegrationConnectionAlreadyExistsError(\n params.workspaceId,\n params.provider,\n params.externalAccountId,\n );\n }\n if (isIntegrationConnectionSlugUniqueViolation(error)) {\n throw new ConnectionSlugConflictError(error);\n }\n throw error;\n }\n\n const row = rows[0];\n if (!row) throw new Error('Integration connection insert returned no rows');\n return toIntegrationConnection(row);\n}\n\nexport interface ResolveUniqueConnectionSlugParams {\n workspaceId: string;\n provider: IntegrationProviderKind;\n externalAccountId: string;\n baseSlug: string;\n}\n\nexport async function resolveUniqueConnectionSlug(\n params: ResolveUniqueConnectionSlugParams,\n options: {tx?: IntegrationDb | IntegrationTx | undefined} = {},\n): Promise<string> {\n const executor = options.tx ?? db();\n const [existing] = await executor\n .select({slug: integrationConnections.slug})\n .from(integrationConnections)\n .where(\n and(\n eq(integrationConnections.workspaceId, params.workspaceId),\n eq(integrationConnections.provider, params.provider),\n eq(integrationConnections.externalAccountId, params.externalAccountId),\n ),\n )\n .limit(1);\n if (existing) return existing.slug;\n\n const workspaceSlugs = await executor\n .select({slug: integrationConnections.slug})\n .from(integrationConnections)\n .where(eq(integrationConnections.workspaceId, params.workspaceId));\n const used = new Set(workspaceSlugs.map((row) => row.slug));\n\n for (let suffixNumber = 1; ; suffixNumber += 1) {\n const suffix = suffixNumber === 1 ? '' : `_${suffixNumber}`;\n const baseBudget = CONNECTION_SLUG_MAX_LENGTH - suffix.length;\n const candidate = `${params.baseSlug.slice(0, baseBudget).replaceAll(/[_-]+$/g, '')}${suffix}`;\n if (!used.has(candidate)) return candidate;\n }\n}\n\nexport type CreateIntegrationConnectionFn = typeof createIntegrationConnection;\n\nexport async function getIntegrationConnectionById(\n id: string,\n options: {tx?: IntegrationDb | IntegrationTx | undefined} = {},\n): Promise<IntegrationConnection | undefined> {\n const executor = options.tx ?? db();\n const rows = await executor\n .select()\n .from(integrationConnections)\n .where(eq(integrationConnections.id, id))\n .limit(1);\n const row = rows[0];\n if (!row) return undefined;\n return toIntegrationConnection(row);\n}\n\nexport type GetIntegrationConnectionByIdFn = typeof getIntegrationConnectionById;\n\nexport interface UpdateIntegrationConnectionLifecycleStatusParams {\n id: string;\n lifecycleStatus: IntegrationConnectionLifecycleStatus;\n}\n\nexport async function updateIntegrationConnectionLifecycleStatus(\n params: UpdateIntegrationConnectionLifecycleStatusParams,\n options: {tx?: IntegrationDb | IntegrationTx | undefined} = {},\n): Promise<IntegrationConnection | undefined> {\n const executor = options.tx ?? db();\n const [row] = await executor\n .update(integrationConnections)\n .set({lifecycleStatus: params.lifecycleStatus, updatedAt: new Date()})\n .where(eq(integrationConnections.id, params.id))\n .returning();\n if (!row) return undefined;\n return toIntegrationConnection(row);\n}\n\nexport type UpdateIntegrationConnectionLifecycleStatusFn =\n typeof updateIntegrationConnectionLifecycleStatus;\n\nexport async function deleteIntegrationConnection(\n params: {id: string},\n options: {tx?: IntegrationDb | IntegrationTx | undefined} = {},\n): Promise<boolean> {\n const executor = options.tx ?? db();\n const result = await executor\n .delete(integrationConnections)\n .where(eq(integrationConnections.id, params.id));\n return (result.rowCount ?? 0) > 0;\n}\n\nexport type DeleteIntegrationConnectionFn = typeof deleteIntegrationConnection;\n\nexport interface ListIntegrationConnectionsParams {\n workspaceId: string;\n}\n\nexport async function listIntegrationConnections(\n params: ListIntegrationConnectionsParams,\n): Promise<IntegrationConnection[]> {\n const rows = await db()\n .select()\n .from(integrationConnections)\n .where(eq(integrationConnections.workspaceId, params.workspaceId))\n .orderBy(integrationConnections.createdAt, integrationConnections.id);\n\n const connections = rows.map(toIntegrationConnection);\n return connections;\n}\n\nexport interface ListIntegrationConnectionsByProviderParams {\n provider: IntegrationProviderKind;\n}\n\nexport async function listIntegrationConnectionsByProvider(\n params: ListIntegrationConnectionsByProviderParams,\n): Promise<IntegrationConnection[]> {\n const rows = await db()\n .select()\n .from(integrationConnections)\n .where(eq(integrationConnections.provider, params.provider))\n .orderBy(integrationConnections.createdAt, integrationConnections.id);\n\n return rows.map(toIntegrationConnection);\n}\n"],"names":["CONNECTION_SLUG_MAX_LENGTH","ConnectionSlugConflictError","and","eq","IntegrationConnectionAlreadyExistsError","db","integrationConnections","toIntegrationConnection","upsertIntegrationConnection","params","options","executor","tx","now","Date","row","insert","values","workspaceId","provider","externalAccountId","slug","displayName","lifecycleStatus","onConflictDoUpdate","target","set","updatedAt","returning","Error","INTEGRATION_CONNECTION_EXTERNAL_UNIQUE_CONSTRAINT","INTEGRATION_CONNECTION_SLUG_UNIQUE_CONSTRAINT","isIntegrationConnectionUniqueViolation","error","current","depth","code","constraint","cause","isIntegrationConnectionSlugUniqueViolation","createIntegrationConnection","rows","resolveUniqueConnectionSlug","existing","select","from","where","limit","workspaceSlugs","used","Set","map","suffixNumber","suffix","baseBudget","length","candidate","baseSlug","slice","replaceAll","has","getIntegrationConnectionById","id","undefined","updateIntegrationConnectionLifecycleStatus","update","deleteIntegrationConnection","result","delete","rowCount","listIntegrationConnections","orderBy","createdAt","connections","listIntegrationConnectionsByProvider"],"mappings":"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"}
1
+ {"version":3,"sources":["../../src/db/connections.ts"],"sourcesContent":["import {CONNECTION_SLUG_MAX_LENGTH} from '@shipfox/api-integration-core-dto';\nimport {ConnectionSlugConflictError} from '@shipfox/api-integration-spi';\nimport {and, eq} from 'drizzle-orm';\nimport type {\n IntegrationConnection,\n IntegrationConnectionLifecycleStatus,\n} from '#core/entities/connection.js';\nimport type {IntegrationProviderKind} from '#core/entities/provider.js';\nimport {IntegrationConnectionAlreadyExistsError} from '#core/errors.js';\nimport {db} from './db.js';\nimport {integrationConnections, toIntegrationConnection} from './schema/connections.js';\n\ntype IntegrationDb = ReturnType<typeof db>;\ntype IntegrationTx = Parameters<Parameters<IntegrationDb['transaction']>[0]>[0];\n\nexport interface UpsertIntegrationConnectionParams {\n workspaceId: string;\n provider: IntegrationProviderKind;\n externalAccountId: string;\n slug: string;\n displayName: string;\n lifecycleStatus?: IntegrationConnectionLifecycleStatus | undefined;\n}\n\nexport async function upsertIntegrationConnection(\n params: UpsertIntegrationConnectionParams,\n options: {tx?: IntegrationDb | IntegrationTx | undefined} = {},\n): Promise<IntegrationConnection> {\n const executor = options.tx ?? db();\n const now = new Date();\n const [row] = await executor\n .insert(integrationConnections)\n .values({\n workspaceId: params.workspaceId,\n provider: params.provider,\n externalAccountId: params.externalAccountId,\n slug: params.slug,\n displayName: params.displayName,\n lifecycleStatus: params.lifecycleStatus ?? 'active',\n })\n .onConflictDoUpdate({\n target: [\n integrationConnections.workspaceId,\n integrationConnections.provider,\n integrationConnections.externalAccountId,\n ],\n set: {\n displayName: params.displayName,\n lifecycleStatus: params.lifecycleStatus ?? 'active',\n updatedAt: now,\n },\n })\n .returning();\n\n if (!row) throw new Error('Integration connection upsert returned no rows');\n return toIntegrationConnection(row);\n}\n\nexport interface CreateIntegrationConnectionParams {\n workspaceId: string;\n provider: IntegrationProviderKind;\n externalAccountId: string;\n slug: string;\n displayName: string;\n lifecycleStatus?: IntegrationConnectionLifecycleStatus | undefined;\n}\n\nconst INTEGRATION_CONNECTION_EXTERNAL_UNIQUE_CONSTRAINT =\n 'integrations_connections_workspace_external_unique';\nconst INTEGRATION_CONNECTION_SLUG_UNIQUE_CONSTRAINT =\n 'integrations_connections_workspace_slug_unique';\n\nexport function isIntegrationConnectionUniqueViolation(error: unknown): boolean {\n let current: unknown = error;\n for (let depth = 0; depth < 5 && current != null; depth += 1) {\n if (typeof current !== 'object') return false;\n const {code, constraint} = current as {code?: unknown; constraint?: unknown};\n if (code === '23505' && constraint === INTEGRATION_CONNECTION_EXTERNAL_UNIQUE_CONSTRAINT) {\n return true;\n }\n current = (current as {cause?: unknown}).cause;\n }\n return false;\n}\n\nexport function isIntegrationConnectionSlugUniqueViolation(error: unknown): boolean {\n let current: unknown = error;\n for (let depth = 0; depth < 5 && current != null; depth += 1) {\n if (typeof current !== 'object') return false;\n const {code, constraint} = current as {code?: unknown; constraint?: unknown};\n if (code === '23505' && constraint === INTEGRATION_CONNECTION_SLUG_UNIQUE_CONSTRAINT) {\n return true;\n }\n current = (current as {cause?: unknown}).cause;\n }\n return false;\n}\n\nexport async function createIntegrationConnection(\n params: CreateIntegrationConnectionParams,\n options: {tx?: IntegrationDb | IntegrationTx | undefined} = {},\n): Promise<IntegrationConnection> {\n const executor = options.tx ?? db();\n let rows: (typeof integrationConnections.$inferSelect)[];\n try {\n rows = await executor\n .insert(integrationConnections)\n .values({\n workspaceId: params.workspaceId,\n provider: params.provider,\n externalAccountId: params.externalAccountId,\n slug: params.slug,\n displayName: params.displayName,\n lifecycleStatus: params.lifecycleStatus ?? 'active',\n })\n .returning();\n } catch (error) {\n if (isIntegrationConnectionUniqueViolation(error)) {\n throw new IntegrationConnectionAlreadyExistsError(\n params.workspaceId,\n params.provider,\n params.externalAccountId,\n );\n }\n if (isIntegrationConnectionSlugUniqueViolation(error)) {\n throw new ConnectionSlugConflictError(error);\n }\n throw error;\n }\n\n const row = rows[0];\n if (!row) throw new Error('Integration connection insert returned no rows');\n return toIntegrationConnection(row);\n}\n\nexport interface ResolveUniqueConnectionSlugParams {\n workspaceId: string;\n provider: IntegrationProviderKind;\n externalAccountId: string;\n baseSlug: string;\n}\n\nexport async function resolveUniqueConnectionSlug(\n params: ResolveUniqueConnectionSlugParams,\n options: {tx?: IntegrationDb | IntegrationTx | undefined} = {},\n): Promise<string> {\n const executor = options.tx ?? db();\n const [existing] = await executor\n .select({slug: integrationConnections.slug})\n .from(integrationConnections)\n .where(\n and(\n eq(integrationConnections.workspaceId, params.workspaceId),\n eq(integrationConnections.provider, params.provider),\n eq(integrationConnections.externalAccountId, params.externalAccountId),\n ),\n )\n .limit(1);\n if (existing) return existing.slug;\n\n const workspaceSlugs = await executor\n .select({slug: integrationConnections.slug})\n .from(integrationConnections)\n .where(eq(integrationConnections.workspaceId, params.workspaceId));\n const used = new Set(workspaceSlugs.map((row) => row.slug));\n\n for (let suffixNumber = 1; ; suffixNumber += 1) {\n const suffix = suffixNumber === 1 ? '' : `_${suffixNumber}`;\n const baseBudget = CONNECTION_SLUG_MAX_LENGTH - suffix.length;\n const candidate = `${params.baseSlug.slice(0, baseBudget).replaceAll(/[_-]+$/g, '')}${suffix}`;\n if (!used.has(candidate)) return candidate;\n }\n}\n\nexport type CreateIntegrationConnectionFn = typeof createIntegrationConnection;\n\nexport async function getIntegrationConnectionById(\n id: string,\n options: {tx?: IntegrationDb | IntegrationTx | undefined} = {},\n): Promise<IntegrationConnection | undefined> {\n const executor = options.tx ?? db();\n const rows = await executor\n .select()\n .from(integrationConnections)\n .where(eq(integrationConnections.id, id))\n .limit(1);\n const row = rows[0];\n if (!row) return undefined;\n return toIntegrationConnection(row);\n}\n\nexport type GetIntegrationConnectionByIdFn = typeof getIntegrationConnectionById;\n\nexport interface GetIntegrationConnectionBySlugParams {\n workspaceId: string;\n slug: string;\n}\n\nexport async function getIntegrationConnectionBySlug(\n params: GetIntegrationConnectionBySlugParams,\n): Promise<IntegrationConnection | undefined> {\n const rows = await db()\n .select()\n .from(integrationConnections)\n .where(\n and(\n eq(integrationConnections.workspaceId, params.workspaceId),\n eq(integrationConnections.slug, params.slug),\n ),\n )\n .limit(1);\n const row = rows[0];\n if (!row) return undefined;\n return toIntegrationConnection(row);\n}\n\nexport type GetIntegrationConnectionBySlugFn = typeof getIntegrationConnectionBySlug;\n\nexport interface UpdateIntegrationConnectionLifecycleStatusParams {\n id: string;\n lifecycleStatus: IntegrationConnectionLifecycleStatus;\n}\n\nexport async function updateIntegrationConnectionLifecycleStatus(\n params: UpdateIntegrationConnectionLifecycleStatusParams,\n options: {tx?: IntegrationDb | IntegrationTx | undefined} = {},\n): Promise<IntegrationConnection | undefined> {\n const executor = options.tx ?? db();\n const [row] = await executor\n .update(integrationConnections)\n .set({lifecycleStatus: params.lifecycleStatus, updatedAt: new Date()})\n .where(eq(integrationConnections.id, params.id))\n .returning();\n if (!row) return undefined;\n return toIntegrationConnection(row);\n}\n\nexport type UpdateIntegrationConnectionLifecycleStatusFn =\n typeof updateIntegrationConnectionLifecycleStatus;\n\nexport async function deleteIntegrationConnection(\n params: {id: string},\n options: {tx?: IntegrationDb | IntegrationTx | undefined} = {},\n): Promise<boolean> {\n const executor = options.tx ?? db();\n const result = await executor\n .delete(integrationConnections)\n .where(eq(integrationConnections.id, params.id));\n return (result.rowCount ?? 0) > 0;\n}\n\nexport type DeleteIntegrationConnectionFn = typeof deleteIntegrationConnection;\n\nexport interface ListIntegrationConnectionsParams {\n workspaceId: string;\n}\n\nexport async function listIntegrationConnections(\n params: ListIntegrationConnectionsParams,\n): Promise<IntegrationConnection[]> {\n const rows = await db()\n .select()\n .from(integrationConnections)\n .where(eq(integrationConnections.workspaceId, params.workspaceId))\n .orderBy(integrationConnections.createdAt, integrationConnections.id);\n\n const connections = rows.map(toIntegrationConnection);\n return connections;\n}\n\nexport interface ListIntegrationConnectionsByProviderParams {\n provider: IntegrationProviderKind;\n}\n\nexport async function listIntegrationConnectionsByProvider(\n params: ListIntegrationConnectionsByProviderParams,\n): Promise<IntegrationConnection[]> {\n const rows = await db()\n .select()\n .from(integrationConnections)\n .where(eq(integrationConnections.provider, params.provider))\n .orderBy(integrationConnections.createdAt, integrationConnections.id);\n\n return rows.map(toIntegrationConnection);\n}\n"],"names":["CONNECTION_SLUG_MAX_LENGTH","ConnectionSlugConflictError","and","eq","IntegrationConnectionAlreadyExistsError","db","integrationConnections","toIntegrationConnection","upsertIntegrationConnection","params","options","executor","tx","now","Date","row","insert","values","workspaceId","provider","externalAccountId","slug","displayName","lifecycleStatus","onConflictDoUpdate","target","set","updatedAt","returning","Error","INTEGRATION_CONNECTION_EXTERNAL_UNIQUE_CONSTRAINT","INTEGRATION_CONNECTION_SLUG_UNIQUE_CONSTRAINT","isIntegrationConnectionUniqueViolation","error","current","depth","code","constraint","cause","isIntegrationConnectionSlugUniqueViolation","createIntegrationConnection","rows","resolveUniqueConnectionSlug","existing","select","from","where","limit","workspaceSlugs","used","Set","map","suffixNumber","suffix","baseBudget","length","candidate","baseSlug","slice","replaceAll","has","getIntegrationConnectionById","id","undefined","getIntegrationConnectionBySlug","updateIntegrationConnectionLifecycleStatus","update","deleteIntegrationConnection","result","delete","rowCount","listIntegrationConnections","orderBy","createdAt","connections","listIntegrationConnectionsByProvider"],"mappings":"AAAA,SAAQA,0BAA0B,QAAO,oCAAoC;AAC7E,SAAQC,2BAA2B,QAAO,+BAA+B;AACzE,SAAQC,GAAG,EAAEC,EAAE,QAAO,cAAc;AAMpC,SAAQC,uCAAuC,QAAO,kBAAkB;AACxE,SAAQC,EAAE,QAAO,UAAU;AAC3B,SAAQC,sBAAsB,EAAEC,uBAAuB,QAAO,0BAA0B;AAcxF,OAAO,eAAeC,4BACpBC,MAAyC,EACzCC,UAA4D,CAAC,CAAC;IAE9D,MAAMC,WAAWD,QAAQE,EAAE,IAAIP;IAC/B,MAAMQ,MAAM,IAAIC;IAChB,MAAM,CAACC,IAAI,GAAG,MAAMJ,SACjBK,MAAM,CAACV,wBACPW,MAAM,CAAC;QACNC,aAAaT,OAAOS,WAAW;QAC/BC,UAAUV,OAAOU,QAAQ;QACzBC,mBAAmBX,OAAOW,iBAAiB;QAC3CC,MAAMZ,OAAOY,IAAI;QACjBC,aAAab,OAAOa,WAAW;QAC/BC,iBAAiBd,OAAOc,eAAe,IAAI;IAC7C,GACCC,kBAAkB,CAAC;QAClBC,QAAQ;YACNnB,uBAAuBY,WAAW;YAClCZ,uBAAuBa,QAAQ;YAC/Bb,uBAAuBc,iBAAiB;SACzC;QACDM,KAAK;YACHJ,aAAab,OAAOa,WAAW;YAC/BC,iBAAiBd,OAAOc,eAAe,IAAI;YAC3CI,WAAWd;QACb;IACF,GACCe,SAAS;IAEZ,IAAI,CAACb,KAAK,MAAM,IAAIc,MAAM;IAC1B,OAAOtB,wBAAwBQ;AACjC;AAWA,MAAMe,oDACJ;AACF,MAAMC,gDACJ;AAEF,OAAO,SAASC,uCAAuCC,KAAc;IACnE,IAAIC,UAAmBD;IACvB,IAAK,IAAIE,QAAQ,GAAGA,QAAQ,KAAKD,WAAW,MAAMC,SAAS,EAAG;QAC5D,IAAI,OAAOD,YAAY,UAAU,OAAO;QACxC,MAAM,EAACE,IAAI,EAAEC,UAAU,EAAC,GAAGH;QAC3B,IAAIE,SAAS,WAAWC,eAAeP,mDAAmD;YACxF,OAAO;QACT;QACAI,UAAU,AAACA,QAA8BI,KAAK;IAChD;IACA,OAAO;AACT;AAEA,OAAO,SAASC,2CAA2CN,KAAc;IACvE,IAAIC,UAAmBD;IACvB,IAAK,IAAIE,QAAQ,GAAGA,QAAQ,KAAKD,WAAW,MAAMC,SAAS,EAAG;QAC5D,IAAI,OAAOD,YAAY,UAAU,OAAO;QACxC,MAAM,EAACE,IAAI,EAAEC,UAAU,EAAC,GAAGH;QAC3B,IAAIE,SAAS,WAAWC,eAAeN,+CAA+C;YACpF,OAAO;QACT;QACAG,UAAU,AAACA,QAA8BI,KAAK;IAChD;IACA,OAAO;AACT;AAEA,OAAO,eAAeE,4BACpB/B,MAAyC,EACzCC,UAA4D,CAAC,CAAC;IAE9D,MAAMC,WAAWD,QAAQE,EAAE,IAAIP;IAC/B,IAAIoC;IACJ,IAAI;QACFA,OAAO,MAAM9B,SACVK,MAAM,CAACV,wBACPW,MAAM,CAAC;YACNC,aAAaT,OAAOS,WAAW;YAC/BC,UAAUV,OAAOU,QAAQ;YACzBC,mBAAmBX,OAAOW,iBAAiB;YAC3CC,MAAMZ,OAAOY,IAAI;YACjBC,aAAab,OAAOa,WAAW;YAC/BC,iBAAiBd,OAAOc,eAAe,IAAI;QAC7C,GACCK,SAAS;IACd,EAAE,OAAOK,OAAO;QACd,IAAID,uCAAuCC,QAAQ;YACjD,MAAM,IAAI7B,wCACRK,OAAOS,WAAW,EAClBT,OAAOU,QAAQ,EACfV,OAAOW,iBAAiB;QAE5B;QACA,IAAImB,2CAA2CN,QAAQ;YACrD,MAAM,IAAIhC,4BAA4BgC;QACxC;QACA,MAAMA;IACR;IAEA,MAAMlB,MAAM0B,IAAI,CAAC,EAAE;IACnB,IAAI,CAAC1B,KAAK,MAAM,IAAIc,MAAM;IAC1B,OAAOtB,wBAAwBQ;AACjC;AASA,OAAO,eAAe2B,4BACpBjC,MAAyC,EACzCC,UAA4D,CAAC,CAAC;IAE9D,MAAMC,WAAWD,QAAQE,EAAE,IAAIP;IAC/B,MAAM,CAACsC,SAAS,GAAG,MAAMhC,SACtBiC,MAAM,CAAC;QAACvB,MAAMf,uBAAuBe,IAAI;IAAA,GACzCwB,IAAI,CAACvC,wBACLwC,KAAK,CACJ5C,IACEC,GAAGG,uBAAuBY,WAAW,EAAET,OAAOS,WAAW,GACzDf,GAAGG,uBAAuBa,QAAQ,EAAEV,OAAOU,QAAQ,GACnDhB,GAAGG,uBAAuBc,iBAAiB,EAAEX,OAAOW,iBAAiB,IAGxE2B,KAAK,CAAC;IACT,IAAIJ,UAAU,OAAOA,SAAStB,IAAI;IAElC,MAAM2B,iBAAiB,MAAMrC,SAC1BiC,MAAM,CAAC;QAACvB,MAAMf,uBAAuBe,IAAI;IAAA,GACzCwB,IAAI,CAACvC,wBACLwC,KAAK,CAAC3C,GAAGG,uBAAuBY,WAAW,EAAET,OAAOS,WAAW;IAClE,MAAM+B,OAAO,IAAIC,IAAIF,eAAeG,GAAG,CAAC,CAACpC,MAAQA,IAAIM,IAAI;IAEzD,IAAK,IAAI+B,eAAe,IAAKA,gBAAgB,EAAG;QAC9C,MAAMC,SAASD,iBAAiB,IAAI,KAAK,CAAC,CAAC,EAAEA,cAAc;QAC3D,MAAME,aAAatD,6BAA6BqD,OAAOE,MAAM;QAC7D,MAAMC,YAAY,GAAG/C,OAAOgD,QAAQ,CAACC,KAAK,CAAC,GAAGJ,YAAYK,UAAU,CAAC,WAAW,MAAMN,QAAQ;QAC9F,IAAI,CAACJ,KAAKW,GAAG,CAACJ,YAAY,OAAOA;IACnC;AACF;AAIA,OAAO,eAAeK,6BACpBC,EAAU,EACVpD,UAA4D,CAAC,CAAC;IAE9D,MAAMC,WAAWD,QAAQE,EAAE,IAAIP;IAC/B,MAAMoC,OAAO,MAAM9B,SAChBiC,MAAM,GACNC,IAAI,CAACvC,wBACLwC,KAAK,CAAC3C,GAAGG,uBAAuBwD,EAAE,EAAEA,KACpCf,KAAK,CAAC;IACT,MAAMhC,MAAM0B,IAAI,CAAC,EAAE;IACnB,IAAI,CAAC1B,KAAK,OAAOgD;IACjB,OAAOxD,wBAAwBQ;AACjC;AASA,OAAO,eAAeiD,+BACpBvD,MAA4C;IAE5C,MAAMgC,OAAO,MAAMpC,KAChBuC,MAAM,GACNC,IAAI,CAACvC,wBACLwC,KAAK,CACJ5C,IACEC,GAAGG,uBAAuBY,WAAW,EAAET,OAAOS,WAAW,GACzDf,GAAGG,uBAAuBe,IAAI,EAAEZ,OAAOY,IAAI,IAG9C0B,KAAK,CAAC;IACT,MAAMhC,MAAM0B,IAAI,CAAC,EAAE;IACnB,IAAI,CAAC1B,KAAK,OAAOgD;IACjB,OAAOxD,wBAAwBQ;AACjC;AASA,OAAO,eAAekD,2CACpBxD,MAAwD,EACxDC,UAA4D,CAAC,CAAC;IAE9D,MAAMC,WAAWD,QAAQE,EAAE,IAAIP;IAC/B,MAAM,CAACU,IAAI,GAAG,MAAMJ,SACjBuD,MAAM,CAAC5D,wBACPoB,GAAG,CAAC;QAACH,iBAAiBd,OAAOc,eAAe;QAAEI,WAAW,IAAIb;IAAM,GACnEgC,KAAK,CAAC3C,GAAGG,uBAAuBwD,EAAE,EAAErD,OAAOqD,EAAE,GAC7ClC,SAAS;IACZ,IAAI,CAACb,KAAK,OAAOgD;IACjB,OAAOxD,wBAAwBQ;AACjC;AAKA,OAAO,eAAeoD,4BACpB1D,MAAoB,EACpBC,UAA4D,CAAC,CAAC;IAE9D,MAAMC,WAAWD,QAAQE,EAAE,IAAIP;IAC/B,MAAM+D,SAAS,MAAMzD,SAClB0D,MAAM,CAAC/D,wBACPwC,KAAK,CAAC3C,GAAGG,uBAAuBwD,EAAE,EAAErD,OAAOqD,EAAE;IAChD,OAAO,AAACM,CAAAA,OAAOE,QAAQ,IAAI,CAAA,IAAK;AAClC;AAQA,OAAO,eAAeC,2BACpB9D,MAAwC;IAExC,MAAMgC,OAAO,MAAMpC,KAChBuC,MAAM,GACNC,IAAI,CAACvC,wBACLwC,KAAK,CAAC3C,GAAGG,uBAAuBY,WAAW,EAAET,OAAOS,WAAW,GAC/DsD,OAAO,CAAClE,uBAAuBmE,SAAS,EAAEnE,uBAAuBwD,EAAE;IAEtE,MAAMY,cAAcjC,KAAKU,GAAG,CAAC5C;IAC7B,OAAOmE;AACT;AAMA,OAAO,eAAeC,qCACpBlE,MAAkD;IAElD,MAAMgC,OAAO,MAAMpC,KAChBuC,MAAM,GACNC,IAAI,CAACvC,wBACLwC,KAAK,CAAC3C,GAAGG,uBAAuBa,QAAQ,EAAEV,OAAOU,QAAQ,GACzDqD,OAAO,CAAClE,uBAAuBmE,SAAS,EAAEnE,uBAAuBwD,EAAE;IAEtE,OAAOrB,KAAKU,GAAG,CAAC5C;AAClB"}
@@ -1,4 +1,4 @@
1
- import { type IntegrationEventReceivedEvent, type SourcePushPayload } from '@shipfox/api-integration-spi';
1
+ import { type IntegrationEventReceivedEvent, type SourcePushPayload, type SourceRepositoryIdentity } from '@shipfox/api-integration-spi';
2
2
  import { db } from './db.js';
3
3
  type IntegrationDb = ReturnType<typeof db>;
4
4
  type IntegrationTx = Parameters<Parameters<IntegrationDb['transaction']>[0]>[0];
@@ -26,6 +26,22 @@ export interface PublishSourcePushParams {
26
26
  export declare function publishSourcePush(params: PublishSourcePushParams): Promise<{
27
27
  published: boolean;
28
28
  }>;
29
+ export interface PublishSourceRepositoryUpdatedParams {
30
+ tx: IntegrationTx;
31
+ provider: string;
32
+ source: string;
33
+ workspaceId: string;
34
+ connectionId: string;
35
+ connectionName: string;
36
+ deliveryId: string;
37
+ receivedAt: string;
38
+ rawPayload: unknown;
39
+ event: string;
40
+ repositories: SourceRepositoryIdentity[];
41
+ }
42
+ export declare function publishSourceRepositoryUpdated(params: PublishSourceRepositoryUpdatedParams): Promise<{
43
+ published: boolean;
44
+ }>;
29
45
  export interface PublishSourceCommitPushedParams {
30
46
  provider: string;
31
47
  workspaceId: string;
@@ -52,6 +68,7 @@ export declare function pruneWebhookDeliveries(params: PruneWebhookDeliveriesPar
52
68
  }>;
53
69
  export type PublishIntegrationEventReceivedFn = typeof publishIntegrationEventReceived;
54
70
  export type PublishSourcePushFn = typeof publishSourcePush;
71
+ export type PublishSourceRepositoryUpdatedFn = typeof publishSourceRepositoryUpdated;
55
72
  export type PublishSourceCommitPushedFn = typeof publishSourceCommitPushed;
56
73
  export type ClaimWebhookDeliveryFn = typeof claimWebhookDelivery;
57
74
  export type RecordDeliveryOnlyFn = typeof recordDeliveryOnly;
@@ -1 +1 @@
1
- {"version":3,"file":"webhook-deliveries.d.ts","sourceRoot":"","sources":["../../src/db/webhook-deliveries.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,6BAA6B,EAElC,KAAK,iBAAiB,EACvB,MAAM,8BAA8B,CAAC;AAGtC,OAAO,EAAC,EAAE,EAAC,MAAM,SAAS,CAAC;AAI3B,KAAK,aAAa,GAAG,UAAU,CAAC,OAAO,EAAE,CAAC,CAAC;AAC3C,KAAK,aAAa,GAAG,UAAU,CAAC,UAAU,CAAC,aAAa,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAChF,KAAK,QAAQ,GAAG,aAAa,GAAG,aAAa,CAAC;AAe9C,MAAM,WAAW,qCAAqC;IACpD,EAAE,EAAE,QAAQ,CAAC;IACb,KAAK,EAAE,6BAA6B,CAAC;CACtC;AAED,MAAM,WAAW,qCAAqC;IACpD,SAAS,EAAE,OAAO,CAAC;CACpB;AAED,wBAAsB,+BAA+B,CACnD,MAAM,EAAE,qCAAqC,GAC5C,OAAO,CAAC,qCAAqC,CAAC,CAyBhD;AAED,MAAM,WAAW,uBAAuB;IACtC,EAAE,EAAE,aAAa,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,cAAc,EAAE,MAAM,CAAC;IACvB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,OAAO,CAAC;IACpB,IAAI,EAAE,iBAAiB,CAAC;CACzB;AAOD,wBAAsB,iBAAiB,CACrC,MAAM,EAAE,uBAAuB,GAC9B,OAAO,CAAC;IAAC,SAAS,EAAE,OAAO,CAAA;CAAC,CAAC,CAgD/B;AAED,MAAM,WAAW,+BAA+B;IAC9C,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,iBAAiB,CAAC;CACzB;AAMD,wBAAsB,yBAAyB,CAC7C,MAAM,EAAE,+BAA+B,GACtC,OAAO,CAAC,IAAI,CAAC,CAYf;AAED,MAAM,WAAW,wBAAwB;IACvC,EAAE,EAAE,QAAQ,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,wBAAsB,oBAAoB,CACxC,MAAM,EAAE,wBAAwB,GAC/B,OAAO,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAC,CAAC,CAiB7B;AAED,wBAAsB,kBAAkB,CAAC,MAAM,EAAE,wBAAwB,GAAG,OAAO,CAAC,IAAI,CAAC,CAExF;AAED,MAAM,WAAW,4BAA4B;IAC3C,SAAS,EAAE,IAAI,CAAC;CACjB;AAED,wBAAsB,sBAAsB,CAC1C,MAAM,EAAE,4BAA4B,GACnC,OAAO,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAC,CAAC,CAK5B;AAED,MAAM,MAAM,iCAAiC,GAAG,OAAO,+BAA+B,CAAC;AACvF,MAAM,MAAM,mBAAmB,GAAG,OAAO,iBAAiB,CAAC;AAC3D,MAAM,MAAM,2BAA2B,GAAG,OAAO,yBAAyB,CAAC;AAC3E,MAAM,MAAM,sBAAsB,GAAG,OAAO,oBAAoB,CAAC;AACjE,MAAM,MAAM,oBAAoB,GAAG,OAAO,kBAAkB,CAAC"}
1
+ {"version":3,"file":"webhook-deliveries.d.ts","sourceRoot":"","sources":["../../src/db/webhook-deliveries.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import { INTEGRATION_EVENT_RECEIVED, INTEGRATION_SOURCE_COMMIT_PUSHED } from '@shipfox/api-integration-spi';
1
+ import { INTEGRATION_EVENT_RECEIVED, INTEGRATION_SOURCE_COMMIT_PUSHED, INTEGRATION_SOURCE_REPOSITORY_UPDATED } from '@shipfox/api-integration-spi';
2
2
  import { writeOutboxEvent, writeOutboxEvents } from '@shipfox/node-outbox';
3
3
  import { lt } from 'drizzle-orm';
4
4
  import { db } from './db.js';
@@ -39,12 +39,7 @@ export async function publishIntegrationEventReceived(params) {
39
39
  published: true
40
40
  };
41
41
  }
42
- // Emits a single source-control push as two outbox rows: the generic
43
- // `INTEGRATION_EVENT_RECEIVED` envelope with the raw provider payload for triggers, and the
44
- // typed `INTEGRATION_SOURCE_COMMIT_PUSHED` event for domain modules. One delivery-dedup gates
45
- // both, so a redelivered webhook writes nothing. Requires a transaction: the dedup insert and
46
- // both outbox rows must commit or roll back together.
47
- export async function publishSourcePush(params) {
42
+ async function publishSourceEvents(params) {
48
43
  const inserted = await params.tx.insert(integrationsWebhookDeliveries).values({
49
44
  provider: params.provider,
50
45
  dedupScope: providerDedupScope(params.provider),
@@ -67,7 +62,7 @@ export async function publishSourcePush(params) {
67
62
  payload: {
68
63
  provider: params.provider,
69
64
  source: params.source,
70
- event: 'push',
65
+ event: params.event,
71
66
  workspaceId: params.workspaceId,
72
67
  connectionId: params.connectionId,
73
68
  connectionName: params.connectionName,
@@ -76,22 +71,73 @@ export async function publishSourcePush(params) {
76
71
  payload: params.rawPayload
77
72
  }
78
73
  },
79
- {
80
- type: INTEGRATION_SOURCE_COMMIT_PUSHED,
81
- payload: {
82
- provider: params.provider,
83
- workspaceId: params.workspaceId,
84
- connectionId: params.connectionId,
85
- deliveryId: params.deliveryId,
86
- receivedAt: params.receivedAt,
87
- push: params.push
88
- }
89
- }
74
+ ...params.typedEvents
90
75
  ]);
91
76
  return {
92
77
  published: true
93
78
  };
94
79
  }
80
+ // Emits a single source-control push as two outbox rows: the generic
81
+ // `INTEGRATION_EVENT_RECEIVED` envelope with the raw provider payload for triggers, and the
82
+ // typed `INTEGRATION_SOURCE_COMMIT_PUSHED` event for domain modules. One delivery-dedup gates
83
+ // both, so a redelivered webhook writes nothing. Requires a transaction: the dedup insert and
84
+ // both outbox rows must commit or roll back together.
85
+ export function publishSourcePush(params) {
86
+ return publishSourceEvents({
87
+ tx: params.tx,
88
+ provider: params.provider,
89
+ source: params.source,
90
+ workspaceId: params.workspaceId,
91
+ connectionId: params.connectionId,
92
+ connectionName: params.connectionName,
93
+ deliveryId: params.deliveryId,
94
+ receivedAt: params.receivedAt,
95
+ rawPayload: params.rawPayload,
96
+ event: 'push',
97
+ typedEvents: [
98
+ {
99
+ type: INTEGRATION_SOURCE_COMMIT_PUSHED,
100
+ payload: {
101
+ provider: params.provider,
102
+ workspaceId: params.workspaceId,
103
+ connectionId: params.connectionId,
104
+ deliveryId: params.deliveryId,
105
+ receivedAt: params.receivedAt,
106
+ push: params.push
107
+ }
108
+ }
109
+ ]
110
+ });
111
+ }
112
+ // Emits the generic provider envelope for triggers and one typed repository event per
113
+ // normalized repository for domain modules. One delivery-dedup gates all rows, so a
114
+ // redelivered webhook writes nothing. Requires a transaction: the dedup insert and all
115
+ // outbox rows must commit or roll back together.
116
+ export function publishSourceRepositoryUpdated(params) {
117
+ return publishSourceEvents({
118
+ tx: params.tx,
119
+ provider: params.provider,
120
+ source: params.source,
121
+ workspaceId: params.workspaceId,
122
+ connectionId: params.connectionId,
123
+ connectionName: params.connectionName,
124
+ deliveryId: params.deliveryId,
125
+ receivedAt: params.receivedAt,
126
+ rawPayload: params.rawPayload,
127
+ event: params.event,
128
+ typedEvents: params.repositories.map((repository)=>({
129
+ type: INTEGRATION_SOURCE_REPOSITORY_UPDATED,
130
+ payload: {
131
+ provider: params.provider,
132
+ workspaceId: params.workspaceId,
133
+ connectionId: params.connectionId,
134
+ deliveryId: params.deliveryId,
135
+ receivedAt: params.receivedAt,
136
+ repository
137
+ }
138
+ }))
139
+ });
140
+ }
95
141
  // Emits ONLY the typed `INTEGRATION_SOURCE_COMMIT_PUSHED` event, intentionally skipping the
96
142
  // `INTEGRATION_EVENT_RECEIVED` envelope so triggers do not run workflows, and skipping the
97
143
  // delivery-dedup row so it is never suppressed. Used to force a definitions re-sync without
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/db/webhook-deliveries.ts"],"sourcesContent":["import {\n INTEGRATION_EVENT_RECEIVED,\n INTEGRATION_SOURCE_COMMIT_PUSHED,\n type IntegrationEventReceivedEvent,\n type IntegrationsEventMap,\n type SourcePushPayload,\n} from '@shipfox/api-integration-spi';\nimport {writeOutboxEvent, writeOutboxEvents} from '@shipfox/node-outbox';\nimport {lt} from 'drizzle-orm';\nimport {db} from './db.js';\nimport {integrationsOutbox} from './schema/outbox.js';\nimport {integrationsWebhookDeliveries} from './schema/webhook-deliveries.js';\n\ntype IntegrationDb = ReturnType<typeof db>;\ntype IntegrationTx = Parameters<Parameters<IntegrationDb['transaction']>[0]>[0];\ntype Executor = IntegrationDb | IntegrationTx;\n\nfunction connectionDedupScope(connectionId: string): string {\n return `connection:${connectionId}`;\n}\n\nfunction providerDedupScope(provider: string): string {\n return `provider:${provider}`;\n}\n\nfunction receivedEventDedupScope(event: IntegrationEventReceivedEvent): string {\n if (event.provider === 'webhook') return connectionDedupScope(event.connectionId);\n return providerDedupScope(event.provider);\n}\n\nexport interface PublishIntegrationEventReceivedParams {\n tx: Executor;\n event: IntegrationEventReceivedEvent;\n}\n\nexport interface PublishIntegrationEventReceivedResult {\n published: boolean;\n}\n\nexport async function publishIntegrationEventReceived(\n params: PublishIntegrationEventReceivedParams,\n): Promise<PublishIntegrationEventReceivedResult> {\n const inserted = await params.tx\n .insert(integrationsWebhookDeliveries)\n .values({\n provider: params.event.provider,\n dedupScope: receivedEventDedupScope(params.event),\n deliveryId: params.event.deliveryId,\n })\n .onConflictDoNothing({\n target: [\n integrationsWebhookDeliveries.provider,\n integrationsWebhookDeliveries.dedupScope,\n integrationsWebhookDeliveries.deliveryId,\n ],\n })\n .returning({deliveryId: integrationsWebhookDeliveries.deliveryId});\n\n if (inserted.length === 0) return {published: false};\n\n await writeOutboxEvent(params.tx, integrationsOutbox, {\n type: INTEGRATION_EVENT_RECEIVED,\n payload: params.event,\n });\n\n return {published: true};\n}\n\nexport interface PublishSourcePushParams {\n tx: IntegrationTx;\n provider: string;\n source: string;\n workspaceId: string;\n connectionId: string;\n connectionName: string;\n deliveryId: string;\n receivedAt: string;\n rawPayload: unknown;\n push: SourcePushPayload;\n}\n\n// Emits a single source-control push as two outbox rows: the generic\n// `INTEGRATION_EVENT_RECEIVED` envelope with the raw provider payload for triggers, and the\n// typed `INTEGRATION_SOURCE_COMMIT_PUSHED` event for domain modules. One delivery-dedup gates\n// both, so a redelivered webhook writes nothing. Requires a transaction: the dedup insert and\n// both outbox rows must commit or roll back together.\nexport async function publishSourcePush(\n params: PublishSourcePushParams,\n): Promise<{published: boolean}> {\n const inserted = await params.tx\n .insert(integrationsWebhookDeliveries)\n .values({\n provider: params.provider,\n dedupScope: providerDedupScope(params.provider),\n deliveryId: params.deliveryId,\n })\n .onConflictDoNothing({\n target: [\n integrationsWebhookDeliveries.provider,\n integrationsWebhookDeliveries.dedupScope,\n integrationsWebhookDeliveries.deliveryId,\n ],\n })\n .returning({deliveryId: integrationsWebhookDeliveries.deliveryId});\n\n if (inserted.length === 0) return {published: false};\n\n await writeOutboxEvents<IntegrationsEventMap>(params.tx, integrationsOutbox, [\n {\n type: INTEGRATION_EVENT_RECEIVED,\n payload: {\n provider: params.provider,\n source: params.source,\n event: 'push',\n workspaceId: params.workspaceId,\n connectionId: params.connectionId,\n connectionName: params.connectionName,\n deliveryId: params.deliveryId,\n receivedAt: params.receivedAt,\n payload: params.rawPayload,\n },\n },\n {\n type: INTEGRATION_SOURCE_COMMIT_PUSHED,\n payload: {\n provider: params.provider,\n workspaceId: params.workspaceId,\n connectionId: params.connectionId,\n deliveryId: params.deliveryId,\n receivedAt: params.receivedAt,\n push: params.push,\n },\n },\n ]);\n\n return {published: true};\n}\n\nexport interface PublishSourceCommitPushedParams {\n provider: string;\n workspaceId: string;\n connectionId: string;\n deliveryId: string;\n receivedAt: string;\n push: SourcePushPayload;\n}\n\n// Emits ONLY the typed `INTEGRATION_SOURCE_COMMIT_PUSHED` event, intentionally skipping the\n// `INTEGRATION_EVENT_RECEIVED` envelope so triggers do not run workflows, and skipping the\n// delivery-dedup row so it is never suppressed. Used to force a definitions re-sync without\n// simulating an inbound webhook.\nexport async function publishSourceCommitPushed(\n params: PublishSourceCommitPushedParams,\n): Promise<void> {\n await writeOutboxEvent<IntegrationsEventMap>(db(), integrationsOutbox, {\n type: INTEGRATION_SOURCE_COMMIT_PUSHED,\n payload: {\n provider: params.provider,\n workspaceId: params.workspaceId,\n connectionId: params.connectionId,\n deliveryId: params.deliveryId,\n receivedAt: params.receivedAt,\n push: params.push,\n },\n });\n}\n\nexport interface RecordDeliveryOnlyParams {\n tx: Executor;\n provider: string;\n deliveryId: string;\n}\n\nexport async function claimWebhookDelivery(\n params: RecordDeliveryOnlyParams,\n): Promise<{claimed: boolean}> {\n const inserted = await params.tx\n .insert(integrationsWebhookDeliveries)\n .values({\n provider: params.provider,\n dedupScope: providerDedupScope(params.provider),\n deliveryId: params.deliveryId,\n })\n .onConflictDoNothing({\n target: [\n integrationsWebhookDeliveries.provider,\n integrationsWebhookDeliveries.dedupScope,\n integrationsWebhookDeliveries.deliveryId,\n ],\n })\n .returning({deliveryId: integrationsWebhookDeliveries.deliveryId});\n return {claimed: inserted.length > 0};\n}\n\nexport async function recordDeliveryOnly(params: RecordDeliveryOnlyParams): Promise<void> {\n await claimWebhookDelivery(params);\n}\n\nexport interface PruneWebhookDeliveriesParams {\n olderThan: Date;\n}\n\nexport async function pruneWebhookDeliveries(\n params: PruneWebhookDeliveriesParams,\n): Promise<{deleted: number}> {\n const result = await db()\n .delete(integrationsWebhookDeliveries)\n .where(lt(integrationsWebhookDeliveries.receivedAt, params.olderThan));\n return {deleted: result.rowCount ?? 0};\n}\n\nexport type PublishIntegrationEventReceivedFn = typeof publishIntegrationEventReceived;\nexport type PublishSourcePushFn = typeof publishSourcePush;\nexport type PublishSourceCommitPushedFn = typeof publishSourceCommitPushed;\nexport type ClaimWebhookDeliveryFn = typeof claimWebhookDelivery;\nexport type RecordDeliveryOnlyFn = typeof recordDeliveryOnly;\n"],"names":["INTEGRATION_EVENT_RECEIVED","INTEGRATION_SOURCE_COMMIT_PUSHED","writeOutboxEvent","writeOutboxEvents","lt","db","integrationsOutbox","integrationsWebhookDeliveries","connectionDedupScope","connectionId","providerDedupScope","provider","receivedEventDedupScope","event","publishIntegrationEventReceived","params","inserted","tx","insert","values","dedupScope","deliveryId","onConflictDoNothing","target","returning","length","published","type","payload","publishSourcePush","source","workspaceId","connectionName","receivedAt","rawPayload","push","publishSourceCommitPushed","claimWebhookDelivery","claimed","recordDeliveryOnly","pruneWebhookDeliveries","result","delete","where","olderThan","deleted","rowCount"],"mappings":"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"}
1
+ {"version":3,"sources":["../../src/db/webhook-deliveries.ts"],"sourcesContent":["import {\n INTEGRATION_EVENT_RECEIVED,\n INTEGRATION_SOURCE_COMMIT_PUSHED,\n INTEGRATION_SOURCE_REPOSITORY_UPDATED,\n type IntegrationEventReceivedEvent,\n type IntegrationsEventMap,\n type SourcePushPayload,\n type SourceRepositoryIdentity,\n} from '@shipfox/api-integration-spi';\nimport {writeOutboxEvent, writeOutboxEvents} from '@shipfox/node-outbox';\nimport {lt} from 'drizzle-orm';\nimport {db} from './db.js';\nimport {integrationsOutbox} from './schema/outbox.js';\nimport {integrationsWebhookDeliveries} from './schema/webhook-deliveries.js';\n\ntype IntegrationDb = ReturnType<typeof db>;\ntype IntegrationTx = Parameters<Parameters<IntegrationDb['transaction']>[0]>[0];\ntype Executor = IntegrationDb | IntegrationTx;\ntype IntegrationOutboxEvent = {\n [K in keyof IntegrationsEventMap & string]: {\n type: K;\n payload: IntegrationsEventMap[K];\n };\n}[keyof IntegrationsEventMap & string];\n\nfunction connectionDedupScope(connectionId: string): string {\n return `connection:${connectionId}`;\n}\n\nfunction providerDedupScope(provider: string): string {\n return `provider:${provider}`;\n}\n\nfunction receivedEventDedupScope(event: IntegrationEventReceivedEvent): string {\n if (event.provider === 'webhook') return connectionDedupScope(event.connectionId);\n return providerDedupScope(event.provider);\n}\n\nexport interface PublishIntegrationEventReceivedParams {\n tx: Executor;\n event: IntegrationEventReceivedEvent;\n}\n\nexport interface PublishIntegrationEventReceivedResult {\n published: boolean;\n}\n\nexport async function publishIntegrationEventReceived(\n params: PublishIntegrationEventReceivedParams,\n): Promise<PublishIntegrationEventReceivedResult> {\n const inserted = await params.tx\n .insert(integrationsWebhookDeliveries)\n .values({\n provider: params.event.provider,\n dedupScope: receivedEventDedupScope(params.event),\n deliveryId: params.event.deliveryId,\n })\n .onConflictDoNothing({\n target: [\n integrationsWebhookDeliveries.provider,\n integrationsWebhookDeliveries.dedupScope,\n integrationsWebhookDeliveries.deliveryId,\n ],\n })\n .returning({deliveryId: integrationsWebhookDeliveries.deliveryId});\n\n if (inserted.length === 0) return {published: false};\n\n await writeOutboxEvent(params.tx, integrationsOutbox, {\n type: INTEGRATION_EVENT_RECEIVED,\n payload: params.event,\n });\n\n return {published: true};\n}\n\ninterface PublishSourceEventsParams {\n tx: IntegrationTx;\n provider: string;\n source: string;\n workspaceId: string;\n connectionId: string;\n connectionName: string;\n deliveryId: string;\n receivedAt: string;\n rawPayload: unknown;\n event: string;\n typedEvents: IntegrationOutboxEvent[];\n}\n\nasync function publishSourceEvents(\n params: PublishSourceEventsParams,\n): Promise<{published: boolean}> {\n const inserted = await params.tx\n .insert(integrationsWebhookDeliveries)\n .values({\n provider: params.provider,\n dedupScope: providerDedupScope(params.provider),\n deliveryId: params.deliveryId,\n })\n .onConflictDoNothing({\n target: [\n integrationsWebhookDeliveries.provider,\n integrationsWebhookDeliveries.dedupScope,\n integrationsWebhookDeliveries.deliveryId,\n ],\n })\n .returning({deliveryId: integrationsWebhookDeliveries.deliveryId});\n\n if (inserted.length === 0) return {published: false};\n\n await writeOutboxEvents<IntegrationsEventMap>(params.tx, integrationsOutbox, [\n {\n type: INTEGRATION_EVENT_RECEIVED,\n payload: {\n provider: params.provider,\n source: params.source,\n event: params.event,\n workspaceId: params.workspaceId,\n connectionId: params.connectionId,\n connectionName: params.connectionName,\n deliveryId: params.deliveryId,\n receivedAt: params.receivedAt,\n payload: params.rawPayload,\n },\n },\n ...params.typedEvents,\n ]);\n\n return {published: true};\n}\n\nexport interface PublishSourcePushParams {\n tx: IntegrationTx;\n provider: string;\n source: string;\n workspaceId: string;\n connectionId: string;\n connectionName: string;\n deliveryId: string;\n receivedAt: string;\n rawPayload: unknown;\n push: SourcePushPayload;\n}\n\n// Emits a single source-control push as two outbox rows: the generic\n// `INTEGRATION_EVENT_RECEIVED` envelope with the raw provider payload for triggers, and the\n// typed `INTEGRATION_SOURCE_COMMIT_PUSHED` event for domain modules. One delivery-dedup gates\n// both, so a redelivered webhook writes nothing. Requires a transaction: the dedup insert and\n// both outbox rows must commit or roll back together.\nexport function publishSourcePush(params: PublishSourcePushParams): Promise<{published: boolean}> {\n return publishSourceEvents({\n tx: params.tx,\n provider: params.provider,\n source: params.source,\n workspaceId: params.workspaceId,\n connectionId: params.connectionId,\n connectionName: params.connectionName,\n deliveryId: params.deliveryId,\n receivedAt: params.receivedAt,\n rawPayload: params.rawPayload,\n event: 'push',\n typedEvents: [\n {\n type: INTEGRATION_SOURCE_COMMIT_PUSHED,\n payload: {\n provider: params.provider,\n workspaceId: params.workspaceId,\n connectionId: params.connectionId,\n deliveryId: params.deliveryId,\n receivedAt: params.receivedAt,\n push: params.push,\n },\n },\n ],\n });\n}\n\nexport interface PublishSourceRepositoryUpdatedParams {\n tx: IntegrationTx;\n provider: string;\n source: string;\n workspaceId: string;\n connectionId: string;\n connectionName: string;\n deliveryId: string;\n receivedAt: string;\n rawPayload: unknown;\n event: string;\n repositories: SourceRepositoryIdentity[];\n}\n\n// Emits the generic provider envelope for triggers and one typed repository event per\n// normalized repository for domain modules. One delivery-dedup gates all rows, so a\n// redelivered webhook writes nothing. Requires a transaction: the dedup insert and all\n// outbox rows must commit or roll back together.\nexport function publishSourceRepositoryUpdated(\n params: PublishSourceRepositoryUpdatedParams,\n): Promise<{published: boolean}> {\n return publishSourceEvents({\n tx: params.tx,\n provider: params.provider,\n source: params.source,\n workspaceId: params.workspaceId,\n connectionId: params.connectionId,\n connectionName: params.connectionName,\n deliveryId: params.deliveryId,\n receivedAt: params.receivedAt,\n rawPayload: params.rawPayload,\n event: params.event,\n typedEvents: params.repositories.map(\n (repository): IntegrationOutboxEvent => ({\n type: INTEGRATION_SOURCE_REPOSITORY_UPDATED,\n payload: {\n provider: params.provider,\n workspaceId: params.workspaceId,\n connectionId: params.connectionId,\n deliveryId: params.deliveryId,\n receivedAt: params.receivedAt,\n repository,\n },\n }),\n ),\n });\n}\n\nexport interface PublishSourceCommitPushedParams {\n provider: string;\n workspaceId: string;\n connectionId: string;\n deliveryId: string;\n receivedAt: string;\n push: SourcePushPayload;\n}\n\n// Emits ONLY the typed `INTEGRATION_SOURCE_COMMIT_PUSHED` event, intentionally skipping the\n// `INTEGRATION_EVENT_RECEIVED` envelope so triggers do not run workflows, and skipping the\n// delivery-dedup row so it is never suppressed. Used to force a definitions re-sync without\n// simulating an inbound webhook.\nexport async function publishSourceCommitPushed(\n params: PublishSourceCommitPushedParams,\n): Promise<void> {\n await writeOutboxEvent<IntegrationsEventMap>(db(), integrationsOutbox, {\n type: INTEGRATION_SOURCE_COMMIT_PUSHED,\n payload: {\n provider: params.provider,\n workspaceId: params.workspaceId,\n connectionId: params.connectionId,\n deliveryId: params.deliveryId,\n receivedAt: params.receivedAt,\n push: params.push,\n },\n });\n}\n\nexport interface RecordDeliveryOnlyParams {\n tx: Executor;\n provider: string;\n deliveryId: string;\n}\n\nexport async function claimWebhookDelivery(\n params: RecordDeliveryOnlyParams,\n): Promise<{claimed: boolean}> {\n const inserted = await params.tx\n .insert(integrationsWebhookDeliveries)\n .values({\n provider: params.provider,\n dedupScope: providerDedupScope(params.provider),\n deliveryId: params.deliveryId,\n })\n .onConflictDoNothing({\n target: [\n integrationsWebhookDeliveries.provider,\n integrationsWebhookDeliveries.dedupScope,\n integrationsWebhookDeliveries.deliveryId,\n ],\n })\n .returning({deliveryId: integrationsWebhookDeliveries.deliveryId});\n return {claimed: inserted.length > 0};\n}\n\nexport async function recordDeliveryOnly(params: RecordDeliveryOnlyParams): Promise<void> {\n await claimWebhookDelivery(params);\n}\n\nexport interface PruneWebhookDeliveriesParams {\n olderThan: Date;\n}\n\nexport async function pruneWebhookDeliveries(\n params: PruneWebhookDeliveriesParams,\n): Promise<{deleted: number}> {\n const result = await db()\n .delete(integrationsWebhookDeliveries)\n .where(lt(integrationsWebhookDeliveries.receivedAt, params.olderThan));\n return {deleted: result.rowCount ?? 0};\n}\n\nexport type PublishIntegrationEventReceivedFn = typeof publishIntegrationEventReceived;\nexport type PublishSourcePushFn = typeof publishSourcePush;\nexport type PublishSourceRepositoryUpdatedFn = typeof publishSourceRepositoryUpdated;\nexport type PublishSourceCommitPushedFn = typeof publishSourceCommitPushed;\nexport type ClaimWebhookDeliveryFn = typeof claimWebhookDelivery;\nexport type RecordDeliveryOnlyFn = typeof recordDeliveryOnly;\n"],"names":["INTEGRATION_EVENT_RECEIVED","INTEGRATION_SOURCE_COMMIT_PUSHED","INTEGRATION_SOURCE_REPOSITORY_UPDATED","writeOutboxEvent","writeOutboxEvents","lt","db","integrationsOutbox","integrationsWebhookDeliveries","connectionDedupScope","connectionId","providerDedupScope","provider","receivedEventDedupScope","event","publishIntegrationEventReceived","params","inserted","tx","insert","values","dedupScope","deliveryId","onConflictDoNothing","target","returning","length","published","type","payload","publishSourceEvents","source","workspaceId","connectionName","receivedAt","rawPayload","typedEvents","publishSourcePush","push","publishSourceRepositoryUpdated","repositories","map","repository","publishSourceCommitPushed","claimWebhookDelivery","claimed","recordDeliveryOnly","pruneWebhookDeliveries","result","delete","where","olderThan","deleted","rowCount"],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -17,13 +17,13 @@ export { ConnectionSlugConflictError, IntegrationCapabilityUnavailableError, Int
17
17
  export type { AgentToolCallInput, AgentToolCatalogEntry, AgentToolCatalogMethod, AgentToolJsonSchema, AgentToolSensitivity, AgentToolSession, AgentToolsProvider, OpenAgentToolsSessionInput, } from '#core/providers/agent-tools.js';
18
18
  export { redactCheckoutSpec } from '#core/providers/redact-checkout-spec.js';
19
19
  export type { IntegrationProviderRegistry } from '#core/providers/registry.js';
20
- export type { CheckoutCredentials, CheckoutPermissions, CheckoutSpec, CreateCheckoutSpecInput, FetchFileInput, FileEntry, FilePage, FileSnapshot, ListFilesInput, ListRepositoriesInput, RepositoryPage, RepositorySnapshot, RepositoryVisibility, ResolveRepositoryInput, SourceControlProvider, } from '#core/providers/source-control.js';
20
+ export type { CheckoutCredentials, CheckoutPermissions, CheckoutSpec, CreateCheckoutSpecInput, FetchFileInput, FileEntry, FilePage, FileSnapshot, ListFilesInput, ListRepositoriesInput, RepositoryPage, RepositorySnapshot, RepositoryVisibility, ResolveRepositoryInput, SourceControlProvider, TriggerReference, } from '#core/providers/source-control.js';
21
21
  export type { IntegrationSourceControlService } from '#core/source-control-service.js';
22
22
  export { createSourceControlIntegrationService } from '#core/source-control-service.js';
23
- export type { GetIntegrationConnectionByIdFn } from '#db/connections.js';
24
- export { getIntegrationConnectionById } from '#db/connections.js';
25
- export type { ClaimWebhookDeliveryFn, PublishIntegrationEventReceivedFn, PublishIntegrationEventReceivedParams, PublishIntegrationEventReceivedResult, PublishSourcePushFn, PublishSourcePushParams, RecordDeliveryOnlyFn, RecordDeliveryOnlyParams, } from '#db/webhook-deliveries.js';
26
- export { claimWebhookDelivery, pruneWebhookDeliveries } from '#db/webhook-deliveries.js';
23
+ export type { GetIntegrationConnectionByIdFn, GetIntegrationConnectionBySlugFn, } from '#db/connections.js';
24
+ export { getIntegrationConnectionById, getIntegrationConnectionBySlug } from '#db/connections.js';
25
+ export type { ClaimWebhookDeliveryFn, PublishIntegrationEventReceivedFn, PublishIntegrationEventReceivedParams, PublishIntegrationEventReceivedResult, PublishSourcePushFn, PublishSourcePushParams, PublishSourceRepositoryUpdatedFn, PublishSourceRepositoryUpdatedParams, RecordDeliveryOnlyFn, RecordDeliveryOnlyParams, } from '#db/webhook-deliveries.js';
26
+ export { claimWebhookDelivery, pruneWebhookDeliveries, publishSourceRepositoryUpdated, } from '#db/webhook-deliveries.js';
27
27
  export { integrationRouteErrorHandler } from '#presentation/routes/errors.js';
28
28
  export interface CreateIntegrationsModuleOptions {
29
29
  providers?: IntegrationProvider[] | undefined;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}