@shipfox/api-integration-slack 4.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 (158) hide show
  1. package/.turbo/turbo-build.log +2 -0
  2. package/.turbo/turbo-type$colon$emit.log +1 -0
  3. package/.turbo/turbo-type.log +1 -0
  4. package/CHANGELOG.md +22 -0
  5. package/LICENSE +21 -0
  6. package/dist/api/client.d.ts +28 -0
  7. package/dist/api/client.d.ts.map +1 -0
  8. package/dist/api/client.js +163 -0
  9. package/dist/api/client.js.map +1 -0
  10. package/dist/config.d.ts +8 -0
  11. package/dist/config.d.ts.map +1 -0
  12. package/dist/config.js +21 -0
  13. package/dist/config.js.map +1 -0
  14. package/dist/core/agent-tools-provider.d.ts +75 -0
  15. package/dist/core/agent-tools-provider.d.ts.map +1 -0
  16. package/dist/core/agent-tools-provider.js +111 -0
  17. package/dist/core/agent-tools-provider.js.map +1 -0
  18. package/dist/core/agent-tools.d.ts +65 -0
  19. package/dist/core/agent-tools.d.ts.map +1 -0
  20. package/dist/core/agent-tools.js +177 -0
  21. package/dist/core/agent-tools.js.map +1 -0
  22. package/dist/core/disconnect.d.ts +18 -0
  23. package/dist/core/disconnect.d.ts.map +1 -0
  24. package/dist/core/disconnect.js +23 -0
  25. package/dist/core/disconnect.js.map +1 -0
  26. package/dist/core/errors.d.ts +44 -0
  27. package/dist/core/errors.d.ts.map +1 -0
  28. package/dist/core/errors.js +71 -0
  29. package/dist/core/errors.js.map +1 -0
  30. package/dist/core/install.d.ts +48 -0
  31. package/dist/core/install.d.ts.map +1 -0
  32. package/dist/core/install.js +88 -0
  33. package/dist/core/install.js.map +1 -0
  34. package/dist/core/scopes.d.ts +4 -0
  35. package/dist/core/scopes.d.ts.map +1 -0
  36. package/dist/core/scopes.js +24 -0
  37. package/dist/core/scopes.js.map +1 -0
  38. package/dist/core/signature.d.ts +10 -0
  39. package/dist/core/signature.d.ts.map +1 -0
  40. package/dist/core/signature.js +18 -0
  41. package/dist/core/signature.js.map +1 -0
  42. package/dist/core/state.d.ts +12 -0
  43. package/dist/core/state.d.ts.map +1 -0
  44. package/dist/core/state.js +54 -0
  45. package/dist/core/state.js.map +1 -0
  46. package/dist/core/tokens.d.ts +35 -0
  47. package/dist/core/tokens.d.ts.map +1 -0
  48. package/dist/core/tokens.js +51 -0
  49. package/dist/core/tokens.js.map +1 -0
  50. package/dist/core/webhook.d.ts +25 -0
  51. package/dist/core/webhook.d.ts.map +1 -0
  52. package/dist/core/webhook.js +160 -0
  53. package/dist/core/webhook.js.map +1 -0
  54. package/dist/db/db.d.ts +403 -0
  55. package/dist/db/db.d.ts.map +1 -0
  56. package/dist/db/db.js +18 -0
  57. package/dist/db/db.js.map +1 -0
  58. package/dist/db/installations.d.ts +40 -0
  59. package/dist/db/installations.d.ts.map +1 -0
  60. package/dist/db/installations.js +73 -0
  61. package/dist/db/installations.js.map +1 -0
  62. package/dist/db/migrations.d.ts +2 -0
  63. package/dist/db/migrations.d.ts.map +1 -0
  64. package/dist/db/migrations.js +5 -0
  65. package/dist/db/migrations.js.map +1 -0
  66. package/dist/db/schema/common.d.ts +2 -0
  67. package/dist/db/schema/common.d.ts.map +1 -0
  68. package/dist/db/schema/common.js +4 -0
  69. package/dist/db/schema/common.js.map +1 -0
  70. package/dist/db/schema/installations.d.ts +203 -0
  71. package/dist/db/schema/installations.d.ts.map +1 -0
  72. package/dist/db/schema/installations.js +42 -0
  73. package/dist/db/schema/installations.js.map +1 -0
  74. package/dist/index.d.ts +59 -0
  75. package/dist/index.d.ts.map +1 -0
  76. package/dist/index.js +73 -0
  77. package/dist/index.js.map +1 -0
  78. package/dist/presentation/dto/integrations.d.ts +2 -0
  79. package/dist/presentation/dto/integrations.d.ts.map +1 -0
  80. package/dist/presentation/dto/integrations.js +3 -0
  81. package/dist/presentation/dto/integrations.js.map +1 -0
  82. package/dist/presentation/e2eRoutes/create-connection.d.ts +16 -0
  83. package/dist/presentation/e2eRoutes/create-connection.d.ts.map +1 -0
  84. package/dist/presentation/e2eRoutes/create-connection.js +65 -0
  85. package/dist/presentation/e2eRoutes/create-connection.js.map +1 -0
  86. package/dist/presentation/e2eRoutes/index.d.ts +5 -0
  87. package/dist/presentation/e2eRoutes/index.d.ts.map +1 -0
  88. package/dist/presentation/e2eRoutes/index.js +11 -0
  89. package/dist/presentation/e2eRoutes/index.js.map +1 -0
  90. package/dist/presentation/routes/errors.d.ts +2 -0
  91. package/dist/presentation/routes/errors.d.ts.map +1 -0
  92. package/dist/presentation/routes/errors.js +75 -0
  93. package/dist/presentation/routes/errors.js.map +1 -0
  94. package/dist/presentation/routes/install.d.ts +19 -0
  95. package/dist/presentation/routes/install.d.ts.map +1 -0
  96. package/dist/presentation/routes/install.js +98 -0
  97. package/dist/presentation/routes/install.js.map +1 -0
  98. package/dist/presentation/routes/webhooks.d.ts +16 -0
  99. package/dist/presentation/routes/webhooks.d.ts.map +1 -0
  100. package/dist/presentation/routes/webhooks.js +166 -0
  101. package/dist/presentation/routes/webhooks.js.map +1 -0
  102. package/dist/tsconfig.test.tsbuildinfo +1 -0
  103. package/drizzle/0000_calm_fantastic_four.sql +16 -0
  104. package/drizzle/meta/0000_snapshot.json +132 -0
  105. package/drizzle/meta/_journal.json +13 -0
  106. package/drizzle.config.ts +7 -0
  107. package/package.json +71 -0
  108. package/src/api/client.test.ts +239 -0
  109. package/src/api/client.ts +243 -0
  110. package/src/config.test.ts +32 -0
  111. package/src/config.ts +20 -0
  112. package/src/connection-external-url.test.ts +25 -0
  113. package/src/core/agent-tools-provider.test.ts +256 -0
  114. package/src/core/agent-tools-provider.ts +147 -0
  115. package/src/core/agent-tools.test.ts +90 -0
  116. package/src/core/agent-tools.ts +189 -0
  117. package/src/core/disconnect.ts +26 -0
  118. package/src/core/errors.ts +92 -0
  119. package/src/core/install.test.ts +155 -0
  120. package/src/core/install.ts +137 -0
  121. package/src/core/scopes.test.ts +22 -0
  122. package/src/core/scopes.ts +25 -0
  123. package/src/core/signature.test.ts +45 -0
  124. package/src/core/signature.ts +41 -0
  125. package/src/core/state.test.ts +48 -0
  126. package/src/core/state.ts +82 -0
  127. package/src/core/tokens.test.ts +163 -0
  128. package/src/core/tokens.ts +98 -0
  129. package/src/core/webhook.test.ts +269 -0
  130. package/src/core/webhook.ts +223 -0
  131. package/src/db/db.ts +16 -0
  132. package/src/db/installations.test.ts +93 -0
  133. package/src/db/installations.ts +141 -0
  134. package/src/db/migrations.ts +4 -0
  135. package/src/db/schema/common.ts +3 -0
  136. package/src/db/schema/installations.ts +44 -0
  137. package/src/index.test.ts +25 -0
  138. package/src/index.ts +196 -0
  139. package/src/presentation/dto/integrations.ts +1 -0
  140. package/src/presentation/e2eRoutes/create-connection.ts +82 -0
  141. package/src/presentation/e2eRoutes/index.test.ts +96 -0
  142. package/src/presentation/e2eRoutes/index.ts +11 -0
  143. package/src/presentation/routes/errors.ts +68 -0
  144. package/src/presentation/routes/install.test.ts +229 -0
  145. package/src/presentation/routes/install.ts +117 -0
  146. package/src/presentation/routes/webhooks.test.ts +266 -0
  147. package/src/presentation/routes/webhooks.ts +170 -0
  148. package/test/api-secrets.d.ts +26 -0
  149. package/test/env.ts +13 -0
  150. package/test/factories/index.ts +1 -0
  151. package/test/globalSetup.ts +23 -0
  152. package/test/index.ts +1 -0
  153. package/test/setup.ts +17 -0
  154. package/tsconfig.build.json +9 -0
  155. package/tsconfig.build.tsbuildinfo +1 -0
  156. package/tsconfig.json +3 -0
  157. package/tsconfig.test.json +9 -0
  158. package/vitest.config.ts +12 -0
@@ -0,0 +1,203 @@
1
+ import type { SlackInstallation } from '#db/installations.js';
2
+ export declare const slackInstallations: import("drizzle-orm/pg-core").PgTableWithColumns<{
3
+ name: "installations";
4
+ schema: undefined;
5
+ columns: {
6
+ id: import("drizzle-orm/pg-core").PgColumn<{
7
+ name: "id";
8
+ tableName: "installations";
9
+ dataType: "string";
10
+ columnType: "PgUUID";
11
+ data: string;
12
+ driverParam: string;
13
+ notNull: true;
14
+ hasDefault: true;
15
+ isPrimaryKey: true;
16
+ isAutoincrement: false;
17
+ hasRuntimeDefault: false;
18
+ enumValues: undefined;
19
+ baseColumn: never;
20
+ identity: undefined;
21
+ generated: undefined;
22
+ }, {}, {}>;
23
+ connectionId: import("drizzle-orm/pg-core").PgColumn<{
24
+ name: "connection_id";
25
+ tableName: "installations";
26
+ dataType: "string";
27
+ columnType: "PgUUID";
28
+ data: string;
29
+ driverParam: string;
30
+ notNull: true;
31
+ hasDefault: false;
32
+ isPrimaryKey: false;
33
+ isAutoincrement: false;
34
+ hasRuntimeDefault: false;
35
+ enumValues: undefined;
36
+ baseColumn: never;
37
+ identity: undefined;
38
+ generated: undefined;
39
+ }, {}, {}>;
40
+ teamId: import("drizzle-orm/pg-core").PgColumn<{
41
+ name: "team_id";
42
+ tableName: "installations";
43
+ dataType: "string";
44
+ columnType: "PgText";
45
+ data: string;
46
+ driverParam: string;
47
+ notNull: true;
48
+ hasDefault: false;
49
+ isPrimaryKey: false;
50
+ isAutoincrement: false;
51
+ hasRuntimeDefault: false;
52
+ enumValues: [string, ...string[]];
53
+ baseColumn: never;
54
+ identity: undefined;
55
+ generated: undefined;
56
+ }, {}, {}>;
57
+ teamName: import("drizzle-orm/pg-core").PgColumn<{
58
+ name: "team_name";
59
+ tableName: "installations";
60
+ dataType: "string";
61
+ columnType: "PgText";
62
+ data: string;
63
+ driverParam: string;
64
+ notNull: true;
65
+ hasDefault: false;
66
+ isPrimaryKey: false;
67
+ isAutoincrement: false;
68
+ hasRuntimeDefault: false;
69
+ enumValues: [string, ...string[]];
70
+ baseColumn: never;
71
+ identity: undefined;
72
+ generated: undefined;
73
+ }, {}, {}>;
74
+ appId: import("drizzle-orm/pg-core").PgColumn<{
75
+ name: "app_id";
76
+ tableName: "installations";
77
+ dataType: "string";
78
+ columnType: "PgText";
79
+ data: string;
80
+ driverParam: string;
81
+ notNull: true;
82
+ hasDefault: false;
83
+ isPrimaryKey: false;
84
+ isAutoincrement: false;
85
+ hasRuntimeDefault: false;
86
+ enumValues: [string, ...string[]];
87
+ baseColumn: never;
88
+ identity: undefined;
89
+ generated: undefined;
90
+ }, {}, {}>;
91
+ botUserId: import("drizzle-orm/pg-core").PgColumn<{
92
+ name: "bot_user_id";
93
+ tableName: "installations";
94
+ dataType: "string";
95
+ columnType: "PgText";
96
+ data: string;
97
+ driverParam: string;
98
+ notNull: true;
99
+ hasDefault: false;
100
+ isPrimaryKey: false;
101
+ isAutoincrement: false;
102
+ hasRuntimeDefault: false;
103
+ enumValues: [string, ...string[]];
104
+ baseColumn: never;
105
+ identity: undefined;
106
+ generated: undefined;
107
+ }, {}, {}>;
108
+ scopes: import("drizzle-orm/pg-core").PgColumn<{
109
+ name: "scopes";
110
+ tableName: "installations";
111
+ dataType: "json";
112
+ columnType: "PgJsonb";
113
+ data: string[];
114
+ driverParam: unknown;
115
+ notNull: true;
116
+ hasDefault: false;
117
+ isPrimaryKey: false;
118
+ isAutoincrement: false;
119
+ hasRuntimeDefault: false;
120
+ enumValues: undefined;
121
+ baseColumn: never;
122
+ identity: undefined;
123
+ generated: undefined;
124
+ }, {}, {
125
+ $type: string[];
126
+ }>;
127
+ status: import("drizzle-orm/pg-core").PgColumn<{
128
+ name: "status";
129
+ tableName: "installations";
130
+ dataType: "string";
131
+ columnType: "PgText";
132
+ data: import("#db/installations.js").SlackInstallationStatus;
133
+ driverParam: string;
134
+ notNull: true;
135
+ hasDefault: false;
136
+ isPrimaryKey: false;
137
+ isAutoincrement: false;
138
+ hasRuntimeDefault: false;
139
+ enumValues: [string, ...string[]];
140
+ baseColumn: never;
141
+ identity: undefined;
142
+ generated: undefined;
143
+ }, {}, {
144
+ $type: import("#db/installations.js").SlackInstallationStatus;
145
+ }>;
146
+ tokenExpiresAt: import("drizzle-orm/pg-core").PgColumn<{
147
+ name: "token_expires_at";
148
+ tableName: "installations";
149
+ dataType: "date";
150
+ columnType: "PgTimestamp";
151
+ data: Date;
152
+ driverParam: string;
153
+ notNull: false;
154
+ hasDefault: false;
155
+ isPrimaryKey: false;
156
+ isAutoincrement: false;
157
+ hasRuntimeDefault: false;
158
+ enumValues: undefined;
159
+ baseColumn: never;
160
+ identity: undefined;
161
+ generated: undefined;
162
+ }, {}, {}>;
163
+ createdAt: import("drizzle-orm/pg-core").PgColumn<{
164
+ name: "created_at";
165
+ tableName: "installations";
166
+ dataType: "date";
167
+ columnType: "PgTimestamp";
168
+ data: Date;
169
+ driverParam: string;
170
+ notNull: true;
171
+ hasDefault: true;
172
+ isPrimaryKey: false;
173
+ isAutoincrement: false;
174
+ hasRuntimeDefault: false;
175
+ enumValues: undefined;
176
+ baseColumn: never;
177
+ identity: undefined;
178
+ generated: undefined;
179
+ }, {}, {}>;
180
+ updatedAt: import("drizzle-orm/pg-core").PgColumn<{
181
+ name: "updated_at";
182
+ tableName: "installations";
183
+ dataType: "date";
184
+ columnType: "PgTimestamp";
185
+ data: Date;
186
+ driverParam: string;
187
+ notNull: true;
188
+ hasDefault: true;
189
+ isPrimaryKey: false;
190
+ isAutoincrement: false;
191
+ hasRuntimeDefault: false;
192
+ enumValues: undefined;
193
+ baseColumn: never;
194
+ identity: undefined;
195
+ generated: undefined;
196
+ }, {}, {}>;
197
+ };
198
+ dialect: "pg";
199
+ }>;
200
+ export type SlackInstallationDb = typeof slackInstallations.$inferSelect;
201
+ export type SlackInstallationCreateDb = typeof slackInstallations.$inferInsert;
202
+ export declare function toSlackInstallation(row: SlackInstallationDb): SlackInstallation;
203
+ //# sourceMappingURL=installations.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"installations.d.ts","sourceRoot":"","sources":["../../../src/db/schema/installations.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAC,iBAAiB,EAAC,MAAM,sBAAsB,CAAC;AAG5D,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAmB9B,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG,OAAO,kBAAkB,CAAC,YAAY,CAAC;AACzE,MAAM,MAAM,yBAAyB,GAAG,OAAO,kBAAkB,CAAC,YAAY,CAAC;AAE/E,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,mBAAmB,GAAG,iBAAiB,CAc/E"}
@@ -0,0 +1,42 @@
1
+ import { uuidv7PrimaryKey } from '@shipfox/node-drizzle';
2
+ import { jsonb, text, timestamp, uniqueIndex, uuid } from 'drizzle-orm/pg-core';
3
+ import { pgTable } from './common.js';
4
+ export const slackInstallations = pgTable('installations', {
5
+ id: uuidv7PrimaryKey(),
6
+ connectionId: uuid('connection_id').notNull(),
7
+ teamId: text('team_id').notNull(),
8
+ teamName: text('team_name').notNull(),
9
+ appId: text('app_id').notNull(),
10
+ botUserId: text('bot_user_id').notNull(),
11
+ scopes: jsonb('scopes').notNull().$type(),
12
+ status: text('status').notNull().$type(),
13
+ tokenExpiresAt: timestamp('token_expires_at', {
14
+ withTimezone: true
15
+ }),
16
+ createdAt: timestamp('created_at', {
17
+ withTimezone: true
18
+ }).notNull().defaultNow(),
19
+ updatedAt: timestamp('updated_at', {
20
+ withTimezone: true
21
+ }).notNull().defaultNow()
22
+ }, (table)=>[
23
+ uniqueIndex('integrations_slack_installations_connection_unique').on(table.connectionId),
24
+ uniqueIndex('integrations_slack_installations_team_unique').on(table.teamId)
25
+ ]);
26
+ export function toSlackInstallation(row) {
27
+ return {
28
+ id: row.id,
29
+ connectionId: row.connectionId,
30
+ teamId: row.teamId,
31
+ teamName: row.teamName,
32
+ appId: row.appId,
33
+ botUserId: row.botUserId,
34
+ scopes: row.scopes,
35
+ status: row.status,
36
+ tokenExpiresAt: row.tokenExpiresAt,
37
+ createdAt: row.createdAt,
38
+ updatedAt: row.updatedAt
39
+ };
40
+ }
41
+
42
+ //# sourceMappingURL=installations.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/db/schema/installations.ts"],"sourcesContent":["import {uuidv7PrimaryKey} from '@shipfox/node-drizzle';\nimport {jsonb, text, timestamp, uniqueIndex, uuid} from 'drizzle-orm/pg-core';\nimport type {SlackInstallation} from '#db/installations.js';\nimport {pgTable} from './common.js';\n\nexport const slackInstallations = pgTable(\n 'installations',\n {\n id: uuidv7PrimaryKey(),\n connectionId: uuid('connection_id').notNull(),\n teamId: text('team_id').notNull(),\n teamName: text('team_name').notNull(),\n appId: text('app_id').notNull(),\n botUserId: text('bot_user_id').notNull(),\n scopes: jsonb('scopes').notNull().$type<string[]>(),\n status: text('status').notNull().$type<SlackInstallation['status']>(),\n tokenExpiresAt: timestamp('token_expires_at', {withTimezone: true}),\n createdAt: timestamp('created_at', {withTimezone: true}).notNull().defaultNow(),\n updatedAt: timestamp('updated_at', {withTimezone: true}).notNull().defaultNow(),\n },\n (table) => [\n uniqueIndex('integrations_slack_installations_connection_unique').on(table.connectionId),\n uniqueIndex('integrations_slack_installations_team_unique').on(table.teamId),\n ],\n);\n\nexport type SlackInstallationDb = typeof slackInstallations.$inferSelect;\nexport type SlackInstallationCreateDb = typeof slackInstallations.$inferInsert;\n\nexport function toSlackInstallation(row: SlackInstallationDb): SlackInstallation {\n return {\n id: row.id,\n connectionId: row.connectionId,\n teamId: row.teamId,\n teamName: row.teamName,\n appId: row.appId,\n botUserId: row.botUserId,\n scopes: row.scopes,\n status: row.status,\n tokenExpiresAt: row.tokenExpiresAt,\n createdAt: row.createdAt,\n updatedAt: row.updatedAt,\n };\n}\n"],"names":["uuidv7PrimaryKey","jsonb","text","timestamp","uniqueIndex","uuid","pgTable","slackInstallations","id","connectionId","notNull","teamId","teamName","appId","botUserId","scopes","$type","status","tokenExpiresAt","withTimezone","createdAt","defaultNow","updatedAt","table","on","toSlackInstallation","row"],"mappings":"AAAA,SAAQA,gBAAgB,QAAO,wBAAwB;AACvD,SAAQC,KAAK,EAAEC,IAAI,EAAEC,SAAS,EAAEC,WAAW,EAAEC,IAAI,QAAO,sBAAsB;AAE9E,SAAQC,OAAO,QAAO,cAAc;AAEpC,OAAO,MAAMC,qBAAqBD,QAChC,iBACA;IACEE,IAAIR;IACJS,cAAcJ,KAAK,iBAAiBK,OAAO;IAC3CC,QAAQT,KAAK,WAAWQ,OAAO;IAC/BE,UAAUV,KAAK,aAAaQ,OAAO;IACnCG,OAAOX,KAAK,UAAUQ,OAAO;IAC7BI,WAAWZ,KAAK,eAAeQ,OAAO;IACtCK,QAAQd,MAAM,UAAUS,OAAO,GAAGM,KAAK;IACvCC,QAAQf,KAAK,UAAUQ,OAAO,GAAGM,KAAK;IACtCE,gBAAgBf,UAAU,oBAAoB;QAACgB,cAAc;IAAI;IACjEC,WAAWjB,UAAU,cAAc;QAACgB,cAAc;IAAI,GAAGT,OAAO,GAAGW,UAAU;IAC7EC,WAAWnB,UAAU,cAAc;QAACgB,cAAc;IAAI,GAAGT,OAAO,GAAGW,UAAU;AAC/E,GACA,CAACE,QAAU;QACTnB,YAAY,sDAAsDoB,EAAE,CAACD,MAAMd,YAAY;QACvFL,YAAY,gDAAgDoB,EAAE,CAACD,MAAMZ,MAAM;KAC5E,EACD;AAKF,OAAO,SAASc,oBAAoBC,GAAwB;IAC1D,OAAO;QACLlB,IAAIkB,IAAIlB,EAAE;QACVC,cAAciB,IAAIjB,YAAY;QAC9BE,QAAQe,IAAIf,MAAM;QAClBC,UAAUc,IAAId,QAAQ;QACtBC,OAAOa,IAAIb,KAAK;QAChBC,WAAWY,IAAIZ,SAAS;QACxBC,QAAQW,IAAIX,MAAM;QAClBE,QAAQS,IAAIT,MAAM;QAClBC,gBAAgBQ,IAAIR,cAAc;QAClCE,WAAWM,IAAIN,SAAS;QACxBE,WAAWI,IAAIJ,SAAS;IAC1B;AACF"}
@@ -0,0 +1,59 @@
1
+ import type { RouteGroup } from '@shipfox/node-fastify';
2
+ import { type SlackApiClient } from '#api/client.js';
3
+ import { config } from '#config.js';
4
+ import { SlackAgentToolsProvider } from '#core/agent-tools-provider.js';
5
+ import type { SlackTokenStore } from '#core/tokens.js';
6
+ import { closeDb, db } from '#db/db.js';
7
+ import { getSlackInstallationByConnectionId } from '#db/installations.js';
8
+ import { migrationsPath } from '#db/migrations.js';
9
+ import { type CreateSlackIntegrationRoutesOptions } from '#presentation/routes/install.js';
10
+ import { type CreateSlackWebhookRoutesOptions } from '#presentation/routes/webhooks.js';
11
+ type SlackInstallationRouteOptions = Omit<CreateSlackIntegrationRoutesOptions, 'slack' | 'connectionCapabilities'>;
12
+ type SlackRouteOptions = Partial<SlackInstallationRouteOptions> & Partial<CreateSlackWebhookRoutesOptions>;
13
+ export type { SlackProvider } from '@shipfox/api-integration-slack-dto';
14
+ export type { SlackApiClient, SlackAuthorization, SlackWebApiResponse } from '#api/client.js';
15
+ export { createSlackApiClient } from '#api/client.js';
16
+ export type { SlackAgentToolCatalogEntry, SlackAgentToolId, SlackAgentToolRequiredScope, } from '#core/agent-tools.js';
17
+ export { SLACK_TOOL_METHODS, slackAgentToolCatalog, slackAgentToolSelectionCatalog, } from '#core/agent-tools.js';
18
+ export type { SlackAgentToolsProviderOptions, SlackToolCallResult, } from '#core/agent-tools-provider.js';
19
+ export { SlackAgentToolsProvider } from '#core/agent-tools-provider.js';
20
+ export { type DisconnectSlackInstallationParams, disconnectSlackInstallation, } from '#core/disconnect.js';
21
+ export { SlackAccessTokenUnavailableError, type SlackAccessTokenUnavailableReason, SlackAuthorizationScopeMismatchError, SlackBotTokenMissingError, SlackConnectionAlreadyLinkedError, SlackConnectionNotFoundError, SlackEnterpriseInstallUnsupportedError, SlackInstallationAlreadyLinkedError, SlackInstallStateActorMismatchError, SlackInstallStateError, SlackIntegrationProviderError, SlackOAuthCallbackError, } from '#core/errors.js';
22
+ export type { ConnectSlackInstallationInput, HandleSlackCallbackParams } from '#core/install.js';
23
+ export { handleSlackCallback, handleSlackOAuthCallbackError } from '#core/install.js';
24
+ export { assertSlackAuthorizationScopes, formatSlackBotScopes, SLACK_BOT_SCOPES, } from '#core/scopes.js';
25
+ export type { VerifySlackSignatureParams } from '#core/signature.js';
26
+ export { verifySlackSignature } from '#core/signature.js';
27
+ export type { SlackInstallStateClaims } from '#core/state.js';
28
+ export { signSlackInstallState, verifySlackInstallState } from '#core/state.js';
29
+ export type { CreateSlackTokenStoreParams, GetSlackAccessTokenParams, SlackConnectionResolverResult, SlackSecretsStore, SlackTokenStore, StoreSlackTokensParams, } from '#core/tokens.js';
30
+ export { createSlackTokenStore, slackSecretsNamespace } from '#core/tokens.js';
31
+ export type { HandleSlackCommandParams, HandleSlackEventParams, SlackWebhookOutcome, } from '#core/webhook.js';
32
+ export { handleSlackCommand, handleSlackEvent, isSelfAuthoredSlackEvent } from '#core/webhook.js';
33
+ export type { SlackInstallation, SlackInstallationStatus, UpsertSlackInstallationParams, } from '#db/installations.js';
34
+ export { deleteSlackInstallationByConnectionId, getSlackInstallationByConnectionId, getSlackInstallationByTeamId, markSlackInstallationRevoked, upsertSlackInstallation, } from '#db/installations.js';
35
+ export { type CreateSlackE2eRoutesOptions, createSlackE2eRoutes, } from '#presentation/e2eRoutes/index.js';
36
+ export { type CreateSlackWebhookRoutesOptions, createSlackWebhookRoutes, SLACK_WEBHOOK_BODY_LIMIT, SLASH_COMMAND_ACK, } from '#presentation/routes/webhooks.js';
37
+ export { closeDb, config, db, migrationsPath };
38
+ export interface CreateSlackIntegrationProviderOptions {
39
+ slack?: SlackApiClient | undefined;
40
+ agentTools?: {
41
+ tokenStore: Pick<SlackTokenStore, 'getAccessToken'>;
42
+ } | undefined;
43
+ getSlackInstallationByConnectionId?: typeof getSlackInstallationByConnectionId | undefined;
44
+ routes?: SlackRouteOptions | undefined;
45
+ }
46
+ export declare function createSlackIntegrationProvider(options?: CreateSlackIntegrationProviderOptions): {
47
+ provider: string;
48
+ displayName: string;
49
+ adapters: {
50
+ agent_tools: SlackAgentToolsProvider;
51
+ } | {
52
+ agent_tools?: never;
53
+ };
54
+ connectionExternalUrl(connection: {
55
+ id: string;
56
+ }): Promise<string | undefined>;
57
+ routes: RouteGroup[];
58
+ };
59
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js ADDED
@@ -0,0 +1,73 @@
1
+ import { SLACK_PROVIDER } from '@shipfox/api-integration-slack-dto';
2
+ import { createSlackApiClient } from '#api/client.js';
3
+ import { config } from '#config.js';
4
+ import { SlackAgentToolsProvider } from '#core/agent-tools-provider.js';
5
+ import { closeDb, db } from '#db/db.js';
6
+ import { getSlackInstallationByConnectionId } from '#db/installations.js';
7
+ import { migrationsPath } from '#db/migrations.js';
8
+ import { createSlackIntegrationRoutes } from '#presentation/routes/install.js';
9
+ import { createSlackWebhookRoutes } from '#presentation/routes/webhooks.js';
10
+ export { createSlackApiClient } from '#api/client.js';
11
+ export { SLACK_TOOL_METHODS, slackAgentToolCatalog, slackAgentToolSelectionCatalog } from '#core/agent-tools.js';
12
+ export { SlackAgentToolsProvider } from '#core/agent-tools-provider.js';
13
+ export { disconnectSlackInstallation } from '#core/disconnect.js';
14
+ export { SlackAccessTokenUnavailableError, SlackAuthorizationScopeMismatchError, SlackBotTokenMissingError, SlackConnectionAlreadyLinkedError, SlackConnectionNotFoundError, SlackEnterpriseInstallUnsupportedError, SlackInstallationAlreadyLinkedError, SlackInstallStateActorMismatchError, SlackInstallStateError, SlackIntegrationProviderError, SlackOAuthCallbackError } from '#core/errors.js';
15
+ export { handleSlackCallback, handleSlackOAuthCallbackError } from '#core/install.js';
16
+ export { assertSlackAuthorizationScopes, formatSlackBotScopes, SLACK_BOT_SCOPES } from '#core/scopes.js';
17
+ export { verifySlackSignature } from '#core/signature.js';
18
+ export { signSlackInstallState, verifySlackInstallState } from '#core/state.js';
19
+ export { createSlackTokenStore, slackSecretsNamespace } from '#core/tokens.js';
20
+ export { handleSlackCommand, handleSlackEvent, isSelfAuthoredSlackEvent } from '#core/webhook.js';
21
+ export { deleteSlackInstallationByConnectionId, getSlackInstallationByConnectionId, getSlackInstallationByTeamId, markSlackInstallationRevoked, upsertSlackInstallation } from '#db/installations.js';
22
+ export { createSlackE2eRoutes } from '#presentation/e2eRoutes/index.js';
23
+ export { createSlackWebhookRoutes, SLACK_WEBHOOK_BODY_LIMIT, SLASH_COMMAND_ACK } from '#presentation/routes/webhooks.js';
24
+ export { closeDb, config, db, migrationsPath };
25
+ export function createSlackIntegrationProvider(options = {}) {
26
+ const slack = options.slack ?? createSlackApiClient();
27
+ const getInstallationByConnectionId = options.getSlackInstallationByConnectionId ?? getSlackInstallationByConnectionId;
28
+ const adapters = options.agentTools ? {
29
+ agent_tools: new SlackAgentToolsProvider({
30
+ slack,
31
+ tokenStore: options.agentTools.tokenStore
32
+ })
33
+ } : {};
34
+ if (options.routes && !hasSlackInstallationRoutesOptions(options.routes) && !hasSlackWebhookRoutesOptions(options.routes)) {
35
+ throw new Error('Slack webhook routes require every core persistence dependency');
36
+ }
37
+ const routes = [];
38
+ if (options.routes && hasSlackInstallationRoutesOptions(options.routes)) {
39
+ const { tokenStore, getExistingSlackConnection, connectSlackInstallation, disconnectSlackInstallation } = options.routes;
40
+ routes.push(createSlackIntegrationRoutes({
41
+ slack,
42
+ connectionCapabilities: adapters.agent_tools ? [
43
+ 'agent_tools'
44
+ ] : [],
45
+ tokenStore,
46
+ getExistingSlackConnection,
47
+ connectSlackInstallation,
48
+ disconnectSlackInstallation
49
+ }));
50
+ }
51
+ if (options.routes && hasSlackWebhookRoutesOptions(options.routes)) {
52
+ routes.push(...createSlackWebhookRoutes(options.routes));
53
+ }
54
+ return {
55
+ provider: SLACK_PROVIDER,
56
+ displayName: 'Slack',
57
+ adapters,
58
+ async connectionExternalUrl (connection) {
59
+ const installation = await getInstallationByConnectionId(connection.id);
60
+ if (!installation) return undefined;
61
+ return `https://app.slack.com/client/${encodeURIComponent(installation.teamId)}`;
62
+ },
63
+ routes
64
+ };
65
+ }
66
+ function hasSlackInstallationRoutesOptions(routes) {
67
+ return routes.tokenStore !== undefined && routes.getExistingSlackConnection !== undefined && routes.connectSlackInstallation !== undefined && routes.disconnectSlackInstallation !== undefined;
68
+ }
69
+ function hasSlackWebhookRoutesOptions(routes) {
70
+ return routes.coreDb !== undefined && routes.publishIntegrationEventReceived !== undefined && routes.recordDeliveryOnly !== undefined && routes.getIntegrationConnectionById !== undefined;
71
+ }
72
+
73
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts"],"sourcesContent":["import {SLACK_PROVIDER} from '@shipfox/api-integration-slack-dto';\nimport type {RouteGroup} from '@shipfox/node-fastify';\nimport {createSlackApiClient, type SlackApiClient} from '#api/client.js';\nimport {config} from '#config.js';\nimport {SlackAgentToolsProvider} from '#core/agent-tools-provider.js';\nimport type {SlackTokenStore} from '#core/tokens.js';\nimport {closeDb, db} from '#db/db.js';\nimport {getSlackInstallationByConnectionId} from '#db/installations.js';\nimport {migrationsPath} from '#db/migrations.js';\nimport {\n type CreateSlackIntegrationRoutesOptions,\n createSlackIntegrationRoutes,\n} from '#presentation/routes/install.js';\nimport {\n type CreateSlackWebhookRoutesOptions,\n createSlackWebhookRoutes,\n} from '#presentation/routes/webhooks.js';\n\ntype SlackInstallationRouteOptions = Omit<\n CreateSlackIntegrationRoutesOptions,\n 'slack' | 'connectionCapabilities'\n>;\ntype SlackRouteOptions = Partial<SlackInstallationRouteOptions> &\n Partial<CreateSlackWebhookRoutesOptions>;\n\nexport type {SlackProvider} from '@shipfox/api-integration-slack-dto';\nexport type {SlackApiClient, SlackAuthorization, SlackWebApiResponse} from '#api/client.js';\nexport {createSlackApiClient} from '#api/client.js';\nexport type {\n SlackAgentToolCatalogEntry,\n SlackAgentToolId,\n SlackAgentToolRequiredScope,\n} from '#core/agent-tools.js';\nexport {\n SLACK_TOOL_METHODS,\n slackAgentToolCatalog,\n slackAgentToolSelectionCatalog,\n} from '#core/agent-tools.js';\nexport type {\n SlackAgentToolsProviderOptions,\n SlackToolCallResult,\n} from '#core/agent-tools-provider.js';\nexport {SlackAgentToolsProvider} from '#core/agent-tools-provider.js';\nexport {\n type DisconnectSlackInstallationParams,\n disconnectSlackInstallation,\n} from '#core/disconnect.js';\nexport {\n SlackAccessTokenUnavailableError,\n type SlackAccessTokenUnavailableReason,\n SlackAuthorizationScopeMismatchError,\n SlackBotTokenMissingError,\n SlackConnectionAlreadyLinkedError,\n SlackConnectionNotFoundError,\n SlackEnterpriseInstallUnsupportedError,\n SlackInstallationAlreadyLinkedError,\n SlackInstallStateActorMismatchError,\n SlackInstallStateError,\n SlackIntegrationProviderError,\n SlackOAuthCallbackError,\n} from '#core/errors.js';\nexport type {ConnectSlackInstallationInput, HandleSlackCallbackParams} from '#core/install.js';\nexport {handleSlackCallback, handleSlackOAuthCallbackError} from '#core/install.js';\nexport {\n assertSlackAuthorizationScopes,\n formatSlackBotScopes,\n SLACK_BOT_SCOPES,\n} from '#core/scopes.js';\nexport type {VerifySlackSignatureParams} from '#core/signature.js';\nexport {verifySlackSignature} from '#core/signature.js';\nexport type {SlackInstallStateClaims} from '#core/state.js';\nexport {signSlackInstallState, verifySlackInstallState} from '#core/state.js';\nexport type {\n CreateSlackTokenStoreParams,\n GetSlackAccessTokenParams,\n SlackConnectionResolverResult,\n SlackSecretsStore,\n SlackTokenStore,\n StoreSlackTokensParams,\n} from '#core/tokens.js';\nexport {createSlackTokenStore, slackSecretsNamespace} from '#core/tokens.js';\nexport type {\n HandleSlackCommandParams,\n HandleSlackEventParams,\n SlackWebhookOutcome,\n} from '#core/webhook.js';\nexport {handleSlackCommand, handleSlackEvent, isSelfAuthoredSlackEvent} from '#core/webhook.js';\nexport type {\n SlackInstallation,\n SlackInstallationStatus,\n UpsertSlackInstallationParams,\n} from '#db/installations.js';\nexport {\n deleteSlackInstallationByConnectionId,\n getSlackInstallationByConnectionId,\n getSlackInstallationByTeamId,\n markSlackInstallationRevoked,\n upsertSlackInstallation,\n} from '#db/installations.js';\nexport {\n type CreateSlackE2eRoutesOptions,\n createSlackE2eRoutes,\n} from '#presentation/e2eRoutes/index.js';\nexport {\n type CreateSlackWebhookRoutesOptions,\n createSlackWebhookRoutes,\n SLACK_WEBHOOK_BODY_LIMIT,\n SLASH_COMMAND_ACK,\n} from '#presentation/routes/webhooks.js';\nexport {closeDb, config, db, migrationsPath};\n\nexport interface CreateSlackIntegrationProviderOptions {\n slack?: SlackApiClient | undefined;\n agentTools?: {tokenStore: Pick<SlackTokenStore, 'getAccessToken'>} | undefined;\n getSlackInstallationByConnectionId?: typeof getSlackInstallationByConnectionId | undefined;\n routes?: SlackRouteOptions | undefined;\n}\n\nexport function createSlackIntegrationProvider(\n options: CreateSlackIntegrationProviderOptions = {},\n) {\n const slack = options.slack ?? createSlackApiClient();\n const getInstallationByConnectionId =\n options.getSlackInstallationByConnectionId ?? getSlackInstallationByConnectionId;\n const adapters = options.agentTools\n ? {\n agent_tools: new SlackAgentToolsProvider({\n slack,\n tokenStore: options.agentTools.tokenStore,\n }),\n }\n : {};\n if (\n options.routes &&\n !hasSlackInstallationRoutesOptions(options.routes) &&\n !hasSlackWebhookRoutesOptions(options.routes)\n ) {\n throw new Error('Slack webhook routes require every core persistence dependency');\n }\n const routes: RouteGroup[] = [];\n if (options.routes && hasSlackInstallationRoutesOptions(options.routes)) {\n const {\n tokenStore,\n getExistingSlackConnection,\n connectSlackInstallation,\n disconnectSlackInstallation,\n } = options.routes;\n routes.push(\n createSlackIntegrationRoutes({\n slack,\n connectionCapabilities: adapters.agent_tools ? ['agent_tools'] : [],\n tokenStore,\n getExistingSlackConnection,\n connectSlackInstallation,\n disconnectSlackInstallation,\n }),\n );\n }\n if (options.routes && hasSlackWebhookRoutesOptions(options.routes)) {\n routes.push(...createSlackWebhookRoutes(options.routes));\n }\n\n return {\n provider: SLACK_PROVIDER,\n displayName: 'Slack',\n adapters,\n async connectionExternalUrl(connection: {id: string}): Promise<string | undefined> {\n const installation = await getInstallationByConnectionId(connection.id);\n if (!installation) return undefined;\n return `https://app.slack.com/client/${encodeURIComponent(installation.teamId)}`;\n },\n routes,\n };\n}\n\nfunction hasSlackInstallationRoutesOptions(\n routes: SlackRouteOptions,\n): routes is SlackInstallationRouteOptions {\n return (\n routes.tokenStore !== undefined &&\n routes.getExistingSlackConnection !== undefined &&\n routes.connectSlackInstallation !== undefined &&\n routes.disconnectSlackInstallation !== undefined\n );\n}\n\nfunction hasSlackWebhookRoutesOptions(\n routes: SlackRouteOptions,\n): routes is CreateSlackWebhookRoutesOptions {\n return (\n routes.coreDb !== undefined &&\n routes.publishIntegrationEventReceived !== undefined &&\n routes.recordDeliveryOnly !== undefined &&\n routes.getIntegrationConnectionById !== undefined\n );\n}\n"],"names":["SLACK_PROVIDER","createSlackApiClient","config","SlackAgentToolsProvider","closeDb","db","getSlackInstallationByConnectionId","migrationsPath","createSlackIntegrationRoutes","createSlackWebhookRoutes","SLACK_TOOL_METHODS","slackAgentToolCatalog","slackAgentToolSelectionCatalog","disconnectSlackInstallation","SlackAccessTokenUnavailableError","SlackAuthorizationScopeMismatchError","SlackBotTokenMissingError","SlackConnectionAlreadyLinkedError","SlackConnectionNotFoundError","SlackEnterpriseInstallUnsupportedError","SlackInstallationAlreadyLinkedError","SlackInstallStateActorMismatchError","SlackInstallStateError","SlackIntegrationProviderError","SlackOAuthCallbackError","handleSlackCallback","handleSlackOAuthCallbackError","assertSlackAuthorizationScopes","formatSlackBotScopes","SLACK_BOT_SCOPES","verifySlackSignature","signSlackInstallState","verifySlackInstallState","createSlackTokenStore","slackSecretsNamespace","handleSlackCommand","handleSlackEvent","isSelfAuthoredSlackEvent","deleteSlackInstallationByConnectionId","getSlackInstallationByTeamId","markSlackInstallationRevoked","upsertSlackInstallation","createSlackE2eRoutes","SLACK_WEBHOOK_BODY_LIMIT","SLASH_COMMAND_ACK","createSlackIntegrationProvider","options","slack","getInstallationByConnectionId","adapters","agentTools","agent_tools","tokenStore","routes","hasSlackInstallationRoutesOptions","hasSlackWebhookRoutesOptions","Error","getExistingSlackConnection","connectSlackInstallation","push","connectionCapabilities","provider","displayName","connectionExternalUrl","connection","installation","id","undefined","encodeURIComponent","teamId","coreDb","publishIntegrationEventReceived","recordDeliveryOnly","getIntegrationConnectionById"],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export { toIntegrationConnectionDto } from '@shipfox/api-integration-core-dto';
2
+ //# sourceMappingURL=integrations.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"integrations.d.ts","sourceRoot":"","sources":["../../../src/presentation/dto/integrations.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,0BAA0B,EAAC,MAAM,mCAAmC,CAAC"}
@@ -0,0 +1,3 @@
1
+ export { toIntegrationConnectionDto } from '@shipfox/api-integration-core-dto';
2
+
3
+ //# sourceMappingURL=integrations.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/presentation/dto/integrations.ts"],"sourcesContent":["export {toIntegrationConnectionDto} from '@shipfox/api-integration-core-dto';\n"],"names":["toIntegrationConnectionDto"],"mappings":"AAAA,SAAQA,0BAA0B,QAAO,oCAAoC"}
@@ -0,0 +1,16 @@
1
+ import type { IntegrationCapability, IntegrationConnection } from '@shipfox/api-integration-core-dto';
2
+ import type { ConnectSlackInstallationInput } from '#core/install.js';
3
+ import type { SlackTokenStore } from '#core/tokens.js';
4
+ export interface CreateE2eSlackConnectionRouteOptions {
5
+ tokenStore: Pick<SlackTokenStore, 'storeTokens'>;
6
+ getExistingSlackConnection: (input: {
7
+ teamId: string;
8
+ }) => Promise<IntegrationConnection<'slack'> | undefined>;
9
+ connectSlackInstallation: (input: ConnectSlackInstallationInput) => Promise<IntegrationConnection<'slack'>>;
10
+ disconnectSlackInstallation: (input: {
11
+ connectionId: string;
12
+ }) => Promise<void>;
13
+ connectionCapabilities: IntegrationCapability[];
14
+ }
15
+ export declare function createE2eSlackConnectionRoute(options: CreateE2eSlackConnectionRouteOptions): import("@shipfox/node-fastify").RouteDefinition;
16
+ //# sourceMappingURL=create-connection.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create-connection.d.ts","sourceRoot":"","sources":["../../../src/presentation/e2eRoutes/create-connection.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,qBAAqB,EAAE,qBAAqB,EAAC,MAAM,mCAAmC,CAAC;AAOpG,OAAO,KAAK,EAAC,6BAA6B,EAAC,MAAM,kBAAkB,CAAC;AACpE,OAAO,KAAK,EAAC,eAAe,EAAC,MAAM,iBAAiB,CAAC;AAGrD,MAAM,WAAW,oCAAoC;IACnD,UAAU,EAAE,IAAI,CAAC,eAAe,EAAE,aAAa,CAAC,CAAC;IACjD,0BAA0B,EAAE,CAAC,KAAK,EAAE;QAClC,MAAM,EAAE,MAAM,CAAC;KAChB,KAAK,OAAO,CAAC,qBAAqB,CAAC,OAAO,CAAC,GAAG,SAAS,CAAC,CAAC;IAC1D,wBAAwB,EAAE,CACxB,KAAK,EAAE,6BAA6B,KACjC,OAAO,CAAC,qBAAqB,CAAC,OAAO,CAAC,CAAC,CAAC;IAC7C,2BAA2B,EAAE,CAAC,KAAK,EAAE;QAAC,YAAY,EAAE,MAAM,CAAA;KAAC,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC9E,sBAAsB,EAAE,qBAAqB,EAAE,CAAC;CACjD;AAED,wBAAgB,6BAA6B,CAAC,OAAO,EAAE,oCAAoC,mDA4C1F"}
@@ -0,0 +1,65 @@
1
+ import { createE2eSlackConnectionBodySchema, createE2eSlackConnectionResponseSchema } from '@shipfox/api-integration-slack-dto';
2
+ import { ClientError, defineRoute } from '@shipfox/node-fastify';
3
+ import { logger } from '@shipfox/node-opentelemetry';
4
+ import { toIntegrationConnectionDto } from '#presentation/dto/integrations.js';
5
+ export function createE2eSlackConnectionRoute(options) {
6
+ return defineRoute({
7
+ method: 'POST',
8
+ path: '/slack-connections',
9
+ description: 'Create a synthetic Slack connection for E2E tests.',
10
+ schema: {
11
+ body: createE2eSlackConnectionBodySchema,
12
+ response: {
13
+ 201: createE2eSlackConnectionResponseSchema
14
+ }
15
+ },
16
+ handler: async (request, reply)=>{
17
+ const body = request.body;
18
+ const existing = await options.getExistingSlackConnection({
19
+ teamId: body.team_id
20
+ });
21
+ if (existing && existing.workspaceId !== body.workspace_id) {
22
+ throw new ClientError('Slack team is already connected to another workspace', 'slack-connection-workspace-mismatch', {
23
+ status: 409
24
+ });
25
+ }
26
+ const connection = existing ?? await options.connectSlackInstallation({
27
+ workspaceId: body.workspace_id,
28
+ teamId: body.team_id,
29
+ teamName: body.team_name,
30
+ appId: body.app_id,
31
+ botUserId: body.bot_user_id,
32
+ scopes: body.scopes,
33
+ tokenExpiresAt: null,
34
+ displayName: `Slack ${body.team_name}`
35
+ });
36
+ try {
37
+ await options.tokenStore.storeTokens({
38
+ connectionId: connection.id,
39
+ botToken: body.bot_token
40
+ });
41
+ } catch (error) {
42
+ if (!existing) await bestEffortDisconnectSlackInstallation(options, connection.id);
43
+ throw error;
44
+ }
45
+ reply.code(201);
46
+ return toIntegrationConnectionDto(connection, {
47
+ capabilities: options.connectionCapabilities
48
+ });
49
+ }
50
+ });
51
+ }
52
+ async function bestEffortDisconnectSlackInstallation(options, connectionId) {
53
+ try {
54
+ await options.disconnectSlackInstallation({
55
+ connectionId
56
+ });
57
+ } catch (error) {
58
+ logger().warn({
59
+ err: error,
60
+ connectionId
61
+ }, 'Slack E2E connection compensation failed after token storage rejection');
62
+ }
63
+ }
64
+
65
+ //# sourceMappingURL=create-connection.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/presentation/e2eRoutes/create-connection.ts"],"sourcesContent":["import type {IntegrationCapability, IntegrationConnection} from '@shipfox/api-integration-core-dto';\nimport {\n createE2eSlackConnectionBodySchema,\n createE2eSlackConnectionResponseSchema,\n} from '@shipfox/api-integration-slack-dto';\nimport {ClientError, defineRoute} from '@shipfox/node-fastify';\nimport {logger} from '@shipfox/node-opentelemetry';\nimport type {ConnectSlackInstallationInput} from '#core/install.js';\nimport type {SlackTokenStore} from '#core/tokens.js';\nimport {toIntegrationConnectionDto} from '#presentation/dto/integrations.js';\n\nexport interface CreateE2eSlackConnectionRouteOptions {\n tokenStore: Pick<SlackTokenStore, 'storeTokens'>;\n getExistingSlackConnection: (input: {\n teamId: string;\n }) => Promise<IntegrationConnection<'slack'> | undefined>;\n connectSlackInstallation: (\n input: ConnectSlackInstallationInput,\n ) => Promise<IntegrationConnection<'slack'>>;\n disconnectSlackInstallation: (input: {connectionId: string}) => Promise<void>;\n connectionCapabilities: IntegrationCapability[];\n}\n\nexport function createE2eSlackConnectionRoute(options: CreateE2eSlackConnectionRouteOptions) {\n return defineRoute({\n method: 'POST',\n path: '/slack-connections',\n description: 'Create a synthetic Slack connection for E2E tests.',\n schema: {\n body: createE2eSlackConnectionBodySchema,\n response: {201: createE2eSlackConnectionResponseSchema},\n },\n handler: async (request, reply) => {\n const body = request.body;\n const existing = await options.getExistingSlackConnection({teamId: body.team_id});\n if (existing && existing.workspaceId !== body.workspace_id) {\n throw new ClientError(\n 'Slack team is already connected to another workspace',\n 'slack-connection-workspace-mismatch',\n {status: 409},\n );\n }\n const connection =\n existing ??\n (await options.connectSlackInstallation({\n workspaceId: body.workspace_id,\n teamId: body.team_id,\n teamName: body.team_name,\n appId: body.app_id,\n botUserId: body.bot_user_id,\n scopes: body.scopes,\n tokenExpiresAt: null,\n displayName: `Slack ${body.team_name}`,\n }));\n try {\n await options.tokenStore.storeTokens({\n connectionId: connection.id,\n botToken: body.bot_token,\n });\n } catch (error) {\n if (!existing) await bestEffortDisconnectSlackInstallation(options, connection.id);\n throw error;\n }\n reply.code(201);\n return toIntegrationConnectionDto(connection, {capabilities: options.connectionCapabilities});\n },\n });\n}\n\nasync function bestEffortDisconnectSlackInstallation(\n options: CreateE2eSlackConnectionRouteOptions,\n connectionId: string,\n): Promise<void> {\n try {\n await options.disconnectSlackInstallation({connectionId});\n } catch (error) {\n logger().warn(\n {err: error, connectionId},\n 'Slack E2E connection compensation failed after token storage rejection',\n );\n }\n}\n"],"names":["createE2eSlackConnectionBodySchema","createE2eSlackConnectionResponseSchema","ClientError","defineRoute","logger","toIntegrationConnectionDto","createE2eSlackConnectionRoute","options","method","path","description","schema","body","response","handler","request","reply","existing","getExistingSlackConnection","teamId","team_id","workspaceId","workspace_id","status","connection","connectSlackInstallation","teamName","team_name","appId","app_id","botUserId","bot_user_id","scopes","tokenExpiresAt","displayName","tokenStore","storeTokens","connectionId","id","botToken","bot_token","error","bestEffortDisconnectSlackInstallation","code","capabilities","connectionCapabilities","disconnectSlackInstallation","warn","err"],"mappings":"AACA,SACEA,kCAAkC,EAClCC,sCAAsC,QACjC,qCAAqC;AAC5C,SAAQC,WAAW,EAAEC,WAAW,QAAO,wBAAwB;AAC/D,SAAQC,MAAM,QAAO,8BAA8B;AAGnD,SAAQC,0BAA0B,QAAO,oCAAoC;AAc7E,OAAO,SAASC,8BAA8BC,OAA6C;IACzF,OAAOJ,YAAY;QACjBK,QAAQ;QACRC,MAAM;QACNC,aAAa;QACbC,QAAQ;YACNC,MAAMZ;YACNa,UAAU;gBAAC,KAAKZ;YAAsC;QACxD;QACAa,SAAS,OAAOC,SAASC;YACvB,MAAMJ,OAAOG,QAAQH,IAAI;YACzB,MAAMK,WAAW,MAAMV,QAAQW,0BAA0B,CAAC;gBAACC,QAAQP,KAAKQ,OAAO;YAAA;YAC/E,IAAIH,YAAYA,SAASI,WAAW,KAAKT,KAAKU,YAAY,EAAE;gBAC1D,MAAM,IAAIpB,YACR,wDACA,uCACA;oBAACqB,QAAQ;gBAAG;YAEhB;YACA,MAAMC,aACJP,YACC,MAAMV,QAAQkB,wBAAwB,CAAC;gBACtCJ,aAAaT,KAAKU,YAAY;gBAC9BH,QAAQP,KAAKQ,OAAO;gBACpBM,UAAUd,KAAKe,SAAS;gBACxBC,OAAOhB,KAAKiB,MAAM;gBAClBC,WAAWlB,KAAKmB,WAAW;gBAC3BC,QAAQpB,KAAKoB,MAAM;gBACnBC,gBAAgB;gBAChBC,aAAa,CAAC,MAAM,EAAEtB,KAAKe,SAAS,EAAE;YACxC;YACF,IAAI;gBACF,MAAMpB,QAAQ4B,UAAU,CAACC,WAAW,CAAC;oBACnCC,cAAcb,WAAWc,EAAE;oBAC3BC,UAAU3B,KAAK4B,SAAS;gBAC1B;YACF,EAAE,OAAOC,OAAO;gBACd,IAAI,CAACxB,UAAU,MAAMyB,sCAAsCnC,SAASiB,WAAWc,EAAE;gBACjF,MAAMG;YACR;YACAzB,MAAM2B,IAAI,CAAC;YACX,OAAOtC,2BAA2BmB,YAAY;gBAACoB,cAAcrC,QAAQsC,sBAAsB;YAAA;QAC7F;IACF;AACF;AAEA,eAAeH,sCACbnC,OAA6C,EAC7C8B,YAAoB;IAEpB,IAAI;QACF,MAAM9B,QAAQuC,2BAA2B,CAAC;YAACT;QAAY;IACzD,EAAE,OAAOI,OAAO;QACdrC,SAAS2C,IAAI,CACX;YAACC,KAAKP;YAAOJ;QAAY,GACzB;IAEJ;AACF"}
@@ -0,0 +1,5 @@
1
+ import type { RouteGroup } from '@shipfox/node-fastify';
2
+ import { type CreateE2eSlackConnectionRouteOptions } from './create-connection.js';
3
+ export type CreateSlackE2eRoutesOptions = CreateE2eSlackConnectionRouteOptions;
4
+ export declare function createSlackE2eRoutes(options: CreateSlackE2eRoutesOptions): RouteGroup;
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/presentation/e2eRoutes/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,uBAAuB,CAAC;AACtD,OAAO,EACL,KAAK,oCAAoC,EAE1C,MAAM,wBAAwB,CAAC;AAEhC,MAAM,MAAM,2BAA2B,GAAG,oCAAoC,CAAC;AAE/E,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,2BAA2B,GAAG,UAAU,CAErF"}
@@ -0,0 +1,11 @@
1
+ import { createE2eSlackConnectionRoute } from './create-connection.js';
2
+ export function createSlackE2eRoutes(options) {
3
+ return {
4
+ prefix: '/integrations',
5
+ routes: [
6
+ createE2eSlackConnectionRoute(options)
7
+ ]
8
+ };
9
+ }
10
+
11
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/presentation/e2eRoutes/index.ts"],"sourcesContent":["import type {RouteGroup} from '@shipfox/node-fastify';\nimport {\n type CreateE2eSlackConnectionRouteOptions,\n createE2eSlackConnectionRoute,\n} from './create-connection.js';\n\nexport type CreateSlackE2eRoutesOptions = CreateE2eSlackConnectionRouteOptions;\n\nexport function createSlackE2eRoutes(options: CreateSlackE2eRoutesOptions): RouteGroup {\n return {prefix: '/integrations', routes: [createE2eSlackConnectionRoute(options)]};\n}\n"],"names":["createE2eSlackConnectionRoute","createSlackE2eRoutes","options","prefix","routes"],"mappings":"AACA,SAEEA,6BAA6B,QACxB,yBAAyB;AAIhC,OAAO,SAASC,qBAAqBC,OAAoC;IACvE,OAAO;QAACC,QAAQ;QAAiBC,QAAQ;YAACJ,8BAA8BE;SAAS;IAAA;AACnF"}
@@ -0,0 +1,2 @@
1
+ export declare function slackRouteErrorHandler(error: unknown): never;
2
+ //# sourceMappingURL=errors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../../src/presentation/routes/errors.ts"],"names":[],"mappings":"AAuBA,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,CA4C5D"}