@joinremba/beacon 0.3.0 → 0.5.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/README.md +309 -305
- package/package.json +2 -1
- package/src/cli-config.ts +9 -48
- package/src/cli.test.ts +51 -1
- package/src/encryption.ts +19 -19
- package/src/index.test.ts +104 -30
- package/src/index.ts +47 -70
- package/src/schema.ts +56 -0
- package/src/types.ts +12 -1
package/src/schema.ts
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
|
|
3
|
+
export interface SchemaField {
|
|
4
|
+
type?: string;
|
|
5
|
+
default?: unknown;
|
|
6
|
+
values?: readonly string[];
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export function typeToSchema(field: SchemaField): z.ZodType<unknown> {
|
|
10
|
+
const type = field.type ?? "string";
|
|
11
|
+
let base: z.ZodType<unknown>;
|
|
12
|
+
|
|
13
|
+
switch (type) {
|
|
14
|
+
case "string":
|
|
15
|
+
case "host":
|
|
16
|
+
base = z.string();
|
|
17
|
+
break;
|
|
18
|
+
case "url":
|
|
19
|
+
base = z.string().url();
|
|
20
|
+
break;
|
|
21
|
+
case "number":
|
|
22
|
+
base = z.coerce.number();
|
|
23
|
+
break;
|
|
24
|
+
case "integer":
|
|
25
|
+
base = z.coerce.number().int();
|
|
26
|
+
break;
|
|
27
|
+
case "boolean":
|
|
28
|
+
base = z
|
|
29
|
+
.string()
|
|
30
|
+
.transform((v) => v === "true" || v === "1" || v === "yes")
|
|
31
|
+
.pipe(z.boolean());
|
|
32
|
+
break;
|
|
33
|
+
case "enum": {
|
|
34
|
+
const values = field.values;
|
|
35
|
+
if (!values || values.length === 0) {
|
|
36
|
+
throw new Error("Enum field must have values defined");
|
|
37
|
+
}
|
|
38
|
+
base = z.enum(values as [string, ...string[]]);
|
|
39
|
+
break;
|
|
40
|
+
}
|
|
41
|
+
case "port":
|
|
42
|
+
base = z.coerce.number().int().min(1).max(65535);
|
|
43
|
+
break;
|
|
44
|
+
case "email":
|
|
45
|
+
base = z.string().email();
|
|
46
|
+
break;
|
|
47
|
+
default:
|
|
48
|
+
base = z.string();
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
if (field.default !== undefined) {
|
|
52
|
+
base = base.default(field.default as string | number | boolean);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
return base;
|
|
56
|
+
}
|
package/src/types.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { z } from "zod";
|
|
2
|
+
import type { Client } from "@joinremba/core";
|
|
2
3
|
|
|
3
4
|
export type FieldType =
|
|
4
5
|
| "string"
|
|
@@ -40,11 +41,21 @@ export interface BeaconOptions {
|
|
|
40
41
|
profiles?: Record<string, Record<string, SchemaEntry>>;
|
|
41
42
|
features?: Record<string, FeatureGate>;
|
|
42
43
|
killSwitches?: Record<string, boolean>;
|
|
44
|
+
client?: Client;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export interface EnsureOptions {
|
|
48
|
+
/** When true (default), throws ConfigValidationError for missing required vars.
|
|
49
|
+
* When false, silently skips missing required vars — useful in test environments. */
|
|
50
|
+
strict?: boolean;
|
|
43
51
|
}
|
|
44
52
|
|
|
45
53
|
export interface Beacon {
|
|
46
|
-
ensure(): Beacon
|
|
54
|
+
ensure(options?: EnsureOptions): Promise<Beacon>;
|
|
47
55
|
get<T = unknown>(key: string): T;
|
|
56
|
+
/** Returns all validated entries as a flat key-value record.
|
|
57
|
+
* Secrets are included — callers should redact as needed. */
|
|
58
|
+
getAll(): Record<string, unknown>;
|
|
48
59
|
readonly secret: Record<string, boolean>;
|
|
49
60
|
isEnabled(feature: string): boolean;
|
|
50
61
|
isKilled(feature: string): boolean;
|