Skip to content

Commit 1330d0d

Browse files
committed
Enable deployment of mock backend via netlify functions.
1 parent c639dbf commit 1330d0d

File tree

12 files changed

+6122
-310
lines changed

12 files changed

+6122
-310
lines changed

frontend/.eslintrc.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
"singleQuote": false,
1919
"arrowParens": "avoid"
2020
}
21-
]
21+
],
22+
"no-console": "error"
2223
}
2324
}

frontend/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,3 +21,4 @@ package-lock.json
2121
*.tgz
2222

2323
app/api/dnd/**/_*.*
24+
storybook-static

frontend/mock-api/functions/api.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import * as serverless from "serverless-http";
2+
import * as createApi from "../index";
3+
const app = createApi();
4+
5+
module.exports.handler = serverless(app);

frontend/mock-api/index.js

Lines changed: 47 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -2,29 +2,32 @@ const path = require("path");
22
const version = require("../package.json").version;
33
const EXPORT_FORM_CONFIG = require("./forms/export-form.json");
44
const mockAuthMiddleware = require("./mockAuthMiddleware");
5+
const express = require("express");
6+
const bodyParser = require("body-parser");
7+
const cors = require("cors");
58

69
// Taken from:
710
// http://stackoverflow.com/questions/2450954/how-to-randomize-shuffle-a-javascript-array
811
function shuffleArray(array) {
9-
for (var i = array.length - 1; i > 0; i--) {
10-
var j = Math.floor(Math.random() * (i + 1));
11-
var temp = array[i];
12+
for (let i = array.length - 1; i > 0; i--) {
13+
const j = Math.floor(Math.random() * (i + 1));
14+
const temp = array[i];
1215
array[i] = array[j];
1316
array[j] = temp;
1417
}
1518
return array;
1619
}
1720

1821
const ERROR = JSON.stringify({
19-
message: "Could not process the request",
22+
message: "Could not process the request"
2023
});
2124

2225
const LONG_DELAY = 500;
2326
const SHORT_DELAY = 300;
2427
const NO_DELAY = 10;
2528

2629
// Simulate API
27-
module.exports = function (app, port) {
30+
function mountApi(app) {
2831
/*
2932
QUERIES
3033
*/
@@ -78,7 +81,7 @@ module.exports = function (app, port) {
7881
id: 1,
7982
status: "DONE",
8083
numberOfResults: 5,
81-
resultUrl: `/api/results/results.csv`,
84+
resultUrl: `/api/results/results.csv`
8285
})
8386
);
8487
}, LONG_DELAY);
@@ -97,8 +100,8 @@ module.exports = function (app, port) {
97100
{ id: "empty-set", label: "Empty Dataset" },
98101
{
99102
id: "another-empty-set",
100-
label: "Another empty dataset with a long name",
101-
},
103+
label: "Another empty dataset with a long name"
104+
}
102105
])
103106
);
104107
});
@@ -149,10 +152,10 @@ module.exports = function (app, port) {
149152
"group 1",
150153
"important",
151154
"jk",
152-
"interesting",
155+
"interesting"
153156
];
154157

155-
for (var i = 25600; i < 35600; i++) {
158+
for (let i = 25600; i < 35600; i++) {
156159
const notExecuted = Math.random() < 0.1;
157160

158161
ids.push({
@@ -168,7 +171,7 @@ module.exports = function (app, port) {
168171
own: Math.random() < 0.1,
169172
shared: Math.random() < 0.8,
170173
resultUrl: notExecuted ? null : `/api/results/results.csv`,
171-
ownerName: "System",
174+
ownerName: "System"
172175
});
173176
}
174177

@@ -229,7 +232,7 @@ module.exports = function (app, port) {
229232
res.send(
230233
JSON.stringify({
231234
successful: 1 + Math.floor(Math.random() * 200),
232-
unsuccessful: 586,
235+
unsuccessful: 586
233236
})
234237
);
235238
}, LONG_DELAY);
@@ -258,16 +261,16 @@ module.exports = function (app, port) {
258261
"1000326535",
259262
"1014150881",
260263
"1017126347",
261-
"1008445564",
264+
"1008445564"
262265
];
263266

264267
const suggestions = storedValues
265268
.map((v, id) => ({
266269
label: v,
267270
value: id,
268-
templateValues: { company: "Columbia Pictures Corporation" },
271+
templateValues: { company: "Columbia Pictures Corporation" }
269272
}))
270-
.filter((v) => v.label.toLowerCase().startsWith(text));
273+
.filter(v => v.label.toLowerCase().startsWith(text));
271274

272275
res.send(JSON.stringify(suggestions));
273276
}, LONG_DELAY);
@@ -285,7 +288,7 @@ module.exports = function (app, port) {
285288

286289
res.send({
287290
unknownCodes: concepts.slice(5),
288-
resolvedConcepts: concepts.slice(1),
291+
resolvedConcepts: concepts.slice(1)
289292
});
290293
}, LONG_DELAY);
291294
}
@@ -299,7 +302,7 @@ module.exports = function (app, port) {
299302

300303
res.send({
301304
version: version,
302-
isDevelopment: process.env.NODE_ENV !== "production",
305+
isDevelopment: process.env.NODE_ENV !== "production"
303306
});
304307
});
305308

@@ -318,16 +321,16 @@ module.exports = function (app, port) {
318321
if (req.params.filterId !== "production_country") return null;
319322

320323
const countries = require("./autocomplete/countries");
321-
const unknownCodes = values.filter((val) => !countries.includes(val));
322-
const resolvedValues = values.filter((val) => countries.includes(val));
324+
const unknownCodes = values.filter(val => !countries.includes(val));
325+
const resolvedValues = values.filter(val => countries.includes(val));
323326

324327
res.send({
325328
unknownCodes: unknownCodes,
326329
resolvedFilter: {
327330
tableId: req.params.tableId,
328331
filterId: req.params.filterId,
329-
value: resolvedValues.map((val) => ({ label: val, value: val })),
330-
},
332+
value: resolvedValues.map(val => ({ label: val, value: val }))
333+
}
331334
});
332335
}, LONG_DELAY);
333336
}
@@ -351,13 +354,13 @@ module.exports = function (app, port) {
351354

352355
if (user === "test" && password === "test") {
353356
res.send({
354-
access_token: "VALID",
357+
access_token: "VALID"
355358
});
356359
} else {
357360
res.status(422);
358361
res.send(
359362
JSON.stringify({
360-
message: "Login failed",
363+
message: "Login failed"
361364
})
362365
);
363366
}
@@ -374,10 +377,10 @@ module.exports = function (app, port) {
374377
domains: ["datasets"],
375378
abilities: ["read", "download", "preserve_id"],
376379
targets: ["imdb"],
377-
creationTime: "2020-01-23T09:52:31.3318485",
378-
},
380+
creationTime: "2020-01-23T09:52:31.3318485"
381+
}
379382
],
380-
groups: [],
383+
groups: []
381384
});
382385
});
383386

@@ -390,7 +393,7 @@ module.exports = function (app, port) {
390393
res.status(201);
391394
res.send(
392395
JSON.stringify({
393-
id: 56000 + Math.floor(Math.random() * 200),
396+
id: 56000 + Math.floor(Math.random() * 200)
394397
})
395398
);
396399
}, LONG_DELAY);
@@ -409,12 +412,12 @@ module.exports = function (app, port) {
409412
if (dice < 0.5) {
410413
return {
411414
formType: "EXPORT_FORM",
412-
values: {},
415+
values: {}
413416
};
414417
} else {
415418
return {
416419
formType: "Other form",
417-
values: {},
420+
values: {}
418421
};
419422
}
420423
}
@@ -428,10 +431,10 @@ module.exports = function (app, port) {
428431
"group 1",
429432
"important",
430433
"jk",
431-
"interesting",
434+
"interesting"
432435
];
433436

434-
for (var i = 55600; i < 85600; i++) {
437+
for (let i = 55600; i < 85600; i++) {
435438
configs.push({
436439
id: i,
437440
label: "Saved Config",
@@ -442,7 +445,7 @@ module.exports = function (app, port) {
442445
own: Math.random() < 0.1,
443446
shared: Math.random() < 0.8,
444447
ownerName: "System",
445-
...getFormConfigAttributes(),
448+
...getFormConfigAttributes()
446449
});
447450
}
448451

@@ -481,4 +484,16 @@ module.exports = function (app, port) {
481484
}, LONG_DELAY);
482485
}
483486
);
487+
}
488+
489+
const createApi = () => {
490+
const app = express();
491+
app.use(cors());
492+
// body parser must be set up before routes are attached
493+
app.use(bodyParser.json());
494+
495+
mountApi(app);
496+
return app;
484497
};
498+
499+
module.exports = createApi;

frontend/mock-api/server.js

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,21 +2,12 @@
22
// EXPRESS SETUP
33
// -----------
44
const path = require("path");
5-
const express = require("express");
6-
const bodyParser = require("body-parser");
7-
const cors = require("cors");
8-
const mountApi = require(".");
5+
const createApi = require(".");
96

107
const isDeveloping = process.env.NODE_ENV !== "production";
118
const port = process.env.PORT || 8001;
12-
const app = express();
13-
const lang = process.env.APP_LANG || "en";
149

15-
app.use(cors());
16-
// body parser must be set up before routes are attached
17-
app.use(bodyParser.json());
18-
19-
mountApi(app, port);
10+
const app = createApi()
2011

2112
if (!isDeveloping) {
2213
app.use("/app/static", express.static(__dirname + "/build"));

frontend/package.json

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,16 @@
1010
},
1111
"scripts": {
1212
"start": "react-app-rewired start",
13-
"build": "react-app-rewired build",
13+
"build-frontend": "react-app-rewired build",
14+
"build": "yarn build-frontend && yarn build-mock-backend",
15+
"build-mock-backend": "tsc mock-api/functions/*",
1416
"test": "react-app-rewired test",
1517
"eject": "react-scripts eject",
1618
"heroku-postbuild": "yarn run build",
1719
"lint": "eslint --ext .ts --ext .tsx src/",
1820
"typecheck": "tsc -p tsconfig.json --noEmit",
1921
"serve": "ts-node mock-api/server"
2022
},
21-
"homepage": "/app/static",
2223
"dependencies": {
2324
"@emotion/babel-plugin": "^11.0.0-next.12",
2425
"@emotion/is-prop-valid": "^0.8.8",
@@ -37,6 +38,7 @@
3738
"lodash.difference": "^4.5.0",
3839
"mustache": "^2.3.0",
3940
"node-sass": "^4.12.0",
41+
"ramda": "^0.27.0",
4042
"react": "^16.13.1",
4143
"react-animated-dots": "^1.0.0",
4244
"react-dnd": "^9.4.0",
@@ -65,9 +67,15 @@
6567
"redux": "^4.0.5",
6668
"redux-form": "^8.2.4",
6769
"redux-multi": "^0.1.12",
68-
"redux-thunk": "^2.3.0"
70+
"redux-thunk": "^2.3.0",
71+
"serverless-http": "^2.5.0"
6972
},
7073
"devDependencies": {
74+
"@storybook/addon-actions": "^5.3.19",
75+
"@storybook/addon-links": "^5.3.19",
76+
"@storybook/addons": "^5.3.19",
77+
"@storybook/preset-create-react-app": "^3.1.4",
78+
"@storybook/react": "^5.3.19",
7179
"@types/axios": "^0.14.0",
7280
"@types/body-parser": "^1.19.0",
7381
"@types/classnames": "^2.2.10",
@@ -82,6 +90,7 @@
8290
"@types/node-sass": "^4.11.1",
8391
"@types/papaparse": "^5.0.4",
8492
"@types/prettier": "^2.0.2",
93+
"@types/ramda": "^0.27.11",
8594
"@types/react": "^16.9.25",
8695
"@types/react-dnd-multi-backend": "^4.0.1",
8796
"@types/react-dom": "^16.9.5",
@@ -109,6 +118,7 @@
109118
"express": "^4.16.2",
110119
"flux-standard-action": "^2.0.1",
111120
"ie-version": "^0.1.0",
121+
"netlify-cli": "^2.58.0",
112122
"nock": "^12.0.3",
113123
"papaparse": "^5.0.0",
114124
"prettier": "^2.0.5",

frontend/src/js/app/Content.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ const PreviewItem = styled("div")`
5454
//@ts-ignore
5555

5656
const generatePreview = (type, item, style) => {
57+
// eslint-disable-next-line no-console
5758
console.log("PREVIEW RENDERED", item.width, item.height, style);
5859
//@ts-ignore
5960

frontend/src/js/common/helpers/fileHelper.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ export async function getFileRows(file: File) {
2727
const rows = cleanFileContent(text);
2828

2929
if (rows.length === 0) {
30+
// eslint-disable-next-line no-console
3031
console.error("An empty file was dropped");
3132
}
3233

frontend/src/js/concept-trees/actions.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ export const loadTree = (datasetId: DatasetIdT, treeId: ConceptIdT) => {
7979

8080
// If the datasetId changed in the mean time, don't load the tree
8181
if (datasetId !== getDatasetId()) {
82+
// eslint-disable-next-line no-console
8283
console.log(`${datasetId} not matching, not loading ${treeId}`);
8384
semaphore.release();
8485
return;

frontend/src/js/concept-trees/globalTreeStoreHelper.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,7 @@ export const getConceptsByIdsWithTablesAndSelects = (
113113
// There should only be one exact root node that has table information
114114
// If it's more or less than one, something went wrong
115115
if (!rootConceptId) {
116+
// eslint-disable-next-line no-console
116117
console.error("No root concept ID found");
117118
return null;
118119
}

frontend/tsconfig.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,5 +24,5 @@
2424
"isolatedModules": true
2525
},
2626
"include": ["src", "node_modules/**/*/*.d.ts"],
27-
"exclude": ["node_modules", "public", ".cache", ".idea", "src/ignored/*"]
27+
"exclude": ["node_modules", "public", ".cache", ".idea", "src/ignored/*"],
2828
}

0 commit comments

Comments
 (0)