@davaux/multisite 0.8.0 → 0.8.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (73) hide show
  1. package/dist/build.d.ts +44 -0
  2. package/dist/build.d.ts.map +1 -0
  3. package/dist/build.js +136 -0
  4. package/dist/build.js.map +1 -0
  5. package/dist/index.d.ts +202 -0
  6. package/dist/index.d.ts.map +1 -0
  7. package/dist/index.js +944 -0
  8. package/dist/index.js.map +1 -0
  9. package/dist/test/fixtures/base/routes/_layout.d.ts +3 -0
  10. package/dist/test/fixtures/base/routes/_layout.d.ts.map +1 -0
  11. package/dist/test/fixtures/base/routes/_layout.js +6 -0
  12. package/dist/test/fixtures/base/routes/_layout.js.map +1 -0
  13. package/dist/test/fixtures/base/routes/about.page.d.ts +3 -0
  14. package/dist/test/fixtures/base/routes/about.page.d.ts.map +1 -0
  15. package/dist/test/fixtures/base/routes/about.page.js +3 -0
  16. package/dist/test/fixtures/base/routes/about.page.js.map +1 -0
  17. package/dist/test/fixtures/base/routes/index.page.d.ts +3 -0
  18. package/dist/test/fixtures/base/routes/index.page.d.ts.map +1 -0
  19. package/dist/test/fixtures/base/routes/index.page.js +3 -0
  20. package/dist/test/fixtures/base/routes/index.page.js.map +1 -0
  21. package/dist/test/fixtures/site-a/routes/_layout.d.ts +3 -0
  22. package/dist/test/fixtures/site-a/routes/_layout.d.ts.map +1 -0
  23. package/dist/test/fixtures/site-a/routes/_layout.js +6 -0
  24. package/dist/test/fixtures/site-a/routes/_layout.js.map +1 -0
  25. package/dist/test/fixtures/site-a/routes/_middleware.d.ts +3 -0
  26. package/dist/test/fixtures/site-a/routes/_middleware.d.ts.map +1 -0
  27. package/dist/test/fixtures/site-a/routes/_middleware.js +6 -0
  28. package/dist/test/fixtures/site-a/routes/_middleware.js.map +1 -0
  29. package/dist/test/fixtures/site-a/routes/config.page.d.ts +3 -0
  30. package/dist/test/fixtures/site-a/routes/config.page.d.ts.map +1 -0
  31. package/dist/test/fixtures/site-a/routes/config.page.js +7 -0
  32. package/dist/test/fixtures/site-a/routes/config.page.js.map +1 -0
  33. package/dist/test/fixtures/site-a/routes/index.page.d.ts +3 -0
  34. package/dist/test/fixtures/site-a/routes/index.page.d.ts.map +1 -0
  35. package/dist/test/fixtures/site-a/routes/index.page.js +3 -0
  36. package/dist/test/fixtures/site-a/routes/index.page.js.map +1 -0
  37. package/dist/test/fixtures/site-a/routes/shop.page.d.ts +3 -0
  38. package/dist/test/fixtures/site-a/routes/shop.page.d.ts.map +1 -0
  39. package/dist/test/fixtures/site-a/routes/shop.page.js +3 -0
  40. package/dist/test/fixtures/site-a/routes/shop.page.js.map +1 -0
  41. package/dist/test/fixtures/site-a/routes/state.page.d.ts +3 -0
  42. package/dist/test/fixtures/site-a/routes/state.page.d.ts.map +1 -0
  43. package/dist/test/fixtures/site-a/routes/state.page.js +3 -0
  44. package/dist/test/fixtures/site-a/routes/state.page.js.map +1 -0
  45. package/dist/test/fixtures/site-b/routes/_error.d.ts +3 -0
  46. package/dist/test/fixtures/site-b/routes/_error.d.ts.map +1 -0
  47. package/dist/test/fixtures/site-b/routes/_error.js +3 -0
  48. package/dist/test/fixtures/site-b/routes/_error.js.map +1 -0
  49. package/dist/test/fixtures/site-b/routes/about.page.d.ts +3 -0
  50. package/dist/test/fixtures/site-b/routes/about.page.d.ts.map +1 -0
  51. package/dist/test/fixtures/site-b/routes/about.page.js +3 -0
  52. package/dist/test/fixtures/site-b/routes/about.page.js.map +1 -0
  53. package/dist/test/multisite.test.d.ts +2 -0
  54. package/dist/test/multisite.test.d.ts.map +1 -0
  55. package/dist/test/multisite.test.js +492 -0
  56. package/dist/test/multisite.test.js.map +1 -0
  57. package/package.json +6 -3
  58. package/CLAUDE.md +0 -133
  59. package/src/build.ts +0 -183
  60. package/src/index.ts +0 -1219
  61. package/src/test/fixtures/base/routes/_layout.ts +0 -6
  62. package/src/test/fixtures/base/routes/about.page.ts +0 -3
  63. package/src/test/fixtures/base/routes/index.page.ts +0 -3
  64. package/src/test/fixtures/site-a/routes/_layout.ts +0 -6
  65. package/src/test/fixtures/site-a/routes/_middleware.ts +0 -6
  66. package/src/test/fixtures/site-a/routes/config.page.ts +0 -7
  67. package/src/test/fixtures/site-a/routes/index.page.ts +0 -3
  68. package/src/test/fixtures/site-a/routes/shop.page.ts +0 -3
  69. package/src/test/fixtures/site-a/routes/state.page.ts +0 -3
  70. package/src/test/fixtures/site-b/routes/_error.ts +0 -3
  71. package/src/test/fixtures/site-b/routes/about.page.ts +0 -3
  72. package/src/test/multisite.test.ts +0 -650
  73. package/tsconfig.json +0 -17
@@ -0,0 +1,492 @@
1
+ import assert from 'node:assert/strict';
2
+ import { once } from 'node:events';
3
+ import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from 'node:fs';
4
+ import http from 'node:http';
5
+ import { tmpdir } from 'node:os';
6
+ import { dirname, join } from 'node:path';
7
+ import { after, before, describe, test } from 'node:test';
8
+ import { fileURLToPath } from 'node:url';
9
+ import { buildMultisiteApps, defineSites, dispatchToSite, mergeScanResults, startMultisiteServer, } from '../index.js';
10
+ const FIXTURES = fileURLToPath(new URL('./fixtures', import.meta.url));
11
+ const baseDir = join(FIXTURES, 'base/routes');
12
+ const siteADir = join(FIXTURES, 'site-a/routes');
13
+ const siteBDir = join(FIXTURES, 'site-b/routes');
14
+ // ─── Test helpers ─────────────────────────────────────────────────────────────
15
+ function fix(base, ...parts) {
16
+ return join(base, ...parts);
17
+ }
18
+ function makeRoute(dir, file, urlPattern, type = 'page') {
19
+ const params = [
20
+ ...[...urlPattern.matchAll(/:(\w+)/g)].map((m) => m[1]),
21
+ ...[...urlPattern.matchAll(/\*(\w+)/g)].map((m) => m[1]),
22
+ ];
23
+ return { filePath: fix(dir, file), urlPattern, type, params };
24
+ }
25
+ function makeLayout(dir, file) {
26
+ const filePath = fix(dir, file);
27
+ return { filePath, dirPath: dirname(filePath) };
28
+ }
29
+ function makeMiddleware(dir, file) {
30
+ const filePath = fix(dir, file);
31
+ return { filePath, dirPath: dirname(filePath) };
32
+ }
33
+ function emptyScan() {
34
+ return { routes: [], layouts: [], middlewares: [] };
35
+ }
36
+ function mockReq(options) {
37
+ const { url, host, method = 'GET' } = options;
38
+ return {
39
+ method,
40
+ url,
41
+ headers: { host },
42
+ on(event, listener) {
43
+ if (event === 'end')
44
+ setImmediate(() => listener());
45
+ return this;
46
+ },
47
+ removeListener() {
48
+ return this;
49
+ },
50
+ destroy() {
51
+ return this;
52
+ },
53
+ };
54
+ }
55
+ function mockRes() {
56
+ let status = 200;
57
+ let body = '';
58
+ let sent = false;
59
+ let ended = false;
60
+ const res = {
61
+ get statusCode() {
62
+ return status;
63
+ },
64
+ set statusCode(v) {
65
+ status = v;
66
+ },
67
+ get headersSent() {
68
+ return sent;
69
+ },
70
+ get writableEnded() {
71
+ return ended;
72
+ },
73
+ writeHead(code, _h) {
74
+ status = code;
75
+ sent = true;
76
+ },
77
+ end(data) {
78
+ if (data != null)
79
+ body = typeof data === 'string' ? data : data.toString('utf-8');
80
+ ended = true;
81
+ },
82
+ getHeader: () => undefined,
83
+ setHeader() { },
84
+ };
85
+ return { res, result: () => ({ status, body }) };
86
+ }
87
+ async function siteRequest(sites, options) {
88
+ const req = mockReq(options);
89
+ const { res, result } = mockRes();
90
+ await dispatchToSite(sites, req, res);
91
+ return result();
92
+ }
93
+ function httpGet(port, path, host) {
94
+ return new Promise((resolve, reject) => {
95
+ http
96
+ .get({ hostname: '127.0.0.1', port, path, headers: { host } }, (res) => {
97
+ const chunks = [];
98
+ res.on('data', (c) => chunks.push(c));
99
+ res.on('end', () => resolve({
100
+ status: res.statusCode ?? 0,
101
+ body: Buffer.concat(chunks).toString(),
102
+ type: String(res.headers['content-type'] ?? ''),
103
+ }));
104
+ })
105
+ .on('error', reject);
106
+ });
107
+ }
108
+ // ─── defineSites ──────────────────────────────────────────────────────────────
109
+ describe('defineSites', () => {
110
+ test('returns the config object unchanged (identity)', () => {
111
+ const config = {
112
+ baseDir: '/some/path',
113
+ sites: [{ name: 'a', hostname: 'a.com' }],
114
+ };
115
+ assert.equal(defineSites(config), config);
116
+ });
117
+ });
118
+ // ─── mergeScanResults — unit tests ────────────────────────────────────────────
119
+ describe('mergeScanResults', () => {
120
+ test('overlay route overrides base route at same URL pattern and type', () => {
121
+ const baseIndex = makeRoute(baseDir, 'index.page.ts', '/');
122
+ const overlayIndex = makeRoute(siteADir, 'index.page.ts', '/');
123
+ const merged = mergeScanResults({ ...emptyScan(), routes: [baseIndex] }, { ...emptyScan(), routes: [overlayIndex] });
124
+ assert.equal(merged.routes.length, 1);
125
+ assert.equal(merged.routes[0].filePath, overlayIndex.filePath);
126
+ });
127
+ test('base routes not in overlay are preserved', () => {
128
+ const baseAbout = makeRoute(baseDir, 'about.page.ts', '/about');
129
+ const overlayIndex = makeRoute(siteADir, 'index.page.ts', '/');
130
+ const merged = mergeScanResults({ ...emptyScan(), routes: [baseAbout] }, { ...emptyScan(), routes: [overlayIndex] });
131
+ assert.equal(merged.routes.length, 2);
132
+ const patterns = merged.routes.map((r) => r.urlPattern);
133
+ assert.ok(patterns.includes('/about'));
134
+ assert.ok(patterns.includes('/'));
135
+ });
136
+ test('overlay-only routes are included alongside base routes', () => {
137
+ const baseIndex = makeRoute(baseDir, 'index.page.ts', '/');
138
+ const overlayShop = makeRoute(siteADir, 'shop.page.ts', '/shop');
139
+ const merged = mergeScanResults({ ...emptyScan(), routes: [baseIndex] }, { ...emptyScan(), routes: [overlayShop] });
140
+ assert.equal(merged.routes.length, 2);
141
+ });
142
+ test('merged routes are sorted static before dynamic', () => {
143
+ const dynamicBase = makeRoute(baseDir, 'about.page.ts', '/:slug');
144
+ const staticOverlay = makeRoute(siteADir, 'index.page.ts', '/about');
145
+ const merged = mergeScanResults({ ...emptyScan(), routes: [dynamicBase] }, { ...emptyScan(), routes: [staticOverlay] });
146
+ assert.equal(merged.routes[0].urlPattern, '/about');
147
+ assert.equal(merged.routes[1].urlPattern, '/:slug');
148
+ });
149
+ test('wildcard routes sort after dynamic routes', () => {
150
+ const dynamic = makeRoute(baseDir, 'slug.page.ts', '/:slug');
151
+ const wildcard = makeRoute(baseDir, 'catch.page.ts', '/*all');
152
+ const merged = mergeScanResults({ ...emptyScan(), routes: [wildcard, dynamic] }, emptyScan());
153
+ assert.equal(merged.routes[0].urlPattern, '/:slug');
154
+ assert.equal(merged.routes[1].urlPattern, '/*all');
155
+ });
156
+ test('routes with different types at the same URL pattern are both kept', () => {
157
+ const baseGet = makeRoute(baseDir, 'api.get.ts', '/api', 'get');
158
+ const overlayPost = makeRoute(siteADir, 'api.post.ts', '/api', 'post');
159
+ const merged = mergeScanResults({ ...emptyScan(), routes: [baseGet] }, { ...emptyScan(), routes: [overlayPost] });
160
+ assert.equal(merged.routes.length, 2);
161
+ const types = merged.routes.map((r) => r.type);
162
+ assert.ok(types.includes('get'));
163
+ assert.ok(types.includes('post'));
164
+ });
165
+ test('overlay layout at same dirPath replaces base layout', () => {
166
+ const baseLayout = makeLayout(baseDir, '_layout.ts');
167
+ const overlayLayout = makeLayout(siteADir, '_layout.ts');
168
+ // Give them the same dirPath to simulate same-depth override
169
+ const syntheticOverlay = { filePath: overlayLayout.filePath, dirPath: baseLayout.dirPath };
170
+ const merged = mergeScanResults({ ...emptyScan(), layouts: [baseLayout] }, { ...emptyScan(), layouts: [syntheticOverlay] });
171
+ assert.equal(merged.layouts.length, 1);
172
+ assert.equal(merged.layouts[0].filePath, overlayLayout.filePath);
173
+ });
174
+ test('layouts at different dirPaths are both kept', () => {
175
+ const baseLayout = makeLayout(baseDir, '_layout.ts');
176
+ const overlayLayout = makeLayout(siteADir, '_layout.ts');
177
+ // Different dirPaths — both survive
178
+ const merged = mergeScanResults({ ...emptyScan(), layouts: [baseLayout] }, { ...emptyScan(), layouts: [overlayLayout] });
179
+ assert.equal(merged.layouts.length, 2);
180
+ });
181
+ test('overlay middleware at same dirPath replaces base middleware', () => {
182
+ const baseMw = makeMiddleware(baseDir, '_middleware.ts');
183
+ const overlayMw = makeMiddleware(siteADir, '_middleware.ts');
184
+ const syntheticOverlay = { filePath: overlayMw.filePath, dirPath: baseMw.dirPath };
185
+ const merged = mergeScanResults({ ...emptyScan(), middlewares: [baseMw] }, { ...emptyScan(), middlewares: [syntheticOverlay] });
186
+ assert.equal(merged.middlewares.length, 1);
187
+ assert.equal(merged.middlewares[0].filePath, overlayMw.filePath);
188
+ });
189
+ test('base middlewares at non-overlapping dirs are all preserved', () => {
190
+ const baseMw = makeMiddleware(baseDir, '_middleware.ts');
191
+ const baseSubMw = makeMiddleware(join(baseDir, 'admin'), '_middleware.ts');
192
+ const overlayMw = makeMiddleware(siteADir, '_middleware.ts');
193
+ // overlayMw.dirPath !== baseMw.dirPath && != baseSubMw.dirPath — all three survive
194
+ const merged = mergeScanResults({ ...emptyScan(), middlewares: [baseMw, baseSubMw] }, { ...emptyScan(), middlewares: [overlayMw] });
195
+ assert.equal(merged.middlewares.length, 3);
196
+ });
197
+ test('overlay error page wins over base error page', () => {
198
+ const merged = mergeScanResults({ ...emptyScan(), errorPage: fix(baseDir, '_error.ts') }, { ...emptyScan(), errorPage: fix(siteBDir, '_error.ts') });
199
+ assert.equal(merged.errorPage, fix(siteBDir, '_error.ts'));
200
+ });
201
+ test('base error page used when overlay has none', () => {
202
+ const merged = mergeScanResults({ ...emptyScan(), errorPage: fix(baseDir, '_error.ts') }, emptyScan());
203
+ assert.equal(merged.errorPage, fix(baseDir, '_error.ts'));
204
+ });
205
+ });
206
+ // ─── buildMultisiteApps + dispatchToSite — integration tests ─────────────────
207
+ describe('buildMultisiteApps', () => {
208
+ test('base route is served when site has no override', async () => {
209
+ const sites = await buildMultisiteApps(defineSites({
210
+ baseDir,
211
+ sites: [{ name: 'site-a', hostname: 'site-a.com', routesDir: siteADir }],
212
+ }));
213
+ // /about exists only in base; site-a does not override it
214
+ const { status, body } = await siteRequest(sites, { url: '/about', host: 'site-a.com' });
215
+ assert.equal(status, 200);
216
+ assert.ok(body.includes('About (base)'));
217
+ });
218
+ test('site route overrides base route at same URL', async () => {
219
+ const sites = await buildMultisiteApps(defineSites({
220
+ baseDir,
221
+ sites: [{ name: 'site-a', hostname: 'site-a.com', routesDir: siteADir }],
222
+ }));
223
+ const { status, body } = await siteRequest(sites, { url: '/', host: 'site-a.com' });
224
+ assert.equal(status, 200);
225
+ assert.ok(body.includes('Home (site-a)'));
226
+ assert.ok(!body.includes('Home (base)'));
227
+ });
228
+ test('site-unique route is served', async () => {
229
+ const sites = await buildMultisiteApps(defineSites({
230
+ baseDir,
231
+ sites: [{ name: 'site-a', hostname: 'site-a.com', routesDir: siteADir }],
232
+ }));
233
+ const { status, body } = await siteRequest(sites, { url: '/shop', host: 'site-a.com' });
234
+ assert.equal(status, 200);
235
+ assert.ok(body.includes('Shop (site-a)'));
236
+ });
237
+ test('site-b gets its own override of /about', async () => {
238
+ const sites = await buildMultisiteApps(defineSites({
239
+ baseDir,
240
+ sites: [
241
+ { name: 'site-a', hostname: 'site-a.com', routesDir: siteADir },
242
+ { name: 'site-b', hostname: 'site-b.com', routesDir: siteBDir },
243
+ ],
244
+ }));
245
+ const a = await siteRequest(sites, { url: '/about', host: 'site-a.com' });
246
+ const b = await siteRequest(sites, { url: '/about', host: 'site-b.com' });
247
+ assert.ok(a.body.includes('About (base)'));
248
+ assert.ok(b.body.includes('About (site-b)'));
249
+ });
250
+ test('hostname dispatch routes to the correct site', async () => {
251
+ const sites = await buildMultisiteApps(defineSites({
252
+ baseDir,
253
+ sites: [
254
+ { name: 'site-a', hostname: 'site-a.com', routesDir: siteADir },
255
+ { name: 'site-b', hostname: 'site-b.com', routesDir: siteBDir },
256
+ ],
257
+ }));
258
+ const a = await siteRequest(sites, { url: '/', host: 'site-a.com' });
259
+ const b = await siteRequest(sites, { url: '/', host: 'site-b.com' });
260
+ assert.ok(a.body.includes('Home (site-a)'));
261
+ assert.ok(b.body.includes('Home (base)')); // site-b has no index override
262
+ });
263
+ test('wildcard fallback site handles unknown hosts', async () => {
264
+ const sites = await buildMultisiteApps(defineSites({
265
+ baseDir,
266
+ sites: [{ name: 'default', hostname: '*', routesDir: siteADir }],
267
+ }));
268
+ const { status, body } = await siteRequest(sites, { url: '/', host: 'unknown.com' });
269
+ assert.equal(status, 200);
270
+ assert.ok(body.includes('Home (site-a)'));
271
+ });
272
+ test('dispatchToSite returns false for unregistered host with no wildcard', async () => {
273
+ const sites = await buildMultisiteApps(defineSites({
274
+ baseDir,
275
+ sites: [{ name: 'site-a', hostname: 'site-a.com', routesDir: siteADir }],
276
+ }));
277
+ const req = mockReq({ url: '/', host: 'other.com' });
278
+ const { res } = mockRes();
279
+ const handled = await dispatchToSite(sites, req, res);
280
+ assert.equal(handled, false);
281
+ });
282
+ test('dispatchToSite returns true when a site handles the request', async () => {
283
+ const sites = await buildMultisiteApps(defineSites({
284
+ baseDir,
285
+ sites: [{ name: 'site-a', hostname: 'site-a.com', routesDir: siteADir }],
286
+ }));
287
+ const req = mockReq({ url: '/', host: 'site-a.com' });
288
+ const { res } = mockRes();
289
+ const handled = await dispatchToSite(sites, req, res);
290
+ assert.equal(handled, true);
291
+ });
292
+ test('site config is accessible via getSite in a route handler', async () => {
293
+ const sites = await buildMultisiteApps(defineSites({
294
+ sites: [
295
+ {
296
+ name: 'site-a',
297
+ hostname: 'site-a.com',
298
+ routesDir: siteADir,
299
+ config: { name: 'My Site A' },
300
+ },
301
+ ],
302
+ }));
303
+ const { status, body } = await siteRequest(sites, { url: '/config', host: 'site-a.com' });
304
+ assert.equal(status, 200);
305
+ assert.ok(body.includes('site-config:My Site A'));
306
+ });
307
+ test('getSite returns undefined when site has no config', async () => {
308
+ const sites = await buildMultisiteApps(defineSites({
309
+ sites: [{ name: 'site-a', hostname: 'site-a.com', routesDir: siteADir }],
310
+ }));
311
+ const { body } = await siteRequest(sites, { url: '/config', host: 'site-a.com' });
312
+ assert.ok(body.includes('site-config:none'));
313
+ });
314
+ test('site with no routesDir serves only base routes', async () => {
315
+ const sites = await buildMultisiteApps(defineSites({
316
+ baseDir,
317
+ sites: [{ name: 'docs', hostname: 'docs.com' }],
318
+ }));
319
+ const { status, body } = await siteRequest(sites, { url: '/about', host: 'docs.com' });
320
+ assert.equal(status, 200);
321
+ assert.ok(body.includes('About (base)'));
322
+ });
323
+ test('site with no baseDir serves only its own routes', async () => {
324
+ const sites = await buildMultisiteApps(defineSites({
325
+ sites: [{ name: 'site-a', hostname: 'site-a.com', routesDir: siteADir }],
326
+ }));
327
+ // /about is only in base — 404 when no baseDir
328
+ const notFound = await siteRequest(sites, { url: '/about', host: 'site-a.com' });
329
+ assert.equal(notFound.status, 404);
330
+ // /shop is site-a-only — should work
331
+ const found = await siteRequest(sites, { url: '/shop', host: 'site-a.com' });
332
+ assert.ok(found.body.includes('Shop (site-a)'));
333
+ });
334
+ test('site-b custom error page is used for 404s on site-b', async () => {
335
+ const sites = await buildMultisiteApps(defineSites({
336
+ baseDir,
337
+ sites: [{ name: 'site-b', hostname: 'site-b.com', routesDir: siteBDir }],
338
+ }));
339
+ const { status, body } = await siteRequest(sites, { url: '/nonexistent', host: 'site-b.com' });
340
+ assert.equal(status, 404);
341
+ assert.ok(body.includes('site-b error: 404'));
342
+ });
343
+ test('multiple hostnames on one site all resolve to the same app', async () => {
344
+ const sites = await buildMultisiteApps(defineSites({
345
+ baseDir,
346
+ sites: [
347
+ {
348
+ name: 'site-a',
349
+ hostname: ['site-a.com', 'www.site-a.com'],
350
+ routesDir: siteADir,
351
+ },
352
+ ],
353
+ }));
354
+ const a1 = await siteRequest(sites, { url: '/', host: 'site-a.com' });
355
+ const a2 = await siteRequest(sites, { url: '/', host: 'www.site-a.com' });
356
+ assert.equal(a1.body, a2.body);
357
+ assert.ok(a1.body.includes('Home (site-a)'));
358
+ });
359
+ test('port in Host header is stripped for hostname matching', async () => {
360
+ const sites = await buildMultisiteApps(defineSites({
361
+ baseDir,
362
+ sites: [{ name: 'site-a', hostname: 'site-a.com', routesDir: siteADir }],
363
+ }));
364
+ const { status, body } = await siteRequest(sites, { url: '/', host: 'site-a.com:3000' });
365
+ assert.equal(status, 200);
366
+ assert.ok(body.includes('Home (site-a)'));
367
+ });
368
+ test('site middleware runs and sets state for its routes', async () => {
369
+ const sites = await buildMultisiteApps(defineSites({
370
+ baseDir,
371
+ sites: [{ name: 'site-a', hostname: 'site-a.com', routesDir: siteADir }],
372
+ }));
373
+ // site-a's _middleware.ts sets ctx.state.visited = 'site-a'
374
+ const { body } = await siteRequest(sites, { url: '/state', host: 'site-a.com' });
375
+ assert.ok(body.includes('state:site-a'));
376
+ });
377
+ });
378
+ // ─── startMultisiteServer — HTTP integration tests ────────────────────────────
379
+ describe('startMultisiteServer', () => {
380
+ let server;
381
+ let serverPort;
382
+ let tmpDir;
383
+ before(async () => {
384
+ tmpDir = mkdtempSync(join(tmpdir(), 'davaux-ms-test-'));
385
+ // Pre-built assets for site-a (production mode picks these up automatically)
386
+ mkdirSync(join(tmpDir, '_davaux', 'site-a'), { recursive: true });
387
+ writeFileSync(join(tmpDir, '_davaux', 'site-a', 'islands.js'), '/* islands-a */');
388
+ writeFileSync(join(tmpDir, '_davaux', 'site-a', 'client.js'), '/* client-a */');
389
+ writeFileSync(join(tmpDir, '_davaux', 'styles.css'), '/* styles */');
390
+ // Shared public dir
391
+ const sharedPublic = join(tmpDir, 'public');
392
+ mkdirSync(sharedPublic);
393
+ writeFileSync(join(sharedPublic, 'shared.txt'), 'shared-content');
394
+ writeFileSync(join(sharedPublic, 'both.txt'), 'from-shared');
395
+ // Site-a per-site public dir
396
+ const siteAPublic = join(tmpDir, 'site-a-public');
397
+ mkdirSync(siteAPublic);
398
+ writeFileSync(join(siteAPublic, 'sitea.txt'), 'sitea-content');
399
+ writeFileSync(join(siteAPublic, 'both.txt'), 'from-sitea');
400
+ const apps = await buildMultisiteApps(defineSites({
401
+ baseDir,
402
+ publicDir: sharedPublic,
403
+ sites: [
404
+ {
405
+ name: 'site-a',
406
+ hostname: 'site-a.com',
407
+ routesDir: siteADir,
408
+ publicDir: siteAPublic,
409
+ },
410
+ {
411
+ name: 'site-b',
412
+ hostname: 'site-b.com',
413
+ routesDir: siteBDir,
414
+ // no islands, no client, no per-site publicDir
415
+ },
416
+ ],
417
+ }), { isDev: false, cwd: tmpDir });
418
+ server = startMultisiteServer(apps, { port: 0, hostname: '127.0.0.1' });
419
+ await once(server, 'listening');
420
+ serverPort = server.address().port;
421
+ });
422
+ after(() => {
423
+ server?.close();
424
+ rmSync(tmpDir, { recursive: true, force: true });
425
+ });
426
+ test('unknown host with no wildcard returns 404', async () => {
427
+ const { status } = await httpGet(serverPort, '/', 'unknown.com');
428
+ assert.equal(status, 404);
429
+ });
430
+ test('/_davaux/livereload.js returns 200 with JS content-type', async () => {
431
+ const { status, type } = await httpGet(serverPort, '/_davaux/livereload.js', 'site-a.com');
432
+ assert.equal(status, 200);
433
+ assert.ok(type.includes('javascript'));
434
+ });
435
+ test('/_davaux/livereload-worker.js returns 200 with JS content-type', async () => {
436
+ const { status, type } = await httpGet(serverPort, '/_davaux/livereload-worker.js', 'site-a.com');
437
+ assert.equal(status, 200);
438
+ assert.ok(type.includes('javascript'));
439
+ });
440
+ test('/_davaux/islands.js served from islandsPath for site-a', async () => {
441
+ const { status, body } = await httpGet(serverPort, '/_davaux/islands.js', 'site-a.com');
442
+ assert.equal(status, 200);
443
+ assert.ok(body.includes('islands-a'));
444
+ });
445
+ test('/_davaux/islands.js returns 404 for site with no islands file', async () => {
446
+ const { status } = await httpGet(serverPort, '/_davaux/islands.js', 'site-b.com');
447
+ assert.equal(status, 404);
448
+ });
449
+ test('/_davaux/styles.css served from shared stylesPath', async () => {
450
+ const { status, body, type } = await httpGet(serverPort, '/_davaux/styles.css', 'site-a.com');
451
+ assert.equal(status, 200);
452
+ assert.ok(type.includes('css'));
453
+ assert.ok(body.includes('styles'));
454
+ });
455
+ test('/_davaux/client.js served from clientPath for site-a', async () => {
456
+ const { status, body } = await httpGet(serverPort, '/_davaux/client.js', 'site-a.com');
457
+ assert.equal(status, 200);
458
+ assert.ok(body.includes('client-a'));
459
+ });
460
+ test('/_davaux/client.js returns 404 for site with no client file', async () => {
461
+ const { status } = await httpGet(serverPort, '/_davaux/client.js', 'site-b.com');
462
+ assert.equal(status, 404);
463
+ });
464
+ test('static file served from shared publicDir', async () => {
465
+ const { status, body } = await httpGet(serverPort, '/shared.txt', 'site-b.com');
466
+ assert.equal(status, 200);
467
+ assert.equal(body, 'shared-content');
468
+ });
469
+ test('static file served from site-specific publicDir', async () => {
470
+ const { status, body } = await httpGet(serverPort, '/sitea.txt', 'site-a.com');
471
+ assert.equal(status, 200);
472
+ assert.equal(body, 'sitea-content');
473
+ });
474
+ test('per-site publicDir takes priority over shared publicDir', async () => {
475
+ const a = await httpGet(serverPort, '/both.txt', 'site-a.com');
476
+ const b = await httpGet(serverPort, '/both.txt', 'site-b.com');
477
+ assert.equal(a.body, 'from-sitea'); // per-site file wins for site-a
478
+ assert.equal(b.body, 'from-shared'); // shared file used for site-b
479
+ });
480
+ test('path traversal does not serve files outside publicDir', async () => {
481
+ const secret = join(tmpDir, 'secret.txt');
482
+ writeFileSync(secret, 'secret-data');
483
+ const { body } = await httpGet(serverPort, '/../secret.txt', 'site-a.com');
484
+ assert.ok(!body.includes('secret-data'));
485
+ });
486
+ test('routes are dispatched correctly through the server', async () => {
487
+ const { status, body } = await httpGet(serverPort, '/', 'site-a.com');
488
+ assert.equal(status, 200);
489
+ assert.ok(body.includes('Home (site-a)'));
490
+ });
491
+ });
492
+ //# sourceMappingURL=multisite.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"multisite.test.js","sourceRoot":"","sources":["../../src/test/multisite.test.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@davaux/multisite",
3
- "version": "0.8.0",
3
+ "version": "0.8.1",
4
4
  "description": "Multi-site hosting for Davaux — run multiple sites from a single codebase",
5
5
  "type": "module",
6
6
  "author": "David L Dyess II",
@@ -13,6 +13,9 @@
13
13
  "url": "https://codeberg.org/davaux/davaux/issues"
14
14
  },
15
15
  "homepage": "https://codeberg.org/davaux/davaux#readme",
16
+ "files": [
17
+ "dist"
18
+ ],
16
19
  "exports": {
17
20
  ".": {
18
21
  "import": "./dist/index.js",
@@ -29,7 +32,7 @@
29
32
  "test": "node --import tsx/esm --test 'src/test/**/*.test.ts'"
30
33
  },
31
34
  "peerDependencies": {
32
- "davaux": ">=0.8.0",
35
+ "davaux": ">=0.8.1",
33
36
  "esbuild": ">=0.17.0"
34
37
  },
35
38
  "devDependencies": {
@@ -39,4 +42,4 @@
39
42
  "tsx": "^4.22.3",
40
43
  "typescript": "^6.0.3"
41
44
  }
42
- }
45
+ }