@fnd-platform/cms 1.0.0-alpha.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.
Files changed (207) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +283 -0
  3. package/lib/cms-project.d.ts +127 -0
  4. package/lib/cms-project.d.ts.map +1 -0
  5. package/lib/cms-project.js +343 -0
  6. package/lib/cms-project.js.map +1 -0
  7. package/lib/index.d.ts +11 -0
  8. package/lib/index.d.ts.map +1 -0
  9. package/lib/index.js +20 -0
  10. package/lib/index.js.map +1 -0
  11. package/lib/options.d.ts +59 -0
  12. package/lib/options.d.ts.map +1 -0
  13. package/lib/options.js +3 -0
  14. package/lib/options.js.map +1 -0
  15. package/lib/templates/admin-breadcrumbs.d.ts +13 -0
  16. package/lib/templates/admin-breadcrumbs.d.ts.map +1 -0
  17. package/lib/templates/admin-breadcrumbs.js +80 -0
  18. package/lib/templates/admin-breadcrumbs.js.map +1 -0
  19. package/lib/templates/admin-content-route.d.ts +18 -0
  20. package/lib/templates/admin-content-route.d.ts.map +1 -0
  21. package/lib/templates/admin-content-route.js +100 -0
  22. package/lib/templates/admin-content-route.js.map +1 -0
  23. package/lib/templates/admin-content-type-route.d.ts +9 -0
  24. package/lib/templates/admin-content-type-route.d.ts.map +1 -0
  25. package/lib/templates/admin-content-type-route.js +96 -0
  26. package/lib/templates/admin-content-type-route.js.map +1 -0
  27. package/lib/templates/admin-header.d.ts +13 -0
  28. package/lib/templates/admin-header.d.ts.map +1 -0
  29. package/lib/templates/admin-header.js +123 -0
  30. package/lib/templates/admin-header.js.map +1 -0
  31. package/lib/templates/admin-index.d.ts +9 -0
  32. package/lib/templates/admin-index.d.ts.map +1 -0
  33. package/lib/templates/admin-index.js +60 -0
  34. package/lib/templates/admin-index.js.map +1 -0
  35. package/lib/templates/admin-layout.d.ts +10 -0
  36. package/lib/templates/admin-layout.d.ts.map +1 -0
  37. package/lib/templates/admin-layout.js +46 -0
  38. package/lib/templates/admin-layout.js.map +1 -0
  39. package/lib/templates/admin-sidebar.d.ts +13 -0
  40. package/lib/templates/admin-sidebar.d.ts.map +1 -0
  41. package/lib/templates/admin-sidebar.js +149 -0
  42. package/lib/templates/admin-sidebar.js.map +1 -0
  43. package/lib/templates/content-editor.d.ts +10 -0
  44. package/lib/templates/content-editor.d.ts.map +1 -0
  45. package/lib/templates/content-editor.js +354 -0
  46. package/lib/templates/content-editor.js.map +1 -0
  47. package/lib/templates/content-schema.d.ts +10 -0
  48. package/lib/templates/content-schema.d.ts.map +1 -0
  49. package/lib/templates/content-schema.js +274 -0
  50. package/lib/templates/content-schema.js.map +1 -0
  51. package/lib/templates/content-table.d.ts +13 -0
  52. package/lib/templates/content-table.d.ts.map +1 -0
  53. package/lib/templates/content-table.js +177 -0
  54. package/lib/templates/content-table.js.map +1 -0
  55. package/lib/templates/content-types-examples.d.ts +19 -0
  56. package/lib/templates/content-types-examples.d.ts.map +1 -0
  57. package/lib/templates/content-types-examples.js +275 -0
  58. package/lib/templates/content-types-examples.js.map +1 -0
  59. package/lib/templates/content-types-registry.d.ts +10 -0
  60. package/lib/templates/content-types-registry.d.ts.map +1 -0
  61. package/lib/templates/content-types-registry.js +87 -0
  62. package/lib/templates/content-types-registry.js.map +1 -0
  63. package/lib/templates/content-types.d.ts +10 -0
  64. package/lib/templates/content-types.d.ts.map +1 -0
  65. package/lib/templates/content-types.js +384 -0
  66. package/lib/templates/content-types.js.map +1 -0
  67. package/lib/templates/dashboard-stats.d.ts +13 -0
  68. package/lib/templates/dashboard-stats.d.ts.map +1 -0
  69. package/lib/templates/dashboard-stats.js +117 -0
  70. package/lib/templates/dashboard-stats.js.map +1 -0
  71. package/lib/templates/editor/index.d.ts +6 -0
  72. package/lib/templates/editor/index.d.ts.map +1 -0
  73. package/lib/templates/editor/index.js +21 -0
  74. package/lib/templates/editor/index.js.map +1 -0
  75. package/lib/templates/editor/rich-text-editor.d.ts +7 -0
  76. package/lib/templates/editor/rich-text-editor.d.ts.map +1 -0
  77. package/lib/templates/editor/rich-text-editor.js +115 -0
  78. package/lib/templates/editor/rich-text-editor.js.map +1 -0
  79. package/lib/templates/editor/toolbar.d.ts +7 -0
  80. package/lib/templates/editor/toolbar.d.ts.map +1 -0
  81. package/lib/templates/editor/toolbar.js +272 -0
  82. package/lib/templates/editor/toolbar.js.map +1 -0
  83. package/lib/templates/form-fields/boolean-field.d.ts +7 -0
  84. package/lib/templates/form-fields/boolean-field.d.ts.map +1 -0
  85. package/lib/templates/form-fields/boolean-field.js +76 -0
  86. package/lib/templates/form-fields/boolean-field.js.map +1 -0
  87. package/lib/templates/form-fields/date-field.d.ts +7 -0
  88. package/lib/templates/form-fields/date-field.d.ts.map +1 -0
  89. package/lib/templates/form-fields/date-field.js +61 -0
  90. package/lib/templates/form-fields/date-field.js.map +1 -0
  91. package/lib/templates/form-fields/datetime-field.d.ts +7 -0
  92. package/lib/templates/form-fields/datetime-field.d.ts.map +1 -0
  93. package/lib/templates/form-fields/datetime-field.js +87 -0
  94. package/lib/templates/form-fields/datetime-field.js.map +1 -0
  95. package/lib/templates/form-fields/index.d.ts +23 -0
  96. package/lib/templates/form-fields/index.d.ts.map +1 -0
  97. package/lib/templates/form-fields/index.js +275 -0
  98. package/lib/templates/form-fields/index.js.map +1 -0
  99. package/lib/templates/form-fields/media-field.d.ts +10 -0
  100. package/lib/templates/form-fields/media-field.d.ts.map +1 -0
  101. package/lib/templates/form-fields/media-field.js +225 -0
  102. package/lib/templates/form-fields/media-field.js.map +1 -0
  103. package/lib/templates/form-fields/multiselect-field.d.ts +7 -0
  104. package/lib/templates/form-fields/multiselect-field.d.ts.map +1 -0
  105. package/lib/templates/form-fields/multiselect-field.js +121 -0
  106. package/lib/templates/form-fields/multiselect-field.js.map +1 -0
  107. package/lib/templates/form-fields/number-field.d.ts +7 -0
  108. package/lib/templates/form-fields/number-field.d.ts.map +1 -0
  109. package/lib/templates/form-fields/number-field.js +87 -0
  110. package/lib/templates/form-fields/number-field.js.map +1 -0
  111. package/lib/templates/form-fields/reference-field.d.ts +9 -0
  112. package/lib/templates/form-fields/reference-field.d.ts.map +1 -0
  113. package/lib/templates/form-fields/reference-field.js +145 -0
  114. package/lib/templates/form-fields/reference-field.js.map +1 -0
  115. package/lib/templates/form-fields/richtext-field.d.ts +9 -0
  116. package/lib/templates/form-fields/richtext-field.d.ts.map +1 -0
  117. package/lib/templates/form-fields/richtext-field.js +60 -0
  118. package/lib/templates/form-fields/richtext-field.js.map +1 -0
  119. package/lib/templates/form-fields/select-field.d.ts +7 -0
  120. package/lib/templates/form-fields/select-field.d.ts.map +1 -0
  121. package/lib/templates/form-fields/select-field.js +70 -0
  122. package/lib/templates/form-fields/select-field.js.map +1 -0
  123. package/lib/templates/form-fields/slug-field.d.ts +7 -0
  124. package/lib/templates/form-fields/slug-field.d.ts.map +1 -0
  125. package/lib/templates/form-fields/slug-field.js +143 -0
  126. package/lib/templates/form-fields/slug-field.js.map +1 -0
  127. package/lib/templates/form-fields/tags-field.d.ts +7 -0
  128. package/lib/templates/form-fields/tags-field.d.ts.map +1 -0
  129. package/lib/templates/form-fields/tags-field.js +172 -0
  130. package/lib/templates/form-fields/tags-field.js.map +1 -0
  131. package/lib/templates/form-fields/text-field.d.ts +7 -0
  132. package/lib/templates/form-fields/text-field.d.ts.map +1 -0
  133. package/lib/templates/form-fields/text-field.js +63 -0
  134. package/lib/templates/form-fields/text-field.js.map +1 -0
  135. package/lib/templates/form-fields/textarea-field.d.ts +7 -0
  136. package/lib/templates/form-fields/textarea-field.d.ts.map +1 -0
  137. package/lib/templates/form-fields/textarea-field.js +64 -0
  138. package/lib/templates/form-fields/textarea-field.js.map +1 -0
  139. package/lib/templates/index.d.ts +34 -0
  140. package/lib/templates/index.d.ts.map +1 -0
  141. package/lib/templates/index.js +92 -0
  142. package/lib/templates/index.js.map +1 -0
  143. package/lib/templates/media/index.d.ts +12 -0
  144. package/lib/templates/media/index.d.ts.map +1 -0
  145. package/lib/templates/media/index.js +50 -0
  146. package/lib/templates/media/index.js.map +1 -0
  147. package/lib/templates/media/media-api.d.ts +13 -0
  148. package/lib/templates/media/media-api.d.ts.map +1 -0
  149. package/lib/templates/media/media-api.js +274 -0
  150. package/lib/templates/media/media-api.js.map +1 -0
  151. package/lib/templates/media/media-grid.d.ts +14 -0
  152. package/lib/templates/media/media-grid.d.ts.map +1 -0
  153. package/lib/templates/media/media-grid.js +314 -0
  154. package/lib/templates/media/media-grid.js.map +1 -0
  155. package/lib/templates/media/media-library-route.d.ts +13 -0
  156. package/lib/templates/media/media-library-route.d.ts.map +1 -0
  157. package/lib/templates/media/media-library-route.js +105 -0
  158. package/lib/templates/media/media-library-route.js.map +1 -0
  159. package/lib/templates/media/media-picker.d.ts +13 -0
  160. package/lib/templates/media/media-picker.d.ts.map +1 -0
  161. package/lib/templates/media/media-picker.js +152 -0
  162. package/lib/templates/media/media-picker.js.map +1 -0
  163. package/lib/templates/media/media-uploader.d.ts +14 -0
  164. package/lib/templates/media/media-uploader.d.ts.map +1 -0
  165. package/lib/templates/media/media-uploader.js +318 -0
  166. package/lib/templates/media/media-uploader.js.map +1 -0
  167. package/lib/templates/recent-content.d.ts +13 -0
  168. package/lib/templates/recent-content.d.ts.map +1 -0
  169. package/lib/templates/recent-content.js +138 -0
  170. package/lib/templates/recent-content.js.map +1 -0
  171. package/lib/templates/slug-utils.d.ts +10 -0
  172. package/lib/templates/slug-utils.d.ts.map +1 -0
  173. package/lib/templates/slug-utils.js +194 -0
  174. package/lib/templates/slug-utils.js.map +1 -0
  175. package/lib/templates/ui-avatar.d.ts +8 -0
  176. package/lib/templates/ui-avatar.d.ts.map +1 -0
  177. package/lib/templates/ui-avatar.js +60 -0
  178. package/lib/templates/ui-avatar.js.map +1 -0
  179. package/lib/templates/ui-badge.d.ts +8 -0
  180. package/lib/templates/ui-badge.d.ts.map +1 -0
  181. package/lib/templates/ui-badge.js +52 -0
  182. package/lib/templates/ui-badge.js.map +1 -0
  183. package/lib/templates/ui-dialog.d.ts +10 -0
  184. package/lib/templates/ui-dialog.d.ts.map +1 -0
  185. package/lib/templates/ui-dialog.js +134 -0
  186. package/lib/templates/ui-dialog.js.map +1 -0
  187. package/lib/templates/ui-dropdown-menu.d.ts +8 -0
  188. package/lib/templates/ui-dropdown-menu.d.ts.map +1 -0
  189. package/lib/templates/ui-dropdown-menu.js +210 -0
  190. package/lib/templates/ui-dropdown-menu.js.map +1 -0
  191. package/lib/templates/ui-popover.d.ts +8 -0
  192. package/lib/templates/ui-popover.d.ts.map +1 -0
  193. package/lib/templates/ui-popover.js +43 -0
  194. package/lib/templates/ui-popover.js.map +1 -0
  195. package/lib/templates/ui-progress.d.ts +10 -0
  196. package/lib/templates/ui-progress.d.ts.map +1 -0
  197. package/lib/templates/ui-progress.js +40 -0
  198. package/lib/templates/ui-progress.js.map +1 -0
  199. package/lib/templates/ui-table.d.ts +8 -0
  200. package/lib/templates/ui-table.d.ts.map +1 -0
  201. package/lib/templates/ui-table.js +129 -0
  202. package/lib/templates/ui-table.js.map +1 -0
  203. package/lib/templates/ui-tabs.d.ts +10 -0
  204. package/lib/templates/ui-tabs.d.ts.map +1 -0
  205. package/lib/templates/ui-tabs.js +67 -0
  206. package/lib/templates/ui-tabs.js.map +1 -0
  207. package/package.json +52 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 fnd-platform contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,283 @@
1
+ # @fnd-platform/cms
2
+
3
+ Projen project class for generating headless CMS admin interfaces with Remix, shadcn/ui, content modeling, and media management in fnd-platform monorepos.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install -D @fnd-platform/cms
9
+ # or
10
+ pnpm add -D @fnd-platform/cms
11
+ ```
12
+
13
+ ## Quick Start
14
+
15
+ Add a CMS package to your monorepo in `.projenrc.ts`:
16
+
17
+ ```typescript
18
+ import { FndMonorepoProject } from '@fnd-platform/core';
19
+ import { FndApiProject } from '@fnd-platform/api';
20
+ import { FndCmsProject } from '@fnd-platform/cms';
21
+
22
+ const monorepo = new FndMonorepoProject({
23
+ name: 'my-app',
24
+ defaultReleaseBranch: 'main',
25
+ });
26
+
27
+ const api = new FndApiProject({
28
+ parent: monorepo,
29
+ name: 'api',
30
+ outdir: 'packages/api',
31
+ });
32
+
33
+ const cms = new FndCmsProject({
34
+ parent: monorepo,
35
+ name: 'cms',
36
+ outdir: 'packages/cms',
37
+ api: api, // Link to API for content operations
38
+ port: 3001,
39
+ mediaUpload: true,
40
+ richTextEditor: 'tiptap',
41
+ });
42
+
43
+ monorepo.synth();
44
+ ```
45
+
46
+ ## Configuration Options
47
+
48
+ | Option | Type | Default | Description |
49
+ | ---------------- | ------------------------- | ----------------- | ---------------------------- |
50
+ | `parent` | `FndMonorepoProject` | **required** | Parent monorepo |
51
+ | `name` | `string` | **required** | Package name |
52
+ | `api` | `FndApiProject` | **required** | Linked API project |
53
+ | `outdir` | `string` | `packages/{name}` | Output directory |
54
+ | `port` | `number` | `3001` | Development server port |
55
+ | `mediaUpload` | `boolean` | `true` | Enable media upload features |
56
+ | `richTextEditor` | `'tiptap'` \| `'lexical'` | `'tiptap'` | Rich text editor library |
57
+ | `shadcnTheme` | `ShadcnTheme` | `'zinc'` | Theme color |
58
+
59
+ ## What Gets Generated
60
+
61
+ ```
62
+ packages/cms/
63
+ ├── app/
64
+ │ ├── routes/
65
+ │ │ ├── _admin.tsx # Admin layout (protected)
66
+ │ │ ├── _admin._index.tsx # Dashboard
67
+ │ │ ├── _admin.content.tsx # Content list
68
+ │ │ ├── _admin.content.$type.tsx # Content by type
69
+ │ │ ├── _admin.content.$type.$id.tsx # Content editor
70
+ │ │ ├── _admin.content.$type.new.tsx # New content
71
+ │ │ ├── _admin.media.tsx # Media library
72
+ │ │ ├── _admin.settings.tsx # Settings
73
+ │ │ └── login.tsx # Admin login
74
+ │ ├── components/
75
+ │ │ ├── admin/ # Admin UI components
76
+ │ │ ├── editor/ # Rich text editor
77
+ │ │ └── ui/ # shadcn/ui components
78
+ │ ├── lib/
79
+ │ │ ├── api.server.ts # API client
80
+ │ │ ├── auth.server.ts # Auth utilities
81
+ │ │ └── content-types.ts # Content type definitions
82
+ │ └── content-types/ # Content type definitions
83
+ ├── package.json
84
+ ├── tailwind.config.js
85
+ ├── vite.config.ts
86
+ └── tsconfig.json
87
+ ```
88
+
89
+ ## Features
90
+
91
+ - **Admin Interface** - Clean, modern admin UI built with shadcn/ui
92
+ - **Content Modeling** - Define flexible content types with various field types
93
+ - **Draft/Publish Workflow** - Content review and publishing workflow
94
+ - **Media Library** - Upload and manage images, videos, and files
95
+ - **Rich Text Editor** - Tiptap or Lexical-based content editing
96
+ - **Role-Based Access** - Admin, editor, and viewer roles
97
+
98
+ ## Examples
99
+
100
+ ### Content Type Definition
101
+
102
+ ```typescript
103
+ // app/content-types/blog-post.ts
104
+ import { defineContentType } from '~/lib/content-types';
105
+
106
+ export const blogPost = defineContentType({
107
+ name: 'blog-post',
108
+ label: 'Blog Post',
109
+ icon: 'FileText',
110
+
111
+ fields: [
112
+ {
113
+ name: 'title',
114
+ type: 'text',
115
+ label: 'Title',
116
+ required: true,
117
+ maxLength: 200,
118
+ },
119
+ {
120
+ name: 'slug',
121
+ type: 'slug',
122
+ label: 'URL Slug',
123
+ required: true,
124
+ source: 'title',
125
+ },
126
+ {
127
+ name: 'content',
128
+ type: 'richtext',
129
+ label: 'Content',
130
+ required: true,
131
+ },
132
+ {
133
+ name: 'featuredImage',
134
+ type: 'media',
135
+ label: 'Featured Image',
136
+ accept: ['image/*'],
137
+ },
138
+ {
139
+ name: 'publishedAt',
140
+ type: 'datetime',
141
+ label: 'Publish Date',
142
+ },
143
+ ],
144
+ });
145
+ ```
146
+
147
+ ### Admin Dashboard Route
148
+
149
+ ```typescript
150
+ // app/routes/_admin._index.tsx
151
+ import { json, type LoaderFunctionArgs } from '@remix-run/node';
152
+ import { useLoaderData } from '@remix-run/react';
153
+ import { requireAdmin } from '~/lib/auth.server';
154
+ import { contentApi } from '~/lib/api.server';
155
+
156
+ export const loader = async ({ request }: LoaderFunctionArgs) => {
157
+ await requireAdmin(request);
158
+
159
+ const [stats, recentContent] = await Promise.all([
160
+ contentApi.getStats(),
161
+ contentApi.list({ limit: 10, sort: '-updatedAt' }),
162
+ ]);
163
+
164
+ return json({ stats, recentContent });
165
+ };
166
+
167
+ export default function Dashboard() {
168
+ const { stats, recentContent } = useLoaderData<typeof loader>();
169
+
170
+ return (
171
+ <div className="space-y-6">
172
+ <h1 className="text-2xl font-bold">Dashboard</h1>
173
+ {/* Dashboard content */}
174
+ </div>
175
+ );
176
+ }
177
+ ```
178
+
179
+ ### Content Editor Route
180
+
181
+ ```typescript
182
+ // app/routes/_admin.content.$type.$id.tsx
183
+ import { json, redirect, type ActionFunctionArgs } from '@remix-run/node';
184
+ import { requireAdmin } from '~/lib/auth.server';
185
+ import { contentApi } from '~/lib/api.server';
186
+
187
+ export const action = async ({ request, params }: ActionFunctionArgs) => {
188
+ await requireAdmin(request);
189
+
190
+ const formData = await request.formData();
191
+ const intent = formData.get('intent');
192
+
193
+ if (intent === 'save') {
194
+ const data = Object.fromEntries(formData);
195
+ await contentApi.update(params.id!, data);
196
+ return json({ success: true });
197
+ }
198
+
199
+ if (intent === 'publish') {
200
+ await contentApi.publish(params.id!);
201
+ return json({ success: true });
202
+ }
203
+
204
+ if (intent === 'delete') {
205
+ await contentApi.delete(params.id!);
206
+ return redirect(`/admin/content/${params.type}`);
207
+ }
208
+
209
+ return json({ error: 'Invalid action' }, { status: 400 });
210
+ };
211
+ ```
212
+
213
+ ## Field Types
214
+
215
+ | Type | Description | Options |
216
+ | ----------- | ----------------- | ---------------------- |
217
+ | `text` | Single line text | `maxLength`, `pattern` |
218
+ | `textarea` | Multi-line text | `maxLength`, `rows` |
219
+ | `richtext` | Rich text editor | `toolbar`, `formats` |
220
+ | `number` | Numeric input | `min`, `max`, `step` |
221
+ | `boolean` | Toggle/checkbox | `default` |
222
+ | `select` | Dropdown select | `options` |
223
+ | `date` | Date picker | `min`, `max` |
224
+ | `datetime` | Date and time | `min`, `max` |
225
+ | `slug` | URL slug | `source` |
226
+ | `media` | Media picker | `accept`, `multiple` |
227
+ | `reference` | Content reference | `referenceType` |
228
+ | `tags` | Tag input | `suggestions` |
229
+
230
+ ## Content Status
231
+
232
+ | Status | Description |
233
+ | ----------- | ------------------------ |
234
+ | `draft` | Being edited, not public |
235
+ | `published` | Live and visible |
236
+ | `scheduled` | Will publish at set time |
237
+ | `archived` | Hidden but preserved |
238
+
239
+ ## Development
240
+
241
+ ```bash
242
+ # Start development server
243
+ cd packages/cms
244
+ pnpm dev
245
+
246
+ # Build for production
247
+ pnpm build
248
+
249
+ # Run tests
250
+ pnpm test
251
+ ```
252
+
253
+ ## API Reference
254
+
255
+ See the [full API documentation](../../docs/api/modules/cms_src.html) for detailed type definitions and examples.
256
+
257
+ ### Project Class
258
+
259
+ - `FndCmsProject` - Projen project class for CMS packages
260
+
261
+ ### Types
262
+
263
+ ```typescript
264
+ import type { FndCmsProjectOptions } from '@fnd-platform/cms';
265
+ ```
266
+
267
+ ## Requirements
268
+
269
+ - Node.js 20+
270
+ - pnpm 8+
271
+ - @fnd-platform/core
272
+ - @fnd-platform/api (for API linking)
273
+
274
+ ## Related
275
+
276
+ - [@fnd-platform/core](../core/README.md) - Core Projen project classes
277
+ - [@fnd-platform/api](../api/README.md) - API package for backend
278
+ - [@fnd-platform/frontend](../frontend/README.md) - Public-facing frontend
279
+ - [@fnd-platform/cognito-auth](../cognito-auth/README.md) - Authentication
280
+
281
+ ## License
282
+
283
+ MIT
@@ -0,0 +1,127 @@
1
+ import { FndFrontendProject } from '@fnd-platform/frontend';
2
+ import type { FndCmsProjectOptions } from './options';
3
+ /**
4
+ * Creates a CMS admin package within an fnd-platform monorepo.
5
+ *
6
+ * This class generates a complete CMS admin interface scaffold with:
7
+ * - Remix app structure (inherited from FndFrontendProject)
8
+ * - Protected admin routes with authentication
9
+ * - Admin layout and dashboard
10
+ * - shadcn/ui components for admin UI
11
+ *
12
+ * The CMS extends the frontend project and adds admin-specific functionality.
13
+ * Authentication is always enabled for CMS (admin access required).
14
+ *
15
+ * @example
16
+ * ```typescript
17
+ * import { FndMonorepoProject } from '@fnd-platform/core';
18
+ * import { FndApiProject } from '@fnd-platform/api';
19
+ * import { FndCmsProject } from '@fnd-platform/cms';
20
+ *
21
+ * const monorepo = new FndMonorepoProject({
22
+ * name: 'my-app',
23
+ * defaultReleaseBranch: 'main',
24
+ * });
25
+ *
26
+ * const api = new FndApiProject({
27
+ * parent: monorepo,
28
+ * name: 'api',
29
+ * });
30
+ *
31
+ * const cms = new FndCmsProject({
32
+ * parent: monorepo,
33
+ * name: 'cms',
34
+ * api: api,
35
+ * });
36
+ *
37
+ * monorepo.synth();
38
+ * ```
39
+ */
40
+ export declare class FndCmsProject extends FndFrontendProject {
41
+ /**
42
+ * Whether media upload functionality is enabled.
43
+ */
44
+ readonly mediaUpload: boolean;
45
+ /**
46
+ * Rich text editor to use for content editing.
47
+ */
48
+ readonly richTextEditor: 'tiptap' | 'lexical';
49
+ /**
50
+ * Creates a new FndCmsProject.
51
+ *
52
+ * @param options - Configuration options for the CMS project
53
+ * @throws {Error} If required options are missing
54
+ */
55
+ constructor(options: FndCmsProjectOptions);
56
+ /**
57
+ * Generates additional shadcn/ui components for the CMS.
58
+ *
59
+ * Creates:
60
+ * - badge.tsx - Status badge component
61
+ * - avatar.tsx - User avatar component
62
+ * - dropdown-menu.tsx - Dropdown menu component
63
+ * - table.tsx - Table component
64
+ * - popover.tsx - Popover component for link dialogs
65
+ */
66
+ private generateUiComponents;
67
+ /**
68
+ * Generates the admin components for the CMS.
69
+ *
70
+ * Creates:
71
+ * - sidebar.tsx - Admin sidebar navigation
72
+ * - header.tsx - Admin header with user menu
73
+ * - breadcrumbs.tsx - Breadcrumb navigation
74
+ * - dashboard-stats.tsx - Dashboard statistics cards
75
+ * - recent-content.tsx - Recent content list
76
+ * - content-table.tsx - Content list table
77
+ */
78
+ private generateAdminComponents;
79
+ /**
80
+ * Generates the admin routes for the CMS.
81
+ *
82
+ * Creates:
83
+ * - _admin.tsx - Admin layout with sidebar and header
84
+ * - _admin._index.tsx - Admin dashboard with stats
85
+ * - _admin.content.tsx - Content section layout
86
+ * - _admin.content._index.tsx - Content overview
87
+ * - _admin.content.$type.tsx - Content type list
88
+ */
89
+ private generateAdminRoutes;
90
+ /**
91
+ * Generates the content type definition system.
92
+ *
93
+ * Creates:
94
+ * - app/lib/content-types.ts - Content type definitions and interfaces
95
+ * - app/lib/content-schema.ts - Zod schema generation utilities
96
+ * - app/lib/slug-utils.ts - Slug generation utilities
97
+ * - app/content-types/index.ts - Content type registry
98
+ * - app/content-types/blog-post.ts - Example blog post content type
99
+ * - app/content-types/page.ts - Example page content type
100
+ * - app/components/form-fields/* - All form field components
101
+ * - app/components/admin/content-editor.tsx - Dynamic content editor
102
+ */
103
+ private generateContentTypeSystem;
104
+ /**
105
+ * Generates the editor components for rich text editing.
106
+ *
107
+ * Creates:
108
+ * - app/components/editor/toolbar.tsx - Editor toolbar with formatting buttons
109
+ * - app/components/editor/rich-text-editor.tsx - Tiptap-based rich text editor
110
+ */
111
+ private generateEditorComponents;
112
+ /**
113
+ * Generates the media library components.
114
+ *
115
+ * Creates:
116
+ * - app/lib/media-api.ts - Client-side API helpers for presigned URL uploads
117
+ * - app/components/media/media-uploader.tsx - Drag-drop upload with progress
118
+ * - app/components/media/media-grid.tsx - Grid display with selection
119
+ * - app/components/media/media-picker.tsx - Dialog for field integration
120
+ * - app/routes/_admin.media.tsx - Media library route
121
+ * - app/components/ui/progress.tsx - Progress bar component
122
+ * - app/components/ui/dialog.tsx - Dialog component
123
+ * - app/components/ui/tabs.tsx - Tabs component
124
+ */
125
+ private generateMediaComponents;
126
+ }
127
+ //# sourceMappingURL=cms-project.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cms-project.d.ts","sourceRoot":"","sources":["../src/cms-project.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAC5D,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,WAAW,CAAC;AAwDtD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AACH,qBAAa,aAAc,SAAQ,kBAAkB;IACnD;;OAEG;IACH,SAAgB,WAAW,EAAE,OAAO,CAAC;IAErC;;OAEG;IACH,SAAgB,cAAc,EAAE,QAAQ,GAAG,SAAS,CAAC;IAErD;;;;;OAKG;gBACS,OAAO,EAAE,oBAAoB;IA6DzC;;;;;;;;;OASG;IACH,OAAO,CAAC,oBAAoB;IAsB5B;;;;;;;;;;OAUG;IACH,OAAO,CAAC,uBAAuB;IA0B/B;;;;;;;;;OASG;IACH,OAAO,CAAC,mBAAmB;IA2B3B;;;;;;;;;;;;OAYG;IACH,OAAO,CAAC,yBAAyB;IA0FjC;;;;;;OAMG;IACH,OAAO,CAAC,wBAAwB;IAUhC;;;;;;;;;;;;OAYG;IACH,OAAO,CAAC,uBAAuB;CAqChC"}