@andrewheberle/serverless-ssh-ca-testing 0.0.0-stage → 0.20.2
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 +84 -2
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +50 -0
- package/dist/cli.js.map +1 -0
- package/dist/config.d.ts +37 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +45 -0
- package/dist/config.js.map +1 -0
- package/dist/format.d.ts +27 -0
- package/dist/format.d.ts.map +1 -0
- package/dist/format.js +31 -0
- package/dist/format.js.map +1 -0
- package/dist/index.d.ts +21 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +68 -0
- package/dist/index.js.map +1 -0
- package/dist/log.d.ts +54 -0
- package/dist/log.d.ts.map +1 -0
- package/dist/log.js +88 -0
- package/dist/log.js.map +1 -0
- package/dist/node.d.ts +17 -0
- package/dist/node.d.ts.map +1 -0
- package/dist/node.js +98 -0
- package/dist/node.js.map +1 -0
- package/dist/server.d.ts +10 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +2 -0
- package/dist/server.js.map +1 -0
- package/dist/worker.d.ts +8 -0
- package/dist/worker.d.ts.map +1 -0
- package/dist/worker.js +25 -0
- package/dist/worker.js.map +1 -0
- package/dist/workerd.d.ts +24 -0
- package/dist/workerd.d.ts.map +1 -0
- package/dist/workerd.js +91 -0
- package/dist/workerd.js.map +1 -0
- package/package.json +72 -5
- package/src/cli.ts +57 -0
- package/src/config.ts +59 -0
- package/src/format.ts +33 -0
- package/src/index.ts +74 -0
- package/src/log.ts +98 -0
- package/src/node.ts +112 -0
- package/src/server.ts +9 -0
- package/src/worker.ts +30 -0
- package/src/workerd.ts +111 -0
package/README.md
CHANGED
|
@@ -1,3 +1,85 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @andrewheberle/serverless-ssh-ca-testing
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Runs the [Serverless SSH CA](../core/README.md) for end-to-end tests of
|
|
4
|
+
clients, such as [ssh-ca-client](https://github.com/andrewheberle/ssh-ca-client).
|
|
5
|
+
|
|
6
|
+
The CA can be run under:
|
|
7
|
+
|
|
8
|
+
- `node`: Node.js, using the package's Node.js helpers with an in-memory
|
|
9
|
+
`node:sqlite` database
|
|
10
|
+
- `workerd`: the Cloudflare Workers runtime, using the Wrangler test harness
|
|
11
|
+
with a local D1 database and Secrets Store, as `wrangler dev` would
|
|
12
|
+
|
|
13
|
+
Nothing is persisted between runs.
|
|
14
|
+
|
|
15
|
+
This package is released with `@andrewheberle/serverless-ssh-ca` and uses
|
|
16
|
+
whichever version of that package is installed alongside it. To test a client
|
|
17
|
+
against an unreleased version of the CA, install a tarball from `npm pack` in
|
|
18
|
+
its place.
|
|
19
|
+
|
|
20
|
+
## Requirements
|
|
21
|
+
|
|
22
|
+
Node.js 24 or later.
|
|
23
|
+
|
|
24
|
+
## Usage
|
|
25
|
+
|
|
26
|
+
```sh
|
|
27
|
+
npm install --save-dev @andrewheberle/serverless-ssh-ca @andrewheberle/serverless-ssh-ca-testing
|
|
28
|
+
npx serverless-ssh-ca-test-server [--runtime node|workerd] config.json
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
The runtime defaults to `node`. Clients that start the server from another
|
|
32
|
+
language can run `node node_modules/@andrewheberle/serverless-ssh-ca-testing/dist/cli.js`,
|
|
33
|
+
which avoids the platform-specific shims in `node_modules/.bin`.
|
|
34
|
+
|
|
35
|
+
The server exits when its standard input is closed, so it does not outlive
|
|
36
|
+
the test that started it. If it cannot start, it writes the reason to
|
|
37
|
+
standard error and exits with status 1.
|
|
38
|
+
|
|
39
|
+
## Configuration
|
|
40
|
+
|
|
41
|
+
The configuration file is a JSON object:
|
|
42
|
+
|
|
43
|
+
| Property | Description |
|
|
44
|
+
|---------------|--------------------------------------------------------------------------|
|
|
45
|
+
| `private_key` | The CA private key in OpenSSH format |
|
|
46
|
+
| `bindings` | The CA configuration, as the Workers vars (environment variables) |
|
|
47
|
+
| `port_file` | Path the port is written to once the CA is listening on `127.0.0.1` |
|
|
48
|
+
| `log_file` | Path that log output from the CA and harness is appended to as JSON lines |
|
|
49
|
+
|
|
50
|
+
The bindings are those documented for the CA, with every value as a string.
|
|
51
|
+
Under `workerd`, Wrangler's working files are written to the directory
|
|
52
|
+
containing the configuration file.
|
|
53
|
+
|
|
54
|
+
## Log file
|
|
55
|
+
|
|
56
|
+
Each line of the log file is a JSON object with at least `level` and
|
|
57
|
+
`message`. Lines logged by the CA are written as they are, and the harness adds
|
|
58
|
+
lines whose `message` starts with `harness`:
|
|
59
|
+
|
|
60
|
+
- `{"level":"info","message":"harness request","method":...,"url":...,"status":...}`
|
|
61
|
+
for every request, where `url` is the path and query. When `status` is 400
|
|
62
|
+
or more, `body` holds the response body, so a test can check why a request
|
|
63
|
+
was rejected.
|
|
64
|
+
- `{"level":"error","message":"harness ...",...}` for a fault, meaning the CA
|
|
65
|
+
or harness failed rather than rejected a request. Some faults, such as a
|
|
66
|
+
failure to record an issued certificate, are only visible in the log, so
|
|
67
|
+
tests should fail if any of these lines appear. A CA log line that
|
|
68
|
+
indicates a fault is followed by a line with the message `harness fault`
|
|
69
|
+
and the original line in `line`.
|
|
70
|
+
|
|
71
|
+
Under `workerd`, the CA's output is copied to the log file every 100ms, so a
|
|
72
|
+
request may be logged shortly after its response is received.
|
|
73
|
+
|
|
74
|
+
## Programmatic use
|
|
75
|
+
|
|
76
|
+
```ts
|
|
77
|
+
import { startTestServer } from "@andrewheberle/serverless-ssh-ca-testing"
|
|
78
|
+
|
|
79
|
+
const server = await startTestServer("node", "config.json")
|
|
80
|
+
// make requests to http://127.0.0.1:${server.port}
|
|
81
|
+
await server.close()
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
Under `node` the CA's `console` output is redirected to the log file until the
|
|
85
|
+
server is closed.
|
package/dist/cli.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":""}
|
package/dist/cli.js
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// Runs the Serverless SSH CA for end-to-end tests of clients.
|
|
3
|
+
//
|
|
4
|
+
// Usage: serverless-ssh-ca-test-server [--runtime node|workerd] <config.json>
|
|
5
|
+
//
|
|
6
|
+
// The process exits when its stdin is closed, so it does not outlive the test
|
|
7
|
+
// that started it.
|
|
8
|
+
import { parseArgs } from "node:util";
|
|
9
|
+
import z from "zod";
|
|
10
|
+
import { readConfig, RuntimeSchema } from "./config.js";
|
|
11
|
+
import { startTestServer } from "./index.js";
|
|
12
|
+
import { LogFile } from "./log.js";
|
|
13
|
+
const usage = "usage: serverless-ssh-ca-test-server [--runtime node|workerd] <config.json>";
|
|
14
|
+
const main = async () => {
|
|
15
|
+
const { values, positionals } = parseArgs({
|
|
16
|
+
options: {
|
|
17
|
+
runtime: { type: "string", default: "node" },
|
|
18
|
+
},
|
|
19
|
+
allowPositionals: true,
|
|
20
|
+
});
|
|
21
|
+
const runtime = RuntimeSchema.safeParse(values.runtime);
|
|
22
|
+
if (!runtime.success) {
|
|
23
|
+
throw new Error(`--runtime ${z.prettifyError(runtime.error)}\n${usage}`);
|
|
24
|
+
}
|
|
25
|
+
const [configFile, ...extra] = positionals;
|
|
26
|
+
if (configFile === undefined || extra.length > 0) {
|
|
27
|
+
throw new Error(usage);
|
|
28
|
+
}
|
|
29
|
+
// faults after start up are written to the log file, where the test
|
|
30
|
+
// reading it will find them
|
|
31
|
+
const config = await readConfig(configFile);
|
|
32
|
+
const log = new LogFile(config.log_file);
|
|
33
|
+
process.on("uncaughtException", (err) => {
|
|
34
|
+
log.fault("uncaught exception", err);
|
|
35
|
+
process.exit(1);
|
|
36
|
+
});
|
|
37
|
+
const server = await startTestServer(runtime.data, configFile);
|
|
38
|
+
process.stdin.on("end", () => {
|
|
39
|
+
server.close().then(() => process.exit(0), (err) => {
|
|
40
|
+
log.fault("close failed", err);
|
|
41
|
+
process.exit(1);
|
|
42
|
+
});
|
|
43
|
+
});
|
|
44
|
+
process.stdin.resume();
|
|
45
|
+
};
|
|
46
|
+
main().catch((err) => {
|
|
47
|
+
console.error(err instanceof Error ? err.message : err);
|
|
48
|
+
process.exit(1);
|
|
49
|
+
});
|
|
50
|
+
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA,8DAA8D;AAC9D,EAAE;AACF,8EAA8E;AAC9E,EAAE;AACF,8EAA8E;AAC9E,mBAAmB;AACnB,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAA;AACrC,OAAO,CAAC,MAAM,KAAK,CAAA;AACnB,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AACvD,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAA;AAC5C,OAAO,EAAE,OAAO,EAAE,MAAM,UAAU,CAAA;AAElC,MAAM,KAAK,GAAG,6EAA6E,CAAA;AAE3F,MAAM,IAAI,GAAG,KAAK,IAAmB,EAAE;IACtC,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,GAAG,SAAS,CAAC;QACzC,OAAO,EAAE;YACR,OAAO,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,EAAE;SAC5C;QACD,gBAAgB,EAAE,IAAI;KACtB,CAAC,CAAA;IAEF,MAAM,OAAO,GAAG,aAAa,CAAC,SAAS,CAAC,MAAM,CAAC,OAAO,CAAC,CAAA;IACvD,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC;QACtB,MAAM,IAAI,KAAK,CAAC,aAAa,CAAC,CAAC,aAAa,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,KAAK,EAAE,CAAC,CAAA;IACzE,CAAC;IAED,MAAM,CAAC,UAAU,EAAE,GAAG,KAAK,CAAC,GAAG,WAAW,CAAA;IAC1C,IAAI,UAAU,KAAK,SAAS,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAClD,MAAM,IAAI,KAAK,CAAC,KAAK,CAAC,CAAA;IACvB,CAAC;IAED,oEAAoE;IACpE,4BAA4B;IAC5B,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,UAAU,CAAC,CAAA;IAC3C,MAAM,GAAG,GAAG,IAAI,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAA;IACxC,OAAO,CAAC,EAAE,CAAC,mBAAmB,EAAE,CAAC,GAAG,EAAE,EAAE;QACvC,GAAG,CAAC,KAAK,CAAC,oBAAoB,EAAE,GAAG,CAAC,CAAA;QACpC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IAChB,CAAC,CAAC,CAAA;IAEF,MAAM,MAAM,GAAG,MAAM,eAAe,CAAC,OAAO,CAAC,IAAI,EAAE,UAAU,CAAC,CAAA;IAE9D,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE;QAC5B,MAAM,CAAC,KAAK,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,GAAY,EAAE,EAAE;YAC3D,GAAG,CAAC,KAAK,CAAC,cAAc,EAAE,GAAG,CAAC,CAAA;YAC9B,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;QAChB,CAAC,CAAC,CAAA;IACH,CAAC,CAAC,CAAA;IACF,OAAO,CAAC,KAAK,CAAC,MAAM,EAAE,CAAA;AACvB,CAAC,CAAA;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,GAAY,EAAE,EAAE;IAC7B,OAAO,CAAC,KAAK,CAAC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAA;IACvD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;AAChB,CAAC,CAAC,CAAA"}
|
package/dist/config.d.ts
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import z from "zod";
|
|
2
|
+
/**
|
|
3
|
+
* The runtimes the CA can be run under by {@link startTestServer}: `node` uses
|
|
4
|
+
* the package's Node.js helpers with an in-memory `node:sqlite` database, and
|
|
5
|
+
* `workerd` uses the Cloudflare Workers runtime with a local D1 database and
|
|
6
|
+
* Secrets Store.
|
|
7
|
+
*/
|
|
8
|
+
export declare const RuntimeSchema: z.ZodEnum<{
|
|
9
|
+
node: "node";
|
|
10
|
+
workerd: "workerd";
|
|
11
|
+
}>;
|
|
12
|
+
/**
|
|
13
|
+
* A runtime the CA can be run under, see {@link RuntimeSchema}.
|
|
14
|
+
*/
|
|
15
|
+
export type Runtime = z.infer<typeof RuntimeSchema>;
|
|
16
|
+
/**
|
|
17
|
+
* The configuration file read by {@link readConfig}.
|
|
18
|
+
*/
|
|
19
|
+
export declare const ConfigSchema: z.ZodObject<{
|
|
20
|
+
private_key: z.ZodString;
|
|
21
|
+
bindings: z.ZodRecord<z.ZodString, z.ZodString>;
|
|
22
|
+
port_file: z.ZodString;
|
|
23
|
+
log_file: z.ZodString;
|
|
24
|
+
}, z.core.$strip>;
|
|
25
|
+
/**
|
|
26
|
+
* The configuration of a test server, see {@link ConfigSchema}.
|
|
27
|
+
*/
|
|
28
|
+
export type TestServerConfig = z.infer<typeof ConfigSchema>;
|
|
29
|
+
/**
|
|
30
|
+
* Read and validate a test server configuration file.
|
|
31
|
+
*
|
|
32
|
+
* @param path The path of a JSON file matching {@link ConfigSchema}
|
|
33
|
+
* @returns The validated configuration
|
|
34
|
+
* @throws Error if the file cannot be read, is not JSON or is not a valid configuration
|
|
35
|
+
*/
|
|
36
|
+
export declare const readConfig: (path: string) => Promise<TestServerConfig>;
|
|
37
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AACA,OAAO,CAAC,MAAM,KAAK,CAAA;AAEnB;;;;;GAKG;AACH,eAAO,MAAM,aAAa;;;EAA8B,CAAA;AAExD;;GAEG;AACH,MAAM,MAAM,OAAO,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,aAAa,CAAC,CAAA;AAEnD;;GAEG;AACH,eAAO,MAAM,YAAY;;;;;iBASvB,CAAA;AAEF;;GAEG;AACH,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,YAAY,CAAC,CAAA;AAE3D;;;;;;GAMG;AACH,eAAO,MAAM,UAAU,SAAgB,MAAM,KAAG,OAAO,CAAC,gBAAgB,CAgBvE,CAAA"}
|
package/dist/config.js
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { readFile } from "node:fs/promises";
|
|
2
|
+
import z from "zod";
|
|
3
|
+
/**
|
|
4
|
+
* The runtimes the CA can be run under by {@link startTestServer}: `node` uses
|
|
5
|
+
* the package's Node.js helpers with an in-memory `node:sqlite` database, and
|
|
6
|
+
* `workerd` uses the Cloudflare Workers runtime with a local D1 database and
|
|
7
|
+
* Secrets Store.
|
|
8
|
+
*/
|
|
9
|
+
export const RuntimeSchema = z.enum(["node", "workerd"]);
|
|
10
|
+
/**
|
|
11
|
+
* The configuration file read by {@link readConfig}.
|
|
12
|
+
*/
|
|
13
|
+
export const ConfigSchema = z.object({
|
|
14
|
+
/** The CA private key in OpenSSH format */
|
|
15
|
+
private_key: z.string().min(1),
|
|
16
|
+
/** The CA configuration, as the Workers vars (environment variables) */
|
|
17
|
+
bindings: z.record(z.string(), z.string()),
|
|
18
|
+
/** Path the listening port is written to once the CA is ready */
|
|
19
|
+
port_file: z.string().min(1),
|
|
20
|
+
/** Path that log output from the CA and harness is appended to */
|
|
21
|
+
log_file: z.string().min(1),
|
|
22
|
+
});
|
|
23
|
+
/**
|
|
24
|
+
* Read and validate a test server configuration file.
|
|
25
|
+
*
|
|
26
|
+
* @param path The path of a JSON file matching {@link ConfigSchema}
|
|
27
|
+
* @returns The validated configuration
|
|
28
|
+
* @throws Error if the file cannot be read, is not JSON or is not a valid configuration
|
|
29
|
+
*/
|
|
30
|
+
export const readConfig = async (path) => {
|
|
31
|
+
const text = await readFile(path, { encoding: "utf-8" });
|
|
32
|
+
let json;
|
|
33
|
+
try {
|
|
34
|
+
json = JSON.parse(text);
|
|
35
|
+
}
|
|
36
|
+
catch (err) {
|
|
37
|
+
throw new Error(`parsing ${path}: ${err instanceof Error ? err.message : String(err)}`, { cause: err });
|
|
38
|
+
}
|
|
39
|
+
const result = ConfigSchema.safeParse(json);
|
|
40
|
+
if (!result.success) {
|
|
41
|
+
throw new Error(`invalid configuration in ${path}:\n${z.prettifyError(result.error)}`);
|
|
42
|
+
}
|
|
43
|
+
return result.data;
|
|
44
|
+
};
|
|
45
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAA;AAC3C,OAAO,CAAC,MAAM,KAAK,CAAA;AAEnB;;;;;GAKG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC,CAAA;AAOxD;;GAEG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,CAAC,MAAM,CAAC;IACpC,2CAA2C;IAC3C,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IAC9B,wEAAwE;IACxE,QAAQ,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC;IAC1C,iEAAiE;IACjE,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IAC5B,kEAAkE;IAClE,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;CAC3B,CAAC,CAAA;AAOF;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,UAAU,GAAG,KAAK,EAAE,IAAY,EAA6B,EAAE;IAC3E,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC,CAAA;IAExD,IAAI,IAAa,CAAA;IACjB,IAAI,CAAC;QACJ,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;IACxB,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACd,MAAM,IAAI,KAAK,CAAC,WAAW,IAAI,KAAK,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,CAAA;IACxG,CAAC;IAED,MAAM,MAAM,GAAG,YAAY,CAAC,SAAS,CAAC,IAAI,CAAC,CAAA;IAC3C,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;QACrB,MAAM,IAAI,KAAK,CAAC,4BAA4B,IAAI,MAAM,CAAC,CAAC,aAAa,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAA;IACvF,CAAC;IAED,OAAO,MAAM,CAAC,IAAI,CAAA;AACnB,CAAC,CAAA"}
|
package/dist/format.d.ts
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Format a value logged by the CA as text, with objects as JSON so log lines
|
|
3
|
+
* from the CA's logger are written as JSON lines.
|
|
4
|
+
*
|
|
5
|
+
* @param value A value passed to a `console` method
|
|
6
|
+
* @returns The value as a string
|
|
7
|
+
*/
|
|
8
|
+
export declare const formatValue: (value: unknown) => string;
|
|
9
|
+
/**
|
|
10
|
+
* Format the arguments to a `console` method as a single line.
|
|
11
|
+
*
|
|
12
|
+
* @param args The arguments passed to a `console` method
|
|
13
|
+
* @returns The arguments formatted with {@link formatValue}, separated by spaces
|
|
14
|
+
*/
|
|
15
|
+
export declare const formatArgs: (args: readonly unknown[]) => string;
|
|
16
|
+
/**
|
|
17
|
+
* Format a request handled by the CA as a log line, including the response
|
|
18
|
+
* body when the request was rejected.
|
|
19
|
+
*
|
|
20
|
+
* @param method The request method
|
|
21
|
+
* @param url The path and query of the request
|
|
22
|
+
* @param status The response status code
|
|
23
|
+
* @param body The response body
|
|
24
|
+
* @returns A JSON line with the message "harness request"
|
|
25
|
+
*/
|
|
26
|
+
export declare const formatRequest: (method: string, url: string, status: number, body: string) => string;
|
|
27
|
+
//# sourceMappingURL=format.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"format.d.ts","sourceRoot":"","sources":["../src/format.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,eAAO,MAAM,WAAW,UAAW,OAAO,KAAG,MAIA,CAAA;AAE7C;;;;;GAKG;AACH,eAAO,MAAM,UAAU,SAAU,SAAS,OAAO,EAAE,KAAG,MAAyC,CAAA;AAE/F;;;;;;;;;GASG;AACH,eAAO,MAAM,aAAa,WAAY,MAAM,OAAO,MAAM,UAAU,MAAM,QAAQ,MAAM,KAAG,MAC0B,CAAA"}
|
package/dist/format.js
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Format a value logged by the CA as text, with objects as JSON so log lines
|
|
3
|
+
* from the CA's logger are written as JSON lines.
|
|
4
|
+
*
|
|
5
|
+
* @param value A value passed to a `console` method
|
|
6
|
+
* @returns The value as a string
|
|
7
|
+
*/
|
|
8
|
+
export const formatValue = (value) => typeof value === "string"
|
|
9
|
+
? value
|
|
10
|
+
: JSON.stringify(value, (_, x) => x instanceof Error
|
|
11
|
+
? { name: x.name, message: x.message, stack: x.stack }
|
|
12
|
+
: typeof x === "bigint" ? x.toString() : x);
|
|
13
|
+
/**
|
|
14
|
+
* Format the arguments to a `console` method as a single line.
|
|
15
|
+
*
|
|
16
|
+
* @param args The arguments passed to a `console` method
|
|
17
|
+
* @returns The arguments formatted with {@link formatValue}, separated by spaces
|
|
18
|
+
*/
|
|
19
|
+
export const formatArgs = (args) => args.map(formatValue).join(" ");
|
|
20
|
+
/**
|
|
21
|
+
* Format a request handled by the CA as a log line, including the response
|
|
22
|
+
* body when the request was rejected.
|
|
23
|
+
*
|
|
24
|
+
* @param method The request method
|
|
25
|
+
* @param url The path and query of the request
|
|
26
|
+
* @param status The response status code
|
|
27
|
+
* @param body The response body
|
|
28
|
+
* @returns A JSON line with the message "harness request"
|
|
29
|
+
*/
|
|
30
|
+
export const formatRequest = (method, url, status, body) => formatValue({ level: "info", message: "harness request", method, url, status, ...(status >= 400 ? { body } : {}) });
|
|
31
|
+
//# sourceMappingURL=format.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"format.js","sourceRoot":"","sources":["../src/format.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,KAAc,EAAU,EAAE,CAAC,OAAO,KAAK,KAAK,QAAQ;IAC/E,CAAC,CAAC,KAAK;IACP,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,CAAC,CAAC,EAAE,CAAU,EAAE,EAAE,CAAC,CAAC,YAAY,KAAK;QAC5D,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE;QACtD,CAAC,CAAC,OAAO,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;AAE7C;;;;;GAKG;AACH,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,IAAwB,EAAU,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;AAE/F;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,MAAc,EAAE,GAAW,EAAE,MAAc,EAAE,IAAY,EAAU,EAAE,CAClG,WAAW,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,iBAAiB,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,IAAI,GAAG,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAA"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { type Runtime } from "./config.js";
|
|
2
|
+
import type { TestServer } from "./server.js";
|
|
3
|
+
export { ConfigSchema, readConfig, RuntimeSchema } from "./config.js";
|
|
4
|
+
export type { Runtime, TestServerConfig } from "./config.js";
|
|
5
|
+
export { FAULT_MESSAGE, FAULT_MESSAGES, isFault, LogFile } from "./log.js";
|
|
6
|
+
export type { TestServer } from "./server.js";
|
|
7
|
+
/**
|
|
8
|
+
* Start the CA under `runtime` using the configuration in `configFile` (see
|
|
9
|
+
* {@link ConfigSchema}), then write the port it is listening on to the
|
|
10
|
+
* configuration's `port_file`.
|
|
11
|
+
*
|
|
12
|
+
* Output from the CA and harness is appended to the configuration's
|
|
13
|
+
* `log_file`, see {@link LogFile}. Under workerd, Wrangler's working files are
|
|
14
|
+
* written to the directory containing `configFile`.
|
|
15
|
+
*
|
|
16
|
+
* @param runtime The runtime to run the CA under, see {@link Runtime}
|
|
17
|
+
* @param configFile The path of the configuration file
|
|
18
|
+
* @returns The running server, see {@link TestServer}
|
|
19
|
+
*/
|
|
20
|
+
export declare const startTestServer: (runtime: Runtime, configFile: string) => Promise<TestServer>;
|
|
21
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAqBA,OAAO,EAAc,KAAK,OAAO,EAAE,MAAM,aAAa,CAAA;AAGtD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AAE7C,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AACrE,YAAY,EAAE,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAA;AAC5D,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,UAAU,CAAA;AAC1E,YAAY,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AAE7C;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,eAAe,YAAmB,OAAO,cAAc,MAAM,KAAG,OAAO,CAAC,UAAU,CA6B9F,CAAA"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Runs the Serverless SSH CA for end-to-end tests of clients, under Node.js or
|
|
3
|
+
* workerd, configured from a file and reporting what it does through a log
|
|
4
|
+
* file of JSON lines (see {@link LogFile}).
|
|
5
|
+
*
|
|
6
|
+
* Most clients run the `serverless-ssh-ca-test-server` command rather than
|
|
7
|
+
* using this module directly.
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```ts
|
|
11
|
+
* import { startTestServer } from "@andrewheberle/serverless-ssh-ca-testing"
|
|
12
|
+
*
|
|
13
|
+
* const server = await startTestServer("node", "config.json")
|
|
14
|
+
* // make requests to http://127.0.0.1:${server.port}
|
|
15
|
+
* await server.close()
|
|
16
|
+
* ```
|
|
17
|
+
*
|
|
18
|
+
* @packageDocumentation
|
|
19
|
+
*/
|
|
20
|
+
import { writeFile } from "node:fs/promises";
|
|
21
|
+
import { dirname, resolve } from "node:path";
|
|
22
|
+
import { readConfig } from "./config.js";
|
|
23
|
+
import { LogFile } from "./log.js";
|
|
24
|
+
import { startNode } from "./node.js";
|
|
25
|
+
export { ConfigSchema, readConfig, RuntimeSchema } from "./config.js";
|
|
26
|
+
export { FAULT_MESSAGE, FAULT_MESSAGES, isFault, LogFile } from "./log.js";
|
|
27
|
+
/**
|
|
28
|
+
* Start the CA under `runtime` using the configuration in `configFile` (see
|
|
29
|
+
* {@link ConfigSchema}), then write the port it is listening on to the
|
|
30
|
+
* configuration's `port_file`.
|
|
31
|
+
*
|
|
32
|
+
* Output from the CA and harness is appended to the configuration's
|
|
33
|
+
* `log_file`, see {@link LogFile}. Under workerd, Wrangler's working files are
|
|
34
|
+
* written to the directory containing `configFile`.
|
|
35
|
+
*
|
|
36
|
+
* @param runtime The runtime to run the CA under, see {@link Runtime}
|
|
37
|
+
* @param configFile The path of the configuration file
|
|
38
|
+
* @returns The running server, see {@link TestServer}
|
|
39
|
+
*/
|
|
40
|
+
export const startTestServer = async (runtime, configFile) => {
|
|
41
|
+
const config = await readConfig(configFile);
|
|
42
|
+
const log = new LogFile(config.log_file);
|
|
43
|
+
let server;
|
|
44
|
+
switch (runtime) {
|
|
45
|
+
case "node":
|
|
46
|
+
server = await startNode(config, log);
|
|
47
|
+
break;
|
|
48
|
+
case "workerd": {
|
|
49
|
+
// loaded on demand as importing Wrangler is slow
|
|
50
|
+
const { startWorkerd } = await import("./workerd.js");
|
|
51
|
+
server = await startWorkerd(config, log, dirname(resolve(configFile)));
|
|
52
|
+
break;
|
|
53
|
+
}
|
|
54
|
+
default: {
|
|
55
|
+
const unknown = runtime;
|
|
56
|
+
throw new Error(`unknown runtime: ${String(unknown)}`);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
try {
|
|
60
|
+
await writeFile(config.port_file, String(server.port));
|
|
61
|
+
}
|
|
62
|
+
catch (err) {
|
|
63
|
+
await server.close();
|
|
64
|
+
throw err;
|
|
65
|
+
}
|
|
66
|
+
return server;
|
|
67
|
+
};
|
|
68
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AACH,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAA;AAC5C,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAC5C,OAAO,EAAE,UAAU,EAAgB,MAAM,aAAa,CAAA;AACtD,OAAO,EAAE,OAAO,EAAE,MAAM,UAAU,CAAA;AAClC,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAA;AAGrC,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAErE,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,UAAU,CAAA;AAG1E;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,KAAK,EAAE,OAAgB,EAAE,UAAkB,EAAuB,EAAE;IAClG,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,UAAU,CAAC,CAAA;IAC3C,MAAM,GAAG,GAAG,IAAI,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAA;IAExC,IAAI,MAAkB,CAAA;IACtB,QAAQ,OAAO,EAAE,CAAC;QACjB,KAAK,MAAM;YACV,MAAM,GAAG,MAAM,SAAS,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;YACrC,MAAK;QACN,KAAK,SAAS,EAAE,CAAC;YAChB,iDAAiD;YACjD,MAAM,EAAE,YAAY,EAAE,GAAG,MAAM,MAAM,CAAC,cAAc,CAAC,CAAA;YACrD,MAAM,GAAG,MAAM,YAAY,CAAC,MAAM,EAAE,GAAG,EAAE,OAAO,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,CAAA;YACtE,MAAK;QACN,CAAC;QACD,SAAS,CAAC;YACT,MAAM,OAAO,GAAU,OAAO,CAAA;YAC9B,MAAM,IAAI,KAAK,CAAC,oBAAoB,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,CAAA;QACvD,CAAC;IACF,CAAC;IAED,IAAI,CAAC;QACJ,MAAM,SAAS,CAAC,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAA;IACvD,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACd,MAAM,MAAM,CAAC,KAAK,EAAE,CAAA;QACpB,MAAM,GAAG,CAAA;IACV,CAAC;IAED,OAAO,MAAM,CAAA;AACd,CAAC,CAAA"}
|
package/dist/log.d.ts
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Messages the CA logs at error level when it has failed rather than rejected
|
|
3
|
+
* a request, see {@link isFault}.
|
|
4
|
+
*/
|
|
5
|
+
export declare const FAULT_MESSAGES: readonly string[];
|
|
6
|
+
/**
|
|
7
|
+
* The message of the line written by {@link LogFile.write} after a CA log line
|
|
8
|
+
* that indicates a fault.
|
|
9
|
+
*/
|
|
10
|
+
export declare const FAULT_MESSAGE = "harness fault";
|
|
11
|
+
/**
|
|
12
|
+
* Report whether a line logged by the CA indicates a fault, such as a database
|
|
13
|
+
* error, rather than an expected rejection of a request. Some faults are only
|
|
14
|
+
* logged, as the CA still issues a certificate when it cannot record it.
|
|
15
|
+
*
|
|
16
|
+
* @param line A line of output from the CA
|
|
17
|
+
* @returns true if the line is an error logged by the CA for a fault
|
|
18
|
+
*/
|
|
19
|
+
export declare const isFault: (line: string) => boolean;
|
|
20
|
+
/**
|
|
21
|
+
* The log file of a test server, written as JSON lines.
|
|
22
|
+
*
|
|
23
|
+
* Lines from the CA are written as they are logged. The harness adds the
|
|
24
|
+
* following lines, whose messages all start with "harness":
|
|
25
|
+
*
|
|
26
|
+
* - `{"level":"info","message":"harness request",...}` for each request, with
|
|
27
|
+
* `method`, `url`, `status` and, when `status` is 400 or more, the response
|
|
28
|
+
* `body`.
|
|
29
|
+
* - `{"level":"error","message":"harness ...",...}` for a fault in the CA or
|
|
30
|
+
* harness. A CA log line that indicates a fault (see {@link isFault}) is
|
|
31
|
+
* followed by a line with the message {@link FAULT_MESSAGE}.
|
|
32
|
+
*/
|
|
33
|
+
export declare class LogFile {
|
|
34
|
+
readonly path: string;
|
|
35
|
+
constructor(path: string);
|
|
36
|
+
/**
|
|
37
|
+
* Append a line of output from the CA, followed by a fault line if it
|
|
38
|
+
* indicates a fault.
|
|
39
|
+
*/
|
|
40
|
+
write(line: string): void;
|
|
41
|
+
/**
|
|
42
|
+
* Append a request handled by the CA.
|
|
43
|
+
*/
|
|
44
|
+
request(method: string, url: string, status: number, body: string): void;
|
|
45
|
+
/**
|
|
46
|
+
* Append a fault in the harness.
|
|
47
|
+
*
|
|
48
|
+
* @param message A description of the fault, which is prefixed with "harness"
|
|
49
|
+
* @param error The error that caused the fault
|
|
50
|
+
*/
|
|
51
|
+
fault(message: string, error: unknown): void;
|
|
52
|
+
private append;
|
|
53
|
+
}
|
|
54
|
+
//# sourceMappingURL=log.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"log.d.ts","sourceRoot":"","sources":["../src/log.ts"],"names":[],"mappings":"AAIA;;;GAGG;AACH,eAAO,MAAM,cAAc,EAAE,SAAS,MAAM,EAAwD,CAAA;AAEpG;;;GAGG;AACH,eAAO,MAAM,aAAa,kBAAkB,CAAA;AAQ5C;;;;;;;GAOG;AACH,eAAO,MAAM,OAAO,SAAU,MAAM,KAAG,OActC,CAAA;AAED;;;;;;;;;;;;GAYG;AACH,qBAAa,OAAO;IACnB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IAErB,YAAY,IAAI,EAAE,MAAM,EAEvB;IAED;;;OAGG;IACH,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAKxB;IAED;;OAEG;IACH,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAEvE;IAED;;;;;OAKG;IACH,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,IAAI,CAE3C;IAED,OAAO,CAAC,MAAM;CAGd"}
|
package/dist/log.js
ADDED
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { appendFileSync } from "node:fs";
|
|
2
|
+
import z from "zod";
|
|
3
|
+
import { formatRequest, formatValue } from "./format.js";
|
|
4
|
+
/**
|
|
5
|
+
* Messages the CA logs at error level when it has failed rather than rejected
|
|
6
|
+
* a request, see {@link isFault}.
|
|
7
|
+
*/
|
|
8
|
+
export const FAULT_MESSAGES = ["unhandled error", "unexpected error from router"];
|
|
9
|
+
/**
|
|
10
|
+
* The message of the line written by {@link LogFile.write} after a CA log line
|
|
11
|
+
* that indicates a fault.
|
|
12
|
+
*/
|
|
13
|
+
export const FAULT_MESSAGE = "harness fault";
|
|
14
|
+
// the fields of a CA log line used to detect faults
|
|
15
|
+
const LogLineSchema = z.object({
|
|
16
|
+
level: z.string(),
|
|
17
|
+
message: z.string(),
|
|
18
|
+
});
|
|
19
|
+
/**
|
|
20
|
+
* Report whether a line logged by the CA indicates a fault, such as a database
|
|
21
|
+
* error, rather than an expected rejection of a request. Some faults are only
|
|
22
|
+
* logged, as the CA still issues a certificate when it cannot record it.
|
|
23
|
+
*
|
|
24
|
+
* @param line A line of output from the CA
|
|
25
|
+
* @returns true if the line is an error logged by the CA for a fault
|
|
26
|
+
*/
|
|
27
|
+
export const isFault = (line) => {
|
|
28
|
+
let json;
|
|
29
|
+
try {
|
|
30
|
+
json = JSON.parse(line);
|
|
31
|
+
}
|
|
32
|
+
catch {
|
|
33
|
+
return false;
|
|
34
|
+
}
|
|
35
|
+
const result = LogLineSchema.safeParse(json);
|
|
36
|
+
if (!result.success || result.data.level.toLowerCase() !== "error") {
|
|
37
|
+
return false;
|
|
38
|
+
}
|
|
39
|
+
return FAULT_MESSAGES.includes(result.data.message) || result.data.message.includes("database");
|
|
40
|
+
};
|
|
41
|
+
/**
|
|
42
|
+
* The log file of a test server, written as JSON lines.
|
|
43
|
+
*
|
|
44
|
+
* Lines from the CA are written as they are logged. The harness adds the
|
|
45
|
+
* following lines, whose messages all start with "harness":
|
|
46
|
+
*
|
|
47
|
+
* - `{"level":"info","message":"harness request",...}` for each request, with
|
|
48
|
+
* `method`, `url`, `status` and, when `status` is 400 or more, the response
|
|
49
|
+
* `body`.
|
|
50
|
+
* - `{"level":"error","message":"harness ...",...}` for a fault in the CA or
|
|
51
|
+
* harness. A CA log line that indicates a fault (see {@link isFault}) is
|
|
52
|
+
* followed by a line with the message {@link FAULT_MESSAGE}.
|
|
53
|
+
*/
|
|
54
|
+
export class LogFile {
|
|
55
|
+
path;
|
|
56
|
+
constructor(path) {
|
|
57
|
+
this.path = path;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Append a line of output from the CA, followed by a fault line if it
|
|
61
|
+
* indicates a fault.
|
|
62
|
+
*/
|
|
63
|
+
write(line) {
|
|
64
|
+
this.append(line);
|
|
65
|
+
if (isFault(line)) {
|
|
66
|
+
this.append(formatValue({ level: "error", message: FAULT_MESSAGE, line }));
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Append a request handled by the CA.
|
|
71
|
+
*/
|
|
72
|
+
request(method, url, status, body) {
|
|
73
|
+
this.append(formatRequest(method, url, status, body));
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Append a fault in the harness.
|
|
77
|
+
*
|
|
78
|
+
* @param message A description of the fault, which is prefixed with "harness"
|
|
79
|
+
* @param error The error that caused the fault
|
|
80
|
+
*/
|
|
81
|
+
fault(message, error) {
|
|
82
|
+
this.append(formatValue({ level: "error", message: `harness ${message}`, error }));
|
|
83
|
+
}
|
|
84
|
+
append(line) {
|
|
85
|
+
appendFileSync(this.path, line + "\n");
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
//# sourceMappingURL=log.js.map
|
package/dist/log.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"log.js","sourceRoot":"","sources":["../src/log.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,SAAS,CAAA;AACxC,OAAO,CAAC,MAAM,KAAK,CAAA;AACnB,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AAExD;;;GAGG;AACH,MAAM,CAAC,MAAM,cAAc,GAAsB,CAAC,iBAAiB,EAAE,8BAA8B,CAAC,CAAA;AAEpG;;;GAGG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,eAAe,CAAA;AAE5C,oDAAoD;AACpD,MAAM,aAAa,GAAG,CAAC,CAAC,MAAM,CAAC;IAC9B,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE;IACjB,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE;CACnB,CAAC,CAAA;AAEF;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,OAAO,GAAG,CAAC,IAAY,EAAW,EAAE;IAChD,IAAI,IAAa,CAAA;IACjB,IAAI,CAAC;QACJ,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;IACxB,CAAC;IAAC,MAAM,CAAC;QACR,OAAO,KAAK,CAAA;IACb,CAAC;IAED,MAAM,MAAM,GAAG,aAAa,CAAC,SAAS,CAAC,IAAI,CAAC,CAAA;IAC5C,IAAI,CAAC,MAAM,CAAC,OAAO,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE,KAAK,OAAO,EAAE,CAAC;QACpE,OAAO,KAAK,CAAA;IACb,CAAC;IAED,OAAO,cAAc,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAA;AAChG,CAAC,CAAA;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,OAAO,OAAO;IACV,IAAI,CAAQ;IAErB,YAAY,IAAY;QACvB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAA;IACjB,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,IAAY;QACjB,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;QACjB,IAAI,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;YACnB,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC,CAAA;QAC3E,CAAC;IACF,CAAC;IAED;;OAEG;IACH,OAAO,CAAC,MAAc,EAAE,GAAW,EAAE,MAAc,EAAE,IAAY;QAChE,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,CAAC,CAAA;IACtD,CAAC;IAED;;;;;OAKG;IACH,KAAK,CAAC,OAAe,EAAE,KAAc;QACpC,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,WAAW,OAAO,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC,CAAA;IACnF,CAAC;IAEO,MAAM,CAAC,IAAY;QAC1B,cAAc,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,CAAC,CAAA;IACvC,CAAC;CACD"}
|
package/dist/node.d.ts
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { TestServerConfig } from "./config.js";
|
|
2
|
+
import type { LogFile } from "./log.js";
|
|
3
|
+
import type { TestServer } from "./server.js";
|
|
4
|
+
/**
|
|
5
|
+
* Run the CA on Node.js, created with the package's Node.js helpers and an
|
|
6
|
+
* in-memory `node:sqlite` database, behind an HTTP server on a random port.
|
|
7
|
+
*
|
|
8
|
+
* Output the CA writes with `console` is written to `log` until the server is
|
|
9
|
+
* closed.
|
|
10
|
+
*
|
|
11
|
+
* @param config The test server configuration
|
|
12
|
+
* @param log The log file for the CA and harness
|
|
13
|
+
* @returns The running server
|
|
14
|
+
* @throws InvalidConfigurationError if `config.bindings` is not a valid CA configuration
|
|
15
|
+
*/
|
|
16
|
+
export declare const startNode: (config: TestServerConfig, log: LogFile) => Promise<TestServer>;
|
|
17
|
+
//# sourceMappingURL=node.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"node.d.ts","sourceRoot":"","sources":["../src/node.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAA;AAEnD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,UAAU,CAAA;AACvC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AA2B7C;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,SAAS,WAAkB,gBAAgB,OAAO,OAAO,KAAG,OAAO,CAAC,UAAU,CAiE1F,CAAA"}
|