@friggframework/core 2.0.0--canary.608.ba60ba6.0 → 2.0.0--canary.608.4bec88a.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/handlers/workers/user-action-worker.js +12 -3
- package/index.js +9 -3
- package/integrations/integration-base.js +9 -23
- package/integrations/integration-router.js +2 -6
- package/integrations/use-cases/dispatch-integration-event.js +7 -8
- package/package.json +5 -5
- package/queues/queuer-util.js +2 -10
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
const { Worker } = require('../../core/Worker');
|
|
2
|
+
// Direct path (not the package index) to avoid a circular require: index.js
|
|
3
|
+
// re-exports this module.
|
|
4
|
+
const { createHandler } = require('../../core/create-handler');
|
|
2
5
|
const {
|
|
3
6
|
GetIntegrationInstance,
|
|
4
7
|
} = require('../../integrations/use-cases/get-integration-instance');
|
|
@@ -148,8 +151,14 @@ class UserActionWorker extends Worker {
|
|
|
148
151
|
}
|
|
149
152
|
}
|
|
150
153
|
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
+
// Wrap in createHandler so the Lambda gets the same runtime setup as every
|
|
155
|
+
// other DB-touching worker: secretsToEnv() (SECRET_ARN injection), connectPrisma()
|
|
156
|
+
// (+ Mongo schema init), and callbackWaitsForEmptyEventLoop=false. The method's
|
|
157
|
+
// return value ({ batchItemFailures }) passes through for ReportBatchItemFailures.
|
|
158
|
+
const userActionQueueWorker = createHandler({
|
|
159
|
+
eventName: 'UserActionQueueWorker',
|
|
160
|
+
isUserFacingResponse: false,
|
|
161
|
+
method: async (event, context) => new UserActionWorker().run(event, context),
|
|
162
|
+
});
|
|
154
163
|
|
|
155
164
|
module.exports = { UserActionWorker, userActionQueueWorker };
|
package/index.js
CHANGED
|
@@ -30,7 +30,9 @@ const {
|
|
|
30
30
|
const {
|
|
31
31
|
GetUserFromAdopterJwt,
|
|
32
32
|
} = require('./user/use-cases/get-user-from-adopter-jwt');
|
|
33
|
-
const {
|
|
33
|
+
const {
|
|
34
|
+
AuthenticateUser,
|
|
35
|
+
} = require('./user/use-cases/authenticate-user');
|
|
34
36
|
|
|
35
37
|
const {
|
|
36
38
|
CredentialRepository,
|
|
@@ -41,14 +43,18 @@ const {
|
|
|
41
43
|
const {
|
|
42
44
|
IntegrationMappingRepository,
|
|
43
45
|
} = require('./integrations/repositories/integration-mapping-repository');
|
|
44
|
-
const {
|
|
46
|
+
const {
|
|
47
|
+
CreateProcess,
|
|
48
|
+
} = require('./integrations/use-cases/create-process');
|
|
45
49
|
const {
|
|
46
50
|
UpdateProcessState,
|
|
47
51
|
} = require('./integrations/use-cases/update-process-state');
|
|
48
52
|
const {
|
|
49
53
|
UpdateProcessMetrics,
|
|
50
54
|
} = require('./integrations/use-cases/update-process-metrics');
|
|
51
|
-
const {
|
|
55
|
+
const {
|
|
56
|
+
GetProcess,
|
|
57
|
+
} = require('./integrations/use-cases/get-process');
|
|
52
58
|
const { Cryptor } = require('./encrypt');
|
|
53
59
|
const {
|
|
54
60
|
BaseError,
|
|
@@ -215,11 +215,11 @@ class IntegrationBase {
|
|
|
215
215
|
/**
|
|
216
216
|
* Returns the modules as object with keys as module names.
|
|
217
217
|
* Uses the keys from Definition.modules to attach modules correctly.
|
|
218
|
-
*
|
|
218
|
+
*
|
|
219
219
|
* Example:
|
|
220
220
|
* Definition.modules = { attio: {...}, quo: { definition: { getName: () => 'quo-attio' } } }
|
|
221
221
|
* Module with getName()='quo-attio' gets attached as this.quo (not this['quo-attio'])
|
|
222
|
-
*
|
|
222
|
+
*
|
|
223
223
|
* @private
|
|
224
224
|
* @param {Array} integrationModules - Array of module instances
|
|
225
225
|
* @returns {Object} The modules object
|
|
@@ -231,16 +231,13 @@ class IntegrationBase {
|
|
|
231
231
|
// e.g., 'quo-attio' → 'quo', 'attio' → 'attio'
|
|
232
232
|
const moduleNameToKey = {};
|
|
233
233
|
if (this.constructor.Definition?.modules) {
|
|
234
|
-
for (const [key, moduleConfig] of Object.entries(
|
|
235
|
-
this.constructor.Definition.modules
|
|
236
|
-
)) {
|
|
234
|
+
for (const [key, moduleConfig] of Object.entries(this.constructor.Definition.modules)) {
|
|
237
235
|
const definition = moduleConfig.definition;
|
|
238
236
|
if (definition) {
|
|
239
237
|
// Use getName() if available, fallback to moduleName
|
|
240
|
-
const definitionName =
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
: definition.moduleName;
|
|
238
|
+
const definitionName = typeof definition.getName === 'function'
|
|
239
|
+
? definition.getName()
|
|
240
|
+
: definition.moduleName;
|
|
244
241
|
if (definitionName) {
|
|
245
242
|
moduleNameToKey[definitionName] = key;
|
|
246
243
|
}
|
|
@@ -539,10 +536,7 @@ class IntegrationBase {
|
|
|
539
536
|
// rather than crashing initialize()).
|
|
540
537
|
const eventDispatch = this.constructor.Definition?.eventDispatch || {};
|
|
541
538
|
for (const [eventName, mode] of Object.entries(eventDispatch)) {
|
|
542
|
-
if (
|
|
543
|
-
this.on[eventName] &&
|
|
544
|
-
this.on[eventName].dispatch === undefined
|
|
545
|
-
) {
|
|
539
|
+
if (this.on[eventName] && this.on[eventName].dispatch === undefined) {
|
|
546
540
|
this.on[eventName] = {
|
|
547
541
|
...this.on[eventName],
|
|
548
542
|
dispatch: mode,
|
|
@@ -706,11 +700,7 @@ class IntegrationBase {
|
|
|
706
700
|
|
|
707
701
|
if (delegateString === 'CREDENTIAL_INVALIDATED') {
|
|
708
702
|
console.log(
|
|
709
|
-
`[Frigg] Module ${
|
|
710
|
-
notifier?.name || '?'
|
|
711
|
-
} reported invalid credentials for integration ${
|
|
712
|
-
this.id
|
|
713
|
-
} — marking ERROR`
|
|
703
|
+
`[Frigg] Module ${notifier?.name || '?'} reported invalid credentials for integration ${this.id} — marking ERROR`
|
|
714
704
|
);
|
|
715
705
|
await this.updateIntegrationStatus.execute(this.id, 'ERROR');
|
|
716
706
|
this.status = 'ERROR';
|
|
@@ -720,11 +710,7 @@ class IntegrationBase {
|
|
|
720
710
|
if (delegateString === 'CREDENTIAL_VALIDATED') {
|
|
721
711
|
if (this.status !== 'ERROR') return;
|
|
722
712
|
console.log(
|
|
723
|
-
`[Frigg] Module ${
|
|
724
|
-
notifier?.name || '?'
|
|
725
|
-
} reported valid credentials for integration ${
|
|
726
|
-
this.id
|
|
727
|
-
} — clearing ERROR → ENABLED`
|
|
713
|
+
`[Frigg] Module ${notifier?.name || '?'} reported valid credentials for integration ${this.id} — clearing ERROR → ENABLED`
|
|
728
714
|
);
|
|
729
715
|
await this.updateIntegrationStatus.execute(this.id, 'ENABLED');
|
|
730
716
|
this.status = 'ENABLED';
|
|
@@ -559,9 +559,7 @@ function setEntityRoutes(router, authenticateUser, useCases) {
|
|
|
559
559
|
? Object.keys(params.data)
|
|
560
560
|
: [];
|
|
561
561
|
console.log(
|
|
562
|
-
`[Frigg] POST /api/authorize userId=${userId} entityType=${
|
|
563
|
-
params.entityType
|
|
564
|
-
} dataKeys=${JSON.stringify(dataKeys)}`
|
|
562
|
+
`[Frigg] POST /api/authorize userId=${userId} entityType=${params.entityType} dataKeys=${JSON.stringify(dataKeys)}`
|
|
565
563
|
);
|
|
566
564
|
|
|
567
565
|
try {
|
|
@@ -579,9 +577,7 @@ function setEntityRoutes(router, authenticateUser, useCases) {
|
|
|
579
577
|
res.json(entityDetails);
|
|
580
578
|
} catch (err) {
|
|
581
579
|
console.error(
|
|
582
|
-
`[Frigg] POST /api/authorize failed userId=${userId} entityType=${
|
|
583
|
-
params.entityType
|
|
584
|
-
} error=${err?.message || err}`
|
|
580
|
+
`[Frigg] POST /api/authorize failed userId=${userId} entityType=${params.entityType} error=${err?.message || err}`
|
|
585
581
|
);
|
|
586
582
|
throw err;
|
|
587
583
|
}
|
|
@@ -3,14 +3,13 @@ const { QueuerUtil } = require('../../queues');
|
|
|
3
3
|
|
|
4
4
|
const SCHEMA_VERSION = 1;
|
|
5
5
|
|
|
6
|
-
// Default lifecycle events that MUTATE and
|
|
7
|
-
// Read-shaped defaults (GET_*/REFRESH_*/WEBHOOK_RECEIVED)
|
|
8
|
-
// a queued read would return a 202 ack instead of the
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
]);
|
|
6
|
+
// Default lifecycle events that MUTATE and are routed through this helper, so
|
|
7
|
+
// they may be queued. Read-shaped defaults (GET_*/REFRESH_*/WEBHOOK_RECEIVED)
|
|
8
|
+
// must never be queued — a queued read would return a 202 ack instead of the
|
|
9
|
+
// data the caller expects. ON_DELETE is intentionally excluded: deletion is
|
|
10
|
+
// dispatched directly (and the record is gone immediately after), so a queued
|
|
11
|
+
// worker re-hydrating by id would discard it as terminal.
|
|
12
|
+
const MUTATING_DEFAULT_EVENTS = new Set(['ON_CREATE', 'ON_UPDATE']);
|
|
14
13
|
|
|
15
14
|
// Custom user actions (events not present in defaultEvents) are mutating by
|
|
16
15
|
// intent; only default events are filtered against the allowlist above.
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@friggframework/core",
|
|
3
3
|
"prettier": "@friggframework/prettier-config",
|
|
4
|
-
"version": "2.0.0--canary.608.
|
|
4
|
+
"version": "2.0.0--canary.608.4bec88a.0",
|
|
5
5
|
"dependencies": {
|
|
6
6
|
"@aws-sdk/client-apigatewaymanagementapi": "^3.588.0",
|
|
7
7
|
"@aws-sdk/client-kms": "^3.588.0",
|
|
@@ -38,9 +38,9 @@
|
|
|
38
38
|
}
|
|
39
39
|
},
|
|
40
40
|
"devDependencies": {
|
|
41
|
-
"@friggframework/eslint-config": "2.0.0--canary.608.
|
|
42
|
-
"@friggframework/prettier-config": "2.0.0--canary.608.
|
|
43
|
-
"@friggframework/test": "2.0.0--canary.608.
|
|
41
|
+
"@friggframework/eslint-config": "2.0.0--canary.608.4bec88a.0",
|
|
42
|
+
"@friggframework/prettier-config": "2.0.0--canary.608.4bec88a.0",
|
|
43
|
+
"@friggframework/test": "2.0.0--canary.608.4bec88a.0",
|
|
44
44
|
"@prisma/client": "^6.19.3",
|
|
45
45
|
"@types/lodash": "4.17.15",
|
|
46
46
|
"@typescript-eslint/eslint-plugin": "^8.0.0",
|
|
@@ -80,5 +80,5 @@
|
|
|
80
80
|
"publishConfig": {
|
|
81
81
|
"access": "public"
|
|
82
82
|
},
|
|
83
|
-
"gitHead": "
|
|
83
|
+
"gitHead": "4bec88a53c1c12df8f84aac9b2eeb6b23ba04c05"
|
|
84
84
|
}
|
package/queues/queuer-util.js
CHANGED
|
@@ -1,9 +1,5 @@
|
|
|
1
1
|
const { v4: uuid } = require('uuid');
|
|
2
|
-
const {
|
|
3
|
-
SQSClient,
|
|
4
|
-
SendMessageCommand,
|
|
5
|
-
SendMessageBatchCommand,
|
|
6
|
-
} = require('@aws-sdk/client-sqs');
|
|
2
|
+
const { SQSClient, SendMessageCommand, SendMessageBatchCommand } = require('@aws-sdk/client-sqs');
|
|
7
3
|
|
|
8
4
|
const awsConfigOptions = () => {
|
|
9
5
|
const config = {};
|
|
@@ -99,11 +95,7 @@ const QueuerUtil = {
|
|
|
99
95
|
// FIFO queues require a deduplication id whenever ContentBasedDeduplication
|
|
100
96
|
// is off — we default to a uuid so every send is treated as distinct (two
|
|
101
97
|
// distinct requests with identical bodies must both run, not be dropped).
|
|
102
|
-
send: async (
|
|
103
|
-
message,
|
|
104
|
-
queueUrl,
|
|
105
|
-
{ messageGroupId, messageDeduplicationId } = {}
|
|
106
|
-
) => {
|
|
98
|
+
send: async (message, queueUrl, { messageGroupId, messageDeduplicationId } = {}) => {
|
|
107
99
|
const command = new SendMessageCommand({
|
|
108
100
|
MessageBody: JSON.stringify(message),
|
|
109
101
|
QueueUrl: queueUrl,
|