miqro 6.1.1 → 6.1.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.
- package/build/esm/editor/auth.d.ts +6 -0
- package/build/esm/editor/auth.js +41 -0
- package/build/esm/editor/common/admin-interface.d.ts +36 -0
- package/build/esm/editor/common/admin-interface.js +44 -0
- package/build/esm/editor/common/constants.d.ts +4 -0
- package/build/esm/editor/common/constants.js +20 -0
- package/build/esm/editor/common/constants.server.d.ts +2 -0
- package/build/esm/editor/common/constants.server.js +4 -0
- package/build/esm/editor/common/editor-index.d.ts +2 -0
- package/build/esm/editor/common/editor-index.js +14 -0
- package/build/esm/editor/common/html-encode.d.ts +1 -0
- package/build/esm/editor/common/html-encode.js +14 -0
- package/build/esm/editor/common/log-socket.d.ts +15 -0
- package/build/esm/editor/common/log-socket.js +70 -0
- package/build/esm/editor/common/templates.d.ts +11 -0
- package/build/esm/editor/common/templates.js +461 -0
- package/build/esm/editor/components/api-preview.d.ts +11 -0
- package/build/esm/editor/components/api-preview.js +90 -0
- package/build/esm/editor/components/editor.d.ts +16 -0
- package/build/esm/editor/components/editor.js +357 -0
- package/build/esm/editor/components/file-browser.d.ts +37 -0
- package/build/esm/editor/components/file-browser.js +126 -0
- package/build/esm/editor/components/file-editor-toolbar.d.ts +22 -0
- package/build/esm/editor/components/file-editor-toolbar.js +93 -0
- package/build/esm/editor/components/file-editor.d.ts +32 -0
- package/build/esm/editor/components/file-editor.js +59 -0
- package/build/esm/editor/components/filter-query.d.ts +1 -0
- package/build/esm/editor/components/filter-query.js +22 -0
- package/build/esm/editor/components/highlight-text-area.d.ts +11 -0
- package/build/esm/editor/components/highlight-text-area.js +124 -0
- package/build/esm/editor/components/log-viewer.d.ts +6 -0
- package/build/esm/editor/components/log-viewer.js +69 -0
- package/build/esm/editor/components/new-file.d.ts +10 -0
- package/build/esm/editor/components/new-file.js +117 -0
- package/build/esm/editor/components/scroll-query.d.ts +7 -0
- package/build/esm/editor/components/scroll-query.js +21 -0
- package/build/esm/editor/components/start-page.d.ts +13 -0
- package/build/esm/editor/components/start-page.js +30 -0
- package/build/esm/editor/http/admin/editor/api/fs/delete.api.d.ts +3 -0
- package/build/esm/editor/http/admin/editor/api/fs/delete.api.js +29 -0
- package/build/esm/editor/http/admin/editor/api/fs/read.api.d.ts +5 -0
- package/build/esm/editor/http/admin/editor/api/fs/read.api.js +49 -0
- package/build/esm/editor/http/admin/editor/api/fs/rename.api.d.ts +4 -0
- package/build/esm/editor/http/admin/editor/api/fs/rename.api.js +39 -0
- package/build/esm/editor/http/admin/editor/api/fs/scan.api.d.ts +26 -0
- package/build/esm/editor/http/admin/editor/api/fs/scan.api.js +149 -0
- package/build/esm/editor/http/admin/editor/api/fs/write.api.d.ts +3 -0
- package/build/esm/editor/http/admin/editor/api/fs/write.api.js +38 -0
- package/build/esm/editor/http/admin/editor/api/server/reload.api.d.ts +10 -0
- package/build/esm/editor/http/admin/editor/api/server/reload.api.js +46 -0
- package/build/esm/editor/http/admin/editor/api/server/restart.api.d.ts +10 -0
- package/build/esm/editor/http/admin/editor/api/server/restart.api.js +45 -0
- package/build/esm/editor/http/admin/editor/editor.d.ts +1 -0
- package/build/esm/editor/http/admin/editor/editor.js +7 -0
- package/build/esm/editor/http/admin/editor/index.api.d.ts +3 -0
- package/build/esm/editor/http/admin/editor/index.api.js +21 -0
- package/build/esm/editor/server.d.ts +3 -0
- package/build/esm/editor/server.js +49 -0
- package/build/esm/editor/ws.d.ts +3 -0
- package/build/esm/editor/ws.js +11 -0
- package/build/esm/src/bin/compile.d.ts +3 -0
- package/build/esm/src/bin/compile.js +30 -0
- package/build/esm/src/bin/doc-md.d.ts +17 -0
- package/build/esm/src/bin/doc-md.js +186 -0
- package/build/esm/src/bin/generate-doc.d.ts +6 -0
- package/build/esm/src/bin/generate-doc.js +53 -0
- package/build/esm/src/bin/test.d.ts +3 -0
- package/build/esm/src/bin/test.js +67 -0
- package/build/esm/src/bin/types.d.ts +3 -0
- package/build/esm/src/bin/types.js +20 -0
- package/editor/auth.ts +51 -0
- package/editor/common/admin-interface.ts +84 -0
- package/editor/common/constants.server.ts +5 -0
- package/editor/common/constants.ts +21 -0
- package/editor/common/editor-index.tsx +17 -0
- package/editor/common/html-encode.ts +14 -0
- package/editor/common/log-socket.tsx +85 -0
- package/editor/common/templates.ts +466 -0
- package/editor/components/api-preview.tsx +116 -0
- package/editor/components/editor.tsx +486 -0
- package/editor/components/file-browser.tsx +308 -0
- package/editor/components/file-editor-toolbar.tsx +191 -0
- package/editor/components/file-editor.tsx +122 -0
- package/editor/components/filter-query.tsx +22 -0
- package/editor/components/highlight-text-area.tsx +144 -0
- package/editor/components/log-viewer.tsx +110 -0
- package/editor/components/new-file.tsx +169 -0
- package/editor/components/scroll-query.tsx +22 -0
- package/editor/components/start-page.tsx +49 -0
- package/editor/http/admin/editor/api/fs/delete.api.tsx +32 -0
- package/editor/http/admin/editor/api/fs/read.api.tsx +55 -0
- package/editor/http/admin/editor/api/fs/rename.api.tsx +41 -0
- package/editor/http/admin/editor/api/fs/scan.api.tsx +181 -0
- package/editor/http/admin/editor/api/fs/write.api.tsx +41 -0
- package/editor/http/admin/editor/api/server/reload.api.ts +53 -0
- package/editor/http/admin/editor/api/server/restart.api.tsx +52 -0
- package/editor/http/admin/editor/editor.tsx +8 -0
- package/editor/http/admin/editor/index.api.tsx +39 -0
- package/editor/server.ts +57 -0
- package/editor/ws.ts +15 -0
- package/package.json +1 -1
- package/src/bin/compile.ts +35 -0
- package/src/bin/doc-md.ts +210 -0
- package/src/bin/generate-doc.ts +64 -0
- package/src/bin/test.ts +92 -0
- package/src/bin/types.ts +22 -0
- package/src/cluster.ts +27 -0
- package/src/common/arguments.ts +503 -0
- package/src/common/assets.ts +128 -0
- package/src/common/checksum.ts +58 -0
- package/src/common/constants.ts +18 -0
- package/src/common/content-type.ts +84 -0
- package/src/common/esbuild.ts +94 -0
- package/src/common/exit.ts +91 -0
- package/src/common/fs.ts +17 -0
- package/src/common/help.ts +51 -0
- package/src/common/jsx.ts +512 -0
- package/src/common/paths.ts +158 -0
- package/src/common/watch.ts +85 -0
- package/src/inflate/inflate-sea.ts +206 -0
- package/src/inflate/inflate.ts +99 -0
- package/src/inflate/md.ts +25 -0
- package/src/inflate/setup-auth.ts +40 -0
- package/src/inflate/setup-cors.ts +40 -0
- package/src/inflate/setup-db.ts +113 -0
- package/src/inflate/setup-error.ts +43 -0
- package/src/inflate/setup-http.ts +655 -0
- package/src/inflate/setup-log.ts +44 -0
- package/src/inflate/setup-middleware.ts +46 -0
- package/src/inflate/setup-server-config.ts +47 -0
- package/src/inflate/setup-test.ts +23 -0
- package/src/inflate/setup-ws.ts +48 -0
- package/src/inflate/setup.doc.ts +68 -0
- package/src/inflate/utils/sea-utils.ts +14 -0
- package/src/lib.ts +19 -0
- package/src/main.ts +87 -0
- package/src/services/app.ts +658 -0
- package/src/services/editor.tsx +101 -0
- package/src/services/globals.ts +143 -0
- package/src/services/hot-reload.ts +48 -0
- package/src/services/migrations.ts +66 -0
- package/src/services/utils/admin-interface.ts +37 -0
- package/src/services/utils/cache.ts +88 -0
- package/src/services/utils/cluster-cache.ts +230 -0
- package/src/services/utils/cluster-ws.ts +197 -0
- package/src/services/utils/db-manager.ts +92 -0
- package/src/services/utils/get-route.ts +70 -0
- package/src/services/utils/log-transport.ts +75 -0
- package/src/services/utils/log.ts +92 -0
- package/src/services/utils/server-interface.ts +172 -0
- package/src/services/utils/websocketmanager.ts +149 -0
- package/src/types/@esbuild.d.ts +1 -0
- package/src/types/@miqro/core.d.ts +2 -0
- package/src/types/@miqro/jsx.d.ts +2 -0
- package/src/types/@miqro/parser.d.ts +2 -0
- package/src/types/@miqro/query.d.ts +2 -0
- package/src/types/@miqro/request.d.ts +2 -0
- package/src/types/@miqro/test.d.ts +2 -0
- package/src/types/@miqro.d.ts +1 -0
- package/src/types/@types.d.ts +1 -0
- package/src/types/browser.globals.d.ts +9 -0
- package/src/types/globals.d.ts +2 -0
- package/src/types/jsx.globals.d.ts +37 -0
- package/src/types/miqro.d.ts +129 -0
- package/src/types/postject.d.ts +1 -0
- package/src/types/server.globals.d.ts +72 -0
- package/src/types.ts +222 -0
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
/*interface SchemaProperties {
|
|
2
|
+
[key: string]: Schema | string;
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
type ParserMode = "add_extra" | "no_extra" | "remove_extra"*/
|
|
6
|
+
export async function getMDDoc(args, logger) {
|
|
7
|
+
const pathList = Object.keys(args.jsonDoc).sort();
|
|
8
|
+
let outMD = "";
|
|
9
|
+
const tableIndexItems = [];
|
|
10
|
+
for (const path of pathList) {
|
|
11
|
+
const pathData = args.jsonDoc[path];
|
|
12
|
+
const methods = Object.keys(pathData);
|
|
13
|
+
for (const method of methods) {
|
|
14
|
+
if (method) {
|
|
15
|
+
const apiDataList = pathData[method];
|
|
16
|
+
for (const apiData of apiDataList) {
|
|
17
|
+
tableIndexItems.push({
|
|
18
|
+
apiData
|
|
19
|
+
});
|
|
20
|
+
outMD += `## ${apiData.identifier /*.replaceAll("_", "-")*/}\n\n`;
|
|
21
|
+
outMD += `${args.showFilePath && apiData.___filePath ? apiData.___filePath + "\n\n" : ""}`;
|
|
22
|
+
if (apiData.name) {
|
|
23
|
+
outMD += `${apiData.name}\n\n`;
|
|
24
|
+
}
|
|
25
|
+
if (apiData.description) {
|
|
26
|
+
outMD += `${apiData.description}\n\n`;
|
|
27
|
+
}
|
|
28
|
+
outMD += `[${method}] ${path}\n\n`;
|
|
29
|
+
outMD += `[${path}](${path}) \n\n`;
|
|
30
|
+
if (apiData.policy) {
|
|
31
|
+
outMD += `### policy\n\n`;
|
|
32
|
+
outMD += policyToString(apiData.policy);
|
|
33
|
+
}
|
|
34
|
+
if (apiData.request) {
|
|
35
|
+
const requestOutMD = parserToString(apiData.request);
|
|
36
|
+
outMD += requestOutMD !== "" ? `### request\n\n${requestOutMD}` : "";
|
|
37
|
+
}
|
|
38
|
+
if (apiData.response && typeof apiData.response !== "boolean") {
|
|
39
|
+
const responseOutMD = parserToString(apiData.response);
|
|
40
|
+
outMD += responseOutMD !== "" ? `### response\n\n${responseOutMD}` : "";
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
const indexTable = getIndexTable(tableIndexItems);
|
|
47
|
+
return `${indexTable}\n\n${outMD}`;
|
|
48
|
+
}
|
|
49
|
+
function getIndexTable(data) {
|
|
50
|
+
return `${data.map(api => `[${api.apiData.identifier /*.replaceAll("_", "-")*/}](#${api.apiData.identifier /*.replaceAll("_", "-")*/.toLocaleLowerCase()})${api.apiData.name || api.apiData.description ? `\n\n\t${api.apiData.name ? api.apiData.name + " " : ""}${api.apiData.description ? api.apiData.description : ""}` : ""}`).join("\n\n")}`;
|
|
51
|
+
}
|
|
52
|
+
function policyToString(policy) {
|
|
53
|
+
let outMD = "| groups | policy |\n";
|
|
54
|
+
outMD += "|--------|--------|\n";
|
|
55
|
+
outMD += `| ${(policy.groups instanceof Array ? policy.groups : [policy.groups]).join(",")} | ${policy.groupPolicy} |\n\n`;
|
|
56
|
+
return outMD;
|
|
57
|
+
}
|
|
58
|
+
export function parserToString(parser) {
|
|
59
|
+
let outMD = "";
|
|
60
|
+
if (parser.status) {
|
|
61
|
+
outMD += `#### status\n\n${parser.status instanceof Array ? parser.status.join(",") : parser.status}\n\n`;
|
|
62
|
+
}
|
|
63
|
+
if (parser.params && typeof parser.params !== "boolean") {
|
|
64
|
+
outMD += `#### path params\n\n`;
|
|
65
|
+
outMD += parserPartToString(parser.params, parser.paramsMode);
|
|
66
|
+
}
|
|
67
|
+
if (parser.headers) {
|
|
68
|
+
outMD += `#### headers\n\n`;
|
|
69
|
+
outMD += parserPartToString(parser.headers, parser.headersMode);
|
|
70
|
+
}
|
|
71
|
+
if (parser.query && parser.query !== true) {
|
|
72
|
+
outMD += `#### query\n\n`;
|
|
73
|
+
outMD += parserPartToString(parser.query, parser.queryMode);
|
|
74
|
+
}
|
|
75
|
+
if (parser.body && parser.body !== true) {
|
|
76
|
+
outMD += `#### body\n\n`;
|
|
77
|
+
outMD += parserPartToString(parser.body, parser.bodyMode);
|
|
78
|
+
}
|
|
79
|
+
return outMD;
|
|
80
|
+
}
|
|
81
|
+
function parserPartToString(arg, mode) {
|
|
82
|
+
if (arg === false) {
|
|
83
|
+
return "not allowed";
|
|
84
|
+
}
|
|
85
|
+
let outMD = "";
|
|
86
|
+
let maxTabulation = 1;
|
|
87
|
+
const parsers = arg instanceof Array ? arg : typeof arg === "string" ? [arg] : [arg];
|
|
88
|
+
for (const parser of parsers) {
|
|
89
|
+
const ret = internalParserToString(parser);
|
|
90
|
+
if (ret.maxTabulation > maxTabulation) {
|
|
91
|
+
maxTabulation = ret.maxTabulation;
|
|
92
|
+
}
|
|
93
|
+
outMD += `| | | | ${getTabulation(ret.maxTabulation * 2)}\n`;
|
|
94
|
+
outMD += `|--------|-------|-------|${getTabulation(ret.maxTabulation * 2, true)}\n`;
|
|
95
|
+
outMD += `${ret.out}\n\n`;
|
|
96
|
+
}
|
|
97
|
+
return outMD;
|
|
98
|
+
}
|
|
99
|
+
function internalParserToString(parser, tabulation = 1) {
|
|
100
|
+
let outMD = "";
|
|
101
|
+
let maxTabulation = tabulation;
|
|
102
|
+
if (typeof parser === "string") {
|
|
103
|
+
outMD += `${getTabulation(tabulation)}${parser}|\n`;
|
|
104
|
+
}
|
|
105
|
+
else {
|
|
106
|
+
const attrNames = Object.keys(parser);
|
|
107
|
+
for (const name of attrNames) {
|
|
108
|
+
const p = parser[name];
|
|
109
|
+
const description = typeof p === "string" ? "" : p.description ? p.description : "";
|
|
110
|
+
if (typeof p === "string") {
|
|
111
|
+
outMD += `${getTabulation(tabulation)}${name} | ${p}|\n`;
|
|
112
|
+
}
|
|
113
|
+
else if (p.type.toLocaleLowerCase() === "object" || p.type.toLocaleLowerCase() === "object?") {
|
|
114
|
+
const rString = p.required === false || p.type.toLocaleLowerCase() === "object?" ? "?" : "";
|
|
115
|
+
outMD += `${getTabulation(tabulation)}${name} | object${rString}| ${description}|\n`;
|
|
116
|
+
const ret = parserBaseObjectTypeToString(p, tabulation + 1);
|
|
117
|
+
if (maxTabulation < ret.maxTabulation) {
|
|
118
|
+
maxTabulation = ret.maxTabulation;
|
|
119
|
+
}
|
|
120
|
+
outMD += `${ret.out}`;
|
|
121
|
+
}
|
|
122
|
+
else if (p.type.toLocaleLowerCase() === "dict" || p.type.toLocaleLowerCase() === "dict?") {
|
|
123
|
+
const rString = p.required === false || p.type.toLocaleLowerCase() === "dict?" ? "?" : "";
|
|
124
|
+
outMD += `${getTabulation(tabulation)}${name} | Dict\\<${p.dictType}\>${rString}| ${description}|\n`;
|
|
125
|
+
if (p.dictType === "object") {
|
|
126
|
+
const ret = parserBaseObjectTypeToString(p, tabulation + 1);
|
|
127
|
+
if (maxTabulation < ret.maxTabulation) {
|
|
128
|
+
maxTabulation = ret.maxTabulation;
|
|
129
|
+
}
|
|
130
|
+
outMD += `${ret.out}`;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
else if (p.type.toLocaleLowerCase() === "array" || p.type.toLocaleLowerCase() === "array?") {
|
|
134
|
+
const rString = p.required === false || p.type.toLocaleLowerCase() === "array?" ? "?" : "";
|
|
135
|
+
outMD += `${getTabulation(tabulation)}${name} | Array\\<${p.arrayType}\>${rString}| ${description}|\n`;
|
|
136
|
+
if (p.arrayType.toLocaleLowerCase() === "object") {
|
|
137
|
+
const ret = parserBaseObjectTypeToString(p, tabulation + 1);
|
|
138
|
+
if (maxTabulation < ret.maxTabulation) {
|
|
139
|
+
maxTabulation = ret.maxTabulation;
|
|
140
|
+
}
|
|
141
|
+
outMD += `${ret.out}`;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
else if (p.type.toLocaleLowerCase() === "regex") {
|
|
145
|
+
outMD += `${getTabulation(tabulation)}${name} | ${p.regex}| ${description}|\n`;
|
|
146
|
+
}
|
|
147
|
+
else if (p.type.toLocaleLowerCase() === "regex?") {
|
|
148
|
+
outMD += `${getTabulation(tabulation)}${name} | ${p.regex}?| ${description}|\n`;
|
|
149
|
+
}
|
|
150
|
+
else if (p.type.toLocaleLowerCase() === "enum") {
|
|
151
|
+
outMD += `${getTabulation(tabulation)}${name} | ${p.type}| ${description}|\n`;
|
|
152
|
+
outMD += `${getTabulation(tabulation + 1)}| ${p.enumValues?.join(",")}|\n`;
|
|
153
|
+
if (maxTabulation < tabulation + 1) {
|
|
154
|
+
maxTabulation = tabulation + 1;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
else if (p.type.toLocaleLowerCase() === "enum?") {
|
|
158
|
+
outMD += `${getTabulation(tabulation)}${name} | ${p.type}?| ${description}|\n`;
|
|
159
|
+
outMD += `${getTabulation(tabulation + 1)}| ${p.enumValues?.join(",")}|\n`;
|
|
160
|
+
if (maxTabulation < tabulation + 1) {
|
|
161
|
+
maxTabulation = tabulation + 1;
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
else {
|
|
165
|
+
const rString = p.required === false ? "?" : "";
|
|
166
|
+
outMD += `${getTabulation(tabulation)}${name} | ${p.type}${rString}| ${description}|\n`;
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
return {
|
|
171
|
+
out: outMD,
|
|
172
|
+
maxTabulation
|
|
173
|
+
};
|
|
174
|
+
}
|
|
175
|
+
function parserBaseObjectTypeToString(arg, tabulation) {
|
|
176
|
+
const options = arg.properties ? arg.properties : {};
|
|
177
|
+
//const outMD = `${getTabulation(tabulation)}name | type |\n${getTabulation(tabulation)}--------|--------|\n`;
|
|
178
|
+
return internalParserToString(options, tabulation + 1);
|
|
179
|
+
}
|
|
180
|
+
function getTabulation(n, header = false) {
|
|
181
|
+
let out = "";
|
|
182
|
+
for (let i = 0; i < n; i++) {
|
|
183
|
+
out += header ? "-|" : "| ";
|
|
184
|
+
}
|
|
185
|
+
return out;
|
|
186
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { Logger, Router } from "@miqro/core";
|
|
2
|
+
import { Arguments } from "../common/arguments.js";
|
|
3
|
+
import { InflatedResult } from "../services/app.js";
|
|
4
|
+
import { RouteFileMap } from "../inflate/setup-http.js";
|
|
5
|
+
export declare function generateDocs(args: Arguments, logger: Logger, result: InflatedResult): Promise<void>;
|
|
6
|
+
export declare function getDocOutput(router: Router, fileMap: RouteFileMap, generateDocAll: boolean, generateDocType: "MD" | "JSON" | "HTML"): Promise<string>;
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { writeFileSync } from "node:fs";
|
|
2
|
+
import { getMDDoc } from "./doc-md.js";
|
|
3
|
+
import { EXIT_CODES } from "../common/constants.js";
|
|
4
|
+
import { inflateMDString2HTML } from "../inflate/md.js";
|
|
5
|
+
export async function generateDocs(args, logger, result) {
|
|
6
|
+
logger.info("writing [%s]", args.generateDocOut);
|
|
7
|
+
writeFileSync(args.generateDocOut, await getDocOutput(result.router, result.fileMap, args.generateDocAll, args.generateDocType));
|
|
8
|
+
}
|
|
9
|
+
export async function getDocOutput(router, fileMap, generateDocAll, generateDocType) {
|
|
10
|
+
/*
|
|
11
|
+
** TODO FIX THIS MESS
|
|
12
|
+
*/
|
|
13
|
+
const fileMapAPIRouteList = Object.keys(fileMap).map(f => fileMap[f]).filter(fMap => fMap.previewMethod === "api").map(fMap => fMap.routes);
|
|
14
|
+
const jsonDoc = router.getJSONDoc();
|
|
15
|
+
if (!generateDocAll) {
|
|
16
|
+
Object.keys(jsonDoc).forEach(path => {
|
|
17
|
+
const methods = Object.keys(jsonDoc[path]);
|
|
18
|
+
methods.forEach(method => {
|
|
19
|
+
const data = jsonDoc[path][method];
|
|
20
|
+
//console.log("[%s] [%s]", path, method);
|
|
21
|
+
if (fileMapAPIRouteList.filter(f => {
|
|
22
|
+
for (const r of f) {
|
|
23
|
+
if (r.method === String(method).toUpperCase() && r.path === path) {
|
|
24
|
+
return true;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
return false;
|
|
28
|
+
}).length === 0) {
|
|
29
|
+
//console.log("DELETE [%s] [%s]", path, method);
|
|
30
|
+
delete jsonDoc[path][method];
|
|
31
|
+
}
|
|
32
|
+
else {
|
|
33
|
+
//console.log("KEEP [%s] [%s]", path, method);
|
|
34
|
+
}
|
|
35
|
+
});
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
switch (generateDocType) {
|
|
39
|
+
case "JSON":
|
|
40
|
+
return JSON.stringify(jsonDoc, undefined, 2);
|
|
41
|
+
break;
|
|
42
|
+
case "MD":
|
|
43
|
+
return await getMDDoc({ showFilePath: true, jsonDoc });
|
|
44
|
+
break;
|
|
45
|
+
case "HTML":
|
|
46
|
+
const md = await getMDDoc({ showFilePath: true, jsonDoc });
|
|
47
|
+
const html = inflateMDString2HTML(md);
|
|
48
|
+
return html;
|
|
49
|
+
break;
|
|
50
|
+
default:
|
|
51
|
+
process.exit(EXIT_CODES.BAD_ARGUMENTS);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { request as reqlRequest } from "@miqro/request";
|
|
3
|
+
import { resetGlobals, runTests } from "@miqro/test/dist/runner/common.js";
|
|
4
|
+
import { getServicePath, TEST_SOCKET } from "../common/paths.js";
|
|
5
|
+
import { createNodeRuntime } from "@miqro/jsx-node";
|
|
6
|
+
import { EXIT_CODES } from "../common/constants.js";
|
|
7
|
+
import { setupTests } from "../inflate/setup-test.js";
|
|
8
|
+
export async function testMain(app) {
|
|
9
|
+
const startMS = Date.now();
|
|
10
|
+
//resetTests();
|
|
11
|
+
resetGlobals();
|
|
12
|
+
//const testLogger = getLogger("test");
|
|
13
|
+
globalThis.test = {
|
|
14
|
+
PORT: TEST_SOCKET,
|
|
15
|
+
request: (request) => reqlRequest({
|
|
16
|
+
...request,
|
|
17
|
+
socketPath: TEST_SOCKET
|
|
18
|
+
}),
|
|
19
|
+
logger: app.logger,
|
|
20
|
+
sleep: async (ms) => new Promise(resolve => setTimeout(resolve, ms)),
|
|
21
|
+
jsx: {
|
|
22
|
+
createRuntime: createNodeRuntime,
|
|
23
|
+
test: (cb, args) => {
|
|
24
|
+
return async () => {
|
|
25
|
+
const runtime = createNodeRuntime(args.runtimeOptions);
|
|
26
|
+
const root = runtime.createElement("root");
|
|
27
|
+
const container = runtime.createContainer(root, args.containerOptions);
|
|
28
|
+
await cb(container, root, runtime);
|
|
29
|
+
container.disconnect();
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
for (const service of app.options.services) {
|
|
35
|
+
const servicePath = getServicePath(service);
|
|
36
|
+
await setupTests(app.logger, servicePath);
|
|
37
|
+
}
|
|
38
|
+
console.log("");
|
|
39
|
+
app.logger.log("===starting tests===");
|
|
40
|
+
console.log("");
|
|
41
|
+
const ret = await runTests(undefined, app.logger);
|
|
42
|
+
console.log("");
|
|
43
|
+
app.logger.log("===tests ended===");
|
|
44
|
+
if (ret.failed.length > 0) {
|
|
45
|
+
console.log("");
|
|
46
|
+
app.logger.error("===failed tests===");
|
|
47
|
+
console.log("");
|
|
48
|
+
}
|
|
49
|
+
const took = Date.now() - startMS;
|
|
50
|
+
ret.failed.forEach(e => {
|
|
51
|
+
app.logger.error("\x1b[31m%s\x1b[0m", e.fullName);
|
|
52
|
+
app.logger.error(e.error);
|
|
53
|
+
});
|
|
54
|
+
console.log("");
|
|
55
|
+
app.logger.log(ret.passed + " tests passed");
|
|
56
|
+
if (ret.failed.length > 0) {
|
|
57
|
+
app.logger.error(ret.failed.length + " failed");
|
|
58
|
+
}
|
|
59
|
+
else {
|
|
60
|
+
app.logger.log(ret.failed.length + " failed");
|
|
61
|
+
}
|
|
62
|
+
app.logger.log("took " + took + "ms");
|
|
63
|
+
if (ret.failed.length > 0) {
|
|
64
|
+
process.exit(EXIT_CODES.TEST_FAILED);
|
|
65
|
+
}
|
|
66
|
+
await app.dbManager.closeAll();
|
|
67
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { initTypes } from "../common/assets.js";
|
|
2
|
+
import { existsSync, writeFileSync } from "node:fs";
|
|
3
|
+
import { TEMPLATES } from "../../editor/common/templates.js";
|
|
4
|
+
import { EXIT_CODES } from "../common/constants.js";
|
|
5
|
+
export async function installTypings(args, logger) {
|
|
6
|
+
if (args.installTypes) {
|
|
7
|
+
logger.debug("writing types");
|
|
8
|
+
// install typing for typescript only if argument --install-types is set
|
|
9
|
+
await initTypes(logger);
|
|
10
|
+
}
|
|
11
|
+
if (args.installTSConfig && !existsSync("tsconfig.json")) {
|
|
12
|
+
logger.info("writing tsconfig.json");
|
|
13
|
+
writeFileSync("tsconfig.json", TEMPLATES["TSCONFIGJSON"].template("", ""));
|
|
14
|
+
}
|
|
15
|
+
else if (args.installTSConfig) {
|
|
16
|
+
logger.error("tsconfig.json already exists!");
|
|
17
|
+
process.exit(EXIT_CODES.ABNORMAL);
|
|
18
|
+
}
|
|
19
|
+
process.exit(EXIT_CODES.NORMAL_EXIT);
|
|
20
|
+
}
|
package/editor/auth.ts
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { AuthConfig, ServerRequest } from "../src/types.js";
|
|
2
|
+
import { AdminRequest } from "./common/admin-interface.js";
|
|
3
|
+
|
|
4
|
+
export const ADMIN_EDITOR_AUTH_KEY = "$$ADMIN_EDITOR_AUTH_KEY$$";
|
|
5
|
+
|
|
6
|
+
export const ADMIN_EDITOR_AUTH_QUERY = "key";
|
|
7
|
+
export const ADMIN_EDITOR_AUTH_COOKIE = ADMIN_EDITOR_AUTH_KEY;
|
|
8
|
+
|
|
9
|
+
export default {
|
|
10
|
+
authService: {
|
|
11
|
+
verify: async (args) => {
|
|
12
|
+
|
|
13
|
+
const adminInterface = (args.req as AdminRequest).editor;
|
|
14
|
+
const serverInterface = (args.req as any as ServerRequest).server;
|
|
15
|
+
const KEY = (adminInterface ? adminInterface.getCache() : serverInterface.cache).get<string>(ADMIN_EDITOR_AUTH_KEY);
|
|
16
|
+
|
|
17
|
+
const validSesson = {
|
|
18
|
+
username: "username",
|
|
19
|
+
account: "account",
|
|
20
|
+
groups: [],
|
|
21
|
+
token: args.token
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
const queryToken = args.req.query[ADMIN_EDITOR_AUTH_QUERY];
|
|
25
|
+
const cookieToken = args.req.cookies[ADMIN_EDITOR_AUTH_COOKIE];
|
|
26
|
+
|
|
27
|
+
//console.log("\n\nqueryToken[%s] cookieToken[%s] KEY[%s]\n\n", queryToken, cookieToken, KEY);
|
|
28
|
+
|
|
29
|
+
if (queryToken) {
|
|
30
|
+
if (queryToken === KEY) {
|
|
31
|
+
args.res.setCookie(ADMIN_EDITOR_AUTH_COOKIE, KEY, {
|
|
32
|
+
expires: new Date(Date.now() + 1000 * 60 * 60 * 24 * 31 * 12 * 500),
|
|
33
|
+
httpOnly: true,
|
|
34
|
+
|
|
35
|
+
//secure: true,
|
|
36
|
+
path: "/",
|
|
37
|
+
//sameSite: "strict"
|
|
38
|
+
});
|
|
39
|
+
args.req.searchParams.delete(ADMIN_EDITOR_AUTH_QUERY);
|
|
40
|
+
const queryString = args.req.searchParams.toString();
|
|
41
|
+
const redirect = args.req.path + (queryString ? "?" + queryString : "");
|
|
42
|
+
await args.res.redirect(redirect);
|
|
43
|
+
return validSesson;
|
|
44
|
+
}
|
|
45
|
+
} else if (cookieToken) {
|
|
46
|
+
return cookieToken === KEY ? validSesson : null;
|
|
47
|
+
}
|
|
48
|
+
return null;
|
|
49
|
+
},
|
|
50
|
+
}
|
|
51
|
+
} as AuthConfig;
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { RouterHandlerOptions } from "@miqro/core";
|
|
2
|
+
import { CacheInterface, ServerRequest } from "../../src/types.js";
|
|
3
|
+
import { MigrationModule } from "../../src/inflate/setup-db.js";
|
|
4
|
+
|
|
5
|
+
export interface EditorAdminInterface {
|
|
6
|
+
getCache: () => CacheInterface;
|
|
7
|
+
//inflateJSX: (path: string, minify?: boolean) => Promise<string>;
|
|
8
|
+
getMigrations(): MigrationModule[];
|
|
9
|
+
stop: () => Promise<void>;
|
|
10
|
+
reload: () => Promise<null | {
|
|
11
|
+
filePath: string;
|
|
12
|
+
error: Error;
|
|
13
|
+
}[]>;
|
|
14
|
+
restart: () => Promise<null | {
|
|
15
|
+
filePath: string;
|
|
16
|
+
error: Error;
|
|
17
|
+
}[]>;
|
|
18
|
+
getHotReloadHTML(): string;
|
|
19
|
+
getInflateErrors(): null | {
|
|
20
|
+
filePath: string;
|
|
21
|
+
error: Error;
|
|
22
|
+
}[];
|
|
23
|
+
getServices(): string[];
|
|
24
|
+
getRouteFileMap(): {
|
|
25
|
+
[filePath: string]: {
|
|
26
|
+
routes: {
|
|
27
|
+
path?: string;
|
|
28
|
+
method?: string | null;
|
|
29
|
+
options?: RouterHandlerOptions;
|
|
30
|
+
inflatePath?: string;
|
|
31
|
+
}[];
|
|
32
|
+
previewMethod: "api" | "html" | null;
|
|
33
|
+
}
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export interface AdminRequest extends ServerRequest {
|
|
38
|
+
editor?: EditorAdminInterface;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/*let currentAdminInterface: EditorAdminInterface | null = null;
|
|
42
|
+
function createFakeAdminInterface(server: any): EditorAdminInterface {
|
|
43
|
+
return {
|
|
44
|
+
getCache: () => {
|
|
45
|
+
return server.cache;
|
|
46
|
+
},
|
|
47
|
+
stop: async () => {
|
|
48
|
+
|
|
49
|
+
},
|
|
50
|
+
restart: async () => {
|
|
51
|
+
return null;
|
|
52
|
+
},
|
|
53
|
+
reload: async () => {
|
|
54
|
+
return null;
|
|
55
|
+
},
|
|
56
|
+
getHotReloadHTML: () => {
|
|
57
|
+
return "";
|
|
58
|
+
},
|
|
59
|
+
getMigrations: () => {
|
|
60
|
+
return [];
|
|
61
|
+
},
|
|
62
|
+
getServices: () => {
|
|
63
|
+
return ["."];
|
|
64
|
+
},
|
|
65
|
+
getRouteFileMap: () => {
|
|
66
|
+
return {};
|
|
67
|
+
},
|
|
68
|
+
getInflateErrors: () => {
|
|
69
|
+
return [];
|
|
70
|
+
},
|
|
71
|
+
inflateJSX: async function inflateJSX(path, minify: boolean = true) {
|
|
72
|
+
return "";
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
export function getEditorAdmin(server): EditorAdminInterface {
|
|
78
|
+
return currentAdminInterface ? currentAdminInterface : createFakeAdminInterface(server);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
export function setEditorAdmin(admin: EditorAdminInterface): void {
|
|
82
|
+
currentAdminInterface = admin;
|
|
83
|
+
}*/
|
|
84
|
+
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export const BASEEDITOR_PATH = "/admin/editor";
|
|
2
|
+
export const LOG_SOCKET_PATH = "/admin/socket";
|
|
3
|
+
export const LOG_WRITE_EVENT = "LogWrite";
|
|
4
|
+
|
|
5
|
+
export const SUPPORTED_LANGUAGES = [
|
|
6
|
+
"text",
|
|
7
|
+
"json",
|
|
8
|
+
"javascript",
|
|
9
|
+
"typescript",
|
|
10
|
+
"dockerfile",
|
|
11
|
+
"yaml",
|
|
12
|
+
"xml",
|
|
13
|
+
"html",
|
|
14
|
+
"css",
|
|
15
|
+
"scss",
|
|
16
|
+
"markdown",
|
|
17
|
+
"c",
|
|
18
|
+
"cpp",
|
|
19
|
+
"bash",
|
|
20
|
+
"python"
|
|
21
|
+
];
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { scanDir } from "../http/admin/editor/api/fs/scan.api.js";
|
|
2
|
+
import { parseInflateErrors } from "../http/admin/editor/api/server/restart.api.js";
|
|
3
|
+
import { AdminRequest } from "./admin-interface.js";
|
|
4
|
+
import { HTMLEncode } from "./html-encode.js";
|
|
5
|
+
|
|
6
|
+
export function EditorIndex(editorCSS: string, editorJS: string, enableHotReload: boolean) {
|
|
7
|
+
return async function editorIndex(req: AdminRequest, res) {
|
|
8
|
+
const admin = req.editor;
|
|
9
|
+
|
|
10
|
+
const errors = parseInflateErrors(admin ? admin.getInflateErrors() : []);
|
|
11
|
+
const files = scanDir(req);
|
|
12
|
+
const migrations = admin ? admin.getMigrations().map(m => m.name) : [];
|
|
13
|
+
const services = admin ? admin.getServices() : ["."];
|
|
14
|
+
const hotReload = enableHotReload ? (admin ? admin.getHotReloadHTML() : "") : "";
|
|
15
|
+
res.html(`<!DOCTYPE html><html><body><style>${editorCSS}</style><script type="module">${editorJS}</script><editor-component class="main-container" reloadstring="${req.uuid}" migrations="${HTMLEncode(JSON.stringify(migrations))}" services="${HTMLEncode(JSON.stringify(services))}" errors="${HTMLEncode(JSON.stringify(errors))}" files="${HTMLEncode(JSON.stringify(files))}"><noscript>Enable JavaScript</noscript></editor-component>${hotReload}</body></html>`)
|
|
16
|
+
}
|
|
17
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export function HTMLEncode(str: string): string {
|
|
2
|
+
let i = str.length;
|
|
3
|
+
const aRet: string[] = [];
|
|
4
|
+
|
|
5
|
+
while (i--) {
|
|
6
|
+
const iC = str[i].charCodeAt(0);
|
|
7
|
+
if (iC < 65 || iC > 127 || (iC > 90 && iC < 97)) {
|
|
8
|
+
aRet[i] = '&#' + iC + ';';
|
|
9
|
+
} else {
|
|
10
|
+
aRet[i] = str[i];
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
return aRet.join('');
|
|
14
|
+
}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
interface LogLine { out: string; identifier: string; level: "error" | "warn" | "debug" | "trace" | "info" }
|
|
2
|
+
|
|
3
|
+
export interface LogSocket {
|
|
4
|
+
lines: LogLine[];
|
|
5
|
+
clearLog: () => void;
|
|
6
|
+
getMaxlogsize: () => number | "unlimited";
|
|
7
|
+
setMaxLogSize: (val: number | "unlimited") => void;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export function useLogSocket(options: { disableLog?: boolean; }): LogSocket {
|
|
11
|
+
|
|
12
|
+
const [_, setmaxLogSize, getMaxlogsize] = jsx.useState<number | "unlimited">(1000000);
|
|
13
|
+
|
|
14
|
+
const [__, setlines, getLines] = jsx.useState<LogLine[]>([]);
|
|
15
|
+
const refresh = jsx.useRefresh();
|
|
16
|
+
|
|
17
|
+
jsx.useEffect(() => {
|
|
18
|
+
|
|
19
|
+
let timeout;
|
|
20
|
+
|
|
21
|
+
function setupSocket() {
|
|
22
|
+
try {
|
|
23
|
+
if (options.disableLog) {
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
console.log("setting up log socket");
|
|
27
|
+
const socket = new WebSocket("/admin/socket");
|
|
28
|
+
socket.addEventListener("error", (err) => {
|
|
29
|
+
console.error(err);
|
|
30
|
+
clearTimeout(timeout);
|
|
31
|
+
timeout = setTimeout(() => {
|
|
32
|
+
setupSocket();
|
|
33
|
+
}, 1000);
|
|
34
|
+
});
|
|
35
|
+
socket.addEventListener("open", () => {
|
|
36
|
+
console.log("log socket open");
|
|
37
|
+
clearTimeout(timeout);
|
|
38
|
+
socket.addEventListener("message", (msg) => {
|
|
39
|
+
const lines = getLines();
|
|
40
|
+
const data = JSON.parse(msg.data);
|
|
41
|
+
//console.log(data.out);
|
|
42
|
+
const maxLogSize = getMaxlogsize();
|
|
43
|
+
if (maxLogSize !== "unlimited" && lines.length >= maxLogSize) {
|
|
44
|
+
lines.splice(0, (lines.length - maxLogSize) + 1);
|
|
45
|
+
}
|
|
46
|
+
lines.push(data);
|
|
47
|
+
setlines(lines);
|
|
48
|
+
refresh();
|
|
49
|
+
});
|
|
50
|
+
});
|
|
51
|
+
socket.addEventListener("close", () => {
|
|
52
|
+
console.log("log socket close");
|
|
53
|
+
clearTimeout(timeout);
|
|
54
|
+
timeout = setTimeout(() => {
|
|
55
|
+
setupSocket();
|
|
56
|
+
}, 1000);
|
|
57
|
+
});
|
|
58
|
+
} catch (e) {
|
|
59
|
+
console.error(e);
|
|
60
|
+
clearTimeout(timeout);
|
|
61
|
+
timeout = setTimeout(() => {
|
|
62
|
+
setupSocket();
|
|
63
|
+
}, 1000);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
setupSocket();
|
|
68
|
+
}, []);
|
|
69
|
+
|
|
70
|
+
return {
|
|
71
|
+
lines: getLines(),
|
|
72
|
+
clearLog: () => {
|
|
73
|
+
setlines([]);
|
|
74
|
+
},
|
|
75
|
+
getMaxlogsize,
|
|
76
|
+
setMaxLogSize: (newValue: number | "unlimited") => {
|
|
77
|
+
if (newValue === "unlimited") {
|
|
78
|
+
setmaxLogSize(newValue);
|
|
79
|
+
} else {
|
|
80
|
+
setmaxLogSize(newValue);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|