@wxn0brp/falcon-frame 0.7.0 → 0.8.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/dist/compress.js +1 -1
- package/dist/cors.d.ts +1 -1
- package/dist/cors.js +53 -17
- package/dist/index.js +6 -2
- package/dist/render.d.ts +9 -2
- package/dist/render.js +28 -7
- package/dist/sse.d.ts +1 -1
- package/dist/types.d.ts +1 -1
- package/package.json +2 -2
package/dist/compress.js
CHANGED
package/dist/cors.d.ts
CHANGED
|
@@ -4,4 +4,4 @@ export interface Opts {
|
|
|
4
4
|
accessControlAllowHeaders?: boolean;
|
|
5
5
|
headers?: Record<string, string>;
|
|
6
6
|
}
|
|
7
|
-
export declare function createCORS(allowedOrigins: string[], opts?: Opts): RouteHandler;
|
|
7
|
+
export declare function createCORS(allowedOrigins: (string | RegExp)[], opts?: Opts): RouteHandler;
|
package/dist/cors.js
CHANGED
|
@@ -4,6 +4,54 @@ function setHeader(res, opts) {
|
|
|
4
4
|
if (opts.accessControlAllowHeaders)
|
|
5
5
|
res.setHeader("Access-Control-Allow-Headers", "Content-Type, Authorization");
|
|
6
6
|
}
|
|
7
|
+
function parseOrigin(origin) {
|
|
8
|
+
try {
|
|
9
|
+
const url = new URL(origin);
|
|
10
|
+
return {
|
|
11
|
+
host: url.hostname,
|
|
12
|
+
port: url.port ||
|
|
13
|
+
(url.protocol === "https:" ? "443" : "80")
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
catch {
|
|
17
|
+
return null;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
function matches(origin, pattern) {
|
|
21
|
+
if (pattern === "*")
|
|
22
|
+
return true;
|
|
23
|
+
if (pattern instanceof RegExp)
|
|
24
|
+
return pattern.test(origin);
|
|
25
|
+
if (pattern.toLowerCase() === origin.toLowerCase())
|
|
26
|
+
return true;
|
|
27
|
+
const o = parseOrigin(origin);
|
|
28
|
+
if (!o)
|
|
29
|
+
return false;
|
|
30
|
+
// *.example.com[:port]
|
|
31
|
+
if (pattern.startsWith("*.")) {
|
|
32
|
+
const [pHost, pPort] = pattern.split(":");
|
|
33
|
+
const base = pHost.slice(2).toLowerCase();
|
|
34
|
+
if (o.host !== base && o.host.endsWith("." + base)) {
|
|
35
|
+
return !pPort || pPort === "*" || pPort === o.port;
|
|
36
|
+
}
|
|
37
|
+
return false;
|
|
38
|
+
}
|
|
39
|
+
// localhost:port
|
|
40
|
+
if (pattern.includes(":")) {
|
|
41
|
+
const [pHost, pPort] = pattern.split(":");
|
|
42
|
+
const base = pHost.toLowerCase();
|
|
43
|
+
return o.host === base && (pPort === "*" || o.port === pPort);
|
|
44
|
+
}
|
|
45
|
+
return false;
|
|
46
|
+
}
|
|
47
|
+
function handleEnd(req, res, next, origin) {
|
|
48
|
+
res.setHeader("Access-Control-Allow-Origin", origin);
|
|
49
|
+
if (req.method === "OPTIONS") {
|
|
50
|
+
res.statusCode = 204;
|
|
51
|
+
return res.end();
|
|
52
|
+
}
|
|
53
|
+
next();
|
|
54
|
+
}
|
|
7
55
|
export function createCORS(allowedOrigins, opts = {}) {
|
|
8
56
|
opts = {
|
|
9
57
|
accessControlAllowMethods: true,
|
|
@@ -16,24 +64,12 @@ export function createCORS(allowedOrigins, opts = {}) {
|
|
|
16
64
|
res.setHeader(key, value);
|
|
17
65
|
}
|
|
18
66
|
}
|
|
19
|
-
|
|
20
|
-
res.setHeader("Access-Control-Allow-Origin", "*");
|
|
21
|
-
setHeader(res, opts);
|
|
22
|
-
if (req.method === "OPTIONS") {
|
|
23
|
-
res.statusCode = 204;
|
|
24
|
-
return res.end();
|
|
25
|
-
}
|
|
26
|
-
return next();
|
|
27
|
-
}
|
|
67
|
+
setHeader(res, opts);
|
|
28
68
|
const origin = req.headers.origin;
|
|
29
|
-
if (
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
res.statusCode = 204;
|
|
34
|
-
return res.end();
|
|
35
|
-
}
|
|
36
|
-
}
|
|
69
|
+
if (allowedOrigins.includes("*"))
|
|
70
|
+
return handleEnd(req, res, next, origin || "*");
|
|
71
|
+
if (origin && allowedOrigins.some((pattern) => matches(origin, pattern)))
|
|
72
|
+
return handleEnd(req, res, next, origin);
|
|
37
73
|
next();
|
|
38
74
|
};
|
|
39
75
|
}
|
package/dist/index.js
CHANGED
|
@@ -43,9 +43,13 @@ export class FalconFrame extends Router {
|
|
|
43
43
|
this.addBodyParser(json({ limit: this.opts.bodyLimit }));
|
|
44
44
|
if (!this.opts.disableUrlencodedParser)
|
|
45
45
|
this.addBodyParser(urlencoded({ limit: this.opts.bodyLimit }));
|
|
46
|
-
this.engine(".html", (path,
|
|
46
|
+
this.engine(".html", (path, data, callback, FF) => {
|
|
47
47
|
try {
|
|
48
|
-
const content = renderHTML(
|
|
48
|
+
const content = renderHTML({
|
|
49
|
+
templatePath: path,
|
|
50
|
+
data,
|
|
51
|
+
FF,
|
|
52
|
+
});
|
|
49
53
|
callback(null, content);
|
|
50
54
|
}
|
|
51
55
|
catch (e) {
|
package/dist/render.d.ts
CHANGED
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
import FalconFrame from "./index.js";
|
|
2
|
-
|
|
2
|
+
import { CombinedVars } from "./types.js";
|
|
3
|
+
export interface RenderHTMLOptions {
|
|
4
|
+
templatePath: string;
|
|
5
|
+
data?: Record<string, any>;
|
|
6
|
+
FF?: FalconFrame<any>;
|
|
3
7
|
noLayout?: boolean;
|
|
8
|
+
FFVar?: CombinedVars<any>;
|
|
9
|
+
/** don't use, used internally */
|
|
10
|
+
_renderedPaths?: string[];
|
|
4
11
|
}
|
|
5
|
-
export declare function renderHTML(
|
|
12
|
+
export declare function renderHTML(options: RenderHTMLOptions): string;
|
package/dist/render.js
CHANGED
|
@@ -1,10 +1,14 @@
|
|
|
1
1
|
import fs from "fs";
|
|
2
2
|
import path from "path";
|
|
3
|
-
export function renderHTML(
|
|
3
|
+
export function renderHTML(options) {
|
|
4
4
|
try {
|
|
5
|
+
let data = options.data || {};
|
|
6
|
+
const { templatePath, _renderedPaths: renderedPaths = [], FF, noLayout, FFVar, } = options;
|
|
5
7
|
const realPath = path.resolve(templatePath);
|
|
6
8
|
if (renderedPaths.includes(realPath))
|
|
7
9
|
return `<!-- Circular dependency detected: tried to render ${templatePath} again -->`;
|
|
10
|
+
if (!fs.existsSync(templatePath))
|
|
11
|
+
return `<!-- Template not found: ${templatePath} -->`;
|
|
8
12
|
let template = fs.readFileSync(templatePath, "utf8");
|
|
9
13
|
// Loading internal data, e.g. <!-- data { "title": "My title" } -->
|
|
10
14
|
const templateDataMatch = template.match(/<!--\s*data\s*(\{.*?\})\s*-->/s);
|
|
@@ -18,7 +22,7 @@ export function renderHTML(templatePath, data = {}, renderedPaths = [], FF, opts
|
|
|
18
22
|
template = template.replace(templateDataMatch[0], "<!-- Invalid template data -->");
|
|
19
23
|
}
|
|
20
24
|
}
|
|
21
|
-
const FFData = FF && FF.getVar("render data");
|
|
25
|
+
const FFData = FFVar?.["render data"] ?? (FF && FF.getVar("render data"));
|
|
22
26
|
data = {
|
|
23
27
|
...(FFData || {}),
|
|
24
28
|
...templateData,
|
|
@@ -29,7 +33,14 @@ export function renderHTML(templatePath, data = {}, renderedPaths = [], FF, opts
|
|
|
29
33
|
// Loading partials, e.g. <!-- include header -->
|
|
30
34
|
template = template.replace(/<!--\s*include\s*(.*?)\s*-->/g, (_, partialName) => {
|
|
31
35
|
const partialPath = path.join(path.dirname(templatePath), partialName + ".html");
|
|
32
|
-
return renderHTML(
|
|
36
|
+
return renderHTML({
|
|
37
|
+
templatePath: partialPath,
|
|
38
|
+
_renderedPaths: [...renderedPaths, realPath],
|
|
39
|
+
noLayout: true,
|
|
40
|
+
data,
|
|
41
|
+
FF,
|
|
42
|
+
FFVar,
|
|
43
|
+
});
|
|
33
44
|
});
|
|
34
45
|
// Loading files, e.g. /* include style.css */
|
|
35
46
|
template = template.replace(/\/\*\s*include\s*(.*?)\s*\*\//g, (_, fileName) => {
|
|
@@ -42,8 +53,8 @@ export function renderHTML(templatePath, data = {}, renderedPaths = [], FF, opts
|
|
|
42
53
|
}
|
|
43
54
|
});
|
|
44
55
|
// Layout
|
|
45
|
-
const FFLayout = FF && FF.getVar("layout");
|
|
46
|
-
if (!
|
|
56
|
+
const FFLayout = FFVar?.layout ?? (FF && FF.getVar("layout"));
|
|
57
|
+
if (!noLayout && FFLayout) {
|
|
47
58
|
const hasHtmlStructure = /<\s*html|<\s*body/i.test(template);
|
|
48
59
|
const forceLayout = /<!--\s*force-layout\s*-->/.test(template);
|
|
49
60
|
const forceNoLayout = /<!--\s*force-no-layout\s*-->/.test(template);
|
|
@@ -52,11 +63,21 @@ export function renderHTML(templatePath, data = {}, renderedPaths = [], FF, opts
|
|
|
52
63
|
return template;
|
|
53
64
|
if (!hasHtmlStructure && forceNoLayout)
|
|
54
65
|
return template;
|
|
55
|
-
return renderHTML(
|
|
66
|
+
return renderHTML({
|
|
67
|
+
templatePath: FFLayout,
|
|
68
|
+
data: {
|
|
69
|
+
...data,
|
|
70
|
+
body: template
|
|
71
|
+
},
|
|
72
|
+
_renderedPaths: [...renderedPaths, realPath],
|
|
73
|
+
noLayout: true,
|
|
74
|
+
FF,
|
|
75
|
+
FFVar,
|
|
76
|
+
});
|
|
56
77
|
}
|
|
57
78
|
return template;
|
|
58
79
|
}
|
|
59
80
|
catch (error) {
|
|
60
|
-
return
|
|
81
|
+
return `<-- Template ${options.templatePath} has errors -->`;
|
|
61
82
|
}
|
|
62
83
|
}
|
package/dist/sse.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type { FFRequest, RouteHandler } from "./types.js";
|
|
2
1
|
import { FFResponse } from "./res.js";
|
|
2
|
+
import type { FFRequest, RouteHandler } from "./types.js";
|
|
3
3
|
export declare class SSEManager {
|
|
4
4
|
private clients;
|
|
5
5
|
getMiddleware(lastHandler?: RouteHandler): RouteHandler;
|
package/dist/types.d.ts
CHANGED
|
@@ -66,7 +66,7 @@ export interface StaticServeOptions {
|
|
|
66
66
|
errorIfDirNotFound?: boolean;
|
|
67
67
|
notRenderHtml?: boolean;
|
|
68
68
|
}
|
|
69
|
-
export type EngineCallback = (path: string,
|
|
69
|
+
export type EngineCallback = (path: string, data: any, callback: (e: any, rendered?: string) => void, FF?: FalconFrame) => void;
|
|
70
70
|
export interface RenderOptions {
|
|
71
71
|
notUseViews?: boolean;
|
|
72
72
|
contentType?: string;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wxn0brp/falcon-frame",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.8.0",
|
|
4
4
|
"main": "dist/index.js",
|
|
5
5
|
"types": "dist/index.d.ts",
|
|
6
6
|
"author": "wxn0brP",
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
"typescript": "*"
|
|
30
30
|
},
|
|
31
31
|
"dependencies": {
|
|
32
|
-
"@wxn0brp/lucerna-log": "^0.2.
|
|
32
|
+
"@wxn0brp/lucerna-log": "^0.2.2"
|
|
33
33
|
},
|
|
34
34
|
"files": [
|
|
35
35
|
"dist"
|