cmx-sdk 0.1.1 → 0.1.3
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 +53 -351
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +88 -333
- package/dist/commands/create-collection.d.ts +9 -0
- package/dist/commands/create-collection.js +32 -0
- package/dist/commands/create-data-type.d.ts +8 -0
- package/dist/commands/create-data-type.js +32 -0
- package/dist/commands/create-form.d.ts +8 -0
- package/dist/commands/create-form.js +32 -0
- package/dist/commands/import-schema.d.ts +5 -0
- package/dist/commands/import-schema.js +96 -0
- package/dist/commands/list-collections.d.ts +1 -0
- package/dist/commands/list-collections.js +27 -0
- package/dist/commands/list-components.d.ts +1 -0
- package/dist/commands/list-components.js +26 -0
- package/dist/commands/list-data-types.d.ts +1 -0
- package/dist/commands/list-data-types.js +27 -0
- package/dist/commands/list-forms.d.ts +1 -0
- package/dist/commands/list-forms.js +27 -0
- package/dist/commands/sync-components.d.ts +6 -0
- package/dist/commands/sync-components.js +42 -0
- package/dist/lib/api-client.d.ts +61 -0
- package/dist/lib/api-client.js +68 -0
- package/package.json +13 -49
- package/src/cli.ts +106 -0
- package/src/commands/create-collection.ts +47 -0
- package/src/commands/create-data-type.ts +53 -0
- package/src/commands/create-form.ts +53 -0
- package/src/commands/import-schema.ts +151 -0
- package/src/commands/list-collections.ts +30 -0
- package/src/commands/list-components.ts +29 -0
- package/src/commands/list-data-types.ts +30 -0
- package/src/commands/list-forms.ts +30 -0
- package/src/commands/sync-components.ts +57 -0
- package/src/lib/api-client.ts +131 -0
- package/tsconfig.json +17 -0
- package/dist/index.d.ts +0 -93
- package/dist/index.js +0 -926
- package/dist/index.js.map +0 -1
package/README.md
CHANGED
|
@@ -1,393 +1,95 @@
|
|
|
1
|
-
#
|
|
1
|
+
# CMX SDK
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
CLI tool for managing CMX schemas and content.
|
|
4
4
|
|
|
5
5
|
## Installation
|
|
6
6
|
|
|
7
7
|
```bash
|
|
8
8
|
npm install cmx-sdk
|
|
9
|
-
# or
|
|
10
|
-
pnpm add cmx-sdk
|
|
11
|
-
# or
|
|
12
|
-
yarn add cmx-sdk
|
|
13
9
|
```
|
|
14
10
|
|
|
15
|
-
##
|
|
16
|
-
|
|
17
|
-
- Type-Safe API Client - Fetch content from CMX Admin with full TypeScript support
|
|
18
|
-
- MDX Rendering - Server-side MDX compilation with reference resolution
|
|
19
|
-
- MDX Components - Pre-built React components (Callout, Embed, BlogCard, Image, etc.)
|
|
20
|
-
- Next.js Optimized - Built-in support for ISR, caching, and revalidation
|
|
21
|
-
- Customizable - Inject your own custom components into MDX rendering
|
|
22
|
-
|
|
23
|
-
## Quick Start
|
|
24
|
-
|
|
25
|
-
### 1. Set up environment variables
|
|
26
|
-
|
|
27
|
-
Create a `.env.local` file:
|
|
11
|
+
## Environment Variables
|
|
28
12
|
|
|
29
|
-
```
|
|
30
|
-
CMX_API_URL=https://your-
|
|
13
|
+
```bash
|
|
14
|
+
CMX_API_URL=https://your-api-url.com
|
|
31
15
|
CMX_API_KEY=your_api_key_here
|
|
32
16
|
```
|
|
33
17
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
```tsx
|
|
37
|
-
import { getCollectionPosts, getCollectionPostDetail } from 'cmx-sdk';
|
|
38
|
-
|
|
39
|
-
// List posts in a collection
|
|
40
|
-
const { collection, posts } = await getCollectionPosts('blog');
|
|
41
|
-
|
|
42
|
-
// Get a specific post with references
|
|
43
|
-
const { collection, post, references } = await getCollectionPostDetail('blog', 'my-post');
|
|
44
|
-
```
|
|
45
|
-
|
|
46
|
-
### 3. Render MDX content
|
|
47
|
-
|
|
48
|
-
```tsx
|
|
49
|
-
import { renderMdx } from 'cmx-sdk';
|
|
50
|
-
|
|
51
|
-
// Render MDX with reference resolution (BlogCard, Image, etc.)
|
|
52
|
-
const { content } = await renderMdx(post.mdx, references);
|
|
53
|
-
return <article>{content}</article>;
|
|
54
|
-
|
|
55
|
-
// With custom components
|
|
56
|
-
import { FeatureCard } from './components/custom';
|
|
57
|
-
const { content } = await renderMdx(post.mdx, references, {
|
|
58
|
-
additionalComponents: { FeatureCard },
|
|
59
|
-
});
|
|
60
|
-
```
|
|
61
|
-
|
|
62
|
-
## API Reference
|
|
63
|
-
|
|
64
|
-
### Content Fetching
|
|
65
|
-
|
|
66
|
-
```tsx
|
|
67
|
-
import {
|
|
68
|
-
getCollectionPosts,
|
|
69
|
-
getCollectionPostDetail,
|
|
70
|
-
getDataEntries,
|
|
71
|
-
getDataEntry,
|
|
72
|
-
getPreviewByToken,
|
|
73
|
-
} from 'cmx-sdk';
|
|
74
|
-
|
|
75
|
-
// Get posts from a collection
|
|
76
|
-
const { posts } = await getCollectionPosts('blog');
|
|
77
|
-
|
|
78
|
-
// Get a specific post with resolved references
|
|
79
|
-
const { post, references } = await getCollectionPostDetail('blog', 'my-post');
|
|
80
|
-
|
|
81
|
-
// Get data entries (custom data types)
|
|
82
|
-
const { items } = await getDataEntries('team-members');
|
|
83
|
-
|
|
84
|
-
// Get data entries with options
|
|
85
|
-
const { items } = await getDataEntries('team-members', {
|
|
86
|
-
sortBy: 'createdAt',
|
|
87
|
-
sortOrder: 'desc',
|
|
88
|
-
limit: 10,
|
|
89
|
-
});
|
|
90
|
-
|
|
91
|
-
// Get a specific data entry
|
|
92
|
-
const entry = await getDataEntry('team-members', 'entry-id');
|
|
93
|
-
|
|
94
|
-
// Get preview content by token (no auth required)
|
|
95
|
-
const preview = await getPreviewByToken(token);
|
|
96
|
-
if (preview) {
|
|
97
|
-
const { content } = await renderMdx(preview.post.mdx, preview.references);
|
|
98
|
-
}
|
|
99
|
-
```
|
|
100
|
-
|
|
101
|
-
### MDX Rendering
|
|
102
|
-
|
|
103
|
-
```tsx
|
|
104
|
-
import { renderMdx, renderMdxPreview } from 'cmx-sdk';
|
|
105
|
-
|
|
106
|
-
// Full rendering with reference resolution
|
|
107
|
-
const { content, references } = await renderMdx(post.mdx, post.references);
|
|
108
|
-
|
|
109
|
-
// With custom components injected
|
|
110
|
-
const { content } = await renderMdx(post.mdx, post.references, {
|
|
111
|
-
additionalComponents: { FeatureCard, PricingTable },
|
|
112
|
-
});
|
|
113
|
-
|
|
114
|
-
// Preview rendering (no reference resolution)
|
|
115
|
-
const element = await renderMdxPreview(mdxString);
|
|
116
|
-
```
|
|
117
|
-
|
|
118
|
-
### Cache Tags
|
|
119
|
-
|
|
120
|
-
Use Next.js cache tags for on-demand revalidation:
|
|
121
|
-
|
|
122
|
-
```tsx
|
|
123
|
-
import { CACHE_TAGS, publicFetchWithTags } from 'cmx-sdk';
|
|
124
|
-
|
|
125
|
-
// Built-in cache tags used by convenience functions:
|
|
126
|
-
// CACHE_TAGS.collections - all collections
|
|
127
|
-
// CACHE_TAGS.collection(slug) - specific collection
|
|
128
|
-
// CACHE_TAGS.post(col, post) - specific post
|
|
129
|
-
// CACHE_TAGS.data - all data types
|
|
130
|
-
// CACHE_TAGS.dataType(slug) - specific data type
|
|
131
|
-
|
|
132
|
-
// Revalidate by tag
|
|
133
|
-
import { revalidateTag } from 'next/cache';
|
|
134
|
-
revalidateTag(CACHE_TAGS.collection('blog'));
|
|
135
|
-
|
|
136
|
-
// Low-level: fetch with custom cache tags
|
|
137
|
-
const data = await publicFetchWithTags<T>(
|
|
138
|
-
'/collections/blog/posts',
|
|
139
|
-
[CACHE_TAGS.collections, CACHE_TAGS.collection('blog')]
|
|
140
|
-
);
|
|
141
|
-
```
|
|
142
|
-
|
|
143
|
-
### Preview Mode
|
|
144
|
-
|
|
145
|
-
```tsx
|
|
146
|
-
import { getPreviewByToken, renderMdx } from 'cmx-sdk';
|
|
147
|
-
|
|
148
|
-
const preview = await getPreviewByToken(token);
|
|
149
|
-
if (preview) {
|
|
150
|
-
const { content } = await renderMdx(preview.post.mdx, preview.references);
|
|
151
|
-
return <article>{content}</article>;
|
|
152
|
-
}
|
|
153
|
-
```
|
|
154
|
-
|
|
155
|
-
## Components
|
|
156
|
-
|
|
157
|
-
The SDK includes MDX components that are automatically available in `renderMdx`:
|
|
158
|
-
|
|
159
|
-
### Standard Components
|
|
18
|
+
## Commands
|
|
160
19
|
|
|
161
|
-
|
|
162
|
-
- `Embed` - External content embedding (YouTube, Twitter, etc.)
|
|
163
|
-
- `Button` - Interactive buttons
|
|
20
|
+
### create-collection
|
|
164
21
|
|
|
165
|
-
|
|
22
|
+
Create a new collection.
|
|
166
23
|
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
-
|
|
170
|
-
- `Image` - Asset images with variants (resolves URL, alt text, dimensions)
|
|
171
|
-
|
|
172
|
-
### Component Catalog
|
|
173
|
-
|
|
174
|
-
Access component metadata and validation:
|
|
175
|
-
|
|
176
|
-
```tsx
|
|
177
|
-
import {
|
|
178
|
-
componentCatalog,
|
|
179
|
-
isValidComponent,
|
|
180
|
-
validateComponentProps,
|
|
181
|
-
validateMdx,
|
|
182
|
-
} from 'cmx-sdk';
|
|
183
|
-
|
|
184
|
-
// Check if a component is valid
|
|
185
|
-
isValidComponent('Callout'); // true
|
|
186
|
-
|
|
187
|
-
// Validate component props
|
|
188
|
-
const result = validateComponentProps('Callout', {
|
|
189
|
-
type: 'info',
|
|
190
|
-
title: 'Note',
|
|
191
|
-
});
|
|
24
|
+
```bash
|
|
25
|
+
# Using JSON
|
|
26
|
+
cmx-sdk create-collection --json '{"type":"post","slug":"blog","name":"ブログ"}'
|
|
192
27
|
|
|
193
|
-
|
|
194
|
-
|
|
28
|
+
# Using individual options
|
|
29
|
+
cmx-sdk create-collection --type post --slug blog --name ブログ --description "ブログ記事"
|
|
195
30
|
```
|
|
196
31
|
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
Generate typed functions and interfaces from your CMX data types and collections.
|
|
32
|
+
### create-data-type
|
|
200
33
|
|
|
201
|
-
|
|
34
|
+
Create a new data type.
|
|
202
35
|
|
|
203
36
|
```bash
|
|
204
|
-
|
|
37
|
+
cmx-sdk create-data-type --json '{"slug":"staff","name":"スタッフ","fields":[...]}'
|
|
205
38
|
```
|
|
206
39
|
|
|
207
|
-
|
|
40
|
+
### create-form
|
|
208
41
|
|
|
209
|
-
|
|
42
|
+
Create a new form definition.
|
|
210
43
|
|
|
211
44
|
```bash
|
|
212
|
-
|
|
213
|
-
```
|
|
214
|
-
|
|
215
|
-
### Requirements
|
|
216
|
-
|
|
217
|
-
Set `CMX_API_URL` and `CMX_API_KEY` in your `.env` or `.env.local`:
|
|
218
|
-
|
|
219
|
-
```env
|
|
220
|
-
CMX_API_URL=https://your-cmx-admin.example.com
|
|
221
|
-
CMX_API_KEY=your_api_key_here
|
|
222
|
-
```
|
|
223
|
-
|
|
224
|
-
### Generated Output
|
|
225
|
-
|
|
226
|
-
```
|
|
227
|
-
generated/cmx/
|
|
228
|
-
├── index.ts
|
|
229
|
-
├── collections/
|
|
230
|
-
│ ├── index.ts
|
|
231
|
-
│ ├── blog.ts # getBlogPosts(), getBlogPostDetail()
|
|
232
|
-
│ └── docs.ts # getDocsPosts(), getDocsPostDetail()
|
|
233
|
-
└── data-types/
|
|
234
|
-
├── index.ts
|
|
235
|
-
├── team-members.ts # TeamMember type, getTeamMembers(), getTeamMember()
|
|
236
|
-
└── faq.ts # Faq type, getFaqs(), getFaq()
|
|
237
|
-
```
|
|
238
|
-
|
|
239
|
-
### Using Generated Code
|
|
240
|
-
|
|
241
|
-
```tsx
|
|
242
|
-
// Before (generic, no type safety)
|
|
243
|
-
import { getDataEntries } from "cmx-sdk"
|
|
244
|
-
const { items } = await getDataEntries("team-members")
|
|
245
|
-
const name = items[0].name // ❌ type is unknown
|
|
246
|
-
|
|
247
|
-
// After (typed, auto-generated)
|
|
248
|
-
import { getTeamMembers } from "./generated/cmx"
|
|
249
|
-
const { items } = await getTeamMembers()
|
|
250
|
-
const name = items[0].name // ✅ type is string
|
|
45
|
+
cmx-sdk create-form --json '{"slug":"contact","name":"お問い合わせ","fields":[...]}'
|
|
251
46
|
```
|
|
252
47
|
|
|
253
|
-
|
|
48
|
+
### sync-components
|
|
254
49
|
|
|
255
|
-
|
|
256
|
-
|---|---|
|
|
257
|
-
| text, textarea, richtext, url, email | `string` |
|
|
258
|
-
| number | `number` |
|
|
259
|
-
| boolean | `boolean` |
|
|
260
|
-
| date, datetime | `string` |
|
|
261
|
-
| select (with choices) | `"value1" \| "value2"` |
|
|
262
|
-
| multiselect | `string[]` or union array |
|
|
263
|
-
| image, file | `string` |
|
|
264
|
-
| relation | `string` (or `string[]` if multiple) |
|
|
265
|
-
| json | `unknown` |
|
|
50
|
+
Sync custom components.
|
|
266
51
|
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
The SDK is fully typed. Import types as needed:
|
|
52
|
+
```bash
|
|
53
|
+
# From file
|
|
54
|
+
cmx-sdk sync-components --file components.json
|
|
272
55
|
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
// API response types
|
|
276
|
-
CollectionPostsResponse,
|
|
277
|
-
CollectionPostDetailResponse,
|
|
278
|
-
DataListResponse,
|
|
279
|
-
DataEntryItem,
|
|
280
|
-
PreviewResponse,
|
|
281
|
-
References,
|
|
282
|
-
PostReference,
|
|
283
|
-
AssetReference,
|
|
284
|
-
// Rendering types
|
|
285
|
-
RenderResult,
|
|
286
|
-
RenderOptions,
|
|
287
|
-
ResolvedReferences,
|
|
288
|
-
// Component types
|
|
289
|
-
ComponentDefinition,
|
|
290
|
-
ValidationResult,
|
|
291
|
-
} from 'cmx-sdk';
|
|
56
|
+
# From JSON string
|
|
57
|
+
cmx-sdk sync-components --json '{"components":[...]}'
|
|
292
58
|
```
|
|
293
59
|
|
|
294
|
-
|
|
60
|
+
### import-schema
|
|
295
61
|
|
|
296
|
-
|
|
62
|
+
Import collections, data types, and forms from a schema file.
|
|
297
63
|
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
```
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
64
|
+
```bash
|
|
65
|
+
cmx-sdk import-schema --file schema.json
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
**schema.json format:**
|
|
69
|
+
|
|
70
|
+
```json
|
|
71
|
+
{
|
|
72
|
+
"collections": [
|
|
73
|
+
{ "type": "post", "slug": "blog", "name": "ブログ" }
|
|
74
|
+
],
|
|
75
|
+
"dataTypes": [
|
|
76
|
+
{ "slug": "staff", "name": "スタッフ", "fields": [...] }
|
|
77
|
+
],
|
|
78
|
+
"forms": [
|
|
79
|
+
{ "slug": "contact", "name": "お問い合わせ", "fields": [...] }
|
|
80
|
+
]
|
|
312
81
|
}
|
|
313
82
|
```
|
|
314
83
|
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
```tsx
|
|
318
|
-
import {
|
|
319
|
-
publicFetcher,
|
|
320
|
-
publicFetchWithTags,
|
|
321
|
-
getPublicApiBaseUrl,
|
|
322
|
-
getPublicApiToken,
|
|
323
|
-
} from 'cmx-sdk';
|
|
324
|
-
|
|
325
|
-
// Use the fetcher directly for custom endpoints
|
|
326
|
-
const data = await publicFetchWithTags<MyType>('/custom/endpoint', ['my-tag']);
|
|
327
|
-
```
|
|
328
|
-
|
|
329
|
-
## Environment Variables
|
|
330
|
-
|
|
331
|
-
| Variable | Description | Required |
|
|
332
|
-
|----------|-------------|----------|
|
|
333
|
-
| `CMX_API_URL` | CMX Admin API base URL | Yes |
|
|
334
|
-
| `CMX_API_KEY` | API key for authentication | Yes |
|
|
335
|
-
|
|
336
|
-
## Next.js Integration
|
|
337
|
-
|
|
338
|
-
The SDK is optimized for Next.js App Router (Server Components):
|
|
339
|
-
|
|
340
|
-
```tsx
|
|
341
|
-
// app/blog/[slug]/page.tsx
|
|
342
|
-
import { getCollectionPosts, getCollectionPostDetail, renderMdx } from 'cmx-sdk';
|
|
84
|
+
## Development
|
|
343
85
|
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
params: Promise<{ slug: string }>;
|
|
348
|
-
}) {
|
|
349
|
-
const { slug } = await params;
|
|
350
|
-
const { post, references } = await getCollectionPostDetail('blog', slug);
|
|
351
|
-
const { content } = await renderMdx(post.mdx, references);
|
|
352
|
-
|
|
353
|
-
return (
|
|
354
|
-
<article>
|
|
355
|
-
<h1>{post.title}</h1>
|
|
356
|
-
<p>{post.description}</p>
|
|
357
|
-
<div className="prose">{content}</div>
|
|
358
|
-
</article>
|
|
359
|
-
);
|
|
360
|
-
}
|
|
86
|
+
```bash
|
|
87
|
+
# Build
|
|
88
|
+
npm run build
|
|
361
89
|
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
return posts.map((post) => ({ slug: post.slug }));
|
|
365
|
-
}
|
|
90
|
+
# Watch mode
|
|
91
|
+
npm run dev
|
|
366
92
|
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
}: {
|
|
370
|
-
params: Promise<{ slug: string }>;
|
|
371
|
-
}) {
|
|
372
|
-
const { slug } = await params;
|
|
373
|
-
const { post } = await getCollectionPostDetail('blog', slug);
|
|
374
|
-
return {
|
|
375
|
-
title: post.title,
|
|
376
|
-
description: post.description,
|
|
377
|
-
};
|
|
378
|
-
}
|
|
93
|
+
# Clean
|
|
94
|
+
npm run clean
|
|
379
95
|
```
|
|
380
|
-
|
|
381
|
-
## Examples
|
|
382
|
-
|
|
383
|
-
Check out the [CMX Starter Kit](https://github.com/kzkm-lab/cmx-starter-kit) for a complete example of using the SDK.
|
|
384
|
-
|
|
385
|
-
## License
|
|
386
|
-
|
|
387
|
-
MIT
|
|
388
|
-
|
|
389
|
-
## Links
|
|
390
|
-
|
|
391
|
-
- [Documentation](https://github.com/kzkm-lab/cmx)
|
|
392
|
-
- [CMX Starter Kit](https://github.com/kzkm-lab/cmx-starter-kit)
|
|
393
|
-
- [Issues](https://github.com/kzkm-lab/cmx/issues)
|
package/dist/cli.d.ts
ADDED