@friggframework/core 0.1.2 → 0.2.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/{Delegate.js → delegate.js} +1 -1
- package/index.js +4 -0
- package/jest.config.js +5 -0
- package/package.json +31 -30
- package/{Worker.js → worker.js} +2 -6
- package/Requester.js +0 -153
- package/auth/ApiKeyBase.js +0 -30
- package/auth/OAuth2Base.js +0 -203
- package/managers/IntegrationConfigManager.js +0 -22
- package/managers/IntegrationManager.js +0 -328
- package/managers/Migrator.js +0 -190
- package/managers/ModuleManager.js +0 -177
- package/managers/SyncManager.js +0 -500
- package/objects/association/Association.js +0 -80
- package/objects/integration/Options.js +0 -68
- package/objects/migration/Options.js +0 -32
- package/objects/sync/Sync.js +0 -118
|
@@ -1,328 +0,0 @@
|
|
|
1
|
-
const Delegate = require('../Delegate');
|
|
2
|
-
const { Credential, Entity, Integration } = require('@friggframework/models');
|
|
3
|
-
|
|
4
|
-
class IntegrationManager extends Delegate {
|
|
5
|
-
static Config = {
|
|
6
|
-
name: 'Integration Name',
|
|
7
|
-
version: '0.0.0', // Integration Version, used for migration and storage purposes, as well as display
|
|
8
|
-
supportedVersions: [], // Eventually usable for deprecation and future test version purposes
|
|
9
|
-
|
|
10
|
-
// an array of events that are process(able) by this Integration
|
|
11
|
-
events: [],
|
|
12
|
-
};
|
|
13
|
-
|
|
14
|
-
constructor(params) {
|
|
15
|
-
super(params);
|
|
16
|
-
this.integrationMO = new Integration();
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
static getName() {
|
|
20
|
-
return this.Config.name;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
static getCurrentVersion() {
|
|
24
|
-
return this.Config.version;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
async validateConfig() {
|
|
28
|
-
const configOptions = await this.getConfigOptions();
|
|
29
|
-
const currentConfig = this.integration.config;
|
|
30
|
-
let needsConfig = false;
|
|
31
|
-
for (const option of configOptions) {
|
|
32
|
-
if (option.required) {
|
|
33
|
-
// For now, just make sure the key exists. We should add more dynamic/better validation later.
|
|
34
|
-
if (
|
|
35
|
-
!Object.prototype.hasOwnProperty.call(
|
|
36
|
-
currentConfig,
|
|
37
|
-
option.key
|
|
38
|
-
)
|
|
39
|
-
) {
|
|
40
|
-
needsConfig = true;
|
|
41
|
-
this.integration.messages.warnings.push({
|
|
42
|
-
title: 'Config Validation Error',
|
|
43
|
-
message: `Missing required field of ${option.label}`,
|
|
44
|
-
timestamp: Date.now(),
|
|
45
|
-
});
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
if (needsConfig) {
|
|
50
|
-
this.integration.status = 'NEEDS_CONFIG';
|
|
51
|
-
await this.integration.save();
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
async testAuth() {
|
|
56
|
-
let didAuthPass = true;
|
|
57
|
-
|
|
58
|
-
try {
|
|
59
|
-
await this.primaryInstance.testAuth();
|
|
60
|
-
} catch {
|
|
61
|
-
didAuthPass = false;
|
|
62
|
-
this.integration.messages.errors.push({
|
|
63
|
-
title: 'Authentication Error',
|
|
64
|
-
message: `There was an error with your ${this.primaryInstance.constructor.getName()} Entity.
|
|
65
|
-
Please reconnect/re-authenticate, or reach out to Support for assistance.`,
|
|
66
|
-
timestamp: Date.now(),
|
|
67
|
-
});
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
try {
|
|
71
|
-
await this.targetInstance.testAuth();
|
|
72
|
-
} catch {
|
|
73
|
-
didAuthPass = false;
|
|
74
|
-
this.integration.messages.errors.push({
|
|
75
|
-
title: 'Authentication Error',
|
|
76
|
-
message: `There was an error with your ${this.targetInstance.constructor.getName()} Entity.
|
|
77
|
-
Please reconnect/re-authenticate, or reach out to Support for assistance.`,
|
|
78
|
-
timestamp: Date.now(),
|
|
79
|
-
});
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
if (!didAuthPass) {
|
|
83
|
-
this.integration.status = 'ERROR';
|
|
84
|
-
this.integration.markModified('messages.error');
|
|
85
|
-
await this.integration.save();
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
static async getInstance(params) {
|
|
90
|
-
const instance = new this(params);
|
|
91
|
-
|
|
92
|
-
params.delegate = instance;
|
|
93
|
-
instance.delegateTypes.push(...this.Config.events);
|
|
94
|
-
return new this(params);
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
static getIntegrationManagerClasses(type = '') {
|
|
98
|
-
const normalizedType = type.toLowerCase();
|
|
99
|
-
const integrationManagerIndex =
|
|
100
|
-
this.integrationTypes.indexOf(normalizedType);
|
|
101
|
-
const integrationManagerClass =
|
|
102
|
-
this.integrationManagerClasses[integrationManagerIndex];
|
|
103
|
-
|
|
104
|
-
if (!integrationManagerClass) {
|
|
105
|
-
throw new Error(
|
|
106
|
-
`Could not find integration manager for type "${type}"`
|
|
107
|
-
);
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
return integrationManagerClass;
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
// Takes entities, User, and Config, and returns an Instance of the IntegrationManager
|
|
114
|
-
static async createIntegration(entities, userId, config) {
|
|
115
|
-
// verify entity ids belong to the user
|
|
116
|
-
const entityMO = new Entity();
|
|
117
|
-
|
|
118
|
-
for (const id of entities) {
|
|
119
|
-
const entity = await entityMO.get(id);
|
|
120
|
-
|
|
121
|
-
if (!entity) {
|
|
122
|
-
throw new Error(`Entity with ID ${id} does not exist.`);
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
if (entity.user.toString() !== userId.toString()) {
|
|
126
|
-
throw new Error(
|
|
127
|
-
'one or more the entities do not belong to the user'
|
|
128
|
-
);
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
// build integration
|
|
133
|
-
const integrationManagerClass = this.getIntegrationManagerClasses(
|
|
134
|
-
config.type
|
|
135
|
-
);
|
|
136
|
-
const integrationMO = new Integration();
|
|
137
|
-
const integration = await integrationMO.create({
|
|
138
|
-
entities: entities,
|
|
139
|
-
user: userId,
|
|
140
|
-
config,
|
|
141
|
-
version: integrationManagerClass.Config.version,
|
|
142
|
-
});
|
|
143
|
-
|
|
144
|
-
const instance = await integrationManagerClass.getInstance({
|
|
145
|
-
userId,
|
|
146
|
-
integrationId: integration.id,
|
|
147
|
-
});
|
|
148
|
-
instance.integration = integration;
|
|
149
|
-
instance.delegateTypes.push(...integrationManagerClass.Config.events);
|
|
150
|
-
|
|
151
|
-
// Need to get special primaryInstance because it has an extra param to pass in
|
|
152
|
-
instance.primaryInstance =
|
|
153
|
-
await this.EntityManagerClass.getEntityManagerInstanceFromEntityId(
|
|
154
|
-
instance.integration.entities[0],
|
|
155
|
-
instance.integration.user
|
|
156
|
-
);
|
|
157
|
-
// Now we can use the general ManagerGetter
|
|
158
|
-
instance.targetInstance =
|
|
159
|
-
await this.EntityManagerClass.getEntityManagerInstanceFromEntityId(
|
|
160
|
-
instance.integration.entities[1],
|
|
161
|
-
instance.integration.user
|
|
162
|
-
);
|
|
163
|
-
|
|
164
|
-
instance.delegate = instance;
|
|
165
|
-
|
|
166
|
-
return instance;
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
static async getFormattedIntegration(integration) {
|
|
170
|
-
const entityMO = new Entity();
|
|
171
|
-
const integrationObj = {
|
|
172
|
-
id: integration.id,
|
|
173
|
-
status: integration.status,
|
|
174
|
-
config: integration.config,
|
|
175
|
-
entities: [],
|
|
176
|
-
version: integration.version,
|
|
177
|
-
messages: integration.messages,
|
|
178
|
-
};
|
|
179
|
-
for (const entityId of integration.entities) {
|
|
180
|
-
// Only return non-internal fields. Leverages "select" and "options" to non-excepted fields and a pure object.
|
|
181
|
-
const entity = await entityMO.get(
|
|
182
|
-
entityId,
|
|
183
|
-
'-dateCreated -dateUpdated -user -credentials -credential -_id -__t -__v',
|
|
184
|
-
{ lean: true }
|
|
185
|
-
);
|
|
186
|
-
integrationObj.entities.push({
|
|
187
|
-
id: entityId,
|
|
188
|
-
...entity,
|
|
189
|
-
});
|
|
190
|
-
}
|
|
191
|
-
return integrationObj;
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
static async getIntegrationsForUserId(userId) {
|
|
195
|
-
const integrationMO = new Integration();
|
|
196
|
-
|
|
197
|
-
const integrationList = await integrationMO.list({ user: userId });
|
|
198
|
-
|
|
199
|
-
const entityMO = new Entity();
|
|
200
|
-
|
|
201
|
-
const responseArray = [];
|
|
202
|
-
for (const integration of integrationList) {
|
|
203
|
-
const integrationObj =
|
|
204
|
-
await IntegrationManager.getFormattedIntegration(integration);
|
|
205
|
-
responseArray.push(integrationObj);
|
|
206
|
-
}
|
|
207
|
-
return responseArray;
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
static async getIntegrationForUserById(userId, integrationId) {
|
|
211
|
-
const integrationMO = new Integration();
|
|
212
|
-
|
|
213
|
-
const integrationList = await integrationMO.list({
|
|
214
|
-
user: userId,
|
|
215
|
-
_id: integrationId,
|
|
216
|
-
});
|
|
217
|
-
|
|
218
|
-
return integrationList[0];
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
static async deleteIntegrationForUserById(userId, integrationId) {
|
|
222
|
-
const integrationMO = new Integration();
|
|
223
|
-
|
|
224
|
-
const integrationList = await integrationMO.list({
|
|
225
|
-
user: userId,
|
|
226
|
-
_id: integrationId,
|
|
227
|
-
});
|
|
228
|
-
if (integrationList.length == 1) {
|
|
229
|
-
await integrationMO.delete(integrationId);
|
|
230
|
-
} else {
|
|
231
|
-
throw new Error(
|
|
232
|
-
`Integration with id of ${integrationId} does not exist for this user`
|
|
233
|
-
);
|
|
234
|
-
}
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
static async getIntegrationById(id) {
|
|
238
|
-
const integrationMO = new Integration();
|
|
239
|
-
return await integrationMO.get(id);
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
static async getFilteredIntegrationsForUserId(userId, filter) {
|
|
243
|
-
const integrationMO = new Integration();
|
|
244
|
-
|
|
245
|
-
const integrationList = await integrationMO.list({
|
|
246
|
-
user: userId,
|
|
247
|
-
...filter,
|
|
248
|
-
});
|
|
249
|
-
|
|
250
|
-
return integrationList;
|
|
251
|
-
}
|
|
252
|
-
|
|
253
|
-
static async getCredentialById(credential_id) {
|
|
254
|
-
const credentialMO = new Credential();
|
|
255
|
-
return credentialMO.get(credential_id);
|
|
256
|
-
}
|
|
257
|
-
|
|
258
|
-
static async listCredentials(options) {
|
|
259
|
-
const credentialMO = new Credential();
|
|
260
|
-
return credentialMO.list(options);
|
|
261
|
-
}
|
|
262
|
-
|
|
263
|
-
static async getEntityById(entity_id) {
|
|
264
|
-
const entityMO = new Entity();
|
|
265
|
-
return entityMO.get(entity_id);
|
|
266
|
-
}
|
|
267
|
-
|
|
268
|
-
static async listEntities(options) {
|
|
269
|
-
const entityMO = new Entity();
|
|
270
|
-
return entityMO.list(options);
|
|
271
|
-
}
|
|
272
|
-
|
|
273
|
-
static async getInstanceFromIntegrationId(params) {
|
|
274
|
-
const { integrationId } = params;
|
|
275
|
-
const integration = await this.getIntegrationById(integrationId);
|
|
276
|
-
const userId = integration.user;
|
|
277
|
-
|
|
278
|
-
const instance = await this.getInstance({ userId, integrationId });
|
|
279
|
-
instance.integration = integration;
|
|
280
|
-
|
|
281
|
-
instance.primaryInstance =
|
|
282
|
-
await this.EntityManagerClass.getEntityManagerInstanceFromEntityId(
|
|
283
|
-
instance.integration.entities[0],
|
|
284
|
-
instance.integration.user
|
|
285
|
-
);
|
|
286
|
-
|
|
287
|
-
instance.targetInstance =
|
|
288
|
-
await this.EntityManagerClass.getEntityManagerInstanceFromEntityId(
|
|
289
|
-
instance.integration.entities[1],
|
|
290
|
-
instance.integration.user
|
|
291
|
-
);
|
|
292
|
-
|
|
293
|
-
return instance;
|
|
294
|
-
}
|
|
295
|
-
|
|
296
|
-
// Children must implement
|
|
297
|
-
async processCreate() {
|
|
298
|
-
throw new Error(
|
|
299
|
-
'processCreate method not implemented in child Manager'
|
|
300
|
-
);
|
|
301
|
-
}
|
|
302
|
-
|
|
303
|
-
async processDelete() {
|
|
304
|
-
throw new Error(
|
|
305
|
-
'processDelete method not implemented in child Manager'
|
|
306
|
-
);
|
|
307
|
-
}
|
|
308
|
-
|
|
309
|
-
async processUpdate() {
|
|
310
|
-
throw new Error(
|
|
311
|
-
'processUpdate method not implemented in child Manager'
|
|
312
|
-
);
|
|
313
|
-
}
|
|
314
|
-
|
|
315
|
-
async getConfigOptions() {
|
|
316
|
-
throw new Error(
|
|
317
|
-
'getConfigOptions method not implemented in child Manager'
|
|
318
|
-
);
|
|
319
|
-
}
|
|
320
|
-
|
|
321
|
-
async getSampleData() {
|
|
322
|
-
throw new Error(
|
|
323
|
-
'getSampleData method not implemented in child Manager'
|
|
324
|
-
);
|
|
325
|
-
}
|
|
326
|
-
}
|
|
327
|
-
|
|
328
|
-
module.exports = IntegrationManager;
|
package/managers/Migrator.js
DELETED
|
@@ -1,190 +0,0 @@
|
|
|
1
|
-
const Delegate = require('../Delegate');
|
|
2
|
-
const { Integration } = require('@friggframework/models');
|
|
3
|
-
const { get } = require('@friggframework/assertions');
|
|
4
|
-
|
|
5
|
-
class Migrator extends Delegate {
|
|
6
|
-
constructor(params) {
|
|
7
|
-
super(params);
|
|
8
|
-
this.integrationMO = new Integration();
|
|
9
|
-
this.options = [];
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
static getInstance() {
|
|
13
|
-
const instance = new this();
|
|
14
|
-
return instance;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
static getName() {
|
|
18
|
-
return this.integrationManager.getName();
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
async migrate(params) {
|
|
22
|
-
try {
|
|
23
|
-
const fromVersion = get(params, 'fromVersion', null);
|
|
24
|
-
const toVersion = get(params, 'toVersion');
|
|
25
|
-
|
|
26
|
-
console.log(
|
|
27
|
-
'Migrate called. First validating whether it can be done.'
|
|
28
|
-
);
|
|
29
|
-
if (
|
|
30
|
-
!this.integrationManager.Config.supportedVersions.some(
|
|
31
|
-
(version) => version === toVersion
|
|
32
|
-
)
|
|
33
|
-
) {
|
|
34
|
-
return this.throwException(
|
|
35
|
-
`Attempting to migrate to an unsupported version. Current supported versions are ${this.integrationManager.Config.supportedVersions.join(
|
|
36
|
-
', '
|
|
37
|
-
)}`,
|
|
38
|
-
'Migration Error'
|
|
39
|
-
);
|
|
40
|
-
}
|
|
41
|
-
const migrationOption = this.options
|
|
42
|
-
.map((val) => val.get())
|
|
43
|
-
.find(
|
|
44
|
-
(option) =>
|
|
45
|
-
option.fromVersion === fromVersion &&
|
|
46
|
-
option.toVersion === toVersion
|
|
47
|
-
);
|
|
48
|
-
if (!migrationOption)
|
|
49
|
-
return this.throwException(
|
|
50
|
-
`No migration option found for version ${fromVersion} to ${toVersion}`,
|
|
51
|
-
'Migration Error'
|
|
52
|
-
);
|
|
53
|
-
// Run all general functions
|
|
54
|
-
for (const generalFunct of migrationOption.generalFunctions) {
|
|
55
|
-
console.log('Running general functions first');
|
|
56
|
-
const res = await generalFunct();
|
|
57
|
-
console.log(res);
|
|
58
|
-
}
|
|
59
|
-
// Get all integration records based on fromVersion
|
|
60
|
-
const filter = {
|
|
61
|
-
'config.type': this.integrationManager.getName(),
|
|
62
|
-
};
|
|
63
|
-
console.log(
|
|
64
|
-
`Retrieved all ${this.integrationManager.getName()} integrations`
|
|
65
|
-
);
|
|
66
|
-
|
|
67
|
-
const integrations = await this.integrationMO.list(filter);
|
|
68
|
-
const filteredIntegrations = integrations.filter((int) => {
|
|
69
|
-
const isNotToVersion = int.version !== toVersion;
|
|
70
|
-
let isFromVersion = true;
|
|
71
|
-
if (fromVersion && fromVersion !== '*') {
|
|
72
|
-
isFromVersion = int.version === fromVersion;
|
|
73
|
-
}
|
|
74
|
-
return isNotToVersion && isFromVersion;
|
|
75
|
-
});
|
|
76
|
-
const results = {
|
|
77
|
-
integrationType: this.integrationManager.getName(),
|
|
78
|
-
totalIntegrations: integrations.length,
|
|
79
|
-
versionReport: {
|
|
80
|
-
startVersions: {},
|
|
81
|
-
endVersions: {},
|
|
82
|
-
},
|
|
83
|
-
statusReport: {
|
|
84
|
-
startStatuses: {},
|
|
85
|
-
endStatuses: {},
|
|
86
|
-
},
|
|
87
|
-
toMigrate: filteredIntegrations.length,
|
|
88
|
-
migrationResults: {
|
|
89
|
-
success: 0,
|
|
90
|
-
needsConfig: 0,
|
|
91
|
-
error: 0,
|
|
92
|
-
},
|
|
93
|
-
};
|
|
94
|
-
|
|
95
|
-
for (const integration of integrations) {
|
|
96
|
-
if (results.versionReport.startVersions[integration.version]) {
|
|
97
|
-
results.versionReport.startVersions[
|
|
98
|
-
integration.version
|
|
99
|
-
] += 1;
|
|
100
|
-
} else {
|
|
101
|
-
results.versionReport.startVersions[
|
|
102
|
-
integration.version
|
|
103
|
-
] = 1;
|
|
104
|
-
}
|
|
105
|
-
if (results.statusReport.startStatuses[integration.status]) {
|
|
106
|
-
results.statusReport.startStatuses[integration.status] += 1;
|
|
107
|
-
} else {
|
|
108
|
-
results.statusReport.startStatuses[integration.status] = 1;
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
// Instantiate the integrationManager based on integration ID, run all specific functions for each integration
|
|
113
|
-
for (const integration of filteredIntegrations) {
|
|
114
|
-
let integrationManagerInstance;
|
|
115
|
-
try {
|
|
116
|
-
integrationManagerInstance =
|
|
117
|
-
await this.integrationManager.getInstanceFromIntegrationId(
|
|
118
|
-
{
|
|
119
|
-
integrationId: integration.id,
|
|
120
|
-
userId: integration.user.id,
|
|
121
|
-
}
|
|
122
|
-
);
|
|
123
|
-
} catch (e) {
|
|
124
|
-
console.log(e);
|
|
125
|
-
}
|
|
126
|
-
// Test Auth
|
|
127
|
-
if (integrationManagerInstance) {
|
|
128
|
-
await integrationManagerInstance.testAuth();
|
|
129
|
-
|
|
130
|
-
// Run functions
|
|
131
|
-
if (
|
|
132
|
-
integrationManagerInstance.integration.status !==
|
|
133
|
-
'ERROR'
|
|
134
|
-
) {
|
|
135
|
-
for (const func of migrationOption.perIntegrationFunctions) {
|
|
136
|
-
const res = await func(integrationManagerInstance);
|
|
137
|
-
console.log(res);
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
// Validate Config
|
|
142
|
-
if (
|
|
143
|
-
integrationManagerInstance.integration.status !==
|
|
144
|
-
'ERROR'
|
|
145
|
-
) {
|
|
146
|
-
await integrationManagerInstance.validateConfig();
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
// Add to results tally
|
|
150
|
-
const currentStatus =
|
|
151
|
-
integrationManagerInstance.integration.status;
|
|
152
|
-
if (currentStatus === 'ENABLED') {
|
|
153
|
-
integrationManagerInstance.integration.version =
|
|
154
|
-
toVersion;
|
|
155
|
-
await integrationManagerInstance.integration.save();
|
|
156
|
-
results.migrationResults.success += 1;
|
|
157
|
-
}
|
|
158
|
-
if (currentStatus === 'NEEDS_CONFIG') {
|
|
159
|
-
integrationManagerInstance.integration.version =
|
|
160
|
-
toVersion;
|
|
161
|
-
await integrationManagerInstance.integration.save();
|
|
162
|
-
results.migrationResults.needsConfig += 1;
|
|
163
|
-
}
|
|
164
|
-
if (currentStatus === 'ERROR')
|
|
165
|
-
results.migrationResults.error += 1;
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
const freshRetrieve = await this.integrationMO.list(filter);
|
|
170
|
-
for (const int of freshRetrieve) {
|
|
171
|
-
if (results.versionReport.endVersions[int.version]) {
|
|
172
|
-
results.versionReport.endVersions[int.version] += 1;
|
|
173
|
-
} else {
|
|
174
|
-
results.versionReport.endVersions[int.version] = 1;
|
|
175
|
-
}
|
|
176
|
-
if (results.statusReport.endStatuses[int.status]) {
|
|
177
|
-
results.statusReport.endStatuses[int.status] += 1;
|
|
178
|
-
} else {
|
|
179
|
-
results.statusReport.endStatuses[int.status] = 1;
|
|
180
|
-
}
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
return results;
|
|
184
|
-
} catch (e) {
|
|
185
|
-
this.throwException(e.message, 'Migrate Error');
|
|
186
|
-
}
|
|
187
|
-
}
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
module.exports = Migrator;
|
|
@@ -1,177 +0,0 @@
|
|
|
1
|
-
const Delegate = require('../Delegate');
|
|
2
|
-
const { Credential, Entity } = require('@friggframework/models');
|
|
3
|
-
const { get } = require('@friggframework/assertions');
|
|
4
|
-
|
|
5
|
-
class ModuleManager extends Delegate {
|
|
6
|
-
static Entity = Entity;
|
|
7
|
-
static Credential = Credential;
|
|
8
|
-
|
|
9
|
-
constructor(params) {
|
|
10
|
-
super(params);
|
|
11
|
-
this.userId = get(params, 'userId');
|
|
12
|
-
|
|
13
|
-
this.entityMO = new this.constructor.Entity();
|
|
14
|
-
this.credentialMO = new this.constructor.Credential();
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
static getName() {
|
|
18
|
-
throw new Error('Module name is not defined');
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
static async getInstance(params) {
|
|
22
|
-
throw new Error(
|
|
23
|
-
'getInstance is not implemented. It is required for ModuleManager. '
|
|
24
|
-
);
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
static async getEntitiesForUserId(userId) {
|
|
28
|
-
const entityMO = new this.Entity();
|
|
29
|
-
// Only return non-internal fields. Leverages "select" and "options" to non-excepted fields and a pure object.
|
|
30
|
-
const list = await entityMO.list(
|
|
31
|
-
{ user: userId },
|
|
32
|
-
'-dateCreated -dateUpdated -user -credentials -credential -__t -__v',
|
|
33
|
-
{ lean: true }
|
|
34
|
-
);
|
|
35
|
-
return list.map((entity) => ({
|
|
36
|
-
id: entity._id,
|
|
37
|
-
type: this.getName(),
|
|
38
|
-
...entity,
|
|
39
|
-
}));
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
async getEntityId() {
|
|
43
|
-
const list = await this.entityMO.list({ user: this.userId });
|
|
44
|
-
if (list.length > 1) {
|
|
45
|
-
throw new Error(
|
|
46
|
-
'There should not be more than one entity associated with a user for this specific class type'
|
|
47
|
-
);
|
|
48
|
-
}
|
|
49
|
-
if (list.length == 0) {
|
|
50
|
-
return null;
|
|
51
|
-
}
|
|
52
|
-
return list[0].id;
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
async validateAuthorizationRequirements() {
|
|
56
|
-
const requirements = await this.getAuthorizationRequirements();
|
|
57
|
-
|
|
58
|
-
if (
|
|
59
|
-
(requirements.type === 'oauth1' ||
|
|
60
|
-
requirements.type === 'oauth2') &&
|
|
61
|
-
!requirements.url
|
|
62
|
-
) {
|
|
63
|
-
return false;
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
return true;
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
async getAuthorizationRequirements(params) {
|
|
70
|
-
// this function must return a dictionary with the following format
|
|
71
|
-
// node only url key is required. Data would be used for Base Authentication
|
|
72
|
-
// let returnData = {
|
|
73
|
-
// url: "callback url for the data or teh redirect url for login",
|
|
74
|
-
// type: one of the types defined in modules/Constants.js
|
|
75
|
-
// data: ["required", "fields", "we", "may", "need"]
|
|
76
|
-
// }
|
|
77
|
-
throw new Error(
|
|
78
|
-
'Authorization requirements method getAuthorizationRequirements() is not defined in the class'
|
|
79
|
-
);
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
async testAuth(params) {
|
|
83
|
-
// this function must invoke a method on the API using authentication
|
|
84
|
-
// if it fails, an exception should be thrown
|
|
85
|
-
throw new Error(
|
|
86
|
-
'Authentication test method testAuth() is not defined in the class'
|
|
87
|
-
);
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
async processAuthorizationCallback(params) {
|
|
91
|
-
// this function takes in a dictionary of callback information along with
|
|
92
|
-
// a unique user id to associate with the entity in the form of
|
|
93
|
-
// {
|
|
94
|
-
// userId: "some id",
|
|
95
|
-
// data: {}
|
|
96
|
-
// }
|
|
97
|
-
|
|
98
|
-
throw new Error(
|
|
99
|
-
'Authorization requirements method processAuthorizationCallback() is not defined in the class'
|
|
100
|
-
);
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
//----------------------------------------------------------------------------------------------------
|
|
104
|
-
// optional
|
|
105
|
-
|
|
106
|
-
async getEntityOptions() {
|
|
107
|
-
// May not be needed if the callback already creates the entity, such as in situations
|
|
108
|
-
// like HubSpot where the account is determined in the authorization flow.
|
|
109
|
-
// This should only be used in situations such as FreshBooks where the user needs to make
|
|
110
|
-
// an account decision on the front end.
|
|
111
|
-
throw new Error(
|
|
112
|
-
'Entity requirement method getEntityOptions() is not defined in the class'
|
|
113
|
-
);
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
async findOrCreateEntity(params) {
|
|
117
|
-
// May not be needed if the callback already creates the entity, such as in situations
|
|
118
|
-
// like HubSpot where the account is determined in the authorization flow.
|
|
119
|
-
// This should only be used in situations such as FreshBooks where the user needs to make
|
|
120
|
-
// an account decision on the front end.
|
|
121
|
-
throw new Error(
|
|
122
|
-
'Entity requirement method findOrCreateEntity() is not defined in the class'
|
|
123
|
-
);
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
async getAllSyncObjects(SyncClass) {
|
|
127
|
-
// takes in a Sync class and will return all objects associated with the SyncClass in an array
|
|
128
|
-
// in the form of
|
|
129
|
-
// [
|
|
130
|
-
// {...object1},{...object2}...
|
|
131
|
-
// ]
|
|
132
|
-
|
|
133
|
-
throw new Error(
|
|
134
|
-
'The method "getAllSyncObjects()" is not defined in the class'
|
|
135
|
-
);
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
async batchCreateSyncObjects(syncObjects, syncManager) {
|
|
139
|
-
// takes in an array of Sync objects that has two pieces of data that
|
|
140
|
-
// are important to the updating module:
|
|
141
|
-
// 1. obj.data -> The data mapped to the obj.keys data
|
|
142
|
-
// 2. obj.syncId -> the id of the newly created sync object in our database. You will need to update
|
|
143
|
-
// the sync object in the database with the your id associated with this data. You
|
|
144
|
-
// can do this by calling the SyncManager function updateSyncObject.
|
|
145
|
-
// [
|
|
146
|
-
// syncObject1,syncObject2, ...
|
|
147
|
-
// ]
|
|
148
|
-
|
|
149
|
-
throw new Error(
|
|
150
|
-
'The method "batchUpdateSyncObjects()" is not defined in the class'
|
|
151
|
-
);
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
async batchUpdateSyncObjects(syncObjects, syncManager) {
|
|
155
|
-
// takes in an array of Sync objects that has two pieces of data that
|
|
156
|
-
// are important to the updating module:
|
|
157
|
-
// 1. obj.data -> The data mapped to the obj.keys data
|
|
158
|
-
// 2. obj.moduleObjectIds[this.constructor.getName()] -> Indexed from the point of view of the module manager
|
|
159
|
-
// it will return a json object holding all of the keys
|
|
160
|
-
// required update this datapoint. an example would be:
|
|
161
|
-
// {companyId:12, email:"test@test.com"}
|
|
162
|
-
// [
|
|
163
|
-
// syncObject1,syncObject2, ...
|
|
164
|
-
// ]
|
|
165
|
-
|
|
166
|
-
throw new Error(
|
|
167
|
-
'The method "batchUpdateSyncObjects()" is not defined in the class'
|
|
168
|
-
);
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
async markCredentialsInvalid() {
|
|
172
|
-
this.credential.auth_is_valid = false;
|
|
173
|
-
return await this.credential.save();
|
|
174
|
-
}
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
module.exports = ModuleManager;
|