@oneuptime/common 10.0.17 → 10.0.18
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/Server/EnvironmentConfig.ts +1 -47
- package/Server/Infrastructure/Queue.ts +0 -3
- package/Server/Services/ScheduledMaintenanceService.ts +2 -18
- package/Server/Services/StatusPageResourceService.ts +98 -1
- package/Server/Types/Markdown.ts +112 -7
- package/Server/Utils/VM/VMAPI.ts +3 -32
- package/Server/Utils/VM/VMRunner.ts +283 -23
- package/ServiceRoute.ts +0 -4
- package/Tests/Server/Utils/VM/VMAPI.test.ts +2 -17
- package/Types/Monitor/MonitorCriteriaInstance.ts +2 -1
- package/UI/Components/Markdown.tsx/MarkdownViewer.tsx +1 -1
- package/UI/Config.ts +1 -13
- package/build/dist/Server/EnvironmentConfig.js +1 -8
- package/build/dist/Server/EnvironmentConfig.js.map +1 -1
- package/build/dist/Server/Infrastructure/Queue.js +0 -3
- package/build/dist/Server/Infrastructure/Queue.js.map +1 -1
- package/build/dist/Server/Services/ScheduledMaintenanceService.js +2 -16
- package/build/dist/Server/Services/ScheduledMaintenanceService.js.map +1 -1
- package/build/dist/Server/Services/StatusPageResourceService.js +89 -1
- package/build/dist/Server/Services/StatusPageResourceService.js.map +1 -1
- package/build/dist/Server/Types/Markdown.js +88 -7
- package/build/dist/Server/Types/Markdown.js.map +1 -1
- package/build/dist/Server/Utils/VM/VMAPI.js +2 -17
- package/build/dist/Server/Utils/VM/VMAPI.js.map +1 -1
- package/build/dist/Server/Utils/VM/VMRunner.js +215 -16
- package/build/dist/Server/Utils/VM/VMRunner.js.map +1 -1
- package/build/dist/ServiceRoute.js +0 -1
- package/build/dist/ServiceRoute.js.map +1 -1
- package/build/dist/Tests/Server/Utils/VM/VMAPI.test.js +2 -15
- package/build/dist/Tests/Server/Utils/VM/VMAPI.test.js.map +1 -1
- package/build/dist/Types/Monitor/MonitorCriteriaInstance.js +2 -1
- package/build/dist/Types/Monitor/MonitorCriteriaInstance.js.map +1 -1
- package/build/dist/UI/Components/Markdown.tsx/MarkdownViewer.js +1 -1
- package/build/dist/UI/Components/Markdown.tsx/MarkdownViewer.js.map +1 -1
- package/build/dist/UI/Config.js +2 -5
- package/build/dist/UI/Config.js.map +1 -1
- package/package.json +1 -1
|
@@ -175,41 +175,19 @@ export const AppApiHostname: Hostname = Hostname.fromString(
|
|
|
175
175
|
}`,
|
|
176
176
|
);
|
|
177
177
|
|
|
178
|
-
export const ProbeIngestHostname: Hostname = Hostname.fromString(
|
|
179
|
-
`${process.env["SERVER_PROBE_INGEST_HOSTNAME"] || "localhost"}:${
|
|
180
|
-
process.env["PROBE_INGEST_PORT"] || 80
|
|
181
|
-
}`,
|
|
182
|
-
);
|
|
183
|
-
|
|
184
178
|
export const OpenTelemetryIngestHostname: Hostname = Hostname.fromString(
|
|
185
179
|
`${process.env["SERVER_TELEMETRY_HOSTNAME"] || "localhost"}:${
|
|
186
180
|
process.env["TELEMETRY_PORT"] || 80
|
|
187
181
|
}`,
|
|
188
182
|
);
|
|
189
183
|
|
|
190
|
-
export const IncomingRequestIngestHostname: Hostname = Hostname.fromString(
|
|
191
|
-
`${process.env["SERVER_INCOMING_REQUEST_INGEST_HOSTNAME"] || "localhost"}:${
|
|
192
|
-
process.env["INCOMING_REQUEST_INGEST_PORT"] || 80
|
|
193
|
-
}`,
|
|
194
|
-
);
|
|
195
|
-
|
|
196
|
-
export const IsolatedVMHostname: Hostname = Hostname.fromString(
|
|
197
|
-
`${process.env["SERVER_ISOLATED_VM_HOSTNAME"] || "localhost"}:${
|
|
198
|
-
process.env["ISOLATED_VM_PORT"] || 80
|
|
199
|
-
}`,
|
|
200
|
-
);
|
|
201
|
-
|
|
202
184
|
export const WorkerHostname: Hostname = Hostname.fromString(
|
|
203
185
|
`${process.env["SERVER_WORKER_HOSTNAME"] || "localhost"}:${
|
|
204
186
|
process.env["WORKER_PORT"] || 80
|
|
205
187
|
}`,
|
|
206
188
|
);
|
|
207
189
|
|
|
208
|
-
export const WorkflowHostname: Hostname =
|
|
209
|
-
`${process.env["SERVER_WORKFLOW_HOSTNAME"] || "localhost"}:${
|
|
210
|
-
process.env["WORKFLOW_PORT"] || 80
|
|
211
|
-
}`,
|
|
212
|
-
);
|
|
190
|
+
export const WorkflowHostname: Hostname = WorkerHostname;
|
|
213
191
|
|
|
214
192
|
export const HomeHostname: Hostname = Hostname.fromString(
|
|
215
193
|
`${process.env["SERVER_HOME_HOSTNAME"] || "localhost"}:${
|
|
@@ -217,30 +195,6 @@ export const HomeHostname: Hostname = Hostname.fromString(
|
|
|
217
195
|
}`,
|
|
218
196
|
);
|
|
219
197
|
|
|
220
|
-
export const AccountsHostname: Hostname = Hostname.fromString(
|
|
221
|
-
`${process.env["SERVER_ACCOUNTS_HOSTNAME"] || "localhost"}:${
|
|
222
|
-
process.env["ACCOUNTS_PORT"] || 80
|
|
223
|
-
}`,
|
|
224
|
-
);
|
|
225
|
-
|
|
226
|
-
export const DashboardHostname: Hostname = Hostname.fromString(
|
|
227
|
-
`${process.env["SERVER_DASHBOARD_HOSTNAME"] || "localhost"}:${
|
|
228
|
-
process.env["DASHBOARD_PORT"] || 80
|
|
229
|
-
}`,
|
|
230
|
-
);
|
|
231
|
-
|
|
232
|
-
export const AdminDashboardHostname: Hostname = Hostname.fromString(
|
|
233
|
-
`${process.env["SERVER_ADMIN_DASHBOARD_HOSTNAME"] || "localhost"}:${
|
|
234
|
-
process.env["ADMIN_DASHBOARD_PORT"] || 80
|
|
235
|
-
}`,
|
|
236
|
-
);
|
|
237
|
-
|
|
238
|
-
export const DocsHostname: Hostname = Hostname.fromString(
|
|
239
|
-
`${process.env["SERVER_DOCS_HOSTNAME"] || "localhost"}:${
|
|
240
|
-
process.env["DOCS_PORT"] || 80
|
|
241
|
-
}`,
|
|
242
|
-
);
|
|
243
|
-
|
|
244
198
|
export const Env: string = process.env["NODE_ENV"] || "production";
|
|
245
199
|
|
|
246
200
|
// Redis does not require password.
|
|
@@ -14,9 +14,6 @@ export enum QueueName {
|
|
|
14
14
|
Workflow = "Workflow",
|
|
15
15
|
Worker = "Worker",
|
|
16
16
|
Telemetry = "Telemetry",
|
|
17
|
-
IncomingRequestIngest = "IncomingRequestIngest",
|
|
18
|
-
ServerMonitorIngest = "ServerMonitorIngest",
|
|
19
|
-
ProbeIngest = "ProbeIngest",
|
|
20
17
|
}
|
|
21
18
|
|
|
22
19
|
export type QueueJob = Job;
|
|
@@ -97,24 +97,8 @@ export class Service extends DatabaseService<Model> {
|
|
|
97
97
|
let statusPageResources: Array<StatusPageResource> = [];
|
|
98
98
|
|
|
99
99
|
if (event.monitors && event.monitors.length > 0) {
|
|
100
|
-
statusPageResources = await StatusPageResourceService.
|
|
101
|
-
|
|
102
|
-
monitorId: QueryHelper.any(
|
|
103
|
-
event.monitors
|
|
104
|
-
.filter((m: Monitor) => {
|
|
105
|
-
return m._id;
|
|
106
|
-
})
|
|
107
|
-
.map((m: Monitor) => {
|
|
108
|
-
return new ObjectID(m._id!);
|
|
109
|
-
}),
|
|
110
|
-
),
|
|
111
|
-
},
|
|
112
|
-
props: {
|
|
113
|
-
isRoot: true,
|
|
114
|
-
ignoreHooks: true,
|
|
115
|
-
},
|
|
116
|
-
skip: 0,
|
|
117
|
-
limit: LIMIT_PER_PROJECT,
|
|
100
|
+
statusPageResources = await StatusPageResourceService.findByMonitors({
|
|
101
|
+
monitors: event.monitors,
|
|
118
102
|
select: {
|
|
119
103
|
_id: true,
|
|
120
104
|
displayName: true,
|
|
@@ -3,21 +3,118 @@ import DeleteBy from "../Types/Database/DeleteBy";
|
|
|
3
3
|
import { OnCreate, OnDelete, OnUpdate } from "../Types/Database/Hooks";
|
|
4
4
|
import Query from "../Types/Database/Query";
|
|
5
5
|
import QueryHelper from "../Types/Database/QueryHelper";
|
|
6
|
+
import Select from "../Types/Database/Select";
|
|
6
7
|
import UpdateBy from "../Types/Database/UpdateBy";
|
|
7
8
|
import DatabaseService from "./DatabaseService";
|
|
9
|
+
import MonitorGroupResourceService from "./MonitorGroupResourceService";
|
|
8
10
|
import SortOrder from "../../Types/BaseDatabase/SortOrder";
|
|
9
|
-
import LIMIT_MAX from "../../Types/Database/LimitMax";
|
|
11
|
+
import LIMIT_MAX, { LIMIT_PER_PROJECT } from "../../Types/Database/LimitMax";
|
|
10
12
|
import CaptureSpan from "../Utils/Telemetry/CaptureSpan";
|
|
11
13
|
import BadDataException from "../../Types/Exception/BadDataException";
|
|
12
14
|
import ObjectID from "../../Types/ObjectID";
|
|
13
15
|
import PositiveNumber from "../../Types/PositiveNumber";
|
|
14
16
|
import Model from "../../Models/DatabaseModels/StatusPageResource";
|
|
17
|
+
import Monitor from "../../Models/DatabaseModels/Monitor";
|
|
18
|
+
import MonitorGroupResource from "../../Models/DatabaseModels/MonitorGroupResource";
|
|
15
19
|
|
|
16
20
|
export class Service extends DatabaseService<Model> {
|
|
17
21
|
public constructor() {
|
|
18
22
|
super(Model);
|
|
19
23
|
}
|
|
20
24
|
|
|
25
|
+
@CaptureSpan()
|
|
26
|
+
public async findByMonitors(data: {
|
|
27
|
+
monitors?: Array<Monitor>;
|
|
28
|
+
monitorIds?: Array<ObjectID>;
|
|
29
|
+
select: Select<Model>;
|
|
30
|
+
}): Promise<Array<Model>> {
|
|
31
|
+
let resolvedMonitorIds: Array<ObjectID>;
|
|
32
|
+
|
|
33
|
+
if (data.monitorIds && data.monitorIds.length > 0) {
|
|
34
|
+
resolvedMonitorIds = data.monitorIds;
|
|
35
|
+
} else if (data.monitors && data.monitors.length > 0) {
|
|
36
|
+
resolvedMonitorIds = data.monitors
|
|
37
|
+
.filter((m: Monitor) => {
|
|
38
|
+
return m._id;
|
|
39
|
+
})
|
|
40
|
+
.map((m: Monitor) => {
|
|
41
|
+
return new ObjectID(m._id!);
|
|
42
|
+
});
|
|
43
|
+
} else {
|
|
44
|
+
return [];
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
if (resolvedMonitorIds.length === 0) {
|
|
48
|
+
return [];
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// Find status page resources directly linked to monitors
|
|
52
|
+
const statusPageResources: Array<Model> = await this.findBy({
|
|
53
|
+
query: {
|
|
54
|
+
monitorId: QueryHelper.any(resolvedMonitorIds),
|
|
55
|
+
},
|
|
56
|
+
props: {
|
|
57
|
+
isRoot: true,
|
|
58
|
+
ignoreHooks: true,
|
|
59
|
+
},
|
|
60
|
+
skip: 0,
|
|
61
|
+
limit: LIMIT_PER_PROJECT,
|
|
62
|
+
select: data.select,
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
// Find monitor groups that contain the affected monitors
|
|
66
|
+
const monitorGroupResources: Array<MonitorGroupResource> =
|
|
67
|
+
await MonitorGroupResourceService.findBy({
|
|
68
|
+
query: {
|
|
69
|
+
monitorId: QueryHelper.any(resolvedMonitorIds),
|
|
70
|
+
},
|
|
71
|
+
props: {
|
|
72
|
+
isRoot: true,
|
|
73
|
+
ignoreHooks: true,
|
|
74
|
+
},
|
|
75
|
+
select: {
|
|
76
|
+
monitorGroupId: true,
|
|
77
|
+
},
|
|
78
|
+
skip: 0,
|
|
79
|
+
limit: LIMIT_PER_PROJECT,
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
const monitorGroupIds: Array<ObjectID> = monitorGroupResources
|
|
83
|
+
.map((r: MonitorGroupResource) => {
|
|
84
|
+
return r.monitorGroupId!;
|
|
85
|
+
})
|
|
86
|
+
.filter((id: ObjectID) => {
|
|
87
|
+
return Boolean(id);
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
if (monitorGroupIds.length > 0) {
|
|
91
|
+
const groupStatusPageResources: Array<Model> = await this.findBy({
|
|
92
|
+
query: {
|
|
93
|
+
monitorGroupId: QueryHelper.any(monitorGroupIds),
|
|
94
|
+
},
|
|
95
|
+
props: {
|
|
96
|
+
isRoot: true,
|
|
97
|
+
ignoreHooks: true,
|
|
98
|
+
},
|
|
99
|
+
skip: 0,
|
|
100
|
+
limit: LIMIT_PER_PROJECT,
|
|
101
|
+
select: data.select,
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
// Merge and deduplicate
|
|
105
|
+
for (const resource of groupStatusPageResources) {
|
|
106
|
+
const alreadyExists: boolean = statusPageResources.some((r: Model) => {
|
|
107
|
+
return r._id === resource._id;
|
|
108
|
+
});
|
|
109
|
+
if (!alreadyExists) {
|
|
110
|
+
statusPageResources.push(resource);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
return statusPageResources;
|
|
116
|
+
}
|
|
117
|
+
|
|
21
118
|
@CaptureSpan()
|
|
22
119
|
protected override async onBeforeCreate(
|
|
23
120
|
createBy: CreateBy<Model>,
|
package/Server/Types/Markdown.ts
CHANGED
|
@@ -124,6 +124,17 @@ export default class Markdown {
|
|
|
124
124
|
return renderer;
|
|
125
125
|
}
|
|
126
126
|
|
|
127
|
+
private static slugify(text: string): string {
|
|
128
|
+
return text
|
|
129
|
+
.toLowerCase()
|
|
130
|
+
.replace(/<[^>]*>/g, "")
|
|
131
|
+
.replace(/&[^;]+;/g, "")
|
|
132
|
+
.replace(/[^\w\s-]/g, "")
|
|
133
|
+
.replace(/\s+/g, "-")
|
|
134
|
+
.replace(/-+/g, "-")
|
|
135
|
+
.replace(/^-|-$/g, "");
|
|
136
|
+
}
|
|
137
|
+
|
|
127
138
|
private static getDocsRenderer(): Renderer {
|
|
128
139
|
if (this.docsRenderer !== null) {
|
|
129
140
|
return this.docsRenderer;
|
|
@@ -136,6 +147,75 @@ export default class Markdown {
|
|
|
136
147
|
};
|
|
137
148
|
|
|
138
149
|
renderer.blockquote = function (quote) {
|
|
150
|
+
const calloutMatch: RegExpMatchArray | null = quote.match(
|
|
151
|
+
/<p[^>]*>\s*<strong>(Note|Warning|Tip|Danger|Info|Caution):?<\/strong>/i,
|
|
152
|
+
);
|
|
153
|
+
|
|
154
|
+
if (calloutMatch) {
|
|
155
|
+
const type: string = calloutMatch[1]!.toLowerCase();
|
|
156
|
+
const configMap: Record<
|
|
157
|
+
string,
|
|
158
|
+
{ border: string; bg: string; icon: string; label: string }
|
|
159
|
+
> = {
|
|
160
|
+
note: {
|
|
161
|
+
border: "border-blue-400",
|
|
162
|
+
bg: "bg-blue-50",
|
|
163
|
+
icon: `<svg class="h-5 w-5 text-blue-500" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"/></svg>`,
|
|
164
|
+
label: "Note",
|
|
165
|
+
},
|
|
166
|
+
info: {
|
|
167
|
+
border: "border-blue-400",
|
|
168
|
+
bg: "bg-blue-50",
|
|
169
|
+
icon: `<svg class="h-5 w-5 text-blue-500" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"/></svg>`,
|
|
170
|
+
label: "Info",
|
|
171
|
+
},
|
|
172
|
+
tip: {
|
|
173
|
+
border: "border-green-400",
|
|
174
|
+
bg: "bg-green-50",
|
|
175
|
+
icon: `<svg class="h-5 w-5 text-green-500" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9.663 17h4.673M12 3v1m6.364 1.636l-.707.707M21 12h-1M4 12H3m3.343-5.657l-.707-.707m2.828 9.9a5 5 0 117.072 0l-.548.547A3.374 3.374 0 0014 18.469V19a2 2 0 11-4 0v-.531c0-.895-.356-1.754-.988-2.386l-.548-.547z"/></svg>`,
|
|
176
|
+
label: "Tip",
|
|
177
|
+
},
|
|
178
|
+
warning: {
|
|
179
|
+
border: "border-yellow-400",
|
|
180
|
+
bg: "bg-yellow-50",
|
|
181
|
+
icon: `<svg class="h-5 w-5 text-yellow-500" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-2.5L13.732 4c-.77-.833-1.964-.833-2.732 0L4.082 16.5c-.77.833.192 2.5 1.732 2.5z"/></svg>`,
|
|
182
|
+
label: "Warning",
|
|
183
|
+
},
|
|
184
|
+
caution: {
|
|
185
|
+
border: "border-yellow-400",
|
|
186
|
+
bg: "bg-yellow-50",
|
|
187
|
+
icon: `<svg class="h-5 w-5 text-yellow-500" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-2.5L13.732 4c-.77-.833-1.964-.833-2.732 0L4.082 16.5c-.77.833.192 2.5 1.732 2.5z"/></svg>`,
|
|
188
|
+
label: "Caution",
|
|
189
|
+
},
|
|
190
|
+
danger: {
|
|
191
|
+
border: "border-red-400",
|
|
192
|
+
bg: "bg-red-50",
|
|
193
|
+
icon: `<svg class="h-5 w-5 text-red-500" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 8v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"/></svg>`,
|
|
194
|
+
label: "Danger",
|
|
195
|
+
},
|
|
196
|
+
};
|
|
197
|
+
|
|
198
|
+
const config: {
|
|
199
|
+
border: string;
|
|
200
|
+
bg: string;
|
|
201
|
+
icon: string;
|
|
202
|
+
label: string;
|
|
203
|
+
} = configMap[type] || configMap["note"]!;
|
|
204
|
+
|
|
205
|
+
const content: string = quote.replace(
|
|
206
|
+
/<p[^>]*>\s*<strong>(Note|Warning|Tip|Danger|Info|Caution):?<\/strong>\s*/i,
|
|
207
|
+
'<p class="mt-2 mb-2 leading-8 text-gray-600">',
|
|
208
|
+
);
|
|
209
|
+
|
|
210
|
+
return `<div class="callout callout-${type} my-4 rounded-r-lg border-l-4 ${config.border} ${config.bg} p-4">
|
|
211
|
+
<div class="flex items-center gap-2 mb-1">
|
|
212
|
+
${config.icon}
|
|
213
|
+
<span class="text-sm font-semibold text-gray-700">${config.label}</span>
|
|
214
|
+
</div>
|
|
215
|
+
<div class="leading-7 text-gray-600 text-sm">${content}</div>
|
|
216
|
+
</div>`;
|
|
217
|
+
}
|
|
218
|
+
|
|
139
219
|
return `<blockquote class="p-4 pt-1 pb-1 my-4 border-s-4 border-indigo-500">
|
|
140
220
|
<div class="leading-8 text-gray-600">${quote}</div>
|
|
141
221
|
</blockquote>`;
|
|
@@ -147,25 +227,50 @@ export default class Markdown {
|
|
|
147
227
|
|
|
148
228
|
renderer.code = function (code, language) {
|
|
149
229
|
if (language === "mermaid") {
|
|
150
|
-
return `<div class="mermaid">${code}</div>`;
|
|
230
|
+
return `<div class="mermaid-wrapper overflow-x-auto my-6"><div class="mermaid">${code}</div></div>`;
|
|
151
231
|
}
|
|
152
232
|
const escaped: string = Markdown.escapeHtml(code);
|
|
153
233
|
return `<pre><code class="language-${language}">${escaped}</code></pre>`;
|
|
154
234
|
};
|
|
155
235
|
|
|
156
236
|
renderer.heading = function (text, level) {
|
|
237
|
+
const slug: string = Markdown.slugify(text);
|
|
238
|
+
const anchor: string =
|
|
239
|
+
level === 2 || level === 3
|
|
240
|
+
? `<a href="#${slug}" class="anchor-link" aria-hidden="true">#</a>`
|
|
241
|
+
: "";
|
|
242
|
+
|
|
157
243
|
if (level === 1) {
|
|
158
|
-
return `<h1 class="my-5 mt-8 text-4xl font-bold tracking-tight text-gray-800">${text}</h1>`;
|
|
244
|
+
return `<h1 id="${slug}" class="my-5 mt-8 text-4xl font-bold tracking-tight text-gray-800">${text}</h1>`;
|
|
159
245
|
} else if (level === 2) {
|
|
160
|
-
return `<h2 class="my-5
|
|
246
|
+
return `<h2 id="${slug}" class="group my-5 mt-8 text-3xl font-bold tracking-tight text-gray-800">${text} ${anchor}</h2>`;
|
|
161
247
|
} else if (level === 3) {
|
|
162
|
-
return `<h3 class="my-5
|
|
248
|
+
return `<h3 id="${slug}" class="group my-5 mt-8 text-2xl font-bold tracking-tight text-gray-800">${text} ${anchor}</h3>`;
|
|
163
249
|
} else if (level === 4) {
|
|
164
|
-
return `<h4 class="my-5
|
|
250
|
+
return `<h4 id="${slug}" class="my-5 mt-8 text-xl font-bold tracking-tight text-gray-800">${text}</h4>`;
|
|
165
251
|
} else if (level === 5) {
|
|
166
|
-
return `<h5 class="my-5
|
|
252
|
+
return `<h5 id="${slug}" class="my-5 mt-8 text-lg font-bold tracking-tight text-gray-800">${text}</h5>`;
|
|
167
253
|
}
|
|
168
|
-
return `<h6 class="my-5 tracking-tight font-bold text-gray-800">${text}</h6>`;
|
|
254
|
+
return `<h6 id="${slug}" class="my-5 tracking-tight font-bold text-gray-800">${text}</h6>`;
|
|
255
|
+
};
|
|
256
|
+
|
|
257
|
+
renderer.table = function (header, body) {
|
|
258
|
+
return `<div class="docs-table-wrapper overflow-x-auto my-6 rounded-lg border border-slate-200">
|
|
259
|
+
<table class="min-w-full text-sm text-left">${header}${body}</table>
|
|
260
|
+
</div>`;
|
|
261
|
+
};
|
|
262
|
+
|
|
263
|
+
renderer.tablerow = function (content) {
|
|
264
|
+
return `<tr class="border-b border-slate-200 last:border-b-0 hover:bg-slate-50/50 transition-colors">${content}</tr>`;
|
|
265
|
+
};
|
|
266
|
+
|
|
267
|
+
renderer.tablecell = function (content, flags) {
|
|
268
|
+
const tag: string = flags.header ? "th" : "td";
|
|
269
|
+
const align: string = flags.align ? ` text-${flags.align}` : "";
|
|
270
|
+
const headerClass: string = flags.header
|
|
271
|
+
? " font-semibold text-slate-900 bg-slate-50"
|
|
272
|
+
: " text-slate-600";
|
|
273
|
+
return `<${tag} class="px-4 py-2.5${align}${headerClass}">${content}</${tag}>`;
|
|
169
274
|
};
|
|
170
275
|
|
|
171
276
|
// Inline code
|
package/Server/Utils/VM/VMAPI.ts
CHANGED
|
@@ -1,15 +1,8 @@
|
|
|
1
|
-
import { IsolatedVMHostname } from "../../../Server/EnvironmentConfig";
|
|
2
|
-
import ClusterKeyAuthorization from "../../Middleware/ClusterKeyAuthorization";
|
|
3
|
-
import HTTPErrorResponse from "../../../Types/API/HTTPErrorResponse";
|
|
4
|
-
import HTTPResponse from "../../../Types/API/HTTPResponse";
|
|
5
|
-
import Protocol from "../../../Types/API/Protocol";
|
|
6
|
-
import Route from "../../../Types/API/Route";
|
|
7
|
-
import URL from "../../../Types/API/URL";
|
|
8
1
|
import ReturnResult from "../../../Types/IsolatedVM/ReturnResult";
|
|
9
2
|
import { JSONObject, JSONValue } from "../../../Types/JSON";
|
|
10
|
-
import API from "../../../Utils/API";
|
|
11
3
|
import logger from "../Logger";
|
|
12
4
|
import CaptureSpan from "../Telemetry/CaptureSpan";
|
|
5
|
+
import VMRunner from "./VMRunner";
|
|
13
6
|
|
|
14
7
|
export default class VMUtil {
|
|
15
8
|
@CaptureSpan()
|
|
@@ -17,32 +10,10 @@ export default class VMUtil {
|
|
|
17
10
|
code: string;
|
|
18
11
|
options: {
|
|
19
12
|
args?: JSONObject | undefined;
|
|
20
|
-
timeout?: number
|
|
13
|
+
timeout?: number;
|
|
21
14
|
};
|
|
22
15
|
}): Promise<ReturnResult> {
|
|
23
|
-
|
|
24
|
-
| HTTPErrorResponse
|
|
25
|
-
| HTTPResponse<JSONObject> = await API.post<JSONObject>({
|
|
26
|
-
url: new URL(
|
|
27
|
-
Protocol.HTTP,
|
|
28
|
-
IsolatedVMHostname,
|
|
29
|
-
new Route("/isolated-vm/run-code"),
|
|
30
|
-
),
|
|
31
|
-
data: {
|
|
32
|
-
...data,
|
|
33
|
-
},
|
|
34
|
-
headers: {
|
|
35
|
-
...ClusterKeyAuthorization.getClusterKeyHeaders(),
|
|
36
|
-
},
|
|
37
|
-
});
|
|
38
|
-
|
|
39
|
-
if (returnResultHttpResponse instanceof HTTPErrorResponse) {
|
|
40
|
-
throw returnResultHttpResponse;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
const returnResult: ReturnResult = returnResultHttpResponse.data as any;
|
|
44
|
-
|
|
45
|
-
return returnResult;
|
|
16
|
+
return VMRunner.runCodeInSandbox(data);
|
|
46
17
|
}
|
|
47
18
|
|
|
48
19
|
@CaptureSpan()
|