@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.
- package/AGENTS.md +152 -0
- 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.
|
|
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
|
+
}
|