@boxxy/server 0.0.1 → 0.1.4
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 +57 -5
- package/dist/auth/authorize-call.d.ts +11 -0
- package/dist/auth/is-browser-request.d.ts +1 -0
- package/dist/auth/pick-request-scope.d.ts +9 -0
- package/dist/config/pick-server-secrets.d.ts +16 -0
- package/dist/config/read-caller-proof.d.ts +10 -0
- package/dist/config/read-server-config.d.ts +9 -0
- package/dist/config/read-trusted-issuers.d.ts +8 -0
- package/dist/config/server-config-schema.d.ts +42 -0
- package/dist/create-capacity-backoff.d.ts +2 -0
- package/dist/handlers/api.d.ts +1683 -0
- package/dist/handlers/attempt-handlers.d.ts +130 -0
- package/dist/handlers/build-owner-fact.d.ts +3 -0
- package/dist/handlers/item-handlers.d.ts +168 -0
- package/dist/handlers/outbox-handlers.d.ts +7 -0
- package/dist/handlers/plan-handlers.d.ts +62 -0
- package/dist/handlers/read-item-ids.d.ts +10 -0
- package/dist/handlers/relation-handlers.d.ts +41 -0
- package/dist/handlers/report-handlers.d.ts +102 -0
- package/dist/handlers/rules-handlers.d.ts +20 -0
- package/dist/handlers/runner-handlers.d.ts +65 -0
- package/dist/handlers/to-wire-json.d.ts +5 -0
- package/dist/handlers/write-levers.d.ts +11 -0
- package/dist/index.d.ts +12 -0
- package/dist/main.d.ts +1 -0
- package/dist/no-caller-proof.d.ts +2 -0
- package/dist/outbox/create-off-outbox.d.ts +3 -0
- package/dist/outbox/start-outbox-sender.d.ts +10 -0
- package/dist/read-limited-request.d.ts +1 -0
- package/dist/rules/create-rules-holder.d.ts +20 -0
- package/dist/rules/load-server-rules.d.ts +7 -0
- package/dist/rules/read-rules-checkout.d.ts +9 -0
- package/dist/serve-api.d.ts +50 -0
- package/dist/start-server.d.ts +18 -0
- package/dist/test-utils/build-mcp-request.d.ts +8 -0
- package/dist/test-utils/build-rpc-request.d.ts +7 -0
- package/dist/test-utils/build-session-input.d.ts +1 -0
- package/dist/test-utils/create-fake-caller-proof.d.ts +5 -0
- package/dist/test-utils/create-test-server.d.ts +35 -0
- package/dist/test-utils/list-owner-procedures.d.ts +5 -0
- package/dist/test-utils/read-mcp-answer.d.ts +11 -0
- package/dist/test-utils/wait-for.d.ts +1 -0
- package/dist/tick/run-tick.d.ts +24 -0
- package/dist/tick/start-tick-loop.d.ts +12 -0
- package/dist/types.d.ts +41 -0
- package/package.json +48 -4
- package/src/auth/authorize-call.ts +50 -0
- package/src/auth/is-browser-request.ts +8 -0
- package/src/auth/pick-request-scope.ts +37 -0
- package/src/config/pick-server-secrets.ts +48 -0
- package/src/config/read-caller-proof.ts +36 -0
- package/src/config/read-server-config.ts +41 -0
- package/src/config/read-trusted-issuers.ts +60 -0
- package/src/config/server-config-schema.ts +71 -0
- package/src/create-capacity-backoff.ts +18 -0
- package/src/handlers/api.ts +23 -0
- package/src/handlers/attempt-handlers.ts +244 -0
- package/src/handlers/build-owner-fact.ts +20 -0
- package/src/handlers/item-handlers.ts +462 -0
- package/src/handlers/outbox-handlers.ts +15 -0
- package/src/handlers/plan-handlers.ts +75 -0
- package/src/handlers/read-item-ids.ts +31 -0
- package/src/handlers/relation-handlers.ts +143 -0
- package/src/handlers/report-handlers.ts +112 -0
- package/src/handlers/rules-handlers.ts +46 -0
- package/src/handlers/runner-handlers.ts +117 -0
- package/src/handlers/to-wire-json.ts +20 -0
- package/src/handlers/write-levers.ts +53 -0
- package/src/index.ts +12 -0
- package/src/main.ts +31 -0
- package/src/no-caller-proof.ts +7 -0
- package/src/outbox/create-off-outbox.ts +21 -0
- package/src/outbox/start-outbox-sender.ts +89 -0
- package/src/read-limited-request.ts +43 -0
- package/src/rules/create-rules-holder.ts +107 -0
- package/src/rules/load-server-rules.ts +24 -0
- package/src/rules/read-rules-checkout.ts +65 -0
- package/src/serve-api.ts +178 -0
- package/src/start-server.ts +308 -0
- package/src/test-utils/build-mcp-request.ts +34 -0
- package/src/test-utils/build-rpc-request.ts +23 -0
- package/src/test-utils/build-session-input.ts +16 -0
- package/src/test-utils/create-fake-caller-proof.ts +18 -0
- package/src/test-utils/create-test-server.ts +166 -0
- package/src/test-utils/list-owner-procedures.ts +38 -0
- package/src/test-utils/read-mcp-answer.ts +26 -0
- package/src/test-utils/wait-for.ts +14 -0
- package/src/tick/run-tick.ts +212 -0
- package/src/tick/start-tick-loop.ts +46 -0
- package/src/types.ts +86 -0
package/README.md
CHANGED
|
@@ -1,7 +1,59 @@
|
|
|
1
|
-
|
|
1
|
+
<div align="center">
|
|
2
|
+
<h1>@boxxy/server</h1>
|
|
2
3
|
|
|
3
|
-
|
|
4
|
-
boxxy
|
|
4
|
+
<p>
|
|
5
|
+
<a href="https://www.npmjs.com/package/@boxxy/server"><img src="https://img.shields.io/npm/v/@boxxy/server" alt="npm version"></a>
|
|
6
|
+
<a href="./LICENSE"><img src="https://img.shields.io/badge/license-MIT-blue" alt="MIT license"></a>
|
|
7
|
+
</p>
|
|
5
8
|
|
|
6
|
-
|
|
7
|
-
|
|
9
|
+
<p>
|
|
10
|
+
<a href="../../docs/design/boxxy/README.md">Documentation</a>
|
|
11
|
+
</p>
|
|
12
|
+
</div>
|
|
13
|
+
|
|
14
|
+
The boxxy server: the API on its owner and worker listeners, and the runner tick that claims tasks,
|
|
15
|
+
reads sessions and sends the facts to pepys.
|
|
16
|
+
|
|
17
|
+
`startServer({ env, log })` reads the configuration file at `BOXXY_CONFIG`, the trust documents and
|
|
18
|
+
the tokens from the environment, then starts both listeners, the tick, the pull request watch and
|
|
19
|
+
the outbox sender. It answers `refused` with a message that names each missing variable and never a
|
|
20
|
+
secret value.
|
|
21
|
+
|
|
22
|
+
## Install
|
|
23
|
+
|
|
24
|
+
Install the package from [npm](https://www.npmjs.com/package/@boxxy/server) with Bun:
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
bun add @boxxy/server
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
The package runs on [Bun](https://bun.sh) 1.3 or newer.
|
|
31
|
+
|
|
32
|
+
## Usage
|
|
33
|
+
|
|
34
|
+
Set the configuration path and the tokens, then start the server from the package folder:
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
BOXXY_CONFIG=/etc/boxxy/boxxy.json \
|
|
38
|
+
BOXXY_WORKER_TOKEN=<worker_token> \
|
|
39
|
+
BOXXY_ATC_TOKEN=<atc_token> \
|
|
40
|
+
bun run start
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
- `<worker_token>` is the token the broker sends on every request to the worker listener.
|
|
44
|
+
- `<atc_token>` is the token the server sends to the atc daemon.
|
|
45
|
+
|
|
46
|
+
With a `pepys` section in the configuration, also set `BOXXY_PEPYS_SIGNING_SECRET`. With a `github`
|
|
47
|
+
section, set `BOXXY_GITHUB_TOKEN` unless a broker adds the GitHub credential.
|
|
48
|
+
|
|
49
|
+
## Features
|
|
50
|
+
|
|
51
|
+
- `startServer`, which wires the store, the atc worker and notifier, pepys and both listeners.
|
|
52
|
+
- `serveApi`, the two listeners as Elysia apps, for a caller that builds its own dependencies.
|
|
53
|
+
- `serverConfigSchema`, the configuration file's schema.
|
|
54
|
+
- `./test-utils/create-test-server`, the API on in-memory fakes, for tests.
|
|
55
|
+
|
|
56
|
+
## Documentation
|
|
57
|
+
|
|
58
|
+
[The API and its auth](../../docs/design/boxxy/v1-api-and-auth.md) sets out the listeners, the
|
|
59
|
+
tokens and which caller may call each procedure.
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { ProvenCall, RequestContext } from '../types.ts';
|
|
2
|
+
export type CallAuthorization = {
|
|
3
|
+
readonly kind: 'owner';
|
|
4
|
+
} | {
|
|
5
|
+
readonly kind: 'session';
|
|
6
|
+
readonly call: ProvenCall | null;
|
|
7
|
+
} | {
|
|
8
|
+
readonly kind: 'refused';
|
|
9
|
+
readonly code: 'UNAUTHORIZED' | 'FORBIDDEN';
|
|
10
|
+
};
|
|
11
|
+
export declare function authorizeCall(ctx: RequestContext, path: readonly string[]): Promise<CallAuthorization>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function isBrowserRequest(headers: Headers): boolean;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { Listener, RequestScope } from '../types.ts';
|
|
2
|
+
interface ScopeInput {
|
|
3
|
+
readonly listener: Listener;
|
|
4
|
+
readonly authorization: string | null;
|
|
5
|
+
readonly workerTokenDigest: Uint8Array;
|
|
6
|
+
}
|
|
7
|
+
export declare function pickRequestScope(input: ScopeInput): RequestScope | null;
|
|
8
|
+
export declare function buildTokenDigest(token: string): Uint8Array;
|
|
9
|
+
export {};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { ServerConfig } from './server-config-schema.ts';
|
|
2
|
+
interface ServerSecrets {
|
|
3
|
+
readonly workerToken: string;
|
|
4
|
+
readonly atcToken: string;
|
|
5
|
+
readonly pepysSigningSecret: string | null;
|
|
6
|
+
readonly githubToken: string | null;
|
|
7
|
+
}
|
|
8
|
+
export type SecretsAnswer = {
|
|
9
|
+
readonly kind: 'found';
|
|
10
|
+
readonly secrets: ServerSecrets;
|
|
11
|
+
} | {
|
|
12
|
+
readonly kind: 'missing';
|
|
13
|
+
readonly names: readonly string[];
|
|
14
|
+
};
|
|
15
|
+
export declare function pickServerSecrets(config: ServerConfig, env: Readonly<Record<string, string | undefined>>): SecretsAnswer;
|
|
16
|
+
export {};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { CallerProof, Clock } from '@boxxy/model';
|
|
2
|
+
import type { ServerConfig } from './server-config-schema.ts';
|
|
3
|
+
export type ProofAnswer = {
|
|
4
|
+
readonly kind: 'read';
|
|
5
|
+
readonly callerProof: CallerProof;
|
|
6
|
+
} | {
|
|
7
|
+
readonly kind: 'refused';
|
|
8
|
+
readonly message: string;
|
|
9
|
+
};
|
|
10
|
+
export declare function readCallerProof(trustedIssuers: ServerConfig['trustedIssuers'], clock: Clock): Promise<ProofAnswer>;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { ServerConfig } from './server-config-schema.ts';
|
|
2
|
+
export type ConfigAnswer = {
|
|
3
|
+
readonly kind: 'read';
|
|
4
|
+
readonly config: ServerConfig;
|
|
5
|
+
} | {
|
|
6
|
+
readonly kind: 'invalid';
|
|
7
|
+
readonly message: string;
|
|
8
|
+
};
|
|
9
|
+
export declare function readServerConfig(path: string): Promise<ConfigAnswer>;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
export declare const serverConfigSchema: z.ZodObject<{
|
|
3
|
+
runner: z.ZodString;
|
|
4
|
+
store: z.ZodObject<{
|
|
5
|
+
file: z.ZodString;
|
|
6
|
+
}, z.core.$strict>;
|
|
7
|
+
rules: z.ZodObject<{
|
|
8
|
+
folder: z.ZodString;
|
|
9
|
+
}, z.core.$strict>;
|
|
10
|
+
api: z.ZodObject<{
|
|
11
|
+
listen: z.ZodObject<{
|
|
12
|
+
hostname: z.ZodString;
|
|
13
|
+
port: z.ZodInt;
|
|
14
|
+
}, z.core.$strict>;
|
|
15
|
+
workerListen: z.ZodObject<{
|
|
16
|
+
hostname: z.ZodString;
|
|
17
|
+
port: z.ZodInt;
|
|
18
|
+
}, z.core.$strict>;
|
|
19
|
+
}, z.core.$strict>;
|
|
20
|
+
spawn: z.ZodObject<{
|
|
21
|
+
target: z.ZodString;
|
|
22
|
+
repoPaths: z.ZodRecord<z.ZodString, z.ZodString>;
|
|
23
|
+
}, z.core.$strict>;
|
|
24
|
+
atc: z.ZodObject<{
|
|
25
|
+
url: z.ZodURL;
|
|
26
|
+
trustedFolders: z.ZodRecord<z.ZodString, z.ZodArray<z.ZodString>>;
|
|
27
|
+
noticeSession: z.ZodOptional<z.ZodString>;
|
|
28
|
+
}, z.core.$strict>;
|
|
29
|
+
trustedIssuers: z.ZodOptional<z.ZodObject<{
|
|
30
|
+
folders: z.ZodArray<z.ZodString>;
|
|
31
|
+
audience: z.ZodString;
|
|
32
|
+
}, z.core.$strict>>;
|
|
33
|
+
pepys: z.ZodOptional<z.ZodObject<{
|
|
34
|
+
ingestUrl: z.ZodURL;
|
|
35
|
+
apiUrl: z.ZodURL;
|
|
36
|
+
environment: z.ZodString;
|
|
37
|
+
}, z.core.$strict>>;
|
|
38
|
+
github: z.ZodOptional<z.ZodObject<{
|
|
39
|
+
baseUrl: z.ZodURL;
|
|
40
|
+
}, z.core.$strict>>;
|
|
41
|
+
}, z.core.$strict>;
|
|
42
|
+
export type ServerConfig = z.infer<typeof serverConfigSchema>;
|