Skip to content

Commit 01ec0aa

Browse files
committed
add experimental data routes
1 parent 0bfc6a7 commit 01ec0aa

File tree

5 files changed

+74
-5
lines changed

5 files changed

+74
-5
lines changed

src/routes/prepareRouter.ts

Lines changed: 35 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,27 @@ type Req = {
3939
interface IFindPrebuildRequest {
4040
req: Req;
4141
serverLookupObject: any;
42+
dataRoutes: boolean | string;
4243
}
44+
45+
export const getDataRequest = ({ req, server, serverLookupObject }) => {
46+
// check data routes
47+
let request;
48+
if (server.dataRoutes) {
49+
const dataSuffix = typeof server.dataRoutes === 'string' ? server.dataRoutes : 'data.json';
50+
if (req.path.endsWith(dataSuffix)) {
51+
const lookup = req.path.replace(dataSuffix, '');
52+
request = serverLookupObject[lookup];
53+
}
54+
}
55+
56+
if (request) {
57+
request.req = req;
58+
}
59+
60+
return request;
61+
};
62+
4363
export const findPrebuiltRequest = ({ req, serverLookupObject }: IFindPrebuildRequest): RequestOptions | false => {
4464
// see if we have a request object with the path as is. (could include / or not.)
4565
let request = serverLookupObject[req.path] ? serverLookupObject[req.path] : false;
@@ -128,19 +148,26 @@ function prepareRouter(Elder) {
128148
shortcodes: elder.shortcodes,
129149
};
130150

131-
async function handleRequest({ res, next, request, dynamic = false }) {
151+
async function handleRequest({ res, next, request, dynamic = false, dataRequest = false }) {
132152
if (!request.route || typeof request.route !== 'string') return next();
133153
if (!routes[request.route]) return next();
134154
const page = new Page({ ...forPage, request, next: dynamic ? next : undefined, route: routes[request.route] });
135-
const html = await page.html();
155+
const { htmlString: html, data } = await page.build();
156+
157+
if (dataRequest && data) {
158+
res.setHeader('Content-Type', 'application/json');
159+
res.end(JSON.stringify(data));
160+
return undefined;
161+
}
136162

137-
// note: html will be undefined if a dynamic route calls skip() as it aborts page building.
138163
if (html && !res.headerSent && !res.headersSent) {
164+
// note: html will be undefined if a dynamic route calls skip() as it aborts page building.
139165
res.setHeader('Content-Type', 'text/html');
140166
res.end(html);
141167

142168
return undefined;
143169
}
170+
144171
return next();
145172
}
146173

@@ -151,7 +178,11 @@ function prepareRouter(Elder) {
151178
// initial request may be well formed if it is modified via a hook BEFORE the router runs.
152179
if (initialRequestIsWellFormed(initialRequest)) return handleRequest({ res, next, request: initialRequest });
153180
if (!needsElderRequest({ req, prefix })) return next();
154-
const request = findPrebuiltRequest({ req, serverLookupObject });
181+
const dataRequest = getDataRequest({ req, server: settings.server, serverLookupObject });
182+
if (dataRequest) {
183+
return handleRequest({ res, next, request: { ...dataRequest, ...initialRequest }, dataRequest: true });
184+
}
185+
const request = findPrebuiltRequest({ req, serverLookupObject, dataRoutes: settings?.server?.dataRoutes });
155186
if (request) return handleRequest({ res, next, request: { ...request, ...initialRequest } });
156187
const dynamicRequest = requestFromDynamicRoute({ req, dynamicRoutes, requestCache });
157188
if (dynamicRequest)

src/utils/__tests__/__snapshots__/validations.spec.ts.snap

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -789,6 +789,7 @@ Object {
789789
"_exclusive": Object {},
790790
"_mutate": undefined,
791791
"_nodes": Array [
792+
"dataRoutes",
792793
"cacheRequests",
793794
"prefix",
794795
],
@@ -830,6 +831,33 @@ Object {
830831
],
831832
"type": "boolean",
832833
},
834+
"dataRoutes": Object {
835+
"_blacklist": Object {
836+
"list": Set {},
837+
"refs": Map {},
838+
},
839+
"_conditions": Array [],
840+
"_default": false,
841+
"_deps": Array [],
842+
"_exclusive": Object {},
843+
"_label": "Experimental: Allows for getting a json response of the data object of a url. Defaults to [path]/data.json but can be any suffix/filename after the route.",
844+
"_mutate": undefined,
845+
"_options": Object {
846+
"abortEarly": true,
847+
"recursive": true,
848+
},
849+
"_type": "boolean",
850+
"_typeError": [Function],
851+
"_whitelist": Object {
852+
"list": Set {},
853+
"refs": Map {},
854+
},
855+
"tests": Array [],
856+
"transforms": Array [
857+
[Function],
858+
],
859+
"type": "boolean",
860+
},
833861
"prefix": Object {
834862
"_blacklist": Object {
835863
"list": Set {},

src/utils/__tests__/getConfig.spec.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,9 @@ describe('#getConfig', () => {
150150
expect.objectContaining({
151151
...common,
152152
context: 'server',
153-
server: false,
153+
server: {
154+
prefix: '',
155+
},
154156
}),
155157
);
156158
expect(r.$$internal).toMatchObject(common$$Internal);

src/utils/__tests__/validations.spec.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ describe('#validations', () => {
5555
server: {
5656
prefix: '',
5757
cacheRequests: true,
58+
dataRoutes: false,
5859
},
5960
shortcodes: {
6061
closePattern: '}}',

src/utils/validations.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,13 @@ const configSchema = yup.object({
105105
.label(
106106
`If Elder.js should cache requests when using dynamic routing. It may be useful to turn off the cache when combining Elder.js with another caching solution to reduce the resources consumed by the server.`,
107107
),
108+
dataRoutes: yup
109+
.boolean()
110+
.notRequired()
111+
.default(false)
112+
.label(
113+
'Experimental: Allows for getting a json response of the data object of a url. Defaults to [path]/data.json but can be any suffix/filename after the route.',
114+
),
108115
}),
109116
prefix: yup
110117
.string()

0 commit comments

Comments
 (0)