@dani-builder/strapi-plugin-builder 0.1.0 → 0.2.0

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.
Files changed (2) hide show
  1. package/AGENTS.md +152 -0
  2. package/package.json +9 -8
package/AGENTS.md ADDED
@@ -0,0 +1,152 @@
1
+ # @dani-builder/strapi-plugin-builder
2
+
3
+ Strapi v5 plugin providing 11 content types, 31 components, and smart API endpoints for a page builder CMS. Installed as a Strapi plugin — not used standalone.
4
+
5
+ ## Installation & Setup
6
+
7
+ ```bash
8
+ # 1. Install the plugin
9
+ pnpm add @dani-builder/strapi-plugin-builder
10
+
11
+ # 2. Enable in Strapi config (config/plugins.ts)
12
+ export default () => ({
13
+ builder: { enabled: true },
14
+ });
15
+
16
+ # 3. Sync content type schemas into your Strapi project
17
+ npx daniworks-builder sync # Full sync (schemas + routes/controllers/services)
18
+ npx daniworks-builder sync --dry-run # Preview changes
19
+ npx daniworks-builder sync --only page # Sync specific content types
20
+ npx daniworks-builder sync --force # Overwrite local modifications
21
+ ```
22
+
23
+ **Schema sync is required** for REST CRUD endpoints to work. The CLI copies schema.json files and generates routes/controllers/services boilerplate into your project's `src/api/` directory. Changes are tracked via `.daniworks-sync-manifest.json`.
24
+
25
+ ## Content Types (11)
26
+
27
+ ### Collection Types (8)
28
+
29
+ | singularName | pluralName | REST endpoint | draftAndPublish | i18n |
30
+ |---|---|---|---|---|
31
+ | page | pages | `api/pages` | true | yes |
32
+ | article | articles | `api/articles` | true | yes |
33
+ | faq | faqs | `api/faqs` | true | yes |
34
+ | category | categories | `api/categories` | false | yes |
35
+ | tag | tags | `api/tags` | false | yes |
36
+ | author | authors | `api/authors` | false | no |
37
+ | inquiry | inquiries | `api/inquiries` | false | no |
38
+ | series | all-series | `api/all-series` | false | yes |
39
+
40
+ ### Single Types (3)
41
+
42
+ | singularName | pluralName | REST endpoint | draftAndPublish | i18n |
43
+ |---|---|---|---|---|
44
+ | navigation | navigations | `api/navigations` | true | yes |
45
+ | global | globals | `api/globals` | true | yes |
46
+ | site-setting | site-settings | `api/site-settings` | false | no |
47
+
48
+ **Series quirk:** `pluralName` is `all-series` (not `series`) because Strapi requires singular and plural names to differ.
49
+
50
+ ## Components (31)
51
+
52
+ ### Blocks (14) — used in Page.blocks dynamic zone
53
+
54
+ `blocks.hero`, `blocks.features`, `blocks.cta`, `blocks.slider`, `blocks.inquiry-form`, `blocks.faq`, `blocks.highlights`, `blocks.bento-grid`, `blocks.testimonials`, `blocks.logo-cloud`, `blocks.stats`, `blocks.pricing`, `blocks.content`, `blocks.team`
55
+
56
+ ### Elements (2)
57
+
58
+ `elements.section`, `elements.footer`
59
+
60
+ ### Shared (15)
61
+
62
+ `shared.link`, `shared.seo`, `shared.feature-item`, `shared.highlight-item`, `shared.bento-item`, `shared.slider-item`, `shared.stat-item`, `shared.team-member`, `shared.testimonial-item`, `shared.pricing-tier`, `shared.logo-item`, `shared.navigation-group`, `shared.brand-colors`, `shared.analytics-setting`, `shared.chatbot-setting`, `shared.site-verification`
63
+
64
+ ## Smart API Endpoints
65
+
66
+ Server-side deep populate — no need for client-side populate building.
67
+
68
+ | Method | Path | Description |
69
+ |---|---|---|
70
+ | GET | `/api/builder/pages` | List pages (minimal populate) |
71
+ | GET | `/api/builder/pages/:documentId` | Single page with all blocks deeply populated |
72
+ | GET | `/api/builder/global` | Global settings (siteWideBlocks + footer, fully populated) |
73
+
74
+ ## Critical Rules
75
+
76
+ 1. **Component registration** — The plugin uses `strapi.get('components').add(map)`. Never assign directly to `strapi.components[uid]`.
77
+ 2. **Components require metadata** — Each component JSON must include `__schema__`, `globalId`, and `collectionName` fields.
78
+ 3. **`__component` required in dynamic zones** — Every block object needs `"__component": "blocks.hero"` etc.
79
+ 4. **Block text lives in `section`** — heading, subheading, and theme are on the `section` sub-component, NOT at block root.
80
+ 5. **Section.theme is a Tailwind preset key** — Values like `'dark'`, `'default'`. No arbitrary CSS colors.
81
+ 6. **`name` fields are admin-only** — Used for CMS identification. Never display in frontend.
82
+ 7. **All media fields are nullable** — Render defensively even for "required" media fields.
83
+ 8. **CT directory names match singularName** — `site-setting/` not `site-settings/`.
84
+
85
+ ## Variant-Based Layouts
86
+
87
+ Blocks use a `variant` enum instead of separate components per layout. Only use values defined in the schema:
88
+
89
+ | Block | Variants |
90
+ |---|---|
91
+ | hero | `side-by-side`, `media-extending`, `fullscreen-media`, `stacked-media` |
92
+ | features | `simple-grid`, `card-grid`, `icon-grid` |
93
+ | cta | `side-by-side`, `centered` |
94
+ | pricing | `card-grid`, `comparison-table` |
95
+ | testimonials | `card-grid`, `alternating`, `single-highlight` |
96
+ | highlights | `media-aside`, `alternating`, `card-grid` |
97
+ | bento-grid | `auto`, `featured-left`, `featured-right` |
98
+ | stats | `simple-row`, `card-grid` |
99
+ | team | `card-grid`, `simple-grid` |
100
+ | logo-cloud | `simple-grid`, `ticker` |
101
+ | slider | `fullscreen`, `card-carousel` |
102
+
103
+ **Never invent variant values** — always check the schema definition.
104
+
105
+ ## REST API Rules (for MCP / programmatic content creation)
106
+
107
+ ```json
108
+ // POST api/pages — create a page with blocks
109
+ {
110
+ "data": {
111
+ "title": "About",
112
+ "slug": "about",
113
+ "locale": "en",
114
+ "blocks": [
115
+ {
116
+ "__component": "blocks.hero",
117
+ "variant": "side-by-side",
118
+ "section": {
119
+ "heading": "About Us",
120
+ "subheading": "Our story",
121
+ "theme": "dark"
122
+ },
123
+ "ctaLink": { "label": "Learn more", "href": "/contact" }
124
+ }
125
+ ]
126
+ }
127
+ }
128
+ ```
129
+
130
+ 1. **`data` wrapper required** — POST/PUT body must be `{ "data": { ... } }`
131
+ 2. **`locale` required** — i18n-enabled CTs fail with `Invalid key` without it
132
+ 3. **Media uploaded separately** — Upload via Strapi Upload API, then reference by ID
133
+ 4. **Deep reads via Smart API** — Standard REST only populates 1 level; use `/api/builder/pages/:docId` for full data
134
+
135
+ ## File Structure
136
+
137
+ ```
138
+ schemas/api/ — Content type schemas (copied to consumer project by sync CLI)
139
+ server/src/
140
+ register.ts — Programmatic component registration
141
+ controllers/ — Smart API controllers (page, global)
142
+ services/ — Populate service (deep populate definitions for all 14 blocks)
143
+ routes/ — Smart API route definitions
144
+ components/ — Component JSON schemas (blocks, elements, shared)
145
+ bin/sync.js — CLI for schema sync
146
+ ```
147
+
148
+ ## Peer Dependencies
149
+
150
+ - `@strapi/strapi` ^5.0.0
151
+ - `@strapi/plugin-color-picker` ^5.0.0
152
+ - `@d3levvv/strapi-react-icons-plugin` ^1.0.0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dani-builder/strapi-plugin-builder",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "description": "Daniworks Builder — reusable CMS components, content types, and smart API for Strapi v5",
5
5
  "license": "MIT",
6
6
  "strapi": {
@@ -22,7 +22,8 @@
22
22
  "dist",
23
23
  "schemas",
24
24
  "bin",
25
- "strapi-server.js"
25
+ "strapi-server.js",
26
+ "AGENTS.md"
26
27
  ],
27
28
  "publishConfig": {
28
29
  "access": "public"
@@ -35,11 +36,6 @@
35
36
  "bin": {
36
37
  "daniworks-builder": "./bin/sync.js"
37
38
  },
38
- "scripts": {
39
- "build": "tsc && node -e \"const fs=require('fs'),p=require('path'),src='server/src/components',dst='dist/server/src/components';(function cp(s,d){fs.mkdirSync(d,{recursive:true});fs.readdirSync(s).forEach(f=>{const sp=p.join(s,f),dp=p.join(d,f);fs.statSync(sp).isDirectory()?cp(sp,dp):f.endsWith('.json')&&fs.copyFileSync(sp,dp);})})(src,dst)\"",
40
- "watch": "strapi-plugin watch",
41
- "verify": "strapi-plugin verify"
42
- },
43
39
  "dependencies": {},
44
40
  "devDependencies": {
45
41
  "@strapi/sdk-plugin": "^5.0.0",
@@ -51,5 +47,10 @@
51
47
  "@strapi/strapi": "^5.0.0",
52
48
  "@strapi/plugin-color-picker": "^5.0.0",
53
49
  "@d3levvv/strapi-react-icons-plugin": "^1.0.0"
50
+ },
51
+ "scripts": {
52
+ "build": "tsc && node -e \"const fs=require('fs'),p=require('path'),src='server/src/components',dst='dist/server/src/components';(function cp(s,d){fs.mkdirSync(d,{recursive:true});fs.readdirSync(s).forEach(f=>{const sp=p.join(s,f),dp=p.join(d,f);fs.statSync(sp).isDirectory()?cp(sp,dp):f.endsWith('.json')&&fs.copyFileSync(sp,dp);})})(src,dst)\"",
53
+ "watch": "strapi-plugin watch",
54
+ "verify": "strapi-plugin verify"
54
55
  }
55
- }
56
+ }