UNPKG

contentful-orm

Version:

A TypeScript-first ORM for Contentful CMS that enables a code-first approach to content modeling

123 lines 5.13 kB
import contentfulManagement from 'contentful-management'; import { ContentfulFieldType } from '../types/index.js'; import { getContentTypeMetadata, getFieldsMetadata } from '../decorators/index.js'; const CONTENTFUL_FIELD_TYPES = { [ContentfulFieldType.Symbol]: 'Symbol', [ContentfulFieldType.Text]: 'Text', [ContentfulFieldType.RichText]: 'RichText', [ContentfulFieldType.Number]: 'Number', [ContentfulFieldType.Integer]: 'Integer', [ContentfulFieldType.Date]: 'Date', [ContentfulFieldType.Location]: 'Location', [ContentfulFieldType.Media]: 'Link', [ContentfulFieldType.Boolean]: 'Boolean', [ContentfulFieldType.Reference]: 'Link', [ContentfulFieldType.Array]: 'Array', [ContentfulFieldType.Object]: 'Object' }; export class ContentfulSync { client; space; environment; spaceId; environmentId; constructor(accessToken, spaceId, environmentId = 'master') { this.client = contentfulManagement.createClient({ accessToken }); this.spaceId = spaceId; this.environmentId = environmentId; this.space = this.client.getSpace(spaceId); this.environment = this.space.then(space => space.getEnvironment(environmentId)); } transformValidation(validation) { if (validation.regexp) { const { pattern, flags } = validation.regexp; return { ...validation, regexp: { pattern, flags: flags ?? '' } }; } return validation; } transformFieldsToContentful(fieldsMap) { return Array.from(fieldsMap.entries()).map(([fieldName, options]) => { const field = { id: fieldName, name: fieldName, type: CONTENTFUL_FIELD_TYPES[options.type], required: options.required ?? false, localized: options.localized ?? false, validations: options.validations?.map(v => this.transformValidation(v)) ?? [] }; if (options.type === ContentfulFieldType.Array) { field.items = { type: CONTENTFUL_FIELD_TYPES[options.itemsType ?? ContentfulFieldType.Text], validations: options.itemsValidations?.map(v => this.transformValidation(v)) ?? [] }; if (options.itemsLinkType) { field.items.linkType = options.itemsLinkType; } } if (options.type === ContentfulFieldType.Reference || options.type === ContentfulFieldType.Media) { field.linkType = options.type === ContentfulFieldType.Media ? 'Asset' : (options.linkType ?? 'Entry'); } return field; }); } async unpublishContentType(contentType) { try { if (contentType.isPublished()) { await contentType.unpublish(); } } catch (error) { console.log('Content type was not published, continuing...'); } } async syncContentType(target) { const metadata = getContentTypeMetadata(target); if (!metadata) { throw new Error(`No content type metadata found for ${target.name}`); } const fields = this.transformFieldsToContentful(getFieldsMetadata(target)); const contentType = { name: metadata.name, displayField: metadata.displayField, description: metadata.description, fields }; const environment = await this.environment; try { // Get the latest version of the content type const existingContentType = await environment.getContentType(metadata.name); console.log(`Updating content type: ${metadata.name}`); // Unpublish first if published if (existingContentType.isPublished()) { console.log('Unpublishing content type...'); await existingContentType.unpublish(); } // Get the latest version after unpublishing const latestVersion = await environment.getContentType(metadata.name); console.log('Updating content type with latest version...'); const updatedContentType = await latestVersion.update(contentType); // Publish the changes console.log('Publishing content type...'); await updatedContentType.publish(); console.log(`Successfully updated content type: ${metadata.name}`); } catch (error) { if (error.name === 'NotFound') { console.log(`Creating content type: ${metadata.name}`); const newContentType = await environment.createContentTypeWithId(metadata.name, contentType); await newContentType.publish(); console.log(`Successfully created content type: ${metadata.name}`); } else { throw error; } } } } //# sourceMappingURL=index.js.map