@agility/management-sdk 0.1.38 → 0.1.39
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/.github/workflows/npm-publish.yml +61 -0
- package/README.md +396 -396
- package/dist/models/exception.d.ts +4 -0
- package/dist/models/exception.js +17 -1
- package/docs/asset-methods.md +381 -381
- package/docs/auth-component.md +360 -360
- package/docs/auth.md +593 -593
- package/docs/batch-methods.md +243 -243
- package/docs/cicd.md +606 -606
- package/docs/container-methods.md +267 -267
- package/docs/content-methods.md +491 -491
- package/docs/instance-methods.md +185 -185
- package/docs/instance-user-methods.md +230 -230
- package/docs/model-methods.md +433 -433
- package/docs/multi-instance-operations.md +191 -191
- package/docs/page-methods.md +737 -737
- package/docs/server-user-methods.md +279 -279
- package/docs/webhook-methods.md +451 -451
- package/license.txt +20 -20
- package/package.json +42 -41
- package/tsconfig.json +14 -14
package/docs/model-methods.md
CHANGED
|
@@ -1,434 +1,434 @@
|
|
|
1
|
-
# Agility CMS & Management API TypeScript SDK
|
|
2
|
-
|
|
3
|
-
## ModelMethods
|
|
4
|
-
|
|
5
|
-
This class provides comprehensive content model management operations for Agility CMS. Content models define the structure and fields for content items, acting as templates that determine what data can be stored and how it's organized.
|
|
6
|
-
|
|
7
|
-
**Important Notes:**
|
|
8
|
-
- Content models define the schema for content items
|
|
9
|
-
- Models contain field definitions that specify data types, validation rules, and UI controls
|
|
10
|
-
- Changes to models may affect existing content items using those models
|
|
11
|
-
- Models are used by containers to organize and validate content
|
|
12
|
-
- Model reference names must be unique within the instance
|
|
13
|
-
|
|
14
|
-
### Function List
|
|
15
|
-
- [getContentModel](#getcontentmodel) - Retrieves a specific content model by ID
|
|
16
|
-
- [getModelByReferenceName](#getmodelbyreferencename) - Retrieves a model by reference name
|
|
17
|
-
- [getContentModules](#getcontentmodules) - Retrieves list of all content modules
|
|
18
|
-
- [getPageModules](#getpagemodules) - Retrieves list of all page modules
|
|
19
|
-
- [saveModel](#savemodel) - Creates or updates a content model
|
|
20
|
-
- [deleteModel](#deletemodel) - Deletes a content model by ID
|
|
21
|
-
|
|
22
|
-
---
|
|
23
|
-
|
|
24
|
-
### getContentModel
|
|
25
|
-
|
|
26
|
-
Retrieves a specific content model by its unique ID.
|
|
27
|
-
|
|
28
|
-
| Parameter | Type | Required | Description |
|
|
29
|
-
|-----------|------|----------|-------------|
|
|
30
|
-
| `id` | `number` | Yes | The model ID to retrieve |
|
|
31
|
-
| `guid` | `string` | Yes | Current website GUID |
|
|
32
|
-
|
|
33
|
-
**Returns:** `Model` - Complete model object with field definitions
|
|
34
|
-
|
|
35
|
-
**Usage Example:**
|
|
36
|
-
```typescript
|
|
37
|
-
const model = await apiClient.modelMethods.getContentModel(123, guid);
|
|
38
|
-
console.log('Model name:', model.displayName);
|
|
39
|
-
console.log('Reference name:', model.referenceName);
|
|
40
|
-
console.log('Description:', model.description);
|
|
41
|
-
console.log('Field count:', model.fields.length);
|
|
42
|
-
|
|
43
|
-
// Display field information
|
|
44
|
-
model.fields.forEach(field => {
|
|
45
|
-
console.log(`Field: ${field.name} (${field.type})`);
|
|
46
|
-
console.log(` Label: ${field.label}`);
|
|
47
|
-
console.log(` Required: ${field.isRequired}`);
|
|
48
|
-
console.log(` Default: ${field.defaultValue}`);
|
|
49
|
-
});
|
|
50
|
-
|
|
51
|
-
// Check if model is in use
|
|
52
|
-
if (model.isInUse) {
|
|
53
|
-
console.log('Model is currently being used by content items');
|
|
54
|
-
} else {
|
|
55
|
-
console.log('Model is not currently in use');
|
|
56
|
-
}
|
|
57
|
-
```
|
|
58
|
-
|
|
59
|
-
**Error Handling:**
|
|
60
|
-
- Throws `Exception` when model not found
|
|
61
|
-
|
|
62
|
-
### getModelByReferenceName
|
|
63
|
-
|
|
64
|
-
Retrieves a content model by its reference name. Returns null if the model doesn't exist.
|
|
65
|
-
|
|
66
|
-
| Parameter | Type | Required | Description |
|
|
67
|
-
|-----------|------|----------|-------------|
|
|
68
|
-
| `referenceName` | `string` | Yes | The reference name of the model |
|
|
69
|
-
| `guid` | `string` | Yes | Current website GUID |
|
|
70
|
-
|
|
71
|
-
**Returns:** `Model | null` - Model object or null if not found
|
|
72
|
-
|
|
73
|
-
**Usage Example:**
|
|
74
|
-
```typescript
|
|
75
|
-
const model = await apiClient.modelMethods.getModelByReferenceName('blog-post', guid);
|
|
76
|
-
if (model) {
|
|
77
|
-
console.log('Model found:', model.displayName);
|
|
78
|
-
console.log('Model ID:', model.id);
|
|
79
|
-
|
|
80
|
-
// Get specific field by name
|
|
81
|
-
const titleField = model.fields.find(f => f.name === 'title');
|
|
82
|
-
if (titleField) {
|
|
83
|
-
console.log('Title field type:', titleField.type);
|
|
84
|
-
console.log('Title field required:', titleField.isRequired);
|
|
85
|
-
}
|
|
86
|
-
} else {
|
|
87
|
-
console.log('Model not found');
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
// Use in validation
|
|
91
|
-
const validateModelExists = async (referenceName) => {
|
|
92
|
-
const model = await apiClient.modelMethods.getModelByReferenceName(referenceName, guid);
|
|
93
|
-
return model !== null;
|
|
94
|
-
};
|
|
95
|
-
|
|
96
|
-
if (await validateModelExists('blog-post')) {
|
|
97
|
-
console.log('Blog post model is available');
|
|
98
|
-
}
|
|
99
|
-
```
|
|
100
|
-
|
|
101
|
-
**Error Handling:**
|
|
102
|
-
- Returns `null` for 404 errors (model not found)
|
|
103
|
-
- Throws `Exception` for other errors
|
|
104
|
-
|
|
105
|
-
### getContentModules
|
|
106
|
-
|
|
107
|
-
Retrieves a list of all content modules in the current website.
|
|
108
|
-
|
|
109
|
-
| Parameter | Type | Required | Description |
|
|
110
|
-
|-----------|------|----------|-------------|
|
|
111
|
-
| `includeDefaults` | `boolean` | Yes | Whether to include default modules |
|
|
112
|
-
| `guid` | `string` | Yes | Current website GUID |
|
|
113
|
-
| `includeModules` | `boolean` | No | Whether to include module details (default: false) |
|
|
114
|
-
|
|
115
|
-
**Returns:** `Model[]` - Array of all content modules
|
|
116
|
-
|
|
117
|
-
**Usage Example:**
|
|
118
|
-
```typescript
|
|
119
|
-
const models = await apiClient.modelMethods.getContentModules(true, guid);
|
|
120
|
-
console.log(`Total models: ${models.length}`);
|
|
121
|
-
|
|
122
|
-
// Display model summary
|
|
123
|
-
models.forEach(model => {
|
|
124
|
-
console.log(`Model: ${model.displayName} (${model.referenceName})`);
|
|
125
|
-
console.log(` Fields: ${model.fields.length}`);
|
|
126
|
-
console.log(` In Use: ${model.isInUse ? 'Yes' : 'No'}`);
|
|
127
|
-
console.log(` Created: ${model.createdDate}`);
|
|
128
|
-
});
|
|
129
|
-
|
|
130
|
-
// Filter models by usage
|
|
131
|
-
const modelsInUse = models.filter(m => m.isInUse);
|
|
132
|
-
const unusedModels = models.filter(m => !m.isInUse);
|
|
133
|
-
console.log(`Models in use: ${modelsInUse.length}`);
|
|
134
|
-
console.log(`Unused models: ${unusedModels.length}`);
|
|
135
|
-
|
|
136
|
-
// Group by field count
|
|
137
|
-
const modelsByFieldCount = models.reduce((acc, model) => {
|
|
138
|
-
const fieldCount = model.fields.length;
|
|
139
|
-
if (!acc[fieldCount]) acc[fieldCount] = [];
|
|
140
|
-
acc[fieldCount].push(model);
|
|
141
|
-
return acc;
|
|
142
|
-
}, {});
|
|
143
|
-
|
|
144
|
-
// Find models with specific fields
|
|
145
|
-
const modelsWithImageFields = models.filter(model =>
|
|
146
|
-
model.fields.some(field => field.type === 'image')
|
|
147
|
-
);
|
|
148
|
-
console.log(`Models with image fields: ${modelsWithImageFields.length}`);
|
|
149
|
-
|
|
150
|
-
// Create model dropdown options
|
|
151
|
-
const modelOptions = models.map(model => ({
|
|
152
|
-
value: model.id,
|
|
153
|
-
label: model.displayName,
|
|
154
|
-
referenceName: model.referenceName
|
|
155
|
-
}));
|
|
156
|
-
```
|
|
157
|
-
|
|
158
|
-
**Error Handling:**
|
|
159
|
-
- Throws `Exception` when retrieval fails
|
|
160
|
-
|
|
161
|
-
### getPageModules
|
|
162
|
-
|
|
163
|
-
Retrieves detailed field definitions for page modules.
|
|
164
|
-
|
|
165
|
-
| Parameter | Type | Required | Description |
|
|
166
|
-
|-----------|------|----------|-------------|
|
|
167
|
-
| `includeDefault` | `boolean` | Yes | Whether to include default modules |
|
|
168
|
-
| `guid` | `string` | Yes | Current website GUID |
|
|
169
|
-
|
|
170
|
-
**Returns:** `Model[]` - Array of page module definitions
|
|
171
|
-
|
|
172
|
-
**Usage Example:**
|
|
173
|
-
```typescript
|
|
174
|
-
const pageModules = await apiClient.modelMethods.getPageModules(true, guid);
|
|
175
|
-
console.log(`Model has ${fields.length} fields`);
|
|
176
|
-
|
|
177
|
-
// Display detailed field information
|
|
178
|
-
fields.forEach(field => {
|
|
179
|
-
console.log(`Field: ${field.name}`);
|
|
180
|
-
console.log(` Type: ${field.type}`);
|
|
181
|
-
console.log(` Label: ${field.label}`);
|
|
182
|
-
console.log(` Required: ${field.isRequired}`);
|
|
183
|
-
console.log(` Hidden: ${field.isHidden}`);
|
|
184
|
-
console.log(` Default: ${field.defaultValue}`);
|
|
185
|
-
console.log(` Help Text: ${field.helpText}`);
|
|
186
|
-
console.log(` Validation: ${field.validation}`);
|
|
187
|
-
console.log('---');
|
|
188
|
-
});
|
|
189
|
-
|
|
190
|
-
// Group fields by type
|
|
191
|
-
const fieldsByType = fields.reduce((acc, field) => {
|
|
192
|
-
if (!acc[field.type]) acc[field.type] = [];
|
|
193
|
-
acc[field.type].push(field);
|
|
194
|
-
return acc;
|
|
195
|
-
}, {});
|
|
196
|
-
|
|
197
|
-
console.log('Fields by type:');
|
|
198
|
-
Object.entries(fieldsByType).forEach(([type, typeFields]) => {
|
|
199
|
-
console.log(` ${type}: ${typeFields.length} fields`);
|
|
200
|
-
});
|
|
201
|
-
|
|
202
|
-
// Find required fields
|
|
203
|
-
const requiredFields = fields.filter(f => f.isRequired);
|
|
204
|
-
console.log(`Required fields: ${requiredFields.map(f => f.name).join(', ')}`);
|
|
205
|
-
|
|
206
|
-
// Create form validation rules
|
|
207
|
-
const validationRules = fields.reduce((acc, field) => {
|
|
208
|
-
acc[field.name] = {
|
|
209
|
-
required: field.isRequired,
|
|
210
|
-
type: field.type,
|
|
211
|
-
defaultValue: field.defaultValue,
|
|
212
|
-
validation: field.validation
|
|
213
|
-
};
|
|
214
|
-
return acc;
|
|
215
|
-
}, {});
|
|
216
|
-
```
|
|
217
|
-
|
|
218
|
-
**Field Types:**
|
|
219
|
-
Common field types include:
|
|
220
|
-
- `text`: Single line text input
|
|
221
|
-
- `textarea`: Multi-line text input
|
|
222
|
-
- `html`: Rich text/HTML editor
|
|
223
|
-
- `number`: Numeric input
|
|
224
|
-
- `boolean`: Checkbox/toggle
|
|
225
|
-
- `date`: Date picker
|
|
226
|
-
- `image`: Image upload
|
|
227
|
-
- `file`: File upload
|
|
228
|
-
- `url`: URL input
|
|
229
|
-
- `contentReference`: Reference to other content items
|
|
230
|
-
|
|
231
|
-
**Error Handling:**
|
|
232
|
-
- Throws `Exception` when model not found
|
|
233
|
-
|
|
234
|
-
### saveModel
|
|
235
|
-
|
|
236
|
-
Creates a new content model or updates an existing one.
|
|
237
|
-
|
|
238
|
-
| Parameter | Type | Required | Description |
|
|
239
|
-
|-----------|------|----------|-------------|
|
|
240
|
-
| `model` | `Model` | Yes | Model object to save |
|
|
241
|
-
| `guid` | `string` | Yes | Current website GUID |
|
|
242
|
-
|
|
243
|
-
**Returns:** `Model` - Saved model object with updated metadata
|
|
244
|
-
|
|
245
|
-
**Usage Example:**
|
|
246
|
-
```typescript
|
|
247
|
-
// Create a new model
|
|
248
|
-
const newModel = {
|
|
249
|
-
referenceName: 'product-review',
|
|
250
|
-
displayName: 'Product Review',
|
|
251
|
-
description: 'Customer product reviews and ratings',
|
|
252
|
-
fields: [
|
|
253
|
-
{
|
|
254
|
-
name: 'title',
|
|
255
|
-
label: 'Review Title',
|
|
256
|
-
type: 'text',
|
|
257
|
-
isRequired: true,
|
|
258
|
-
helpText: 'Enter a brief title for the review'
|
|
259
|
-
},
|
|
260
|
-
{
|
|
261
|
-
name: 'content',
|
|
262
|
-
label: 'Review Content',
|
|
263
|
-
type: 'textarea',
|
|
264
|
-
isRequired: true,
|
|
265
|
-
helpText: 'Enter the detailed review content'
|
|
266
|
-
},
|
|
267
|
-
{
|
|
268
|
-
name: 'rating',
|
|
269
|
-
label: 'Rating',
|
|
270
|
-
type: 'number',
|
|
271
|
-
isRequired: true,
|
|
272
|
-
validation: 'min:1,max:5',
|
|
273
|
-
helpText: 'Rate from 1 to 5 stars'
|
|
274
|
-
},
|
|
275
|
-
{
|
|
276
|
-
name: 'reviewerName',
|
|
277
|
-
label: 'Reviewer Name',
|
|
278
|
-
type: 'text',
|
|
279
|
-
isRequired: false,
|
|
280
|
-
helpText: 'Name of the person writing the review'
|
|
281
|
-
},
|
|
282
|
-
{
|
|
283
|
-
name: 'verified',
|
|
284
|
-
label: 'Verified Purchase',
|
|
285
|
-
type: 'boolean',
|
|
286
|
-
defaultValue: false,
|
|
287
|
-
helpText: 'Check if this is a verified purchase'
|
|
288
|
-
}
|
|
289
|
-
]
|
|
290
|
-
};
|
|
291
|
-
|
|
292
|
-
const savedModel = await apiClient.modelMethods.saveModel(newModel, guid);
|
|
293
|
-
console.log('Model created with ID:', savedModel.id);
|
|
294
|
-
|
|
295
|
-
// Update existing model
|
|
296
|
-
const existingModel = await apiClient.modelMethods.getModel(123, guid);
|
|
297
|
-
existingModel.displayName = 'Updated Display Name';
|
|
298
|
-
existingModel.description = 'Updated description';
|
|
299
|
-
|
|
300
|
-
// Add a new field
|
|
301
|
-
existingModel.fields.push({
|
|
302
|
-
name: 'newField',
|
|
303
|
-
label: 'New Field',
|
|
304
|
-
type: 'text',
|
|
305
|
-
isRequired: false,
|
|
306
|
-
helpText: 'This is a new field'
|
|
307
|
-
});
|
|
308
|
-
|
|
309
|
-
const updatedModel = await apiClient.modelMethods.saveModel(existingModel, guid);
|
|
310
|
-
console.log('Model updated:', updatedModel.displayName);
|
|
311
|
-
```
|
|
312
|
-
|
|
313
|
-
**Model Structure:**
|
|
314
|
-
```typescript
|
|
315
|
-
interface Model {
|
|
316
|
-
id?: number; // Auto-generated for new models
|
|
317
|
-
referenceName: string; // Unique identifier (required)
|
|
318
|
-
displayName: string; // Human-readable name (required)
|
|
319
|
-
description?: string; // Optional description
|
|
320
|
-
fields: ModelField[]; // Array of field definitions
|
|
321
|
-
isInUse?: boolean; // Read-only property
|
|
322
|
-
createdDate?: string; // Auto-generated
|
|
323
|
-
modifiedDate?: string; // Auto-generated
|
|
324
|
-
}
|
|
325
|
-
|
|
326
|
-
interface ModelField {
|
|
327
|
-
name: string; // Field name/identifier
|
|
328
|
-
label: string; // Display label
|
|
329
|
-
type: string; // Field type (text, number, etc.)
|
|
330
|
-
isRequired: boolean; // Whether field is required
|
|
331
|
-
isHidden?: boolean; // Whether field is hidden in UI
|
|
332
|
-
defaultValue?: any; // Default value
|
|
333
|
-
helpText?: string; // Help text for users
|
|
334
|
-
validation?: string; // Validation rules
|
|
335
|
-
options?: any[]; // Options for dropdown/select fields
|
|
336
|
-
}
|
|
337
|
-
```
|
|
338
|
-
|
|
339
|
-
**Error Handling:**
|
|
340
|
-
- Throws `Exception` when validation fails (duplicate reference name, invalid field types, etc.)
|
|
341
|
-
- Throws `Exception` when save operation fails
|
|
342
|
-
|
|
343
|
-
### deleteModel
|
|
344
|
-
|
|
345
|
-
Deletes a content model by its ID.
|
|
346
|
-
|
|
347
|
-
| Parameter | Type | Required | Description |
|
|
348
|
-
|-----------|------|----------|-------------|
|
|
349
|
-
| `modelID` | `number` | Yes | The model ID to delete |
|
|
350
|
-
| `guid` | `string` | Yes | Current website GUID |
|
|
351
|
-
|
|
352
|
-
**Returns:** `string` - Confirmation message of successful deletion
|
|
353
|
-
|
|
354
|
-
**Usage Example:**
|
|
355
|
-
```typescript
|
|
356
|
-
try {
|
|
357
|
-
const result = await apiClient.modelMethods.deleteModel(123, guid);
|
|
358
|
-
console.log(result); // "Model deleted successfully"
|
|
359
|
-
} catch (error) {
|
|
360
|
-
if (error.message.includes('in use')) {
|
|
361
|
-
console.log('Cannot delete model: currently in use by content items or containers');
|
|
362
|
-
// Handle by removing dependencies first
|
|
363
|
-
} else {
|
|
364
|
-
console.error('Failed to delete model:', error.message);
|
|
365
|
-
}
|
|
366
|
-
}
|
|
367
|
-
|
|
368
|
-
// Safe model deletion with checks
|
|
369
|
-
const safeDeleteModel = async (modelID) => {
|
|
370
|
-
try {
|
|
371
|
-
// Check if model is in use
|
|
372
|
-
const model = await apiClient.modelMethods.getModel(modelID, guid);
|
|
373
|
-
if (model.isInUse) {
|
|
374
|
-
console.log(`Cannot delete model "${model.displayName}": currently in use`);
|
|
375
|
-
return false;
|
|
376
|
-
}
|
|
377
|
-
|
|
378
|
-
// Perform deletion
|
|
379
|
-
const result = await apiClient.modelMethods.deleteModel(modelID, guid);
|
|
380
|
-
console.log('Model deleted successfully');
|
|
381
|
-
return true;
|
|
382
|
-
} catch (error) {
|
|
383
|
-
console.error('Failed to delete model:', error.message);
|
|
384
|
-
return false;
|
|
385
|
-
}
|
|
386
|
-
};
|
|
387
|
-
|
|
388
|
-
// Bulk cleanup of unused models
|
|
389
|
-
const cleanupUnusedModels = async () => {
|
|
390
|
-
const models = await apiClient.modelMethods.getModelList(guid);
|
|
391
|
-
const unusedModels = models.filter(m => !m.isInUse);
|
|
392
|
-
|
|
393
|
-
console.log(`Found ${unusedModels.length} unused models`);
|
|
394
|
-
|
|
395
|
-
for (const model of unusedModels) {
|
|
396
|
-
if (confirm(`Delete unused model "${model.displayName}"?`)) {
|
|
397
|
-
await safeDeleteModel(model.id);
|
|
398
|
-
}
|
|
399
|
-
}
|
|
400
|
-
};
|
|
401
|
-
```
|
|
402
|
-
|
|
403
|
-
**Deletion Restrictions:**
|
|
404
|
-
- Cannot delete a model that is currently in use by content items
|
|
405
|
-
- Cannot delete a model that is assigned to containers
|
|
406
|
-
- Cannot delete a model that is referenced by other models
|
|
407
|
-
|
|
408
|
-
**Best Practices:**
|
|
409
|
-
- Always check if a model is in use before attempting deletion
|
|
410
|
-
- Consider archiving or renaming models instead of deleting them
|
|
411
|
-
- Remove all dependencies (content items, containers) before deleting a model
|
|
412
|
-
- Backup model definitions before deletion for potential restoration
|
|
413
|
-
|
|
414
|
-
**Error Handling:**
|
|
415
|
-
- Throws `Exception` when model not found
|
|
416
|
-
- Throws `Exception` when model is in use and cannot be deleted
|
|
417
|
-
- Throws `Exception` when insufficient permissions to delete models
|
|
418
|
-
|
|
419
|
-
---
|
|
420
|
-
|
|
421
|
-
## Navigation
|
|
422
|
-
- [← Back to Main Documentation](../README.md)
|
|
423
|
-
- [Authentication & Setup](./auth.md)
|
|
424
|
-
- [Multi-Instance Operations](./multi-instance-operations.md)
|
|
425
|
-
- [AssetMethods](./asset-methods.md)
|
|
426
|
-
- [BatchMethods](./batch-methods.md)
|
|
427
|
-
- [ContainerMethods](./container-methods.md)
|
|
428
|
-
- [ContentMethods](./content-methods.md)
|
|
429
|
-
- [InstanceMethods](./instance-methods.md)
|
|
430
|
-
- [InstanceUserMethods](./instance-user-methods.md)
|
|
431
|
-
- **ModelMethods** *(current)*
|
|
432
|
-
- [PageMethods](./page-methods.md)
|
|
433
|
-
- [ServerUserMethods](./server-user-methods.md)
|
|
1
|
+
# Agility CMS & Management API TypeScript SDK
|
|
2
|
+
|
|
3
|
+
## ModelMethods
|
|
4
|
+
|
|
5
|
+
This class provides comprehensive content model management operations for Agility CMS. Content models define the structure and fields for content items, acting as templates that determine what data can be stored and how it's organized.
|
|
6
|
+
|
|
7
|
+
**Important Notes:**
|
|
8
|
+
- Content models define the schema for content items
|
|
9
|
+
- Models contain field definitions that specify data types, validation rules, and UI controls
|
|
10
|
+
- Changes to models may affect existing content items using those models
|
|
11
|
+
- Models are used by containers to organize and validate content
|
|
12
|
+
- Model reference names must be unique within the instance
|
|
13
|
+
|
|
14
|
+
### Function List
|
|
15
|
+
- [getContentModel](#getcontentmodel) - Retrieves a specific content model by ID
|
|
16
|
+
- [getModelByReferenceName](#getmodelbyreferencename) - Retrieves a model by reference name
|
|
17
|
+
- [getContentModules](#getcontentmodules) - Retrieves list of all content modules
|
|
18
|
+
- [getPageModules](#getpagemodules) - Retrieves list of all page modules
|
|
19
|
+
- [saveModel](#savemodel) - Creates or updates a content model
|
|
20
|
+
- [deleteModel](#deletemodel) - Deletes a content model by ID
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
### getContentModel
|
|
25
|
+
|
|
26
|
+
Retrieves a specific content model by its unique ID.
|
|
27
|
+
|
|
28
|
+
| Parameter | Type | Required | Description |
|
|
29
|
+
|-----------|------|----------|-------------|
|
|
30
|
+
| `id` | `number` | Yes | The model ID to retrieve |
|
|
31
|
+
| `guid` | `string` | Yes | Current website GUID |
|
|
32
|
+
|
|
33
|
+
**Returns:** `Model` - Complete model object with field definitions
|
|
34
|
+
|
|
35
|
+
**Usage Example:**
|
|
36
|
+
```typescript
|
|
37
|
+
const model = await apiClient.modelMethods.getContentModel(123, guid);
|
|
38
|
+
console.log('Model name:', model.displayName);
|
|
39
|
+
console.log('Reference name:', model.referenceName);
|
|
40
|
+
console.log('Description:', model.description);
|
|
41
|
+
console.log('Field count:', model.fields.length);
|
|
42
|
+
|
|
43
|
+
// Display field information
|
|
44
|
+
model.fields.forEach(field => {
|
|
45
|
+
console.log(`Field: ${field.name} (${field.type})`);
|
|
46
|
+
console.log(` Label: ${field.label}`);
|
|
47
|
+
console.log(` Required: ${field.isRequired}`);
|
|
48
|
+
console.log(` Default: ${field.defaultValue}`);
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
// Check if model is in use
|
|
52
|
+
if (model.isInUse) {
|
|
53
|
+
console.log('Model is currently being used by content items');
|
|
54
|
+
} else {
|
|
55
|
+
console.log('Model is not currently in use');
|
|
56
|
+
}
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
**Error Handling:**
|
|
60
|
+
- Throws `Exception` when model not found
|
|
61
|
+
|
|
62
|
+
### getModelByReferenceName
|
|
63
|
+
|
|
64
|
+
Retrieves a content model by its reference name. Returns null if the model doesn't exist.
|
|
65
|
+
|
|
66
|
+
| Parameter | Type | Required | Description |
|
|
67
|
+
|-----------|------|----------|-------------|
|
|
68
|
+
| `referenceName` | `string` | Yes | The reference name of the model |
|
|
69
|
+
| `guid` | `string` | Yes | Current website GUID |
|
|
70
|
+
|
|
71
|
+
**Returns:** `Model | null` - Model object or null if not found
|
|
72
|
+
|
|
73
|
+
**Usage Example:**
|
|
74
|
+
```typescript
|
|
75
|
+
const model = await apiClient.modelMethods.getModelByReferenceName('blog-post', guid);
|
|
76
|
+
if (model) {
|
|
77
|
+
console.log('Model found:', model.displayName);
|
|
78
|
+
console.log('Model ID:', model.id);
|
|
79
|
+
|
|
80
|
+
// Get specific field by name
|
|
81
|
+
const titleField = model.fields.find(f => f.name === 'title');
|
|
82
|
+
if (titleField) {
|
|
83
|
+
console.log('Title field type:', titleField.type);
|
|
84
|
+
console.log('Title field required:', titleField.isRequired);
|
|
85
|
+
}
|
|
86
|
+
} else {
|
|
87
|
+
console.log('Model not found');
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// Use in validation
|
|
91
|
+
const validateModelExists = async (referenceName) => {
|
|
92
|
+
const model = await apiClient.modelMethods.getModelByReferenceName(referenceName, guid);
|
|
93
|
+
return model !== null;
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
if (await validateModelExists('blog-post')) {
|
|
97
|
+
console.log('Blog post model is available');
|
|
98
|
+
}
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
**Error Handling:**
|
|
102
|
+
- Returns `null` for 404 errors (model not found)
|
|
103
|
+
- Throws `Exception` for other errors
|
|
104
|
+
|
|
105
|
+
### getContentModules
|
|
106
|
+
|
|
107
|
+
Retrieves a list of all content modules in the current website.
|
|
108
|
+
|
|
109
|
+
| Parameter | Type | Required | Description |
|
|
110
|
+
|-----------|------|----------|-------------|
|
|
111
|
+
| `includeDefaults` | `boolean` | Yes | Whether to include default modules |
|
|
112
|
+
| `guid` | `string` | Yes | Current website GUID |
|
|
113
|
+
| `includeModules` | `boolean` | No | Whether to include module details (default: false) |
|
|
114
|
+
|
|
115
|
+
**Returns:** `Model[]` - Array of all content modules
|
|
116
|
+
|
|
117
|
+
**Usage Example:**
|
|
118
|
+
```typescript
|
|
119
|
+
const models = await apiClient.modelMethods.getContentModules(true, guid);
|
|
120
|
+
console.log(`Total models: ${models.length}`);
|
|
121
|
+
|
|
122
|
+
// Display model summary
|
|
123
|
+
models.forEach(model => {
|
|
124
|
+
console.log(`Model: ${model.displayName} (${model.referenceName})`);
|
|
125
|
+
console.log(` Fields: ${model.fields.length}`);
|
|
126
|
+
console.log(` In Use: ${model.isInUse ? 'Yes' : 'No'}`);
|
|
127
|
+
console.log(` Created: ${model.createdDate}`);
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
// Filter models by usage
|
|
131
|
+
const modelsInUse = models.filter(m => m.isInUse);
|
|
132
|
+
const unusedModels = models.filter(m => !m.isInUse);
|
|
133
|
+
console.log(`Models in use: ${modelsInUse.length}`);
|
|
134
|
+
console.log(`Unused models: ${unusedModels.length}`);
|
|
135
|
+
|
|
136
|
+
// Group by field count
|
|
137
|
+
const modelsByFieldCount = models.reduce((acc, model) => {
|
|
138
|
+
const fieldCount = model.fields.length;
|
|
139
|
+
if (!acc[fieldCount]) acc[fieldCount] = [];
|
|
140
|
+
acc[fieldCount].push(model);
|
|
141
|
+
return acc;
|
|
142
|
+
}, {});
|
|
143
|
+
|
|
144
|
+
// Find models with specific fields
|
|
145
|
+
const modelsWithImageFields = models.filter(model =>
|
|
146
|
+
model.fields.some(field => field.type === 'image')
|
|
147
|
+
);
|
|
148
|
+
console.log(`Models with image fields: ${modelsWithImageFields.length}`);
|
|
149
|
+
|
|
150
|
+
// Create model dropdown options
|
|
151
|
+
const modelOptions = models.map(model => ({
|
|
152
|
+
value: model.id,
|
|
153
|
+
label: model.displayName,
|
|
154
|
+
referenceName: model.referenceName
|
|
155
|
+
}));
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
**Error Handling:**
|
|
159
|
+
- Throws `Exception` when retrieval fails
|
|
160
|
+
|
|
161
|
+
### getPageModules
|
|
162
|
+
|
|
163
|
+
Retrieves detailed field definitions for page modules.
|
|
164
|
+
|
|
165
|
+
| Parameter | Type | Required | Description |
|
|
166
|
+
|-----------|------|----------|-------------|
|
|
167
|
+
| `includeDefault` | `boolean` | Yes | Whether to include default modules |
|
|
168
|
+
| `guid` | `string` | Yes | Current website GUID |
|
|
169
|
+
|
|
170
|
+
**Returns:** `Model[]` - Array of page module definitions
|
|
171
|
+
|
|
172
|
+
**Usage Example:**
|
|
173
|
+
```typescript
|
|
174
|
+
const pageModules = await apiClient.modelMethods.getPageModules(true, guid);
|
|
175
|
+
console.log(`Model has ${fields.length} fields`);
|
|
176
|
+
|
|
177
|
+
// Display detailed field information
|
|
178
|
+
fields.forEach(field => {
|
|
179
|
+
console.log(`Field: ${field.name}`);
|
|
180
|
+
console.log(` Type: ${field.type}`);
|
|
181
|
+
console.log(` Label: ${field.label}`);
|
|
182
|
+
console.log(` Required: ${field.isRequired}`);
|
|
183
|
+
console.log(` Hidden: ${field.isHidden}`);
|
|
184
|
+
console.log(` Default: ${field.defaultValue}`);
|
|
185
|
+
console.log(` Help Text: ${field.helpText}`);
|
|
186
|
+
console.log(` Validation: ${field.validation}`);
|
|
187
|
+
console.log('---');
|
|
188
|
+
});
|
|
189
|
+
|
|
190
|
+
// Group fields by type
|
|
191
|
+
const fieldsByType = fields.reduce((acc, field) => {
|
|
192
|
+
if (!acc[field.type]) acc[field.type] = [];
|
|
193
|
+
acc[field.type].push(field);
|
|
194
|
+
return acc;
|
|
195
|
+
}, {});
|
|
196
|
+
|
|
197
|
+
console.log('Fields by type:');
|
|
198
|
+
Object.entries(fieldsByType).forEach(([type, typeFields]) => {
|
|
199
|
+
console.log(` ${type}: ${typeFields.length} fields`);
|
|
200
|
+
});
|
|
201
|
+
|
|
202
|
+
// Find required fields
|
|
203
|
+
const requiredFields = fields.filter(f => f.isRequired);
|
|
204
|
+
console.log(`Required fields: ${requiredFields.map(f => f.name).join(', ')}`);
|
|
205
|
+
|
|
206
|
+
// Create form validation rules
|
|
207
|
+
const validationRules = fields.reduce((acc, field) => {
|
|
208
|
+
acc[field.name] = {
|
|
209
|
+
required: field.isRequired,
|
|
210
|
+
type: field.type,
|
|
211
|
+
defaultValue: field.defaultValue,
|
|
212
|
+
validation: field.validation
|
|
213
|
+
};
|
|
214
|
+
return acc;
|
|
215
|
+
}, {});
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
**Field Types:**
|
|
219
|
+
Common field types include:
|
|
220
|
+
- `text`: Single line text input
|
|
221
|
+
- `textarea`: Multi-line text input
|
|
222
|
+
- `html`: Rich text/HTML editor
|
|
223
|
+
- `number`: Numeric input
|
|
224
|
+
- `boolean`: Checkbox/toggle
|
|
225
|
+
- `date`: Date picker
|
|
226
|
+
- `image`: Image upload
|
|
227
|
+
- `file`: File upload
|
|
228
|
+
- `url`: URL input
|
|
229
|
+
- `contentReference`: Reference to other content items
|
|
230
|
+
|
|
231
|
+
**Error Handling:**
|
|
232
|
+
- Throws `Exception` when model not found
|
|
233
|
+
|
|
234
|
+
### saveModel
|
|
235
|
+
|
|
236
|
+
Creates a new content model or updates an existing one.
|
|
237
|
+
|
|
238
|
+
| Parameter | Type | Required | Description |
|
|
239
|
+
|-----------|------|----------|-------------|
|
|
240
|
+
| `model` | `Model` | Yes | Model object to save |
|
|
241
|
+
| `guid` | `string` | Yes | Current website GUID |
|
|
242
|
+
|
|
243
|
+
**Returns:** `Model` - Saved model object with updated metadata
|
|
244
|
+
|
|
245
|
+
**Usage Example:**
|
|
246
|
+
```typescript
|
|
247
|
+
// Create a new model
|
|
248
|
+
const newModel = {
|
|
249
|
+
referenceName: 'product-review',
|
|
250
|
+
displayName: 'Product Review',
|
|
251
|
+
description: 'Customer product reviews and ratings',
|
|
252
|
+
fields: [
|
|
253
|
+
{
|
|
254
|
+
name: 'title',
|
|
255
|
+
label: 'Review Title',
|
|
256
|
+
type: 'text',
|
|
257
|
+
isRequired: true,
|
|
258
|
+
helpText: 'Enter a brief title for the review'
|
|
259
|
+
},
|
|
260
|
+
{
|
|
261
|
+
name: 'content',
|
|
262
|
+
label: 'Review Content',
|
|
263
|
+
type: 'textarea',
|
|
264
|
+
isRequired: true,
|
|
265
|
+
helpText: 'Enter the detailed review content'
|
|
266
|
+
},
|
|
267
|
+
{
|
|
268
|
+
name: 'rating',
|
|
269
|
+
label: 'Rating',
|
|
270
|
+
type: 'number',
|
|
271
|
+
isRequired: true,
|
|
272
|
+
validation: 'min:1,max:5',
|
|
273
|
+
helpText: 'Rate from 1 to 5 stars'
|
|
274
|
+
},
|
|
275
|
+
{
|
|
276
|
+
name: 'reviewerName',
|
|
277
|
+
label: 'Reviewer Name',
|
|
278
|
+
type: 'text',
|
|
279
|
+
isRequired: false,
|
|
280
|
+
helpText: 'Name of the person writing the review'
|
|
281
|
+
},
|
|
282
|
+
{
|
|
283
|
+
name: 'verified',
|
|
284
|
+
label: 'Verified Purchase',
|
|
285
|
+
type: 'boolean',
|
|
286
|
+
defaultValue: false,
|
|
287
|
+
helpText: 'Check if this is a verified purchase'
|
|
288
|
+
}
|
|
289
|
+
]
|
|
290
|
+
};
|
|
291
|
+
|
|
292
|
+
const savedModel = await apiClient.modelMethods.saveModel(newModel, guid);
|
|
293
|
+
console.log('Model created with ID:', savedModel.id);
|
|
294
|
+
|
|
295
|
+
// Update existing model
|
|
296
|
+
const existingModel = await apiClient.modelMethods.getModel(123, guid);
|
|
297
|
+
existingModel.displayName = 'Updated Display Name';
|
|
298
|
+
existingModel.description = 'Updated description';
|
|
299
|
+
|
|
300
|
+
// Add a new field
|
|
301
|
+
existingModel.fields.push({
|
|
302
|
+
name: 'newField',
|
|
303
|
+
label: 'New Field',
|
|
304
|
+
type: 'text',
|
|
305
|
+
isRequired: false,
|
|
306
|
+
helpText: 'This is a new field'
|
|
307
|
+
});
|
|
308
|
+
|
|
309
|
+
const updatedModel = await apiClient.modelMethods.saveModel(existingModel, guid);
|
|
310
|
+
console.log('Model updated:', updatedModel.displayName);
|
|
311
|
+
```
|
|
312
|
+
|
|
313
|
+
**Model Structure:**
|
|
314
|
+
```typescript
|
|
315
|
+
interface Model {
|
|
316
|
+
id?: number; // Auto-generated for new models
|
|
317
|
+
referenceName: string; // Unique identifier (required)
|
|
318
|
+
displayName: string; // Human-readable name (required)
|
|
319
|
+
description?: string; // Optional description
|
|
320
|
+
fields: ModelField[]; // Array of field definitions
|
|
321
|
+
isInUse?: boolean; // Read-only property
|
|
322
|
+
createdDate?: string; // Auto-generated
|
|
323
|
+
modifiedDate?: string; // Auto-generated
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
interface ModelField {
|
|
327
|
+
name: string; // Field name/identifier
|
|
328
|
+
label: string; // Display label
|
|
329
|
+
type: string; // Field type (text, number, etc.)
|
|
330
|
+
isRequired: boolean; // Whether field is required
|
|
331
|
+
isHidden?: boolean; // Whether field is hidden in UI
|
|
332
|
+
defaultValue?: any; // Default value
|
|
333
|
+
helpText?: string; // Help text for users
|
|
334
|
+
validation?: string; // Validation rules
|
|
335
|
+
options?: any[]; // Options for dropdown/select fields
|
|
336
|
+
}
|
|
337
|
+
```
|
|
338
|
+
|
|
339
|
+
**Error Handling:**
|
|
340
|
+
- Throws `Exception` when validation fails (duplicate reference name, invalid field types, etc.)
|
|
341
|
+
- Throws `Exception` when save operation fails
|
|
342
|
+
|
|
343
|
+
### deleteModel
|
|
344
|
+
|
|
345
|
+
Deletes a content model by its ID.
|
|
346
|
+
|
|
347
|
+
| Parameter | Type | Required | Description |
|
|
348
|
+
|-----------|------|----------|-------------|
|
|
349
|
+
| `modelID` | `number` | Yes | The model ID to delete |
|
|
350
|
+
| `guid` | `string` | Yes | Current website GUID |
|
|
351
|
+
|
|
352
|
+
**Returns:** `string` - Confirmation message of successful deletion
|
|
353
|
+
|
|
354
|
+
**Usage Example:**
|
|
355
|
+
```typescript
|
|
356
|
+
try {
|
|
357
|
+
const result = await apiClient.modelMethods.deleteModel(123, guid);
|
|
358
|
+
console.log(result); // "Model deleted successfully"
|
|
359
|
+
} catch (error) {
|
|
360
|
+
if (error.message.includes('in use')) {
|
|
361
|
+
console.log('Cannot delete model: currently in use by content items or containers');
|
|
362
|
+
// Handle by removing dependencies first
|
|
363
|
+
} else {
|
|
364
|
+
console.error('Failed to delete model:', error.message);
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
// Safe model deletion with checks
|
|
369
|
+
const safeDeleteModel = async (modelID) => {
|
|
370
|
+
try {
|
|
371
|
+
// Check if model is in use
|
|
372
|
+
const model = await apiClient.modelMethods.getModel(modelID, guid);
|
|
373
|
+
if (model.isInUse) {
|
|
374
|
+
console.log(`Cannot delete model "${model.displayName}": currently in use`);
|
|
375
|
+
return false;
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
// Perform deletion
|
|
379
|
+
const result = await apiClient.modelMethods.deleteModel(modelID, guid);
|
|
380
|
+
console.log('Model deleted successfully');
|
|
381
|
+
return true;
|
|
382
|
+
} catch (error) {
|
|
383
|
+
console.error('Failed to delete model:', error.message);
|
|
384
|
+
return false;
|
|
385
|
+
}
|
|
386
|
+
};
|
|
387
|
+
|
|
388
|
+
// Bulk cleanup of unused models
|
|
389
|
+
const cleanupUnusedModels = async () => {
|
|
390
|
+
const models = await apiClient.modelMethods.getModelList(guid);
|
|
391
|
+
const unusedModels = models.filter(m => !m.isInUse);
|
|
392
|
+
|
|
393
|
+
console.log(`Found ${unusedModels.length} unused models`);
|
|
394
|
+
|
|
395
|
+
for (const model of unusedModels) {
|
|
396
|
+
if (confirm(`Delete unused model "${model.displayName}"?`)) {
|
|
397
|
+
await safeDeleteModel(model.id);
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
};
|
|
401
|
+
```
|
|
402
|
+
|
|
403
|
+
**Deletion Restrictions:**
|
|
404
|
+
- Cannot delete a model that is currently in use by content items
|
|
405
|
+
- Cannot delete a model that is assigned to containers
|
|
406
|
+
- Cannot delete a model that is referenced by other models
|
|
407
|
+
|
|
408
|
+
**Best Practices:**
|
|
409
|
+
- Always check if a model is in use before attempting deletion
|
|
410
|
+
- Consider archiving or renaming models instead of deleting them
|
|
411
|
+
- Remove all dependencies (content items, containers) before deleting a model
|
|
412
|
+
- Backup model definitions before deletion for potential restoration
|
|
413
|
+
|
|
414
|
+
**Error Handling:**
|
|
415
|
+
- Throws `Exception` when model not found
|
|
416
|
+
- Throws `Exception` when model is in use and cannot be deleted
|
|
417
|
+
- Throws `Exception` when insufficient permissions to delete models
|
|
418
|
+
|
|
419
|
+
---
|
|
420
|
+
|
|
421
|
+
## Navigation
|
|
422
|
+
- [← Back to Main Documentation](../README.md)
|
|
423
|
+
- [Authentication & Setup](./auth.md)
|
|
424
|
+
- [Multi-Instance Operations](./multi-instance-operations.md)
|
|
425
|
+
- [AssetMethods](./asset-methods.md)
|
|
426
|
+
- [BatchMethods](./batch-methods.md)
|
|
427
|
+
- [ContainerMethods](./container-methods.md)
|
|
428
|
+
- [ContentMethods](./content-methods.md)
|
|
429
|
+
- [InstanceMethods](./instance-methods.md)
|
|
430
|
+
- [InstanceUserMethods](./instance-user-methods.md)
|
|
431
|
+
- **ModelMethods** *(current)*
|
|
432
|
+
- [PageMethods](./page-methods.md)
|
|
433
|
+
- [ServerUserMethods](./server-user-methods.md)
|
|
434
434
|
- [WebhookMethods](./webhook-methods.md)
|