Skip to content

Commit 7f93fb4

Browse files
authored
Merge pull request #890 from live-codes/fixes
Fixes
2 parents b94bd82 + f9e6adf commit 7f93fb4

7 files changed

Lines changed: 54 additions & 37 deletions

File tree

.nvmrc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
v18.20.4
1+
v24.4.1

Dockerfile

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
FROM node:24.1.0-alpine3.21 AS builder
1+
FROM node:24.4.1-alpine3.22 AS builder
22

33
RUN apk update --no-cache && apk add --no-cache git
44

@@ -21,13 +21,14 @@ ARG SANDBOX_HOST_NAME
2121
ARG SANDBOX_PORT
2222
ARG FIREBASE_CONFIG
2323
ARG DOCS_BASE_URL
24+
ARG NODE_OPTIONS
2425

2526
RUN if [ "$DOCS_BASE_URL" == "null" ]; \
2627
then npm run build:app; \
2728
else npm run build; \
2829
fi
2930

30-
FROM node:24.1.0-alpine3.21 AS server
31+
FROM node:24.4.1-alpine3.22 AS server
3132

3233
RUN addgroup -S appgroup
3334
RUN adduser -S appuser -G appgroup

docker-compose.yml

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ services:
1212
- SANDBOX_PORT=${SANDBOX_PORT:-8090}
1313
- FIREBASE_CONFIG=${FIREBASE_CONFIG:-}
1414
- DOCS_BASE_URL=${DOCS_BASE_URL:-null}
15+
- LOCAL_MODULES=${LOCAL_MODULES:-false}
16+
- NODE_OPTIONS=--max-old-space-size=4096
1517
restart: unless-stopped
1618
environment:
1719
- SELF_HOSTED=true
@@ -26,6 +28,7 @@ services:
2628
- LOG_URL=${LOG_URL:-null}
2729
- VALKEY_HOST=valkey
2830
- VALKEY_PORT=6379
31+
- NODE_OPTIONS=--max-old-space-size=4096
2932
volumes:
3033
- ./assets:/srv/build/assets
3134
depends_on:
@@ -38,21 +41,29 @@ services:
3841
- valkey-data:/data
3942
command:
4043
[
41-
'sh',
42-
'-c',
44+
"sh",
45+
"-c",
4346
'if [ "$SELF_HOSTED_SHARE" != "false" ]; then valkey-server --save 60 1 --loglevel warning; fi',
4447
]
4548

4649
server:
4750
image: caddy:2.10.0-alpine
48-
entrypoint: ['/bin/sh', './entrypoint.sh']
49-
command: ['caddy', 'run', '--config', '/etc/caddy/Caddyfile', '--adapter', 'caddyfile']
51+
entrypoint: ["/bin/sh", "./entrypoint.sh"]
52+
command:
53+
[
54+
"caddy",
55+
"run",
56+
"--config",
57+
"/etc/caddy/Caddyfile",
58+
"--adapter",
59+
"caddyfile",
60+
]
5061
restart: unless-stopped
5162
ports:
52-
- '80:80'
53-
- '${PORT:-443}:${PORT:-443}'
54-
- '${SANDBOX_PORT:-8090}:${SANDBOX_PORT:-8090}'
55-
- '${BROADCAST_PORT:-3030}:${BROADCAST_PORT:-3030}'
63+
- "80:80"
64+
- "${PORT:-443}:${PORT:-443}"
65+
- "${SANDBOX_PORT:-8090}:${SANDBOX_PORT:-8090}"
66+
- "${BROADCAST_PORT:-3030}:${BROADCAST_PORT:-3030}"
5667
environment:
5768
- HOST_NAME=${HOST_NAME:-livecodes.localhost}
5869
- PORT=${PORT:-443}

server/src/broadcast/index.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -106,17 +106,17 @@ export const broadcast = ({
106106
});
107107
});
108108

109-
app.get('/channels/:id', (req, res) => {
109+
app.get('/channels/:id', async (req, res) => {
110110
const channel = req.params.id;
111111
if (channels[channel]) {
112112
channels[channel].lastAccessed = Date.now();
113113
const hasData = Object.keys(channels[channel].data || {}).length > 0;
114114
const views = ['index', 'code', 'result'] as const;
115115
const view = req.query.view;
116116
const file = views.find((v) => v === view) || (hasData ? 'index' : 'result');
117-
const fileContent = fs
118-
.readFileSync(path.join(broadcastDir, `/${file}.html`), 'utf-8')
119-
.replaceAll('{{AppUrl}}', appUrl);
117+
const fileContent = (
118+
await fs.promises.readFile(path.join(broadcastDir, `/${file}.html`), 'utf-8')
119+
).replaceAll('{{AppUrl}}', appUrl);
120120
res.status(200).send(fileContent);
121121
} else {
122122
res.status(404).send('Channel not found!');

server/src/sandbox.ts

Lines changed: 21 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3,41 +3,47 @@ import cors from 'cors';
33
import express from 'express';
44
import fs from 'node:fs';
55
import path from 'node:path';
6-
import { sandboxVersion } from '../../src/livecodes/html/sandbox/index.ts';
76
import { dirname } from './utils.ts';
87

9-
export const sandbox = ({ hostname, port }: { hostname: string; port: number }) => {
8+
export const sandbox = async ({ hostname, port }: { hostname: string; port: number }) => {
109
const app = express();
1110

1211
app.use(cors());
1312
app.disable('x-powered-by');
1413

1514
const sandboxDir = path.resolve(dirname, 'sandbox');
16-
let sandboxVersionDir = path.resolve(sandboxDir, sandboxVersion);
17-
fs.readdirSync(sandboxDir).forEach((v) => {
18-
if (fs.statSync(path.resolve(sandboxDir, v)).isDirectory()) {
19-
sandboxVersionDir = path.resolve(sandboxDir, v);
20-
}
21-
});
15+
const dirs = await fs.promises.readdir(sandboxDir);
16+
const version =
17+
dirs
18+
.filter((v) => v.startsWith('v'))
19+
.map((v) => Number(v.slice(1)))
20+
.filter((v) => !Number.isNaN(v))
21+
.sort((a, b) => b - a)
22+
.map((v) => 'v' + v)
23+
.pop() || '';
24+
const sandboxVersionDir = path.resolve(sandboxDir, version);
2225

2326
app.use('/', (req, res) => {
2427
if (req.path === '/') {
2528
res.set('Content-Type', 'text/html');
2629
res.status(200).sendFile(path.resolve(sandboxVersionDir, 'index.html'));
2730
return;
2831
}
29-
const reqPath = req.path.endsWith('/')
32+
let reqPath = req.path.endsWith('/')
3033
? req.path + 'index.html'
3134
: !req.path.split('/').pop()?.includes('.')
3235
? req.path + '.html'
3336
: req.path;
34-
res.set('Content-Type', 'text/html');
35-
const filePath = path.resolve(dirname, 'sandbox' + reqPath);
36-
if (fs.existsSync(filePath)) {
37-
res.status(200).sendFile(filePath);
38-
return;
37+
if (reqPath.startsWith('/')) {
38+
reqPath = reqPath.slice(1);
3939
}
40-
res.status(404).sendFile(path.resolve(sandboxVersionDir, 'index.html'));
40+
const filePath = path.resolve(sandboxDir, reqPath);
41+
const onError = (_err: unknown) => {
42+
if (res.headersSent) return;
43+
res.status(404).sendFile(path.resolve(sandboxVersionDir, 'index.html'));
44+
};
45+
res.set('Content-Type', 'text/html');
46+
res.status(200).sendFile(filePath, onError);
4147
});
4248

4349
app.listen(port, () => {

server/src/utils.ts

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ const getDirname = (metaUrl: string) => path.dirname(fileURLToPath(metaUrl));
1010
export const dirname = getDirname(import.meta.url);
1111
export const appDir = path.resolve(dirname, '../../build/');
1212

13-
const getFileContent = async (fullUrl: string) => {
13+
const getFileContent = (fullUrl: string): Promise<string> => {
1414
let pathname: string;
1515
try {
1616
const url = new URL(fullUrl);
@@ -21,11 +21,10 @@ const getFileContent = async (fullUrl: string) => {
2121
if (!pathname.trim()) {
2222
pathname = 'index.html';
2323
}
24-
let filePath = path.resolve(appDir, pathname);
25-
if (!fs.existsSync(filePath)) {
26-
filePath = path.resolve(appDir, '404.html');
27-
}
28-
return fs.promises.readFile(filePath, 'utf8');
24+
const filePath = path.resolve(appDir, pathname);
25+
return fs.promises
26+
.readFile(filePath, 'utf8')
27+
.catch(() => fs.promises.readFile(path.resolve(appDir, '404.html'), 'utf8'));
2928
};
3029

3130
const convertToWebRequest = (req: express.Request) => {

src/livecodes/styles/inc-menu.scss

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -570,7 +570,7 @@ i.arrow {
570570
width: var(--s16);
571571

572572
&[for='theme-color-custom'] {
573-
background: conic-gradient(in hsl longer hue, red 0 0);
573+
background: conic-gradient(in hsl longer hue, red 0 100%);
574574
filter: contrast(0.5);
575575
}
576576

0 commit comments

Comments
 (0)