@yannelli/zoomies 0.0.0
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/LICENSE +21 -0
- package/README.md +97 -0
- package/dist/cli/client.d.ts +77 -0
- package/dist/cli/client.d.ts.map +1 -0
- package/dist/cli/client.js +300 -0
- package/dist/cli/client.js.map +1 -0
- package/dist/cli/commands/certs.d.ts +11 -0
- package/dist/cli/commands/certs.d.ts.map +1 -0
- package/dist/cli/commands/certs.js +110 -0
- package/dist/cli/commands/certs.js.map +1 -0
- package/dist/cli/commands/flags.d.ts +29 -0
- package/dist/cli/commands/flags.d.ts.map +1 -0
- package/dist/cli/commands/flags.js +104 -0
- package/dist/cli/commands/flags.js.map +1 -0
- package/dist/cli/commands/reload.d.ts +11 -0
- package/dist/cli/commands/reload.d.ts.map +1 -0
- package/dist/cli/commands/reload.js +35 -0
- package/dist/cli/commands/reload.js.map +1 -0
- package/dist/cli/commands/sites.d.ts +11 -0
- package/dist/cli/commands/sites.d.ts.map +1 -0
- package/dist/cli/commands/sites.js +221 -0
- package/dist/cli/commands/sites.js.map +1 -0
- package/dist/cli/commands/status.d.ts +10 -0
- package/dist/cli/commands/status.d.ts.map +1 -0
- package/dist/cli/commands/status.js +41 -0
- package/dist/cli/commands/status.js.map +1 -0
- package/dist/cli/commands/upstreams.d.ts +21 -0
- package/dist/cli/commands/upstreams.d.ts.map +1 -0
- package/dist/cli/commands/upstreams.js +248 -0
- package/dist/cli/commands/upstreams.js.map +1 -0
- package/dist/cli/dispatcher.d.ts +45 -0
- package/dist/cli/dispatcher.d.ts.map +1 -0
- package/dist/cli/dispatcher.js +192 -0
- package/dist/cli/dispatcher.js.map +1 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +42 -0
- package/dist/index.js.map +1 -0
- package/dist/server/api/db-context.d.ts +50 -0
- package/dist/server/api/db-context.d.ts.map +1 -0
- package/dist/server/api/db-context.js +76 -0
- package/dist/server/api/db-context.js.map +1 -0
- package/dist/server/api/error-mapping.d.ts +19 -0
- package/dist/server/api/error-mapping.d.ts.map +1 -0
- package/dist/server/api/error-mapping.js +56 -0
- package/dist/server/api/error-mapping.js.map +1 -0
- package/dist/server/api/handlers/site-cert.d.ts +49 -0
- package/dist/server/api/handlers/site-cert.d.ts.map +1 -0
- package/dist/server/api/handlers/site-cert.js +54 -0
- package/dist/server/api/handlers/site-cert.js.map +1 -0
- package/dist/server/api/handlers/sites.d.ts +67 -0
- package/dist/server/api/handlers/sites.d.ts.map +1 -0
- package/dist/server/api/handlers/sites.js +78 -0
- package/dist/server/api/handlers/sites.js.map +1 -0
- package/dist/server/api/handlers/upstreams.d.ts +64 -0
- package/dist/server/api/handlers/upstreams.d.ts.map +1 -0
- package/dist/server/api/handlers/upstreams.js +97 -0
- package/dist/server/api/handlers/upstreams.js.map +1 -0
- package/dist/server/auth/require-token.d.ts +24 -0
- package/dist/server/auth/require-token.d.ts.map +1 -0
- package/dist/server/auth/require-token.js +98 -0
- package/dist/server/auth/require-token.js.map +1 -0
- package/dist/server/certs/acme-account.d.ts +37 -0
- package/dist/server/certs/acme-account.d.ts.map +1 -0
- package/dist/server/certs/acme-account.js +49 -0
- package/dist/server/certs/acme-account.js.map +1 -0
- package/dist/server/certs/challenge-store.d.ts +53 -0
- package/dist/server/certs/challenge-store.d.ts.map +1 -0
- package/dist/server/certs/challenge-store.js +66 -0
- package/dist/server/certs/challenge-store.js.map +1 -0
- package/dist/server/certs/issue.d.ts +106 -0
- package/dist/server/certs/issue.d.ts.map +1 -0
- package/dist/server/certs/issue.js +107 -0
- package/dist/server/certs/issue.js.map +1 -0
- package/dist/server/certs/renew.d.ts +34 -0
- package/dist/server/certs/renew.d.ts.map +1 -0
- package/dist/server/certs/renew.js +36 -0
- package/dist/server/certs/renew.js.map +1 -0
- package/dist/server/certs/scheduler.d.ts +68 -0
- package/dist/server/certs/scheduler.d.ts.map +1 -0
- package/dist/server/certs/scheduler.js +76 -0
- package/dist/server/certs/scheduler.js.map +1 -0
- package/dist/server/db/connection.d.ts +10 -0
- package/dist/server/db/connection.d.ts.map +1 -0
- package/dist/server/db/connection.js +16 -0
- package/dist/server/db/connection.js.map +1 -0
- package/dist/server/db/migrate.d.ts +12 -0
- package/dist/server/db/migrate.d.ts.map +1 -0
- package/dist/server/db/migrate.js +37 -0
- package/dist/server/db/migrate.js.map +1 -0
- package/dist/server/db/migrations/0001_init.sql +42 -0
- package/dist/server/domain/cert.d.ts +17 -0
- package/dist/server/domain/cert.d.ts.map +1 -0
- package/dist/server/domain/cert.js +22 -0
- package/dist/server/domain/cert.js.map +1 -0
- package/dist/server/domain/errors.d.ts +36 -0
- package/dist/server/domain/errors.d.ts.map +1 -0
- package/dist/server/domain/errors.js +37 -0
- package/dist/server/domain/errors.js.map +1 -0
- package/dist/server/domain/site.d.ts +15 -0
- package/dist/server/domain/site.d.ts.map +1 -0
- package/dist/server/domain/site.js +25 -0
- package/dist/server/domain/site.js.map +1 -0
- package/dist/server/domain/upstream.d.ts +25 -0
- package/dist/server/domain/upstream.d.ts.map +1 -0
- package/dist/server/domain/upstream.js +24 -0
- package/dist/server/domain/upstream.js.map +1 -0
- package/dist/server/index.d.ts +2 -0
- package/dist/server/index.d.ts.map +1 -0
- package/dist/server/index.js +4 -0
- package/dist/server/index.js.map +1 -0
- package/dist/server/reload/atomic-write.d.ts +44 -0
- package/dist/server/reload/atomic-write.d.ts.map +1 -0
- package/dist/server/reload/atomic-write.js +151 -0
- package/dist/server/reload/atomic-write.js.map +1 -0
- package/dist/server/reload/health-probe.d.ts +62 -0
- package/dist/server/reload/health-probe.d.ts.map +1 -0
- package/dist/server/reload/health-probe.js +105 -0
- package/dist/server/reload/health-probe.js.map +1 -0
- package/dist/server/reload/reload.d.ts +118 -0
- package/dist/server/reload/reload.d.ts.map +1 -0
- package/dist/server/reload/reload.js +232 -0
- package/dist/server/reload/reload.js.map +1 -0
- package/dist/server/renderer/render-bundle.d.ts +18 -0
- package/dist/server/renderer/render-bundle.d.ts.map +1 -0
- package/dist/server/renderer/render-bundle.js +32 -0
- package/dist/server/renderer/render-bundle.js.map +1 -0
- package/dist/server/renderer/render-site.d.ts +5 -0
- package/dist/server/renderer/render-site.d.ts.map +1 -0
- package/dist/server/renderer/render-site.js +144 -0
- package/dist/server/renderer/render-site.js.map +1 -0
- package/dist/server/repositories/cert-repository.d.ts +19 -0
- package/dist/server/repositories/cert-repository.d.ts.map +1 -0
- package/dist/server/repositories/cert-repository.js +112 -0
- package/dist/server/repositories/cert-repository.js.map +1 -0
- package/dist/server/repositories/site-repository.d.ts +17 -0
- package/dist/server/repositories/site-repository.d.ts.map +1 -0
- package/dist/server/repositories/site-repository.js +122 -0
- package/dist/server/repositories/site-repository.js.map +1 -0
- package/dist/server/repositories/upstream-repository.d.ts +22 -0
- package/dist/server/repositories/upstream-repository.d.ts.map +1 -0
- package/dist/server/repositories/upstream-repository.js +142 -0
- package/dist/server/repositories/upstream-repository.js.map +1 -0
- package/dist/server/validator/nginx-binary.d.ts +9 -0
- package/dist/server/validator/nginx-binary.d.ts.map +1 -0
- package/dist/server/validator/nginx-binary.js +11 -0
- package/dist/server/validator/nginx-binary.js.map +1 -0
- package/dist/server/validator/validate.d.ts +29 -0
- package/dist/server/validator/validate.d.ts.map +1 -0
- package/dist/server/validator/validate.js +69 -0
- package/dist/server/validator/validate.js.map +1 -0
- package/dist/server/worker/main.d.ts +43 -0
- package/dist/server/worker/main.d.ts.map +1 -0
- package/dist/server/worker/main.js +181 -0
- package/dist/server/worker/main.js.map +1 -0
- package/dist/version.d.ts +2 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +2 -0
- package/dist/version.js.map +1 -0
- package/package.json +84 -0
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `zoomies upstreams <subcommand>` — CRUD over upstreams.
|
|
3
|
+
*
|
|
4
|
+
* `create` collects targets via a repeated `--target host:port:weight` flag.
|
|
5
|
+
* `update` accepts `--targets-json` so callers can replace the whole targets
|
|
6
|
+
* list atomically — partial mutations of a single target row would race the
|
|
7
|
+
* other targets in the same upstream and are out of scope.
|
|
8
|
+
*/
|
|
9
|
+
import { CliClientError } from '../client.js';
|
|
10
|
+
import { FlagParseError, parseFlags } from './flags.js';
|
|
11
|
+
const VALID_LOAD_BALANCERS = ['round_robin', 'least_conn', 'ip_hash'];
|
|
12
|
+
export const UPSTREAMS_USAGE = `Usage: zoomies upstreams <subcommand> [args]
|
|
13
|
+
|
|
14
|
+
Subcommands:
|
|
15
|
+
list Tabular listing of all upstreams
|
|
16
|
+
get <id> JSON dump of one upstream
|
|
17
|
+
create --name <n> --load-balancer <round_robin|least_conn|ip_hash>
|
|
18
|
+
--target host:port:weight ... Create upstream (repeat --target)
|
|
19
|
+
update <id> [--name X] [--load-balancer X] [--targets-json '<json>']
|
|
20
|
+
Patch an existing upstream
|
|
21
|
+
|
|
22
|
+
The --target value is host:port:weight (e.g. 10.0.0.1:8080:1). Pass --target
|
|
23
|
+
multiple times to add multiple backends.
|
|
24
|
+
|
|
25
|
+
The --targets-json contract: a JSON array of objects
|
|
26
|
+
[{"host":"10.0.0.1","port":8080,"weight":1}, ...]
|
|
27
|
+
Replaces the full targets list. Use only when scripting; --target on create
|
|
28
|
+
is friendlier for ad-hoc use.
|
|
29
|
+
`;
|
|
30
|
+
function shortId(id) {
|
|
31
|
+
return id.slice(0, 8);
|
|
32
|
+
}
|
|
33
|
+
function isLoadBalancer(value) {
|
|
34
|
+
return VALID_LOAD_BALANCERS.includes(value);
|
|
35
|
+
}
|
|
36
|
+
function printUsage(ctx) {
|
|
37
|
+
ctx.stdout.write(UPSTREAMS_USAGE);
|
|
38
|
+
return 0;
|
|
39
|
+
}
|
|
40
|
+
function writeUsageErr(ctx, msg) {
|
|
41
|
+
ctx.stderr.write(`zoomies upstreams: ${msg}\n`);
|
|
42
|
+
ctx.stderr.write(UPSTREAMS_USAGE);
|
|
43
|
+
return 2;
|
|
44
|
+
}
|
|
45
|
+
function handleClientError(ctx, err) {
|
|
46
|
+
if (err instanceof CliClientError) {
|
|
47
|
+
ctx.stderr.write(`zoomies upstreams: ${err.message} (${err.code})\n`);
|
|
48
|
+
return 1;
|
|
49
|
+
}
|
|
50
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
51
|
+
ctx.stderr.write(`zoomies upstreams: ${message}\n`);
|
|
52
|
+
return 1;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Parse a single `--target host:port:weight` value.
|
|
56
|
+
*
|
|
57
|
+
* Splits on `:` from the right so an IPv6 literal (e.g. `[::1]:8080:1`)
|
|
58
|
+
* still parses cleanly: the last two segments are always port + weight,
|
|
59
|
+
* and the remainder is host.
|
|
60
|
+
*/
|
|
61
|
+
export function parseTargetFlag(value) {
|
|
62
|
+
const parts = value.split(':');
|
|
63
|
+
if (parts.length < 3) {
|
|
64
|
+
throw new FlagParseError(`--target must be host:port:weight (got '${value}')`);
|
|
65
|
+
}
|
|
66
|
+
const weightStr = parts[parts.length - 1];
|
|
67
|
+
const portStr = parts[parts.length - 2];
|
|
68
|
+
const host = parts.slice(0, -2).join(':');
|
|
69
|
+
if (host === '') {
|
|
70
|
+
throw new FlagParseError(`--target host is empty (got '${value}')`);
|
|
71
|
+
}
|
|
72
|
+
const port = Number.parseInt(portStr, 10);
|
|
73
|
+
const weight = Number.parseInt(weightStr, 10);
|
|
74
|
+
if (!Number.isFinite(port) || port < 1 || port > 65535) {
|
|
75
|
+
throw new FlagParseError(`--target port must be 1-65535 (got '${portStr}')`);
|
|
76
|
+
}
|
|
77
|
+
if (!Number.isFinite(weight) || weight < 1) {
|
|
78
|
+
throw new FlagParseError(`--target weight must be >= 1 (got '${weightStr}')`);
|
|
79
|
+
}
|
|
80
|
+
return { host, port, weight };
|
|
81
|
+
}
|
|
82
|
+
async function runList(ctx) {
|
|
83
|
+
try {
|
|
84
|
+
const upstreams = await ctx.client.upstreams.list();
|
|
85
|
+
if (upstreams.length === 0) {
|
|
86
|
+
ctx.stdout.write('(no upstreams)\n');
|
|
87
|
+
return 0;
|
|
88
|
+
}
|
|
89
|
+
const header = ['id', 'name', 'load_balancer', 'targets', 'created_at'];
|
|
90
|
+
const rows = upstreams.map((u) => [
|
|
91
|
+
shortId(u.id),
|
|
92
|
+
u.name,
|
|
93
|
+
u.loadBalancer,
|
|
94
|
+
String(u.targets.length),
|
|
95
|
+
u.createdAt,
|
|
96
|
+
]);
|
|
97
|
+
const widths = header.map((h, i) => Math.max(h.length, ...rows.map((r) => (r[i] ?? '').length)));
|
|
98
|
+
const fmt = (cols) => cols.map((c, i) => c.padEnd(widths[i] ?? 0)).join(' ');
|
|
99
|
+
ctx.stdout.write(fmt(header) + '\n');
|
|
100
|
+
for (const row of rows) {
|
|
101
|
+
ctx.stdout.write(fmt(row) + '\n');
|
|
102
|
+
}
|
|
103
|
+
return 0;
|
|
104
|
+
}
|
|
105
|
+
catch (err) {
|
|
106
|
+
return handleClientError(ctx, err);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
async function runGet(args, ctx) {
|
|
110
|
+
const [id] = args;
|
|
111
|
+
if (id === undefined) {
|
|
112
|
+
return writeUsageErr(ctx, 'get requires an upstream id');
|
|
113
|
+
}
|
|
114
|
+
try {
|
|
115
|
+
const upstream = await ctx.client.upstreams.get(id);
|
|
116
|
+
ctx.stdout.write(JSON.stringify(upstream, null, 2) + '\n');
|
|
117
|
+
return 0;
|
|
118
|
+
}
|
|
119
|
+
catch (err) {
|
|
120
|
+
return handleClientError(ctx, err);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
async function runCreate(args, ctx) {
|
|
124
|
+
let parsed;
|
|
125
|
+
try {
|
|
126
|
+
parsed = parseFlags(args, {
|
|
127
|
+
valueFlags: new Set(['name', 'load-balancer']),
|
|
128
|
+
repeatedFlags: new Set(['target']),
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
catch (err) {
|
|
132
|
+
if (err instanceof FlagParseError) {
|
|
133
|
+
return writeUsageErr(ctx, err.message);
|
|
134
|
+
}
|
|
135
|
+
throw err;
|
|
136
|
+
}
|
|
137
|
+
const name = parsed.flags['name'];
|
|
138
|
+
const loadBalancer = parsed.flags['load-balancer'];
|
|
139
|
+
if (name === undefined || loadBalancer === undefined) {
|
|
140
|
+
return writeUsageErr(ctx, 'create requires --name and --load-balancer');
|
|
141
|
+
}
|
|
142
|
+
if (!isLoadBalancer(loadBalancer)) {
|
|
143
|
+
return writeUsageErr(ctx, `--load-balancer must be one of ${VALID_LOAD_BALANCERS.join('|')}`);
|
|
144
|
+
}
|
|
145
|
+
const targetValues = parsed.repeated['target'] ?? [];
|
|
146
|
+
if (targetValues.length === 0) {
|
|
147
|
+
return writeUsageErr(ctx, 'create requires at least one --target host:port:weight');
|
|
148
|
+
}
|
|
149
|
+
let targets;
|
|
150
|
+
try {
|
|
151
|
+
targets = targetValues.map((v) => parseTargetFlag(v));
|
|
152
|
+
}
|
|
153
|
+
catch (err) {
|
|
154
|
+
if (err instanceof FlagParseError) {
|
|
155
|
+
return writeUsageErr(ctx, err.message);
|
|
156
|
+
}
|
|
157
|
+
throw err;
|
|
158
|
+
}
|
|
159
|
+
const input = {
|
|
160
|
+
name,
|
|
161
|
+
loadBalancer,
|
|
162
|
+
targets,
|
|
163
|
+
};
|
|
164
|
+
try {
|
|
165
|
+
const upstream = await ctx.client.upstreams.create(input);
|
|
166
|
+
ctx.stdout.write(upstream.id + '\n');
|
|
167
|
+
return 0;
|
|
168
|
+
}
|
|
169
|
+
catch (err) {
|
|
170
|
+
return handleClientError(ctx, err);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
async function runUpdate(args, ctx) {
|
|
174
|
+
let parsed;
|
|
175
|
+
try {
|
|
176
|
+
parsed = parseFlags(args, {
|
|
177
|
+
valueFlags: new Set(['name', 'load-balancer', 'targets-json']),
|
|
178
|
+
});
|
|
179
|
+
}
|
|
180
|
+
catch (err) {
|
|
181
|
+
if (err instanceof FlagParseError) {
|
|
182
|
+
return writeUsageErr(ctx, err.message);
|
|
183
|
+
}
|
|
184
|
+
throw err;
|
|
185
|
+
}
|
|
186
|
+
const [id] = parsed.positional;
|
|
187
|
+
if (id === undefined) {
|
|
188
|
+
return writeUsageErr(ctx, 'update requires an upstream id');
|
|
189
|
+
}
|
|
190
|
+
const patch = {};
|
|
191
|
+
if (parsed.flags['name'] !== undefined) {
|
|
192
|
+
patch.name = parsed.flags['name'];
|
|
193
|
+
}
|
|
194
|
+
if (parsed.flags['load-balancer'] !== undefined) {
|
|
195
|
+
const lb = parsed.flags['load-balancer'];
|
|
196
|
+
if (!isLoadBalancer(lb)) {
|
|
197
|
+
return writeUsageErr(ctx, `--load-balancer must be one of ${VALID_LOAD_BALANCERS.join('|')}`);
|
|
198
|
+
}
|
|
199
|
+
patch.loadBalancer = lb;
|
|
200
|
+
}
|
|
201
|
+
if (parsed.flags['targets-json'] !== undefined) {
|
|
202
|
+
try {
|
|
203
|
+
const targets = JSON.parse(parsed.flags['targets-json']);
|
|
204
|
+
if (!Array.isArray(targets)) {
|
|
205
|
+
return writeUsageErr(ctx, '--targets-json must be a JSON array');
|
|
206
|
+
}
|
|
207
|
+
patch.targets = targets;
|
|
208
|
+
}
|
|
209
|
+
catch (err) {
|
|
210
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
211
|
+
return writeUsageErr(ctx, `--targets-json: invalid JSON (${message})`);
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
try {
|
|
215
|
+
await ctx.client.upstreams.update(id, patch);
|
|
216
|
+
ctx.stdout.write('ok\n');
|
|
217
|
+
return 0;
|
|
218
|
+
}
|
|
219
|
+
catch (err) {
|
|
220
|
+
return handleClientError(ctx, err);
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
export const upstreamsCommand = {
|
|
224
|
+
name: 'upstreams',
|
|
225
|
+
describe: 'List / create / update upstreams',
|
|
226
|
+
usage: UPSTREAMS_USAGE,
|
|
227
|
+
async run(args, ctx) {
|
|
228
|
+
if (args.includes('--help') || args.includes('-h')) {
|
|
229
|
+
return printUsage(ctx);
|
|
230
|
+
}
|
|
231
|
+
const [sub, ...rest] = args;
|
|
232
|
+
switch (sub) {
|
|
233
|
+
case undefined:
|
|
234
|
+
return printUsage(ctx);
|
|
235
|
+
case 'list':
|
|
236
|
+
return runList(ctx);
|
|
237
|
+
case 'get':
|
|
238
|
+
return runGet(rest, ctx);
|
|
239
|
+
case 'create':
|
|
240
|
+
return runCreate(rest, ctx);
|
|
241
|
+
case 'update':
|
|
242
|
+
return runUpdate(rest, ctx);
|
|
243
|
+
default:
|
|
244
|
+
return writeUsageErr(ctx, `unknown subcommand '${sub}'`);
|
|
245
|
+
}
|
|
246
|
+
},
|
|
247
|
+
};
|
|
248
|
+
//# sourceMappingURL=upstreams.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"upstreams.js","sourceRoot":"","sources":["../../../src/cli/commands/upstreams.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Hand-rolled CLI argv parser and dispatcher.
|
|
3
|
+
*
|
|
4
|
+
* Phase 0 was explicit about not adding deps for things the standard
|
|
5
|
+
* library can do; this dispatcher is intentionally minimal:
|
|
6
|
+
* - parse top-level flags up to the first non-flag positional,
|
|
7
|
+
* - resolve a `Command` record by name,
|
|
8
|
+
* - build a `CommandContext` (no DB, no client) and hand the remaining
|
|
9
|
+
* argv to `command.run(args, ctx)`.
|
|
10
|
+
*
|
|
11
|
+
* `--version` / `-v` and `--help` / `-h` are zero-side-effect: they never
|
|
12
|
+
* open the DB or construct a client. The CLI client factory is only invoked
|
|
13
|
+
* when a real command runs, and is overridable via {@link dispatchWithClient}
|
|
14
|
+
* for tests.
|
|
15
|
+
*/
|
|
16
|
+
import { type CliClient } from './client.js';
|
|
17
|
+
export interface CommandContext {
|
|
18
|
+
mode: 'local' | 'http';
|
|
19
|
+
httpUrl: string;
|
|
20
|
+
httpToken?: string | undefined;
|
|
21
|
+
stdout: NodeJS.WritableStream;
|
|
22
|
+
stderr: NodeJS.WritableStream;
|
|
23
|
+
client: CliClient;
|
|
24
|
+
}
|
|
25
|
+
export interface Command {
|
|
26
|
+
name: string;
|
|
27
|
+
describe: string;
|
|
28
|
+
usage: string;
|
|
29
|
+
run(args: readonly string[], ctx: CommandContext): Promise<number>;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Factory wrapping `createLocalClient` / `createHttpClient`. Tests pass a
|
|
33
|
+
* substitute via {@link dispatchWithClient} so they can inject a fake client
|
|
34
|
+
* without monkey-patching module-scope code.
|
|
35
|
+
*/
|
|
36
|
+
export interface ClientFactory {
|
|
37
|
+
(mode: 'local' | 'http', httpUrl: string, httpToken: string | undefined): CliClient;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Dispatch with an injected client factory. Tests use this to substitute
|
|
41
|
+
* a fake client and verify dispatcher behaviour without touching the DB.
|
|
42
|
+
*/
|
|
43
|
+
export declare function dispatchWithClient(argv: readonly string[], factory: ClientFactory, stdout?: NodeJS.WritableStream, stderr?: NodeJS.WritableStream): Promise<number>;
|
|
44
|
+
export declare function dispatch(argv: readonly string[]): Promise<number>;
|
|
45
|
+
//# sourceMappingURL=dispatcher.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dispatcher.d.ts","sourceRoot":"","sources":["../../src/cli/dispatcher.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAGH,OAAO,EAAuC,KAAK,SAAS,EAAE,MAAM,aAAa,CAAC;AAOlF,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,OAAO,GAAG,MAAM,CAAC;IACvB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC/B,MAAM,EAAE,MAAM,CAAC,cAAc,CAAC;IAC9B,MAAM,EAAE,MAAM,CAAC,cAAc,CAAC;IAC9B,MAAM,EAAE,SAAS,CAAC;CACnB;AAED,MAAM,WAAW,OAAO;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,EAAE,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;CACpE;AAED;;;;GAIG;AACH,MAAM,WAAW,aAAa;IAC5B,CAAC,IAAI,EAAE,OAAO,GAAG,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,SAAS,GAAG,SAAS,CAAC;CACrF;AAiID;;;GAGG;AACH,wBAAsB,kBAAkB,CACtC,IAAI,EAAE,SAAS,MAAM,EAAE,EACvB,OAAO,EAAE,aAAa,EACtB,MAAM,GAAE,MAAM,CAAC,cAA+B,EAC9C,MAAM,GAAE,MAAM,CAAC,cAA+B,GAC7C,OAAO,CAAC,MAAM,CAAC,CAgEjB;AAKD,wBAAsB,QAAQ,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAEvE"}
|
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Hand-rolled CLI argv parser and dispatcher.
|
|
3
|
+
*
|
|
4
|
+
* Phase 0 was explicit about not adding deps for things the standard
|
|
5
|
+
* library can do; this dispatcher is intentionally minimal:
|
|
6
|
+
* - parse top-level flags up to the first non-flag positional,
|
|
7
|
+
* - resolve a `Command` record by name,
|
|
8
|
+
* - build a `CommandContext` (no DB, no client) and hand the remaining
|
|
9
|
+
* argv to `command.run(args, ctx)`.
|
|
10
|
+
*
|
|
11
|
+
* `--version` / `-v` and `--help` / `-h` are zero-side-effect: they never
|
|
12
|
+
* open the DB or construct a client. The CLI client factory is only invoked
|
|
13
|
+
* when a real command runs, and is overridable via {@link dispatchWithClient}
|
|
14
|
+
* for tests.
|
|
15
|
+
*/
|
|
16
|
+
import { version } from '../version.js';
|
|
17
|
+
import { createHttpClient, createLocalClient } from './client.js';
|
|
18
|
+
import { certsCommand } from './commands/certs.js';
|
|
19
|
+
import { reloadCommand } from './commands/reload.js';
|
|
20
|
+
import { sitesCommand } from './commands/sites.js';
|
|
21
|
+
import { statusCommand } from './commands/status.js';
|
|
22
|
+
import { upstreamsCommand } from './commands/upstreams.js';
|
|
23
|
+
const COMMANDS = [
|
|
24
|
+
statusCommand,
|
|
25
|
+
sitesCommand,
|
|
26
|
+
upstreamsCommand,
|
|
27
|
+
certsCommand,
|
|
28
|
+
reloadCommand,
|
|
29
|
+
];
|
|
30
|
+
const DEFAULT_API_URL = 'http://localhost:3000';
|
|
31
|
+
/**
|
|
32
|
+
* Walk argv consuming top-level flags until we hit the first non-flag
|
|
33
|
+
* positional. That positional and everything after it are the command's
|
|
34
|
+
* own argv — we hand them off unparsed.
|
|
35
|
+
*
|
|
36
|
+
* Mid-stream `--help` / `--version` still trigger the global behaviour
|
|
37
|
+
* (i.e. `zoomies sites --help` falls through to the sites command's help;
|
|
38
|
+
* `zoomies --help sites` shows global help). The split is on position:
|
|
39
|
+
* once we see a non-flag, we stop parsing top-level flags.
|
|
40
|
+
*/
|
|
41
|
+
function parseTopLevel(args) {
|
|
42
|
+
let showVersion = false;
|
|
43
|
+
let showHelp = false;
|
|
44
|
+
let modeOverride = null;
|
|
45
|
+
let httpUrl = process.env.ZOOMIES_API_URL ?? DEFAULT_API_URL;
|
|
46
|
+
let httpToken = process.env.ZOOMIES_API_TOKEN;
|
|
47
|
+
const rest = [];
|
|
48
|
+
let i = 0;
|
|
49
|
+
while (i < args.length) {
|
|
50
|
+
const arg = args[i];
|
|
51
|
+
if (arg === undefined) {
|
|
52
|
+
i += 1;
|
|
53
|
+
continue;
|
|
54
|
+
}
|
|
55
|
+
if (arg === '--version' || arg === '-v') {
|
|
56
|
+
showVersion = true;
|
|
57
|
+
i += 1;
|
|
58
|
+
continue;
|
|
59
|
+
}
|
|
60
|
+
if (arg === '--help' || arg === '-h') {
|
|
61
|
+
showHelp = true;
|
|
62
|
+
i += 1;
|
|
63
|
+
continue;
|
|
64
|
+
}
|
|
65
|
+
if (arg === '--local') {
|
|
66
|
+
modeOverride = 'local';
|
|
67
|
+
i += 1;
|
|
68
|
+
continue;
|
|
69
|
+
}
|
|
70
|
+
if (arg.startsWith('--api-url=')) {
|
|
71
|
+
httpUrl = arg.slice('--api-url='.length);
|
|
72
|
+
i += 1;
|
|
73
|
+
continue;
|
|
74
|
+
}
|
|
75
|
+
if (arg === '--api-url') {
|
|
76
|
+
const next = args[i + 1];
|
|
77
|
+
if (next === undefined) {
|
|
78
|
+
throw new Error('--api-url requires a value');
|
|
79
|
+
}
|
|
80
|
+
httpUrl = next;
|
|
81
|
+
i += 2;
|
|
82
|
+
continue;
|
|
83
|
+
}
|
|
84
|
+
if (arg.startsWith('--token=')) {
|
|
85
|
+
httpToken = arg.slice('--token='.length);
|
|
86
|
+
i += 1;
|
|
87
|
+
continue;
|
|
88
|
+
}
|
|
89
|
+
if (arg === '--token') {
|
|
90
|
+
const next = args[i + 1];
|
|
91
|
+
if (next === undefined) {
|
|
92
|
+
throw new Error('--token requires a value');
|
|
93
|
+
}
|
|
94
|
+
httpToken = next;
|
|
95
|
+
i += 2;
|
|
96
|
+
continue;
|
|
97
|
+
}
|
|
98
|
+
// First non-flag positional → command name. Everything from here on
|
|
99
|
+
// (including subsequent flags) belongs to the command.
|
|
100
|
+
rest.push(...args.slice(i));
|
|
101
|
+
break;
|
|
102
|
+
}
|
|
103
|
+
return { showVersion, showHelp, modeOverride, httpUrl, httpToken, rest };
|
|
104
|
+
}
|
|
105
|
+
function writeVersion(stdout) {
|
|
106
|
+
stdout.write(`zoomies ${version}\n`);
|
|
107
|
+
return 0;
|
|
108
|
+
}
|
|
109
|
+
function writeHelp(stdout) {
|
|
110
|
+
const banner = `zoomies ${version} — control plane for NGINX reverse proxy (pre-alpha)\n` +
|
|
111
|
+
`\n` +
|
|
112
|
+
`Usage: zoomies [global flags] <command> [args]\n` +
|
|
113
|
+
`\n` +
|
|
114
|
+
`Commands:\n`;
|
|
115
|
+
const longestName = COMMANDS.reduce((m, c) => Math.max(m, c.name.length), 0);
|
|
116
|
+
const commandLines = COMMANDS.map((c) => ` ${c.name.padEnd(longestName)} ${c.describe}`).join('\n');
|
|
117
|
+
const flagsBlock = `\n\n` +
|
|
118
|
+
`Global flags:\n` +
|
|
119
|
+
` --local Run against the local SQLite DB instead of the HTTP API\n` +
|
|
120
|
+
` --api-url <url> HTTP API base URL (env: ZOOMIES_API_URL, default ${DEFAULT_API_URL})\n` +
|
|
121
|
+
` --token <token> Bearer token for the HTTP API (env: ZOOMIES_API_TOKEN)\n` +
|
|
122
|
+
` --version, -v Print version and exit\n` +
|
|
123
|
+
` --help, -h Show this help\n` +
|
|
124
|
+
`\n` +
|
|
125
|
+
`Run \`zoomies <command> --help\` for command-specific usage.\n`;
|
|
126
|
+
stdout.write(banner + commandLines + flagsBlock);
|
|
127
|
+
return 0;
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Dispatch with an injected client factory. Tests use this to substitute
|
|
131
|
+
* a fake client and verify dispatcher behaviour without touching the DB.
|
|
132
|
+
*/
|
|
133
|
+
export async function dispatchWithClient(argv, factory, stdout = process.stdout, stderr = process.stderr) {
|
|
134
|
+
// argv shape: ['node', 'zoomies', ...]. Skip the first two entries.
|
|
135
|
+
const args = argv.slice(2);
|
|
136
|
+
let parsed;
|
|
137
|
+
try {
|
|
138
|
+
parsed = parseTopLevel(args);
|
|
139
|
+
}
|
|
140
|
+
catch (err) {
|
|
141
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
142
|
+
stderr.write(`zoomies: ${message}\n`);
|
|
143
|
+
return 2;
|
|
144
|
+
}
|
|
145
|
+
if (parsed.showVersion) {
|
|
146
|
+
return writeVersion(stdout);
|
|
147
|
+
}
|
|
148
|
+
if (parsed.rest.length === 0) {
|
|
149
|
+
// No command. `--help` is implied — render the banner.
|
|
150
|
+
return writeHelp(stdout);
|
|
151
|
+
}
|
|
152
|
+
const [commandName, ...commandArgs] = parsed.rest;
|
|
153
|
+
if (commandName === undefined) {
|
|
154
|
+
return writeHelp(stdout);
|
|
155
|
+
}
|
|
156
|
+
if (parsed.showHelp && parsed.rest.length === 0) {
|
|
157
|
+
return writeHelp(stdout);
|
|
158
|
+
}
|
|
159
|
+
const command = COMMANDS.find((c) => c.name === commandName);
|
|
160
|
+
if (command === undefined) {
|
|
161
|
+
stderr.write(`zoomies: unknown command '${commandName}'. Run \`zoomies --help\` for the command list.\n`);
|
|
162
|
+
return 2;
|
|
163
|
+
}
|
|
164
|
+
// Pass `--help` / `-h` through to the command itself so per-command
|
|
165
|
+
// help is single-sourced in each command module.
|
|
166
|
+
if (parsed.showHelp && !commandArgs.includes('--help') && !commandArgs.includes('-h')) {
|
|
167
|
+
commandArgs.push('--help');
|
|
168
|
+
}
|
|
169
|
+
const mode = parsed.modeOverride ?? 'http';
|
|
170
|
+
const client = factory(mode, parsed.httpUrl, parsed.httpToken);
|
|
171
|
+
const ctx = {
|
|
172
|
+
mode,
|
|
173
|
+
httpUrl: parsed.httpUrl,
|
|
174
|
+
httpToken: parsed.httpToken,
|
|
175
|
+
stdout,
|
|
176
|
+
stderr,
|
|
177
|
+
client,
|
|
178
|
+
};
|
|
179
|
+
try {
|
|
180
|
+
return await command.run(commandArgs, ctx);
|
|
181
|
+
}
|
|
182
|
+
catch (err) {
|
|
183
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
184
|
+
stderr.write(`zoomies: ${message}\n`);
|
|
185
|
+
return 1;
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
const defaultFactory = (mode, httpUrl, httpToken) => mode === 'local' ? createLocalClient() : createHttpClient(httpUrl, httpToken);
|
|
189
|
+
export async function dispatch(argv) {
|
|
190
|
+
return dispatchWithClient(argv, defaultFactory);
|
|
191
|
+
}
|
|
192
|
+
//# sourceMappingURL=dispatcher.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dispatcher.js","sourceRoot":"","sources":["../../src/cli/dispatcher.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CLI entrypoint. Two fast paths bypass the dispatcher to preserve sync
|
|
3
|
+
* behaviour required by the legacy test suite:
|
|
4
|
+
*
|
|
5
|
+
* 1. `--version` / `-v` prints the version line and returns 0 synchronously.
|
|
6
|
+
* 2. No arguments at all prints the help banner and returns 0 synchronously.
|
|
7
|
+
*
|
|
8
|
+
* Every other argv shape is delegated to {@link dispatch}, which returns a
|
|
9
|
+
* Promise<number>.
|
|
10
|
+
*/
|
|
11
|
+
export declare function main(argv: readonly string[]): number | Promise<number>;
|
|
12
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAKA;;;;;;;;;GASG;AACH,wBAAgB,IAAI,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAiBtE"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { resolve } from 'node:path';
|
|
2
|
+
import { pathToFileURL } from 'node:url';
|
|
3
|
+
import { dispatch } from './cli/dispatcher.js';
|
|
4
|
+
import { version } from './version.js';
|
|
5
|
+
/**
|
|
6
|
+
* CLI entrypoint. Two fast paths bypass the dispatcher to preserve sync
|
|
7
|
+
* behaviour required by the legacy test suite:
|
|
8
|
+
*
|
|
9
|
+
* 1. `--version` / `-v` prints the version line and returns 0 synchronously.
|
|
10
|
+
* 2. No arguments at all prints the help banner and returns 0 synchronously.
|
|
11
|
+
*
|
|
12
|
+
* Every other argv shape is delegated to {@link dispatch}, which returns a
|
|
13
|
+
* Promise<number>.
|
|
14
|
+
*/
|
|
15
|
+
export function main(argv) {
|
|
16
|
+
const [, , ...args] = argv;
|
|
17
|
+
if (args.includes('--version') || args.includes('-v')) {
|
|
18
|
+
process.stdout.write(`zoomies ${version}\n`);
|
|
19
|
+
return 0;
|
|
20
|
+
}
|
|
21
|
+
if (args.length === 0) {
|
|
22
|
+
process.stdout.write(`zoomies ${version} — control plane for NGINX reverse proxy (pre-alpha)\n` +
|
|
23
|
+
`Run \`zoomies --help\` for the command list, \`zoomies --version\` for the version.\n`);
|
|
24
|
+
return 0;
|
|
25
|
+
}
|
|
26
|
+
return dispatch(argv);
|
|
27
|
+
}
|
|
28
|
+
const entryArg = process.argv[1];
|
|
29
|
+
const entryUrl = entryArg ? pathToFileURL(resolve(entryArg)).href : undefined;
|
|
30
|
+
const isEntrypoint = entryUrl !== undefined && import.meta.url === entryUrl;
|
|
31
|
+
if (isEntrypoint) {
|
|
32
|
+
const result = main(process.argv);
|
|
33
|
+
if (typeof result === 'number') {
|
|
34
|
+
process.exit(result);
|
|
35
|
+
}
|
|
36
|
+
else {
|
|
37
|
+
void result.then((code) => {
|
|
38
|
+
process.exit(code);
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAC/C,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAEvC;;;;;;;;;GASG;AACH,MAAM,UAAU,IAAI,CAAC,IAAuB;IAC1C,MAAM,CAAC,EAAE,AAAD,EAAG,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC;IAE3B,IAAI,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QACtD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,WAAW,OAAO,IAAI,CAAC,CAAC;QAC7C,OAAO,CAAC,CAAC;IACX,CAAC;IAED,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACtB,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,WAAW,OAAO,wDAAwD;YACxE,uFAAuF,CAC1F,CAAC;QACF,OAAO,CAAC,CAAC;IACX,CAAC;IAED,OAAO,QAAQ,CAAC,IAAI,CAAC,CAAC;AACxB,CAAC;AAED,MAAM,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACjC,MAAM,QAAQ,GAAG,QAAQ,CAAC,CAAC,CAAC,aAAa,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC;AAC9E,MAAM,YAAY,GAAG,QAAQ,KAAK,SAAS,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,KAAK,QAAQ,CAAC;AAC5E,IAAI,YAAY,EAAE,CAAC;IACjB,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IAClC,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE,CAAC;QAC/B,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACvB,CAAC;SAAM,CAAC;QACN,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE;YACxB,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACrB,CAAC,CAAC,CAAC;IACL,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Process-wide database singleton + repository factory used by every Route
|
|
3
|
+
* Handler.
|
|
4
|
+
*
|
|
5
|
+
* Route Handlers run inside the long-lived Next.js Node process, so we open
|
|
6
|
+
* the SQLite database once on first use and reuse the connection. Each call
|
|
7
|
+
* to {@link getRepositories} hands back fresh repository instances — the
|
|
8
|
+
* prepared statements they cache live on the repo itself (a few ms of
|
|
9
|
+
* preparation cost per request is negligible compared to JSON
|
|
10
|
+
* serialisation), and re-instantiating per call keeps the API surface flat.
|
|
11
|
+
*
|
|
12
|
+
* Tests inject their own in-memory DB via {@link resetDbForTesting}; the
|
|
13
|
+
* same hook is used by `pnpm dev` to drop and re-open the connection when
|
|
14
|
+
* Next.js hot-reloads a module that imports this file.
|
|
15
|
+
*/
|
|
16
|
+
import type Database from 'better-sqlite3';
|
|
17
|
+
import { CertRepository } from '../repositories/cert-repository.js';
|
|
18
|
+
import { SiteRepository } from '../repositories/site-repository.js';
|
|
19
|
+
import { UpstreamRepository } from '../repositories/upstream-repository.js';
|
|
20
|
+
/**
|
|
21
|
+
* Return the process-wide database connection, opening it on first use.
|
|
22
|
+
*
|
|
23
|
+
* The state directory is `$ZOOMIES_STATE_DIR` if set, otherwise
|
|
24
|
+
* `<cwd>/.zoomies`. The directory is created recursively if missing. The
|
|
25
|
+
* database file lives at `<stateDir>/zoomies.db` and is migrated on open.
|
|
26
|
+
*/
|
|
27
|
+
export declare function getDb(): Database.Database;
|
|
28
|
+
export interface Repositories {
|
|
29
|
+
sites: SiteRepository;
|
|
30
|
+
upstreams: UpstreamRepository;
|
|
31
|
+
certs: CertRepository;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Construct a fresh set of repositories backed by the shared connection.
|
|
35
|
+
*
|
|
36
|
+
* Cheap to call per-request; repository constructors only prepare a handful
|
|
37
|
+
* of statements against an already-open database handle.
|
|
38
|
+
*/
|
|
39
|
+
export declare function getRepositories(): Repositories;
|
|
40
|
+
/**
|
|
41
|
+
* Replace (or clear) the cached database singleton.
|
|
42
|
+
*
|
|
43
|
+
* - Tests pass in their own in-memory connection so handlers operate on
|
|
44
|
+
* the same DB the test seeded.
|
|
45
|
+
* - Passing `null` or no argument closes any existing connection and
|
|
46
|
+
* forces the next {@link getDb} call to re-open from disk; used by the
|
|
47
|
+
* `pnpm dev` watcher when modules reload.
|
|
48
|
+
*/
|
|
49
|
+
export declare function resetDbForTesting(db?: Database.Database | null): void;
|
|
50
|
+
//# sourceMappingURL=db-context.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"db-context.d.ts","sourceRoot":"","sources":["../../../src/server/api/db-context.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAKH,OAAO,KAAK,QAAQ,MAAM,gBAAgB,CAAC;AAI3C,OAAO,EAAE,cAAc,EAAE,MAAM,oCAAoC,CAAC;AACpE,OAAO,EAAE,cAAc,EAAE,MAAM,oCAAoC,CAAC;AACpE,OAAO,EAAE,kBAAkB,EAAE,MAAM,wCAAwC,CAAC;AAI5E;;;;;;GAMG;AACH,wBAAgB,KAAK,IAAI,QAAQ,CAAC,QAAQ,CAWzC;AAED,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,cAAc,CAAC;IACtB,SAAS,EAAE,kBAAkB,CAAC;IAC9B,KAAK,EAAE,cAAc,CAAC;CACvB;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,IAAI,YAAY,CAO9C;AAED;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,CAAC,EAAE,CAAC,EAAE,QAAQ,CAAC,QAAQ,GAAG,IAAI,GAAG,IAAI,CAUrE"}
|