@bernierllc/contentful-cma-client 1.0.2
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/.eslintrc.cjs +34 -0
- package/README.md +441 -0
- package/dist/ContentfulCMAClient.d.ts +119 -0
- package/dist/ContentfulCMAClient.js +538 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +12 -0
- package/dist/types.d.ts +39 -0
- package/dist/types.js +9 -0
- package/jest.config.cjs +31 -0
- package/package.json +44 -0
- package/src/ContentfulCMAClient.ts +694 -0
- package/src/__tests__/ContentfulCMAClient.test.ts +841 -0
- package/src/index.ts +16 -0
- package/src/types.ts +51 -0
- package/tsconfig.json +29 -0
package/.eslintrc.cjs
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Copyright (c) 2025 Bernier LLC
|
|
3
|
+
|
|
4
|
+
This file is licensed to the client under a limited-use license.
|
|
5
|
+
The client may use and modify this code *only within the scope of the project it was delivered for*.
|
|
6
|
+
Redistribution or use in other products or commercial offerings is not permitted without written consent from Bernier LLC.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
module.exports = {
|
|
10
|
+
root: true,
|
|
11
|
+
parser: '@typescript-eslint/parser',
|
|
12
|
+
parserOptions: {
|
|
13
|
+
ecmaVersion: 2020,
|
|
14
|
+
sourceType: 'module',
|
|
15
|
+
project: './tsconfig.json',
|
|
16
|
+
tsconfigRootDir: __dirname
|
|
17
|
+
},
|
|
18
|
+
plugins: ['@typescript-eslint'],
|
|
19
|
+
extends: [
|
|
20
|
+
'eslint:recommended',
|
|
21
|
+
'plugin:@typescript-eslint/recommended',
|
|
22
|
+
'plugin:@typescript-eslint/recommended-requiring-type-checking'
|
|
23
|
+
],
|
|
24
|
+
rules: {
|
|
25
|
+
'@typescript-eslint/no-explicit-any': 'warn',
|
|
26
|
+
'@typescript-eslint/no-unsafe-assignment': 'warn',
|
|
27
|
+
'@typescript-eslint/no-unsafe-argument': 'warn',
|
|
28
|
+
'@typescript-eslint/explicit-module-boundary-types': 'off',
|
|
29
|
+
'@typescript-eslint/no-unused-vars': ['error', { argsIgnorePattern: '^_' }],
|
|
30
|
+
'@typescript-eslint/no-floating-promises': 'error',
|
|
31
|
+
'@typescript-eslint/no-misused-promises': 'error'
|
|
32
|
+
},
|
|
33
|
+
ignorePatterns: ['dist', 'node_modules', '*.cjs', '**/__tests__/**', '**/*.test.ts']
|
|
34
|
+
};
|
package/README.md
ADDED
|
@@ -0,0 +1,441 @@
|
|
|
1
|
+
# @bernierllc/contentful-cma-client
|
|
2
|
+
|
|
3
|
+
Thin wrapper around the official `contentful-management` npm package, providing consistent error handling, logging, and typed interfaces for all CMA (Content Management API) operations.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @bernierllc/contentful-cma-client
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Features
|
|
12
|
+
|
|
13
|
+
- ✅ **Typed Interfaces** - Full TypeScript support using `@bernierllc/contentful-types`
|
|
14
|
+
- ✅ **Comprehensive CRUD** - Entries, Assets, Content Types operations
|
|
15
|
+
- ✅ **Bulk Operations** - Batch create, update, publish, delete
|
|
16
|
+
- ✅ **Automatic Pagination** - `getAllEntries()` and `getAllAssets()` handle pagination automatically
|
|
17
|
+
- ✅ **Consistent Logging** - Integrated with `@bernierllc/logger`
|
|
18
|
+
- ✅ **Error Handling** - Graceful error handling with detailed logging
|
|
19
|
+
- ✅ **Publishing Workflow** - Publish, unpublish, archive, unarchive support
|
|
20
|
+
|
|
21
|
+
## Usage
|
|
22
|
+
|
|
23
|
+
### Basic Setup
|
|
24
|
+
|
|
25
|
+
```typescript
|
|
26
|
+
import { ContentfulCMAClient } from '@bernierllc/contentful-cma-client';
|
|
27
|
+
|
|
28
|
+
const client = new ContentfulCMAClient({
|
|
29
|
+
accessToken: 'your-cma-token',
|
|
30
|
+
spaceId: 'your-space-id',
|
|
31
|
+
environmentId: 'master' // optional, defaults to 'master'
|
|
32
|
+
});
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
### Entry Operations
|
|
36
|
+
|
|
37
|
+
#### Get Entry
|
|
38
|
+
|
|
39
|
+
```typescript
|
|
40
|
+
const entry = await client.getEntry<BlogPost>('entry-id');
|
|
41
|
+
console.log(entry.fields.title);
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
#### Get Entries with Query
|
|
45
|
+
|
|
46
|
+
```typescript
|
|
47
|
+
const entries = await client.getEntries<BlogPost>({
|
|
48
|
+
content_type: 'blogPost',
|
|
49
|
+
limit: 10,
|
|
50
|
+
skip: 0
|
|
51
|
+
});
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
#### Get All Entries (with automatic pagination)
|
|
55
|
+
|
|
56
|
+
```typescript
|
|
57
|
+
const allEntries = await client.getAllEntries<BlogPost>({
|
|
58
|
+
content_type: 'blogPost'
|
|
59
|
+
});
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
#### Create Entry
|
|
63
|
+
|
|
64
|
+
```typescript
|
|
65
|
+
const newEntry = await client.createEntry<BlogPost>(
|
|
66
|
+
'blogPost',
|
|
67
|
+
{
|
|
68
|
+
title: { 'en-US': 'My Blog Post' },
|
|
69
|
+
body: { 'en-US': 'Content here...' }
|
|
70
|
+
}
|
|
71
|
+
);
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
#### Create Entry with Custom ID
|
|
75
|
+
|
|
76
|
+
```typescript
|
|
77
|
+
const newEntry = await client.createEntry<BlogPost>(
|
|
78
|
+
'blogPost',
|
|
79
|
+
{
|
|
80
|
+
title: { 'en-US': 'My Blog Post' }
|
|
81
|
+
},
|
|
82
|
+
{ entryId: 'custom-entry-id' }
|
|
83
|
+
);
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
#### Update Entry
|
|
87
|
+
|
|
88
|
+
```typescript
|
|
89
|
+
const updatedEntry = await client.updateEntry<BlogPost>(
|
|
90
|
+
'entry-id',
|
|
91
|
+
{
|
|
92
|
+
title: { 'en-US': 'Updated Title' }
|
|
93
|
+
},
|
|
94
|
+
2 // version number
|
|
95
|
+
);
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
#### Publish Entry
|
|
99
|
+
|
|
100
|
+
```typescript
|
|
101
|
+
const publishedEntry = await client.publishEntry('entry-id', 2);
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
#### Unpublish Entry
|
|
105
|
+
|
|
106
|
+
```typescript
|
|
107
|
+
await client.unpublishEntry('entry-id');
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
#### Archive Entry
|
|
111
|
+
|
|
112
|
+
```typescript
|
|
113
|
+
await client.archiveEntry('entry-id', 2);
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
#### Unarchive Entry
|
|
117
|
+
|
|
118
|
+
```typescript
|
|
119
|
+
await client.unarchiveEntry('entry-id');
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
#### Delete Entry
|
|
123
|
+
|
|
124
|
+
```typescript
|
|
125
|
+
await client.deleteEntry('entry-id');
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
### Asset Operations
|
|
129
|
+
|
|
130
|
+
#### Get Asset
|
|
131
|
+
|
|
132
|
+
```typescript
|
|
133
|
+
const asset = await client.getAsset('asset-id');
|
|
134
|
+
console.log(asset.fields.file['en-US'].url);
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
#### Create Asset
|
|
138
|
+
|
|
139
|
+
```typescript
|
|
140
|
+
const newAsset = await client.createAsset({
|
|
141
|
+
title: { 'en-US': 'My Image' },
|
|
142
|
+
file: {
|
|
143
|
+
'en-US': {
|
|
144
|
+
url: 'https://example.com/image.jpg',
|
|
145
|
+
fileName: 'image.jpg',
|
|
146
|
+
contentType: 'image/jpeg',
|
|
147
|
+
details: { size: 12345 }
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
});
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
#### Process Asset (after upload)
|
|
154
|
+
|
|
155
|
+
```typescript
|
|
156
|
+
await client.processAsset('asset-id', 1, 'en-US');
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
#### Publish Asset
|
|
160
|
+
|
|
161
|
+
```typescript
|
|
162
|
+
const publishedAsset = await client.publishAsset('asset-id', 2);
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
#### Delete Asset
|
|
166
|
+
|
|
167
|
+
```typescript
|
|
168
|
+
await client.deleteAsset('asset-id');
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
### Content Type Operations
|
|
172
|
+
|
|
173
|
+
#### Get Content Type
|
|
174
|
+
|
|
175
|
+
```typescript
|
|
176
|
+
const contentType = await client.getContentType('blogPost');
|
|
177
|
+
console.log(contentType.fields);
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
#### Get All Content Types
|
|
181
|
+
|
|
182
|
+
```typescript
|
|
183
|
+
const contentTypes = await client.getContentTypes();
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
### Bulk Operations
|
|
187
|
+
|
|
188
|
+
#### Bulk Create Entries
|
|
189
|
+
|
|
190
|
+
```typescript
|
|
191
|
+
const result = await client.bulkCreateEntries([
|
|
192
|
+
{ contentTypeId: 'blogPost', fields: { title: { 'en-US': 'Post 1' } } },
|
|
193
|
+
{ contentTypeId: 'blogPost', fields: { title: { 'en-US': 'Post 2' } } }
|
|
194
|
+
]);
|
|
195
|
+
|
|
196
|
+
console.log(`Created: ${result.successful.length}`);
|
|
197
|
+
console.log(`Failed: ${result.failed.length}`);
|
|
198
|
+
|
|
199
|
+
// Handle failures
|
|
200
|
+
result.failed.forEach(failure => {
|
|
201
|
+
console.error(`Failed to create:`, failure.error);
|
|
202
|
+
});
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
#### Bulk Publish Entries
|
|
206
|
+
|
|
207
|
+
```typescript
|
|
208
|
+
const result = await client.bulkPublishEntries([
|
|
209
|
+
{ entryId: 'entry-1', version: 2 },
|
|
210
|
+
{ entryId: 'entry-2', version: 1 }
|
|
211
|
+
]);
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
#### Bulk Delete Entries
|
|
215
|
+
|
|
216
|
+
```typescript
|
|
217
|
+
const result = await client.bulkDeleteEntries([
|
|
218
|
+
'entry-1',
|
|
219
|
+
'entry-2',
|
|
220
|
+
'entry-3'
|
|
221
|
+
]);
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
## Configuration Options
|
|
225
|
+
|
|
226
|
+
```typescript
|
|
227
|
+
interface ContentfulCMAConfig {
|
|
228
|
+
accessToken: string; // Required: CMA access token
|
|
229
|
+
spaceId: string; // Required: Contentful space ID
|
|
230
|
+
environmentId?: string; // Optional: defaults to 'master'
|
|
231
|
+
host?: string; // Optional: defaults to 'api.contentful.com'
|
|
232
|
+
retryOnError?: boolean; // Optional: defaults to true
|
|
233
|
+
timeout?: number; // Optional: defaults to 30000ms
|
|
234
|
+
}
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
## Query Options
|
|
238
|
+
|
|
239
|
+
```typescript
|
|
240
|
+
interface CMAQueryOptions {
|
|
241
|
+
skip?: number; // Number of items to skip
|
|
242
|
+
limit?: number; // Number of items to return
|
|
243
|
+
order?: string; // Sort order (e.g., '-sys.createdAt')
|
|
244
|
+
locale?: string; // Locale filter
|
|
245
|
+
content_type?: string; // Content type filter
|
|
246
|
+
[key: string]: any; // Additional Contentful query params
|
|
247
|
+
}
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
## Type Safety
|
|
251
|
+
|
|
252
|
+
This package uses types from `@bernierllc/contentful-types`:
|
|
253
|
+
|
|
254
|
+
```typescript
|
|
255
|
+
import type {
|
|
256
|
+
ContentfulEntry,
|
|
257
|
+
ContentfulAsset,
|
|
258
|
+
ContentfulContentType
|
|
259
|
+
} from '@bernierllc/contentful-types';
|
|
260
|
+
|
|
261
|
+
interface BlogPost {
|
|
262
|
+
title: { [locale: string]: string };
|
|
263
|
+
body: { [locale: string]: string };
|
|
264
|
+
author: { [locale: string]: ContentfulLink<'Entry'> };
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
const entry = await client.getEntry<BlogPost>('entry-id');
|
|
268
|
+
// entry.fields is typed as BlogPost
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
## Error Handling
|
|
272
|
+
|
|
273
|
+
All methods log errors and throw them for you to handle:
|
|
274
|
+
|
|
275
|
+
```typescript
|
|
276
|
+
try {
|
|
277
|
+
const entry = await client.getEntry('non-existent-id');
|
|
278
|
+
} catch (error) {
|
|
279
|
+
console.error('Failed to get entry:', error);
|
|
280
|
+
}
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
Bulk operations return both successful and failed operations:
|
|
284
|
+
|
|
285
|
+
```typescript
|
|
286
|
+
const result = await client.bulkCreateEntries(entries);
|
|
287
|
+
|
|
288
|
+
// Process successful
|
|
289
|
+
result.successful.forEach(entry => {
|
|
290
|
+
console.log('Created:', entry.sys.id);
|
|
291
|
+
});
|
|
292
|
+
|
|
293
|
+
// Handle failures
|
|
294
|
+
result.failed.forEach(({ item, error }) => {
|
|
295
|
+
console.error('Failed to create:', error);
|
|
296
|
+
});
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
## Logging
|
|
300
|
+
|
|
301
|
+
This package uses `@bernierllc/logger` for consistent logging:
|
|
302
|
+
|
|
303
|
+
- **info**: Operation completions, initialization
|
|
304
|
+
- **debug**: Request/response details, operation start
|
|
305
|
+
- **error**: Failures with context
|
|
306
|
+
|
|
307
|
+
All logs include context (spaceId, environmentId, operation details).
|
|
308
|
+
|
|
309
|
+
## MECE Principles
|
|
310
|
+
|
|
311
|
+
This package follows MECE (Mutually Exclusive, Collectively Exhaustive) architecture:
|
|
312
|
+
|
|
313
|
+
**Includes:**
|
|
314
|
+
- ✅ Content Management API operations (CMA)
|
|
315
|
+
- ✅ CRUD for Entries, Assets, Content Types
|
|
316
|
+
- ✅ Publishing workflow operations
|
|
317
|
+
- ✅ Bulk operations
|
|
318
|
+
|
|
319
|
+
**Excludes:**
|
|
320
|
+
- ❌ Content Delivery API (use `@bernierllc/contentful-cda-client`)
|
|
321
|
+
- ❌ GraphQL queries (use `@bernierllc/contentful-graphql-client`)
|
|
322
|
+
- ❌ Webhook handling (use `@bernierllc/contentful-webhook-handler`)
|
|
323
|
+
- ❌ OAuth/Auth management (use `@bernierllc/contentful-auth`)
|
|
324
|
+
|
|
325
|
+
## API
|
|
326
|
+
|
|
327
|
+
### ContentfulCMAClient
|
|
328
|
+
|
|
329
|
+
Main client class for interacting with Contentful Content Management API.
|
|
330
|
+
|
|
331
|
+
**Constructor:**
|
|
332
|
+
```typescript
|
|
333
|
+
new ContentfulCMAClient(config: ContentfulCMAConfig)
|
|
334
|
+
```
|
|
335
|
+
|
|
336
|
+
**Entry Methods:**
|
|
337
|
+
- `getEntry<T>(entryId: string): Promise<ContentfulEntry<T>>`
|
|
338
|
+
- `getEntries<T>(query?: CMAQueryOptions): Promise<ContentfulCollection<ContentfulEntry<T>>>`
|
|
339
|
+
- `getAllEntries<T>(query?: CMAQueryOptions): Promise<ContentfulEntry<T>[]>`
|
|
340
|
+
- `createEntry<T>(contentTypeId: string, fields: T, options?: CreateEntryOptions): Promise<ContentfulEntry<T>>`
|
|
341
|
+
- `updateEntry<T>(entryId: string, fields: Partial<T>, version: number): Promise<ContentfulEntry<T>>`
|
|
342
|
+
- `publishEntry(entryId: string, version: number): Promise<ContentfulEntry>`
|
|
343
|
+
- `unpublishEntry(entryId: string): Promise<ContentfulEntry>`
|
|
344
|
+
- `archiveEntry(entryId: string, version: number): Promise<ContentfulEntry>`
|
|
345
|
+
- `unarchiveEntry(entryId: string): Promise<ContentfulEntry>`
|
|
346
|
+
- `deleteEntry(entryId: string): Promise<void>`
|
|
347
|
+
|
|
348
|
+
**Asset Methods:**
|
|
349
|
+
- `getAsset(assetId: string): Promise<ContentfulAsset>`
|
|
350
|
+
- `getAssets(query?: CMAQueryOptions): Promise<ContentfulCollection<ContentfulAsset>>`
|
|
351
|
+
- `getAllAssets(query?: CMAQueryOptions): Promise<ContentfulAsset[]>`
|
|
352
|
+
- `createAsset(fields: AssetFields, options?: CreateAssetOptions): Promise<ContentfulAsset>`
|
|
353
|
+
- `processAsset(assetId: string, version: number, locale: string): Promise<ContentfulAsset>`
|
|
354
|
+
- `publishAsset(assetId: string, version: number): Promise<ContentfulAsset>`
|
|
355
|
+
- `deleteAsset(assetId: string): Promise<void>`
|
|
356
|
+
|
|
357
|
+
**Content Type Methods:**
|
|
358
|
+
- `getContentType(contentTypeId: string): Promise<ContentfulContentType>`
|
|
359
|
+
- `getContentTypes(): Promise<ContentfulCollection<ContentfulContentType>>`
|
|
360
|
+
|
|
361
|
+
**Bulk Methods:**
|
|
362
|
+
- `bulkCreateEntries<T>(entries: BulkCreateEntry<T>[]): Promise<BulkOperationResult<ContentfulEntry<T>>>`
|
|
363
|
+
- `bulkPublishEntries(entries: BulkPublishEntry[]): Promise<BulkOperationResult<ContentfulEntry>>`
|
|
364
|
+
- `bulkDeleteEntries(entryIds: string[]): Promise<BulkOperationResult<void>>`
|
|
365
|
+
- `bulkCreateAssets(assets: AssetFields[]): Promise<BulkOperationResult<ContentfulAsset>>`
|
|
366
|
+
|
|
367
|
+
## Integrations
|
|
368
|
+
|
|
369
|
+
### Logger Integration
|
|
370
|
+
|
|
371
|
+
This package integrates with `@bernierllc/logger` for consistent logging across all operations. The logger is initialized automatically and provides:
|
|
372
|
+
|
|
373
|
+
- **Structured logging** with operation context (spaceId, environmentId, entryId)
|
|
374
|
+
- **Log levels**: info, debug, error
|
|
375
|
+
- **Automatic error tracking** with full error details
|
|
376
|
+
|
|
377
|
+
```typescript
|
|
378
|
+
// Logger is automatically initialized
|
|
379
|
+
const client = new ContentfulCMAClient(config);
|
|
380
|
+
|
|
381
|
+
// Logs are emitted for all operations
|
|
382
|
+
await client.getEntry('entry-id');
|
|
383
|
+
// Logs: [INFO] Fetching entry entry-id from space xxx-space-id
|
|
384
|
+
```
|
|
385
|
+
|
|
386
|
+
### NeverHub Integration
|
|
387
|
+
|
|
388
|
+
This package does **not** require NeverHub integration as it is a core client library. However, services using this client can integrate with `@bernierllc/neverhub-adapter` for event tracking:
|
|
389
|
+
|
|
390
|
+
```typescript
|
|
391
|
+
import { ContentfulCMAClient } from '@bernierllc/contentful-cma-client';
|
|
392
|
+
import { NeverHubAdapter } from '@bernierllc/neverhub-adapter';
|
|
393
|
+
|
|
394
|
+
class ContentfulService {
|
|
395
|
+
private client: ContentfulCMAClient;
|
|
396
|
+
private neverhub?: NeverHubAdapter;
|
|
397
|
+
|
|
398
|
+
async initialize() {
|
|
399
|
+
this.client = new ContentfulCMAClient(config);
|
|
400
|
+
|
|
401
|
+
// Optional NeverHub integration for event tracking
|
|
402
|
+
if (await NeverHubAdapter.detect()) {
|
|
403
|
+
this.neverhub = new NeverHubAdapter();
|
|
404
|
+
await this.neverhub.register({
|
|
405
|
+
type: 'contentful-service',
|
|
406
|
+
capabilities: ['content-management']
|
|
407
|
+
});
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
async createEntry<T>(contentTypeId: string, fields: T) {
|
|
412
|
+
const entry = await this.client.createEntry(contentTypeId, fields);
|
|
413
|
+
|
|
414
|
+
// Track event in NeverHub (if available)
|
|
415
|
+
if (this.neverhub) {
|
|
416
|
+
await this.neverhub.logEvent({
|
|
417
|
+
type: 'content.created',
|
|
418
|
+
data: { entryId: entry.sys.id, contentType: contentTypeId }
|
|
419
|
+
});
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
return entry;
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
```
|
|
426
|
+
|
|
427
|
+
**Integration Status:**
|
|
428
|
+
- ✅ Logger integration: Required (built-in)
|
|
429
|
+
- ⚪ NeverHub integration: Optional (consumer responsibility)
|
|
430
|
+
- ✅ Graceful degradation: Works standalone without external services
|
|
431
|
+
|
|
432
|
+
## Related Packages
|
|
433
|
+
|
|
434
|
+
- [@bernierllc/contentful-types](../contentful-types) - TypeScript types
|
|
435
|
+
- [@bernierllc/contentful-cda-client](../contentful-cda-client) - Content Delivery API
|
|
436
|
+
- [@bernierllc/contentful-graphql-client](../contentful-graphql-client) - GraphQL API
|
|
437
|
+
- [@bernierllc/contentful-gateway-service](../../service/contentful-gateway-service) - Unified gateway
|
|
438
|
+
|
|
439
|
+
## License
|
|
440
|
+
|
|
441
|
+
Copyright (c) 2025 Bernier LLC. See LICENSE.md for details.
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import { ContentfulEntry, ContentfulAsset, ContentfulContentType, ContentfulCMAConfig } from '@bernierllc/contentful-types';
|
|
2
|
+
import { CMAQueryOptions, CMAEntryCreateOptions, CMAEntryUpdateOptions, CMAAssetCreateOptions, CMABulkOperationResult } from './types';
|
|
3
|
+
export declare class ContentfulCMAClient {
|
|
4
|
+
private client;
|
|
5
|
+
private logger;
|
|
6
|
+
private config;
|
|
7
|
+
constructor(config: ContentfulCMAConfig);
|
|
8
|
+
/**
|
|
9
|
+
* Get entry by ID
|
|
10
|
+
*/
|
|
11
|
+
getEntry<T = Record<string, unknown>>(entryId: string): Promise<ContentfulEntry<T>>;
|
|
12
|
+
/**
|
|
13
|
+
* Get multiple entries with optional query parameters
|
|
14
|
+
*/
|
|
15
|
+
getEntries<T = Record<string, unknown>>(query?: CMAQueryOptions): Promise<ContentfulEntry<T>[]>;
|
|
16
|
+
/**
|
|
17
|
+
* Get all entries with automatic pagination
|
|
18
|
+
*/
|
|
19
|
+
getAllEntries<T = Record<string, unknown>>(query?: Omit<CMAQueryOptions, 'skip' | 'limit'>): Promise<ContentfulEntry<T>[]>;
|
|
20
|
+
/**
|
|
21
|
+
* Create entry
|
|
22
|
+
*/
|
|
23
|
+
createEntry<T = Record<string, unknown>>(contentTypeId: string, fields: T, options?: CMAEntryCreateOptions): Promise<ContentfulEntry<T>>;
|
|
24
|
+
/**
|
|
25
|
+
* Update entry
|
|
26
|
+
*/
|
|
27
|
+
updateEntry<T = Record<string, unknown>>(entryId: string, fields: T, version: number, _options?: CMAEntryUpdateOptions): Promise<ContentfulEntry<T>>;
|
|
28
|
+
/**
|
|
29
|
+
* Publish entry
|
|
30
|
+
*/
|
|
31
|
+
publishEntry(entryId: string, version: number): Promise<ContentfulEntry>;
|
|
32
|
+
/**
|
|
33
|
+
* Unpublish entry
|
|
34
|
+
*/
|
|
35
|
+
unpublishEntry(entryId: string): Promise<ContentfulEntry>;
|
|
36
|
+
/**
|
|
37
|
+
* Archive entry
|
|
38
|
+
*/
|
|
39
|
+
archiveEntry(entryId: string, version: number): Promise<ContentfulEntry>;
|
|
40
|
+
/**
|
|
41
|
+
* Unarchive entry
|
|
42
|
+
*/
|
|
43
|
+
unarchiveEntry(entryId: string): Promise<ContentfulEntry>;
|
|
44
|
+
/**
|
|
45
|
+
* Delete entry
|
|
46
|
+
*/
|
|
47
|
+
deleteEntry(entryId: string): Promise<void>;
|
|
48
|
+
/**
|
|
49
|
+
* Get asset by ID
|
|
50
|
+
*/
|
|
51
|
+
getAsset(assetId: string): Promise<ContentfulAsset>;
|
|
52
|
+
/**
|
|
53
|
+
* Get multiple assets with optional query parameters
|
|
54
|
+
*/
|
|
55
|
+
getAssets(query?: CMAQueryOptions): Promise<ContentfulAsset[]>;
|
|
56
|
+
/**
|
|
57
|
+
* Get all assets with automatic pagination
|
|
58
|
+
*/
|
|
59
|
+
getAllAssets(query?: Omit<CMAQueryOptions, 'skip' | 'limit'>): Promise<ContentfulAsset[]>;
|
|
60
|
+
/**
|
|
61
|
+
* Create asset
|
|
62
|
+
*/
|
|
63
|
+
createAsset(fields: Record<string, unknown>, options?: CMAAssetCreateOptions): Promise<ContentfulAsset>;
|
|
64
|
+
/**
|
|
65
|
+
* Process asset (for uploaded files)
|
|
66
|
+
*/
|
|
67
|
+
processAsset(assetId: string, version: number, locale?: string): Promise<ContentfulAsset>;
|
|
68
|
+
/**
|
|
69
|
+
* Publish asset
|
|
70
|
+
*/
|
|
71
|
+
publishAsset(assetId: string, version: number): Promise<ContentfulAsset>;
|
|
72
|
+
/**
|
|
73
|
+
* Unpublish asset
|
|
74
|
+
*/
|
|
75
|
+
unpublishAsset(assetId: string): Promise<ContentfulAsset>;
|
|
76
|
+
/**
|
|
77
|
+
* Delete asset
|
|
78
|
+
*/
|
|
79
|
+
deleteAsset(assetId: string): Promise<void>;
|
|
80
|
+
/**
|
|
81
|
+
* Get content type by ID
|
|
82
|
+
*/
|
|
83
|
+
getContentType(contentTypeId: string): Promise<ContentfulContentType>;
|
|
84
|
+
/**
|
|
85
|
+
* Get all content types
|
|
86
|
+
*/
|
|
87
|
+
getContentTypes(query?: CMAQueryOptions): Promise<ContentfulContentType[]>;
|
|
88
|
+
/**
|
|
89
|
+
* Bulk create entries
|
|
90
|
+
*/
|
|
91
|
+
bulkCreateEntries<T = Record<string, unknown>>(entries: Array<{
|
|
92
|
+
contentTypeId: string;
|
|
93
|
+
fields: T;
|
|
94
|
+
entryId?: string;
|
|
95
|
+
}>): Promise<CMABulkOperationResult<ContentfulEntry<T>>>;
|
|
96
|
+
/**
|
|
97
|
+
* Bulk delete entries
|
|
98
|
+
*/
|
|
99
|
+
bulkDeleteEntries(entryIds: string[]): Promise<CMABulkOperationResult<string>>;
|
|
100
|
+
/**
|
|
101
|
+
* Bulk publish entries
|
|
102
|
+
*/
|
|
103
|
+
bulkPublishEntries(entries: Array<{
|
|
104
|
+
entryId: string;
|
|
105
|
+
version: number;
|
|
106
|
+
}>): Promise<CMABulkOperationResult<ContentfulEntry>>;
|
|
107
|
+
/**
|
|
108
|
+
* Helper method to extract error message
|
|
109
|
+
*/
|
|
110
|
+
private getErrorMessage;
|
|
111
|
+
/**
|
|
112
|
+
* Get current space ID
|
|
113
|
+
*/
|
|
114
|
+
getSpaceId(): string;
|
|
115
|
+
/**
|
|
116
|
+
* Get current environment ID
|
|
117
|
+
*/
|
|
118
|
+
getEnvironmentId(): string;
|
|
119
|
+
}
|