Skip to content

Commit 71d30f2

Browse files
Merge pull request #3 from Crawlith/codex/restructure-repo-for-clean-structure-j3jmsi
Introduce typed PLATFORM_SIZES, improved font/WASM pipeline, API param parsing, UI refresh, and workspace reorg
2 parents c7995e6 + 7c68467 commit 71d30f2

19 files changed

Lines changed: 862 additions & 526 deletions

File tree

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,6 @@ coverage
1010
!.env.example
1111
.og-cache
1212
.temp
13+
14+
# generated previews (binary, excluded from PR tooling)
15+
templates/*/preview.png

apps/server-node/src/index.ts

Lines changed: 39 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
import express, { type Request, type Response } from 'express';
21
import { nodeAdapter } from '@og-engine/adapter-node';
32
import { createHandler } from '@og-engine/core';
4-
import type { OGRequest, MetaRequest } from '@og-engine/types';
3+
import type { MetaRequest, OGRequest, PlatformSize } from '@og-engine/types';
4+
import express, { type Request, type Response } from 'express';
55

66
const app = express();
77
const port = process.env.PORT ?? 3000;
@@ -12,23 +12,50 @@ const adapter = nodeAdapter({
1212
});
1313

1414
const handler = createHandler({ platform: adapter });
15+
const PLATFORM_SIZES: ReadonlyArray<PlatformSize> = [
16+
'twitter-og',
17+
'facebook-og',
18+
'linkedin-og',
19+
'ig-post',
20+
'ig-story',
21+
'discord',
22+
'whatsapp',
23+
'github',
24+
'og'
25+
];
26+
27+
function parseSize(value: unknown): PlatformSize {
28+
if (typeof value === 'string' && PLATFORM_SIZES.includes(value as PlatformSize)) {
29+
return value as PlatformSize;
30+
}
31+
32+
return 'og';
33+
}
34+
35+
function parseFormat(value: unknown): OGRequest['format'] {
36+
if (value === 'jpeg' || value === 'png') {
37+
return value;
38+
}
39+
40+
return 'png';
41+
}
1542

1643
app.get('/health', (_request: Request, response: Response) => {
1744
response.json({ ok: true });
1845
});
1946

2047
app.get('/api/og', async (req: Request, res: Response) => {
2148
try {
22-
const { template, size = 'og', format = 'png', ...params } = req.query;
49+
const { template, size, format, ...params } = req.query;
2350

24-
if (!template) {
51+
if (!template || typeof template !== 'string') {
2552
return res.status(400).send('Missing template parameter');
2653
}
2754

2855
const ogReq: OGRequest = {
29-
template: template as string,
30-
size: size as any,
31-
format: format as any,
56+
template,
57+
size: parseSize(size),
58+
format: parseFormat(format),
3259
params: params as Record<string, string>
3360
};
3461

@@ -40,34 +67,30 @@ app.get('/api/og', async (req: Request, res: Response) => {
4067
});
4168
res.send(buffer);
4269
} catch (error) {
43-
console.error('Render error:', error);
4470
res.status(500).send(error instanceof Error ? error.message : 'Internal Server Error');
4571
}
4672
});
4773

4874
app.get('/api/meta', async (req: Request, res: Response) => {
4975
try {
50-
const { template, size = 'og', ...params } = req.query;
76+
const { template, size, ...params } = req.query;
5177

52-
if (!template) {
78+
if (!template || typeof template !== 'string') {
5379
return res.status(400).send('Missing template parameter');
5480
}
5581

5682
const metaReq: MetaRequest = {
57-
template: template as string,
58-
size: size as any,
83+
template,
84+
size: parseSize(size),
5985
params: params as Record<string, string>,
6086
baseUrl: `${req.protocol}://${req.get('host')}`
6187
};
6288

6389
const meta = await handler.handleMetaRequest(metaReq);
6490
res.json(meta);
6591
} catch (error) {
66-
console.error('Meta error:', error);
6792
res.status(500).send(error instanceof Error ? error.message : 'Internal Server Error');
6893
}
6994
});
7095

71-
app.listen(port, () => {
72-
console.log(`Server listening on port ${port}`);
73-
});
96+
app.listen(port);

apps/web/src/app/api/og/route.ts

Lines changed: 37 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,42 @@
11
import { NextRequest } from 'next/server';
22
import { nodeAdapter } from '@og-engine/adapter-node';
33
import { createHandler } from '@og-engine/core';
4-
import type { OGRequest } from '@og-engine/types';
4+
import type { OGRequest, PlatformSize } from '@og-engine/types';
5+
6+
7+
const PLATFORM_SIZES: ReadonlyArray<PlatformSize> = [
8+
'twitter-og',
9+
'facebook-og',
10+
'linkedin-og',
11+
'ig-post',
12+
'ig-story',
13+
'discord',
14+
'whatsapp',
15+
'github',
16+
'og'
17+
];
18+
19+
function parseSize(value: string | null): PlatformSize {
20+
if (value && PLATFORM_SIZES.includes(value as PlatformSize)) {
21+
return value as PlatformSize;
22+
}
23+
24+
return 'og';
25+
}
26+
27+
function parseFormat(value: string | null): OGRequest['format'] {
28+
if (value === 'jpeg' || value === 'png') {
29+
return value;
30+
}
31+
32+
return 'png';
33+
}
534

635
export async function GET(req: NextRequest) {
736
const { searchParams } = new URL(req.url);
837
const template = searchParams.get('template');
9-
const size = searchParams.get('size') || 'og';
10-
const format = searchParams.get('format') || 'png';
38+
const size = searchParams.get('size');
39+
const format = searchParams.get('format');
1140

1241
if (!template) {
1342
return new Response('Missing template', { status: 400 });
@@ -30,23 +59,22 @@ export async function GET(req: NextRequest) {
3059

3160
const ogReq: OGRequest = {
3261
template,
33-
size: size as any,
34-
format: format as any,
62+
size: parseSize(size),
63+
format: parseFormat(format),
3564
params
3665
};
3766

3867
try {
3968
const { buffer, contentType, headers } = await handler.handleImageRequest(ogReq);
4069

41-
return new Response(buffer as any, {
70+
return new Response(buffer as unknown as BodyInit, {
4271
status: 200,
4372
headers: {
4473
'Content-Type': contentType,
4574
...headers
4675
}
4776
});
48-
} catch (err) {
49-
console.error('API Error details:', err);
50-
return new Response(err instanceof Error ? err.message : 'Internal error', { status: 500 });
77+
} catch (error) {
78+
return new Response(error instanceof Error ? error.message : 'Internal error', { status: 500 });
5179
}
5280
}
Lines changed: 23 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,32 @@
1-
import { NextRequest, NextResponse } from 'next/server';
21
import fs from 'node:fs';
32
import path from 'node:path';
3+
import { NextRequest, NextResponse } from 'next/server';
44

55
export async function GET(
6-
request: NextRequest,
7-
{ params }: { params: { id: string } }
6+
_request: NextRequest,
7+
{ params }: { params: Promise<{ id: string }> }
88
) {
9-
const { id } = params;
10-
const previewPath = path.join(process.cwd(), '../../templates', id, 'preview.png');
11-
const fallbackPath = path.join(process.cwd(), '../../templates', id, 'preview.svg');
12-
13-
try {
14-
if (fs.existsSync(previewPath)) {
15-
const buffer = fs.readFileSync(previewPath);
16-
return new NextResponse(buffer, {
17-
headers: { 'Content-Type': 'image/png' },
18-
});
19-
}
9+
const { id } = await params;
10+
const previewPath = path.join(process.cwd(), '../../templates', id, 'preview.png');
11+
const fallbackPath = path.join(process.cwd(), '../../templates', id, 'preview.svg');
2012

21-
if (fs.existsSync(fallbackPath)) {
22-
const buffer = fs.readFileSync(fallbackPath);
23-
return new NextResponse(buffer, {
24-
headers: { 'Content-Type': 'image/svg+xml' },
25-
});
26-
}
13+
try {
14+
if (fs.existsSync(previewPath)) {
15+
const buffer = fs.readFileSync(previewPath);
16+
return new NextResponse(buffer, {
17+
headers: { 'Content-Type': 'image/png' }
18+
});
19+
}
2720

28-
return new NextResponse('Not Found', { status: 404 });
29-
} catch (err) {
30-
return new NextResponse('Internal Error', { status: 500 });
21+
if (fs.existsSync(fallbackPath)) {
22+
const buffer = fs.readFileSync(fallbackPath);
23+
return new NextResponse(buffer, {
24+
headers: { 'Content-Type': 'image/svg+xml' }
25+
});
3126
}
27+
28+
return new NextResponse('Not Found', { status: 404 });
29+
} catch {
30+
return new NextResponse('Internal Error', { status: 500 });
31+
}
3232
}

0 commit comments

Comments
 (0)