Skip to content

Commit 748167c

Browse files
committed
refactor: small updates
Add JSDoc types and comments. Split code. Rename `build` to `buildServer`. Rename `pathToIndex` to `projectRootPath`. Change `npm run dev` to `npm start` in the `directories.js` comment.
1 parent 8d33a83 commit 748167c

File tree

12 files changed

+268
-202
lines changed

12 files changed

+268
-202
lines changed

server/app.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import staticRouter from "./src/static/staticRouter.js";
88
* @param {import("fastify").FastifyServerOptions} options
99
* @returns {import("fastify").FastifyInstance}
1010
*/
11-
function build(options = {}) {
11+
function buildServer(options = {}) {
1212
const fastify = Fastify(options);
1313

1414
fastify.addHook("onRequest", (request, reply, done) => {
@@ -26,4 +26,4 @@ function build(options = {}) {
2626
return fastify;
2727
}
2828

29-
export { build };
29+
export { buildServer };

server/index.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
import { build } from "./app.js";
1+
import { buildServer } from "./app.js";
22

33
const PORT = 8080;
44

5-
const server = build();
5+
const server = buildServer();
66

77
try {
88
await server.listen({ port: PORT });

server/src/config/directories.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
1-
import { join } from "path";
1+
import path from "path";
22
import process from "process";
33

44
// Checks if the directory is explicitly specified.
5-
// It can be specified by writing for example `npm run dev other-frameworks-directory`.
5+
// It can be specified by writing for example `npm start other-frameworks-directory`.
66
const isFrameworksDirectorySpecifies = process.argv.length === 3;
77

88
const frameworksDirectory = isFrameworksDirectorySpecifies
9-
? join(process.cwd(), "..", process.argv[2])
10-
: join(process.cwd(), "..", "frameworks");
9+
? path.join(process.cwd(), "..", process.argv[2])
10+
: path.join(process.cwd(), "..", "frameworks");
1111

1212
if (isFrameworksDirectorySpecifies) {
1313
console.log(`Changing working directory to ${process.argv[2]}`);

server/src/csp/cspRouter.js

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,12 @@ import { addCSP, disableCSP, enableCSP, getCSP } from "./cspControllers.js";
33
/**
44
* A plugin that provide encapsulated routes
55
* @param {import("fastify").FastifyInstance} fastify
6-
* @param {import("fastify").RegisterOptions} options
76
*/
8-
async function routes(fastify, _options) {
7+
async function routes(fastify) {
98
fastify.addContentTypeParser(
109
"application/csp-report",
1110
{ parseAs: "string" },
12-
fastify.getDefaultJsonParser("ignore", "ignore")
11+
fastify.getDefaultJsonParser("ignore", "ignore"),
1312
);
1413

1514
fastify.get("/enable", enableCSP);
Lines changed: 20 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,28 @@
1-
import path from "path";
2-
import fs from "fs";
1+
import { loadFrameworkVersions } from "./frameworksServices.js";
32

4-
import { frameworksDirectory } from "../config/directories.js";
5-
import isFrameworkDir from "./utils/isFrameworkDir.js";
6-
import { loadFrameworkInfo } from "./helpers/index.js";
3+
/**
4+
* @typedef {import("fastify").FastifyRequest} Request
5+
* @typedef {import("fastify").FastifyReply} Reply
6+
*/
77

8-
export async function loadFrameworkVersionInformation(filterForFramework) {
9-
const resultsProm = [];
10-
const frameworksPath = path.resolve(frameworksDirectory);
11-
const keyedTypes = ["keyed", "non-keyed"];
8+
/**
9+
* @param {Request} request
10+
* @param {Reply} reply
11+
*/
12+
export async function getFrameworksVersions(_request, reply) {
13+
performance.mark("Start");
1214

13-
for (const keyedType of keyedTypes) {
14-
const directories = fs.readdirSync(path.resolve(frameworksPath, keyedType));
15+
const frameworks = await loadFrameworkVersions();
1516

16-
for (const directory of directories) {
17-
const pathInFrameworksDir = `${keyedType}/${directory}`;
17+
performance.mark("End");
1818

19-
if (filterForFramework && filterForFramework !== pathInFrameworksDir) {
20-
continue;
21-
}
19+
const executionTime = performance.measure(
20+
"/ls duration measurement",
21+
"Start",
22+
"End",
23+
).duration;
2224

23-
if (!isFrameworkDir(keyedType, directory)) {
24-
continue;
25-
}
25+
console.log(`/ls duration: ${executionTime}ms`);
2626

27-
const frameworkInfo = loadFrameworkInfo(keyedType, directory);
28-
resultsProm.push(frameworkInfo);
29-
}
30-
}
31-
return Promise.all(resultsProm);
27+
return reply.send(frameworks);
3228
}
Lines changed: 3 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,11 @@
1-
import { loadFrameworkVersionInformation } from "./frameworksControllers.js";
1+
import { getFrameworksVersions } from "./frameworksControllers.js";
22

33
/**
44
* A plugin that provide encapsulated routes
55
* @param {import("fastify").FastifyInstance} fastify
6-
* @param {import("fastify").RegisterOptions} options
76
*/
8-
async function routes(fastify, _options) {
9-
fastify.get("/ls", async function (_request, reply) {
10-
performance.mark("Start");
11-
12-
const frameworks = await loadFrameworkVersionInformation();
13-
reply.send(frameworks);
14-
15-
performance.mark("End");
16-
const executionTime = performance.measure(
17-
"/ls duration measurement",
18-
"Start",
19-
"End",
20-
).duration;
21-
22-
console.log(`/ls duration: ${executionTime}ms`);
23-
return;
24-
});
7+
async function routes(fastify) {
8+
fastify.get("/ls", getFrameworksVersions);
259
}
2610

2711
export default routes;
Lines changed: 178 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,178 @@
1+
import path from "path";
2+
import fs from "fs";
3+
4+
import { frameworksDirectory } from "../config/directories.js";
5+
import { buildFrameworkVersionString, copyProps } from "./helpers/index.js";
6+
7+
const keyedTypes = ["keyed", "non-keyed"];
8+
9+
class PackageJSONProvider {
10+
#frameworksDir;
11+
12+
/** @param {string} frameworksDir */
13+
constructor(frameworksDir) {
14+
this.#frameworksDir = frameworksDir;
15+
}
16+
17+
/**
18+
* Returns the parsed package.json
19+
* @param {string} keyedDir
20+
* @param {string} framework
21+
* @returns {Promise<unknown>}
22+
*/
23+
async getPackageJSON(keyedDir, framework) {
24+
try {
25+
const packageJSONPath = path.join(
26+
this.#frameworksDir,
27+
keyedDir,
28+
framework,
29+
"package.json",
30+
);
31+
const packageJSON = await fs.promises.readFile(packageJSONPath, "utf-8");
32+
return JSON.parse(packageJSON);
33+
} catch (error) {
34+
if (error.code === "ENOENT") {
35+
throw new Error(`Package.json not found for ${framework}.`);
36+
}
37+
console.error(error);
38+
}
39+
}
40+
41+
/**
42+
* Returns the parsed package-lock.json
43+
* @param {string} keyedDir
44+
* @param {string} framework
45+
* @returns {Promise<unknown>}
46+
*/
47+
async getPackageLockJSON(keyedDir, framework) {
48+
try {
49+
const packageLockJSONPath = path.join(
50+
this.#frameworksDir,
51+
keyedDir,
52+
framework,
53+
"package-lock.json",
54+
);
55+
const packageLockJSON = await fs.promises.readFile(
56+
packageLockJSONPath,
57+
"utf-8",
58+
);
59+
return JSON.parse(packageLockJSON);
60+
} catch (error) {
61+
if (error.code === "ENOENT") {
62+
throw new Error(`Package-lock.json not found for ${framework}.`);
63+
}
64+
console.error(error);
65+
}
66+
}
67+
}
68+
69+
/**
70+
* @param {string} keyedDir
71+
* @param {string} framework
72+
* @returns {boolean}
73+
*/
74+
async function isFrameworkDir(keyedDir, framework) {
75+
const frameworkPath = path.resolve(frameworksDirectory, keyedDir, framework);
76+
const packageJSONPath = path.resolve(frameworkPath, "package.json");
77+
const packageLockJSONPath = path.resolve(frameworkPath, "package-lock.json");
78+
const exists =
79+
fs.existsSync(packageJSONPath) && fs.existsSync(packageLockJSONPath);
80+
81+
return exists;
82+
}
83+
84+
const packageJSONProvider = new PackageJSONProvider(frameworksDirectory);
85+
86+
/**
87+
* Load framework information from package.json and package-lock.json files.
88+
* @param {string} keyedDir - The type of the framework directory (e.g., "keyed" or "non-keyed").
89+
* @param {string} framework - The name of the framework directory.
90+
* @returns {Promise<object>} - The loaded framework information.
91+
*/
92+
export async function loadFrameworkInfo(keyedDir, framework) {
93+
const result = {
94+
type: keyedDir,
95+
directory: framework,
96+
};
97+
const packageJSON = await packageJSONProvider.getPackageJSON(
98+
keyedDir,
99+
framework,
100+
);
101+
const packageLockJSON = await packageJSONProvider.getPackageLockJSON(
102+
keyedDir,
103+
framework,
104+
);
105+
106+
const benchmarkData = packageJSON["js-framework-benchmark"];
107+
if (!benchmarkData) {
108+
result.error =
109+
"package.json must contain a 'js-framework-benchmark' property";
110+
return result;
111+
}
112+
113+
if (benchmarkData.frameworkVersionFromPackage) {
114+
const packageNames = benchmarkData.frameworkVersionFromPackage.split(":");
115+
116+
result.versions = {};
117+
118+
for (const packageName of packageNames) {
119+
if (packageLockJSON.dependencies?.[packageName]) {
120+
result.versions[packageName] =
121+
packageLockJSON.dependencies[packageName].version;
122+
} else if (packageLockJSON.packages?.[`node_modules/${packageName}`]) {
123+
result.versions[packageName] =
124+
packageLockJSON.packages[`node_modules/${packageName}`].version;
125+
} else {
126+
result.versions[packageName] = "ERROR: Not found in package-lock";
127+
}
128+
}
129+
130+
result.frameworkVersionString = buildFrameworkVersionString(
131+
framework,
132+
packageNames.map((name) => result.versions[name]).join(" + "),
133+
keyedDir,
134+
);
135+
136+
copyProps(result, benchmarkData);
137+
} else if (typeof benchmarkData.frameworkVersion === "string") {
138+
result.version = benchmarkData.frameworkVersion;
139+
result.frameworkVersionString = buildFrameworkVersionString(
140+
framework,
141+
result.version,
142+
keyedDir,
143+
);
144+
145+
copyProps(result, benchmarkData);
146+
} else {
147+
result.error =
148+
"package.json must contain a 'frameworkVersionFromPackage' or 'frameworkVersion' in the 'js-framework-benchmark'.property";
149+
}
150+
151+
return result;
152+
}
153+
154+
export async function loadFrameworkVersions(filterForFramework) {
155+
const resultsProm = [];
156+
157+
for (const keyedType of keyedTypes) {
158+
const directories = await fs.promises.readdir(
159+
path.resolve(frameworksDirectory, keyedType),
160+
);
161+
162+
for (const directory of directories) {
163+
const frameworkPath = path.join(keyedType, directory);
164+
165+
if (filterForFramework && filterForFramework !== frameworkPath) {
166+
continue;
167+
}
168+
169+
if (!isFrameworkDir(keyedType, directory)) {
170+
continue;
171+
}
172+
173+
const frameworkInfoPromise = loadFrameworkInfo(keyedType, directory);
174+
resultsProm.push(frameworkInfoPromise);
175+
}
176+
}
177+
return Promise.all(resultsProm);
178+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
/**
2+
* @param {string} directoryName
3+
* @param {string} version
4+
* @param {string} keyedDir
5+
* @returns
6+
*/
7+
export function buildFrameworkVersionString(directoryName, version, keyedDir) {
8+
return `${directoryName}${version ? `-v${version}` : ""}-${keyedDir}`;
9+
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
/**
2+
* @typedef {Object} BenchmarkData
3+
* @prop {string} issues
4+
* @prop {string} customURL
5+
* @prop {string} frameworkHomeURL
6+
* @prop {string} useShadowRoot
7+
* @prop {string} useRowShadowRoot
8+
* @prop {string} shadowRootName
9+
* @prop {string} buttonsInShadowRoot
10+
*/
11+
12+
/**
13+
* @param {unknown} result
14+
* @param {BenchmarkData} benchmarkData
15+
*/
16+
export function copyProps(result, benchmarkData) {
17+
const {
18+
issues,
19+
customURL,
20+
frameworkHomeURL,
21+
useShadowRoot,
22+
useRowShadowRoot,
23+
shadowRootName,
24+
buttonsInShadowRoot,
25+
} = benchmarkData;
26+
27+
result.issues = issues;
28+
result.customURL = customURL;
29+
result.frameworkHomeURL = frameworkHomeURL;
30+
result.useShadowRoot = useShadowRoot;
31+
result.useRowShadowRoot = useRowShadowRoot;
32+
result.shadowRootName = useShadowRoot
33+
? shadowRootName ?? "main-element"
34+
: undefined;
35+
result.buttonsInShadowRoot = useShadowRoot
36+
? buttonsInShadowRoot ?? true
37+
: undefined;
38+
}

0 commit comments

Comments
 (0)