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.
Files changed (62) hide show
  1. package/build/editor.bundle.js +26 -2
  2. package/build/esm/editor/common/templates.js +16 -0
  3. package/build/esm/editor/components/editor.js +8 -0
  4. package/build/esm/editor/components/file-editor.js +1 -1
  5. package/build/esm/editor/components/highlight-text-area.js +2 -1
  6. package/build/esm/src/bin/types.js +8 -0
  7. package/build/esm/src/common/arguments.d.ts +7 -1
  8. package/build/esm/src/common/arguments.js +72 -10
  9. package/build/esm/src/common/help.d.ts +1 -1
  10. package/build/esm/src/common/help.js +33 -29
  11. package/build/esm/src/common/jwt.d.ts +49 -0
  12. package/build/esm/src/common/jwt.js +76 -0
  13. package/build/esm/src/inflate/inflate-sea.js +9 -8
  14. package/build/esm/src/inflate/setup-http.d.ts +1 -0
  15. package/build/esm/src/inflate/setup-http.js +8 -0
  16. package/build/esm/src/inflate/setup-ws.d.ts +1 -1
  17. package/build/esm/src/inflate/setup-ws.js +2 -2
  18. package/build/esm/src/lib.d.ts +1 -1
  19. package/build/esm/src/lib.js +2 -2
  20. package/build/esm/src/main.js +3 -1
  21. package/build/esm/src/services/app.d.ts +2 -0
  22. package/build/esm/src/services/app.js +7 -6
  23. package/build/esm/src/services/globals.js +45 -1
  24. package/build/esm/src/services/utils/cluster-ws.d.ts +4 -2
  25. package/build/esm/src/services/utils/cluster-ws.js +10 -1
  26. package/build/esm/src/services/utils/log-transport.d.ts +2 -2
  27. package/build/esm/src/services/utils/log-transport.js +8 -3
  28. package/build/esm/src/services/utils/server-interface.d.ts +4 -30
  29. package/build/esm/src/services/utils/server-interface.js +44 -59
  30. package/build/esm/src/services/utils/websocketmanager.d.ts +3 -0
  31. package/build/esm/src/services/utils/websocketmanager.js +8 -2
  32. package/build/esm/src/types.d.ts +76 -5
  33. package/build/lib.cjs +2992 -369
  34. package/editor/common/templates.ts +15 -0
  35. package/editor/components/editor.tsx +8 -0
  36. package/editor/components/file-editor.tsx +1 -1
  37. package/editor/components/highlight-text-area.tsx +2 -1
  38. package/package.json +4 -3
  39. package/sea/install-nodejs.sh +1 -1
  40. package/sea/node.version.tag +1 -1
  41. package/sea/types.json +1 -1
  42. package/src/bin/types.ts +7 -0
  43. package/src/common/arguments.ts +84 -11
  44. package/src/common/help.ts +33 -29
  45. package/src/common/jwt.ts +85 -0
  46. package/src/inflate/inflate-sea.ts +9 -8
  47. package/src/inflate/setup-db.ts +3 -1
  48. package/src/inflate/setup-http.ts +9 -0
  49. package/src/inflate/setup-ws.ts +4 -3
  50. package/src/lib.ts +2 -2
  51. package/src/main.ts +3 -1
  52. package/src/services/app.ts +10 -6
  53. package/src/services/globals.ts +45 -2
  54. package/src/services/utils/cluster-ws.ts +6 -1
  55. package/src/services/utils/log-transport.ts +10 -4
  56. package/src/services/utils/server-interface.ts +44 -133
  57. package/src/services/utils/websocketmanager.ts +10 -2
  58. package/src/types/cookie.d.ts +2 -0
  59. package/src/types/jose.d.ts +2 -0
  60. package/src/types/miqro.d.ts +92 -2
  61. package/src/types/server.globals.d.ts +4 -29
  62. package/src/types.ts +78 -5
@@ -1,5 +1,6 @@
1
1
  //@ts-ignore
2
2
  import { ReadBuffer, URLEncodedParser, JSONParser, TextParser, CORS, SessionHandler } from "@miqro/core";
3
+ import cluster from "node:cluster";
3
4
  import { strictEqual } from "node:assert";
4
5
  import { HTMLEncode } from "@miqro/jsx-node";
5
6
  import { createElement as realCreateElement, enableDebugLog, useRuntime, Link, Router, usePathname, Fragment, useEffect, useRef, useState, useQuery, useRefresh, useElement, createContext, useContext, Component, Props } from "@miqro/jsx";
@@ -7,7 +8,10 @@ import { createElement as realCreateElement, enableDebugLog, useRuntime, Link, R
7
8
  import { jsx2HTML } from "../common/jsx.js";
8
9
  import { inflateMD2HTML } from "../inflate/md.js";
9
10
  import { EXIT_CODES } from "../common/constants.js";
10
- import { ServerGlobal } from "../lib.js";
11
+ import { ClusterCache, LocalCache, ServerGlobal } from "../lib.js";
12
+ import { decodeJWT, decodeProtectedHeaderJWT, decryptJWT, encryptJWT, signJWT, verifyJWT } from "../common/jwt.js";
13
+ import { createSecretKey } from "node:crypto";
14
+ import { Parser } from "@miqro/parser";
11
15
 
12
16
  /*const globaljsx: any = Object.freeze({
13
17
  useContext,
@@ -83,7 +87,46 @@ const globalServer: ServerGlobal = Object.freeze<ServerGlobal>({
83
87
  session: SessionHandler
84
88
  }),
85
89
  encodeHTML: HTMLEncode,
86
- inflateMDtoHTML: inflateMD2HTML
90
+ inflateMDtoHTML: inflateMD2HTML,
91
+ createSecretKey,
92
+ newParser() {
93
+ return new Parser();
94
+ },
95
+ newClusterCache(name, logger) {
96
+ return new ClusterCache(name, logger);
97
+ },
98
+ newLocalCache(name, logger) {
99
+ return new LocalCache(name, logger);
100
+ },
101
+ getWorkerNumber(): number {
102
+ return cluster.isPrimary || process.env["CLUSTER_NODE_NUMBER"] === undefined ? 0 : parseInt(process.env["CLUSTER_NODE_NUMBER"], 10);
103
+ },
104
+ getWorkerCount(): number {
105
+ return cluster.isPrimary || process.env["CLUSTER_NODE_NUMBER"] === undefined || process.env["CLUSTER_COUNT"] === undefined ? 1 : parseInt(process.env["CLUSTER_COUNT"], 10);
106
+ },
107
+ isPrimaryWorker(): boolean {
108
+ return cluster.isPrimary || process.env["CLUSTER_NODE_NUMBER"] === "0";
109
+ },
110
+ jwt: {
111
+ decode(jwt) {
112
+ return decodeJWT(jwt);
113
+ },
114
+ decodeProtectedHeader(token) {
115
+ return decodeProtectedHeaderJWT(token);
116
+ },
117
+ decrypt(jwt, secret, options) {
118
+ return decryptJWT(jwt, secret, options);
119
+ },
120
+ encrypt(payload, secret, options) {
121
+ return encryptJWT(payload, secret, options);
122
+ },
123
+ sign(payload, secret, options) {
124
+ return signJWT(payload, secret, options);
125
+ },
126
+ verify(jwt, secret, options) {
127
+ return verifyJWT(jwt, secret, options);
128
+ }
129
+ }
87
130
  }) as ServerGlobal;
88
131
 
89
132
  export function browserJSXGlobals(inFile: string, jsxPath: string | false = false, useExport = true): string {
@@ -17,7 +17,7 @@ export interface ClusterWebSocketServer2Message {
17
17
  export class ClusterWebSocketServer2 extends WebSocketServer {
18
18
  public remoteClients: Set<string> = new Set();
19
19
  listener: (data: any) => Promise<void>;
20
- public constructor(protected name: string, options: WebSocketServerOptions) {
20
+ public constructor(protected name: string, public path: string, public logger: Logger | Console, options: WebSocketServerOptions) {
21
21
  super({
22
22
  ...options,
23
23
  validate: (req) => {
@@ -25,6 +25,7 @@ export class ClusterWebSocketServer2 extends WebSocketServer {
25
25
  this.options.maxConnections !== undefined &&
26
26
  this.clients.size + this.remoteClients.size >= this.options.maxConnections
27
27
  ) {
28
+ this.logger?.warn("[%s] max web socket connection reached! connection refused from [%s]", req.uuid, req.socket.remoteAddress);
28
29
  return false;
29
30
  } else {
30
31
  return options.validate ? options.validate(req) : true;
@@ -41,6 +42,8 @@ export class ClusterWebSocketServer2 extends WebSocketServer {
41
42
  errorMessage: error.message
42
43
  } as ClusterWebSocketServer2Message);
43
44
  }
45
+ this.logger?.error("[%s] error from (%s) error [%s]", req.uuid, req.req.socket.remoteAddress, error);
46
+ this.logger?.error(error);
44
47
  if (options.onError) {
45
48
  options.onError(req, error);
46
49
  }
@@ -55,6 +58,7 @@ export class ClusterWebSocketServer2 extends WebSocketServer {
55
58
  clientUUID: req.uuid
56
59
  } as ClusterWebSocketServer2Message);
57
60
  }
61
+ this.logger?.log("[%s] new web socket connection from (%s)", req.uuid, req.req.socket.remoteAddress);
58
62
  if (options.onConnection) {
59
63
  options.onConnection(req);
60
64
  }
@@ -69,6 +73,7 @@ export class ClusterWebSocketServer2 extends WebSocketServer {
69
73
  clientUUID: req.uuid
70
74
  } as ClusterWebSocketServer2Message);
71
75
  }
76
+ this.logger?.log("[%s] [%s] web socket disconnection from (%s)", req.uuid, this.path, req.req.socket.remoteAddress);
72
77
  if (options.onDisconnect) {
73
78
  options.onDisconnect(req);
74
79
  }
@@ -1,11 +1,17 @@
1
- import { ConsoleTransport, FileTransport, LoggerTransportWriteArgs, LogLevel, WriteArgs } from "@miqro/core";
1
+ import { ConsoleTransport, FileTransport, LoggerTransport, LoggerTransportWriteArgs, LogLevel, WriteArgs } from "@miqro/core";
2
2
  import { format } from "node:util";
3
3
  import { LOG_SOCKET_PATH, LOG_WRITE_EVENT } from "../../../editor/common/constants.js";
4
4
  import { Miqro } from "../app.js";
5
5
 
6
6
  export function createLogProviderOptions(app: Miqro) {
7
7
  const defaultConsole = ConsoleTransport();
8
- const defaultFile = FileTransport();
8
+ //console.log("app.options.logFile [%s]", app.options.logFile);
9
+ const defaultFile: LoggerTransport | undefined =
10
+ app.options.logFile !== true && app.options.logFile !== false && String(app.options.logFile).toUpperCase() !== "TRUE" && String(app.options.logFile).toUpperCase() !== "FALSE" &&
11
+ app.options.logFile ? FileTransport(app.options.logFile) :
12
+ String(app.options.logFile).toUpperCase() === "TRUE" || app.options.logFile === true || app.options.logFile === undefined ?
13
+ FileTransport() :
14
+ undefined;
9
15
  const defaultWrite = async (args: LoggerTransportWriteArgs, level?: LogLevel) => {
10
16
  try {
11
17
  const serviceNamesWithLogConfigReplaceConsole = level === undefined && app.inflated ?
@@ -14,9 +20,9 @@ export function createLogProviderOptions(app: Miqro) {
14
20
  Object.keys(app.inflated.logConfigMap).filter(serviceName => app.inflated.logConfigMap[serviceName].replaceFileTransport) : [];
15
21
  await Promise.allSettled((level === undefined ?
16
22
  [
17
- level === undefined && serviceNamesWithLogConfigReplaceConsole.length === 0 ?
23
+ level === undefined && serviceNamesWithLogConfigReplaceConsole.length === 0 && defaultConsole ?
18
24
  defaultConsole.write(args) : Promise.resolve(),
19
- level === undefined && serviceNamesWithLogConfigReplaceFile.length === 0 ?
25
+ level === undefined && serviceNamesWithLogConfigReplaceFile.length === 0 && defaultFile ?
20
26
  defaultFile.write(args) : Promise.resolve()
21
27
  ] : []).concat(app.inflated ?
22
28
  Object.keys(app.inflated.logConfigMap).map(serviceName => app.inflated.logConfigMap[serviceName]).filter(c => c.level === level).map(c => c.write(args)) : []
@@ -7,118 +7,33 @@ import { Miqro } from "../app.js";
7
7
  import { WebSocketManager } from "./websocketmanager.js";
8
8
  import { execSync } from "node:child_process";
9
9
  import { LogProvider } from "./log.js";
10
-
11
- /*
12
- {
13
- cache: this.cache,
14
- localCache: this.localCache,
15
- db: {
16
- get: (name: string) => {
17
- return this.dbManager.getDB(name);
18
- },
19
- getMigrations: () => {
20
- if (this.inflated) {
21
- const ret: NamedMigration[] = [];
22
- for (const d of this.inflated.dbList) {
23
- ret.push(...(d.migrations.map(m => {
24
- return {
25
- name: m.name,
26
- service: m.service,
27
- dbName: m.dbName
28
- }
29
- })));
30
- }
31
- return ret;
32
- }
33
- return [];
34
- },
35
- migrate: (options) => {
36
- return this.migrate(options);
37
- },
38
- },
39
- ws: {
40
- get: (path: string) => {
41
- if (path === LOG_SOCKET_PATH) {
42
- throw new Error("cannot use this path");
43
- }
44
- return this.webSocketManager.getWS(path);
45
- },
46
- disconnectAll: (path: string) => {
47
- if (path === LOG_SOCKET_PATH) {
48
- throw new Error("cannot use this path");
49
- }
50
- this.webSocketManager.disconnectAllFrom(path);
51
- }
52
- },
53
- isPrimaryWorker: () => {
54
- return cluster.isPrimary || process.env["CLUSTER_NODE_NUMBER"] === "0";
55
- },
56
- openBrowser: (path: string) => {
57
- const PORT = this.options.port;
58
- const URL = `http://localhost:${PORT}${path}`;
59
- const DEFAULT_OPEN = process.platform === "win32" ? "explorer" : process.platform === "darwin" ? "open" : "xdg-open";
60
- const OPEN = process.env["BROWSER"] ? process.env["BROWSER"] === "none" ? false : process.env["BROWSER"] : DEFAULT_OPEN;
61
- if (OPEN) {
62
- const openCMD = `${OPEN} "${URL}"`;
63
- this.logger?.info("opening browser with [%s]", openCMD);
64
- execSync(openCMD);
65
- } else {
66
- this.logger?.warn("ignoring browser [%s]", process.env["BROWSER"]);
67
- }
68
- },
69
- logger: this.logger,
70
- getLogger: (identifier: string, options?: { level?: any; transports?: any[]; formatter?: any; }) => {
71
- return this.loggerProvider.getLogger(identifier, options);
72
- }
73
- }*/
10
+ import { initGlobals } from "../globals.js";
74
11
 
75
12
  export interface ServerInterfaceImplOptions {
76
13
  cache: CacheInterface;
77
14
  localCache: CacheInterface;
78
15
  dbManager: DBManager;
79
- wsManager: WebSocketManager;
16
+ webSocketManager: WebSocketManager;
80
17
  logger?: Logger;
81
18
  app?: Miqro;
82
19
  port?: string;
83
20
  loggerProvider?: LogProvider;
84
21
  }
85
22
 
86
- export class ServerInterfaceImpl implements ServerInterface {
87
- public cache: CacheInterface;
88
- public localCache: CacheInterface;
89
- public logger?: Logger;
90
- public port?: string;
91
-
92
- public db: {
93
- get(name: string): Database | null;
94
- getMigrations(): NamedMigration[];
95
- migrate(options: MigrateOptions): Promise<void>;
96
- };
97
- public ws: {
98
- get(path: string): WebSocketServer | undefined;
99
- disconnectAll(path: string): void;
100
- };
101
- public loggerProvider?: LogProvider;
102
-
103
- constructor(options: ServerInterfaceImplOptions) {
104
- this.cache = options.cache;
105
- this.localCache = options.localCache;
106
- this.logger = options.logger ? options.logger : options.loggerProvider ? options.loggerProvider.getLogger("server") : undefined;
107
- this.port = options.port;
108
-
109
- const dbManager = options.dbManager;
110
- const wsManager = options.wsManager;
111
- this.loggerProvider = options.loggerProvider;
112
- const app = options.app;
113
-
114
- this.db = Object.freeze({
115
- get: (name: string) => {
116
- return dbManager.getDB(name);
23
+ export function createServerInterface(options: ServerInterfaceImplOptions): ServerInterface {
24
+ initGlobals();
25
+ return Object.freeze<ServerInterface>({
26
+ cache: options.cache,
27
+ localCache: options.localCache,
28
+ logger: options.logger,
29
+ db: {
30
+ get(name) {
31
+ return options.dbManager.getDB(name);
117
32
  },
118
- getMigrations: () => {
119
- if (app?.inflated) {
33
+ getMigrations() {
34
+ if (options.app?.inflated) {
120
35
  const ret: NamedMigration[] = [];
121
- for (const d of app?.inflated.dbList) {
36
+ for (const d of options.app?.inflated.dbList) {
122
37
  ret.push(...(d.migrations.map(m => {
123
38
  return {
124
39
  name: m.name,
@@ -131,42 +46,38 @@ export class ServerInterfaceImpl implements ServerInterface {
131
46
  }
132
47
  return [];
133
48
  },
134
- migrate: (options: MigrateOptions) => {
135
- return app?.migrate(options);
136
- }
137
- });
138
- this.ws = Object.freeze({
49
+ migrate(migrateOptions) {
50
+ return options?.app?.migrate(migrateOptions);
51
+ },
52
+ },
53
+ ws: {
139
54
  get: (name: string) => {
140
- return wsManager?.getWS(name);
55
+ return options?.webSocketManager?.getWS(name);
141
56
  },
142
57
  disconnectAll: (path: string) => {
143
- return wsManager?.disconnectAllButLOGSocket();
58
+ return options?.webSocketManager?.disconnectAllButLOGSocket();
59
+ }
60
+ },
61
+ openBrowser(path) {
62
+ const PORT = options.port;
63
+ const URL = `http://localhost${PORT ? `:${PORT}` : ""}${path}`;
64
+ const DEFAULT_OPEN = process.platform === "win32" ? "explorer" : process.platform === "darwin" ? "open" : "xdg-open";
65
+ const OPEN = options?.app?.options.browser !== undefined && String(options?.app?.options.browser).toUpperCase() !== "TRUE" && String(options?.app?.options.browser).toUpperCase() !== "1" ?
66
+ String(options?.app.options.browser).toUpperCase() !== "0" && String(options?.app?.options.browser).toUpperCase() !== "FALSE" && String(options?.app?.options.browser).toUpperCase() !== "NONE" && options?.app?.options.browser ?
67
+ options?.app.options.browser : false :
68
+ process.env["BROWSER"] ?
69
+ process.env["BROWSER"] === "none" ? false : process.env["BROWSER"] : DEFAULT_OPEN;
70
+ if (OPEN) {
71
+ const openCMD = `${OPEN} "${URL}"`;
72
+ options?.logger?.info("opening browser with [%s]", openCMD);
73
+ execSync(openCMD);
74
+ } else {
75
+ options?.logger?.warn("ignoring browser [%s]", OPEN);
144
76
  }
145
- });
146
- }
147
- public getWorkerNumber(): number {
148
- return cluster.isPrimary || process.env["CLUSTER_NODE_NUMBER"] === undefined ? 0 : parseInt(process.env["CLUSTER_NODE_NUMBER"], 10);
149
- }
150
- public getWorkerCount(): number {
151
- return cluster.isPrimary || process.env["CLUSTER_NODE_NUMBER"] === undefined || process.env["CLUSTER_COUNT"] === undefined ? 1 : parseInt(process.env["CLUSTER_COUNT"], 10);
152
- }
153
- public isPrimaryWorker(): boolean {
154
- return cluster.isPrimary || process.env["CLUSTER_NODE_NUMBER"] === "0";
155
- }
156
- public openBrowser(path: string): void {
157
- const PORT = this.port;
158
- const URL = `http://localhost${PORT ? `:${PORT}` : ""}${path}`;
159
- const DEFAULT_OPEN = process.platform === "win32" ? "explorer" : process.platform === "darwin" ? "open" : "xdg-open";
160
- const OPEN = process.env["BROWSER"] ? process.env["BROWSER"] === "none" ? false : process.env["BROWSER"] : DEFAULT_OPEN;
161
- if (OPEN) {
162
- const openCMD = `${OPEN} "${URL}"`;
163
- this.logger?.info("opening browser with [%s]", openCMD);
164
- execSync(openCMD);
165
- } else {
166
- this.logger?.warn("ignoring browser [%s]", process.env["BROWSER"]);
167
- }
168
- }
169
- public getLogger(identifier: string, options?: { level?: any; transports?: any[]; formatter?: any; }): Logger {
170
- return this.loggerProvider?.getLogger(identifier, options);
171
- }
77
+ },
78
+ getLogger(identifier, loggerOptions) {
79
+ return options?.loggerProvider?.getLogger(identifier, loggerOptions);
80
+ },
81
+ ...server
82
+ });
172
83
  }
@@ -2,9 +2,11 @@ import { Logger } from "@miqro/core";
2
2
  import { LOG_SOCKET_PATH } from "../../../editor/common/constants.js";
3
3
  import { ClusterWebSocketServer2 } from "./cluster-ws.js";
4
4
  import { WSConfig } from "../../types.js";
5
+ import { LogProvider } from "./log.js";
5
6
 
6
7
  export interface WebSocketManagerOptions {
7
8
  logger?: Logger | Console;
9
+ loggerProvider?: LogProvider;
8
10
  name?: string;
9
11
  avoidLogSocket?: boolean;
10
12
  }
@@ -14,10 +16,12 @@ export class WebSocketManager {
14
16
  public logger?: Logger | Console | null = null;
15
17
  public name: string;
16
18
  public avoidLogSocket: boolean;
19
+ public loggerProvider: LogProvider;
17
20
  constructor(options?: WebSocketManagerOptions) {
18
21
  this.onUpgrade = this.onUpgrade.bind(this);
19
22
  this.logger = options && options.logger ? options.logger : null;
20
23
  this.name = options && options.name ? options.name : "WebSocketManager";
24
+ this.loggerProvider = options.loggerProvider;
21
25
  this.avoidLogSocket = options && options.avoidLogSocket ? options.avoidLogSocket : false;
22
26
  }
23
27
 
@@ -46,7 +50,9 @@ export class WebSocketManager {
46
50
  throw new Error(`ws on path ${wsConfig.path} already setup!`);
47
51
  }
48
52
  this.logger?.debug("setting up websocket on [%s]", wsConfig.path);
49
- const server = new ClusterWebSocketServer2(wsConfig.path, wsConfig);
53
+ const identifier = wsConfig.path.replaceAll("/", "_").toUpperCase();
54
+ const logger = this.loggerProvider && identifier.length >= 0 ? this.loggerProvider.getLogger(identifier.substring(identifier.charAt(0) === "_" ? 1 : 0)) : this.logger;
55
+ const server = new ClusterWebSocketServer2(this.name + wsConfig.path, wsConfig.path, logger, wsConfig);
50
56
  this.runningGlobalWSMap.set(wsConfig.path, server);
51
57
  }
52
58
  }
@@ -65,7 +71,9 @@ export class WebSocketManager {
65
71
  throw new Error(`ws on path ${wsConfig.path} already setup!`);
66
72
  }
67
73
  this.logger?.debug("setting up websocket on [%s]", wsConfig.path);
68
- const server = new ClusterWebSocketServer2(this.name + wsConfig.path, wsConfig);
74
+ const identifier = wsConfig.path.replaceAll("/", "_").toUpperCase();
75
+ const logger = this.loggerProvider && identifier.length >= 0 ? this.loggerProvider.getLogger(identifier.substring(identifier.charAt(0) === "_" ? 1 : 0)) : this.logger;
76
+ const server = new ClusterWebSocketServer2(this.name + wsConfig.path, wsConfig.path, logger, wsConfig);
69
77
  this.runningGlobalWSMap.set(wsConfig.path, server);
70
78
  }
71
79
  }
@@ -0,0 +1,2 @@
1
+ import "../globals.js";
2
+ export * from "cookie/index.js";
@@ -0,0 +1,2 @@
1
+ import "../globals.js";
2
+ export * from "jose/types/index.js";
@@ -1,7 +1,10 @@
1
1
  import "./globals.js";
2
2
  import { Database, Migration } from "@miqro/query/lib.js";
3
+ import { ReadBuffer, URLEncodedParser, JSONParser, TextParser, CORS, SessionHandler } from "@miqro/core/lib.js";
3
4
  import { ErrorHandler, HandlerWithOptions, CORSOptions, LogLevel, LoggerTransportWriteArgs, Request, Response, WebSocketServer, Logger, WebSocketServerOptions, SessionHandlerOptions, RouteOptions, Handler } from "@miqro/core/lib.js";
4
- import { ParserInterface } from "@miqro/parser/lib.js";
5
+ import { Parser, ParserInterface } from "@miqro/parser/lib.js";
6
+ import { ProtectedHeaderParameters, EncryptOptions, SignOptions, JWTPayload, JWTDecryptOptions, JWTDecryptResult, JWTVerifyResult, JWTVerifyOptions } from "jose/types/index.js";
7
+ import { KeyObject } from "node:crypto";
5
8
 
6
9
  /*export * from "@miqro/core/lib.js";
7
10
  export * from "@miqro/query/lib.js";*/
@@ -10,6 +13,93 @@ export interface AuthConfig extends SessionHandlerOptions {
10
13
 
11
14
  }
12
15
 
16
+ export interface EncryptJWTOptions {
17
+ alg?: string;
18
+ enc?: string;
19
+ iat?: number | string | Date;
20
+ iss?: string;
21
+ aud?: string;
22
+ exp?: number | string | Date;
23
+ options?: EncryptOptions;
24
+ }
25
+
26
+ export interface JWTSignOptions {
27
+ alg?: string;
28
+ iat?: number | string | Date;
29
+ iss?: string;
30
+ aud?: string;
31
+ exp?: number | string | Date;
32
+ options?: SignOptions;
33
+ }
34
+
35
+ export interface ServerGlobal {
36
+ encodeHTML: (str: string) => string;
37
+ inflateMDtoHTML: (str: string) => string;
38
+ middleware: {
39
+ buffer: typeof ReadBuffer;
40
+ url: typeof URLEncodedParser;
41
+ json: typeof JSONParser;
42
+ text: typeof TextParser;
43
+ cors: typeof CORS;
44
+ session: typeof SessionHandler;
45
+ };
46
+ newParser(): Parser;
47
+ newClusterCache: (name: string, logger?: Logger) => CacheInterface;
48
+ newLocalCache: (name: string, logger?: Logger) => CacheInterface;
49
+ createSecretKey: (key: string, encoding: BufferEncoding) => KeyObject;
50
+ getWorkerCount: () => number;
51
+ getWorkerNumber: () => number;
52
+ isPrimaryWorker: () => boolean;
53
+ jwt: {
54
+ /**
55
+ * creates a JWT encrypted token with jose
56
+ *
57
+ * @param payload the payload to encrypt
58
+ * @param secret the secret example. const secret = createSecretKey(process.env.JWT_SECRET, 'utf-8');
59
+ * @param options options like expiratation date, issuer and audience
60
+ * @returns
61
+ */
62
+ encrypt: (payload: JWTPayload, secret: KeyObject, options?: Partial<EncryptJWTOptions>) => Promise<string>
63
+ /**
64
+ * decrypts a JWT token with jose
65
+ * @param jwt the JWT token
66
+ * @param secret the secret example. const secret = createSecretKey(process.env.JWT_SECRET, 'utf-8');
67
+ * @param options options like issuer and audience
68
+ * @returns
69
+ */
70
+ decrypt: <PayloadType = JWTPayload>(jwt: string, secret: KeyObject, options?: Partial<JWTDecryptOptions>) => Promise<JWTDecryptResult<PayloadType>>;
71
+ /**
72
+ * verify a JWT token with jose
73
+ * @param jwt the JWT token
74
+ * @param secret the secret example. const secret = createSecretKey(process.env.JWT_SECRET, 'utf-8');
75
+ * @param options options like issuer and audience
76
+ * @returns
77
+ */
78
+ verify: <PayloadType = JWTPayload>(jwt: string, secret: KeyObject, options?: Partial<JWTVerifyOptions>) => Promise<JWTVerifyResult<PayloadType>>;
79
+ /**
80
+ * creates a signed JWT with jose
81
+ *
82
+ * @param payload the payload to encrypt
83
+ * @param secret the secret example. const secret = createSecretKey(process.env.JWT_SECRET, 'utf-8');
84
+ * @param options options like expiratation date, issuer and audience
85
+ * @returns
86
+ */
87
+ sign: (payload: JWTPayload, secret: KeyObject, options?: Partial<JWTSignOptions>) => Promise<string>;
88
+ /**
89
+ * decodes a protected header with jose
90
+ * @param token
91
+ * @returns
92
+ */
93
+ decodeProtectedHeader: (token: string | object) => ProtectedHeaderParameters;
94
+ /**
95
+ * decodes a jwt token
96
+ * @param jwt
97
+ * @returns
98
+ */
99
+ decode: <PayloadType = JWTPayload>(jwt: string) => PayloadType & JWTPayload;
100
+ }
101
+ }
102
+
13
103
  export interface MiddlewareConfig {
14
104
  middleware?: Array<HandlerWithOptions | Handler>;
15
105
  post?: Array<HandlerWithOptions | Handler>;
@@ -97,7 +187,7 @@ export interface MigrateOptions {
97
187
  name?: string;
98
188
  }
99
189
 
100
- export interface ServerInterface {
190
+ export interface ServerInterface extends ServerGlobal{
101
191
  // null values are if the feature has been disabled
102
192
  db: {
103
193
  get(name: string): Database | null;
@@ -1,38 +1,13 @@
1
1
  import "./jsx.globals.js";
2
2
 
3
- import { Logger, WebSocketServer, ReadBuffer, URLEncodedParser, JSONParser, TextParser, CORS, SessionHandler } from "@miqro/core/lib.js";
4
- import { request } from "./@miqro/request.js";
3
+ import { Logger } from "./@miqro/core/lib.js";
4
+ import { request } from "./@miqro/request/lib.js";
5
5
  import { RuntimeHTMLElement, Runtime, RuntimeContainer, RuntimeURL, RuntimeOptions, RuntimeShadowRootInit } from "./@miqro/jsx.js";
6
+ import { ServerGlobal } from "./miqro.js";
6
7
 
7
8
  declare global {
8
9
  // only available server side
9
- var server: {
10
- /*// null values are if the feature has been disabled
11
- db: {
12
- get(name: string): Database | null;
13
- },
14
- ws: {
15
- get(path: string): WebSocketServer | undefined;
16
- disconnectAll(path: string): void;
17
- };
18
- cache: {
19
- get: (key: string) => any;
20
- set: (key: string, value: unknown) => void;
21
- delete: (key: string) => void;
22
- has: (key: string) => boolean;
23
- };
24
- logger: Logger;*/
25
- middleware: {
26
- buffer: typeof ReadBuffer;
27
- url: typeof URLEncodedParser;
28
- json: typeof JSONParser;
29
- text: typeof TextParser;
30
- cors: typeof CORS;
31
- session: typeof SessionHandler;
32
- }
33
- encodeHTML: (str: string) => string;
34
- inflateMDtoHTML: (str: string) => string;
35
- }
10
+ var server: ServerGlobal;
36
11
 
37
12
  var test: {
38
13
  PORT: string;
package/src/types.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import { Database } from "@miqro/query";
2
2
  import { WebSocketServerOptions, SessionHandlerOptions, Logger, WebSocketServer, ReadBuffer, URLEncodedParser, JSONParser, TextParser, CORS, SessionHandler, RouteOptions, Handler, Request, Response, LogLevel, LoggerTransportWriteArgs, CORSOptions, HandlerWithOptions, ErrorHandler } from "@miqro/core";
3
3
  import { request } from "@miqro/request";
4
- import { ParserInterface } from "@miqro/parser";
4
+ import { Parser, ParserInterface } from "@miqro/parser";
5
5
  import { RuntimeHTMLElement, Runtime, RuntimeContainer, RuntimeURL, RuntimeOptions, RuntimeShadowRootInit } from "@miqro/jsx";
6
6
  import {
7
7
  RuntimeElementDefinitionOptions,
@@ -11,6 +11,27 @@ import {
11
11
  enableDebugLog
12
12
  } from "@miqro/jsx";
13
13
  import * as jsxLib from "@miqro/jsx";
14
+ import { EncryptOptions, JWTDecryptOptions, JWTDecryptResult, JWTPayload, JWTVerifyOptions, JWTVerifyResult, ProtectedHeaderParameters, SignOptions } from "jose";
15
+ import { KeyObject } from "node:crypto";
16
+
17
+ export interface EncryptJWTOptions {
18
+ alg?: string;
19
+ enc?: string;
20
+ iat?: number | string | Date;
21
+ iss?: string;
22
+ aud?: string;
23
+ exp?: number | string | Date;
24
+ options?: EncryptOptions;
25
+ }
26
+
27
+ export interface JWTSignOptions {
28
+ alg?: string;
29
+ iat?: number | string | Date;
30
+ iss?: string;
31
+ aud?: string;
32
+ exp?: number | string | Date;
33
+ options?: SignOptions;
34
+ }
14
35
 
15
36
  declare global {
16
37
  // jsx only for the default value of tsconfig.json
@@ -55,6 +76,61 @@ export interface ServerGlobal {
55
76
  cors: typeof CORS;
56
77
  session: typeof SessionHandler;
57
78
  };
79
+ newParser(): Parser;
80
+ newClusterCache: (name: string, logger?: Logger) => CacheInterface;
81
+ newLocalCache: (name: string, logger?: Logger) => CacheInterface;
82
+ createSecretKey: (key: string, encoding: BufferEncoding) => KeyObject;
83
+ getWorkerCount: () => number;
84
+ getWorkerNumber: () => number;
85
+ isPrimaryWorker: () => boolean;
86
+ jwt: {
87
+ /**
88
+ * creates a JWT encrypted token with jose
89
+ *
90
+ * @param payload the payload to encrypt
91
+ * @param secret the secret example. const secret = createSecretKey(process.env.JWT_SECRET, 'utf-8');
92
+ * @param options options like expiratation date, issuer and audience
93
+ * @returns
94
+ */
95
+ encrypt: (payload: JWTPayload, secret: KeyObject, options?: Partial<EncryptJWTOptions>) => Promise<string>
96
+ /**
97
+ * decrypts a JWT token with jose
98
+ * @param jwt the JWT token
99
+ * @param secret the secret example. const secret = createSecretKey(process.env.JWT_SECRET, 'utf-8');
100
+ * @param options options like issuer and audience
101
+ * @returns
102
+ */
103
+ decrypt: <PayloadType = JWTPayload>(jwt: string, secret: KeyObject, options?: Partial<JWTDecryptOptions>) => Promise<JWTDecryptResult<PayloadType>>;
104
+ /**
105
+ * verify a JWT token with jose
106
+ * @param jwt the JWT token
107
+ * @param secret the secret example. const secret = createSecretKey(process.env.JWT_SECRET, 'utf-8');
108
+ * @param options options like issuer and audience
109
+ * @returns
110
+ */
111
+ verify: <PayloadType = JWTPayload>(jwt: string, secret: KeyObject, options?: Partial<JWTVerifyOptions>) => Promise<JWTVerifyResult<PayloadType>>;
112
+ /**
113
+ * creates a signed JWT with jose
114
+ *
115
+ * @param payload the payload to encrypt
116
+ * @param secret the secret example. const secret = createSecretKey(process.env.JWT_SECRET, 'utf-8');
117
+ * @param options options like expiratation date, issuer and audience
118
+ * @returns
119
+ */
120
+ sign: (payload: JWTPayload, secret: KeyObject, options?: Partial<JWTSignOptions>) => Promise<string>;
121
+ /**
122
+ * decodes a protected header with jose
123
+ * @param token
124
+ * @returns
125
+ */
126
+ decodeProtectedHeader: (token: string | object) => ProtectedHeaderParameters;
127
+ /**
128
+ * decodes a jwt token
129
+ * @param jwt
130
+ * @returns
131
+ */
132
+ decode: <PayloadType = JWTPayload>(jwt: string) => PayloadType & JWTPayload;
133
+ }
58
134
  }
59
135
 
60
136
  export interface CacheInterface {
@@ -92,7 +168,7 @@ export interface LogConfig {
92
168
  write: (args: LoggerTransportWriteArgs) => Promise<void> | void;
93
169
  }
94
170
 
95
- export interface ServerInterface {
171
+ export interface ServerInterface extends ServerGlobal {
96
172
  // null values are if the feature has been disabled
97
173
  db: {
98
174
  get(name: string): Database | null;
@@ -106,9 +182,6 @@ export interface ServerInterface {
106
182
  cache: CacheInterface;
107
183
  localCache: CacheInterface;
108
184
  logger?: Logger;
109
- isPrimaryWorker: () => boolean;
110
- getWorkerNumber: () => number;
111
- getWorkerCount: () => number;
112
185
  openBrowser: (path: string) => void;
113
186
  getLogger: (identifier: string, options?: { level?: any; transports?: any[]; formatter?: any; }) => Logger;
114
187
  }