@agility/management-sdk 0.1.32 → 0.1.34
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/.cursor/api-coverage.md +217 -0
- package/.cursor/api-documentation-manifest.md +275 -0
- package/.cursor/api-functions-analysis.md +111 -0
- package/.cursor/breakout-manifest.md +278 -0
- package/.cursor/docs-final-check.md +269 -0
- package/.cursor/github-actions-improvements.md +76 -0
- package/.cursor/hardening.md +271 -0
- package/.cursor/linting-fix.md +160 -0
- package/.cursor/manifest.md +243 -0
- package/.cursor/mocks.md +100 -0
- package/.cursor/test-coverage.md +841 -0
- package/.env +92 -0
- package/README.md +87 -315
- package/coverage/base.css +224 -0
- package/coverage/block-navigation.js +87 -0
- package/coverage/coverage-summary.json +43 -0
- package/coverage/favicon.png +0 -0
- package/coverage/index.html +161 -0
- package/coverage/lcov-report/base.css +224 -0
- package/coverage/lcov-report/block-navigation.js +87 -0
- package/coverage/lcov-report/favicon.png +0 -0
- package/coverage/lcov-report/index.html +161 -0
- package/coverage/lcov-report/prettify.css +1 -0
- package/coverage/lcov-report/prettify.js +2 -0
- package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
- package/coverage/lcov-report/sorter.js +210 -0
- package/coverage/lcov-report/src/apiClient.ts.html +199 -0
- package/coverage/lcov-report/src/apiMethods/assetMethods.ts.html +682 -0
- package/coverage/lcov-report/src/apiMethods/batchMethods.ts.html +736 -0
- package/coverage/lcov-report/src/apiMethods/clientInstance.ts.html +403 -0
- package/coverage/lcov-report/src/apiMethods/containerMethods.ts.html +460 -0
- package/coverage/lcov-report/src/apiMethods/contentMethods.ts.html +1183 -0
- package/coverage/lcov-report/src/apiMethods/index.html +266 -0
- package/coverage/lcov-report/src/apiMethods/instanceMethods.ts.html +160 -0
- package/coverage/lcov-report/src/apiMethods/instanceUserMethods.ts.html +268 -0
- package/coverage/lcov-report/src/apiMethods/modelMethods.ts.html +352 -0
- package/coverage/lcov-report/src/apiMethods/pageMethods.ts.html +1276 -0
- package/coverage/lcov-report/src/apiMethods/serverUserMethods.ts.html +196 -0
- package/coverage/lcov-report/src/apiMethods/webhookMethods.ts.html +271 -0
- package/coverage/lcov-report/src/enums/batchItemType.ts.html +106 -0
- package/coverage/lcov-report/src/enums/batchOperationType.ts.html +142 -0
- package/coverage/lcov-report/src/enums/batchState..ts.html +106 -0
- package/coverage/lcov-report/src/enums/index.html +161 -0
- package/coverage/lcov-report/src/enums/workflowOperationType.ts.html +175 -0
- package/coverage/lcov-report/src/index.html +116 -0
- package/coverage/lcov-report/src/models/assetContainer.ts.html +106 -0
- package/coverage/lcov-report/src/models/assetGalleries.ts.html +103 -0
- package/coverage/lcov-report/src/models/assetMediaGrouping.ts.html +136 -0
- package/coverage/lcov-report/src/models/assetMediaGroupingMetaData.ts.html +97 -0
- package/coverage/lcov-report/src/models/batch.ts.html +178 -0
- package/coverage/lcov-report/src/models/batchItem.ts.html +127 -0
- package/coverage/lcov-report/src/models/container.ts.html +232 -0
- package/coverage/lcov-report/src/models/contentDefinitionTypeID.ts.html +142 -0
- package/coverage/lcov-report/src/models/contentItem.ts.html +202 -0
- package/coverage/lcov-report/src/models/contentSectionDefaultModule.ts.html +106 -0
- package/coverage/lcov-report/src/models/contentSectionDefinition.ts.html +196 -0
- package/coverage/lcov-report/src/models/contentViewColumn.ts.html +109 -0
- package/coverage/lcov-report/src/models/exception.ts.html +109 -0
- package/coverage/lcov-report/src/models/index.html +476 -0
- package/coverage/lcov-report/src/models/instanceRole.ts.html +106 -0
- package/coverage/lcov-report/src/models/instanceUser.ts.html +130 -0
- package/coverage/lcov-report/src/models/locales.ts.html +100 -0
- package/coverage/lcov-report/src/models/media.ts.html +178 -0
- package/coverage/lcov-report/src/models/model.ts.html +172 -0
- package/coverage/lcov-report/src/models/notification.ts.html +124 -0
- package/coverage/lcov-report/src/models/options.ts.html +109 -0
- package/coverage/lcov-report/src/models/pageItem.ts.html +268 -0
- package/coverage/lcov-report/src/models/pageModel.ts.html +130 -0
- package/coverage/lcov-report/src/models/sharedModule.ts.html +106 -0
- package/coverage/lcov-report/src/models/sitemap.ts.html +148 -0
- package/coverage/lcov-report/src/models/websiteUser.ts.html +157 -0
- package/coverage/lcov.info +1459 -0
- package/coverage/prettify.css +1 -0
- package/coverage/prettify.js +2 -0
- package/coverage/sort-arrow-sprite.png +0 -0
- package/coverage/sorter.js +210 -0
- package/coverage/src/apiClient.ts.html +199 -0
- package/coverage/src/apiMethods/assetMethods.ts.html +682 -0
- package/coverage/src/apiMethods/batchMethods.ts.html +736 -0
- package/coverage/src/apiMethods/clientInstance.ts.html +403 -0
- package/coverage/src/apiMethods/containerMethods.ts.html +460 -0
- package/coverage/src/apiMethods/contentMethods.ts.html +1183 -0
- package/coverage/src/apiMethods/index.html +266 -0
- package/coverage/src/apiMethods/instanceMethods.ts.html +160 -0
- package/coverage/src/apiMethods/instanceUserMethods.ts.html +268 -0
- package/coverage/src/apiMethods/modelMethods.ts.html +352 -0
- package/coverage/src/apiMethods/pageMethods.ts.html +1276 -0
- package/coverage/src/apiMethods/serverUserMethods.ts.html +196 -0
- package/coverage/src/apiMethods/webhookMethods.ts.html +271 -0
- package/coverage/src/enums/batchItemType.ts.html +106 -0
- package/coverage/src/enums/batchOperationType.ts.html +142 -0
- package/coverage/src/enums/batchState..ts.html +106 -0
- package/coverage/src/enums/index.html +161 -0
- package/coverage/src/enums/workflowOperationType.ts.html +175 -0
- package/coverage/src/index.html +116 -0
- package/coverage/src/models/assetContainer.ts.html +106 -0
- package/coverage/src/models/assetGalleries.ts.html +103 -0
- package/coverage/src/models/assetMediaGrouping.ts.html +136 -0
- package/coverage/src/models/assetMediaGroupingMetaData.ts.html +97 -0
- package/coverage/src/models/batch.ts.html +178 -0
- package/coverage/src/models/batchItem.ts.html +127 -0
- package/coverage/src/models/container.ts.html +232 -0
- package/coverage/src/models/contentDefinitionTypeID.ts.html +142 -0
- package/coverage/src/models/contentItem.ts.html +202 -0
- package/coverage/src/models/contentSectionDefaultModule.ts.html +106 -0
- package/coverage/src/models/contentSectionDefinition.ts.html +196 -0
- package/coverage/src/models/contentViewColumn.ts.html +109 -0
- package/coverage/src/models/exception.ts.html +109 -0
- package/coverage/src/models/index.html +476 -0
- package/coverage/src/models/instanceRole.ts.html +106 -0
- package/coverage/src/models/instanceUser.ts.html +130 -0
- package/coverage/src/models/locales.ts.html +100 -0
- package/coverage/src/models/media.ts.html +178 -0
- package/coverage/src/models/model.ts.html +172 -0
- package/coverage/src/models/notification.ts.html +124 -0
- package/coverage/src/models/options.ts.html +109 -0
- package/coverage/src/models/pageItem.ts.html +268 -0
- package/coverage/src/models/pageModel.ts.html +130 -0
- package/coverage/src/models/sharedModule.ts.html +106 -0
- package/coverage/src/models/sitemap.ts.html +148 -0
- package/coverage/src/models/websiteUser.ts.html +157 -0
- package/dist/.tsbuildinfo +1 -0
- package/dist/apiClient.d.ts.map +1 -0
- package/dist/apiClient.js.map +1 -0
- package/dist/apiMethods/assetMethods.d.ts.map +1 -0
- package/dist/apiMethods/assetMethods.js +38 -38
- package/dist/apiMethods/assetMethods.js.map +1 -0
- package/dist/apiMethods/batchMethods.d.ts.map +1 -0
- package/dist/apiMethods/batchMethods.js +33 -33
- package/dist/apiMethods/batchMethods.js.map +1 -0
- package/dist/apiMethods/clientInstance.d.ts.map +1 -0
- package/dist/apiMethods/clientInstance.js +18 -15
- package/dist/apiMethods/clientInstance.js.map +1 -0
- package/dist/apiMethods/containerMethods.d.ts.map +1 -0
- package/dist/apiMethods/containerMethods.js +20 -20
- package/dist/apiMethods/containerMethods.js.map +1 -0
- package/dist/apiMethods/contentMethods.d.ts.map +1 -0
- package/dist/apiMethods/contentMethods.js +68 -68
- package/dist/apiMethods/contentMethods.js.map +1 -0
- package/dist/apiMethods/instanceMethods.d.ts.map +1 -0
- package/dist/apiMethods/instanceMethods.js +3 -3
- package/dist/apiMethods/instanceMethods.js.map +1 -0
- package/dist/apiMethods/instanceUserMethods.d.ts.map +1 -0
- package/dist/apiMethods/instanceUserMethods.js +10 -10
- package/dist/apiMethods/instanceUserMethods.js.map +1 -0
- package/dist/apiMethods/modelMethods.d.ts.map +1 -0
- package/dist/apiMethods/modelMethods.js +13 -13
- package/dist/apiMethods/modelMethods.js.map +1 -0
- package/dist/apiMethods/pageMethods.d.ts +2 -1
- package/dist/apiMethods/pageMethods.d.ts.map +1 -0
- package/dist/apiMethods/pageMethods.js +79 -73
- package/dist/apiMethods/pageMethods.js.map +1 -0
- package/dist/apiMethods/serverUserMethods.d.ts.map +1 -0
- package/dist/apiMethods/serverUserMethods.js +4 -4
- package/dist/apiMethods/serverUserMethods.js.map +1 -0
- package/dist/apiMethods/webhookMethods.d.ts.map +1 -0
- package/dist/apiMethods/webhookMethods.js +11 -11
- package/dist/apiMethods/webhookMethods.js.map +1 -0
- package/dist/enums/assetGroupingType.d.ts.map +1 -0
- package/dist/enums/assetGroupingType.js +1 -1
- package/dist/enums/assetGroupingType.js.map +1 -0
- package/dist/enums/batchItemType.d.ts.map +1 -0
- package/dist/enums/batchItemType.js +1 -1
- package/dist/enums/batchItemType.js.map +1 -0
- package/dist/enums/batchOperationType.d.ts.map +1 -0
- package/dist/enums/batchOperationType.js +1 -1
- package/dist/enums/batchOperationType.js.map +1 -0
- package/dist/enums/batchState..d.ts.map +1 -0
- package/dist/enums/batchState..js +1 -1
- package/dist/enums/batchState..js.map +1 -0
- package/dist/enums/pageItemTemplateType.d.ts.map +1 -0
- package/dist/enums/pageItemTemplateType.js +1 -1
- package/dist/enums/pageItemTemplateType.js.map +1 -0
- package/dist/enums/workflowOperationType.d.ts.map +1 -0
- package/dist/enums/workflowOperationType.js +1 -1
- package/dist/enums/workflowOperationType.js.map +1 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +5 -1
- package/dist/index.js.map +1 -0
- package/dist/models/assetContainer.d.ts.map +1 -0
- package/dist/models/assetContainer.js.map +1 -0
- package/dist/models/assetGalleries.d.ts.map +1 -0
- package/dist/models/assetGalleries.js.map +1 -0
- package/dist/models/assetMediaGrouping.d.ts.map +1 -0
- package/dist/models/assetMediaGrouping.js.map +1 -0
- package/dist/models/assetMediaGroupingMetaData.d.ts.map +1 -0
- package/dist/models/assetMediaGroupingMetaData.js.map +1 -0
- package/dist/models/batch.d.ts.map +1 -0
- package/dist/models/batch.js.map +1 -0
- package/dist/models/batchItem.d.ts.map +1 -0
- package/dist/models/batchItem.js.map +1 -0
- package/dist/models/batchTypes.d.ts.map +1 -0
- package/dist/models/batchTypes.js.map +1 -0
- package/dist/models/container.d.ts.map +1 -0
- package/dist/models/container.js.map +1 -0
- package/dist/models/contentDefinitionTypeID.d.ts.map +1 -0
- package/dist/models/contentDefinitionTypeID.js +1 -1
- package/dist/models/contentDefinitionTypeID.js.map +1 -0
- package/dist/models/contentItem.d.ts.map +1 -0
- package/dist/models/contentItem.js.map +1 -0
- package/dist/models/contentItemHistory.d.ts.map +1 -0
- package/dist/models/contentItemHistory.js.map +1 -0
- package/dist/models/contentListFilterModel.d.ts.map +1 -0
- package/dist/models/contentListFilterModel.js.map +1 -0
- package/dist/models/contentSectionDefaultModule.d.ts.map +1 -0
- package/dist/models/contentSectionDefaultModule.js.map +1 -0
- package/dist/models/contentSectionDefinition.d.ts.map +1 -0
- package/dist/models/contentSectionDefinition.js.map +1 -0
- package/dist/models/contentViewColumn.d.ts.map +1 -0
- package/dist/models/contentViewColumn.js.map +1 -0
- package/dist/models/exception.d.ts.map +1 -0
- package/dist/models/exception.js +2 -0
- package/dist/models/exception.js.map +1 -0
- package/dist/models/instanceRole.d.ts.map +1 -0
- package/dist/models/instanceRole.js.map +1 -0
- package/dist/models/instanceUser.d.ts.map +1 -0
- package/dist/models/instanceUser.js.map +1 -0
- package/dist/models/itemComments.d.ts.map +1 -0
- package/dist/models/itemComments.js.map +1 -0
- package/dist/models/listParams.d.ts.map +1 -0
- package/dist/models/listParams.js.map +1 -0
- package/dist/models/locales.d.ts.map +1 -0
- package/dist/models/locales.js +2 -0
- package/dist/models/locales.js.map +1 -0
- package/dist/models/media.d.ts.map +1 -0
- package/dist/models/media.js.map +1 -0
- package/dist/models/model.d.ts.map +1 -0
- package/dist/models/model.js.map +1 -0
- package/dist/models/notification.d.ts.map +1 -0
- package/dist/models/notification.js.map +1 -0
- package/dist/models/options.d.ts.map +1 -0
- package/dist/models/options.js.map +1 -0
- package/dist/models/pageHistory.d.ts.map +1 -0
- package/dist/models/pageHistory.js.map +1 -0
- package/dist/models/pageItem.d.ts.map +1 -0
- package/dist/models/pageItem.js.map +1 -0
- package/dist/models/pageModel.d.ts.map +1 -0
- package/dist/models/pageModel.js.map +1 -0
- package/dist/models/serverUser.d.ts.map +1 -0
- package/dist/models/serverUser.js.map +1 -0
- package/dist/models/sharedModule.d.ts.map +1 -0
- package/dist/models/sharedModule.js.map +1 -0
- package/dist/models/sitemap.d.ts.map +1 -0
- package/dist/models/sitemap.js.map +1 -0
- package/dist/models/webhook.d.ts.map +1 -0
- package/dist/models/webhook.js.map +1 -0
- package/dist/models/websiteListing.d.ts.map +1 -0
- package/dist/models/websiteListing.js.map +1 -0
- package/dist/models/websiteUser.d.ts.map +1 -0
- package/dist/models/websiteUser.js.map +1 -0
- package/docs/asset-methods.md +382 -0
- package/docs/auth-component.md +361 -0
- package/docs/auth.md +594 -0
- package/docs/batch-methods.md +244 -0
- package/docs/cicd.md +607 -0
- package/docs/container-methods.md +268 -0
- package/docs/content-methods.md +423 -0
- package/docs/instance-methods.md +105 -0
- package/docs/instance-user-methods.md +231 -0
- package/docs/model-methods.md +434 -0
- package/docs/multi-instance-operations.md +192 -0
- package/docs/page-methods.md +671 -0
- package/docs/server-user-methods.md +280 -0
- package/docs/webhook-methods.md +452 -0
- package/package.json +1 -1
package/docs/cicd.md
ADDED
|
@@ -0,0 +1,607 @@
|
|
|
1
|
+
# CI/CD & Automated Environments
|
|
2
|
+
|
|
3
|
+
This guide covers using the Agility CMS Management SDK in automated environments such as CI/CD pipelines, serverless functions, and other programmatic scenarios where the OAuth flow isn't practical.
|
|
4
|
+
|
|
5
|
+
## Table of Contents
|
|
6
|
+
|
|
7
|
+
- [Overview](#overview)
|
|
8
|
+
- [Token-Based Authentication](#token-based-authentication)
|
|
9
|
+
- [Environment Configuration](#environment-configuration)
|
|
10
|
+
- [CI/CD Pipeline Examples](#cicd-pipeline-examples)
|
|
11
|
+
- [Serverless Functions](#serverless-functions)
|
|
12
|
+
- [Token Management](#token-management)
|
|
13
|
+
- [Security Best Practices](#security-best-practices)
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
## Overview
|
|
18
|
+
|
|
19
|
+
In automated environments, the interactive OAuth flow isn't practical. Instead, you'll use **access tokens** directly. This approach is ideal for:
|
|
20
|
+
|
|
21
|
+
- **CI/CD Pipelines** - Automated content deployment
|
|
22
|
+
- **Serverless Functions** - Event-triggered content operations
|
|
23
|
+
- **Scheduled Jobs** - Content synchronization, backups, etc.
|
|
24
|
+
- **Build Processes** - Static site generation with fresh content
|
|
25
|
+
- **Automated Testing** - Integration tests requiring content operations
|
|
26
|
+
|
|
27
|
+
---
|
|
28
|
+
|
|
29
|
+
## Token-Based Authentication
|
|
30
|
+
|
|
31
|
+
### Using Options Constructor
|
|
32
|
+
|
|
33
|
+
```typescript
|
|
34
|
+
import * as mgmtApi from '@agility/management-sdk';
|
|
35
|
+
|
|
36
|
+
// Set token via Options constructor
|
|
37
|
+
const options = new mgmtApi.Options();
|
|
38
|
+
options.token = process.env.AGILITY_API_TOKEN;
|
|
39
|
+
|
|
40
|
+
const apiClient = new mgmtApi.ApiClient(options);
|
|
41
|
+
// Token is automatically stored in keytar for consistency
|
|
42
|
+
|
|
43
|
+
// Ready to use immediately
|
|
44
|
+
const guid = process.env.AGILITY_GUID;
|
|
45
|
+
const locale = 'en-us';
|
|
46
|
+
|
|
47
|
+
const contentItem = await apiClient.contentMethods.getContentItem(22, guid, locale);
|
|
48
|
+
console.log('Content retrieved:', contentItem.fields.title);
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
### Using setToken Method
|
|
52
|
+
|
|
53
|
+
```typescript
|
|
54
|
+
import * as mgmtApi from '@agility/management-sdk';
|
|
55
|
+
|
|
56
|
+
// Initialize without token
|
|
57
|
+
const apiClient = new mgmtApi.ApiClient();
|
|
58
|
+
|
|
59
|
+
// Set token programmatically
|
|
60
|
+
await apiClient.setToken(process.env.AGILITY_API_TOKEN);
|
|
61
|
+
|
|
62
|
+
// Ready to use
|
|
63
|
+
const content = await apiClient.contentMethods.getContentList(guid, locale);
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
---
|
|
67
|
+
|
|
68
|
+
## Environment Configuration
|
|
69
|
+
|
|
70
|
+
### Environment Variables
|
|
71
|
+
|
|
72
|
+
Set up your environment variables for secure token management:
|
|
73
|
+
|
|
74
|
+
```bash
|
|
75
|
+
# .env file
|
|
76
|
+
AGILITY_API_TOKEN=your_access_token_here
|
|
77
|
+
AGILITY_GUID=your_website_guid
|
|
78
|
+
AGILITY_LOCALE=en-us
|
|
79
|
+
AGILITY_REGION=us # Optional: us, ca, eu, aus, dev
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
### Loading Configuration
|
|
83
|
+
|
|
84
|
+
```typescript
|
|
85
|
+
import * as mgmtApi from '@agility/management-sdk';
|
|
86
|
+
import dotenv from 'dotenv';
|
|
87
|
+
|
|
88
|
+
// Load environment variables
|
|
89
|
+
dotenv.config();
|
|
90
|
+
|
|
91
|
+
// Validate required environment variables
|
|
92
|
+
const requiredEnvVars = ['AGILITY_API_TOKEN', 'AGILITY_GUID'];
|
|
93
|
+
for (const envVar of requiredEnvVars) {
|
|
94
|
+
if (!process.env[envVar]) {
|
|
95
|
+
throw new Error(`Missing required environment variable: ${envVar}`);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// Initialize client with environment configuration
|
|
100
|
+
const options = new mgmtApi.Options();
|
|
101
|
+
options.token = process.env.AGILITY_API_TOKEN;
|
|
102
|
+
|
|
103
|
+
const apiClient = new mgmtApi.ApiClient(options);
|
|
104
|
+
|
|
105
|
+
// Global configuration
|
|
106
|
+
const config = {
|
|
107
|
+
guid: process.env.AGILITY_GUID!,
|
|
108
|
+
locale: process.env.AGILITY_LOCALE || 'en-us',
|
|
109
|
+
region: process.env.AGILITY_REGION || 'us'
|
|
110
|
+
};
|
|
111
|
+
|
|
112
|
+
export { apiClient, config };
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
---
|
|
116
|
+
|
|
117
|
+
## CI/CD Pipeline Examples
|
|
118
|
+
|
|
119
|
+
### GitHub Actions
|
|
120
|
+
|
|
121
|
+
```yaml
|
|
122
|
+
# .github/workflows/content-deploy.yml
|
|
123
|
+
name: Deploy Content
|
|
124
|
+
|
|
125
|
+
on:
|
|
126
|
+
push:
|
|
127
|
+
branches: [main]
|
|
128
|
+
workflow_dispatch:
|
|
129
|
+
|
|
130
|
+
jobs:
|
|
131
|
+
deploy:
|
|
132
|
+
runs-on: ubuntu-latest
|
|
133
|
+
|
|
134
|
+
steps:
|
|
135
|
+
- uses: actions/checkout@v3
|
|
136
|
+
|
|
137
|
+
- name: Setup Node.js
|
|
138
|
+
uses: actions/setup-node@v3
|
|
139
|
+
with:
|
|
140
|
+
node-version: '18'
|
|
141
|
+
|
|
142
|
+
- name: Install dependencies
|
|
143
|
+
run: npm ci
|
|
144
|
+
|
|
145
|
+
- name: Deploy Content
|
|
146
|
+
env:
|
|
147
|
+
AGILITY_API_TOKEN: ${{ secrets.AGILITY_API_TOKEN }}
|
|
148
|
+
AGILITY_GUID: ${{ secrets.AGILITY_GUID }}
|
|
149
|
+
AGILITY_LOCALE: 'en-us'
|
|
150
|
+
run: node deploy-content.js
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
```javascript
|
|
154
|
+
// deploy-content.js
|
|
155
|
+
const mgmtApi = require('@agility/management-sdk');
|
|
156
|
+
|
|
157
|
+
async function deployContent() {
|
|
158
|
+
// Initialize with token from environment
|
|
159
|
+
const options = new mgmtApi.Options();
|
|
160
|
+
options.token = process.env.AGILITY_API_TOKEN;
|
|
161
|
+
|
|
162
|
+
const apiClient = new mgmtApi.ApiClient(options);
|
|
163
|
+
|
|
164
|
+
const guid = process.env.AGILITY_GUID;
|
|
165
|
+
const locale = process.env.AGILITY_LOCALE;
|
|
166
|
+
|
|
167
|
+
try {
|
|
168
|
+
// Deploy content items
|
|
169
|
+
const contentItems = [
|
|
170
|
+
{
|
|
171
|
+
properties: {
|
|
172
|
+
referenceName: 'deployment-notice',
|
|
173
|
+
definitionName: 'Announcement',
|
|
174
|
+
state: 2
|
|
175
|
+
},
|
|
176
|
+
fields: {
|
|
177
|
+
title: `Deployment ${new Date().toISOString()}`,
|
|
178
|
+
content: 'Application deployed successfully',
|
|
179
|
+
publishDate: new Date().toISOString()
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
];
|
|
183
|
+
|
|
184
|
+
for (const item of contentItems) {
|
|
185
|
+
const contentId = await apiClient.contentMethods.saveContentItem(
|
|
186
|
+
item,
|
|
187
|
+
guid,
|
|
188
|
+
locale
|
|
189
|
+
);
|
|
190
|
+
console.log(`✅ Content created: ${contentId}`);
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
console.log('🚀 Content deployment completed successfully');
|
|
194
|
+
|
|
195
|
+
} catch (error) {
|
|
196
|
+
console.error('❌ Deployment failed:', error.message);
|
|
197
|
+
process.exit(1);
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
deployContent();
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
### GitLab CI
|
|
205
|
+
|
|
206
|
+
```yaml
|
|
207
|
+
# .gitlab-ci.yml
|
|
208
|
+
stages:
|
|
209
|
+
- deploy
|
|
210
|
+
|
|
211
|
+
deploy_content:
|
|
212
|
+
stage: deploy
|
|
213
|
+
image: node:18
|
|
214
|
+
script:
|
|
215
|
+
- npm ci
|
|
216
|
+
- node deploy-content.js
|
|
217
|
+
variables:
|
|
218
|
+
AGILITY_GUID: $AGILITY_GUID
|
|
219
|
+
AGILITY_LOCALE: "en-us"
|
|
220
|
+
environment: production
|
|
221
|
+
only:
|
|
222
|
+
- main
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
### Jenkins Pipeline
|
|
226
|
+
|
|
227
|
+
```groovy
|
|
228
|
+
pipeline {
|
|
229
|
+
agent any
|
|
230
|
+
|
|
231
|
+
environment {
|
|
232
|
+
AGILITY_API_TOKEN = credentials('agility-api-token')
|
|
233
|
+
AGILITY_GUID = credentials('agility-guid')
|
|
234
|
+
AGILITY_LOCALE = 'en-us'
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
stages {
|
|
238
|
+
stage('Deploy Content') {
|
|
239
|
+
steps {
|
|
240
|
+
sh 'npm ci'
|
|
241
|
+
sh 'node deploy-content.js'
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
---
|
|
249
|
+
|
|
250
|
+
## Serverless Functions
|
|
251
|
+
|
|
252
|
+
### AWS Lambda
|
|
253
|
+
|
|
254
|
+
```typescript
|
|
255
|
+
import * as mgmtApi from '@agility/management-sdk';
|
|
256
|
+
|
|
257
|
+
// Initialize outside handler for connection reuse
|
|
258
|
+
const options = new mgmtApi.Options();
|
|
259
|
+
options.token = process.env.AGILITY_API_TOKEN;
|
|
260
|
+
const apiClient = new mgmtApi.ApiClient(options);
|
|
261
|
+
|
|
262
|
+
const config = {
|
|
263
|
+
guid: process.env.AGILITY_GUID!,
|
|
264
|
+
locale: process.env.AGILITY_LOCALE || 'en-us'
|
|
265
|
+
};
|
|
266
|
+
|
|
267
|
+
export const handler = async (event: any, context: any) => {
|
|
268
|
+
try {
|
|
269
|
+
// Process event data
|
|
270
|
+
const { title, content, category } = JSON.parse(event.body);
|
|
271
|
+
|
|
272
|
+
// Create content item
|
|
273
|
+
const contentItem = {
|
|
274
|
+
properties: {
|
|
275
|
+
referenceName: 'api-content',
|
|
276
|
+
definitionName: 'Article',
|
|
277
|
+
state: 2
|
|
278
|
+
},
|
|
279
|
+
fields: {
|
|
280
|
+
title: title,
|
|
281
|
+
content: content,
|
|
282
|
+
category: category,
|
|
283
|
+
publishDate: new Date().toISOString()
|
|
284
|
+
}
|
|
285
|
+
};
|
|
286
|
+
|
|
287
|
+
const contentId = await apiClient.contentMethods.saveContentItem(
|
|
288
|
+
contentItem,
|
|
289
|
+
config.guid,
|
|
290
|
+
config.locale
|
|
291
|
+
);
|
|
292
|
+
|
|
293
|
+
return {
|
|
294
|
+
statusCode: 200,
|
|
295
|
+
body: JSON.stringify({
|
|
296
|
+
success: true,
|
|
297
|
+
contentId: contentId,
|
|
298
|
+
message: 'Content created successfully'
|
|
299
|
+
})
|
|
300
|
+
};
|
|
301
|
+
|
|
302
|
+
} catch (error) {
|
|
303
|
+
console.error('Lambda error:', error);
|
|
304
|
+
|
|
305
|
+
return {
|
|
306
|
+
statusCode: 500,
|
|
307
|
+
body: JSON.stringify({
|
|
308
|
+
success: false,
|
|
309
|
+
error: error.message
|
|
310
|
+
})
|
|
311
|
+
};
|
|
312
|
+
}
|
|
313
|
+
};
|
|
314
|
+
```
|
|
315
|
+
|
|
316
|
+
### Vercel Functions
|
|
317
|
+
|
|
318
|
+
```typescript
|
|
319
|
+
// api/create-content.ts
|
|
320
|
+
import type { VercelRequest, VercelResponse } from '@vercel/node';
|
|
321
|
+
import * as mgmtApi from '@agility/management-sdk';
|
|
322
|
+
|
|
323
|
+
export default async function handler(req: VercelRequest, res: VercelResponse) {
|
|
324
|
+
if (req.method !== 'POST') {
|
|
325
|
+
return res.status(405).json({ error: 'Method not allowed' });
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
try {
|
|
329
|
+
// Initialize API client
|
|
330
|
+
const options = new mgmtApi.Options();
|
|
331
|
+
options.token = process.env.AGILITY_API_TOKEN;
|
|
332
|
+
const apiClient = new mgmtApi.ApiClient(options);
|
|
333
|
+
|
|
334
|
+
// Process request
|
|
335
|
+
const { title, content } = req.body;
|
|
336
|
+
|
|
337
|
+
const contentItem = {
|
|
338
|
+
properties: {
|
|
339
|
+
referenceName: 'vercel-content',
|
|
340
|
+
definitionName: 'BlogPost',
|
|
341
|
+
state: 2
|
|
342
|
+
},
|
|
343
|
+
fields: {
|
|
344
|
+
title: title,
|
|
345
|
+
content: content,
|
|
346
|
+
publishDate: new Date().toISOString()
|
|
347
|
+
}
|
|
348
|
+
};
|
|
349
|
+
|
|
350
|
+
const contentId = await apiClient.contentMethods.saveContentItem(
|
|
351
|
+
contentItem,
|
|
352
|
+
process.env.AGILITY_GUID!,
|
|
353
|
+
'en-us'
|
|
354
|
+
);
|
|
355
|
+
|
|
356
|
+
res.status(200).json({
|
|
357
|
+
success: true,
|
|
358
|
+
contentId: contentId
|
|
359
|
+
});
|
|
360
|
+
|
|
361
|
+
} catch (error) {
|
|
362
|
+
console.error('Vercel function error:', error);
|
|
363
|
+
res.status(500).json({
|
|
364
|
+
success: false,
|
|
365
|
+
error: error.message
|
|
366
|
+
});
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
```
|
|
370
|
+
|
|
371
|
+
---
|
|
372
|
+
|
|
373
|
+
## Token Management
|
|
374
|
+
|
|
375
|
+
### Token Validation
|
|
376
|
+
|
|
377
|
+
```typescript
|
|
378
|
+
import * as mgmtApi from '@agility/management-sdk';
|
|
379
|
+
|
|
380
|
+
async function validateToken(token: string): Promise<boolean> {
|
|
381
|
+
try {
|
|
382
|
+
const options = new mgmtApi.Options();
|
|
383
|
+
options.token = token;
|
|
384
|
+
const apiClient = new mgmtApi.ApiClient(options);
|
|
385
|
+
|
|
386
|
+
// Test token by making a simple API call
|
|
387
|
+
const locales = await apiClient.instanceMethods.getLocales(
|
|
388
|
+
process.env.AGILITY_GUID!
|
|
389
|
+
);
|
|
390
|
+
|
|
391
|
+
return locales.length > 0;
|
|
392
|
+
|
|
393
|
+
} catch (error) {
|
|
394
|
+
console.error('Token validation failed:', error.message);
|
|
395
|
+
return false;
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
// Usage in CI/CD
|
|
400
|
+
if (!(await validateToken(process.env.AGILITY_API_TOKEN!))) {
|
|
401
|
+
console.error('❌ Invalid API token');
|
|
402
|
+
process.exit(1);
|
|
403
|
+
}
|
|
404
|
+
```
|
|
405
|
+
|
|
406
|
+
### Token Rotation
|
|
407
|
+
|
|
408
|
+
```typescript
|
|
409
|
+
// token-rotation.js
|
|
410
|
+
const mgmtApi = require('@agility/management-sdk');
|
|
411
|
+
|
|
412
|
+
class TokenRotationService {
|
|
413
|
+
constructor() {
|
|
414
|
+
this.currentToken = process.env.AGILITY_API_TOKEN;
|
|
415
|
+
this.backupToken = process.env.AGILITY_API_TOKEN_BACKUP;
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
async getWorkingToken() {
|
|
419
|
+
// Try current token first
|
|
420
|
+
if (await this.validateToken(this.currentToken)) {
|
|
421
|
+
return this.currentToken;
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
// Fallback to backup token
|
|
425
|
+
if (await this.validateToken(this.backupToken)) {
|
|
426
|
+
console.warn('⚠️ Using backup token - main token may be expired');
|
|
427
|
+
return this.backupToken;
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
throw new Error('No valid tokens available');
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
async validateToken(token) {
|
|
434
|
+
try {
|
|
435
|
+
const options = new mgmtApi.Options();
|
|
436
|
+
options.token = token;
|
|
437
|
+
const apiClient = new mgmtApi.ApiClient(options);
|
|
438
|
+
|
|
439
|
+
await apiClient.instanceMethods.getLocales(process.env.AGILITY_GUID);
|
|
440
|
+
return true;
|
|
441
|
+
} catch {
|
|
442
|
+
return false;
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
module.exports = TokenRotationService;
|
|
448
|
+
```
|
|
449
|
+
|
|
450
|
+
---
|
|
451
|
+
|
|
452
|
+
## Security Best Practices
|
|
453
|
+
|
|
454
|
+
### Environment Variable Security
|
|
455
|
+
|
|
456
|
+
```typescript
|
|
457
|
+
// security-config.ts
|
|
458
|
+
export class SecurityConfig {
|
|
459
|
+
private static validateToken(token: string): boolean {
|
|
460
|
+
// Basic token format validation
|
|
461
|
+
if (!token || typeof token !== 'string') {
|
|
462
|
+
return false;
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
// Check minimum length
|
|
466
|
+
if (token.length < 20) {
|
|
467
|
+
return false;
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
// Check for placeholder values
|
|
471
|
+
const placeholders = ['your_token', 'replace_me', 'token_here'];
|
|
472
|
+
return !placeholders.some(placeholder =>
|
|
473
|
+
token.toLowerCase().includes(placeholder)
|
|
474
|
+
);
|
|
475
|
+
}
|
|
476
|
+
|
|
477
|
+
static getSecureToken(): string {
|
|
478
|
+
const token = process.env.AGILITY_API_TOKEN;
|
|
479
|
+
|
|
480
|
+
if (!token) {
|
|
481
|
+
throw new Error('AGILITY_API_TOKEN environment variable is required');
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
if (!this.validateToken(token)) {
|
|
485
|
+
throw new Error('Invalid token format detected');
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
return token;
|
|
489
|
+
}
|
|
490
|
+
|
|
491
|
+
static getSecureConfig() {
|
|
492
|
+
return {
|
|
493
|
+
token: this.getSecureToken(),
|
|
494
|
+
guid: process.env.AGILITY_GUID || (() => {
|
|
495
|
+
throw new Error('AGILITY_GUID environment variable is required');
|
|
496
|
+
})(),
|
|
497
|
+
locale: process.env.AGILITY_LOCALE || 'en-us'
|
|
498
|
+
};
|
|
499
|
+
}
|
|
500
|
+
}
|
|
501
|
+
```
|
|
502
|
+
|
|
503
|
+
### Error Handling
|
|
504
|
+
|
|
505
|
+
```typescript
|
|
506
|
+
// error-handling.ts
|
|
507
|
+
import * as mgmtApi from '@agility/management-sdk';
|
|
508
|
+
|
|
509
|
+
export class CICDErrorHandler {
|
|
510
|
+
static async executeWithRetry<T>(
|
|
511
|
+
operation: () => Promise<T>,
|
|
512
|
+
maxRetries: number = 3,
|
|
513
|
+
delay: number = 1000
|
|
514
|
+
): Promise<T> {
|
|
515
|
+
for (let attempt = 1; attempt <= maxRetries; attempt++) {
|
|
516
|
+
try {
|
|
517
|
+
return await operation();
|
|
518
|
+
} catch (error) {
|
|
519
|
+
console.error(`Attempt ${attempt} failed:`, error.message);
|
|
520
|
+
|
|
521
|
+
if (attempt === maxRetries) {
|
|
522
|
+
throw error;
|
|
523
|
+
}
|
|
524
|
+
|
|
525
|
+
// Exponential backoff
|
|
526
|
+
const waitTime = delay * Math.pow(2, attempt - 1);
|
|
527
|
+
console.log(`⏳ Retrying in ${waitTime}ms...`);
|
|
528
|
+
await new Promise(resolve => setTimeout(resolve, waitTime));
|
|
529
|
+
}
|
|
530
|
+
}
|
|
531
|
+
|
|
532
|
+
throw new Error('All retry attempts failed');
|
|
533
|
+
}
|
|
534
|
+
|
|
535
|
+
static handleCICDError(error: any, context: string): never {
|
|
536
|
+
console.error(`❌ CICD Error in ${context}:`, error.message);
|
|
537
|
+
|
|
538
|
+
// Log additional context for debugging
|
|
539
|
+
if (error.response) {
|
|
540
|
+
console.error('Response status:', error.response.status);
|
|
541
|
+
console.error('Response data:', error.response.data);
|
|
542
|
+
}
|
|
543
|
+
|
|
544
|
+
// Exit with error code for CI/CD pipeline
|
|
545
|
+
process.exit(1);
|
|
546
|
+
}
|
|
547
|
+
}
|
|
548
|
+
|
|
549
|
+
// Usage example
|
|
550
|
+
try {
|
|
551
|
+
const result = await CICDErrorHandler.executeWithRetry(async () => {
|
|
552
|
+
return await apiClient.contentMethods.saveContentItem(contentData, guid, locale);
|
|
553
|
+
});
|
|
554
|
+
|
|
555
|
+
console.log('✅ Content saved successfully:', result);
|
|
556
|
+
} catch (error) {
|
|
557
|
+
CICDErrorHandler.handleCICDError(error, 'content creation');
|
|
558
|
+
}
|
|
559
|
+
```
|
|
560
|
+
|
|
561
|
+
### Logging and Monitoring
|
|
562
|
+
|
|
563
|
+
```typescript
|
|
564
|
+
// cicd-logger.ts
|
|
565
|
+
export class CICDLogger {
|
|
566
|
+
private static logLevel = process.env.LOG_LEVEL || 'INFO';
|
|
567
|
+
|
|
568
|
+
static info(message: string, data?: any) {
|
|
569
|
+
const timestamp = new Date().toISOString();
|
|
570
|
+
console.log(`[${timestamp}] INFO: ${message}`, data || '');
|
|
571
|
+
}
|
|
572
|
+
|
|
573
|
+
static error(message: string, error?: any) {
|
|
574
|
+
const timestamp = new Date().toISOString();
|
|
575
|
+
console.error(`[${timestamp}] ERROR: ${message}`, error || '');
|
|
576
|
+
}
|
|
577
|
+
|
|
578
|
+
static logOperation(operation: string, guid: string, locale: string) {
|
|
579
|
+
this.info(`Starting operation: ${operation}`, { guid, locale });
|
|
580
|
+
}
|
|
581
|
+
|
|
582
|
+
static logSuccess(operation: string, result: any) {
|
|
583
|
+
this.info(`Operation completed: ${operation}`, { result });
|
|
584
|
+
}
|
|
585
|
+
|
|
586
|
+
static logFailure(operation: string, error: any) {
|
|
587
|
+
this.error(`Operation failed: ${operation}`, error);
|
|
588
|
+
}
|
|
589
|
+
}
|
|
590
|
+
```
|
|
591
|
+
|
|
592
|
+
---
|
|
593
|
+
|
|
594
|
+
## Navigation
|
|
595
|
+
- [← Back to Main Documentation](../README.md)
|
|
596
|
+
- [Authentication & Setup](./auth.md)
|
|
597
|
+
- [AssetMethods](./asset-methods.md)
|
|
598
|
+
- [BatchMethods](./batch-methods.md)
|
|
599
|
+
- [ContainerMethods](./container-methods.md)
|
|
600
|
+
- [ContentMethods](./content-methods.md)
|
|
601
|
+
- [InstanceMethods](./instance-methods.md)
|
|
602
|
+
- [InstanceUserMethods](./instance-user-methods.md)
|
|
603
|
+
- [ModelMethods](./model-methods.md)
|
|
604
|
+
- [PageMethods](./page-methods.md)
|
|
605
|
+
- [ServerUserMethods](./server-user-methods.md)
|
|
606
|
+
- [WebhookMethods](./webhook-methods.md)
|
|
607
|
+
- [Multi-Instance Operations](./multi-instance-operations.md)
|