{"_id":"@407dev/ipolish-content-schema","_rev":"2-d0b9f1ce8b69d486d4ddce4c11d47086","name":"@407dev/ipolish-content-schema","dist-tags":{"latest":"0.3.0"},"versions":{"0.3.0":{"name":"@407dev/ipolish-content-schema","version":"0.3.0","_id":"@407dev/ipolish-content-schema@0.3.0","maintainers":[{"name":"daviddecorso","email":"david@407.dev"},{"name":"lrossell","email":"lucas@407.dev"}],"homepage":"https://github.com/407dev/ipolish-content-schema#readme","bugs":{"url":"https://github.com/407dev/ipolish-content-schema/issues"},"dist":{"shasum":"2fd7cf8ad2cb3aeb535492843dbae73305666b50","tarball":"https://registry.npmjs.org/@407dev/ipolish-content-schema/-/ipolish-content-schema-0.3.0.tgz","fileCount":16,"integrity":"sha512-4tm8IFAqku3p37Ayy0McYmrU6FflNXBVz0DpJYRhZaLcsd2qHcgjz/jn+VPE2wlsrLjD7BVyzEIHoPOn7qgESw==","signatures":[{"sig":"MEYCIQCeTrlSLmzQw4kHuiC2bK/ZBaAeq1t0sjfIppunQXGc8gIhANaDh9C35SehRx4xidWhQziNE2/WprjfDOY8Ypv6S/Gv","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":51442},"main":"./dist/index.cjs","type":"module","_from":"file:407dev-ipolish-content-schema-0.3.0.tgz","types":"./dist/index.d.ts","module":"./dist/index.js","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"},"./types":{"types":"./dist/types.d.ts","import":"./dist/types.js","require":"./dist/types.cjs"}},"scripts":{"dev":"tsup --watch","test":"vitest run","build":"tsup","type-check":"tsc --noEmit"},"_npmUser":{"name":"lrossell","email":"lucas@407.dev"},"_resolved":"/tmp/cdea0593e2775269770b5ba17c6b2ed5/407dev-ipolish-content-schema-0.3.0.tgz","_integrity":"sha512-4tm8IFAqku3p37Ayy0McYmrU6FflNXBVz0DpJYRhZaLcsd2qHcgjz/jn+VPE2wlsrLjD7BVyzEIHoPOn7qgESw==","repository":{"url":"git+https://github.com/407dev/ipolish-content-schema.git","type":"git"},"_npmVersion":"10.8.2","description":"Shared Zod schemas + inferred types for ipolish CMS-authored content (the CMS↔app contract).","directories":{},"sideEffects":false,"_nodeVersion":"20.20.2","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"zod":"^4.1.11","tsup":"^8.3.5","vitest":"^2.1.8","typescript":"~5.9.2"},"peerDependencies":{"zod":"^4.1.0"},"peerDependenciesMeta":{"zod":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/ipolish-content-schema_0.3.0_1782499479839_0.30897075121074047","host":"s3://npm-registry-packages-npm-production"}}},"time":{"created":"2026-06-26T18:44:39.667Z","modified":"2026-08-12T01:09:30.599Z","0.3.0":"2026-06-26T18:44:39.979Z"},"bugs":{"url":"https://github.com/407dev/ipolish-content-schema/issues"},"homepage":"https://github.com/407dev/ipolish-content-schema#readme","repository":{"url":"git+https://github.com/407dev/ipolish-content-schema.git","type":"git"},"description":"Shared Zod schemas + inferred types for ipolish CMS-authored content (the CMS↔app contract).","maintainers":[{"email":"david@407.dev","name":"daviddecorso"},{"email":"lucas@407.dev","name":"lrossell"},{"email":"ethan@407.dev","name":"ethan407"}],"readme":"# @407dev/ipolish-content-schema\n\nSingle source of truth for the **CMS↔app content contract** — the shapes that\n`ipolish-cms` writes into layout-component `content` JSON and `ipolish-app` reads\nback. Zod schemas with inferred TypeScript types.\n\n## Why this exists\n\nThe app and CMS used to each keep their own hand-maintained copy of these shapes.\nWhen the CMS changed vibe `name`/`description` from plain strings to localized\nmaps (`{ en, es, ... }`), the app's copy didn't follow and rendered an object as a\nReact child → production crash.\n\nWith one shared schema, the app imports the **inferred type** and runs `tsc` in\nCI, so widening a field here makes every mismatched consumer fail to compile\ninstead of crashing in production. (Runtime `safeParse` gating is a planned Phase 2\non top of this.)\n\n## What it owns\n\nSelf-contained authored content (no Supabase/DB types):\n\n- `LocalizedText` / `localized()` — the inline translation primitive (4-level\n  locale fallback: direct → case-insensitive → base-language → `en`)\n- Quiz content + scoring helpers (`QuizContentSchema`, `getQuizResultIndex`, …)\n- Vibe content — `StoredVibe`/`StoredVibeSchema` (loose: tolerates legacy\n  plain-string `name`/`description`) and `Vibe`/`VibeSchema` (normalized maps)\n- Banner content (`BannerContentSchema`)\n\nIt owns only the shared **read** contract. CMS-only write concerns — seed data\n(`DEFAULT_VIBES`, `DEFAULT_QUIZ_CONTENT`) and `normalizeVibe` — live in the CMS,\nbuilt on the types exported here. Runtime-hydrated content that references\nSupabase rows (picture-palettes, trending-colors, video-list) stays in the app.\n\n## Two entry points\n\n- `@407dev/ipolish-content-schema` — Zod schemas + types + helpers. Used by the **CMS**\n  (which validates content). Requires `zod`.\n- `@407dev/ipolish-content-schema/types` — structural types + pure helpers, **no Zod at\n  runtime and none in the type graph**. Used by the **app** (React Native) so Zod\n  never enters its bundle. `zod` is an *optional* peer dependency for this reason.\n\n## Publishing (public npm)\n\nPublished to the **public npm registry** as the scoped public package\n`@407dev/ipolish-content-schema`. It installs over the plain npm protocol, so\nconsumers never clone or build it (works on any yarn/pnpm/git version, no\nEAS-yarn risk) — and because it's public, **no token is needed to install it**.\n\nCI publishes on a release tag (`.github/workflows/publish.yml`); manual fallback:\n\n```bash\npnpm version <patch|minor>        # bump + push tag\npnpm publish                      # prepare → tsup builds dist, then publishes\n```\n\nPublishing requires an npm token with publish rights on the `@407dev` org\n(`NPM_TOKEN` repo secret in CI; `npm login` locally). `publishConfig.access` is\n`public` so the scoped package is published publicly rather than private.\n\n## Consuming it\n\nNo registry config and no token — it's a normal public npm package. Just depend\non it by version:\n\n```jsonc\n\"@407dev/ipolish-content-schema\": \"^0.3.0\"\n```\n\nA content-shape change is **not done** until a new version is published and green\nin both `ipolish-cms` and `ipolish-app`.\n\n## Local development\n\nLink locally instead of waiting on a publish:\n\n```bash\npnpm dev            # tsup --watch → rebuilds dist/ on every save\n\n# app (yarn 4):  yarn add @407dev/ipolish-content-schema@portal:../ipolish-content-schema\n# cms (pnpm):    \"@407dev/ipolish-content-schema\": \"link:../ipolish-content-schema\"\n```\n\nMetro/Vite consume compiled `dist/`, so a build must always be present.\n\n## Scripts\n\n- `pnpm build` — emit `dist/` (ESM + CJS + d.ts) via tsup\n- `pnpm dev` — watch build\n- `pnpm test` — schema tests (vitest)\n- `pnpm type-check` — `tsc --noEmit`\n","readmeFilename":"README.md"}