{"_id":"@actuate-media/component-blocks","_rev":"4-68ff11122310f4a9f744f5f891728155","name":"@actuate-media/component-blocks","dist-tags":{"latest":"0.2.2"},"versions":{"0.2.0":{"name":"@actuate-media/component-blocks","version":"0.2.0","_id":"@actuate-media/component-blocks@0.2.0","maintainers":[{"name":"actuate_media","email":"strategize@actuatemedia.com"}],"homepage":"https://github.com/actuate-media/actuatecms#readme","bugs":{"url":"https://github.com/actuate-media/actuatecms/issues"},"bin":{"actuate-component-blocks":"dist/cli.js"},"dist":{"shasum":"3783c2673665da47c5b6b8a4f9700a7396996538","tarball":"https://registry.npmjs.org/@actuate-media/component-blocks/-/component-blocks-0.2.0.tgz","fileCount":35,"integrity":"sha512-Inngt137/vGnmfV10LF4qz5BqcOFEf9+XE5yygm8gDSERmrKCjb04EqiV1qVW4STK5k1FLlIrKdMwYI7l7zykw==","signatures":[{"sig":"MEYCIQDmQ+r/v4XjcxbfFDQGDiqGfYgEoLIPjG5XjR1UXysDBAIhANdMDH7R2MAUCDsib7Vwy4bWrXBkiH0gL4AUVeCv5wRo","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":219782},"main":"./dist/index.js","type":"module","_from":"file:actuate-media-component-blocks-0.2.0.tgz","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","default":"./dist/index.js"},"./cli":{"types":"./dist/cli.d.ts","import":"./dist/cli.js","default":"./dist/cli.js"},"./discriminated-union":{"types":"./dist/discriminated-union.d.ts","import":"./dist/discriminated-union.js","default":"./dist/discriminated-union.js"}},"scripts":{"dev":"tsc --project tsconfig.json --watch --preserveWatchOutput","test":"vitest run","build":"tsc --project tsconfig.json","clean":"rm -rf dist .turbo","type-check":"tsc --noEmit"},"_npmUser":{"name":"actuate_media","email":"strategize@actuatemedia.com"},"_resolved":"/tmp/c95accba70689e763e1ac48668dd065d/actuate-media-component-blocks-0.2.0.tgz","_integrity":"sha512-Inngt137/vGnmfV10LF4qz5BqcOFEf9+XE5yygm8gDSERmrKCjb04EqiV1qVW4STK5k1FLlIrKdMwYI7l7zykw==","repository":{"url":"git+https://github.com/actuate-media/actuatecms.git","type":"git","directory":"packages/component-blocks"},"_npmVersion":"10.9.8","description":"Extract a Manifest of React component props for use as type-aware CMS blocks.","directories":{},"_nodeVersion":"22.22.3","dependencies":{"react-docgen-typescript":"^2.2.2"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"react":"^19.2.0","vitest":"^3.0.0","typescript":"^5.7.0","@types/node":"^22.0.0","@types/react":"^19.0.0"},"peerDependencies":{"typescript":">=5.0.0"},"_npmOperationalInternal":{"tmp":"tmp/component-blocks_0.2.0_1779696050111_0.8136046310901746","host":"s3://npm-registry-packages-npm-production"},"deprecated":"Renamed to @prenta/component-blocks — see https://github.com/actuate-media/prenta"},"0.2.1":{"name":"@actuate-media/component-blocks","version":"0.2.1","_id":"@actuate-media/component-blocks@0.2.1","maintainers":[{"name":"actuate_media","email":"strategize@actuatemedia.com"}],"homepage":"https://github.com/actuate-media/actuatecms#readme","bugs":{"url":"https://github.com/actuate-media/actuatecms/issues"},"bin":{"actuate-component-blocks":"dist/cli.js"},"dist":{"shasum":"0ea7f21fb620a4ebe2d9b9b424592f40f96ccc7a","tarball":"https://registry.npmjs.org/@actuate-media/component-blocks/-/component-blocks-0.2.1.tgz","fileCount":36,"integrity":"sha512-24eAgiLWXIaN+A0MTM6jUYkWW5ZJBJsCP48w+pVd0dPTk9WSM834zKB9jO0hLg+W31VwzCUNiZYzLToOHOdrfg==","signatures":[{"sig":"MEUCIATyCRiK3QHEyrpE1HPMfOvVroHInbYgThxRHw1iwEd2AiEAj9++xZw87+3ROaOoMegGsnUUAj9ppB2ugw5F5Vy+Ies=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":235775},"main":"./dist/index.js","type":"module","_from":"file:actuate-media-component-blocks-0.2.1.tgz","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","default":"./dist/index.js"},"./cli":{"types":"./dist/cli.d.ts","import":"./dist/cli.js","default":"./dist/cli.js"},"./discriminated-union":{"types":"./dist/discriminated-union.d.ts","import":"./dist/discriminated-union.js","default":"./dist/discriminated-union.js"}},"scripts":{"dev":"tsc --project tsconfig.json --watch --preserveWatchOutput","test":"vitest run","build":"tsc --project tsconfig.json","clean":"rm -rf dist .turbo","type-check":"tsc --noEmit"},"_npmUser":{"name":"actuate_media","email":"strategize@actuatemedia.com"},"_resolved":"/tmp/7d321246d104a365e25feb22cced8eaa/actuate-media-component-blocks-0.2.1.tgz","_integrity":"sha512-24eAgiLWXIaN+A0MTM6jUYkWW5ZJBJsCP48w+pVd0dPTk9WSM834zKB9jO0hLg+W31VwzCUNiZYzLToOHOdrfg==","repository":{"url":"git+https://github.com/actuate-media/actuatecms.git","type":"git","directory":"packages/component-blocks"},"_npmVersion":"10.9.8","description":"Extract a Manifest of React component props for use as type-aware CMS blocks.","directories":{},"_nodeVersion":"22.22.3","dependencies":{"react-docgen-typescript":"^2.2.2"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"react":"^19.2.0","vitest":"^4.1.0","typescript":"^5.7.0","@types/node":"^22.0.0","@types/react":"^19.0.0"},"peerDependencies":{"typescript":">=5.0.0"},"_npmOperationalInternal":{"tmp":"tmp/component-blocks_0.2.1_1781106973059_0.6376638662973821","host":"s3://npm-registry-packages-npm-production"},"deprecated":"Renamed to @prenta/component-blocks — see https://github.com/actuate-media/prenta"},"0.2.2":{"name":"@actuate-media/component-blocks","version":"0.2.2","license":"MIT","_id":"@actuate-media/component-blocks@0.2.2","maintainers":[{"name":"actuate_media","email":"strategize@actuatemedia.com"}],"homepage":"https://github.com/actuate-media/actuatecms#readme","bugs":{"url":"https://github.com/actuate-media/actuatecms/issues"},"bin":{"actuate-component-blocks":"dist/cli.js"},"dist":{"shasum":"fda981679b7ba5b9b308ad0e58be6d5a4041d960","tarball":"https://registry.npmjs.org/@actuate-media/component-blocks/-/component-blocks-0.2.2.tgz","fileCount":36,"integrity":"sha512-nu/8C8R/Ad8sr2oMwIwP8eH6bWg053tFTJkFsQChOTh4rG30VQj8FsFPvfsmxZpqmk23Ms+AIIAQpoEsYG7qKw==","signatures":[{"sig":"MEUCIQCvdummA+tjK4X3Jm2rx52GRLJsRoxK1S3ob5OXj2bZtQIgfZSdtGXI1GSdVO+kSZWx5mOpVeVK2ZBVy6jjkQAPBns=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":236019},"main":"./dist/index.js","type":"module","_from":"file:actuate-media-component-blocks-0.2.2.tgz","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","default":"./dist/index.js"},"./cli":{"types":"./dist/cli.d.ts","import":"./dist/cli.js","default":"./dist/cli.js"},"./discriminated-union":{"types":"./dist/discriminated-union.d.ts","import":"./dist/discriminated-union.js","default":"./dist/discriminated-union.js"}},"scripts":{"dev":"tsc --project tsconfig.json --watch --preserveWatchOutput","test":"vitest run","build":"tsc --project tsconfig.json","clean":"rm -rf dist .turbo","type-check":"tsc --noEmit"},"_npmUser":{"name":"actuate_media","email":"strategize@actuatemedia.com"},"_resolved":"/tmp/5673054b7ae272a7f8950d49401d7941/actuate-media-component-blocks-0.2.2.tgz","_integrity":"sha512-nu/8C8R/Ad8sr2oMwIwP8eH6bWg053tFTJkFsQChOTh4rG30VQj8FsFPvfsmxZpqmk23Ms+AIIAQpoEsYG7qKw==","repository":{"url":"git+https://github.com/actuate-media/actuatecms.git","type":"git","directory":"packages/component-blocks"},"_npmVersion":"10.9.8","description":"Extract a Manifest of React component props for use as type-aware CMS blocks.","directories":{},"_nodeVersion":"22.23.1","dependencies":{"react-docgen-typescript":"^2.2.2"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"react":"^19.2.0","vitest":"^4.1.0","typescript":"^5.7.0","@types/node":"^22.0.0","@types/react":"^19.0.0"},"peerDependencies":{"typescript":">=5.0.0"},"_npmOperationalInternal":{"tmp":"tmp/component-blocks_0.2.2_1783301962212_0.14856293207297622","host":"s3://npm-registry-packages-npm-production"},"deprecated":"Renamed to @prenta/component-blocks — see https://github.com/actuate-media/prenta"}},"time":{"created":"2026-05-25T08:00:49.888Z","modified":"2026-07-30T20:44:36.985Z","0.2.0":"2026-05-25T08:00:50.264Z","0.2.1":"2026-06-10T15:56:13.199Z","0.2.2":"2026-07-06T01:39:22.348Z"},"bugs":{"url":"https://github.com/actuate-media/actuatecms/issues"},"license":"MIT","homepage":"https://github.com/actuate-media/actuatecms#readme","repository":{"url":"git+https://github.com/actuate-media/actuatecms.git","type":"git","directory":"packages/component-blocks"},"description":"Extract a Manifest of React component props for use as type-aware CMS blocks.","maintainers":[{"name":"actuate_media","email":"strategize@actuatemedia.com"}],"readme":"# @actuate-media/component-blocks\n\nTurn your real React components into typed CMS blocks. This is the first slice of Actuate's \"component-aware blocks\" — a feature no other headless CMS does well.\n\n## What it does\n\nYou point this package at a directory of React components, it reads their TypeScript prop types, and emits a JSON manifest. The Actuate CMS uses that manifest to render the right admin form for each component, validate stored content against the real prop shape, and warn you when a content document references a component prop that no longer exists.\n\n## Install\n\n```bash\npnpm add -D @actuate-media/component-blocks\n```\n\n## Usage\n\n### Programmatic\n\n```ts\nimport { extractManifest } from '@actuate-media/component-blocks'\n\nconst manifest = extractManifest({\n  rootDir: './src/blocks',\n  filePattern: '**/*.tsx',\n})\n\nconsole.log(manifest.components.map((c) => c.name))\n// → ['Hero', 'FeatureGrid', 'Testimonial']\n```\n\n### CLI\n\n```bash\nnpx actuate-component-blocks extract \\\n  --root ./src/blocks \\\n  --out ./actuate-blocks.json\n```\n\n### Wire up the CMS field\n\nIn your `actuate.config.ts`:\n\n```ts\nimport manifest from './actuate-blocks.json' assert { type: 'json' }\n\nexport default {\n  collections: {\n    pages: {\n      fields: {\n        body: {\n          type: 'componentBlock',\n          label: 'Page content',\n          manifest,\n          // Optional: restrict which components editors can pick\n          allow: ['Hero', 'FeatureGrid'],\n        },\n      },\n    },\n  },\n}\n```\n\n## What gets extracted\n\n| TypeScript type                           | Extracted `PropType.kind`                   |\n| ----------------------------------------- | ------------------------------------------- |\n| `string` / `number` / `boolean`           | `string` / `number` / `boolean`             |\n| `\"left\" \\| \"right\"`                       | `enum` with the literal values              |\n| `1 \\| 2 \\| 3`                             | `enum` with the literal values              |\n| `string \\| number`                        | `union` of sub-types                        |\n| `{ label: string }` (inline)              | `object` with the nested fields             |\n| `string[]` / `Array<string>`              | `array` with its `itemType`                 |\n| Same-file `interface X { ... }` reference | Resolved to the inline shape                |\n| Cross-file imports, `ReactNode`, etc.     | `reference` with `targetType: '<the name>'` |\n| Anything the scanner can't classify       | `unknown`                                   |\n\nThe component's `displayName` comes from the component identifier (or `react-docgen-typescript`'s detected display name). JSDoc on the component populates `description`; JSDoc on individual props populates each prop's `description`. Destructuring defaults (e.g. `{ alignment = 'center' }`) are captured as `defaultValue`.\n\n## What's next\n\nThis package ships the **foundation**. The forthcoming slices add:\n\n- An admin form generator that renders the right input per `PropType`\n- A CLI diff tool that flags incompatible prop changes between manifests\n- Live-preview rendering of the selected block right inside the editor\n- Discriminated-union and migration-prompt support\n\nSee `docs/component-blocks.md` for the design and `docs/roadmap-status.md` for the full Phase 4 plan.\n","readmeFilename":"README.md"}