@oomol-lab/open-connector 1.7.0 → 1.8.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/README.md +4 -0
- package/assets/open-connector/catalog/apps/airtable.json +134 -0
- package/assets/open-connector/catalog/apps/aisa.json +916 -76
- package/assets/open-connector/catalog/apps/cal.json +24 -6
- package/assets/open-connector/catalog/apps/discordbot.json +2 -2
- package/assets/open-connector/catalog/apps/enormail.json +411 -0
- package/assets/open-connector/catalog/apps/feishu_app_bot.json +158 -0
- package/assets/open-connector/catalog/apps/github.json +275 -0
- package/assets/open-connector/catalog/apps/gitlab.json +125 -0
- package/assets/open-connector/catalog/apps/gmail.json +151 -0
- package/assets/open-connector/catalog/apps/googlecalendar.json +206 -0
- package/assets/open-connector/catalog/apps/googledrive.json +479 -0
- package/assets/open-connector/catalog/apps/googlesheets.json +144 -0
- package/assets/open-connector/catalog/apps/hithink_finance.json +6 -3
- package/assets/open-connector/catalog/apps/indexed.json +1115 -0
- package/assets/open-connector/catalog/apps/linear.json +116 -0
- package/assets/open-connector/catalog/apps/notion.json +142 -0
- package/assets/open-connector/catalog/apps/one_drive.json +185 -0
- package/assets/open-connector/catalog/apps/outlook.json +182 -0
- package/assets/open-connector/catalog/apps/shopify.json +282 -0
- package/assets/open-connector/catalog/apps/slack.json +182 -0
- package/assets/open-connector/catalog/apps/spotify.json +46 -43
- package/assets/open-connector/catalog/apps/stripe.json +96 -0
- package/assets/open-connector/catalog/apps/telegram.json +138 -0
- package/assets/open-connector/catalog/apps/weixin_store.json +543 -2
- package/assets/open-connector/catalog/apps/woocommerce.json +127 -0
- package/assets/open-connector/catalog/apps/zendesk.json +152 -0
- package/assets/open-connector/catalog/apps/zerotier.json +9 -9
- package/assets/open-connector/catalog/apps-index.json +1 -1
- package/assets/open-connector/migrations/0014_saas_project.sql +55 -0
- package/assets/open-connector/migrations/0015_saas_cleanup_runtime.sql +8 -0
- package/assets/open-connector/migrations/0016_trigger_policy.sql +1 -0
- package/assets/open-connector/migrations/0017_trigger_subscriptions.sql +17 -0
- package/assets/open-connector/migrations/postgresql/0014_saas_project.sql +55 -0
- package/assets/open-connector/migrations/postgresql/0015_saas_cleanup_runtime.sql +8 -0
- package/assets/open-connector/migrations/postgresql/0016_trigger_policy.sql +1 -0
- package/assets/open-connector/migrations/postgresql/0017_trigger_subscriptions.sql +17 -0
- package/package.json +2 -2
- package/src/connection-service.d.ts +40 -7
- package/src/connection-service.js +60 -18
- package/src/core/action-policy.d.ts +8 -1
- package/src/core/action-policy.js +51 -0
- package/src/core/cast.d.ts +3 -0
- package/src/core/cast.js +4 -1
- package/src/core/guarded-fetch.d.ts +5 -0
- package/src/core/guarded-fetch.js +13 -4
- package/src/core/remote-http.d.ts +33 -0
- package/src/core/remote-http.js +104 -0
- package/src/core/request.d.ts +1 -0
- package/src/core/request.js +7 -0
- package/src/core/types.d.ts +4 -0
- package/src/marketplace/marketplace-service.d.ts +0 -1
- package/src/marketplace/marketplace-service.js +80 -92
- package/src/mcp.js +19 -5
- package/src/oauth/oauth-flow-service.d.ts +8 -1
- package/src/oauth/oauth-flow-service.js +10 -4
- package/src/providers/action-contracts.generated.d.ts +4 -2
- package/src/providers/airtable/executors.d.ts +3 -0
- package/src/providers/airtable/executors.js +2 -0
- package/src/providers/airtable/trigger-on-record-changed.d.ts +2 -0
- package/src/providers/airtable/trigger-on-record-changed.definition.d.ts +4 -0
- package/src/providers/airtable/trigger-on-record-changed.definition.js +54 -0
- package/src/providers/airtable/trigger-on-record-changed.js +235 -0
- package/src/providers/aisa/executors.js +196 -22
- package/src/providers/cal/actions.js +5 -1
- package/src/providers/enormail/executors.d.ts +4 -0
- package/src/providers/enormail/executors.js +97 -0
- package/src/providers/feishu_app_bot/executors.d.ts +3 -0
- package/src/providers/feishu_app_bot/executors.js +2 -0
- package/src/providers/feishu_app_bot/trigger-config.d.ts +1 -0
- package/src/providers/feishu_app_bot/trigger-config.js +10 -0
- package/src/providers/feishu_app_bot/trigger-on-event.d.ts +2 -0
- package/src/providers/feishu_app_bot/trigger-on-event.definition.d.ts +4 -0
- package/src/providers/feishu_app_bot/trigger-on-event.definition.js +63 -0
- package/src/providers/feishu_app_bot/trigger-on-event.js +29 -0
- package/src/providers/feishu_app_bot/trigger-subscriptions.d.ts +5 -0
- package/src/providers/feishu_app_bot/trigger-subscriptions.js +70 -0
- package/src/providers/github/executors.d.ts +3 -0
- package/src/providers/github/executors.js +6 -0
- package/src/providers/github/trigger-on-repo-event.d.ts +2 -0
- package/src/providers/github/trigger-on-repo-event.definition.d.ts +4 -0
- package/src/providers/github/trigger-on-repo-event.definition.js +94 -0
- package/src/providers/github/trigger-on-repo-event.js +168 -0
- package/src/providers/github/trigger-watch-pull-request.d.ts +2 -0
- package/src/providers/github/trigger-watch-pull-request.definition.d.ts +4 -0
- package/src/providers/github/trigger-watch-pull-request.definition.js +49 -0
- package/src/providers/github/trigger-watch-pull-request.js +106 -0
- package/src/providers/gitlab/executors.d.ts +3 -0
- package/src/providers/gitlab/executors.js +2 -0
- package/src/providers/gitlab/trigger-on-project-event.d.ts +2 -0
- package/src/providers/gitlab/trigger-on-project-event.definition.d.ts +5 -0
- package/src/providers/gitlab/trigger-on-project-event.definition.js +63 -0
- package/src/providers/gitlab/trigger-on-project-event.js +186 -0
- package/src/providers/gmail/executors.d.ts +3 -0
- package/src/providers/gmail/executors.js +2 -0
- package/src/providers/gmail/trigger-on-message-received.d.ts +2 -0
- package/src/providers/gmail/trigger-on-message-received.definition.d.ts +4 -0
- package/src/providers/gmail/trigger-on-message-received.definition.js +74 -0
- package/src/providers/gmail/trigger-on-message-received.js +232 -0
- package/src/providers/googlecalendar/executors.d.ts +3 -0
- package/src/providers/googlecalendar/executors.js +2 -0
- package/src/providers/googlecalendar/trigger-on-event-changed.d.ts +2 -0
- package/src/providers/googlecalendar/trigger-on-event-changed.definition.d.ts +4 -0
- package/src/providers/googlecalendar/trigger-on-event-changed.definition.js +74 -0
- package/src/providers/googlecalendar/trigger-on-event-changed.js +233 -0
- package/src/providers/googledrive/executors.d.ts +3 -0
- package/src/providers/googledrive/executors.js +7 -0
- package/src/providers/googledrive/trigger-changes.d.ts +12 -0
- package/src/providers/googledrive/trigger-changes.definition.d.ts +7 -0
- package/src/providers/googledrive/trigger-changes.definition.js +101 -0
- package/src/providers/googledrive/trigger-changes.js +452 -0
- package/src/providers/googledrive/trigger-on-file-change.d.ts +2 -0
- package/src/providers/googledrive/trigger-on-file-change.definition.d.ts +4 -0
- package/src/providers/googledrive/trigger-on-file-change.definition.js +77 -0
- package/src/providers/googledrive/trigger-on-file-change.js +258 -0
- package/src/providers/googlesheets/executors.d.ts +3 -0
- package/src/providers/googlesheets/executors.js +2 -0
- package/src/providers/googlesheets/trigger-on-row-added.d.ts +2 -0
- package/src/providers/googlesheets/trigger-on-row-added.definition.d.ts +4 -0
- package/src/providers/googlesheets/trigger-on-row-added.definition.js +54 -0
- package/src/providers/googlesheets/trigger-on-row-added.js +234 -0
- package/src/providers/hithink_finance/runtime.js +1 -1
- package/src/providers/indexed/executors.d.ts +4 -0
- package/src/providers/indexed/executors.js +16 -0
- package/src/providers/indexed/runtime.d.ts +26 -0
- package/src/providers/indexed/runtime.js +129 -0
- package/src/providers/linear/executors.d.ts +3 -0
- package/src/providers/linear/executors.js +2 -0
- package/src/providers/linear/trigger-on-issue-changed.d.ts +2 -0
- package/src/providers/linear/trigger-on-issue-changed.definition.d.ts +5 -0
- package/src/providers/linear/trigger-on-issue-changed.definition.js +43 -0
- package/src/providers/linear/trigger-on-issue-changed.js +215 -0
- package/src/providers/notion/executors.d.ts +3 -0
- package/src/providers/notion/executors.js +2 -0
- package/src/providers/notion/trigger-on-database-page-event.d.ts +2 -0
- package/src/providers/notion/trigger-on-database-page-event.definition.d.ts +4 -0
- package/src/providers/notion/trigger-on-database-page-event.definition.js +63 -0
- package/src/providers/notion/trigger-on-database-page-event.js +293 -0
- package/src/providers/one_drive/executors.d.ts +3 -0
- package/src/providers/one_drive/executors.js +2 -0
- package/src/providers/one_drive/trigger-on-item-changed.d.ts +2 -0
- package/src/providers/one_drive/trigger-on-item-changed.definition.d.ts +4 -0
- package/src/providers/one_drive/trigger-on-item-changed.definition.js +63 -0
- package/src/providers/one_drive/trigger-on-item-changed.js +214 -0
- package/src/providers/outlook/executors.d.ts +3 -0
- package/src/providers/outlook/executors.js +2 -0
- package/src/providers/outlook/trigger-on-message-received.d.ts +2 -0
- package/src/providers/outlook/trigger-on-message-received.definition.d.ts +4 -0
- package/src/providers/outlook/trigger-on-message-received.definition.js +93 -0
- package/src/providers/outlook/trigger-on-message-received.js +226 -0
- package/src/providers/outlook_calendar/executors.js +6 -0
- package/src/providers/provider-loader.d.ts +5 -0
- package/src/providers/provider-loader.js +4 -0
- package/src/providers/registry.generated.js +2 -0
- package/src/providers/shopify/executors.d.ts +3 -0
- package/src/providers/shopify/executors.js +2 -0
- package/src/providers/shopify/trigger-on-shop-event.d.ts +2 -0
- package/src/providers/shopify/trigger-on-shop-event.definition.d.ts +4 -0
- package/src/providers/shopify/trigger-on-shop-event.definition.js +214 -0
- package/src/providers/shopify/trigger-on-shop-event.js +165 -0
- package/src/providers/slack/executors.d.ts +3 -0
- package/src/providers/slack/executors.js +2 -0
- package/src/providers/slack/trigger-on-message-posted.d.ts +2 -0
- package/src/providers/slack/trigger-on-message-posted.definition.d.ts +4 -0
- package/src/providers/slack/trigger-on-message-posted.definition.js +80 -0
- package/src/providers/slack/trigger-on-message-posted.js +176 -0
- package/src/providers/spotify/runtime.js +15 -4
- package/src/providers/stripe/executors.d.ts +3 -0
- package/src/providers/stripe/executors.js +2 -0
- package/src/providers/stripe/trigger-on-event.d.ts +2 -0
- package/src/providers/stripe/trigger-on-event.definition.d.ts +4 -0
- package/src/providers/stripe/trigger-on-event.definition.js +43 -0
- package/src/providers/stripe/trigger-on-event.js +212 -0
- package/src/providers/telegram/executors.d.ts +3 -0
- package/src/providers/telegram/executors.js +2 -0
- package/src/providers/telegram/trigger-on-update.d.ts +2 -0
- package/src/providers/telegram/trigger-on-update.definition.d.ts +5 -0
- package/src/providers/telegram/trigger-on-update.definition.js +78 -0
- package/src/providers/telegram/trigger-on-update.js +141 -0
- package/src/providers/weixin_store/access-token.d.ts +2 -1
- package/src/providers/weixin_store/access-token.js +15 -4
- package/src/providers/weixin_store/executors.js +97 -12
- package/src/providers/woocommerce/executors.d.ts +3 -0
- package/src/providers/woocommerce/executors.js +2 -0
- package/src/providers/woocommerce/trigger-on-store-event.d.ts +2 -0
- package/src/providers/woocommerce/trigger-on-store-event.definition.d.ts +4 -0
- package/src/providers/woocommerce/trigger-on-store-event.definition.js +55 -0
- package/src/providers/woocommerce/trigger-on-store-event.js +179 -0
- package/src/providers/zendesk/executors.d.ts +3 -0
- package/src/providers/zendesk/executors.js +2 -0
- package/src/providers/zendesk/trigger-on-event.d.ts +2 -0
- package/src/providers/zendesk/trigger-on-event.definition.d.ts +5 -0
- package/src/providers/zendesk/trigger-on-event.definition.js +101 -0
- package/src/providers/zendesk/trigger-on-event.js +188 -0
- package/src/saas/saas-cleanup-service.d.ts +26 -0
- package/src/saas/saas-cleanup-service.js +124 -0
- package/src/saas/saas-client.d.ts +86 -0
- package/src/saas/saas-client.js +369 -0
- package/src/saas/saas-execution-service.d.ts +15 -0
- package/src/saas/saas-execution-service.js +21 -0
- package/src/saas/saas-oauth-service.d.ts +25 -0
- package/src/saas/saas-oauth-service.js +197 -0
- package/src/saas/saas-project-service.d.ts +61 -0
- package/src/saas/saas-project-service.js +211 -0
- package/src/server/actions/action-idempotency.d.ts +1 -0
- package/src/server/actions/action-idempotency.js +1 -0
- package/src/server/actions/action-runner.d.ts +7 -0
- package/src/server/actions/action-runner.js +43 -7
- package/src/server/actions/run-log-summary.js +9 -0
- package/src/server/api/auth.d.ts +1 -0
- package/src/server/api/auth.js +13 -2
- package/src/server/api/cache-policy.js +4 -1
- package/src/server/api/connection-input.d.ts +7 -1
- package/src/server/api/connection-input.js +7 -1
- package/src/server/api/connection-routes.d.ts +3 -1
- package/src/server/api/connection-routes.js +21 -3
- package/src/server/api/http-utils.d.ts +4 -3
- package/src/server/api/oauth-completion-page.d.ts +124 -0
- package/src/server/api/oauth-completion-page.js +113 -18
- package/src/server/api/openapi.js +112 -14
- package/src/server/api/policy-input.js +6 -0
- package/src/server/api/runtime-api.d.ts +10 -2
- package/src/server/api/runtime-api.js +17 -4
- package/src/server/api/saas-completion-page.d.ts +2 -0
- package/src/server/api/saas-completion-page.js +103 -0
- package/src/server/connect-app.d.ts +5 -0
- package/src/server/connect-app.js +50 -0
- package/src/server/connect-server.d.ts +12 -0
- package/src/server/connect-server.js +147 -13
- package/src/server/connector-runtime.d.ts +3 -1
- package/src/server/connector-runtime.js +5 -2
- package/src/server/files/transit-files.js +16 -7
- package/src/server/proxy/proxy-runner.d.ts +5 -1
- package/src/server/proxy/proxy-runner.js +72 -26
- package/src/server/storage/connection-request-store.d.ts +41 -1
- package/src/server/storage/connection-request-store.js +245 -20
- package/src/server/storage/connection-store.d.ts +16 -0
- package/src/server/storage/connection-store.js +119 -0
- package/src/server/storage/node-runtime-database.js +3 -3
- package/src/server/storage/{postgres-migrations.d.ts → postgres/migrations.d.ts} +2 -2
- package/src/server/storage/{postgres-migrations.js → postgres/migrations.js} +1 -1
- package/src/server/storage/postgres/runtime-store.d.ts +43 -0
- package/src/server/storage/{postgres-runtime-store.js → postgres/runtime-store.js} +59 -94
- package/src/server/storage/runtime-database.d.ts +4 -0
- package/src/server/storage/runtime-sql.d.ts +1 -1
- package/src/server/storage/runtime-sql.js +2 -1
- package/src/server/storage/runtime-store.d.ts +1 -0
- package/src/server/storage/runtime-token-service.d.ts +2 -0
- package/src/server/storage/runtime-token-service.js +3 -0
- package/src/server/storage/saas-project-store.d.ts +77 -0
- package/src/server/storage/saas-project-store.js +273 -0
- package/src/server/storage/{sqlite-runtime-store.d.ts → sqlite/runtime-store.d.ts} +21 -25
- package/src/server/storage/{sqlite-runtime-store.js → sqlite/runtime-store.js} +100 -115
- package/src/server/storage/trigger-store.d.ts +16 -0
- package/src/server/storage/trigger-store.js +96 -0
- package/src/triggers/common/config.d.ts +2 -0
- package/src/triggers/common/config.js +17 -0
- package/src/triggers/common/configOptions.d.ts +13 -0
- package/src/triggers/common/configOptions.js +1 -0
- package/src/triggers/common/encoding.d.ts +3 -0
- package/src/triggers/common/encoding.js +19 -0
- package/src/triggers/common/integration.d.ts +115 -0
- package/src/triggers/common/integration.js +31 -0
- package/src/triggers/common/json.d.ts +6 -0
- package/src/triggers/common/json.js +91 -0
- package/src/triggers/common/poll.d.ts +41 -0
- package/src/triggers/common/poll.js +15 -0
- package/src/triggers/common/proxy.d.ts +14 -0
- package/src/triggers/common/proxy.js +1 -0
- package/src/triggers/common/types.d.ts +42 -0
- package/src/triggers/common/types.js +1 -0
- package/src/triggers/maintenance.d.ts +40 -0
- package/src/triggers/maintenance.js +120 -0
- package/src/triggers/metadata.d.ts +8 -0
- package/src/triggers/metadata.js +1 -0
- package/src/triggers/request.d.ts +33 -0
- package/src/triggers/request.js +52 -0
- package/src/triggers/resources.d.ts +12 -0
- package/src/triggers/resources.js +121 -0
- package/src/triggers/signature.d.ts +4 -0
- package/src/triggers/signature.js +48 -0
- package/src/triggers/store.d.ts +29 -0
- package/src/triggers/store.js +1 -0
- package/src/triggers/subscriptions.d.ts +22 -0
- package/src/triggers/subscriptions.js +220 -0
- package/src/triggers/trigger-runner.d.ts +34 -0
- package/src/triggers/trigger-runner.js +169 -0
- package/src/server/storage/postgres-runtime-store.d.ts +0 -39
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { queueSaasConnections, queueSaasRequests } from "./saas-project-store.js";
|
|
1
2
|
/** Shared SQL lifecycle for SQLite, PostgreSQL and D1. Secrets use the runtime's codec. */
|
|
2
3
|
export class ConnectionRequestStore {
|
|
3
4
|
transaction;
|
|
@@ -10,16 +11,7 @@ export class ConnectionRequestStore {
|
|
|
10
11
|
const now = Date.parse(pending.createdAt);
|
|
11
12
|
const value = await this.secretCodec.encode(JSON.stringify(pending));
|
|
12
13
|
await this.transaction([
|
|
13
|
-
|
|
14
|
-
sql: "delete from connection_requests where expires_at <= ?",
|
|
15
|
-
values: [new Date(now - 86_400_000).toISOString()],
|
|
16
|
-
},
|
|
17
|
-
{
|
|
18
|
-
sql: `update connection_requests set phase = 'completed', status = 'failed', error_code = 'request_superseded',
|
|
19
|
-
error_message = 'A newer authorization request replaced this request.', value = null, updated_at = ?
|
|
20
|
-
where owner = ? and service = ? and phase = 'pending' and expires_at > ?`,
|
|
21
|
-
values: [now, pending.owner, pending.service, pending.createdAt],
|
|
22
|
-
},
|
|
14
|
+
...this.retireRequests(pending.owner, pending.service, now),
|
|
23
15
|
{
|
|
24
16
|
sql: `insert into connection_requests (id, owner, service, state, phase, status, value, expires_at, created_at, updated_at)
|
|
25
17
|
values (?, ?, ?, ?, 'pending', 'initiated', ?, ?, ?, ?)`,
|
|
@@ -63,7 +55,7 @@ export class ConnectionRequestStore {
|
|
|
63
55
|
async claim(state) {
|
|
64
56
|
const [[row]] = await this.transaction([
|
|
65
57
|
{
|
|
66
|
-
sql: "update connection_requests set phase = 'processing', updated_at = ? where state = ? and phase = 'pending' and expires_at > ? returning value",
|
|
58
|
+
sql: "update connection_requests set phase = 'processing', updated_at = ? where kind = 'local' and state = ? and phase = 'pending' and expires_at > ? returning value",
|
|
67
59
|
values: [Date.now(), state, new Date().toISOString()],
|
|
68
60
|
},
|
|
69
61
|
]);
|
|
@@ -75,7 +67,7 @@ export class ConnectionRequestStore {
|
|
|
75
67
|
await this.transaction([
|
|
76
68
|
{
|
|
77
69
|
sql: `update connection_requests set phase = 'completed', status = 'failed', error_code = ?, error_message = ?, value = null, updated_at = ?
|
|
78
|
-
where id = ? and phase = 'processing'`,
|
|
70
|
+
where kind = 'local' and id = ? and phase = 'processing'`,
|
|
79
71
|
values: [errorCode, errorMessage, Date.now(), id],
|
|
80
72
|
},
|
|
81
73
|
]);
|
|
@@ -84,17 +76,32 @@ export class ConnectionRequestStore {
|
|
|
84
76
|
const id = pending.target?.id ?? crypto.randomUUID();
|
|
85
77
|
const revision = crypto.randomUUID();
|
|
86
78
|
const value = await this.secretCodec.encode(JSON.stringify(credential));
|
|
79
|
+
const accountId = credential.authType !== "no_auth" && credential.metadata.providerAccountVerified === true
|
|
80
|
+
? credential.profile.accountId
|
|
81
|
+
: null;
|
|
87
82
|
signal?.throwIfAborted();
|
|
88
83
|
const now = new Date();
|
|
89
|
-
const active = "exists (select 1 from connection_requests where id = ? and phase = 'processing')";
|
|
84
|
+
const active = "exists (select 1 from connection_requests where kind = 'local' and id = ? and phase = 'processing')";
|
|
90
85
|
const write = pending.target
|
|
91
86
|
? {
|
|
92
|
-
sql: `update connections set value = ?, revision = ?, updated_at =
|
|
93
|
-
|
|
87
|
+
sql: `update connections set value = ?, revision = ?, updated_at = ?, source = 'local',
|
|
88
|
+
managed_project_id = null, provider_config_id = null, external_user_id = null, remote_account_id = null, local_request_id = null, provider_account_id = ? where id = ? and revision = ? and ${active}
|
|
89
|
+
and (not exists (select 1 from trigger_subscriptions where connection_id = connections.id and mode <> 'resource-set' and status in ('active', 'deleting'))
|
|
90
|
+
or (provider_account_id is not null and provider_account_id = ?)) returning id`,
|
|
91
|
+
values: [
|
|
92
|
+
value,
|
|
93
|
+
revision,
|
|
94
|
+
now.toISOString(),
|
|
95
|
+
accountId,
|
|
96
|
+
id,
|
|
97
|
+
pending.target.revision,
|
|
98
|
+
pending.connectionRequestId,
|
|
99
|
+
accountId,
|
|
100
|
+
],
|
|
94
101
|
}
|
|
95
102
|
: {
|
|
96
|
-
sql: `insert into connections (id, revision, service, connection_name, value, updated_at)
|
|
97
|
-
select ?, ?, ?, ?, ?, ? where ${active} returning id`,
|
|
103
|
+
sql: `insert into connections (id, revision, service, connection_name, value, updated_at, provider_account_id)
|
|
104
|
+
select ?, ?, ?, ?, ?, ?, ? where ${active} returning id`,
|
|
98
105
|
values: [
|
|
99
106
|
id,
|
|
100
107
|
revision,
|
|
@@ -102,17 +109,235 @@ export class ConnectionRequestStore {
|
|
|
102
109
|
pending.connectionName,
|
|
103
110
|
value,
|
|
104
111
|
now.toISOString(),
|
|
112
|
+
accountId,
|
|
105
113
|
pending.connectionRequestId,
|
|
106
114
|
],
|
|
107
115
|
};
|
|
108
|
-
const
|
|
116
|
+
const results = await this.transaction([
|
|
117
|
+
{ sql: "update connections set revision = revision where id = ?", values: [id] },
|
|
118
|
+
queueSaasConnections(`id = ? and revision = ? and ${active}`, [
|
|
119
|
+
id,
|
|
120
|
+
pending.target?.revision ?? "",
|
|
121
|
+
pending.connectionRequestId,
|
|
122
|
+
]),
|
|
109
123
|
write,
|
|
110
124
|
{
|
|
111
125
|
sql: `update connection_requests set phase = 'completed', status = 'connected', app_id = ?, value = null, updated_at = ?
|
|
112
|
-
where id = ? and phase = 'processing' and exists (select 1 from connections where id = ? and revision = ?)`,
|
|
126
|
+
where kind = 'local' and id = ? and phase = 'processing' and exists (select 1 from connections where id = ? and revision = ?)`,
|
|
113
127
|
values: [id, now.getTime(), pending.connectionRequestId, id, revision],
|
|
114
128
|
},
|
|
115
129
|
]);
|
|
116
|
-
return
|
|
130
|
+
return results[2].length ? id : undefined;
|
|
131
|
+
}
|
|
132
|
+
retireRequests(owner, service, now) {
|
|
133
|
+
const expired = "expires_at <= ?";
|
|
134
|
+
const superseded = "owner = ? and service = ? and phase = 'pending'";
|
|
135
|
+
return [
|
|
136
|
+
queueSaasRequests(expired, [new Date(now - 86_400_000).toISOString()]),
|
|
137
|
+
queueSaasRequests(superseded, [owner, service]),
|
|
138
|
+
{
|
|
139
|
+
sql: `update connection_requests set phase = 'completed', status = 'failed', error_code = 'request_expired',
|
|
140
|
+
value = null, candidate_value = null, lease_id = null, lease_until = null, updated_at = ?
|
|
141
|
+
where kind = 'saas' and phase <> 'completed' and ${expired}`,
|
|
142
|
+
values: [now, new Date(now - 86_400_000).toISOString()],
|
|
143
|
+
},
|
|
144
|
+
{
|
|
145
|
+
sql: "delete from connection_requests where expires_at <= ?",
|
|
146
|
+
values: [new Date(now - 86_400_000).toISOString()],
|
|
147
|
+
},
|
|
148
|
+
{
|
|
149
|
+
sql: `update connection_requests set phase = 'completed', status = 'failed', error_code = 'request_superseded',
|
|
150
|
+
error_message = 'A newer authorization request replaced this request.', value = null, candidate_value = null,
|
|
151
|
+
lease_id = null, lease_until = null, updated_at = ? where ${superseded} and (kind = 'saas' or expires_at > ?)`,
|
|
152
|
+
values: [now, owner, service, new Date(now).toISOString()],
|
|
153
|
+
},
|
|
154
|
+
];
|
|
155
|
+
}
|
|
156
|
+
async createSaas(pending) {
|
|
157
|
+
if (!this.secretCodec.encrypted)
|
|
158
|
+
throw new Error("SaaS requests require encrypted storage.");
|
|
159
|
+
const value = await this.secretCodec.encode(JSON.stringify(pending));
|
|
160
|
+
const leaseId = crypto.randomUUID();
|
|
161
|
+
const returnUri = pending.returnUri ? await this.secretCodec.encode(pending.returnUri) : null;
|
|
162
|
+
const now = Date.now();
|
|
163
|
+
await this.transaction([
|
|
164
|
+
...this.retireRequests(pending.owner, pending.service, now),
|
|
165
|
+
{
|
|
166
|
+
sql: `insert into connection_requests
|
|
167
|
+
(id, owner, service, state, kind, phase, saas_phase, status, value, expires_at, created_at, updated_at,
|
|
168
|
+
managed_project_id, provider_config_id, external_user_id, lease_id, lease_until, return_uri)
|
|
169
|
+
values (?, ?, ?, ?, 'saas', 'pending', 'creating', 'initiated', ?, ?, ?, ?,
|
|
170
|
+
(select managed_project_id from managed_project where managed_project_id = ?), ?, ?, ?, ?, ?)`,
|
|
171
|
+
values: [
|
|
172
|
+
pending.connectionRequestId,
|
|
173
|
+
pending.owner,
|
|
174
|
+
pending.service,
|
|
175
|
+
crypto.randomUUID(),
|
|
176
|
+
value,
|
|
177
|
+
pending.expiresAt,
|
|
178
|
+
Date.parse(pending.createdAt),
|
|
179
|
+
now,
|
|
180
|
+
pending.managedProjectId,
|
|
181
|
+
pending.providerConfigId,
|
|
182
|
+
pending.externalUserId,
|
|
183
|
+
leaseId,
|
|
184
|
+
now + 45_000,
|
|
185
|
+
returnUri,
|
|
186
|
+
],
|
|
187
|
+
},
|
|
188
|
+
]);
|
|
189
|
+
return { pending, leaseId, phase: "creating", remoteRequestId: null, pollAttempts: 0 };
|
|
190
|
+
}
|
|
191
|
+
async claimSaas(id, owner, now = Date.now()) {
|
|
192
|
+
const leaseId = crypto.randomUUID();
|
|
193
|
+
const [[row]] = await this.transaction([
|
|
194
|
+
{
|
|
195
|
+
sql: `update connection_requests set lease_id = ?, lease_until = ?, updated_at = ?
|
|
196
|
+
where id = ? and owner = ? and kind = 'saas' and phase = 'pending' and expires_at > ?
|
|
197
|
+
and next_poll_at <= ? and (lease_until is null or lease_until <= ?) returning *`,
|
|
198
|
+
values: [leaseId, now + 45_000, now, id, owner, new Date(now - 86_400_000).toISOString(), now, now],
|
|
199
|
+
},
|
|
200
|
+
]);
|
|
201
|
+
if (!row)
|
|
202
|
+
return undefined;
|
|
203
|
+
return {
|
|
204
|
+
pending: JSON.parse(await this.secretCodec.decode(row.value)),
|
|
205
|
+
leaseId,
|
|
206
|
+
pollAttempts: Number(row.poll_attempts),
|
|
207
|
+
phase: row.saas_phase,
|
|
208
|
+
remoteRequestId: row.remote_request_id,
|
|
209
|
+
candidate: row.candidate_value
|
|
210
|
+
? {
|
|
211
|
+
...JSON.parse(await this.secretCodec.decode(row.candidate_value)),
|
|
212
|
+
connectedAccountId: row.remote_account_id,
|
|
213
|
+
}
|
|
214
|
+
: undefined,
|
|
215
|
+
};
|
|
216
|
+
}
|
|
217
|
+
async saveSaasRequest(lease, remoteRequestId, expiresAt) {
|
|
218
|
+
const now = Date.now();
|
|
219
|
+
const [[row]] = await this.transaction([
|
|
220
|
+
{
|
|
221
|
+
sql: `update connection_requests set remote_request_id = ?, expires_at = coalesce(?, expires_at), saas_phase = 'pending', updated_at = ?
|
|
222
|
+
where id = ? and kind = 'saas' and phase = 'pending' and saas_phase = 'creating' and lease_id = ? and lease_until > ? returning id`,
|
|
223
|
+
values: [remoteRequestId, expiresAt ?? null, now, lease.pending.connectionRequestId, lease.leaseId, now],
|
|
224
|
+
},
|
|
225
|
+
]);
|
|
226
|
+
return !!row;
|
|
227
|
+
}
|
|
228
|
+
async saveSaasCandidate(lease, candidate) {
|
|
229
|
+
const value = await this.secretCodec.encode(JSON.stringify({ profile: candidate.profile, status: candidate.status, comment: candidate.comment }));
|
|
230
|
+
const now = Date.now();
|
|
231
|
+
const [[row]] = await this.transaction([
|
|
232
|
+
{
|
|
233
|
+
sql: `update connection_requests set remote_account_id = ?, candidate_value = ?, saas_phase = 'candidate', updated_at = ?
|
|
234
|
+
where id = ? and kind = 'saas' and phase = 'pending' and saas_phase = 'pending'
|
|
235
|
+
and lease_id = ? and lease_until > ? returning id`,
|
|
236
|
+
values: [candidate.connectedAccountId, value, now, lease.pending.connectionRequestId, lease.leaseId, now],
|
|
237
|
+
},
|
|
238
|
+
]);
|
|
239
|
+
return !!row;
|
|
240
|
+
}
|
|
241
|
+
async releaseSaas(lease, nextPollAt, failed = false) {
|
|
242
|
+
const now = Date.now();
|
|
243
|
+
const [[row]] = await this.transaction([
|
|
244
|
+
{
|
|
245
|
+
sql: `update connection_requests set lease_id = null, lease_until = null, next_poll_at = ?, poll_attempts = ?
|
|
246
|
+
where id = ? and kind = 'saas' and phase = 'pending' and lease_id = ? and lease_until > ? returning id`,
|
|
247
|
+
values: [
|
|
248
|
+
Math.max(nextPollAt, now + 2_000),
|
|
249
|
+
failed ? lease.pollAttempts + 1 : 0,
|
|
250
|
+
lease.pending.connectionRequestId,
|
|
251
|
+
lease.leaseId,
|
|
252
|
+
now,
|
|
253
|
+
],
|
|
254
|
+
},
|
|
255
|
+
]);
|
|
256
|
+
return !!row;
|
|
257
|
+
}
|
|
258
|
+
async failSaas(lease, code, message) {
|
|
259
|
+
const now = Date.now();
|
|
260
|
+
const active = "id = ? and lease_id = ? and lease_until > ? and phase = 'pending' and kind = 'saas'";
|
|
261
|
+
const values = [lease.pending.connectionRequestId, lease.leaseId, now];
|
|
262
|
+
const [, rows] = await this.transaction([
|
|
263
|
+
queueSaasRequests(active, values),
|
|
264
|
+
{
|
|
265
|
+
sql: `update connection_requests set phase = 'completed', status = 'failed', error_code = ?, error_message = ?,
|
|
266
|
+
value = null, candidate_value = null, lease_id = null, lease_until = null, updated_at = ? where ${active} returning id`,
|
|
267
|
+
values: [code, message, now, ...values],
|
|
268
|
+
},
|
|
269
|
+
]);
|
|
270
|
+
return rows.length > 0;
|
|
271
|
+
}
|
|
272
|
+
async getSaasReturnUri(id, owner) {
|
|
273
|
+
const [[row]] = await this.transaction([
|
|
274
|
+
{
|
|
275
|
+
sql: "select return_uri from connection_requests where id = ? and owner = ? and kind = 'saas' and phase = 'completed' and expires_at > ?",
|
|
276
|
+
values: [id, owner, new Date(Date.now() - 86_400_000).toISOString()],
|
|
277
|
+
},
|
|
278
|
+
]);
|
|
279
|
+
return row?.return_uri ? this.secretCodec.decode(row.return_uri) : undefined;
|
|
280
|
+
}
|
|
281
|
+
async cancelSaas(id, owner) {
|
|
282
|
+
await this.transaction([
|
|
283
|
+
queueSaasRequests("id = ? and owner = ?", [id, owner]),
|
|
284
|
+
{
|
|
285
|
+
sql: `update connection_requests set phase = 'completed', status = 'failed', error_code = 'request_cancelled',
|
|
286
|
+
value = null, candidate_value = null, lease_id = null, lease_until = null, updated_at = ?
|
|
287
|
+
where id = ? and owner = ? and kind = 'saas' and phase <> 'completed'`,
|
|
288
|
+
values: [Date.now(), id, owner],
|
|
289
|
+
},
|
|
290
|
+
]);
|
|
291
|
+
}
|
|
292
|
+
async expireSaas(now = Date.now()) {
|
|
293
|
+
await this.transaction([
|
|
294
|
+
queueSaasRequests("expires_at <= ?", [new Date(now - 86_400_000).toISOString()]),
|
|
295
|
+
{
|
|
296
|
+
sql: `update connection_requests set phase = 'completed', status = 'failed', error_code = 'request_expired',
|
|
297
|
+
value = null, candidate_value = null, lease_id = null, lease_until = null, updated_at = ?
|
|
298
|
+
where kind = 'saas' and phase <> 'completed' and expires_at <= ?`,
|
|
299
|
+
values: [now, new Date(now - 86_400_000).toISOString()],
|
|
300
|
+
},
|
|
301
|
+
]);
|
|
302
|
+
}
|
|
303
|
+
async completeSaas(lease) {
|
|
304
|
+
const { pending } = lease;
|
|
305
|
+
const now = Date.now();
|
|
306
|
+
const id = pending.target?.id ?? pending.connectionId;
|
|
307
|
+
const revision = crypto.randomUUID();
|
|
308
|
+
const active = `id = ? and kind = 'saas' and phase = 'pending' and saas_phase = 'candidate'
|
|
309
|
+
and lease_id = ? and lease_until > ? and expires_at > ?`;
|
|
310
|
+
const activeValues = [pending.connectionRequestId, lease.leaseId, now, new Date(now - 86_400_000).toISOString()];
|
|
311
|
+
const target = pending.target
|
|
312
|
+
? "exists (select 1 from connections where id = ? and revision = ? and not exists (select 1 from trigger_subscriptions where connection_id = connections.id and mode <> 'resource-set' and status in ('active', 'deleting')))"
|
|
313
|
+
: "not exists (select 1 from connections where service = ? and connection_name = ?)";
|
|
314
|
+
const targetValues = pending.target ? [id, pending.target.revision] : [pending.service, pending.connectionName];
|
|
315
|
+
const results = await this.transaction([
|
|
316
|
+
{ sql: "update connections set revision = revision where id = ?", values: [id] },
|
|
317
|
+
queueSaasConnections(`id = ? and revision = ? and exists (select 1 from connection_requests where ${active} and remote_account_id <> connections.remote_account_id)`, [id, pending.target?.revision ?? "", ...activeValues]),
|
|
318
|
+
{
|
|
319
|
+
sql: `insert into connections
|
|
320
|
+
(id, revision, service, connection_name, value, updated_at, source, managed_project_id, provider_config_id, external_user_id, remote_account_id, local_request_id)
|
|
321
|
+
select ?, ?, service, ?, candidate_value, ?, 'saas', managed_project_id, provider_config_id, external_user_id, remote_account_id, id
|
|
322
|
+
from connection_requests where ${active} and ${target}
|
|
323
|
+
on conflict (id) do update set revision = excluded.revision, value = excluded.value, updated_at = excluded.updated_at,
|
|
324
|
+
source = excluded.source, managed_project_id = excluded.managed_project_id, provider_config_id = excluded.provider_config_id,
|
|
325
|
+
external_user_id = excluded.external_user_id, remote_account_id = excluded.remote_account_id, local_request_id = excluded.local_request_id returning id`,
|
|
326
|
+
values: [id, revision, pending.connectionName, new Date(now).toISOString(), ...activeValues, ...targetValues],
|
|
327
|
+
},
|
|
328
|
+
{
|
|
329
|
+
sql: `update connection_requests set phase = 'completed', status = 'connected', app_id = ?, value = null,
|
|
330
|
+
candidate_value = null, lease_id = null, lease_until = null, updated_at = ?
|
|
331
|
+
where ${active} and exists (select 1 from connections where id = ? and revision = ?) returning id`,
|
|
332
|
+
values: [id, now, ...activeValues, id, revision],
|
|
333
|
+
},
|
|
334
|
+
queueSaasRequests(active, activeValues),
|
|
335
|
+
{
|
|
336
|
+
sql: `update connection_requests set phase = 'completed', status = 'failed', error_code = 'request_key_conflict', error_message = 'The connection changed during authorization.',
|
|
337
|
+
value = null, candidate_value = null, lease_id = null, lease_until = null, updated_at = ? where ${active} returning id`,
|
|
338
|
+
values: [now, ...activeValues],
|
|
339
|
+
},
|
|
340
|
+
]);
|
|
341
|
+
return results[3].length ? "connected" : results[5].length ? "conflict" : "lease_lost";
|
|
117
342
|
}
|
|
118
343
|
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { IConnectionStore, StoredConnection, StoredLocalConnection } from "../../connection-service.ts";
|
|
2
|
+
import type { ResolvedCredential } from "../../core/types.ts";
|
|
3
|
+
import type { ISecretCodec } from "../secrets/secret-codec-core.ts";
|
|
4
|
+
import type { RequestTransaction } from "./connection-request-store.ts";
|
|
5
|
+
/** Connection writes share the request transaction so replacing/deleting remote references cannot lose cleanup work. */
|
|
6
|
+
export declare class SqlConnectionStore implements IConnectionStore {
|
|
7
|
+
private readonly transaction;
|
|
8
|
+
private readonly codec;
|
|
9
|
+
constructor(transaction: RequestTransaction, codec: ISecretCodec);
|
|
10
|
+
private read;
|
|
11
|
+
get(service: string, connectionName: string): Promise<StoredConnection | undefined>;
|
|
12
|
+
list(): Promise<StoredConnection[]>;
|
|
13
|
+
set(service: string, connectionName: string, credential: ResolvedCredential): Promise<StoredLocalConnection>;
|
|
14
|
+
updateCredential(input: StoredLocalConnection, refresh?: boolean): Promise<boolean>;
|
|
15
|
+
delete(service: string, connectionName: string): Promise<void>;
|
|
16
|
+
}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import { HttpRequestError } from "../api/http-utils.js";
|
|
2
|
+
import { queueSaasConnections, readSaasConnection } from "./saas-project-store.js";
|
|
3
|
+
/** Connection writes share the request transaction so replacing/deleting remote references cannot lose cleanup work. */
|
|
4
|
+
export class SqlConnectionStore {
|
|
5
|
+
transaction;
|
|
6
|
+
codec;
|
|
7
|
+
constructor(transaction, codec) {
|
|
8
|
+
this.transaction = transaction;
|
|
9
|
+
this.codec = codec;
|
|
10
|
+
}
|
|
11
|
+
async read(row) {
|
|
12
|
+
if (row.source === "saas")
|
|
13
|
+
return readSaasConnection(row, this.codec);
|
|
14
|
+
return {
|
|
15
|
+
id: row.id,
|
|
16
|
+
revision: row.revision,
|
|
17
|
+
service: row.service,
|
|
18
|
+
connectionName: row.connection_name,
|
|
19
|
+
credential: JSON.parse(await this.codec.decode(row.value)),
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
async get(service, connectionName) {
|
|
23
|
+
const [[row]] = await this.transaction([
|
|
24
|
+
{
|
|
25
|
+
sql: "select * from connections where service = ? and connection_name = ?",
|
|
26
|
+
values: [service, connectionName],
|
|
27
|
+
},
|
|
28
|
+
]);
|
|
29
|
+
return row ? this.read(row) : undefined;
|
|
30
|
+
}
|
|
31
|
+
async list() {
|
|
32
|
+
const [rows] = await this.transaction([
|
|
33
|
+
{ sql: "select * from connections order by service, connection_name", values: [] },
|
|
34
|
+
]);
|
|
35
|
+
return Promise.all(rows.map((row) => this.read(row)));
|
|
36
|
+
}
|
|
37
|
+
async set(service, connectionName, credential) {
|
|
38
|
+
const value = await this.codec.encode(JSON.stringify(credential));
|
|
39
|
+
const [, , [row]] = await this.transaction([
|
|
40
|
+
{
|
|
41
|
+
sql: "update connections set revision = revision where service = ? and connection_name = ?",
|
|
42
|
+
values: [service, connectionName],
|
|
43
|
+
},
|
|
44
|
+
queueSaasConnections("service = ? and connection_name = ?", [service, connectionName]),
|
|
45
|
+
{
|
|
46
|
+
sql: `insert into connections (id, revision, service, connection_name, value, updated_at, provider_account_id)
|
|
47
|
+
values (?, ?, ?, ?, ?, ?, ?) on conflict (service, connection_name) do update set
|
|
48
|
+
revision = excluded.revision, value = excluded.value, updated_at = excluded.updated_at,
|
|
49
|
+
source = 'local', managed_project_id = null, provider_config_id = null, external_user_id = null,
|
|
50
|
+
remote_account_id = null, local_request_id = null, provider_account_id = excluded.provider_account_id
|
|
51
|
+
where not exists (select 1 from trigger_subscriptions where connection_id = connections.id and mode <> 'resource-set' and status in ('active', 'deleting'))
|
|
52
|
+
or (connections.provider_account_id is not null and connections.provider_account_id = excluded.provider_account_id) returning id, revision`,
|
|
53
|
+
values: [
|
|
54
|
+
crypto.randomUUID(),
|
|
55
|
+
crypto.randomUUID(),
|
|
56
|
+
service,
|
|
57
|
+
connectionName,
|
|
58
|
+
value,
|
|
59
|
+
new Date().toISOString(),
|
|
60
|
+
credential.authType !== "no_auth" && credential.metadata.providerAccountVerified === true
|
|
61
|
+
? credential.profile.accountId
|
|
62
|
+
: null,
|
|
63
|
+
],
|
|
64
|
+
},
|
|
65
|
+
]);
|
|
66
|
+
if (!row)
|
|
67
|
+
throw new HttpRequestError("connection_has_subscriptions", "Cancel or abandon remote Trigger subscriptions before replacing this connection.", 409);
|
|
68
|
+
return { id: row.id, revision: row.revision, service, connectionName, credential };
|
|
69
|
+
}
|
|
70
|
+
async updateCredential(input, refresh = false) {
|
|
71
|
+
const value = await this.codec.encode(JSON.stringify(input.credential));
|
|
72
|
+
const [, [row]] = await this.transaction([
|
|
73
|
+
{ sql: "update connections set revision = revision where id = ?", values: [input.id] },
|
|
74
|
+
{
|
|
75
|
+
sql: `update connections set revision = ?, value = ?, updated_at = ?, provider_account_id = ?
|
|
76
|
+
where service = ? and connection_name = ? and id = ? and revision = ? and source = 'local'
|
|
77
|
+
and (? = 1 or not exists (select 1 from trigger_subscriptions where connection_id = connections.id and mode <> 'resource-set' and status in ('active', 'deleting'))
|
|
78
|
+
or (provider_account_id is not null and provider_account_id = ?)) returning id`,
|
|
79
|
+
values: [
|
|
80
|
+
crypto.randomUUID(),
|
|
81
|
+
value,
|
|
82
|
+
new Date().toISOString(),
|
|
83
|
+
input.credential.authType !== "no_auth" && input.credential.metadata.providerAccountVerified === true
|
|
84
|
+
? input.credential.profile.accountId
|
|
85
|
+
: null,
|
|
86
|
+
input.service,
|
|
87
|
+
input.connectionName,
|
|
88
|
+
input.id,
|
|
89
|
+
input.revision,
|
|
90
|
+
refresh ? 1 : 0,
|
|
91
|
+
input.credential.authType !== "no_auth" && input.credential.metadata.providerAccountVerified === true
|
|
92
|
+
? input.credential.profile.accountId
|
|
93
|
+
: null,
|
|
94
|
+
],
|
|
95
|
+
},
|
|
96
|
+
]);
|
|
97
|
+
return row !== undefined;
|
|
98
|
+
}
|
|
99
|
+
async delete(service, connectionName) {
|
|
100
|
+
const [, , , [remaining]] = await this.transaction([
|
|
101
|
+
{
|
|
102
|
+
sql: "update connections set revision = revision where service = ? and connection_name = ?",
|
|
103
|
+
values: [service, connectionName],
|
|
104
|
+
},
|
|
105
|
+
queueSaasConnections("service = ? and connection_name = ?", [service, connectionName]),
|
|
106
|
+
{
|
|
107
|
+
sql: `delete from connections where service = ? and connection_name = ? and not exists
|
|
108
|
+
(select 1 from trigger_subscriptions where connection_id = connections.id and mode <> 'resource-set' and status in ('active', 'deleting'))`,
|
|
109
|
+
values: [service, connectionName],
|
|
110
|
+
},
|
|
111
|
+
{
|
|
112
|
+
sql: "select id from connections where service = ? and connection_name = ?",
|
|
113
|
+
values: [service, connectionName],
|
|
114
|
+
},
|
|
115
|
+
]);
|
|
116
|
+
if (remaining)
|
|
117
|
+
throw new HttpRequestError("connection_has_subscriptions", "Cancel or abandon remote Trigger subscriptions before disconnecting this connection.", 409);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { migratePostgresDatabase } from "./postgres
|
|
2
|
-
import { SqliteRuntimeDatabase } from "./sqlite
|
|
1
|
+
import { migratePostgresDatabase } from "./postgres/migrations.js";
|
|
2
|
+
import { SqliteRuntimeDatabase } from "./sqlite/runtime-store.js";
|
|
3
3
|
export async function createNodeRuntimeDatabase(options) {
|
|
4
4
|
if (options.backend === "sqlite") {
|
|
5
5
|
return new SqliteRuntimeDatabase(options.path, options);
|
|
@@ -7,7 +7,7 @@ export async function createNodeRuntimeDatabase(options) {
|
|
|
7
7
|
const connectionString = options.connectionString.trim();
|
|
8
8
|
assertPostgresDatabaseUrl(connectionString);
|
|
9
9
|
// pg is loaded only when OOMOL_CONNECT_DATABASE_URL selects PostgreSQL; the SQLite default never pays for it.
|
|
10
|
-
const { PostgresRuntimeDatabase } = await import("./postgres
|
|
10
|
+
const { PostgresRuntimeDatabase } = await import("./postgres/runtime-store.js");
|
|
11
11
|
return await PostgresRuntimeDatabase.open(connectionString, options);
|
|
12
12
|
}
|
|
13
13
|
/** What `migrate` entry points print without OOMOL_CONNECT_DATABASE_URL: SQLite has no explicit migrate step. */
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type { RuntimeLogger } from "
|
|
2
|
-
import type { MigrationSource } from "
|
|
1
|
+
import type { RuntimeLogger } from "../../../core/types.ts";
|
|
2
|
+
import type { MigrationSource } from "../migration-source.ts";
|
|
3
3
|
import type { Pool } from "pg";
|
|
4
4
|
export interface PostgresMigrationOptions {
|
|
5
5
|
pool: Pool;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import type { IConnectionStore } from "../../../connection-service.ts";
|
|
2
|
+
import type { RuntimeLogger } from "../../../core/types.ts";
|
|
3
|
+
import type { IMarketplaceStore } from "../../../marketplace/marketplace-service.ts";
|
|
4
|
+
import type { IOAuthClientConfigStore } from "../../../oauth/oauth-client-config-service.ts";
|
|
5
|
+
import type { IOAuthStateStore } from "../../../oauth/oauth-flow-service.ts";
|
|
6
|
+
import type { ISecretCodec } from "../../secrets/secret-codec-core.ts";
|
|
7
|
+
import type { IIdempotencyStore } from "../idempotency-store.ts";
|
|
8
|
+
import type { MigrationSource } from "../migration-source.ts";
|
|
9
|
+
import type { RuntimeDatabase } from "../runtime-database.ts";
|
|
10
|
+
import type { IRuntimePolicyStore } from "../runtime-policy-store.ts";
|
|
11
|
+
import type { IRunLogStore } from "../runtime-store.ts";
|
|
12
|
+
import type { IRuntimeTokenStore } from "../runtime-token-service.ts";
|
|
13
|
+
import { ConnectionRequestStore } from "../connection-request-store.ts";
|
|
14
|
+
import { SaasProjectStore } from "../saas-project-store.ts";
|
|
15
|
+
import { SqlTriggerStore } from "../trigger-store.ts";
|
|
16
|
+
export interface PostgresRuntimeDatabaseOptions {
|
|
17
|
+
logger?: RuntimeLogger;
|
|
18
|
+
runLimit?: number;
|
|
19
|
+
secretCodec?: ISecretCodec;
|
|
20
|
+
poolMax?: number;
|
|
21
|
+
connectionTimeoutMs?: number;
|
|
22
|
+
migrations?: MigrationSource;
|
|
23
|
+
}
|
|
24
|
+
export declare class PostgresRuntimeDatabase implements RuntimeDatabase {
|
|
25
|
+
readonly saasProjectStore: SaasProjectStore;
|
|
26
|
+
readonly connectionRequestStore: ConnectionRequestStore;
|
|
27
|
+
readonly connectionStore: IConnectionStore;
|
|
28
|
+
readonly triggerStore: SqlTriggerStore;
|
|
29
|
+
readonly oauthClientConfigStore: IOAuthClientConfigStore;
|
|
30
|
+
readonly oauthStateStore: IOAuthStateStore;
|
|
31
|
+
readonly runtimeTokenStore: IRuntimeTokenStore;
|
|
32
|
+
readonly runtimePolicyStore: IRuntimePolicyStore;
|
|
33
|
+
readonly runLogStore: IRunLogStore;
|
|
34
|
+
readonly idempotencyStore: IIdempotencyStore;
|
|
35
|
+
readonly marketplaceStore: IMarketplaceStore;
|
|
36
|
+
private readonly pool;
|
|
37
|
+
private readonly secretCodec;
|
|
38
|
+
private constructor();
|
|
39
|
+
static open(connectionString: string, options?: PostgresRuntimeDatabaseOptions): Promise<PostgresRuntimeDatabase>;
|
|
40
|
+
close(): Promise<void>;
|
|
41
|
+
resetRuntimeData(): Promise<void>;
|
|
42
|
+
rotateSecretCodec(nextSecretCodec: ISecretCodec): Promise<void>;
|
|
43
|
+
}
|