Published
Edited
Jun 17, 2022
Importers
12 stars
Insert cell
Insert cell
Insert cell
Router = require('express-router-browserify@3.0.1')
Insert cell
Insert cell
app = {
const app = Router();
// Horay! CORS middleware! As this is the first route all routes will have CORS headers added
app.use((req, res, next) => {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
next() // Let a following route actually do the response
});
app.get('/response', (req, res) => {
res.json(req);
});
app.get('/setResponseHeader/:header/:value', (req, res) => {
res.header(req.params.header, req.params.value)
res.header('Access-Control-Expose-Headers', `${req.params.header}`) // can also do '*'
res.end();
});
app.get('/throw', (req, res) => {
throw new Error("Throwing example")
});
app.get('/asyncthrow', async (req, res) => {
throw new Error("Throwing example")
});
// If nothing has done a response, we have fallen through to this middleware, which will return a default
app.use((req, res) => {
res.status(404).end();
});
return app
}
Insert cell
Insert cell
Insert cell
handleWithExpress = app => async (req, res, context) => {
req.app = app; // Note, annoying gotcha
req.context = context; // we tuck the context into the request so handlers can access e.g. secrets

// https://github.com/expressjs/express/blob/508936853a6e311099c9985d4c11a4b1b8f6af07/lib/response.js#L831
res.cookie = function(name, value, options) {
var opts = options || {};
var secret = this.req.secret;
var signed = opts.signed;

if (signed && !secret) {
throw new Error('cookieParser("secret") required for signed cookies');
}

var val =
typeof value === 'object' ? 'j:' + JSON.stringify(value) : String(value);

if (signed) {
val = 's:' + cookie_signature.sign(val, secret);
}

if ('maxAge' in opts) {
opts.expires = new Date(Date.now() + opts.maxAge);
opts.maxAge /= 1000;
}

if (opts.path == null) {
opts.path = '/';
}
opts.encode = encodeURIComponent;
return this.header('Set-Cookie', cookie.serialize(name, String(val), opts));
};
// https://github.com/expressjs/express/blob/508936853a6e311099c9985d4c11a4b1b8f6af07/lib/response.js#L801
res.clearCookie = function(name, options) {
var opts = { path: '/', ...options, expires: new Date(1) };
this.cookie(name, '', opts);
};
try {
await app(req, res, err =>
err ? res.status(500).send(err.message) : res.status(404).end()
);
} catch (err) {
req.status(500).send(err.message);
}
}
Insert cell
Insert cell
test_router_endpoint = {
return deploy("test_router_endpoint", handleWithExpress(app), {
cell: "test_router_endpoint"
})
}
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
ci.test(
"/response route returns payload containing Response keys",
async () => {
const response = await (await fetch(
test_router_endpoint.href + "/response"
)).json();
expect(Object.keys(response)).toEqual(
expect.arrayContaining([
"url",
"method",
"query",
"params",
"headers",
"ip",
"context"
])
);
}
)
Insert cell
ci.test("/setResponseHeader returns response with response header set", async () => {
const response = await fetch(test_router_endpoint.href + "/setResponseHeader/foo/bar")
expect(response.headers.get('foo')).toBe("bar");
})
Insert cell
ci.test("default route is 404", async () => {
expect((await fetch(test_router_endpoint.href)).status).toBe(404)
})
Insert cell
ci.test("/throw route is 500", async () => {
expect((await fetch(test_router_endpoint.href + "/throw")).status).toBe(500);
})
Insert cell
ci.test("/asyncthrow route is 500", async () => {
expect((await fetch(test_router_endpoint.href + "/throw")).status).toBe(500);
})
Insert cell
Insert cell
Insert cell

One platform to build and deploy the best data apps

Experiment and prototype by building visualizations in live JavaScript notebooks. Collaborate with your team and decide which concepts to build out.
Use Observable Framework to build data apps locally. Use data loaders to build in any language or library, including Python, SQL, and R.
Seamlessly deploy to Observable. Test before you ship, use automatic deploy-on-commit, and ensure your projects are always up-to-date.
Learn more