@shipfox/api-integration-linear 2.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.
- package/.turbo/turbo-build.log +2 -0
- package/.turbo/turbo-type$colon$emit.log +1 -0
- package/.turbo/turbo-type.log +1 -0
- package/CHANGELOG.md +89 -0
- package/LICENSE +21 -0
- package/README.md +88 -0
- package/dist/api/client.d.ts +29 -0
- package/dist/api/client.d.ts.map +1 -0
- package/dist/api/client.js +189 -0
- package/dist/api/client.js.map +1 -0
- package/dist/config.d.ts +8 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +22 -0
- package/dist/config.js.map +1 -0
- package/dist/core/agent-tools-provider.d.ts +32 -0
- package/dist/core/agent-tools-provider.d.ts.map +1 -0
- package/dist/core/agent-tools-provider.js +63 -0
- package/dist/core/agent-tools-provider.js.map +1 -0
- package/dist/core/agent-tools.d.ts +10 -0
- package/dist/core/agent-tools.d.ts.map +1 -0
- package/dist/core/agent-tools.js +920 -0
- package/dist/core/agent-tools.js.map +1 -0
- package/dist/core/disconnect.d.ts +18 -0
- package/dist/core/disconnect.d.ts.map +1 -0
- package/dist/core/disconnect.js +23 -0
- package/dist/core/disconnect.js.map +1 -0
- package/dist/core/errors.d.ts +35 -0
- package/dist/core/errors.d.ts.map +1 -0
- package/dist/core/errors.js +59 -0
- package/dist/core/errors.js.map +1 -0
- package/dist/core/install.d.ts +47 -0
- package/dist/core/install.d.ts.map +1 -0
- package/dist/core/install.js +102 -0
- package/dist/core/install.js.map +1 -0
- package/dist/core/scopes.d.ts +4 -0
- package/dist/core/scopes.d.ts.map +1 -0
- package/dist/core/scopes.js +17 -0
- package/dist/core/scopes.js.map +1 -0
- package/dist/core/state.d.ts +12 -0
- package/dist/core/state.d.ts.map +1 -0
- package/dist/core/state.js +54 -0
- package/dist/core/state.js.map +1 -0
- package/dist/core/tokens.d.ts +39 -0
- package/dist/core/tokens.d.ts.map +1 -0
- package/dist/core/tokens.js +117 -0
- package/dist/core/tokens.js.map +1 -0
- package/dist/core/webhook.d.ts +16 -0
- package/dist/core/webhook.d.ts.map +1 -0
- package/dist/core/webhook.js +105 -0
- package/dist/core/webhook.js.map +1 -0
- package/dist/db/db.d.ts +369 -0
- package/dist/db/db.d.ts.map +1 -0
- package/dist/db/db.js +18 -0
- package/dist/db/db.js.map +1 -0
- package/dist/db/installations.d.ts +53 -0
- package/dist/db/installations.d.ts.map +1 -0
- package/dist/db/installations.js +125 -0
- package/dist/db/installations.js.map +1 -0
- package/dist/db/migrations.d.ts +2 -0
- package/dist/db/migrations.d.ts.map +1 -0
- package/dist/db/migrations.js +5 -0
- package/dist/db/migrations.js.map +1 -0
- package/dist/db/schema/common.d.ts +2 -0
- package/dist/db/schema/common.d.ts.map +1 -0
- package/dist/db/schema/common.js +4 -0
- package/dist/db/schema/common.js.map +1 -0
- package/dist/db/schema/installations.d.ts +186 -0
- package/dist/db/schema/installations.d.ts.map +1 -0
- package/dist/db/schema/installations.js +40 -0
- package/dist/db/schema/installations.js.map +1 -0
- package/dist/index.d.ts +53 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +56 -0
- package/dist/index.js.map +1 -0
- package/dist/presentation/dto/integrations.d.ts +17 -0
- package/dist/presentation/dto/integrations.d.ts.map +1 -0
- package/dist/presentation/dto/integrations.js +6 -0
- package/dist/presentation/dto/integrations.js.map +1 -0
- package/dist/presentation/e2eRoutes/create-connection.d.ts +16 -0
- package/dist/presentation/e2eRoutes/create-connection.d.ts.map +1 -0
- package/dist/presentation/e2eRoutes/create-connection.js +64 -0
- package/dist/presentation/e2eRoutes/create-connection.js.map +1 -0
- package/dist/presentation/e2eRoutes/index.d.ts +5 -0
- package/dist/presentation/e2eRoutes/index.d.ts.map +1 -0
- package/dist/presentation/e2eRoutes/index.js +11 -0
- package/dist/presentation/e2eRoutes/index.js.map +1 -0
- package/dist/presentation/routes/errors.d.ts +2 -0
- package/dist/presentation/routes/errors.d.ts.map +1 -0
- package/dist/presentation/routes/errors.js +65 -0
- package/dist/presentation/routes/errors.js.map +1 -0
- package/dist/presentation/routes/install.d.ts +19 -0
- package/dist/presentation/routes/install.d.ts.map +1 -0
- package/dist/presentation/routes/install.js +100 -0
- package/dist/presentation/routes/install.js.map +1 -0
- package/dist/presentation/routes/webhooks.d.ts +11 -0
- package/dist/presentation/routes/webhooks.d.ts.map +1 -0
- package/dist/presentation/routes/webhooks.js +136 -0
- package/dist/presentation/routes/webhooks.js.map +1 -0
- package/dist/tsconfig.test.tsbuildinfo +1 -0
- package/drizzle/0000_initial.sql +15 -0
- package/drizzle/meta/0000_snapshot.json +126 -0
- package/drizzle/meta/_journal.json +13 -0
- package/drizzle.config.ts +7 -0
- package/package.json +72 -0
- package/src/api/client.test.ts +366 -0
- package/src/api/client.ts +281 -0
- package/src/config.test.ts +34 -0
- package/src/config.ts +22 -0
- package/src/connection-external-url.test.ts +64 -0
- package/src/core/agent-tools-provider.test.ts +245 -0
- package/src/core/agent-tools-provider.ts +106 -0
- package/src/core/agent-tools.ts +918 -0
- package/src/core/disconnect.test.ts +45 -0
- package/src/core/disconnect.ts +27 -0
- package/src/core/errors.ts +71 -0
- package/src/core/install.ts +162 -0
- package/src/core/scopes.ts +18 -0
- package/src/core/state.test.ts +51 -0
- package/src/core/state.ts +85 -0
- package/src/core/tokens.test.ts +281 -0
- package/src/core/tokens.ts +219 -0
- package/src/core/webhook.test.ts +318 -0
- package/src/core/webhook.ts +146 -0
- package/src/db/db.ts +18 -0
- package/src/db/installations.test.ts +182 -0
- package/src/db/installations.ts +215 -0
- package/src/db/migrations.ts +4 -0
- package/src/db/schema/common.ts +3 -0
- package/src/db/schema/installations.ts +42 -0
- package/src/index.test.ts +20 -0
- package/src/index.ts +153 -0
- package/src/presentation/dto/integrations.ts +9 -0
- package/src/presentation/e2eRoutes/create-connection.ts +85 -0
- package/src/presentation/e2eRoutes/index.test.ts +193 -0
- package/src/presentation/e2eRoutes/index.ts +14 -0
- package/src/presentation/routes/errors.ts +60 -0
- package/src/presentation/routes/install.test.ts +460 -0
- package/src/presentation/routes/install.ts +132 -0
- package/src/presentation/routes/webhooks.test.ts +407 -0
- package/src/presentation/routes/webhooks.ts +154 -0
- package/test/api-secrets.d.ts +28 -0
- package/test/env.ts +13 -0
- package/test/factories/index.ts +1 -0
- package/test/globalSetup.ts +23 -0
- package/test/index.ts +1 -0
- package/test/setup.ts +17 -0
- package/tsconfig.build.json +9 -0
- package/tsconfig.build.tsbuildinfo +1 -0
- package/tsconfig.json +3 -0
- package/tsconfig.test.json +9 -0
- package/vitest.config.ts +12 -0
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
import type { LinearInstallation } from '#db/installations.js';
|
|
2
|
+
export declare const linearInstallations: 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
|
+
organizationId: import("drizzle-orm/pg-core").PgColumn<{
|
|
41
|
+
name: "organization_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
|
+
organizationUrlKey: import("drizzle-orm/pg-core").PgColumn<{
|
|
58
|
+
name: "organization_url_key";
|
|
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
|
+
appUserId: import("drizzle-orm/pg-core").PgColumn<{
|
|
75
|
+
name: "app_user_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
|
+
scopes: import("drizzle-orm/pg-core").PgColumn<{
|
|
92
|
+
name: "scopes";
|
|
93
|
+
tableName: "installations";
|
|
94
|
+
dataType: "json";
|
|
95
|
+
columnType: "PgJsonb";
|
|
96
|
+
data: string[];
|
|
97
|
+
driverParam: unknown;
|
|
98
|
+
notNull: true;
|
|
99
|
+
hasDefault: false;
|
|
100
|
+
isPrimaryKey: false;
|
|
101
|
+
isAutoincrement: false;
|
|
102
|
+
hasRuntimeDefault: false;
|
|
103
|
+
enumValues: undefined;
|
|
104
|
+
baseColumn: never;
|
|
105
|
+
identity: undefined;
|
|
106
|
+
generated: undefined;
|
|
107
|
+
}, {}, {
|
|
108
|
+
$type: string[];
|
|
109
|
+
}>;
|
|
110
|
+
tokenExpiresAt: import("drizzle-orm/pg-core").PgColumn<{
|
|
111
|
+
name: "token_expires_at";
|
|
112
|
+
tableName: "installations";
|
|
113
|
+
dataType: "date";
|
|
114
|
+
columnType: "PgTimestamp";
|
|
115
|
+
data: Date;
|
|
116
|
+
driverParam: string;
|
|
117
|
+
notNull: false;
|
|
118
|
+
hasDefault: false;
|
|
119
|
+
isPrimaryKey: false;
|
|
120
|
+
isAutoincrement: false;
|
|
121
|
+
hasRuntimeDefault: false;
|
|
122
|
+
enumValues: undefined;
|
|
123
|
+
baseColumn: never;
|
|
124
|
+
identity: undefined;
|
|
125
|
+
generated: undefined;
|
|
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").LinearInstallationStatus;
|
|
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").LinearInstallationStatus;
|
|
145
|
+
}>;
|
|
146
|
+
createdAt: import("drizzle-orm/pg-core").PgColumn<{
|
|
147
|
+
name: "created_at";
|
|
148
|
+
tableName: "installations";
|
|
149
|
+
dataType: "date";
|
|
150
|
+
columnType: "PgTimestamp";
|
|
151
|
+
data: Date;
|
|
152
|
+
driverParam: string;
|
|
153
|
+
notNull: true;
|
|
154
|
+
hasDefault: true;
|
|
155
|
+
isPrimaryKey: false;
|
|
156
|
+
isAutoincrement: false;
|
|
157
|
+
hasRuntimeDefault: false;
|
|
158
|
+
enumValues: undefined;
|
|
159
|
+
baseColumn: never;
|
|
160
|
+
identity: undefined;
|
|
161
|
+
generated: undefined;
|
|
162
|
+
}, {}, {}>;
|
|
163
|
+
updatedAt: import("drizzle-orm/pg-core").PgColumn<{
|
|
164
|
+
name: "updated_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
|
+
};
|
|
181
|
+
dialect: "pg";
|
|
182
|
+
}>;
|
|
183
|
+
export type LinearInstallationDb = typeof linearInstallations.$inferSelect;
|
|
184
|
+
export type LinearInstallationCreateDb = typeof linearInstallations.$inferInsert;
|
|
185
|
+
export declare function toLinearInstallation(row: LinearInstallationDb): LinearInstallation;
|
|
186
|
+
//# 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,kBAAkB,EAAC,MAAM,sBAAsB,CAAC;AAG7D,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAkB/B,CAAC;AAEF,MAAM,MAAM,oBAAoB,GAAG,OAAO,mBAAmB,CAAC,YAAY,CAAC;AAC3E,MAAM,MAAM,0BAA0B,GAAG,OAAO,mBAAmB,CAAC,YAAY,CAAC;AAEjF,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,oBAAoB,GAAG,kBAAkB,CAalF"}
|
|
@@ -0,0 +1,40 @@
|
|
|
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 linearInstallations = pgTable('installations', {
|
|
5
|
+
id: uuidv7PrimaryKey(),
|
|
6
|
+
connectionId: uuid('connection_id').notNull(),
|
|
7
|
+
organizationId: text('organization_id').notNull(),
|
|
8
|
+
organizationUrlKey: text('organization_url_key').notNull(),
|
|
9
|
+
appUserId: text('app_user_id').notNull(),
|
|
10
|
+
scopes: jsonb('scopes').notNull().$type(),
|
|
11
|
+
tokenExpiresAt: timestamp('token_expires_at', {
|
|
12
|
+
withTimezone: true
|
|
13
|
+
}),
|
|
14
|
+
status: text('status').notNull().$type(),
|
|
15
|
+
createdAt: timestamp('created_at', {
|
|
16
|
+
withTimezone: true
|
|
17
|
+
}).notNull().defaultNow(),
|
|
18
|
+
updatedAt: timestamp('updated_at', {
|
|
19
|
+
withTimezone: true
|
|
20
|
+
}).notNull().defaultNow()
|
|
21
|
+
}, (table)=>[
|
|
22
|
+
uniqueIndex('integrations_linear_installations_connection_unique').on(table.connectionId),
|
|
23
|
+
uniqueIndex('integrations_linear_installations_organization_unique').on(table.organizationId)
|
|
24
|
+
]);
|
|
25
|
+
export function toLinearInstallation(row) {
|
|
26
|
+
return {
|
|
27
|
+
id: row.id,
|
|
28
|
+
connectionId: row.connectionId,
|
|
29
|
+
organizationId: row.organizationId,
|
|
30
|
+
organizationUrlKey: row.organizationUrlKey,
|
|
31
|
+
appUserId: row.appUserId,
|
|
32
|
+
scopes: row.scopes,
|
|
33
|
+
tokenExpiresAt: row.tokenExpiresAt,
|
|
34
|
+
status: row.status,
|
|
35
|
+
createdAt: row.createdAt,
|
|
36
|
+
updatedAt: row.updatedAt
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
//# 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 {LinearInstallation} from '#db/installations.js';\nimport {pgTable} from './common.js';\n\nexport const linearInstallations = pgTable(\n 'installations',\n {\n id: uuidv7PrimaryKey(),\n connectionId: uuid('connection_id').notNull(),\n organizationId: text('organization_id').notNull(),\n organizationUrlKey: text('organization_url_key').notNull(),\n appUserId: text('app_user_id').notNull(),\n scopes: jsonb('scopes').notNull().$type<string[]>(),\n tokenExpiresAt: timestamp('token_expires_at', {withTimezone: true}),\n status: text('status').notNull().$type<LinearInstallation['status']>(),\n createdAt: timestamp('created_at', {withTimezone: true}).notNull().defaultNow(),\n updatedAt: timestamp('updated_at', {withTimezone: true}).notNull().defaultNow(),\n },\n (table) => [\n uniqueIndex('integrations_linear_installations_connection_unique').on(table.connectionId),\n uniqueIndex('integrations_linear_installations_organization_unique').on(table.organizationId),\n ],\n);\n\nexport type LinearInstallationDb = typeof linearInstallations.$inferSelect;\nexport type LinearInstallationCreateDb = typeof linearInstallations.$inferInsert;\n\nexport function toLinearInstallation(row: LinearInstallationDb): LinearInstallation {\n return {\n id: row.id,\n connectionId: row.connectionId,\n organizationId: row.organizationId,\n organizationUrlKey: row.organizationUrlKey,\n appUserId: row.appUserId,\n scopes: row.scopes,\n tokenExpiresAt: row.tokenExpiresAt,\n status: row.status,\n createdAt: row.createdAt,\n updatedAt: row.updatedAt,\n };\n}\n"],"names":["uuidv7PrimaryKey","jsonb","text","timestamp","uniqueIndex","uuid","pgTable","linearInstallations","id","connectionId","notNull","organizationId","organizationUrlKey","appUserId","scopes","$type","tokenExpiresAt","withTimezone","status","createdAt","defaultNow","updatedAt","table","on","toLinearInstallation","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,sBAAsBD,QACjC,iBACA;IACEE,IAAIR;IACJS,cAAcJ,KAAK,iBAAiBK,OAAO;IAC3CC,gBAAgBT,KAAK,mBAAmBQ,OAAO;IAC/CE,oBAAoBV,KAAK,wBAAwBQ,OAAO;IACxDG,WAAWX,KAAK,eAAeQ,OAAO;IACtCI,QAAQb,MAAM,UAAUS,OAAO,GAAGK,KAAK;IACvCC,gBAAgBb,UAAU,oBAAoB;QAACc,cAAc;IAAI;IACjEC,QAAQhB,KAAK,UAAUQ,OAAO,GAAGK,KAAK;IACtCI,WAAWhB,UAAU,cAAc;QAACc,cAAc;IAAI,GAAGP,OAAO,GAAGU,UAAU;IAC7EC,WAAWlB,UAAU,cAAc;QAACc,cAAc;IAAI,GAAGP,OAAO,GAAGU,UAAU;AAC/E,GACA,CAACE,QAAU;QACTlB,YAAY,uDAAuDmB,EAAE,CAACD,MAAMb,YAAY;QACxFL,YAAY,yDAAyDmB,EAAE,CAACD,MAAMX,cAAc;KAC7F,EACD;AAKF,OAAO,SAASa,qBAAqBC,GAAyB;IAC5D,OAAO;QACLjB,IAAIiB,IAAIjB,EAAE;QACVC,cAAcgB,IAAIhB,YAAY;QAC9BE,gBAAgBc,IAAId,cAAc;QAClCC,oBAAoBa,IAAIb,kBAAkB;QAC1CC,WAAWY,IAAIZ,SAAS;QACxBC,QAAQW,IAAIX,MAAM;QAClBE,gBAAgBS,IAAIT,cAAc;QAClCE,QAAQO,IAAIP,MAAM;QAClBC,WAAWM,IAAIN,SAAS;QACxBE,WAAWI,IAAIJ,SAAS;IAC1B;AACF"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { type LinearApiClient } from '#api/client.js';
|
|
2
|
+
import { config } from '#config.js';
|
|
3
|
+
import { LinearAgentToolsProvider } from '#core/agent-tools-provider.js';
|
|
4
|
+
import type { LinearTokenStore } from '#core/tokens.js';
|
|
5
|
+
import { closeDb, db } from '#db/db.js';
|
|
6
|
+
import { getLinearInstallationByConnectionId } from '#db/installations.js';
|
|
7
|
+
import { migrationsPath } from '#db/migrations.js';
|
|
8
|
+
import { type CreateLinearIntegrationRoutesOptions } from '#presentation/routes/install.js';
|
|
9
|
+
import { type CreateLinearWebhookRoutesOptions } from '#presentation/routes/webhooks.js';
|
|
10
|
+
export type { LinearProvider } from '@shipfox/api-integration-linear-dto';
|
|
11
|
+
export type { LinearApiClient, LinearAuthorization, LinearIdentity } from '#api/client.js';
|
|
12
|
+
export { createLinearApiClient } from '#api/client.js';
|
|
13
|
+
export type { LinearAgentToolCatalogEntry, LinearAgentToolCategory, LinearAgentToolId, LinearAgentToolRequiredScope, } from '#core/agent-tools.js';
|
|
14
|
+
export { linearAgentToolCatalog, linearAgentToolSelectionCatalog, } from '#core/agent-tools.js';
|
|
15
|
+
export { type DisconnectLinearInstallationParams, disconnectLinearInstallation, } from '#core/disconnect.js';
|
|
16
|
+
export { LinearAccessTokenMissingError, LinearAuthorizationScopeMismatchError, LinearConnectionAlreadyLinkedError, LinearConnectionNotFoundError, LinearInstallationAlreadyLinkedError, LinearInstallStateActorMismatchError, LinearInstallStateError, LinearIntegrationProviderError, LinearOAuthCallbackError, LinearTokenUnrefreshableError, } from '#core/errors.js';
|
|
17
|
+
export type { ConnectLinearInstallationInput, HandleLinearCallbackParams } from '#core/install.js';
|
|
18
|
+
export { handleLinearCallback, handleLinearOAuthCallbackError } from '#core/install.js';
|
|
19
|
+
export { assertLinearAuthorizationScopes, formatLinearOAuthScopes, LINEAR_OAUTH_SCOPES, } from '#core/scopes.js';
|
|
20
|
+
export type { LinearInstallStateClaims } from '#core/state.js';
|
|
21
|
+
export { signLinearInstallState, verifyLinearInstallState } from '#core/state.js';
|
|
22
|
+
export type { CreateLinearTokenStoreParams, GetLinearAccessTokenParams, LinearConnectionResolverResult, LinearSecretsStore, LinearTokenStore, StoreLinearTokensParams, } from '#core/tokens.js';
|
|
23
|
+
export { createLinearTokenStore, linearSecretsNamespace, } from '#core/tokens.js';
|
|
24
|
+
export type { HandleLinearWebhookOutcome, HandleLinearWebhookParams } from '#core/webhook.js';
|
|
25
|
+
export { handleLinearWebhook } from '#core/webhook.js';
|
|
26
|
+
export type { LinearInstallation, LinearInstallationStatus, UpdateLinearInstallationTokenExpiryParams, UpsertLinearInstallationParams, } from '#db/installations.js';
|
|
27
|
+
export { getLinearInstallationByConnectionId, getLinearInstallationByOrganizationId, markLinearInstallationRevoked, updateLinearInstallationTokenExpiry, upsertLinearInstallation, withLinearRefreshLock, } from '#db/installations.js';
|
|
28
|
+
export { type CreateLinearE2eRoutesOptions, createLinearE2eRoutes, } from '#presentation/e2eRoutes/index.js';
|
|
29
|
+
export { closeDb, config, db, migrationsPath };
|
|
30
|
+
export interface CreateLinearIntegrationProviderOptions {
|
|
31
|
+
linear?: LinearApiClient | undefined;
|
|
32
|
+
agentTools?: {
|
|
33
|
+
tokenStore: Pick<LinearTokenStore, 'getAccessToken'>;
|
|
34
|
+
endpoint?: string | URL | undefined;
|
|
35
|
+
callTimeoutMs?: number | undefined;
|
|
36
|
+
} | undefined;
|
|
37
|
+
getLinearInstallationByConnectionId?: typeof getLinearInstallationByConnectionId | undefined;
|
|
38
|
+
routes?: (Omit<CreateLinearIntegrationRoutesOptions, 'linear' | 'connectionCapabilities'> & Partial<CreateLinearWebhookRoutesOptions>) | undefined;
|
|
39
|
+
}
|
|
40
|
+
export declare function createLinearIntegrationProvider(options?: CreateLinearIntegrationProviderOptions): {
|
|
41
|
+
provider: string;
|
|
42
|
+
displayName: string;
|
|
43
|
+
adapters: {
|
|
44
|
+
agent_tools: LinearAgentToolsProvider;
|
|
45
|
+
} | {
|
|
46
|
+
agent_tools?: never;
|
|
47
|
+
};
|
|
48
|
+
connectionExternalUrl(connection: {
|
|
49
|
+
id: string;
|
|
50
|
+
}): Promise<string | undefined>;
|
|
51
|
+
routes: import("@shipfox/node-fastify").RouteGroup[];
|
|
52
|
+
};
|
|
53
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAwB,KAAK,eAAe,EAAC,MAAM,gBAAgB,CAAC;AAC3E,OAAO,EAAC,MAAM,EAAC,MAAM,YAAY,CAAC;AAClC,OAAO,EAAC,wBAAwB,EAAC,MAAM,+BAA+B,CAAC;AACvE,OAAO,KAAK,EAAC,gBAAgB,EAAC,MAAM,iBAAiB,CAAC;AACtD,OAAO,EAAC,OAAO,EAAE,EAAE,EAAC,MAAM,WAAW,CAAC;AACtC,OAAO,EAAC,mCAAmC,EAAC,MAAM,sBAAsB,CAAC;AACzE,OAAO,EAAC,cAAc,EAAC,MAAM,mBAAmB,CAAC;AACjD,OAAO,EACL,KAAK,oCAAoC,EAE1C,MAAM,iCAAiC,CAAC;AACzC,OAAO,EACL,KAAK,gCAAgC,EAEtC,MAAM,kCAAkC,CAAC;AAE1C,YAAY,EAAC,cAAc,EAAC,MAAM,qCAAqC,CAAC;AACxE,YAAY,EAAC,eAAe,EAAE,mBAAmB,EAAE,cAAc,EAAC,MAAM,gBAAgB,CAAC;AACzF,OAAO,EAAC,qBAAqB,EAAC,MAAM,gBAAgB,CAAC;AACrD,YAAY,EACV,2BAA2B,EAC3B,uBAAuB,EACvB,iBAAiB,EACjB,4BAA4B,GAC7B,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EACL,sBAAsB,EACtB,+BAA+B,GAChC,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EACL,KAAK,kCAAkC,EACvC,4BAA4B,GAC7B,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACL,6BAA6B,EAC7B,qCAAqC,EACrC,kCAAkC,EAClC,6BAA6B,EAC7B,oCAAoC,EACpC,oCAAoC,EACpC,uBAAuB,EACvB,8BAA8B,EAC9B,wBAAwB,EACxB,6BAA6B,GAC9B,MAAM,iBAAiB,CAAC;AACzB,YAAY,EAAC,8BAA8B,EAAE,0BAA0B,EAAC,MAAM,kBAAkB,CAAC;AACjG,OAAO,EAAC,oBAAoB,EAAE,8BAA8B,EAAC,MAAM,kBAAkB,CAAC;AACtF,OAAO,EACL,+BAA+B,EAC/B,uBAAuB,EACvB,mBAAmB,GACpB,MAAM,iBAAiB,CAAC;AACzB,YAAY,EAAC,wBAAwB,EAAC,MAAM,gBAAgB,CAAC;AAC7D,OAAO,EAAC,sBAAsB,EAAE,wBAAwB,EAAC,MAAM,gBAAgB,CAAC;AAChF,YAAY,EACV,4BAA4B,EAC5B,0BAA0B,EAC1B,8BAA8B,EAC9B,kBAAkB,EAClB,gBAAgB,EAChB,uBAAuB,GACxB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACL,sBAAsB,EACtB,sBAAsB,GACvB,MAAM,iBAAiB,CAAC;AACzB,YAAY,EAAC,0BAA0B,EAAE,yBAAyB,EAAC,MAAM,kBAAkB,CAAC;AAC5F,OAAO,EAAC,mBAAmB,EAAC,MAAM,kBAAkB,CAAC;AACrD,YAAY,EACV,kBAAkB,EAClB,wBAAwB,EACxB,yCAAyC,EACzC,8BAA8B,GAC/B,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EACL,mCAAmC,EACnC,qCAAqC,EACrC,6BAA6B,EAC7B,mCAAmC,EACnC,wBAAwB,EACxB,qBAAqB,GACtB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EACL,KAAK,4BAA4B,EACjC,qBAAqB,GACtB,MAAM,kCAAkC,CAAC;AAC1C,OAAO,EAAC,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE,cAAc,EAAC,CAAC;AAE7C,MAAM,WAAW,sCAAsC;IACrD,MAAM,CAAC,EAAE,eAAe,GAAG,SAAS,CAAC;IACrC,UAAU,CAAC,EACP;QACE,UAAU,EAAE,IAAI,CAAC,gBAAgB,EAAE,gBAAgB,CAAC,CAAC;QACrD,QAAQ,CAAC,EAAE,MAAM,GAAG,GAAG,GAAG,SAAS,CAAC;QACpC,aAAa,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;KACpC,GACD,SAAS,CAAC;IACd,mCAAmC,CAAC,EAAE,OAAO,mCAAmC,GAAG,SAAS,CAAC;IAC7F,MAAM,CAAC,EACH,CAAC,IAAI,CAAC,oCAAoC,EAAE,QAAQ,GAAG,wBAAwB,CAAC,GAC9E,OAAO,CAAC,gCAAgC,CAAC,CAAC,GAC5C,SAAS,CAAC;CACf;AAED,wBAAgB,+BAA+B,CAC7C,OAAO,GAAE,sCAA2C;;;;;;;;sCA4BV;QAAC,EAAE,EAAE,MAAM,CAAA;KAAC,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC;;EAOrF"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { LINEAR_PROVIDER } from '@shipfox/api-integration-linear-dto';
|
|
2
|
+
import { createLinearApiClient } from '#api/client.js';
|
|
3
|
+
import { config } from '#config.js';
|
|
4
|
+
import { LinearAgentToolsProvider } from '#core/agent-tools-provider.js';
|
|
5
|
+
import { closeDb, db } from '#db/db.js';
|
|
6
|
+
import { getLinearInstallationByConnectionId } from '#db/installations.js';
|
|
7
|
+
import { migrationsPath } from '#db/migrations.js';
|
|
8
|
+
import { createLinearIntegrationRoutes } from '#presentation/routes/install.js';
|
|
9
|
+
import { createLinearWebhookRoutes } from '#presentation/routes/webhooks.js';
|
|
10
|
+
export { createLinearApiClient } from '#api/client.js';
|
|
11
|
+
export { linearAgentToolCatalog, linearAgentToolSelectionCatalog } from '#core/agent-tools.js';
|
|
12
|
+
export { disconnectLinearInstallation } from '#core/disconnect.js';
|
|
13
|
+
export { LinearAccessTokenMissingError, LinearAuthorizationScopeMismatchError, LinearConnectionAlreadyLinkedError, LinearConnectionNotFoundError, LinearInstallationAlreadyLinkedError, LinearInstallStateActorMismatchError, LinearInstallStateError, LinearIntegrationProviderError, LinearOAuthCallbackError, LinearTokenUnrefreshableError } from '#core/errors.js';
|
|
14
|
+
export { handleLinearCallback, handleLinearOAuthCallbackError } from '#core/install.js';
|
|
15
|
+
export { assertLinearAuthorizationScopes, formatLinearOAuthScopes, LINEAR_OAUTH_SCOPES } from '#core/scopes.js';
|
|
16
|
+
export { signLinearInstallState, verifyLinearInstallState } from '#core/state.js';
|
|
17
|
+
export { createLinearTokenStore, linearSecretsNamespace } from '#core/tokens.js';
|
|
18
|
+
export { handleLinearWebhook } from '#core/webhook.js';
|
|
19
|
+
export { getLinearInstallationByConnectionId, getLinearInstallationByOrganizationId, markLinearInstallationRevoked, updateLinearInstallationTokenExpiry, upsertLinearInstallation, withLinearRefreshLock } from '#db/installations.js';
|
|
20
|
+
export { createLinearE2eRoutes } from '#presentation/e2eRoutes/index.js';
|
|
21
|
+
export { closeDb, config, db, migrationsPath };
|
|
22
|
+
export function createLinearIntegrationProvider(options = {}) {
|
|
23
|
+
const linear = options.linear ?? createLinearApiClient();
|
|
24
|
+
const getInstallationByConnectionId = options.getLinearInstallationByConnectionId ?? getLinearInstallationByConnectionId;
|
|
25
|
+
const adapters = options.agentTools ? {
|
|
26
|
+
agent_tools: new LinearAgentToolsProvider(options.agentTools)
|
|
27
|
+
} : {};
|
|
28
|
+
const routes = options.routes ? [
|
|
29
|
+
createLinearIntegrationRoutes({
|
|
30
|
+
linear,
|
|
31
|
+
connectionCapabilities: adapters.agent_tools ? [
|
|
32
|
+
'agent_tools'
|
|
33
|
+
] : [],
|
|
34
|
+
...options.routes
|
|
35
|
+
})
|
|
36
|
+
] : [];
|
|
37
|
+
if (options.routes && hasLinearWebhookRoutesOptions(options.routes)) {
|
|
38
|
+
routes.push(createLinearWebhookRoutes(options.routes));
|
|
39
|
+
}
|
|
40
|
+
return {
|
|
41
|
+
provider: LINEAR_PROVIDER,
|
|
42
|
+
displayName: 'Linear',
|
|
43
|
+
adapters,
|
|
44
|
+
async connectionExternalUrl (connection) {
|
|
45
|
+
const installation = await getInstallationByConnectionId(connection.id);
|
|
46
|
+
if (!installation?.organizationUrlKey) return undefined;
|
|
47
|
+
return `https://linear.app/${encodeURIComponent(installation.organizationUrlKey)}/settings`;
|
|
48
|
+
},
|
|
49
|
+
routes
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
function hasLinearWebhookRoutesOptions(routes) {
|
|
53
|
+
return routes.coreDb !== undefined && routes.publishIntegrationEventReceived !== undefined && routes.recordDeliveryOnly !== undefined && routes.getIntegrationConnectionById !== undefined;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["import {LINEAR_PROVIDER} from '@shipfox/api-integration-linear-dto';\nimport {createLinearApiClient, type LinearApiClient} from '#api/client.js';\nimport {config} from '#config.js';\nimport {LinearAgentToolsProvider} from '#core/agent-tools-provider.js';\nimport type {LinearTokenStore} from '#core/tokens.js';\nimport {closeDb, db} from '#db/db.js';\nimport {getLinearInstallationByConnectionId} from '#db/installations.js';\nimport {migrationsPath} from '#db/migrations.js';\nimport {\n type CreateLinearIntegrationRoutesOptions,\n createLinearIntegrationRoutes,\n} from '#presentation/routes/install.js';\nimport {\n type CreateLinearWebhookRoutesOptions,\n createLinearWebhookRoutes,\n} from '#presentation/routes/webhooks.js';\n\nexport type {LinearProvider} from '@shipfox/api-integration-linear-dto';\nexport type {LinearApiClient, LinearAuthorization, LinearIdentity} from '#api/client.js';\nexport {createLinearApiClient} from '#api/client.js';\nexport type {\n LinearAgentToolCatalogEntry,\n LinearAgentToolCategory,\n LinearAgentToolId,\n LinearAgentToolRequiredScope,\n} from '#core/agent-tools.js';\nexport {\n linearAgentToolCatalog,\n linearAgentToolSelectionCatalog,\n} from '#core/agent-tools.js';\nexport {\n type DisconnectLinearInstallationParams,\n disconnectLinearInstallation,\n} from '#core/disconnect.js';\nexport {\n LinearAccessTokenMissingError,\n LinearAuthorizationScopeMismatchError,\n LinearConnectionAlreadyLinkedError,\n LinearConnectionNotFoundError,\n LinearInstallationAlreadyLinkedError,\n LinearInstallStateActorMismatchError,\n LinearInstallStateError,\n LinearIntegrationProviderError,\n LinearOAuthCallbackError,\n LinearTokenUnrefreshableError,\n} from '#core/errors.js';\nexport type {ConnectLinearInstallationInput, HandleLinearCallbackParams} from '#core/install.js';\nexport {handleLinearCallback, handleLinearOAuthCallbackError} from '#core/install.js';\nexport {\n assertLinearAuthorizationScopes,\n formatLinearOAuthScopes,\n LINEAR_OAUTH_SCOPES,\n} from '#core/scopes.js';\nexport type {LinearInstallStateClaims} from '#core/state.js';\nexport {signLinearInstallState, verifyLinearInstallState} from '#core/state.js';\nexport type {\n CreateLinearTokenStoreParams,\n GetLinearAccessTokenParams,\n LinearConnectionResolverResult,\n LinearSecretsStore,\n LinearTokenStore,\n StoreLinearTokensParams,\n} from '#core/tokens.js';\nexport {\n createLinearTokenStore,\n linearSecretsNamespace,\n} from '#core/tokens.js';\nexport type {HandleLinearWebhookOutcome, HandleLinearWebhookParams} from '#core/webhook.js';\nexport {handleLinearWebhook} from '#core/webhook.js';\nexport type {\n LinearInstallation,\n LinearInstallationStatus,\n UpdateLinearInstallationTokenExpiryParams,\n UpsertLinearInstallationParams,\n} from '#db/installations.js';\nexport {\n getLinearInstallationByConnectionId,\n getLinearInstallationByOrganizationId,\n markLinearInstallationRevoked,\n updateLinearInstallationTokenExpiry,\n upsertLinearInstallation,\n withLinearRefreshLock,\n} from '#db/installations.js';\nexport {\n type CreateLinearE2eRoutesOptions,\n createLinearE2eRoutes,\n} from '#presentation/e2eRoutes/index.js';\nexport {closeDb, config, db, migrationsPath};\n\nexport interface CreateLinearIntegrationProviderOptions {\n linear?: LinearApiClient | undefined;\n agentTools?:\n | {\n tokenStore: Pick<LinearTokenStore, 'getAccessToken'>;\n endpoint?: string | URL | undefined;\n callTimeoutMs?: number | undefined;\n }\n | undefined;\n getLinearInstallationByConnectionId?: typeof getLinearInstallationByConnectionId | undefined;\n routes?:\n | (Omit<CreateLinearIntegrationRoutesOptions, 'linear' | 'connectionCapabilities'> &\n Partial<CreateLinearWebhookRoutesOptions>)\n | undefined;\n}\n\nexport function createLinearIntegrationProvider(\n options: CreateLinearIntegrationProviderOptions = {},\n) {\n const linear = options.linear ?? createLinearApiClient();\n const getInstallationByConnectionId =\n options.getLinearInstallationByConnectionId ?? getLinearInstallationByConnectionId;\n const adapters = options.agentTools\n ? {\n agent_tools: new LinearAgentToolsProvider(options.agentTools),\n }\n : {};\n\n const routes = options.routes\n ? [\n createLinearIntegrationRoutes({\n linear,\n connectionCapabilities: adapters.agent_tools ? ['agent_tools'] : [],\n ...options.routes,\n }),\n ]\n : [];\n if (options.routes && hasLinearWebhookRoutesOptions(options.routes)) {\n routes.push(createLinearWebhookRoutes(options.routes));\n }\n\n return {\n provider: LINEAR_PROVIDER,\n displayName: 'Linear',\n adapters,\n async connectionExternalUrl(connection: {id: string}): Promise<string | undefined> {\n const installation = await getInstallationByConnectionId(connection.id);\n if (!installation?.organizationUrlKey) return undefined;\n return `https://linear.app/${encodeURIComponent(installation.organizationUrlKey)}/settings`;\n },\n routes,\n };\n}\n\nfunction hasLinearWebhookRoutesOptions(\n routes: Partial<CreateLinearWebhookRoutesOptions>,\n): routes is CreateLinearWebhookRoutesOptions {\n return (\n routes.coreDb !== undefined &&\n routes.publishIntegrationEventReceived !== undefined &&\n routes.recordDeliveryOnly !== undefined &&\n routes.getIntegrationConnectionById !== undefined\n );\n}\n"],"names":["LINEAR_PROVIDER","createLinearApiClient","config","LinearAgentToolsProvider","closeDb","db","getLinearInstallationByConnectionId","migrationsPath","createLinearIntegrationRoutes","createLinearWebhookRoutes","linearAgentToolCatalog","linearAgentToolSelectionCatalog","disconnectLinearInstallation","LinearAccessTokenMissingError","LinearAuthorizationScopeMismatchError","LinearConnectionAlreadyLinkedError","LinearConnectionNotFoundError","LinearInstallationAlreadyLinkedError","LinearInstallStateActorMismatchError","LinearInstallStateError","LinearIntegrationProviderError","LinearOAuthCallbackError","LinearTokenUnrefreshableError","handleLinearCallback","handleLinearOAuthCallbackError","assertLinearAuthorizationScopes","formatLinearOAuthScopes","LINEAR_OAUTH_SCOPES","signLinearInstallState","verifyLinearInstallState","createLinearTokenStore","linearSecretsNamespace","handleLinearWebhook","getLinearInstallationByOrganizationId","markLinearInstallationRevoked","updateLinearInstallationTokenExpiry","upsertLinearInstallation","withLinearRefreshLock","createLinearE2eRoutes","createLinearIntegrationProvider","options","linear","getInstallationByConnectionId","adapters","agentTools","agent_tools","routes","connectionCapabilities","hasLinearWebhookRoutesOptions","push","provider","displayName","connectionExternalUrl","connection","installation","id","organizationUrlKey","undefined","encodeURIComponent","coreDb","publishIntegrationEventReceived","recordDeliveryOnly","getIntegrationConnectionById"],"mappings":"AAAA,SAAQA,eAAe,QAAO,sCAAsC;AACpE,SAAQC,qBAAqB,QAA6B,iBAAiB;AAC3E,SAAQC,MAAM,QAAO,aAAa;AAClC,SAAQC,wBAAwB,QAAO,gCAAgC;AAEvE,SAAQC,OAAO,EAAEC,EAAE,QAAO,YAAY;AACtC,SAAQC,mCAAmC,QAAO,uBAAuB;AACzE,SAAQC,cAAc,QAAO,oBAAoB;AACjD,SAEEC,6BAA6B,QACxB,kCAAkC;AACzC,SAEEC,yBAAyB,QACpB,mCAAmC;AAI1C,SAAQR,qBAAqB,QAAO,iBAAiB;AAOrD,SACES,sBAAsB,EACtBC,+BAA+B,QAC1B,uBAAuB;AAC9B,SAEEC,4BAA4B,QACvB,sBAAsB;AAC7B,SACEC,6BAA6B,EAC7BC,qCAAqC,EACrCC,kCAAkC,EAClCC,6BAA6B,EAC7BC,oCAAoC,EACpCC,oCAAoC,EACpCC,uBAAuB,EACvBC,8BAA8B,EAC9BC,wBAAwB,EACxBC,6BAA6B,QACxB,kBAAkB;AAEzB,SAAQC,oBAAoB,EAAEC,8BAA8B,QAAO,mBAAmB;AACtF,SACEC,+BAA+B,EAC/BC,uBAAuB,EACvBC,mBAAmB,QACd,kBAAkB;AAEzB,SAAQC,sBAAsB,EAAEC,wBAAwB,QAAO,iBAAiB;AAShF,SACEC,sBAAsB,EACtBC,sBAAsB,QACjB,kBAAkB;AAEzB,SAAQC,mBAAmB,QAAO,mBAAmB;AAOrD,SACE1B,mCAAmC,EACnC2B,qCAAqC,EACrCC,6BAA6B,EAC7BC,mCAAmC,EACnCC,wBAAwB,EACxBC,qBAAqB,QAChB,uBAAuB;AAC9B,SAEEC,qBAAqB,QAChB,mCAAmC;AAC1C,SAAQlC,OAAO,EAAEF,MAAM,EAAEG,EAAE,EAAEE,cAAc,GAAE;AAkB7C,OAAO,SAASgC,gCACdC,UAAkD,CAAC,CAAC;IAEpD,MAAMC,SAASD,QAAQC,MAAM,IAAIxC;IACjC,MAAMyC,gCACJF,QAAQlC,mCAAmC,IAAIA;IACjD,MAAMqC,WAAWH,QAAQI,UAAU,GAC/B;QACEC,aAAa,IAAI1C,yBAAyBqC,QAAQI,UAAU;IAC9D,IACA,CAAC;IAEL,MAAME,SAASN,QAAQM,MAAM,GACzB;QACEtC,8BAA8B;YAC5BiC;YACAM,wBAAwBJ,SAASE,WAAW,GAAG;gBAAC;aAAc,GAAG,EAAE;YACnE,GAAGL,QAAQM,MAAM;QACnB;KACD,GACD,EAAE;IACN,IAAIN,QAAQM,MAAM,IAAIE,8BAA8BR,QAAQM,MAAM,GAAG;QACnEA,OAAOG,IAAI,CAACxC,0BAA0B+B,QAAQM,MAAM;IACtD;IAEA,OAAO;QACLI,UAAUlD;QACVmD,aAAa;QACbR;QACA,MAAMS,uBAAsBC,UAAwB;YAClD,MAAMC,eAAe,MAAMZ,8BAA8BW,WAAWE,EAAE;YACtE,IAAI,CAACD,cAAcE,oBAAoB,OAAOC;YAC9C,OAAO,CAAC,mBAAmB,EAAEC,mBAAmBJ,aAAaE,kBAAkB,EAAE,SAAS,CAAC;QAC7F;QACAV;IACF;AACF;AAEA,SAASE,8BACPF,MAAiD;IAEjD,OACEA,OAAOa,MAAM,KAAKF,aAClBX,OAAOc,+BAA+B,KAAKH,aAC3CX,OAAOe,kBAAkB,KAAKJ,aAC9BX,OAAOgB,4BAA4B,KAAKL;AAE5C"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { IntegrationCapability, IntegrationConnection } from '@shipfox/api-integration-core-dto';
|
|
2
|
+
export declare function toIntegrationConnectionDto(connection: IntegrationConnection, params: {
|
|
3
|
+
capabilities: IntegrationCapability[];
|
|
4
|
+
}): {
|
|
5
|
+
created_at: string;
|
|
6
|
+
updated_at: string;
|
|
7
|
+
external_url?: string;
|
|
8
|
+
id: string;
|
|
9
|
+
workspace_id: string;
|
|
10
|
+
provider: string;
|
|
11
|
+
external_account_id: string;
|
|
12
|
+
slug: string;
|
|
13
|
+
display_name: string;
|
|
14
|
+
lifecycle_status: import("@shipfox/api-integration-core-dto").IntegrationConnectionLifecycleStatus;
|
|
15
|
+
capabilities: IntegrationCapability[];
|
|
16
|
+
};
|
|
17
|
+
//# 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,KAAK,EAAC,qBAAqB,EAAE,qBAAqB,EAAC,MAAM,mCAAmC,CAAC;AAGpG,wBAAgB,0BAA0B,CACxC,UAAU,EAAE,qBAAqB,EACjC,MAAM,EAAE;IAAC,YAAY,EAAE,qBAAqB,EAAE,CAAA;CAAC;;;;;;;;;;;;EAGhD"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { toIntegrationConnectionDto as toCoreIntegrationConnectionDto } from '@shipfox/api-integration-core-dto';
|
|
2
|
+
export function toIntegrationConnectionDto(connection, params) {
|
|
3
|
+
return toCoreIntegrationConnectionDto(connection, params);
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
//# sourceMappingURL=integrations.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/presentation/dto/integrations.ts"],"sourcesContent":["import type {IntegrationCapability, IntegrationConnection} from '@shipfox/api-integration-core-dto';\nimport {toIntegrationConnectionDto as toCoreIntegrationConnectionDto} from '@shipfox/api-integration-core-dto';\n\nexport function toIntegrationConnectionDto(\n connection: IntegrationConnection,\n params: {capabilities: IntegrationCapability[]},\n) {\n return toCoreIntegrationConnectionDto(connection, params);\n}\n"],"names":["toIntegrationConnectionDto","toCoreIntegrationConnectionDto","connection","params"],"mappings":"AACA,SAAQA,8BAA8BC,8BAA8B,QAAO,oCAAoC;AAE/G,OAAO,SAASD,2BACdE,UAAiC,EACjCC,MAA+C;IAE/C,OAAOF,+BAA+BC,YAAYC;AACpD"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { IntegrationCapability, IntegrationConnection } from '@shipfox/api-integration-core-dto';
|
|
2
|
+
import type { ConnectLinearInstallationInput } from '#core/install.js';
|
|
3
|
+
import type { LinearTokenStore } from '#core/tokens.js';
|
|
4
|
+
export interface CreateE2eLinearConnectionRouteOptions {
|
|
5
|
+
tokenStore: Pick<LinearTokenStore, 'storeTokens'>;
|
|
6
|
+
getExistingLinearConnection: (input: {
|
|
7
|
+
organizationId: string;
|
|
8
|
+
}) => Promise<IntegrationConnection<'linear'> | undefined>;
|
|
9
|
+
connectLinearInstallation: (input: ConnectLinearInstallationInput) => Promise<IntegrationConnection<'linear'>>;
|
|
10
|
+
disconnectLinearInstallation: (input: {
|
|
11
|
+
connectionId: string;
|
|
12
|
+
}) => Promise<void>;
|
|
13
|
+
connectionCapabilities: IntegrationCapability[];
|
|
14
|
+
}
|
|
15
|
+
export declare function createE2eLinearConnectionRoute(options: CreateE2eLinearConnectionRouteOptions): 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,8BAA8B,EAAC,MAAM,kBAAkB,CAAC;AACrE,OAAO,KAAK,EAAC,gBAAgB,EAAC,MAAM,iBAAiB,CAAC;AAGtD,MAAM,WAAW,qCAAqC;IACpD,UAAU,EAAE,IAAI,CAAC,gBAAgB,EAAE,aAAa,CAAC,CAAC;IAClD,2BAA2B,EAAE,CAAC,KAAK,EAAE;QACnC,cAAc,EAAE,MAAM,CAAC;KACxB,KAAK,OAAO,CAAC,qBAAqB,CAAC,QAAQ,CAAC,GAAG,SAAS,CAAC,CAAC;IAC3D,yBAAyB,EAAE,CACzB,KAAK,EAAE,8BAA8B,KAClC,OAAO,CAAC,qBAAqB,CAAC,QAAQ,CAAC,CAAC,CAAC;IAC9C,4BAA4B,EAAE,CAAC,KAAK,EAAE;QAAC,YAAY,EAAE,MAAM,CAAA;KAAC,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC/E,sBAAsB,EAAE,qBAAqB,EAAE,CAAC;CACjD;AAED,wBAAgB,8BAA8B,CAAC,OAAO,EAAE,qCAAqC,mDA+C5F"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { createE2eLinearConnectionBodySchema, createE2eLinearConnectionResponseSchema } from '@shipfox/api-integration-linear-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 createE2eLinearConnectionRoute(options) {
|
|
6
|
+
return defineRoute({
|
|
7
|
+
method: 'POST',
|
|
8
|
+
path: '/linear-connections',
|
|
9
|
+
description: 'Create a synthetic Linear connection for E2E tests.',
|
|
10
|
+
schema: {
|
|
11
|
+
body: createE2eLinearConnectionBodySchema,
|
|
12
|
+
response: {
|
|
13
|
+
201: createE2eLinearConnectionResponseSchema
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
handler: async (request, reply)=>{
|
|
17
|
+
const body = request.body;
|
|
18
|
+
const existing = await options.getExistingLinearConnection({
|
|
19
|
+
organizationId: body.organization_id
|
|
20
|
+
});
|
|
21
|
+
if (existing && existing.workspaceId !== body.workspace_id) {
|
|
22
|
+
throw new ClientError('Linear organization is already connected to another workspace', 'linear-connection-workspace-mismatch', {
|
|
23
|
+
status: 409
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
const connection = existing ?? await options.connectLinearInstallation({
|
|
27
|
+
workspaceId: body.workspace_id,
|
|
28
|
+
organizationId: body.organization_id,
|
|
29
|
+
organizationUrlKey: body.organization_url_key,
|
|
30
|
+
appUserId: body.app_user_id,
|
|
31
|
+
scopes: body.scopes,
|
|
32
|
+
tokenExpiresAt: null,
|
|
33
|
+
displayName: body.display_name
|
|
34
|
+
});
|
|
35
|
+
try {
|
|
36
|
+
await options.tokenStore.storeTokens({
|
|
37
|
+
connectionId: connection.id,
|
|
38
|
+
accessToken: body.access_token
|
|
39
|
+
});
|
|
40
|
+
} catch (error) {
|
|
41
|
+
if (!existing) await bestEffortDisconnectLinearInstallation(options, connection.id);
|
|
42
|
+
throw error;
|
|
43
|
+
}
|
|
44
|
+
reply.code(201);
|
|
45
|
+
return toIntegrationConnectionDto(connection, {
|
|
46
|
+
capabilities: options.connectionCapabilities
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
async function bestEffortDisconnectLinearInstallation(options, connectionId) {
|
|
52
|
+
try {
|
|
53
|
+
await options.disconnectLinearInstallation({
|
|
54
|
+
connectionId
|
|
55
|
+
});
|
|
56
|
+
} catch (error) {
|
|
57
|
+
logger().warn({
|
|
58
|
+
err: error,
|
|
59
|
+
connectionId
|
|
60
|
+
}, 'Linear E2E connection compensation failed after token storage rejection');
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
//# 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 createE2eLinearConnectionBodySchema,\n createE2eLinearConnectionResponseSchema,\n} from '@shipfox/api-integration-linear-dto';\nimport {ClientError, defineRoute} from '@shipfox/node-fastify';\nimport {logger} from '@shipfox/node-opentelemetry';\nimport type {ConnectLinearInstallationInput} from '#core/install.js';\nimport type {LinearTokenStore} from '#core/tokens.js';\nimport {toIntegrationConnectionDto} from '#presentation/dto/integrations.js';\n\nexport interface CreateE2eLinearConnectionRouteOptions {\n tokenStore: Pick<LinearTokenStore, 'storeTokens'>;\n getExistingLinearConnection: (input: {\n organizationId: string;\n }) => Promise<IntegrationConnection<'linear'> | undefined>;\n connectLinearInstallation: (\n input: ConnectLinearInstallationInput,\n ) => Promise<IntegrationConnection<'linear'>>;\n disconnectLinearInstallation: (input: {connectionId: string}) => Promise<void>;\n connectionCapabilities: IntegrationCapability[];\n}\n\nexport function createE2eLinearConnectionRoute(options: CreateE2eLinearConnectionRouteOptions) {\n return defineRoute({\n method: 'POST',\n path: '/linear-connections',\n description: 'Create a synthetic Linear connection for E2E tests.',\n schema: {\n body: createE2eLinearConnectionBodySchema,\n response: {201: createE2eLinearConnectionResponseSchema},\n },\n handler: async (request, reply) => {\n const body = request.body;\n const existing = await options.getExistingLinearConnection({\n organizationId: body.organization_id,\n });\n if (existing && existing.workspaceId !== body.workspace_id) {\n throw new ClientError(\n 'Linear organization is already connected to another workspace',\n 'linear-connection-workspace-mismatch',\n {status: 409},\n );\n }\n const connection =\n existing ??\n (await options.connectLinearInstallation({\n workspaceId: body.workspace_id,\n organizationId: body.organization_id,\n organizationUrlKey: body.organization_url_key,\n appUserId: body.app_user_id,\n scopes: body.scopes,\n tokenExpiresAt: null,\n displayName: body.display_name,\n }));\n\n try {\n await options.tokenStore.storeTokens({\n connectionId: connection.id,\n accessToken: body.access_token,\n });\n } catch (error) {\n if (!existing) await bestEffortDisconnectLinearInstallation(options, connection.id);\n throw error;\n }\n\n reply.code(201);\n return toIntegrationConnectionDto(connection, {capabilities: options.connectionCapabilities});\n },\n });\n}\n\nasync function bestEffortDisconnectLinearInstallation(\n options: CreateE2eLinearConnectionRouteOptions,\n connectionId: string,\n): Promise<void> {\n try {\n await options.disconnectLinearInstallation({connectionId});\n } catch (error) {\n logger().warn(\n {err: error, connectionId},\n 'Linear E2E connection compensation failed after token storage rejection',\n );\n }\n}\n"],"names":["createE2eLinearConnectionBodySchema","createE2eLinearConnectionResponseSchema","ClientError","defineRoute","logger","toIntegrationConnectionDto","createE2eLinearConnectionRoute","options","method","path","description","schema","body","response","handler","request","reply","existing","getExistingLinearConnection","organizationId","organization_id","workspaceId","workspace_id","status","connection","connectLinearInstallation","organizationUrlKey","organization_url_key","appUserId","app_user_id","scopes","tokenExpiresAt","displayName","display_name","tokenStore","storeTokens","connectionId","id","accessToken","access_token","error","bestEffortDisconnectLinearInstallation","code","capabilities","connectionCapabilities","disconnectLinearInstallation","warn","err"],"mappings":"AACA,SACEA,mCAAmC,EACnCC,uCAAuC,QAClC,sCAAsC;AAC7C,SAAQC,WAAW,EAAEC,WAAW,QAAO,wBAAwB;AAC/D,SAAQC,MAAM,QAAO,8BAA8B;AAGnD,SAAQC,0BAA0B,QAAO,oCAAoC;AAc7E,OAAO,SAASC,+BAA+BC,OAA8C;IAC3F,OAAOJ,YAAY;QACjBK,QAAQ;QACRC,MAAM;QACNC,aAAa;QACbC,QAAQ;YACNC,MAAMZ;YACNa,UAAU;gBAAC,KAAKZ;YAAuC;QACzD;QACAa,SAAS,OAAOC,SAASC;YACvB,MAAMJ,OAAOG,QAAQH,IAAI;YACzB,MAAMK,WAAW,MAAMV,QAAQW,2BAA2B,CAAC;gBACzDC,gBAAgBP,KAAKQ,eAAe;YACtC;YACA,IAAIH,YAAYA,SAASI,WAAW,KAAKT,KAAKU,YAAY,EAAE;gBAC1D,MAAM,IAAIpB,YACR,iEACA,wCACA;oBAACqB,QAAQ;gBAAG;YAEhB;YACA,MAAMC,aACJP,YACC,MAAMV,QAAQkB,yBAAyB,CAAC;gBACvCJ,aAAaT,KAAKU,YAAY;gBAC9BH,gBAAgBP,KAAKQ,eAAe;gBACpCM,oBAAoBd,KAAKe,oBAAoB;gBAC7CC,WAAWhB,KAAKiB,WAAW;gBAC3BC,QAAQlB,KAAKkB,MAAM;gBACnBC,gBAAgB;gBAChBC,aAAapB,KAAKqB,YAAY;YAChC;YAEF,IAAI;gBACF,MAAM1B,QAAQ2B,UAAU,CAACC,WAAW,CAAC;oBACnCC,cAAcZ,WAAWa,EAAE;oBAC3BC,aAAa1B,KAAK2B,YAAY;gBAChC;YACF,EAAE,OAAOC,OAAO;gBACd,IAAI,CAACvB,UAAU,MAAMwB,uCAAuClC,SAASiB,WAAWa,EAAE;gBAClF,MAAMG;YACR;YAEAxB,MAAM0B,IAAI,CAAC;YACX,OAAOrC,2BAA2BmB,YAAY;gBAACmB,cAAcpC,QAAQqC,sBAAsB;YAAA;QAC7F;IACF;AACF;AAEA,eAAeH,uCACblC,OAA8C,EAC9C6B,YAAoB;IAEpB,IAAI;QACF,MAAM7B,QAAQsC,4BAA4B,CAAC;YAACT;QAAY;IAC1D,EAAE,OAAOI,OAAO;QACdpC,SAAS0C,IAAI,CACX;YAACC,KAAKP;YAAOJ;QAAY,GACzB;IAEJ;AACF"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { RouteGroup } from '@shipfox/node-fastify';
|
|
2
|
+
import { type CreateE2eLinearConnectionRouteOptions } from './create-connection.js';
|
|
3
|
+
export type CreateLinearE2eRoutesOptions = CreateE2eLinearConnectionRouteOptions;
|
|
4
|
+
export declare function createLinearE2eRoutes(options: CreateLinearE2eRoutesOptions): 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,qCAAqC,EAE3C,MAAM,wBAAwB,CAAC;AAEhC,MAAM,MAAM,4BAA4B,GAAG,qCAAqC,CAAC;AAEjF,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,4BAA4B,GAAG,UAAU,CAKvF"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { createE2eLinearConnectionRoute } from './create-connection.js';
|
|
2
|
+
export function createLinearE2eRoutes(options) {
|
|
3
|
+
return {
|
|
4
|
+
prefix: '/integrations',
|
|
5
|
+
routes: [
|
|
6
|
+
createE2eLinearConnectionRoute(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 CreateE2eLinearConnectionRouteOptions,\n createE2eLinearConnectionRoute,\n} from './create-connection.js';\n\nexport type CreateLinearE2eRoutesOptions = CreateE2eLinearConnectionRouteOptions;\n\nexport function createLinearE2eRoutes(options: CreateLinearE2eRoutesOptions): RouteGroup {\n return {\n prefix: '/integrations',\n routes: [createE2eLinearConnectionRoute(options)],\n };\n}\n"],"names":["createE2eLinearConnectionRoute","createLinearE2eRoutes","options","prefix","routes"],"mappings":"AACA,SAEEA,8BAA8B,QACzB,yBAAyB;AAIhC,OAAO,SAASC,sBAAsBC,OAAqC;IACzE,OAAO;QACLC,QAAQ;QACRC,QAAQ;YAACJ,+BAA+BE;SAAS;IACnD;AACF"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../../src/presentation/routes/errors.ts"],"names":[],"mappings":"AAqBA,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,CAsC7D"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { ConnectionSlugConflictError } from '@shipfox/api-integration-core-dto';
|
|
2
|
+
import { ClientError } from '@shipfox/node-fastify';
|
|
3
|
+
import { LinearAuthorizationScopeMismatchError, LinearConnectionAlreadyLinkedError, LinearInstallationAlreadyLinkedError, LinearInstallStateActorMismatchError, LinearInstallStateError, LinearIntegrationProviderError, LinearOAuthCallbackError } from '#core/errors.js';
|
|
4
|
+
function providerStatus(reason) {
|
|
5
|
+
if (reason === 'rate-limited') return 429;
|
|
6
|
+
if (reason === 'timeout' || reason === 'provider-unavailable') return 503;
|
|
7
|
+
return 422;
|
|
8
|
+
}
|
|
9
|
+
export function linearRouteErrorHandler(error) {
|
|
10
|
+
if (error instanceof LinearInstallStateError) {
|
|
11
|
+
throw new ClientError(error.message, 'invalid-linear-install-state', {
|
|
12
|
+
status: 400
|
|
13
|
+
});
|
|
14
|
+
}
|
|
15
|
+
if (error instanceof LinearInstallStateActorMismatchError) {
|
|
16
|
+
throw new ClientError(error.message, 'linear-install-state-actor-mismatch', {
|
|
17
|
+
status: 403
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
if (error instanceof LinearInstallationAlreadyLinkedError) {
|
|
21
|
+
throw new ClientError(error.message, 'linear-installation-already-linked', {
|
|
22
|
+
status: 409
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
if (error instanceof LinearConnectionAlreadyLinkedError) {
|
|
26
|
+
throw new ClientError(error.message, 'linear-connection-already-linked', {
|
|
27
|
+
status: 409
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
if (error instanceof LinearAuthorizationScopeMismatchError) {
|
|
31
|
+
throw new ClientError(error.message, 'linear-authorization-scope-mismatch', {
|
|
32
|
+
status: 422,
|
|
33
|
+
details: {
|
|
34
|
+
missing_scopes: error.missingScopes
|
|
35
|
+
}
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
if (error instanceof LinearOAuthCallbackError) {
|
|
39
|
+
throw new ClientError(error.message, 'linear-oauth-callback-error', {
|
|
40
|
+
status: 422,
|
|
41
|
+
details: {
|
|
42
|
+
error: error.providerError,
|
|
43
|
+
...error.providerDescription ? {
|
|
44
|
+
error_description: error.providerDescription
|
|
45
|
+
} : {}
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
if (error instanceof ConnectionSlugConflictError) {
|
|
50
|
+
throw new ClientError(error.message, 'slug-conflict', {
|
|
51
|
+
status: 409
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
if (error instanceof LinearIntegrationProviderError) {
|
|
55
|
+
throw new ClientError(error.message, error.reason, {
|
|
56
|
+
details: {
|
|
57
|
+
retry_after_seconds: error.retryAfterSeconds
|
|
58
|
+
},
|
|
59
|
+
status: providerStatus(error.reason)
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
throw error;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
//# sourceMappingURL=errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/presentation/routes/errors.ts"],"sourcesContent":["import {\n ConnectionSlugConflictError,\n type IntegrationProviderErrorReason,\n} from '@shipfox/api-integration-core-dto';\nimport {ClientError} from '@shipfox/node-fastify';\nimport {\n LinearAuthorizationScopeMismatchError,\n LinearConnectionAlreadyLinkedError,\n LinearInstallationAlreadyLinkedError,\n LinearInstallStateActorMismatchError,\n LinearInstallStateError,\n LinearIntegrationProviderError,\n LinearOAuthCallbackError,\n} from '#core/errors.js';\n\nfunction providerStatus(reason: IntegrationProviderErrorReason): number {\n if (reason === 'rate-limited') return 429;\n if (reason === 'timeout' || reason === 'provider-unavailable') return 503;\n return 422;\n}\n\nexport function linearRouteErrorHandler(error: unknown): never {\n if (error instanceof LinearInstallStateError) {\n throw new ClientError(error.message, 'invalid-linear-install-state', {status: 400});\n }\n if (error instanceof LinearInstallStateActorMismatchError) {\n throw new ClientError(error.message, 'linear-install-state-actor-mismatch', {status: 403});\n }\n if (error instanceof LinearInstallationAlreadyLinkedError) {\n throw new ClientError(error.message, 'linear-installation-already-linked', {status: 409});\n }\n if (error instanceof LinearConnectionAlreadyLinkedError) {\n throw new ClientError(error.message, 'linear-connection-already-linked', {status: 409});\n }\n if (error instanceof LinearAuthorizationScopeMismatchError) {\n throw new ClientError(error.message, 'linear-authorization-scope-mismatch', {\n status: 422,\n details: {missing_scopes: error.missingScopes},\n });\n }\n if (error instanceof LinearOAuthCallbackError) {\n throw new ClientError(error.message, 'linear-oauth-callback-error', {\n status: 422,\n details: {\n error: error.providerError,\n ...(error.providerDescription ? {error_description: error.providerDescription} : {}),\n },\n });\n }\n if (error instanceof ConnectionSlugConflictError) {\n throw new ClientError(error.message, 'slug-conflict', {status: 409});\n }\n if (error instanceof LinearIntegrationProviderError) {\n throw new ClientError(error.message, error.reason, {\n details: {retry_after_seconds: error.retryAfterSeconds},\n status: providerStatus(error.reason),\n });\n }\n throw error;\n}\n"],"names":["ConnectionSlugConflictError","ClientError","LinearAuthorizationScopeMismatchError","LinearConnectionAlreadyLinkedError","LinearInstallationAlreadyLinkedError","LinearInstallStateActorMismatchError","LinearInstallStateError","LinearIntegrationProviderError","LinearOAuthCallbackError","providerStatus","reason","linearRouteErrorHandler","error","message","status","details","missing_scopes","missingScopes","providerError","providerDescription","error_description","retry_after_seconds","retryAfterSeconds"],"mappings":"AAAA,SACEA,2BAA2B,QAEtB,oCAAoC;AAC3C,SAAQC,WAAW,QAAO,wBAAwB;AAClD,SACEC,qCAAqC,EACrCC,kCAAkC,EAClCC,oCAAoC,EACpCC,oCAAoC,EACpCC,uBAAuB,EACvBC,8BAA8B,EAC9BC,wBAAwB,QACnB,kBAAkB;AAEzB,SAASC,eAAeC,MAAsC;IAC5D,IAAIA,WAAW,gBAAgB,OAAO;IACtC,IAAIA,WAAW,aAAaA,WAAW,wBAAwB,OAAO;IACtE,OAAO;AACT;AAEA,OAAO,SAASC,wBAAwBC,KAAc;IACpD,IAAIA,iBAAiBN,yBAAyB;QAC5C,MAAM,IAAIL,YAAYW,MAAMC,OAAO,EAAE,gCAAgC;YAACC,QAAQ;QAAG;IACnF;IACA,IAAIF,iBAAiBP,sCAAsC;QACzD,MAAM,IAAIJ,YAAYW,MAAMC,OAAO,EAAE,uCAAuC;YAACC,QAAQ;QAAG;IAC1F;IACA,IAAIF,iBAAiBR,sCAAsC;QACzD,MAAM,IAAIH,YAAYW,MAAMC,OAAO,EAAE,sCAAsC;YAACC,QAAQ;QAAG;IACzF;IACA,IAAIF,iBAAiBT,oCAAoC;QACvD,MAAM,IAAIF,YAAYW,MAAMC,OAAO,EAAE,oCAAoC;YAACC,QAAQ;QAAG;IACvF;IACA,IAAIF,iBAAiBV,uCAAuC;QAC1D,MAAM,IAAID,YAAYW,MAAMC,OAAO,EAAE,uCAAuC;YAC1EC,QAAQ;YACRC,SAAS;gBAACC,gBAAgBJ,MAAMK,aAAa;YAAA;QAC/C;IACF;IACA,IAAIL,iBAAiBJ,0BAA0B;QAC7C,MAAM,IAAIP,YAAYW,MAAMC,OAAO,EAAE,+BAA+B;YAClEC,QAAQ;YACRC,SAAS;gBACPH,OAAOA,MAAMM,aAAa;gBAC1B,GAAIN,MAAMO,mBAAmB,GAAG;oBAACC,mBAAmBR,MAAMO,mBAAmB;gBAAA,IAAI,CAAC,CAAC;YACrF;QACF;IACF;IACA,IAAIP,iBAAiBZ,6BAA6B;QAChD,MAAM,IAAIC,YAAYW,MAAMC,OAAO,EAAE,iBAAiB;YAACC,QAAQ;QAAG;IACpE;IACA,IAAIF,iBAAiBL,gCAAgC;QACnD,MAAM,IAAIN,YAAYW,MAAMC,OAAO,EAAED,MAAMF,MAAM,EAAE;YACjDK,SAAS;gBAACM,qBAAqBT,MAAMU,iBAAiB;YAAA;YACtDR,QAAQL,eAAeG,MAAMF,MAAM;QACrC;IACF;IACA,MAAME;AACR"}
|