miqro 6.1.3 → 6.2.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/build/editor.bundle.js +26 -2
- package/build/esm/editor/common/templates.js +16 -0
- package/build/esm/editor/components/editor.js +8 -0
- package/build/esm/editor/components/file-editor.js +1 -1
- package/build/esm/editor/components/highlight-text-area.js +2 -1
- package/build/esm/src/bin/types.js +8 -0
- package/build/esm/src/common/arguments.d.ts +7 -1
- package/build/esm/src/common/arguments.js +72 -10
- package/build/esm/src/common/help.d.ts +1 -1
- package/build/esm/src/common/help.js +33 -29
- package/build/esm/src/common/jwt.d.ts +49 -0
- package/build/esm/src/common/jwt.js +76 -0
- package/build/esm/src/inflate/inflate-sea.js +9 -8
- package/build/esm/src/inflate/setup-http.d.ts +1 -0
- package/build/esm/src/inflate/setup-http.js +8 -0
- package/build/esm/src/inflate/setup-ws.d.ts +1 -1
- package/build/esm/src/inflate/setup-ws.js +2 -2
- package/build/esm/src/lib.d.ts +1 -1
- package/build/esm/src/lib.js +2 -2
- package/build/esm/src/main.js +3 -1
- package/build/esm/src/services/app.d.ts +2 -0
- package/build/esm/src/services/app.js +7 -6
- package/build/esm/src/services/globals.js +45 -1
- package/build/esm/src/services/utils/cluster-ws.d.ts +4 -2
- package/build/esm/src/services/utils/cluster-ws.js +10 -1
- package/build/esm/src/services/utils/log-transport.d.ts +2 -2
- package/build/esm/src/services/utils/log-transport.js +8 -3
- package/build/esm/src/services/utils/server-interface.d.ts +4 -30
- package/build/esm/src/services/utils/server-interface.js +44 -59
- package/build/esm/src/services/utils/websocketmanager.d.ts +3 -0
- package/build/esm/src/services/utils/websocketmanager.js +8 -2
- package/build/esm/src/types.d.ts +76 -5
- package/build/lib.cjs +2992 -369
- package/editor/common/templates.ts +15 -0
- package/editor/components/editor.tsx +8 -0
- package/editor/components/file-editor.tsx +1 -1
- package/editor/components/highlight-text-area.tsx +2 -1
- package/package.json +4 -3
- package/sea/install-nodejs.sh +1 -1
- package/sea/node.version.tag +1 -1
- package/sea/types.json +1 -1
- package/src/bin/types.ts +7 -0
- package/src/common/arguments.ts +84 -11
- package/src/common/help.ts +33 -29
- package/src/common/jwt.ts +85 -0
- package/src/inflate/inflate-sea.ts +9 -8
- package/src/inflate/setup-db.ts +3 -1
- package/src/inflate/setup-http.ts +9 -0
- package/src/inflate/setup-ws.ts +4 -3
- package/src/lib.ts +2 -2
- package/src/main.ts +3 -1
- package/src/services/app.ts +10 -6
- package/src/services/globals.ts +45 -2
- package/src/services/utils/cluster-ws.ts +6 -1
- package/src/services/utils/log-transport.ts +10 -4
- package/src/services/utils/server-interface.ts +44 -133
- package/src/services/utils/websocketmanager.ts +10 -2
- package/src/types/cookie.d.ts +2 -0
- package/src/types/jose.d.ts +2 -0
- package/src/types/miqro.d.ts +92 -2
- package/src/types/server.globals.d.ts +4 -29
- package/src/types.ts +78 -5
package/build/editor.bundle.js
CHANGED
|
@@ -8835,8 +8835,8 @@ function HighlightTextArea({ content, language, oncontentchange, tabChar, disabl
|
|
|
8835
8835
|
ev.preventDefault();
|
|
8836
8836
|
if (elementRef.current) {
|
|
8837
8837
|
if (content !== elementRef.current.textContent) {
|
|
8838
|
-
elementRef.current.innerHTML = runHighlight(elementRef.current.textContent, language);
|
|
8839
8838
|
}
|
|
8839
|
+
elementRef.current.innerHTML = runHighlight(elementRef.current.textContent, language);
|
|
8840
8840
|
}
|
|
8841
8841
|
},
|
|
8842
8842
|
onkeydown: (ev) => {
|
|
@@ -9272,7 +9272,7 @@ function FileEditor({ disableLog, disablePreview, disableReload, togglePanel, is
|
|
|
9272
9272
|
apiPreview
|
|
9273
9273
|
}
|
|
9274
9274
|
) : /* @__PURE__ */ JSX.createElement(JSX.Fragment, null),
|
|
9275
|
-
previewPath ? /* @__PURE__ */ JSX.createElement(
|
|
9275
|
+
previewPath && isPanelVisible("right") ? /* @__PURE__ */ JSX.createElement(
|
|
9276
9276
|
"div",
|
|
9277
9277
|
{
|
|
9278
9278
|
class: `file-editor-preview`,
|
|
@@ -9577,6 +9577,22 @@ export default {
|
|
|
9577
9577
|
]
|
|
9578
9578
|
}
|
|
9579
9579
|
}
|
|
9580
|
+
`
|
|
9581
|
+
},
|
|
9582
|
+
MIQROJSON: {
|
|
9583
|
+
prefix: "",
|
|
9584
|
+
sufix: ".json",
|
|
9585
|
+
filename: "miqro",
|
|
9586
|
+
displayName: "miqro.json file",
|
|
9587
|
+
language: "json",
|
|
9588
|
+
template: () => `{
|
|
9589
|
+
"services": ["src/"],
|
|
9590
|
+
"inflateDir": "build/",
|
|
9591
|
+
"name": "server",
|
|
9592
|
+
"browser": true,
|
|
9593
|
+
"logFile": false,
|
|
9594
|
+
"port": "3000"
|
|
9595
|
+
}
|
|
9580
9596
|
`
|
|
9581
9597
|
},
|
|
9582
9598
|
MINIFIEDJSX: {
|
|
@@ -10505,6 +10521,14 @@ function Editor(props) {
|
|
|
10505
10521
|
const { files: files2, services: services2 } = await r.json();
|
|
10506
10522
|
setfiles(files2);
|
|
10507
10523
|
setservices(services2);
|
|
10524
|
+
for (const file of files2) {
|
|
10525
|
+
if (opened[file.filePath]) {
|
|
10526
|
+
opened[file.filePath] = {
|
|
10527
|
+
content: opened[file.filePath].content,
|
|
10528
|
+
...file
|
|
10529
|
+
};
|
|
10530
|
+
}
|
|
10531
|
+
}
|
|
10508
10532
|
}
|
|
10509
10533
|
}
|
|
10510
10534
|
function isDirCollapsed(dir) {
|
|
@@ -281,6 +281,22 @@ export default {
|
|
|
281
281
|
]
|
|
282
282
|
}
|
|
283
283
|
}
|
|
284
|
+
`
|
|
285
|
+
},
|
|
286
|
+
MIQROJSON: {
|
|
287
|
+
prefix: "",
|
|
288
|
+
sufix: ".json",
|
|
289
|
+
filename: "miqro",
|
|
290
|
+
displayName: "miqro.json file",
|
|
291
|
+
language: "json",
|
|
292
|
+
template: () => `{
|
|
293
|
+
"services": ["src/"],
|
|
294
|
+
"inflateDir": "build/",
|
|
295
|
+
"name": "server",
|
|
296
|
+
"browser": true,
|
|
297
|
+
"logFile": false,
|
|
298
|
+
"port": "3000"
|
|
299
|
+
}
|
|
284
300
|
`
|
|
285
301
|
},
|
|
286
302
|
MINIFIEDJSX: {
|
|
@@ -147,6 +147,14 @@ export function Editor(props) {
|
|
|
147
147
|
const { files, services } = await r.json();
|
|
148
148
|
setfiles(files);
|
|
149
149
|
setservices(services);
|
|
150
|
+
for (const file of files) {
|
|
151
|
+
if (opened[file.filePath]) {
|
|
152
|
+
opened[file.filePath] = {
|
|
153
|
+
content: opened[file.filePath].content,
|
|
154
|
+
...file
|
|
155
|
+
};
|
|
156
|
+
}
|
|
157
|
+
}
|
|
150
158
|
}
|
|
151
159
|
}
|
|
152
160
|
function isDirCollapsed(dir) {
|
|
@@ -50,7 +50,7 @@ export function FileEditor({ disableLog, disablePreview, disableReload, togglePa
|
|
|
50
50
|
}
|
|
51
51
|
}, content: content, language: language }) : JSX.createElement("p", null, "binary data not supported")),
|
|
52
52
|
apiPreview && apiPreview.length > 0 ? JSX.createElement(APIPReview, { isPanelVisible: isPanelVisible, apiPreview: apiPreview }) : JSX.createElement(JSX.Fragment, null),
|
|
53
|
-
previewPath ? JSX.createElement("div", { class: `file-editor-preview`, style: `${!isPanelVisible("right") ? "display: none;" : ""}` },
|
|
53
|
+
previewPath && isPanelVisible("right") ? JSX.createElement("div", { class: `file-editor-preview`, style: `${!isPanelVisible("right") ? "display: none;" : ""}` },
|
|
54
54
|
JSX.createElement("div", { class: "file-editor-preview-path" },
|
|
55
55
|
JSX.createElement("a", { href: previewPath, target: "_blank" }, "open in new window")),
|
|
56
56
|
JSX.createElement("iframe", { ref: iFrameRef, src: previewPath, sandbox: "allow-scripts allow-same-origin" })) : JSX.createElement(JSX.Fragment, null))));
|
|
@@ -94,8 +94,9 @@ export function HighlightTextArea({ content, language, oncontentchange, tabChar,
|
|
|
94
94
|
if (elementRef.current) {
|
|
95
95
|
if (content !== elementRef.current.textContent) {
|
|
96
96
|
//setlastContent(String(elementRef.current.textContent));
|
|
97
|
-
elementRef.current.innerHTML = runHighlight(elementRef.current.textContent, language);
|
|
97
|
+
//elementRef.current.innerHTML = runHighlight(elementRef.current.textContent, language);
|
|
98
98
|
}
|
|
99
|
+
elementRef.current.innerHTML = runHighlight(elementRef.current.textContent, language);
|
|
99
100
|
}
|
|
100
101
|
}, onkeydown: ev => {
|
|
101
102
|
if (ev.keyCode === 9) {
|
|
@@ -16,5 +16,13 @@ export async function installTypings(args, logger) {
|
|
|
16
16
|
logger.error("tsconfig.json already exists!");
|
|
17
17
|
process.exit(EXIT_CODES.ABNORMAL);
|
|
18
18
|
}
|
|
19
|
+
if (args.installMiqroJSON && !existsSync("miqro.json")) {
|
|
20
|
+
logger.info("writing miqro.json");
|
|
21
|
+
writeFileSync("miqro.json", TEMPLATES["MIQROJSON"].template("", ""));
|
|
22
|
+
}
|
|
23
|
+
else if (args.installMiqroJSON) {
|
|
24
|
+
logger.error("miqro.json already exists!");
|
|
25
|
+
process.exit(EXIT_CODES.ABNORMAL);
|
|
26
|
+
}
|
|
19
27
|
process.exit(EXIT_CODES.NORMAL_EXIT);
|
|
20
28
|
}
|
|
@@ -3,12 +3,18 @@ interface MiqroJSON {
|
|
|
3
3
|
port?: string | number;
|
|
4
4
|
inflateDir?: string;
|
|
5
5
|
name?: string;
|
|
6
|
+
browser?: string | boolean;
|
|
7
|
+
logFile?: string | boolean;
|
|
8
|
+
editor?: boolean;
|
|
6
9
|
}
|
|
7
10
|
export declare function importMiqroJSON(inFile: string): MiqroJSON;
|
|
8
11
|
export declare function getPORT(): string;
|
|
9
12
|
export interface Arguments {
|
|
10
|
-
name
|
|
13
|
+
name?: string;
|
|
14
|
+
browser?: string | boolean;
|
|
15
|
+
logFile?: string | boolean;
|
|
11
16
|
installTypes: boolean;
|
|
17
|
+
installMiqroJSON: boolean;
|
|
12
18
|
installTSConfig: boolean;
|
|
13
19
|
test: boolean;
|
|
14
20
|
port: string;
|
|
@@ -18,7 +18,10 @@ const MiqroJSONSchema = {
|
|
|
18
18
|
name: "string?",
|
|
19
19
|
services: "string[]?",
|
|
20
20
|
port: "number?|string?",
|
|
21
|
-
inflateDir: "string?"
|
|
21
|
+
inflateDir: "string?",
|
|
22
|
+
browser: "boolean?|string?",
|
|
23
|
+
logFile: "boolean?|string?",
|
|
24
|
+
editor: "boolean?"
|
|
22
25
|
}
|
|
23
26
|
};
|
|
24
27
|
export function importMiqroJSON(inFile) {
|
|
@@ -42,8 +45,11 @@ export function parseArguments() {
|
|
|
42
45
|
const args = cluster.isPrimary ? process.argv.slice(2, process.argv.length) : process.argv.slice(3, process.argv.length);
|
|
43
46
|
const flags = {
|
|
44
47
|
name: null,
|
|
48
|
+
browser: null,
|
|
49
|
+
logFile: null,
|
|
45
50
|
hotreload: null,
|
|
46
51
|
miqroJSONPath: null,
|
|
52
|
+
installMiqroJSON: null,
|
|
47
53
|
disableMiqroJSON: null,
|
|
48
54
|
installTypes: null,
|
|
49
55
|
port: null,
|
|
@@ -130,7 +136,7 @@ export function parseArguments() {
|
|
|
130
136
|
console.error(usage);
|
|
131
137
|
process.exit(EXIT_CODES.BAD_ARGUMENTS);
|
|
132
138
|
}
|
|
133
|
-
const cPort = String(args[i + 1])
|
|
139
|
+
const cPort = String(args[i + 1]);
|
|
134
140
|
if (typeof cPort !== "string") {
|
|
135
141
|
console.error("bad arguments. --port must be a string.");
|
|
136
142
|
console.error(usage);
|
|
@@ -154,6 +160,36 @@ export function parseArguments() {
|
|
|
154
160
|
flags.name = cName;
|
|
155
161
|
i++;
|
|
156
162
|
continue;
|
|
163
|
+
case "--log-file":
|
|
164
|
+
if (flags.logFile !== null) {
|
|
165
|
+
console.error("bad arguments.");
|
|
166
|
+
console.error(usage);
|
|
167
|
+
process.exit(EXIT_CODES.BAD_ARGUMENTS);
|
|
168
|
+
}
|
|
169
|
+
const cLofFile = String(args[i + 1]);
|
|
170
|
+
if (typeof cLofFile !== "string") {
|
|
171
|
+
console.error("bad arguments. --port must be a string.");
|
|
172
|
+
console.error(usage);
|
|
173
|
+
process.exit(EXIT_CODES.BAD_ARGUMENTS);
|
|
174
|
+
}
|
|
175
|
+
flags.logFile = cLofFile;
|
|
176
|
+
i++;
|
|
177
|
+
continue;
|
|
178
|
+
case "--browser":
|
|
179
|
+
if (flags.browser !== null) {
|
|
180
|
+
console.error("bad arguments.");
|
|
181
|
+
console.error(usage);
|
|
182
|
+
process.exit(EXIT_CODES.BAD_ARGUMENTS);
|
|
183
|
+
}
|
|
184
|
+
const cBrowser = String(args[i + 1]);
|
|
185
|
+
if (typeof cBrowser !== "string") {
|
|
186
|
+
console.error("bad arguments. --port must be a string.");
|
|
187
|
+
console.error(usage);
|
|
188
|
+
process.exit(EXIT_CODES.BAD_ARGUMENTS);
|
|
189
|
+
}
|
|
190
|
+
flags.browser = cBrowser;
|
|
191
|
+
i++;
|
|
192
|
+
continue;
|
|
157
193
|
case "--generate-doc":
|
|
158
194
|
if (flags.generateDoc !== null) {
|
|
159
195
|
console.error("bad arguments.");
|
|
@@ -228,6 +264,14 @@ export function parseArguments() {
|
|
|
228
264
|
}
|
|
229
265
|
flags.editor = true;
|
|
230
266
|
continue;
|
|
267
|
+
case "--install-miqrojson":
|
|
268
|
+
if (flags.installMiqroJSON !== null) {
|
|
269
|
+
console.error("bad arguments. --install-miqrojson already set.");
|
|
270
|
+
console.error(usage);
|
|
271
|
+
process.exit(EXIT_CODES.BAD_ARGUMENTS);
|
|
272
|
+
}
|
|
273
|
+
flags.installMiqroJSON = true;
|
|
274
|
+
continue;
|
|
231
275
|
case "--inflate-sea":
|
|
232
276
|
if (flags.inflateSEA !== null) {
|
|
233
277
|
console.error("bad arguments. --inflate-sea already set.");
|
|
@@ -308,7 +352,6 @@ export function parseArguments() {
|
|
|
308
352
|
}
|
|
309
353
|
}
|
|
310
354
|
flags.inflate = flags.inflate ? flags.inflate : false;
|
|
311
|
-
flags.editor = flags.editor ? flags.editor : false;
|
|
312
355
|
flags.test = flags.test ? flags.test : false;
|
|
313
356
|
flags.inflateDir = flags.inflateDir ? flags.inflateDir : undefined;
|
|
314
357
|
const miqroJSONPath = !flags.disableMiqroJSON ? flags.miqroJSONPath ? resolve(flags.miqroJSONPath) : getMiqroJSONPath() : false;
|
|
@@ -322,7 +365,7 @@ export function parseArguments() {
|
|
|
322
365
|
}
|
|
323
366
|
}
|
|
324
367
|
}
|
|
325
|
-
if (
|
|
368
|
+
if (flags.port === null) {
|
|
326
369
|
if (miqroRC.port) {
|
|
327
370
|
flags.port = String(miqroRC.port);
|
|
328
371
|
}
|
|
@@ -332,13 +375,29 @@ export function parseArguments() {
|
|
|
332
375
|
flags.inflateDir = miqroRC.inflateDir;
|
|
333
376
|
}
|
|
334
377
|
}
|
|
335
|
-
if (
|
|
378
|
+
if (flags.name === null) {
|
|
336
379
|
if (miqroRC.name) {
|
|
337
380
|
flags.name = miqroRC.name;
|
|
338
381
|
}
|
|
339
382
|
}
|
|
383
|
+
if (flags.logFile === null) {
|
|
384
|
+
if (miqroRC.logFile !== undefined) {
|
|
385
|
+
flags.logFile = miqroRC.logFile;
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
if (flags.browser === null) {
|
|
389
|
+
if (miqroRC.browser !== undefined) {
|
|
390
|
+
flags.browser = miqroRC.browser;
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
if (flags.editor === null) {
|
|
394
|
+
if (miqroRC.editor !== undefined) {
|
|
395
|
+
flags.editor = miqroRC.editor;
|
|
396
|
+
}
|
|
397
|
+
}
|
|
340
398
|
}
|
|
341
|
-
|
|
399
|
+
flags.editor = flags.editor ? flags.editor : false;
|
|
400
|
+
if (services.length === 0 && (!flags.installTSConfig && !flags.installTypes && !flags.installMiqroJSON)) {
|
|
342
401
|
flags.inflateDir = flags.inflateDir ? flags.inflateDir : undefined;
|
|
343
402
|
console.error(`bad arguments. missing --service argument`);
|
|
344
403
|
console.error(usage);
|
|
@@ -368,16 +427,16 @@ export function parseArguments() {
|
|
|
368
427
|
console.error("bad arguments. cannot use --inflate with --editor");
|
|
369
428
|
process.exit(EXIT_CODES.BAD_ARGUMENTS);
|
|
370
429
|
}
|
|
371
|
-
if (flags.inflate && (flags.installTypes || flags.installTSConfig)) {
|
|
372
|
-
console.error("bad arguments. cannot use --inflate with --install-types");
|
|
430
|
+
if (flags.inflate && (flags.installTypes || flags.installTSConfig || flags.installMiqroJSON)) {
|
|
431
|
+
console.error("bad arguments. cannot use --inflate with --install-types, --install-tsconfig or --install-miqrojson");
|
|
373
432
|
process.exit(EXIT_CODES.BAD_ARGUMENTS);
|
|
374
433
|
}
|
|
375
434
|
if (flags.inflateSEA && !flags.inflate) {
|
|
376
435
|
console.error("bad arguments. cannot use --inflate-sea without --inflate");
|
|
377
436
|
process.exit(EXIT_CODES.BAD_ARGUMENTS);
|
|
378
437
|
}
|
|
379
|
-
if (flags.editor && (flags.installTypes || flags.installTSConfig)) {
|
|
380
|
-
console.error("bad arguments. cannot use --editor with --install-
|
|
438
|
+
if (flags.editor && (flags.installTypes || flags.installTSConfig || flags.installMiqroJSON)) {
|
|
439
|
+
console.error("bad arguments. cannot use --editor with--install-types, --install-tsconfig or --install-miqrojson");
|
|
381
440
|
process.exit(EXIT_CODES.BAD_ARGUMENTS);
|
|
382
441
|
}
|
|
383
442
|
if (flags.test && (flags.hotreload || flags.editor || flags.compile || flags.inflate)) {
|
|
@@ -403,11 +462,14 @@ export function parseArguments() {
|
|
|
403
462
|
const generateDocType = flags.generateDocType ? flags.generateDocType : "MD";
|
|
404
463
|
return {
|
|
405
464
|
name: flags.name ? flags.name : undefined,
|
|
465
|
+
browser: flags.browser !== null ? flags.browser : undefined,
|
|
466
|
+
logFile: flags.logFile !== null ? flags.logFile : undefined,
|
|
406
467
|
generateDocAll: flags.generateDocAll ? true : false,
|
|
407
468
|
hotreload: flags.hotreload ? true : false,
|
|
408
469
|
disableMiqroJSON: flags.disableMiqroJSON !== null ? flags.disableMiqroJSON : false,
|
|
409
470
|
miqroJSONPath: miqroJSONPath ? miqroJSONPath : false,
|
|
410
471
|
installTypes: flags.installTypes ? true : false,
|
|
472
|
+
installMiqroJSON: flags.installMiqroJSON ? true : false,
|
|
411
473
|
installTSConfig: flags.installTSConfig ? true : false,
|
|
412
474
|
inflate: flags.inflate,
|
|
413
475
|
port: flags.port ? flags.port : getPORT(),
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
export declare const BIN_NAME = "miqro";
|
|
2
2
|
export declare const usage = "usage: miqro [...FLAGS] --service app/\n\n==examples==\n\nmiqro --watch --service front/\nPORT=8181 miqro --service api/ --service front/\nmiqro --test --service front/\nmiqro --inflate --service front/\nmiqro --generate-doc --generate-doc-out API.md --service front/\nCLUSTER_COUNT=10 miqro-cluster --service api/";
|
|
3
|
-
export declare const help = "\n==flags==\n\n-v, --version\
|
|
3
|
+
export declare const help = "\n==flags==\n\n-v, --version\n\toutputs the version number\n-h, --help\n\toutputs this page.\n--watch\n\tuse to enable the hot-reload functionality.\n--test\n\trun the tests for a service.\n--migrate-up\n\tmigrations up.\n--migrate-down\n\tmigrations down.\n--inflate\n\tinflates the application.\n--inflate-dir\n\tto set the output directory of the --inflate command. default value is inflated/.\n--editor\n\truns the application with a built-in editor.\n--generate-doc\n\tgenerates a documentation for the api endpoints of the service.\n--generate-doc-out\n\tthe output file for the generated documentation. default value is API.md.\n--generate-doc-type\n\tthe format of the generated documentation. it can be JSON or MD. default value is MD.\n--generate-doc-all\n\toutputs all the server routes in the documentation output.\n--compile\n\tinflates the application and tries to create a NODE SEA binary.\n--inflate-sea\n\tinflates the application with sea compilation scripts.\n--install-tsconfig\n\tcreates a tsconfig.json configured to use with --install-types.\n--install-types\n\tcreates and updates the .types/ folder use together with --install-tsconfig.\n--install-miqrojson\n\tcreates a default miqro.json file.\n--disable-miqrojson\n\tdisables the load of miqro.json file.\n--log-file\n\toverrides the default log file from LOG_FILE.\n--browser\n\toverrides the default browser from BROWSER.\n--config\n\toverrides the default miqro.json path.\n--port\n\toverrides the default port from PORT.\n--name\n\toverrides the default name of the server.\n\n==environment variables==\n\nPORT\n\toverride the default 8080 port.\nBROWSER\n\toverride the default browser. change to none to disable.\".\nLOG_FILE\n\toverride the default ./server.log file\nDB\n\tenable the server.db features\nDB_STORAGE\n\toverride the default local db location ./db.sqlite3\nDB_DIALECT\n\toverride the default node:sqlite\nDB_CONNECTION\n\toverride the default connection url\nCLEAR_JSX_CACHE\n\tset to 1 or 0 to enable or disable the clearing of the esbuild cache defaults to 1.\nJSX_TMP\n\tset custom location of esbuild builds defaults to /tmp/jsx_tmp.\n";
|
|
@@ -13,36 +13,40 @@ CLUSTER_COUNT=10 ${BIN_NAME}-cluster --service api/`;
|
|
|
13
13
|
export const help = `
|
|
14
14
|
==flags==
|
|
15
15
|
|
|
16
|
-
-v, --version\
|
|
17
|
-
-h, --help\
|
|
18
|
-
--watch\
|
|
19
|
-
--test\
|
|
20
|
-
--migrate-up\
|
|
21
|
-
--migrate-down\
|
|
22
|
-
--inflate\
|
|
23
|
-
--inflate-dir\
|
|
24
|
-
--editor\
|
|
25
|
-
--generate-doc\
|
|
26
|
-
--generate-doc-out\tthe output file for the generated documentation. default value is API.md.
|
|
27
|
-
--generate-doc-type\tthe format of the generated documentation. it can be JSON or MD. default value is MD.
|
|
28
|
-
--generate-doc-all\toutputs all the server routes in the documentation output.
|
|
29
|
-
--compile\
|
|
30
|
-
--inflate-sea\
|
|
31
|
-
--install-tsconfig\tcreates a tsconfig.json configured to use with --install-types.
|
|
32
|
-
--install-types\
|
|
33
|
-
--
|
|
34
|
-
--
|
|
35
|
-
--
|
|
36
|
-
--
|
|
16
|
+
-v, --version\n\toutputs the version number
|
|
17
|
+
-h, --help\n\toutputs this page.
|
|
18
|
+
--watch\n\tuse to enable the hot-reload functionality.
|
|
19
|
+
--test\n\trun the tests for a service.
|
|
20
|
+
--migrate-up\n\tmigrations up.
|
|
21
|
+
--migrate-down\n\tmigrations down.
|
|
22
|
+
--inflate\n\tinflates the application.
|
|
23
|
+
--inflate-dir\n\tto set the output directory of the --inflate command. default value is inflated/.
|
|
24
|
+
--editor\n\truns the application with a built-in editor.
|
|
25
|
+
--generate-doc\n\tgenerates a documentation for the api endpoints of the service.
|
|
26
|
+
--generate-doc-out\n\tthe output file for the generated documentation. default value is API.md.
|
|
27
|
+
--generate-doc-type\n\tthe format of the generated documentation. it can be JSON or MD. default value is MD.
|
|
28
|
+
--generate-doc-all\n\toutputs all the server routes in the documentation output.
|
|
29
|
+
--compile\n\tinflates the application and tries to create a NODE SEA binary.
|
|
30
|
+
--inflate-sea\n\tinflates the application with sea compilation scripts.
|
|
31
|
+
--install-tsconfig\n\tcreates a tsconfig.json configured to use with --install-types.
|
|
32
|
+
--install-types\n\tcreates and updates the .types/ folder use together with --install-tsconfig.
|
|
33
|
+
--install-miqrojson\n\tcreates a default miqro.json file.
|
|
34
|
+
--disable-miqrojson\n\tdisables the load of miqro.json file.
|
|
35
|
+
--log-file\n\toverrides the default log file from LOG_FILE.
|
|
36
|
+
--browser\n\toverrides the default browser from BROWSER.
|
|
37
|
+
--config\n\toverrides the default miqro.json path.
|
|
38
|
+
--port\n\toverrides the default port from PORT.
|
|
39
|
+
--name\n\toverrides the default name of the server.
|
|
37
40
|
|
|
38
41
|
==environment variables==
|
|
39
42
|
|
|
40
|
-
PORT\
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
43
|
+
PORT\n\toverride the default 8080 port.
|
|
44
|
+
BROWSER\n\toverride the default browser. change to none to disable.".
|
|
45
|
+
LOG_FILE\n\toverride the default ./server.log file
|
|
46
|
+
DB\n\tenable the server.db features
|
|
47
|
+
DB_STORAGE\n\toverride the default local db location ./db.sqlite3
|
|
48
|
+
DB_DIALECT\n\toverride the default node:sqlite
|
|
49
|
+
DB_CONNECTION\n\toverride the default connection url
|
|
50
|
+
CLEAR_JSX_CACHE\n\tset to 1 or 0 to enable or disable the clearing of the esbuild cache defaults to 1.
|
|
51
|
+
JSX_TMP\n\tset custom location of esbuild builds defaults to /tmp/jsx_tmp.
|
|
48
52
|
`;
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { JWTDecryptOptions, JWTDecryptResult, JWTPayload, JWTVerifyOptions, JWTVerifyResult, ProtectedHeaderParameters } from "jose";
|
|
2
|
+
import { KeyObject } from "node:crypto";
|
|
3
|
+
import { EncryptJWTOptions, JWTSignOptions } from "../types.js";
|
|
4
|
+
/**
|
|
5
|
+
* creates a JWT encrypted token with jose
|
|
6
|
+
*
|
|
7
|
+
* @param payload the payload to encrypt
|
|
8
|
+
* @param secret the secret example. const secret = createSecretKey(process.env.JWT_SECRET, 'utf-8');
|
|
9
|
+
* @param options options like expiratation date, issuer and audience
|
|
10
|
+
* @returns
|
|
11
|
+
*/
|
|
12
|
+
export declare function encryptJWT(payload: JWTPayload, secret: KeyObject, options?: Partial<EncryptJWTOptions>): Promise<string>;
|
|
13
|
+
/**
|
|
14
|
+
* decrypts a JWT token with jose
|
|
15
|
+
* @param jwt the JWT token
|
|
16
|
+
* @param secret the secret example. const secret = createSecretKey(process.env.JWT_SECRET, 'utf-8');
|
|
17
|
+
* @param options options like issuer and audience
|
|
18
|
+
* @returns
|
|
19
|
+
*/
|
|
20
|
+
export declare function decryptJWT<PayloadType = JWTPayload>(jwt: string, secret: KeyObject, options?: Partial<JWTDecryptOptions>): Promise<JWTDecryptResult<PayloadType>>;
|
|
21
|
+
/**
|
|
22
|
+
* verify a JWT token with jose
|
|
23
|
+
* @param jwt the JWT token
|
|
24
|
+
* @param secret the secret example. const secret = createSecretKey(process.env.JWT_SECRET, 'utf-8');
|
|
25
|
+
* @param options options like issuer and audience
|
|
26
|
+
* @returns
|
|
27
|
+
*/
|
|
28
|
+
export declare function verifyJWT<PayloadType = JWTPayload>(jwt: string, secret: KeyObject, options?: Partial<JWTVerifyOptions>): Promise<JWTVerifyResult<PayloadType>>;
|
|
29
|
+
/**
|
|
30
|
+
* creates a signed JWT with jose
|
|
31
|
+
*
|
|
32
|
+
* @param payload the payload to encrypt
|
|
33
|
+
* @param secret the secret example. const secret = createSecretKey(process.env.JWT_SECRET, 'utf-8');
|
|
34
|
+
* @param options options like expiratation date, issuer and audience
|
|
35
|
+
* @returns
|
|
36
|
+
*/
|
|
37
|
+
export declare function signJWT(payload: JWTPayload, secret: KeyObject, options?: Partial<JWTSignOptions>): Promise<string>;
|
|
38
|
+
/**
|
|
39
|
+
* decodes a protected header with jose
|
|
40
|
+
* @param token
|
|
41
|
+
* @returns
|
|
42
|
+
*/
|
|
43
|
+
export declare function decodeProtectedHeaderJWT(token: string | object): ProtectedHeaderParameters;
|
|
44
|
+
/**
|
|
45
|
+
* decodes a jwt token
|
|
46
|
+
* @param jwt
|
|
47
|
+
* @returns
|
|
48
|
+
*/
|
|
49
|
+
export declare function decodeJWT<PayloadType = JWTPayload>(jwt: string): PayloadType & JWTPayload;
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { EncryptJWT, SignJWT, decodeJwt, decodeProtectedHeader, jwtDecrypt as joseJWTDecrypt, jwtVerify } from "jose";
|
|
2
|
+
/**
|
|
3
|
+
* creates a JWT encrypted token with jose
|
|
4
|
+
*
|
|
5
|
+
* @param payload the payload to encrypt
|
|
6
|
+
* @param secret the secret example. const secret = createSecretKey(process.env.JWT_SECRET, 'utf-8');
|
|
7
|
+
* @param options options like expiratation date, issuer and audience
|
|
8
|
+
* @returns
|
|
9
|
+
*/
|
|
10
|
+
export async function encryptJWT(payload, secret, options) {
|
|
11
|
+
const en = new EncryptJWT(payload)
|
|
12
|
+
.setProtectedHeader({
|
|
13
|
+
alg: options?.alg ? options?.alg : 'dir',
|
|
14
|
+
enc: options?.enc ? options?.enc : 'A128CBC-HS256'
|
|
15
|
+
})
|
|
16
|
+
.setIssuedAt(options?.iat)
|
|
17
|
+
.setIssuer(options?.iss ? options?.iss : 'urn:example:issuer')
|
|
18
|
+
.setAudience(options?.aud ? options?.aud : 'urn:example:audience')
|
|
19
|
+
.setExpirationTime(options?.exp ? options?.exp : '2h');
|
|
20
|
+
return await en.encrypt(secret, options?.options);
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* decrypts a JWT token with jose
|
|
24
|
+
* @param jwt the JWT token
|
|
25
|
+
* @param secret the secret example. const secret = createSecretKey(process.env.JWT_SECRET, 'utf-8');
|
|
26
|
+
* @param options options like issuer and audience
|
|
27
|
+
* @returns
|
|
28
|
+
*/
|
|
29
|
+
export async function decryptJWT(jwt, secret, options) {
|
|
30
|
+
return await joseJWTDecrypt(jwt, secret, options);
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* verify a JWT token with jose
|
|
34
|
+
* @param jwt the JWT token
|
|
35
|
+
* @param secret the secret example. const secret = createSecretKey(process.env.JWT_SECRET, 'utf-8');
|
|
36
|
+
* @param options options like issuer and audience
|
|
37
|
+
* @returns
|
|
38
|
+
*/
|
|
39
|
+
export async function verifyJWT(jwt, secret, options) {
|
|
40
|
+
return await jwtVerify(jwt, secret, options);
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* creates a signed JWT with jose
|
|
44
|
+
*
|
|
45
|
+
* @param payload the payload to encrypt
|
|
46
|
+
* @param secret the secret example. const secret = createSecretKey(process.env.JWT_SECRET, 'utf-8');
|
|
47
|
+
* @param options options like expiratation date, issuer and audience
|
|
48
|
+
* @returns
|
|
49
|
+
*/
|
|
50
|
+
export async function signJWT(payload, secret, options) {
|
|
51
|
+
const sign = new SignJWT(payload)
|
|
52
|
+
.setProtectedHeader({
|
|
53
|
+
alg: options?.alg ? options?.alg : 'HS256',
|
|
54
|
+
})
|
|
55
|
+
.setIssuedAt(options?.iat)
|
|
56
|
+
.setIssuer(options?.iss ? options?.iss : 'urn:example:issuer')
|
|
57
|
+
.setAudience(options?.aud ? options?.aud : 'urn:example:audience')
|
|
58
|
+
.setExpirationTime(options?.exp ? options?.exp : '2h');
|
|
59
|
+
return sign.sign(secret, options?.options);
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* decodes a protected header with jose
|
|
63
|
+
* @param token
|
|
64
|
+
* @returns
|
|
65
|
+
*/
|
|
66
|
+
export function decodeProtectedHeaderJWT(token) {
|
|
67
|
+
return decodeProtectedHeader(token);
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* decodes a jwt token
|
|
71
|
+
* @param jwt
|
|
72
|
+
* @returns
|
|
73
|
+
*/
|
|
74
|
+
export function decodeJWT(jwt) {
|
|
75
|
+
return decodeJwt(jwt);
|
|
76
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { chmodSync, constants, mkdirSync, writeFileSync } from "node:fs";
|
|
2
|
-
import { dirname, extname, join, relative, resolve } from "node:path";
|
|
2
|
+
import { basename, dirname, extname, join, relative, resolve } from "node:path";
|
|
3
3
|
import { cwd, platform } from "node:process";
|
|
4
4
|
import { getAuthConfigPath, getCORSConfigPath, getDBConfigPath, getErrorConfigPath, getMiddlewareConfigPath, getMigrationsPath, getServerConfigPath, getWSConfigPath } from "../common/paths.js";
|
|
5
5
|
import { getAsset } from "../common/assets.js";
|
|
@@ -54,22 +54,22 @@ export async function inflateAppForSea(logger, inflateDir, services) {
|
|
|
54
54
|
})`;
|
|
55
55
|
}).join(",");
|
|
56
56
|
writeFile(logger, join(inflateDir, "sea", "package.json"), `{ "type": "module", "private": true }`);
|
|
57
|
-
writeFile(logger, join(inflateDir, "sea", "app.cjs"), `const {
|
|
57
|
+
writeFile(logger, join(inflateDir, "sea", "app.cjs"), `const { createServerInterface, ServerRequestHandler, WebSocketManager, initGlobals, DBManager, App, LoggerHandler, LogProvider, LocalCache, ClusterCache } = require("./lib.cjs");
|
|
58
58
|
|
|
59
59
|
async function main() {
|
|
60
60
|
const PORT = process.env["PORT"] ? process.env["PORT"] : 8080;
|
|
61
|
-
const
|
|
61
|
+
const loggerProvider = new LogProvider();
|
|
62
62
|
const localCache = new LocalCache();
|
|
63
63
|
const cache = new ClusterCache();
|
|
64
64
|
const webSocketManager = new WebSocketManager();
|
|
65
65
|
const dbManager = new DBManager();
|
|
66
66
|
await initGlobals();
|
|
67
|
-
const serverInterface =
|
|
67
|
+
const serverInterface = createServerInterface({
|
|
68
68
|
cache,
|
|
69
69
|
localCache,
|
|
70
|
-
|
|
70
|
+
loggerProvider,
|
|
71
71
|
wsManager: webSocketManager,
|
|
72
|
-
logger:
|
|
72
|
+
logger: loggerProvider.getLogger("server"),
|
|
73
73
|
dbManager,
|
|
74
74
|
port: PORT
|
|
75
75
|
});
|
|
@@ -118,9 +118,10 @@ ${Object.keys(serviceRouteFileMap)
|
|
|
118
118
|
.map(filePath => serviceRouteFileMap[filePath])
|
|
119
119
|
.filter(data => data.previewMethod === "api")
|
|
120
120
|
.map(data => data.routes.map(r => {
|
|
121
|
-
const rPath =
|
|
121
|
+
const rPath = join(relative(cwd(), dirname(data.filePath)), basename(data.filePath));
|
|
122
122
|
if (rPath) {
|
|
123
|
-
const
|
|
123
|
+
const rPathExt = extname(rPath);
|
|
124
|
+
const apiInflatedPath = join("..", "..", rPath.substring(0, rPath.length - rPathExt.length) + ".js");
|
|
124
125
|
return ` await appendAPIModule(router, "../../${service}/http", "./${apiInflatedPath}", (await import("./${apiInflatedPath}")).default);`;
|
|
125
126
|
}
|
|
126
127
|
else {
|
|
@@ -55,6 +55,7 @@ function createStaticRoute(service, logger, router, dir, file, inflateDir, route
|
|
|
55
55
|
path: normalizePath(path)
|
|
56
56
|
}],
|
|
57
57
|
service,
|
|
58
|
+
filePath: file.filePath,
|
|
58
59
|
previewMethod: "html"
|
|
59
60
|
};
|
|
60
61
|
if (inflateDir) {
|
|
@@ -137,6 +138,7 @@ async function createRouterFromDirectory(server, hotreload, service, logger, dir
|
|
|
137
138
|
routeFileMap[file.filePath] = {
|
|
138
139
|
routes,
|
|
139
140
|
service,
|
|
141
|
+
filePath: file.filePath,
|
|
140
142
|
previewMethod: "api"
|
|
141
143
|
};
|
|
142
144
|
const inflatedCode = inflateDir ? await inflateJSX(file.filePath, {
|
|
@@ -175,6 +177,7 @@ async function createRouterFromDirectory(server, hotreload, service, logger, dir
|
|
|
175
177
|
routeFileMap[file.filePath] = {
|
|
176
178
|
routes,
|
|
177
179
|
service,
|
|
180
|
+
filePath: file.filePath,
|
|
178
181
|
previewMethod: "html"
|
|
179
182
|
};
|
|
180
183
|
for (const r of routes) {
|
|
@@ -228,6 +231,7 @@ async function createRouterFromDirectory(server, hotreload, service, logger, dir
|
|
|
228
231
|
const routes = getRoutes(join("/", dirname(relative(dir, file.filePath))), file.subName + ".html", module.apiOptions);
|
|
229
232
|
routeFileMap[file.filePath] = {
|
|
230
233
|
routes,
|
|
234
|
+
filePath: file.filePath,
|
|
231
235
|
service,
|
|
232
236
|
previewMethod: "html"
|
|
233
237
|
};
|
|
@@ -296,6 +300,7 @@ async function createRouterFromDirectory(server, hotreload, service, logger, dir
|
|
|
296
300
|
method: "GET",
|
|
297
301
|
path
|
|
298
302
|
}],
|
|
303
|
+
filePath: file.filePath,
|
|
299
304
|
service,
|
|
300
305
|
previewMethod: "html"
|
|
301
306
|
};
|
|
@@ -345,6 +350,7 @@ async function createRouterFromDirectory(server, hotreload, service, logger, dir
|
|
|
345
350
|
path
|
|
346
351
|
}],
|
|
347
352
|
service,
|
|
353
|
+
filePath: file.filePath,
|
|
348
354
|
previewMethod: "html"
|
|
349
355
|
};
|
|
350
356
|
if (inflateDir) {
|
|
@@ -402,6 +408,7 @@ async function createRouterFromDirectory(server, hotreload, service, logger, dir
|
|
|
402
408
|
method: "GET",
|
|
403
409
|
path
|
|
404
410
|
}],
|
|
411
|
+
filePath: file.filePath,
|
|
405
412
|
service,
|
|
406
413
|
previewMethod: "html"
|
|
407
414
|
};
|
|
@@ -459,6 +466,7 @@ async function createRouterFromDirectory(server, hotreload, service, logger, dir
|
|
|
459
466
|
path
|
|
460
467
|
}],
|
|
461
468
|
service,
|
|
469
|
+
filePath: file.filePath,
|
|
462
470
|
previewMethod: "html"
|
|
463
471
|
};
|
|
464
472
|
if (inflateDir) {
|