vortez 5.0.0-dev.19 → 5.0.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.
- package/.gitignore +2 -0
- package/README.md +33 -9
- package/build/Template/Compiler.d.ts +70 -0
- package/build/Template/Compiler.js +135 -0
- package/build/Template/Compiler.js.map +1 -0
- package/build/Template/StreamCompiler.d.ts +16 -0
- package/build/Template/StreamCompiler.js +54 -0
- package/build/Template/StreamCompiler.js.map +1 -0
- package/build/Template/Template.d.ts +49 -0
- package/build/Template/Template.js +77 -0
- package/build/Template/Template.js.map +1 -0
- package/build/Vortez.d.ts +1 -1
- package/build/Vortez.js +1 -1
- package/build/Vortez.js.map +1 -1
- package/build/beta/JwtManager/JwtError.d.ts +8 -0
- package/build/beta/JwtManager/JwtError.js +10 -0
- package/build/beta/JwtManager/JwtError.js.map +1 -0
- package/build/beta/JwtManager/JwtManager.d.ts +4 -0
- package/build/beta/JwtManager/JwtManager.js +27 -7
- package/build/beta/JwtManager/JwtManager.js.map +1 -1
- package/build/server/BodyParser.d.ts +6 -0
- package/build/server/BodyParser.js +18 -3
- package/build/server/BodyParser.js.map +1 -1
- package/build/server/Request.d.ts +6 -4
- package/build/server/Request.js +15 -10
- package/build/server/Request.js.map +1 -1
- package/build/server/Response.d.ts +56 -10
- package/build/server/Response.js +204 -92
- package/build/server/Response.js.map +1 -1
- package/build/server/Server.js +29 -6
- package/build/server/Server.js.map +1 -1
- package/build/server/config/Config.d.ts +15 -13
- package/build/server/config/Config.js +8 -6
- package/build/server/config/Config.js.map +1 -1
- package/build/server/config/Loader.js +1 -1
- package/build/server/config/Loader.js.map +1 -1
- package/build/server/router/Router.d.ts +1 -1
- package/build/server/router/Router.js +4 -4
- package/build/server/router/Router.js.map +1 -1
- package/build/server/router/middleware/HttpMiddleware.js +5 -5
- package/build/server/router/middleware/HttpMiddleware.js.map +1 -1
- package/build/server/router/middleware/WsMiddleware.js +1 -1
- package/build/server/router/middleware/WsMiddleware.js.map +1 -1
- package/build/server/security/PathSecurity.d.ts +45 -0
- package/build/server/security/PathSecurity.js +108 -0
- package/build/server/security/PathSecurity.js.map +1 -0
- package/build/server/websocket/Websocket.js +4 -1
- package/build/server/websocket/Websocket.js.map +1 -1
- package/build/utilities/ConsoleUI.d.ts +2 -1
- package/build/utilities/ConsoleUI.js +2 -1
- package/build/utilities/ConsoleUI.js.map +1 -1
- package/build/utilities/DebugUI.d.ts +1 -1
- package/build/utilities/DebugUI.js +1 -1
- package/build/utilities/Encoding.d.ts +22 -0
- package/build/utilities/Encoding.js +26 -0
- package/build/utilities/Encoding.js.map +1 -0
- package/build/utilities/Env.js +7 -2
- package/build/utilities/Env.js.map +1 -1
- package/build/utilities/File.d.ts +10 -0
- package/build/utilities/File.js +19 -0
- package/build/utilities/File.js.map +1 -0
- package/build/utilities/Flatten.d.ts +18 -1
- package/build/utilities/Flatten.js +18 -1
- package/build/utilities/Flatten.js.map +1 -1
- package/build/utilities/Object.d.ts +16 -0
- package/build/utilities/Object.js +48 -0
- package/build/utilities/Object.js.map +1 -0
- package/build/utilities/Path.d.ts +31 -11
- package/build/utilities/Path.js +48 -15
- package/build/utilities/Path.js.map +1 -1
- package/build/utilities/Time.d.ts +21 -0
- package/build/utilities/Time.js +25 -0
- package/build/utilities/Time.js.map +1 -0
- package/build/utilities/Utilities.d.ts +43 -34
- package/build/utilities/Utilities.js +48 -38
- package/build/utilities/Utilities.js.map +1 -1
- package/changes.md +5 -0
- package/docs/ARCHITECTURE.md +142 -0
- package/global/style/template/error.css +29 -0
- package/global/style/template/folder.css +79 -0
- package/global/{Style/Template/Template.css → style/template/template.css} +60 -68
- package/global/template/error.vhtml +29 -0
- package/global/template/folder.vhtml +54 -0
- package/package.json +2 -2
- package/build/Template.d.ts +0 -46
- package/build/Template.js +0 -81
- package/build/Template.js.map +0 -1
- package/global/Style/Template/Error.css +0 -30
- package/global/Style/Template/Folder.css +0 -77
- package/global/Template/Error.vhtml +0 -29
- package/global/Template/Folder.vhtml +0 -41
- package/tests/Template/template.js +0 -18
- package/tests/Template/template.txt +0 -13
- package/tests/Template/template.vhtml +0 -23
- package/tests/config/config.js +0 -233
- package/tests/debug.js +0 -34
- package/tests/jwtManager/jwtManager.js +0 -342
- package/tests/router.js +0 -596
- package/tests/schema/schema.js +0 -368
- package/tests/test.env +0 -0
- package/tests/test.js +0 -131
- package/tests/test.vhtml +0 -14
- package/tests/utilities.js +0 -28
- package/tests/websocket.vhtml +0 -86
- /package/global/{Source/Logo_960.png → source/logo_960.png} +0 -0
- /package/global/{Source/Logo_SM_960.png → source/logo_SM_960.png} +0 -0
|
@@ -1,93 +1,99 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @author NetFeez <netfeez.dev@gmail.com>
|
|
3
|
-
* @description
|
|
3
|
+
* @description Exports all utility classes and functions, providing a centralized access point for various helper methods used throughout the project.
|
|
4
|
+
* This includes:
|
|
5
|
+
* - file operations: `Utilities.File`.
|
|
6
|
+
* - object manipulation: `Utilities.Object`.
|
|
7
|
+
* - encoding: `Utilities.Encoding`.
|
|
8
|
+
* - time utilities: `Utilities.Time`.
|
|
9
|
+
* and more utilities.
|
|
4
10
|
* @license Apache-2.0
|
|
5
11
|
*/
|
|
6
|
-
import { promises as FSP } from "fs";
|
|
7
12
|
import _Path from './Path.js';
|
|
8
13
|
import _Env from './Env.js';
|
|
9
14
|
import _ConsoleUI from './ConsoleUI.js';
|
|
10
15
|
import _DebugUI from './DebugUI.js';
|
|
11
16
|
import _Schema from './schema/Schema.js';
|
|
12
17
|
import _Flatten from './Flatten.js';
|
|
18
|
+
import _File from './File.js';
|
|
19
|
+
import _Object from './Object.js';
|
|
20
|
+
import _Encoding from './Encoding.js';
|
|
21
|
+
import _Time from './Time.js';
|
|
13
22
|
export { Path } from './Path.js';
|
|
14
23
|
export { Env } from './Env.js';
|
|
15
24
|
export { ConsoleUI } from './ConsoleUI.js';
|
|
16
25
|
export { DebugUI } from './DebugUI.js';
|
|
17
26
|
export { Schema } from './schema/Schema.js';
|
|
18
27
|
export { Flatten } from './Flatten.js';
|
|
28
|
+
export { File } from './File.js';
|
|
29
|
+
export { Object } from './Object.js';
|
|
30
|
+
export { Encoding } from './Encoding.js';
|
|
31
|
+
export { Time } from './Time.js';
|
|
19
32
|
export class Utilities {
|
|
20
33
|
/**
|
|
21
|
-
* Checks if a file exists
|
|
22
|
-
* @param path - The path to
|
|
23
|
-
* @returns A promise that resolves to
|
|
34
|
+
* Checks if a file exists at the given path.
|
|
35
|
+
* @param path - The file path to check.
|
|
36
|
+
* @returns A promise that resolves to true if the file exists, false otherwise.
|
|
37
|
+
* @deprecated Use Utilities.File.exists instead.
|
|
24
38
|
*/
|
|
25
39
|
static async fileExists(path) {
|
|
26
|
-
return
|
|
40
|
+
return Utilities.File.exists(path);
|
|
27
41
|
}
|
|
28
42
|
/**
|
|
29
|
-
*
|
|
30
|
-
* @param obj1 - The first
|
|
31
|
-
* @param obj2 - The second
|
|
32
|
-
* @returns A boolean indicating
|
|
43
|
+
* Checks if two values are deeply equal.
|
|
44
|
+
* @param obj1 - The first value to compare.
|
|
45
|
+
* @param obj2 - The second value to compare.
|
|
46
|
+
* @returns A boolean indicating if the values are deeply equal.
|
|
47
|
+
* @deprecated Use Utilities.Object.deepEqual instead.
|
|
33
48
|
*/
|
|
34
49
|
static deepEqual(obj1, obj2) {
|
|
35
|
-
|
|
36
|
-
return true;
|
|
37
|
-
if (typeof obj1 !== typeof obj2 ||
|
|
38
|
-
obj1 === null || obj2 === null)
|
|
39
|
-
return false;
|
|
40
|
-
const keys1 = Object.keys(obj1);
|
|
41
|
-
const keys2 = Object.keys(obj2);
|
|
42
|
-
if (keys1.length !== keys2.length)
|
|
43
|
-
return false;
|
|
44
|
-
for (const key of keys1)
|
|
45
|
-
if (!keys2.includes(key) ||
|
|
46
|
-
!this.deepEqual(obj1[key], obj2[key]))
|
|
47
|
-
return false;
|
|
48
|
-
return true;
|
|
50
|
+
return Utilities.Object.deepEqual(obj1, obj2);
|
|
49
51
|
}
|
|
50
52
|
/**
|
|
51
|
-
* Flattens a nested object into a single-level object with dot
|
|
53
|
+
* Flattens a nested object into a single-level object with dot-separated keys.
|
|
52
54
|
* @param object - The object to flatten.
|
|
53
|
-
* @param depth - The maximum depth to
|
|
54
|
-
* @returns
|
|
55
|
+
* @param depth - The maximum depth to flatten (default is 10).
|
|
56
|
+
* @returns A new object with flattened keys.
|
|
57
|
+
* @deprecated Use Utilities.Flatten.object instead.
|
|
55
58
|
*/
|
|
56
59
|
static flattenObject(object, depth = 10) {
|
|
57
60
|
return Utilities.Flatten.object(object, depth);
|
|
58
61
|
}
|
|
59
62
|
/**
|
|
60
|
-
*
|
|
61
|
-
* @
|
|
62
|
-
* @
|
|
63
|
-
* @
|
|
63
|
+
* Unflattens a flattened object back into its original nested structure.
|
|
64
|
+
* @param obj - The flattened object to unflatten.
|
|
65
|
+
* @returns A new object with the original nested structure.
|
|
66
|
+
* @deprecated Use Utilities.Flatten.unObject instead.
|
|
64
67
|
*/
|
|
65
68
|
static unFlattenObject(obj) {
|
|
66
69
|
return Utilities.Flatten.unObject(obj);
|
|
67
70
|
}
|
|
68
71
|
/**
|
|
69
|
-
* Pauses
|
|
72
|
+
* Pauses execution for a specified duration.
|
|
70
73
|
* @param ms - The number of milliseconds to sleep.
|
|
71
74
|
* @returns A promise that resolves after the given time.
|
|
75
|
+
* @deprecated Use Utilities.Time.sleep instead.
|
|
72
76
|
*/
|
|
73
77
|
static sleep(ms) {
|
|
74
|
-
return
|
|
78
|
+
return Utilities.Time.sleep(ms);
|
|
75
79
|
}
|
|
76
80
|
/**
|
|
77
81
|
* Encodes a string to base64url format.
|
|
78
|
-
* @param data - The string
|
|
82
|
+
* @param data - The string to encode.
|
|
79
83
|
* @returns The base64url-encoded string.
|
|
84
|
+
* @deprecated Use Utilities.Encoding.base64UrlEncode instead.
|
|
80
85
|
*/
|
|
81
86
|
static base64UrlEncode(data) {
|
|
82
|
-
return
|
|
87
|
+
return Utilities.Encoding.base64UrlEncode(data);
|
|
83
88
|
}
|
|
84
89
|
/**
|
|
85
90
|
* Decodes a base64url-encoded string.
|
|
86
|
-
* @param data - The base64url-encoded string
|
|
87
|
-
* @returns The decoded string.
|
|
91
|
+
* @param data - The base64url-encoded string to decode.
|
|
92
|
+
* @returns The decoded UTF-8 string.
|
|
93
|
+
* @deprecated Use Utilities.Encoding.base64UrlDecode instead.
|
|
88
94
|
*/
|
|
89
95
|
static base64UrlDecode(data) {
|
|
90
|
-
return
|
|
96
|
+
return Utilities.Encoding.base64UrlDecode(data);
|
|
91
97
|
}
|
|
92
98
|
}
|
|
93
99
|
(function (Utilities) {
|
|
@@ -97,6 +103,10 @@ export class Utilities {
|
|
|
97
103
|
Utilities.DebugUI = _DebugUI;
|
|
98
104
|
Utilities.Schema = _Schema;
|
|
99
105
|
Utilities.Flatten = _Flatten;
|
|
106
|
+
Utilities.File = _File;
|
|
107
|
+
Utilities.Object = _Object;
|
|
108
|
+
Utilities.Encoding = _Encoding;
|
|
109
|
+
Utilities.Time = _Time;
|
|
100
110
|
})(Utilities || (Utilities = {}));
|
|
101
111
|
export default Utilities;
|
|
102
112
|
//# sourceMappingURL=Utilities.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Utilities.js","sourceRoot":"","sources":["../../src/utilities/Utilities.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"Utilities.js","sourceRoot":"","sources":["../../src/utilities/Utilities.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,OAAO,KAAK,MAAM,WAAW,CAAC;AAC9B,OAAO,IAAI,MAAM,UAAU,CAAC;AAC5B,OAAO,UAAU,MAAM,gBAAgB,CAAC;AACxC,OAAO,QAAQ,MAAM,cAAc,CAAC;AACpC,OAAO,OAAO,MAAM,oBAAoB,CAAC;AACzC,OAAO,QAAQ,MAAM,cAAc,CAAC;AACpC,OAAO,KAAK,MAAM,WAAW,CAAC;AAC9B,OAAO,OAAO,MAAM,aAAa,CAAC;AAClC,OAAO,SAAS,MAAM,eAAe,CAAC;AACtC,OAAO,KAAK,MAAM,WAAW,CAAC;AAE9B,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,GAAG,EAAE,MAAM,UAAU,CAAC;AAC/B,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAC5C,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,MAAM,OAAO,SAAS;IAClB;;;;;OAKG;IACI,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,IAAY;QACvC,OAAO,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IACvC,CAAC;IACD;;;;;;OAMG;IACI,MAAM,CAAC,SAAS,CAAC,IAAS,EAAE,IAAS;QACxC,OAAO,SAAS,CAAC,MAAM,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IAClD,CAAC;IACD;;;;;;OAMG;IACI,MAAM,CAAC,aAAa,CAA0C,MAAS,EAAE,QAAW,EAAO;QAC9F,OAAO,SAAS,CAAC,OAAO,CAAC,MAAM,CAAC,MAAkC,EAAE,KAAK,CAAmC,CAAC;IACjH,CAAC;IACD;;;;;OAKG;IACI,MAAM,CAAC,eAAe,CAA2B,GAAQ;QAC5D,OAAO,SAAS,CAAC,OAAO,CAAC,QAAQ,CAAS,GAAiC,CAAC,CAAC;IACjF,CAAC;IACD;;;;;OAKG;IACI,MAAM,CAAC,KAAK,CAAC,EAAU;QAC1B,OAAO,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IACpC,CAAC;IACD;;;;;OAKG;IACI,MAAM,CAAC,eAAe,CAAC,IAAY;QACtC,OAAO,SAAS,CAAC,QAAQ,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC;IACpD,CAAC;IACD;;;;;OAKG;IACI,MAAM,CAAC,eAAe,CAAC,IAAY;QACtC,OAAO,SAAS,CAAC,QAAQ,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC;IACpD,CAAC;CACJ;AACD,WAAiB,SAAS;IACR,cAAI,GAAG,KAAK,CAAC;IACb,aAAG,GAAG,IAAI,CAAC;IACX,mBAAS,GAAG,UAAU,CAAC;IACvB,iBAAO,GAAG,QAAQ,CAAC;IACnB,gBAAM,GAAG,OAAO,CAAC;IACjB,iBAAO,GAAG,QAAQ,CAAC;IACnB,cAAI,GAAG,KAAK,CAAC;IACb,gBAAM,GAAG,OAAO,CAAC;IACjB,kBAAQ,GAAG,SAAS,CAAC;IACrB,cAAI,GAAG,KAAK,CAAC;AA0C/B,CAAC,EApDgB,SAAS,KAAT,SAAS,QAoDzB;AACD,eAAe,SAAS,CAAC"}
|
package/changes.md
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
# version (5.0.0)
|
|
2
2
|
## 📒 Notes
|
|
3
3
|
- **Breaking Change**: The server's debugging interface has been refactored. Users interacting with the old `DebugUI` will need to adapt to the new `ServerDebug` module.
|
|
4
|
+
- **Acknowledgment**: Special thanks to my girlfriend for helping identify a critical path traversal vulnerability before this stable release.
|
|
4
5
|
## ➕ Added
|
|
5
6
|
- **(Utilities/DebugUI)**: Introduced a new generic, reusable `DebugUI` class for creating command-line interfaces.
|
|
6
7
|
- **(Server/ServerDebug)**: Added a new `ServerDebug` module to provide server-specific commands, built upon the new generic `DebugUI`.
|
|
@@ -32,6 +33,10 @@
|
|
|
32
33
|
- **(Server/WebSocket)**: Overhauled the WebSocket connection lifecycle for improved security and developer experience.
|
|
33
34
|
- The `WebSocket` class no longer accepts connections in its constructor. Instead, it waits in a `pending` state.
|
|
34
35
|
- Added `accept()` and `reject()` methods to give the framework full control over the connection handshake.
|
|
36
|
+
- **(Server/Response)**: The `send()`, `sendJson()`, `sendFile()`, `sendFolder()`, and `sendTemplate()` methods are now **async** and return `Promise<void>`. **This is a breaking change.**
|
|
37
|
+
- All response methods now require `await` in calling code for proper error handling.
|
|
38
|
+
- Added `sendReadable()` for streaming responses with backpressure support via `stream/promises`.
|
|
39
|
+
- HTTP range requests (206 Partial Content) are now properly handled in streaming contexts.
|
|
35
40
|
|
|
36
41
|
# version (4.1.0)
|
|
37
42
|
## ➕ Added
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
# Vortez Architecture Guide
|
|
2
|
+
|
|
3
|
+
This document explains how Vortez works internally, how requests are processed end-to-end, and how teams can run it confidently in production.
|
|
4
|
+
|
|
5
|
+
## Who This Is For
|
|
6
|
+
|
|
7
|
+
- Engineers evaluating Vortez for backend and real-time workloads.
|
|
8
|
+
- Teams onboarding to an existing Vortez codebase.
|
|
9
|
+
- Contributors who need to understand extension points and runtime behavior.
|
|
10
|
+
|
|
11
|
+
## System At A Glance
|
|
12
|
+
|
|
13
|
+
```mermaid
|
|
14
|
+
flowchart TD
|
|
15
|
+
A[Application Code] --> B[Vortez Server]
|
|
16
|
+
B --> C[Config]
|
|
17
|
+
B --> D[Router]
|
|
18
|
+
D --> E[HTTP Rules]
|
|
19
|
+
D --> F[WebSocket Rules]
|
|
20
|
+
E --> G[HttpMiddleware Pipeline]
|
|
21
|
+
F --> H[WsMiddleware Pipeline]
|
|
22
|
+
G --> I[Response Helpers]
|
|
23
|
+
H --> J[WebSocket Client]
|
|
24
|
+
I --> K[Template Engine]
|
|
25
|
+
B --> L[Logger Manager]
|
|
26
|
+
B --> M[Utilities]
|
|
27
|
+
B --> N[Beta Modules: JWT + Mail]
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## Request Lifecycle (HTTP)
|
|
31
|
+
|
|
32
|
+
```mermaid
|
|
33
|
+
flowchart TD
|
|
34
|
+
A[Incoming HTTP request] --> B[Router.requestManager]
|
|
35
|
+
B --> C[Build Request object]
|
|
36
|
+
C --> D[Build Response object]
|
|
37
|
+
D --> E[Routing Algorithm route]
|
|
38
|
+
E --> F{Rule matched}
|
|
39
|
+
F -->|No| G[Response.sendError 404]
|
|
40
|
+
F -->|Yes| H[HttpRule.exec]
|
|
41
|
+
H --> I[Run HTTP middleware pipeline]
|
|
42
|
+
I --> J{Pipeline status}
|
|
43
|
+
J -->|Success| K[Route action executes]
|
|
44
|
+
J -->|Error| L[Error middleware or default handler]
|
|
45
|
+
K --> M[send/sendJson/sendFile/sendFolder/sendTemplate]
|
|
46
|
+
L --> N[ServerError or 500 response]
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
### Key behavior
|
|
50
|
+
|
|
51
|
+
- Route parameters are extracted before action execution.
|
|
52
|
+
- Middleware is snapshot-based at rule registration time.
|
|
53
|
+
- If no route matches, Vortez returns a 404 error page.
|
|
54
|
+
- File and folder responses include path-safety checks for traversal protection.
|
|
55
|
+
|
|
56
|
+
## Request Lifecycle (WebSocket)
|
|
57
|
+
|
|
58
|
+
```mermaid
|
|
59
|
+
flowchart TD
|
|
60
|
+
A[Upgrade request] --> B[Router.upgradeManager]
|
|
61
|
+
B --> C[Build Request + WebSocket wrapper]
|
|
62
|
+
C --> D[Routing Algorithm route]
|
|
63
|
+
D --> E{Rule matched}
|
|
64
|
+
E -->|No| F[Reject 404]
|
|
65
|
+
E -->|Yes| G[WsRule.exec]
|
|
66
|
+
G --> H[Run WS middleware pipeline]
|
|
67
|
+
H --> I{Connection state}
|
|
68
|
+
I -->|pending and valid| J[Accept handshake]
|
|
69
|
+
I -->|error| K[Reject handshake]
|
|
70
|
+
J --> L[Route action executes]
|
|
71
|
+
L --> M[message/close/finish/error events]
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
### Key behavior
|
|
75
|
+
|
|
76
|
+
- WS routes also support middleware and error middleware.
|
|
77
|
+
- If middleware completes and state is pending, handshake is auto-accepted.
|
|
78
|
+
- Errors before accept are converted into explicit handshake rejection.
|
|
79
|
+
|
|
80
|
+
## Routing Strategies
|
|
81
|
+
|
|
82
|
+
- FIFO
|
|
83
|
+
- First matching rule wins.
|
|
84
|
+
- Predictable registration-order behavior.
|
|
85
|
+
- Good default for simple APIs and deterministic route priority.
|
|
86
|
+
- Tree
|
|
87
|
+
- Segment-based navigation through static, param, and wildcard nodes.
|
|
88
|
+
- Better scalability for large route maps.
|
|
89
|
+
- Falls back to rule test checks in optional-edge cases.
|
|
90
|
+
|
|
91
|
+
## Configuration Model
|
|
92
|
+
|
|
93
|
+
Configuration is schema-driven and normalized on startup.
|
|
94
|
+
|
|
95
|
+
- Host, port, SSL
|
|
96
|
+
- Routing algorithm selection
|
|
97
|
+
- Templates for folder and error pages
|
|
98
|
+
- Logging controls per channel
|
|
99
|
+
|
|
100
|
+
This gives stable defaults while preserving explicit overrides.
|
|
101
|
+
|
|
102
|
+
## Static Files And Templates
|
|
103
|
+
|
|
104
|
+
- `sendFile` supports byte-range requests for media and binary responses.
|
|
105
|
+
- `sendFolder` resolves paths inside a secured base directory.
|
|
106
|
+
- `sendTemplate` uses Vortez template compilation with variable and block expansion.
|
|
107
|
+
|
|
108
|
+
## Build And Test Pipeline
|
|
109
|
+
|
|
110
|
+
```mermaid
|
|
111
|
+
flowchart LR
|
|
112
|
+
A[npm run compile] --> B[scripts/compile.sh]
|
|
113
|
+
B --> C[tsc build to build/]
|
|
114
|
+
D[npm test] --> E[scripts/test.sh]
|
|
115
|
+
E --> F[tsc source]
|
|
116
|
+
F --> G[tsc tests]
|
|
117
|
+
G --> H[node build-tests/test.js]
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
## Operational Checklist For Production
|
|
121
|
+
|
|
122
|
+
- Use HTTPS with valid key/certificate and explicit TLS termination strategy.
|
|
123
|
+
- Configure reverse proxy headers if deploying behind load balancers.
|
|
124
|
+
- Register global middleware before route registration.
|
|
125
|
+
- Choose `Tree` algorithm for large route sets.
|
|
126
|
+
- Define custom error and folder templates for consistent UX.
|
|
127
|
+
- Enable structured log persistence and shipping to your observability stack.
|
|
128
|
+
- Add health/readiness endpoints and graceful shutdown handling.
|
|
129
|
+
- Run CI for compile + tests on every change.
|
|
130
|
+
|
|
131
|
+
## Recommended Documentation Map
|
|
132
|
+
|
|
133
|
+
To match industry-grade developer experience, keep docs split by user intent:
|
|
134
|
+
|
|
135
|
+
- Getting Started: first server in 5 minutes.
|
|
136
|
+
- Core Concepts: routing, middleware, request/response.
|
|
137
|
+
- Production Guide: deployment, scaling, reliability.
|
|
138
|
+
- Security Guide: SSL, headers, path safety, secrets.
|
|
139
|
+
- API Reference: exported classes and methods.
|
|
140
|
+
- Examples: REST API, static site, SPA/PWA, WebSocket chat.
|
|
141
|
+
|
|
142
|
+
This architecture guide is the canonical high-level reference for that set.
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
#error {
|
|
2
|
+
--color-bg: rgb(255,180,220);
|
|
3
|
+
--color-code: rgb(255,0,0);
|
|
4
|
+
--color-message: rgb(0,0,0);
|
|
5
|
+
--color-bg-image: rgba(255,0,0,0.1);
|
|
6
|
+
|
|
7
|
+
background: var(--color-bg);
|
|
8
|
+
height: 100%;
|
|
9
|
+
position: fixed;
|
|
10
|
+
width: 100%;
|
|
11
|
+
overflow: visible;
|
|
12
|
+
& > .content {
|
|
13
|
+
text-align: center;
|
|
14
|
+
width: 90%;
|
|
15
|
+
overflow: visible;
|
|
16
|
+
}
|
|
17
|
+
& > .code {
|
|
18
|
+
color: var(--color-code);
|
|
19
|
+
font-size: 3em;
|
|
20
|
+
}
|
|
21
|
+
& > .message {
|
|
22
|
+
color: var(--color-message);
|
|
23
|
+
font-size: 1em;
|
|
24
|
+
margin-bottom: 1em;
|
|
25
|
+
}
|
|
26
|
+
& > .loading {
|
|
27
|
+
width: 30%;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
#folder {
|
|
2
|
+
--color-bg: rgb(255,180,220);
|
|
3
|
+
--color-bg-content: rgba(255,0,0,0.1);
|
|
4
|
+
--color-bg-back: rgba(180,220,255,0.5);
|
|
5
|
+
--color-bg-back-action: rgba(180,220,255,0.75);
|
|
6
|
+
--color-bg-search: rgba(255,180,220,0.5);
|
|
7
|
+
--color-bg-search-action: rgba(255,180,220,0.75);
|
|
8
|
+
--color-bg-item: rgba(220,255,180,0.25);
|
|
9
|
+
--color-bg-item-action: rgba(220,255,180,0.5);
|
|
10
|
+
--color-border-search-action: rgb(180,220,255);
|
|
11
|
+
|
|
12
|
+
align-items: center;
|
|
13
|
+
background: var(--color-bg);
|
|
14
|
+
height: 100%;
|
|
15
|
+
overflow: visible scroll;
|
|
16
|
+
position: fixed;
|
|
17
|
+
width: 100%;
|
|
18
|
+
|
|
19
|
+
& > .content {
|
|
20
|
+
background: var(--color-bg-content);
|
|
21
|
+
border-radius: 2em;
|
|
22
|
+
margin-top: 2em;
|
|
23
|
+
padding: 2em;
|
|
24
|
+
text-align: center;
|
|
25
|
+
width: 70%;
|
|
26
|
+
|
|
27
|
+
& > .options {
|
|
28
|
+
display: flex;
|
|
29
|
+
text-align: start;
|
|
30
|
+
|
|
31
|
+
& > #input-path:focus {
|
|
32
|
+
border: var(--color-border-search-action) 3px double;
|
|
33
|
+
margin: calc(0.5em - 3px);
|
|
34
|
+
outline: none;
|
|
35
|
+
}
|
|
36
|
+
& > #input-path:focus,
|
|
37
|
+
& > #input-change:hover {
|
|
38
|
+
background: var(--color-bg-search-action);
|
|
39
|
+
}
|
|
40
|
+
& > #input-change {
|
|
41
|
+
cursor: pointer;
|
|
42
|
+
}
|
|
43
|
+
& > .back,
|
|
44
|
+
& > #input-path,
|
|
45
|
+
& > #input-change {
|
|
46
|
+
background: var(--color-bg-back);
|
|
47
|
+
border-radius: 1em;
|
|
48
|
+
color: rgb(0,0,0);
|
|
49
|
+
display: inline-block;
|
|
50
|
+
margin: 0.5em;
|
|
51
|
+
padding: 1em;
|
|
52
|
+
text-decoration: none;
|
|
53
|
+
}
|
|
54
|
+
& > #input-path,
|
|
55
|
+
& > #input-change {
|
|
56
|
+
background: var(--color-bg-search);
|
|
57
|
+
border: none;
|
|
58
|
+
}
|
|
59
|
+
& > .back:hover {
|
|
60
|
+
background: var(--color-bg-back-action);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
& > .list {
|
|
64
|
+
list-style: none;
|
|
65
|
+
& .item {
|
|
66
|
+
background: var(--color-bg-item);
|
|
67
|
+
border-radius: 1em;
|
|
68
|
+
color: rgb(0,0,0);
|
|
69
|
+
display: block;
|
|
70
|
+
margin: 0.25em;
|
|
71
|
+
padding: 1em;
|
|
72
|
+
text-decoration: none;
|
|
73
|
+
&:hover {
|
|
74
|
+
background: var(--color-bg-item-action);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
@import './
|
|
2
|
-
@import './
|
|
1
|
+
@import './folder.css';
|
|
2
|
+
@import './error.css';
|
|
3
3
|
|
|
4
4
|
* {
|
|
5
5
|
padding: 0px;
|
|
6
6
|
margin: 0px;
|
|
7
7
|
}
|
|
8
|
-
.
|
|
8
|
+
.center-X {
|
|
9
9
|
align-items: center;
|
|
10
10
|
display: flex;
|
|
11
11
|
flex-direction: column;
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
height: 100%;
|
|
15
15
|
overflow: visible;
|
|
16
16
|
}
|
|
17
|
-
.
|
|
17
|
+
.center-Y {
|
|
18
18
|
/* align-items: center; */
|
|
19
19
|
display: flex;
|
|
20
20
|
flex-direction: column;
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
height: 100%;
|
|
24
24
|
overflow: visible;
|
|
25
25
|
}
|
|
26
|
-
.
|
|
26
|
+
.loading {
|
|
27
27
|
align-items: center;
|
|
28
28
|
animation: Entrada 0.2s linear 0s 1, Fluctuar 4s linear 1s infinite;
|
|
29
29
|
background: var(--Color_Fondo);
|
|
@@ -36,70 +36,62 @@
|
|
|
36
36
|
position: relative;
|
|
37
37
|
width: 40%;
|
|
38
38
|
z-index: 0;
|
|
39
|
-
}
|
|
40
|
-
.Carga .C_Fondo,
|
|
41
|
-
.Carga .C_Fondo2 {
|
|
42
|
-
align-items: center;
|
|
43
|
-
background: var(--Color_Fondo, rgb(0,0,0));
|
|
44
|
-
border-radius: 50%;
|
|
45
|
-
box-sizing: content-box;
|
|
46
|
-
display: flex;
|
|
47
|
-
height: 96%;
|
|
48
|
-
justify-content: center;
|
|
49
|
-
overflow: hidden;
|
|
50
|
-
position: absolute;
|
|
51
|
-
width: 96%;
|
|
52
|
-
}
|
|
53
|
-
.Carga .C_Fondo2 {
|
|
54
|
-
height: 92%;
|
|
55
|
-
width: 92%;
|
|
56
|
-
}
|
|
57
|
-
.Carga .C_Logo {
|
|
58
|
-
/*background: var(--Color_Fondo) url('/Src/Recursos/Íconos/NetFeez-Labs/[Ícono] - SM - 960.png');
|
|
59
|
-
background-attachment: local;
|
|
60
|
-
background-position:center top;
|
|
61
|
-
background-repeat: no-repeat;
|
|
62
|
-
background-size: cover;
|
|
63
|
-
border-radius: 50%;
|
|
64
|
-
height: 0px;
|
|
65
|
-
padding-bottom: 100%;*/
|
|
66
|
-
animation: FluctuarImg 4s linear 0s infinite;
|
|
67
|
-
border-radius: 50%;
|
|
68
|
-
width: 100%;
|
|
69
|
-
height: 100%;
|
|
70
|
-
}
|
|
71
|
-
.Carga .C_Fondo::before,
|
|
72
|
-
.Carga .C_Fondo::after,
|
|
73
|
-
.Carga::before,
|
|
74
|
-
.Carga::after {
|
|
75
|
-
animation: Girar 5s linear 0s infinite;
|
|
76
|
-
background: linear-gradient(90deg, rgb(100,100,0), rgb(0,100,180));
|
|
77
|
-
content: '';
|
|
78
|
-
height: 25%;
|
|
79
|
-
position: absolute;
|
|
80
|
-
width: 125%;
|
|
81
|
-
z-index: -1;
|
|
82
|
-
}
|
|
83
|
-
.Carga .C_Fondo::after,
|
|
84
|
-
.Carga::after {
|
|
85
|
-
animation-direction: reverse;
|
|
86
|
-
animation-duration: 3s;
|
|
87
|
-
background: linear-gradient(0deg, rgb(255,0,255), rgb(0,255,0));
|
|
88
|
-
height: 125%;
|
|
89
|
-
width: 25%;
|
|
90
|
-
}
|
|
91
|
-
.Carga .C_Fondo::before,
|
|
92
|
-
.Carga .C_Fondo::after {
|
|
93
|
-
background: linear-gradient(90deg, rgb(0,0,255), rgb(255,255,0));
|
|
94
|
-
animation-duration: 4s;
|
|
95
|
-
z-index: 0;
|
|
96
|
-
}
|
|
97
|
-
.Carga .C_Fondo::after {
|
|
98
|
-
background: linear-gradient(0deg, rgb(255,0,0), rgb(0,255,255));
|
|
99
|
-
animation-duration: 2s;
|
|
100
|
-
z-index: 0;
|
|
101
|
-
}
|
|
102
39
|
|
|
40
|
+
& > .background-1,
|
|
41
|
+
& > .background-2 {
|
|
42
|
+
align-items: center;
|
|
43
|
+
background: var(--Color_Fondo, rgb(0,0,0));
|
|
44
|
+
border-radius: 50%;
|
|
45
|
+
box-sizing: content-box;
|
|
46
|
+
display: flex;
|
|
47
|
+
height: 96%;
|
|
48
|
+
justify-content: center;
|
|
49
|
+
overflow: hidden;
|
|
50
|
+
position: absolute;
|
|
51
|
+
width: 96%;
|
|
52
|
+
}
|
|
53
|
+
& > .background-2 {
|
|
54
|
+
height: 92%;
|
|
55
|
+
width: 92%;
|
|
56
|
+
}
|
|
57
|
+
& > .logo {
|
|
58
|
+
animation: FluctuarImg 4s linear 0s infinite;
|
|
59
|
+
border-radius: 50%;
|
|
60
|
+
width: 100%;
|
|
61
|
+
height: 100%;
|
|
62
|
+
}
|
|
63
|
+
& > .background-1::before,
|
|
64
|
+
& > .background-1::after,
|
|
65
|
+
&::before,
|
|
66
|
+
&::after {
|
|
67
|
+
animation: Girar 5s linear 0s infinite;
|
|
68
|
+
background: linear-gradient(90deg, rgb(100,100,0), rgb(0,100,180));
|
|
69
|
+
content: '';
|
|
70
|
+
height: 25%;
|
|
71
|
+
position: absolute;
|
|
72
|
+
width: 125%;
|
|
73
|
+
z-index: -1;
|
|
74
|
+
}
|
|
75
|
+
& > .background-1::after,
|
|
76
|
+
&::after {
|
|
77
|
+
animation-direction: reverse;
|
|
78
|
+
animation-duration: 3s;
|
|
79
|
+
background: linear-gradient(0deg, rgb(255,0,255), rgb(0,255,0));
|
|
80
|
+
height: 125%;
|
|
81
|
+
width: 25%;
|
|
82
|
+
}
|
|
83
|
+
& > .background-1::before,
|
|
84
|
+
& > .background-1::after {
|
|
85
|
+
background: linear-gradient(90deg, rgb(0,0,255), rgb(255,255,0));
|
|
86
|
+
animation-duration: 4s;
|
|
87
|
+
z-index: 0;
|
|
88
|
+
}
|
|
89
|
+
& > .background-1::after {
|
|
90
|
+
background: linear-gradient(0deg, rgb(255,0,0), rgb(0,255,255));
|
|
91
|
+
animation-duration: 2s;
|
|
92
|
+
z-index: 0;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
103
95
|
@keyframes Entrada {
|
|
104
96
|
0% {opacity: 0;}
|
|
105
97
|
100% {opacity: 1;}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="es">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8">
|
|
5
|
+
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
|
6
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
7
|
+
<link rel="stylesheet" href="/vortez:global/style/template/template.css">
|
|
8
|
+
<title>[Vortez] - {{status}}</title>
|
|
9
|
+
</head>
|
|
10
|
+
<body>
|
|
11
|
+
<div id="error" class="center-X center-Y">
|
|
12
|
+
<div class="content">
|
|
13
|
+
<h1 class="code">Status: {{status}}</h1>
|
|
14
|
+
<p class="message">{{message}}</p>
|
|
15
|
+
<div class="center-X center-Y">
|
|
16
|
+
<div class="loading">
|
|
17
|
+
<div class="background-1"></div>
|
|
18
|
+
<div class="background-2"></div>
|
|
19
|
+
<picture>
|
|
20
|
+
<source srcset="/vortez:global/source/logo_SM_960.png"/>
|
|
21
|
+
<source srcset="/favicon.ico"/>
|
|
22
|
+
<img class="logo">
|
|
23
|
+
</picture>
|
|
24
|
+
</div>
|
|
25
|
+
</div>
|
|
26
|
+
</div>
|
|
27
|
+
</div>
|
|
28
|
+
</body>
|
|
29
|
+
</html>
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="es">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8">
|
|
5
|
+
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
|
6
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
7
|
+
<link rel="stylesheet" href="/vortez:global/style/template/template.css">
|
|
8
|
+
<title>[Vortez] - Folder</title>
|
|
9
|
+
</head>
|
|
10
|
+
<body>
|
|
11
|
+
<div id="folder" class="center-X">
|
|
12
|
+
<div class="content">
|
|
13
|
+
<h1 class="path">Folder: {{Url}}</h1>
|
|
14
|
+
<div class="options">
|
|
15
|
+
<vortez-if name="Url" condition="!=" expected="/">
|
|
16
|
+
<a class="back" href="{{Url}}/../">Back</a>
|
|
17
|
+
<vortez-else />
|
|
18
|
+
<span class="back disabled">Back</span>
|
|
19
|
+
</vortez-if>
|
|
20
|
+
<input id="input-path" type="search" placeholder="enter the path... {{Url}}" value="{{Url}}"/>
|
|
21
|
+
<input id="input-change"type="button" value="change"/>
|
|
22
|
+
</div>
|
|
23
|
+
<ul class="list">
|
|
24
|
+
<vortez-each name="folder" value="name">
|
|
25
|
+
<li>
|
|
26
|
+
<vortez-if name="Url" condition="==" expected="/">
|
|
27
|
+
<a class="item" href="./{{name}}">
|
|
28
|
+
<vortez-if name="name" condition="==" expected="style">
|
|
29
|
+
<span class="folder">[Folder]</span>
|
|
30
|
+
</vortez-if>
|
|
31
|
+
{{name}}
|
|
32
|
+
</a>
|
|
33
|
+
<vortez-else />
|
|
34
|
+
<a class="item" href="{{Url}}/{{name}}">{{name}}</a>
|
|
35
|
+
</vortez-if>
|
|
36
|
+
</li>
|
|
37
|
+
</vortez-each>
|
|
38
|
+
</ul>
|
|
39
|
+
</div>
|
|
40
|
+
<script>
|
|
41
|
+
const inputChange = document.querySelector('#input-change');
|
|
42
|
+
const inputPath = document.querySelector('#input-path');
|
|
43
|
+
inputChange.addEventListener('click', () => {
|
|
44
|
+
window.location.href = inputPath.value;
|
|
45
|
+
});
|
|
46
|
+
inputPath.addEventListener('keydown', (event) => {
|
|
47
|
+
inputPath.value.length <= '{{Url}}'.length && event.key == 'Backspace'
|
|
48
|
+
? event.preventDefault()
|
|
49
|
+
: false;
|
|
50
|
+
})
|
|
51
|
+
</script>
|
|
52
|
+
</div>
|
|
53
|
+
</body>
|
|
54
|
+
</html>
|