@friggframework/devtools 2.0.0-next.2 → 2.0.0-next.20
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/build-command/index.js +52 -0
- package/frigg-cli/deploy-command/index.js +33 -0
- package/frigg-cli/index.js +17 -1
- package/frigg-cli/index.test.js +1 -4
- package/frigg-cli/install-command/index.js +1 -4
- package/frigg-cli/start-command/index.js +8 -2
- package/infrastructure/create-frigg-infrastructure.js +1 -3
- package/infrastructure/serverless-template.js +15 -27
- package/package.json +11 -9
- package/frigg-cli/utils/backend-path.js +0 -26
- package/infrastructure/app-handler-helpers.js +0 -57
- package/infrastructure/backend-utils.js +0 -90
- package/infrastructure/routers/auth.js +0 -26
- package/infrastructure/routers/integration-defined-routers.js +0 -37
- package/infrastructure/routers/middleware/loadUser.js +0 -15
- package/infrastructure/routers/middleware/requireLoggedInUser.js +0 -12
- package/infrastructure/routers/user.js +0 -41
- package/infrastructure/routers/websocket.js +0 -55
- package/infrastructure/workers/integration-defined-workers.js +0 -24
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
const { spawnSync } = require('child_process');
|
|
2
|
+
const path = require('path');
|
|
3
|
+
|
|
4
|
+
function buildCommand(options) {
|
|
5
|
+
console.log('Building the serverless application...');
|
|
6
|
+
console.log('Hello from npm link world')
|
|
7
|
+
const backendPath = path.resolve(process.cwd());
|
|
8
|
+
const infrastructurePath = 'infrastructure.js';
|
|
9
|
+
const command = 'serverless';
|
|
10
|
+
const serverlessArgs = [
|
|
11
|
+
'package',
|
|
12
|
+
'--config',
|
|
13
|
+
infrastructurePath,
|
|
14
|
+
'--stage',
|
|
15
|
+
options.stage
|
|
16
|
+
];
|
|
17
|
+
|
|
18
|
+
// Add support for --verbose option
|
|
19
|
+
if (options.verbose) {
|
|
20
|
+
serverlessArgs.push('--verbose');
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
console.log('Running command from ', backendPath);
|
|
24
|
+
console.log('Serverless Command:', command, serverlessArgs.join(' '));
|
|
25
|
+
|
|
26
|
+
const result = spawnSync(command, serverlessArgs, {
|
|
27
|
+
cwd: backendPath,
|
|
28
|
+
stdio: 'inherit',
|
|
29
|
+
shell: true,
|
|
30
|
+
env: {
|
|
31
|
+
...process.env,
|
|
32
|
+
NODE_PATH: path.resolve(backendPath, 'node_modules'),
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
if (result.status !== 0) {
|
|
37
|
+
console.error(`Serverless build failed with code ${result.status}`);
|
|
38
|
+
process.exit(1);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// childProcess.on('error', (error) => {
|
|
42
|
+
// console.error(`Error executing command: ${error.message}`);
|
|
43
|
+
// });
|
|
44
|
+
|
|
45
|
+
// childProcess.on('close', (code) => {
|
|
46
|
+
// if (code !== 0) {
|
|
47
|
+
// console.log(`Child process exited with code ${code}`);
|
|
48
|
+
// }
|
|
49
|
+
// });
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
module.exports = { buildCommand };
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
const { spawn } = require('child_process');
|
|
2
|
+
const path = require('path');
|
|
3
|
+
|
|
4
|
+
function deployCommand(options) {
|
|
5
|
+
console.log('Deploying the serverless application...');
|
|
6
|
+
const backendPath = path.resolve(process.cwd());
|
|
7
|
+
const infrastructurePath = 'infrastructure.js';
|
|
8
|
+
const command = 'serverless';
|
|
9
|
+
const serverlessArgs = [
|
|
10
|
+
'deploy',
|
|
11
|
+
'--config',
|
|
12
|
+
infrastructurePath,
|
|
13
|
+
'--stage',
|
|
14
|
+
options.stage
|
|
15
|
+
];
|
|
16
|
+
|
|
17
|
+
const childProcess = spawn(command, serverlessArgs, {
|
|
18
|
+
cwd: backendPath,
|
|
19
|
+
stdio: 'inherit',
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
childProcess.on('error', (error) => {
|
|
23
|
+
console.error(`Error executing command: ${error.message}`);
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
childProcess.on('close', (code) => {
|
|
27
|
+
if (code !== 0) {
|
|
28
|
+
console.log(`Child process exited with code ${code}`);
|
|
29
|
+
}
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
module.exports = { deployCommand };
|
package/frigg-cli/index.js
CHANGED
|
@@ -3,6 +3,8 @@
|
|
|
3
3
|
const { Command } = require('commander');
|
|
4
4
|
const { installCommand } = require('./install-command');
|
|
5
5
|
const { startCommand } = require('./start-command'); // Assuming you have a startCommand module
|
|
6
|
+
const { buildCommand } = require('./build-command');
|
|
7
|
+
const { deployCommand } = require('./deploy-command');
|
|
6
8
|
|
|
7
9
|
const program = new Command();
|
|
8
10
|
program
|
|
@@ -13,8 +15,22 @@ program
|
|
|
13
15
|
program
|
|
14
16
|
.command('start')
|
|
15
17
|
.description('Run the backend and optional frontend')
|
|
18
|
+
.option('-s, --stage <stage>', 'deployment stage', 'dev')
|
|
16
19
|
.action(startCommand);
|
|
17
20
|
|
|
21
|
+
program
|
|
22
|
+
.command('build')
|
|
23
|
+
.description('Build the serverless application')
|
|
24
|
+
.option('-s, --stage <stage>', 'deployment stage', 'dev')
|
|
25
|
+
.option('-v, --verbose', 'enable verbose output')
|
|
26
|
+
.action(buildCommand);
|
|
27
|
+
|
|
28
|
+
program
|
|
29
|
+
.command('deploy')
|
|
30
|
+
.description('Deploy the serverless application')
|
|
31
|
+
.option('-s, --stage <stage>', 'deployment stage', 'dev')
|
|
32
|
+
.action(deployCommand);
|
|
33
|
+
|
|
18
34
|
program.parse(process.argv);
|
|
19
35
|
|
|
20
|
-
module.exports = { installCommand, startCommand };
|
|
36
|
+
module.exports = { installCommand, startCommand, buildCommand, deployCommand };
|
package/frigg-cli/index.test.js
CHANGED
|
@@ -1,10 +1,7 @@
|
|
|
1
1
|
const { Command } = require('commander');
|
|
2
2
|
const { installCommand } = require('./index');
|
|
3
3
|
const { validatePackageExists } = require('./install-command/validate-package');
|
|
4
|
-
const {
|
|
5
|
-
findNearestBackendPackageJson,
|
|
6
|
-
validateBackendPath,
|
|
7
|
-
} = require('./utils/backend-path');
|
|
4
|
+
const { findNearestBackendPackageJson, validateBackendPath } = require('@friggframework/core');
|
|
8
5
|
const { installPackage } = require('./install-command/install-package');
|
|
9
6
|
const { createIntegrationFile } = require('./install-command/integration-file');
|
|
10
7
|
const { updateBackendJsFile } = require('./install-command/backend-js');
|
|
@@ -4,15 +4,12 @@ const { resolve } = require('node:path');
|
|
|
4
4
|
const { updateBackendJsFile } = require('./backend-js');
|
|
5
5
|
const { logInfo, logError } = require('./logger');
|
|
6
6
|
const { commitChanges } = require('./commit-changes');
|
|
7
|
-
const {
|
|
8
|
-
findNearestBackendPackageJson,
|
|
9
|
-
validateBackendPath,
|
|
10
|
-
} = require('../utils/backend-path');
|
|
11
7
|
const { handleEnvVariables } = require('./environment-variables');
|
|
12
8
|
const {
|
|
13
9
|
validatePackageExists,
|
|
14
10
|
searchAndSelectPackage,
|
|
15
11
|
} = require('./validate-package');
|
|
12
|
+
const { findNearestBackendPackageJson, validateBackendPath } = require('@friggframework/core');
|
|
16
13
|
|
|
17
14
|
const installCommand = async (apiModuleName) => {
|
|
18
15
|
try {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
const { spawn } = require('child_process');
|
|
2
2
|
const path = require('path');
|
|
3
3
|
|
|
4
|
-
function startCommand() {
|
|
4
|
+
function startCommand(options) {
|
|
5
5
|
console.log('Starting backend and optional frontend...');
|
|
6
6
|
// Suppress AWS SDK warning message about maintenance mode
|
|
7
7
|
process.env.AWS_SDK_JS_SUPPRESS_MAINTENANCE_MODE_MESSAGE = 1;
|
|
@@ -9,7 +9,13 @@ function startCommand() {
|
|
|
9
9
|
console.log(`Starting backend in ${backendPath}...`);
|
|
10
10
|
const infrastructurePath = 'infrastructure.js';
|
|
11
11
|
const command = 'serverless';
|
|
12
|
-
const args = [
|
|
12
|
+
const args = [
|
|
13
|
+
'offline',
|
|
14
|
+
'--config',
|
|
15
|
+
infrastructurePath,
|
|
16
|
+
'--stage',
|
|
17
|
+
options.stage
|
|
18
|
+
];
|
|
13
19
|
|
|
14
20
|
const childProcess = spawn(command, args, {
|
|
15
21
|
cwd: backendPath,
|
|
@@ -2,9 +2,7 @@ const path = require('path');
|
|
|
2
2
|
const fs = require('fs-extra');
|
|
3
3
|
const { composeServerlessDefinition } = require('./serverless-template');
|
|
4
4
|
|
|
5
|
-
const {
|
|
6
|
-
findNearestBackendPackageJson,
|
|
7
|
-
} = require('../frigg-cli/utils/backend-path');
|
|
5
|
+
const { findNearestBackendPackageJson } = require('@friggframework/core');
|
|
8
6
|
|
|
9
7
|
function createFriggInfrastructure() {
|
|
10
8
|
const backendPath = findNearestBackendPackageJson();
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
const path = require('path');
|
|
2
2
|
const fs = require('fs');
|
|
3
3
|
|
|
4
|
-
const composeServerlessDefinition = (AppDefinition
|
|
4
|
+
const composeServerlessDefinition = (AppDefinition) => {
|
|
5
5
|
const definition = {
|
|
6
6
|
frameworkVersion: '>=3.17.0',
|
|
7
7
|
service: AppDefinition.name || 'create-frigg-app',
|
|
8
8
|
package: {
|
|
9
9
|
individually: true,
|
|
10
|
+
exclude: ["!**/node_modules/aws-sdk/**", "!**/node_modules/@aws-sdk/**", "!package.json"],
|
|
10
11
|
},
|
|
11
12
|
useDotenv: true,
|
|
12
13
|
provider: {
|
|
@@ -30,6 +31,7 @@ const composeServerlessDefinition = (AppDefinition, IntegrationFactory) => {
|
|
|
30
31
|
],
|
|
31
32
|
},
|
|
32
33
|
plugins: [
|
|
34
|
+
'serverless-jetpack',
|
|
33
35
|
'serverless-dotenv-plugin',
|
|
34
36
|
'serverless-offline-sqs',
|
|
35
37
|
'serverless-offline',
|
|
@@ -50,19 +52,13 @@ const composeServerlessDefinition = (AppDefinition, IntegrationFactory) => {
|
|
|
50
52
|
secretAccessKey: 'root',
|
|
51
53
|
skipCacheInvalidation: false,
|
|
52
54
|
},
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
includeModules: {
|
|
56
|
-
forceExclude: ['aws-sdk'],
|
|
57
|
-
},
|
|
58
|
-
packager: 'npm',
|
|
59
|
-
excludeFiles: ['src/**/*.test.js', 'test/'],
|
|
55
|
+
jetpack: {
|
|
56
|
+
base: '..',
|
|
60
57
|
},
|
|
61
58
|
},
|
|
62
59
|
functions: {
|
|
63
60
|
defaultWebsocket: {
|
|
64
|
-
handler:
|
|
65
|
-
'/../node_modules/@friggframework/devtools/infrastructure/routers/websocket.handler',
|
|
61
|
+
handler: 'node_modules/@friggframework/core/handlers/routers/websocket.handler',
|
|
66
62
|
events: [
|
|
67
63
|
{
|
|
68
64
|
websocket: {
|
|
@@ -82,8 +78,7 @@ const composeServerlessDefinition = (AppDefinition, IntegrationFactory) => {
|
|
|
82
78
|
],
|
|
83
79
|
},
|
|
84
80
|
auth: {
|
|
85
|
-
handler:
|
|
86
|
-
'/../node_modules/@friggframework/devtools/infrastructure/routers/auth.handler',
|
|
81
|
+
handler: 'node_modules/@friggframework/core/handlers/routers/auth.handler',
|
|
87
82
|
events: [
|
|
88
83
|
{
|
|
89
84
|
http: {
|
|
@@ -109,8 +104,7 @@ const composeServerlessDefinition = (AppDefinition, IntegrationFactory) => {
|
|
|
109
104
|
],
|
|
110
105
|
},
|
|
111
106
|
user: {
|
|
112
|
-
handler:
|
|
113
|
-
'/../node_modules/@friggframework/devtools/infrastructure/routers/user.handler',
|
|
107
|
+
handler: 'node_modules/@friggframework/core/handlers/routers/user.handler',
|
|
114
108
|
events: [
|
|
115
109
|
{
|
|
116
110
|
http: {
|
|
@@ -213,23 +207,16 @@ const composeServerlessDefinition = (AppDefinition, IntegrationFactory) => {
|
|
|
213
207
|
};
|
|
214
208
|
|
|
215
209
|
// Add integration-specific functions and resources
|
|
216
|
-
AppDefinition.integrations
|
|
210
|
+
for (const integration of AppDefinition.integrations) {
|
|
217
211
|
const integrationName = integration.Definition.name;
|
|
218
212
|
|
|
219
213
|
// Add function for the integration
|
|
220
214
|
definition.functions[integrationName] = {
|
|
221
|
-
handler:
|
|
222
|
-
// events: integration.Definition.routes.map((route) => ({
|
|
223
|
-
// http: {
|
|
224
|
-
// path: `/api/${integrationName}-integration${route.path}`,
|
|
225
|
-
// method: route.method || 'ANY',
|
|
226
|
-
// cors: true,
|
|
227
|
-
// },
|
|
228
|
-
// })),
|
|
215
|
+
handler: `node_modules/@friggframework/core/handlers/routers/integration-defined-routers.handlers.${integrationName}.handler`,
|
|
229
216
|
events: [
|
|
230
217
|
{
|
|
231
218
|
http: {
|
|
232
|
-
path: `/api/${integrationName}-integration/{proxy
|
|
219
|
+
path: `/api/${integrationName}-integration/{proxy+}`,
|
|
233
220
|
method: 'ANY',
|
|
234
221
|
cors: true,
|
|
235
222
|
},
|
|
@@ -247,6 +234,7 @@ const composeServerlessDefinition = (AppDefinition, IntegrationFactory) => {
|
|
|
247
234
|
Properties: {
|
|
248
235
|
QueueName: `\${self:custom.${queueReference}}`,
|
|
249
236
|
MessageRetentionPeriod: 60,
|
|
237
|
+
VisibilityTimeout: 1800, // 30 minutes
|
|
250
238
|
RedrivePolicy: {
|
|
251
239
|
maxReceiveCount: 1,
|
|
252
240
|
deadLetterTargetArn: {
|
|
@@ -259,7 +247,7 @@ const composeServerlessDefinition = (AppDefinition, IntegrationFactory) => {
|
|
|
259
247
|
// Add Queue Worker for the integration
|
|
260
248
|
const queueWorkerName = `${integrationName}QueueWorker`;
|
|
261
249
|
definition.functions[queueWorkerName] = {
|
|
262
|
-
handler:
|
|
250
|
+
handler: `node_modules/@friggframework/core/handlers/workers/integration-defined-workers.handlers.${integrationName}.queueWorker`,
|
|
263
251
|
reservedConcurrency: 5,
|
|
264
252
|
events: [
|
|
265
253
|
{
|
|
@@ -277,13 +265,13 @@ const composeServerlessDefinition = (AppDefinition, IntegrationFactory) => {
|
|
|
277
265
|
// Add Queue URL for the integration to the ENVironment variables
|
|
278
266
|
definition.provider.environment = {
|
|
279
267
|
...definition.provider.environment,
|
|
280
|
-
[integrationName.toUpperCase()
|
|
268
|
+
[`${integrationName.toUpperCase()}_QUEUE_URL`]: {
|
|
281
269
|
Ref: queueReference,
|
|
282
270
|
},
|
|
283
271
|
};
|
|
284
272
|
|
|
285
273
|
definition.custom[queueReference] = queueName;
|
|
286
|
-
}
|
|
274
|
+
}
|
|
287
275
|
|
|
288
276
|
return definition;
|
|
289
277
|
};
|
package/package.json
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@friggframework/devtools",
|
|
3
3
|
"prettier": "@friggframework/prettier-config",
|
|
4
|
-
"version": "2.0.0-next.
|
|
4
|
+
"version": "2.0.0-next.20",
|
|
5
5
|
"dependencies": {
|
|
6
6
|
"@babel/eslint-parser": "^7.18.9",
|
|
7
7
|
"@babel/parser": "^7.25.3",
|
|
8
8
|
"@babel/traverse": "^7.25.3",
|
|
9
|
-
"@friggframework/
|
|
10
|
-
"@
|
|
11
|
-
"@hapi/boom": "^7.4.11",
|
|
9
|
+
"@friggframework/test": "2.0.0-next.20",
|
|
10
|
+
"@hapi/boom": "^10.0.1",
|
|
12
11
|
"@inquirer/prompts": "^5.3.8",
|
|
13
12
|
"axios": "^1.7.2",
|
|
14
13
|
"body-parser": "^1.20.2",
|
|
@@ -24,16 +23,19 @@
|
|
|
24
23
|
"express": "^4.19.2",
|
|
25
24
|
"express-async-handler": "^1.2.0",
|
|
26
25
|
"fs-extra": "^11.2.0",
|
|
27
|
-
"lodash": "
|
|
26
|
+
"lodash": "4.17.21",
|
|
28
27
|
"serverless-http": "^2.7.0"
|
|
29
28
|
},
|
|
30
29
|
"devDependencies": {
|
|
31
|
-
"@friggframework/eslint-config": "2.0.0-next.
|
|
32
|
-
"@friggframework/prettier-config": "2.0.0-next.
|
|
30
|
+
"@friggframework/eslint-config": "2.0.0-next.20",
|
|
31
|
+
"@friggframework/prettier-config": "2.0.0-next.20",
|
|
32
|
+
"prettier": "^2.7.1",
|
|
33
|
+
"serverless": "3.39.0",
|
|
33
34
|
"serverless-dotenv-plugin": "^6.0.0",
|
|
35
|
+
"serverless-jetpack": "^0.11.2",
|
|
34
36
|
"serverless-offline": "^13.8.0",
|
|
35
37
|
"serverless-offline-sqs": "^8.0.0",
|
|
36
|
-
"serverless-
|
|
38
|
+
"serverless-plugin-monorepo": "^0.11.0"
|
|
37
39
|
},
|
|
38
40
|
"scripts": {
|
|
39
41
|
"lint:fix": "prettier --write --loglevel error . && eslint . --fix",
|
|
@@ -57,5 +59,5 @@
|
|
|
57
59
|
"publishConfig": {
|
|
58
60
|
"access": "public"
|
|
59
61
|
},
|
|
60
|
-
"gitHead": "
|
|
62
|
+
"gitHead": "fc1be6e5b653e9f77116226781dc1be8899de00f"
|
|
61
63
|
}
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
const fs = require('fs-extra');
|
|
2
|
-
const path = require('path');
|
|
3
|
-
const PACKAGE_JSON = 'package.json';
|
|
4
|
-
|
|
5
|
-
function findNearestBackendPackageJson() {
|
|
6
|
-
let currentDir = process.cwd();
|
|
7
|
-
while (currentDir !== path.parse(currentDir).root) {
|
|
8
|
-
const packageJsonPath = path.join(currentDir, 'backend', PACKAGE_JSON);
|
|
9
|
-
if (fs.existsSync(packageJsonPath)) {
|
|
10
|
-
return packageJsonPath;
|
|
11
|
-
}
|
|
12
|
-
currentDir = path.dirname(currentDir);
|
|
13
|
-
}
|
|
14
|
-
return null;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
function validateBackendPath(backendPath) {
|
|
18
|
-
if (!backendPath) {
|
|
19
|
-
throw new Error('Could not find a backend package.json file.');
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
module.exports = {
|
|
24
|
-
findNearestBackendPackageJson,
|
|
25
|
-
validateBackendPath,
|
|
26
|
-
};
|
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
const { createHandler, flushDebugLog } = require('@friggframework/core');
|
|
2
|
-
const express = require('express');
|
|
3
|
-
const bodyParser = require('body-parser');
|
|
4
|
-
const cors = require('cors');
|
|
5
|
-
const Boom = require('@hapi/boom');
|
|
6
|
-
const loadUserManager = require('./routers/middleware/loadUser');
|
|
7
|
-
const serverlessHttp = require('serverless-http');
|
|
8
|
-
|
|
9
|
-
const createApp = (applyMiddleware) => {
|
|
10
|
-
const app = express();
|
|
11
|
-
|
|
12
|
-
app.use(bodyParser.json({ limit: '10mb' }));
|
|
13
|
-
app.use(bodyParser.urlencoded({ extended: true }));
|
|
14
|
-
app.use(
|
|
15
|
-
cors({
|
|
16
|
-
origin: '*',
|
|
17
|
-
credentials: true,
|
|
18
|
-
})
|
|
19
|
-
);
|
|
20
|
-
|
|
21
|
-
app.use(loadUserManager);
|
|
22
|
-
|
|
23
|
-
if (applyMiddleware) applyMiddleware(app);
|
|
24
|
-
|
|
25
|
-
// Handle sending error response and logging server errors to console
|
|
26
|
-
app.use((err, req, res, next) => {
|
|
27
|
-
const boomError = err.isBoom ? err : Boom.boomify(err);
|
|
28
|
-
const {
|
|
29
|
-
output: { statusCode = 500 },
|
|
30
|
-
} = boomError;
|
|
31
|
-
|
|
32
|
-
if (statusCode >= 500) {
|
|
33
|
-
flushDebugLog(boomError);
|
|
34
|
-
res.status(statusCode).json({ error: 'Internal Server Error' });
|
|
35
|
-
} else {
|
|
36
|
-
res.status(statusCode).json({ error: err.message });
|
|
37
|
-
}
|
|
38
|
-
});
|
|
39
|
-
|
|
40
|
-
return app;
|
|
41
|
-
};
|
|
42
|
-
|
|
43
|
-
function createAppHandler(eventName, router, shouldUseDatabase = true) {
|
|
44
|
-
const app = createApp((app) => {
|
|
45
|
-
app.use(router);
|
|
46
|
-
});
|
|
47
|
-
return createHandler({
|
|
48
|
-
eventName,
|
|
49
|
-
method: serverlessHttp(app),
|
|
50
|
-
shouldUseDatabase,
|
|
51
|
-
});
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
module.exports = {
|
|
55
|
-
createApp,
|
|
56
|
-
createAppHandler,
|
|
57
|
-
};
|
|
@@ -1,90 +0,0 @@
|
|
|
1
|
-
const { createFriggBackend, Worker } = require('@friggframework/core');
|
|
2
|
-
const {
|
|
3
|
-
findNearestBackendPackageJson,
|
|
4
|
-
} = require('../frigg-cli/utils/backend-path');
|
|
5
|
-
const path = require('path');
|
|
6
|
-
const fs = require('fs-extra');
|
|
7
|
-
|
|
8
|
-
const backendPath = findNearestBackendPackageJson();
|
|
9
|
-
if (!backendPath) {
|
|
10
|
-
throw new Error('Could not find backend package.json');
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
const backendDir = path.dirname(backendPath);
|
|
14
|
-
const backendFilePath = path.join(backendDir, 'index.js');
|
|
15
|
-
if (!fs.existsSync(backendFilePath)) {
|
|
16
|
-
throw new Error('Could not find index.js');
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
const backendJsFile = require(backendFilePath);
|
|
20
|
-
const { Router } = require('express');
|
|
21
|
-
const appDefinition = backendJsFile.Definition;
|
|
22
|
-
|
|
23
|
-
const backend = createFriggBackend(appDefinition);
|
|
24
|
-
const loadRouterFromObject = (IntegrationClass, routerObject) => {
|
|
25
|
-
const router = Router();
|
|
26
|
-
const { path, method, event } = routerObject;
|
|
27
|
-
console.log(
|
|
28
|
-
`Registering ${method} ${path} for ${IntegrationClass.Definition.name}`
|
|
29
|
-
);
|
|
30
|
-
router[method.toLowerCase()](path, async (req, res, next) => {
|
|
31
|
-
try {
|
|
32
|
-
const integration = new IntegrationClass({});
|
|
33
|
-
await integration.loadModules();
|
|
34
|
-
await integration.registerEventHandlers();
|
|
35
|
-
const result = await integration.send(event, req.body);
|
|
36
|
-
res.json(result);
|
|
37
|
-
} catch (error) {
|
|
38
|
-
next(error);
|
|
39
|
-
}
|
|
40
|
-
});
|
|
41
|
-
|
|
42
|
-
return router;
|
|
43
|
-
};
|
|
44
|
-
const createQueueWorker = (integrationClass) => {
|
|
45
|
-
class QueueWorker extends Worker {
|
|
46
|
-
constructor(params) {
|
|
47
|
-
super(params);
|
|
48
|
-
}
|
|
49
|
-
async _run(params, context) {
|
|
50
|
-
try {
|
|
51
|
-
let instance;
|
|
52
|
-
if (!params.integrationId) {
|
|
53
|
-
instance = new integrationClass({});
|
|
54
|
-
await instance.loadModules();
|
|
55
|
-
// await instance.loadUserActions();
|
|
56
|
-
await instance.registerEventHandlers();
|
|
57
|
-
console.log(
|
|
58
|
-
`${params.event} for ${integrationClass.Definition.name} integration with no integrationId`
|
|
59
|
-
);
|
|
60
|
-
} else {
|
|
61
|
-
instance =
|
|
62
|
-
await integrationClass.getInstanceFromIntegrationId({
|
|
63
|
-
integrationId: params.integrationId,
|
|
64
|
-
});
|
|
65
|
-
console.log(
|
|
66
|
-
`${params.event} for ${instance.integration.config.type} of integrationId: ${params.integrationId}`
|
|
67
|
-
);
|
|
68
|
-
}
|
|
69
|
-
const res = await instance.send(params.event, {
|
|
70
|
-
data: params.data,
|
|
71
|
-
context,
|
|
72
|
-
});
|
|
73
|
-
return res;
|
|
74
|
-
} catch (error) {
|
|
75
|
-
console.error(
|
|
76
|
-
`Error in ${params.event} for ${integrationClass.Definition.name}:`,
|
|
77
|
-
error
|
|
78
|
-
);
|
|
79
|
-
throw error;
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
return QueueWorker;
|
|
84
|
-
};
|
|
85
|
-
|
|
86
|
-
module.exports = {
|
|
87
|
-
...backend,
|
|
88
|
-
loadRouterFromObject,
|
|
89
|
-
createQueueWorker,
|
|
90
|
-
};
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
const { createIntegrationRouter } = require('@friggframework/core');
|
|
2
|
-
const { createAppHandler } = require('./../app-handler-helpers');
|
|
3
|
-
const { requireLoggedInUser } = require('./middleware/requireLoggedInUser');
|
|
4
|
-
const {
|
|
5
|
-
moduleFactory,
|
|
6
|
-
integrationFactory,
|
|
7
|
-
IntegrationHelper,
|
|
8
|
-
} = require('./../backend-utils');
|
|
9
|
-
|
|
10
|
-
const router = createIntegrationRouter({
|
|
11
|
-
factory: { moduleFactory, integrationFactory, IntegrationHelper },
|
|
12
|
-
requireLoggedInUser,
|
|
13
|
-
getUserId: (req) => req.user.getUserId(),
|
|
14
|
-
});
|
|
15
|
-
|
|
16
|
-
router.route('/redirect/:appId').get((req, res) => {
|
|
17
|
-
res.redirect(
|
|
18
|
-
`${process.env.FRONTEND_URI}/redirect/${
|
|
19
|
-
req.params.appId
|
|
20
|
-
}?${new URLSearchParams(req.query)}`
|
|
21
|
-
);
|
|
22
|
-
});
|
|
23
|
-
|
|
24
|
-
const handler = createAppHandler('HTTP Event: Auth', router);
|
|
25
|
-
|
|
26
|
-
module.exports = { handler, router };
|
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
const { createIntegrationRouter } = require('@friggframework/core');
|
|
2
|
-
const { createAppHandler } = require('./../app-handler-helpers');
|
|
3
|
-
const { requireLoggedInUser } = require('./middleware/requireLoggedInUser');
|
|
4
|
-
const {
|
|
5
|
-
moduleFactory,
|
|
6
|
-
integrationFactory,
|
|
7
|
-
IntegrationHelper,
|
|
8
|
-
loadRouterFromObject,
|
|
9
|
-
} = require('./../backend-utils');
|
|
10
|
-
const { Router } = require('express');
|
|
11
|
-
|
|
12
|
-
const handlers = {};
|
|
13
|
-
integrationFactory.integrationClasses.forEach((IntegrationClass) => {
|
|
14
|
-
const router = Router();
|
|
15
|
-
const basePath = `/api/${IntegrationClass.Definition.name}-integration`;
|
|
16
|
-
IntegrationClass.Definition.routes.forEach((routeDef) => {
|
|
17
|
-
if (typeof routeDef === 'function') {
|
|
18
|
-
router.use(basePath, routeDef(IntegrationClass));
|
|
19
|
-
} else if (typeof routeDef === 'object') {
|
|
20
|
-
router.use(
|
|
21
|
-
basePath,
|
|
22
|
-
loadRouterFromObject(IntegrationClass, routeDef)
|
|
23
|
-
);
|
|
24
|
-
} else if (routeDef instanceof express.Router) {
|
|
25
|
-
router.use(basePath, routeDef);
|
|
26
|
-
}
|
|
27
|
-
});
|
|
28
|
-
|
|
29
|
-
handlers[`${IntegrationClass.Definition.name}`] = {
|
|
30
|
-
handler: createAppHandler(
|
|
31
|
-
`HTTP Event: ${IntegrationClass.Definition.name}`,
|
|
32
|
-
router
|
|
33
|
-
),
|
|
34
|
-
};
|
|
35
|
-
});
|
|
36
|
-
|
|
37
|
-
module.exports = { handlers };
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
const catchAsyncError = require('express-async-handler');
|
|
2
|
-
const { User } = require('../../backend-utils');
|
|
3
|
-
|
|
4
|
-
module.exports = catchAsyncError(async (req, res, next) => {
|
|
5
|
-
const authorizationHeader = req.headers.authorization;
|
|
6
|
-
|
|
7
|
-
if (authorizationHeader) {
|
|
8
|
-
// Removes "Bearer " and trims
|
|
9
|
-
const token = authorizationHeader.split(' ')[1].trim();
|
|
10
|
-
// Load user for later middleware/routes to use
|
|
11
|
-
req.user = await User.newUser({ token });
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
return next();
|
|
15
|
-
});
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
const Boom = require('@hapi/boom');
|
|
2
|
-
|
|
3
|
-
// CheckLoggedIn Middleware
|
|
4
|
-
const requireLoggedInUser = (req, res, next) => {
|
|
5
|
-
if (!req.user || !req.user.isLoggedIn()) {
|
|
6
|
-
throw Boom.unauthorized('Invalid Token');
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
next();
|
|
10
|
-
};
|
|
11
|
-
|
|
12
|
-
module.exports = { requireLoggedInUser };
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
const express = require('express');
|
|
2
|
-
const { createAppHandler } = require('../app-handler-helpers');
|
|
3
|
-
const { checkRequiredParams } = require('@friggframework/core');
|
|
4
|
-
const { User } = require('../backend-utils');
|
|
5
|
-
const catchAsyncError = require('express-async-handler');
|
|
6
|
-
|
|
7
|
-
const router = express();
|
|
8
|
-
|
|
9
|
-
// define the login endpoint
|
|
10
|
-
router.route('/user/login').post(
|
|
11
|
-
catchAsyncError(async (req, res) => {
|
|
12
|
-
const { username, password } = checkRequiredParams(req.body, [
|
|
13
|
-
'username',
|
|
14
|
-
'password',
|
|
15
|
-
]);
|
|
16
|
-
const user = await User.loginUser({ username, password });
|
|
17
|
-
const token = await user.createUserToken(120);
|
|
18
|
-
res.status(201);
|
|
19
|
-
res.json({ token });
|
|
20
|
-
})
|
|
21
|
-
);
|
|
22
|
-
|
|
23
|
-
router.route('/user/create').post(
|
|
24
|
-
catchAsyncError(async (req, res) => {
|
|
25
|
-
const { username, password } = checkRequiredParams(req.body, [
|
|
26
|
-
'username',
|
|
27
|
-
'password',
|
|
28
|
-
]);
|
|
29
|
-
const user = await User.createIndividualUser({
|
|
30
|
-
username,
|
|
31
|
-
password,
|
|
32
|
-
});
|
|
33
|
-
const token = await user.createUserToken(120);
|
|
34
|
-
res.status(201);
|
|
35
|
-
res.json({ token });
|
|
36
|
-
})
|
|
37
|
-
);
|
|
38
|
-
|
|
39
|
-
const handler = createAppHandler('HTTP Event: User', router);
|
|
40
|
-
|
|
41
|
-
module.exports = { handler, router };
|
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
const { createHandler } = require('@friggframework/core');
|
|
2
|
-
const { WebsocketConnection } = require('@friggframework/core');
|
|
3
|
-
|
|
4
|
-
const handleWebSocketConnection = async (event, context) => {
|
|
5
|
-
// Handle different WebSocket events
|
|
6
|
-
switch (event.requestContext.eventType) {
|
|
7
|
-
case 'CONNECT':
|
|
8
|
-
// Handle new connection
|
|
9
|
-
try {
|
|
10
|
-
const connectionId = event.requestContext.connectionId;
|
|
11
|
-
await WebsocketConnection.create({ connectionId });
|
|
12
|
-
console.log(`Stored new connection: ${connectionId}`);
|
|
13
|
-
return { statusCode: 200, body: 'Connected.' };
|
|
14
|
-
} catch (error) {
|
|
15
|
-
console.error('Error storing connection:', error);
|
|
16
|
-
return { statusCode: 500, body: 'Error connecting.' };
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
case 'DISCONNECT':
|
|
20
|
-
// Handle disconnection
|
|
21
|
-
try {
|
|
22
|
-
const connectionId = event.requestContext.connectionId;
|
|
23
|
-
await WebsocketConnection.deleteOne({ connectionId });
|
|
24
|
-
console.log(`Removed connection: ${connectionId}`);
|
|
25
|
-
return { statusCode: 200, body: 'Disconnected.' };
|
|
26
|
-
} catch (error) {
|
|
27
|
-
console.error('Error removing connection:', error);
|
|
28
|
-
return { statusCode: 500, body: 'Error disconnecting.' };
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
case 'MESSAGE':
|
|
32
|
-
// Handle incoming message
|
|
33
|
-
const message = JSON.parse(event.body);
|
|
34
|
-
console.log('Received message:', message);
|
|
35
|
-
|
|
36
|
-
// Process the message and send a response
|
|
37
|
-
const responseMessage = { message: 'Message received' };
|
|
38
|
-
return {
|
|
39
|
-
statusCode: 200,
|
|
40
|
-
body: JSON.stringify(responseMessage),
|
|
41
|
-
};
|
|
42
|
-
|
|
43
|
-
default:
|
|
44
|
-
return { statusCode: 400, body: 'Unhandled event type.' };
|
|
45
|
-
}
|
|
46
|
-
};
|
|
47
|
-
|
|
48
|
-
const handler = createHandler({
|
|
49
|
-
eventName: 'WebSocket Event',
|
|
50
|
-
method: handleWebSocketConnection,
|
|
51
|
-
shouldUseDatabase: true, // Set to true as we're using the database
|
|
52
|
-
isUserFacingResponse: true, // This is a server-to-server response
|
|
53
|
-
});
|
|
54
|
-
|
|
55
|
-
module.exports = { handler };
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
const { createHandler } = require('@friggframework/core');
|
|
2
|
-
const { integrationFactory, createQueueWorker } = require('./../backend-utils');
|
|
3
|
-
|
|
4
|
-
const handlers = {};
|
|
5
|
-
integrationFactory.integrationClasses.forEach((IntegrationClass) => {
|
|
6
|
-
const defaultQueueWorker = createQueueWorker(IntegrationClass);
|
|
7
|
-
|
|
8
|
-
handlers[`${IntegrationClass.Definition.name}`] = {
|
|
9
|
-
queueWorker: createHandler({
|
|
10
|
-
eventName: `Queue Worker for ${IntegrationClass.Definition.name}`,
|
|
11
|
-
isUserFacingResponse: false,
|
|
12
|
-
method: async (event, context) => {
|
|
13
|
-
const worker = new defaultQueueWorker();
|
|
14
|
-
await worker.run(event, context);
|
|
15
|
-
return {
|
|
16
|
-
message: 'Successfully processed the Generic Queue Worker',
|
|
17
|
-
input: event,
|
|
18
|
-
};
|
|
19
|
-
},
|
|
20
|
-
}),
|
|
21
|
-
};
|
|
22
|
-
});
|
|
23
|
-
|
|
24
|
-
module.exports = { handlers };
|