@friggframework/core 2.0.0--canary.396.0dd37aa.0 → 2.0.0--canary.397.216d54b.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/backend-utils.js +24 -12
- package/handlers/routers/auth.js +1 -7
- package/handlers/routers/integration-defined-routers.js +3 -5
- package/handlers/workers/integration-defined-workers.js +5 -6
- package/index.js +0 -4
- package/integrations/index.js +0 -2
- package/integrations/integration-router.js +105 -176
- package/integrations/integration.js +51 -4
- package/integrations/use-cases/create-integration.js +20 -10
- package/integrations/use-cases/delete-integration-for-user.js +29 -5
- package/integrations/use-cases/get-integration-instance.js +73 -0
- package/integrations/use-cases/get-integrations-for-user.js +1 -1
- package/integrations/use-cases/{get-integration.js → update-integration.js} +12 -13
- package/integrations/utils/map-integration-dto.js +16 -1
- package/module-plugin/index.js +0 -2
- package/module-plugin/module-repository.js +13 -2
- package/module-plugin/module.js +10 -18
- package/module-plugin/use-cases/get-entity-options-by-id.js +58 -0
- package/module-plugin/use-cases/get-entity-options-by-type.js +34 -0
- package/module-plugin/use-cases/get-module-instance-from-type.js +31 -0
- package/module-plugin/use-cases/get-module.js +56 -0
- package/module-plugin/use-cases/refresh-entity-options.js +58 -0
- package/module-plugin/use-cases/test-module-auth.js +54 -0
- package/package.json +5 -5
- package/integrations/integration-factory.js +0 -195
- package/module-plugin/module-factory.js +0 -42
|
@@ -1,28 +1,52 @@
|
|
|
1
1
|
const Boom = require('@hapi/boom');
|
|
2
2
|
|
|
3
3
|
class DeleteIntegrationForUser {
|
|
4
|
-
constructor({ integrationRepository }) {
|
|
4
|
+
constructor({ integrationRepository, integrationClasses }) {
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* @type {import('../integration-repository').IntegrationRepository}
|
|
8
8
|
*/
|
|
9
9
|
this.integrationRepository = integrationRepository;
|
|
10
|
+
this.integrationClasses = integrationClasses;
|
|
10
11
|
}
|
|
11
12
|
|
|
12
13
|
async execute(integrationId, userId) {
|
|
13
|
-
const
|
|
14
|
+
const integrationRecord = await this.integrationRepository.findIntegrationById(integrationId);
|
|
14
15
|
|
|
15
|
-
if (!
|
|
16
|
+
if (!integrationRecord) {
|
|
16
17
|
throw Boom.notFound(
|
|
17
18
|
`Integration with id of ${integrationId} does not exist`
|
|
18
19
|
);
|
|
19
20
|
}
|
|
20
21
|
|
|
21
|
-
|
|
22
|
-
|
|
22
|
+
const integrationClass = this.integrationClasses.find(
|
|
23
|
+
(integrationClass) => integrationClass.Definition.name === integrationRecord.config.type
|
|
24
|
+
);
|
|
25
|
+
|
|
26
|
+
if (integrationRecord.userId !== userId) {
|
|
27
|
+
throw new Error(
|
|
28
|
+
`Integration ${integrationId} does not belong to User ${userId}`
|
|
29
|
+
);
|
|
23
30
|
}
|
|
24
31
|
|
|
32
|
+
const integrationInstance = new Integration({
|
|
33
|
+
id: integrationRecord.id,
|
|
34
|
+
userId: integrationRecord.userId,
|
|
35
|
+
entities: integrationRecord.entitiesIds,
|
|
36
|
+
config: integrationRecord.config,
|
|
37
|
+
status: integrationRecord.status,
|
|
38
|
+
version: integrationRecord.version,
|
|
39
|
+
messages: integrationRecord.messages,
|
|
40
|
+
integrationClass: integrationClass,
|
|
41
|
+
modules: [],
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
// 6. Complete async initialization (load dynamic actions, register handlers)
|
|
45
|
+
await integrationInstance.initialize();
|
|
46
|
+
await integrationInstance.send('ON_DELETE');
|
|
47
|
+
|
|
25
48
|
await this.integrationRepository.deleteIntegrationById(integrationId);
|
|
49
|
+
|
|
26
50
|
}
|
|
27
51
|
}
|
|
28
52
|
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
const { Integration } = require('../integration');
|
|
2
|
+
|
|
3
|
+
class GetIntegrationInstance {
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* @class GetIntegrationInstance
|
|
7
|
+
* @description Use case for retrieving a single integration instance by ID and user.
|
|
8
|
+
* @param {Object} params
|
|
9
|
+
* @param {import('../integration-repository').IntegrationRepository} params.integrationRepository - Repository for integration data access
|
|
10
|
+
* @param {Array<import('../integration').Integration>} params.integrationClasses - Array of available integration classes
|
|
11
|
+
* @param {import('../module-plugin/module-service').ModuleService} params.moduleService - Service for module instantiation and management
|
|
12
|
+
*/
|
|
13
|
+
constructor({
|
|
14
|
+
integrationRepository,
|
|
15
|
+
integrationClasses,
|
|
16
|
+
moduleService,
|
|
17
|
+
}) {
|
|
18
|
+
this.integrationRepository = integrationRepository;
|
|
19
|
+
this.integrationClasses = integrationClasses;
|
|
20
|
+
this.moduleService = moduleService;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
async execute(integrationId, userId) {
|
|
24
|
+
const integrationRecord = await this.integrationRepository.findIntegrationById(integrationId);
|
|
25
|
+
|
|
26
|
+
if (!integrationRecord) {
|
|
27
|
+
throw new Error(`No integration found by the ID of ${integrationId}`);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const integrationClass = this.integrationClasses.find(
|
|
31
|
+
(integrationClass) => integrationClass.Definition.name === integrationRecord.config.type
|
|
32
|
+
);
|
|
33
|
+
|
|
34
|
+
if (!integrationClass) {
|
|
35
|
+
throw new Error(`No integration class found for type: ${integrationRecord.config.type}`);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
if (integrationRecord.userId !== userId) {
|
|
39
|
+
throw new Error(
|
|
40
|
+
`Integration ${integrationId} does not belong to User ${userId}`
|
|
41
|
+
);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
const modules = [];
|
|
46
|
+
for (const entityId of integrationRecord.entitiesIds) {
|
|
47
|
+
const moduleInstance = await this.moduleService.getModuleInstance(
|
|
48
|
+
entityId,
|
|
49
|
+
integrationRecord.userId
|
|
50
|
+
);
|
|
51
|
+
modules.push(moduleInstance);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const integrationInstance = new Integration({
|
|
55
|
+
id: integrationRecord.id,
|
|
56
|
+
userId: integrationRecord.userId,
|
|
57
|
+
entities: integrationRecord.entitiesIds,
|
|
58
|
+
config: integrationRecord.config,
|
|
59
|
+
status: integrationRecord.status,
|
|
60
|
+
version: integrationRecord.version,
|
|
61
|
+
messages: integrationRecord.messages,
|
|
62
|
+
integrationClass: integrationClass,
|
|
63
|
+
modules
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
await integrationInstance.initialize();
|
|
68
|
+
|
|
69
|
+
return integrationInstance;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
module.exports = { GetIntegrationInstance };
|
|
@@ -2,12 +2,11 @@ const { Integration } = require('../integration');
|
|
|
2
2
|
const { mapIntegrationClassToIntegrationDTO } = require('../utils/map-integration-dto');
|
|
3
3
|
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
class GetIntegration {
|
|
5
|
+
class UpdateIntegration {
|
|
7
6
|
|
|
8
7
|
/**
|
|
9
|
-
* @class
|
|
10
|
-
* @description Use case for
|
|
8
|
+
* @class UpdateIntegration
|
|
9
|
+
* @description Use case for updating a single integration by ID and user.
|
|
11
10
|
* @param {Object} params
|
|
12
11
|
* @param {import('../integration-repository').IntegrationRepository} params.integrationRepository - Repository for integration data access
|
|
13
12
|
* @param {Array<import('../integration').Integration>} params.integrationClasses - Array of available integration classes
|
|
@@ -23,7 +22,7 @@ class GetIntegration {
|
|
|
23
22
|
this.moduleService = moduleService;
|
|
24
23
|
}
|
|
25
24
|
|
|
26
|
-
async execute(integrationId, userId) {
|
|
25
|
+
async execute(integrationId, userId, config) {
|
|
27
26
|
// 1. Get integration record from repository
|
|
28
27
|
const integrationRecord = await this.integrationRepository.findIntegrationById(integrationId);
|
|
29
28
|
|
|
@@ -31,6 +30,11 @@ class GetIntegration {
|
|
|
31
30
|
throw new Error(`No integration found by the ID of ${integrationId}`);
|
|
32
31
|
}
|
|
33
32
|
|
|
33
|
+
// 2. Get the correct Integration class by type
|
|
34
|
+
const integrationClass = this.integrationClasses.find(
|
|
35
|
+
(integrationClass) => integrationClass.Definition.name === integrationRecord.config.type
|
|
36
|
+
);
|
|
37
|
+
|
|
34
38
|
if (!integrationClass) {
|
|
35
39
|
throw new Error(`No integration class found for type: ${integrationRecord.config.type}`);
|
|
36
40
|
}
|
|
@@ -41,11 +45,6 @@ class GetIntegration {
|
|
|
41
45
|
);
|
|
42
46
|
}
|
|
43
47
|
|
|
44
|
-
// 2. Get the correct Integration class by type
|
|
45
|
-
const integrationClass = this.integrationClasses.find(
|
|
46
|
-
(integrationClass) => integrationClass.Definition.name === integrationRecord.config.type
|
|
47
|
-
);
|
|
48
|
-
|
|
49
48
|
|
|
50
49
|
// 3. Load modules based on entity references
|
|
51
50
|
const modules = [];
|
|
@@ -59,14 +58,13 @@ class GetIntegration {
|
|
|
59
58
|
|
|
60
59
|
// 4. Create the Integration domain entity with modules
|
|
61
60
|
const integrationInstance = new Integration({
|
|
62
|
-
id: integrationRecord.
|
|
61
|
+
id: integrationRecord.id,
|
|
63
62
|
userId: integrationRecord.userId,
|
|
64
63
|
entities: integrationRecord.entitiesIds,
|
|
65
64
|
config: integrationRecord.config,
|
|
66
65
|
status: integrationRecord.status,
|
|
67
66
|
version: integrationRecord.version,
|
|
68
67
|
messages: integrationRecord.messages,
|
|
69
|
-
entityReference: integrationRecord.entityReference,
|
|
70
68
|
integrationClass: integrationClass,
|
|
71
69
|
modules
|
|
72
70
|
});
|
|
@@ -74,9 +72,10 @@ class GetIntegration {
|
|
|
74
72
|
|
|
75
73
|
// 6. Complete async initialization (load dynamic actions, register handlers)
|
|
76
74
|
await integrationInstance.initialize();
|
|
75
|
+
await integrationInstance.send('ON_UPDATE', { config });
|
|
77
76
|
|
|
78
77
|
return mapIntegrationClassToIntegrationDTO(integrationInstance);
|
|
79
78
|
}
|
|
80
79
|
}
|
|
81
80
|
|
|
82
|
-
module.exports = {
|
|
81
|
+
module.exports = { UpdateIntegration };
|
|
@@ -19,4 +19,19 @@ function mapIntegrationClassToIntegrationDTO(integration) {
|
|
|
19
19
|
};
|
|
20
20
|
}
|
|
21
21
|
|
|
22
|
-
|
|
22
|
+
|
|
23
|
+
const getModulesDefinitionFromIntegrationClasses = (integrationClasses) => {
|
|
24
|
+
return [
|
|
25
|
+
...new Set(
|
|
26
|
+
integrationClasses
|
|
27
|
+
.map((integration) =>
|
|
28
|
+
Object.values(integration.Definition.modules).map(
|
|
29
|
+
(module) => module.definition
|
|
30
|
+
)
|
|
31
|
+
)
|
|
32
|
+
.flat()
|
|
33
|
+
),
|
|
34
|
+
];
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
module.exports = { mapIntegrationClassToIntegrationDTO, getModulesDefinitionFromIntegrationClasses };
|
package/module-plugin/index.js
CHANGED
|
@@ -6,7 +6,6 @@ const { BasicAuthRequester } = require('./requester/basic');
|
|
|
6
6
|
const { OAuth2Requester } = require('./requester/oauth-2');
|
|
7
7
|
const { Requester } = require('./requester/requester');
|
|
8
8
|
const { ModuleConstants } = require('./ModuleConstants');
|
|
9
|
-
const { ModuleFactory } = require('./module-factory');
|
|
10
9
|
|
|
11
10
|
module.exports = {
|
|
12
11
|
Credential,
|
|
@@ -17,5 +16,4 @@ module.exports = {
|
|
|
17
16
|
OAuth2Requester,
|
|
18
17
|
Requester,
|
|
19
18
|
ModuleConstants,
|
|
20
|
-
ModuleFactory,
|
|
21
19
|
};
|
|
@@ -48,11 +48,22 @@ class ModuleRepository {
|
|
|
48
48
|
}
|
|
49
49
|
|
|
50
50
|
async findEntitiesByIds(entityIds) {
|
|
51
|
-
|
|
51
|
+
const entities = await Entity.find(
|
|
52
52
|
{ _id: { $in: entityIds } },
|
|
53
|
-
'
|
|
53
|
+
'',
|
|
54
54
|
{ lean: true }
|
|
55
55
|
);
|
|
56
|
+
|
|
57
|
+
return entities.map(e => ({
|
|
58
|
+
id: e._id.toString(),
|
|
59
|
+
accountId: e.accountId,
|
|
60
|
+
credentialId: e.credential.toString(),
|
|
61
|
+
userId: e.user.toString(),
|
|
62
|
+
name: e.name,
|
|
63
|
+
externalId: e.externalId,
|
|
64
|
+
type: e.__t,
|
|
65
|
+
moduleName: e.moduleName,
|
|
66
|
+
}));
|
|
56
67
|
}
|
|
57
68
|
}
|
|
58
69
|
|
package/module-plugin/module.js
CHANGED
|
@@ -9,6 +9,7 @@ const { ModuleConstants } = require('./ModuleConstants');
|
|
|
9
9
|
|
|
10
10
|
class Module extends Delegate {
|
|
11
11
|
|
|
12
|
+
//todo: entity should be replaced with actual entity properties
|
|
12
13
|
/**
|
|
13
14
|
*
|
|
14
15
|
* @param {Object} params
|
|
@@ -25,8 +26,6 @@ class Module extends Delegate {
|
|
|
25
26
|
this.entity = entityObj;
|
|
26
27
|
this.credential = entityObj?.credential;
|
|
27
28
|
this.definition = definition;
|
|
28
|
-
this.getEntityOptions = this.definition.getEntityOptions;
|
|
29
|
-
this.refreshEntityOptions = this.definition.refreshEntityOptions;
|
|
30
29
|
this.name = this.definition.moduleName;
|
|
31
30
|
this.modelName = this.definition.modelName;
|
|
32
31
|
this.apiClass = this.definition.API;
|
|
@@ -56,6 +55,15 @@ class Module extends Delegate {
|
|
|
56
55
|
return this.name;
|
|
57
56
|
}
|
|
58
57
|
|
|
58
|
+
getEntityOptions() {
|
|
59
|
+
return this.definition.getEntityOptions()
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
async refreshEntityOptions(options) {
|
|
63
|
+
await this.definition.refreshEntityOptions(options);
|
|
64
|
+
return this.getEntityOptions();
|
|
65
|
+
}
|
|
66
|
+
|
|
59
67
|
apiParamsFromCredential(credential) {
|
|
60
68
|
return _.pick(credential, ...this.apiPropertiesToPersist?.credential);
|
|
61
69
|
}
|
|
@@ -103,22 +111,6 @@ class Module extends Delegate {
|
|
|
103
111
|
return this.CredentialModel;
|
|
104
112
|
}
|
|
105
113
|
|
|
106
|
-
// todo: remove this method from all places
|
|
107
|
-
// async getEntitiesForUserId(userId) {
|
|
108
|
-
// // Only return non-internal fields. Leverages "select" and "options" to non-excepted fields and a pure object.
|
|
109
|
-
// const list = await this.EntityModel.find(
|
|
110
|
-
// { user: userId },
|
|
111
|
-
// '-dateCreated -dateUpdated -user -credentials -credential -__t -__v',
|
|
112
|
-
// { lean: true }
|
|
113
|
-
// );
|
|
114
|
-
// console.log('getEntitiesForUserId list', list, userId);
|
|
115
|
-
// return list.map((entity) => ({
|
|
116
|
-
// id: entity._id,
|
|
117
|
-
// type: this.getName(),
|
|
118
|
-
// ...entity,
|
|
119
|
-
// }));
|
|
120
|
-
// }
|
|
121
|
-
|
|
122
114
|
async validateAuthorizationRequirements() {
|
|
123
115
|
const requirements = await this.getAuthorizationRequirements();
|
|
124
116
|
let valid = true;
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
const { Module } = require('../module');
|
|
2
|
+
|
|
3
|
+
class GetEntityOptionsById {
|
|
4
|
+
/**
|
|
5
|
+
* @param {Object} params
|
|
6
|
+
* @param {import('../module-repository').ModuleRepository} params.moduleRepository
|
|
7
|
+
* @param {} params.moduleDefinitions
|
|
8
|
+
*/
|
|
9
|
+
constructor({ moduleRepository, moduleDefinitions }) {
|
|
10
|
+
this.moduleRepository = moduleRepository;
|
|
11
|
+
this.moduleDefinitions = moduleDefinitions;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Retrieve a Module instance for a given user and entity/module type.
|
|
16
|
+
* @param {string} userId
|
|
17
|
+
* @param {string} entityId
|
|
18
|
+
*/
|
|
19
|
+
async execute(entityId, userId) {
|
|
20
|
+
const entity = await this.moduleRepository.findEntityById(
|
|
21
|
+
entityId,
|
|
22
|
+
userId
|
|
23
|
+
);
|
|
24
|
+
|
|
25
|
+
if (!entity) {
|
|
26
|
+
throw new Error(`Entity ${entityId} not found`);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
if (entity.userId !== userId) {
|
|
30
|
+
throw new Error(
|
|
31
|
+
`Entity ${entityId} does not belong to user ${userId}`
|
|
32
|
+
);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const entityType = entity.type;
|
|
36
|
+
const moduleDefinition = this.moduleDefinitions.find((def) => {
|
|
37
|
+
const modelName = Module.getEntityModelFromDefinition(def).modelName;
|
|
38
|
+
return entityType === modelName;
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
if (!moduleDefinition) {
|
|
42
|
+
throw new Error(
|
|
43
|
+
`Module definition not found for entity type: ${entityType}`
|
|
44
|
+
);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const module = new Module({
|
|
48
|
+
userId,
|
|
49
|
+
entity,
|
|
50
|
+
definition: moduleDefinition,
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
const entityOptions = await module.getEntityOptions();
|
|
54
|
+
return entityOptions;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
module.exports = { GetEntityOptionsById };
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
const { Module } = require('../module');
|
|
2
|
+
|
|
3
|
+
class GetEntityOptionsByType {
|
|
4
|
+
/**
|
|
5
|
+
* @param {Object} params
|
|
6
|
+
* @param {} params.moduleDefinitions
|
|
7
|
+
*/
|
|
8
|
+
constructor({ moduleDefinitions }) {
|
|
9
|
+
this.moduleDefinitions = moduleDefinitions;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Retrieve a Module instance for a given user and entity/module type.
|
|
14
|
+
* @param {string} userId
|
|
15
|
+
* @param {string} type – human-readable module/entity type (e.g. "Hubspot")
|
|
16
|
+
*/
|
|
17
|
+
async execute(userId, type) {
|
|
18
|
+
const moduleDefinition = this.moduleDefinitions.find(
|
|
19
|
+
(def) => def.getName() === type
|
|
20
|
+
);
|
|
21
|
+
if (!moduleDefinition) {
|
|
22
|
+
throw new Error(`Module definition not found for type: ${type}`);
|
|
23
|
+
}
|
|
24
|
+
const moduleInstance = new Module({
|
|
25
|
+
userId,
|
|
26
|
+
definition: moduleDefinition,
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
const entityOptions = await moduleInstance.getEntityOptions();
|
|
30
|
+
return entityOptions;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
module.exports = { GetEntityOptionsByType };
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
const { Module } = require('../module');
|
|
2
|
+
|
|
3
|
+
class GetModuleInstanceFromType {
|
|
4
|
+
/**
|
|
5
|
+
* @param {Object} params
|
|
6
|
+
* @param {} params.moduleDefinitions
|
|
7
|
+
*/
|
|
8
|
+
constructor({ moduleDefinitions }) {
|
|
9
|
+
this.moduleDefinitions = moduleDefinitions;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Retrieve a Module instance for a given user and entity/module type.
|
|
14
|
+
* @param {string} userId
|
|
15
|
+
* @param {string} type – human-readable module/entity type (e.g. "Hubspot")
|
|
16
|
+
*/
|
|
17
|
+
async execute(userId, type) {
|
|
18
|
+
const moduleDefinition = this.moduleDefinitions.find(
|
|
19
|
+
(def) => def.getName() === type
|
|
20
|
+
);
|
|
21
|
+
if (!moduleDefinition) {
|
|
22
|
+
throw new Error(`Module definition not found for type: ${type}`);
|
|
23
|
+
}
|
|
24
|
+
return new Module({
|
|
25
|
+
userId,
|
|
26
|
+
definition: moduleDefinition,
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
module.exports = { GetModuleInstanceFromType };
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
const { Module } = require('../module');
|
|
2
|
+
|
|
3
|
+
class GetModule {
|
|
4
|
+
constructor({ moduleRepository, moduleDefinitions }) {
|
|
5
|
+
this.moduleRepository = moduleRepository;
|
|
6
|
+
this.moduleDefinitions = moduleDefinitions;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
async execute(entityId, userId) {
|
|
10
|
+
const entity = await this.moduleRepository.findEntityById(
|
|
11
|
+
entityId,
|
|
12
|
+
userId
|
|
13
|
+
);
|
|
14
|
+
|
|
15
|
+
if (!entity) {
|
|
16
|
+
throw new Error(`Entity ${entityId} not found`);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
if (entity.userId !== userId) {
|
|
20
|
+
throw new Error(
|
|
21
|
+
`Entity ${entityId} does not belong to user ${userId}`
|
|
22
|
+
);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const entityType = entity.type;
|
|
26
|
+
const moduleDefinition = this.moduleDefinitions.find((def) => {
|
|
27
|
+
const modelName = Module.getEntityModelFromDefinition(def).modelName;
|
|
28
|
+
return entityType === modelName;
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
if (!moduleDefinition) {
|
|
32
|
+
throw new Error(
|
|
33
|
+
`Module definition not found for entity type: ${entityType}`
|
|
34
|
+
);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const module = new Module({
|
|
38
|
+
userId,
|
|
39
|
+
entity,
|
|
40
|
+
definition: moduleDefinition,
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
// todo: this properties should be methods in the Module class
|
|
44
|
+
return {
|
|
45
|
+
id: module.entity.id,
|
|
46
|
+
name: module.entity.name,
|
|
47
|
+
type: module.entity.moduleName,
|
|
48
|
+
moduleName: module.entity.moduleName,
|
|
49
|
+
credential: module.credential,
|
|
50
|
+
externalId: module.entity.externalId,
|
|
51
|
+
userId: module.entity.user.toString(),
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
module.exports = { GetModule };
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
const { Module } = require('../module');
|
|
2
|
+
|
|
3
|
+
class RefreshEntityOptions {
|
|
4
|
+
/**
|
|
5
|
+
* @param {Object} params
|
|
6
|
+
* @param {import('../module-repository').ModuleRepository} params.moduleRepository
|
|
7
|
+
* @param {} params.moduleDefinitions
|
|
8
|
+
*/
|
|
9
|
+
constructor({ moduleRepository, moduleDefinitions }) {
|
|
10
|
+
this.moduleRepository = moduleRepository;
|
|
11
|
+
this.moduleDefinitions = moduleDefinitions;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Retrieve a Module instance for a given user and entity/module type.
|
|
16
|
+
* @param {string} userId
|
|
17
|
+
* @param {string} entityId
|
|
18
|
+
*/
|
|
19
|
+
async execute(entityId, userId, options) {
|
|
20
|
+
const entity = await this.moduleRepository.findEntityById(
|
|
21
|
+
entityId,
|
|
22
|
+
userId
|
|
23
|
+
);
|
|
24
|
+
|
|
25
|
+
if (!entity) {
|
|
26
|
+
throw new Error(`Entity ${entityId} not found`);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
if (entity.userId !== userId) {
|
|
30
|
+
throw new Error(
|
|
31
|
+
`Entity ${entityId} does not belong to user ${userId}`
|
|
32
|
+
);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const entityType = entity.type;
|
|
36
|
+
const moduleDefinition = this.moduleDefinitions.find((def) => {
|
|
37
|
+
const modelName = Module.getEntityModelFromDefinition(def).modelName;
|
|
38
|
+
return entityType === modelName;
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
if (!moduleDefinition) {
|
|
42
|
+
throw new Error(
|
|
43
|
+
`Module definition not found for entity type: ${entityType}`
|
|
44
|
+
);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const module = new Module({
|
|
48
|
+
userId,
|
|
49
|
+
entity,
|
|
50
|
+
definition: moduleDefinition,
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
await module.refreshEntityOptions(options);
|
|
54
|
+
return module.getEntityOptions();
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
module.exports = { RefreshEntityOptions };
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
const { Module } = require('../module');
|
|
2
|
+
|
|
3
|
+
class TestModuleAuth {
|
|
4
|
+
/**
|
|
5
|
+
* @param {Object} params - Configuration parameters.
|
|
6
|
+
* @param {import('./module-repository').ModuleRepository} params.moduleRepository - Repository for module data operations.
|
|
7
|
+
* @param {Array<Object>} params.moduleDefinitions - Array of module definitions.
|
|
8
|
+
*/
|
|
9
|
+
constructor({ moduleRepository, moduleDefinitions }) {
|
|
10
|
+
this.moduleRepository = moduleRepository;
|
|
11
|
+
this.moduleDefinitions = moduleDefinitions;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
async execute(entityId, userId) {
|
|
15
|
+
const entity = await this.moduleRepository.findEntityById(
|
|
16
|
+
entityId,
|
|
17
|
+
userId
|
|
18
|
+
);
|
|
19
|
+
|
|
20
|
+
if (!entity) {
|
|
21
|
+
throw new Error(`Entity ${entityId} not found`);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
if (entity.userId !== userId) {
|
|
25
|
+
throw new Error(
|
|
26
|
+
`Entity ${entityId} does not belong to user ${userId}`
|
|
27
|
+
);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const entityType = entity.type;
|
|
31
|
+
const moduleDefinition = this.moduleDefinitions.find((def) => {
|
|
32
|
+
const modelName = Module.getEntityModelFromDefinition(def).modelName;
|
|
33
|
+
return entityType === modelName;
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
if (!moduleDefinition) {
|
|
37
|
+
throw new Error(
|
|
38
|
+
`Module definition not found for entity type: ${entityType}`
|
|
39
|
+
);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const module = new Module({
|
|
43
|
+
userId,
|
|
44
|
+
entity,
|
|
45
|
+
definition: moduleDefinition,
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
const testAuthResponse = await module.testAuth();
|
|
49
|
+
|
|
50
|
+
return testAuthResponse;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
module.exports = { TestModuleAuth };
|
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.
|
|
4
|
+
"version": "2.0.0--canary.397.216d54b.0",
|
|
5
5
|
"dependencies": {
|
|
6
6
|
"@hapi/boom": "^10.0.1",
|
|
7
7
|
"aws-sdk": "^2.1200.0",
|
|
@@ -22,9 +22,9 @@
|
|
|
22
22
|
"uuid": "^9.0.1"
|
|
23
23
|
},
|
|
24
24
|
"devDependencies": {
|
|
25
|
-
"@friggframework/eslint-config": "2.0.0--canary.
|
|
26
|
-
"@friggframework/prettier-config": "2.0.0--canary.
|
|
27
|
-
"@friggframework/test": "2.0.0--canary.
|
|
25
|
+
"@friggframework/eslint-config": "2.0.0--canary.397.216d54b.0",
|
|
26
|
+
"@friggframework/prettier-config": "2.0.0--canary.397.216d54b.0",
|
|
27
|
+
"@friggframework/test": "2.0.0--canary.397.216d54b.0",
|
|
28
28
|
"@types/lodash": "4.17.15",
|
|
29
29
|
"@typescript-eslint/eslint-plugin": "^8.0.0",
|
|
30
30
|
"chai": "^4.3.6",
|
|
@@ -53,5 +53,5 @@
|
|
|
53
53
|
},
|
|
54
54
|
"homepage": "https://github.com/friggframework/frigg#readme",
|
|
55
55
|
"description": "",
|
|
56
|
-
"gitHead": "
|
|
56
|
+
"gitHead": "216d54b42aece5fa6473620fca6ee1ae11a46d8b"
|
|
57
57
|
}
|