@beechcms/cms 0.7.0 → 0.8.1
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/README.md +1 -0
- package/bin/cli.mjs +303 -339
- package/bin/create.mjs +391 -457
- package/package.json +20 -13
- package/bin/templates/blog.ts +0 -35
- package/bin/templates/commerce.ts +0 -29
- package/bin/templates/contact.ts +0 -23
- package/bin/templates/empty.ts +0 -41
- package/bin/templates/gallery.ts +0 -16
- package/bin/templates/tasks.ts +0 -12
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@beechcms/cms",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.8.1",
|
|
4
4
|
"description": "Edge-Native, Schema-Driven Headless CMS built on Cloudflare Workers, D1, and R2. Features the Botanical Engine for alias-stable field management, a modular widget layer, and a React + Vite admin dashboard.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"cms",
|
|
@@ -33,33 +33,35 @@
|
|
|
33
33
|
"node": ">=18.0.0"
|
|
34
34
|
},
|
|
35
35
|
"bin": {
|
|
36
|
+
"cms": "bin/create.mjs",
|
|
37
|
+
"@beechcms/cms": "bin/create.mjs",
|
|
36
38
|
"beechcms": "bin/create.mjs",
|
|
37
39
|
"beech": "bin/cli.mjs"
|
|
38
40
|
},
|
|
39
41
|
"type": "module",
|
|
40
42
|
"devDependencies": {
|
|
41
|
-
"@eslint/js": "^
|
|
42
|
-
"@types/node": "^
|
|
43
|
+
"@eslint/js": "^10.0.1",
|
|
44
|
+
"@types/node": "^26.5.1",
|
|
43
45
|
"cross-env": "^10.1.0",
|
|
44
|
-
"eslint": "^
|
|
45
|
-
"execa": "^
|
|
46
|
-
"globals": "^
|
|
46
|
+
"eslint": "^10.10.0",
|
|
47
|
+
"execa": "^10.0.1",
|
|
48
|
+
"globals": "^17.12.0",
|
|
47
49
|
"husky": "^9.1.7",
|
|
48
|
-
"ink": "^
|
|
50
|
+
"ink": "^7.1.1",
|
|
49
51
|
"ink-spinner": "^5.0.0",
|
|
50
52
|
"react": "^19.2.7",
|
|
51
|
-
"react-doctor": "^0.
|
|
53
|
+
"react-doctor": "^0.9.14",
|
|
52
54
|
"strip-ansi": "^7.2.0",
|
|
53
55
|
"tsx": "^4.22.4",
|
|
54
56
|
"turbo": "^2.9.18",
|
|
55
57
|
"typedoc": "^0.28.20",
|
|
56
58
|
"typedoc-plugin-markdown": "^4.12.0",
|
|
57
|
-
"typescript": "^
|
|
59
|
+
"typescript": "^7.0.2",
|
|
58
60
|
"vitepress": "^1.6.4",
|
|
59
|
-
"vitest": "^
|
|
61
|
+
"vitest": "^5.0.0"
|
|
60
62
|
},
|
|
61
63
|
"dependencies": {
|
|
62
|
-
"@beechcms/cli": "^0.
|
|
64
|
+
"@beechcms/cli": "^0.8.1",
|
|
63
65
|
"@clack/prompts": "^0.9.1",
|
|
64
66
|
"picocolors": "^1.1.1"
|
|
65
67
|
},
|
|
@@ -76,9 +78,10 @@
|
|
|
76
78
|
}
|
|
77
79
|
},
|
|
78
80
|
"scripts": {
|
|
79
|
-
"docs:generate": "typedoc",
|
|
81
|
+
"docs:generate": "turbo run build && typedoc",
|
|
80
82
|
"docs:dev": "vitepress dev docs",
|
|
81
|
-
"docs:
|
|
83
|
+
"docs:check": "node scripts/docs-fact-check.mjs",
|
|
84
|
+
"docs:build": "turbo run build && typedoc && node scripts/docs-fact-check.mjs && vitepress build docs",
|
|
82
85
|
"docs:preview": "vitepress preview docs",
|
|
83
86
|
"beech": "node bin/cli.mjs",
|
|
84
87
|
"dev": "node scripts/dev.mjs",
|
|
@@ -103,6 +106,10 @@
|
|
|
103
106
|
"setup:graph": "node scripts/setup-graph.mjs",
|
|
104
107
|
"release": "node scripts/release.mjs",
|
|
105
108
|
"release:preview": "node scripts/release.mjs --preview",
|
|
109
|
+
"release:current": "node scripts/release.mjs --current",
|
|
110
|
+
"version:list": "node scripts/release.mjs list",
|
|
111
|
+
"version:get": "node scripts/release.mjs get",
|
|
112
|
+
"version:set": "node scripts/release.mjs set",
|
|
106
113
|
"postinstall": "node scripts/check-docker.mjs",
|
|
107
114
|
"doctor": "react-doctor -y --no-dead-code"
|
|
108
115
|
}
|
package/bin/templates/blog.ts
DELETED
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
/** Post: blog article with rich text, cover image, tags and SEO */
|
|
2
|
-
export const POST_SEED: Seed = {
|
|
3
|
-
slug: 'posts',
|
|
4
|
-
label: 'Post',
|
|
5
|
-
labelPlural: 'Posts',
|
|
6
|
-
displayNameAlias: 'title',
|
|
7
|
-
allowPublicRead: true,
|
|
8
|
-
allowDrafts: true,
|
|
9
|
-
branches: [
|
|
10
|
-
{ id: 'pst_01', alias: 'title', label: 'Title', type: 'text', requiredOnCreate: true },
|
|
11
|
-
{ id: 'pst_02', alias: 'publishedAt', label: 'Published at', type: 'date' },
|
|
12
|
-
{ id: 'pst_03', alias: 'coverImage', label: 'Cover image', type: 'file', fileOptions: { accept: 'image' } },
|
|
13
|
-
{ id: 'pst_04', alias: 'excerpt', label: 'Excerpt', type: 'text' },
|
|
14
|
-
{ id: 'pst_05', alias: 'tags', label: 'Tags', type: 'json', options: ['news', 'tutorial', 'release', 'guide', 'opinion'] },
|
|
15
|
-
{ id: 'pst_06', alias: 'body', label: 'Body', type: 'richtext' },
|
|
16
|
-
{ id: 'pst_07', alias: 'metaTitle', label: 'Meta title (SEO)', type: 'text' },
|
|
17
|
-
{ id: 'pst_08', alias: 'metaDescription', label: 'Meta description (SEO)', type: 'text' },
|
|
18
|
-
],
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
/** Author: content creator profile with photo and social link */
|
|
22
|
-
export const AUTHOR_SEED: Seed = {
|
|
23
|
-
slug: 'authors',
|
|
24
|
-
label: 'Author',
|
|
25
|
-
labelPlural: 'Authors',
|
|
26
|
-
displayNameAlias: 'name',
|
|
27
|
-
allowPublicRead: true,
|
|
28
|
-
branches: [
|
|
29
|
-
{ id: 'aut_01', alias: 'name', label: 'Name', type: 'text', requiredOnCreate: true },
|
|
30
|
-
{ id: 'aut_02', alias: 'bio', label: 'Bio', type: 'text' },
|
|
31
|
-
{ id: 'aut_03', alias: 'photo', label: 'Photo', type: 'file', fileOptions: { accept: 'image' } },
|
|
32
|
-
{ id: 'aut_04', alias: 'website', label: 'Website URL', type: 'text' },
|
|
33
|
-
{ id: 'aut_05', alias: 'active', label: 'Active', type: 'boolean' },
|
|
34
|
-
],
|
|
35
|
-
}
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
/** Product: e-commerce product catalog with prices, inventory and ratings */
|
|
2
|
-
export const PRODUCT_SEED: Seed = {
|
|
3
|
-
slug: 'products',
|
|
4
|
-
label: 'Product',
|
|
5
|
-
labelPlural: 'Products',
|
|
6
|
-
displayNameAlias: 'name',
|
|
7
|
-
allowPublicRead: true,
|
|
8
|
-
branches: [
|
|
9
|
-
{ alias: 'name', label: 'Product Name', type: 'text', requiredOnCreate: true },
|
|
10
|
-
{ alias: 'description', label: 'Description', type: 'richtext' },
|
|
11
|
-
{ alias: 'price', label: 'Price', type: 'number', numberOptions: { format: 'currency', currency: 'EUR', decimals: 2, min: 0, control: 'input', prefix: '€' } },
|
|
12
|
-
{ alias: 'inventory', label: 'Stock level', type: 'number', numberOptions: { min: 0, step: 1, control: 'stepper' } },
|
|
13
|
-
{ alias: 'rating', label: 'Rating', type: 'number', numberOptions: { min: 1, max: 5, step: 0.5, control: 'rating' } }
|
|
14
|
-
],
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
/** Review: product review */
|
|
18
|
-
export const REVIEW_SEED: Seed = {
|
|
19
|
-
slug: 'reviews',
|
|
20
|
-
label: 'Review',
|
|
21
|
-
labelPlural: 'Reviews',
|
|
22
|
-
displayNameAlias: 'title',
|
|
23
|
-
allowPublicRead: true,
|
|
24
|
-
branches: [
|
|
25
|
-
{ alias: 'title', label: 'Review Title', type: 'text', requiredOnCreate: true },
|
|
26
|
-
{ alias: 'body', label: 'Body', type: 'text' },
|
|
27
|
-
{ alias: 'score', label: 'Score', type: 'number', numberOptions: { min: 1, max: 5, step: 1, control: 'rating' } }
|
|
28
|
-
],
|
|
29
|
-
}
|
package/bin/templates/contact.ts
DELETED
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Message: public contact form submission.
|
|
3
|
-
*
|
|
4
|
-
* allowPublicPost: true — the Public API accepts POST requests without authentication,
|
|
5
|
-
* so any frontend form can submit directly to this seed.
|
|
6
|
-
* email visibility:masked — the email is stored in full but returned partially
|
|
7
|
-
* redacted in API responses (e.g. "jo**@example.com").
|
|
8
|
-
* email public:false — the email is never exposed through the Public API.
|
|
9
|
-
*/
|
|
10
|
-
export const MESSAGE_SEED: Seed = {
|
|
11
|
-
slug: 'messages',
|
|
12
|
-
label: 'Message',
|
|
13
|
-
labelPlural: 'Messages',
|
|
14
|
-
displayNameAlias: 'name',
|
|
15
|
-
allowPublicPost: true,
|
|
16
|
-
branches: [
|
|
17
|
-
{ id: 'msg_01', alias: 'name', label: 'Name', type: 'text', requiredOnCreate: true },
|
|
18
|
-
{ id: 'msg_02', alias: 'email', label: 'Email', type: 'text', requiredOnCreate: true, policies: { visibility: 'masked', public: false } },
|
|
19
|
-
{ id: 'msg_03', alias: 'subject', label: 'Subject', type: 'text', requiredOnCreate: true },
|
|
20
|
-
{ id: 'msg_04', alias: 'message', label: 'Message', type: 'richtext', requiredOnCreate: true },
|
|
21
|
-
{ id: 'msg_05', alias: 'read', label: 'Read', type: 'boolean' },
|
|
22
|
-
],
|
|
23
|
-
}
|
package/bin/templates/empty.ts
DELETED
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Your seeds go here.
|
|
3
|
-
*
|
|
4
|
-
* A Seed defines a content type: its slug (used in API URLs), its display labels,
|
|
5
|
-
* and its branches (fields).
|
|
6
|
-
*
|
|
7
|
-
* Each Branch has:
|
|
8
|
-
* id — immutable database key (e.g. 'abc_01'). Never change this after
|
|
9
|
-
* the first migration or stored data will break.
|
|
10
|
-
* alias — the name used in API payloads (e.g. 'title'). Safe to rename.
|
|
11
|
-
* label — human-readable label shown in the dashboard.
|
|
12
|
-
* type — 'text' | 'number' | 'boolean' | 'date' | 'richtext' | 'file' | 'json'
|
|
13
|
-
*
|
|
14
|
-
* Seed-level flags:
|
|
15
|
-
* allowPublicRead — expose entries via the unauthenticated Public API (GET).
|
|
16
|
-
* allowPublicPost — accept submissions via the Public API (POST). Useful for forms.
|
|
17
|
-
* allowDrafts — enable a pending-draft workflow for this content type.
|
|
18
|
-
* displayNameAlias — which branch alias is used as the entry title in the dashboard.
|
|
19
|
-
*
|
|
20
|
-
* Branch policies (all optional):
|
|
21
|
-
* policies.visibility — 'full' (default) | 'masked' | 'hidden'
|
|
22
|
-
* policies.public — false to exclude the field from Public API responses
|
|
23
|
-
* policies.search — false to exclude the field from full-text search
|
|
24
|
-
*
|
|
25
|
-
* Example — uncomment and adapt to define your first content type:
|
|
26
|
-
*
|
|
27
|
-
* export const PROJECT_SEED: Seed = {
|
|
28
|
-
* slug: 'projects',
|
|
29
|
-
* label: 'Project',
|
|
30
|
-
* labelPlural: 'Projects',
|
|
31
|
-
* displayNameAlias: 'title',
|
|
32
|
-
* allowPublicRead: true,
|
|
33
|
-
* branches: [
|
|
34
|
-
* { id: 'prj_01', alias: 'title', label: 'Title', type: 'text', requiredOnCreate: true },
|
|
35
|
-
* { id: 'prj_02', alias: 'description', label: 'Description', type: 'text' },
|
|
36
|
-
* { id: 'prj_03', alias: 'coverImage', label: 'Cover image', type: 'file' },
|
|
37
|
-
* { id: 'prj_04', alias: 'tags', label: 'Tags', type: 'json' },
|
|
38
|
-
* { id: 'prj_05', alias: 'published', label: 'Published', type: 'boolean' },
|
|
39
|
-
* ],
|
|
40
|
-
* }
|
|
41
|
-
*/
|
package/bin/templates/gallery.ts
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
/** Gallery item: image or media asset with title, tags and featured flag */
|
|
2
|
-
export const GALLERY_SEED: Seed = {
|
|
3
|
-
slug: 'gallery',
|
|
4
|
-
label: 'Item',
|
|
5
|
-
labelPlural: 'Gallery',
|
|
6
|
-
displayNameAlias: 'title',
|
|
7
|
-
allowPublicRead: true,
|
|
8
|
-
branches: [
|
|
9
|
-
{ id: 'gal_01', alias: 'title', label: 'Title', type: 'text', requiredOnCreate: true },
|
|
10
|
-
{ id: 'gal_02', alias: 'description', label: 'Description', type: 'text' },
|
|
11
|
-
{ id: 'gal_03', alias: 'image', label: 'Image', type: 'file', requiredOnCreate: true, fileOptions: { accept: 'image' } },
|
|
12
|
-
{ id: 'gal_04', alias: 'tags', label: 'Tags', type: 'json' },
|
|
13
|
-
{ id: 'gal_05', alias: 'date', label: 'Date', type: 'date' },
|
|
14
|
-
{ id: 'gal_06', alias: 'featured', label: 'Featured', type: 'boolean' },
|
|
15
|
-
],
|
|
16
|
-
}
|
package/bin/templates/tasks.ts
DELETED
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
/** Task: project management tasks with progress slider */
|
|
2
|
-
export const TASK_SEED: Seed = {
|
|
3
|
-
slug: 'tasks',
|
|
4
|
-
label: 'Task',
|
|
5
|
-
labelPlural: 'Tasks',
|
|
6
|
-
displayNameAlias: 'title',
|
|
7
|
-
branches: [
|
|
8
|
-
{ alias: 'title', label: 'Task Title', type: 'text', requiredOnCreate: true },
|
|
9
|
-
{ alias: 'taskStatus', label: 'Status', type: 'text', options: ['todo', 'in_progress', 'done'] },
|
|
10
|
-
{ alias: 'completion', label: 'Completion', type: 'number', numberOptions: { format: 'percentage', min: 0, max: 100, step: 5, control: 'slider' } }
|
|
11
|
-
],
|
|
12
|
-
}
|