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.

116 lines (103 loc) 3.81 kB
import type { IContentItem } from "@kontent-ai/delivery-sdk"; import type { ContentTypeModels } from "@kontent-ai/management-sdk"; import Chalk from "chalk"; import { itemsConfig } from "../../config.js"; import { wrapComment } from "../../core/comment.utils.js"; import type { GeneratedSet } from "../../core/core.models.js"; import { resolveCase } from "../../core/resolvers.js"; export interface ItemGeneratorConfig { readonly environmentData: { readonly items: readonly Readonly<IContentItem>[]; readonly types: readonly Readonly<ContentTypeModels.ContentType>[]; }; } export function getItemsGenerator(config: ItemGeneratorConfig) { const getItemCodenameType = (typeCodename: string, items: readonly Readonly<IContentItem>[]): string => { return `export type ${resolveCase(typeCodename, "pascalCase")}Codenames = ${items.map((item) => `'${item.system.codename}'`).join(" | ")};`; }; const getItemCodenamesProp = (typeCodename: string, items: readonly Readonly<IContentItem>[]): string => { const values = items.reduce((code, item, index) => { const isLast = index === items.length - 1; return `${code}\n ${wrapComment(item.system.name)} ${item.system.codename}: { codename: '${item.system.codename}', id: '${item.system.id}' }${!isLast ? ",\n" : ""}`; }, ""); return `export const ${typeCodename}Items = { ${values} } as const;`; }; const groupItemsByType = (items: readonly Readonly<IContentItem>[]): Map<string, readonly Readonly<IContentItem>[]> => { return items.reduce<Map<string, readonly Readonly<IContentItem>[]>>((itemsByType, item) => { const existingGroupItems = itemsByType.get(item.system.type); if (existingGroupItems) { itemsByType.set(item.system.type, [...existingGroupItems, item]); } else { itemsByType.set(item.system.type, [item]); } return itemsByType; }, new Map<string, readonly Readonly<IContentItem>[]>()); }; return { getItemFiles(): GeneratedSet { return { folderName: itemsConfig.itemsFolderName, files: Array.from(groupItemsByType(config.environmentData.items)).map(([typeCodename, items]) => { const type = config.environmentData.types.find((t) => t.codename.toLowerCase() === typeCodename.toLowerCase()); if (!type) { throw new Error(`Type with codename '${Chalk.red(typeCodename)}' not found`); } return { filename: `${typeCodename}.items.ts`, text: `${wrapComment("Object representing identifiers of available items", { lines: [ { name: "Type name", value: type.name, }, { name: "Codename", value: type.codename, }, { name: "Id", value: type.id, }, ], })} ${getItemCodenamesProp(typeCodename, items)}`, }; }), }; }, getCodenameFiles(): GeneratedSet { return { folderName: itemsConfig.codenamesFolderName, files: Array.from(groupItemsByType(config.environmentData.items)).map(([typeCodename, items]) => { const type = config.environmentData.types.find((t) => t.codename.toLowerCase() === typeCodename.toLowerCase()); if (!type) { throw new Error(`Type with codename '${Chalk.red(typeCodename)}' not found`); } return { filename: `${typeCodename}.codenames.ts`, text: `${wrapComment("Type representing available item codenames", { lines: [ { name: "Type name", value: type.name, }, { name: "Type codename", value: type.codename, }, ], })} ${getItemCodenameType(typeCodename, items)}`, }; }), }; }, }; }