Skip to content

Commit 568637e

Browse files
refactor: more things
1 parent 8ae58f3 commit 568637e

File tree

5 files changed

+91
-79
lines changed

5 files changed

+91
-79
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,6 @@
4747
"typescript": "^5.2.2"
4848
},
4949
"dependencies": {
50-
"@kitajs/html": "^2.0.1"
50+
"@kitajs/html": "^2.2.1"
5151
}
5252
}

src/html.ts

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import { Elysia } from 'elysia';
2+
import { isHtml } from './is-html';
3+
import { HtmlOptions } from './options';
4+
5+
export function html(options: HtmlOptions = {}) {
6+
// Defaults
7+
options.contentType ??= 'text/html; charset=utf8';
8+
options.autoDetect ??= true;
9+
options.isHtml ??= isHtml;
10+
options.autoDoctype ??= true;
11+
12+
let instance = new Elysia({ name: '@elysiajs/html' }).derive(() => ({
13+
html(value: string) {
14+
if (options.autoDoctype && !isHtml(value)) {
15+
value = '<!doctype html>' + value;
16+
}
17+
18+
return new Response(value, {
19+
headers: { 'content-type': options.contentType! }
20+
});
21+
}
22+
}));
23+
24+
if (options.autoDetect) {
25+
instance = instance.onAfterHandle(({ set }, response) => {
26+
if (typeof response === 'string' && isHtml(response)) {
27+
set.headers['content-type'] = options.contentType!;
28+
return new Response(response, set);
29+
}
30+
});
31+
}
32+
33+
return instance;
34+
}

src/index.ts

Lines changed: 5 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -1,79 +1,6 @@
1-
import { Elysia } from 'elysia';
1+
export * from './html';
2+
export * from './options';
3+
export * from './is-html';
24

3-
export interface HtmlOptions {
4-
/**
5-
* The content-type of the response.
6-
*
7-
* @default 'text/html; charset=utf8'
8-
*/
9-
contentType?: string;
10-
11-
/**
12-
* Whether to automatically detect HTML content and set the content-type.
13-
*
14-
* @default true
15-
*/
16-
autoDetect?: boolean;
17-
18-
/**
19-
* Whether to automatically add `<!doctype html>` to the response, if not found.
20-
*
21-
* @default true
22-
*/
23-
autoDoctype?: boolean;
24-
25-
/**
26-
* The function used to detect if a string is a html or not. Default
27-
* implementation checks if the strings starts with a doctype or a html tag.
28-
* Implementation is case insensitive.
29-
*
30-
* @default isHtml
31-
*/
32-
isHtml?: (this: void, value: string) => boolean;
33-
}
34-
35-
export function html(options: HtmlOptions = {}) {
36-
// Defaults
37-
options.contentType ??= 'text/html; charset=utf8';
38-
options.autoDetect ??= true;
39-
options.isHtml ??= isHtml;
40-
options.autoDoctype ??= true;
41-
42-
let instance = new Elysia({ name: '@elysiajs/html' }).derive(() => ({
43-
html(value: string) {
44-
if (options.autoDoctype && !isHtml(value)) {
45-
value = doctype + value;
46-
}
47-
48-
return new Response(value, {
49-
headers: { 'content-type': options.contentType! }
50-
});
51-
}
52-
}));
53-
54-
if (options.autoDetect) {
55-
instance = instance.onAfterHandle(({ set }, response) => {
56-
if (typeof response === 'string' && isHtml(response)) {
57-
set.headers['content-type'] = options.contentType!;
58-
return new Response(response, set);
59-
}
60-
});
61-
}
62-
63-
return instance;
64-
}
65-
66-
/**
67-
* The lowercased doctype of HTML.
68-
*/
69-
const doctype = '<!doctype html>';
70-
71-
/**
72-
* Checks if the strings starts with a doctype or a html tag. Implementation is
73-
* case insensitive.
74-
*/
75-
export function isHtml(this: void, value: string) {
76-
// Trims the start and limits the length to the doctype length.
77-
value = value.trimStart().slice(0, doctype.length).toLowerCase();
78-
return value == doctype || value.startsWith('<html>');
79-
}
5+
// We cannot use `export * as Html` because @kitajs/html uses `export =`
6+
export const Html = require('@kitajs/html') as typeof import('@kitajs/html');

src/is-html.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
/**
2+
* There's no real way to validate HTML, so this is a best guess.
3+
*
4+
* @see https://stackoverflow.com/q/1732348
5+
* @see https://stackoverflow.com/q/11229831
6+
*/
7+
export function isHtml(this: void, value: string) {
8+
const length = value.length;
9+
return length > 3 && value[0] === '<' && value[length - 1] === '>';
10+
}

src/options.ts

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
/**
2+
* Options for @elysiajs/html plugin.
3+
*
4+
* @link https://elysiajs.com/plugins/html.html
5+
*/
6+
export interface HtmlOptions {
7+
/**
8+
* The content-type of the response.
9+
*
10+
* @default 'text/html; charset=utf8'
11+
*/
12+
contentType?: string;
13+
14+
/**
15+
* Whether to automatically detect HTML content and set the content-type.
16+
*
17+
* @default true
18+
*/
19+
autoDetect?: boolean;
20+
21+
/**
22+
* Whether to automatically add `<!doctype html>` to the response, if not found.
23+
*
24+
* @default true
25+
*/
26+
autoDoctype?: boolean;
27+
28+
/**
29+
* The function used to detect if a string is a html or not. Default
30+
* implementation if length is greater than 3, starts with `<` and ends
31+
* with `>`.
32+
*
33+
* There's no real way to validate HTML, so this is a best guess.
34+
*
35+
* @see https://stackoverflow.com/q/1732348
36+
* @see https://stackoverflow.com/q/11229831
37+
*
38+
* @default isHtml
39+
*/
40+
isHtml?: (this: void, value: string) => boolean;
41+
}

0 commit comments

Comments
 (0)