miqro 7.0.1 → 7.0.3

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 (148) hide show
  1. package/build/esm/editor/auth.d.ts +6 -0
  2. package/build/esm/editor/auth.js +41 -0
  3. package/build/esm/editor/common/admin-interface.d.ts +36 -0
  4. package/build/esm/editor/common/admin-interface.js +44 -0
  5. package/build/esm/editor/common/constants.d.ts +4 -0
  6. package/build/esm/editor/common/constants.js +20 -0
  7. package/build/esm/editor/common/constants.server.d.ts +2 -0
  8. package/build/esm/editor/common/constants.server.js +4 -0
  9. package/build/esm/editor/common/editor-index.d.ts +2 -0
  10. package/build/esm/editor/common/editor-index.js +14 -0
  11. package/build/esm/editor/common/html-encode.d.ts +1 -0
  12. package/build/esm/editor/common/html-encode.js +14 -0
  13. package/build/esm/editor/common/log-socket.d.ts +15 -0
  14. package/build/esm/editor/common/log-socket.js +71 -0
  15. package/build/esm/editor/common/templates.d.ts +11 -0
  16. package/build/esm/editor/common/templates.js +477 -0
  17. package/build/esm/editor/components/api-preview.d.ts +11 -0
  18. package/build/esm/editor/components/api-preview.js +92 -0
  19. package/build/esm/editor/components/editor.d.ts +16 -0
  20. package/build/esm/editor/components/editor.js +367 -0
  21. package/build/esm/editor/components/file-browser.d.ts +37 -0
  22. package/build/esm/editor/components/file-browser.js +127 -0
  23. package/build/esm/editor/components/file-editor-toolbar.d.ts +22 -0
  24. package/build/esm/editor/components/file-editor-toolbar.js +95 -0
  25. package/build/esm/editor/components/file-editor.d.ts +32 -0
  26. package/build/esm/editor/components/file-editor.js +61 -0
  27. package/build/esm/editor/components/filter-query.d.ts +1 -0
  28. package/build/esm/editor/components/filter-query.js +23 -0
  29. package/build/esm/editor/components/highlight-text-area.d.ts +11 -0
  30. package/build/esm/editor/components/highlight-text-area.js +127 -0
  31. package/build/esm/editor/components/log-viewer.d.ts +6 -0
  32. package/build/esm/editor/components/log-viewer.js +71 -0
  33. package/build/esm/editor/components/new-file.d.ts +10 -0
  34. package/build/esm/editor/components/new-file.js +119 -0
  35. package/build/esm/editor/components/scroll-query.d.ts +7 -0
  36. package/build/esm/editor/components/scroll-query.js +22 -0
  37. package/build/esm/editor/components/start-page.d.ts +13 -0
  38. package/build/esm/editor/components/start-page.js +32 -0
  39. package/build/esm/editor/http/admin/editor/api/fs/delete.api.d.ts +3 -0
  40. package/build/esm/editor/http/admin/editor/api/fs/delete.api.js +30 -0
  41. package/build/esm/editor/http/admin/editor/api/fs/read.api.d.ts +5 -0
  42. package/build/esm/editor/http/admin/editor/api/fs/read.api.js +50 -0
  43. package/build/esm/editor/http/admin/editor/api/fs/rename.api.d.ts +4 -0
  44. package/build/esm/editor/http/admin/editor/api/fs/rename.api.js +40 -0
  45. package/build/esm/editor/http/admin/editor/api/fs/scan.api.d.ts +26 -0
  46. package/build/esm/editor/http/admin/editor/api/fs/scan.api.js +150 -0
  47. package/build/esm/editor/http/admin/editor/api/fs/write.api.d.ts +3 -0
  48. package/build/esm/editor/http/admin/editor/api/fs/write.api.js +39 -0
  49. package/build/esm/editor/http/admin/editor/api/server/reload.api.d.ts +10 -0
  50. package/build/esm/editor/http/admin/editor/api/server/reload.api.js +46 -0
  51. package/build/esm/editor/http/admin/editor/api/server/restart.api.d.ts +10 -0
  52. package/build/esm/editor/http/admin/editor/api/server/restart.api.js +46 -0
  53. package/build/esm/editor/http/admin/editor/editor.d.ts +1 -0
  54. package/build/esm/editor/http/admin/editor/editor.js +8 -0
  55. package/build/esm/editor/http/admin/editor/index.api.d.ts +3 -0
  56. package/build/esm/editor/http/admin/editor/index.api.js +22 -0
  57. package/build/esm/editor/server.d.ts +3 -0
  58. package/build/esm/editor/server.js +49 -0
  59. package/build/esm/editor/ws.d.ts +3 -0
  60. package/build/esm/editor/ws.js +11 -0
  61. package/build/esm/src/inflate/inflate-sea.js +8 -1
  62. package/build/esm/src/services/app.js +7 -2
  63. package/build/lib.cjs +14 -3
  64. package/editor/auth.ts +51 -0
  65. package/editor/common/admin-interface.ts +84 -0
  66. package/editor/common/constants.server.ts +5 -0
  67. package/editor/common/constants.ts +21 -0
  68. package/editor/common/editor-index.tsx +17 -0
  69. package/editor/common/html-encode.ts +14 -0
  70. package/editor/common/log-socket.tsx +87 -0
  71. package/editor/common/templates.ts +481 -0
  72. package/editor/components/api-preview.tsx +118 -0
  73. package/editor/components/editor.tsx +496 -0
  74. package/editor/components/file-browser.tsx +311 -0
  75. package/editor/components/file-editor-toolbar.tsx +194 -0
  76. package/editor/components/file-editor.tsx +125 -0
  77. package/editor/components/filter-query.tsx +26 -0
  78. package/editor/components/highlight-text-area.tsx +148 -0
  79. package/editor/components/log-viewer.tsx +113 -0
  80. package/editor/components/new-file.tsx +172 -0
  81. package/editor/components/scroll-query.tsx +25 -0
  82. package/editor/components/start-page.tsx +52 -0
  83. package/editor/http/admin/editor/api/fs/delete.api.tsx +32 -0
  84. package/editor/http/admin/editor/api/fs/read.api.tsx +55 -0
  85. package/editor/http/admin/editor/api/fs/rename.api.tsx +41 -0
  86. package/editor/http/admin/editor/api/fs/scan.api.tsx +181 -0
  87. package/editor/http/admin/editor/api/fs/write.api.tsx +41 -0
  88. package/editor/http/admin/editor/api/server/reload.api.ts +53 -0
  89. package/editor/http/admin/editor/api/server/restart.api.tsx +52 -0
  90. package/editor/http/admin/editor/editor.tsx +10 -0
  91. package/editor/http/admin/editor/index.api.tsx +42 -0
  92. package/editor/server.ts +57 -0
  93. package/editor/ws.ts +15 -0
  94. package/package.json +2 -2
  95. package/src/bin/compile.ts +35 -0
  96. package/src/bin/doc-md.ts +210 -0
  97. package/src/bin/generate-doc.ts +64 -0
  98. package/src/bin/test.ts +92 -0
  99. package/src/bin/types.ts +34 -0
  100. package/src/cluster.ts +27 -0
  101. package/src/common/arguments.ts +762 -0
  102. package/src/common/assets.ts +148 -0
  103. package/src/common/checksum.ts +58 -0
  104. package/src/common/constants.ts +18 -0
  105. package/src/common/content-type.ts +84 -0
  106. package/src/common/esbuild.ts +102 -0
  107. package/src/common/exit.ts +91 -0
  108. package/src/common/fs.ts +82 -0
  109. package/src/common/help.ts +60 -0
  110. package/src/common/jsx.ts +562 -0
  111. package/src/common/jwt.ts +85 -0
  112. package/src/common/paths.ts +107 -0
  113. package/src/common/watch.ts +88 -0
  114. package/src/inflate/inflate-sea.ts +244 -0
  115. package/src/inflate/inflate.ts +101 -0
  116. package/src/inflate/md.ts +25 -0
  117. package/src/inflate/setup-auth.ts +41 -0
  118. package/src/inflate/setup-cors.ts +41 -0
  119. package/src/inflate/setup-db.ts +117 -0
  120. package/src/inflate/setup-error.ts +44 -0
  121. package/src/inflate/setup-http.ts +704 -0
  122. package/src/inflate/setup-log.ts +45 -0
  123. package/src/inflate/setup-middleware.ts +47 -0
  124. package/src/inflate/setup-server-config.ts +48 -0
  125. package/src/inflate/setup-test.ts +23 -0
  126. package/src/inflate/setup-ws.ts +50 -0
  127. package/src/inflate/setup.doc.ts +92 -0
  128. package/src/inflate/utils/sea-utils.ts +14 -0
  129. package/src/lib.ts +34 -0
  130. package/src/main.ts +101 -0
  131. package/src/services/app.ts +703 -0
  132. package/src/services/editor.tsx +101 -0
  133. package/src/services/globals.ts.ignore +186 -0
  134. package/src/services/hot-reload.ts +51 -0
  135. package/src/services/migrations.ts +68 -0
  136. package/src/services/utils/admin-interface.ts +37 -0
  137. package/src/services/utils/cache.ts +88 -0
  138. package/src/services/utils/cluster-cache.ts +230 -0
  139. package/src/services/utils/cluster-ws.ts +202 -0
  140. package/src/services/utils/db-manager.ts +92 -0
  141. package/src/services/utils/get-route.ts +70 -0
  142. package/src/services/utils/jwt.ts +25 -0
  143. package/src/services/utils/log-transport.ts +81 -0
  144. package/src/services/utils/log.ts +92 -0
  145. package/src/services/utils/middleware.ts +10 -0
  146. package/src/services/utils/server-interface.ts +122 -0
  147. package/src/services/utils/websocketmanager.ts +157 -0
  148. package/src/types.ts +307 -0
@@ -0,0 +1,101 @@
1
+ import { APIRoute, Handler, HandlerWithOptions, Router, RouterHandlerOptions, SessionHandler } from "@miqro/core";
2
+ import { getAsset } from "../common/assets.js";
3
+
4
+ import { BASEEDITOR_PATH } from "../../editor/common/constants.js";
5
+ import EDITOR_AUTH from "../../editor/auth.js";
6
+
7
+ /*import writeAPI from "../../editor/http/admin/editor/api/fs/write.api.js";
8
+ import renameAPI from "../../editor/http/admin/editor/api/fs/rename.api.js";
9
+ import deleteAPI from "../../editor/http/admin/editor/api/fs/delete.api.js";
10
+ import readAPI from "../../editor/http/admin/editor/api/fs/read.api.js";
11
+ import scanAPI from "../../editor/http/admin/editor/api/fs/scan.api.js";
12
+ import restartAPI from "../../editor/http/admin/editor/api/server/restart.api.js";
13
+ import reloadAPI from "../../editor/http/admin/editor/api/server/reload.api.js";*/
14
+
15
+ import { AdminRequest, EditorAdminInterface } from "../../editor/common/admin-interface.js";
16
+ import { CONTENT_TYPE_MAP } from "../common/content-type.js";
17
+
18
+ export async function createEditorRouter(adminInterface: EditorAdminInterface): Promise<Router> {
19
+ const router = new Router();
20
+ const innerRouter = new Router();
21
+
22
+ innerRouter.use(async (req: AdminRequest, res) => {
23
+ res.setHeader("x-uuid", req.uuid);
24
+ req.editor = adminInterface;
25
+ });
26
+
27
+ const editorFont = Buffer.from(getAsset("editor-assets/font.ttf"));
28
+ const editorJS = Buffer.from(getAsset("editor-assets/editor.bundle.js")).toString().trim();
29
+ const editorCSS = Buffer.from(getAsset("editor-assets/style.css")).toString().trim().split("\n").map(l => l.trim()).filter(l => l).join("");
30
+
31
+ const writeAPI = (await import("../../editor/http/admin/editor/api/fs/write.api.js")).default;
32
+ const renameAPI = (await import("../../editor/http/admin/editor/api/fs/rename.api.js")).default;
33
+ const deleteAPI = (await import("../../editor/http/admin/editor/api/fs/delete.api.js")).default;
34
+ const readAPI = (await import("../../editor/http/admin/editor/api/fs/read.api.js")).default;
35
+ const scanAPI = (await import("../../editor/http/admin/editor/api/fs/scan.api.js")).default;
36
+ const restartAPI = (await import("../../editor/http/admin/editor/api/server/restart.api.js")).default;
37
+ const reloadAPI = (await import("../../editor/http/admin/editor/api/server/reload.api.js")).default;
38
+
39
+ const authHandler = SessionHandler(EDITOR_AUTH);
40
+
41
+ const { EditorIndex } = await import("../../editor/common/editor-index.js");
42
+
43
+ innerRouter.use(authHandler);
44
+
45
+ innerRouter.post(`/api/fs/write`, getHandler(/*authHandler, */writeAPI));
46
+
47
+ innerRouter.post(`/api/fs/rename`, getHandler(/*authHandler, */renameAPI));
48
+
49
+ innerRouter.post(`/api/fs/read`, getHandler(/*authHandler, */readAPI));
50
+
51
+ innerRouter.post(`/api/fs/delete`, getHandler(/*authHandler, */deleteAPI));
52
+
53
+ innerRouter.get(`/api/fs/scan`, getHandler(/*authHandler, */scanAPI));
54
+
55
+ innerRouter.post(`/api/server/restart`, getHandler(/*authHandler, */restartAPI));
56
+
57
+ innerRouter.post(`/api/server/reload`, getHandler(/*authHandler, */reloadAPI));
58
+
59
+ innerRouter.get(`/font.ttf`, async (_req, res) => {
60
+ return await res.asyncEnd({
61
+ status: 200,
62
+ headers: {
63
+ ["Content-Type"]: CONTENT_TYPE_MAP[".ttf"]
64
+ },
65
+ body: editorFont
66
+ })
67
+ });
68
+
69
+ innerRouter.get("/", EditorIndex(editorCSS, editorJS, false));
70
+
71
+
72
+
73
+ innerRouter.use(async (req: AdminRequest, res) => {
74
+ delete req.editor;
75
+ });
76
+
77
+ router.use(innerRouter, BASEEDITOR_PATH);
78
+
79
+ return router;
80
+ }
81
+
82
+ function getHandlerOptions(router: APIRoute): RouterHandlerOptions {
83
+ return {
84
+ description: router.description,
85
+ //handler: router,
86
+ middleware: router.middleware,
87
+ request: router.request,
88
+ response: router.response,
89
+ };
90
+ }
91
+
92
+ function getHandler(/*auth: Handler, */router: APIRoute): HandlerWithOptions {
93
+ /*const ret = new Router();
94
+ ret.use(auth);
95
+ ret.use(router.handler, undefined, undefined, getHandlerOptions(router));
96
+ return ret;*/
97
+ return {
98
+ ...getHandlerOptions(router),
99
+ handler: router.handler as Handler
100
+ }
101
+ }
@@ -0,0 +1,186 @@
1
+ //@ts-ignore
2
+ import { ReadBuffer, URLEncodedParser, JSONParser, TextParser, CORS, SessionHandler } from "@miqro/core";
3
+ import cluster from "node:cluster";
4
+ import { strictEqual } from "node:assert";
5
+ import { HTMLEncode } from "@miqro/jsx-node";
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
+
8
+ import { jsx2HTML } from "../common/jsx.js";
9
+ import { inflateMD2HTML } from "../inflate/md.js";
10
+ import { EXIT_CODES } from "../common/constants.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";
15
+
16
+ /*const globaljsx: any = Object.freeze({
17
+ useContext,
18
+ useRuntime,
19
+ createContext,
20
+ useState,
21
+ useEffect,
22
+ useQuery,
23
+ useRef,
24
+ useElement,
25
+ useRefresh,
26
+ Link,
27
+ Router,
28
+ usePathname
29
+ });*/
30
+ const globalJSX: any = Object.freeze({
31
+ createElement: (...args: [tag: string | Component | typeof Fragment, attributes: Props | null | undefined, ...children: Array<any>]) => {
32
+ const ret = realCreateElement(...args);
33
+ ret.toString = () => jsx2HTML(ret)
34
+ return ret;
35
+ },
36
+ Fragment,
37
+ enableDebugLog
38
+ });
39
+ const globaljsx: any = Object.freeze({
40
+ useContext,
41
+ useRuntime,
42
+ createContext,
43
+ useState,
44
+ useEffect,
45
+ useQuery,
46
+ useRef,
47
+ useElement,
48
+ useRefresh,
49
+ Link,
50
+ Router,
51
+ usePathname,
52
+ define: function define() {
53
+ /*const callSites = getCallSite();
54
+ const caller = callSites[2];
55
+ if (CLEAR_JSX_CACHE) {
56
+ const scriptName = basename(caller.scriptName);
57
+ const originalName = scriptName.substring(0, scriptName.length - ".mjs".length);
58
+ //server.logger.debug("browser.define not available server side!");
59
+ //server.logger.trace("browser.define not available server side! %s", originalName);
60
+ } else {
61
+ //server.logger.debug("browser.define not available server side!");
62
+ //server.logger.trace("browser.define not available server side! %s:%s:%s", caller.scriptName, caller.lineNumber, caller.column);
63
+ }*/
64
+ }
65
+ });
66
+ const globalWindow: any = Object.freeze({
67
+ addEventListener: function define() {
68
+ /*const callSites = getCallSite();
69
+ const caller = callSites[2];
70
+ if (CLEAR_JSX_CACHE) {
71
+ const scriptName = basename(caller.scriptName);
72
+ //server.logger.debug("window.addEventListener not available server side!");
73
+ server.logger.trace("window.addEventListener not available server side! %s", scriptName.substring(0, scriptName.length - ".mjs".length));
74
+ } else {
75
+ //server.logger.debug("window.addEventListener not available server side!");
76
+ server.logger.trace("window.addEventListener not available server side! %s:%s:%s", caller.scriptName, caller.lineNumber, caller.column);
77
+ }*/
78
+ }
79
+ });
80
+ const globalServer: ServerGlobal = Object.freeze<ServerGlobal>({
81
+ middleware: Object.freeze({
82
+ buffer: ReadBuffer,
83
+ url: URLEncodedParser,
84
+ json: JSONParser,
85
+ text: TextParser,
86
+ cors: CORS,
87
+ session: SessionHandler
88
+ }),
89
+ encodeHTML: HTMLEncode,
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
+ }
130
+ }) as ServerGlobal;
131
+
132
+ export function browserJSXGlobals(inFile: string, jsxPath: string | false = false, useExport = true): string {
133
+ const PRE = `import { enableDebugLog, useRuntime, Link, usePathname, createContext, useContext, useElement, useRefresh, useQuery, define, Router, useState, useEffect, useRef, createElement, Fragment } from "${jsxPath}";
134
+ globalThis.JSX = Object.freeze({
135
+ createElement,
136
+ Fragment,
137
+ enableDebugLog
138
+ });
139
+
140
+ globalThis.newParser = () => new Parser();
141
+ globalThis.jsx = Object.freeze({
142
+ define,
143
+ useRuntime,
144
+ createContext,
145
+ useContext,
146
+ useState,
147
+ useEffect,
148
+ useQuery,
149
+ useRef,
150
+ useElement,
151
+ useRefresh,
152
+ usePathname,
153
+ Link,
154
+ Router
155
+ });`;
156
+ return `${jsxPath ? PRE : ""}\n${useExport ? `export * from "${inFile}";import * as lib from "${inFile}";export default lib.default;` : `import * as lib from "${inFile}"`}`;
157
+ }
158
+
159
+ export function initGlobals() {//webSocketManager: WebSocketManager, dbManager: DBManager) {
160
+ //const logger = getLogger(SERVER_IDENTIFIER);
161
+ globalThis.server = globalServer;
162
+ //globalThis.jsx = globaljsx;
163
+ /*for (const key of Object.keys(globaljsx)) {
164
+ globalThis[key] = globaljsx[key];
165
+ }*/
166
+ globalThis.JSX = globalJSX;
167
+ globalThis.jsx = globaljsx;
168
+ globalThis.window = globalWindow;
169
+ }
170
+
171
+ export function assertGlobalTampered() {
172
+ try {
173
+ //strictEqual(globalThis.utils, globalUtils, "globalThis.utils tamperered");
174
+ strictEqual(globalThis.JSX, globalJSX, "globalThis.JSX tamperered");
175
+ //strictEqual(globalThis.jsx, globaljsx, "globalThis.jsx tamperered");
176
+ /*for (const key of Object.keys(globaljsx)) {
177
+ strictEqual(globalThis[key], globaljsx[key], "globalThis.jsx tamperered");
178
+ }*/
179
+ strictEqual(globalThis.server, globalServer, "globalThis.server tamperered");
180
+ strictEqual(globalThis.jsx, globaljsx, "globalThis.jsx tamperered");
181
+ strictEqual(globalThis.window, globalWindow, "globalThis.window tamperered");
182
+ } catch (e) {
183
+ console.error(e);
184
+ process.exit(EXIT_CODES.GLOBALS_ALTERED);
185
+ }
186
+ }
@@ -0,0 +1,51 @@
1
+ //import { checkEnvVariable } from "@miqro/core";
2
+
3
+ import { HOT_RELOAD_PATH } from "../common/constants.js";
4
+
5
+ export function getHotReloadScript() {
6
+ const HOT_RELOAD_JS_SCRIPT = `
7
+ // Create WebSocket connection.
8
+
9
+ function getSocket() {
10
+ return new WebSocket("${HOT_RELOAD_PATH}");
11
+ }
12
+
13
+ const socket = getSocket();
14
+
15
+ let timeout;
16
+
17
+ function tryConnection() {
18
+ try {
19
+ const newSocket = getSocket();
20
+ newSocket.addEventListener("open", (event) => {
21
+ console.log("reloading");
22
+ setTimeout(()=>{
23
+ window.location.reload();
24
+ }, 500);
25
+
26
+ });
27
+ newSocket.addEventListener("error", (err) => {
28
+ console.error(err);
29
+ timeout = setTimeout(tryConnection, 500);
30
+ });
31
+ } catch (e) {
32
+ console.error(e);
33
+ timeout = setTimeout(tryConnection, 500);
34
+ }
35
+ }
36
+
37
+ // Connection closed
38
+ socket.addEventListener("close", (event) => {
39
+ clearTimeout(timeout);
40
+ timeout = setTimeout(tryConnection, 500);
41
+ });
42
+
43
+ socket.addEventListener("error", (err) => {
44
+ console.error(err);
45
+ });`;
46
+ return `<script>${HOT_RELOAD_JS_SCRIPT}</script>`;
47
+ }
48
+
49
+ /*export function isHotReloadEnabled() {
50
+ return checkEnvVariable("HOT_RELOAD", "0") === "1";
51
+ }*/
@@ -0,0 +1,68 @@
1
+ import { Logger } from "@miqro/core";
2
+ import { Database, DatabaseLogger, migration } from "@miqro/query";
3
+ import { dirname, extname, relative, resolve } from "node:path";
4
+ import { mkdirSync, writeFileSync } from "node:fs";
5
+ import { cwd } from "node:process";
6
+
7
+ import { getMigrationsPath } from "../common/paths.js";
8
+ import { importJSXFile, inflateJSX } from "../common/jsx.js";
9
+
10
+ export async function runMigrations(logger: Logger | undefined, db: Database | null, servicePath: string, service: string, inflateDir: string | undefined | false, migrations: string[]) {
11
+ const migrationsFolderPath = getMigrationsPath(servicePath);
12
+ if (migrationsFolderPath) {
13
+ logger?.debug("running migrations from [%s]", service);
14
+ if (!db) {
15
+ throw new Error("cannot run migrations with the database disabled!");
16
+ }
17
+ const serviceMigrations = await migration.up.folder(db as any, migrationsFolderPath, logger as DatabaseLogger, (inFile: string) => importJSXFile(inFile, logger));
18
+ migrations.push(...serviceMigrations);
19
+
20
+ if (inflateDir) {
21
+ for (const migration of serviceMigrations) {
22
+ const inflatePath = resolve(inflateDir, service, "migration", migration.substring(0, migration.length - extname(migration).length) + ".cjs");
23
+ mkdirSync(dirname(inflatePath), {
24
+ recursive: true
25
+ });
26
+ logger?.log("writing [%s]", relative(cwd(), inflatePath));
27
+ writeFileSync(inflatePath, await inflateJSX(resolve(migrationsFolderPath, migration), {
28
+ // embemedJSX: false,
29
+ minify: false,
30
+ useExport: true,
31
+ platform: "node",
32
+ logger
33
+ }));
34
+ }
35
+ }
36
+ }
37
+ return migrations;
38
+ }
39
+
40
+ export async function runMigrationsDown(logger: Logger | Console | undefined, db: Database | null, servicePath: string, service: string, inflateDir: string | undefined, migrations: string[]) {
41
+ const migrationsFolderPath = getMigrationsPath(servicePath)
42
+ if (migrationsFolderPath) {
43
+ logger?.debug("running migrations from [%s]", service);
44
+ if (!db) {
45
+ throw new Error("cannot run migrations with the database disabled!");
46
+ }
47
+ const serviceMigrations = await migration.down.folder(db as any, migrationsFolderPath, logger as DatabaseLogger, (inFile: string) => importJSXFile(inFile, logger));
48
+ migrations.push(...serviceMigrations);
49
+
50
+ if (inflateDir) {
51
+ for (const migration of serviceMigrations) {
52
+ const inflatePath = resolve(inflateDir, service, "migration", migration.substring(0, migration.length - extname(migration).length) + ".cjs");
53
+ mkdirSync(dirname(inflatePath), {
54
+ recursive: true
55
+ });
56
+ logger?.log("writing [%s]", relative(cwd(), inflatePath));
57
+ writeFileSync(inflatePath, await inflateJSX(resolve(migrationsFolderPath, migration), {
58
+ // embemedJSX: false,
59
+ platform: "node",
60
+ minify: false,
61
+ useExport: true,
62
+ logger
63
+ }));
64
+ }
65
+ }
66
+ }
67
+ return migrations;
68
+ }
@@ -0,0 +1,37 @@
1
+ import { EditorAdminInterface } from "../../../editor/common/admin-interface.js";
2
+ import { MigrationModule } from "../../inflate/setup-db.js";
3
+ import { Miqro } from "../app.js";
4
+ import { getHotReloadScript } from "../hot-reload.js";
5
+ import { ClusterCache } from "./cluster-cache.js";
6
+
7
+ export function createAdminInterface(app: Miqro): EditorAdminInterface {
8
+ const adminCache = new ClusterCache("EditorCache[" + app.options.name + "]");
9
+ return {
10
+ getCache: () => adminCache,
11
+ stop: () => app.stop(),
12
+ restart: () => app.restart(),
13
+ reload: () => app.reload(),
14
+ getHotReloadHTML: getHotReloadScript,
15
+ getMigrations: () => {
16
+ if (app.inflated) {
17
+ const ret: MigrationModule[] = [];
18
+ for (const db of app.inflated.dbList) {
19
+ for (const m of db.migrations) {
20
+ ret.push(m);
21
+ }
22
+ }
23
+ return ret;
24
+ }
25
+ return [];
26
+ },
27
+ getServices: () => {
28
+ return app.options.services;
29
+ },
30
+ getRouteFileMap: () => {
31
+ return app.inflated ? app.inflated.fileMap : {};
32
+ },
33
+ getInflateErrors: () => {
34
+ return app.inflated ? app.inflated.errors : [];
35
+ }
36
+ }
37
+ }
@@ -0,0 +1,88 @@
1
+ import { Logger } from "@miqro/core";
2
+ import { CacheInterface } from "../../types.js";
3
+
4
+ export class LocalCache implements CacheInterface {
5
+ private localCache = new Map<string, unknown>();
6
+
7
+ constructor(public name: string, public logger?: Logger) {
8
+ }
9
+
10
+ dispose() {
11
+
12
+ }
13
+
14
+ get<T = any>(key: string): T | undefined {
15
+ this.logger?.trace("get(%s)", key);
16
+ return this.localCache.get(key) as T;
17
+ }
18
+ set(key: string, value: unknown): void {
19
+ this.localCache.set(key, value);
20
+ this.logger?.trace("set(%s, ...)", key);
21
+ }
22
+ unset(key: string): void {
23
+ this.logger?.trace("unset(%s)", key);
24
+ this.localCache.delete(key);
25
+ }
26
+ has(key: string): boolean {
27
+ this.logger?.trace("has(%s)", key);
28
+ return this.localCache.has(key);
29
+ }
30
+
31
+ set_add(key: string, value: unknown): void {
32
+ this.logger?.trace("set_add(%s)", key);
33
+ const list = this.localCache.has(key) ? this.localCache.get(key) : new Set<string>();
34
+ if (!(list instanceof Set)) {
35
+ throw new Error("cannot apply on non Set");
36
+ }
37
+ if (!list.has(value)) {
38
+ list.add(value);
39
+ }
40
+ this.localCache.set(key, list);
41
+ }
42
+ set_delete(key: string, value: unknown): void {
43
+ this.logger?.trace("set_delete(%s)", key);
44
+ const list = this.localCache.has(key) ? this.localCache.get(key) : new Set<string>();
45
+ if (!(list instanceof Set)) {
46
+ throw new Error("cannot apply on non Set");
47
+ }
48
+ if (list.has(value)) {
49
+ list.delete(value);
50
+ }
51
+ this.localCache.set(key, list);
52
+ }
53
+ set_has(key: string, value: unknown): boolean {
54
+ this.logger?.trace("set_has(%s)", key);
55
+ const list = this.localCache.has(key) ? this.localCache.get(key) : new Set<string>();
56
+ if (!(list instanceof Set)) {
57
+ throw new Error("cannot apply on non Set");
58
+ }
59
+ const ret = list.has(value);
60
+ this.localCache.set(key, list);
61
+ return ret;
62
+ }
63
+ set_clear(key: string): void {
64
+ this.logger?.trace("set_clear(%s)", key);
65
+ const list = this.localCache.has(key) ? this.localCache.get(key) : new Set<string>();
66
+ if (!(list instanceof Set)) {
67
+ throw new Error("cannot apply on non Set");
68
+ }
69
+ list.clear();
70
+ this.localCache.set(key, list);
71
+ }
72
+ array_push(key: string, value: unknown): void {
73
+ this.logger?.trace("array_push(%s)", key);
74
+ const list = this.localCache.has(key) ? this.localCache.get(key) : [];
75
+ if (!(list instanceof Array)) {
76
+ throw new Error("cannot apply on non Array");
77
+ }
78
+ list.push(value);
79
+ this.localCache.set(key, list);
80
+ }
81
+ array_clear(key: string): void {
82
+ this.logger?.trace("array_clear(%s)", key);
83
+ if (this.localCache.has(key) && !(this.localCache.get(key) instanceof Array)) {
84
+ throw new Error("cannot apply on non Array");
85
+ }
86
+ this.localCache.set(key, []);
87
+ }
88
+ }