@joinremba/beacon 0.5.1 → 0.5.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@joinremba/beacon",
3
- "version": "0.5.1",
3
+ "version": "0.5.2",
4
4
  "description": "Validate environment variables, config, secrets, and runtime feature gates before production breaks.",
5
5
  "type": "module",
6
6
  "main": "./src/index.ts",
@@ -68,10 +68,10 @@
68
68
  "bun": ">=1.3.1"
69
69
  },
70
70
  "dependencies": {
71
- "@joinremba/core": "^0.4.0",
72
71
  "zod": "^4.4.2"
73
72
  },
74
73
  "devDependencies": {
74
+ "@joinremba/core": "^0.4.0",
75
75
  "@types/bun": "latest",
76
76
  "@typescript-eslint/eslint-plugin": "^7.18.0",
77
77
  "@typescript-eslint/parser": "^7.18.0",
package/src/cli-config.ts CHANGED
@@ -1,3 +1,4 @@
1
+ import type { z } from "zod";
1
2
  import type { FeatureGate, SchemaEntry } from "./types";
2
3
  import { typeToSchema, type SchemaField } from "./schema";
3
4
 
@@ -147,9 +148,10 @@ export async function runCheck(
147
148
  const field = entry as { required?: boolean; default?: unknown };
148
149
  required = field.required !== false;
149
150
  hasDefault = field.default !== undefined;
150
- } else {
151
- const f = entry as { required?: boolean };
151
+ } else if ("schema" in entry) {
152
+ const f = entry as { required?: boolean; schema: z.ZodType<unknown> };
152
153
  required = f.required !== false;
154
+ hasDefault = f.schema.safeParse(undefined).success;
153
155
  }
154
156
 
155
157
  if (raw === undefined || raw === "") {
@@ -164,13 +166,16 @@ export async function runCheck(
164
166
  continue;
165
167
  }
166
168
 
167
- const isSecret = isField ? (entry as { secret?: boolean }).secret : false;
169
+ const isSecret = (entry as { secret?: boolean }).secret ?? false;
168
170
  const display = isSecret ? SECRET_CENSOR : raw;
169
171
 
170
172
  try {
171
173
  if (isField) {
172
174
  const schema = typeToSchema(entry as SchemaField);
173
175
  schema.parse(raw);
176
+ } else if ("schema" in entry) {
177
+ const f = entry as { schema: z.ZodType<unknown> };
178
+ f.schema.parse(raw);
174
179
  }
175
180
  results.push({
176
181
  key,
package/src/cli.ts CHANGED
@@ -171,9 +171,7 @@ async function handleInit(args: ParsedArgs) {
171
171
  : [args.profile];
172
172
 
173
173
  for (const profile of profilesToGenerate) {
174
- const output = profile
175
- ? args.output || `.env.example.${profile}`
176
- : args.output || ".env.example";
174
+ const output = profile ? `.env.example.${profile}` : args.output || ".env.example";
177
175
  const example = generateEnvExample(config, profile);
178
176
  await Bun.write(output, example);
179
177
  console.log(` ${icon.pass} Generated ${color.bold(output)}`);
package/src/index.ts CHANGED
@@ -14,6 +14,7 @@ import { typeToSchema } from "./schema";
14
14
 
15
15
  export type {
16
16
  BeaconOptions,
17
+ EnsureOptions,
17
18
  FeatureGate,
18
19
  FieldDefinition,
19
20
  FieldDefinitionWithSchema,
package/src/schema.ts CHANGED
@@ -27,6 +27,9 @@ export function typeToSchema(field: SchemaField): z.ZodType<unknown> {
27
27
  case "boolean":
28
28
  base = z
29
29
  .string()
30
+ .refine((v) => ["true", "false", "1", "0", "yes", "no"].includes(v), {
31
+ message: "Expected one of: true, false, 1, 0, yes, no",
32
+ })
30
33
  .transform((v) => v === "true" || v === "1" || v === "yes")
31
34
  .pipe(z.boolean());
32
35
  break;