Files
sveltekit-adapters/packages/adapter-appwrite/files/server.js
2024-02-18 21:46:01 -06:00

215 lines
5.6 KiB
JavaScript

// @ts-nocheck
import micro, { json as parseJson, text as parseText, send } from 'micro';
const USER_CODE_PATH = 'ENTRYPATH';
const ENTRYPOINT = 'ENTRY';
process.env['OPEN_RUNTIMES_SECRET'] = 'SECRET';
console.log(process.env['OPEN_RUNTIMES_SECRET']);
const server = micro(async (req, res) => {
const timeout = req.headers[`x-open-runtimes-timeout`] ?? '';
let safeTimeout = null;
if (timeout) {
if (isNaN(timeout) || timeout === 0) {
return send(res, 500, 'Header "x-open-runtimes-timeout" must be an integer greater than 0.');
}
safeTimeout = +timeout;
}
if (
!req.headers[`x-open-runtimes-secret`] ||
req.headers[`x-open-runtimes-secret`] !== (process.env['OPEN_RUNTIMES_SECRET'] ?? '')
) {
return send(res, 500, 'Unauthorized. Provide correct "x-open-runtimes-secret" header.');
}
const logs = [];
const errors = [];
const contentType = req.headers['content-type'] ?? 'text/plain';
const bodyRaw = await parseText(req);
let body = bodyRaw;
if (contentType.includes('application/json')) {
body = await parseJson(req);
}
const headers = {};
Object.keys(req.headers)
.filter((header) => !header.toLowerCase().startsWith('x-open-runtimes-'))
.forEach((header) => {
headers[header.toLowerCase()] = req.headers[header];
});
const scheme = req.headers['x-forwarded-proto'] ?? 'http';
const defaultPort = scheme === 'https' ? '443' : '80';
const host = req.headers['host'].includes(':')
? req.headers['host'].split(':')[0]
: req.headers['host'];
const port = +(req.headers['host'].includes(':')
? req.headers['host'].split(':')[1]
: defaultPort);
const path = req.url.includes('?') ? req.url.split('?')[0] : req.url;
const queryString = req.url.includes('?') ? req.url.split('?')[1] : '';
const query = {};
for (const param of queryString.split('&')) {
let [key, ...valueArr] = param.split('=');
const value = valueArr.join('=');
if (key) {
query[key] = value ?? '';
}
}
const url = `${scheme}://${host}${port.toString() === defaultPort ? '' : `:${port}`}${path}${queryString === '' ? '' : `?${queryString}`}`;
const context = {
req: {
bodyRaw,
body,
headers,
method: req.method,
host,
scheme,
query,
queryString,
port,
url,
path
},
res: {
send: function (body, statusCode = 200, headers = {}) {
return {
body: body,
statusCode: statusCode,
headers: headers
};
},
json: function (obj, statusCode = 200, headers = {}) {
headers['content-type'] = 'application/json';
return this.send(JSON.stringify(obj), statusCode, headers);
},
empty: function () {
return this.send('', 204, {});
},
redirect: function (url, statusCode = 301, headers = {}) {
headers['location'] = url;
return this.send('', statusCode, headers);
}
},
log: function (message) {
console.log(message);
},
error: function (message) {
console.log(message);
}
};
let output = null;
async function execute() {
let userFunction;
try {
userFunction = await import(USER_CODE_PATH + '/' + ENTRYPOINT);
} catch (err) {
if (err.code === 'ERR_REQUIRE_ESM') {
userFunction = await import(USER_CODE_PATH + '/' + ENTRYPOINT);
} else {
throw err;
}
}
if (!(userFunction || userFunction.constructor || userFunction.call || userFunction.apply)) {
throw new Error('User function is not valid.');
}
if (userFunction.default) {
if (
!(
userFunction.default.constructor ||
userFunction.default.call ||
userFunction.default.apply
)
) {
throw new Error('User function is not valid.');
}
output = await userFunction.default(context);
} else {
output = await userFunction(context);
}
}
try {
if (safeTimeout !== null) {
let executed = true;
const timeoutPromise = new Promise((promiseRes) => {
setTimeout(() => {
executed = false;
promiseRes(true);
}, safeTimeout * 1000);
});
await Promise.race([execute(), timeoutPromise]);
if (!executed) {
context.error('Execution timed out.');
output = context.res.send('', 500, {});
}
} else {
await execute();
}
} catch (e) {
if (e.code === 'MODULE_NOT_FOUND') {
context.error('Could not load code file.');
}
context.error(e.stack || e);
output = context.res.send('', 500, {});
}
if (output === null || output === undefined) {
context.error(
'Return statement missing. return context.res.empty() if no response is expected.'
);
output = context.res.send('', 500, {});
}
output.body = output.body ?? '';
output.statusCode = output.statusCode ?? 200;
output.headers = output.headers ?? {};
for (const header in output.headers) {
if (header.toLowerCase().startsWith('x-open-runtimes-')) {
continue;
}
res.setHeader(header.toLowerCase(), output.headers[header]);
}
const contentTypeValue = res.getHeader('content-type') ?? 'text/plain';
if (!contentTypeValue.startsWith('multipart/') && !contentTypeValue.includes('charset=')) {
res.setHeader('content-type', contentTypeValue + '; charset=utf-8');
}
// if (customstd) {
// context.log('');
// context.log('----------------------------------------------------------------------------');
// context.log('Unsupported logs detected. Use context.log() or context.error() for logging.');
// context.log('----------------------------------------------------------------------------');
// context.log(customstd);
// context.log('----------------------------------------------------------------------------');
// }
res.setHeader('x-open-runtimes-logs', encodeURIComponent(logs.join('\n')));
res.setHeader('x-open-runtimes-errors', encodeURIComponent(errors.join('\n')));
return send(res, output.statusCode, output.body);
});
server.listen(3000);