@mybe/sdk 1.0.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/README.md +364 -0
- package/package.json +25 -0
package/README.md
ADDED
|
@@ -0,0 +1,364 @@
|
|
|
1
|
+
# Mybe CMS SDK
|
|
2
|
+
|
|
3
|
+
A TypeScript SDK for fetching content from Mybe CMS.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @mybe/sdk
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Features
|
|
12
|
+
|
|
13
|
+
- ✅ **Zero Dependencies** - Uses native fetch API
|
|
14
|
+
- ✅ **TypeScript Support** - Full type safety with TypeScript
|
|
15
|
+
- ✅ **Auto Environment Detection** - Automatically detects development vs production
|
|
16
|
+
- ✅ **Error Handling** - Custom error classes for better error handling
|
|
17
|
+
- ✅ **Pagination Support** - Built-in pagination for large datasets
|
|
18
|
+
- ✅ **Status Filtering** - Filter content by status (draft, published, archived)
|
|
19
|
+
- ✅ **Locale Filtering** - Filter content by locale for multi-language support
|
|
20
|
+
|
|
21
|
+
## Quick Start
|
|
22
|
+
|
|
23
|
+
```typescript
|
|
24
|
+
import { MybeSDK } from '@mybe/sdk';
|
|
25
|
+
|
|
26
|
+
// Initialize the SDK
|
|
27
|
+
const sdk = new MybeSDK({
|
|
28
|
+
apiKey: 'your-api-key'
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
// Fetch a single content entry
|
|
32
|
+
const content = await sdk.getContent('content-id');
|
|
33
|
+
|
|
34
|
+
// Fetch content by type with filters
|
|
35
|
+
const contentList = await sdk.getContentByType('content-type-id', {
|
|
36
|
+
status: 'published',
|
|
37
|
+
limit: 10
|
|
38
|
+
});
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## Configuration
|
|
42
|
+
|
|
43
|
+
### Basic Configuration
|
|
44
|
+
|
|
45
|
+
```typescript
|
|
46
|
+
const sdk = new MybeSDK({
|
|
47
|
+
apiKey: 'your-api-key'
|
|
48
|
+
});
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
The SDK automatically detects the environment:
|
|
52
|
+
- **Development** (`NODE_ENV=development`): Uses `http://localhost:3001/api/v1`
|
|
53
|
+
- **Production**: Uses `https://api.mybe.app/api/v1`
|
|
54
|
+
|
|
55
|
+
### Custom Base URL (Optional)
|
|
56
|
+
|
|
57
|
+
```typescript
|
|
58
|
+
const sdk = new MybeSDK({
|
|
59
|
+
apiKey: 'your-api-key',
|
|
60
|
+
baseUrl: 'https://custom-api.example.com/api/v1'
|
|
61
|
+
});
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
## API Reference
|
|
65
|
+
|
|
66
|
+
### Content Models (Content Types)
|
|
67
|
+
|
|
68
|
+
#### `getContentModels(projectId: string)`
|
|
69
|
+
|
|
70
|
+
Get all content models for a project.
|
|
71
|
+
|
|
72
|
+
```typescript
|
|
73
|
+
const contentModels = await sdk.getContentModels('project-id');
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
**Returns:** `Promise<ContentType[]>`
|
|
77
|
+
|
|
78
|
+
#### `getContentModel(contentTypeId: string)`
|
|
79
|
+
|
|
80
|
+
Get a specific content model by ID.
|
|
81
|
+
|
|
82
|
+
```typescript
|
|
83
|
+
const contentModel = await sdk.getContentModel('content-type-id');
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
**Returns:** `Promise<ContentType>`
|
|
87
|
+
|
|
88
|
+
### Content Entries
|
|
89
|
+
|
|
90
|
+
#### `getContent(contentId: string)`
|
|
91
|
+
|
|
92
|
+
Get a single content entry by ID.
|
|
93
|
+
|
|
94
|
+
```typescript
|
|
95
|
+
const content = await sdk.getContent('content-id');
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
**Returns:** `Promise<ContentEntry>`
|
|
99
|
+
|
|
100
|
+
#### `getContentByType(contentTypeId: string, options?: ContentFilterOptions)`
|
|
101
|
+
|
|
102
|
+
Get all content entries for a specific content type.
|
|
103
|
+
|
|
104
|
+
```typescript
|
|
105
|
+
const result = await sdk.getContentByType('content-type-id', {
|
|
106
|
+
status: 'published',
|
|
107
|
+
limit: 20,
|
|
108
|
+
lastKey: 'pagination-key' // For pagination
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
console.log(result.data); // Array of content entries
|
|
112
|
+
console.log(result.pagination.hasMore); // Boolean
|
|
113
|
+
console.log(result.pagination.lastEvaluatedKey); // For next page
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
**Options:**
|
|
117
|
+
- `status?: 'draft' | 'published' | 'archived'` - Filter by status
|
|
118
|
+
- `locale?: string` - Filter by locale (e.g., 'en-US', 'bn-BD', 'fr-FR', 'es-ES')
|
|
119
|
+
- `limit?: number` - Number of items per page
|
|
120
|
+
- `lastKey?: string` - Pagination key from previous response
|
|
121
|
+
|
|
122
|
+
**Returns:** `Promise<ContentListResponse>`
|
|
123
|
+
|
|
124
|
+
#### `getContentByProject(projectId: string, options?: ContentFilterOptions)`
|
|
125
|
+
|
|
126
|
+
Get all content entries for a project.
|
|
127
|
+
|
|
128
|
+
```typescript
|
|
129
|
+
const result = await sdk.getContentByProject('project-id', {
|
|
130
|
+
status: 'published',
|
|
131
|
+
limit: 20
|
|
132
|
+
});
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
**Options:**
|
|
136
|
+
- `status?: 'draft' | 'published' | 'archived'` - Filter by status
|
|
137
|
+
- `locale?: string` - Filter by locale (e.g., 'en-US', 'bn-BD', 'fr-FR', 'es-ES')
|
|
138
|
+
- `limit?: number` - Number of items per page
|
|
139
|
+
- `lastKey?: string` - Pagination key from previous response
|
|
140
|
+
|
|
141
|
+
**Returns:** `Promise<ContentListResponse>`
|
|
142
|
+
|
|
143
|
+
## Pagination Example
|
|
144
|
+
|
|
145
|
+
```typescript
|
|
146
|
+
let lastKey: string | undefined;
|
|
147
|
+
let allContent: ContentEntry[] = [];
|
|
148
|
+
|
|
149
|
+
do {
|
|
150
|
+
const result = await sdk.getContentByType('content-type-id', {
|
|
151
|
+
status: 'published',
|
|
152
|
+
limit: 50,
|
|
153
|
+
lastKey: lastKey ? JSON.stringify(result.pagination.lastEvaluatedKey) : undefined
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
allContent = [...allContent, ...result.data];
|
|
157
|
+
lastKey = result.pagination.hasMore
|
|
158
|
+
? JSON.stringify(result.pagination.lastEvaluatedKey)
|
|
159
|
+
: undefined;
|
|
160
|
+
|
|
161
|
+
} while (lastKey);
|
|
162
|
+
|
|
163
|
+
console.log(`Fetched ${allContent.length} total items`);
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
## Error Handling
|
|
167
|
+
|
|
168
|
+
The SDK provides custom error classes for better error handling:
|
|
169
|
+
|
|
170
|
+
```typescript
|
|
171
|
+
import {
|
|
172
|
+
MybeSDK,
|
|
173
|
+
NotFoundError,
|
|
174
|
+
UnauthorizedError,
|
|
175
|
+
ValidationError,
|
|
176
|
+
ServerError
|
|
177
|
+
} from '@mybe/sdk';
|
|
178
|
+
|
|
179
|
+
try {
|
|
180
|
+
const content = await sdk.getContent('content-id');
|
|
181
|
+
} catch (error) {
|
|
182
|
+
if (error instanceof NotFoundError) {
|
|
183
|
+
console.error('Content not found');
|
|
184
|
+
} else if (error instanceof UnauthorizedError) {
|
|
185
|
+
console.error('Invalid API key');
|
|
186
|
+
} else if (error instanceof ValidationError) {
|
|
187
|
+
console.error('Validation error:', error.message);
|
|
188
|
+
} else if (error instanceof ServerError) {
|
|
189
|
+
console.error('Server error:', error.message);
|
|
190
|
+
} else {
|
|
191
|
+
console.error('Unknown error:', error);
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
### Error Types
|
|
197
|
+
|
|
198
|
+
- `MybeSDKError` - Base error class
|
|
199
|
+
- `NotFoundError` - Resource not found (404)
|
|
200
|
+
- `UnauthorizedError` - Invalid API key (401)
|
|
201
|
+
- `ForbiddenError` - Insufficient permissions (403)
|
|
202
|
+
- `ValidationError` - Validation failed (400)
|
|
203
|
+
- `ServerError` - Internal server error (500)
|
|
204
|
+
|
|
205
|
+
## TypeScript Types
|
|
206
|
+
|
|
207
|
+
The SDK exports all TypeScript types for your convenience:
|
|
208
|
+
|
|
209
|
+
```typescript
|
|
210
|
+
import type {
|
|
211
|
+
ContentType,
|
|
212
|
+
ContentEntry,
|
|
213
|
+
ContentFilterOptions,
|
|
214
|
+
PaginationResponse,
|
|
215
|
+
APIResponse,
|
|
216
|
+
ContentListResponse
|
|
217
|
+
} from '@mybe/sdk';
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
### ContentType
|
|
221
|
+
|
|
222
|
+
```typescript
|
|
223
|
+
interface ContentType {
|
|
224
|
+
id: string;
|
|
225
|
+
project_id: string;
|
|
226
|
+
name: string;
|
|
227
|
+
slug: string;
|
|
228
|
+
description?: string;
|
|
229
|
+
created_at: string;
|
|
230
|
+
updated_at: string;
|
|
231
|
+
}
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
### ContentEntry
|
|
235
|
+
|
|
236
|
+
```typescript
|
|
237
|
+
interface ContentEntry {
|
|
238
|
+
id: string;
|
|
239
|
+
content_type_id: string;
|
|
240
|
+
project_id: string;
|
|
241
|
+
slug?: string;
|
|
242
|
+
status: 'draft' | 'published' | 'archived';
|
|
243
|
+
data: Record<string, any>;
|
|
244
|
+
locale?: string;
|
|
245
|
+
created_by: string;
|
|
246
|
+
updated_by?: string;
|
|
247
|
+
published_at?: string;
|
|
248
|
+
created_at: string;
|
|
249
|
+
updated_at: string;
|
|
250
|
+
}
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
## Examples
|
|
254
|
+
|
|
255
|
+
### Fetch Published Blog Posts
|
|
256
|
+
|
|
257
|
+
```typescript
|
|
258
|
+
const sdk = new MybeSDK({ apiKey: 'your-api-key' });
|
|
259
|
+
|
|
260
|
+
const posts = await sdk.getContentByType('blog-post-type-id', {
|
|
261
|
+
status: 'published',
|
|
262
|
+
limit: 10
|
|
263
|
+
});
|
|
264
|
+
|
|
265
|
+
posts.data.forEach(post => {
|
|
266
|
+
console.log(post.data.title);
|
|
267
|
+
console.log(post.data.content);
|
|
268
|
+
});
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
### Fetch All Content Models
|
|
272
|
+
|
|
273
|
+
```typescript
|
|
274
|
+
const contentModels = await sdk.getContentModels('project-id');
|
|
275
|
+
|
|
276
|
+
contentModels.forEach(model => {
|
|
277
|
+
console.log(`${model.name} (${model.slug})`);
|
|
278
|
+
});
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
### Fetch Single Content Entry
|
|
282
|
+
|
|
283
|
+
```typescript
|
|
284
|
+
const content = await sdk.getContent('content-entry-id');
|
|
285
|
+
|
|
286
|
+
console.log(content.data); // Your content data
|
|
287
|
+
console.log(content.status); // draft | published | archived
|
|
288
|
+
```
|
|
289
|
+
|
|
290
|
+
### Multi-locale Content
|
|
291
|
+
|
|
292
|
+
Fetch content in different languages using the locale filter:
|
|
293
|
+
|
|
294
|
+
```typescript
|
|
295
|
+
const sdk = new MybeSDK({ apiKey: 'your-api-key' });
|
|
296
|
+
|
|
297
|
+
// Fetch English content
|
|
298
|
+
const englishPosts = await sdk.getContentByType('blog-post-type-id', {
|
|
299
|
+
status: 'published',
|
|
300
|
+
locale: 'en-US',
|
|
301
|
+
limit: 10
|
|
302
|
+
});
|
|
303
|
+
|
|
304
|
+
// Fetch Bangla content
|
|
305
|
+
const banglaPosts = await sdk.getContentByType('blog-post-type-id', {
|
|
306
|
+
status: 'published',
|
|
307
|
+
locale: 'bn-BD',
|
|
308
|
+
limit: 10
|
|
309
|
+
});
|
|
310
|
+
|
|
311
|
+
// Fetch French content
|
|
312
|
+
const frenchPosts = await sdk.getContentByType('blog-post-type-id', {
|
|
313
|
+
status: 'published',
|
|
314
|
+
locale: 'fr-FR',
|
|
315
|
+
limit: 10
|
|
316
|
+
});
|
|
317
|
+
|
|
318
|
+
// Fetch Spanish content
|
|
319
|
+
const spanishPosts = await sdk.getContentByType('blog-post-type-id', {
|
|
320
|
+
status: 'published',
|
|
321
|
+
locale: 'es-ES',
|
|
322
|
+
limit: 10
|
|
323
|
+
});
|
|
324
|
+
```
|
|
325
|
+
|
|
326
|
+
**Building a Multi-language Website:**
|
|
327
|
+
|
|
328
|
+
```typescript
|
|
329
|
+
// Get user's preferred language
|
|
330
|
+
const userLocale = getUserPreferredLocale(); // e.g., 'bn-BD'
|
|
331
|
+
|
|
332
|
+
// Fetch content in user's language
|
|
333
|
+
const localizedContent = await sdk.getContentByType('content-type-id', {
|
|
334
|
+
status: 'published',
|
|
335
|
+
locale: userLocale,
|
|
336
|
+
limit: 20
|
|
337
|
+
});
|
|
338
|
+
|
|
339
|
+
// Display localized content
|
|
340
|
+
localizedContent.data.forEach(item => {
|
|
341
|
+
console.log(item.data.title); // Title in user's language
|
|
342
|
+
console.log(item.metadata.locale); // e.g., 'bn-BD'
|
|
343
|
+
});
|
|
344
|
+
```
|
|
345
|
+
|
|
346
|
+
**Supported Locales:**
|
|
347
|
+
- `en-US` - English (United States)
|
|
348
|
+
- `bn-BD` - Bangla (Bangladesh)
|
|
349
|
+
- `fr-FR` - French (France)
|
|
350
|
+
- `es-ES` - Spanish (Spain)
|
|
351
|
+
- Custom locales as configured in your CMS
|
|
352
|
+
|
|
353
|
+
## Requirements
|
|
354
|
+
|
|
355
|
+
- Node.js 18+ (for native fetch support)
|
|
356
|
+
- TypeScript 5.0+ (for development)
|
|
357
|
+
|
|
358
|
+
## License
|
|
359
|
+
|
|
360
|
+
MIT
|
|
361
|
+
|
|
362
|
+
## Support
|
|
363
|
+
|
|
364
|
+
For issues and questions, please visit the [GitHub repository](https://github.com/MyBeeInovationLabs/mybe-cms).
|
package/package.json
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@mybe/sdk",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"main": "./dist/index.js",
|
|
6
|
+
"types": "./dist/index.d.ts",
|
|
7
|
+
"exports": {
|
|
8
|
+
".": {
|
|
9
|
+
"types": "./dist/index.d.ts",
|
|
10
|
+
"default": "./dist/index.js"
|
|
11
|
+
}
|
|
12
|
+
},
|
|
13
|
+
"scripts": {
|
|
14
|
+
"build": "tsc",
|
|
15
|
+
"dev": "tsc --watch",
|
|
16
|
+
"typecheck": "tsc --noEmit",
|
|
17
|
+
"test": "npm run build && npx tsx test.ts",
|
|
18
|
+
"prepublishOnly": "npm run build",
|
|
19
|
+
"prepack": "npm run build"
|
|
20
|
+
},
|
|
21
|
+
"dependencies": {},
|
|
22
|
+
"devDependencies": {
|
|
23
|
+
"typescript": "^5.9.2"
|
|
24
|
+
}
|
|
25
|
+
}
|