Skip to content

Commit

Permalink
Adds core type representing typed IContentItem to further improve typ…
Browse files Browse the repository at this point in the history
…ings on elements & generic content item
  • Loading branch information
Enngage committed Oct 4, 2024
1 parent cafd2a2 commit 1afb705
Show file tree
Hide file tree
Showing 6 changed files with 150 additions and 98 deletions.
2 changes: 2 additions & 0 deletions lib/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ export const deliveryConfig = {
taxonomiesFolderName: `taxonomies`,
systemTypesFolderName: 'system',
coreCodenamesFilename: 'delivery.codenames',
coreTypeFilename: 'core.type',
coreContentTypeName: 'CoreContentType',

sdkTypes: {
contentItem: 'IContentItem',
Expand Down
157 changes: 93 additions & 64 deletions lib/generators/delivery/delivery-content-type.generator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,18 +81,11 @@ export function deliveryContentTypeGenerator(config: DeliveryContentTypeGenerato
taxonomy: mapName(config.nameResolvers?.taxonomy, 'pascalCase')
};

const getSystemTypeImports = (): readonly string[] => {
const getContentTypeSystemImports = (): readonly string[] => {
return [
importer.importType({
filePathOrPackage: `../${deliveryConfig.systemTypesFolderName}/${deliveryConfig.coreCodenamesFilename}.ts`,
importValue: [
sharedTypesConfig.collectionCodenames,
sharedTypesConfig.languageCodenames,
sharedTypesConfig.workflowCodenames,
sharedTypesConfig.workflowStepCodenames
]
.map((m) => m)
.join(', ')
filePathOrPackage: `../${deliveryConfig.systemTypesFolderName}/${coreConfig.barrelExportFilename}`,
importValue: [deliveryConfig.coreContentTypeName].map((m) => m).join(', ')
})
];
};
Expand Down Expand Up @@ -198,7 +191,7 @@ export function deliveryContentTypeGenerator(config: DeliveryContentTypeGenerato
return {
imports: sortAlphabetically(
[
...getSystemTypeImports(),
...getContentTypeSystemImports(),
...getReferencedTypeImports(data.contentType, data.flattenedElements),
...getReferencedTaxonomyImports(data.flattenedElements),
...getSnippetImports(snippets)
Expand Down Expand Up @@ -239,15 +232,15 @@ export function deliveryContentTypeGenerator(config: DeliveryContentTypeGenerato
};
};

const getDeliverySdkImports = (
const getTypeDeliverySdkImports = (
typeOrSnippet: ContentTypeOrSnippet,
flattenedElements: readonly FlattenedElement[]
): readonly string[] => {
const mainType =
typeOrSnippet instanceof ContentTypeModels.ContentType ? deliveryConfig.sdkTypes.contentItem : deliveryConfig.sdkTypes.snippet;

return sortAlphabetically(
[mainType, ...(flattenedElements.length ? [deliveryConfig.sdkTypes.elements] : [])],
[
...(typeOrSnippet instanceof ContentTypeSnippetModels.ContentTypeSnippet ? [deliveryConfig.sdkTypes.snippet] : []),
...(flattenedElements.length ? [deliveryConfig.sdkTypes.elements] : [])
],
(importValue) => importValue
);
};
Expand All @@ -270,7 +263,7 @@ export function deliveryContentTypeGenerator(config: DeliveryContentTypeGenerato
return `
${importer.importType({
filePathOrPackage: deliveryConfig.npmPackageName,
importValue: `${getDeliverySdkImports(snippet, flattenedElements).join(', ')}`
importValue: `${getTypeDeliverySdkImports(snippet, flattenedElements).join(', ')}`
})}
${importsResult.imports.join('\n')}
Expand Down Expand Up @@ -308,7 +301,7 @@ ${getElementsCode(flattenedElements)}>;
return `
${importer.importType({
filePathOrPackage: deliveryConfig.npmPackageName,
importValue: `${getDeliverySdkImports(contentType, flattenedElements).join(', ')}`
importValue: `${getTypeDeliverySdkImports(contentType, flattenedElements).join(', ')}`
})}
${importsResult.imports.join('\n')}
Expand All @@ -323,14 +316,9 @@ ${wrapComment(`
* Id: ${contentType.id}
* Codename: ${contentType.codename}
`)}
export type ${importsResult.typeName} = ${deliveryConfig.sdkTypes.contentItem}<
export type ${importsResult.typeName} = ${deliveryConfig.coreContentTypeName}<
${getElementsCode(flattenedElements)}${importsResult.contentTypeExtends ? ` ${importsResult.contentTypeExtends}` : ''},
'${contentType.codename}',
${sharedTypesConfig.languageCodenames},
${sharedTypesConfig.collectionCodenames},
${sharedTypesConfig.workflowCodenames},
${sharedTypesConfig.workflowStepCodenames},
${nameOfTypeRepresentingAllElementCodenames}>;
'${contentType.codename}'>;
`;
};

Expand Down Expand Up @@ -391,12 +379,6 @@ ${nameOfTypeRepresentingAllElementCodenames}>;
if (flattenedElements.length === 0) {
return `export type ${typeName} = never`;
}

const el = flattenedElements.find((m) => m.codename === 'link__f25fb651_eea8_4a0a_8e39_ac5a0f97ed72');
if (el) {
console.log(el);
}

return `export type ${typeName} = ${flattenedElements.map((element) => `'${element.codename}'`).join(' | ')};`;
};

Expand All @@ -406,24 +388,27 @@ ${nameOfTypeRepresentingAllElementCodenames}>;
.with({ type: 'text' }, () => 'TextElement')
.with({ type: 'number' }, () => 'NumberElement')
.with({ type: 'modular_content' }, (linkedItemsElement) => {
if (!linkedItemsElement.allowedContentTypes?.length) {
return 'LinkedItemsElement';
}
return `LinkedItemsElement<${getLinkedItemsAllowedTypes(linkedItemsElement.allowedContentTypes ?? []).join(' | ')}>`;
return `LinkedItemsElement<${
linkedItemsElement.allowedContentTypes?.length
? getLinkedItemsAllowedTypes(linkedItemsElement.allowedContentTypes).join(' | ')
: deliveryConfig.coreContentTypeName
}>`;
})
.with({ type: 'subpages' }, (linkedItemsElement) => {
if (!linkedItemsElement.allowedContentTypes?.length) {
return 'LinkedItemsElement';
}
return `LinkedItemsElement<${getLinkedItemsAllowedTypes(linkedItemsElement.allowedContentTypes ?? []).join(' | ')}>`;
return `LinkedItemsElement<${
linkedItemsElement.allowedContentTypes?.length
? getLinkedItemsAllowedTypes(linkedItemsElement.allowedContentTypes).join(' | ')
: deliveryConfig.coreContentTypeName
}>`;
})
.with({ type: 'asset' }, () => 'AssetsElement')
.with({ type: 'date_time' }, () => 'DateTimeElement')
.with({ type: 'rich_text' }, (richTextElement) => {
if (!richTextElement.allowedContentTypes?.length) {
return 'RichTextElement';
}
return `RichTextElement<${getLinkedItemsAllowedTypes(richTextElement.allowedContentTypes ?? []).join(' | ')}>`;
return `RichTextElement<${
richTextElement.allowedContentTypes?.length
? getLinkedItemsAllowedTypes(richTextElement.allowedContentTypes).join(' | ')
: deliveryConfig.coreContentTypeName
}>`;
})
.with({ type: 'multiple_choice' }, (multipleChoiceElement) => {
if (!multipleChoiceElement.multipleChoiceOptions?.length) {
Expand Down Expand Up @@ -451,6 +436,70 @@ ${nameOfTypeRepresentingAllElementCodenames}>;
return types.map((type) => nameResolvers.contentType(type));
};

const getCoreContentTypeFile = (): GeneratedFile => {
const sdkImports: string[] = [deliveryConfig.sdkTypes.contentItem, deliveryConfig.sdkTypes.contentItemElements];

const codenameImports: string[] = [
sharedTypesConfig.contentTypeCodenames,
sharedTypesConfig.collectionCodenames,
sharedTypesConfig.languageCodenames,
sharedTypesConfig.workflowCodenames,
sharedTypesConfig.workflowStepCodenames
];

const contentTypeGenericArgName: string = 'TContentTypeCodename';
const elementsGenericArgName: string = 'TElements';

return {
filename: `${deliveryConfig.coreTypeFilename}.ts`,
text: `
${importer.importType({
filePathOrPackage: deliveryConfig.npmPackageName,
importValue: `${sdkImports.join(', ')}`
})}
${importer.importType({
filePathOrPackage: `./${deliveryConfig.coreCodenamesFilename}.ts`,
importValue: `${codenameImports.join(', ')}`
})}
${wrapComment(`\n * Core content type used in favor of generic '${deliveryConfig.sdkTypes.contentItem}'\n`)}
export type ${deliveryConfig.coreContentTypeName}<
${elementsGenericArgName} extends ${deliveryConfig.sdkTypes.contentItemElements} = ${deliveryConfig.sdkTypes.contentItemElements},
${contentTypeGenericArgName} extends ${sharedTypesConfig.contentTypeCodenames} = ${sharedTypesConfig.contentTypeCodenames}
> = ${deliveryConfig.sdkTypes.contentItem}<
${elementsGenericArgName},
${contentTypeGenericArgName},
${sharedTypesConfig.languageCodenames},
${sharedTypesConfig.collectionCodenames},
${sharedTypesConfig.workflowCodenames},
${sharedTypesConfig.workflowStepCodenames}
>;
`
};
};

const getCodenamesFile = (): GeneratedFile => {
return {
filename: `${deliveryConfig.coreCodenamesFilename}.ts`,
text: `
${wrapComment(`\n * Type representing all languages\n`)}
${getLanguageCodenamesType(config.environmentData.languages)}
${wrapComment(`\n * Type representing all content types\n`)}
${getContentTypeCodenamesType(config.environmentData.types)}
${wrapComment(`\n * Type representing all collections\n`)}
${getCollectionCodenamesType(config.environmentData.collections)}
${wrapComment(`\n * Type representing all workflows\n`)}
${getWorkflowCodenamesType(config.environmentData.workflows)}
${wrapComment(`\n * Type representing all worksflow steps across all workflows\n`)}
${getWorkflowStepCodenamesType(config.environmentData.workflows)}
`
};
};

return {
generateModels: (): {
contentTypeFiles: GeneratedSet;
Expand All @@ -470,27 +519,7 @@ ${nameOfTypeRepresentingAllElementCodenames}>;
getSystemFiles(): GeneratedSet {
return {
folderName: deliveryConfig.systemTypesFolderName,
files: [
{
filename: `${deliveryConfig.coreCodenamesFilename}.ts`,
text: `
${wrapComment(`\n * Type representing all languages\n`)}
${getLanguageCodenamesType(config.environmentData.languages)}
${wrapComment(`\n * Type representing all content types\n`)}
${getContentTypeCodenamesType(config.environmentData.types)}
${wrapComment(`\n * Type representing all collections\n`)}
${getCollectionCodenamesType(config.environmentData.collections)}
${wrapComment(`\n * Type representing all workflows\n`)}
${getWorkflowCodenamesType(config.environmentData.workflows)}
${wrapComment(`\n * Type representing all worksflow steps across all workflows\n`)}
${getWorkflowStepCodenamesType(config.environmentData.workflows)}
`
}
]
files: [getCoreContentTypeFile(), getCodenamesFile()]
};
}
};
Expand Down
13 changes: 4 additions & 9 deletions sample/delivery/content-types/actor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@
* -------------------------------------------------------------------------------
**/

import type { Elements, IContentItem } from '@kontent-ai/delivery-sdk';
import type { CollectionCodenames, LanguageCodenames, WorkflowCodenames, WorkflowStepCodenames } from '../system/delivery.codenames.js';
import type { Elements } from '@kontent-ai/delivery-sdk';
import type { CoreContentType } from '../system/index.js';

/**
* Type representing all available element codenames for Actor
Expand All @@ -27,7 +27,7 @@ export type ActorElementCodenames = 'url' | 'first_name' | 'last_name' | 'photo'
* Id: 58099989-319f-495f-aa36-cb3710854e36
* Codename: actor
*/
export type Actor = IContentItem<
export type Actor = CoreContentType<
{
/**
* Url
Expand Down Expand Up @@ -67,10 +67,5 @@ export type Actor = IContentItem<
*/
readonly photo: Elements.AssetsElement;
},
'actor',
LanguageCodenames,
CollectionCodenames,
WorkflowCodenames,
WorkflowStepCodenames,
ActorElementCodenames
'actor'
>;
44 changes: 19 additions & 25 deletions sample/delivery/content-types/movie.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,21 @@
/**
* This file has been auto-generated by '@kontent-ai/model-generator@8.0.0-0'.
*
* (c) Kontent.ai
*
* -------------------------------------------------------------------------------
*
* Project: Movie Database
* Environment: Production
* Id: da5abe9f-fdad-4168-97cd-b3464be2ccb9
*
* -------------------------------------------------------------------------------
**/

/**
* This file has been auto-generated by '@kontent-ai/model-generator@8.0.0-0'.
*
* (c) Kontent.ai
*
* -------------------------------------------------------------------------------
*
* Project: Movie Database
* Environment: Production
* Id: da5abe9f-fdad-4168-97cd-b3464be2ccb9
*
* -------------------------------------------------------------------------------
**/

import type { Elements, IContentItem } from '@kontent-ai/delivery-sdk';
import type { Actor } from './index.js';
import type { CollectionCodenames, LanguageCodenames, WorkflowCodenames, WorkflowStepCodenames } from '../system/delivery.codenames.js';
import type { Elements } from '@kontent-ai/delivery-sdk';
import type { CoreContentType } from '../system/index.js';
import type { Releasecategory } from '../taxonomies/index.js';
import type { Actor } from './index.js';

/**
* Type representing all available element codenames for Movie
Expand All @@ -38,7 +37,7 @@ export type MovieElementCodenames =
* Id: b0c0f9c2-ffb6-4e62-bac9-34e14172dd8c
* Codename: movie
*/
export type Movie = IContentItem<
export type Movie = CoreContentType<
{
/**
* Title
Expand All @@ -57,7 +56,7 @@ export type Movie = IContentItem<
* Codename: plot
* Id: f7ee4f27-27fd-a19b-3c5c-102aae1c50ce
*/
readonly plot: Elements.RichTextElement;
readonly plot: Elements.RichTextElement<CoreContentType>;
/**
* Released
*
Expand Down Expand Up @@ -124,10 +123,5 @@ export type Movie = IContentItem<
*/
readonly releasecategory: Elements.TaxonomyElement<Releasecategory, 'releasecategory'>;
},
'movie',
LanguageCodenames,
CollectionCodenames,
WorkflowCodenames,
WorkflowStepCodenames,
MovieElementCodenames
'movie'
>;
31 changes: 31 additions & 0 deletions sample/delivery/system/core.type.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@

/**
* This file has been auto-generated by '@kontent-ai/model-generator@8.0.0-0'.
*
* (c) Kontent.ai
*
* -------------------------------------------------------------------------------
*
* Project: Movie Database
* Environment: Production
* Id: da5abe9f-fdad-4168-97cd-b3464be2ccb9
*
* -------------------------------------------------------------------------------
**/

import type { IContentItem, IContentItemElements } from '@kontent-ai/delivery-sdk';
import type {
ContentTypeCodenames,
CollectionCodenames,
LanguageCodenames,
WorkflowCodenames,
WorkflowStepCodenames
} from './delivery.codenames.js';

/**
* Core content type used in favor of generic 'IContentItem'
*/
export type CoreContentType<
TElements extends IContentItemElements = IContentItemElements,
TContentTypeCodename extends ContentTypeCodenames = ContentTypeCodenames
> = IContentItem<TElements, TContentTypeCodename, LanguageCodenames, CollectionCodenames, WorkflowCodenames, WorkflowStepCodenames>;
1 change: 1 addition & 0 deletions sample/delivery/system/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,5 @@
* -------------------------------------------------------------------------------
**/

export * from './core.type.js';
export * from './delivery.codenames.js';

0 comments on commit 1afb705

Please sign in to comment.