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.
Files changed (106) hide show
  1. package/.gitignore +2 -0
  2. package/README.md +33 -9
  3. package/build/Template/Compiler.d.ts +70 -0
  4. package/build/Template/Compiler.js +135 -0
  5. package/build/Template/Compiler.js.map +1 -0
  6. package/build/Template/StreamCompiler.d.ts +16 -0
  7. package/build/Template/StreamCompiler.js +54 -0
  8. package/build/Template/StreamCompiler.js.map +1 -0
  9. package/build/Template/Template.d.ts +49 -0
  10. package/build/Template/Template.js +77 -0
  11. package/build/Template/Template.js.map +1 -0
  12. package/build/Vortez.d.ts +1 -1
  13. package/build/Vortez.js +1 -1
  14. package/build/Vortez.js.map +1 -1
  15. package/build/beta/JwtManager/JwtError.d.ts +8 -0
  16. package/build/beta/JwtManager/JwtError.js +10 -0
  17. package/build/beta/JwtManager/JwtError.js.map +1 -0
  18. package/build/beta/JwtManager/JwtManager.d.ts +4 -0
  19. package/build/beta/JwtManager/JwtManager.js +27 -7
  20. package/build/beta/JwtManager/JwtManager.js.map +1 -1
  21. package/build/server/BodyParser.d.ts +6 -0
  22. package/build/server/BodyParser.js +18 -3
  23. package/build/server/BodyParser.js.map +1 -1
  24. package/build/server/Request.d.ts +6 -4
  25. package/build/server/Request.js +15 -10
  26. package/build/server/Request.js.map +1 -1
  27. package/build/server/Response.d.ts +56 -10
  28. package/build/server/Response.js +204 -92
  29. package/build/server/Response.js.map +1 -1
  30. package/build/server/Server.js +29 -6
  31. package/build/server/Server.js.map +1 -1
  32. package/build/server/config/Config.d.ts +15 -13
  33. package/build/server/config/Config.js +8 -6
  34. package/build/server/config/Config.js.map +1 -1
  35. package/build/server/config/Loader.js +1 -1
  36. package/build/server/config/Loader.js.map +1 -1
  37. package/build/server/router/Router.d.ts +1 -1
  38. package/build/server/router/Router.js +4 -4
  39. package/build/server/router/Router.js.map +1 -1
  40. package/build/server/router/middleware/HttpMiddleware.js +5 -5
  41. package/build/server/router/middleware/HttpMiddleware.js.map +1 -1
  42. package/build/server/router/middleware/WsMiddleware.js +1 -1
  43. package/build/server/router/middleware/WsMiddleware.js.map +1 -1
  44. package/build/server/security/PathSecurity.d.ts +45 -0
  45. package/build/server/security/PathSecurity.js +108 -0
  46. package/build/server/security/PathSecurity.js.map +1 -0
  47. package/build/server/websocket/Websocket.js +4 -1
  48. package/build/server/websocket/Websocket.js.map +1 -1
  49. package/build/utilities/ConsoleUI.d.ts +2 -1
  50. package/build/utilities/ConsoleUI.js +2 -1
  51. package/build/utilities/ConsoleUI.js.map +1 -1
  52. package/build/utilities/DebugUI.d.ts +1 -1
  53. package/build/utilities/DebugUI.js +1 -1
  54. package/build/utilities/Encoding.d.ts +22 -0
  55. package/build/utilities/Encoding.js +26 -0
  56. package/build/utilities/Encoding.js.map +1 -0
  57. package/build/utilities/Env.js +7 -2
  58. package/build/utilities/Env.js.map +1 -1
  59. package/build/utilities/File.d.ts +10 -0
  60. package/build/utilities/File.js +19 -0
  61. package/build/utilities/File.js.map +1 -0
  62. package/build/utilities/Flatten.d.ts +18 -1
  63. package/build/utilities/Flatten.js +18 -1
  64. package/build/utilities/Flatten.js.map +1 -1
  65. package/build/utilities/Object.d.ts +16 -0
  66. package/build/utilities/Object.js +48 -0
  67. package/build/utilities/Object.js.map +1 -0
  68. package/build/utilities/Path.d.ts +31 -11
  69. package/build/utilities/Path.js +48 -15
  70. package/build/utilities/Path.js.map +1 -1
  71. package/build/utilities/Time.d.ts +21 -0
  72. package/build/utilities/Time.js +25 -0
  73. package/build/utilities/Time.js.map +1 -0
  74. package/build/utilities/Utilities.d.ts +43 -34
  75. package/build/utilities/Utilities.js +48 -38
  76. package/build/utilities/Utilities.js.map +1 -1
  77. package/changes.md +5 -0
  78. package/docs/ARCHITECTURE.md +142 -0
  79. package/global/style/template/error.css +29 -0
  80. package/global/style/template/folder.css +79 -0
  81. package/global/{Style/Template/Template.css → style/template/template.css} +60 -68
  82. package/global/template/error.vhtml +29 -0
  83. package/global/template/folder.vhtml +54 -0
  84. package/package.json +2 -2
  85. package/build/Template.d.ts +0 -46
  86. package/build/Template.js +0 -81
  87. package/build/Template.js.map +0 -1
  88. package/global/Style/Template/Error.css +0 -30
  89. package/global/Style/Template/Folder.css +0 -77
  90. package/global/Template/Error.vhtml +0 -29
  91. package/global/Template/Folder.vhtml +0 -41
  92. package/tests/Template/template.js +0 -18
  93. package/tests/Template/template.txt +0 -13
  94. package/tests/Template/template.vhtml +0 -23
  95. package/tests/config/config.js +0 -233
  96. package/tests/debug.js +0 -34
  97. package/tests/jwtManager/jwtManager.js +0 -342
  98. package/tests/router.js +0 -596
  99. package/tests/schema/schema.js +0 -368
  100. package/tests/test.env +0 -0
  101. package/tests/test.js +0 -131
  102. package/tests/test.vhtml +0 -14
  103. package/tests/utilities.js +0 -28
  104. package/tests/websocket.vhtml +0 -86
  105. /package/global/{Source/Logo_960.png → source/logo_960.png} +0 -0
  106. /package/global/{Source/Logo_SM_960.png → source/logo_SM_960.png} +0 -0
@@ -1,368 +0,0 @@
1
- // @ts-check
2
- import { strict as assert } from 'assert';
3
-
4
- import { Logger } from '../../build/Vortez.js';
5
- import { Schema } from '../../build/utilities/schema/Schema.js';
6
- import { SchemaError } from '../../build/utilities/schema/SchemaError.js';
7
-
8
- const logger = new Logger({ prefix: 'SCHEMA' });
9
-
10
- let testsPassed = 0;
11
- let testsFailed = 0;
12
-
13
- const x = new Schema({
14
- host: { type: 'string', required: true, minLength: 1 },
15
- port: { type: 'number', minimum: 0, maximum: 65535, default: 80 },
16
- ssl: {
17
- type: 'object',
18
- nullable: true,
19
- default: null,
20
- schema: {
21
- pubKey: { type: 'string', required: true },
22
- privKey: { type: 'string', required: true }
23
- }
24
- }
25
- });
26
- const y = x.processData({ host: 'localhost' });
27
-
28
- /**
29
- * Logs test results.
30
- * @param { string } testName The test name.
31
- * @param { boolean } passed Whether the test passed.
32
- * @param { unknown | null } error Optional error object for failures.
33
- */
34
- function logTestResult(testName, passed, error = null) {
35
- if (passed) {
36
- logger.log(`&C2✓ ${testName}`);
37
- testsPassed++;
38
- } else {
39
- const message = error instanceof Error ? error.message : String(error);
40
- logger.error(`&C1✗ ${testName}${error ? ': ' + message : ''}`);
41
- testsFailed++;
42
- }
43
- }
44
-
45
- /**
46
- * Ensures processData applies defaults and keeps valid values.
47
- */
48
- function testProcessDataWithDefaults() {
49
- try {
50
- const schema = new Schema({
51
- host: { type: 'string', required: true, minLength: 1 },
52
- port: { type: 'number', minimum: 0, maximum: 65535, default: 80 },
53
- ssl: {
54
- type: 'object',
55
- nullable: true,
56
- default: null,
57
- schema: {
58
- pubKey: { type: 'string', required: true },
59
- privKey: { type: 'string', required: true }
60
- }
61
- }
62
- });
63
-
64
- const data = schema.processData({ host: 'localhost' });
65
- assert.equal(data.host, 'localhost');
66
- assert.equal(data.port, 80);
67
- assert.equal(data.ssl, null);
68
-
69
- logTestResult('processData - Applies defaults', true);
70
- } catch (error) {
71
- logTestResult('processData - Applies defaults', false, error);
72
- }
73
- }
74
-
75
- /**
76
- * Ensures required keys fail when not provided.
77
- */
78
- function testRequiredFieldFailure() {
79
- try {
80
- const schema = new Schema({
81
- host: { type: 'string', required: true }
82
- });
83
-
84
- try {
85
- // @ts-expect-error Runtime validation test with missing required key on purpose.
86
- schema.processData({});
87
- logTestResult('required - Missing required key fails', false, new Error('Should have thrown'));
88
- } catch (error) {
89
- assert.ok(error instanceof SchemaError);
90
- logTestResult('required - Missing required key fails', true);
91
- }
92
- } catch (error) {
93
- logTestResult('required - Missing required key fails', false, error);
94
- }
95
- }
96
-
97
- /**
98
- * Covers edge cases where numeric/string limits are 0.
99
- */
100
- function testZeroBoundaries() {
101
- try {
102
- const stringSchema = new Schema({
103
- emptyOnly: { type: 'string', required: true, maxLength: 0, minLength: 0 }
104
- });
105
- const numberSchema = new Schema({
106
- count: { type: 'number', required: true, minimum: 0, maximum: 0 }
107
- });
108
-
109
- const validString = stringSchema.processData({ emptyOnly: '' });
110
- const validNumber = numberSchema.processData({ count: 0 });
111
-
112
- assert.equal(validString.emptyOnly, '');
113
- assert.equal(validNumber.count, 0);
114
-
115
- assert.throws(() => stringSchema.processData({ emptyOnly: 'x' }), SchemaError);
116
- assert.throws(() => numberSchema.processData({ count: -1 }), SchemaError);
117
-
118
- logTestResult('limits - Zero boundaries enforced', true);
119
- } catch (error) {
120
- logTestResult('limits - Zero boundaries enforced', false, error);
121
- }
122
- }
123
-
124
- /**
125
- * Ensures array size validation and element validation work together.
126
- */
127
- function testArrayValidation() {
128
- try {
129
- const schema = new Schema({
130
- tags: {
131
- type: 'array',
132
- required: true,
133
- minimum: 0,
134
- maximum: 2,
135
- property: { type: 'string', minLength: 1 }
136
- }
137
- });
138
-
139
- const valid = schema.processData({ tags: [] });
140
- assert.deepEqual(valid.tags, []);
141
-
142
- assert.throws(() => schema.processData({ tags: ['a', 'b', 'c'] }), SchemaError);
143
- assert.throws(() => schema.processData({ tags: [''] }), SchemaError);
144
-
145
- logTestResult('array - Limits and item validation', true);
146
- } catch (error) {
147
- logTestResult('array - Limits and item validation', false, error);
148
- }
149
- }
150
-
151
- /**
152
- * Ensures deep dot-path updates in processPartialData work.
153
- */
154
- function testDeepPartialProcessing() {
155
- try {
156
- const schema = new Schema({
157
- profile: {
158
- type: 'object',
159
- required: true,
160
- schema: {
161
- address: {
162
- type: 'object',
163
- required: true,
164
- schema: {
165
- zip: { type: 'number', required: true, minimum: 0 }
166
- }
167
- }
168
- }
169
- }
170
- });
171
-
172
- const partial = schema.processPartialData({ 'profile.address.zip': 1200 });
173
- assert.equal(partial['profile.address.zip'], 1200);
174
-
175
- assert.throws(() => schema.processPartialData({ 'profile.address.missing': 1 }), SchemaError);
176
-
177
- logTestResult('partial - Deep object path validation', true);
178
- } catch (error) {
179
- logTestResult('partial - Deep object path validation', false, error);
180
- }
181
- }
182
-
183
- /**
184
- * Ensures processData in partial mode rejects unknown root keys.
185
- */
186
- function testPartialUnknownRootKey() {
187
- try {
188
- const schema = new Schema({
189
- host: { type: 'string', required: true }
190
- });
191
-
192
- assert.throws(
193
- // @ts-expect-error Runtime validation test with unknown key on purpose.
194
- () => schema.processData({ host: 'localhost', extra: 'x' }, true),
195
- SchemaError
196
- );
197
-
198
- logTestResult('partial - Unknown root key rejected', true);
199
- } catch (error) {
200
- logTestResult('partial - Unknown root key rejected', false, error);
201
- }
202
- }
203
-
204
- /**
205
- * Ensures object properties reject arrays as invalid object values.
206
- */
207
- function testObjectRejectsArrayValue() {
208
- try {
209
- const schema = new Schema({
210
- profile: {
211
- type: 'object',
212
- required: true,
213
- schema: {
214
- zip: { type: 'number', required: true }
215
- }
216
- }
217
- });
218
-
219
- assert.throws(
220
- // @ts-expect-error Runtime validation test with invalid object value on purpose.
221
- () => schema.processData({ profile: [] }),
222
- SchemaError
223
- );
224
-
225
- logTestResult('object - Arrays are rejected', true);
226
- } catch (error) {
227
- logTestResult('object - Arrays are rejected', false, error);
228
- }
229
- }
230
-
231
- /**
232
- * Ensures JSON Schema output maps arrays with items/minItems/maxItems.
233
- */
234
- function testJsonSchemaArrayMapping() {
235
- try {
236
- const schema = new Schema({
237
- tags: {
238
- type: 'array',
239
- minimum: 1,
240
- maximum: 3,
241
- property: { type: 'string', minLength: 2 }
242
- }
243
- });
244
-
245
- const json = schema.jsonSchema;
246
- const tags = json.properties?.tags;
247
- const tagsItems = tags?.items;
248
-
249
- assert.equal(tags?.type, 'array');
250
- assert.equal(tags?.minItems, 1);
251
- assert.equal(tags?.maxItems, 3);
252
- assert.ok(tagsItems && !Array.isArray(tagsItems));
253
- assert.equal(tagsItems.type, 'string');
254
- assert.equal(tagsItems.minLength, 2);
255
-
256
- logTestResult('jsonSchema - Array mapping', true);
257
- } catch (error) {
258
- logTestResult('jsonSchema - Array mapping', false, error);
259
- }
260
- }
261
-
262
- /**
263
- * Ensures string enum validation accepts only allowed values.
264
- */
265
- function testStringEnumValidation() {
266
- try {
267
- const schema = new Schema({
268
- mode: { type: 'string', required: true, enum: ['A', 'B'] }
269
- });
270
-
271
- const valid = schema.processData({ mode: 'A' });
272
- assert.equal(valid.mode, 'A');
273
-
274
- assert.throws(() => schema.processData({ mode: 'C' }), SchemaError);
275
-
276
- logTestResult('string - Enum validation', true);
277
- } catch (error) {
278
- logTestResult('string - Enum validation', false, error);
279
- }
280
- }
281
-
282
- /**
283
- * Ensures JSON Schema output contains enum for string properties.
284
- */
285
- function testJsonSchemaStringEnumMapping() {
286
- try {
287
- const schema = new Schema({
288
- mode: { type: 'string', enum: ['A', 'B'] }
289
- });
290
-
291
- const json = schema.jsonSchema;
292
- const mode = json.properties?.mode;
293
-
294
- assert.equal(mode?.type, 'string');
295
- assert.deepEqual(mode?.enum, ['A', 'B']);
296
-
297
- logTestResult('jsonSchema - String enum mapping', true);
298
- } catch (error) {
299
- logTestResult('jsonSchema - String enum mapping', false, error);
300
- }
301
- }
302
-
303
- /**
304
- * Ensures nested unique keys are listed with dot notation.
305
- */
306
- function testUniqueKeyCollection() {
307
- try {
308
- const schema = new Schema({
309
- username: { type: 'string', unique: true },
310
- profile: {
311
- type: 'object',
312
- schema: {
313
- email: { type: 'string', unique: true },
314
- country: { type: 'string' }
315
- }
316
- }
317
- });
318
-
319
- const uniques = schema.uniques.sort();
320
- assert.deepEqual(uniques, ['profile.email', 'username']);
321
-
322
- logTestResult('uniques - Nested keys collected', true);
323
- } catch (error) {
324
- logTestResult('uniques - Nested keys collected', false, error);
325
- }
326
- }
327
-
328
- /**
329
- * Ensures invalid schema definitions fail at construction time.
330
- */
331
- function testInvalidSchemaDefinition() {
332
- try {
333
- assert.throws(() => {
334
- // @ts-ignore Runtime validation test with invalid shape on purpose.
335
- new Schema({ name: { type: 'string', pattern: 'not-a-regexp' } });
336
- }, SchemaError);
337
-
338
- logTestResult('schema - Invalid definition rejected', true);
339
- } catch (error) {
340
- logTestResult('schema - Invalid definition rejected', false, error);
341
- }
342
- }
343
-
344
- function runTests() {
345
- logger.log('\n&C6=== Schema Test Suite ===\n');
346
-
347
- testProcessDataWithDefaults();
348
- testRequiredFieldFailure();
349
- testZeroBoundaries();
350
- testArrayValidation();
351
- testDeepPartialProcessing();
352
- testPartialUnknownRootKey();
353
- testObjectRejectsArrayValue();
354
- testJsonSchemaArrayMapping();
355
- testStringEnumValidation();
356
- testJsonSchemaStringEnumMapping();
357
- testUniqueKeyCollection();
358
- testInvalidSchemaDefinition();
359
-
360
- logger.log('\n&C6=== Results ===');
361
- logger.log(`&C2✓ Passed: ${testsPassed}`);
362
- logger.log(`&C1✗ Failed: ${testsFailed}`);
363
- logger.log(`&C3Total: ${testsPassed + testsFailed}\n`);
364
-
365
- process.exit(testsFailed > 0 ? 1 : 0);
366
- }
367
-
368
- runTests();
package/tests/test.env DELETED
File without changes
package/tests/test.js DELETED
@@ -1,131 +0,0 @@
1
- /// @ts-check
2
-
3
- import Vortez, { Logger, Utilities } from "../build/Vortez.js";
4
- import "./debug.js";
5
- import "./utilities.js";
6
-
7
- /* | ENABLING ALL THE Vortez LOGS IN CONSOLE | */
8
- Logger.Debug.showAll = true;
9
- /* | CREATING DEBUG INSTANCE TO THE TESTS | */
10
- const debug = new Logger({ prefix: 'TEST' });
11
-
12
- /* | CREATING ENV VARIABLES FOR THE TESTS | */
13
-
14
- await Utilities.Env.load('tests/test.env');
15
- // Utilities.Env.loadSync('tests/test.env');
16
-
17
- /* | CREATING SERVER | */
18
- const server = new Vortez({ port: 8001 });
19
-
20
- /* | FILE RULE TEST | */
21
- server.router.addFile('/File', 'changes.md')
22
- server.router.addFile('/favicon.ico', 'global/Source/Logo_SM_960.png');
23
-
24
- /* | FILE RULE TEST USING AUTH EXEC | */
25
- server.router.addFile('/FileWA', 'changes.md')
26
- .use(async (request, Response, next) => {
27
- const { Auth } = request.searchParams;
28
- if (Auth === 'AuthYes') return next();
29
- throw new Vortez.ServerError('No authorized', 401);
30
- });
31
-
32
- /* | CREATING RULES WITH THE RULE CONSTRUCTOR | */
33
- server.router.addRules(
34
- new Vortez.Router.HttpRule('GET', '/MyFile/*', (Rq, Rs) => Rs.sendFile('Test/Test.js'))
35
- );
36
-
37
- /* | FOLDER RULES TEST | */
38
- server.router.addFolder('/Folder', '.debug');
39
-
40
- /* | ACTION RULES TEST | */
41
- server.router.addAction('ALL', '/', (Rq, Rs) => {
42
- return Rs.sendTemplate('tests/test.vhtml', {
43
- Tittle: '[NetFeez-Labs] · Tests',
44
- Sources: {
45
- File: '/File',
46
- FileWithAuthFunction_NoAuth: '/FileWA',
47
- FileWithAuthFunction_Auth: '/FileWA?Auth=AuthYes',
48
- Folder: '/Folder',
49
- RuleParams: '/RuleParams/param1/param2/param3/XD',
50
- WebSocket: '/WebSocket'
51
- }
52
- });
53
- });
54
-
55
- /* | URL RULE PARAMS TEST | */
56
- server.router.addAction('ALL', '/RuleParams/$?param1/$?b/$?c/*', (Rq, Rs) => {
57
- Rs.sendJson({
58
- Url: Rq.url,
59
- RuleParams: Rq.ruleParams
60
- })
61
- });
62
-
63
- /* | WEBSOCKET RULE TEST | */
64
- /**
65
- * @typedef {import('../build/server/websocket/Websocket.js').Websocket} WebSocket
66
- */
67
- /** @type {Set<WebSocket>} */
68
- const clients = new Set();
69
- /** @type {Set<string>} */
70
- const usernames = new Set();
71
-
72
- /**
73
- *
74
- * @param {string | Buffer} message
75
- * @param {WebSocket | null | undefined} exclude
76
- */
77
- function broadCast(message, exclude = null) {
78
- clients.forEach(client => {
79
- if (!exclude || client !== exclude) client.send(message)
80
- })
81
- }
82
-
83
- server.router.addAction('ALL', 'WebSocket', (Rq, Rs) => {
84
- return Rs.sendTemplate('tests/websocket.vhtml', {
85
- Host: `/WebSocket`
86
- });
87
- });
88
-
89
- server.router.addWebsocket('/WebSocket/$?username', (request, socket) => {
90
- const username = request.ruleParams.username;
91
- if (!username) {
92
- socket.send('error: no username');
93
- socket.end();
94
- return;
95
- }
96
- if (usernames.has(username)) {
97
- socket.send('error: username already in use');
98
- socket.end();
99
- return;
100
- }
101
- usernames.add(username)
102
- clients.add(socket);
103
- debug.log("[WebSocket]", "new client", username);
104
-
105
- socket.send("[server] hallo");
106
- broadCast('[server] new client: ' + username, socket);
107
-
108
- socket.on('message', (data, info) => {
109
- if (info.opCode !== 0x1) return;
110
- const message = username + ': ' + data.toString();
111
- debug.log(['[WebSocket]', message]);
112
- broadCast(message, socket);
113
- });
114
- socket.on('error', (Error) => {
115
- debug.log('[WebSocket-Error]: ' + Error.message);
116
- });
117
- socket.on('finish', () => {
118
- clients.delete(socket);
119
- usernames.delete(username);
120
- broadCast('[server] client disconnected: ' + username);
121
- debug.log('[WebSocket-Finish]: client disconnected')
122
- });
123
- }).use((request, client, next) => {
124
- const { username } = request.ruleParams;
125
- if (!username) return next(new Vortez.ServerError('no username', 400));
126
- if (username === 'system') return next(new Vortez.ServerError('you cant use system as username', 400));
127
- return next();
128
- });
129
- const cli = new Vortez.ServerDebug(server);
130
- cli.start();
131
- server.start();
package/tests/test.vhtml DELETED
@@ -1,14 +0,0 @@
1
- <!DOCTYPE html>
2
- <html lang="es-CO">
3
- <head>
4
- <meta charset="UTF-8">
5
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
- <title>${Tittle}</title>
7
- </head>
8
- <body>
9
- <h1>${Tittle}</h1>
10
- $(Sources, text, url) {
11
- <a href="%url%">%text%</a><br>
12
- }
13
- </body>
14
- </html>
@@ -1,28 +0,0 @@
1
- //@ts-check
2
- import Utilities from "../build/utilities/Utilities.js";
3
-
4
- try {
5
- const toFlatten = {
6
- a: { b: {
7
- c: "a.b.c",
8
- d: "a.b.c.d",
9
- f: {g:{h:{i:{j:{j:{k:{l:"a.b.c.d.f.g.h.i.j.j.k.l"}}}}}}},
10
- z: {g:{h:{i:{j:{j:{k:{l2:"a.b.z.d.f.g.h.i.j.j.k.l2"}}}}}}}
11
- },
12
- null: null,
13
- undefined: undefined
14
- },
15
- e: { f: "e.f" },
16
- arr: [1,2,3,4]
17
- }
18
-
19
- const flattened = Utilities.flattenObject(toFlatten, 9);
20
- const unFlattened = Utilities.unFlattenObject(flattened);
21
- if (!Utilities.deepEqual(toFlatten, unFlattened)) {
22
- throw new Error("Flatten test fail: toFlatten != unFlattened");
23
- } else {
24
- console.log("Flatten test success");
25
- }
26
- } catch (error) {
27
- console.error(error);
28
- }
@@ -1,86 +0,0 @@
1
- <!DOCTYPE html>
2
- <html lang="es-CO">
3
- <head>
4
- <meta charset="UTF-8">
5
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
- <title>[NetFeez-Labs · WebSocket]</title>
7
- </head>
8
- <body>
9
- <h1>[NetFeez-Labs · WebSocket]</h1>
10
- <input id="username" type="text" placeholder="Username"/>
11
- <button id="Connect">Conectar</button>
12
- <button id="Disconnect">Desconectar</button>
13
- <br/>
14
- <input id="InMessage" type="text" placeholder="Message/Command"/>
15
- <button id="Send">Enviar</button>
16
- <div id="Log"></div>
17
- <script>
18
- window.host = "${Host}";
19
- const BtnConnect = document.querySelector('#Connect');
20
- const BtnDisconnect = document.querySelector('#Disconnect');
21
- const BtnSend = document.querySelector('#Send');
22
-
23
- const inUsername = document.querySelector('#username');
24
- const InMessage = document.querySelector('#InMessage');
25
- const OutLog = document.querySelector('#Log');
26
-
27
- let Connected = false;
28
- /** @type {WebSocket} */
29
- let Connection = null;
30
-
31
- /** @param {string} Message */
32
- const Log = (Message, Prefix = 'WS') => {
33
- console.log(`[${Prefix}]:`, Message);
34
- let Element = document.createElement('p');
35
- Element.innerText = `[${Prefix}]: ` + Message;
36
- if (OutLog.firstChild) {
37
- OutLog.insertBefore(Element, OutLog.firstChild);
38
- } else {
39
- OutLog.appendChild(Element);
40
- }
41
- }
42
-
43
- const Connect = () => {
44
- if (Connected) {
45
- Log('Ya estas conectado');
46
- } else {
47
- const username = inUsername.value;
48
- Log('Conectando...');
49
- Connection = new WebSocket(`${Host}/${username}`);
50
- Connection.onerror = () => {
51
- Log('fallo en la conexión', 'ER');
52
- }
53
- Connection.onclose = () => {
54
- Connected = false;
55
- Connection = null;
56
- }
57
- Connection.onopen = () => {
58
- Connected = true;
59
- Log('Conectado');
60
- }
61
- Connection.onmessage = (Ev) => {
62
- Log(Ev.data, '<');
63
- console.log(Ev.data);
64
- };
65
- }
66
- }
67
- const Disconnect = () => {
68
- Connection.close();
69
- }
70
- const Send = () => {
71
- if (Connected) {
72
- let Message = InMessage.value;
73
- InMessage.value = '';
74
- Connection.send(Message);
75
- Log(Message, '>');
76
- } else {
77
- Log('Debes conectarte primero');
78
- }
79
- }
80
-
81
- BtnConnect.addEventListener('click', () => Connect());
82
- BtnDisconnect.addEventListener('click', () => Disconnect());
83
- BtnSend.addEventListener('click', () => Send());
84
- </script>
85
- </body>
86
- </html>