diff --git a/payload-types.ts b/payload-types.ts index edc51ecd4..96a6a8afa 100644 --- a/payload-types.ts +++ b/payload-types.ts @@ -8,6 +8,7 @@ export interface Config {} export interface NavigationArray { array?: { text?: string; + textarea?: string; id?: string; }[]; } @@ -17,317 +18,8 @@ export interface NavigationArray { */ export interface GlobalWithStrictAccess { title: string; -} -/** - * This interface was referenced by `Config`'s JSON-Schema - * via the `definition` "blocks-global". - */ -export interface BlocksGlobal { - blocks?: ( - | { - color: string; - id?: string; - blockName?: string; - blockType: 'quote'; - } - | { - label: string; - url: string; - id?: string; - blockName?: string; - blockType: 'cta'; - } - )[]; -} -/** - * This interface was referenced by `Config`'s JSON-Schema - * via the `definition` "admins". - */ -export interface Admin { - email?: string; - resetPasswordToken?: string; - apiKey?: string; - apiKeyIndex?: string; - loginAttempts?: number; -} -/** - * This interface was referenced by `Config`'s JSON-Schema - * via the `definition` "all-fields". - */ -export interface AllFields { - text: string; - descriptionText?: string; - descriptionFunction?: string; - email?: string; - number?: number; - group?: { - nestedText1?: string; - nestedText2?: string; - }; - array?: { - arrayText1: string; - arrayText2: string; - arrayText3?: string; - id?: string; - }[]; - blocks: ( - | { - testEmail: string; - id?: string; - blockName?: string; - blockType: 'email'; - } - | { - testNumber: number; - id?: string; - blockName?: string; - blockType: 'number'; - } - | { - color: string; - id?: string; - blockName?: string; - blockType: 'quote'; - } - | { - label: string; - url: string; - id?: string; - blockName?: string; - blockType: 'cta'; - } - )[]; - slug: string; -} -/** - * This interface was referenced by `Config`'s JSON-Schema - * via the `definition` "auto-label". - */ -export interface AutoLabel { - autoLabelField?: string; - noLabel?: string; - labelOverride?: string; - specialBlock?: { - testNumber?: number; - id?: string; - blockName?: string; - blockType: 'number'; - }[]; - noLabelBlock?: { - testNumber?: number; - id?: string; - blockName?: string; - blockType: 'number'; - }[]; - items?: { - itemName?: string; - id?: string; - }[]; - noLabelArray?: { - textField?: string; - id?: string; - }[]; -} -/** - * This interface was referenced by `Config`'s JSON-Schema - * via the `definition` "code". - */ -export interface Code {} -/** - * This interface was referenced by `Config`'s JSON-Schema - * via the `definition` "conditions". - */ -export interface Conditions { - title: string; - number?: number; - simpleCondition: string; - orCondition: string; - nestedConditions?: string; - blocks: ( - | { - testEmail: string; - id?: string; - blockName?: string; - blockType: 'email'; - } - | { - testNumber: number; - id?: string; - blockName?: string; - blockType: 'number'; - } - | { - color: string; - id?: string; - blockName?: string; - blockType: 'quote'; - } - | { - label: string; - url: string; - id?: string; - blockName?: string; - blockType: 'cta'; - } - )[]; -} -/** - * This interface was referenced by `Config`'s JSON-Schema - * via the `definition` "custom-components". - */ -export interface CustomComponent { - title: string; - componentDescription?: string; - array?: { - nestedArrayCustomField?: string; - id?: string; - }[]; - group?: { - nestedGroupCustomField?: string; - }; - nestedText1?: string; - nestedText2?: string; -} -/** - * This interface was referenced by `Config`'s JSON-Schema - * via the `definition` "custom-id". - */ -export interface CustomID { - id?: number; - name: string; -} -/** - * This interface was referenced by `Config`'s JSON-Schema - * via the `definition` "files". - */ -export interface File { - url?: string; - filename?: string; - mimeType?: string; - filesize?: number; -} -/** - * This interface was referenced by `Config`'s JSON-Schema - * via the `definition` "default-values". - */ -export interface DefaultValueTest { - text?: string; - email?: string; - number?: number; - group?: { - nestedText1?: string; - nestedText2?: string; - }; - array?: { - arrayText1?: string; - arrayText2?: string; - arrayText3?: string; - id?: string; - }[]; - blocks?: ( - | { - testEmail: string; - id?: string; - blockName?: string; - blockType: 'email'; - } - | { - testNumber: number; - id?: string; - blockName?: string; - blockType: 'number'; - } - | { - color: string; - id?: string; - blockName?: string; - blockType: 'quote'; - } - | { - label: string; - url: string; - id?: string; - blockName?: string; - blockType: 'cta'; - } - )[]; - slug?: string; -} -/** - * This interface was referenced by `Config`'s JSON-Schema - * via the `definition` "blocks". - */ -export interface Blocks { - layout: ( - | { - testEmail: string; - id?: string; - blockName?: string; - blockType: 'email'; - } - | { - testNumber: number; - id?: string; - blockName?: string; - blockType: 'number'; - } - | { - color: string; - id?: string; - blockName?: string; - blockType: 'quote'; - } - | { - label: string; - url: string; - id?: string; - blockName?: string; - blockType: 'cta'; - } - )[]; - nonLocalizedLayout: ( - | { - testEmail: string; - id?: string; - blockName?: string; - blockType: 'email'; - } - | { - testNumber: number; - id?: string; - blockName?: string; - blockType: 'number'; - } - | { - color: string; - id?: string; - blockName?: string; - blockType: 'quote'; - } - | { - label: string; - url: string; - id?: string; - blockName?: string; - blockType: 'cta'; - } - )[]; -} -/** - * This interface was referenced by `Config`'s JSON-Schema - * via the `definition` "hidden-fields". - */ -export interface HiddenFields { - title: string; - hiddenAdmin: string; - hiddenAPI: string; -} -/** - * This interface was referenced by `Config`'s JSON-Schema - * via the `definition` "hooks". - */ -export interface Hook { - title: string; + relationship: (string | LocalizedPost)[]; + singleRelationship: string | LocalizedPost; } /** * This interface was referenced by `Config`'s JSON-Schema @@ -336,6 +28,7 @@ export interface Hook { export interface LocalizedPost { title: string; summary?: string; + description: string; priority: number; localizedGroup?: { text?: string; @@ -355,22 +48,117 @@ export interface LocalizedPost { } /** * This interface was referenced by `Config`'s JSON-Schema - * via the `definition` "localized-arrays". + * via the `definition` "blocks-global". */ -export interface LocalizedArray { - array: { - arrayText1: string; - arrayText2: string; - arrayText3?: string; - id?: string; - }[]; +export interface BlocksGlobal { + blocks?: ( + | { + author: string | PublicUser; + quote: string; + color: string; + id?: string; + blockName?: string; + blockType: 'quote'; + } + | { + label: string; + url: string; + id?: string; + blockName?: string; + blockType: 'cta'; + } + )[]; } /** * This interface was referenced by `Config`'s JSON-Schema - * via the `definition` "local-operations". + * via the `definition` "public-users". */ -export interface LocalOperation { - title: string; +export interface PublicUser { + email?: string; + resetPasswordToken?: string; + _verified?: boolean; + _verificationToken?: string; + loginAttempts?: number; + adminOnly?: string; +} +/** + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "admins". + */ +export interface Admin { + email?: string; + resetPasswordToken?: string; + enableAPIKey?: boolean; + apiKey?: string; + apiKeyIndex?: string; + loginAttempts?: number; + publicUser?: (string | PublicUser)[]; +} +/** + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "all-fields". + */ +export interface AllFields { + text: string; + descriptionText?: string; + descriptionFunction?: string; + image?: string | Media; + email?: string; + number?: number; + group?: { + nestedText1?: string; + nestedText2?: string; + }; + array?: { + arrayText1: string; + arrayText2: string; + arrayText3?: string; + checkbox?: boolean; + id?: string; + }[]; + blocks: ( + | { + testEmail: string; + id?: string; + blockName?: string; + blockType: 'email'; + } + | { + testNumber: number; + id?: string; + blockName?: string; + blockType: 'number'; + } + | { + author: string | PublicUser; + quote: string; + color: string; + id?: string; + blockName?: string; + blockType: 'quote'; + } + | { + label: string; + url: string; + id?: string; + blockName?: string; + blockType: 'cta'; + } + )[]; + relationship?: string | Conditions; + relationshipHasMany?: (string | LocalizedPost)[]; + relationshipMultipleCollections?: + | { + value: string | LocalizedPost; + relationTo: 'localized-posts'; + } + | { + value: string | Conditions; + relationTo: 'conditions'; + }; + textarea?: string; + slug: string; + checkbox?: boolean; } /** * This interface was referenced by `Config`'s JSON-Schema @@ -418,6 +206,287 @@ export interface Media { }; }; alt: string; + foundUploadSizes?: boolean; +} +/** + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "conditions". + */ +export interface Conditions { + title: string; + enableTest?: boolean; + number?: number; + simpleCondition: string; + orCondition: string; + nestedConditions?: string; + blocks: ( + | { + testEmail: string; + id?: string; + blockName?: string; + blockType: 'email'; + } + | { + testNumber: number; + id?: string; + blockName?: string; + blockType: 'number'; + } + | { + author: string | PublicUser; + quote: string; + color: string; + id?: string; + blockName?: string; + blockType: 'quote'; + } + | { + label: string; + url: string; + id?: string; + blockName?: string; + blockType: 'cta'; + } + )[]; +} +/** + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "auto-label". + */ +export interface AutoLabel { + autoLabelField?: string; + noLabel?: string; + labelOverride?: string; + testRelationship?: string | AllFields; + specialBlock?: { + testNumber?: number; + id?: string; + blockName?: string; + blockType: 'number'; + }[]; + noLabelBlock?: { + testNumber?: number; + id?: string; + blockName?: string; + blockType: 'number'; + }[]; + items?: { + itemName?: string; + id?: string; + }[]; + noLabelArray?: { + textField?: string; + id?: string; + }[]; +} +/** + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "code". + */ +export interface Code { + code: string; +} +/** + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "custom-components". + */ +export interface CustomComponent { + title: string; + description: string; + componentDescription?: string; + array?: { + nestedArrayCustomField?: string; + id?: string; + }[]; + group?: { + nestedGroupCustomField?: string; + }; + nestedText1?: string; + nestedText2?: string; +} +/** + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "custom-id". + */ +export interface CustomID { + id?: number; + name: string; +} +/** + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "files". + */ +export interface File { + url?: string; + filename?: string; + mimeType?: string; + filesize?: number; + owner: string | Admin; +} +/** + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "default-values". + */ +export interface DefaultValueTest { + text?: string; + image?: string | Media; + email?: string; + number?: number; + group?: { + nestedText1?: string; + nestedText2?: string; + }; + array?: { + arrayText1?: string; + arrayText2?: string; + arrayText3?: string; + checkbox?: boolean; + id?: string; + }[]; + blocks?: ( + | { + testEmail: string; + id?: string; + blockName?: string; + blockType: 'email'; + } + | { + testNumber: number; + id?: string; + blockName?: string; + blockType: 'number'; + } + | { + author: string | PublicUser; + quote: string; + color: string; + id?: string; + blockName?: string; + blockType: 'quote'; + } + | { + label: string; + url: string; + id?: string; + blockName?: string; + blockType: 'cta'; + } + )[]; + relationship?: string | Conditions; + relationshipHasMany?: (string | LocalizedPost)[]; + relationshipMultipleCollections?: + | { + value: string | LocalizedPost; + relationTo: 'localized-posts'; + } + | { + value: string | Conditions; + relationTo: 'conditions'; + }; + textarea?: string; + slug?: string; + checkbox?: boolean; +} +/** + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "blocks". + */ +export interface Blocks { + layout: ( + | { + testEmail: string; + id?: string; + blockName?: string; + blockType: 'email'; + } + | { + testNumber: number; + id?: string; + blockName?: string; + blockType: 'number'; + } + | { + author: string | PublicUser; + quote: string; + color: string; + id?: string; + blockName?: string; + blockType: 'quote'; + } + | { + label: string; + url: string; + id?: string; + blockName?: string; + blockType: 'cta'; + } + )[]; + nonLocalizedLayout: ( + | { + testEmail: string; + id?: string; + blockName?: string; + blockType: 'email'; + } + | { + testNumber: number; + id?: string; + blockName?: string; + blockType: 'number'; + } + | { + author: string | PublicUser; + quote: string; + color: string; + id?: string; + blockName?: string; + blockType: 'quote'; + } + | { + label: string; + url: string; + id?: string; + blockName?: string; + blockType: 'cta'; + } + )[]; +} +/** + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "hidden-fields". + */ +export interface HiddenFields { + title: string; + hiddenAdmin: string; + hiddenAPI: string; +} +/** + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "hooks". + */ +export interface Hook { + title: string; + description: string; +} +/** + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "localized-arrays". + */ +export interface LocalizedArray { + array: { + allowPublicReadability?: boolean; + arrayText1: string; + arrayText2: string; + arrayText3?: string; + id?: string; + }[]; +} +/** + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "local-operations". + */ +export interface LocalOperation { + title: string; } /** * This interface was referenced by `Config`'s JSON-Schema @@ -444,28 +513,71 @@ export interface NestedArray { export interface PreviewablePost { title: string; } -/** - * This interface was referenced by `Config`'s JSON-Schema - * via the `definition` "public-users". - */ -export interface PublicUser { - email?: string; - resetPasswordToken?: string; - _verificationToken?: string; - loginAttempts?: number; - adminOnly?: string; -} /** * This interface was referenced by `Config`'s JSON-Schema * via the `definition` "relationship-a". */ -export interface RelationshipA {} +export interface RelationshipA { + post?: string | RelationshipB; + LocalizedPost?: (string | LocalizedPost)[]; + postLocalizedMultiple?: ( + | { + value: string | LocalizedPost; + relationTo: 'localized-posts'; + } + | { + value: string | AllFields; + relationTo: 'all-fields'; + } + | { + value: number | CustomID; + relationTo: 'custom-id'; + } + )[]; + postManyRelationships?: { + value: string | RelationshipB; + relationTo: 'relationship-b'; + }; + postMaxDepth?: string | RelationshipB; + customID?: (number | CustomID)[]; +} /** * This interface was referenced by `Config`'s JSON-Schema * via the `definition` "relationship-b". */ export interface RelationshipB { title?: string; + post?: (string | RelationshipA)[]; + postManyRelationships?: + | { + value: string | RelationshipA; + relationTo: 'relationship-a'; + } + | { + value: string | Media; + relationTo: 'media'; + }; + localizedPosts?: ( + | { + value: string | LocalizedPost; + relationTo: 'localized-posts'; + } + | { + value: string | PreviewablePost; + relationTo: 'previewable-post'; + } + )[]; + strictAccess?: string | StrictAccess; +} +/** + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "strict-access". + */ +export interface StrictAccess { + address: string; + city: string; + state: string; + zip: number; } /** * This interface was referenced by `Config`'s JSON-Schema @@ -477,16 +589,6 @@ export interface RichText {} * via the `definition` "select". */ export interface Select {} -/** - * This interface was referenced by `Config`'s JSON-Schema - * via the `definition` "strict-access". - */ -export interface StrictAccess { - address: string; - city: string; - state: string; - zip: number; -} /** * This interface was referenced by `Config`'s JSON-Schema * via the `definition` "validations". @@ -510,6 +612,7 @@ export interface Validation { */ export interface Unique { title: string; + description?: string; } /** * This interface was referenced by `Config`'s JSON-Schema diff --git a/src/bin/generateTypes.ts b/src/bin/generateTypes.ts index 809df818b..f330fd3fe 100644 --- a/src/bin/generateTypes.ts +++ b/src/bin/generateTypes.ts @@ -8,7 +8,22 @@ import { SanitizedConfig } from '../config/types'; import loadConfig from '../config/load'; import { SanitizedGlobalConfig } from '../globals/config/types'; -function generateFieldTypes(fields: Field[]): { +function getCollectionIDType(collections: SanitizedCollectionConfig[], slug): 'string' | 'number' { + const matchedCollection = collections.find((collection) => collection.slug === slug); + if (matchedCollection) { + const idField = matchedCollection.fields.find((field) => 'name' in field && field.name === 'id'); + + if (idField && idField.type === 'number') { + return 'number'; + } + + return 'string'; + } + + return undefined; +} + +function generateFieldTypes(config: SanitizedConfig, fields: Field[]): { properties: { [k: string]: JSONSchema4; } @@ -24,6 +39,8 @@ function generateFieldTypes(fields: Field[]): { switch (field.type) { case 'text': + case 'textarea': + case 'code': case 'email': { fieldSchema = { type: 'string' }; break; @@ -34,12 +51,131 @@ function generateFieldTypes(fields: Field[]): { break; } + case 'checkbox': { + fieldSchema = { type: 'boolean' }; + break; + } + + // TODO: + // Add enum types like Radio and Select + // Add point field type + + case 'relationship': { + if (Array.isArray(field.relationTo)) { + if (field.hasMany) { + fieldSchema = { + type: 'array', + items: { + oneOf: field.relationTo.map((relation) => { + const idFieldType = getCollectionIDType(config.collections, relation); + + return { + type: 'object', + additionalProperties: false, + properties: { + value: { + oneOf: [ + { + type: idFieldType, + }, + { + $ref: `#/definitions/${relation}`, + }, + ], + }, + relationTo: { + const: relation, + }, + }, + required: ['value', 'relationTo'], + }; + }), + }, + }; + } else { + fieldSchema = { + oneOf: field.relationTo.map((relation) => { + const idFieldType = getCollectionIDType(config.collections, relation); + + return { + type: 'object', + additionalProperties: false, + properties: { + value: { + oneOf: [ + { + type: idFieldType, + }, + { + $ref: `#/definitions/${relation}`, + }, + ], + }, + relationTo: { + const: relation, + }, + }, + required: ['value', 'relationTo'], + }; + }), + }; + } + } else { + const idFieldType = getCollectionIDType(config.collections, field.relationTo); + + if (field.hasMany) { + fieldSchema = { + type: 'array', + items: { + oneOf: [ + { + type: idFieldType, + }, + { + $ref: `#/definitions/${field.relationTo}`, + }, + ], + }, + }; + } else { + fieldSchema = { + oneOf: [ + { + type: idFieldType, + }, + { + $ref: `#/definitions/${field.relationTo}`, + }, + ], + }; + } + } + + break; + } + + case 'upload': { + const idFieldType = getCollectionIDType(config.collections, field.relationTo); + + fieldSchema = { + oneOf: [ + { + type: idFieldType, + }, + { + $ref: `#/definitions/${field.relationTo}`, + }, + ], + }; + break; + } + case 'blocks': { fieldSchema = { type: 'array', items: { oneOf: field.blocks.map((block) => { - const blockSchema = generateFieldTypes(block.fields); + const blockSchema = generateFieldTypes(config, block.fields); return { type: 'object', @@ -67,14 +203,14 @@ function generateFieldTypes(fields: Field[]): { items: { type: 'object', additionalProperties: false, - ...generateFieldTypes(field.fields), + ...generateFieldTypes(config, field.fields), }, }; break; } case 'row': { - const topLevelFields = generateFieldTypes(field.fields); + const topLevelFields = generateFieldTypes(config, field.fields); requiredTopLevelProps = requiredTopLevelProps.concat(topLevelFields.required); topLevelProps = topLevelProps.concat(Object.entries(topLevelFields.properties).map((prop) => prop)); break; @@ -84,7 +220,7 @@ function generateFieldTypes(fields: Field[]): { fieldSchema = { type: 'object', additionalProperties: false, - ...generateFieldTypes(field.fields), + ...generateFieldTypes(config, field.fields), }; break; } @@ -128,14 +264,14 @@ function generateFieldTypes(fields: Field[]): { }; } -function entityToJsonSchema(entity: SanitizedCollectionConfig | SanitizedGlobalConfig): any { +function entityToJsonSchema(config: SanitizedConfig, entity: SanitizedCollectionConfig | SanitizedGlobalConfig): any { const title = 'label' in entity ? entity.label : entity.labels.singular; return { title, type: 'object', additionalProperties: false, - ...generateFieldTypes(entity.fields), + ...generateFieldTypes(config, entity.fields), }; } @@ -145,11 +281,11 @@ function configToJsonSchema(config: SanitizedConfig): JSONSchema4 { [ ...config.globals.map((global) => [ global.slug, - entityToJsonSchema(global), + entityToJsonSchema(config, global), ]), ...config.collections.map((collection) => [ collection.slug, - entityToJsonSchema(collection), + entityToJsonSchema(config, collection), ]), ], ),