miqro 7.2.0 → 7.2.2

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 (34) hide show
  1. package/build/editor.bundle.js +3 -3
  2. package/build/esm/editor/auth.js +2 -1
  3. package/build/esm/editor/auth.js.map +1 -1
  4. package/build/esm/editor/http/admin/editor/api/fs/read.api.js +2 -2
  5. package/build/esm/editor/http/admin/editor/api/fs/read.api.js.map +1 -1
  6. package/build/esm/editor/ws.js +1 -1
  7. package/build/esm/editor/ws.js.map +1 -1
  8. package/build/esm/src/cluster.js +0 -0
  9. package/build/esm/src/common/esbuild.js +1 -1
  10. package/build/esm/src/common/esbuild.js.map +1 -1
  11. package/build/esm/src/inflate/inflate-sea.js +2 -2
  12. package/build/esm/src/inflate/inflate-sea.js.map +1 -1
  13. package/build/esm/src/main.js +0 -0
  14. package/build/esm/src/services/app.js +3 -3
  15. package/build/esm/src/services/utils/cluster-cache.js +90 -64
  16. package/build/esm/src/services/utils/cluster-cache.js.map +1 -1
  17. package/build/esm/src/services/utils/cluster-ws.js +2 -2
  18. package/build/esm/src/services/utils/cluster-ws.js.map +1 -1
  19. package/build/esm/src/services/utils/websocketmanager.js +2 -1
  20. package/build/esm/src/services/utils/websocketmanager.js.map +1 -1
  21. package/build/lib.cjs +1466 -1222
  22. package/editor/auth.ts +2 -1
  23. package/editor/http/admin/editor/api/fs/read.api.tsx +2 -2
  24. package/editor/ws.ts +1 -1
  25. package/package.json +8 -8
  26. package/sea/install-esbuild.sh +1 -1
  27. package/sea/install-nodejs.sh +1 -1
  28. package/sea/node.version.tag +1 -1
  29. package/src/common/esbuild.ts +1 -1
  30. package/src/inflate/inflate-sea.ts +2 -2
  31. package/src/services/app.ts +3 -3
  32. package/src/services/utils/cluster-cache.ts +90 -65
  33. package/src/services/utils/cluster-ws.ts +2 -2
  34. package/src/services/utils/websocketmanager.ts +2 -1
package/editor/auth.ts CHANGED
@@ -1,3 +1,4 @@
1
+ import { timingSafeEqual } from "node:crypto";
1
2
  import { AuthConfig, ServerRequest } from "../src/types.js";
2
3
  import { AdminRequest } from "./common/admin-interface.js";
3
4
 
@@ -27,7 +28,7 @@ export default {
27
28
  //console.log("\n\nqueryToken[%s] cookieToken[%s] KEY[%s]\n\n", queryToken, cookieToken, KEY);
28
29
 
29
30
  if (queryToken) {
30
- if (queryToken === KEY) {
31
+ if (typeof queryToken === "string" && timingSafeEqual(Buffer.from(queryToken), Buffer.from(KEY))) {
31
32
  args.res.setCookie(ADMIN_EDITOR_AUTH_COOKIE, KEY, {
32
33
  expires: new Date(Date.now() + 1000 * 60 * 60 * 24 * 31 * 12 * 500),
33
34
  httpOnly: true,
@@ -1,5 +1,5 @@
1
1
  import { APIRoute, JSONParser } from "@miqro/core";
2
- import { readFileSync } from "node:fs";
2
+ import { readFileSync, realpathSync } from "node:fs";
3
3
  import { SUPPORTED_LANGUAGES } from "../../../../../common/constants.js";
4
4
  import { relative, resolve } from "node:path";
5
5
  import { getLanguage } from "./scan.api.js";
@@ -45,7 +45,7 @@ export function readFile(path: string) {
45
45
  }
46
46
 
47
47
  export function getPath(path: string) {
48
- const realPath = resolve(BASE_PATH, path);
48
+ const realPath = realpathSync(resolve(BASE_PATH, path));
49
49
 
50
50
  if (relative(BASE_PATH, realPath).startsWith("..")) {
51
51
  throw new Error("invalid path! [" + path + "]");
package/editor/ws.ts CHANGED
@@ -10,6 +10,6 @@ export default {
10
10
 
11
11
  const KEY = cache.get("AUTH_KEY");
12
12
  const cookieToken = req.cookies["auth"];
13
- return cookieToken === KEY ? true : false;
13
+ return cookieToken && KEY && cookieToken === KEY ? true : false;
14
14
  },
15
15
  } as WSConfig;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "miqro",
3
- "version": "7.2.0",
3
+ "version": "7.2.2",
4
4
  "description": "",
5
5
  "type": "module",
6
6
  "main": "build/esm/src/lib.js",
@@ -41,17 +41,17 @@
41
41
  },
42
42
  "dependencies": {
43
43
  "postject": "1.0.0-alpha.6",
44
- "@miqro/core": "^5.0.16",
44
+ "@miqro/core": "^5.0.17",
45
45
  "@miqro/jsx": "^1.0.1",
46
46
  "@miqro/jsx-dom": "^1.0.4",
47
47
  "@miqro/jsx-node": "^1.0.6",
48
- "@miqro/parser": "^2.0.4",
49
- "@miqro/query": "^0.0.4",
50
- "@miqro/runner": "^2.0.1",
48
+ "@miqro/parser": "^2.0.5",
49
+ "@miqro/query": "^0.0.7",
50
+ "@miqro/runner": "^2.0.2",
51
51
  "@miqro/test": "^0.2.9",
52
- "@miqro/test-http": "^0.1.2",
53
- "esbuild": "0.25.11",
54
- "jose": "6.1.0",
52
+ "@miqro/test-http": "^0.1.3",
53
+ "esbuild": "0.28.0",
54
+ "jose": "6.2.1",
55
55
  "showdown": "2.1.0"
56
56
  }
57
57
  }
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env sh
2
2
 
3
3
  TARGET="${PWD}/sea/deps/esbuild"
4
- VERSION="0.25.11"
4
+ VERSION="0.28.0"
5
5
 
6
6
  if [ -d "$TARGET" ]; then
7
7
  echo "$TARGET already exists exist."
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env sh
2
2
 
3
3
  TARGET="${PWD}/sea/deps/nodejs"
4
- VERSION="25.0.0"
4
+ VERSION="25.9.0"
5
5
 
6
6
  if [ -d "$TARGET" ]; then
7
7
  echo "$TARGET already exists exist."
@@ -1 +1 @@
1
- 25.0.0
1
+ 25.9.0
@@ -73,7 +73,7 @@ export async function esBuild(options: {
73
73
  try {
74
74
  //const logger = getLogger(`${SERVER_IDENTIFIER}_ESBUILD`);
75
75
  const valid = await validateESBuild(logger);
76
- const esBuildCMD = `${getESBuildBinaryPath()} "${options.entryPoints[0]}" ${(options.external ? options.external : NODEJS_EXTERNAL).map(e => `--external:${e}`).join(" ")} --loader:.js=jsx --jsx-factory=${options.jsxFactory} --jsx-fragment=${options.jsxFragment} ${options.bundle ? " --bundle" : ""}${options.minify ? " --minify" : ""}${options.outfile ? ` --outfile="${options.outfile}"` : ""}${options.platform ? ` --platform=${options.platform}` : ""}${options.mainFields ? ` --main-fields=${options.mainFields}` : ""}${options.keepNames ? ` --keep-names` : ""}`;
76
+ const esBuildCMD = `${getESBuildBinaryPath()} "${options.entryPoints[0]}" ${(options.external ? options.external : NODEJS_EXTERNAL).map(e => `--external:"${e}"`).join(" ")} --loader:.js=jsx --jsx-factory=${options.jsxFactory} --jsx-fragment=${options.jsxFragment} ${options.bundle ? " --bundle" : ""}${options.minify ? " --minify" : ""}${options.outfile ? ` --outfile="${options.outfile}"` : ""}${options.platform ? ` --platform=${options.platform}` : ""}${options.mainFields ? ` --main-fields=${options.mainFields}` : ""}${options.keepNames ? ` --keep-names` : ""}`;
77
77
  logger?.trace(esBuildCMD);
78
78
  if (!valid) {
79
79
  const err = new Error(`esbuild installation at [${getESBuildBinaryPath()}] tampered`);
@@ -212,7 +212,7 @@ async function runMigrations(db) {
212
212
  await migration.init(db);
213
213
  ${serviceMigrations.map(file => {
214
214
  const name = `${file.substring(0, file.length - extname(file).length)}`;
215
- return ` await migration.up.module(db, "${file}", (await require("../${relative(service, "")}/${service}/migration/${name}.cjs")).default)`;
215
+ return ` await migration.up.module(db, (await require("../${relative(service, "")}/${service}/migration/${name}.cjs")).default.name ?? "${file}", (await require("../${relative(service, "")}/${service}/migration/${name}.cjs")).default)`;
216
216
  }).join("\n")}
217
217
  }
218
218
  module.exports = {
@@ -224,7 +224,7 @@ async function runMigrations(db) {
224
224
  await migration.init(db);
225
225
  ${serviceMigrations.reverse().map(file => {
226
226
  const name = `${file.substring(0, file.length - extname(file).length)}`;
227
- return ` await migration.down.module(db, "${file}", (await require("../${relative(service, "")}/${service}/migration/${name}.cjs")).default)`;
227
+ return ` await migration.down.module(db, (await require("../${relative(service, "")}/${service}/migration/${name}.cjs")).default.name ?? "${file}", (await require("../${relative(service, "")}/${service}/migration/${name}.cjs")).default)`;
228
228
  }).join("\n")}
229
229
  }
230
230
  module.exports = {
@@ -133,8 +133,8 @@ export class Miqro {
133
133
  msg &&
134
134
  msg.action &&
135
135
  msg.type === MiqroApplicationMessageType &&
136
- msg.target === this.options.name,
137
- msg.fromPID !== process.pid,
136
+ msg.target === this.options.name &&
137
+ msg.fromPID !== process.pid &&
138
138
  (msg.action === "reload" || msg.action === "restart")) {
139
139
  this.logger?.debug("remote server message from [%s] [%s]", msg.fromPID, msg.action);
140
140
  switch (msg.action) {
@@ -145,7 +145,7 @@ export class Miqro {
145
145
  await this.restart(true);
146
146
  break;
147
147
  default:
148
- throw new Error("unsopported message for ApplicaitonServer");
148
+ throw new Error("unsupported message for ApplicationServer");
149
149
  }
150
150
  }
151
151
  } catch (e) {
@@ -6,7 +6,7 @@ const ClusterCacheType = "$$$$$$$$$$$ClusterCacheType$$$$$$$$$$$";
6
6
  interface ClusterCacheMessage {
7
7
  type: typeof ClusterCacheType;
8
8
  target: string;
9
- action: "set" | "unset" | "set_add" | "set_delete" | "array_push";
9
+ action: "set" | "unset" | "set_add" | "set_delete" | "array_push" | "set_clear" | "array_clear";
10
10
  fromPID: number;
11
11
  key: string;
12
12
  value?: string;
@@ -28,11 +28,29 @@ export class ClusterCache implements CacheInterface {
28
28
  msg.key &&
29
29
  msg.action &&
30
30
  msg.type === ClusterCacheType &&
31
- msg.fromPID !== process.pid,
32
- (msg.action === "set_add" || msg.action === "set" || msg.action === "unset" || msg.action === "set_delete" || msg.action === "array_push") &&
31
+ msg.fromPID !== process.pid &&
32
+ (msg.action === "set_clear" || msg.action === "array_clear" || msg.action === "set_add" || msg.action === "set" || msg.action === "unset" || msg.action === "set_delete" || msg.action === "array_push") &&
33
33
  msg.target === this.name) {
34
34
  this.logger?.debug("remote cluster cache message from [%s] [%s] [%s] [%s]", msg.fromPID, msg.target, msg.action, msg.key);
35
35
  switch (msg.action) {
36
+ case "set_clear": {
37
+ const list = this.localCache.has(msg.key) ? this.localCache.get(msg.key) : new Set<string>();
38
+ if (!(list instanceof Set)) {
39
+ throw new Error("cannot apply clear on non set");
40
+ }
41
+ list.clear();
42
+ this.localCache.set(msg.key, list);
43
+ break;
44
+ }
45
+ case "array_clear": {
46
+ //this.localCache.set(msg.key, msg.value);
47
+ const list = this.localCache.has(msg.key) ? this.localCache.get(msg.key) : [];
48
+ if (!(list instanceof Array)) {
49
+ throw new Error("cannot apply clear on non array");
50
+ }
51
+ this.localCache.set(msg.key, []);
52
+ break;
53
+ }
36
54
  case "unset":
37
55
  this.localCache.delete(msg.key);
38
56
  break;
@@ -43,7 +61,7 @@ export class ClusterCache implements CacheInterface {
43
61
  //this.localCache.set(msg.key, msg.value);
44
62
  const list = this.localCache.has(msg.key) ? this.localCache.get(msg.key) : new Set<string>();
45
63
  if (!(list instanceof Set)) {
46
- throw new Error("cannot apply push on non array");
64
+ throw new Error("cannot apply add on non set");
47
65
  }
48
66
  if (!list.has(msg.value)) {
49
67
  list.add(msg.value);
@@ -55,7 +73,7 @@ export class ClusterCache implements CacheInterface {
55
73
  //this.localCache.set(msg.key, msg.value);
56
74
  const list = this.localCache.has(msg.key) ? this.localCache.get(msg.key) : new Set<string>();
57
75
  if (!(list instanceof Set)) {
58
- throw new Error("cannot apply push on non array");
76
+ throw new Error("cannot apply delete on non set");
59
77
  }
60
78
  if (list.has(msg.value)) {
61
79
  list.delete(msg.value);
@@ -100,33 +118,25 @@ export class ClusterCache implements CacheInterface {
100
118
  set(key: string, value: unknown): void {
101
119
  this.localCache.set(key, value);
102
120
  this.logger?.trace("set(%s, ...)", key);
103
- if (process.send) {
104
- setTimeout(() => {
105
- process.send({
106
- type: ClusterCacheType,
107
- action: "set",
108
- target: this.name,
109
- fromPID: process.pid,
110
- key,
111
- value
112
- } as ClusterCacheMessage);
113
- }, 10);
114
- }
121
+ sendTimeout({
122
+ type: ClusterCacheType,
123
+ action: "set",
124
+ target: this.name,
125
+ fromPID: process.pid,
126
+ key,
127
+ value
128
+ } as ClusterCacheMessage);
115
129
  }
116
130
  unset(key: string): void {
117
131
  this.logger?.trace("unset(%s)", key);
118
132
  this.localCache.delete(key);
119
- if (process.send) {
120
- setTimeout(() => {
121
- process.send({
122
- type: ClusterCacheType,
123
- target: this.name,
124
- action: "unset",
125
- fromPID: process.pid,
126
- key
127
- } as ClusterCacheMessage);
128
- }, 10);
129
- }
133
+ sendTimeout({
134
+ type: ClusterCacheType,
135
+ target: this.name,
136
+ action: "unset",
137
+ fromPID: process.pid,
138
+ key
139
+ } as ClusterCacheMessage);
130
140
  }
131
141
  has(key: string): boolean {
132
142
  this.logger?.trace("has(%s)", key);
@@ -143,19 +153,14 @@ export class ClusterCache implements CacheInterface {
143
153
  list.add(value);
144
154
  }
145
155
  this.localCache.set(key, list);
146
-
147
- if (process.send) {
148
- setTimeout(() => {
149
- process.send({
150
- type: ClusterCacheType,
151
- target: this.name,
152
- action: "set_add",
153
- fromPID: process.pid,
154
- key,
155
- value
156
- } as ClusterCacheMessage);
157
- }, 10);
158
- }
156
+ sendTimeout({
157
+ type: ClusterCacheType,
158
+ target: this.name,
159
+ action: "set_add",
160
+ fromPID: process.pid,
161
+ key,
162
+ value
163
+ } as ClusterCacheMessage);
159
164
  }
160
165
  set_delete(key: string, value: unknown): void {
161
166
  this.logger?.trace("delete(%s)", key);
@@ -167,18 +172,14 @@ export class ClusterCache implements CacheInterface {
167
172
  list.delete(value);
168
173
  }
169
174
  this.localCache.set(key, list);
170
- if (process.send) {
171
- setTimeout(() => {
172
- process.send({
173
- type: ClusterCacheType,
174
- target: this.name,
175
- action: "set_delete",
176
- fromPID: process.pid,
177
- key,
178
- value
179
- } as ClusterCacheMessage);
180
- }, 10);
181
- }
175
+ sendTimeout({
176
+ type: ClusterCacheType,
177
+ target: this.name,
178
+ action: "set_delete",
179
+ fromPID: process.pid,
180
+ key,
181
+ value
182
+ } as ClusterCacheMessage);
182
183
  }
183
184
  set_has(key: string, value: unknown): boolean {
184
185
  this.logger?.trace("set_has(%s)", key);
@@ -198,6 +199,13 @@ export class ClusterCache implements CacheInterface {
198
199
  }
199
200
  list.clear();
200
201
  this.localCache.set(key, list);
202
+ sendTimeout({
203
+ type: ClusterCacheType,
204
+ target: this.name,
205
+ action: "set_clear",
206
+ fromPID: process.pid,
207
+ key
208
+ } as ClusterCacheMessage);
201
209
  }
202
210
  array_push(key: string, value: unknown): void {
203
211
  this.logger?.trace("array_push(%s)", key);
@@ -207,18 +215,14 @@ export class ClusterCache implements CacheInterface {
207
215
  }
208
216
  list.push(value);
209
217
  this.localCache.set(key, list);
210
- if (process.send) {
211
- setTimeout(() => {
212
- process.send({
213
- type: ClusterCacheType,
214
- target: this.name,
215
- action: "array_push",
216
- fromPID: process.pid,
217
- key,
218
- value
219
- } as ClusterCacheMessage);
220
- }, 10);
221
- }
218
+ sendTimeout({
219
+ type: ClusterCacheType,
220
+ target: this.name,
221
+ action: "array_push",
222
+ fromPID: process.pid,
223
+ key,
224
+ value
225
+ } as ClusterCacheMessage);
222
226
  }
223
227
  array_clear(key: string): void {
224
228
  this.logger?.trace("array_clear(%s)", key);
@@ -226,5 +230,26 @@ export class ClusterCache implements CacheInterface {
226
230
  throw new Error("cannot apply on non Array");
227
231
  }
228
232
  this.localCache.set(key, []);
233
+ sendTimeout({
234
+ type: ClusterCacheType,
235
+ target: this.name,
236
+ action: "array_clear",
237
+ fromPID: process.pid,
238
+ key
239
+ } as ClusterCacheMessage);
229
240
  }
230
241
  }
242
+
243
+ function sendTimeout(msg: ClusterCacheMessage) {
244
+ if (process.send) {
245
+ setTimeout(() => {
246
+ try {
247
+ if (process.send) {
248
+ process.send(msg);
249
+ }
250
+ } catch (e) {
251
+ console.error(e);
252
+ }
253
+ }, 10);
254
+ }
255
+ }
@@ -58,7 +58,7 @@ export class ClusterWebSocketServer2 extends WebSocketServer {
58
58
  clientUUID: req.uuid
59
59
  } as ClusterWebSocketServer2Message);
60
60
  }
61
- this.logger?.log("[%s] new web socket connection from (%s)", req.uuid, req.req.socket.remoteAddress);
61
+ this.logger?.debug("[%s] new web socket connection from (%s)", req.uuid, req.req.socket.remoteAddress);
62
62
  if (options.onConnection) {
63
63
  options.onConnection(req);
64
64
  }
@@ -73,7 +73,7 @@ export class ClusterWebSocketServer2 extends WebSocketServer {
73
73
  clientUUID: req.uuid
74
74
  } as ClusterWebSocketServer2Message);
75
75
  }
76
- this.logger?.log("[%s] [%s] web socket disconnection from (%s)", req.uuid, this.path, req.req.socket.remoteAddress);
76
+ this.logger?.debug("[%s] [%s] web socket disconnection from (%s)", req.uuid, this.path, req.req.socket.remoteAddress);
77
77
  if (options.onDisconnect) {
78
78
  options.onDisconnect(req);
79
79
  }
@@ -28,7 +28,8 @@ export class WebSocketManager {
28
28
  public deleteWS(path: string) {
29
29
  const ws = this.runningGlobalWSMap.get(path);
30
30
  this.disconnectAllFrom(path);
31
- ws.dispose();
31
+ if (ws)
32
+ ws.dispose();
32
33
  this.runningGlobalWSMap.delete(path);
33
34
  }
34
35