@serverkgg/bridge 0.0.8 → 0.0.9
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/package.json +3 -3
- package/src/cli/validate.ts +1 -0
- package/src/context/bridgeContext.ts +10 -0
- package/src/context/index.ts +1 -0
- package/src/core/bridgeDownloadError.ts +10 -0
- package/src/core/bridgeHold.ts +12 -0
- package/src/core/bridgeKind.ts +2 -0
- package/src/core/bridgeUserError.test.ts +23 -0
- package/src/core/bridgeUserError.ts +12 -0
- package/src/core/index.ts +3 -0
- package/src/manifest/index.ts +1 -0
- package/src/manifest/manifest.test.ts +85 -0
- package/src/manifest/manifest.ts +21 -0
- package/src/manifest/presence.ts +48 -0
- package/src/manifest/primitives.ts +6 -0
- package/src/modules/bridge.ts +45 -2
- package/src/modules/bridgeDriver.ts +2 -0
- package/src/modules/bridgeModule.ts +25 -3
- package/src/panel/bridgeDetail.ts +49 -0
- package/src/panel/bridgeLayout.ts +1 -0
- package/src/panel/bridgePanel.ts +30 -0
- package/src/panel/bridgeUploadMode.ts +4 -0
- package/src/panel/index.ts +2 -0
- package/src/protocol/bridgeEgress.ts +8 -1
- package/src/protocol/bridgeEvents.ts +4 -0
- package/src/protocol/bridgeFrame.ts +28 -1
- package/src/protocol/bridgeLimits.ts +10 -0
- package/src/runtime/bridgeActions.ts +7 -0
- package/src/runtime/bridgeDriver.test.ts +477 -2
- package/src/runtime/bridgeDriver.ts +116 -3
- package/src/runtime/bridgeEgress.ts +3 -0
- package/src/runtime/bridgeEvents.ts +7 -5
- package/src/runtime/bridgeFiles.test.ts +625 -15
- package/src/runtime/bridgeFiles.ts +152 -45
- package/src/runtime/bridgeInstall.test.ts +118 -0
- package/src/runtime/bridgeInstall.ts +55 -0
- package/src/runtime/bridgeNet.ts +32 -3
- package/src/runtime/bridgePending.test.ts +148 -0
- package/src/runtime/bridgePending.ts +43 -0
- package/src/runtime/bridgeRegistry.test.ts +134 -0
- package/src/runtime/bridgeRegistry.ts +26 -4
- package/src/runtime/bridgeServer.test.ts +338 -0
- package/src/runtime/bridgeServer.ts +25 -3
- package/src/runtime/bridgeSupervisor.ts +18 -0
- package/src/runtime/bridgeZip.ts +179 -58
- package/src/runtime/serve.ts +64 -4
- package/src/wire/panel.test.ts +166 -0
- package/src/wire/panel.ts +32 -0
package/src/wire/panel.test.ts
CHANGED
|
@@ -8,6 +8,7 @@ import {
|
|
|
8
8
|
BridgeKind,
|
|
9
9
|
BridgeLayout,
|
|
10
10
|
type BridgeManifest,
|
|
11
|
+
BridgeUploadMode,
|
|
11
12
|
} from "@serverkgg/bridge/protocol";
|
|
12
13
|
import { bridgeManifestSchema } from "./panel";
|
|
13
14
|
|
|
@@ -283,3 +284,168 @@ describe("the panel mirror", () => {
|
|
|
283
284
|
).toBe(false);
|
|
284
285
|
});
|
|
285
286
|
});
|
|
287
|
+
|
|
288
|
+
const detailManifest = (): BridgeManifest => ({
|
|
289
|
+
version: "1.0.0",
|
|
290
|
+
panel: {
|
|
291
|
+
tabs: [
|
|
292
|
+
{
|
|
293
|
+
id: "version",
|
|
294
|
+
title: text("Version"),
|
|
295
|
+
sections: [
|
|
296
|
+
{
|
|
297
|
+
layout: BridgeLayout.Form,
|
|
298
|
+
id: "version",
|
|
299
|
+
target: BridgeFormTarget.Variables,
|
|
300
|
+
reinstall: true,
|
|
301
|
+
fields: [
|
|
302
|
+
{
|
|
303
|
+
key: "MC_VERSION",
|
|
304
|
+
control: BridgeControl.Text,
|
|
305
|
+
label: text("Version"),
|
|
306
|
+
},
|
|
307
|
+
],
|
|
308
|
+
clears: [
|
|
309
|
+
{
|
|
310
|
+
variable: "MODPACK",
|
|
311
|
+
warning: text("Applying this removes the modpack"),
|
|
312
|
+
},
|
|
313
|
+
],
|
|
314
|
+
},
|
|
315
|
+
{
|
|
316
|
+
layout: BridgeLayout.Detail,
|
|
317
|
+
id: "modpack-status",
|
|
318
|
+
title: text("Running a modpack"),
|
|
319
|
+
module: "modpackStatus",
|
|
320
|
+
reinstall: true,
|
|
321
|
+
variable: "MODPACK",
|
|
322
|
+
confirm: BridgeConfirm.Strong,
|
|
323
|
+
related: {
|
|
324
|
+
tab: "modpacks",
|
|
325
|
+
label: text("Browse modpacks"),
|
|
326
|
+
},
|
|
327
|
+
actions: [
|
|
328
|
+
{
|
|
329
|
+
id: "update",
|
|
330
|
+
label: text("Update"),
|
|
331
|
+
confirm: BridgeConfirm.Strong,
|
|
332
|
+
},
|
|
333
|
+
],
|
|
334
|
+
},
|
|
335
|
+
],
|
|
336
|
+
},
|
|
337
|
+
],
|
|
338
|
+
},
|
|
339
|
+
terminal: null,
|
|
340
|
+
modules: [
|
|
341
|
+
{
|
|
342
|
+
id: "modpackStatus",
|
|
343
|
+
kind: BridgeKind.Detail,
|
|
344
|
+
requiresRunning: false,
|
|
345
|
+
refreshSeconds: null,
|
|
346
|
+
pageSize: null,
|
|
347
|
+
dependsOn: [],
|
|
348
|
+
actions: [
|
|
349
|
+
BridgeAction.Read,
|
|
350
|
+
"update",
|
|
351
|
+
],
|
|
352
|
+
},
|
|
353
|
+
],
|
|
354
|
+
events: [],
|
|
355
|
+
});
|
|
356
|
+
|
|
357
|
+
describe("detail sections", () => {
|
|
358
|
+
test("round-trips a detail section and a clearing form", () => {
|
|
359
|
+
const source = detailManifest();
|
|
360
|
+
|
|
361
|
+
expect(bridgeManifestSchema.parse(source)).toEqual(source);
|
|
362
|
+
});
|
|
363
|
+
|
|
364
|
+
test("refuses a clear whose variable is not an env key", () => {
|
|
365
|
+
const source = detailManifest();
|
|
366
|
+
const [form] = source.panel?.tabs[0]?.sections ?? [];
|
|
367
|
+
|
|
368
|
+
if (form?.layout !== BridgeLayout.Form) {
|
|
369
|
+
throw new Error("fixture is missing its form section");
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
form.clears = [
|
|
373
|
+
{
|
|
374
|
+
variable: "mod pack",
|
|
375
|
+
warning: text("Broken"),
|
|
376
|
+
},
|
|
377
|
+
];
|
|
378
|
+
|
|
379
|
+
expect(bridgeManifestSchema.safeParse(source).success).toBe(false);
|
|
380
|
+
});
|
|
381
|
+
});
|
|
382
|
+
|
|
383
|
+
const uploadManifest = (mode?: BridgeUploadMode): BridgeManifest => ({
|
|
384
|
+
version: "1.0.0",
|
|
385
|
+
panel: {
|
|
386
|
+
tabs: [
|
|
387
|
+
{
|
|
388
|
+
id: "modpacks",
|
|
389
|
+
title: text("Modpacks"),
|
|
390
|
+
sections: [
|
|
391
|
+
{
|
|
392
|
+
layout: BridgeLayout.Table,
|
|
393
|
+
id: "pending",
|
|
394
|
+
module: "pending",
|
|
395
|
+
columns: [
|
|
396
|
+
{
|
|
397
|
+
key: "name",
|
|
398
|
+
label: text("Name"),
|
|
399
|
+
},
|
|
400
|
+
],
|
|
401
|
+
upload: {
|
|
402
|
+
label: text("Upload"),
|
|
403
|
+
extensions: [
|
|
404
|
+
"jar",
|
|
405
|
+
],
|
|
406
|
+
staging: ".serverk-staging/pending-upload",
|
|
407
|
+
mode,
|
|
408
|
+
},
|
|
409
|
+
},
|
|
410
|
+
],
|
|
411
|
+
},
|
|
412
|
+
],
|
|
413
|
+
},
|
|
414
|
+
terminal: null,
|
|
415
|
+
modules: [
|
|
416
|
+
{
|
|
417
|
+
id: "pending",
|
|
418
|
+
kind: BridgeKind.Collection,
|
|
419
|
+
requiresRunning: false,
|
|
420
|
+
refreshSeconds: null,
|
|
421
|
+
pageSize: null,
|
|
422
|
+
dependsOn: [],
|
|
423
|
+
actions: [],
|
|
424
|
+
},
|
|
425
|
+
],
|
|
426
|
+
events: [],
|
|
427
|
+
});
|
|
428
|
+
|
|
429
|
+
describe("the upload mirror", () => {
|
|
430
|
+
test("carries the file upload mode through unchanged", () => {
|
|
431
|
+
const source = uploadManifest(BridgeUploadMode.File);
|
|
432
|
+
const parsed = bridgeManifestSchema.parse(source);
|
|
433
|
+
const [section] = parsed.panel?.tabs[0]?.sections ?? [];
|
|
434
|
+
|
|
435
|
+
if (section?.layout !== BridgeLayout.Table) {
|
|
436
|
+
throw new Error("fixture is missing its table section");
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
expect(section.upload?.mode).toBe(BridgeUploadMode.File);
|
|
440
|
+
});
|
|
441
|
+
|
|
442
|
+
test("takes an upload that declares no mode", () => {
|
|
443
|
+
expect(bridgeManifestSchema.safeParse(uploadManifest()).success).toBe(true);
|
|
444
|
+
});
|
|
445
|
+
|
|
446
|
+
test("refuses an upload mode the platform does not know", () => {
|
|
447
|
+
const source = uploadManifest("stream" as BridgeUploadMode);
|
|
448
|
+
|
|
449
|
+
expect(bridgeManifestSchema.safeParse(source).success).toBe(false);
|
|
450
|
+
});
|
|
451
|
+
});
|
package/src/wire/panel.ts
CHANGED
|
@@ -17,6 +17,7 @@ import {
|
|
|
17
17
|
BridgeTerminalLevel,
|
|
18
18
|
type BridgeTerminalManifest,
|
|
19
19
|
type BridgeTerminalRuleManifest,
|
|
20
|
+
BridgeUploadMode,
|
|
20
21
|
} from "@serverkgg/bridge/protocol";
|
|
21
22
|
import { z } from "zod";
|
|
22
23
|
import { zEnvKey } from "./zEnvKey";
|
|
@@ -27,6 +28,8 @@ const ACTION_FIELDS_LIMIT = 5;
|
|
|
27
28
|
|
|
28
29
|
const SECTION_ACTIONS_LIMIT = 10;
|
|
29
30
|
|
|
31
|
+
const FORM_CLEARS_LIMIT = 8;
|
|
32
|
+
|
|
30
33
|
const zKey = z
|
|
31
34
|
.string()
|
|
32
35
|
.min(1)
|
|
@@ -107,6 +110,16 @@ export const bridgeSectionActionSchema = z.object({
|
|
|
107
110
|
fields: z.array(bridgeFieldSchema).max(ACTION_FIELDS_LIMIT).optional(),
|
|
108
111
|
});
|
|
109
112
|
|
|
113
|
+
export const bridgeTabRefSchema = z.object({
|
|
114
|
+
tab: zBridgeId,
|
|
115
|
+
label: panelTextSchema,
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
export const bridgeFormClearSchema = z.object({
|
|
119
|
+
variable: zEnvKey,
|
|
120
|
+
warning: panelTextSchema,
|
|
121
|
+
});
|
|
122
|
+
|
|
110
123
|
export const bridgeSectionAddSchema = z.object({
|
|
111
124
|
label: panelTextSchema,
|
|
112
125
|
placeholder: z.string().max(256).optional(),
|
|
@@ -116,6 +129,7 @@ export const bridgeSectionUploadSchema = z.object({
|
|
|
116
129
|
label: panelTextSchema,
|
|
117
130
|
extensions: z.array(z.string().min(1).max(16)).min(1).max(8),
|
|
118
131
|
staging: z.string().min(1).max(128),
|
|
132
|
+
mode: z.enum(BridgeUploadMode).optional(),
|
|
119
133
|
});
|
|
120
134
|
|
|
121
135
|
export const bridgeActionsSectionSchema = z.object({
|
|
@@ -141,6 +155,23 @@ export const bridgeFormSectionSchema = z.object({
|
|
|
141
155
|
confirm: z.enum(BridgeConfirm).optional(),
|
|
142
156
|
confirmText: panelTextSchema.optional(),
|
|
143
157
|
fields: z.array(bridgeFieldSchema).min(1).max(32),
|
|
158
|
+
clears: z.array(bridgeFormClearSchema).max(FORM_CLEARS_LIMIT).optional(),
|
|
159
|
+
visibleWhen: bridgeVisibleWhenSchema.optional(),
|
|
160
|
+
access: z.enum(BridgeAccess).optional(),
|
|
161
|
+
});
|
|
162
|
+
|
|
163
|
+
export const bridgeDetailSectionSchema = z.object({
|
|
164
|
+
layout: z.literal(BridgeLayout.Detail),
|
|
165
|
+
id: zBridgeId,
|
|
166
|
+
title: panelTextSchema.optional(),
|
|
167
|
+
module: zBridgeModuleId,
|
|
168
|
+
actions: z.array(bridgeSectionActionSchema).max(SECTION_ACTIONS_LIMIT).optional(),
|
|
169
|
+
reinstall: z.boolean().optional(),
|
|
170
|
+
variable: zEnvKey.optional(),
|
|
171
|
+
confirm: z.enum(BridgeConfirm).optional(),
|
|
172
|
+
confirmText: panelTextSchema.optional(),
|
|
173
|
+
related: bridgeTabRefSchema.optional(),
|
|
174
|
+
empty: panelTextSchema.optional(),
|
|
144
175
|
visibleWhen: bridgeVisibleWhenSchema.optional(),
|
|
145
176
|
access: z.enum(BridgeAccess).optional(),
|
|
146
177
|
});
|
|
@@ -197,6 +228,7 @@ export const bridgeSectionSchema: z.ZodType<BridgeSection> = z.discriminatedUnio
|
|
|
197
228
|
bridgeActionsSectionSchema,
|
|
198
229
|
bridgeCardsSectionSchema,
|
|
199
230
|
bridgeCatalogSectionSchema,
|
|
231
|
+
bridgeDetailSectionSchema,
|
|
200
232
|
bridgeFormSectionSchema,
|
|
201
233
|
bridgeTableSectionSchema,
|
|
202
234
|
]);
|