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.

170 lines (151 loc) 6.08 kB
import type { EnvironmentModels } from "@kontent-ai/management-sdk"; import chalk from "chalk"; import { type CliAction, type CreateFilesConfig, type EnvironmentEntity, environmentEntities, type GeneratedFile, type GeneratedSet, type ModuleFileExtension, } from "../../core/core.models.js"; import { uniqueFilter } from "../../core/core.utils.js"; import { getManagementKontentFetcher, type ManagementKontentFetcher } from "../../fetch/management-kontent-fetcher.js"; import { getFileManager } from "../../files/file-manager.js"; import type { FormatOptions } from "../../format/formatter.js"; import { type EnvironmentEntities, getEnvironmentGenerator } from "./environment.generator.js"; export type GenerateEnvironmentModelsConfig = { readonly environmentId: string; readonly addTimestamp: boolean; readonly managementApiKey: string; readonly entities?: readonly EnvironmentEntity[]; readonly moduleFileExtension: ModuleFileExtension; readonly managementBaseUrl?: string; readonly formatOptions?: FormatOptions; readonly disableComments?: boolean; } & CreateFilesConfig; export async function generateEnvironmentModelsAsync(config: GenerateEnvironmentModelsConfig): Promise<readonly GeneratedFile[]> { console.log(chalk.green("Model generator started \n")); console.log(`Generating '${chalk.yellow("environment" satisfies CliAction)}' models\n`); const { environmentFiles, environmentInfo } = await getFilesAsync(config); const fileManager = getFileManager({ disableComments: config.disableComments ?? false, ...config, environmentInfo, }); const setFiles = await fileManager.getSetFilesAsync([environmentFiles]); if (config.createFiles) { fileManager.createFiles(setFiles); } console.log(chalk.green("\nCompleted")); return setFiles; } async function getFilesAsync(config: GenerateEnvironmentModelsConfig): Promise<{ readonly environmentFiles: GeneratedSet; readonly moduleFileExtension: ModuleFileExtension; readonly environmentInfo: Readonly<EnvironmentModels.EnvironmentInformationModel>; }> { const kontentFetcher = getManagementKontentFetcher({ environmentId: config.environmentId, managementApiKey: config.managementApiKey, baseUrl: config.managementBaseUrl, }); const entitiesToCreate: readonly EnvironmentEntity[] = config.entities ?? environmentEntities; // default to all entities export const environmentInfo = await kontentFetcher.getEnvironmentInfoAsync(); const entities = await getEntitiesAsync({ kontentFetcher, entitiesConfig: entitiesToCreate, }); return { environmentInfo, environmentFiles: getEnvironmentGenerator({ environmentInfo, environmentEntities: entities, entitiesToCreate: entitiesToCreate, disableComments: config.disableComments ?? false, }).generateEnvironmentModels(), moduleFileExtension: config.moduleFileExtension, }; } async function getEntitiesAsync({ kontentFetcher, entitiesConfig, }: { kontentFetcher: ManagementKontentFetcher; entitiesConfig: readonly EnvironmentEntity[]; }): Promise<EnvironmentEntities> { const entitiesToFetch = getEntitiesToFetchFromApi(entitiesConfig); const [ languages, taxonomies, contentTypes, snippets, collections, workflows, webhooks, assetFolders, roles, customApps, spaces, previewUrls, ] = await Promise.all([ fetchEntity({ canFetch: () => entitiesToFetch.includes("languages"), fetch: () => kontentFetcher.getLanguagesAsync() }), fetchEntity({ canFetch: () => entitiesToFetch.includes("taxonomies"), fetch: () => kontentFetcher.getTaxonomiesAsync() }), fetchEntity({ canFetch: () => entitiesToFetch.includes("contentTypes"), fetch: () => kontentFetcher.getTypesAsync() }), fetchEntity({ canFetch: () => entitiesToFetch.includes("snippets"), fetch: () => kontentFetcher.getSnippetsAsync() }), fetchEntity({ canFetch: () => entitiesToFetch.includes("collections"), fetch: () => kontentFetcher.getCollectionsAsync() }), fetchEntity({ canFetch: () => entitiesToFetch.includes("workflows"), fetch: () => kontentFetcher.getWorkflowsAsync() }), fetchEntity({ canFetch: () => entitiesToFetch.includes("webhooks"), fetch: () => kontentFetcher.getWebhooksAsync() }), fetchEntity({ canFetch: () => entitiesToFetch.includes("assetFolders"), fetch: () => kontentFetcher.getAssetFoldersAsync(), }), fetchEntity({ canFetch: () => entitiesToFetch.includes("roles"), fetch: () => kontentFetcher.getRolesAsync() }), fetchEntity({ canFetch: () => entitiesToFetch.includes("customApps"), fetch: () => kontentFetcher.getCustomApps() }), fetchEntity({ canFetch: () => entitiesToFetch.includes("spaces"), fetch: () => kontentFetcher.getSpaces() }), fetchEntity({ canFetch: () => entitiesToFetch.includes("previewUrls"), fetch: () => kontentFetcher.getPreviewUrlConfiguration(), }), ]); return { assetFolders, collections, languages, roles, snippets, taxonomies, contentTypes, webhooks, workflows, customApps, previewUrls, spaces, }; } function getEntitiesToFetchFromApi(entityTypes: readonly EnvironmentEntity[]): readonly EnvironmentEntity[] { return ( [ ...entityTypes, // when requesting snippets or content types, we need to fetch taxonomies & (snippets or types) as well // this is is because we need these entities to narrow down types for elements ...(entityTypes.includes("contentTypes") || entityTypes.includes("snippets") ? (["taxonomies", "snippets", "contentTypes"] satisfies readonly EnvironmentEntity[]) : []), // when requesting preview urls, we need to fetch spaces & content types as well ...(entityTypes.includes("previewUrls") ? (["spaces", "contentTypes"] satisfies readonly EnvironmentEntity[]) : []), ] satisfies readonly EnvironmentEntity[] ).filter(uniqueFilter); } function fetchEntity<T>({ canFetch, fetch, }: { canFetch: () => boolean; fetch: () => Promise<(T extends Array<T> ? readonly Array<T>[] : T) | undefined>; }): Promise<(T extends Array<T> ? readonly Array<T>[] : T) | undefined> { if (!canFetch()) { return Promise.resolve(undefined); } return fetch(); }