@homeflare/site 0.1.1 → 0.1.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 CHANGED
@@ -5,11 +5,12 @@ hosts) and **pinned values**; `derive()` builds every hostname, address, zone su
5
5
  Access URL, OIDC redirect and vault mount name from it, the same way in every repo.
6
6
 
7
7
  ```sh
8
- bun add @homeflare/site effect@4.0.0-rc.115
8
+ bun add @homeflare/site effect@4.0.1
9
9
  ```
10
10
 
11
- ⛔ **`effect` is a pinned peer.** Effect release candidates are not compatible with each
12
- other, and the override behaviour this package relies on is measured per version.
11
+ ⛔ **`effect` is a pinned peer.** The override behaviour this package relies on is measured
12
+ per Effect version (stable 4.0.1 today), and the `@effect/*` packages are only compatible with
13
+ the exact `effect` they were released with.
13
14
 
14
15
  ★ **Why.** A public stack that types a hostname cannot be run by anyone else, and a stack
15
16
  that re-derives a name its own way drifts from its siblings. Swapping the apex here
@@ -1,5 +1,5 @@
1
1
  // src/version.ts
2
- var VERSION = "0.1.1";
2
+ var VERSION = "0.1.2";
3
3
 
4
4
  // src/errors.ts
5
5
  class SiteError extends Error {
@@ -284,5 +284,5 @@ function decodeSite(input, options = {}) {
284
284
 
285
285
  export { VERSION, SiteError, unknownKey, lookup, SITE_FORMAT, SiteSchema, checkDeriveVersion, assertStage, addressOn, APEX_ZONE, joinPath, formatIssues, decodeStrict, validateSite, decodeSite };
286
286
 
287
- //# debugId=5B3234B6C968C76F64756E2164756E21
288
- //# sourceMappingURL=index-rstgshyz.js.map
287
+ //# debugId=B55825B45C9EA1CC64756E2164756E21
288
+ //# sourceMappingURL=index-j6tpnkxv.js.map
@@ -2,7 +2,7 @@
2
2
  "version": 3,
3
3
  "sources": ["../src/version.ts", "../src/errors.ts", "../src/schema.ts", "../src/primitives.ts", "../src/guards.ts", "../src/decode.ts", "../src/net.ts", "../src/references.ts"],
4
4
  "sourcesContent": [
5
- "// ⛔ GENERATED by scripts/sync-versions.ts — do not edit. Source: package.json.\nexport const VERSION: string = '0.1.1';\n",
5
+ "// ⛔ GENERATED by scripts/sync-versions.ts — do not edit. Source: package.json.\nexport const VERSION: string = '0.1.2';\n",
6
6
  "/**\n * The one error this package throws.\n *\n * ★ ONE CLASS, A `code` TO SWITCH ON. Callers mostly print the message and stop; the few\n * that branch (a scaffold harness skipping `derive-version` in a dry run, say) branch on\n * `code`, which is stable, rather than on message text, which is not.\n *\n * ⛔ Messages name paths, keys and the fix — never a value from a live file beyond the\n * one being complained about. A site file is private, and an error string ends up in CI\n * logs.\n */\n\nexport type SiteErrorCode =\n /** The file does not match the schema. `issues` lists `path: problem`. */\n | 'decode'\n /** A value points at something the file does not declare (a zone, host, network). */\n | 'reference'\n /** A consumer asked for a product, service, zone, host or pin nobody declared. */\n | 'unknown-key'\n /** The file was reviewed against a different `@homeflare/site` version. */\n | 'derive-version'\n /** A non-live site was asked to plan stage `live`. */\n | 'stage'\n /** The observed vault or account is not the one the site describes. */\n | 'identity'\n /** The file could not be located, read or parsed. */\n | 'load'\n /** The file is not committed on `main` and `siteDev` was not set. */\n | 'checkout'\n /** An environment override was refused. */\n | 'override';\n\nexport class SiteError extends Error {\n override readonly name = 'SiteError';\n readonly code: SiteErrorCode;\n /** One line per problem, each naming its path. Empty when the message says it all. */\n readonly issues: readonly string[];\n\n constructor(code: SiteErrorCode, message: string, issues: readonly string[] = []) {\n super(issues.length === 0 ? message : `${message}\\n ${issues.join('\\n ')}`);\n this.code = code;\n this.issues = issues;\n }\n}\n\n/** Throw `unknown-key`, listing what IS declared so the fix is one glance away. */\nexport function unknownKey(kind: string, key: string, declared: Iterable<string>): never {\n const known = [...declared].sort();\n const list = known.length === 0 ? 'none are declared' : `declared: ${known.join(', ')}`;\n throw new SiteError('unknown-key', `unknown ${kind} \"${key}\" (${list})`);\n}\n\n/**\n * Look a key up in a record, or throw `unknown-key`.\n * ⛔ No fallback, ever. A plausible default host is how a typo becomes a live DNS record.\n */\nexport function lookup<V>(kind: string, record: Readonly<Record<string, V>>, key: string): V {\n if (!Object.hasOwn(record, key)) unknownKey(kind, key, Object.keys(record));\n return record[key] as V;\n}\n",
7
7
  "/**\n * The site file: BASE VALUES and PINNED values, nothing derived.\n *\n * ★ BASE VALUES are the few things every name is relative to — the apex, a handful of\n * labels, networks and hosts. `derive()` builds hostnames and addresses from them, so\n * swapping the apex changes every derived name by substitution and nothing else.\n *\n * ⛔ PINNED VALUES ARE NEVER DERIVED. Physical names (Workers, D1, KV, R2, Durable Objects)\n * follow no rule, and deriving one would REPLACE it: a derived D1 name deletes the data\n * behind the old one. Certificate hostnames on adopted certificates reissue and revoke\n * the certificate a host is still serving if they change. Adopted ids name objects that\n * already exist. Policy and SSH principal lists are explicit so a break-glass principal\n * can never vanish because a network leg was renamed.\n *\n * ⛔ UNKNOWN KEYS ARE REFUSED (see decode.ts). A misspelt optional field would otherwise\n * decode as \"absent\" and the file would look valid while saying less than its author\n * meant.\n */\nimport * as Effect from 'effect/Effect';\nimport * as Schema from 'effect/Schema';\nimport {\n AbsolutePath,\n AccountId,\n CertificateName,\n GithubOwner,\n HostNumber,\n Hostname,\n Ipv4,\n Ipv4Cidr,\n Label,\n ListEntry,\n NonBlank,\n PhysicalName,\n PinKey,\n Port,\n SemVer,\n} from './primitives.ts';\n\n/** The site file format this package reads. A new format is a new literal, never a reuse. */\nexport const SITE_FORMAT = 1;\n\nconst emptyRecord = <S extends Schema.Top>(schema: S) =>\n schema.pipe(Schema.withDecodingDefaultKey(Effect.succeed({})));\n\nconst Scheme = Schema.Literals(['http', 'https']);\n\n/**\n * A machine. Its FQDN is `<key>.<zone>`; its address on a network is that network's base\n * plus `legs[network]`.\n * ★ `zone: \"apex\"` places the host directly under the apex (`docs.<apex>`).\n */\nconst Host = Schema.Struct({\n zone: Schema.optionalKey(Label),\n aliases: Schema.optionalKey(Schema.Array(Label)),\n legs: Schema.optionalKey(Schema.Record(Label, HostNumber)),\n});\n\n/** A public product: `<label ?? key>.<apex>`, or its own `domain`. Never both. */\nconst Product = Schema.Struct({\n label: Schema.optionalKey(Label),\n domain: Schema.optionalKey(Hostname),\n});\n\n/** An internal endpoint on a declared host. ⛔ The scheme is explicit, never guessed. */\nconst Service = Schema.Struct({ host: Label, port: Port, scheme: Scheme });\n\nconst Account = Schema.Struct({\n id: AccountId,\n zones: Schema.Array(Hostname),\n /** Each surface becomes an OpenBao mount `cloudflare-<alias>-<surface>`. */\n surfaces: Schema.Array(Label),\n});\n\nconst Vault = Schema.Struct({\n /** `<vault-host>` = `<label>.<apex>`. */\n label: Label,\n /**\n * `<vault-api-host>` = `<apiLabel>.<vault-host>`.\n * ⚠️ NOT `vaultApi` beside a `vault` label. Measured 2026-09-21 on effect 4.0.0-rc.115:\n * constant-cased env names nest by prefix, so `HF_SITE_VAULT_API` made the provider\n * read `vault` as a record and the whole decode failed \"Expected string\". No field\n * name here may be another's name plus `_…`; tests/overrides.test.ts asserts it.\n */\n apiLabel: Label,\n /**\n * ⛔ PINNED IDENTITY: the `cluster_name` the vault reports on `sys/health`. Set at init,\n * never derived; plans compare it before touching anything (see identity.ts).\n */\n clusterName: NonBlank,\n namespace: Schema.String.pipe(Schema.withDecodingDefaultKey(Effect.succeed(''))),\n port: Port.pipe(Schema.withDecodingDefaultKey(Effect.succeed(8200))),\n /** The vault's address on the private Mesh path. Machines use it; strict TLS applies. */\n meshAddress: Ipv4,\n /** The LAN pass-through proxy: a declared host, its port, and its scheme. */\n lan: Schema.Struct({ host: Label, port: Port, scheme: Scheme }),\n oidcMount: Label.pipe(Schema.withDecodingDefaultKey(Effect.succeed('oidc'))),\n /** The port `bao login -method=oidc` listens on for its localhost callback. */\n cliCallbackPort: Port.pipe(Schema.withDecodingDefaultKey(Effect.succeed(8250))),\n});\n\nconst Pinned = Schema.Struct({\n names: emptyRecord(Schema.Record(PinKey, PhysicalName)),\n certificates: emptyRecord(Schema.Record(PinKey, Schema.NonEmptyArray(CertificateName))),\n adopted: emptyRecord(Schema.Record(PinKey, NonBlank)),\n policies: emptyRecord(Schema.Record(PinKey, Schema.Array(ListEntry))),\n sshPrincipals: emptyRecord(Schema.Record(PinKey, Schema.Array(ListEntry))),\n});\n\nexport const SiteSchema = Schema.Struct({\n /** The file format. Only {@link SITE_FORMAT} decodes. */\n version: Schema.Literal(SITE_FORMAT),\n /**\n * The `@homeflare/site` version whose derive rules this file was reviewed against.\n * ⛔ A repo refuses to load when its installed package differs (see guards.ts), so a\n * derive change can never rename live objects without someone bumping this line.\n */\n deriveVersion: SemVer,\n /** ⛔ Only a `live` site may plan stage `live` (see guards.ts). */\n kind: Schema.Literals(['live', 'testing', 'example']),\n apex: Hostname,\n /**\n * Zone suffixes under the apex: `{ \"mgmt\": \"mgmt\" }` gives `mgmt.<apex>`.\n * ⛔ `mgmt` is required (it is `<mgmt-zone>`), and the key `apex` is reserved.\n */\n zones: Schema.StructWithRest(Schema.Struct({ mgmt: Label }), [Schema.Record(Label, Label)]),\n networks: Schema.Record(Label, Ipv4Cidr),\n hosts: Schema.Record(Label, Host),\n clusters: emptyRecord(Schema.Record(Label, Schema.Struct({ members: Schema.Array(Label) }))),\n products: emptyRecord(Schema.Record(Label, Product)),\n services: emptyRecord(Schema.Record(Label, Service)),\n cloudflare: Schema.Struct({\n accounts: Schema.Record(Label, Account),\n access: Schema.Struct({ team: Label }),\n }),\n github: Schema.Struct({ owner: GithubOwner }),\n paths: Schema.Struct({ estateRoot: AbsolutePath }),\n vault: Vault,\n pinned: Pinned.pipe(Schema.withDecodingDefaultKey(Effect.succeed({}))),\n});\n\n/** A decoded site: defaults applied, every value checked. */\nexport type Site = typeof SiteSchema.Type;\n/** What a site file may contain before defaults are applied. */\nexport type SiteInput = typeof SiteSchema.Encoded;\n",
8
8
  "/**\n * The value shapes a site file is made of. Each one refuses at decode time, naming its path,\n * so a typo fails when the file is read rather than when a plan renames something.\n *\n * ⛔ LOWERCASE ONLY for DNS names. Cloudflare, OpenBao and ssh compare names as strings in\n * places, and `Mgmt.Example.com` is not `mgmt.example.com` to a principal list.\n */\nimport * as Schema from 'effect/Schema';\n\n/** One DNS label: `v`, `mgmt`, `node-a`. Also the shape of every key a consumer looks up. */\nexport const Label = Schema.String.check(\n Schema.isPattern(/^[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?$/, {\n message: 'Expected a lowercase DNS label (a-z, 0-9, inner hyphens, at most 63)',\n }),\n);\n\n/** A fully qualified name with at least two labels: `example.com`, `shop.example.net`. */\nexport const Hostname = Schema.String.check(\n Schema.isPattern(\n /^(?=.{1,253}$)([a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?\\.)+[a-z]([a-z0-9-]{0,61}[a-z0-9])?$/,\n { message: 'Expected a lowercase fully qualified hostname such as example.com' },\n ),\n);\n\n/** A certificate name: a hostname, or one leading wildcard label. */\nexport const CertificateName = Schema.String.check(\n Schema.isPattern(\n /^(\\*\\.)?([a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?\\.)+[a-z]([a-z0-9-]{0,61}[a-z0-9])?$/,\n { message: 'Expected a hostname, optionally with one leading *. wildcard' },\n ),\n);\n\nconst OCTET = '(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])';\n\n/** A dotted-quad IPv4 address, every octet 0–255. */\nexport const Ipv4 = Schema.String.check(\n Schema.isPattern(new RegExp(`^(${OCTET}\\\\.){3}${OCTET}$`), {\n message: 'Expected an IPv4 address such as 192.0.2.10',\n }),\n);\n\n/** Parse `a.b.c.d/p` into a 32-bit base and a prefix length. `undefined` when malformed. */\nexport function parseCidr(cidr: string): { base: number; prefix: number } | undefined {\n const match = new RegExp(`^((${OCTET}\\\\.){3}${OCTET})/([0-9]{1,2})$`).exec(cidr);\n if (match === null) return undefined;\n const prefix = Number(match[match.length - 1]);\n const base = (match[1] ?? '').split('.').reduce((acc, octet) => acc * 256 + Number(octet), 0);\n return { base, prefix };\n}\n\n/**\n * An IPv4 network, `/8` to `/30`, written at its network address.\n *\n * ⚠️ `192.0.2.5/24` is refused, not normalised. A host address with a prefix usually means\n * someone pasted an interface address where a network belongs; normalising it would hide\n * the mistake and derive every leg address from the wrong idea of the network.\n */\nexport const Ipv4Cidr = Schema.String.check(\n Schema.makeFilter(\n (value: string) => {\n const parsed = parseCidr(value);\n if (parsed === undefined) return 'Expected an IPv4 network such as 192.0.2.0/24';\n if (parsed.prefix < 8 || parsed.prefix > 30) return 'Expected a prefix between /8 and /30';\n const hostBits = 2 ** (32 - parsed.prefix);\n if (parsed.base % hostBits !== 0) return 'Expected the network address (host bits zero)';\n return undefined;\n },\n { expected: 'an IPv4 network' },\n ),\n);\n\n/** A host's number on a network: `.11` on a /24 is 11. Checked against the prefix later. */\nexport const HostNumber = Schema.Number.check(\n Schema.isInt(),\n Schema.isBetween({ minimum: 1, maximum: 16_777_214 }),\n);\n\nexport const Port = Schema.Number.check(\n Schema.isInt(),\n Schema.isBetween({ minimum: 1, maximum: 65_535 }),\n);\n\n/** A Cloudflare account id: 32 lowercase hex characters. */\nexport const AccountId = Schema.String.check(\n Schema.isPattern(/^[0-9a-f]{32}$/, {\n message: 'Expected a 32-character lowercase hex account id',\n }),\n);\n\n/** A GitHub user or organisation login. GitHub itself allows uppercase here. */\nexport const GithubOwner = Schema.String.check(\n Schema.isPattern(/^[A-Za-z0-9]([A-Za-z0-9-]{0,37}[A-Za-z0-9])?$/, {\n message: 'Expected a GitHub login (letters, digits, inner hyphens)',\n }),\n);\n\n/** An absolute POSIX path with no trailing slash: `/opt/example`. */\nexport const AbsolutePath = Schema.String.check(\n Schema.isPattern(/^(\\/[^/\\0]+)+$/, {\n message: 'Expected an absolute path without a trailing slash',\n }),\n);\n\n/** A semver version, as npm writes one: `0.1.0`, `1.0.0-rc.1`. */\nexport const SemVer = Schema.String.check(\n Schema.isPattern(/^\\d+\\.\\d+\\.\\d+(-[0-9A-Za-z.-]+)?$/, { message: 'Expected a semver version' }),\n);\n\n/** A key into a `pinned` table: `alerts.d1`, `ssh-host.host`. Dotted, lowercase. */\nexport const PinKey = Schema.String.check(\n Schema.isPattern(/^[a-z0-9]+([._-][a-z0-9]+)*$/, {\n message: 'Expected a lowercase dotted key such as alerts.d1',\n }),\n);\n\n/**\n * A physical resource name: Worker, D1, KV, R2, Durable Object class.\n * ★ Case is allowed because Durable Object bindings name PascalCase classes.\n */\nexport const PhysicalName = Schema.String.check(\n Schema.isPattern(/^[A-Za-z0-9][A-Za-z0-9._-]*$/, {\n message: 'Expected a resource name (letters, digits, dot, dash, underscore)',\n }),\n);\n\n/**\n * One SSH principal or policy entry.\n * ⛔ No commas and no whitespace. OpenBao stores principal lists comma-joined, so an entry\n * holding a comma silently becomes two principals, and a stray space becomes a name no\n * host will ever present.\n */\nexport const ListEntry = Schema.String.check(\n Schema.isPattern(/^[^\\s,]+$/, { message: 'Expected one entry with no commas or whitespace' }),\n);\n\n/** A free-form identifier that must not be blank: cluster names, adopted ids, CNs. */\nexport const NonBlank = Schema.String.check(\n Schema.isPattern(/^\\S(.*\\S)?$/, { message: 'Expected a non-blank value without edge spaces' }),\n);\n",
@@ -12,6 +12,6 @@
12
12
  "/**\n * Checks that span fields: every zone, host and network a value names is declared.\n *\n * ★ WHY NOT IN THE SCHEMA. A struct-level filter reports one issue at the struct's own\n * path; these checks want to name the exact field (`services.grafana.host`), and they\n * want to report every broken reference at once rather than the first.\n */\nimport { lastHostNumber } from './net.ts';\nimport type { Site } from './schema.ts';\n\n/** The zone key that means the apex itself. Reserved: a site may not declare it. */\nexport const APEX_ZONE = 'apex';\n\nfunction hostHasZone(site: Site, host: string): boolean {\n return Object.hasOwn(site.hosts, host) && site.hosts[host]?.zone !== undefined;\n}\n\nfunction checkHosts(site: Site, issues: string[]): void {\n for (const [key, host] of Object.entries(site.hosts)) {\n const zone = host.zone;\n if (zone !== undefined && zone !== APEX_ZONE && !Object.hasOwn(site.zones, zone)) {\n issues.push(`hosts.${key}.zone: \"${zone}\" is not a declared zone or \"${APEX_ZONE}\"`);\n }\n for (const [network, number] of Object.entries(host.legs ?? {})) {\n const cidr = site.networks[network];\n if (cidr === undefined) {\n issues.push(`hosts.${key}.legs.${network}: \"${network}\" is not a declared network`);\n } else if (number > lastHostNumber(cidr)) {\n issues.push(`hosts.${key}.legs.${network}: host number ${number} does not fit ${network}`);\n }\n }\n }\n}\n\nfunction checkZonedHost(site: Site, path: string, host: string, issues: string[]): void {\n if (!Object.hasOwn(site.hosts, host)) {\n issues.push(`${path}: \"${host}\" is not a declared host`);\n } else if (!hostHasZone(site, host)) {\n issues.push(`${path}: host \"${host}\" has no zone, so it has no hostname`);\n }\n}\n\nfunction checkAccounts(site: Site, issues: string[]): void {\n for (const [alias, account] of Object.entries(site.cloudflare.accounts)) {\n const seen = new Set<string>();\n for (const surface of account.surfaces) {\n // ⚠️ A repeated surface derives the same mount name twice; the second declaration\n // would silently be the same mount, so a typo'd duplicate is refused here.\n if (seen.has(surface)) {\n issues.push(`cloudflare.accounts.${alias}.surfaces: \"${surface}\" is listed twice`);\n }\n seen.add(surface);\n }\n }\n}\n\n/** Every broken reference in `site`, each naming its path. Empty when the site is sound. */\nexport function referenceIssues(site: Site): readonly string[] {\n const issues: string[] = [];\n\n if (Object.hasOwn(site.zones, APEX_ZONE)) {\n issues.push(`zones.${APEX_ZONE}: reserved — a host with zone \"${APEX_ZONE}\" sits on the apex`);\n }\n checkHosts(site, issues);\n for (const [key, cluster] of Object.entries(site.clusters)) {\n for (const [i, member] of cluster.members.entries()) {\n checkZonedHost(site, `clusters.${key}.members.${i}`, member, issues);\n }\n }\n for (const [key, product] of Object.entries(site.products)) {\n if (product.label !== undefined && product.domain !== undefined) {\n issues.push(`products.${key}: set label OR domain, not both`);\n }\n }\n for (const [key, service] of Object.entries(site.services)) {\n checkZonedHost(site, `services.${key}.host`, service.host, issues);\n }\n checkZonedHost(site, 'vault.lan.host', site.vault.lan.host, issues);\n checkAccounts(site, issues);\n\n return issues;\n}\n"
13
13
  ],
14
14
  "mappings": "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",
15
- "debugId": "5B3234B6C968C76F64756E2164756E21",
15
+ "debugId": "B55825B45C9EA1CC64756E2164756E21",
16
16
  "names": []
17
17
  }
package/dist/index.js CHANGED
@@ -12,7 +12,7 @@ import {
12
12
  lookup,
13
13
  unknownKey,
14
14
  validateSite
15
- } from "./index-rstgshyz.js";
15
+ } from "./index-j6tpnkxv.js";
16
16
  // src/derive.ts
17
17
  function zoneOf(site, key) {
18
18
  if (key === APEX_ZONE)
package/dist/load.js CHANGED
@@ -4,7 +4,7 @@ import {
4
4
  decodeStrict,
5
5
  formatIssues,
6
6
  validateSite
7
- } from "./index-rstgshyz.js";
7
+ } from "./index-j6tpnkxv.js";
8
8
 
9
9
  // src/load.ts
10
10
  import { readFile } from "node:fs/promises";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@homeflare/site",
3
- "version": "0.1.1",
3
+ "version": "0.1.2",
4
4
  "description": "One typed site config: base values, pinned names, and every hostname and address derived from them.",
5
5
  "homepage": "https://github.com/taslabs-net/homeflare-kit/tree/main/packages/site#readme",
6
6
  "bugs": "https://github.com/taslabs-net/homeflare-kit/issues",
@@ -36,6 +36,6 @@
36
36
  "access": "public"
37
37
  },
38
38
  "peerDependencies": {
39
- "effect": "4.0.0-rc.115"
39
+ "effect": "4.0.1"
40
40
  }
41
41
  }
package/site.example.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "version": 1,
3
- "deriveVersion": "0.1.1",
3
+ "deriveVersion": "0.1.2",
4
4
  "kind": "example",
5
5
  "apex": "example.com",
6
6
  "zones": { "mgmt": "mgmt", "lab": "lab" },
package/src/version.ts CHANGED
@@ -1,2 +1,2 @@
1
1
  // ⛔ GENERATED by scripts/sync-versions.ts — do not edit. Source: package.json.
2
- export const VERSION: string = '0.1.1';
2
+ export const VERSION: string = '0.1.2';