@yourrealm/sdk 0.0.0-alpha.1378.ce03c8dc

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 (230) hide show
  1. package/LICENSE-EXCEPTION +26 -0
  2. package/README.md +34 -0
  3. package/dist/chunk-3R6KEFOI.js +22 -0
  4. package/dist/chunk-67BDAMYX.js +376 -0
  5. package/dist/chunk-AITGS27R.js +139 -0
  6. package/dist/chunk-CMAEHQ4F.js +6 -0
  7. package/dist/chunk-MLKGABMK.js +9 -0
  8. package/dist/chunk-O3UIK34B.js +1430 -0
  9. package/dist/chunk-VHTUSZUX.js +176 -0
  10. package/dist/cli.js +9006 -0
  11. package/dist/docker.js +54 -0
  12. package/dist/index.js +1053 -0
  13. package/dist/ingress.js +436 -0
  14. package/dist/jsx-runtime.js +2 -0
  15. package/dist/preact.js +22 -0
  16. package/dist/service-url.js +11 -0
  17. package/dist/services.js +213 -0
  18. package/dist/test.js +5069 -0
  19. package/dist/ui.js +254 -0
  20. package/dist/worker-protocol.js +89 -0
  21. package/package.json +112 -0
  22. package/src/app-icon.ts +74 -0
  23. package/src/apply.ts +52 -0
  24. package/src/bundle-ui.ts +211 -0
  25. package/src/bundle.ts +546 -0
  26. package/src/cli/build-dev-landing.ts +84 -0
  27. package/src/cli/build-install-panel.ts +90 -0
  28. package/src/cli/build-runtime.ts +133 -0
  29. package/src/cli/build.ts +63 -0
  30. package/src/cli/dev.ts +107 -0
  31. package/src/cli/down.ts +60 -0
  32. package/src/cli/main.ts +56 -0
  33. package/src/cli/test.ts +61 -0
  34. package/src/cli/validate.ts +37 -0
  35. package/src/compile.ts +100 -0
  36. package/src/create-app.ts +982 -0
  37. package/src/deep-merge.ts +33 -0
  38. package/src/dev/fixture.ts +48 -0
  39. package/src/dev/install-handler.ts +383 -0
  40. package/src/dev/server.ts +968 -0
  41. package/src/dev/stack.ts +108 -0
  42. package/src/dev/state.ts +159 -0
  43. package/src/docker.ts +96 -0
  44. package/src/errors.ts +61 -0
  45. package/src/factory.ts +481 -0
  46. package/src/garage.ts +56 -0
  47. package/src/generator/hash.ts +6 -0
  48. package/src/generator/resolve-refs.ts +207 -0
  49. package/src/grants-builder.ts +100 -0
  50. package/src/grants.ts +260 -0
  51. package/src/home-api.ts +172 -0
  52. package/src/home-cookie.ts +10 -0
  53. package/src/home-registry.ts +120 -0
  54. package/src/home.ts +187 -0
  55. package/src/host-registry.ts +143 -0
  56. package/src/http-header.ts +20 -0
  57. package/src/identifiers.ts +49 -0
  58. package/src/index.ts +66 -0
  59. package/src/info.ts +64 -0
  60. package/src/ini.ts +50 -0
  61. package/src/json.ts +14 -0
  62. package/src/jsx-runtime/index.ts +5 -0
  63. package/src/keys.ts +29 -0
  64. package/src/mysql.ts +56 -0
  65. package/src/pack-build.ts +108 -0
  66. package/src/pack.ts +115 -0
  67. package/src/peer-registry.ts +121 -0
  68. package/src/peer-world.ts +117 -0
  69. package/src/permission-meta.ts +116 -0
  70. package/src/permissions.ts +108 -0
  71. package/src/pkg-root.ts +34 -0
  72. package/src/postgres.ts +79 -0
  73. package/src/preact/index.ts +27 -0
  74. package/src/redis.ts +43 -0
  75. package/src/ref.ts +271 -0
  76. package/src/remote-registry.ts +33 -0
  77. package/src/required-host-kinds.ts +110 -0
  78. package/src/resolve-context.ts +111 -0
  79. package/src/resolve.ts +471 -0
  80. package/src/runtime/docker/compose/compose-schema.ts +118 -0
  81. package/src/runtime/docker/compose/convert-to-docker-compose.ts +278 -0
  82. package/src/runtime/docker/compose/default-hardening.ts +21 -0
  83. package/src/runtime/docker/compose/effects.ts +107 -0
  84. package/src/runtime/docker/compose/index.ts +17 -0
  85. package/src/runtime/docker/compose/labels.ts +39 -0
  86. package/src/runtime/docker/compose/types.ts +78 -0
  87. package/src/runtime/docker/home-proxy-server/index.ts +177 -0
  88. package/src/runtime/docker/home-proxy-server/protocol.ts +53 -0
  89. package/src/runtime/docker/ingress/build-config.ts +819 -0
  90. package/src/runtime/docker/ingress/index.ts +16 -0
  91. package/src/runtime/docker/ingress/types.ts +182 -0
  92. package/src/runtime/docker/log-frames.ts +121 -0
  93. package/src/runtime/docker/logs-server/index.ts +366 -0
  94. package/src/runtime/docker/spawn-server/context-key.ts +82 -0
  95. package/src/runtime/docker/spawn-server/index.ts +492 -0
  96. package/src/runtime/docker/spawn-server/protocol.ts +70 -0
  97. package/src/runtime/docker/spawn-server/spec.ts +122 -0
  98. package/src/runtime/docker/stats-server/disks.ts +161 -0
  99. package/src/runtime/docker/stats-server/index.ts +322 -0
  100. package/src/runtime/home-client/index.ts +71 -0
  101. package/src/runtime/log-line.ts +24 -0
  102. package/src/runtime/logs-client/index.ts +175 -0
  103. package/src/runtime/spawn-client/index.ts +93 -0
  104. package/src/runtime/spawn-client/kaniko.ts +79 -0
  105. package/src/runtime/stats-client/index.ts +65 -0
  106. package/src/runtime/stats-sample.ts +95 -0
  107. package/src/safe-json.ts +37 -0
  108. package/src/sandbox.ts +1209 -0
  109. package/src/schema/build-apps.ts +38 -0
  110. package/src/schema/home.ts +217 -0
  111. package/src/schema/host.ts +792 -0
  112. package/src/schema/inputs.ts +26 -0
  113. package/src/schema/nodes.ts +75 -0
  114. package/src/schema/peer.ts +400 -0
  115. package/src/schema/public-domain.ts +116 -0
  116. package/src/schema/remote.ts +74 -0
  117. package/src/security.ts +594 -0
  118. package/src/serialize.ts +21 -0
  119. package/src/service-definition.ts +284 -0
  120. package/src/service-url.ts +64 -0
  121. package/src/service.ts +39 -0
  122. package/src/services/index.ts +5 -0
  123. package/src/shared.ts +65 -0
  124. package/src/speculative-silo.ts +96 -0
  125. package/src/stable-secret.ts +14 -0
  126. package/src/surfaces.ts +264 -0
  127. package/src/tailwind-bin.ts +56 -0
  128. package/src/test/boot.ts +192 -0
  129. package/src/test/compile.ts +501 -0
  130. package/src/test/describe.ts +117 -0
  131. package/src/test/index.ts +11 -0
  132. package/src/test/ingress-fixture.ts +37 -0
  133. package/src/test/types.ts +318 -0
  134. package/src/trusted-headers.ts +79 -0
  135. package/src/types.ts +126 -0
  136. package/src/ui/components/aside.tsx +96 -0
  137. package/src/ui/components/badge.tsx +42 -0
  138. package/src/ui/components/button.tsx +59 -0
  139. package/src/ui/components/card.tsx +106 -0
  140. package/src/ui/components/checkbox.tsx +37 -0
  141. package/src/ui/components/code-block.tsx +29 -0
  142. package/src/ui/components/combobox.tsx +119 -0
  143. package/src/ui/components/config-field.tsx +284 -0
  144. package/src/ui/components/dialog.tsx +137 -0
  145. package/src/ui/components/domain-editor.tsx +317 -0
  146. package/src/ui/components/domain-list.ts +205 -0
  147. package/src/ui/components/dropdown-menu.tsx +73 -0
  148. package/src/ui/components/empty-state.tsx +51 -0
  149. package/src/ui/components/highlight.ts +59 -0
  150. package/src/ui/components/icons.tsx +101 -0
  151. package/src/ui/components/image-posture.tsx +85 -0
  152. package/src/ui/components/input.tsx +28 -0
  153. package/src/ui/components/label.tsx +16 -0
  154. package/src/ui/components/line-chart.tsx +113 -0
  155. package/src/ui/components/page.tsx +39 -0
  156. package/src/ui/components/permission-row.tsx +262 -0
  157. package/src/ui/components/permission-section.tsx +51 -0
  158. package/src/ui/components/pie-chart.tsx +245 -0
  159. package/src/ui/components/schema-block.tsx +60 -0
  160. package/src/ui/components/separator.tsx +42 -0
  161. package/src/ui/components/sheet.tsx +130 -0
  162. package/src/ui/components/sidebar.tsx +650 -0
  163. package/src/ui/components/silo-picker.tsx +510 -0
  164. package/src/ui/components/skeleton.tsx +13 -0
  165. package/src/ui/components/sonner.tsx +33 -0
  166. package/src/ui/components/switch.tsx +58 -0
  167. package/src/ui/components/table-view.ts +219 -0
  168. package/src/ui/components/table.tsx +506 -0
  169. package/src/ui/components/tabs.tsx +59 -0
  170. package/src/ui/components/timeago.tsx +84 -0
  171. package/src/ui/components/tooltip.tsx +56 -0
  172. package/src/ui/components.json +21 -0
  173. package/src/ui/dev/dev-shell.tsx +145 -0
  174. package/src/ui/home/home-grid.tsx +177 -0
  175. package/src/ui/hooks/use-mobile.ts +19 -0
  176. package/src/ui/index.ts +189 -0
  177. package/src/ui/install/adapter.ts +193 -0
  178. package/src/ui/install/deploy-targets-picker.tsx +185 -0
  179. package/src/ui/install/install-app-panel.tsx +912 -0
  180. package/src/ui/install/install-error.tsx +62 -0
  181. package/src/ui/install/perms-inactive.ts +50 -0
  182. package/src/ui/install/required-fields.ts +37 -0
  183. package/src/ui/install/tabs-form.tsx +557 -0
  184. package/src/ui/tokens.css +279 -0
  185. package/src/ui/utils.ts +78 -0
  186. package/src/ui-error.ts +139 -0
  187. package/src/ui-runtime/dev-landing-entry.tsx +258 -0
  188. package/src/ui-runtime/index.ts +83 -0
  189. package/src/ui-runtime/install-entry.tsx +119 -0
  190. package/src/ui-runtime/mount.ts +367 -0
  191. package/src/ui-runtime/runtime.css +56 -0
  192. package/src/ui-surface.ts +451 -0
  193. package/src/valkey.ts +43 -0
  194. package/src/worker/extract-tar.ts +125 -0
  195. package/src/worker/identity.ts +183 -0
  196. package/src/worker/index.ts +16 -0
  197. package/src/worker/public-ip.ts +92 -0
  198. package/src/worker/queue.ts +54 -0
  199. package/src/worker/reconcile.ts +127 -0
  200. package/src/worker/start-worker.ts +227 -0
  201. package/src/worker/ui-proxy.ts +335 -0
  202. package/src/worker/uplink.ts +523 -0
  203. package/src/worker/validate.ts +34 -0
  204. package/src/worker/verify-relay.ts +102 -0
  205. package/src/worker-protocol/app-dirs.ts +94 -0
  206. package/src/worker-protocol/home-proxy-paths.ts +76 -0
  207. package/src/worker-protocol/index.ts +55 -0
  208. package/src/worker-protocol/ingress.ts +166 -0
  209. package/src/worker-protocol/logs-socket-path.ts +50 -0
  210. package/src/worker-protocol/networks.ts +39 -0
  211. package/src/worker-protocol/node-version.ts +70 -0
  212. package/src/worker-protocol/silo-paths.ts +114 -0
  213. package/src/worker-protocol/spawn-paths.ts +165 -0
  214. package/src/worker-protocol/stats-socket-path.ts +40 -0
  215. package/src/worker-protocol/update-files.ts +77 -0
  216. package/src/worker-protocol/uplink/constants.ts +86 -0
  217. package/src/worker-protocol/uplink/errors.ts +61 -0
  218. package/src/worker-protocol/uplink/frame.ts +114 -0
  219. package/src/worker-protocol/uplink/identity.ts +40 -0
  220. package/src/worker-protocol/uplink/index.ts +63 -0
  221. package/src/worker-protocol/uplink/methods.ts +462 -0
  222. package/src/worker-protocol/uplink/mux.ts +646 -0
  223. package/src/worker-protocol/uplink/protocol.ts +11 -0
  224. package/src/worker-protocol/uplink/rpc.ts +309 -0
  225. package/src/worker-protocol/uplink/session.ts +540 -0
  226. package/src/worker-protocol/uplink/test-support.ts +188 -0
  227. package/src/worker-protocol/worker-mount.ts +27 -0
  228. package/src/worker-protocol/worker-state.ts +190 -0
  229. package/src/xml.ts +49 -0
  230. package/src/yaml.ts +15 -0
@@ -0,0 +1,177 @@
1
+ // Worker-side `home-proxy.sock` broker. Binds a unix socket; a granted app
2
+ // connects, sends one request line, and gets back one response line, relayed
3
+ // to Home as an `apiAccess` call on the worker's uplink — the app container
4
+ // holds no credential and reaches Home through nothing else.
5
+ //
6
+ // The broker owns the socket and the caller's identity: one socket per granted
7
+ // app, and the `forward` the worker injects is bound to that app's id, so a
8
+ // request's identity is the socket it arrived on and cannot be spelled by the
9
+ // caller. Which surface of Home the sub-path lands on, and the fence that
10
+ // keeps it there, are Home's — the worker builds no URL. The schema's literal
11
+ // `..`/`//` reject (protocol.ts) stays as cheap input hygiene at the door.
12
+
13
+ import { dirname } from "@std/path";
14
+ import {
15
+ homeProxyRequestSchema,
16
+ type HomeProxyRequest,
17
+ type HomeProxyResponse,
18
+ } from "./protocol.ts";
19
+
20
+ // Caps the raw request line so a hostile caller can't exhaust memory before
21
+ // the schema runs.
22
+ const MAX_REQUEST_BYTES = 64 * 1024;
23
+ // A caller must send its (small) request line within this window; bounds a
24
+ // slow-loris that connects and stalls to pin a connection/fd.
25
+ const REQUEST_READ_TIMEOUT_MS = 30 * 1000;
26
+ // Per-request budget for the relay to Home. Aborts on expiry so a hung Home
27
+ // can't pin the conn/fd forever.
28
+ const FORWARD_TIMEOUT_MS = 30 * 1000;
29
+
30
+ const encoder = new TextEncoder();
31
+ const decoder = new TextDecoder();
32
+
33
+ interface StartOpts {
34
+ /** Host path to bind this app's proxy socket at. Required — the worker
35
+ * passes the per-app `home-proxy/<appId>/home-proxy.sock` path (the socket
36
+ * sits alone in its own per-app dir; the server mkdirs the dir before
37
+ * binding). */
38
+ socketPath: string;
39
+ /**
40
+ * Relays one validated request to Home. The worker binds this to the
41
+ * `apiAccess` method with this socket's app id, so the identity travels with
42
+ * the closure rather than with anything the caller sent.
43
+ */
44
+ forward: (req: HomeProxyRequest) => Promise<HomeProxyResponse>;
45
+ }
46
+
47
+ interface ServerHandle {
48
+ /** Stop the server: close the listener, drop active conns, remove the socket file. */
49
+ stop(): Promise<void>;
50
+ }
51
+
52
+ export async function startHomeProxyServer(opts: StartOpts): Promise<ServerHandle> {
53
+ const socketPath = opts.socketPath;
54
+
55
+ // The socket lives alone in its own per-app directory: the app mounts the
56
+ // dir, not the socket file (a file bind-mount of a unix socket doesn't wire
57
+ // across containers on macOS Docker), and one socket per dir keeps an app
58
+ // from mounting a dir holding a sibling's socket.
59
+ await Deno.mkdir(dirname(socketPath), { recursive: true });
60
+ await Deno.remove(socketPath).catch(() => {});
61
+ const listener = Deno.listen({ transport: "unix", path: socketPath });
62
+ const conns = new Set<Deno.Conn>();
63
+
64
+ void acceptLoop(listener, conns, opts.forward);
65
+
66
+ return {
67
+ async stop() {
68
+ try {
69
+ listener.close();
70
+ } catch {}
71
+ for (const c of conns) {
72
+ try {
73
+ c.close();
74
+ } catch {}
75
+ }
76
+ conns.clear();
77
+ await Deno.remove(socketPath).catch(() => {});
78
+ },
79
+ };
80
+ }
81
+
82
+ type Forward = StartOpts["forward"];
83
+
84
+ async function acceptLoop(
85
+ listener: Deno.Listener,
86
+ conns: Set<Deno.Conn>,
87
+ forward: Forward,
88
+ ): Promise<void> {
89
+ try {
90
+ for await (const conn of listener) {
91
+ conns.add(conn);
92
+ handleConnection(conn as Deno.UnixConn, forward).finally(() => {
93
+ conns.delete(conn);
94
+ try {
95
+ conn.close();
96
+ } catch {}
97
+ });
98
+ }
99
+ } catch {
100
+ // Listener was closed via stop().
101
+ }
102
+ }
103
+
104
+ // One connection == one request. Every caller/forward failure is turned
105
+ // into a response line; nothing throws across the accept loop.
106
+ async function handleConnection(conn: Deno.UnixConn, forward: Forward): Promise<void> {
107
+ const writer = conn.writable.getWriter();
108
+ let res: HomeProxyResponse;
109
+ try {
110
+ const raw = await withTimeout(
111
+ readRequest(conn),
112
+ REQUEST_READ_TIMEOUT_MS,
113
+ "home proxy request read timed out",
114
+ );
115
+ let req: HomeProxyRequest;
116
+ try {
117
+ req = homeProxyRequestSchema.parse(JSON.parse(raw));
118
+ } catch (err) {
119
+ // Bad shape or unsafe path: reject with 400, never forward.
120
+ res = { status: 400, body: { error: (err as Error).message ?? String(err) } };
121
+ await writeLine(writer, res).catch(() => {});
122
+ return;
123
+ }
124
+ // The uplink is down, or Home refused: either way the app gets a 502, the
125
+ // same answer it got when this hop was a fetch.
126
+ res = await withTimeout(forward(req), FORWARD_TIMEOUT_MS, "home proxy forward timed out");
127
+ } catch (err) {
128
+ res = { status: 502, body: { error: (err as Error).message ?? String(err) } };
129
+ }
130
+ await writeLine(writer, res).catch(() => {});
131
+ try {
132
+ writer.releaseLock();
133
+ } catch {}
134
+ try {
135
+ conn.close();
136
+ } catch {}
137
+ }
138
+
139
+ // Read one `\n`-terminated request line, bounded. Mirrors the spawn server.
140
+ async function readRequest(conn: Deno.UnixConn): Promise<string> {
141
+ const buf = new Uint8Array(1);
142
+ const collected: number[] = [];
143
+ while (collected.length < MAX_REQUEST_BYTES) {
144
+ const n = await conn.read(buf);
145
+ if (n === null) break;
146
+ if (n === 0) continue;
147
+ if (buf[0] === 0x0a) break;
148
+ collected.push(buf[0]!);
149
+ }
150
+ if (collected.length >= MAX_REQUEST_BYTES) throw new Error("home proxy request too large");
151
+ const raw = decoder.decode(new Uint8Array(collected)).trim();
152
+ if (!raw) throw new Error("empty home proxy request");
153
+ return raw;
154
+ }
155
+
156
+ async function writeLine(
157
+ writer: WritableStreamDefaultWriter<Uint8Array>,
158
+ obj: HomeProxyResponse,
159
+ ): Promise<void> {
160
+ await writer.write(encoder.encode(JSON.stringify(obj) + "\n"));
161
+ }
162
+
163
+ // Race `p` against a wall-clock budget. The loser keeps running in the
164
+ // background; the read's pending op unblocks when the conn closes.
165
+ async function withTimeout<T>(p: Promise<T>, ms: number, message: string): Promise<T> {
166
+ let timer: ReturnType<typeof setTimeout> | undefined;
167
+ try {
168
+ return await Promise.race([
169
+ p,
170
+ new Promise<never>((_, reject) => {
171
+ timer = setTimeout(() => reject(new Error(message)), ms);
172
+ }),
173
+ ]);
174
+ } finally {
175
+ clearTimeout(timer);
176
+ }
177
+ }
@@ -0,0 +1,53 @@
1
+ // The `home-proxy.sock` wire contract. One newline-delimited JSON request
2
+ // in, one newline-delimited JSON response out, mirroring `spawn.sock`.
3
+ //
4
+ // The app supplies only a *sub-path*: which surface of Home it lands on, and
5
+ // the fence that keeps it there, are Home's — the worker relays the request as
6
+ // an `apiAccess` call and builds no URL. This schema is cheap input hygiene at
7
+ // the door: malformed shapes and literal `..`/`//`, not encoded traversal.
8
+
9
+ import { z } from "zod";
10
+
11
+ const MAX_PATH = 2048;
12
+
13
+ // Path-segment + query charset only: letters, digits, `-._~`, `/`, and the
14
+ // query chars `?=&%`. The absence of `:` and `\` means a sub-path can't
15
+ // carry a scheme (`://`), an authority, or a windows separator; control
16
+ // chars and spaces are excluded by the same allowlist.
17
+ const SAFE_SUBPATH = /^\/[A-Za-z0-9._~/?=&%-]*$/;
18
+
19
+ // Cheap pre-filter, NOT the security boundary (see the file header): catches
20
+ // malformed shape + obvious literal traversal at the door. Encoded traversal
21
+ // (`%2e%2e`) intentionally passes here and is caught by Home, which is the
22
+ // side that resolves the path against a real URL.
23
+ function isSafeSubPath(p: string): boolean {
24
+ if (!SAFE_SUBPATH.test(p)) return false; // leading "/" + charset
25
+ if (p.includes("..")) return false; // literal path traversal
26
+ if (p.includes("//")) return false; // empty segment / protocol-relative
27
+ return true;
28
+ }
29
+
30
+ /**
31
+ * One control-plane call: `method` + `path` + an optional JSON `body`, relayed
32
+ * to Home verbatim under the app id the socket belongs to.
33
+ */
34
+ export const homeProxyRequestSchema = z
35
+ .object({
36
+ method: z.enum(["GET", "POST", "PUT", "PATCH", "DELETE"]),
37
+ path: z.string().min(1).max(MAX_PATH).refine(isSafeSubPath, { message: "unsafe path" }),
38
+ body: z.unknown().optional(),
39
+ })
40
+ .strict();
41
+
42
+ export type HomeProxyRequest = z.infer<typeof homeProxyRequestSchema>;
43
+ export type HomeProxyMethod = HomeProxyRequest["method"];
44
+
45
+ /** The single line the broker writes back: Home's status + parsed body. */
46
+ export const homeProxyResponseSchema = z
47
+ .object({
48
+ status: z.number().int(),
49
+ body: z.unknown(),
50
+ })
51
+ .strict();
52
+
53
+ export type HomeProxyResponse = z.infer<typeof homeProxyResponseSchema>;