All files / src/functions add.fastify.routes.ts

100% Statements 59/59
100% Branches 25/25
100% Functions 12/12
100% Lines 44/44

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93    2x 2x 2x             2x 2x       2x   2x       9x 9x 9x   9x 9x   13x               13x 13x   9x     9x 9x 12x 12x     9x 8x   8x 8x   8x 8x   8x 8x   8x 8x   8x 2x 2x 4x     6x 6x         9x 8x 8x     9x     9x 1x 1x         2x  
'use strict';
 
import * as fs from 'fs';
import * as path from 'path';
import {hrtime} from 'node:process';
 
import {IncomingMessage, Server, ServerResponse} from 'http';
import {FastifyInstance} from 'fastify';
 
import {ItemStat} from '@owservable/folders';
 
import addRoute from './add.route';
import cleanRelativePath from './clean.relative.path';
 
let routesRootFolder: string;
 
const NS_PER_SEC: number = 1e9;
 
const addFastifyRoutes = async (
	fastify: FastifyInstance<Server<typeof IncomingMessage, typeof ServerResponse>, IncomingMessage, ServerResponse<IncomingMessage>>,
	folder: string,
	verbose: boolean = false
): Promise<void> => {
	if (verbose) console.log('\n[@owservable/fastify-auto-routes] -> addFastifyRoutes:', folder);
	if (!routesRootFolder) routesRootFolder = folder;
 
	const fileNames: string[] = await fs.promises.readdir(folder);
	const stats: ItemStat[] = await Promise.all(
		fileNames.map(
			async (name): Promise<ItemStat> => ({
				name,
				fullPath: path.join(folder, name),
				isDirectory: (await fs.promises.lstat(path.join(folder, name))).isDirectory()
			})
		)
	);
 
	const files: ItemStat[] = stats.filter((stat: ItemStat): boolean => !stat.isDirectory);
	const folders: ItemStat[] = stats.filter((stat: ItemStat): boolean => stat.isDirectory);
 
	if (verbose) console.log('[@owservable/fastify-auto-routes] -> addFastifyRoutes:', folder, `${files.length} files`);
 
	// Process files in parallel batches for better performance
	const BATCH_SIZE = 10; // Process up to 10 files concurrently
	const validFiles: ItemStat[] = files.filter((file: ItemStat): boolean => {
		const ext: string = path.extname(file.name);
		return ext === '.ts' || ext === '.js';
	});
 
	const processFile = async (file: ItemStat): Promise<void> => {
		if (verbose) console.log('[@owservable/fastify-auto-routes] -> addFastifyRoutes: processing...', `${folder}/${file.name}`);
 
		const ext: string = path.extname(file.name);
		const relativeFilePath: string = cleanRelativePath(routesRootFolder, file.fullPath, ext as '.ts' | '.js');
 
		const start: number = Number(hrtime.bigint());
		if (verbose) console.log('[@owservable/fastify-auto-routes] -> addFastifyRoutes: loading file...', file.fullPath);
 
		const routeModule = await import(file.fullPath);
		const routes = routeModule.default || routeModule;
 
		const time: number = Number(Number(hrtime.bigint()) - start) / NS_PER_SEC;
		if (verbose) console.log('[@owservable/fastify-auto-routes] -> addFastifyRoutes: loaded file', `[${time.toFixed(3)}s] ${folder}/${file.name}`);
 
		if (Array.isArray(routes)) {
			if (verbose) console.log('[@owservable/fastify-auto-routes] -> addFastifyRoutes:', file.fullPath, `${routes.length} routes`);
			for (const route of routes) {
				addRoute(fastify, route, relativeFilePath, verbose);
			}
		} else {
			if (verbose) console.log('[@owservable/fastify-auto-routes] -> addFastifyRoutes:', file.fullPath, '1 route');
			addRoute(fastify, routes, relativeFilePath, verbose);
		}
	};
 
	// Process files in parallel batches
	for (let i = 0; i < validFiles.length; i += BATCH_SIZE) {
		const batch: ItemStat[] = validFiles.slice(i, i + BATCH_SIZE);
		await Promise.all(batch.map(processFile));
	}
 
	if (verbose) console.log('[@owservable/fastify-auto-routes] -> addFastifyRoutes:', folder, 'subfolders:', `${folders.length} subfolders`);
 
	// Process subdirectories in parallel for better performance
	await Promise.all(
		folders.map(async (sub: ItemStat): Promise<void> => {
			await addFastifyRoutes(fastify, sub.fullPath, verbose);
		})
	);
};
 
export default addFastifyRoutes;