contentful-typescript-generator
Version:
Used to generate typescript models from your Contentful environment
70 lines (63 loc) • 2.66 kB
JavaScript
import * as contentfulManagement from 'contentful-management';
function renderSymbol(field) {
const inValidation = field.validations?.find((v) => !!v.in);
return !!inValidation ? `contentful.EntryFieldTypes.Symbol<${inValidation.in.map((value) => `"${value}"`).join(" | ")}>` : "contentful.EntryFieldTypes.Symbol";
}
function renderEntryLink(field) {
const linkContentType = field.validations?.find((v) => v.linkContentType)?.linkContentType;
if (!linkContentType || linkContentType.length === 0) {
return "contentful.EntryFieldTypes.EntryLink";
}
return `contentful.EntryFieldTypes.EntryLink<${linkContentType.map((type) => `${type.charAt(0).toUpperCase() + type.slice(1)}EntrySkeleton`).join(" | ")}>`;
}
function renderAssetLink() {
return "contentful.EntryFieldTypes.AssetLink";
}
function renderLink(field) {
return field.linkType === "Entry" ? renderEntryLink(field) : renderAssetLink();
}
function renderArray(field) {
return field.items?.type === "Link" ? `contentful.EntryFieldTypes.Array<${renderLink(field.items)}>` : field.items?.type === "Symbol" ? `contentful.EntryFieldTypes.Array<${renderSymbol(field.items)}>` : "";
}
function renderFieldType(field) {
switch (field.type) {
case "Symbol":
return renderSymbol(field);
case "Link":
return renderLink(field);
case "Array":
return renderArray(field);
default:
return `contentful.EntryFieldTypes.${field.type}`;
}
}
async function getEnvironment(accessToken, spaceId, environmentId) {
const client = contentfulManagement.createClient({ accessToken });
const space = await client.getSpace(spaceId);
return space.getEnvironment(environmentId);
}
function renderField(field) {
const type = renderFieldType(field);
return [`/** ${field.name} */
`, field.id, ":", type, ";"].join("");
}
function renderContentType(contentType) {
const typeName = contentType.sys.id.charAt(0).toUpperCase() + contentType.sys.id.slice(1);
const fields = contentType.fields.filter((field) => field.omitted !== true).map((field) => renderField(field)).join("\n ");
return `export type ${typeName}EntrySkeleton = {
contentTypeId: "${contentType.sys.id}";
fields: {
${fields}
};
};`;
}
async function generateTypes(environment) {
try {
const contentTypes = await environment.getContentTypes();
const types = contentTypes.items.map((contentType) => renderContentType(contentType));
return 'import * as contentful from "contentful";\n\n' + types.join("\n\n");
} catch (error) {
console.error("Error writing TypeScript typings to file:", error);
}
}
export { generateTypes, getEnvironment };