@shipfox/api-integration-core 13.1.0 → 14.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 (89) hide show
  1. package/.turbo/turbo-build.log +4 -4
  2. package/CHANGELOG.md +31 -0
  3. package/dist/core/event-catalogs.d.ts +18 -0
  4. package/dist/core/event-catalogs.d.ts.map +1 -0
  5. package/dist/core/event-catalogs.js +27 -0
  6. package/dist/core/event-catalogs.js.map +1 -0
  7. package/dist/core/providers/registry.d.ts +1 -0
  8. package/dist/core/providers/registry.d.ts.map +1 -1
  9. package/dist/core/providers/registry.js +4 -1
  10. package/dist/core/providers/registry.js.map +1 -1
  11. package/dist/core/providers/source-control.d.ts +1 -1
  12. package/dist/core/providers/source-control.d.ts.map +1 -1
  13. package/dist/core/providers/source-control.js.map +1 -1
  14. package/dist/core/source-control-service.d.ts +5 -1
  15. package/dist/core/source-control-service.d.ts.map +1 -1
  16. package/dist/core/source-control-service.js +12 -0
  17. package/dist/core/source-control-service.js.map +1 -1
  18. package/dist/db/connections.d.ts +4 -1
  19. package/dist/db/connections.d.ts.map +1 -1
  20. package/dist/db/connections.js +15 -6
  21. package/dist/db/connections.js.map +1 -1
  22. package/dist/index.d.ts +1 -1
  23. package/dist/index.d.ts.map +1 -1
  24. package/dist/index.js.map +1 -1
  25. package/dist/metrics/instance.d.ts.map +1 -1
  26. package/dist/metrics/instance.js +2 -0
  27. package/dist/metrics/instance.js.map +1 -1
  28. package/dist/presentation/inter-module.d.ts.map +1 -1
  29. package/dist/presentation/inter-module.js +27 -5
  30. package/dist/presentation/inter-module.js.map +1 -1
  31. package/dist/presentation/routes/errors.d.ts.map +1 -1
  32. package/dist/presentation/routes/errors.js +1 -1
  33. package/dist/presentation/routes/errors.js.map +1 -1
  34. package/dist/presentation/routes/manage-connections.d.ts.map +1 -1
  35. package/dist/presentation/routes/manage-connections.js +7 -3
  36. package/dist/presentation/routes/manage-connections.js.map +1 -1
  37. package/dist/providers/gitea.d.ts.map +1 -1
  38. package/dist/providers/gitea.js +5 -1
  39. package/dist/providers/gitea.js.map +1 -1
  40. package/dist/providers/github.d.ts.map +1 -1
  41. package/dist/providers/github.js +6 -5
  42. package/dist/providers/github.js.map +1 -1
  43. package/dist/providers/jira.d.ts.map +1 -1
  44. package/dist/providers/jira.js +7 -2
  45. package/dist/providers/jira.js.map +1 -1
  46. package/dist/providers/linear.d.ts.map +1 -1
  47. package/dist/providers/linear.js +6 -4
  48. package/dist/providers/linear.js.map +1 -1
  49. package/dist/providers/sentry.d.ts.map +1 -1
  50. package/dist/providers/sentry.js +3 -1
  51. package/dist/providers/sentry.js.map +1 -1
  52. package/dist/providers/slack.d.ts.map +1 -1
  53. package/dist/providers/slack.js +6 -4
  54. package/dist/providers/slack.js.map +1 -1
  55. package/dist/tsconfig.test.tsbuildinfo +1 -1
  56. package/package.json +12 -12
  57. package/src/core/agent-tool-selection.test.ts +4 -0
  58. package/src/core/event-catalogs.test.ts +16 -0
  59. package/src/core/event-catalogs.ts +34 -0
  60. package/src/core/providers/registry.test.ts +4 -0
  61. package/src/core/providers/registry.ts +9 -3
  62. package/src/core/providers/source-control.ts +2 -0
  63. package/src/core/secret-cleanup.test.ts +1 -0
  64. package/src/core/source-control-service.test.ts +48 -0
  65. package/src/core/source-control-service.ts +16 -0
  66. package/src/db/connections.test.ts +167 -0
  67. package/src/db/connections.ts +21 -4
  68. package/src/db/secret-cleanups.test.ts +1 -0
  69. package/src/index.ts +2 -0
  70. package/src/metrics/instance.ts +2 -0
  71. package/src/presentation/inter-module.test.ts +219 -0
  72. package/src/presentation/inter-module.ts +28 -3
  73. package/src/presentation/routes/errors.ts +3 -0
  74. package/src/presentation/routes/list-connections.test.ts +13 -1
  75. package/src/presentation/routes/list-repositories.test.ts +9 -0
  76. package/src/presentation/routes/manage-connections.test.ts +52 -0
  77. package/src/presentation/routes/manage-connections.ts +6 -2
  78. package/src/providers/gitea.ts +5 -0
  79. package/src/providers/github.ts +6 -1
  80. package/src/providers/jira.test.ts +3 -0
  81. package/src/providers/jira.ts +6 -0
  82. package/src/providers/linear.test.ts +3 -0
  83. package/src/providers/linear.ts +6 -1
  84. package/src/providers/modules.test.ts +64 -1
  85. package/src/providers/sentry.ts +3 -0
  86. package/src/providers/slack.test.ts +4 -0
  87. package/src/providers/slack.ts +6 -1
  88. package/test/route-utils.ts +4 -0
  89. 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: 54 files with swc (429.87ms)
3
- 2026-08-23T10:00:30.716Z [INFO] asset workflow-bundle-e0d869d865fd59433325.js 3.17 MiB [emitted] [immutable] (name: main)
2
+ Successfully compiled: 55 files with swc (438.35ms)
3
+ 2026-08-23T20:27:01.669Z [INFO] asset workflow-bundle-e0d869d865fd59433325.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
@@ -15,6 +15,6 @@ optional modules 30 bytes [optional]
15
15
  __temporal_custom_payload_converter (ignored) 15 bytes [optional] [built] [code generated]
16
16
  __temporal_custom_failure_converter (ignored) 15 bytes [optional] [built] [code generated]
17
17
  ../../../shared/node/temporal/dist/workflow-error-interceptor.js 1.21 KiB [built] [code generated]
18
- webpack 5.107.2 compiled successfully in 9121 ms
19
- 2026-08-23T10:00:30.775Z [INFO] Workflow bundle created { size: '3.17MB' }
18
+ webpack 5.107.2 compiled successfully in 7983 ms
19
+ 2026-08-23T20:27:01.689Z [INFO] Workflow bundle created { size: '3.17MB' }
20
20
  /home/runner/work/shipfox/shipfox/libs/api/integration/core/dist/temporal/workflows/index.js: 3328998 bytes
package/CHANGELOG.md CHANGED
@@ -1,5 +1,36 @@
1
1
  # @shipfox/api-integration-core
2
2
 
3
+ ## 14.0.0
4
+
5
+ ### Major Changes
6
+
7
+ - 18e9bad: Adds source-control ref resolution that pins branch and tag names to commits.
8
+
9
+ ### Minor Changes
10
+
11
+ - 1b71a66: Exposes each provider's event catalog and the fixed-event providers on the integration validation context. Every provider now refuses the reserved `manual` and `cron` connection slugs.
12
+
13
+ ### Patch Changes
14
+
15
+ - c44641f: Adds provider capabilities to the `integrations.connection.available` event, so subscribers can tell a tool connection from a source-control connection. The publisher now carries the capabilities the connection DTO already exposes.
16
+ - Updated dependencies [09924ca]
17
+ - Updated dependencies [4f30864]
18
+ - Updated dependencies [18e9bad]
19
+ - Updated dependencies [c44641f]
20
+ - Updated dependencies [1b71a66]
21
+ - Updated dependencies [b766ee3]
22
+ - @shipfox/api-agent-dto@14.0.0
23
+ - @shipfox/api-workflows-dto@14.0.0
24
+ - @shipfox/api-integration-spi@2.0.0
25
+ - @shipfox/api-integration-core-dto@14.0.0
26
+ - @shipfox/api-integration-gitea@14.0.0
27
+ - @shipfox/api-integration-github@14.0.0
28
+ - @shipfox/api-integration-sentry@14.0.0
29
+ - @shipfox/api-integration-slack@14.0.0
30
+ - @shipfox/api-integration-jira@14.0.0
31
+ - @shipfox/api-integration-linear@14.0.0
32
+ - @shipfox/api-integration-webhook@14.0.0
33
+
3
34
  ## 13.1.0
4
35
 
5
36
  ### Patch Changes
@@ -0,0 +1,18 @@
1
+ import type { IntegrationProviderRegistry } from '#core/providers/registry.js';
2
+ /**
3
+ * Providers whose single event name is minted by Shipfox. An explicit event on
4
+ * one of these providers is provably wrong unless it is that one name; every
5
+ * other provider's event names are provider-minted and never treated as a
6
+ * closed set. `manual` and `cron` are registered built-in trigger sources;
7
+ * sync classifies them by literal, before slug resolution.
8
+ */
9
+ export declare const FIXED_EVENT_PROVIDERS: readonly ['webhook'];
10
+ export interface ProviderEventCatalog {
11
+ provider: string;
12
+ events: string[];
13
+ }
14
+ /** Keeps fixed-provider metadata aligned with the enabled provider registry. */
15
+ export declare function buildFixedEventProviders(registry: IntegrationProviderRegistry): Array<(typeof FIXED_EVENT_PROVIDERS)[number]>;
16
+ /** Collects the event names each registered provider documents. */
17
+ export declare function buildProviderEventCatalogs(registry: IntegrationProviderRegistry): ProviderEventCatalog[];
18
+ //# sourceMappingURL=event-catalogs.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"event-catalogs.d.ts","sourceRoot":"","sources":["../../src/core/event-catalogs.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,2BAA2B,EAAC,MAAM,6BAA6B,CAAC;AAE7E;;;;;;GAMG;AACH,eAAO,MAAM,qBAAqB,YAAI,SAAS,CAAU,CAAC;AAE1D,MAAM,WAAW,oBAAoB;IACnC,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAED,gFAAgF;AAChF,wBAAgB,wBAAwB,CACtC,QAAQ,EAAE,2BAA2B,GACpC,KAAK,CAAC,CAAC,OAAO,qBAAqB,CAAC,CAAC,MAAM,CAAC,CAAC,CAG/C;AAED,mEAAmE;AACnE,wBAAgB,0BAA0B,CACxC,QAAQ,EAAE,2BAA2B,GACpC,oBAAoB,EAAE,CAMxB"}
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Providers whose single event name is minted by Shipfox. An explicit event on
3
+ * one of these providers is provably wrong unless it is that one name; every
4
+ * other provider's event names are provider-minted and never treated as a
5
+ * closed set. `manual` and `cron` are registered built-in trigger sources;
6
+ * sync classifies them by literal, before slug resolution.
7
+ */ export const FIXED_EVENT_PROVIDERS = [
8
+ 'webhook'
9
+ ];
10
+ /** Keeps fixed-provider metadata aligned with the enabled provider registry. */ export function buildFixedEventProviders(registry) {
11
+ const registeredProviders = new Set(registry.list().map(({ provider })=>provider));
12
+ return FIXED_EVENT_PROVIDERS.filter((provider)=>registeredProviders.has(provider));
13
+ }
14
+ /** Collects the event names each registered provider documents. */ export function buildProviderEventCatalogs(registry) {
15
+ return registry.list().flatMap((provider)=>{
16
+ const catalog = provider.eventCatalog;
17
+ if (catalog === undefined) return [];
18
+ return [
19
+ {
20
+ provider: provider.provider,
21
+ events: catalog.events.map((event)=>event.name)
22
+ }
23
+ ];
24
+ });
25
+ }
26
+
27
+ //# sourceMappingURL=event-catalogs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/core/event-catalogs.ts"],"sourcesContent":["import type {IntegrationProviderRegistry} from '#core/providers/registry.js';\n\n/**\n * Providers whose single event name is minted by Shipfox. An explicit event on\n * one of these providers is provably wrong unless it is that one name; every\n * other provider's event names are provider-minted and never treated as a\n * closed set. `manual` and `cron` are registered built-in trigger sources;\n * sync classifies them by literal, before slug resolution.\n */\nexport const FIXED_EVENT_PROVIDERS = ['webhook'] as const;\n\nexport interface ProviderEventCatalog {\n provider: string;\n events: string[];\n}\n\n/** Keeps fixed-provider metadata aligned with the enabled provider registry. */\nexport function buildFixedEventProviders(\n registry: IntegrationProviderRegistry,\n): Array<(typeof FIXED_EVENT_PROVIDERS)[number]> {\n const registeredProviders = new Set(registry.list().map(({provider}) => provider));\n return FIXED_EVENT_PROVIDERS.filter((provider) => registeredProviders.has(provider));\n}\n\n/** Collects the event names each registered provider documents. */\nexport function buildProviderEventCatalogs(\n registry: IntegrationProviderRegistry,\n): ProviderEventCatalog[] {\n return registry.list().flatMap((provider) => {\n const catalog = provider.eventCatalog;\n if (catalog === undefined) return [];\n return [{provider: provider.provider, events: catalog.events.map((event) => event.name)}];\n });\n}\n"],"names":["FIXED_EVENT_PROVIDERS","buildFixedEventProviders","registry","registeredProviders","Set","list","map","provider","filter","has","buildProviderEventCatalogs","flatMap","catalog","eventCatalog","undefined","events","event","name"],"mappings":"AAEA;;;;;;CAMC,GACD,OAAO,MAAMA,wBAAwB;IAAC;CAAU,CAAU;AAO1D,8EAA8E,GAC9E,OAAO,SAASC,yBACdC,QAAqC;IAErC,MAAMC,sBAAsB,IAAIC,IAAIF,SAASG,IAAI,GAAGC,GAAG,CAAC,CAAC,EAACC,QAAQ,EAAC,GAAKA;IACxE,OAAOP,sBAAsBQ,MAAM,CAAC,CAACD,WAAaJ,oBAAoBM,GAAG,CAACF;AAC5E;AAEA,iEAAiE,GACjE,OAAO,SAASG,2BACdR,QAAqC;IAErC,OAAOA,SAASG,IAAI,GAAGM,OAAO,CAAC,CAACJ;QAC9B,MAAMK,UAAUL,SAASM,YAAY;QACrC,IAAID,YAAYE,WAAW,OAAO,EAAE;QACpC,OAAO;YAAC;gBAACP,UAAUA,SAASA,QAAQ;gBAAEQ,QAAQH,QAAQG,MAAM,CAACT,GAAG,CAAC,CAACU,QAAUA,MAAMC,IAAI;YAAC;SAAE;IAC3F;AACF"}
@@ -6,4 +6,5 @@ export interface IntegrationProviderRegistry {
6
6
  getSourceControl(provider: IntegrationProviderKind): NonNullable<IntegrationProviderAdapters['source_control']>;
7
7
  }
8
8
  export declare function createIntegrationProviderRegistry(providers: IntegrationProvider[]): IntegrationProviderRegistry;
9
+ export declare function getIntegrationProviderCapabilities(adapters: IntegrationProvider['adapters']): IntegrationCapability[];
9
10
  //# sourceMappingURL=registry.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../../src/core/providers/registry.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,qBAAqB,EACrB,mBAAmB,EACnB,2BAA2B,EAC3B,uBAAuB,EACvB,6BAA6B,EAC9B,MAAM,4BAA4B,CAAC;AAMpC,MAAM,WAAW,2BAA2B;IAC1C,IAAI,CAAC,UAAU,CAAC,EAAE,qBAAqB,GAAG,SAAS,GAAG,6BAA6B,EAAE,CAAC;IACtF,GAAG,CAAC,QAAQ,EAAE,uBAAuB,GAAG,6BAA6B,CAAC;IACtE,UAAU,CAAC,UAAU,SAAS,qBAAqB,EACjD,QAAQ,EAAE,uBAAuB,EACjC,UAAU,EAAE,UAAU,GACrB,WAAW,CAAC,2BAA2B,CAAC,UAAU,CAAC,CAAC,CAAC;IACxD,gBAAgB,CACd,QAAQ,EAAE,uBAAuB,GAChC,WAAW,CAAC,2BAA2B,CAAC,gBAAgB,CAAC,CAAC,CAAC;CAC/D;AAED,wBAAgB,iCAAiC,CAC/C,SAAS,EAAE,mBAAmB,EAAE,GAC/B,2BAA2B,CAE7B"}
1
+ {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../../src/core/providers/registry.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,qBAAqB,EACrB,mBAAmB,EACnB,2BAA2B,EAC3B,uBAAuB,EACvB,6BAA6B,EAC9B,MAAM,4BAA4B,CAAC;AAMpC,MAAM,WAAW,2BAA2B;IAC1C,IAAI,CAAC,UAAU,CAAC,EAAE,qBAAqB,GAAG,SAAS,GAAG,6BAA6B,EAAE,CAAC;IACtF,GAAG,CAAC,QAAQ,EAAE,uBAAuB,GAAG,6BAA6B,CAAC;IACtE,UAAU,CAAC,UAAU,SAAS,qBAAqB,EACjD,QAAQ,EAAE,uBAAuB,EACjC,UAAU,EAAE,UAAU,GACrB,WAAW,CAAC,2BAA2B,CAAC,UAAU,CAAC,CAAC,CAAC;IACxD,gBAAgB,CACd,QAAQ,EAAE,uBAAuB,GAChC,WAAW,CAAC,2BAA2B,CAAC,gBAAgB,CAAC,CAAC,CAAC;CAC/D;AAED,wBAAgB,iCAAiC,CAC/C,SAAS,EAAE,mBAAmB,EAAE,GAC/B,2BAA2B,CAE7B;AA4DD,wBAAgB,kCAAkC,CAChD,QAAQ,EAAE,mBAAmB,CAAC,UAAU,CAAC,GACxC,qBAAqB,EAAE,CAIzB"}
@@ -45,8 +45,11 @@ function normalizeProvider(provider) {
45
45
  return {
46
46
  ...provider,
47
47
  adapters,
48
- capabilities: Object.entries(adapters).filter(([, adapter])=>Boolean(adapter)).map(([capability])=>capability)
48
+ capabilities: getIntegrationProviderCapabilities(adapters)
49
49
  };
50
50
  }
51
+ export function getIntegrationProviderCapabilities(adapters) {
52
+ return Object.entries(adapters ?? {}).filter(([, adapter])=>Boolean(adapter)).map(([capability])=>capability);
53
+ }
51
54
 
52
55
  //# sourceMappingURL=registry.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/core/providers/registry.ts"],"sourcesContent":["import {isLowercaseAlphaSlug} from '@shipfox/regex';\nimport type {\n IntegrationCapability,\n IntegrationProvider,\n IntegrationProviderAdapters,\n IntegrationProviderKind,\n RegisteredIntegrationProvider,\n} from '#core/entities/provider.js';\nimport {\n IntegrationCapabilityUnavailableError,\n IntegrationProviderUnavailableError,\n} from '#core/errors.js';\n\nexport interface IntegrationProviderRegistry {\n list(capability?: IntegrationCapability | undefined): RegisteredIntegrationProvider[];\n get(provider: IntegrationProviderKind): RegisteredIntegrationProvider;\n getAdapter<Capability extends IntegrationCapability>(\n provider: IntegrationProviderKind,\n capability: Capability,\n ): NonNullable<IntegrationProviderAdapters[Capability]>;\n getSourceControl(\n provider: IntegrationProviderKind,\n ): NonNullable<IntegrationProviderAdapters['source_control']>;\n}\n\nexport function createIntegrationProviderRegistry(\n providers: IntegrationProvider[],\n): IntegrationProviderRegistry {\n return new MapIntegrationProviderRegistry(providers);\n}\n\nclass MapIntegrationProviderRegistry implements IntegrationProviderRegistry {\n private readonly providers: Map<IntegrationProviderKind, RegisteredIntegrationProvider>;\n\n constructor(providers: IntegrationProvider[]) {\n this.providers = new Map();\n\n for (const provider of providers) {\n if (!isLowercaseAlphaSlug(provider.provider)) {\n throw new Error(`Invalid integration provider id: ${provider.provider}`);\n }\n if (this.providers.has(provider.provider)) {\n throw new Error(`Duplicate integration provider registered: ${provider.provider}`);\n }\n\n this.providers.set(provider.provider, normalizeProvider(provider));\n }\n }\n\n list(capability?: IntegrationCapability | undefined): RegisteredIntegrationProvider[] {\n const providers = [...this.providers.values()];\n if (!capability) return providers;\n return providers.filter((provider) => provider.capabilities.includes(capability));\n }\n\n get(provider: IntegrationProviderKind): RegisteredIntegrationProvider {\n const resolved = this.providers.get(provider);\n if (!resolved) throw new IntegrationProviderUnavailableError(provider);\n return resolved;\n }\n\n getAdapter<Capability extends IntegrationCapability>(\n provider: IntegrationProviderKind,\n capability: Capability,\n ): NonNullable<IntegrationProviderAdapters[Capability]> {\n const resolved = this.get(provider);\n const adapter = resolved.adapters[capability];\n if (!adapter) {\n throw new IntegrationCapabilityUnavailableError(capability, provider);\n }\n return adapter as NonNullable<IntegrationProviderAdapters[Capability]>;\n }\n\n getSourceControl(\n provider: IntegrationProviderKind,\n ): NonNullable<IntegrationProviderAdapters['source_control']> {\n return this.getAdapter(provider, 'source_control');\n }\n}\n\nfunction normalizeProvider(provider: IntegrationProvider): RegisteredIntegrationProvider {\n const adapters = provider.adapters ?? {};\n return {\n ...provider,\n adapters,\n capabilities: Object.entries(adapters)\n .filter(([, adapter]) => Boolean(adapter))\n .map(([capability]) => capability as IntegrationCapability),\n };\n}\n"],"names":["isLowercaseAlphaSlug","IntegrationCapabilityUnavailableError","IntegrationProviderUnavailableError","createIntegrationProviderRegistry","providers","MapIntegrationProviderRegistry","Map","provider","Error","has","set","normalizeProvider","list","capability","values","filter","capabilities","includes","get","resolved","getAdapter","adapter","adapters","getSourceControl","Object","entries","Boolean","map"],"mappings":"AAAA,SAAQA,oBAAoB,QAAO,iBAAiB;AAQpD,SACEC,qCAAqC,EACrCC,mCAAmC,QAC9B,kBAAkB;AAczB,OAAO,SAASC,kCACdC,SAAgC;IAEhC,OAAO,IAAIC,+BAA+BD;AAC5C;AAEA,IAAA,AAAMC,iCAAN,MAAMA;IAGJ,YAAYD,SAAgC,CAAE;QAC5C,IAAI,CAACA,SAAS,GAAG,IAAIE;QAErB,KAAK,MAAMC,YAAYH,UAAW;YAChC,IAAI,CAACJ,qBAAqBO,SAASA,QAAQ,GAAG;gBAC5C,MAAM,IAAIC,MAAM,CAAC,iCAAiC,EAAED,SAASA,QAAQ,EAAE;YACzE;YACA,IAAI,IAAI,CAACH,SAAS,CAACK,GAAG,CAACF,SAASA,QAAQ,GAAG;gBACzC,MAAM,IAAIC,MAAM,CAAC,2CAA2C,EAAED,SAASA,QAAQ,EAAE;YACnF;YAEA,IAAI,CAACH,SAAS,CAACM,GAAG,CAACH,SAASA,QAAQ,EAAEI,kBAAkBJ;QAC1D;IACF;IAEAK,KAAKC,UAA8C,EAAmC;QACpF,MAAMT,YAAY;eAAI,IAAI,CAACA,SAAS,CAACU,MAAM;SAAG;QAC9C,IAAI,CAACD,YAAY,OAAOT;QACxB,OAAOA,UAAUW,MAAM,CAAC,CAACR,WAAaA,SAASS,YAAY,CAACC,QAAQ,CAACJ;IACvE;IAEAK,IAAIX,QAAiC,EAAiC;QACpE,MAAMY,WAAW,IAAI,CAACf,SAAS,CAACc,GAAG,CAACX;QACpC,IAAI,CAACY,UAAU,MAAM,IAAIjB,oCAAoCK;QAC7D,OAAOY;IACT;IAEAC,WACEb,QAAiC,EACjCM,UAAsB,EACgC;QACtD,MAAMM,WAAW,IAAI,CAACD,GAAG,CAACX;QAC1B,MAAMc,UAAUF,SAASG,QAAQ,CAACT,WAAW;QAC7C,IAAI,CAACQ,SAAS;YACZ,MAAM,IAAIpB,sCAAsCY,YAAYN;QAC9D;QACA,OAAOc;IACT;IAEAE,iBACEhB,QAAiC,EAC2B;QAC5D,OAAO,IAAI,CAACa,UAAU,CAACb,UAAU;IACnC;AACF;AAEA,SAASI,kBAAkBJ,QAA6B;IACtD,MAAMe,WAAWf,SAASe,QAAQ,IAAI,CAAC;IACvC,OAAO;QACL,GAAGf,QAAQ;QACXe;QACAN,cAAcQ,OAAOC,OAAO,CAACH,UAC1BP,MAAM,CAAC,CAAC,GAAGM,QAAQ,GAAKK,QAAQL,UAChCM,GAAG,CAAC,CAAC,CAACd,WAAW,GAAKA;IAC3B;AACF"}
1
+ {"version":3,"sources":["../../../src/core/providers/registry.ts"],"sourcesContent":["import {isLowercaseAlphaSlug} from '@shipfox/regex';\nimport type {\n IntegrationCapability,\n IntegrationProvider,\n IntegrationProviderAdapters,\n IntegrationProviderKind,\n RegisteredIntegrationProvider,\n} from '#core/entities/provider.js';\nimport {\n IntegrationCapabilityUnavailableError,\n IntegrationProviderUnavailableError,\n} from '#core/errors.js';\n\nexport interface IntegrationProviderRegistry {\n list(capability?: IntegrationCapability | undefined): RegisteredIntegrationProvider[];\n get(provider: IntegrationProviderKind): RegisteredIntegrationProvider;\n getAdapter<Capability extends IntegrationCapability>(\n provider: IntegrationProviderKind,\n capability: Capability,\n ): NonNullable<IntegrationProviderAdapters[Capability]>;\n getSourceControl(\n provider: IntegrationProviderKind,\n ): NonNullable<IntegrationProviderAdapters['source_control']>;\n}\n\nexport function createIntegrationProviderRegistry(\n providers: IntegrationProvider[],\n): IntegrationProviderRegistry {\n return new MapIntegrationProviderRegistry(providers);\n}\n\nclass MapIntegrationProviderRegistry implements IntegrationProviderRegistry {\n private readonly providers: Map<IntegrationProviderKind, RegisteredIntegrationProvider>;\n\n constructor(providers: IntegrationProvider[]) {\n this.providers = new Map();\n\n for (const provider of providers) {\n if (!isLowercaseAlphaSlug(provider.provider)) {\n throw new Error(`Invalid integration provider id: ${provider.provider}`);\n }\n if (this.providers.has(provider.provider)) {\n throw new Error(`Duplicate integration provider registered: ${provider.provider}`);\n }\n\n this.providers.set(provider.provider, normalizeProvider(provider));\n }\n }\n\n list(capability?: IntegrationCapability | undefined): RegisteredIntegrationProvider[] {\n const providers = [...this.providers.values()];\n if (!capability) return providers;\n return providers.filter((provider) => provider.capabilities.includes(capability));\n }\n\n get(provider: IntegrationProviderKind): RegisteredIntegrationProvider {\n const resolved = this.providers.get(provider);\n if (!resolved) throw new IntegrationProviderUnavailableError(provider);\n return resolved;\n }\n\n getAdapter<Capability extends IntegrationCapability>(\n provider: IntegrationProviderKind,\n capability: Capability,\n ): NonNullable<IntegrationProviderAdapters[Capability]> {\n const resolved = this.get(provider);\n const adapter = resolved.adapters[capability];\n if (!adapter) {\n throw new IntegrationCapabilityUnavailableError(capability, provider);\n }\n return adapter as NonNullable<IntegrationProviderAdapters[Capability]>;\n }\n\n getSourceControl(\n provider: IntegrationProviderKind,\n ): NonNullable<IntegrationProviderAdapters['source_control']> {\n return this.getAdapter(provider, 'source_control');\n }\n}\n\nfunction normalizeProvider(provider: IntegrationProvider): RegisteredIntegrationProvider {\n const adapters = provider.adapters ?? {};\n return {\n ...provider,\n adapters,\n capabilities: getIntegrationProviderCapabilities(adapters),\n };\n}\n\nexport function getIntegrationProviderCapabilities(\n adapters: IntegrationProvider['adapters'],\n): IntegrationCapability[] {\n return Object.entries(adapters ?? {})\n .filter(([, adapter]) => Boolean(adapter))\n .map(([capability]) => capability as IntegrationCapability);\n}\n"],"names":["isLowercaseAlphaSlug","IntegrationCapabilityUnavailableError","IntegrationProviderUnavailableError","createIntegrationProviderRegistry","providers","MapIntegrationProviderRegistry","Map","provider","Error","has","set","normalizeProvider","list","capability","values","filter","capabilities","includes","get","resolved","getAdapter","adapter","adapters","getSourceControl","getIntegrationProviderCapabilities","Object","entries","Boolean","map"],"mappings":"AAAA,SAAQA,oBAAoB,QAAO,iBAAiB;AAQpD,SACEC,qCAAqC,EACrCC,mCAAmC,QAC9B,kBAAkB;AAczB,OAAO,SAASC,kCACdC,SAAgC;IAEhC,OAAO,IAAIC,+BAA+BD;AAC5C;AAEA,IAAA,AAAMC,iCAAN,MAAMA;IAGJ,YAAYD,SAAgC,CAAE;QAC5C,IAAI,CAACA,SAAS,GAAG,IAAIE;QAErB,KAAK,MAAMC,YAAYH,UAAW;YAChC,IAAI,CAACJ,qBAAqBO,SAASA,QAAQ,GAAG;gBAC5C,MAAM,IAAIC,MAAM,CAAC,iCAAiC,EAAED,SAASA,QAAQ,EAAE;YACzE;YACA,IAAI,IAAI,CAACH,SAAS,CAACK,GAAG,CAACF,SAASA,QAAQ,GAAG;gBACzC,MAAM,IAAIC,MAAM,CAAC,2CAA2C,EAAED,SAASA,QAAQ,EAAE;YACnF;YAEA,IAAI,CAACH,SAAS,CAACM,GAAG,CAACH,SAASA,QAAQ,EAAEI,kBAAkBJ;QAC1D;IACF;IAEAK,KAAKC,UAA8C,EAAmC;QACpF,MAAMT,YAAY;eAAI,IAAI,CAACA,SAAS,CAACU,MAAM;SAAG;QAC9C,IAAI,CAACD,YAAY,OAAOT;QACxB,OAAOA,UAAUW,MAAM,CAAC,CAACR,WAAaA,SAASS,YAAY,CAACC,QAAQ,CAACJ;IACvE;IAEAK,IAAIX,QAAiC,EAAiC;QACpE,MAAMY,WAAW,IAAI,CAACf,SAAS,CAACc,GAAG,CAACX;QACpC,IAAI,CAACY,UAAU,MAAM,IAAIjB,oCAAoCK;QAC7D,OAAOY;IACT;IAEAC,WACEb,QAAiC,EACjCM,UAAsB,EACgC;QACtD,MAAMM,WAAW,IAAI,CAACD,GAAG,CAACX;QAC1B,MAAMc,UAAUF,SAASG,QAAQ,CAACT,WAAW;QAC7C,IAAI,CAACQ,SAAS;YACZ,MAAM,IAAIpB,sCAAsCY,YAAYN;QAC9D;QACA,OAAOc;IACT;IAEAE,iBACEhB,QAAiC,EAC2B;QAC5D,OAAO,IAAI,CAACa,UAAU,CAACb,UAAU;IACnC;AACF;AAEA,SAASI,kBAAkBJ,QAA6B;IACtD,MAAMe,WAAWf,SAASe,QAAQ,IAAI,CAAC;IACvC,OAAO;QACL,GAAGf,QAAQ;QACXe;QACAN,cAAcQ,mCAAmCF;IACnD;AACF;AAEA,OAAO,SAASE,mCACdF,QAAyC;IAEzC,OAAOG,OAAOC,OAAO,CAACJ,YAAY,CAAC,GAChCP,MAAM,CAAC,CAAC,GAAGM,QAAQ,GAAKM,QAAQN,UAChCO,GAAG,CAAC,CAAC,CAACf,WAAW,GAAKA;AAC3B"}
@@ -1,2 +1,2 @@
1
- export type { CheckoutCredentials, CheckoutPermissions, CheckoutSpec, CreateCheckoutSpecInput, FetchFileInput, FileEntry, FilePage, FileSnapshot, ListFilesInput, ListRepositoriesInput, RepositoryPage, RepositorySnapshot, RepositoryVisibility, ResolveRepositoryInput, SourceControlProvider, TriggerReference, } from '@shipfox/api-integration-spi';
1
+ export type { CheckoutCredentials, CheckoutPermissions, CheckoutSpec, CreateCheckoutSpecInput, FetchFileInput, FileEntry, FilePage, FileSnapshot, ListFilesInput, ListRepositoriesInput, RepositoryPage, RepositorySnapshot, RepositoryVisibility, ResolvedRef, ResolveRefInput, 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,EACrB,gBAAgB,GACjB,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,WAAW,EACX,eAAe,EACf,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 TriggerReference,\n} from '@shipfox/api-integration-spi';\n"],"names":[],"mappings":"AAAA,WAiBsC"}
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 ResolvedRef,\n ResolveRefInput,\n ResolveRepositoryInput,\n SourceControlProvider,\n TriggerReference,\n} from '@shipfox/api-integration-spi';\n"],"names":[],"mappings":"AAAA,WAmBsC"}
@@ -1,11 +1,12 @@
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, TriggerReference } from './providers/source-control.js';
3
+ import type { CheckoutPermissions, CheckoutSpec, FilePage, FileSnapshot, RepositoryPage, RepositorySnapshot, ResolvedRef, 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
8
  resolveTriggerReference(input: ResolveTriggerReferenceInput): Promise<TriggerReference | null>;
9
+ resolveSourceRef(input: ResolveSourceRefInput): Promise<ResolvedRef>;
9
10
  listFiles(input: ListSourceFilesInput): Promise<FilePage>;
10
11
  fetchFile(input: FetchSourceFileInput): Promise<FileSnapshot>;
11
12
  createCheckoutSpec(input: CreateSourceCheckoutSpecInput): Promise<CheckoutSpec>;
@@ -26,6 +27,9 @@ export interface ResolveTriggerReferenceInput {
26
27
  connectionId: string;
27
28
  payload: unknown;
28
29
  }
30
+ export interface ResolveSourceRefInput extends ResolveSourceRepositoryInput {
31
+ ref: string;
32
+ }
29
33
  export interface ListSourceFilesInput extends ResolveSourceRepositoryInput {
30
34
  ref: string;
31
35
  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,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"}
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,WAAW,EACX,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,gBAAgB,CAAC,KAAK,EAAE,qBAAqB,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC;IACrE,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,qBAAsB,SAAQ,4BAA4B;IACzE,GAAG,EAAE,MAAM,CAAC;CACb;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,CAgHhF"}
@@ -45,6 +45,18 @@ export function createSourceControlIntegrationService({ registry, getIntegration
45
45
  const sourceControl = registry.get(connection.provider).adapters.source_control;
46
46
  return sourceControl?.resolveTriggerReference(payload) ?? null;
47
47
  },
48
+ async resolveSourceRef ({ workspaceId, connectionId, externalRepositoryId, ref }) {
49
+ const connection = await getConnection(connectionId);
50
+ if (connection.workspaceId !== workspaceId) {
51
+ throw new IntegrationConnectionWorkspaceMismatchError(connectionId);
52
+ }
53
+ const sourceControl = registry.getAdapter(connection.provider, 'source_control');
54
+ return await sourceControl.resolveRef({
55
+ connection,
56
+ externalRepositoryId,
57
+ ref
58
+ });
59
+ },
48
60
  async listFiles ({ workspaceId, connectionId, externalRepositoryId, ref, prefix, limit, cursor }) {
49
61
  const connection = await getConnection(connectionId);
50
62
  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 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":"AACA,SACEA,mCAAmC,EACnCC,kCAAkC,EAClCC,kCAAkC,EAClCC,2CAA2C,QACtC,cAAc;AAsErB,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,yBAAwB,EAACH,WAAW,EAAEZ,YAAY,EAAEgB,OAAO,EAAC;YAChE,MAAMf,aAAa,MAAMF,cAAcC;YACvC,IAAIC,WAAWW,WAAW,KAAKA,aAAa;gBAC1C,MAAM,IAAIjB,4CAA4CK;YACxD;YAEA,wEAAwE;YACxE,uEAAuE;YACvE,8BAA8B;YAC9B,MAAMQ,gBAAgBX,SAASoB,GAAG,CAAChB,WAAWS,QAAQ,EAAEQ,QAAQ,CAACC,cAAc;YAC/E,OAAOX,eAAeO,wBAAwBC,YAAY;QAC5D;QAEA,MAAMI,WAAU,EAACR,WAAW,EAAEZ,YAAY,EAAEa,oBAAoB,EAAEQ,GAAG,EAAEC,MAAM,EAAEjB,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,cAAcY,SAAS,CAAC;gBACnCnB;gBACAY;gBACAQ;gBACAC;gBACAjB;gBACAC;YACF;QACF;QAEA,MAAMiB,WAAU,EAACX,WAAW,EAAEZ,YAAY,EAAEa,oBAAoB,EAAEQ,GAAG,EAAEG,IAAI,EAAC;YAC1E,MAAMvB,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,cAAce,SAAS,CAAC;gBACnCtB;gBACAY;gBACAQ;gBACAG;YACF;QACF;QAEA,MAAMC,oBAAmB,EAACb,WAAW,EAAEZ,YAAY,EAAEa,oBAAoB,EAAEQ,GAAG,EAAEK,WAAW,EAAC;YAC1F,MAAMzB,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,cAAciB,kBAAkB,EAAE;gBACrC,MAAM,IAAIjC,oCAAoCS,WAAWS,QAAQ;YACnE;YAEA,OAAO,MAAMF,cAAciB,kBAAkB,CAAC;gBAC5CxB;gBACAY;gBACAQ;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 ResolvedRef,\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 resolveSourceRef(input: ResolveSourceRefInput): Promise<ResolvedRef>;\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 ResolveSourceRefInput extends ResolveSourceRepositoryInput {\n ref: 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 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 resolveSourceRef({workspaceId, connectionId, externalRepositoryId, ref}) {\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.resolveRef({connection, externalRepositoryId, ref});\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","resolveSourceRef","ref","resolveRef","listFiles","prefix","fetchFile","path","createCheckoutSpec","permissions"],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  import type { IntegrationConnection, IntegrationConnectionLifecycleStatus } from '#core/entities/connection.js';
2
- import type { IntegrationProviderKind } from '#core/entities/provider.js';
2
+ import type { IntegrationCapability, IntegrationProviderKind } from '#core/entities/provider.js';
3
3
  import { db } from './db.js';
4
4
  type IntegrationDb = ReturnType<typeof db>;
5
5
  type IntegrationTx = Parameters<Parameters<IntegrationDb['transaction']>[0]>[0];
@@ -10,6 +10,7 @@ export interface UpsertIntegrationConnectionParams {
10
10
  slug: string;
11
11
  displayName: string;
12
12
  lifecycleStatus?: IntegrationConnectionLifecycleStatus | undefined;
13
+ capabilities?: IntegrationCapability[] | undefined;
13
14
  }
14
15
  export declare function upsertIntegrationConnection(params: UpsertIntegrationConnectionParams, options?: {
15
16
  tx?: IntegrationDb | IntegrationTx | undefined;
@@ -21,6 +22,7 @@ export interface CreateIntegrationConnectionParams {
21
22
  slug: string;
22
23
  displayName: string;
23
24
  lifecycleStatus?: IntegrationConnectionLifecycleStatus | undefined;
25
+ capabilities?: IntegrationCapability[] | undefined;
24
26
  }
25
27
  export declare function isIntegrationConnectionUniqueViolation(error: unknown): boolean;
26
28
  export declare function isIntegrationConnectionSlugUniqueViolation(error: unknown): boolean;
@@ -50,6 +52,7 @@ export type GetIntegrationConnectionBySlugFn = typeof getIntegrationConnectionBy
50
52
  export interface UpdateIntegrationConnectionLifecycleStatusParams {
51
53
  id: string;
52
54
  lifecycleStatus: IntegrationConnectionLifecycleStatus;
55
+ capabilities?: IntegrationCapability[] | undefined;
53
56
  }
54
57
  export declare function updateIntegrationConnectionLifecycleStatus(params: UpdateIntegrationConnectionLifecycleStatusParams, options?: {
55
58
  tx?: IntegrationDb | IntegrationTx | undefined;
@@ -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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"}
@@ -1,4 +1,4 @@
1
- import { CONNECTION_SLUG_MAX_LENGTH, INTEGRATION_CONNECTION_AVAILABLE } from '@shipfox/api-integration-core-dto';
1
+ import { CONNECTION_SLUG_MAX_LENGTH, INTEGRATION_CONNECTION_AVAILABLE, RESERVED_CONNECTION_SLUGS } from '@shipfox/api-integration-core-dto';
2
2
  import { ConnectionSlugConflictError } from '@shipfox/api-integration-spi';
3
3
  import { writeOutboxEvent } from '@shipfox/node-outbox';
4
4
  import { and, eq } from 'drizzle-orm';
@@ -7,6 +7,7 @@ import { db } from './db.js';
7
7
  import { integrationConnections, toIntegrationConnection } from './schema/connections.js';
8
8
  import { integrationsOutbox } from './schema/outbox.js';
9
9
  export async function upsertIntegrationConnection(params, options = {}) {
10
+ assertConnectionSlugIsNotReserved(params.slug);
10
11
  if (options.tx === undefined) {
11
12
  return await db().transaction((tx)=>upsertIntegrationConnection(params, {
12
13
  tx
@@ -45,7 +46,7 @@ export async function upsertIntegrationConnection(params, options = {}) {
45
46
  if (!row) throw new Error('Integration connection upsert returned no rows');
46
47
  const connection = toIntegrationConnection(row);
47
48
  if (becameAvailable) {
48
- await writeConnectionAvailableEvent(executor, connection);
49
+ await writeConnectionAvailableEvent(executor, connection, params.capabilities);
49
50
  }
50
51
  return connection;
51
52
  }
@@ -76,6 +77,7 @@ export function isIntegrationConnectionSlugUniqueViolation(error) {
76
77
  return false;
77
78
  }
78
79
  export async function createIntegrationConnection(params, options = {}) {
80
+ assertConnectionSlugIsNotReserved(params.slug);
79
81
  if (options.tx === undefined) {
80
82
  return await db().transaction((tx)=>createIntegrationConnection(params, {
81
83
  tx
@@ -105,11 +107,12 @@ export async function createIntegrationConnection(params, options = {}) {
105
107
  if (!row) throw new Error('Integration connection insert returned no rows');
106
108
  const connection = toIntegrationConnection(row);
107
109
  if (connection.lifecycleStatus === 'active') {
108
- await writeConnectionAvailableEvent(executor, connection);
110
+ await writeConnectionAvailableEvent(executor, connection, params.capabilities);
109
111
  }
110
112
  return connection;
111
113
  }
112
114
  export async function resolveUniqueConnectionSlug(params, options = {}) {
115
+ assertConnectionSlugIsNotReserved(params.baseSlug);
113
116
  const executor = options.tx ?? db();
114
117
  const [existing] = await executor.select({
115
118
  slug: integrationConnections.slug
@@ -126,6 +129,11 @@ export async function resolveUniqueConnectionSlug(params, options = {}) {
126
129
  if (!used.has(candidate)) return candidate;
127
130
  }
128
131
  }
132
+ function assertConnectionSlugIsNotReserved(slug) {
133
+ const normalizedSlug = slug.toLowerCase().replaceAll(/[_-]+$/g, '');
134
+ if (!RESERVED_CONNECTION_SLUGS.includes(normalizedSlug)) return;
135
+ throw new ConnectionSlugConflictError(new Error(`Slug "${slug}" is reserved for a built-in trigger source`));
136
+ }
129
137
  export async function getIntegrationConnectionById(id, options = {}) {
130
138
  const executor = options.tx ?? db();
131
139
  const rows = await executor.select().from(integrationConnections).where(eq(integrationConnections.id, id)).limit(1);
@@ -157,18 +165,19 @@ export async function updateIntegrationConnectionLifecycleStatus(params, options
157
165
  if (!row) return undefined;
158
166
  const connection = toIntegrationConnection(row);
159
167
  if (existing.lifecycleStatus !== 'active' && connection.lifecycleStatus === 'active') {
160
- await writeConnectionAvailableEvent(executor, connection);
168
+ await writeConnectionAvailableEvent(executor, connection, params.capabilities);
161
169
  }
162
170
  return connection;
163
171
  }
164
- async function writeConnectionAvailableEvent(executor, connection) {
172
+ async function writeConnectionAvailableEvent(executor, connection, capabilities) {
165
173
  await writeOutboxEvent(executor, integrationsOutbox, {
166
174
  type: INTEGRATION_CONNECTION_AVAILABLE,
167
175
  payload: {
168
176
  provider: connection.provider,
169
177
  workspaceId: connection.workspaceId,
170
178
  connectionId: connection.id,
171
- slug: connection.slug
179
+ slug: connection.slug,
180
+ capabilities: capabilities ?? []
172
181
  }
173
182
  });
174
183
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/db/connections.ts"],"sourcesContent":["import {\n CONNECTION_SLUG_MAX_LENGTH,\n INTEGRATION_CONNECTION_AVAILABLE,\n type IntegrationsEventMap,\n} from '@shipfox/api-integration-core-dto';\nimport {ConnectionSlugConflictError} from '@shipfox/api-integration-spi';\nimport {writeOutboxEvent} from '@shipfox/node-outbox';\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';\nimport {integrationsOutbox} from './schema/outbox.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 if (options.tx === undefined) {\n return await db().transaction((tx) => upsertIntegrationConnection(params, {tx}));\n }\n\n const executor = options.tx;\n const now = new Date();\n let [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 .onConflictDoNothing({\n target: [\n integrationConnections.workspaceId,\n integrationConnections.provider,\n integrationConnections.externalAccountId,\n ],\n })\n .returning();\n\n let becameAvailable = row?.lifecycleStatus === 'active';\n if (!row) {\n const [existing] = await executor\n .select({\n id: integrationConnections.id,\n lifecycleStatus: integrationConnections.lifecycleStatus,\n })\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 .for('update');\n if (!existing) throw new Error('Integration connection upsert conflict row was not found');\n\n [row] = await executor\n .update(integrationConnections)\n .set({\n displayName: params.displayName,\n lifecycleStatus: params.lifecycleStatus ?? 'active',\n updatedAt: now,\n })\n .where(eq(integrationConnections.id, existing.id))\n .returning();\n becameAvailable = existing.lifecycleStatus !== 'active' && row?.lifecycleStatus === 'active';\n }\n\n if (!row) throw new Error('Integration connection upsert returned no rows');\n const connection = toIntegrationConnection(row);\n if (becameAvailable) {\n await writeConnectionAvailableEvent(executor, connection);\n }\n return connection;\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 if (options.tx === undefined) {\n return await db().transaction((tx) => createIntegrationConnection(params, {tx}));\n }\n\n const executor = options.tx;\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 const connection = toIntegrationConnection(row);\n if (connection.lifecycleStatus === 'active') {\n await writeConnectionAvailableEvent(executor, connection);\n }\n return connection;\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 if (options.tx === undefined) {\n return await db().transaction((tx) => updateIntegrationConnectionLifecycleStatus(params, {tx}));\n }\n\n const executor = options.tx;\n const [existing] = await executor\n .select({lifecycleStatus: integrationConnections.lifecycleStatus})\n .from(integrationConnections)\n .where(eq(integrationConnections.id, params.id))\n .limit(1)\n .for('update');\n if (!existing) return undefined;\n\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 const connection = toIntegrationConnection(row);\n if (existing.lifecycleStatus !== 'active' && connection.lifecycleStatus === 'active') {\n await writeConnectionAvailableEvent(executor, connection);\n }\n return connection;\n}\n\nexport type UpdateIntegrationConnectionLifecycleStatusFn =\n typeof updateIntegrationConnectionLifecycleStatus;\n\nasync function writeConnectionAvailableEvent(\n executor: IntegrationDb | IntegrationTx,\n connection: IntegrationConnection,\n): Promise<void> {\n await writeOutboxEvent<IntegrationsEventMap>(executor, integrationsOutbox, {\n type: INTEGRATION_CONNECTION_AVAILABLE,\n payload: {\n provider: connection.provider,\n workspaceId: connection.workspaceId,\n connectionId: connection.id,\n slug: connection.slug,\n },\n });\n}\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","INTEGRATION_CONNECTION_AVAILABLE","ConnectionSlugConflictError","writeOutboxEvent","and","eq","IntegrationConnectionAlreadyExistsError","db","integrationConnections","toIntegrationConnection","integrationsOutbox","upsertIntegrationConnection","params","options","tx","undefined","transaction","executor","now","Date","row","insert","values","workspaceId","provider","externalAccountId","slug","displayName","lifecycleStatus","onConflictDoNothing","target","returning","becameAvailable","existing","select","id","from","where","limit","for","Error","update","set","updatedAt","connection","writeConnectionAvailableEvent","INTEGRATION_CONNECTION_EXTERNAL_UNIQUE_CONSTRAINT","INTEGRATION_CONNECTION_SLUG_UNIQUE_CONSTRAINT","isIntegrationConnectionUniqueViolation","error","current","depth","code","constraint","cause","isIntegrationConnectionSlugUniqueViolation","createIntegrationConnection","rows","resolveUniqueConnectionSlug","workspaceSlugs","used","Set","map","suffixNumber","suffix","baseBudget","length","candidate","baseSlug","slice","replaceAll","has","getIntegrationConnectionById","getIntegrationConnectionBySlug","updateIntegrationConnectionLifecycleStatus","type","payload","connectionId","deleteIntegrationConnection","result","delete","rowCount","listIntegrationConnections","orderBy","createdAt","connections","listIntegrationConnectionsByProvider"],"mappings":"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"}
1
+ {"version":3,"sources":["../../src/db/connections.ts"],"sourcesContent":["import {\n CONNECTION_SLUG_MAX_LENGTH,\n INTEGRATION_CONNECTION_AVAILABLE,\n type IntegrationsEventMap,\n RESERVED_CONNECTION_SLUGS,\n} from '@shipfox/api-integration-core-dto';\nimport {ConnectionSlugConflictError} from '@shipfox/api-integration-spi';\nimport {writeOutboxEvent} from '@shipfox/node-outbox';\nimport {and, eq} from 'drizzle-orm';\nimport type {\n IntegrationConnection,\n IntegrationConnectionLifecycleStatus,\n} from '#core/entities/connection.js';\nimport type {IntegrationCapability, IntegrationProviderKind} from '#core/entities/provider.js';\nimport {IntegrationConnectionAlreadyExistsError} from '#core/errors.js';\nimport {db} from './db.js';\nimport {integrationConnections, toIntegrationConnection} from './schema/connections.js';\nimport {integrationsOutbox} from './schema/outbox.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 capabilities?: IntegrationCapability[] | undefined;\n}\n\nexport async function upsertIntegrationConnection(\n params: UpsertIntegrationConnectionParams,\n options: {tx?: IntegrationDb | IntegrationTx | undefined} = {},\n): Promise<IntegrationConnection> {\n assertConnectionSlugIsNotReserved(params.slug);\n if (options.tx === undefined) {\n return await db().transaction((tx) => upsertIntegrationConnection(params, {tx}));\n }\n\n const executor = options.tx;\n const now = new Date();\n let [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 .onConflictDoNothing({\n target: [\n integrationConnections.workspaceId,\n integrationConnections.provider,\n integrationConnections.externalAccountId,\n ],\n })\n .returning();\n\n let becameAvailable = row?.lifecycleStatus === 'active';\n if (!row) {\n const [existing] = await executor\n .select({\n id: integrationConnections.id,\n lifecycleStatus: integrationConnections.lifecycleStatus,\n })\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 .for('update');\n if (!existing) throw new Error('Integration connection upsert conflict row was not found');\n\n [row] = await executor\n .update(integrationConnections)\n .set({\n displayName: params.displayName,\n lifecycleStatus: params.lifecycleStatus ?? 'active',\n updatedAt: now,\n })\n .where(eq(integrationConnections.id, existing.id))\n .returning();\n becameAvailable = existing.lifecycleStatus !== 'active' && row?.lifecycleStatus === 'active';\n }\n\n if (!row) throw new Error('Integration connection upsert returned no rows');\n const connection = toIntegrationConnection(row);\n if (becameAvailable) {\n await writeConnectionAvailableEvent(executor, connection, params.capabilities);\n }\n return connection;\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 capabilities?: IntegrationCapability[] | 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 assertConnectionSlugIsNotReserved(params.slug);\n if (options.tx === undefined) {\n return await db().transaction((tx) => createIntegrationConnection(params, {tx}));\n }\n\n const executor = options.tx;\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 const connection = toIntegrationConnection(row);\n if (connection.lifecycleStatus === 'active') {\n await writeConnectionAvailableEvent(executor, connection, params.capabilities);\n }\n return connection;\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 assertConnectionSlugIsNotReserved(params.baseSlug);\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\nfunction assertConnectionSlugIsNotReserved(slug: string): void {\n const normalizedSlug = slug.toLowerCase().replaceAll(/[_-]+$/g, '');\n if (!(RESERVED_CONNECTION_SLUGS as readonly string[]).includes(normalizedSlug)) return;\n throw new ConnectionSlugConflictError(\n new Error(`Slug \"${slug}\" is reserved for a built-in trigger source`),\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 capabilities?: IntegrationCapability[] | undefined;\n}\n\nexport async function updateIntegrationConnectionLifecycleStatus(\n params: UpdateIntegrationConnectionLifecycleStatusParams,\n options: {tx?: IntegrationDb | IntegrationTx | undefined} = {},\n): Promise<IntegrationConnection | undefined> {\n if (options.tx === undefined) {\n return await db().transaction((tx) => updateIntegrationConnectionLifecycleStatus(params, {tx}));\n }\n\n const executor = options.tx;\n const [existing] = await executor\n .select({lifecycleStatus: integrationConnections.lifecycleStatus})\n .from(integrationConnections)\n .where(eq(integrationConnections.id, params.id))\n .limit(1)\n .for('update');\n if (!existing) return undefined;\n\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 const connection = toIntegrationConnection(row);\n if (existing.lifecycleStatus !== 'active' && connection.lifecycleStatus === 'active') {\n await writeConnectionAvailableEvent(executor, connection, params.capabilities);\n }\n return connection;\n}\n\nexport type UpdateIntegrationConnectionLifecycleStatusFn =\n typeof updateIntegrationConnectionLifecycleStatus;\n\nasync function writeConnectionAvailableEvent(\n executor: IntegrationDb | IntegrationTx,\n connection: IntegrationConnection,\n capabilities: IntegrationCapability[] | undefined,\n): Promise<void> {\n await writeOutboxEvent<IntegrationsEventMap>(executor, integrationsOutbox, {\n type: INTEGRATION_CONNECTION_AVAILABLE,\n payload: {\n provider: connection.provider,\n workspaceId: connection.workspaceId,\n connectionId: connection.id,\n slug: connection.slug,\n capabilities: capabilities ?? [],\n },\n });\n}\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","INTEGRATION_CONNECTION_AVAILABLE","RESERVED_CONNECTION_SLUGS","ConnectionSlugConflictError","writeOutboxEvent","and","eq","IntegrationConnectionAlreadyExistsError","db","integrationConnections","toIntegrationConnection","integrationsOutbox","upsertIntegrationConnection","params","options","assertConnectionSlugIsNotReserved","slug","tx","undefined","transaction","executor","now","Date","row","insert","values","workspaceId","provider","externalAccountId","displayName","lifecycleStatus","onConflictDoNothing","target","returning","becameAvailable","existing","select","id","from","where","limit","for","Error","update","set","updatedAt","connection","writeConnectionAvailableEvent","capabilities","INTEGRATION_CONNECTION_EXTERNAL_UNIQUE_CONSTRAINT","INTEGRATION_CONNECTION_SLUG_UNIQUE_CONSTRAINT","isIntegrationConnectionUniqueViolation","error","current","depth","code","constraint","cause","isIntegrationConnectionSlugUniqueViolation","createIntegrationConnection","rows","resolveUniqueConnectionSlug","baseSlug","workspaceSlugs","used","Set","map","suffixNumber","suffix","baseBudget","length","candidate","slice","replaceAll","has","normalizedSlug","toLowerCase","includes","getIntegrationConnectionById","getIntegrationConnectionBySlug","updateIntegrationConnectionLifecycleStatus","type","payload","connectionId","deleteIntegrationConnection","result","delete","rowCount","listIntegrationConnections","orderBy","createdAt","connections","listIntegrationConnectionsByProvider"],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -17,7 +17,7 @@ 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, TriggerReference, } from '#core/providers/source-control.js';
20
+ export type { CheckoutCredentials, CheckoutPermissions, CheckoutSpec, CreateCheckoutSpecInput, FetchFileInput, FileEntry, FilePage, FileSnapshot, ListFilesInput, ListRepositoriesInput, RepositoryPage, RepositorySnapshot, RepositoryVisibility, ResolvedRef, ResolveRefInput, 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
23
  export type { GetIntegrationConnectionByIdFn, GetIntegrationConnectionBySlugFn, } from '#db/connections.js';
@@ -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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"}