@serverkgg/bridge 0.0.7 → 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.
Files changed (52) hide show
  1. package/package.json +4 -3
  2. package/src/cli/validate.ts +1 -0
  3. package/src/context/bridgeContext.ts +10 -0
  4. package/src/context/index.ts +1 -0
  5. package/src/core/bridgeDownloadError.ts +10 -0
  6. package/src/core/bridgeHold.ts +12 -0
  7. package/src/core/bridgeKind.ts +2 -0
  8. package/src/core/bridgeUserError.test.ts +23 -0
  9. package/src/core/bridgeUserError.ts +12 -0
  10. package/src/core/index.ts +3 -0
  11. package/src/manifest/index.ts +1 -0
  12. package/src/manifest/manifest.test.ts +85 -0
  13. package/src/manifest/manifest.ts +21 -0
  14. package/src/manifest/presence.ts +48 -0
  15. package/src/manifest/primitives.ts +6 -0
  16. package/src/modules/bridge.ts +45 -2
  17. package/src/modules/bridgeDriver.ts +2 -0
  18. package/src/modules/bridgeModule.ts +25 -3
  19. package/src/panel/bridgeDetail.ts +49 -0
  20. package/src/panel/bridgeLayout.ts +1 -0
  21. package/src/panel/bridgePanel.ts +30 -0
  22. package/src/panel/bridgeUploadMode.ts +4 -0
  23. package/src/panel/index.ts +2 -0
  24. package/src/protocol/bridgeEgress.ts +8 -1
  25. package/src/protocol/bridgeEvents.ts +4 -0
  26. package/src/protocol/bridgeFrame.ts +28 -1
  27. package/src/protocol/bridgeLimits.ts +10 -0
  28. package/src/runtime/bridgeActions.ts +7 -0
  29. package/src/runtime/bridgeDriver.test.ts +477 -2
  30. package/src/runtime/bridgeDriver.ts +116 -3
  31. package/src/runtime/bridgeEgress.ts +3 -0
  32. package/src/runtime/bridgeEvents.ts +7 -5
  33. package/src/runtime/bridgeFiles.test.ts +625 -15
  34. package/src/runtime/bridgeFiles.ts +152 -45
  35. package/src/runtime/bridgeInstall.test.ts +118 -0
  36. package/src/runtime/bridgeInstall.ts +55 -0
  37. package/src/runtime/bridgeNet.ts +32 -3
  38. package/src/runtime/bridgePending.test.ts +148 -0
  39. package/src/runtime/bridgePending.ts +43 -0
  40. package/src/runtime/bridgePrivilege.test.ts +77 -0
  41. package/src/runtime/bridgePrivilege.ts +5 -3
  42. package/src/runtime/bridgeRegistry.test.ts +134 -0
  43. package/src/runtime/bridgeRegistry.ts +26 -4
  44. package/src/runtime/bridgeServer.test.ts +338 -0
  45. package/src/runtime/bridgeServer.ts +25 -3
  46. package/src/runtime/bridgeSupervisor.ts +18 -0
  47. package/src/runtime/bridgeZip.ts +179 -58
  48. package/src/runtime/serve.ts +64 -4
  49. package/src/wire/index.ts +2 -0
  50. package/src/wire/panel.test.ts +451 -0
  51. package/src/wire/panel.ts +295 -0
  52. package/src/wire/zEnvKey.ts +7 -0
@@ -0,0 +1,295 @@
1
+ import {
2
+ BRIDGE_ID_PATTERN,
3
+ BRIDGE_MODULE_ID_PATTERN,
4
+ BridgeAccess,
5
+ BridgeConfirm,
6
+ BridgeControl,
7
+ BridgeFormTarget,
8
+ BridgeIcon,
9
+ BridgeKind,
10
+ BridgeLayout,
11
+ type BridgeManifest,
12
+ type BridgePanel,
13
+ type BridgeSection,
14
+ BridgeStream,
15
+ type BridgeTerminalArg,
16
+ type BridgeTerminalCommand,
17
+ BridgeTerminalLevel,
18
+ type BridgeTerminalManifest,
19
+ type BridgeTerminalRuleManifest,
20
+ BridgeUploadMode,
21
+ } from "@serverkgg/bridge/protocol";
22
+ import { z } from "zod";
23
+ import { zEnvKey } from "./zEnvKey";
24
+
25
+ const PANEL_TEXT_LENGTH_LIMIT = 512;
26
+
27
+ const ACTION_FIELDS_LIMIT = 5;
28
+
29
+ const SECTION_ACTIONS_LIMIT = 10;
30
+
31
+ const FORM_CLEARS_LIMIT = 8;
32
+
33
+ const zKey = z
34
+ .string()
35
+ .min(1)
36
+ .max(64)
37
+ .regex(/^[A-Za-z][A-Za-z0-9_-]*$/);
38
+
39
+ const zBridgeId = z.string().min(1).max(32).regex(BRIDGE_ID_PATTERN);
40
+
41
+ export const zBridgeModuleId = z.string().min(1).max(32).regex(BRIDGE_MODULE_ID_PATTERN);
42
+
43
+ export const bridgeValueSchema = z.union([
44
+ z.boolean(),
45
+ z.number(),
46
+ z.string().max(8192),
47
+ z.null(),
48
+ ]);
49
+
50
+ export type BridgeValueInput = z.infer<typeof bridgeValueSchema>;
51
+
52
+ export const bridgeValuesSchema = z.record(zKey, bridgeValueSchema);
53
+
54
+ export type BridgeValuesInput = z.infer<typeof bridgeValuesSchema>;
55
+
56
+ export const panelTextSchema = z.object({
57
+ ar: z.string().min(1).max(PANEL_TEXT_LENGTH_LIMIT),
58
+ en: z.string().min(1).max(PANEL_TEXT_LENGTH_LIMIT),
59
+ });
60
+
61
+ export const bridgeOptionSchema = z.object({
62
+ value: z.string().min(1).max(128),
63
+ label: panelTextSchema,
64
+ help: panelTextSchema.optional(),
65
+ latest: z.boolean().optional(),
66
+ });
67
+
68
+ export const bridgeVisibleWhenSchema = z
69
+ .object({
70
+ variable: zKey,
71
+ values: z.array(z.string().max(128)).min(1).max(16).optional(),
72
+ empty: z.boolean().optional(),
73
+ })
74
+ .refine((rule) => rule.empty !== undefined || rule.values !== undefined);
75
+
76
+ export const bridgeOptionsRefSchema = z.object({
77
+ module: zBridgeModuleId,
78
+ });
79
+
80
+ export const bridgePreviewRefSchema = z.object({
81
+ module: zBridgeModuleId,
82
+ });
83
+
84
+ export const bridgeFieldSchema = z.object({
85
+ key: zKey,
86
+ control: z.enum(BridgeControl),
87
+ label: panelTextSchema,
88
+ help: panelTextSchema.optional(),
89
+ warning: panelTextSchema.optional(),
90
+ placeholder: z.string().max(256).optional(),
91
+ min: z.number().optional(),
92
+ max: z.number().optional(),
93
+ step: z.number().optional(),
94
+ maxLength: z.int().positive().optional(),
95
+ options: z
96
+ .union([
97
+ z.array(bridgeOptionSchema).max(64),
98
+ bridgeOptionsRefSchema,
99
+ ])
100
+ .optional(),
101
+ visibleWhen: bridgeVisibleWhenSchema.optional(),
102
+ });
103
+
104
+ export const bridgeSectionActionSchema = z.object({
105
+ id: zKey,
106
+ label: panelTextSchema,
107
+ confirm: z.enum(BridgeConfirm).optional(),
108
+ confirmText: panelTextSchema.optional(),
109
+ download: z.boolean().optional(),
110
+ fields: z.array(bridgeFieldSchema).max(ACTION_FIELDS_LIMIT).optional(),
111
+ });
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
+
123
+ export const bridgeSectionAddSchema = z.object({
124
+ label: panelTextSchema,
125
+ placeholder: z.string().max(256).optional(),
126
+ });
127
+
128
+ export const bridgeSectionUploadSchema = z.object({
129
+ label: panelTextSchema,
130
+ extensions: z.array(z.string().min(1).max(16)).min(1).max(8),
131
+ staging: z.string().min(1).max(128),
132
+ mode: z.enum(BridgeUploadMode).optional(),
133
+ });
134
+
135
+ export const bridgeActionsSectionSchema = z.object({
136
+ layout: z.literal(BridgeLayout.Actions),
137
+ id: zBridgeId,
138
+ title: panelTextSchema.optional(),
139
+ help: panelTextSchema.optional(),
140
+ module: zBridgeModuleId,
141
+ actions: z.array(bridgeSectionActionSchema).min(1).max(SECTION_ACTIONS_LIMIT),
142
+ visibleWhen: bridgeVisibleWhenSchema.optional(),
143
+ access: z.enum(BridgeAccess).optional(),
144
+ });
145
+
146
+ export const bridgeFormSectionSchema = z.object({
147
+ layout: z.literal(BridgeLayout.Form),
148
+ id: zBridgeId,
149
+ title: panelTextSchema.optional(),
150
+ target: z.enum(BridgeFormTarget),
151
+ module: zBridgeModuleId.optional(),
152
+ preview: bridgePreviewRefSchema.optional(),
153
+ reinstall: z.boolean().optional(),
154
+ restartHint: z.boolean().optional(),
155
+ confirm: z.enum(BridgeConfirm).optional(),
156
+ confirmText: panelTextSchema.optional(),
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(),
175
+ visibleWhen: bridgeVisibleWhenSchema.optional(),
176
+ access: z.enum(BridgeAccess).optional(),
177
+ });
178
+
179
+ export const bridgeColumnSchema = z.object({
180
+ key: zKey,
181
+ label: panelTextSchema,
182
+ });
183
+
184
+ export const bridgeTableSectionSchema = z.object({
185
+ layout: z.literal(BridgeLayout.Table),
186
+ id: zBridgeId,
187
+ title: panelTextSchema.optional(),
188
+ module: zBridgeModuleId,
189
+ restartHint: z.boolean().optional(),
190
+ columns: z.array(bridgeColumnSchema).min(1).max(8),
191
+ add: bridgeSectionAddSchema.optional(),
192
+ upload: bridgeSectionUploadSchema.optional(),
193
+ actions: z.array(bridgeSectionActionSchema).max(8).optional(),
194
+ empty: panelTextSchema.optional(),
195
+ visibleWhen: bridgeVisibleWhenSchema.optional(),
196
+ access: z.enum(BridgeAccess).optional(),
197
+ });
198
+
199
+ export const bridgeCardsSectionSchema = z.object({
200
+ layout: z.literal(BridgeLayout.Cards),
201
+ id: zBridgeId,
202
+ title: panelTextSchema.optional(),
203
+ module: zBridgeModuleId,
204
+ titleKey: zKey,
205
+ subtitleKey: zKey.optional(),
206
+ actions: z.array(bridgeSectionActionSchema).max(8).optional(),
207
+ empty: panelTextSchema.optional(),
208
+ visibleWhen: bridgeVisibleWhenSchema.optional(),
209
+ access: z.enum(BridgeAccess).optional(),
210
+ });
211
+
212
+ export const bridgeCatalogSectionSchema = z.object({
213
+ layout: z.literal(BridgeLayout.Catalog),
214
+ id: zBridgeId,
215
+ title: panelTextSchema.optional(),
216
+ module: zBridgeModuleId,
217
+ restartHint: z.boolean().optional(),
218
+ reinstall: z.boolean().optional(),
219
+ variable: zEnvKey.optional(),
220
+ confirm: z.enum(BridgeConfirm).optional(),
221
+ confirmText: panelTextSchema.optional(),
222
+ empty: panelTextSchema.optional(),
223
+ visibleWhen: bridgeVisibleWhenSchema.optional(),
224
+ access: z.enum(BridgeAccess).optional(),
225
+ });
226
+
227
+ export const bridgeSectionSchema: z.ZodType<BridgeSection> = z.discriminatedUnion("layout", [
228
+ bridgeActionsSectionSchema,
229
+ bridgeCardsSectionSchema,
230
+ bridgeCatalogSectionSchema,
231
+ bridgeDetailSectionSchema,
232
+ bridgeFormSectionSchema,
233
+ bridgeTableSectionSchema,
234
+ ]);
235
+
236
+ export const bridgeTabSchema = z.object({
237
+ id: zBridgeId,
238
+ title: panelTextSchema,
239
+ icon: z.enum(BridgeIcon).optional(),
240
+ sections: z.array(bridgeSectionSchema).min(1).max(8),
241
+ access: z.enum(BridgeAccess).optional(),
242
+ });
243
+
244
+ export const bridgePanelSchema: z.ZodType<BridgePanel> = z.object({
245
+ tabs: z.array(bridgeTabSchema).min(1).max(8),
246
+ });
247
+
248
+ export const bridgeTerminalArgSchema: z.ZodType<BridgeTerminalArg> = z.object({
249
+ key: zKey,
250
+ label: panelTextSchema.optional(),
251
+ required: z.boolean().optional(),
252
+ variadic: z.boolean().optional(),
253
+ values: z.array(z.string().min(1).max(64)).max(64).optional(),
254
+ module: zBridgeModuleId.optional(),
255
+ column: zKey.optional(),
256
+ });
257
+
258
+ export const bridgeTerminalCommandSchema: z.ZodType<BridgeTerminalCommand> = z.object({
259
+ name: z.string().min(1).max(64),
260
+ summary: panelTextSchema,
261
+ syntax: z.string().max(160).optional(),
262
+ args: z.array(bridgeTerminalArgSchema).max(8).optional(),
263
+ danger: z.boolean().optional(),
264
+ requiresRunning: z.boolean().optional(),
265
+ });
266
+
267
+ export const bridgeTerminalRuleSchema: z.ZodType<BridgeTerminalRuleManifest> = z.object({
268
+ match: z.string().min(1).max(512),
269
+ flags: z.string().max(8),
270
+ level: z.enum(BridgeTerminalLevel),
271
+ stream: z.enum(BridgeStream).optional(),
272
+ });
273
+
274
+ export const bridgeTerminalManifestSchema: z.ZodType<BridgeTerminalManifest> = z.object({
275
+ commands: z.array(bridgeTerminalCommandSchema).max(128),
276
+ rules: z.array(bridgeTerminalRuleSchema).max(64),
277
+ });
278
+
279
+ export const bridgeModuleManifestSchema = z.object({
280
+ id: zBridgeModuleId,
281
+ kind: z.enum(BridgeKind),
282
+ requiresRunning: z.boolean(),
283
+ refreshSeconds: z.int().positive().nullable(),
284
+ pageSize: z.int().positive().nullable().default(null),
285
+ dependsOn: z.array(zKey).max(8),
286
+ actions: z.array(z.string().min(1).max(64)).max(16),
287
+ });
288
+
289
+ export const bridgeManifestSchema: z.ZodType<BridgeManifest> = z.object({
290
+ version: z.string(),
291
+ panel: bridgePanelSchema.nullable(),
292
+ terminal: bridgeTerminalManifestSchema.nullable().default(null),
293
+ modules: z.array(bridgeModuleManifestSchema).max(32),
294
+ events: z.array(z.string().min(1).max(64)).max(32),
295
+ });
@@ -0,0 +1,7 @@
1
+ import { z } from "zod";
2
+
3
+ export const zEnvKey = z
4
+ .string()
5
+ .min(2)
6
+ .max(32)
7
+ .regex(/^[A-Z][A-Z0-9_]*$/);