@fasl-work/caos-app-shell 0.13.0 → 0.14.0
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.
- package/README.md +9 -1
- package/bin/caos-shell-gate.mjs +74 -72
- package/dist/chart.js +2 -2
- package/dist/{chunk-3QYQCWSZ.js → chunk-YECZXGVG.js} +1 -1
- package/dist/index.d.ts +184 -7
- package/dist/index.js +535 -116
- package/dist/{keys-CTQZafOf.d.ts → keys-DDQGijwQ.d.ts} +5 -3
- package/dist/keys.d.ts +1 -1
- package/dist/keys.js +1 -1
- package/gate/areas.mjs +698 -631
- package/gate/inpage.mjs +1416 -1270
- package/gate/run.mjs +1036 -780
- package/gate/serve.mjs +101 -101
- package/package.json +1 -1
- package/reserved-classes.json +42 -0
- package/src/content/executive.schema.json +659 -659
- package/styles.css +829 -769
- package/dist/{chunk-YVVDBSAC.js → chunk-33WTUQ7Q.js} +1 -1
package/gate/serve.mjs
CHANGED
|
@@ -1,101 +1,101 @@
|
|
|
1
|
-
// A static server that answers the way GitHub Pages does, so a local gate run sees what the deployed site will:
|
|
2
|
-
// an existing file is 200; a directory without a trailing slash is a 301 to the slash; a directory with one serves its
|
|
3
|
-
// index.html; `/name` falls back to `name.html`; anything else is 404 with the site's 404.html. There is no SPA
|
|
4
|
-
// fallback, which is the point: a route that was not materialised, or an artifact missing from the build, fails here
|
|
5
|
-
// exactly as it would on Pages (failure classes 2 and 22: deep links that 404, artifacts answered with HTML).
|
|
6
|
-
|
|
7
|
-
import { createServer } from 'node:http';
|
|
8
|
-
import { existsSync, readFileSync, statSync } from 'node:fs';
|
|
9
|
-
import { extname, join, normalize, resolve, sep } from 'node:path';
|
|
10
|
-
|
|
11
|
-
const MIME = {
|
|
12
|
-
'.html': 'text/html; charset=utf-8',
|
|
13
|
-
'.js': 'text/javascript; charset=utf-8',
|
|
14
|
-
'.mjs': 'text/javascript; charset=utf-8',
|
|
15
|
-
'.css': 'text/css; charset=utf-8',
|
|
16
|
-
'.json': 'application/json; charset=utf-8',
|
|
17
|
-
'.geojson': 'application/geo+json',
|
|
18
|
-
'.svg': 'image/svg+xml',
|
|
19
|
-
'.png': 'image/png',
|
|
20
|
-
'.jpg': 'image/jpeg',
|
|
21
|
-
'.jpeg': 'image/jpeg',
|
|
22
|
-
'.webp': 'image/webp',
|
|
23
|
-
'.gif': 'image/gif',
|
|
24
|
-
'.ico': 'image/x-icon',
|
|
25
|
-
'.woff': 'font/woff',
|
|
26
|
-
'.woff2': 'font/woff2',
|
|
27
|
-
'.ttf': 'font/ttf',
|
|
28
|
-
'.txt': 'text/plain; charset=utf-8',
|
|
29
|
-
'.csv': 'text/csv; charset=utf-8',
|
|
30
|
-
'.map': 'application/json',
|
|
31
|
-
'.wasm': 'application/wasm',
|
|
32
|
-
'.webmanifest': 'application/manifest+json',
|
|
33
|
-
'.xml': 'application/xml',
|
|
34
|
-
};
|
|
35
|
-
|
|
36
|
-
/**
|
|
37
|
-
* @param {string} dir the built site
|
|
38
|
-
* @param {string} basePath the site's base path ('/' for a custom domain, '/Repo/' for a project page)
|
|
39
|
-
* @param {number} port 0 for any free port (the gate), or a fixed one (a product's preview)
|
|
40
|
-
* @returns {Promise<{ url: string, close: () => Promise<void> }>}
|
|
41
|
-
*/
|
|
42
|
-
export function servePages(dir, basePath = '/', port = 0) {
|
|
43
|
-
const root = resolve(dir);
|
|
44
|
-
const base = basePath.endsWith('/') ? basePath : `${basePath}/`;
|
|
45
|
-
const notFound = join(root, '404.html');
|
|
46
|
-
const server = createServer((req, res) => {
|
|
47
|
-
const send = (status, file, headers = {}) => {
|
|
48
|
-
res.writeHead(status, { 'Content-Type': MIME[extname(file).toLowerCase()] ?? 'application/octet-stream', 'Cache-Control': 'no-store', ...headers });
|
|
49
|
-
res.end(req.method === 'HEAD' ? undefined : readFileSync(file));
|
|
50
|
-
};
|
|
51
|
-
const missing = () => {
|
|
52
|
-
if (existsSync(notFound)) send(404, notFound);
|
|
53
|
-
else {
|
|
54
|
-
res.writeHead(404, { 'Content-Type': 'text/plain' });
|
|
55
|
-
res.end('404');
|
|
56
|
-
}
|
|
57
|
-
};
|
|
58
|
-
let path;
|
|
59
|
-
let search = '';
|
|
60
|
-
try {
|
|
61
|
-
const u = new URL(req.url ?? '/', 'http://x');
|
|
62
|
-
path = decodeURIComponent(u.pathname);
|
|
63
|
-
search = u.search;
|
|
64
|
-
} catch {
|
|
65
|
-
return missing();
|
|
66
|
-
}
|
|
67
|
-
if (`${path}/` === base) {
|
|
68
|
-
res.writeHead(301, { Location: base });
|
|
69
|
-
return res.end();
|
|
70
|
-
}
|
|
71
|
-
if (!path.startsWith(base)) return missing();
|
|
72
|
-
const rel = path.slice(base.length);
|
|
73
|
-
const file = normalize(join(root, rel));
|
|
74
|
-
if (file !== root && !file.startsWith(root + sep)) return missing();
|
|
75
|
-
if (existsSync(file)) {
|
|
76
|
-
const st = statSync(file);
|
|
77
|
-
if (st.isFile()) return send(200, file);
|
|
78
|
-
if (st.isDirectory()) {
|
|
79
|
-
const index = join(file, 'index.html');
|
|
80
|
-
if (!existsSync(index)) return missing();
|
|
81
|
-
if (!path.endsWith('/')) {
|
|
82
|
-
// the query string survives the redirect, as a Pages host keeps it (an old link /app?case=B2 must reach its case)
|
|
83
|
-
res.writeHead(301, { Location: `${path}/${search}` });
|
|
84
|
-
return res.end();
|
|
85
|
-
}
|
|
86
|
-
return send(200, index);
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
if (!path.endsWith('/') && existsSync(`${file}.html`)) return send(200, `${file}.html`);
|
|
90
|
-
return missing();
|
|
91
|
-
});
|
|
92
|
-
return new Promise((ok) => {
|
|
93
|
-
server.listen(port, '127.0.0.1', () => {
|
|
94
|
-
const { port } = server.address();
|
|
95
|
-
ok({
|
|
96
|
-
url: `http://127.0.0.1:${port}${base}`,
|
|
97
|
-
close: () => new Promise((done) => server.close(() => done())),
|
|
98
|
-
});
|
|
99
|
-
});
|
|
100
|
-
});
|
|
101
|
-
}
|
|
1
|
+
// A static server that answers the way GitHub Pages does, so a local gate run sees what the deployed site will:
|
|
2
|
+
// an existing file is 200; a directory without a trailing slash is a 301 to the slash; a directory with one serves its
|
|
3
|
+
// index.html; `/name` falls back to `name.html`; anything else is 404 with the site's 404.html. There is no SPA
|
|
4
|
+
// fallback, which is the point: a route that was not materialised, or an artifact missing from the build, fails here
|
|
5
|
+
// exactly as it would on Pages (failure classes 2 and 22: deep links that 404, artifacts answered with HTML).
|
|
6
|
+
|
|
7
|
+
import { createServer } from 'node:http';
|
|
8
|
+
import { existsSync, readFileSync, statSync } from 'node:fs';
|
|
9
|
+
import { extname, join, normalize, resolve, sep } from 'node:path';
|
|
10
|
+
|
|
11
|
+
const MIME = {
|
|
12
|
+
'.html': 'text/html; charset=utf-8',
|
|
13
|
+
'.js': 'text/javascript; charset=utf-8',
|
|
14
|
+
'.mjs': 'text/javascript; charset=utf-8',
|
|
15
|
+
'.css': 'text/css; charset=utf-8',
|
|
16
|
+
'.json': 'application/json; charset=utf-8',
|
|
17
|
+
'.geojson': 'application/geo+json',
|
|
18
|
+
'.svg': 'image/svg+xml',
|
|
19
|
+
'.png': 'image/png',
|
|
20
|
+
'.jpg': 'image/jpeg',
|
|
21
|
+
'.jpeg': 'image/jpeg',
|
|
22
|
+
'.webp': 'image/webp',
|
|
23
|
+
'.gif': 'image/gif',
|
|
24
|
+
'.ico': 'image/x-icon',
|
|
25
|
+
'.woff': 'font/woff',
|
|
26
|
+
'.woff2': 'font/woff2',
|
|
27
|
+
'.ttf': 'font/ttf',
|
|
28
|
+
'.txt': 'text/plain; charset=utf-8',
|
|
29
|
+
'.csv': 'text/csv; charset=utf-8',
|
|
30
|
+
'.map': 'application/json',
|
|
31
|
+
'.wasm': 'application/wasm',
|
|
32
|
+
'.webmanifest': 'application/manifest+json',
|
|
33
|
+
'.xml': 'application/xml',
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* @param {string} dir the built site
|
|
38
|
+
* @param {string} basePath the site's base path ('/' for a custom domain, '/Repo/' for a project page)
|
|
39
|
+
* @param {number} port 0 for any free port (the gate), or a fixed one (a product's preview)
|
|
40
|
+
* @returns {Promise<{ url: string, close: () => Promise<void> }>}
|
|
41
|
+
*/
|
|
42
|
+
export function servePages(dir, basePath = '/', port = 0) {
|
|
43
|
+
const root = resolve(dir);
|
|
44
|
+
const base = basePath.endsWith('/') ? basePath : `${basePath}/`;
|
|
45
|
+
const notFound = join(root, '404.html');
|
|
46
|
+
const server = createServer((req, res) => {
|
|
47
|
+
const send = (status, file, headers = {}) => {
|
|
48
|
+
res.writeHead(status, { 'Content-Type': MIME[extname(file).toLowerCase()] ?? 'application/octet-stream', 'Cache-Control': 'no-store', ...headers });
|
|
49
|
+
res.end(req.method === 'HEAD' ? undefined : readFileSync(file));
|
|
50
|
+
};
|
|
51
|
+
const missing = () => {
|
|
52
|
+
if (existsSync(notFound)) send(404, notFound);
|
|
53
|
+
else {
|
|
54
|
+
res.writeHead(404, { 'Content-Type': 'text/plain' });
|
|
55
|
+
res.end('404');
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
let path;
|
|
59
|
+
let search = '';
|
|
60
|
+
try {
|
|
61
|
+
const u = new URL(req.url ?? '/', 'http://x');
|
|
62
|
+
path = decodeURIComponent(u.pathname);
|
|
63
|
+
search = u.search;
|
|
64
|
+
} catch {
|
|
65
|
+
return missing();
|
|
66
|
+
}
|
|
67
|
+
if (`${path}/` === base) {
|
|
68
|
+
res.writeHead(301, { Location: base });
|
|
69
|
+
return res.end();
|
|
70
|
+
}
|
|
71
|
+
if (!path.startsWith(base)) return missing();
|
|
72
|
+
const rel = path.slice(base.length);
|
|
73
|
+
const file = normalize(join(root, rel));
|
|
74
|
+
if (file !== root && !file.startsWith(root + sep)) return missing();
|
|
75
|
+
if (existsSync(file)) {
|
|
76
|
+
const st = statSync(file);
|
|
77
|
+
if (st.isFile()) return send(200, file);
|
|
78
|
+
if (st.isDirectory()) {
|
|
79
|
+
const index = join(file, 'index.html');
|
|
80
|
+
if (!existsSync(index)) return missing();
|
|
81
|
+
if (!path.endsWith('/')) {
|
|
82
|
+
// the query string survives the redirect, as a Pages host keeps it (an old link /app?case=B2 must reach its case)
|
|
83
|
+
res.writeHead(301, { Location: `${path}/${search}` });
|
|
84
|
+
return res.end();
|
|
85
|
+
}
|
|
86
|
+
return send(200, index);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
if (!path.endsWith('/') && existsSync(`${file}.html`)) return send(200, `${file}.html`);
|
|
90
|
+
return missing();
|
|
91
|
+
});
|
|
92
|
+
return new Promise((ok) => {
|
|
93
|
+
server.listen(port, '127.0.0.1', () => {
|
|
94
|
+
const { port } = server.address();
|
|
95
|
+
ok({
|
|
96
|
+
url: `http://127.0.0.1:${port}${base}`,
|
|
97
|
+
close: () => new Promise((done) => server.close(() => done())),
|
|
98
|
+
});
|
|
99
|
+
});
|
|
100
|
+
});
|
|
101
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fasl-work/caos-app-shell",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.14.0",
|
|
4
4
|
"description": "Shared web-app shell, workbench primitives, content primitives, design system and measured gate for the CAOS / Faena public apps (ADR-0016, ADR-0017, ADR-0071).",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Felipe Santibáñez-Leal",
|
package/reserved-classes.json
CHANGED
|
@@ -22,6 +22,7 @@
|
|
|
22
22
|
"caos-architecture-diagram",
|
|
23
23
|
"caos-badges",
|
|
24
24
|
"caos-bars",
|
|
25
|
+
"caos-card",
|
|
25
26
|
"caos-chart",
|
|
26
27
|
"caos-chart-key",
|
|
27
28
|
"caos-chart-legend",
|
|
@@ -33,8 +34,15 @@
|
|
|
33
34
|
"caos-chipgroup-label",
|
|
34
35
|
"caos-cw",
|
|
35
36
|
"caos-cw-context",
|
|
37
|
+
"caos-cw-focus",
|
|
36
38
|
"caos-cw-panel",
|
|
37
39
|
"caos-cw-panel-head",
|
|
40
|
+
"caos-deck",
|
|
41
|
+
"caos-deck-bar",
|
|
42
|
+
"caos-deck-btn",
|
|
43
|
+
"caos-deck-card",
|
|
44
|
+
"caos-deck-position",
|
|
45
|
+
"caos-deck-track",
|
|
38
46
|
"caos-doc-reference-list",
|
|
39
47
|
"caos-doc-references",
|
|
40
48
|
"caos-doc-section",
|
|
@@ -82,11 +90,24 @@
|
|
|
82
90
|
"caos-exec-title",
|
|
83
91
|
"caos-exec-value",
|
|
84
92
|
"caos-field",
|
|
93
|
+
"caos-flip",
|
|
94
|
+
"caos-flip-back",
|
|
95
|
+
"caos-flip-content",
|
|
96
|
+
"caos-flip-face",
|
|
97
|
+
"caos-flip-front",
|
|
98
|
+
"caos-flip-icon",
|
|
99
|
+
"caos-flip-inner",
|
|
100
|
+
"caos-flip-return",
|
|
101
|
+
"caos-flip-return-title",
|
|
102
|
+
"caos-flip-title",
|
|
103
|
+
"caos-flip-toggle",
|
|
85
104
|
"caos-focus-actions",
|
|
105
|
+
"caos-focus-enter",
|
|
86
106
|
"caos-focus-hud",
|
|
87
107
|
"caos-focus-instrument",
|
|
88
108
|
"caos-focus-label",
|
|
89
109
|
"caos-focus-rail",
|
|
110
|
+
"caos-focus-rail-body",
|
|
90
111
|
"caos-focus-shell",
|
|
91
112
|
"caos-focus-stage",
|
|
92
113
|
"caos-gauge-dot",
|
|
@@ -306,6 +327,7 @@
|
|
|
306
327
|
"caos-architecture-diagram",
|
|
307
328
|
"caos-badges",
|
|
308
329
|
"caos-bars",
|
|
330
|
+
"caos-card",
|
|
309
331
|
"caos-chart",
|
|
310
332
|
"caos-chart-key",
|
|
311
333
|
"caos-chart-legend",
|
|
@@ -318,8 +340,15 @@
|
|
|
318
340
|
"caos-col-text",
|
|
319
341
|
"caos-cw",
|
|
320
342
|
"caos-cw-context",
|
|
343
|
+
"caos-cw-focus",
|
|
321
344
|
"caos-cw-panel",
|
|
322
345
|
"caos-cw-panel-head",
|
|
346
|
+
"caos-deck",
|
|
347
|
+
"caos-deck-bar",
|
|
348
|
+
"caos-deck-btn",
|
|
349
|
+
"caos-deck-card",
|
|
350
|
+
"caos-deck-position",
|
|
351
|
+
"caos-deck-track",
|
|
323
352
|
"caos-doc-reference-list",
|
|
324
353
|
"caos-doc-references",
|
|
325
354
|
"caos-doc-section",
|
|
@@ -367,11 +396,24 @@
|
|
|
367
396
|
"caos-exec-title",
|
|
368
397
|
"caos-exec-value",
|
|
369
398
|
"caos-field",
|
|
399
|
+
"caos-flip",
|
|
400
|
+
"caos-flip-back",
|
|
401
|
+
"caos-flip-content",
|
|
402
|
+
"caos-flip-face",
|
|
403
|
+
"caos-flip-front",
|
|
404
|
+
"caos-flip-icon",
|
|
405
|
+
"caos-flip-inner",
|
|
406
|
+
"caos-flip-return",
|
|
407
|
+
"caos-flip-return-title",
|
|
408
|
+
"caos-flip-title",
|
|
409
|
+
"caos-flip-toggle",
|
|
370
410
|
"caos-focus-actions",
|
|
411
|
+
"caos-focus-enter",
|
|
371
412
|
"caos-focus-hud",
|
|
372
413
|
"caos-focus-instrument",
|
|
373
414
|
"caos-focus-label",
|
|
374
415
|
"caos-focus-rail",
|
|
416
|
+
"caos-focus-rail-body",
|
|
375
417
|
"caos-focus-shell",
|
|
376
418
|
"caos-focus-stage",
|
|
377
419
|
"caos-gauge-dot",
|