UNPKG

@agility/management-sdk

Version:
397 lines (302 loc) 19.8 kB
# Agility CMS & Management API TypeScript SDK ## Table of Contents - [About the Management API SDK](#about-the-management-api-sdk) - [Getting Started](#getting-started) - [Authentication & Setup](./docs/auth.md) - [API Method Classes](#api-method-classes) - [Examples](#examples) - [TypeScript Interfaces](#typescript-interfaces) - [Available Enums](#available-enums) --- ## About the Management API SDK - Provides a facility to developers to use the new Agility Management API more effectively. - Provides methods to perform operations on Assets, Batches, Containers, Content, Models, Pages, and Users. - **Content and Page Creation** - Create individual or multiple content items and pages (which automatically get added to batches). - **Essential batch workflow operations** - Perform publish, unpublish, approve, decline, and request approval operations on existing batches. - Ability to generate Content in bulk for a Website. - **Strongly typed TypeScript interfaces** for all batch operations with comprehensive error handling. ## Getting Started ### Prerequisites 1. Clone the repository agility-cms-management-sdk-typescript. 2. Import the index file to make use of the Options class. 3. You will need valid Agility CMS credentials to authenticate and obtain an access token. ### Authentication For detailed authentication instructions, including OAuth 2.0 setup, token management, and security best practices, see the **[Authentication & Setup Guide](./docs/auth.md)**. ### Making a Request #### Simple OAuth Authentication (Recommended) 1. First, initiate the authorization flow by making a GET request to the authorization endpoint: ```javascript const authUrl = 'https://mgmt.aglty.io/oauth/authorize'; //if you wish to implement offline access using refresh tokens, use this URL (enables refresh tokens) //const authUrl = 'https://mgmt.aglty.io/oauth/authorize?scope=offline-access '; const params = new URLSearchParams({ response_type: 'code', redirect_uri: 'YOUR_REDIRECT_URI', state: 'YOUR_STATE', scope: 'openid profile email offline_access' }); // Redirect the user to the authorization URL window.location.href = `${authUrl}?${params.toString()}`; ``` 2. After successful authentication, you'll receive an authorization code at your redirect URI. Use this code to obtain an access token: ```javascript const response = await fetch('https://mgmt.aglty.io/oauth/token', { method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, body: new URLSearchParams({ code: 'YOUR_AUTHORIZATION_CODE' }) }); const { access_token, refresh_token, expires_in } = await response.json(); ``` 3. Use the obtained token to initialize the SDK: ```javascript import * as mgmtApi from "@agility/management-sdk"; // Initialize the Options Class with your authentication token let options = new mgmtApi.Options(); options.token = access_token; // Use the token obtained from authentication // Initialize the APIClient Class let apiClient = new mgmtApi.ApiClient(options); let guid = "<<Provide the Guid of the Website>>"; let locale = "<<Provide the locale of the Website>>"; // Example: en-us // Now you can make authenticated requests var contentItem = await apiClient.contentMethods.getContentItem(22, guid, locale); console.log(JSON.stringify(contentItem)); ``` 4. When the access token expires, use the refresh token to obtain a new access token: ```javascript const response = await fetch('https://mgmt.aglty.io/oauth/refresh', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ refresh_token: 'YOUR_REFRESH_TOKEN' }) }); const { access_token, refresh_token, expires_in } = await response.json(); ``` #### Manual Token Authentication (For CI/CD) ```typescript import * as mgmtApi from "@agility/management-sdk"; // Token-based approach for CI/CD and automated environments const options = new mgmtApi.Options(); options.token = process.env.AGILITY_API_TOKEN; const apiClient = new mgmtApi.ApiClient(options); const guid = process.env.AGILITY_GUID; const locale = "en-us"; const contentItem = await apiClient.contentMethods.getContentItem(22, guid, locale); console.log('Content retrieved:', contentItem.fields.title); ``` > 💡 **Note**: The new OAuth authentication requires `keytar` for secure token storage. See the [Authentication & Setup Guide](./docs/auth.md) for OAuth setup or [CI/CD & Automated Environments](./docs/cicd.md) for token-based authentication. ## API Method Classes ### File and Media Management - **[AssetMethods](./docs/asset-methods.md)** - File and media management operations (15 functions) - [deleteFile](./docs/asset-methods.md#deletefile), [moveFile](./docs/asset-methods.md#movefile), [getMediaList](./docs/asset-methods.md#getmedialist), [getGalleries](./docs/asset-methods.md#getgalleries), [getGalleryById](./docs/asset-methods.md#getgallerybyid), [getGalleryByName](./docs/asset-methods.md#getgallerybyname), [getDefaultContainer](./docs/asset-methods.md#getdefaultcontainer), [saveGallery](./docs/asset-methods.md#savegallery), [deleteGallery](./docs/asset-methods.md#deletegallery), [getAssetByID](./docs/asset-methods.md#getassetbyid), [getAssetByUrl](./docs/asset-methods.md#getassetbyurl), [upload](./docs/asset-methods.md#upload), [createFolder](./docs/asset-methods.md#createfolder), [deleteFolder](./docs/asset-methods.md#deletefolder), [renameFolder](./docs/asset-methods.md#renamefolder) ### Workflow Operations - **[BatchMethods](./docs/batch-methods.md)** - Batch workflow operations (7 functions) - [getBatch](./docs/batch-methods.md#getbatch), [publishBatch](./docs/batch-methods.md#publishbatch), [unpublishBatch](./docs/batch-methods.md#unpublishbatch), [approveBatch](./docs/batch-methods.md#approvebatch), [declineBatch](./docs/batch-methods.md#declinebatch), [requestApprovalBatch](./docs/batch-methods.md#requestapprovalbatch), [getBatchTypes](./docs/batch-methods.md#getbatchtypes) ### Content Management - **[ContainerMethods](./docs/container-methods.md)** - Container management operations (8 functions) - [getContainerByID](./docs/container-methods.md#getcontainerbyid), [getContainersByModel](./docs/container-methods.md#getcontainersbymodel), [getContainerByReferenceName](./docs/container-methods.md#getcontainerbyreferencename), [getContainerSecurity](./docs/container-methods.md#getcontainersecurity), [getContainerList](./docs/container-methods.md#getcontainerlist), [getNotificationList](./docs/container-methods.md#getnotificationlist), [saveContainer](./docs/container-methods.md#savecontainer), [deleteContainer](./docs/container-methods.md#deletecontainer) - **[ContentMethods](./docs/content-methods.md)** - Content item operations (14 functions) - [getContentItem](./docs/content-methods.md#getcontentitem), [publishContent](./docs/content-methods.md#publishcontent), [unPublishContent](./docs/content-methods.md#unpublishcontent), [batchWorkflowContent](./docs/content-methods.md#batchworkflowcontent), [contentRequestApproval](./docs/content-methods.md#contentrequestapproval), [approveContent](./docs/content-methods.md#approvecontent), [declineContent](./docs/content-methods.md#declinecontent), [deleteContent](./docs/content-methods.md#deletecontent), [saveContentItem](./docs/content-methods.md#savecontentitem), [saveContentItems](./docs/content-methods.md#savecontentitems), [getContentItems](./docs/content-methods.md#getcontentitems), [getContentList](./docs/content-methods.md#getcontentlist), [getContentHistory](./docs/content-methods.md#getcontenthistory), [getContentComments](./docs/content-methods.md#getcontentcomments) - **[ModelMethods](./docs/model-methods.md)** - Content model operations (6 functions) - [getContentModel](./docs/model-methods.md#getcontentmodel), [getModelByReferenceName](./docs/model-methods.md#getmodelbyreferencename), [getContentModules](./docs/model-methods.md#getcontentmodules), [getPageModules](./docs/model-methods.md#getpagemodules), [saveModel](./docs/model-methods.md#savemodel), [deleteModel](./docs/model-methods.md#deletemodel) ### Page Management - **[PageMethods](./docs/page-methods.md)** - Page management operations (18 functions) - [getPage](./docs/page-methods.md#getpage), [getPageByPath](./docs/page-methods.md#getpagebypath), [getPageHistory](./docs/page-methods.md#getpagehistory), [getPageComments](./docs/page-methods.md#getpagecomments), [getPageList](./docs/page-methods.md#getpagelist), [getPageListByPageTemplateID](./docs/page-methods.md#getpagelistbypagetemplateid), [getPageListByPage](./docs/page-methods.md#getpagelistbypage), [getPageListByPageAndPageTemplateID](./docs/page-methods.md#getpagelistbypageandpagetemplateid), [getPageTree](./docs/page-methods.md#getpagetree), [getPageTemplateList](./docs/page-methods.md#getpagetemplatelist), [getPageSecurity](./docs/page-methods.md#getpagesecurity), [getPageItemTemplateList](./docs/page-methods.md#getpageitemtemplatelist), [getPageContentZones](./docs/page-methods.md#getpagecontentzones), [savePage](./docs/page-methods.md#savepage), [savePageSecurity](./docs/page-methods.md#savepagesecurity), [movePageItem](./docs/page-methods.md#movepageitem), [deletePage](./docs/page-methods.md#deletepage), [batchWorkflowPages](./docs/page-methods.md#batchworkflowpages) ### User Management - **[InstanceMethods](./docs/instance-methods.md)** - Instance-level operations (2 functions) - [getLocales](./docs/instance-methods.md#getlocales), [getFetchApiStatus](./docs/instance-methods.md#getfetchapistatus) - **[InstanceUserMethods](./docs/instance-user-methods.md)** - Instance user management (3 functions) - [getUsers](./docs/instance-user-methods.md#getusers), [saveUser](./docs/instance-user-methods.md#saveuser), [deleteUser](./docs/instance-user-methods.md#deleteuser) - **[ServerUserMethods](./docs/server-user-methods.md)** - Server user operations (2 functions) - [me](./docs/server-user-methods.md#me), [you](./docs/server-user-methods.md#you) ### Integration - **[WebhookMethods](./docs/webhook-methods.md)** - Webhook management (4 functions) - [getWebhook](./docs/webhook-methods.md#getwebhook), [webhookList](./docs/webhook-methods.md#webhooklist), [saveWebhook](./docs/webhook-methods.md#savewebhook), [deleteWebhook](./docs/webhook-methods.md#deletewebhook) ### Multi-Instance Operations - **[Multi-Instance Operations](./docs/multi-instance-operations.md)** - Advanced workflows for managing content across multiple instances and locales - Configuration-driven content creation across multiple environments - Parallel processing and batch operations - Performance optimization and error handling - Cross-instance synchronization and reporting ### CI/CD & Automation - **[CI/CD & Automated Environments](./docs/cicd.md)** - Token-based authentication for automated environments - CI/CD pipeline examples (GitHub Actions, GitLab CI, Jenkins) - Serverless functions (AWS Lambda, Vercel) - Environment configuration and security best practices - Token management and rotation ## Examples ### Understanding Agility CMS Batch Architecture Agility CMS uses a simple approach for working with content and batches: #### Content/Page Creation (Handled by Respective Controllers) - **contentMethods.saveContentItem()** - Creates a single new content item and adds it to a batch - **contentMethods.saveContentItems()** - Creates multiple new content items and adds them to a batch - **pageMethods.savePage()** - Creates a new page and adds it to a batch - These methods create the content AND automatically handle batch creation/management #### Batch Workflow Operations (Handled by Batch Controller) - **batchMethods.publishBatch()** - Publishes all items in an existing batch - **batchMethods.unpublishBatch()** - Unpublishes all items in an existing batch - **batchMethods.approveBatch()** - Approves all items in an existing batch - **batchMethods.declineBatch()** - Declines all items in an existing batch - **batchMethods.requestApprovalBatch()** - Requests approval for all items in an existing batch - **batchMethods.getBatch()** - Retrieves details of an existing batch - **batchMethods.getBatchTypes()** - Retrieves all batch-related enum types for developer discovery ### Complete Workflow Example ```typescript import * as mgmtApi from '@agility/management-sdk'; // Authenticate with simple OAuth flow const client = new mgmtApi.ApiClient(); await client.auth(); const guid = 'your-instance-guid'; const locale = 'en-us'; // Get batch types for dynamic UI and validation const batchTypes = await client.batchMethods.getBatchTypes(guid); console.log('Available batch types loaded:', batchTypes); // Create NEW content items (handled by content controller) // This automatically creates and manages batches const newContentBatchID = await client.contentMethods.saveContentItem(locale, { properties: { referenceName: 'blog-post', definitionName: 'BlogPost', state: 2 }, fields: { title: 'My New Blog Post', content: 'This is the blog post content...' } }); // Create NEW page (handled by page controller) // This automatically creates and manages batches const newPageBatchID = await client.pageMethods.savePage(locale, { name: 'new-product-page', title: 'New Product Page', menuText: 'New Product', pageType: 'static', templateName: 'Product Template', parentPageID: -1 }); // Retrieve details of an existing batch const batchDetails = await client.batchMethods.getBatch(newContentBatchID, guid); console.log('Batch details:', batchDetails); // Perform workflow operations on existing batches await client.batchMethods.publishBatch(newContentBatchID, guid); await client.batchMethods.approveBatch(newPageBatchID, guid); // Or use immediate return for custom polling const batchId = await client.batchMethods.publishBatch(newContentBatchID, guid, true); console.log('Batch submitted for publishing:', batchId); console.log('All operations completed successfully!'); ``` ### Batch Workflow Operations Perform workflow operations (publish, unpublish, approve, decline, request approval) on multiple content items or pages in a single operation using the `WorkflowOperationType` enum: ```typescript import * as mgmtApi from '@agility/management-sdk'; import { WorkflowOperationType } from '@agility/management-sdk'; const options = new mgmtApi.Options(); options.token = 'your-access-token'; const client = new mgmtApi.ApiClient(options); const guid = 'your-instance-guid'; const locale = 'en-us'; // Batch publish multiple content items const contentIDs = [101, 102, 103]; const publishedContentIDs = await client.contentMethods.batchWorkflowContent( contentIDs, guid, locale, WorkflowOperationType.Publish ); console.log('Published content IDs:', publishedContentIDs); // Batch unpublish multiple content items const unpublishedContentIDs = await client.contentMethods.batchWorkflowContent( contentIDs, guid, locale, WorkflowOperationType.Unpublish ); console.log('Unpublished content IDs:', unpublishedContentIDs); // Batch approve multiple content items const approvedContentIDs = await client.contentMethods.batchWorkflowContent( contentIDs, guid, locale, WorkflowOperationType.Approve ); console.log('Approved content IDs:', approvedContentIDs); // Batch publish multiple pages const pageIDs = [201, 202, 203]; const publishedPageIDs = await client.pageMethods.batchWorkflowPages( pageIDs, guid, locale, WorkflowOperationType.Publish ); console.log('Published page IDs:', publishedPageIDs); // Batch unpublish multiple pages const unpublishedPageIDs = await client.pageMethods.batchWorkflowPages( pageIDs, guid, locale, WorkflowOperationType.Unpublish ); console.log('Unpublished page IDs:', unpublishedPageIDs); // Get batch ID immediately for custom polling (optional 5th parameter) const [batchId] = await client.contentMethods.batchWorkflowContent( contentIDs, guid, locale, WorkflowOperationType.Publish, true ); console.log('Batch submitted, ID:', batchId); ``` ### Checking Fetch API Sync Status After batch operations, you may want to verify that changes have propagated to the Fetch API CDN before using the content on your frontend: ```typescript import * as mgmtApi from '@agility/management-sdk'; const options = new mgmtApi.Options(); options.token = 'your-access-token'; const client = new mgmtApi.ApiClient(options); const guid = 'your-instance-guid'; // After a batch publish operation, wait for CDN sync await client.batchMethods.publishBatch(batchId, guid); // Wait for sync to complete await client.instanceMethods.getFetchApiStatus(guid, 'fetch', true); console.log('Sync complete! Content is now available on the CDN'); // Or just check current status without waiting const status = await client.instanceMethods.getFetchApiStatus(guid); console.log('Sync in progress:', status.inProgress); ``` ## TypeScript Interfaces ### Batch Response Interfaces ```typescript interface BatchTypesResponse { itemTypes: EnumInfo[]; // Page, ContentItem, ContentList, Tag, ModuleDef operationTypes: EnumInfo[]; // All operation types workflowOperations: EnumInfo[]; // Publish, Unpublish, Approve, Decline, RequestApproval states: EnumInfo[]; // None, Pending, InProcess, Processed, Deleted } interface EnumInfo { value: number; // Numeric enum value name: string; // String name (e.g., "Publish") description: string; // Human-readable description } ``` ## Available Enums ### WorkflowOperationType (for batch processing) > **Note**: In the API documentation (Swagger UI), these operations appear as descriptive dropdown options (Publish, Unpublish, Approve, Decline, RequestApproval) instead of numbers. - `Publish = 1` - `Unpublish = 2` - `Approve = 3` - `Decline = 4` - `RequestApproval = 5` ### BatchItemType > **Note**: In the API documentation (Swagger UI), these appear as descriptive dropdown options (Page, ContentItem, ContentList, Tag, ModuleDef) instead of numbers. - `Page = 1` - `ContentItem = 2` - `ContentList = 3` - `Tag = 4` - `ModuleDef = 5` ### BatchState > **Note**: In the API documentation (Swagger UI), these appear as descriptive names (None, Pending, InProcess, Processed, Deleted) instead of numbers. - `None = 0` - Batch created but not submitted for processing - `Pending = 1` - Batch is pending processing - `InProcess = 2` - Batch is currently being processed - `Processed = 3` - Batch has been processed successfully - `Deleted = 4` - Batch has been deleted ## Error Handling All methods throw exceptions on failure: ```typescript try { const batch = await client.batchMethods.getBatch(123, 'instance-guid'); } catch (error) { console.error('Failed to get batch:', error.message); } ``` ## License MIT If you have feedback or questions about this starter, please use the [Github Issues](https://github.com/agility/agility-cms-management-sdk-typescript/issues) on this repo, join our [Community Slack Channel](https://join.slack.com/t/agilitycommunity/shared_invite/enQtNzI2NDc3MzU4Njc2LWI2OTNjZTI3ZGY1NWRiNTYzNmEyNmI0MGZlZTRkYzI3NmRjNzkxYmI5YTZjNTg2ZTk4NGUzNjg5NzY3OWViZGI) or create a post on the [Agility Developer Community](https://help.agilitycms.com/hc/en-us/community/topics).