@shipfox/api-integration-jira 4.0.0 → 5.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 +1 -1
- package/CHANGELOG.md +21 -0
- package/dist/api/client.d.ts +33 -0
- package/dist/api/client.d.ts.map +1 -0
- package/dist/api/client.js +143 -0
- package/dist/api/client.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 +21 -0
- package/dist/core/disconnect.js.map +1 -0
- package/dist/core/errors.d.ts +37 -0
- package/dist/core/errors.d.ts.map +1 -1
- package/dist/core/errors.js +63 -0
- package/dist/core/errors.js.map +1 -1
- package/dist/core/install.d.ts +55 -0
- package/dist/core/install.d.ts.map +1 -0
- package/dist/core/install.js +121 -0
- package/dist/core/install.js.map +1 -0
- package/dist/core/pending.d.ts +43 -0
- package/dist/core/pending.d.ts.map +1 -0
- package/dist/core/pending.js +107 -0
- package/dist/core/pending.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 +23 -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 +51 -0
- package/dist/core/state.js.map +1 -0
- package/dist/core/tokens.d.ts +6 -0
- package/dist/core/tokens.d.ts.map +1 -1
- package/dist/core/tokens.js +82 -6
- package/dist/core/tokens.js.map +1 -1
- package/dist/db/db.d.ts +188 -0
- package/dist/db/db.d.ts.map +1 -1
- package/dist/db/db.js +3 -1
- package/dist/db/db.js.map +1 -1
- package/dist/db/installations.d.ts +21 -0
- package/dist/db/installations.d.ts.map +1 -1
- package/dist/db/installations.js +82 -19
- package/dist/db/installations.js.map +1 -1
- package/dist/db/pending-selections.d.ts +17 -0
- package/dist/db/pending-selections.d.ts.map +1 -0
- package/dist/db/pending-selections.js +27 -0
- package/dist/db/pending-selections.js.map +1 -0
- package/dist/db/schema/installations.js +2 -2
- package/dist/db/schema/installations.js.map +1 -1
- package/dist/db/schema/pending-selections.d.ts +105 -0
- package/dist/db/schema/pending-selections.d.ts.map +1 -0
- package/dist/db/schema/pending-selections.js +24 -0
- package/dist/db/schema/pending-selections.js.map +1 -0
- package/dist/index.d.ts +26 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +27 -4
- package/dist/index.js.map +1 -1
- package/dist/presentation/dto/integrations.d.ts +2 -0
- package/dist/presentation/dto/integrations.d.ts.map +1 -0
- package/dist/presentation/dto/integrations.js +3 -0
- package/dist/presentation/dto/integrations.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 +58 -0
- package/dist/presentation/routes/errors.js.map +1 -0
- package/dist/presentation/routes/install.d.ts +21 -0
- package/dist/presentation/routes/install.d.ts.map +1 -0
- package/dist/presentation/routes/install.js +130 -0
- package/dist/presentation/routes/install.js.map +1 -0
- package/dist/tsconfig.test.tsbuildinfo +1 -1
- package/drizzle/0000_whole_master_chief.sql +8 -1
- package/drizzle/meta/0000_snapshot.json +47 -3
- package/package.json +21 -24
- package/src/api/client.test.ts +29 -0
- package/src/api/client.ts +213 -0
- package/src/core/disconnect.test.ts +24 -0
- package/src/core/disconnect.ts +25 -0
- package/src/core/errors.ts +79 -0
- package/src/core/install.test.ts +129 -0
- package/src/core/install.ts +191 -0
- package/src/core/pending.ts +146 -0
- package/src/core/scopes.test.ts +19 -0
- package/src/core/scopes.ts +20 -0
- package/src/core/state.test.ts +38 -0
- package/src/core/state.ts +79 -0
- package/src/core/tokens-refresh.test.ts +106 -0
- package/src/core/tokens.ts +145 -8
- package/src/db/db.ts +2 -1
- package/src/db/installations.test.ts +37 -1
- package/src/db/installations.ts +120 -23
- package/src/db/pending-selections.ts +55 -0
- package/src/db/schema/installations.ts +2 -2
- package/src/db/schema/pending-selections.ts +31 -0
- package/src/index.test.ts +7 -2
- package/src/index.ts +66 -2
- package/src/presentation/dto/integrations.ts +1 -0
- package/src/presentation/routes/errors.ts +61 -0
- package/src/presentation/routes/install.ts +147 -0
- package/tsconfig.build.tsbuildinfo +1 -1
- package/turbo.json +9 -0
package/dist/db/db.d.ts
CHANGED
|
@@ -234,6 +234,100 @@ export declare const schema: {
|
|
|
234
234
|
};
|
|
235
235
|
dialect: "pg";
|
|
236
236
|
}>;
|
|
237
|
+
jiraPendingSelections: import("drizzle-orm/pg-core").PgTableWithColumns<{
|
|
238
|
+
name: "pending_selections";
|
|
239
|
+
schema: undefined;
|
|
240
|
+
columns: {
|
|
241
|
+
stateHash: import("drizzle-orm/pg-core").PgColumn<{
|
|
242
|
+
name: "state_hash";
|
|
243
|
+
tableName: "pending_selections";
|
|
244
|
+
dataType: "string";
|
|
245
|
+
columnType: "PgText";
|
|
246
|
+
data: string;
|
|
247
|
+
driverParam: string;
|
|
248
|
+
notNull: true;
|
|
249
|
+
hasDefault: false;
|
|
250
|
+
isPrimaryKey: true;
|
|
251
|
+
isAutoincrement: false;
|
|
252
|
+
hasRuntimeDefault: false;
|
|
253
|
+
enumValues: [string, ...string[]];
|
|
254
|
+
baseColumn: never;
|
|
255
|
+
identity: undefined;
|
|
256
|
+
generated: undefined;
|
|
257
|
+
}, {}, {}>;
|
|
258
|
+
workspaceId: import("drizzle-orm/pg-core").PgColumn<{
|
|
259
|
+
name: "workspace_id";
|
|
260
|
+
tableName: "pending_selections";
|
|
261
|
+
dataType: "string";
|
|
262
|
+
columnType: "PgUUID";
|
|
263
|
+
data: string;
|
|
264
|
+
driverParam: string;
|
|
265
|
+
notNull: true;
|
|
266
|
+
hasDefault: false;
|
|
267
|
+
isPrimaryKey: false;
|
|
268
|
+
isAutoincrement: false;
|
|
269
|
+
hasRuntimeDefault: false;
|
|
270
|
+
enumValues: undefined;
|
|
271
|
+
baseColumn: never;
|
|
272
|
+
identity: undefined;
|
|
273
|
+
generated: undefined;
|
|
274
|
+
}, {}, {}>;
|
|
275
|
+
expiresAt: import("drizzle-orm/pg-core").PgColumn<{
|
|
276
|
+
name: "expires_at";
|
|
277
|
+
tableName: "pending_selections";
|
|
278
|
+
dataType: "date";
|
|
279
|
+
columnType: "PgTimestamp";
|
|
280
|
+
data: Date;
|
|
281
|
+
driverParam: string;
|
|
282
|
+
notNull: true;
|
|
283
|
+
hasDefault: false;
|
|
284
|
+
isPrimaryKey: false;
|
|
285
|
+
isAutoincrement: false;
|
|
286
|
+
hasRuntimeDefault: false;
|
|
287
|
+
enumValues: undefined;
|
|
288
|
+
baseColumn: never;
|
|
289
|
+
identity: undefined;
|
|
290
|
+
generated: undefined;
|
|
291
|
+
}, {}, {}>;
|
|
292
|
+
sites: import("drizzle-orm/pg-core").PgColumn<{
|
|
293
|
+
name: "sites";
|
|
294
|
+
tableName: "pending_selections";
|
|
295
|
+
dataType: "json";
|
|
296
|
+
columnType: "PgJsonb";
|
|
297
|
+
data: import("../index.js").JiraAccessibleResource[];
|
|
298
|
+
driverParam: unknown;
|
|
299
|
+
notNull: true;
|
|
300
|
+
hasDefault: false;
|
|
301
|
+
isPrimaryKey: false;
|
|
302
|
+
isAutoincrement: false;
|
|
303
|
+
hasRuntimeDefault: false;
|
|
304
|
+
enumValues: undefined;
|
|
305
|
+
baseColumn: never;
|
|
306
|
+
identity: undefined;
|
|
307
|
+
generated: undefined;
|
|
308
|
+
}, {}, {
|
|
309
|
+
$type: import("../index.js").JiraAccessibleResource[];
|
|
310
|
+
}>;
|
|
311
|
+
createdAt: import("drizzle-orm/pg-core").PgColumn<{
|
|
312
|
+
name: "created_at";
|
|
313
|
+
tableName: "pending_selections";
|
|
314
|
+
dataType: "date";
|
|
315
|
+
columnType: "PgTimestamp";
|
|
316
|
+
data: Date;
|
|
317
|
+
driverParam: string;
|
|
318
|
+
notNull: true;
|
|
319
|
+
hasDefault: true;
|
|
320
|
+
isPrimaryKey: false;
|
|
321
|
+
isAutoincrement: false;
|
|
322
|
+
hasRuntimeDefault: false;
|
|
323
|
+
enumValues: undefined;
|
|
324
|
+
baseColumn: never;
|
|
325
|
+
identity: undefined;
|
|
326
|
+
generated: undefined;
|
|
327
|
+
}, {}, {}>;
|
|
328
|
+
};
|
|
329
|
+
dialect: "pg";
|
|
330
|
+
}>;
|
|
237
331
|
};
|
|
238
332
|
export declare function db(): NodePgDatabase<{
|
|
239
333
|
jiraInstallations: import("drizzle-orm/pg-core").PgTableWithColumns<{
|
|
@@ -470,6 +564,100 @@ export declare function db(): NodePgDatabase<{
|
|
|
470
564
|
};
|
|
471
565
|
dialect: "pg";
|
|
472
566
|
}>;
|
|
567
|
+
jiraPendingSelections: import("drizzle-orm/pg-core").PgTableWithColumns<{
|
|
568
|
+
name: "pending_selections";
|
|
569
|
+
schema: undefined;
|
|
570
|
+
columns: {
|
|
571
|
+
stateHash: import("drizzle-orm/pg-core").PgColumn<{
|
|
572
|
+
name: "state_hash";
|
|
573
|
+
tableName: "pending_selections";
|
|
574
|
+
dataType: "string";
|
|
575
|
+
columnType: "PgText";
|
|
576
|
+
data: string;
|
|
577
|
+
driverParam: string;
|
|
578
|
+
notNull: true;
|
|
579
|
+
hasDefault: false;
|
|
580
|
+
isPrimaryKey: true;
|
|
581
|
+
isAutoincrement: false;
|
|
582
|
+
hasRuntimeDefault: false;
|
|
583
|
+
enumValues: [string, ...string[]];
|
|
584
|
+
baseColumn: never;
|
|
585
|
+
identity: undefined;
|
|
586
|
+
generated: undefined;
|
|
587
|
+
}, {}, {}>;
|
|
588
|
+
workspaceId: import("drizzle-orm/pg-core").PgColumn<{
|
|
589
|
+
name: "workspace_id";
|
|
590
|
+
tableName: "pending_selections";
|
|
591
|
+
dataType: "string";
|
|
592
|
+
columnType: "PgUUID";
|
|
593
|
+
data: string;
|
|
594
|
+
driverParam: string;
|
|
595
|
+
notNull: true;
|
|
596
|
+
hasDefault: false;
|
|
597
|
+
isPrimaryKey: false;
|
|
598
|
+
isAutoincrement: false;
|
|
599
|
+
hasRuntimeDefault: false;
|
|
600
|
+
enumValues: undefined;
|
|
601
|
+
baseColumn: never;
|
|
602
|
+
identity: undefined;
|
|
603
|
+
generated: undefined;
|
|
604
|
+
}, {}, {}>;
|
|
605
|
+
expiresAt: import("drizzle-orm/pg-core").PgColumn<{
|
|
606
|
+
name: "expires_at";
|
|
607
|
+
tableName: "pending_selections";
|
|
608
|
+
dataType: "date";
|
|
609
|
+
columnType: "PgTimestamp";
|
|
610
|
+
data: Date;
|
|
611
|
+
driverParam: string;
|
|
612
|
+
notNull: true;
|
|
613
|
+
hasDefault: false;
|
|
614
|
+
isPrimaryKey: false;
|
|
615
|
+
isAutoincrement: false;
|
|
616
|
+
hasRuntimeDefault: false;
|
|
617
|
+
enumValues: undefined;
|
|
618
|
+
baseColumn: never;
|
|
619
|
+
identity: undefined;
|
|
620
|
+
generated: undefined;
|
|
621
|
+
}, {}, {}>;
|
|
622
|
+
sites: import("drizzle-orm/pg-core").PgColumn<{
|
|
623
|
+
name: "sites";
|
|
624
|
+
tableName: "pending_selections";
|
|
625
|
+
dataType: "json";
|
|
626
|
+
columnType: "PgJsonb";
|
|
627
|
+
data: import("../index.js").JiraAccessibleResource[];
|
|
628
|
+
driverParam: unknown;
|
|
629
|
+
notNull: true;
|
|
630
|
+
hasDefault: false;
|
|
631
|
+
isPrimaryKey: false;
|
|
632
|
+
isAutoincrement: false;
|
|
633
|
+
hasRuntimeDefault: false;
|
|
634
|
+
enumValues: undefined;
|
|
635
|
+
baseColumn: never;
|
|
636
|
+
identity: undefined;
|
|
637
|
+
generated: undefined;
|
|
638
|
+
}, {}, {
|
|
639
|
+
$type: import("../index.js").JiraAccessibleResource[];
|
|
640
|
+
}>;
|
|
641
|
+
createdAt: import("drizzle-orm/pg-core").PgColumn<{
|
|
642
|
+
name: "created_at";
|
|
643
|
+
tableName: "pending_selections";
|
|
644
|
+
dataType: "date";
|
|
645
|
+
columnType: "PgTimestamp";
|
|
646
|
+
data: Date;
|
|
647
|
+
driverParam: string;
|
|
648
|
+
notNull: true;
|
|
649
|
+
hasDefault: true;
|
|
650
|
+
isPrimaryKey: false;
|
|
651
|
+
isAutoincrement: false;
|
|
652
|
+
hasRuntimeDefault: false;
|
|
653
|
+
enumValues: undefined;
|
|
654
|
+
baseColumn: never;
|
|
655
|
+
identity: undefined;
|
|
656
|
+
generated: undefined;
|
|
657
|
+
}, {}, {}>;
|
|
658
|
+
};
|
|
659
|
+
dialect: "pg";
|
|
660
|
+
}>;
|
|
473
661
|
}>;
|
|
474
662
|
export declare function closeDb(): void;
|
|
475
663
|
//# sourceMappingURL=db.d.ts.map
|
package/dist/db/db.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"db.d.ts","sourceRoot":"","sources":["../../src/db/db.ts"],"names":[],"mappings":"AAAA,OAAO,EAAU,KAAK,cAAc,EAAC,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"db.d.ts","sourceRoot":"","sources":["../../src/db/db.ts"],"names":[],"mappings":"AAAA,OAAO,EAAU,KAAK,cAAc,EAAC,MAAM,uBAAuB,CAAC;AAKnE,eAAO,MAAM,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAA6C,CAAC;AAIjE,wBAAgB,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAGjB;AAED,wBAAgB,OAAO,IAAI,IAAI,CAE9B"}
|
package/dist/db/db.js
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import { drizzle } from '@shipfox/node-drizzle';
|
|
2
2
|
import { pgClient } from '@shipfox/node-postgres';
|
|
3
3
|
import { jiraInstallations } from './schema/installations.js';
|
|
4
|
+
import { jiraPendingSelections } from './schema/pending-selections.js';
|
|
4
5
|
export const schema = {
|
|
5
|
-
jiraInstallations
|
|
6
|
+
jiraInstallations,
|
|
7
|
+
jiraPendingSelections
|
|
6
8
|
};
|
|
7
9
|
let database;
|
|
8
10
|
export function db() {
|
package/dist/db/db.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/db/db.ts"],"sourcesContent":["import {drizzle, type NodePgDatabase} from '@shipfox/node-drizzle';\nimport {pgClient} from '@shipfox/node-postgres';\nimport {jiraInstallations} from './schema/installations.js';\n\nexport const schema = {jiraInstallations};\n\nlet database: NodePgDatabase<typeof schema> | undefined;\n\nexport function db() {\n if (!database) database = drizzle(pgClient(), {schema});\n return database;\n}\n\nexport function closeDb(): void {\n database = undefined;\n}\n"],"names":["drizzle","pgClient","jiraInstallations","schema","database","db","closeDb","undefined"],"mappings":"AAAA,SAAQA,OAAO,QAA4B,wBAAwB;AACnE,SAAQC,QAAQ,QAAO,yBAAyB;AAChD,SAAQC,iBAAiB,QAAO,4BAA4B;
|
|
1
|
+
{"version":3,"sources":["../../src/db/db.ts"],"sourcesContent":["import {drizzle, type NodePgDatabase} from '@shipfox/node-drizzle';\nimport {pgClient} from '@shipfox/node-postgres';\nimport {jiraInstallations} from './schema/installations.js';\nimport {jiraPendingSelections} from './schema/pending-selections.js';\n\nexport const schema = {jiraInstallations, jiraPendingSelections};\n\nlet database: NodePgDatabase<typeof schema> | undefined;\n\nexport function db() {\n if (!database) database = drizzle(pgClient(), {schema});\n return database;\n}\n\nexport function closeDb(): void {\n database = undefined;\n}\n"],"names":["drizzle","pgClient","jiraInstallations","jiraPendingSelections","schema","database","db","closeDb","undefined"],"mappings":"AAAA,SAAQA,OAAO,QAA4B,wBAAwB;AACnE,SAAQC,QAAQ,QAAO,yBAAyB;AAChD,SAAQC,iBAAiB,QAAO,4BAA4B;AAC5D,SAAQC,qBAAqB,QAAO,iCAAiC;AAErE,OAAO,MAAMC,SAAS;IAACF;IAAmBC;AAAqB,EAAE;AAEjE,IAAIE;AAEJ,OAAO,SAASC;IACd,IAAI,CAACD,UAAUA,WAAWL,QAAQC,YAAY;QAACG;IAAM;IACrD,OAAOC;AACT;AAEA,OAAO,SAASE;IACdF,WAAWG;AACb"}
|
|
@@ -26,9 +26,30 @@ export interface UpsertJiraInstallationParams {
|
|
|
26
26
|
status: JiraInstallationStatus;
|
|
27
27
|
tokenExpiresAt?: Date | null | undefined;
|
|
28
28
|
}
|
|
29
|
+
export interface UpdateJiraInstallationTokenExpiryParams {
|
|
30
|
+
connectionId: string;
|
|
31
|
+
tokenExpiresAt: Date | null;
|
|
32
|
+
scopes?: string[] | undefined;
|
|
33
|
+
}
|
|
29
34
|
export declare function upsertJiraInstallation(params: UpsertJiraInstallationParams, options?: {
|
|
30
35
|
tx?: unknown;
|
|
31
36
|
}): Promise<JiraInstallation>;
|
|
37
|
+
export declare function getJiraInstallationByCloudId(cloudId: string, options?: {
|
|
38
|
+
tx?: unknown;
|
|
39
|
+
}): Promise<JiraInstallation | undefined>;
|
|
40
|
+
export declare function updateJiraInstallationTokenExpiry(params: UpdateJiraInstallationTokenExpiryParams, options?: {
|
|
41
|
+
tx?: unknown;
|
|
42
|
+
}): Promise<JiraInstallation | undefined>;
|
|
43
|
+
export declare function deleteJiraInstallationByConnectionId(connectionId: string, options?: {
|
|
44
|
+
tx?: unknown;
|
|
45
|
+
}): Promise<boolean>;
|
|
46
|
+
export type JiraRefreshLockResult<T> = {
|
|
47
|
+
acquired: true;
|
|
48
|
+
value: T;
|
|
49
|
+
} | {
|
|
50
|
+
acquired: false;
|
|
51
|
+
};
|
|
52
|
+
export declare function withJiraRefreshLock<T>(connectionId: string, fn: () => Promise<T>): Promise<JiraRefreshLockResult<T>>;
|
|
32
53
|
export declare function getJiraInstallationByConnectionId(connectionId: string, options?: {
|
|
33
54
|
tx?: unknown;
|
|
34
55
|
}): Promise<JiraInstallation | undefined>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"installations.d.ts","sourceRoot":"","sources":["../../src/db/installations.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"installations.d.ts","sourceRoot":"","sources":["../../src/db/installations.ts"],"names":[],"mappings":"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"}
|
package/dist/db/installations.js
CHANGED
|
@@ -1,26 +1,17 @@
|
|
|
1
|
+
import { isUniqueViolation } from '@shipfox/node-drizzle';
|
|
2
|
+
import { pgClient } from '@shipfox/node-postgres';
|
|
1
3
|
import { eq, sql } from 'drizzle-orm';
|
|
2
|
-
import { JiraInstallationSiteMismatchError } from '#core/errors.js';
|
|
4
|
+
import { JiraConnectionAlreadyLinkedError, JiraInstallationAlreadyLinkedError, JiraInstallationSiteMismatchError } from '#core/errors.js';
|
|
3
5
|
import { db } from './db.js';
|
|
4
6
|
import { jiraInstallations, toJiraInstallation } from './schema/installations.js';
|
|
5
7
|
export async function upsertJiraInstallation(params, options = {}) {
|
|
6
8
|
const executor = options.tx ?? db();
|
|
7
9
|
const now = new Date();
|
|
8
10
|
const webhookIds = params.webhookIds ?? [];
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
siteName: params.siteName,
|
|
14
|
-
authorizingAccountId: params.authorizingAccountId,
|
|
15
|
-
scopes: params.scopes,
|
|
16
|
-
webhookIds,
|
|
17
|
-
webhookExpiresAt: params.webhookExpiresAt ?? null,
|
|
18
|
-
status: params.status,
|
|
19
|
-
tokenExpiresAt: params.tokenExpiresAt ?? null
|
|
20
|
-
}).onConflictDoUpdate({
|
|
21
|
-
target: jiraInstallations.connectionId,
|
|
22
|
-
setWhere: eq(jiraInstallations.cloudId, params.cloudId),
|
|
23
|
-
set: {
|
|
11
|
+
let row;
|
|
12
|
+
try {
|
|
13
|
+
[row] = await executor.insert(jiraInstallations).values({
|
|
14
|
+
connectionId: params.connectionId,
|
|
24
15
|
cloudId: params.cloudId,
|
|
25
16
|
siteUrl: params.siteUrl,
|
|
26
17
|
siteName: params.siteName,
|
|
@@ -29,13 +20,85 @@ export async function upsertJiraInstallation(params, options = {}) {
|
|
|
29
20
|
webhookIds,
|
|
30
21
|
webhookExpiresAt: params.webhookExpiresAt ?? null,
|
|
31
22
|
status: params.status,
|
|
32
|
-
tokenExpiresAt: params.tokenExpiresAt ?? null
|
|
33
|
-
|
|
23
|
+
tokenExpiresAt: params.tokenExpiresAt ?? null
|
|
24
|
+
}).onConflictDoUpdate({
|
|
25
|
+
target: jiraInstallations.connectionId,
|
|
26
|
+
setWhere: eq(jiraInstallations.cloudId, params.cloudId),
|
|
27
|
+
set: {
|
|
28
|
+
cloudId: params.cloudId,
|
|
29
|
+
siteUrl: params.siteUrl,
|
|
30
|
+
siteName: params.siteName,
|
|
31
|
+
authorizingAccountId: params.authorizingAccountId,
|
|
32
|
+
scopes: params.scopes,
|
|
33
|
+
webhookIds,
|
|
34
|
+
webhookExpiresAt: params.webhookExpiresAt ?? null,
|
|
35
|
+
status: params.status,
|
|
36
|
+
tokenExpiresAt: params.tokenExpiresAt ?? null,
|
|
37
|
+
updatedAt: now
|
|
38
|
+
}
|
|
39
|
+
}).returning();
|
|
40
|
+
} catch (error) {
|
|
41
|
+
if (isUniqueViolation(error, 'integrations_jira_installations_connection_unique')) {
|
|
42
|
+
throw new JiraConnectionAlreadyLinkedError(params.connectionId);
|
|
34
43
|
}
|
|
35
|
-
|
|
44
|
+
if (isUniqueViolation(error, 'integrations_jira_installations_cloud_id_unique')) {
|
|
45
|
+
throw new JiraInstallationAlreadyLinkedError(params.cloudId);
|
|
46
|
+
}
|
|
47
|
+
throw error;
|
|
48
|
+
}
|
|
36
49
|
if (!row) throw new JiraInstallationSiteMismatchError(params.connectionId, params.cloudId);
|
|
37
50
|
return toJiraInstallation(row);
|
|
38
51
|
}
|
|
52
|
+
export async function getJiraInstallationByCloudId(cloudId, options = {}) {
|
|
53
|
+
const executor = options.tx ?? db();
|
|
54
|
+
const rows = await executor.select().from(jiraInstallations).where(eq(jiraInstallations.cloudId, cloudId)).limit(1);
|
|
55
|
+
const row = rows[0];
|
|
56
|
+
return row ? toJiraInstallation(row) : undefined;
|
|
57
|
+
}
|
|
58
|
+
export async function updateJiraInstallationTokenExpiry(params, options = {}) {
|
|
59
|
+
const executor = options.tx ?? db();
|
|
60
|
+
const [row] = await executor.update(jiraInstallations).set({
|
|
61
|
+
tokenExpiresAt: params.tokenExpiresAt,
|
|
62
|
+
...params.scopes === undefined ? {} : {
|
|
63
|
+
scopes: params.scopes
|
|
64
|
+
},
|
|
65
|
+
updatedAt: new Date()
|
|
66
|
+
}).where(eq(jiraInstallations.connectionId, params.connectionId)).returning();
|
|
67
|
+
return row ? toJiraInstallation(row) : undefined;
|
|
68
|
+
}
|
|
69
|
+
export async function deleteJiraInstallationByConnectionId(connectionId, options = {}) {
|
|
70
|
+
const executor = options.tx ?? db();
|
|
71
|
+
const result = await executor.delete(jiraInstallations).where(eq(jiraInstallations.connectionId, connectionId));
|
|
72
|
+
return (result.rowCount ?? 0) > 0;
|
|
73
|
+
}
|
|
74
|
+
export function withJiraRefreshLock(connectionId, fn) {
|
|
75
|
+
return withJiraRefreshLockClient(connectionId, fn);
|
|
76
|
+
}
|
|
77
|
+
async function withJiraRefreshLockClient(connectionId, fn) {
|
|
78
|
+
const client = await pgClient().connect();
|
|
79
|
+
let acquired = false;
|
|
80
|
+
try {
|
|
81
|
+
const lock = await client.query('SELECT pg_try_advisory_lock(hashtext($1)) AS acquired', [
|
|
82
|
+
connectionId
|
|
83
|
+
]);
|
|
84
|
+
acquired = lock.rows[0]?.acquired === true;
|
|
85
|
+
if (!acquired) return {
|
|
86
|
+
acquired: false
|
|
87
|
+
};
|
|
88
|
+
return {
|
|
89
|
+
acquired: true,
|
|
90
|
+
value: await fn()
|
|
91
|
+
};
|
|
92
|
+
} finally{
|
|
93
|
+
try {
|
|
94
|
+
if (acquired) await client.query('SELECT pg_advisory_unlock(hashtext($1))', [
|
|
95
|
+
connectionId
|
|
96
|
+
]);
|
|
97
|
+
} finally{
|
|
98
|
+
client.release();
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
}
|
|
39
102
|
export async function getJiraInstallationByConnectionId(connectionId, options = {}) {
|
|
40
103
|
const executor = options.tx ?? db();
|
|
41
104
|
const rows = await executor.select().from(jiraInstallations).where(eq(jiraInstallations.connectionId, connectionId)).limit(1);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/db/installations.ts"],"sourcesContent":["import {eq, sql} from 'drizzle-orm';\nimport {JiraInstallationSiteMismatchError} from '#core/errors.js';\nimport {db} from './db.js';\nimport {jiraInstallations, toJiraInstallation} from './schema/installations.js';\n\nexport type JiraInstallationStatus = 'installed' | 'revoked';\n\nexport interface JiraInstallation {\n id: string;\n connectionId: string;\n cloudId: string;\n siteUrl: string;\n siteName: string;\n authorizingAccountId: string;\n scopes: string[];\n webhookIds: number[];\n webhookExpiresAt: Date | null;\n status: JiraInstallationStatus;\n tokenExpiresAt: Date | null;\n createdAt: Date;\n updatedAt: Date;\n}\n\nexport interface UpsertJiraInstallationParams {\n connectionId: string;\n cloudId: string;\n siteUrl: string;\n siteName: string;\n authorizingAccountId: string;\n scopes: string[];\n webhookIds?: number[] | undefined;\n webhookExpiresAt?: Date | null | undefined;\n status: JiraInstallationStatus;\n tokenExpiresAt?: Date | null | undefined;\n}\n\ntype JiraDb = ReturnType<typeof db>;\ntype JiraTx = Parameters<Parameters<JiraDb['transaction']>[0]>[0];\n\nexport async function upsertJiraInstallation(\n params: UpsertJiraInstallationParams,\n options: {tx?: unknown} = {},\n): Promise<JiraInstallation> {\n const executor = (options.tx ?? db()) as JiraDb | JiraTx;\n const now = new Date();\n const webhookIds = params.webhookIds ?? [];\n const [row] = await executor\n .insert(jiraInstallations)\n .values({\n connectionId: params.connectionId,\n cloudId: params.cloudId,\n siteUrl: params.siteUrl,\n siteName: params.siteName,\n authorizingAccountId: params.authorizingAccountId,\n scopes: params.scopes,\n webhookIds,\n webhookExpiresAt: params.webhookExpiresAt ?? null,\n status: params.status,\n tokenExpiresAt: params.tokenExpiresAt ?? null,\n })\n .onConflictDoUpdate({\n target: jiraInstallations.connectionId,\n setWhere: eq(jiraInstallations.cloudId, params.cloudId),\n set: {\n cloudId: params.cloudId,\n siteUrl: params.siteUrl,\n siteName: params.siteName,\n authorizingAccountId: params.authorizingAccountId,\n scopes: params.scopes,\n webhookIds,\n webhookExpiresAt: params.webhookExpiresAt ?? null,\n status: params.status,\n tokenExpiresAt: params.tokenExpiresAt ?? null,\n updatedAt: now,\n },\n })\n .returning();\n\n if (!row) throw new JiraInstallationSiteMismatchError(params.connectionId, params.cloudId);\n return toJiraInstallation(row);\n}\n\nexport async function getJiraInstallationByConnectionId(\n connectionId: string,\n options: {tx?: unknown} = {},\n): Promise<JiraInstallation | undefined> {\n const executor = (options.tx ?? db()) as JiraDb | JiraTx;\n const rows = await executor\n .select()\n .from(jiraInstallations)\n .where(eq(jiraInstallations.connectionId, connectionId))\n .limit(1);\n const row = rows[0];\n if (!row) return undefined;\n return toJiraInstallation(row);\n}\n\nexport async function getJiraInstallationByWebhookId(\n webhookId: number,\n options: {tx?: unknown} = {},\n): Promise<JiraInstallation | undefined> {\n const executor = (options.tx ?? db()) as JiraDb | JiraTx;\n const rows = await executor\n .select()\n .from(jiraInstallations)\n .where(sql`${jiraInstallations.webhookIds} @> ${JSON.stringify([webhookId])}::jsonb`)\n .limit(1);\n const row = rows[0];\n if (!row) return undefined;\n return toJiraInstallation(row);\n}\n\nexport async function markJiraInstallationRevoked(\n connectionId: string,\n options: {tx?: unknown} = {},\n): Promise<JiraInstallation | undefined> {\n const executor = (options.tx ?? db()) as JiraDb | JiraTx;\n const [row] = await executor\n .update(jiraInstallations)\n .set({status: 'revoked', updatedAt: new Date()})\n .where(eq(jiraInstallations.connectionId, connectionId))\n .returning();\n if (!row) return undefined;\n return toJiraInstallation(row);\n}\n"],"names":["eq","sql","JiraInstallationSiteMismatchError","db","jiraInstallations","toJiraInstallation","upsertJiraInstallation","params","options","executor","tx","now","Date","webhookIds","row","insert","values","connectionId","cloudId","siteUrl","siteName","authorizingAccountId","scopes","webhookExpiresAt","status","tokenExpiresAt","onConflictDoUpdate","target","setWhere","set","updatedAt","returning","getJiraInstallationByConnectionId","rows","select","from","where","limit","undefined","getJiraInstallationByWebhookId","webhookId","JSON","stringify","markJiraInstallationRevoked","update"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../src/db/installations.ts"],"sourcesContent":["import {isUniqueViolation} from '@shipfox/node-drizzle';\nimport {pgClient} from '@shipfox/node-postgres';\nimport {eq, sql} from 'drizzle-orm';\nimport {\n JiraConnectionAlreadyLinkedError,\n JiraInstallationAlreadyLinkedError,\n JiraInstallationSiteMismatchError,\n} from '#core/errors.js';\nimport {db} from './db.js';\nimport {jiraInstallations, toJiraInstallation} from './schema/installations.js';\n\nexport type JiraInstallationStatus = 'installed' | 'revoked';\n\nexport interface JiraInstallation {\n id: string;\n connectionId: string;\n cloudId: string;\n siteUrl: string;\n siteName: string;\n authorizingAccountId: string;\n scopes: string[];\n webhookIds: number[];\n webhookExpiresAt: Date | null;\n status: JiraInstallationStatus;\n tokenExpiresAt: Date | null;\n createdAt: Date;\n updatedAt: Date;\n}\n\nexport interface UpsertJiraInstallationParams {\n connectionId: string;\n cloudId: string;\n siteUrl: string;\n siteName: string;\n authorizingAccountId: string;\n scopes: string[];\n webhookIds?: number[] | undefined;\n webhookExpiresAt?: Date | null | undefined;\n status: JiraInstallationStatus;\n tokenExpiresAt?: Date | null | undefined;\n}\n\nexport interface UpdateJiraInstallationTokenExpiryParams {\n connectionId: string;\n tokenExpiresAt: Date | null;\n scopes?: string[] | undefined;\n}\n\ntype JiraDb = ReturnType<typeof db>;\ntype JiraTx = Parameters<Parameters<JiraDb['transaction']>[0]>[0];\n\nexport async function upsertJiraInstallation(\n params: UpsertJiraInstallationParams,\n options: {tx?: unknown} = {},\n): Promise<JiraInstallation> {\n const executor = (options.tx ?? db()) as JiraDb | JiraTx;\n const now = new Date();\n const webhookIds = params.webhookIds ?? [];\n let row: typeof jiraInstallations.$inferSelect | undefined;\n try {\n [row] = await executor\n .insert(jiraInstallations)\n .values({\n connectionId: params.connectionId,\n cloudId: params.cloudId,\n siteUrl: params.siteUrl,\n siteName: params.siteName,\n authorizingAccountId: params.authorizingAccountId,\n scopes: params.scopes,\n webhookIds,\n webhookExpiresAt: params.webhookExpiresAt ?? null,\n status: params.status,\n tokenExpiresAt: params.tokenExpiresAt ?? null,\n })\n .onConflictDoUpdate({\n target: jiraInstallations.connectionId,\n setWhere: eq(jiraInstallations.cloudId, params.cloudId),\n set: {\n cloudId: params.cloudId,\n siteUrl: params.siteUrl,\n siteName: params.siteName,\n authorizingAccountId: params.authorizingAccountId,\n scopes: params.scopes,\n webhookIds,\n webhookExpiresAt: params.webhookExpiresAt ?? null,\n status: params.status,\n tokenExpiresAt: params.tokenExpiresAt ?? null,\n updatedAt: now,\n },\n })\n .returning();\n } catch (error) {\n if (isUniqueViolation(error, 'integrations_jira_installations_connection_unique')) {\n throw new JiraConnectionAlreadyLinkedError(params.connectionId);\n }\n if (isUniqueViolation(error, 'integrations_jira_installations_cloud_id_unique')) {\n throw new JiraInstallationAlreadyLinkedError(params.cloudId);\n }\n throw error;\n }\n\n if (!row) throw new JiraInstallationSiteMismatchError(params.connectionId, params.cloudId);\n return toJiraInstallation(row);\n}\n\nexport async function getJiraInstallationByCloudId(\n cloudId: string,\n options: {tx?: unknown} = {},\n): Promise<JiraInstallation | undefined> {\n const executor = (options.tx ?? db()) as JiraDb | JiraTx;\n const rows = await executor\n .select()\n .from(jiraInstallations)\n .where(eq(jiraInstallations.cloudId, cloudId))\n .limit(1);\n const row = rows[0];\n return row ? toJiraInstallation(row) : undefined;\n}\n\nexport async function updateJiraInstallationTokenExpiry(\n params: UpdateJiraInstallationTokenExpiryParams,\n options: {tx?: unknown} = {},\n): Promise<JiraInstallation | undefined> {\n const executor = (options.tx ?? db()) as JiraDb | JiraTx;\n const [row] = await executor\n .update(jiraInstallations)\n .set({\n tokenExpiresAt: params.tokenExpiresAt,\n ...(params.scopes === undefined ? {} : {scopes: params.scopes}),\n updatedAt: new Date(),\n })\n .where(eq(jiraInstallations.connectionId, params.connectionId))\n .returning();\n return row ? toJiraInstallation(row) : undefined;\n}\n\nexport async function deleteJiraInstallationByConnectionId(\n connectionId: string,\n options: {tx?: unknown} = {},\n): Promise<boolean> {\n const executor = (options.tx ?? db()) as JiraDb | JiraTx;\n const result = await executor\n .delete(jiraInstallations)\n .where(eq(jiraInstallations.connectionId, connectionId));\n return (result.rowCount ?? 0) > 0;\n}\n\nexport type JiraRefreshLockResult<T> = {acquired: true; value: T} | {acquired: false};\n\nexport function withJiraRefreshLock<T>(\n connectionId: string,\n fn: () => Promise<T>,\n): Promise<JiraRefreshLockResult<T>> {\n return withJiraRefreshLockClient(connectionId, fn);\n}\n\nasync function withJiraRefreshLockClient<T>(\n connectionId: string,\n fn: () => Promise<T>,\n): Promise<JiraRefreshLockResult<T>> {\n const client = await pgClient().connect();\n let acquired = false;\n try {\n const lock = await client.query<{acquired: boolean}>(\n 'SELECT pg_try_advisory_lock(hashtext($1)) AS acquired',\n [connectionId],\n );\n acquired = lock.rows[0]?.acquired === true;\n if (!acquired) return {acquired: false};\n return {acquired: true, value: await fn()};\n } finally {\n try {\n if (acquired) await client.query('SELECT pg_advisory_unlock(hashtext($1))', [connectionId]);\n } finally {\n client.release();\n }\n }\n}\n\nexport async function getJiraInstallationByConnectionId(\n connectionId: string,\n options: {tx?: unknown} = {},\n): Promise<JiraInstallation | undefined> {\n const executor = (options.tx ?? db()) as JiraDb | JiraTx;\n const rows = await executor\n .select()\n .from(jiraInstallations)\n .where(eq(jiraInstallations.connectionId, connectionId))\n .limit(1);\n const row = rows[0];\n if (!row) return undefined;\n return toJiraInstallation(row);\n}\n\nexport async function getJiraInstallationByWebhookId(\n webhookId: number,\n options: {tx?: unknown} = {},\n): Promise<JiraInstallation | undefined> {\n const executor = (options.tx ?? db()) as JiraDb | JiraTx;\n const rows = await executor\n .select()\n .from(jiraInstallations)\n .where(sql`${jiraInstallations.webhookIds} @> ${JSON.stringify([webhookId])}::jsonb`)\n .limit(1);\n const row = rows[0];\n if (!row) return undefined;\n return toJiraInstallation(row);\n}\n\nexport async function markJiraInstallationRevoked(\n connectionId: string,\n options: {tx?: unknown} = {},\n): Promise<JiraInstallation | undefined> {\n const executor = (options.tx ?? db()) as JiraDb | JiraTx;\n const [row] = await executor\n .update(jiraInstallations)\n .set({status: 'revoked', updatedAt: new Date()})\n .where(eq(jiraInstallations.connectionId, connectionId))\n .returning();\n if (!row) return undefined;\n return toJiraInstallation(row);\n}\n"],"names":["isUniqueViolation","pgClient","eq","sql","JiraConnectionAlreadyLinkedError","JiraInstallationAlreadyLinkedError","JiraInstallationSiteMismatchError","db","jiraInstallations","toJiraInstallation","upsertJiraInstallation","params","options","executor","tx","now","Date","webhookIds","row","insert","values","connectionId","cloudId","siteUrl","siteName","authorizingAccountId","scopes","webhookExpiresAt","status","tokenExpiresAt","onConflictDoUpdate","target","setWhere","set","updatedAt","returning","error","getJiraInstallationByCloudId","rows","select","from","where","limit","undefined","updateJiraInstallationTokenExpiry","update","deleteJiraInstallationByConnectionId","result","delete","rowCount","withJiraRefreshLock","fn","withJiraRefreshLockClient","client","connect","acquired","lock","query","value","release","getJiraInstallationByConnectionId","getJiraInstallationByWebhookId","webhookId","JSON","stringify","markJiraInstallationRevoked"],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { jiraPendingSelections } from './schema/pending-selections.js';
|
|
2
|
+
export declare function saveJiraPendingSelection(params: {
|
|
3
|
+
stateHash: string;
|
|
4
|
+
workspaceId: string;
|
|
5
|
+
expiresAt: Date;
|
|
6
|
+
sites: typeof jiraPendingSelections.$inferInsert.sites;
|
|
7
|
+
}): Promise<void>;
|
|
8
|
+
export declare function getJiraPendingSelection(params: {
|
|
9
|
+
stateHash: string;
|
|
10
|
+
workspaceId: string;
|
|
11
|
+
}): Promise<import("./schema/pending-selections.js").JiraPendingSelection | undefined>;
|
|
12
|
+
export declare function deleteJiraPendingSelection(params: {
|
|
13
|
+
stateHash: string;
|
|
14
|
+
workspaceId: string;
|
|
15
|
+
}): Promise<void>;
|
|
16
|
+
export declare function listExpiredJiraPendingSelections(now: Date): Promise<import("./schema/pending-selections.js").JiraPendingSelection[]>;
|
|
17
|
+
//# sourceMappingURL=pending-selections.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pending-selections.d.ts","sourceRoot":"","sources":["../../src/db/pending-selections.ts"],"names":[],"mappings":"AAEA,OAAO,EAAC,qBAAqB,EAAyB,MAAM,gCAAgC,CAAC;AAE7F,wBAAsB,wBAAwB,CAAC,MAAM,EAAE;IACrD,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,IAAI,CAAC;IAChB,KAAK,EAAE,OAAO,qBAAqB,CAAC,YAAY,CAAC,KAAK,CAAC;CACxD,GAAG,OAAO,CAAC,IAAI,CAAC,CAQhB;AAED,wBAAsB,uBAAuB,CAAC,MAAM,EAAE;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAC,sFAa7F;AAED,wBAAsB,0BAA0B,CAAC,MAAM,EAAE;IACvD,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;CACrB,GAAG,OAAO,CAAC,IAAI,CAAC,CAShB;AAED,wBAAsB,gCAAgC,CAAC,GAAG,EAAE,IAAI,4EAM/D"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { and, eq, lt } from 'drizzle-orm';
|
|
2
|
+
import { db } from './db.js';
|
|
3
|
+
import { jiraPendingSelections, toJiraPendingSelection } from './schema/pending-selections.js';
|
|
4
|
+
export async function saveJiraPendingSelection(params) {
|
|
5
|
+
await db().insert(jiraPendingSelections).values(params).onConflictDoUpdate({
|
|
6
|
+
target: jiraPendingSelections.stateHash,
|
|
7
|
+
set: {
|
|
8
|
+
workspaceId: params.workspaceId,
|
|
9
|
+
expiresAt: params.expiresAt,
|
|
10
|
+
sites: params.sites
|
|
11
|
+
}
|
|
12
|
+
});
|
|
13
|
+
}
|
|
14
|
+
export async function getJiraPendingSelection(params) {
|
|
15
|
+
const rows = await db().select().from(jiraPendingSelections).where(and(eq(jiraPendingSelections.stateHash, params.stateHash), eq(jiraPendingSelections.workspaceId, params.workspaceId))).limit(1);
|
|
16
|
+
const row = rows[0];
|
|
17
|
+
return row ? toJiraPendingSelection(row) : undefined;
|
|
18
|
+
}
|
|
19
|
+
export async function deleteJiraPendingSelection(params) {
|
|
20
|
+
await db().delete(jiraPendingSelections).where(and(eq(jiraPendingSelections.stateHash, params.stateHash), eq(jiraPendingSelections.workspaceId, params.workspaceId)));
|
|
21
|
+
}
|
|
22
|
+
export async function listExpiredJiraPendingSelections(now) {
|
|
23
|
+
const rows = await db().select().from(jiraPendingSelections).where(lt(jiraPendingSelections.expiresAt, now));
|
|
24
|
+
return rows.map(toJiraPendingSelection);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
//# sourceMappingURL=pending-selections.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/db/pending-selections.ts"],"sourcesContent":["import {and, eq, lt} from 'drizzle-orm';\nimport {db} from './db.js';\nimport {jiraPendingSelections, toJiraPendingSelection} from './schema/pending-selections.js';\n\nexport async function saveJiraPendingSelection(params: {\n stateHash: string;\n workspaceId: string;\n expiresAt: Date;\n sites: typeof jiraPendingSelections.$inferInsert.sites;\n}): Promise<void> {\n await db()\n .insert(jiraPendingSelections)\n .values(params)\n .onConflictDoUpdate({\n target: jiraPendingSelections.stateHash,\n set: {workspaceId: params.workspaceId, expiresAt: params.expiresAt, sites: params.sites},\n });\n}\n\nexport async function getJiraPendingSelection(params: {stateHash: string; workspaceId: string}) {\n const rows = await db()\n .select()\n .from(jiraPendingSelections)\n .where(\n and(\n eq(jiraPendingSelections.stateHash, params.stateHash),\n eq(jiraPendingSelections.workspaceId, params.workspaceId),\n ),\n )\n .limit(1);\n const row = rows[0];\n return row ? toJiraPendingSelection(row) : undefined;\n}\n\nexport async function deleteJiraPendingSelection(params: {\n stateHash: string;\n workspaceId: string;\n}): Promise<void> {\n await db()\n .delete(jiraPendingSelections)\n .where(\n and(\n eq(jiraPendingSelections.stateHash, params.stateHash),\n eq(jiraPendingSelections.workspaceId, params.workspaceId),\n ),\n );\n}\n\nexport async function listExpiredJiraPendingSelections(now: Date) {\n const rows = await db()\n .select()\n .from(jiraPendingSelections)\n .where(lt(jiraPendingSelections.expiresAt, now));\n return rows.map(toJiraPendingSelection);\n}\n"],"names":["and","eq","lt","db","jiraPendingSelections","toJiraPendingSelection","saveJiraPendingSelection","params","insert","values","onConflictDoUpdate","target","stateHash","set","workspaceId","expiresAt","sites","getJiraPendingSelection","rows","select","from","where","limit","row","undefined","deleteJiraPendingSelection","delete","listExpiredJiraPendingSelections","now","map"],"mappings":"AAAA,SAAQA,GAAG,EAAEC,EAAE,EAAEC,EAAE,QAAO,cAAc;AACxC,SAAQC,EAAE,QAAO,UAAU;AAC3B,SAAQC,qBAAqB,EAAEC,sBAAsB,QAAO,iCAAiC;AAE7F,OAAO,eAAeC,yBAAyBC,MAK9C;IACC,MAAMJ,KACHK,MAAM,CAACJ,uBACPK,MAAM,CAACF,QACPG,kBAAkB,CAAC;QAClBC,QAAQP,sBAAsBQ,SAAS;QACvCC,KAAK;YAACC,aAAaP,OAAOO,WAAW;YAAEC,WAAWR,OAAOQ,SAAS;YAAEC,OAAOT,OAAOS,KAAK;QAAA;IACzF;AACJ;AAEA,OAAO,eAAeC,wBAAwBV,MAAgD;IAC5F,MAAMW,OAAO,MAAMf,KAChBgB,MAAM,GACNC,IAAI,CAAChB,uBACLiB,KAAK,CACJrB,IACEC,GAAGG,sBAAsBQ,SAAS,EAAEL,OAAOK,SAAS,GACpDX,GAAGG,sBAAsBU,WAAW,EAAEP,OAAOO,WAAW,IAG3DQ,KAAK,CAAC;IACT,MAAMC,MAAML,IAAI,CAAC,EAAE;IACnB,OAAOK,MAAMlB,uBAAuBkB,OAAOC;AAC7C;AAEA,OAAO,eAAeC,2BAA2BlB,MAGhD;IACC,MAAMJ,KACHuB,MAAM,CAACtB,uBACPiB,KAAK,CACJrB,IACEC,GAAGG,sBAAsBQ,SAAS,EAAEL,OAAOK,SAAS,GACpDX,GAAGG,sBAAsBU,WAAW,EAAEP,OAAOO,WAAW;AAGhE;AAEA,OAAO,eAAea,iCAAiCC,GAAS;IAC9D,MAAMV,OAAO,MAAMf,KAChBgB,MAAM,GACNC,IAAI,CAAChB,uBACLiB,KAAK,CAACnB,GAAGE,sBAAsBW,SAAS,EAAEa;IAC7C,OAAOV,KAAKW,GAAG,CAACxB;AAClB"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { uuidv7PrimaryKey } from '@shipfox/node-drizzle';
|
|
2
|
-
import {
|
|
2
|
+
import { jsonb, text, timestamp, uniqueIndex, uuid } from 'drizzle-orm/pg-core';
|
|
3
3
|
import { pgTable } from './common.js';
|
|
4
4
|
export const jiraInstallations = pgTable('installations', {
|
|
5
5
|
id: uuidv7PrimaryKey(),
|
|
@@ -25,7 +25,7 @@ export const jiraInstallations = pgTable('installations', {
|
|
|
25
25
|
}).notNull().defaultNow()
|
|
26
26
|
}, (table)=>[
|
|
27
27
|
uniqueIndex('integrations_jira_installations_connection_unique').on(table.connectionId),
|
|
28
|
-
|
|
28
|
+
uniqueIndex('integrations_jira_installations_cloud_id_unique').on(table.cloudId)
|
|
29
29
|
]);
|
|
30
30
|
export function toJiraInstallation(row) {
|
|
31
31
|
return {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/db/schema/installations.ts"],"sourcesContent":["import {uuidv7PrimaryKey} from '@shipfox/node-drizzle';\nimport {
|
|
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 {JiraInstallation} from '#db/installations.js';\nimport {pgTable} from './common.js';\n\nexport const jiraInstallations = pgTable(\n 'installations',\n {\n id: uuidv7PrimaryKey(),\n connectionId: uuid('connection_id').notNull(),\n cloudId: text('cloud_id').notNull(),\n siteUrl: text('site_url').notNull(),\n siteName: text('site_name').notNull(),\n authorizingAccountId: text('authorizing_account_id').notNull(),\n scopes: jsonb('scopes').$type<string[]>().notNull(),\n webhookIds: jsonb('webhook_ids').$type<number[]>().notNull().default([]),\n webhookExpiresAt: timestamp('webhook_expires_at', {withTimezone: true}),\n status: text('status').notNull().$type<JiraInstallation['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_jira_installations_connection_unique').on(table.connectionId),\n uniqueIndex('integrations_jira_installations_cloud_id_unique').on(table.cloudId),\n ],\n);\n\nexport type JiraInstallationDb = typeof jiraInstallations.$inferSelect;\nexport type JiraInstallationCreateDb = typeof jiraInstallations.$inferInsert;\n\nexport function toJiraInstallation(row: JiraInstallationDb): JiraInstallation {\n return {\n id: row.id,\n connectionId: row.connectionId,\n cloudId: row.cloudId,\n siteUrl: row.siteUrl,\n siteName: row.siteName,\n authorizingAccountId: row.authorizingAccountId,\n scopes: row.scopes,\n webhookIds: row.webhookIds,\n webhookExpiresAt: row.webhookExpiresAt,\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","jiraInstallations","id","connectionId","notNull","cloudId","siteUrl","siteName","authorizingAccountId","scopes","$type","webhookIds","default","webhookExpiresAt","withTimezone","status","tokenExpiresAt","createdAt","defaultNow","updatedAt","table","on","toJiraInstallation","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,oBAAoBD,QAC/B,iBACA;IACEE,IAAIR;IACJS,cAAcJ,KAAK,iBAAiBK,OAAO;IAC3CC,SAAST,KAAK,YAAYQ,OAAO;IACjCE,SAASV,KAAK,YAAYQ,OAAO;IACjCG,UAAUX,KAAK,aAAaQ,OAAO;IACnCI,sBAAsBZ,KAAK,0BAA0BQ,OAAO;IAC5DK,QAAQd,MAAM,UAAUe,KAAK,GAAaN,OAAO;IACjDO,YAAYhB,MAAM,eAAee,KAAK,GAAaN,OAAO,GAAGQ,OAAO,CAAC,EAAE;IACvEC,kBAAkBhB,UAAU,sBAAsB;QAACiB,cAAc;IAAI;IACrEC,QAAQnB,KAAK,UAAUQ,OAAO,GAAGM,KAAK;IACtCM,gBAAgBnB,UAAU,oBAAoB;QAACiB,cAAc;IAAI;IACjEG,WAAWpB,UAAU,cAAc;QAACiB,cAAc;IAAI,GAAGV,OAAO,GAAGc,UAAU;IAC7EC,WAAWtB,UAAU,cAAc;QAACiB,cAAc;IAAI,GAAGV,OAAO,GAAGc,UAAU;AAC/E,GACA,CAACE,QAAU;QACTtB,YAAY,qDAAqDuB,EAAE,CAACD,MAAMjB,YAAY;QACtFL,YAAY,mDAAmDuB,EAAE,CAACD,MAAMf,OAAO;KAChF,EACD;AAKF,OAAO,SAASiB,mBAAmBC,GAAuB;IACxD,OAAO;QACLrB,IAAIqB,IAAIrB,EAAE;QACVC,cAAcoB,IAAIpB,YAAY;QAC9BE,SAASkB,IAAIlB,OAAO;QACpBC,SAASiB,IAAIjB,OAAO;QACpBC,UAAUgB,IAAIhB,QAAQ;QACtBC,sBAAsBe,IAAIf,oBAAoB;QAC9CC,QAAQc,IAAId,MAAM;QAClBE,YAAYY,IAAIZ,UAAU;QAC1BE,kBAAkBU,IAAIV,gBAAgB;QACtCE,QAAQQ,IAAIR,MAAM;QAClBC,gBAAgBO,IAAIP,cAAc;QAClCC,WAAWM,IAAIN,SAAS;QACxBE,WAAWI,IAAIJ,SAAS;IAC1B;AACF"}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import type { JiraAccessibleResource } from '#api/client.js';
|
|
2
|
+
export declare const jiraPendingSelections: import("drizzle-orm/pg-core").PgTableWithColumns<{
|
|
3
|
+
name: "pending_selections";
|
|
4
|
+
schema: undefined;
|
|
5
|
+
columns: {
|
|
6
|
+
stateHash: import("drizzle-orm/pg-core").PgColumn<{
|
|
7
|
+
name: "state_hash";
|
|
8
|
+
tableName: "pending_selections";
|
|
9
|
+
dataType: "string";
|
|
10
|
+
columnType: "PgText";
|
|
11
|
+
data: string;
|
|
12
|
+
driverParam: string;
|
|
13
|
+
notNull: true;
|
|
14
|
+
hasDefault: false;
|
|
15
|
+
isPrimaryKey: true;
|
|
16
|
+
isAutoincrement: false;
|
|
17
|
+
hasRuntimeDefault: false;
|
|
18
|
+
enumValues: [string, ...string[]];
|
|
19
|
+
baseColumn: never;
|
|
20
|
+
identity: undefined;
|
|
21
|
+
generated: undefined;
|
|
22
|
+
}, {}, {}>;
|
|
23
|
+
workspaceId: import("drizzle-orm/pg-core").PgColumn<{
|
|
24
|
+
name: "workspace_id";
|
|
25
|
+
tableName: "pending_selections";
|
|
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
|
+
expiresAt: import("drizzle-orm/pg-core").PgColumn<{
|
|
41
|
+
name: "expires_at";
|
|
42
|
+
tableName: "pending_selections";
|
|
43
|
+
dataType: "date";
|
|
44
|
+
columnType: "PgTimestamp";
|
|
45
|
+
data: Date;
|
|
46
|
+
driverParam: string;
|
|
47
|
+
notNull: true;
|
|
48
|
+
hasDefault: false;
|
|
49
|
+
isPrimaryKey: false;
|
|
50
|
+
isAutoincrement: false;
|
|
51
|
+
hasRuntimeDefault: false;
|
|
52
|
+
enumValues: undefined;
|
|
53
|
+
baseColumn: never;
|
|
54
|
+
identity: undefined;
|
|
55
|
+
generated: undefined;
|
|
56
|
+
}, {}, {}>;
|
|
57
|
+
sites: import("drizzle-orm/pg-core").PgColumn<{
|
|
58
|
+
name: "sites";
|
|
59
|
+
tableName: "pending_selections";
|
|
60
|
+
dataType: "json";
|
|
61
|
+
columnType: "PgJsonb";
|
|
62
|
+
data: JiraAccessibleResource[];
|
|
63
|
+
driverParam: unknown;
|
|
64
|
+
notNull: true;
|
|
65
|
+
hasDefault: false;
|
|
66
|
+
isPrimaryKey: false;
|
|
67
|
+
isAutoincrement: false;
|
|
68
|
+
hasRuntimeDefault: false;
|
|
69
|
+
enumValues: undefined;
|
|
70
|
+
baseColumn: never;
|
|
71
|
+
identity: undefined;
|
|
72
|
+
generated: undefined;
|
|
73
|
+
}, {}, {
|
|
74
|
+
$type: JiraAccessibleResource[];
|
|
75
|
+
}>;
|
|
76
|
+
createdAt: import("drizzle-orm/pg-core").PgColumn<{
|
|
77
|
+
name: "created_at";
|
|
78
|
+
tableName: "pending_selections";
|
|
79
|
+
dataType: "date";
|
|
80
|
+
columnType: "PgTimestamp";
|
|
81
|
+
data: Date;
|
|
82
|
+
driverParam: string;
|
|
83
|
+
notNull: true;
|
|
84
|
+
hasDefault: true;
|
|
85
|
+
isPrimaryKey: false;
|
|
86
|
+
isAutoincrement: false;
|
|
87
|
+
hasRuntimeDefault: false;
|
|
88
|
+
enumValues: undefined;
|
|
89
|
+
baseColumn: never;
|
|
90
|
+
identity: undefined;
|
|
91
|
+
generated: undefined;
|
|
92
|
+
}, {}, {}>;
|
|
93
|
+
};
|
|
94
|
+
dialect: "pg";
|
|
95
|
+
}>;
|
|
96
|
+
export type JiraPendingSelectionDb = typeof jiraPendingSelections.$inferSelect;
|
|
97
|
+
export interface JiraPendingSelection {
|
|
98
|
+
stateHash: string;
|
|
99
|
+
workspaceId: string;
|
|
100
|
+
expiresAt: Date;
|
|
101
|
+
sites: JiraAccessibleResource[];
|
|
102
|
+
createdAt: Date;
|
|
103
|
+
}
|
|
104
|
+
export declare function toJiraPendingSelection(row: JiraPendingSelectionDb): JiraPendingSelection;
|
|
105
|
+
//# sourceMappingURL=pending-selections.d.ts.map
|