sashiko 0.11.4 → 0.12.2
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 +74 -1
- package/dist/core/app.d.ts +16 -0
- package/dist/core/app.d.ts.map +1 -1
- package/dist/core/app.js +55 -3
- package/dist/core/app.js.map +1 -1
- package/dist/core/compiler.d.ts +2 -0
- package/dist/core/compiler.d.ts.map +1 -1
- package/dist/core/compiler.js.map +1 -1
- package/dist/core/context.d.ts +61 -0
- package/dist/core/context.d.ts.map +1 -1
- package/dist/core/context.js +183 -0
- package/dist/core/context.js.map +1 -1
- package/dist/core/index.d.ts +2 -1
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js.map +1 -1
- package/dist/core/inject.d.ts.map +1 -1
- package/dist/core/inject.js +6 -0
- package/dist/core/inject.js.map +1 -1
- package/dist/core/mounted-group.d.ts +5 -0
- package/dist/core/mounted-group.d.ts.map +1 -1
- package/dist/core/mounted-group.js +10 -0
- package/dist/core/mounted-group.js.map +1 -1
- package/dist/core/response.d.ts.map +1 -1
- package/dist/core/response.js +25 -0
- package/dist/core/response.js.map +1 -1
- package/dist/openapi/generate.d.ts.map +1 -1
- package/dist/openapi/generate.js +2 -0
- package/dist/openapi/generate.js.map +1 -1
- package/dist/server/static.d.ts +45 -0
- package/dist/server/static.d.ts.map +1 -0
- package/dist/server/static.js +204 -0
- package/dist/server/static.js.map +1 -0
- package/dist/utils/mime.d.ts +2 -0
- package/dist/utils/mime.d.ts.map +1 -0
- package/dist/utils/mime.js +52 -0
- package/dist/utils/mime.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
import { createReadStream, realpathSync, statSync } from 'node:fs';
|
|
2
|
+
import { realpath, stat } from 'node:fs/promises';
|
|
3
|
+
import { isAbsolute, resolve, sep } from 'node:path';
|
|
4
|
+
import { kRawSend } from '../core/context.js';
|
|
5
|
+
import { HttpError } from '../core/errors.js';
|
|
6
|
+
import { contentTypeFor } from '../utils/mime.js';
|
|
7
|
+
const UNITS = { s: 1, m: 60, h: 3600, d: 86_400 };
|
|
8
|
+
export function parseMaxAge(value) {
|
|
9
|
+
if (value === undefined)
|
|
10
|
+
return 0;
|
|
11
|
+
if (typeof value === 'number') {
|
|
12
|
+
if (!Number.isFinite(value) || value < 0)
|
|
13
|
+
throw new Error(`[sashiko] invalid maxAge ${value}.`);
|
|
14
|
+
return Math.floor(value);
|
|
15
|
+
}
|
|
16
|
+
const m = /^(\d+)\s*([smhd])$/.exec(value.trim());
|
|
17
|
+
if (!m)
|
|
18
|
+
throw new Error(`[sashiko] invalid maxAge "${value}"; use seconds or "10s", "30m", "12h", "7d".`);
|
|
19
|
+
return Number(m[1]) * UNITS[m[2]];
|
|
20
|
+
}
|
|
21
|
+
/** Raiz real (symlinks resolvidos), conferida na configuração: um diretório que não existe falha cedo. */
|
|
22
|
+
export function resolveRoot(root) {
|
|
23
|
+
let real;
|
|
24
|
+
try {
|
|
25
|
+
real = realpathSync(resolve(root));
|
|
26
|
+
}
|
|
27
|
+
catch {
|
|
28
|
+
throw new Error(`[sashiko] static root "${root}" does not exist.`);
|
|
29
|
+
}
|
|
30
|
+
if (!statSync(real).isDirectory())
|
|
31
|
+
throw new Error(`[sashiko] static root "${root}" is not a directory.`);
|
|
32
|
+
return real;
|
|
33
|
+
}
|
|
34
|
+
const notFound = () => new HttpError(404, 'Not Found', 'NOT_FOUND');
|
|
35
|
+
/**
|
|
36
|
+
* Caminho dentro da raiz, ou `undefined` se a requisição tentar sair dela (path traversal) (F-13):
|
|
37
|
+
* byte nulo, barra invertida e segmentos `..` são recusados antes de resolver, e o resultado real
|
|
38
|
+
* (depois de seguir symlinks) precisa continuar dentro da raiz.
|
|
39
|
+
*/
|
|
40
|
+
async function insideRoot(root, relative, dotfiles) {
|
|
41
|
+
if (relative.includes('\0') || relative.includes('\\'))
|
|
42
|
+
return undefined;
|
|
43
|
+
const segments = relative.split('/').filter((s) => s !== '' && s !== '.');
|
|
44
|
+
if (segments.some((s) => s === '..'))
|
|
45
|
+
return undefined;
|
|
46
|
+
if (dotfiles === 'deny' && segments.some((s) => s.startsWith('.')))
|
|
47
|
+
return undefined;
|
|
48
|
+
const candidate = resolve(root, ...segments);
|
|
49
|
+
if (candidate !== root && !candidate.startsWith(root + sep))
|
|
50
|
+
return undefined;
|
|
51
|
+
try {
|
|
52
|
+
const real = await realpath(candidate);
|
|
53
|
+
return real === root || real.startsWith(root + sep) ? real : undefined;
|
|
54
|
+
}
|
|
55
|
+
catch {
|
|
56
|
+
return candidate; // não existe: o stat responde 404 adiante
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
async function fileStat(path) {
|
|
60
|
+
try {
|
|
61
|
+
return await stat(path);
|
|
62
|
+
}
|
|
63
|
+
catch {
|
|
64
|
+
return undefined;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
const etagOf = (s) => `W/"${s.size.toString(16)}-${Math.floor(s.mtimeMs).toString(16)}"`;
|
|
68
|
+
function contentDisposition(name) {
|
|
69
|
+
const ascii = name.replace(/[^\x20-\x7e]/g, '_').replace(/["\\]/g, '_');
|
|
70
|
+
return `attachment; filename="${ascii}"; filename*=UTF-8''${encodeURIComponent(name)}`;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* `bytes=a-b`, `bytes=a-` ou `bytes=-n` sobre `size`. `undefined` = não satisfazível (416); `null` = ignorar
|
|
74
|
+
* e enviar o arquivo inteiro (outra unidade, vários intervalos ou sintaxe que não entendemos, RFC 9110 §14.2).
|
|
75
|
+
*/
|
|
76
|
+
function parseRange(header, size) {
|
|
77
|
+
const value = header.trim();
|
|
78
|
+
if (!/^bytes=/i.test(value) || value.includes(','))
|
|
79
|
+
return null;
|
|
80
|
+
const m = /^bytes=(\d*)-(\d*)$/i.exec(value);
|
|
81
|
+
if (!m)
|
|
82
|
+
return null;
|
|
83
|
+
const [, a, b] = m;
|
|
84
|
+
if (a === '' && b === '')
|
|
85
|
+
return undefined;
|
|
86
|
+
let start;
|
|
87
|
+
let end;
|
|
88
|
+
if (a === '') {
|
|
89
|
+
const n = Number(b);
|
|
90
|
+
if (n === 0)
|
|
91
|
+
return undefined;
|
|
92
|
+
start = Math.max(0, size - n);
|
|
93
|
+
end = size - 1;
|
|
94
|
+
}
|
|
95
|
+
else {
|
|
96
|
+
start = Number(a);
|
|
97
|
+
end = b === '' ? size - 1 : Math.min(Number(b), size - 1);
|
|
98
|
+
}
|
|
99
|
+
return start > end || start >= size ? undefined : { start, end };
|
|
100
|
+
}
|
|
101
|
+
/** Envia um arquivo já resolvido e conferido, com cache condicional e `Range` (F-13). */
|
|
102
|
+
export async function sendResolvedFile(ctx, path, s, opts) {
|
|
103
|
+
const res = ctx.res;
|
|
104
|
+
const type = contentTypeFor(path, opts.mimeTypes);
|
|
105
|
+
const etag = opts.etag === false ? undefined : etagOf(s);
|
|
106
|
+
const modified = opts.lastModified === false ? undefined : new Date(Math.floor(s.mtimeMs / 1000) * 1000);
|
|
107
|
+
if (etag)
|
|
108
|
+
res.setHeader('ETag', etag);
|
|
109
|
+
if (modified)
|
|
110
|
+
res.setHeader('Last-Modified', modified.toUTCString());
|
|
111
|
+
const maxAge = parseMaxAge(opts.maxAge);
|
|
112
|
+
res.setHeader('Cache-Control', opts.noCache ? 'no-cache' : `public, max-age=${maxAge}${opts.immutable ? ', immutable' : ''}`);
|
|
113
|
+
res.setHeader('Accept-Ranges', 'bytes');
|
|
114
|
+
if (opts.download) {
|
|
115
|
+
const name = typeof opts.download === 'string' ? opts.download : (path.split(sep).pop() ?? 'download');
|
|
116
|
+
res.setHeader('Content-Disposition', contentDisposition(name));
|
|
117
|
+
}
|
|
118
|
+
// Condicionais (RFC 9110): If-None-Match prevalece sobre If-Modified-Since.
|
|
119
|
+
const inm = ctx.get('if-none-match');
|
|
120
|
+
const ims = ctx.get('if-modified-since');
|
|
121
|
+
const fresh = inm
|
|
122
|
+
? etag !== undefined && inm.split(',').some((t) => t.trim() === '*' || t.trim().replace(/^W\//, '') === etag.replace(/^W\//, ''))
|
|
123
|
+
: ims !== undefined && modified !== undefined && !Number.isNaN(Date.parse(ims)) && modified.getTime() <= Date.parse(ims);
|
|
124
|
+
if (fresh) {
|
|
125
|
+
res.statusCode = 304;
|
|
126
|
+
res.removeHeader('Content-Type');
|
|
127
|
+
return void res.end();
|
|
128
|
+
}
|
|
129
|
+
let start = 0;
|
|
130
|
+
let end = s.size - 1;
|
|
131
|
+
const rangeHeader = ctx.get('range');
|
|
132
|
+
const ifRange = ctx.get('if-range');
|
|
133
|
+
// Range só vale para GET. If-Range exige comparação forte: nossos ETags são fracos e nunca a satisfazem;
|
|
134
|
+
// uma data precisa ser exatamente o Last-Modified (RFC 9110 §13.1.5).
|
|
135
|
+
const ifRangeOk = !ifRange ||
|
|
136
|
+
(!ifRange.startsWith('"') && !ifRange.startsWith('W/') && modified !== undefined && Date.parse(ifRange) === modified.getTime());
|
|
137
|
+
const rangeApplies = ctx.method === 'GET' && rangeHeader !== undefined && ifRangeOk;
|
|
138
|
+
if (rangeApplies && s.size > 0) {
|
|
139
|
+
const range = parseRange(rangeHeader, s.size);
|
|
140
|
+
if (range === undefined) {
|
|
141
|
+
res.statusCode = 416;
|
|
142
|
+
res.setHeader('Content-Range', `bytes */${s.size}`);
|
|
143
|
+
return void res.end();
|
|
144
|
+
}
|
|
145
|
+
if (range) {
|
|
146
|
+
({ start, end } = range);
|
|
147
|
+
res.statusCode = 206;
|
|
148
|
+
res.setHeader('Content-Range', `bytes ${start}-${end}/${s.size}`);
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
res.setHeader('Content-Length', String(s.size === 0 ? 0 : end - start + 1));
|
|
152
|
+
if (ctx.method === 'HEAD' || s.size === 0) {
|
|
153
|
+
res.setHeader('Content-Type', type);
|
|
154
|
+
return void res.end();
|
|
155
|
+
}
|
|
156
|
+
ctx[kRawSend](createReadStream(path, { start, end }), type);
|
|
157
|
+
}
|
|
158
|
+
/** `ctx.sendFile()`: confere o caminho e envia (F-13). */
|
|
159
|
+
export async function sendFile(ctx, path, opts = {}) {
|
|
160
|
+
// Como `ctx.json()`/`ctx.send()`: depois que a resposta saiu, um novo envio é ignorado (sem mexer nos headers).
|
|
161
|
+
if (ctx.sent)
|
|
162
|
+
return;
|
|
163
|
+
let full;
|
|
164
|
+
if (opts.root !== undefined) {
|
|
165
|
+
full = await insideRoot(resolveRoot(opts.root), path, 'deny');
|
|
166
|
+
}
|
|
167
|
+
else {
|
|
168
|
+
if (!isAbsolute(path))
|
|
169
|
+
throw new Error('[sashiko] ctx.sendFile(): use an absolute path, or pass { root } with a relative one.');
|
|
170
|
+
full = path;
|
|
171
|
+
}
|
|
172
|
+
const s = full ? await fileStat(full) : undefined;
|
|
173
|
+
if (!full || !s?.isFile())
|
|
174
|
+
throw notFound();
|
|
175
|
+
await sendResolvedFile(ctx, full, s, opts);
|
|
176
|
+
}
|
|
177
|
+
/** Handler de `app.static()`: resolve o resto do path dentro da raiz, com índice e fallback de SPA. */
|
|
178
|
+
export function staticHandler(rootInput, opts) {
|
|
179
|
+
const root = resolveRoot(rootInput);
|
|
180
|
+
parseMaxAge(opts.maxAge); // valida já
|
|
181
|
+
const dotfiles = opts.dotfiles ?? 'deny';
|
|
182
|
+
const index = opts.index === undefined ? 'index.html' : opts.index;
|
|
183
|
+
return async (ctx) => {
|
|
184
|
+
const rest = ctx.params['*'] ?? '';
|
|
185
|
+
let full = await insideRoot(root, rest, dotfiles);
|
|
186
|
+
let s = full ? await fileStat(full) : undefined;
|
|
187
|
+
if (full && s?.isDirectory()) {
|
|
188
|
+
full = index ? await insideRoot(root, `${rest}/${index}`, dotfiles) : undefined;
|
|
189
|
+
s = full ? await fileStat(full) : undefined;
|
|
190
|
+
}
|
|
191
|
+
if (full && s?.isFile())
|
|
192
|
+
return sendResolvedFile(ctx, full, s, opts);
|
|
193
|
+
// SPA: só para paths sem extensão, para um asset que falta continuar 404.
|
|
194
|
+
const last = rest.split('/').pop() ?? '';
|
|
195
|
+
if (opts.fallback && full !== undefined && !last.includes('.')) {
|
|
196
|
+
const fb = await insideRoot(root, opts.fallback, 'allow');
|
|
197
|
+
const fs = fb ? await fileStat(fb) : undefined;
|
|
198
|
+
if (fb && fs?.isFile())
|
|
199
|
+
return sendResolvedFile(ctx, fb, fs, { ...opts, noCache: true });
|
|
200
|
+
}
|
|
201
|
+
throw notFound();
|
|
202
|
+
};
|
|
203
|
+
}
|
|
204
|
+
//# sourceMappingURL=static.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"static.js","sourceRoot":"","sources":["../../src/server/static.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mime.d.ts","sourceRoot":"","sources":["../../src/utils/mime.ts"],"names":[],"mappings":"AA+CA,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,GAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAM,GAAG,MAAM,CAKrG"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tipos de conteúdo por extensão, sem dependência (F-13). Cobre o que uma API e uma SPA servem; o resto
|
|
3
|
+
* sai como `application/octet-stream` (com `nosniff`, o navegador não tenta adivinhar). Acrescente tipos
|
|
4
|
+
* com a opção `mimeTypes` do `static()`/`sendFile()`.
|
|
5
|
+
*/
|
|
6
|
+
const TYPES = {
|
|
7
|
+
html: 'text/html',
|
|
8
|
+
htm: 'text/html',
|
|
9
|
+
css: 'text/css',
|
|
10
|
+
js: 'text/javascript',
|
|
11
|
+
mjs: 'text/javascript',
|
|
12
|
+
cjs: 'text/javascript',
|
|
13
|
+
json: 'application/json',
|
|
14
|
+
map: 'application/json',
|
|
15
|
+
webmanifest: 'application/manifest+json',
|
|
16
|
+
txt: 'text/plain',
|
|
17
|
+
md: 'text/markdown',
|
|
18
|
+
csv: 'text/csv',
|
|
19
|
+
xml: 'application/xml',
|
|
20
|
+
yaml: 'application/yaml',
|
|
21
|
+
yml: 'application/yaml',
|
|
22
|
+
svg: 'image/svg+xml',
|
|
23
|
+
png: 'image/png',
|
|
24
|
+
jpg: 'image/jpeg',
|
|
25
|
+
jpeg: 'image/jpeg',
|
|
26
|
+
gif: 'image/gif',
|
|
27
|
+
webp: 'image/webp',
|
|
28
|
+
avif: 'image/avif',
|
|
29
|
+
ico: 'image/x-icon',
|
|
30
|
+
woff: 'font/woff',
|
|
31
|
+
woff2: 'font/woff2',
|
|
32
|
+
ttf: 'font/ttf',
|
|
33
|
+
otf: 'font/otf',
|
|
34
|
+
pdf: 'application/pdf',
|
|
35
|
+
zip: 'application/zip',
|
|
36
|
+
gz: 'application/gzip',
|
|
37
|
+
wasm: 'application/wasm',
|
|
38
|
+
mp4: 'video/mp4',
|
|
39
|
+
webm: 'video/webm',
|
|
40
|
+
mp3: 'audio/mpeg',
|
|
41
|
+
wav: 'audio/wav',
|
|
42
|
+
ogg: 'audio/ogg',
|
|
43
|
+
};
|
|
44
|
+
/** Tipos de texto recebem `charset=utf-8`. */
|
|
45
|
+
const TEXT = /^(text\/|application\/(json|manifest\+json|xml|yaml|javascript))|\+xml$|\+json$/;
|
|
46
|
+
export function contentTypeFor(filename, extra = {}) {
|
|
47
|
+
const dot = filename.lastIndexOf('.');
|
|
48
|
+
const ext = dot === -1 ? '' : filename.slice(dot + 1).toLowerCase();
|
|
49
|
+
const type = extra[ext] ?? TYPES[ext] ?? 'application/octet-stream';
|
|
50
|
+
return TEXT.test(type) && !type.includes('charset') ? `${type}; charset=utf-8` : type;
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=mime.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mime.js","sourceRoot":"","sources":["../../src/utils/mime.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,MAAM,KAAK,GAA2B;IACpC,IAAI,EAAE,WAAW;IACjB,GAAG,EAAE,WAAW;IAChB,GAAG,EAAE,UAAU;IACf,EAAE,EAAE,iBAAiB;IACrB,GAAG,EAAE,iBAAiB;IACtB,GAAG,EAAE,iBAAiB;IACtB,IAAI,EAAE,kBAAkB;IACxB,GAAG,EAAE,kBAAkB;IACvB,WAAW,EAAE,2BAA2B;IACxC,GAAG,EAAE,YAAY;IACjB,EAAE,EAAE,eAAe;IACnB,GAAG,EAAE,UAAU;IACf,GAAG,EAAE,iBAAiB;IACtB,IAAI,EAAE,kBAAkB;IACxB,GAAG,EAAE,kBAAkB;IACvB,GAAG,EAAE,eAAe;IACpB,GAAG,EAAE,WAAW;IAChB,GAAG,EAAE,YAAY;IACjB,IAAI,EAAE,YAAY;IAClB,GAAG,EAAE,WAAW;IAChB,IAAI,EAAE,YAAY;IAClB,IAAI,EAAE,YAAY;IAClB,GAAG,EAAE,cAAc;IACnB,IAAI,EAAE,WAAW;IACjB,KAAK,EAAE,YAAY;IACnB,GAAG,EAAE,UAAU;IACf,GAAG,EAAE,UAAU;IACf,GAAG,EAAE,iBAAiB;IACtB,GAAG,EAAE,iBAAiB;IACtB,EAAE,EAAE,kBAAkB;IACtB,IAAI,EAAE,kBAAkB;IACxB,GAAG,EAAE,WAAW;IAChB,IAAI,EAAE,YAAY;IAClB,GAAG,EAAE,YAAY;IACjB,GAAG,EAAE,WAAW;IAChB,GAAG,EAAE,WAAW;CACjB,CAAC;AAEF,8CAA8C;AAC9C,MAAM,IAAI,GAAG,iFAAiF,CAAC;AAE/F,MAAM,UAAU,cAAc,CAAC,QAAgB,EAAE,KAAK,GAAqC,EAAE;IAC3F,MAAM,GAAG,GAAG,QAAQ,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;IACtC,MAAM,GAAG,GAAG,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;IACpE,MAAM,IAAI,GAAG,KAAK,CAAC,GAAG,CAAC,IAAI,KAAK,CAAC,GAAG,CAAC,IAAI,0BAA0B,CAAC;IACpE,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,iBAAiB,CAAC,CAAC,CAAC,IAAI,CAAC;AACxF,CAAC"}
|