Skip to content

Commit

Permalink
Add support for Noto Sans
Browse files Browse the repository at this point in the history
  • Loading branch information
FlorianKoerner committed Jun 16, 2024
1 parent 1bd9f3b commit df95f2a
Show file tree
Hide file tree
Showing 16 changed files with 609 additions and 261 deletions.
528 changes: 396 additions & 132 deletions package-lock.json

Large diffs are not rendered by default.

14 changes: 10 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"type": "module",
"scripts": {
"dev": "tsx --watch ./src/server.ts",
"build": "tsc --build && cp -r src/fonts dist/fonts",
"build": "tsc --build",
"start": "node ./dist/server.js",
"test": "node --test tests/*.js"
},
Expand All @@ -21,21 +21,27 @@
"@dicebear/api-9": "*",
"@dicebear/converter": "^9.0.0",
"@fastify/cors": "^8.4.0",
"@fontsource/noto-sans": "^5.0.22",
"@fontsource/noto-sans-jp": "^5.0.19",
"@fontsource/noto-sans-kr": "^5.0.19",
"@fontsource/noto-sans-sc": "^5.0.19",
"@fontsource/noto-sans-thai": "^5.0.14",
"@woff2/woff2-rs": "^1.0.1",
"change-case": "^5.0.2",
"fastify": "^4.23.2",
"qs": "^6.11.2"
},
"devDependencies": {
"@dicebear/core": "^7.0.1",
"@tsconfig/node18": "^1.0.2",
"@tsconfig/node20": "^20.1.4",
"@types/json-schema": "^7.0.13",
"@types/node": "^16.11.7",
"@types/node": "^20.14.2",
"@types/qs": "^6.9.8",
"prettier": "^2.4.1",
"tsx": "^3.13.0",
"typescript": "^5.2.2"
},
"engines": {
"node": ">=18.0.0"
"node": "^18.20 || >=20.10"
}
}
10 changes: 7 additions & 3 deletions src/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,13 @@ import { config } from './config.js';
import fastify from 'fastify';
import cors from '@fastify/cors';

import { parseQueryString } from './utils/parseQueryString.js';
import { parseQueryString } from './utils/query-string.js';
import { versionRoutes } from './routes/version.js';
import { getVersions } from './utils/getVersions.js';
import { getVersions } from './utils/versions.js';
import { loadAllFonts } from './utils/fonts.js';
import { Font } from './types.js';

export const app = async () => {
export const app = async (fonts: Font[]) => {
const app = fastify({
logger: config.logger,
querystringParser: (str) => parseQueryString(str),
Expand All @@ -20,6 +22,8 @@ export const app = async () => {
maxParamLength: 1024,
});

app.decorate('fonts', fonts);

await app.register(cors);

await app.register(versionRoutes, { versions: await getVersions() });
Expand Down
94 changes: 0 additions & 94 deletions src/fonts/inter/License.txt

This file was deleted.

Binary file removed src/fonts/inter/inter-bold.otf
Binary file not shown.
Binary file removed src/fonts/inter/inter-regular.otf
Binary file not shown.
18 changes: 5 additions & 13 deletions src/handler/avatar.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import type { FastifyReply, FastifyRequest } from 'fastify';
import type { FastifyInstance, FastifyReply, FastifyRequest } from 'fastify';
import type { Core } from '../types.js';
import { config } from '../config.js';
import { toJpeg, toPng } from '@dicebear/converter';
import { getRequiredFonts, loadAllFonts } from '../utils/fonts.js';

export type AvatarRequest = {
Params: {
Expand All @@ -11,16 +12,7 @@ export type AvatarRequest = {
Querystring: Record<string, any>;
};

export function avatarHandler(core: Core, style: any) {
const interRegular = new URL(
'../fonts/inter/inter-regular.otf',
import.meta.url
);

const interBold = new URL('../fonts/inter/inter-bold.otf', import.meta.url);

const fonts = [interRegular.pathname, interBold.pathname];

export function avatarHandler(app: FastifyInstance, core: Core, style: any) {
return async (
request: FastifyRequest<AvatarRequest>,
reply: FastifyReply
Expand Down Expand Up @@ -73,7 +65,7 @@ export function avatarHandler(core: Core, style: any) {

const png = await toPng(avatar.toString(), {
includeExif: config.png.exif,
fonts,
fonts: getRequiredFonts(avatar.toString(), app.fonts),
}).toArrayBuffer();

return Buffer.from(png);
Expand All @@ -84,7 +76,7 @@ export function avatarHandler(core: Core, style: any) {

const jpeg = await toJpeg(avatar.toString(), {
includeExif: config.jpeg.exif,
fonts,
fonts: getRequiredFonts(avatar.toString(), app.fonts),
}).toArrayBuffer();

return Buffer.from(jpeg);
Expand Down
8 changes: 4 additions & 4 deletions src/routes/style.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import type { FastifyPluginCallback } from 'fastify';
import type { FastifyPluginAsync, FastifyPluginCallback } from 'fastify';
import type { JSONSchema7Definition } from 'json-schema';
import type { Core } from '../types.js';
import { schemaHandler } from '../handler/schema.js';
import { parseQueryString } from '../utils/parseQueryString.js';
import { parseQueryString } from '../utils/query-string.js';
import { AvatarRequest, avatarHandler } from '../handler/avatar.js';
import { config } from '../config.js';

Expand Down Expand Up @@ -46,7 +46,7 @@ export const styleRoutes: FastifyPluginCallback<Options> = (
querystring: optionsSchema,
params: paramsSchema,
},
handler: avatarHandler(core, style),
handler: avatarHandler(app, core, style),
});

app.route<AvatarRequest>({
Expand All @@ -61,7 +61,7 @@ export const styleRoutes: FastifyPluginCallback<Options> = (
querystring: optionsSchema,
params: paramsSchema,
},
handler: avatarHandler(core, style),
handler: avatarHandler(app, core, style),
});

done();
Expand Down
27 changes: 17 additions & 10 deletions src/server.ts
Original file line number Diff line number Diff line change
@@ -1,27 +1,34 @@
import cluster from "node:cluster";
import cluster from 'node:cluster';
import { config } from './config.js';
import { app } from './app.js';
import { loadAllFonts } from './utils/fonts.js';
import { ensureCacheDir } from './utils/cache.js';

const useCluster = config.workers > 1;

// Ensure cache directory
ensureCacheDir();

// Preload all fonts
const fonts = await loadAllFonts();

if (cluster.isPrimary && useCluster) {
for (let i = 0; i < config.workers; i++) {
cluster.fork();
}

cluster.on(
"exit",
(worker, code, signal) => {
console.log(`Worker ${worker.process.pid} died with code ${code} and signal ${signal}`);
cluster.on('exit', (worker, code, signal) => {
console.log(
`Worker ${worker.process.pid} died with code ${code} and signal ${signal}`
);

// Fork a new worker
cluster.fork();
},
);
// Fork a new worker
cluster.fork();
});
} else {
console.log(`Worker ${process.pid} started`);

const server = await app();
const server = await app(fonts);

server.listen(
{
Expand Down
11 changes: 11 additions & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
import { JSONSchema7 } from 'json-schema';

declare module 'fastify' {
interface FastifyInstance {
fonts: Font[];
}
}

export type Core = {
createAvatar: (
style: any,
Expand Down Expand Up @@ -50,3 +56,8 @@ export type Config = {
avatar: number;
};
};

export type Font = {
font: string;
ranges: [number, number][];
};
17 changes: 17 additions & 0 deletions src/utils/cache.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { promises as fs, existsSync } from 'fs';
import path from 'path';
import { fileURLToPath } from 'url';

const __dirname = fileURLToPath(new URL('.', import.meta.url));

export function getCacheDir() {
return path.join(__dirname, '..', '..', '.cache');
}

export async function ensureCacheDir() {
const cacheDir = getCacheDir();

if (!existsSync(cacheDir)) {
await fs.mkdir(cacheDir);
}
}
Loading

0 comments on commit df95f2a

Please sign in to comment.