@serverkgg/bridge 0.0.3 → 0.0.5

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/README.md CHANGED
@@ -41,7 +41,7 @@ bunx serverk-bridge validate
41
41
  bunx serverk-bridge compile
42
42
  ```
43
43
 
44
- `validate` checks `serverk.yml` against the real platform schema, verifies the logo and banner, and validates the driver's panel wiring. `compile` produces `dist/bridge-amd64` and `dist/bridge-arm64`.
44
+ `validate` checks `serverk.yml` against the real platform schema, verifies the logo and banner, and validates the driver's panel wiring. `compile` produces `dist/bridge`, an amd64 binary — serverk publishes game images for `linux/amd64` only.
45
45
 
46
46
  ## Compatibility
47
47
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@serverkgg/bridge",
3
- "version": "0.0.3",
3
+ "version": "0.0.5",
4
4
  "description": "Serverk game bridge — driver runtime, wire protocol, manifest schema, and maintainer CLI",
5
5
  "homepage": "https://serverk.gg",
6
6
  "license": "SEE LICENSE IN LICENSE.md",
@@ -1,14 +1,10 @@
1
1
  import { parseArgs } from "node:util";
2
2
 
3
- const TARGETS: Record<string, string> = {
4
- amd64: "bun-linux-x64",
5
- arm64: "bun-linux-arm64",
6
- };
3
+ const TARGET = "bun-linux-x64";
7
4
 
8
5
  const HELP = `serverk-bridge compile [options]
9
6
 
10
7
  options:
11
- --arch <amd64|arm64> architecture to compile (repeatable, default: both)
12
8
  --entry <path> entrypoint (default: src/main.ts)
13
9
  --outdir <path> output directory (default: dist)
14
10
  --help show this help`;
@@ -17,10 +13,6 @@ export const runCompile = async (args: string[]) => {
17
13
  const { values } = parseArgs({
18
14
  args,
19
15
  options: {
20
- arch: {
21
- type: "string",
22
- multiple: true,
23
- },
24
16
  entry: {
25
17
  type: "string",
26
18
  default: "src/main.ts",
@@ -42,34 +34,24 @@ export const runCompile = async (args: string[]) => {
42
34
  return;
43
35
  }
44
36
 
45
- const arches = values.arch?.length ? values.arch : Object.keys(TARGETS);
46
-
47
- for (const arch of arches) {
48
- const target = TARGETS[arch];
49
-
50
- if (!target) {
51
- throw new Error(`unknown arch "${arch}" — expected amd64 or arm64`);
52
- }
53
-
54
- const outfile = `${values.outdir}/bridge-${arch}`;
55
- const child = Bun.spawn(
56
- [
57
- "bun",
58
- "build",
59
- "--compile",
60
- `--target=${target}`,
61
- values.entry,
62
- "--outfile",
63
- outfile,
64
- ],
65
- {
66
- stderr: "inherit",
67
- stdout: "inherit",
68
- },
69
- );
37
+ const outfile = `${values.outdir}/bridge`;
38
+ const child = Bun.spawn(
39
+ [
40
+ "bun",
41
+ "build",
42
+ "--compile",
43
+ `--target=${TARGET}`,
44
+ values.entry,
45
+ "--outfile",
46
+ outfile,
47
+ ],
48
+ {
49
+ stderr: "inherit",
50
+ stdout: "inherit",
51
+ },
52
+ );
70
53
 
71
- if ((await child.exited) !== 0) {
72
- throw new Error(`compile failed for ${arch}`);
73
- }
54
+ if ((await child.exited) !== 0) {
55
+ throw new Error("compile failed");
74
56
  }
75
57
  };
package/src/cli/main.ts CHANGED
@@ -11,7 +11,7 @@ const USAGE = `serverk-bridge <command>
11
11
  commands:
12
12
  validate validate serverk.yml, assets, and driver wiring
13
13
  schema write the serverk.yml JSON Schema for editor tooling
14
- compile compile the bridge binary for amd64 and arm64
14
+ compile compile the bridge binary for amd64
15
15
  link use a local bridge checkout while developing
16
16
 
17
17
  run "serverk-bridge <command> --help" for options`;
@@ -2,3 +2,8 @@ export enum PortProtocol {
2
2
  Tcp = "tcp",
3
3
  Udp = "udp",
4
4
  }
5
+
6
+ export enum PortJoin {
7
+ Combined = "combined",
8
+ Separate = "separate",
9
+ }
@@ -1,5 +1,6 @@
1
1
  import { describe, expect, test } from "bun:test";
2
2
  import { z } from "zod";
3
+ import { PortJoin } from "../core";
3
4
  import { GameCategory } from "./category";
4
5
  import { guidePackageSchema, MANIFEST_SCHEMA_VERSION, manifestSchema, packageSchema } from "./manifest";
5
6
 
@@ -55,6 +56,34 @@ const failure = (input: unknown) => {
55
56
  }));
56
57
  };
57
58
 
59
+ const withPort = (extra: Record<string, unknown>) => {
60
+ const manifest = base();
61
+ const [game] = manifest.container.ports;
62
+
63
+ if (!game) {
64
+ throw new Error("fixture is missing its port");
65
+ }
66
+
67
+ return {
68
+ ...manifest,
69
+ container: {
70
+ ...manifest.container,
71
+ ports: [
72
+ {
73
+ ...game,
74
+ ...extra,
75
+ },
76
+ ],
77
+ },
78
+ };
79
+ };
80
+
81
+ const withPortSrv = (srv: unknown) => {
82
+ return withPort({
83
+ srv,
84
+ });
85
+ };
86
+
58
87
  describe("defaults", () => {
59
88
  test("fills in the optional sections so consumers never guard", () => {
60
89
  const manifest = manifestSchema.parse(base());
@@ -72,6 +101,81 @@ describe("defaults", () => {
72
101
  });
73
102
  expect(manifest.guides).toEqual([]);
74
103
  expect(manifest.secrets).toEqual([]);
104
+ expect(manifest.container.ports[0]?.srv).toBeUndefined();
105
+ expect(manifest.container.ports[0]?.name).toBeUndefined();
106
+ expect(manifest.container.ports[0]?.hint).toBeUndefined();
107
+ expect(manifest.container.ports[0]?.join).toBe(PortJoin.Combined);
108
+ });
109
+ });
110
+
111
+ describe("port presentation", () => {
112
+ test("keeps the localized name, hint and join style a port declares", () => {
113
+ const manifest = manifestSchema.parse(
114
+ withPort({
115
+ name: {
116
+ ar: "بيدروك",
117
+ en: "Bedrock",
118
+ },
119
+ hint: {
120
+ ar: "العنوان في خانة والمنفذ في خانة ثانية",
121
+ en: "Address and port go in separate fields",
122
+ },
123
+ join: "separate",
124
+ }),
125
+ );
126
+
127
+ expect(manifest.container.ports[0]?.name).toEqual({
128
+ ar: "بيدروك",
129
+ en: "Bedrock",
130
+ });
131
+ expect(manifest.container.ports[0]?.hint?.en).toBe("Address and port go in separate fields");
132
+ expect(manifest.container.ports[0]?.join).toBe(PortJoin.Separate);
133
+ });
134
+
135
+ test("rejects a port name missing one language", () => {
136
+ expect(
137
+ failure(
138
+ withPort({
139
+ name: {
140
+ en: "Bedrock",
141
+ },
142
+ }),
143
+ ),
144
+ ).toEqual([
145
+ {
146
+ path: "container.ports.0.name.ar",
147
+ message: "Invalid input: expected string, received undefined",
148
+ },
149
+ ]);
150
+ });
151
+ });
152
+
153
+ describe("port srv", () => {
154
+ test("keeps the service label a port declares", () => {
155
+ const manifest = manifestSchema.parse(
156
+ withPortSrv({
157
+ service: "_minecraft",
158
+ }),
159
+ );
160
+
161
+ expect(manifest.container.ports[0]?.srv).toEqual({
162
+ service: "_minecraft",
163
+ });
164
+ });
165
+
166
+ test("rejects a service label without its underscore", () => {
167
+ expect(
168
+ failure(
169
+ withPortSrv({
170
+ service: "minecraft",
171
+ }),
172
+ ),
173
+ ).toEqual([
174
+ {
175
+ path: "container.ports.0.srv.service",
176
+ message: "must be an underscore-prefixed service label such as _minecraft",
177
+ },
178
+ ]);
75
179
  });
76
180
  });
77
181
 
@@ -1,5 +1,5 @@
1
1
  import { z } from "zod";
2
- import { PortProtocol } from "../core";
2
+ import { PortJoin, PortProtocol } from "../core";
3
3
  import { BridgeIcon } from "../panel/bridgeIcon";
4
4
  import { GameCategory } from "./category";
5
5
  import { type GuideEntry, type GuideTag, guideEntrySchema, guideTagSchema } from "./guide";
@@ -43,6 +43,26 @@ const manifestPortSchema = z.object({
43
43
  containerPort: zPort,
44
44
  protocol: z.enum(PortProtocol).default(PortProtocol.Tcp),
45
45
  hostRange: manifestHostRangeSchema,
46
+ name: localizedText(48).optional().meta({
47
+ description: "Player-facing name of this port, such as Java or Bedrock. The key is shown when omitted.",
48
+ }),
49
+ hint: localizedText(160).optional().meta({
50
+ description: "One short line telling the player where this address goes in the game client.",
51
+ }),
52
+ join: z.enum(PortJoin).default(PortJoin.Combined).meta({
53
+ description: "How the game client takes the address: combined as host:port, or separate address and port fields.",
54
+ }),
55
+ srv: z
56
+ .object({
57
+ service: z
58
+ .string()
59
+ .regex(/^_[a-z0-9-]{1,15}$/, "must be an underscore-prefixed service label such as _minecraft"),
60
+ })
61
+ .optional()
62
+ .meta({
63
+ description:
64
+ "Publishes this port as an SRV record under the server hostname, so players join by name with no port.",
65
+ }),
46
66
  });
47
67
 
48
68
  export type ManifestPort = z.infer<typeof manifestPortSchema>;