{"_id":"@bernierllc/site-config-core","_rev":"4-4633bc173c7f0c6cd9440d94a09d47ba","name":"@bernierllc/site-config-core","dist-tags":{"latest":"0.3.1"},"versions":{"0.0.1":{"name":"@bernierllc/site-config-core","version":"0.0.1","keywords":["oidc","trusted-publishing","setup"],"_id":"@bernierllc/site-config-core@0.0.1","maintainers":[{"name":"alikhan410","email":"mczeyo@gmail.com"},{"name":"mkbernier","email":"mkbernier@gmail.com"}],"dist":{"shasum":"abd93c777e1fadc0b7a4775c3854201356f6563d","tarball":"https://registry.npmjs.org/@bernierllc/site-config-core/-/site-config-core-0.0.1.tgz","fileCount":2,"integrity":"sha512-FTGvYuv0+I6bm8HQzpFI/PI4mr0q0gastSbQ8W6S85VKMyQWGiKQ0Xxhop038wJ8gz/C/zXm2xR/kzkOQeMKZg==","signatures":[{"sig":"MEQCIA/qhrLOsZ70Y1853tNn8V5IDMEJXFQ+06er15nVysVBAiAtgQfb6Bzwwg7IswIr2I/1HQD8OCXIgC2ZH9FxM3qAOA==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":2075},"_npmUser":{"name":"mkbernier","email":"mkbernier@gmail.com"},"_npmVersion":"11.12.1","description":"OIDC trusted publishing setup package for @bernierllc/site-config-core","directories":{},"_nodeVersion":"25.9.0","_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/site-config-core_0.0.1_1781634244592_0.10486587250633006","host":"s3://npm-registry-packages-npm-production"}},"0.2.0":{"name":"@bernierllc/site-config-core","version":"0.2.0","keywords":["site-config","website-builder","schema","zod","config","bernierllc"],"author":{"name":"Bernier LLC"},"license":"Bernier LLC","_id":"@bernierllc/site-config-core@0.2.0","maintainers":[{"name":"alikhan410","email":"mczeyo@gmail.com"},{"name":"mkbernier","email":"mkbernier@gmail.com"}],"homepage":"https://github.com/bernierllc/tools#readme","bugs":{"url":"https://github.com/bernierllc/tools/issues"},"dist":{"shasum":"fd6717ef530c2fee4e1475c26dd120ad2197e66a","tarball":"https://registry.npmjs.org/@bernierllc/site-config-core/-/site-config-core-0.2.0.tgz","fileCount":39,"integrity":"sha512-3ywy+wjGMcjBr8CLRBWrYiLioApeoAG4rjNYhxIVbKMLwaeu04e5NSAuedlRI2WInJUvH//sqPB+ww/x17IJIg==","signatures":[{"sig":"MEUCIHF4II81bbg5vlmw3t9LMBIKowU7WlpB4iKtnEMZnqLaAiEA7UMV1Nd6rm+nZ12reidBfatmfo3jB6vNBkWYPoqsd7E=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":71297},"main":"dist/index.js","_from":"file:bernierllc-site-config-core-0.2.0.tgz","types":"dist/index.d.ts","engines":{"node":">=18.0.0"},"scripts":{"lint":"eslint src/**/*.ts","test":"jest","build":"tsc","clean":"rm -rf dist","prebuild":"npm run clean","test:run":"jest","test:watch":"jest --watch","test:coverage":"jest --coverage"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:a5576167-564b-47d3-86b3-67460bea06dc"}},"_resolved":"/home/runner/work/tools/tools/packages/core/site-config-core/bernierllc-site-config-core-0.2.0.tgz","_integrity":"sha512-3ywy+wjGMcjBr8CLRBWrYiLioApeoAG4rjNYhxIVbKMLwaeu04e5NSAuedlRI2WInJUvH//sqPB+ww/x17IJIg==","bernierllc":{"runtime":"universal","category":"core","integration":{"logger":"integrated","neverhub":"not-applicable","neveradmin":"not-applicable"}},"repository":{"url":"git+https://github.com/bernierllc/tools.git","type":"git","directory":"packages/core/site-config-core"},"_npmVersion":"11.17.0","description":"Typed SiteConfig schema, Zod validation, and pure helpers for config-driven website profiles.","directories":{},"_nodeVersion":"24.16.0","dependencies":{"zod":"^3.22.0","@bernierllc/logger":"1.7.0","@bernierllc/schema-validator":"3.0.0"},"publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"_hasShrinkwrap":false,"devDependencies":{"jest":"^29.7.0","eslint":"^8.0.0","rimraf":"^5.0.0","ts-jest":"^29.1.2","typescript":"^5.3.3","@types/jest":"^29.5.12","@types/node":"^20.11.19"},"_npmOperationalInternal":{"tmp":"tmp/site-config-core_0.2.0_1781801881751_0.17327957698868635","host":"s3://npm-registry-packages-npm-production"}},"0.3.0":{"name":"@bernierllc/site-config-core","version":"0.3.0","keywords":["site-config","website-builder","schema","zod","config","bernierllc"],"author":{"name":"Bernier LLC"},"license":"Bernier LLC","_id":"@bernierllc/site-config-core@0.3.0","maintainers":[{"name":"alikhan410","email":"mczeyo@gmail.com"},{"name":"mkbernier","email":"mkbernier@gmail.com"}],"homepage":"https://github.com/bernierllc/tools#readme","bugs":{"url":"https://github.com/bernierllc/tools/issues"},"dist":{"shasum":"07122824383da4a37b1435296879339b9224ab36","tarball":"https://registry.npmjs.org/@bernierllc/site-config-core/-/site-config-core-0.3.0.tgz","fileCount":39,"integrity":"sha512-QHTqop0MQ9GJIQhXHeLMtYHUdKBnZWssUzcmYmmOiCmW9J85dDwdM9uPa2KF9BLGVTl4vir7iIXlowZ7UTq5+A==","signatures":[{"sig":"MEUCIAM4ZQ/QuZwI9momujK/U8X0D6yL3XLkWP8tLOrWFm5WAiEA/nf1UjUQAn64knb05p2vC5/HWX2fU3lW2mG0vH0plBg=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":72589},"main":"dist/index.js","_from":"file:bernierllc-site-config-core-0.3.0.tgz","types":"dist/index.d.ts","engines":{"node":">=18.0.0"},"scripts":{"lint":"eslint src/**/*.ts","test":"jest","build":"tsc","clean":"rm -rf dist","prebuild":"npm run clean","test:run":"jest","test:watch":"jest --watch","test:coverage":"jest --coverage"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:a5576167-564b-47d3-86b3-67460bea06dc"}},"_resolved":"/home/runner/work/tools/tools/packages/core/site-config-core/bernierllc-site-config-core-0.3.0.tgz","_integrity":"sha512-QHTqop0MQ9GJIQhXHeLMtYHUdKBnZWssUzcmYmmOiCmW9J85dDwdM9uPa2KF9BLGVTl4vir7iIXlowZ7UTq5+A==","bernierllc":{"runtime":"universal","category":"core","integration":{"logger":"integrated","neverhub":"not-applicable","neveradmin":"not-applicable"}},"repository":{"url":"git+https://github.com/bernierllc/tools.git","type":"git","directory":"packages/core/site-config-core"},"_npmVersion":"11.17.0","description":"Typed SiteConfig schema, Zod validation, and pure helpers for config-driven website profiles.","directories":{},"_nodeVersion":"24.16.0","dependencies":{"zod":"^3.22.0","@bernierllc/logger":"1.7.0","@bernierllc/schema-validator":"3.0.0"},"publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"_hasShrinkwrap":false,"devDependencies":{"jest":"^29.7.0","eslint":"^8.0.0","rimraf":"^5.0.0","ts-jest":"^29.1.2","typescript":"^5.3.3","@types/jest":"^29.5.12","@types/node":"^20.11.19"},"_npmOperationalInternal":{"tmp":"tmp/site-config-core_0.3.0_1781985861851_0.37416078911557427","host":"s3://npm-registry-packages-npm-production"}},"0.3.1":{"name":"@bernierllc/site-config-core","version":"0.3.1","description":"Typed SiteConfig schema, Zod validation, and pure helpers for config-driven website profiles.","main":"dist/index.js","types":"dist/index.d.ts","keywords":["site-config","website-builder","schema","zod","config","bernierllc"],"author":{"name":"Bernier LLC"},"license":"Bernier LLC","repository":{"type":"git","url":"git+https://github.com/bernierllc/tools.git","directory":"packages/core/site-config-core"},"dependencies":{"zod":"^3.22.0","@bernierllc/logger":"1.7.1","@bernierllc/schema-validator":"3.0.0"},"devDependencies":{"@types/jest":"^29.5.12","@types/node":"^20.11.19","eslint":"^8.0.0","jest":"^29.7.0","rimraf":"^5.0.0","ts-jest":"^29.1.2","typescript":"^5.3.3"},"engines":{"node":">=18.0.0"},"publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"bernierllc":{"runtime":"universal","category":"core","integration":{"neverhub":"not-applicable","neveradmin":"not-applicable","logger":"integrated"}},"scripts":{"build":"tsc","test":"jest","test:watch":"jest --watch","test:run":"jest","test:coverage":"jest --coverage","lint":"eslint src/**/*.ts","clean":"rm -rf dist","prebuild":"npm run clean"},"_id":"@bernierllc/site-config-core@0.3.1","bugs":{"url":"https://github.com/bernierllc/tools/issues"},"homepage":"https://github.com/bernierllc/tools#readme","_integrity":"sha512-Ow/d0IRD1DHdDHfndKwDB7SJ0lnY4V1fnHnsYRhSI3HS/PkP0z4O1WNnfbLB51cKqMJjcE17qx1x+4Ipubzcgw==","_resolved":"/home/runner/work/tools/tools/packages/core/site-config-core/bernierllc-site-config-core-0.3.1.tgz","_from":"file:bernierllc-site-config-core-0.3.1.tgz","_nodeVersion":"24.18.0","_npmVersion":"12.0.1","dist":{"integrity":"sha512-Ow/d0IRD1DHdDHfndKwDB7SJ0lnY4V1fnHnsYRhSI3HS/PkP0z4O1WNnfbLB51cKqMJjcE17qx1x+4Ipubzcgw==","shasum":"a533c3e414c5ac3e923ffa6bdda7c6cde5458d18","tarball":"https://registry.npmjs.org/@bernierllc/site-config-core/-/site-config-core-0.3.1.tgz","fileCount":39,"unpackedSize":72589,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQCqqSjifCWUQOlNJlfRWHDAjSfGQEZ6EWe0ddUs0/Q9fAIhAOaecBqNTHq0rBr++T4HNWHb/rkMJZ8GDcfuJB856lmU"}]},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:a5576167-564b-47d3-86b3-67460bea06dc"}},"directories":{},"maintainers":[{"name":"alikhan410","email":"mczeyo@gmail.com"},{"name":"mkbernier","email":"mkbernier@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/site-config-core_0.3.1_1784015699918_0.16149780049662343"},"_hasShrinkwrap":false}},"time":{"created":"2026-06-16T18:24:04.402Z","modified":"2026-07-14T07:55:00.167Z","0.0.1":"2026-06-16T18:24:05.220Z","0.2.0":"2026-06-18T16:58:02.506Z","0.3.0":"2026-06-20T20:04:21.990Z","0.3.1":"2026-07-14T07:55:00.045Z"},"bugs":{"url":"https://github.com/bernierllc/tools/issues"},"author":{"name":"Bernier LLC"},"license":"Bernier LLC","homepage":"https://github.com/bernierllc/tools#readme","keywords":["site-config","website-builder","schema","zod","config","bernierllc"],"repository":{"type":"git","url":"git+https://github.com/bernierllc/tools.git","directory":"packages/core/site-config-core"},"description":"Typed SiteConfig schema, Zod validation, and pure helpers for config-driven website profiles.","maintainers":[{"name":"alikhan410","email":"mczeyo@gmail.com"},{"name":"mkbernier","email":"mkbernier@gmail.com"}],"readme":"# @bernierllc/site-config-core\n\nTyped SiteConfig schema, Zod validation, and pure helpers for config-driven website profiles.\n\n## Overview\n\nThe canonical data layer for website builder profiles. No I/O, no rendering — pure data:\nvalidate, transform, inspect.\n\n| Export | Description |\n|--------|-------------|\n| `SiteConfigSchema` | Root Zod schema for a complete site configuration |\n| `SiteSectionSchema` | Discriminated union of all section types |\n| `HexColorSchema` | `#rrggbb` validated branded hex color |\n| `validate(raw)` | Returns a Zod `SafeParseReturnType` — never throws |\n| `defaultConfig(tenantId, slug)` | Factory returning a draft-status default config |\n| `completenessScore(config)` | 0–100 score across 6 named checkpoints |\n| `completenessCheckpoints(config)` | Raw checkpoint array for custom progress UI |\n| `toCssVariables(theme)` | Emits 5 CSS custom property key-value pairs |\n| `mergeConfigs(base, patch)` | Shallow merge of branding/theme, validated by schema |\n| `diffConfigs(a, b)` | Structured diff of changed fields and section changes |\n| `SiteConfigError` | Base error class with `code` and `context` |\n| `SiteConfigValidationError` | Thrown on schema validation failure (code: `VALIDATION_ERROR`) |\n\n## Installation\n\n```bash\nnpm install @bernierllc/site-config-core\n```\n\n## Usage\n\n### Creating a default draft config\n\n```typescript\nimport { defaultConfig, validate } from '@bernierllc/site-config-core';\n\nconst config = defaultConfig('tenant-abc', 'acme-plumbing');\n// config.status === 'draft'\n// config.theme.heroStyle === 'minimal'\n// config.branding.name === '' (draft — fill in before marking ready)\n\nconst result = validate(config);\nif (result.success) {\n  console.log(result.data.tenantId); // 'tenant-abc'\n} else {\n  console.error(result.error.issues);\n}\n```\n\n### Validating an unknown payload\n\n```typescript\nimport { validate } from '@bernierllc/site-config-core';\n\nconst result = validate(rawPayloadFromRequest);\nif (!result.success) {\n  // result.error.issues contains every Zod validation issue\n  throw new Error(result.error.message);\n}\n// result.data is fully typed as SiteConfig\n```\n\n### Completeness scoring\n\n```typescript\nimport { completenessScore, mergeConfigs, defaultConfig } from '@bernierllc/site-config-core';\n\nconst config = mergeConfigs(defaultConfig('t', 'acme'), {\n  branding: { name: 'Acme Plumbing', tagline: 'We fix things fast' },\n  sections: [\n    { type: 'services', items: [{ id: 's1', name: 'Drain Cleaning' }] },\n    { type: 'contact', email: 'hello@acme.com' },\n  ],\n});\n\nconst { score, checkpoints, missingFields } = completenessScore(config);\n// score: 50 (3 of 6 checkpoints pass)\n// missingFields: ['logo', 'theme' is always true, 'status']\n\ncheckpoints.forEach(cp => {\n  console.log(`${cp.label}: ${cp.passed ? 'done' : cp.detail ?? 'incomplete'}`);\n});\n```\n\n### Emitting CSS variables from a theme\n\n```typescript\nimport { toCssVariables, defaultConfig } from '@bernierllc/site-config-core';\n\nconst { theme } = defaultConfig('t', 's');\nconst vars = toCssVariables(theme);\n// {\n//   '--color-primary':   '#1a1a1a',\n//   '--color-secondary': '#ffffff',\n//   '--color-accent':    '#3b82f6',\n//   '--font-heading':    'Inter',\n//   '--font-body':       'Inter',\n// }\n\n// Apply in a browser context:\nObject.entries(vars).forEach(([prop, val]) => {\n  document.documentElement.style.setProperty(prop, val);\n});\n```\n\n### Merging a partial patch\n\n```typescript\nimport { mergeConfigs, defaultConfig } from '@bernierllc/site-config-core';\n\nconst base = defaultConfig('tenant-1', 'my-site');\n\n// Only override what changed — unchanged fields survive\nconst updated = mergeConfigs(base, {\n  branding: { name: 'My Site' },\n  status: 'ready',\n});\n// updated.branding.name === 'My Site'\n// updated.theme.fontHeading === 'Inter'  ← preserved\n```\n\n### Diffing two configs\n\n```typescript\nimport { diffConfigs, mergeConfigs, defaultConfig } from '@bernierllc/site-config-core';\n\nconst a = defaultConfig('t', 's');\nconst b = mergeConfigs(a, {\n  status: 'published',\n  sections: [{ type: 'hero', headline: 'Welcome' }],\n});\n\nconst diff = diffConfigs(a, b);\n// diff.changedFields: [{ path: 'status', from: 'draft', to: 'published' }, ...]\n// diff.addedSections: ['hero']\n// diff.removedSections: []\n```\n\n### Error handling\n\n```typescript\nimport {\n  SiteConfigError,\n  SiteConfigValidationError,\n} from '@bernierllc/site-config-core';\n\ntry {\n  doSomethingWithConfig(config);\n} catch (error) {\n  if (error instanceof SiteConfigValidationError) {\n    // code === 'VALIDATION_ERROR'\n    console.error(error.code, error.context);\n  } else if (error instanceof SiteConfigError) {\n    console.error(error.code, error.message);\n    if (error.cause) {\n      console.error('caused by:', error.cause);\n    }\n  }\n}\n```\n\n## SiteSection types\n\nThe `sections` array accepts any of these discriminated types:\n\n| `type` | Required fields | Notable optional fields |\n|--------|-----------------|------------------------|\n| `hero` | — | `headline`, `subheadline`, `ctaLabel`, `ctaHref` |\n| `services` | — | `title`, `items[]` (id, name, description, category, price) |\n| `team` | — | `title`, `members[]` (id, name, role, bio, avatarUrl) |\n| `serviceArea` | — | `title`, `cities[]`, `mapEmbedUrl` |\n| `hours` | — | `title`, `schedule` (Record<string,string>) |\n| `contact` | — | `email`, `phone`, `address`, `showForm` |\n| `custom` | `id`, `title`, `content` | — |\n\nMultiple sections of the same type are allowed (e.g., two `custom` sections).\n\n## Completeness checkpoints\n\n`completenessScore` evaluates exactly 6 named checkpoints in order:\n\n| name | label | Passes when |\n|------|-------|-------------|\n| `branding` | Business identity | `branding.name` and `branding.tagline` are both non-empty |\n| `logo` | Logo uploaded | `branding.logoUrl` is set |\n| `theme` | Colors & fonts | `primaryColor` and `secondaryColor` are present |\n| `services` | Services listed | A `services` section exists with at least one item |\n| `contact` | Contact info | A `contact` section has `email` or `phone` |\n| `status` | Site marked ready | `status` is `ready` or `published` |\n\n## MECE Boundary\n\n**Includes**: schema, types, validation, pure helpers (factory, completeness, CSS vars, merge, diff).\n\n**Excludes**: persistence, rendering, HTTP, React components. Those live in `site-builder-service` and `site-preview-ui`.\n\n## License\n\nCopyright (c) 2025 Bernier LLC. See LICENSE for details.\n","readmeFilename":"README.md"}