@friggframework/devtools 2.0.0-next.0 → 2.0.0-next.2
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/frigg-cli/index.js +8 -2
- package/frigg-cli/index.test.js +87 -35
- package/frigg-cli/{environmentVariables.js → install-command/environment-variables.js} +11 -18
- package/frigg-cli/install-command/environment-variables.test.js +136 -0
- package/frigg-cli/{installCommand.js → install-command/index.js} +7 -7
- package/frigg-cli/{validatePackage.js → install-command/validate-package.js} +9 -13
- package/frigg-cli/start-command/index.js +30 -0
- package/index.js +4 -2
- package/infrastructure/app-handler-helpers.js +57 -0
- package/infrastructure/backend-utils.js +90 -0
- package/infrastructure/create-frigg-infrastructure.js +38 -0
- package/infrastructure/index.js +4 -0
- package/infrastructure/routers/auth.js +26 -0
- package/infrastructure/routers/integration-defined-routers.js +37 -0
- package/infrastructure/routers/middleware/loadUser.js +15 -0
- package/infrastructure/routers/middleware/requireLoggedInUser.js +12 -0
- package/infrastructure/routers/user.js +41 -0
- package/infrastructure/routers/websocket.js +55 -0
- package/infrastructure/serverless-template.js +291 -0
- package/infrastructure/workers/integration-defined-workers.js +24 -0
- package/package.json +18 -7
- package/test/mock-integration.js +61 -56
- package/frigg-cli/environmentVariables.test.js +0 -86
- /package/frigg-cli/{backendJs.js → install-command/backend-js.js} +0 -0
- /package/frigg-cli/{commitChanges.js → install-command/commit-changes.js} +0 -0
- /package/frigg-cli/{installPackage.js → install-command/install-package.js} +0 -0
- /package/frigg-cli/{integrationFile.js → install-command/integration-file.js} +0 -0
- /package/frigg-cli/{logger.js → install-command/logger.js} +0 -0
- /package/frigg-cli/{template.js → install-command/template.js} +0 -0
- /package/frigg-cli/{backendPath.js → utils/backend-path.js} +0 -0
package/test/mock-integration.js
CHANGED
|
@@ -1,65 +1,65 @@
|
|
|
1
|
-
const {
|
|
1
|
+
const {
|
|
2
|
+
Auther,
|
|
3
|
+
Credential,
|
|
4
|
+
Entity,
|
|
5
|
+
IntegrationFactory,
|
|
6
|
+
createObjectId,
|
|
7
|
+
} = require('@friggframework/core');
|
|
2
8
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
9
|
+
async function createMockIntegration(
|
|
10
|
+
IntegrationClass,
|
|
11
|
+
userId = null,
|
|
12
|
+
config = { type: IntegrationClass.Definition.name }
|
|
13
|
+
) {
|
|
14
|
+
const integrationFactory = new IntegrationFactory([IntegrationClass]);
|
|
6
15
|
userId = userId || createObjectId();
|
|
7
16
|
|
|
8
17
|
const insertOptions = {
|
|
9
18
|
new: true,
|
|
10
19
|
upsert: true,
|
|
11
20
|
setDefaultsOnInsert: true,
|
|
12
|
-
}
|
|
13
|
-
const user = {user: userId}
|
|
14
|
-
|
|
15
|
-
const credential = await Credential.findOneAndUpdate(
|
|
16
|
-
user,
|
|
17
|
-
{ $set: user },
|
|
18
|
-
insertOptions
|
|
19
|
-
);
|
|
20
|
-
const entity1 = await Entity.findOneAndUpdate(
|
|
21
|
-
user,
|
|
22
|
-
{
|
|
23
|
-
$set: {
|
|
24
|
-
credential: credential.id,
|
|
25
|
-
user: userId,
|
|
26
|
-
name: 'Test user',
|
|
27
|
-
externalId: '1234567890123456',
|
|
28
|
-
},
|
|
29
|
-
},
|
|
30
|
-
insertOptions
|
|
31
|
-
);
|
|
32
|
-
const entity2 = await Entity.findOneAndUpdate(
|
|
33
|
-
user,
|
|
34
|
-
{
|
|
35
|
-
$set: {
|
|
36
|
-
credential: credential.id,
|
|
37
|
-
user: userId,
|
|
38
|
-
},
|
|
39
|
-
},
|
|
40
|
-
insertOptions
|
|
41
|
-
);
|
|
21
|
+
};
|
|
22
|
+
const user = { user: userId };
|
|
42
23
|
|
|
43
|
-
const entities = [
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
await
|
|
47
|
-
|
|
48
|
-
userId,
|
|
49
|
-
|
|
24
|
+
const entities = [];
|
|
25
|
+
for (const moduleName in IntegrationClass.modules) {
|
|
26
|
+
const ModuleDef = IntegrationClass.Definition.modules[moduleName];
|
|
27
|
+
const module = await Auther.getInstance({
|
|
28
|
+
definition: ModuleDef,
|
|
29
|
+
userId: userId,
|
|
30
|
+
});
|
|
31
|
+
const credential = await module.CredentialModel.findOneAndUpdate(
|
|
32
|
+
user,
|
|
33
|
+
{ $set: user },
|
|
34
|
+
insertOptions
|
|
35
|
+
);
|
|
36
|
+
entities.push(
|
|
37
|
+
(
|
|
38
|
+
await module.EntityModel.findOneAndUpdate(
|
|
39
|
+
user,
|
|
40
|
+
{
|
|
41
|
+
$set: {
|
|
42
|
+
credential,
|
|
43
|
+
user: userId,
|
|
44
|
+
name: `Test ${moduleName}`,
|
|
45
|
+
externalId: `1234567890123456_${moduleName}`,
|
|
46
|
+
},
|
|
47
|
+
},
|
|
48
|
+
insertOptions
|
|
49
|
+
)
|
|
50
|
+
).id
|
|
50
51
|
);
|
|
52
|
+
}
|
|
51
53
|
|
|
52
|
-
integration
|
|
54
|
+
const integration = await integrationFactory.createIntegration(
|
|
55
|
+
entities,
|
|
56
|
+
userId,
|
|
57
|
+
config
|
|
58
|
+
);
|
|
53
59
|
|
|
54
|
-
|
|
55
|
-
if (Object.entries(IntegrationClassDef.modules).length <= i) break
|
|
56
|
-
const [moduleName, ModuleDef] = Object.entries(IntegrationClassDef.modules)[i];
|
|
57
|
-
const module = await Auther.getInstance({definition: ModuleDef, userId: userId})
|
|
58
|
-
module.entity = entities[i];
|
|
59
|
-
integration[moduleName] = module;
|
|
60
|
-
}
|
|
60
|
+
integration.id = integration.record._id;
|
|
61
61
|
|
|
62
|
-
return integration
|
|
62
|
+
return integration;
|
|
63
63
|
}
|
|
64
64
|
|
|
65
65
|
function createMockApiObject(jest, api = {}, mockMethodMap) {
|
|
@@ -67,17 +67,22 @@ function createMockApiObject(jest, api = {}, mockMethodMap) {
|
|
|
67
67
|
// and values which are the mock response (or implementation)
|
|
68
68
|
const clone = (data) => JSON.parse(JSON.stringify(data));
|
|
69
69
|
|
|
70
|
-
for (const [methodName, mockDataOrImplementation] of Object.entries(
|
|
70
|
+
for (const [methodName, mockDataOrImplementation] of Object.entries(
|
|
71
|
+
mockMethodMap
|
|
72
|
+
)) {
|
|
71
73
|
if (mockDataOrImplementation instanceof Function) {
|
|
72
74
|
api[methodName] = jest.fn(mockDataOrImplementation);
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
|
|
75
|
+
} else if (api[methodName]?.constructor?.name === 'AsyncFunction') {
|
|
76
|
+
api[methodName] = jest
|
|
77
|
+
.fn()
|
|
78
|
+
.mockResolvedValue(clone(mockDataOrImplementation));
|
|
76
79
|
} else {
|
|
77
|
-
api[methodName] = jest
|
|
80
|
+
api[methodName] = jest
|
|
81
|
+
.fn()
|
|
82
|
+
.mockReturnValue(clone(mockDataOrImplementation));
|
|
78
83
|
}
|
|
79
84
|
}
|
|
80
85
|
return api;
|
|
81
86
|
}
|
|
82
87
|
|
|
83
|
-
module.exports = {createMockIntegration, createMockApiObject};
|
|
88
|
+
module.exports = { createMockIntegration, createMockApiObject };
|
|
@@ -1,86 +0,0 @@
|
|
|
1
|
-
const { handleEnvVariables } = require('./environmentVariables');
|
|
2
|
-
const { logInfo } = require('./logger');
|
|
3
|
-
const inquirer = require('inquirer');
|
|
4
|
-
const fs = require('fs');
|
|
5
|
-
const dotenv = require('dotenv');
|
|
6
|
-
const { resolve } = require('node:path');
|
|
7
|
-
const { parse } = require('@babel/parser');
|
|
8
|
-
const traverse = require('@babel/traverse');
|
|
9
|
-
|
|
10
|
-
jest.mock('inquirer');
|
|
11
|
-
jest.mock('fs');
|
|
12
|
-
jest.mock('dotenv');
|
|
13
|
-
jest.mock('./logger');
|
|
14
|
-
jest.mock('@babel/parser');
|
|
15
|
-
jest.mock('@babel/traverse');
|
|
16
|
-
|
|
17
|
-
describe('handleEnvVariables', () => {
|
|
18
|
-
const backendPath = '/mock/backend/path';
|
|
19
|
-
const modulePath = '/mock/module/path';
|
|
20
|
-
|
|
21
|
-
beforeEach(() => {
|
|
22
|
-
jest.clearAllMocks();
|
|
23
|
-
fs.readFileSync.mockReturnValue(`
|
|
24
|
-
const Definition = {
|
|
25
|
-
env: {
|
|
26
|
-
client_id: process.env.GOOGLE_CALENDAR_CLIENT_ID,
|
|
27
|
-
client_secret: process.env.GOOGLE_CALENDAR_CLIENT_SECRET,
|
|
28
|
-
redirect_uri: \`\${process.env.REDIRECT_URI}/google-calendar\`,
|
|
29
|
-
scope: process.env.GOOGLE_CALENDAR_SCOPE,
|
|
30
|
-
}
|
|
31
|
-
};
|
|
32
|
-
`);
|
|
33
|
-
parse.mockReturnValue({});
|
|
34
|
-
traverse.default.mockImplementation((ast, visitor) => {
|
|
35
|
-
visitor.ObjectProperty({
|
|
36
|
-
node: {
|
|
37
|
-
key: { name: 'env' },
|
|
38
|
-
value: {
|
|
39
|
-
properties: [
|
|
40
|
-
{ key: { name: 'client_id' }, value: { type: 'MemberExpression', object: { name: 'process' }, property: { name: 'GOOGLE_CALENDAR_CLIENT_ID' } } },
|
|
41
|
-
{ key: { name: 'client_secret' }, value: { type: 'MemberExpression', object: { name: 'process' }, property: { name: 'GOOGLE_CALENDAR_CLIENT_SECRET' } } },
|
|
42
|
-
{ key: { name: 'redirect_uri' }, value: { type: 'MemberExpression', object: { name: 'process' }, property: { name: 'REDIRECT_URI' } } },
|
|
43
|
-
{ key: { name: 'scope' }, value: { type: 'MemberExpression', object: { name: 'process' }, property: { name: 'GOOGLE_CALENDAR_SCOPE' } } },
|
|
44
|
-
]
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
});
|
|
48
|
-
});
|
|
49
|
-
});
|
|
50
|
-
|
|
51
|
-
xit('should identify and handle missing environment variables', async () => {
|
|
52
|
-
const localEnvPath = resolve(backendPath, '../.env');
|
|
53
|
-
const localDevConfigPath = resolve(backendPath, '../src/configs/dev.json');
|
|
54
|
-
|
|
55
|
-
fs.existsSync.mockImplementation((path) => path === localEnvPath || path === localDevConfigPath);
|
|
56
|
-
dotenv.parse.mockReturnValue({});
|
|
57
|
-
fs.readFileSync.mockImplementation((path) => {
|
|
58
|
-
if (path === resolve(modulePath, 'index.js')) return 'mock module content';
|
|
59
|
-
if (path === localEnvPath) return '';
|
|
60
|
-
if (path === localDevConfigPath) return '{}';
|
|
61
|
-
return '';
|
|
62
|
-
});
|
|
63
|
-
|
|
64
|
-
inquirer.prompt.mockResolvedValueOnce({ addEnvVars: true })
|
|
65
|
-
.mockResolvedValueOnce({ value: 'client_id_value' })
|
|
66
|
-
.mockResolvedValueOnce({ value: 'client_secret_value' })
|
|
67
|
-
.mockResolvedValueOnce({ value: 'redirect_uri_value' })
|
|
68
|
-
.mockResolvedValueOnce({ value: 'scope_value' });
|
|
69
|
-
|
|
70
|
-
await handleEnvVariables(backendPath, modulePath);
|
|
71
|
-
|
|
72
|
-
expect(logInfo).toHaveBeenCalledWith('Searching for missing environment variables...');
|
|
73
|
-
expect(logInfo).toHaveBeenCalledWith('Missing environment variables: GOOGLE_CALENDAR_CLIENT_ID, GOOGLE_CALENDAR_CLIENT_SECRET, REDIRECT_URI, GOOGLE_CALENDAR_SCOPE');
|
|
74
|
-
expect(inquirer.prompt).toHaveBeenCalledTimes(5);
|
|
75
|
-
expect(fs.appendFileSync).toHaveBeenCalledWith(localEnvPath, '\nGOOGLE_CALENDAR_CLIENT_ID=client_id_value\nGOOGLE_CALENDAR_CLIENT_SECRET=client_secret_value\nREDIRECT_URI=redirect_uri_value\nGOOGLE_CALENDAR_SCOPE=scope_value');
|
|
76
|
-
expect(fs.writeFileSync).toHaveBeenCalledWith(
|
|
77
|
-
localDevConfigPath,
|
|
78
|
-
JSON.stringify({
|
|
79
|
-
GOOGLE_CALENDAR_CLIENT_ID: 'client_id_value',
|
|
80
|
-
GOOGLE_CALENDAR_CLIENT_SECRET: 'client_secret_value',
|
|
81
|
-
REDIRECT_URI: 'redirect_uri_value',
|
|
82
|
-
GOOGLE_CALENDAR_SCOPE: 'scope_value'
|
|
83
|
-
}, null, 2)
|
|
84
|
-
);
|
|
85
|
-
});
|
|
86
|
-
});
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|