diff --git a/lib/config.ts b/lib/config.ts index 39cc327..9bf1613 100644 --- a/lib/config.ts +++ b/lib/config.ts @@ -44,6 +44,8 @@ export const deliveryConfig = { taxonomiesFolderName: `taxonomies`, systemTypesFolderName: 'system', coreCodenamesFilename: 'delivery.codenames', + coreTypeFilename: 'core.type', + coreContentTypeName: 'CoreContentType', sdkTypes: { contentItem: 'IContentItem', diff --git a/lib/generators/delivery/delivery-content-type.generator.ts b/lib/generators/delivery/delivery-content-type.generator.ts index 9422344..950df88 100644 --- a/lib/generators/delivery/delivery-content-type.generator.ts +++ b/lib/generators/delivery/delivery-content-type.generator.ts @@ -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(', ') }) ]; }; @@ -198,7 +191,7 @@ export function deliveryContentTypeGenerator(config: DeliveryContentTypeGenerato return { imports: sortAlphabetically( [ - ...getSystemTypeImports(), + ...getContentTypeSystemImports(), ...getReferencedTypeImports(data.contentType, data.flattenedElements), ...getReferencedTaxonomyImports(data.flattenedElements), ...getSnippetImports(snippets) @@ -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 ); }; @@ -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')} @@ -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')} @@ -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}'>; `; }; @@ -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(' | ')};`; }; @@ -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) { @@ -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; @@ -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()] }; } }; diff --git a/sample/delivery/content-types/actor.ts b/sample/delivery/content-types/actor.ts index 3d93e16..8458be0 100644 --- a/sample/delivery/content-types/actor.ts +++ b/sample/delivery/content-types/actor.ts @@ -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 @@ -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 @@ -67,10 +67,5 @@ export type Actor = IContentItem< */ readonly photo: Elements.AssetsElement; }, - 'actor', - LanguageCodenames, - CollectionCodenames, - WorkflowCodenames, - WorkflowStepCodenames, - ActorElementCodenames + 'actor' >; diff --git a/sample/delivery/content-types/movie.ts b/sample/delivery/content-types/movie.ts index 09273ad..14998bb 100644 --- a/sample/delivery/content-types/movie.ts +++ b/sample/delivery/content-types/movie.ts @@ -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 @@ -38,7 +37,7 @@ export type MovieElementCodenames = * Id: b0c0f9c2-ffb6-4e62-bac9-34e14172dd8c * Codename: movie */ -export type Movie = IContentItem< +export type Movie = CoreContentType< { /** * Title @@ -57,7 +56,7 @@ export type Movie = IContentItem< * Codename: plot * Id: f7ee4f27-27fd-a19b-3c5c-102aae1c50ce */ - readonly plot: Elements.RichTextElement; + readonly plot: Elements.RichTextElement; /** * Released * @@ -124,10 +123,5 @@ export type Movie = IContentItem< */ readonly releasecategory: Elements.TaxonomyElement; }, - 'movie', - LanguageCodenames, - CollectionCodenames, - WorkflowCodenames, - WorkflowStepCodenames, - MovieElementCodenames + 'movie' >; diff --git a/sample/delivery/system/core.type.ts b/sample/delivery/system/core.type.ts new file mode 100644 index 0000000..70e918d --- /dev/null +++ b/sample/delivery/system/core.type.ts @@ -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; diff --git a/sample/delivery/system/index.ts b/sample/delivery/system/index.ts index f68040f..0e57cfc 100644 --- a/sample/delivery/system/index.ts +++ b/sample/delivery/system/index.ts @@ -13,4 +13,5 @@ * ------------------------------------------------------------------------------- **/ +export * from './core.type.js'; export * from './delivery.codenames.js';