Skip to content

Commit 27c4cef

Browse files
committed
1 - generate more complex API during build
1 parent 1c7f92b commit 27c4cef

File tree

4 files changed

+88
-2
lines changed

4 files changed

+88
-2
lines changed

.eslintignore

+1
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,4 @@
1414
/.node_modules.ember-try/
1515

1616
/tmp/
17+
generate.mjs

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -25,3 +25,4 @@
2525
/DEBUG/
2626

2727
/tmp/
28+
/public/api/

generate.mjs

+84
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
/*
2+
This script is used to generate the JSON files for the API.
3+
It reads the pokemons.json file and generates the list and single files.
4+
5+
The list files are paginated with 48 items per page.
6+
The single files are used to get the details of a specific pokemon.
7+
8+
In the process, the data is transformed to match the JSON:API specification.
9+
10+
Currently it does not treat prev and next evolutions as relationships
11+
though it is possible to do so and we may want to add that to the API in the future.
12+
*/
13+
import { readFileSync, writeFileSync, existsSync, mkdirSync } from 'fs';
14+
15+
const raw = JSON.parse(readFileSync('./public/pokemons.json', 'utf8'));
16+
17+
const POKEMON = raw.data.map((pokemon) => {
18+
const id = String(pokemon.id);
19+
delete pokemon.id;
20+
return {
21+
id,
22+
type: 'pokemon',
23+
attributes: pokemon,
24+
};
25+
});
26+
const SLICES = [];
27+
const sliceSize = 48;
28+
29+
function links(slice) {
30+
slice.links.self = `/api/pokemon/list/${slice.meta.currentPage}.json`;
31+
slice.links.prev = slice.meta.currentPage === 1 ? null : `/api/pokemon/list/${slice.meta.currentPage - 1}.json`;
32+
slice.links.next = slice.meta.currentPage === slice.meta.totalPages ? null : `/api/pokemon/list/${slice.meta.currentPage + 1}.json`;
33+
slice.links.first = `/api/pokemon/list/1.json`;
34+
slice.links.last = `/api/pokemon/list/${slice.meta.totalPages}.json`;
35+
}
36+
37+
function meta(slice, index) {
38+
slice.meta.currentPage = index + 1;
39+
slice.meta.totalPages = SLICES.length;
40+
slice.meta.total = POKEMON.length;
41+
slice.meta.estimatedTotal = POKEMON.length;
42+
slice.meta.page = { size: slice.data.length, total: POKEMON.length, estimatedTotal: POKEMON.length }
43+
}
44+
45+
function ensureDirectoryExistence(dirname) {
46+
if (existsSync(dirname)) {
47+
return true;
48+
}
49+
50+
mkdirSync(dirname, { recursive: true });
51+
}
52+
53+
function populateSlices() {
54+
const temp = POKEMON.slice();
55+
56+
while (temp.length) {
57+
SLICES.push({
58+
data: temp.splice(0, sliceSize),
59+
meta: {},
60+
links: {},
61+
});
62+
}
63+
64+
SLICES.forEach((slice, index) => {
65+
meta(slice, index);
66+
links(slice);
67+
});
68+
69+
SLICES.forEach((slice, index) => {
70+
writeFileSync(`./public/api/pokemon/list/${index + 1}.json`, JSON.stringify(slice));
71+
72+
if (index === 0) {
73+
writeFileSync('./public/api/pokemon/list.json', JSON.stringify(slice));
74+
}
75+
});
76+
}
77+
78+
ensureDirectoryExistence('./public/api/pokemon/list');
79+
ensureDirectoryExistence('./public/api/pokemon/single');
80+
populateSlices();
81+
82+
POKEMON.forEach((pokemon) => {
83+
writeFileSync(`./public/api/pokemon/single/${pokemon.id}.json`, JSON.stringify({ data: pokemon }));
84+
});

package.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
"ember-eslint-parser": "^0.5.0"
1515
},
1616
"scripts": {
17-
"build": "vite build",
17+
"build": "node ./generate.mjs; vite build",
1818
"lint": "concurrently \"pnpm:lint:*(!fix)\" --names \"lint:\"",
1919
"lint:css": "stylelint \"**/*.css\"",
2020
"lint:css:fix": "concurrently \"pnpm:lint:css -- --fix\"",
@@ -24,7 +24,7 @@
2424
"lint:js": "eslint . --cache",
2525
"lint:js:fix": "eslint . --fix",
2626
"lint:types": "glint",
27-
"start": "vite",
27+
"start": "node ./generate.mjs; vite",
2828
"test": "concurrently \"pnpm:test:*\" --names \"test:\"",
2929
"test:ember": "vite build --mode test && ember test --path dist"
3030
},

0 commit comments

Comments
 (0)