diff --git a/packages/core/strapi/lib/commands/content-types/generate-types/attributes.js b/packages/core/strapi/lib/commands/content-types/generate-types/attributes.js index b3eda643d0..7ceb18fb99 100644 --- a/packages/core/strapi/lib/commands/content-types/generate-types/attributes.js +++ b/packages/core/strapi/lib/commands/content-types/generate-types/attributes.js @@ -11,9 +11,13 @@ const generateAttributesDefinition = (attributes, uid) => { attributesDefinitions.push([attributeName, type]); } - return attributesDefinitions + const formattedDefinitions = attributesDefinitions .map(([name, attributeType]) => ` ${name}: ${attributeType};`) .join('\n'); + + return ` attributes: { +${formattedDefinitions} + }`; }; const getAttributeType = (attribute, uid) => { diff --git a/packages/core/strapi/lib/commands/content-types/generate-types/components.js b/packages/core/strapi/lib/commands/content-types/generate-types/components.js index b77758c36d..84ce538574 100644 --- a/packages/core/strapi/lib/commands/content-types/generate-types/components.js +++ b/packages/core/strapi/lib/commands/content-types/generate-types/components.js @@ -1,20 +1,28 @@ 'use strict'; +const fp = require('lodash/fp'); + const { generateAttributesDefinition } = require('./attributes'); const { addImport } = require('./imports'); +const { mapKeyValuesToType } = require('./utils'); const generateComponentDefinition = (uid, schema, type) => { addImport('ComponentSchema'); + const componentInfo = mapKeyValuesToType(schema.info, 'info', 2); + const componentOptions = mapKeyValuesToType(schema.options, 'options', 2); + const componentPluginOptions = mapKeyValuesToType(schema.pluginOptions, 'pluginOptions', 2); + const componentAttributes = generateAttributesDefinition(schema.attributes, uid); + const definitions = [componentInfo, componentOptions, componentPluginOptions, componentAttributes] + .filter(def => !fp.isNil(def)) + .join('\n'); + return ` interface ${type} extends ComponentSchema { - attributes: { -${componentAttributes} - } -} -`; +${definitions} +}`; }; module.exports = { diff --git a/packages/core/strapi/lib/commands/content-types/generate-types/content-types.js b/packages/core/strapi/lib/commands/content-types/generate-types/content-types.js index ff0ec0d501..78acd3fc50 100644 --- a/packages/core/strapi/lib/commands/content-types/generate-types/content-types.js +++ b/packages/core/strapi/lib/commands/content-types/generate-types/content-types.js @@ -4,6 +4,7 @@ const fp = require('lodash/fp'); const { generateAttributesDefinition } = require('./attributes'); const { addImport } = require('./imports'); +const { mapKeyValuesToType } = require('./utils'); const generateContentTypeDefinition = (uid, schema, type) => { const { kind } = schema; @@ -11,15 +12,25 @@ const generateContentTypeDefinition = (uid, schema, type) => { addImport(baseInterface); + const contentTypeInfo = mapKeyValuesToType(schema.info, 'info', 2); + const contentTypeOptions = mapKeyValuesToType(schema.options, 'options', 2); + const contentTypePluginOptions = mapKeyValuesToType(schema.pluginOptions, 'pluginOptions', 2); + const contentTypeAttributes = generateAttributesDefinition(schema.attributes, uid); + const definitions = [ + contentTypeInfo, + contentTypeOptions, + contentTypePluginOptions, + contentTypeAttributes, + ] + .filter(def => !fp.isNil(def)) + .join('\n'); + return ` interface ${type} extends ${baseInterface} { - attributes: { -${contentTypeAttributes} - } -} -`; +${definitions} +}`; }; module.exports = { generateContentTypeDefinition }; diff --git a/packages/core/strapi/lib/commands/content-types/generate-types/index.js b/packages/core/strapi/lib/commands/content-types/generate-types/index.js index 1db85e9756..1b872002a3 100644 --- a/packages/core/strapi/lib/commands/content-types/generate-types/index.js +++ b/packages/core/strapi/lib/commands/content-types/generate-types/index.js @@ -30,7 +30,7 @@ module.exports = async function({ outDir, file }) { const fullDefinition = [ imports, - definitions.map(fp.get('definition')).join(''), + definitions.map(fp.get('definition')).join('\n'), globalDefinition, ].join(''); diff --git a/packages/core/strapi/lib/commands/content-types/generate-types/utils.js b/packages/core/strapi/lib/commands/content-types/generate-types/utils.js index 91b615b715..cdb804e436 100644 --- a/packages/core/strapi/lib/commands/content-types/generate-types/utils.js +++ b/packages/core/strapi/lib/commands/content-types/generate-types/utils.js @@ -9,7 +9,45 @@ const logWarning = message => { const getSchemaTypeName = fp.flow(fp.replace(/(:.)/, ' '), fp.camelCase, fp.upperFirst); +const mapKeyValuesToType = (object, typeName, indent = 0) => { + if (!object || fp.isEmpty(object)) { + return null; + } + + const formattedTypeName = typeName.includes('-') ? `'${typeName}'` : typeName; + + const properties = Object.entries(object) + .reduce((acc, [key, value]) => { + const offset = ' '.repeat(indent + 2); + const formattedKey = key.includes('-') ? `'${key}'` : key; + + // Common values + let newValue = value; + + // Object values + if (fp.isObject(value)) { + return `${acc} +${mapKeyValuesToType(value, key, indent + 2)}`; + } + + // String values + else if (fp.isString(value)) { + newValue = `'${value}'`; + } + + return `${acc} +${offset}${formattedKey}: ${newValue}`; + }, '') + // Removing leading \n (when acc is an empty string) + .slice(1); + + return `${' '.repeat(indent)}${formattedTypeName}: { +${properties} +${' '.repeat(indent)}};`; +}; + module.exports = { logWarning, getSchemaTypeName, + mapKeyValuesToType, }; diff --git a/packages/core/strapi/lib/types/core/schemas/index.d.ts b/packages/core/strapi/lib/types/core/schemas/index.d.ts index 4c1480c900..8f7b873c7e 100644 --- a/packages/core/strapi/lib/types/core/schemas/index.d.ts +++ b/packages/core/strapi/lib/types/core/schemas/index.d.ts @@ -4,11 +4,11 @@ import { KeysBy, StringRecord } from '../../utils'; /** * Litteral union type representing the possible natures of a content type */ - export type ContentTypeKind = 'singleType' | 'collectionType'; +export type ContentTypeKind = 'singleType' | 'collectionType'; - /** - * Litteral union type representing the possible types of a model - */ +/** + * Litteral union type representing the possible types of a model + */ export type SchemaModelType = 'contentType' | 'component'; /** @@ -58,12 +58,12 @@ export interface SchemaInfo { /** * Singular form of the content type name */ - singularName: string; + singularName?: string; /** * Plural form of the collection type name */ - pluralName: string; + pluralName?: string; /** * Description of the model @@ -85,7 +85,7 @@ export interface SchemaAttributes extends StringRecord {} * Structure containing every core schema options and their associated value */ export interface SchemaOptions { - draftAndPublish: boolean; + draftAndPublish?: boolean; populateCreatorFields?: boolean; comment?: string; } @@ -101,7 +101,7 @@ export interface ContentTypeSchema extends Schema { /** * Determine the type of the content type (single-type or collection-type) */ - kind: ContentTypeKind; + kind: ContentTypeKind; } /** @@ -123,4 +123,4 @@ export interface SingleTypeSchema extends ContentTypeSchema { */ export interface ComponentSchema extends Schema { modelType: 'component'; -} \ No newline at end of file +}