mirror of
https://github.com/noodlapp/noodl-cloudservice.git
synced 2026-01-11 14:52:53 +01:00
chore: Split routes and add typings (#5)
This commit is contained in:
97
packages/noodl-cloudservice/package-lock.json
generated
97
packages/noodl-cloudservice/package-lock.json
generated
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "@noodl/cloudservice",
|
||||
"version": "1.0.0",
|
||||
"version": "0.2.4",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@noodl/cloudservice",
|
||||
"version": "1.0.0",
|
||||
"version": "0.2.4",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"isolated-vm": "^4.4.2",
|
||||
@@ -16,6 +16,7 @@
|
||||
"winston-mongodb": "^5.1.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/express": "^4.17.21",
|
||||
"ts-node": "^10.9.2",
|
||||
"typescript": "^5.2.2"
|
||||
}
|
||||
@@ -937,12 +938,12 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@types/express": {
|
||||
"version": "4.17.7",
|
||||
"resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.7.tgz",
|
||||
"integrity": "sha512-dCOT5lcmV/uC2J9k0rPafATeeyz+99xTt54ReX11/LObZgfzJqZNcW27zGhYyX+9iSEGXGt5qLPwRSvBZcLvtQ==",
|
||||
"version": "4.17.21",
|
||||
"resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.21.tgz",
|
||||
"integrity": "sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==",
|
||||
"dependencies": {
|
||||
"@types/body-parser": "*",
|
||||
"@types/express-serve-static-core": "*",
|
||||
"@types/express-serve-static-core": "^4.17.33",
|
||||
"@types/qs": "*",
|
||||
"@types/serve-static": "*"
|
||||
}
|
||||
@@ -975,6 +976,17 @@
|
||||
"express-unless": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/express/node_modules/@types/express-serve-static-core": {
|
||||
"version": "4.17.41",
|
||||
"resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.41.tgz",
|
||||
"integrity": "sha512-OaJ7XLaelTgrvlZD8/aa0vvvxZdUmlCn6MtWeB7TkiKW70BQLc9XEPpDLPdbo52ZhXUCrznlWdCHWxJWtdyajA==",
|
||||
"dependencies": {
|
||||
"@types/node": "*",
|
||||
"@types/qs": "*",
|
||||
"@types/range-parser": "*",
|
||||
"@types/send": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/fs-capacitor": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/fs-capacitor/-/fs-capacitor-2.0.0.tgz",
|
||||
@@ -1046,6 +1058,20 @@
|
||||
"resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.4.tgz",
|
||||
"integrity": "sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw=="
|
||||
},
|
||||
"node_modules/@types/send": {
|
||||
"version": "0.17.4",
|
||||
"resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.4.tgz",
|
||||
"integrity": "sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==",
|
||||
"dependencies": {
|
||||
"@types/mime": "^1",
|
||||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/send/node_modules/@types/mime": {
|
||||
"version": "1.3.5",
|
||||
"resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz",
|
||||
"integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w=="
|
||||
},
|
||||
"node_modules/@types/serve-static": {
|
||||
"version": "1.15.2",
|
||||
"resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.2.tgz",
|
||||
@@ -1450,6 +1476,17 @@
|
||||
"graphql": "^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/apollo-server-express/node_modules/@types/express": {
|
||||
"version": "4.17.7",
|
||||
"resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.7.tgz",
|
||||
"integrity": "sha512-dCOT5lcmV/uC2J9k0rPafATeeyz+99xTt54ReX11/LObZgfzJqZNcW27zGhYyX+9iSEGXGt5qLPwRSvBZcLvtQ==",
|
||||
"dependencies": {
|
||||
"@types/body-parser": "*",
|
||||
"@types/express-serve-static-core": "*",
|
||||
"@types/qs": "*",
|
||||
"@types/serve-static": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/apollo-server-express/node_modules/subscriptions-transport-ws": {
|
||||
"version": "0.9.19",
|
||||
"resolved": "https://registry.npmjs.org/subscriptions-transport-ws/-/subscriptions-transport-ws-0.9.19.tgz",
|
||||
@@ -7615,14 +7652,27 @@
|
||||
}
|
||||
},
|
||||
"@types/express": {
|
||||
"version": "4.17.7",
|
||||
"resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.7.tgz",
|
||||
"integrity": "sha512-dCOT5lcmV/uC2J9k0rPafATeeyz+99xTt54ReX11/LObZgfzJqZNcW27zGhYyX+9iSEGXGt5qLPwRSvBZcLvtQ==",
|
||||
"version": "4.17.21",
|
||||
"resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.21.tgz",
|
||||
"integrity": "sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==",
|
||||
"requires": {
|
||||
"@types/body-parser": "*",
|
||||
"@types/express-serve-static-core": "*",
|
||||
"@types/express-serve-static-core": "^4.17.33",
|
||||
"@types/qs": "*",
|
||||
"@types/serve-static": "*"
|
||||
},
|
||||
"dependencies": {
|
||||
"@types/express-serve-static-core": {
|
||||
"version": "4.17.41",
|
||||
"resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.41.tgz",
|
||||
"integrity": "sha512-OaJ7XLaelTgrvlZD8/aa0vvvxZdUmlCn6MtWeB7TkiKW70BQLc9XEPpDLPdbo52ZhXUCrznlWdCHWxJWtdyajA==",
|
||||
"requires": {
|
||||
"@types/node": "*",
|
||||
"@types/qs": "*",
|
||||
"@types/range-parser": "*",
|
||||
"@types/send": "*"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"@types/express-jwt": {
|
||||
@@ -7723,6 +7773,22 @@
|
||||
"resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.4.tgz",
|
||||
"integrity": "sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw=="
|
||||
},
|
||||
"@types/send": {
|
||||
"version": "0.17.4",
|
||||
"resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.4.tgz",
|
||||
"integrity": "sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==",
|
||||
"requires": {
|
||||
"@types/mime": "^1",
|
||||
"@types/node": "*"
|
||||
},
|
||||
"dependencies": {
|
||||
"@types/mime": {
|
||||
"version": "1.3.5",
|
||||
"resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz",
|
||||
"integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"@types/serve-static": {
|
||||
"version": "1.15.2",
|
||||
"resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.2.tgz",
|
||||
@@ -8042,6 +8108,17 @@
|
||||
"type-is": "^1.6.16"
|
||||
},
|
||||
"dependencies": {
|
||||
"@types/express": {
|
||||
"version": "4.17.7",
|
||||
"resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.7.tgz",
|
||||
"integrity": "sha512-dCOT5lcmV/uC2J9k0rPafATeeyz+99xTt54ReX11/LObZgfzJqZNcW27zGhYyX+9iSEGXGt5qLPwRSvBZcLvtQ==",
|
||||
"requires": {
|
||||
"@types/body-parser": "*",
|
||||
"@types/express-serve-static-core": "*",
|
||||
"@types/qs": "*",
|
||||
"@types/serve-static": "*"
|
||||
}
|
||||
},
|
||||
"subscriptions-transport-ws": {
|
||||
"version": "0.9.19",
|
||||
"resolved": "https://registry.npmjs.org/subscriptions-transport-ws/-/subscriptions-transport-ws-0.9.19.tgz",
|
||||
|
||||
@@ -25,7 +25,8 @@
|
||||
"winston-mongodb": "^5.1.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"typescript": "^5.2.2",
|
||||
"ts-node": "^10.9.2"
|
||||
"@types/express": "^4.17.21",
|
||||
"ts-node": "^10.9.2",
|
||||
"typescript": "^5.2.2"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,97 +1,14 @@
|
||||
import { NoodlParseServerOptions, createNoodlParseServer } from "./parse";
|
||||
import { executeFunction } from "./function";
|
||||
import { CFVersion, deployFunctions, getLatestVersion } from "./function-deploy";
|
||||
import { Logger } from "./logger";
|
||||
import type { Request, Response, NextFunction } from "express"
|
||||
import { NoodlParseServerOptions, NoodlParseServerResult, createNoodlParseServer } from "./parse";
|
||||
import { routeFunctions } from "./routes/functions";
|
||||
import { routeFunctionsAdmin } from "./routes/functions-admin";
|
||||
|
||||
function createMiddleware(noodlServer) {
|
||||
return async function middleware(req, res, next) {
|
||||
function createMiddleware(noodlServer: NoodlParseServerResult) {
|
||||
return async function middleware(req: Request, res: Response, next: NextFunction) {
|
||||
if (req.url.startsWith('/functions/') && req.method === 'POST') {
|
||||
try {
|
||||
const path = req.url;
|
||||
const functionId = decodeURIComponent(path.split('/')[2]);
|
||||
|
||||
if (functionId === undefined)
|
||||
return next()
|
||||
|
||||
console.log('Running cloud function ' + functionId);
|
||||
|
||||
let requestVersion = req.headers['x-noodl-cloud-version'];
|
||||
let version: CFVersion = requestVersion
|
||||
? { functionVersion: requestVersion }
|
||||
: await getLatestVersion(noodlServer.options)
|
||||
|
||||
// Execute the request
|
||||
const cfResponse = await executeFunction({
|
||||
port: noodlServer.options.port,
|
||||
appId: noodlServer.options.appId,
|
||||
masterKey: noodlServer.options.masterKey,
|
||||
version,
|
||||
logger: new Logger(noodlServer),
|
||||
headers: req.headers,
|
||||
functionId,
|
||||
body: req.body,
|
||||
timeOut: noodlServer.functionOptions.timeOut,
|
||||
memoryLimit: noodlServer.functionOptions.memoryLimit,
|
||||
})
|
||||
|
||||
if (cfResponse.headers) {
|
||||
res.status(cfResponse.statusCode)
|
||||
.set(cfResponse.headers)
|
||||
.send(cfResponse.body)
|
||||
} else {
|
||||
res.status(cfResponse.statusCode)
|
||||
.set({ 'Content-Type': 'application/json' })
|
||||
.send(cfResponse.body)
|
||||
}
|
||||
} catch (e) {
|
||||
console.log('Something went wrong when running function', e)
|
||||
res.status(400).json({
|
||||
error: "Something when wrong..."
|
||||
})
|
||||
}
|
||||
routeFunctions(noodlServer, req, res, next);
|
||||
} else if (req.url.startsWith('/functions-admin')) {
|
||||
if (req.headers['x-parse-master-key'] !== noodlServer.options.masterKey) {
|
||||
return res.status(401).json({
|
||||
message: 'Not authorized'
|
||||
})
|
||||
}
|
||||
|
||||
if (req.headers['x-parse-application-id'] !== noodlServer.options.appId) {
|
||||
return res.status(401).json({
|
||||
message: 'Not authorized'
|
||||
})
|
||||
}
|
||||
|
||||
// Deploy a new version
|
||||
if (req.method === 'POST' && req.url === "/functions-admin/deploy") {
|
||||
if (!req.body || typeof req.body.deploy !== "string" || typeof req.body.runtime !== "string") {
|
||||
return res.status(400).json({
|
||||
message: 'Must supply deploy and runtime'
|
||||
})
|
||||
}
|
||||
|
||||
console.log('Uploading deploy...')
|
||||
const { version } = await deployFunctions({
|
||||
port: noodlServer.options.port,
|
||||
appId: noodlServer.options.appId,
|
||||
masterKey: noodlServer.options.masterKey,
|
||||
runtime: req.body.runtime,
|
||||
data: req.body.deploy
|
||||
})
|
||||
|
||||
console.log('Upload completed, version: ' + version)
|
||||
res.json({
|
||||
status: 'success',
|
||||
version
|
||||
})
|
||||
} else if (req.method === 'GET' && req.url === "/functions-admin/info") {
|
||||
res.json({
|
||||
version: '1.0'
|
||||
})
|
||||
} else res.status(400).json({
|
||||
message: 'Function not supported'
|
||||
})
|
||||
|
||||
routeFunctionsAdmin(noodlServer, req, res, next);
|
||||
} else {
|
||||
next()
|
||||
}
|
||||
@@ -104,7 +21,7 @@ export function createNoodlServer(options: NoodlParseServerOptions) {
|
||||
const cfMiddleware = createMiddleware(noodlServer);
|
||||
|
||||
// Combine the Noodl Cloud Function middleware with the Parse middleware into one middleware.
|
||||
const middleware = (req: Request, res: Response, next: () => void) => {
|
||||
const middleware = (req: Request, res: Response, next: NextFunction) => {
|
||||
cfMiddleware(req, res, () => {
|
||||
noodlServer.server.app(req, res, next);
|
||||
});
|
||||
|
||||
52
packages/noodl-cloudservice/src/routes/functions-admin.ts
Normal file
52
packages/noodl-cloudservice/src/routes/functions-admin.ts
Normal file
@@ -0,0 +1,52 @@
|
||||
import type { Request, Response, NextFunction } from "express"
|
||||
import { NoodlParseServerResult } from "../parse"
|
||||
import { deployFunctions } from "../function-deploy"
|
||||
|
||||
export async function routeFunctionsAdmin(
|
||||
noodlServer: NoodlParseServerResult,
|
||||
req: Request,
|
||||
res: Response,
|
||||
_next: NextFunction
|
||||
) {
|
||||
if (req.headers['x-parse-master-key'] !== noodlServer.options.masterKey) {
|
||||
return res.status(401).json({
|
||||
message: 'Not authorized'
|
||||
})
|
||||
}
|
||||
|
||||
if (req.headers['x-parse-application-id'] !== noodlServer.options.appId) {
|
||||
return res.status(401).json({
|
||||
message: 'Not authorized'
|
||||
})
|
||||
}
|
||||
|
||||
// Deploy a new version
|
||||
if (req.method === 'POST' && req.url === "/functions-admin/deploy") {
|
||||
if (!req.body || typeof req.body.deploy !== "string" || typeof req.body.runtime !== "string") {
|
||||
return res.status(400).json({
|
||||
message: 'Must supply deploy and runtime'
|
||||
})
|
||||
}
|
||||
|
||||
console.log('Uploading deploy...')
|
||||
const { version } = await deployFunctions({
|
||||
port: noodlServer.options.port,
|
||||
appId: noodlServer.options.appId,
|
||||
masterKey: noodlServer.options.masterKey,
|
||||
runtime: req.body.runtime,
|
||||
data: req.body.deploy
|
||||
})
|
||||
|
||||
console.log('Upload completed, version: ' + version)
|
||||
res.json({
|
||||
status: 'success',
|
||||
version
|
||||
})
|
||||
} else if (req.method === 'GET' && req.url === "/functions-admin/info") {
|
||||
res.json({
|
||||
version: '1.0'
|
||||
})
|
||||
} else res.status(400).json({
|
||||
message: 'Function not supported'
|
||||
})
|
||||
}
|
||||
57
packages/noodl-cloudservice/src/routes/functions.ts
Normal file
57
packages/noodl-cloudservice/src/routes/functions.ts
Normal file
@@ -0,0 +1,57 @@
|
||||
import type { Request, Response, NextFunction } from "express"
|
||||
import { executeFunction } from "../function";
|
||||
import { CFVersion, getLatestVersion } from "../function-deploy";
|
||||
import { Logger } from "../logger";
|
||||
import { NoodlParseServerResult } from "../parse";
|
||||
|
||||
export async function routeFunctions(
|
||||
noodlServer: NoodlParseServerResult,
|
||||
req: Request,
|
||||
res: Response,
|
||||
next: NextFunction
|
||||
) {
|
||||
try {
|
||||
const path = req.url;
|
||||
const functionId = decodeURIComponent(path.split("/")[2]);
|
||||
|
||||
if (functionId === undefined) return next();
|
||||
|
||||
console.log("Running cloud function " + functionId);
|
||||
|
||||
let requestVersion = req.headers["x-noodl-cloud-version"];
|
||||
let version: CFVersion = requestVersion
|
||||
? { functionVersion: String(requestVersion) }
|
||||
: await getLatestVersion(noodlServer.options);
|
||||
|
||||
// Execute the request
|
||||
const cfResponse = await executeFunction({
|
||||
port: noodlServer.options.port,
|
||||
appId: noodlServer.options.appId,
|
||||
masterKey: noodlServer.options.masterKey,
|
||||
version,
|
||||
logger: new Logger(noodlServer),
|
||||
headers: req.headers,
|
||||
functionId,
|
||||
body: req.body,
|
||||
timeOut: noodlServer.functionOptions.timeOut,
|
||||
memoryLimit: noodlServer.functionOptions.memoryLimit,
|
||||
});
|
||||
|
||||
if (cfResponse.headers) {
|
||||
res
|
||||
.status(cfResponse.statusCode)
|
||||
.set(cfResponse.headers)
|
||||
.send(cfResponse.body);
|
||||
} else {
|
||||
res
|
||||
.status(cfResponse.statusCode)
|
||||
.set({ "Content-Type": "application/json" })
|
||||
.send(cfResponse.body);
|
||||
}
|
||||
} catch (e) {
|
||||
console.log("Something went wrong when running function", e);
|
||||
res.status(400).json({
|
||||
error: "Something when wrong...",
|
||||
});
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user