UNPKG

@kontent-ai/model-generator

Version:

This utility generates strongly-typed models for Delivery JS SDK, Migration toolkit or just general scripting to improve the experience when referencing Kontent.ai related objects.

396 lines 19.1 kB
import { match } from "ts-pattern"; import { toGuidelinesComment, wrapComment } from "../../core/comment.utils.js"; import { findRequired, getStringOrUndefinedAsPropertyValue, isNotUndefined, toSafePropertyValue } from "../../core/core.utils.js"; import { getFlattenedElements } from "../../core/element.utils.js"; import { resolvePropertyName } from "../../core/resolvers.js"; export function getEnvironmentGenerator(config) { const generateEnvironmentModels = () => { return { folderName: "structure", files: [ getEntityFile({ entitiesToCreate: config.entitiesToCreate, entitiesProp: "languages", filename: "languages.ts", exportedConstName: "languages", entities: config.environmentEntities.languages, getCode: getLanguages, }), getEntityFile({ entitiesToCreate: config.entitiesToCreate, entitiesProp: "collections", filename: "collections.ts", exportedConstName: "collections", entities: config.environmentEntities.collections, getCode: getCollections, }), getEntityFile({ entitiesToCreate: config.entitiesToCreate, entitiesProp: "contentTypes", filename: "contentTypes.ts", exportedConstName: "contentTypes", entities: config.environmentEntities.contentTypes, getCode: getContentTypes, }), getEntityFile({ entitiesToCreate: config.entitiesToCreate, entitiesProp: "snippets", filename: "contentTypeSnippets.ts", exportedConstName: "contentTypeSnippets", entities: config.environmentEntities.snippets, getCode: getSnippets, }), getEntityFile({ entitiesToCreate: config.entitiesToCreate, entitiesProp: "workflows", filename: "workflows.ts", exportedConstName: "workflows", entities: config.environmentEntities.workflows, getCode: getWorkflows, }), getEntityFile({ entitiesToCreate: config.entitiesToCreate, entitiesProp: "roles", filename: "roles.ts", exportedConstName: "roles", entities: config.environmentEntities.roles, getCode: getRoles, }), getEntityFile({ entitiesToCreate: config.entitiesToCreate, entitiesProp: "assetFolders", filename: "assetFolders.ts", exportedConstName: "assetFolders", entities: config.environmentEntities.assetFolders, getCode: getAssetFolders, }), getEntityFile({ entitiesToCreate: config.entitiesToCreate, entitiesProp: "webhooks", filename: "webhooks.ts", exportedConstName: "webhooks", entities: config.environmentEntities.webhooks, getCode: getWebhooks, }), getEntityFile({ entitiesToCreate: config.entitiesToCreate, entitiesProp: "taxonomies", filename: "taxonomies.ts", exportedConstName: "taxonomies", entities: config.environmentEntities.taxonomies, getCode: getTaxonomies, }), getEntityFile({ entitiesToCreate: config.entitiesToCreate, entitiesProp: "customApps", filename: "customApps.ts", exportedConstName: "customApps", entities: config.environmentEntities.customApps, getCode: getCustomApps, }), getEntityFile({ entitiesToCreate: config.entitiesToCreate, entitiesProp: "spaces", filename: "spaces.ts", exportedConstName: "spaces", entities: config.environmentEntities.spaces, getCode: getSpaces, }), getEntityFile({ entitiesToCreate: config.entitiesToCreate, entitiesProp: "previewUrls", filename: "previewUrls.ts", exportedConstName: "previewUrls", entities: config.environmentEntities.previewUrls, getCode: getPreviewUrls, }), ].filter(isNotUndefined), }; }; const getEntityFile = ({ entities, getCode, filename, entitiesToCreate, exportedConstName, entitiesProp, }) => { if (!(entities && entitiesToCreate.includes(entitiesProp))) { return undefined; } return { filename: filename, text: wrapInConst({ constName: exportedConstName, text: getCode(entities) }), }; }; const getLanguages = (languages) => { return languages.reduce((code, language, index) => { const isLast = index === languages.length - 1; return `${code}\n ${wrapComment(language.name)} ${resolvePropertyName(language.codename)}: { name: '${toSafePropertyValue(language.name)}', codename: '${language.codename}', id: '${language.id}', isActive: ${language.isActive ? "true" : "false"}, isDefault: ${language.isDefault ? "true" : "false"}, fallbackLanguageId: ${getStringOrUndefinedAsPropertyValue(language.fallbackLanguage?.id)}, externalId: ${getStringOrUndefinedAsPropertyValue(language.externalId)}, }${!isLast ? ",\n" : ""}`; }, ""); }; const getWorkflows = (workflows) => { return workflows.reduce((code, workflow, index) => { const isLast = index === workflows.length - 1; return `${code}\n ${wrapComment(workflow.name)} ${workflow.codename}: { name: '${toSafePropertyValue(workflow.name)}', codename: '${workflow.codename}', id: '${workflow.id}', steps: ${getWorkflowSteps(workflow)} }${!isLast ? ",\n" : ""}`; }, ""); }; const getCustomApps = (customApps) => { return customApps.reduce((code, customApp, index) => { const isLast = index === customApps.length - 1; return `${code}\n ${wrapComment(customApp.name)} ${resolvePropertyName(customApp.codename)}: { name: '${toSafePropertyValue(customApp.name)}', codename: '${customApp.codename}', sourceUrl: '${customApp.source_url}' }${!isLast ? ",\n" : ""}`; }, ""); }; const getSpaces = (spaces) => { return spaces.reduce((code, space, index) => { const isLast = index === spaces.length - 1; return `${code}\n ${wrapComment(space.name)} ${resolvePropertyName(space.codename)}: { name: '${toSafePropertyValue(space.name)}', codename: '${space.codename}', id: '${space.id}' }${!isLast ? ",\n" : ""}`; }, ""); }; const getPreviewUrls = (previewConfiguration) => { const spaces = config.environmentEntities.spaces; const contentTypes = config.environmentEntities.contentTypes; if (!spaces) { throw new Error("Spaces are expected to be present in the environment entities."); } if (!contentTypes) { throw new Error("Content types are expected to be present in the environment entities."); } return ` spaceDomains: { ${previewConfiguration.spaceDomains.reduce((code, spaceDomain, index) => { const isLast = index === previewConfiguration.spaceDomains.length - 1; const space = findRequired(spaces, (m) => m.id === spaceDomain.space.id, `Space with id '${spaceDomain.space.id}' not found.`); return `${code}\n ${space.codename}: { spaceName: '${toSafePropertyValue(space.name)}', spaceCodename: '${space.codename}', domain: '${spaceDomain.domain}' }${!isLast ? ",\n" : ""}`; }, "")} }, previewUrlPatterns: { ${previewConfiguration.previewUrlPatterns.reduce((code, previewUrlPattern, index) => { const isLast = index === previewConfiguration.previewUrlPatterns.length - 1; const contentType = findRequired(contentTypes, (m) => m.id === previewUrlPattern.contentType.id, `Content type with id '${previewUrlPattern.contentType.id}' not found.`); return `${code}\n ${contentType.codename}: { contentTypeName: '${toSafePropertyValue(contentType.name)}', contentTypeCodename: '${contentType.codename}', urlPatterns: { ${previewUrlPattern.urlPatterns.reduce((code, urlPattern, index) => { const isLast = index === previewUrlPattern.urlPatterns.length - 1; const space = config.environmentEntities.spaces?.find((m) => m.id === urlPattern.space?.id); return `${code}\n ${space?.codename ?? "default"}: { spaceName: ${getStringOrUndefinedAsPropertyValue(space?.name)}, spaceCodename: ${getStringOrUndefinedAsPropertyValue(space?.codename)}, url: '${urlPattern.urlPattern}', }${!isLast ? ",\n" : ""}`; }, "")} } }${!isLast ? ",\n" : ""}`; }, "")} } `; }; const getAssetFolders = (assetFolders, isFirstLevel = true) => { return (assetFolders.reduce((code, assetFolder, index) => { const isLast = index === assetFolders.length - 1; return `${code}\n ${wrapComment(assetFolder.name)} ${assetFolder.codename}: { name: '${toSafePropertyValue(assetFolder.name)}', codename: '${assetFolder.codename}', id: '${assetFolder.id}', externalId: ${getStringOrUndefinedAsPropertyValue(assetFolder.externalId)}, folders: ${getAssetFolders(assetFolder.folders, false)}}${!isLast ? ",\n" : ""}`; }, !isFirstLevel ? "{" : "") + (!isFirstLevel ? "}" : "")); }; const getSnippets = (snippets) => { return snippets.reduce((code, snippet, index) => { const isLast = index === snippets.length - 1; return `${code}\n ${wrapComment(snippet.name)} ${snippet.codename}: { name: '${toSafePropertyValue(snippet.name)}', codename: '${snippet.codename}', id: '${snippet.id}', externalId: ${getStringOrUndefinedAsPropertyValue(snippet.externalId)}, elements: {${getContentTypeElements(snippet.elements)}} }${!isLast ? ",\n" : ""}`; }, ""); }; const getContentTypes = (contentTypes) => { return contentTypes.reduce((code, contentType, index) => { const isLast = index === contentTypes.length - 1; return `${code}\n ${wrapComment(contentType.name)} ${contentType.codename}: { name: '${toSafePropertyValue(contentType.name)}', codename: '${contentType.codename}', id: '${contentType.id}', externalId: ${getStringOrUndefinedAsPropertyValue(contentType.externalId)}, elements: {${getContentTypeElements(contentType.elements)}} }${!isLast ? ",\n" : ""}`; }, ""); }; const getContentTypeElements = (elements) => { if (!config.environmentEntities.snippets) { throw new Error("Snippets are expected to be present in the environment entities."); } if (!config.environmentEntities.taxonomies) { throw new Error("Taxonomies are expected to be present in the environment entities."); } if (!config.environmentEntities.contentTypes) { throw new Error("Content types are expected to be present in the environment entities."); } const flattenedElements = getFlattenedElements({ elements: elements, snippets: config.environmentEntities.snippets, taxonomies: config.environmentEntities.taxonomies, types: config.environmentEntities.contentTypes, }); return flattenedElements.reduce((code, element, index) => { const isLast = index === flattenedElements.length - 1; const elementOptions = getElementOptionsCode(element); return `${code} ${wrapComment(element.title, { lines: [ { name: "Guidelines", value: element.guidelines ? toGuidelinesComment(element.guidelines) : undefined, }, ], })} ${element.codename}: { name: '${toSafePropertyValue(element.title)}', codename: '${element.codename}', id: '${element.id}', externalId: ${getStringOrUndefinedAsPropertyValue(element.externalId)}, required: ${element.isRequired}, type: '${element.type}' ${elementOptions ? `, options: ${elementOptions}` : ""} }${!isLast ? ",\n" : ""}`; }, ""); }; const getElementOptionsCode = (flattenedElement) => { return match(flattenedElement.originalElement) .returnType() .with({ type: "multiple_choice" }, (element) => { return `${element.options.reduce((code, option, index) => { const isLast = index === element.options.length - 1; return `${code}\n ${wrapComment(option.name)} ${option.codename ? option.codename : resolvePropertyName(option.name)}: { name: '${toSafePropertyValue(option.name)}', id: '${option.id}', codename: ${getStringOrUndefinedAsPropertyValue(option.codename)}, externalId: ${getStringOrUndefinedAsPropertyValue(option.external_id)} }${!isLast ? ",\n" : ""}`; }, "{")}}`; }) .otherwise(() => undefined); }; const getTaxonomies = (taxonomies) => { return taxonomies.reduce((code, taxonomy, index) => { const isLast = index === taxonomies.length - 1; return `${code}\n ${wrapComment(taxonomy.name)} ${taxonomy.codename}: { name: '${toSafePropertyValue(taxonomy.name)}', codename: '${taxonomy.codename}', externalId: ${getStringOrUndefinedAsPropertyValue(taxonomy.externalId)}, id: '${taxonomy.id}', ${getTaxonomyTerms(taxonomy.terms)} }${!isLast ? ",\n" : ""}`; }, ""); }; const getCollections = (collections) => { return collections.reduce((code, collection, index) => { const isLast = index === collections.length - 1; return `${code}\n ${wrapComment(collection.name)} ${collection.codename}: { name: '${toSafePropertyValue(collection.name)}', codename: '${collection.codename}', id: '${collection.id}' }${!isLast ? ",\n" : ""}`; }, ""); }; const getRoles = (roles) => { return roles.reduce((code, role, index) => { const isLast = index === roles.length - 1; return `${code}\n ${wrapComment(role.name)} ${resolvePropertyName(role.codename ?? role.name)}: { name: '${toSafePropertyValue(role.name)}', codename: ${getStringOrUndefinedAsPropertyValue(role.codename)}, id: '${role.id}' }${!isLast ? ",\n" : ""}`; }, ""); }; const getWebhooks = (webhooks) => { return webhooks.reduce((code, webhook, index) => { const isLast = index === webhooks.length - 1; return `${code}\n ${wrapComment(webhook.name)} ${resolvePropertyName(webhook.name)}: { name: '${toSafePropertyValue(webhook.name)}', url: '${webhook.url}', id: '${webhook.id}' }${!isLast ? ",\n" : ""}`; }, ""); }; const getTaxonomyTerms = (terms) => { return `${terms.reduce((code, term, index) => { const isLast = index === terms.length - 1; return `${code}\n ${wrapComment(term.name)} ${term.codename}: { name: '${toSafePropertyValue(term.name)}', codename: '${term.codename}', id: '${term.id}', externalId: ${getStringOrUndefinedAsPropertyValue(term.externalId)}, ${getTaxonomyTerms(term.terms)} }${!isLast ? ",\n" : ""}`; }, "terms: {")}}`; }; const getWorkflowSteps = (workflow) => { // The order of these steps should reflect the order in which they appear in the Kontent UI const steps = [...workflow.steps, workflow.scheduledStep, workflow.publishedStep, workflow.archivedStep]; return `{${steps.reduce((code, step) => { return `${code} ${step.codename}: { name: '${toSafePropertyValue(step.name)}', codename: '${step.codename}', id: '${step.id}' },`; }, "")}}`; }; const wrapInConst = ({ constName, text }) => { return `export const ${constName} = { ${text} } as const;`; }; return { generateEnvironmentModels, }; } //# sourceMappingURL=environment.generator.js.map