diff --git a/packages/core/data-transfer/src/engine/index.ts b/packages/core/data-transfer/src/engine/index.ts index 917df2098c..92e303d34d 100644 --- a/packages/core/data-transfer/src/engine/index.ts +++ b/packages/core/data-transfer/src/engine/index.ts @@ -73,7 +73,7 @@ export const TransferGroupPresets: TransferGroupFilter = { export const DEFAULT_VERSION_STRATEGY = 'ignore'; export const DEFAULT_SCHEMA_STRATEGY = 'strict'; -type SchemaMap = Utils.StringRecord; +type SchemaMap = Utils.String.Dict; class TransferEngine< S extends ISourceProvider = ISourceProvider, diff --git a/packages/core/data-transfer/src/strapi/providers/remote-destination/index.ts b/packages/core/data-transfer/src/strapi/providers/remote-destination/index.ts index 94efcbda7b..740c78f753 100644 --- a/packages/core/data-transfer/src/strapi/providers/remote-destination/index.ts +++ b/packages/core/data-transfer/src/strapi/providers/remote-destination/index.ts @@ -263,7 +263,7 @@ class RemoteStrapiDestinationProvider implements IDestinationProvider { return Promise.resolve(null); } - return this.dispatcher.dispatchTransferAction>('getSchemas'); + return this.dispatcher.dispatchTransferAction>('getSchemas'); } createEntitiesWriteStream(): Writable { diff --git a/packages/core/data-transfer/src/strapi/providers/remote-source/index.ts b/packages/core/data-transfer/src/strapi/providers/remote-source/index.ts index ea7a301629..4d21811f7a 100644 --- a/packages/core/data-transfer/src/strapi/providers/remote-source/index.ts +++ b/packages/core/data-transfer/src/strapi/providers/remote-source/index.ts @@ -278,7 +278,7 @@ class RemoteStrapiSourceProvider implements ISourceProvider { async getSchemas() { const schemas = - (await this.dispatcher?.dispatchTransferAction>( + (await this.dispatcher?.dispatchTransferAction>( 'getSchemas' )) ?? null; diff --git a/packages/core/data-transfer/src/utils/schema.ts b/packages/core/data-transfer/src/utils/schema.ts index e2045cad6e..45143ddb78 100644 --- a/packages/core/data-transfer/src/utils/schema.ts +++ b/packages/core/data-transfer/src/utils/schema.ts @@ -22,6 +22,6 @@ const VALID_SCHEMA_PROPERTIES = [ * Sanitize a schemas dictionary by omitting unwanted properties * The list of allowed properties can be found here: {@link VALID_SCHEMA_PROPERTIES} */ -export const mapSchemasValues = (schemas: Utils.StringRecord) => { - return mapValues(pick(VALID_SCHEMA_PROPERTIES), schemas) as Utils.StringRecord; +export const mapSchemasValues = (schemas: Utils.String.Dict) => { + return mapValues(pick(VALID_SCHEMA_PROPERTIES), schemas) as Utils.String.Dict; }; diff --git a/packages/core/strapi/lib/types/core/attributes/common.d.ts b/packages/core/strapi/lib/types/core/attributes/common.d.ts index fbd0b9c47d..e7f95e3c5c 100644 --- a/packages/core/strapi/lib/types/core/attributes/common.d.ts +++ b/packages/core/strapi/lib/types/core/attributes/common.d.ts @@ -25,7 +25,7 @@ export type Configurable = { configurable: true }; export type NonConfigurable = { configurable: false }; // custom field -export type CustomField = { +export type CustomField = { customField: T; options?: P; }; @@ -46,7 +46,7 @@ export type DefaultTo = { default: T }; export type Any = | Attribute.BigInteger | Attribute.Boolean - | Attribute.Component + | Attribute.Component | Attribute.DateTime | Attribute.Date | Attribute.Decimal @@ -56,7 +56,7 @@ export type Any = | Attribute.Float | Attribute.Integer | Attribute.JSON - | Attribute.Media + | Attribute.Media | Attribute.Password | Attribute.Relation | Attribute.RichText @@ -64,4 +64,4 @@ export type Any = | Attribute.Text | Attribute.Time | Attribute.Timestamp - | Attribute.UID; + | Attribute.UID; diff --git a/packages/core/strapi/lib/types/core/attributes/dynamic-zone.d.ts b/packages/core/strapi/lib/types/core/attributes/dynamic-zone.d.ts index 3822ceb38a..9212400edf 100644 --- a/packages/core/strapi/lib/types/core/attributes/dynamic-zone.d.ts +++ b/packages/core/strapi/lib/types/core/attributes/dynamic-zone.d.ts @@ -14,7 +14,7 @@ export type DynamicZone = Array< - Utils.GetArrayValues extends infer P + Utils.Array.Values extends infer P ? P extends Common.UID.ContentType ? Attribute.GetValues

& { __component: P } : never diff --git a/packages/core/strapi/lib/types/core/attributes/enumeration.d.ts b/packages/core/strapi/lib/types/core/attributes/enumeration.d.ts index 94c55e3500..ddcd236efb 100644 --- a/packages/core/strapi/lib/types/core/attributes/enumeration.d.ts +++ b/packages/core/strapi/lib/types/core/attributes/enumeration.d.ts @@ -12,7 +12,7 @@ export type Enumeration = Attribute.Attribute<'enumerat Attribute.PrivateOption & Attribute.RequiredOption; -export type EnumerationValue = Utils.GetArrayValues; +export type EnumerationValue = Utils.Array.Values; export type GetEnumerationValue = T extends Enumeration ? EnumerationValue diff --git a/packages/core/strapi/lib/types/core/attributes/relation.d.ts b/packages/core/strapi/lib/types/core/attributes/relation.d.ts index 48a8ba4a9a..9b6a072b76 100644 --- a/packages/core/strapi/lib/types/core/attributes/relation.d.ts +++ b/packages/core/strapi/lib/types/core/attributes/relation.d.ts @@ -19,7 +19,7 @@ export type BasicRelationProperties< target: T; } & R extends `morph${string}` ? { - morphBy?: Utils.KeysBy< + morphBy?: Utils.Object.KeysBy< Common.Schemas[T]['attributes'], Attribute.Relation >; @@ -41,7 +41,9 @@ export type Relation< // Properties (R extends BasicRelationsType ? BasicRelationProperties - : PolymorphicRelationProperties) & + : R extends PolymorphicRelationsType + ? PolymorphicRelationProperties + : {}) & // Options Attribute.ConfigurableOption & Attribute.PrivateOption; diff --git a/packages/core/strapi/lib/types/core/attributes/uid.d.ts b/packages/core/strapi/lib/types/core/attributes/uid.d.ts index 7536321777..b923ec14fc 100644 --- a/packages/core/strapi/lib/types/core/attributes/uid.d.ts +++ b/packages/core/strapi/lib/types/core/attributes/uid.d.ts @@ -1,4 +1,4 @@ -import type { Attribute, Common } from '@strapi/strapi'; +import type { Attribute, Common, Utils } from '@strapi/strapi'; export interface UIDOptions { separator?: string; @@ -10,13 +10,18 @@ export interface UIDOptions { export interface UIDProperties< // Own Schema Reference - T extends Common.UID.Schema | undefined, + T extends Common.UID.Schema, // Target attribute - U extends T extends Common.UID.Schema ? Attribute.GetKeysByType : undefined, + U extends TargetAttributeByUID, // UID options S extends UIDOptions = UIDOptions > { - targetField: U extends undefined ? string | undefined : U; + targetField: U; + options: UIDOptions & S; +} + +export interface GenericUIDProperties { + targetField?: string; options: UIDOptions & S; } @@ -29,7 +34,7 @@ export type UID< S extends UIDOptions = UIDOptions > = Attribute.Attribute<'uid'> & // Properties - UIDProperties & + (T extends Common.UID.Schema ? UIDProperties : GenericUIDProperties) & // Options Attribute.ConfigurableOption & Attribute.DefaultOption & @@ -38,8 +43,8 @@ export type UID< Attribute.RequiredOption; type TargetAttributeByUID = T extends Common.UID.Schema - ? Attribute.GetKeysByType - : undefined; + ? Utils.Guard.Never, string> + : never; export type UIDValue = string; diff --git a/packages/core/strapi/lib/types/core/attributes/utils.d.ts b/packages/core/strapi/lib/types/core/attributes/utils.d.ts index 9184381ddf..2fe6a68851 100644 --- a/packages/core/strapi/lib/types/core/attributes/utils.d.ts +++ b/packages/core/strapi/lib/types/core/attributes/utils.d.ts @@ -6,13 +6,13 @@ export type GetKeysByType< T extends Common.UID.Schema, U extends Attribute.Type, P = never -> = Utils.KeysBy, Attribute.Attribute & Utils.NeverGuard>; +> = Utils.Object.KeysBy, Attribute.Attribute & Utils.Guard.Never>; export type GetByType< T extends Common.UID.Schema, U extends Attribute.Type, P = never -> = Utils.PickBy, Attribute.Attribute & Utils.NeverGuard>; +> = Utils.Object.PickBy, Attribute.Attribute & Utils.Guard.Never>; export type Get> = Utils.Get, U>; @@ -60,7 +60,7 @@ export type GetValues = GetKey [key in GetOptionalKeys as key extends U ? key : never]?: GetValueByKey; }; -export type GetRequiredKeys = Utils.KeysBy< +export type GetRequiredKeys = Utils.Object.KeysBy< GetAll, { required: true } >; diff --git a/packages/core/strapi/lib/types/core/common/controller.d.ts b/packages/core/strapi/lib/types/core/common/controller.d.ts index 24b55beaf1..1fcdc96b2f 100644 --- a/packages/core/strapi/lib/types/core/common/controller.d.ts +++ b/packages/core/strapi/lib/types/core/common/controller.d.ts @@ -1,8 +1,8 @@ -import type koa from 'koa'; +import type { ExtendableContext, Next } from 'koa'; export type ControllerHandler = ( - context: koa.ExtendableContext, - next: koa.Next + context: ExtendableContext, + next: Next ) => Promise | T | void; export type Controller = Record; diff --git a/packages/core/strapi/lib/types/core/common/uid.d.ts b/packages/core/strapi/lib/types/core/common/uid.d.ts index adec2a2cb8..5ef444cc1b 100644 --- a/packages/core/strapi/lib/types/core/common/uid.d.ts +++ b/packages/core/strapi/lib/types/core/common/uid.d.ts @@ -17,11 +17,11 @@ export type Middleware = Registry.Keys; export type ContentType = Registry.Keys; export type CollectionType = Extract< - Utils.KeysBy, + Utils.Object.KeysBy, ContentType >; export type SingleType = Extract< - Utils.KeysBy, + Utils.Object.KeysBy, ContentType >; diff --git a/packages/core/strapi/lib/types/core/namespace.d.ts b/packages/core/strapi/lib/types/core/namespace.d.ts index 1f633ef262..c506eac2f7 100644 --- a/packages/core/strapi/lib/types/core/namespace.d.ts +++ b/packages/core/strapi/lib/types/core/namespace.d.ts @@ -67,7 +67,7 @@ export type GetSeparator = T extends Scoped * type T = WithSeparator | WithSeparator * // ^ 'admin::' | 'api::{string}.' */ -export type WithSeparator = Utils.Suffix>; +export type WithSeparator = Utils.String.Suffix>; /** * Represents namespaces composed of an origin and a name, separated by colons 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 c23e4cebf4..8e24b09065 100644 --- a/packages/core/strapi/lib/types/core/schemas/index.d.ts +++ b/packages/core/strapi/lib/types/core/schemas/index.d.ts @@ -78,7 +78,9 @@ export interface Info { /** * Low level data structure referencing every schema attribute and its name */ -export interface Attributes extends Utils.StringRecord {} +export interface Attributes { + [key: string]: Attribute.Any; +} /** * Structure containing every core schema options and their associated value diff --git a/packages/core/strapi/lib/types/core/strapi/index.d.ts b/packages/core/strapi/lib/types/core/strapi/index.d.ts index 2fc6e04aa8..6904ae16a2 100644 --- a/packages/core/strapi/lib/types/core/strapi/index.d.ts +++ b/packages/core/strapi/lib/types/core/strapi/index.d.ts @@ -1,7 +1,6 @@ -import type Koa from 'koa'; import { Database } from '@strapi/database'; -import type { StringMap } from './utils'; +import type { Shared } from '@strapi/strapi'; import type { GenericController } from '../../../core-api/controller'; import type { GenericService } from '../../../core-api/service'; @@ -21,7 +20,7 @@ interface CustomFieldServerOptions { * The existing Strapi data type the custom field uses */ type: string; - + /** * Settings for the input size in the Admin UI */ @@ -69,7 +68,7 @@ export interface Strapi { * * It returns all the registered services */ - readonly services: StringMap; + readonly services: Shared.Services; /** * Find a service using its unique identifier @@ -81,7 +80,7 @@ export interface Strapi { * * It returns all the registered controllers */ - readonly controllers: StringMap; + readonly controllers: Shared.Controllers; /** * Find a controller using its unique identifier diff --git a/packages/core/strapi/lib/types/core/uid.d.ts b/packages/core/strapi/lib/types/core/uid.d.ts index 9b308aaca9..ef4fe25823 100644 --- a/packages/core/strapi/lib/types/core/uid.d.ts +++ b/packages/core/strapi/lib/types/core/uid.d.ts @@ -1,7 +1,7 @@ import type * as Namespace from './namespace'; import type * as Utils from '../utils'; -type StringSuffix = Utils.Suffix; +type StringSuffix = Utils.String.Suffix; /** * Template for services' unique identifier diff --git a/packages/core/strapi/lib/types/utils.d.ts b/packages/core/strapi/lib/types/utils.d.ts deleted file mode 100644 index 44afa53f49..0000000000 --- a/packages/core/strapi/lib/types/utils.d.ts +++ /dev/null @@ -1,121 +0,0 @@ -/** - * - * Common utilities used across Strapi typings - * - * */ - -/** - * Alias for any literal type (useful for template string parameters) - */ -export type Literal = string | number | bigint | boolean; - -/** - * Used to check if a string includes a given literal - */ -export type Includes = `${string}${S}${string}`; - -/** - * Used to make sure the given string is not empty - */ -export type NonEmpty = T extends '' ? never : T; - -/** - * Split the given string into a tuple using the given `S` literal - */ -export type Split = T extends `${infer A}${S}${infer B}` - ? [A, ...Split] - : T extends '' - ? [] - : [T]; - -/** - * Aggregate the given tuple into a string, separated by the given `S` literal - */ -export type Join = T extends [ - infer F extends Literal, - ...infer R -] - ? R['length'] extends 0 - ? F - : `${F}${S}${Join}` - : never; - -/** - * Add a literal suffix (`S`) at the end of the given string - */ -export type Suffix = `${T}${S}`; - -/** - * Add a literal prefix (`S`) at the beginning of the given string - */ -export type Prefix = `${S}${T}`; - -/** - * - * Extract the array values into an union type - * - **/ -export type GetArrayValues> = T extends Array ? U : never; - -/** - * Creates a record where every key is a string and every value is `T` - */ -export type StringRecord = Record; - -/** - * Retrieve object's (`T`) keys if they extends the given `U` type. - * - * @example - * type X = KeysBy<{ foo: 'bar', bar: 'foo', foobar: 2 }, string> - * // 'foo' | 'bar' - * - * type Base = { x: 'foo' | 'bar' }; - * type Obj = { foo: { x: 'foo' }, bar: { x: 'bar' }, other: { x: '42' } }; - * type X = KeysBy - * // 'foo' | 'bar' - */ -export type KeysBy = { - [key in keyof T]: T[key] extends U ? key : never; -}[keyof T]; - -/** - * Retrieve object's (`T`) properties if their value extends the given `U` type. - * - * @example - * type X = KeysBy<{ foo: 'bar', bar: 'foo', foobar: 2 }, string> - * // { foo: 'bar', bar: 'foo' } - * - * type Base = { x: 'foo' | 'bar' }; - * type Obj = { foo: { x: 'foo' }, bar: { x: 'bar' }, other: { x: '42' } }; - * type X = KeysBy - * // { foo: { x: 'foo' }, bar: { x: 'bar' } } - */ -export type PickBy = Pick>; - -/** - * Assign a default value `U` to `T` if `T` is of type `never` - * - * @example - * type X = NeverGuard<{ foo: 'bar' }, string> - * // { foo: 'bar' } - * - * type X = NeverGuard - * // unknown - * - * type X = NeverGuard - * // string - */ -export type NeverGuard = [T] extends [never] ? U : T; - -/** - * Get the type of a specific key `U` in `T` - * - * @example - * - * type X = Get<{ foo: 'bar', 'bar': 'foo' }, 'foo'> - * // 'bar' - * - * type X = Get<{ foo: 'bar', 'bar': 'foo' }, 'bar'> - * // 'foo' - */ -export type Get = T[U]; diff --git a/packages/core/strapi/lib/types/utils/array.d.ts b/packages/core/strapi/lib/types/utils/array.d.ts new file mode 100644 index 0000000000..05227aac62 --- /dev/null +++ b/packages/core/strapi/lib/types/utils/array.d.ts @@ -0,0 +1,6 @@ +/** + * + * Extract the array values into an union type + * + **/ +export type Values> = T extends Array ? U : never; diff --git a/packages/core/strapi/lib/types/utils/guard.d.ts b/packages/core/strapi/lib/types/utils/guard.d.ts new file mode 100644 index 0000000000..a2440defee --- /dev/null +++ b/packages/core/strapi/lib/types/utils/guard.d.ts @@ -0,0 +1,14 @@ +/** + * Assign a default value `U` to `T` if `T` is of type `never` + * + * @example + * type X = Never<{ foo: 'bar' }, string> + * // { foo: 'bar' } + * + * type X = Never + * // unknown + * + * type X = Never + * // string + */ +export type Never = [T] extends [never] ? U : T; diff --git a/packages/core/strapi/lib/types/utils/index.d.ts b/packages/core/strapi/lib/types/utils/index.d.ts new file mode 100644 index 0000000000..c98b194ada --- /dev/null +++ b/packages/core/strapi/lib/types/utils/index.d.ts @@ -0,0 +1,18 @@ +export * as Array from './array'; +export * as Guard from './guard'; +export * as Object from './object'; +export * as String from './string'; +export * as Tuple from './tuple'; + +/** + * Get the type of a specific key `U` in `T` + * + * @example + * + * type X = Get<{ foo: 'bar', 'bar': 'foo' }, 'foo'> + * // 'bar' + * + * type X = Get<{ foo: 'bar', 'bar': 'foo' }, 'bar'> + * // 'foo' + */ +export type Get = T[U]; diff --git a/packages/core/strapi/lib/types/utils/object.d.ts b/packages/core/strapi/lib/types/utils/object.d.ts new file mode 100644 index 0000000000..a1c43664d2 --- /dev/null +++ b/packages/core/strapi/lib/types/utils/object.d.ts @@ -0,0 +1,29 @@ +/** + * Retrieve object's (`T`) keys if they extends the given `U` type. + * + * @example + * type X = KeysBy<{ foo: 'bar', bar: 'foo', foobar: 2 }, string> + * // 'foo' | 'bar' + * + * type Base = { x: 'foo' | 'bar' }; + * type Obj = { foo: { x: 'foo' }, bar: { x: 'bar' }, other: { x: '42' } }; + * type X = KeysBy + * // 'foo' | 'bar' + */ +export type KeysBy = { + [key in keyof T]: T[key] extends U ? key : never; +}[keyof T]; + +/** + * Retrieve object's (`T`) properties if their value extends the given `U` type. + * + * @example + * type X = KeysBy<{ foo: 'bar', bar: 'foo', foobar: 2 }, string> + * // { foo: 'bar', bar: 'foo' } + * + * type Base = { x: 'foo' | 'bar' }; + * type Obj = { foo: { x: 'foo' }, bar: { x: 'bar' }, other: { x: '42' } }; + * type X = KeysBy + * // { foo: { x: 'foo' }, bar: { x: 'bar' } } + */ +export type PickBy = Pick>; diff --git a/packages/core/strapi/lib/types/utils/string.d.ts b/packages/core/strapi/lib/types/utils/string.d.ts new file mode 100644 index 0000000000..3b17f57139 --- /dev/null +++ b/packages/core/strapi/lib/types/utils/string.d.ts @@ -0,0 +1,38 @@ +/** + * Alias for any literal type (useful for template string parameters) + */ +export type Literal = string | number | bigint | boolean; + +/** + * Used to check if a string includes a given literal + */ +export type Includes = `${string}${S}${string}`; + +/** + * Used to make sure the given string is not empty + */ +export type NonEmpty = T extends '' ? never : T; + +/** + * Split the given string into a tuple using the given `S` literal + */ +export type Split = T extends `${infer A}${S}${infer B}` + ? [A, ...Split] + : T extends '' + ? [] + : [T]; + +/** + * Add a literal suffix (`S`) at the end of the given string + */ +export type Suffix = `${T}${S}`; + +/** + * Add a literal prefix (`S`) at the beginning of the given string + */ +export type Prefix = `${S}${T}`; + +/** + * Creates a record where every key is a string and every value is `T` + */ +export type Dict = Record; diff --git a/packages/core/strapi/lib/types/utils/tuple.d.ts b/packages/core/strapi/lib/types/utils/tuple.d.ts new file mode 100644 index 0000000000..8fdf356b2e --- /dev/null +++ b/packages/core/strapi/lib/types/utils/tuple.d.ts @@ -0,0 +1,13 @@ +import type { Literal } from './string'; + +/** + * Aggregate the given tuple into a string, separated by the given `S` literal + */ +export type Join = T extends [ + infer F extends Literal, + ...infer R +] + ? R['length'] extends 0 + ? F + : `${F}${S}${Join}` + : never;