Files
brand/test/brand-json-consistency.test.mjs
zeekay 8689537969 feat(brand): white-label registry + host resolver (hanzo/lux/zoo/pars)
Add the multi-brand layer the fleet already expected (id-shared's
TenantConfig.brandPackage names @hanzo/brand; console/brands.ts modeled it):

- brand-id.ts: BrandId + HOST_BRANDS suffix table + brandFromHost(host).
  Exact suffix / dot-boundary match — lookalike hosts (lux.network.evil.com)
  cannot impersonate a brand. Pure module, no React/data deps.
- marks.ts: per-brand mark geometry. The Hanzo mark is consumed from
  @hanzo/logo (MARK_PATHS/MARK_VIEWBOX) — never re-typed. Lux/Zoo/Pars are
  the console v1 currentColor marks. renderMarkSVG() string helper.
- registry.ts: BrandIdentity + BRANDS registry + getBrand(host) +
  toBrandContract() (projects to @hanzo/id's BrandContract).
- logos.tsx: stop re-typing the block-H — consume @hanzo/logo; add the
  white-label <BrandLogo> component.

Fix: normalizeHost trims before stripping the port (padded host:port kept
its port under the old order — latent in the console source this consolidates).

13 node:test cases against the built dist: white-label invariant (distinct
marks, no Hanzo H in lux/zoo/pars), suffix-confusion attackers, port/case
insensitivity, brand.json<->registry consistency. type-check + build green.

Version 1.3.4 -> 1.4.0 (additive).
2026-07-21 09:27:10 -07:00

44 lines
1.8 KiB
JavaScript

/**
* brand.json ⟷ registry consistency.
*
* The Hanzo identity lives in TWO artifacts: the typed registry (for TS
* consumers) and brand.json (the runtime artifact the id portal fetches). They
* MUST agree — this test fails if they drift, keeping the single-source promise
* honest without a fragile cross-boundary import.
*/
import test from 'node:test'
import assert from 'node:assert/strict'
import { readFileSync } from 'node:fs'
import { fileURLToPath } from 'node:url'
import { BRANDS, toBrandContract } from '../dist/index.mjs'
const brandJson = JSON.parse(readFileSync(fileURLToPath(new URL('../brand.json', import.meta.url)), 'utf8'))
test('registry Hanzo entry agrees with brand.json', () => {
const h = BRANDS.hanzo
const j = brandJson.brand
assert.equal(h.name, j.name, 'name')
assert.equal(h.title, j.title, 'title')
assert.equal(h.tagline, j.description, 'tagline == brand.json description')
assert.equal(h.legalName, j.legalEntity, 'legalName == brand.json legalEntity')
assert.equal(h.domain, j.appDomain, 'domain == brand.json appDomain')
assert.equal(h.docsDomain, j.docsDomain, 'docsDomain')
})
test('registry Hanzo theme agrees with brand.json theme', () => {
const h = BRANDS.hanzo
const j = brandJson.brand.theme
assert.equal(h.theme.light.accent1, j.light.accent1, 'light accent1')
assert.equal(h.theme.dark.accent1, j.dark.accent1, 'dark accent1')
assert.equal(h.theme.light.surface1, j.light.surface1, 'light surface1')
assert.equal(h.theme.dark.surface1, j.dark.surface1, 'dark surface1')
})
test('brand.json still satisfies the id BrandContract via toBrandContract', () => {
// toBrandContract(Hanzo) must produce the same identity brand.json advertises.
const c = toBrandContract(BRANDS.hanzo)
assert.equal(c.name, brandJson.brand.name)
assert.equal(c.appDomain, brandJson.brand.appDomain)
})