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.
- package/build/editor.bundle.js +3 -3
- package/build/esm/editor/auth.js +2 -1
- package/build/esm/editor/auth.js.map +1 -1
- package/build/esm/editor/http/admin/editor/api/fs/read.api.js +2 -2
- package/build/esm/editor/http/admin/editor/api/fs/read.api.js.map +1 -1
- package/build/esm/editor/ws.js +1 -1
- package/build/esm/editor/ws.js.map +1 -1
- package/build/esm/src/cluster.js +0 -0
- package/build/esm/src/common/esbuild.js +1 -1
- package/build/esm/src/common/esbuild.js.map +1 -1
- package/build/esm/src/inflate/inflate-sea.js +2 -2
- package/build/esm/src/inflate/inflate-sea.js.map +1 -1
- package/build/esm/src/main.js +0 -0
- package/build/esm/src/services/app.js +3 -3
- package/build/esm/src/services/utils/cluster-cache.js +90 -64
- package/build/esm/src/services/utils/cluster-cache.js.map +1 -1
- package/build/esm/src/services/utils/cluster-ws.js +2 -2
- package/build/esm/src/services/utils/cluster-ws.js.map +1 -1
- package/build/esm/src/services/utils/websocketmanager.js +2 -1
- package/build/esm/src/services/utils/websocketmanager.js.map +1 -1
- package/build/lib.cjs +1466 -1222
- package/editor/auth.ts +2 -1
- package/editor/http/admin/editor/api/fs/read.api.tsx +2 -2
- package/editor/ws.ts +1 -1
- package/package.json +8 -8
- package/sea/install-esbuild.sh +1 -1
- package/sea/install-nodejs.sh +1 -1
- package/sea/node.version.tag +1 -1
- package/src/common/esbuild.ts +1 -1
- package/src/inflate/inflate-sea.ts +2 -2
- package/src/services/app.ts +3 -3
- package/src/services/utils/cluster-cache.ts +90 -65
- package/src/services/utils/cluster-ws.ts +2 -2
- 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
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "miqro",
|
|
3
|
-
"version": "7.2.
|
|
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.
|
|
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.
|
|
49
|
-
"@miqro/query": "^0.0.
|
|
50
|
-
"@miqro/runner": "^2.0.
|
|
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.
|
|
53
|
-
"esbuild": "0.
|
|
54
|
-
"jose": "6.1
|
|
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
|
}
|
package/sea/install-esbuild.sh
CHANGED
package/sea/install-nodejs.sh
CHANGED
package/sea/node.version.tag
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
25.
|
|
1
|
+
25.9.0
|
package/src/common/esbuild.ts
CHANGED
|
@@ -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
|
|
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 = {
|
package/src/services/app.ts
CHANGED
|
@@ -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("
|
|
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
|
|
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
|
|
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
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
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
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
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
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
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
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
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
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
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?.
|
|
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?.
|
|
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
|
}
|