@friggframework/core 2.0.0--canary.703.12b980b.0 → 2.0.0--canary.707.df80bfd.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/CHANGELOG.md +11 -0
- package/CLAUDE.md +28 -0
- package/README.md +105 -0
- package/application/commands/integration-commands.js +20 -10
- package/application/commands/scheduler-commands.js +11 -7
- package/application/commands/user-commands.js +17 -5
- package/application/index.js +6 -2
- package/core/Worker.js +31 -7
- package/core/create-handler.js +9 -0
- package/credential/repositories/credential-repository-documentdb.js +34 -0
- package/credential/repositories/credential-repository-interface.js +15 -0
- package/credential/repositories/credential-repository-mongo.js +23 -0
- package/credential/repositories/credential-repository-postgres.js +28 -0
- package/credential/use-cases/credential-operations-for-user.js +202 -0
- package/credential/use-cases/reauthorize-credential-for-user.js +73 -0
- package/database/config.js +48 -24
- package/database/documentdb-encryption-service.js +9 -22
- package/database/documentdb-utils.js +2 -2
- package/database/encryption/README.md +78 -14
- package/database/encryption/documentdb-encryption-service.md +78 -1
- package/database/encryption/encryption-config.js +219 -0
- package/database/encryption/encryption-schema-registry.js +121 -24
- package/database/encryption/field-encryption-service.js +69 -5
- package/database/encryption/integration-mapping-encryption.js +1 -1
- package/database/encryption/test-support/fake-ciphertext.js +15 -0
- package/database/organization-where.js +18 -0
- package/database/prisma.js +15 -38
- package/database/unique-violation.js +25 -0
- package/database/use-cases/check-encryption-health-use-case.js +43 -52
- package/errors/index.js +0 -4
- package/extensions/bootstrap-runner.js +43 -0
- package/extensions/extension-loader.js +230 -0
- package/extensions/index.js +44 -0
- package/extensions/initialize-app.js +123 -0
- package/extensions/prisma-composer.js +270 -0
- package/extensions/route-mounter.js +103 -0
- package/extensions/schema-composer.js +188 -0
- package/generated/prisma-mongodb/edge.js +33 -42
- package/generated/prisma-mongodb/index-browser.js +30 -39
- package/generated/prisma-mongodb/index.d.ts +3187 -2005
- package/generated/prisma-mongodb/index.js +33 -42
- package/generated/prisma-mongodb/package.json +1 -1
- package/generated/prisma-mongodb/schema.prisma +86 -59
- package/generated/prisma-mongodb/wasm.js +33 -42
- package/generated/prisma-postgresql/edge.js +33 -42
- package/generated/prisma-postgresql/index-browser.js +30 -39
- package/generated/prisma-postgresql/index.d.ts +3380 -2177
- package/generated/prisma-postgresql/index.js +33 -42
- package/generated/prisma-postgresql/package.json +1 -1
- package/generated/prisma-postgresql/schema.prisma +81 -57
- package/generated/prisma-postgresql/wasm.js +33 -42
- package/handlers/WEBHOOKS.md +0 -29
- package/handlers/app-definition-loader.js +128 -19
- package/handlers/app-handler-helpers.js +27 -8
- package/handlers/backend-utils.js +31 -25
- package/handlers/integration-event-dispatcher.js +3 -7
- package/handlers/middleware/admin-auth.js +14 -1
- package/handlers/routers/auth.js +46 -10
- package/handlers/routers/health.js +13 -4
- package/handlers/routers/integration-defined-routers.js +144 -92
- package/handlers/routers/integration-webhook-routers.js +100 -50
- package/handlers/workers/integration-defined-workers.js +5 -2
- package/index.js +66 -16
- package/infrastructure/scheduler/index.js +19 -6
- package/infrastructure/scheduler/netlify-scheduler-adapter.js +216 -0
- package/infrastructure/scheduler/scheduled-job-repository.js +118 -0
- package/infrastructure/scheduler/scheduler-service-factory.js +55 -7
- package/integrations/index.js +1 -14
- package/integrations/integration-base.js +2 -163
- package/integrations/integration-router.js +132 -102
- package/integrations/repositories/integration-mapping-repository-documentdb.js +0 -50
- package/integrations/repositories/integration-mapping-repository-interface.js +0 -15
- package/integrations/repositories/integration-mapping-repository-mongo.js +0 -29
- package/integrations/repositories/integration-mapping-repository-postgres.js +0 -30
- package/integrations/repositories/integration-mapping-repository.js +0 -29
- package/integrations/repositories/integration-not-found.js +14 -0
- package/integrations/repositories/integration-repository-documentdb.js +37 -9
- package/integrations/repositories/integration-repository-interface.js +17 -4
- package/integrations/repositories/integration-repository-mongo.js +64 -96
- package/integrations/repositories/integration-repository-postgres.js +63 -81
- package/integrations/repositories/process-repository-mongo.js +1 -1
- package/integrations/schedule-config.js +80 -0
- package/integrations/tests/doubles/test-integration-repository.js +12 -1
- package/integrations/use-cases/create-integration.js +56 -31
- package/integrations/use-cases/delete-integration-for-user.js +4 -4
- package/integrations/use-cases/dispatch-ongoing-syncs.js +100 -0
- package/integrations/use-cases/get-integration-for-user.js +2 -4
- package/integrations/use-cases/get-integration-instance.js +4 -4
- package/integrations/use-cases/get-integrations-for-user.js +79 -39
- package/integrations/use-cases/get-possible-integrations.js +2 -7
- package/integrations/use-cases/index.js +7 -1
- package/integrations/use-cases/integration-operations-for-user.js +256 -0
- package/integrations/use-cases/resolve-integration-ownership.js +177 -0
- package/integrations/use-cases/update-integration.js +4 -4
- package/integrations/utils/map-integration-dto.js +43 -14
- package/management-api/create-management-api-router.js +49 -0
- package/management-api/error-response.js +116 -0
- package/management-api/management-api-config.js +151 -0
- package/management-api/meta-router.js +76 -0
- package/management-api/openapi/build-openapi.js +144 -0
- package/management-api/openapi/components.js +415 -0
- package/management-api/openapi/v1-operations.js +83 -0
- package/management-api/openapi/v2-operations.js +264 -0
- package/management-api/route-registry.js +411 -0
- package/management-api/test-support/http-client.js +39 -0
- package/management-api/use-cases/get-management-api-meta.js +57 -0
- package/management-api/v1-deprecation.js +120 -0
- package/management-api/v2/create-v2-router.js +85 -0
- package/management-api/v2/dependencies.js +281 -0
- package/management-api/v2/dto.js +143 -0
- package/management-api/v2/handlers/authorization.js +94 -0
- package/management-api/v2/handlers/credentials.js +33 -0
- package/management-api/v2/handlers/entities.js +77 -0
- package/management-api/v2/handlers/integrations.js +128 -0
- package/management-api/v2/handlers/proxy.js +34 -0
- package/management-api/v2/request.js +85 -0
- package/management-api/v2/test-support/fake-dependencies.js +103 -0
- package/modules/domain/authorization-session.js +144 -0
- package/modules/entity-scope.js +15 -0
- package/modules/entity-type-registry.js +311 -0
- package/modules/index.js +14 -0
- package/modules/module-factory.js +12 -0
- package/modules/module.js +53 -2
- package/modules/proxy/proxy-bases.js +169 -0
- package/modules/proxy/proxy-errors.js +31 -0
- package/modules/proxy/proxy-path.js +183 -0
- package/modules/proxy/proxy-policy.js +277 -0
- package/modules/repositories/authorization-session-repository-documentdb.js +112 -0
- package/modules/repositories/authorization-session-repository-factory.js +31 -0
- package/modules/repositories/authorization-session-repository-interface.js +47 -0
- package/modules/repositories/authorization-session-repository-prisma.js +87 -0
- package/modules/repositories/entity-not-found.js +18 -0
- package/modules/repositories/module-repository-documentdb.js +51 -6
- package/modules/repositories/module-repository-interface.js +19 -2
- package/modules/repositories/module-repository-mongo.js +67 -74
- package/modules/repositories/module-repository-postgres.js +66 -74
- package/modules/repositories/module-repository.js +2 -1
- package/modules/requester/proxy-request.js +245 -0
- package/modules/requester/requester.js +35 -5
- package/modules/scope-config.js +192 -0
- package/modules/scope-policy.js +112 -0
- package/modules/scope-resolution.js +288 -0
- package/modules/scope-visibility.js +247 -0
- package/modules/tests/doubles/in-memory-authorization-session-repository.js +45 -0
- package/modules/tests/doubles/ownership-matching.js +18 -0
- package/modules/use-cases/authorize-entity-for-user.js +61 -0
- package/modules/use-cases/create-entity-from-credential.js +113 -0
- package/modules/use-cases/entity-operations-for-user.js +162 -0
- package/modules/use-cases/entity-types.js +139 -0
- package/modules/use-cases/execute-entity-proxy-request.js +331 -0
- package/modules/use-cases/get-authorization-requirements.js +100 -0
- package/modules/use-cases/get-entities-for-user.js +26 -13
- package/modules/use-cases/get-entity-module-for-user.js +113 -0
- package/modules/use-cases/get-entity-options-by-id.js +10 -4
- package/modules/use-cases/get-entity-options-by-type.js +1 -1
- package/modules/use-cases/get-module-instance-from-type.js +1 -1
- package/modules/use-cases/get-module.js +10 -4
- package/modules/use-cases/manage-access.js +21 -0
- package/modules/use-cases/multi-step-authorization.js +329 -0
- package/modules/use-cases/process-authorization-callback.js +53 -19
- package/modules/use-cases/refresh-entity-options.js +10 -4
- package/modules/use-cases/test-module-auth.js +10 -4
- package/package.json +6 -7
- package/prisma-mongodb/schema.prisma +86 -59
- package/prisma-postgresql/migrations/20261003000000_add_authorization_session/migration.sql +28 -0
- package/prisma-postgresql/migrations/20261015000000_add_organization_membership/migration.sql +26 -0
- package/prisma-postgresql/migrations/20261016000000_add_entity_integration_organization/migration.sql +25 -0
- package/prisma-postgresql/migrations/20261017000000_add_scheduled_job/migration.sql +28 -0
- package/prisma-postgresql/schema.prisma +81 -57
- package/providers/index.js +23 -0
- package/providers/resolve-provider.js +93 -0
- package/providers/runtime-detection.js +124 -0
- package/queues/index.js +25 -0
- package/queues/providers/index.js +11 -0
- package/queues/providers/netlify-background-provider.js +150 -0
- package/queues/providers/qstash-queue-provider.js +219 -0
- package/queues/providers/sqs-queue-provider.js +70 -0
- package/queues/queue-client-interface.js +55 -0
- package/queues/queue-message-auth.js +193 -0
- package/queues/queue-provider-factory.js +101 -0
- package/queues/queue-provider.js +65 -0
- package/queues/queuer-util.js +2 -9
- package/queues/sqs-queue-client.js +81 -0
- package/types/index.d.ts +2 -0
- package/types/modules/index.d.ts +214 -0
- package/types/user/index.d.ts +134 -0
- package/user/adopter-jwt-config.js +177 -0
- package/user/adopter-jwt-errors.js +59 -0
- package/user/adopter-token-verifier.js +122 -0
- package/user/app-user-helpers.js +97 -0
- package/user/create-user-authentication.js +64 -0
- package/user/membership.js +51 -0
- package/user/repositories/organization-membership-record.js +19 -0
- package/user/repositories/organization-membership-repository-documentdb.js +106 -0
- package/user/repositories/organization-membership-repository-factory.js +42 -0
- package/user/repositories/organization-membership-repository-interface.js +57 -0
- package/user/repositories/organization-membership-repository-mongo.js +13 -0
- package/user/repositories/organization-membership-repository-postgres.js +29 -0
- package/user/repositories/organization-membership-repository-prisma.js +81 -0
- package/user/repositories/user-repository-documentdb.js +27 -2
- package/user/repositories/user-repository-interface.js +18 -0
- package/user/repositories/user-repository-mongo.js +24 -0
- package/user/repositories/user-repository-postgres.js +18 -0
- package/user/tests/doubles/adopter-jwt-fixtures.js +220 -0
- package/user/use-cases/authenticate-user.js +7 -1
- package/user/use-cases/ensure-organization-membership.js +92 -0
- package/user/use-cases/find-individual-users-by-organization.js +54 -0
- package/user/use-cases/get-user-from-adopter-jwt.js +95 -124
- package/user/use-cases/get-user-from-x-frigg-headers.js +83 -80
- package/user/user.js +64 -1
- package/errors/mapping-already-exists-error.js +0 -14
- package/handlers/workers/integration-triggers.js +0 -25
- package/infrastructure/scheduler/recurrence.js +0 -204
- package/integrations/define/DESIGN.md +0 -122
- package/integrations/define/config.js +0 -98
- package/integrations/define/define-app.js +0 -66
- package/integrations/define/define-extension.js +0 -154
- package/integrations/define/define-integration.js +0 -335
- package/integrations/define/examples/deal-alerts.js +0 -140
- package/integrations/define/extension-binding.js +0 -174
- package/integrations/define/index.js +0 -11
- package/integrations/define/json-schema-lite.js +0 -68
- package/integrations/define/subscriptions.js +0 -186
- package/integrations/define/tests/fixtures/hubspot.js +0 -109
- package/integrations/define/tests/fixtures/slack.js +0 -26
- package/integrations/define/use.js +0 -39
- package/integrations/definitions/README.md +0 -278
- package/integrations/definitions/canonical.js +0 -11
- package/integrations/definitions/capabilities/AUDIT.md +0 -480
- package/integrations/definitions/capabilities/acmeerp.capabilities.json +0 -633
- package/integrations/definitions/capabilities/asana.capabilities.json +0 -279
- package/integrations/definitions/capabilities/calendly.capabilities.json +0 -385
- package/integrations/definitions/capabilities/docusign.capabilities.json +0 -314
- package/integrations/definitions/capabilities/fathom.capabilities.json +0 -238
- package/integrations/definitions/capabilities/github.capabilities.json +0 -585
- package/integrations/definitions/capabilities/hubspot.capabilities.json +0 -822
- package/integrations/definitions/capabilities/jira.capabilities.json +0 -391
- package/integrations/definitions/capabilities/klaviyo.capabilities.json +0 -503
- package/integrations/definitions/capabilities/linear.capabilities.json +0 -378
- package/integrations/definitions/capabilities/netsuite.capabilities.json +0 -535
- package/integrations/definitions/capabilities/notion.capabilities.json +0 -208
- package/integrations/definitions/capabilities/phone.capabilities.json +0 -511
- package/integrations/definitions/capabilities/pipedrive.capabilities.json +0 -430
- package/integrations/definitions/capabilities/quickbooks.capabilities.json +0 -635
- package/integrations/definitions/capabilities/salesforce.capabilities.json +0 -568
- package/integrations/definitions/capabilities/shopify.capabilities.json +0 -1128
- package/integrations/definitions/capabilities/slack.capabilities.json +0 -373
- package/integrations/definitions/capabilities/stripe.capabilities.json +0 -630
- package/integrations/definitions/capabilities/webflow.capabilities.json +0 -196
- package/integrations/definitions/capabilities/zendesk.capabilities.json +0 -422
- package/integrations/definitions/compile.js +0 -80
- package/integrations/definitions/config-form.js +0 -137
- package/integrations/definitions/examples/acme-erp-quickbooks.definition.json +0 -467
- package/integrations/definitions/examples/asana-slack.definition.json +0 -219
- package/integrations/definitions/examples/calendly-salesforce.definition.json +0 -459
- package/integrations/definitions/examples/docusign-salesforce.definition.json +0 -305
- package/integrations/definitions/examples/fathom-hubspot-notion.definition.json +0 -575
- package/integrations/definitions/examples/github-linear.definition.json +0 -322
- package/integrations/definitions/examples/hubspot-slack.definition.json +0 -427
- package/integrations/definitions/examples/klaviyo-hubspot.definition.json +0 -336
- package/integrations/definitions/examples/phone-hubspot.definition.json +0 -633
- package/integrations/definitions/examples/pipedrive-hubspot.definition.json +0 -136
- package/integrations/definitions/examples/pipedrive-phone.definition.json +0 -340
- package/integrations/definitions/examples/records/phone-hubspot.definition-version.json +0 -652
- package/integrations/definitions/examples/records/phone-hubspot.integration.json +0 -86
- package/integrations/definitions/examples/records/phone-hubspot.mappings.json +0 -39
- package/integrations/definitions/examples/records/phone-hubspot.workflow-run.json +0 -62
- package/integrations/definitions/examples/shopify-klaviyo.definition.json +0 -488
- package/integrations/definitions/examples/shopify-netsuite.definition.json +0 -622
- package/integrations/definitions/examples/stripe-quickbooks.definition.json +0 -476
- package/integrations/definitions/examples/webflow-hubspot-slack.definition.json +0 -262
- package/integrations/definitions/examples/zendesk-jira.definition.json +0 -604
- package/integrations/definitions/expressions.js +0 -229
- package/integrations/definitions/index.js +0 -48
- package/integrations/definitions/integration-runtime.js +0 -779
- package/integrations/definitions/interpreter.js +0 -104
- package/integrations/definitions/manifests.js +0 -177
- package/integrations/definitions/renderers/common.js +0 -67
- package/integrations/definitions/renderers/html.js +0 -129
- package/integrations/definitions/renderers/hubspot.js +0 -59
- package/integrations/definitions/renderers/preview.js +0 -154
- package/integrations/definitions/renderers/slack.js +0 -146
- package/integrations/definitions/repositories/definition-version-repository.js +0 -67
- package/integrations/definitions/repositories/workflow-run-repository.js +0 -80
- package/integrations/definitions/router.js +0 -170
- package/integrations/definitions/runtime.js +0 -268
- package/integrations/definitions/schema/capability-manifest.v0.1.schema.json +0 -549
- package/integrations/definitions/schema/installation.v0.1.schema.json +0 -130
- package/integrations/definitions/schema/integration-definition.v0.1.schema.json +0 -909
- package/integrations/definitions/schema/records.md +0 -105
- package/integrations/definitions/schema-check.js +0 -58
- package/integrations/definitions/scripts/check-manifests.js +0 -220
- package/integrations/definitions/scripts/validate.js +0 -66
- package/integrations/definitions/steps.js +0 -123
- package/integrations/definitions/sync-engine.js +0 -297
- package/integrations/definitions/tests/helpers-fake-crm.js +0 -49
- package/integrations/definitions/transforms.js +0 -91
- package/integrations/definitions/use-cases/definition-use-cases.js +0 -245
- package/integrations/definitions/validate.js +0 -436
- package/integrations/definitions/versioning.js +0 -176
- package/integrations/definitions/webhooks.js +0 -119
- package/integrations/integration-types.js +0 -73
- package/integrations/triggers.js +0 -244
- package/integrations/use-cases/run-trigger-tick.js +0 -155
- package/integrations/use-cases/run-trigger.js +0 -77
- package/prisma-postgresql/migrations/20261018000000_add_data_defined_integrations/migration.sql +0 -66
- package/prisma-postgresql/migrations/20261019000000_workflow_run_waits/migration.sql +0 -7
- package/prisma-postgresql/migrations/20261019120000_definition_workspace/migration.sql +0 -5
|
@@ -22,7 +22,6 @@ const { getTelemetry } = require('../telemetry/telemetry-runtime');
|
|
|
22
22
|
const { instrumentHandler } = require('../telemetry/instrument-handler');
|
|
23
23
|
const { bindTelemetryContext } = require('../telemetry/bind-telemetry-context');
|
|
24
24
|
const { getLogger } = require('../logs');
|
|
25
|
-
const { TRIGGER_RUN, TRIGGER_TICK, resolveTrigger } = require('./triggers');
|
|
26
25
|
|
|
27
26
|
const constantsToBeMigrated = {
|
|
28
27
|
defaultEvents: {
|
|
@@ -36,8 +35,6 @@ const constantsToBeMigrated = {
|
|
|
36
35
|
REFRESH_USER_ACTION_OPTIONS: 'REFRESH_USER_ACTION_OPTIONS',
|
|
37
36
|
WEBHOOK_RECEIVED: 'WEBHOOK_RECEIVED', // HTTP handler, no DB
|
|
38
37
|
ON_WEBHOOK: 'ON_WEBHOOK', // Queue worker, DB-connected
|
|
39
|
-
[TRIGGER_RUN]: TRIGGER_RUN, // Queue worker: one recurring trigger run (ADR-055)
|
|
40
|
-
[TRIGGER_TICK]: TRIGGER_TICK, // Queue worker: a trigger tick carrying on from its page cursor
|
|
41
38
|
// etc...
|
|
42
39
|
},
|
|
43
40
|
types: {
|
|
@@ -46,26 +43,6 @@ const constantsToBeMigrated = {
|
|
|
46
43
|
},
|
|
47
44
|
};
|
|
48
45
|
|
|
49
|
-
/**
|
|
50
|
-
* The facts about a webhook request that signature checks need, small enough to travel in the queue message: the
|
|
51
|
-
* method, the public URL the vendor called, and the raw body (up to 96 KB; beyond that it is left out and a check that
|
|
52
|
-
* needs it fails closed, because SQS messages are capped at 256 KB and the parsed body travels too).
|
|
53
|
-
*/
|
|
54
|
-
const RAW_BODY_LIMIT = 96 * 1024;
|
|
55
|
-
function webhookRequestFacts(req) {
|
|
56
|
-
const h = req.headers || {};
|
|
57
|
-
const proto = String(h['x-forwarded-proto'] || req.protocol || 'https').split(',')[0].trim();
|
|
58
|
-
const host = h['x-forwarded-host'] || h.host;
|
|
59
|
-
const url = host ? `${proto}://${host}${req.originalUrl || req.url || ''}` : undefined;
|
|
60
|
-
const raw = req.rawBody;
|
|
61
|
-
const rawBody = raw == null ? undefined : (Buffer.isBuffer(raw) ? raw.toString('utf8') : String(raw));
|
|
62
|
-
return {
|
|
63
|
-
method: req.method,
|
|
64
|
-
...(url ? { url } : {}),
|
|
65
|
-
...(rawBody !== undefined && Buffer.byteLength(rawBody) <= RAW_BODY_LIMIT ? { rawBody } : {}),
|
|
66
|
-
};
|
|
67
|
-
}
|
|
68
|
-
|
|
69
46
|
class IntegrationBase {
|
|
70
47
|
// todo: maybe we can pass this as Dependency Injection in the sub-class constructor
|
|
71
48
|
integrationRepository = createIntegrationRepository();
|
|
@@ -114,9 +91,6 @@ class IntegrationBase {
|
|
|
114
91
|
extensions: {},
|
|
115
92
|
// usage: { canonical: ['records.synced'], custom: { 'deals.enriched': { unit, label } } }
|
|
116
93
|
usage: {},
|
|
117
|
-
// Recurring triggers (ADR-055) — see integrations/triggers.js
|
|
118
|
-
// Shape: { [name]: { every | at | cron, timezone?, tick?, when?, overlap?, configurable?, handler } }
|
|
119
|
-
triggers: {},
|
|
120
94
|
display: {
|
|
121
95
|
name: 'Integration Name',
|
|
122
96
|
logo: '',
|
|
@@ -129,14 +103,6 @@ class IntegrationBase {
|
|
|
129
103
|
return this.Definition.name;
|
|
130
104
|
}
|
|
131
105
|
|
|
132
|
-
/**
|
|
133
|
-
* The deployed integration whose queue and functions this one runs on: itself, unless another class hosts it
|
|
134
|
-
* (`static Host`, e.g. a published integration definition run by the shared runtime).
|
|
135
|
-
*/
|
|
136
|
-
static getDeploymentName() {
|
|
137
|
-
return (this.Host || this).Definition.name;
|
|
138
|
-
}
|
|
139
|
-
|
|
140
106
|
static getCurrentVersion() {
|
|
141
107
|
return this.Definition.version;
|
|
142
108
|
}
|
|
@@ -205,14 +171,6 @@ class IntegrationBase {
|
|
|
205
171
|
type: constantsToBeMigrated.types.LIFE_CYCLE_EVENT,
|
|
206
172
|
handler: this.onWebhook,
|
|
207
173
|
},
|
|
208
|
-
[TRIGGER_RUN]: {
|
|
209
|
-
type: constantsToBeMigrated.types.LIFE_CYCLE_EVENT,
|
|
210
|
-
handler: this.onTriggerRun,
|
|
211
|
-
},
|
|
212
|
-
[TRIGGER_TICK]: {
|
|
213
|
-
type: constantsToBeMigrated.types.LIFE_CYCLE_EVENT,
|
|
214
|
-
handler: this.onTriggerTick,
|
|
215
|
-
},
|
|
216
174
|
};
|
|
217
175
|
}
|
|
218
176
|
|
|
@@ -499,35 +457,6 @@ class IntegrationBase {
|
|
|
499
457
|
);
|
|
500
458
|
}
|
|
501
459
|
|
|
502
|
-
/**
|
|
503
|
-
* Insert-only mapping write; usable as an atomic claim/lock row.
|
|
504
|
-
* @throws {MappingAlreadyExistsError} If a mapping for sourceId exists
|
|
505
|
-
*/
|
|
506
|
-
async createMapping(sourceId, mapping) {
|
|
507
|
-
if (!sourceId) {
|
|
508
|
-
throw new Error(`sourceId must be set`);
|
|
509
|
-
}
|
|
510
|
-
return await this.integrationMappingRepository.createMapping(
|
|
511
|
-
this.id,
|
|
512
|
-
sourceId,
|
|
513
|
-
mapping
|
|
514
|
-
);
|
|
515
|
-
}
|
|
516
|
-
|
|
517
|
-
/**
|
|
518
|
-
* Deletes the mapping for sourceId. A missing mapping is not an error
|
|
519
|
-
* (resolves with deletedCount 0).
|
|
520
|
-
*/
|
|
521
|
-
async deleteMapping(sourceId) {
|
|
522
|
-
if (!sourceId) {
|
|
523
|
-
throw new Error(`sourceId must be set`);
|
|
524
|
-
}
|
|
525
|
-
return await this.integrationMappingRepository.deleteMapping(
|
|
526
|
-
this.id,
|
|
527
|
-
sourceId
|
|
528
|
-
);
|
|
529
|
-
}
|
|
530
|
-
|
|
531
460
|
/**
|
|
532
461
|
* CHILDREN CAN OVERRIDE THESE CONFIGURATION METHODS
|
|
533
462
|
*/
|
|
@@ -564,90 +493,10 @@ class IntegrationBase {
|
|
|
564
493
|
} else if (this.status === 'NEEDS_CONFIG') {
|
|
565
494
|
await this.persistStatus('ENABLED');
|
|
566
495
|
}
|
|
567
|
-
await this.reportTriggerChoices();
|
|
568
496
|
}
|
|
569
497
|
|
|
570
498
|
async onDelete(params) {}
|
|
571
499
|
|
|
572
|
-
/**
|
|
573
|
-
* The recurring triggers declared for one installation (ADR-055): `Definition.triggers`, each with its `name`.
|
|
574
|
-
* Static so the tick can read them from a record without hydrating the installation; a class whose triggers
|
|
575
|
-
* depend on the installation (integrations published as definitions, `Definition.instanceTriggers`) overrides it.
|
|
576
|
-
* @param {{ config?: Object, record?: Object }} [installation]
|
|
577
|
-
* @returns {Promise<Array<Object>>}
|
|
578
|
-
*/
|
|
579
|
-
static async triggersFor(installation = {}) {
|
|
580
|
-
return Object.entries(this.Definition?.triggers || {}).map(([name, t]) => ({ ...t, name }));
|
|
581
|
-
}
|
|
582
|
-
|
|
583
|
-
/** This installation's trigger declarations (the static `triggersFor`, unless a subclass knows better). */
|
|
584
|
-
async triggerDeclarations() {
|
|
585
|
-
return this.constructor.triggersFor({ config: this.config || {}, record: this.record });
|
|
586
|
-
}
|
|
587
|
-
|
|
588
|
-
/**
|
|
589
|
-
* Run one recurring trigger: the queue worker dispatches `FRIGG_TRIGGER_RUN` here with
|
|
590
|
-
* `{ integrationId, trigger, scheduledFor }` after hydrating the installation. The handler is called as
|
|
591
|
-
* `handler(payload, ctx)` with `payload = { trigger, scheduledFor }` and `ctx = { modules, config, log, integration }`
|
|
592
|
-
* (ADR-054); a string handler names a method on this instance. Overlap and the run record: use-cases/run-trigger.js.
|
|
593
|
-
*/
|
|
594
|
-
async onTriggerRun({ data = {} } = {}) {
|
|
595
|
-
const declarations = await this.triggerDeclarations();
|
|
596
|
-
const declaration = declarations.find((t) => t.name === data.trigger);
|
|
597
|
-
const resolved = declaration ? resolveTrigger(declaration.name, declaration, this.config || {}) : null;
|
|
598
|
-
const payload = { trigger: data.trigger, scheduledFor: data.scheduledFor };
|
|
599
|
-
const invoke = async (p) => {
|
|
600
|
-
const handler = typeof declaration.handler === 'string' ? this[declaration.handler] : declaration.handler;
|
|
601
|
-
if (typeof handler !== 'function') throw new Error(`Trigger "${declaration.name}" handler "${declaration.handler}" is not a method of ${this.constructor.Definition?.name}`);
|
|
602
|
-
return handler.call(this, p, { modules: this.modules, config: this.config || {}, log: this.logger, integration: this });
|
|
603
|
-
};
|
|
604
|
-
const { RunTrigger } = require('./use-cases/run-trigger');
|
|
605
|
-
if (!this.triggerProcessRepository) {
|
|
606
|
-
const { createProcessRepository } = require('./repositories/process-repository-factory');
|
|
607
|
-
this.triggerProcessRepository = createProcessRepository();
|
|
608
|
-
}
|
|
609
|
-
const outcome = await new RunTrigger({ processRepository: this.triggerProcessRepository }).execute({ integration: this, resolved, invoke, payload });
|
|
610
|
-
if (outcome.status !== 'ran') {
|
|
611
|
-
this.logger.info('Trigger run not started', { eventName: `${this.logger.name}.trigger_${outcome.status}`, trigger: data.trigger, reason: outcome.reason });
|
|
612
|
-
}
|
|
613
|
-
return outcome;
|
|
614
|
-
}
|
|
615
|
-
|
|
616
|
-
/** The queue a one-time scheduled job (a paused run's resume) fires into: this integration's deployment queue (`<NAME>_QUEUE_URL`). */
|
|
617
|
-
scheduleQueueUrl() {
|
|
618
|
-
if (typeof this.getQueueUrl === 'function') return this.getQueueUrl();
|
|
619
|
-
return process.env[`${this.constructor.getDeploymentName().toUpperCase().replace(/-/g, '_')}_QUEUE_URL`];
|
|
620
|
-
}
|
|
621
|
-
|
|
622
|
-
/** A tick that ran out of time continues here, on a dry instance, from its page cursor. */
|
|
623
|
-
async onTriggerTick({ data = {}, context } = {}) {
|
|
624
|
-
const { runTriggerTick } = require('./use-cases/run-trigger-tick');
|
|
625
|
-
return runTriggerTick(this.constructor, data, context);
|
|
626
|
-
}
|
|
627
|
-
|
|
628
|
-
/**
|
|
629
|
-
* Report each trigger timing this installation chose that cannot be used (not configurable, or under the
|
|
630
|
-
* floor): the trigger keeps its default, and the integration gets a warning message saying why. No-op for an
|
|
631
|
-
* integration without triggers.
|
|
632
|
-
*/
|
|
633
|
-
async reportTriggerChoices() {
|
|
634
|
-
if (this.id === undefined || this.id === null) return [];
|
|
635
|
-
try {
|
|
636
|
-
const declarations = await this.triggerDeclarations();
|
|
637
|
-
const problems = declarations
|
|
638
|
-
.map((t) => ({ name: t.name, problems: resolveTrigger(t.name, t, this.config || {}).problems }))
|
|
639
|
-
.filter((p) => p.problems.length);
|
|
640
|
-
for (const p of problems) {
|
|
641
|
-
await this.updateIntegrationMessages.execute(this.id, 'warnings', 'Trigger timing not changed', `${p.name}: ${p.problems.join('; ')}`, Date.now());
|
|
642
|
-
}
|
|
643
|
-
return problems;
|
|
644
|
-
} catch (error) {
|
|
645
|
-
// A report, never a reason to fail the update.
|
|
646
|
-
this.logger.warn('Trigger choices not checked', { eventName: `${this.logger.name}.trigger_choices_unchecked`, error });
|
|
647
|
-
return [];
|
|
648
|
-
}
|
|
649
|
-
}
|
|
650
|
-
|
|
651
500
|
async getConfigOptions() {
|
|
652
501
|
const options = {
|
|
653
502
|
jsonSchema: {},
|
|
@@ -719,7 +568,6 @@ class IntegrationBase {
|
|
|
719
568
|
body,
|
|
720
569
|
headers: req.headers,
|
|
721
570
|
query: req.query,
|
|
722
|
-
...webhookRequestFacts(req),
|
|
723
571
|
});
|
|
724
572
|
|
|
725
573
|
res.status(200).json({ received: true });
|
|
@@ -729,15 +577,6 @@ class IntegrationBase {
|
|
|
729
577
|
// Default: no-op, integrations override this
|
|
730
578
|
}
|
|
731
579
|
|
|
732
|
-
/**
|
|
733
|
-
* What a module's verifyWebhookSignature needs about a queued delivery (onWebhookReceived put it there): the
|
|
734
|
-
* headers, the parsed body, the raw body exactly as received, and the method and public URL some vendors sign
|
|
735
|
-
* (HubSpot v3). Call as `this.<module>.api.verifyWebhookSignature(this.webhookVerificationInput(data))`.
|
|
736
|
-
*/
|
|
737
|
-
webhookVerificationInput(data = {}) {
|
|
738
|
-
return { headers: data.headers || {}, body: data.body, query: data.query || {}, rawBody: data.rawBody, method: data.method, url: data.url };
|
|
739
|
-
}
|
|
740
|
-
|
|
741
580
|
/**
|
|
742
581
|
* Queue a webhook for asynchronous worker dispatch.
|
|
743
582
|
*
|
|
@@ -754,7 +593,7 @@ class IntegrationBase {
|
|
|
754
593
|
async queueWebhook(data) {
|
|
755
594
|
const { QueuerUtil } = require('../queues');
|
|
756
595
|
|
|
757
|
-
const queueName = `${this.constructor.
|
|
596
|
+
const queueName = `${this.constructor.Definition.name
|
|
758
597
|
.toUpperCase()
|
|
759
598
|
.replace(/-/g, '_')}_QUEUE_URL`;
|
|
760
599
|
const queueUrl = process.env[queueName];
|
|
@@ -1096,4 +935,4 @@ class IntegrationBase {
|
|
|
1096
935
|
}
|
|
1097
936
|
}
|
|
1098
937
|
|
|
1099
|
-
module.exports = { IntegrationBase
|
|
938
|
+
module.exports = { IntegrationBase };
|