@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.
Files changed (30) hide show
  1. package/frigg-cli/index.js +8 -2
  2. package/frigg-cli/index.test.js +87 -35
  3. package/frigg-cli/{environmentVariables.js → install-command/environment-variables.js} +11 -18
  4. package/frigg-cli/install-command/environment-variables.test.js +136 -0
  5. package/frigg-cli/{installCommand.js → install-command/index.js} +7 -7
  6. package/frigg-cli/{validatePackage.js → install-command/validate-package.js} +9 -13
  7. package/frigg-cli/start-command/index.js +30 -0
  8. package/index.js +4 -2
  9. package/infrastructure/app-handler-helpers.js +57 -0
  10. package/infrastructure/backend-utils.js +90 -0
  11. package/infrastructure/create-frigg-infrastructure.js +38 -0
  12. package/infrastructure/index.js +4 -0
  13. package/infrastructure/routers/auth.js +26 -0
  14. package/infrastructure/routers/integration-defined-routers.js +37 -0
  15. package/infrastructure/routers/middleware/loadUser.js +15 -0
  16. package/infrastructure/routers/middleware/requireLoggedInUser.js +12 -0
  17. package/infrastructure/routers/user.js +41 -0
  18. package/infrastructure/routers/websocket.js +55 -0
  19. package/infrastructure/serverless-template.js +291 -0
  20. package/infrastructure/workers/integration-defined-workers.js +24 -0
  21. package/package.json +18 -7
  22. package/test/mock-integration.js +61 -56
  23. package/frigg-cli/environmentVariables.test.js +0 -86
  24. /package/frigg-cli/{backendJs.js → install-command/backend-js.js} +0 -0
  25. /package/frigg-cli/{commitChanges.js → install-command/commit-changes.js} +0 -0
  26. /package/frigg-cli/{installPackage.js → install-command/install-package.js} +0 -0
  27. /package/frigg-cli/{integrationFile.js → install-command/integration-file.js} +0 -0
  28. /package/frigg-cli/{logger.js → install-command/logger.js} +0 -0
  29. /package/frigg-cli/{template.js → install-command/template.js} +0 -0
  30. /package/frigg-cli/{backendPath.js → utils/backend-path.js} +0 -0
@@ -1,65 +1,65 @@
1
- const { Auther, Credential, Entity, IntegrationFactory, createObjectId } = require('@friggframework/core');
1
+ const {
2
+ Auther,
3
+ Credential,
4
+ Entity,
5
+ IntegrationFactory,
6
+ createObjectId,
7
+ } = require('@friggframework/core');
2
8
 
3
-
4
- async function createMockIntegration(IntegrationClassDef, userId = null, config = {},) {
5
- const integrationFactory = new IntegrationFactory([IntegrationClassDef]);
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 = [entity1, entity2]
44
-
45
- const integration =
46
- await integrationFactory.createIntegration(
47
- entities,
48
- userId,
49
- config,
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.id = integration.record._id
54
+ const integration = await integrationFactory.createIntegration(
55
+ entities,
56
+ userId,
57
+ config
58
+ );
53
59
 
54
- for (const i in entities){
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(mockMethodMap)) {
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
- else if (api[methodName]?.constructor?.name === "AsyncFunction") {
75
- api[methodName] = jest.fn().mockResolvedValue(clone(mockDataOrImplementation));
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.fn().mockReturnValue(clone(mockDataOrImplementation));
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
- });