Move utils to namespaces & fix types

This commit is contained in:
Convly 2023-05-26 17:14:07 +02:00
parent f0841f681d
commit 94e3595718
23 changed files with 162 additions and 157 deletions

View File

@ -73,7 +73,7 @@ export const TransferGroupPresets: TransferGroupFilter = {
export const DEFAULT_VERSION_STRATEGY = 'ignore';
export const DEFAULT_SCHEMA_STRATEGY = 'strict';
type SchemaMap = Utils.StringRecord<Schema.Schema>;
type SchemaMap = Utils.String.Dict<Schema.Schema>;
class TransferEngine<
S extends ISourceProvider = ISourceProvider,

View File

@ -263,7 +263,7 @@ class RemoteStrapiDestinationProvider implements IDestinationProvider {
return Promise.resolve(null);
}
return this.dispatcher.dispatchTransferAction<Utils.StringRecord<Schema.Schema>>('getSchemas');
return this.dispatcher.dispatchTransferAction<Utils.String.Dict<Schema.Schema>>('getSchemas');
}
createEntitiesWriteStream(): Writable {

View File

@ -278,7 +278,7 @@ class RemoteStrapiSourceProvider implements ISourceProvider {
async getSchemas() {
const schemas =
(await this.dispatcher?.dispatchTransferAction<Utils.StringRecord<Schema.Schema>>(
(await this.dispatcher?.dispatchTransferAction<Utils.String.Dict<Schema.Schema>>(
'getSchemas'
)) ?? null;

View File

@ -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<Schema.Schema>) => {
return mapValues(pick(VALID_SCHEMA_PROPERTIES), schemas) as Utils.StringRecord<Schema.Schema>;
export const mapSchemasValues = (schemas: Utils.String.Dict<Schema.Schema>) => {
return mapValues(pick(VALID_SCHEMA_PROPERTIES), schemas) as Utils.String.Dict<Schema.Schema>;
};

View File

@ -25,7 +25,7 @@ export type Configurable = { configurable: true };
export type NonConfigurable = { configurable: false };
// custom field
export type CustomField<T extends string, P extends object = undefined> = {
export type CustomField<T extends string, P extends object | undefined = undefined> = {
customField: T;
options?: P;
};
@ -46,7 +46,7 @@ export type DefaultTo<T> = { default: T };
export type Any =
| Attribute.BigInteger
| Attribute.Boolean
| Attribute.Component<unknown, boolean>
| Attribute.Component<Common.UID.Component, boolean>
| Attribute.DateTime
| Attribute.Date
| Attribute.Decimal
@ -56,7 +56,7 @@ export type Any =
| Attribute.Float
| Attribute.Integer
| Attribute.JSON
| Attribute.Media<unknown, boolean>
| Attribute.Media<Attribute.AllowedMediaTypes | undefined, boolean>
| Attribute.Password
| Attribute.Relation
| Attribute.RichText
@ -64,4 +64,4 @@ export type Any =
| Attribute.Text
| Attribute.Time
| Attribute.Timestamp
| Attribute.UID<unknown>;
| Attribute.UID<Common.UID.Schema | undefined>;

View File

@ -14,7 +14,7 @@ export type DynamicZone<T extends Common.UID.Component[] = Common.UID.Component[
Attribute.RequiredOption;
type DynamicZoneValue<T extends Common.UID.Component[]> = Array<
Utils.GetArrayValues<T> extends infer P
Utils.Array.Values<T> extends infer P
? P extends Common.UID.ContentType
? Attribute.GetValues<P> & { __component: P }
: never

View File

@ -12,7 +12,7 @@ export type Enumeration<T extends string[] = []> = Attribute.Attribute<'enumerat
Attribute.PrivateOption &
Attribute.RequiredOption;
export type EnumerationValue<T extends string[]> = Utils.GetArrayValues<T>;
export type EnumerationValue<T extends string[]> = Utils.Array.Values<T>;
export type GetEnumerationValue<T extends Attribute.Attribute> = T extends Enumeration<infer U>
? EnumerationValue<U>

View File

@ -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<Common.UID.Schema, Attribute.PolymorphicRelationsType>
>;
@ -41,7 +41,9 @@ export type Relation<
// Properties
(R extends BasicRelationsType
? BasicRelationProperties<S, R, T>
: PolymorphicRelationProperties<R>) &
: R extends PolymorphicRelationsType
? PolymorphicRelationProperties<R>
: {}) &
// Options
Attribute.ConfigurableOption &
Attribute.PrivateOption;

View File

@ -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<T, 'string' | 'text'> : undefined,
U extends TargetAttributeByUID<T>,
// UID options
S extends UIDOptions = UIDOptions
> {
targetField: U extends undefined ? string | undefined : U;
targetField: U;
options: UIDOptions & S;
}
export interface GenericUIDProperties<S extends UIDOptions = UIDOptions> {
targetField?: string;
options: UIDOptions & S;
}
@ -29,7 +34,7 @@ export type UID<
S extends UIDOptions = UIDOptions
> = Attribute.Attribute<'uid'> &
// Properties
UIDProperties<T, U, S> &
(T extends Common.UID.Schema ? UIDProperties<T, U, S> : GenericUIDProperties<S>) &
// Options
Attribute.ConfigurableOption &
Attribute.DefaultOption<UIDValue> &
@ -38,8 +43,8 @@ export type UID<
Attribute.RequiredOption;
type TargetAttributeByUID<T extends Common.UID.Schema | undefined> = T extends Common.UID.Schema
? Attribute.GetKeysByType<T, 'string' | 'text'>
: undefined;
? Utils.Guard.Never<Attribute.GetKeysByType<T, 'string' | 'text'>, string>
: never;
export type UIDValue = string;

View File

@ -6,13 +6,13 @@ export type GetKeysByType<
T extends Common.UID.Schema,
U extends Attribute.Type,
P = never
> = Utils.KeysBy<GetAll<T>, Attribute.Attribute<U> & Utils.NeverGuard<P, unknown>>;
> = Utils.Object.KeysBy<GetAll<T>, Attribute.Attribute<U> & Utils.Guard.Never<P, unknown>>;
export type GetByType<
T extends Common.UID.Schema,
U extends Attribute.Type,
P = never
> = Utils.PickBy<GetAll<T>, Attribute.Attribute<U> & Utils.NeverGuard<P, unknown>>;
> = Utils.Object.PickBy<GetAll<T>, Attribute.Attribute<U> & Utils.Guard.Never<P, unknown>>;
export type Get<T extends Common.UID.Schema, U extends GetKeys<T>> = Utils.Get<GetAll<T>, U>;
@ -60,7 +60,7 @@ export type GetValues<T extends Common.UID.Schema, U extends GetKeys<T> = GetKey
[key in GetOptionalKeys<T> as key extends U ? key : never]?: GetValueByKey<T, key>;
};
export type GetRequiredKeys<T extends Common.UID.Schema> = Utils.KeysBy<
export type GetRequiredKeys<T extends Common.UID.Schema> = Utils.Object.KeysBy<
GetAll<T>,
{ required: true }
>;

View File

@ -1,8 +1,8 @@
import type koa from 'koa';
import type { ExtendableContext, Next } from 'koa';
export type ControllerHandler = <T>(
context: koa.ExtendableContext,
next: koa.Next
context: ExtendableContext,
next: Next
) => Promise<T | void> | T | void;
export type Controller = Record<string, ControllerHandler>;

View File

@ -17,11 +17,11 @@ export type Middleware = Registry.Keys<Shared.Middlewares, UID.Middleware>;
export type ContentType = Registry.Keys<Shared.ContentTypes, UID.ContentType>;
export type CollectionType = Extract<
Utils.KeysBy<Shared.ContentTypes, SchemaNamespace.CollectionType>,
Utils.Object.KeysBy<Shared.ContentTypes, SchemaNamespace.CollectionType>,
ContentType
>;
export type SingleType = Extract<
Utils.KeysBy<Shared.ContentTypes, SchemaNamespace.SingleType>,
Utils.Object.KeysBy<Shared.ContentTypes, SchemaNamespace.SingleType>,
ContentType
>;

View File

@ -67,7 +67,7 @@ export type GetSeparator<T extends Any = Any> = T extends Scoped
* type T = WithSeparator<Admin> | WithSeparator<API>
* // ^ 'admin::' | 'api::{string}.'
*/
export type WithSeparator<N extends Any> = Utils.Suffix<N, GetSeparator<N>>;
export type WithSeparator<N extends Any> = Utils.String.Suffix<N, GetSeparator<N>>;
/**
* Represents namespaces composed of an origin and a name, separated by colons

View File

@ -78,7 +78,9 @@ export interface Info {
/**
* Low level data structure referencing every schema attribute and its name
*/
export interface Attributes extends Utils.StringRecord<Attribute.Any> {}
export interface Attributes {
[key: string]: Attribute.Any;
}
/**
* Structure containing every core schema options and their associated value

View File

@ -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<GenericService>;
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<GenericController>;
readonly controllers: Shared.Controllers;
/**
* Find a controller using its unique identifier

View File

@ -1,7 +1,7 @@
import type * as Namespace from './namespace';
import type * as Utils from '../utils';
type StringSuffix<T extends string> = Utils.Suffix<T, string>;
type StringSuffix<T extends string> = Utils.String.Suffix<T, string>;
/**
* Template for services' unique identifier

View File

@ -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<S extends Literal> = `${string}${S}${string}`;
/**
* Used to make sure the given string is not empty
*/
export type NonEmpty<T extends string> = T extends '' ? never : T;
/**
* Split the given string into a tuple using the given `S` literal
*/
export type Split<T extends string, S extends Literal> = T extends `${infer A}${S}${infer B}`
? [A, ...Split<B, S>]
: T extends ''
? []
: [T];
/**
* Aggregate the given tuple into a string, separated by the given `S` literal
*/
export type Join<T extends unknown[], S extends Literal> = T extends [
infer F extends Literal,
...infer R
]
? R['length'] extends 0
? F
: `${F}${S}${Join<R, S>}`
: never;
/**
* Add a literal suffix (`S`) at the end of the given string
*/
export type Suffix<T extends string, S extends Literal> = `${T}${S}`;
/**
* Add a literal prefix (`S`) at the beginning of the given string
*/
export type Prefix<T extends string, S extends Literal> = `${S}${T}`;
/**
*
* Extract the array values into an union type
*
**/
export type GetArrayValues<T extends Array<unknown>> = T extends Array<infer U> ? U : never;
/**
* Creates a record where every key is a string and every value is `T`
*/
export type StringRecord<T> = Record<string, T>;
/**
* 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<Obj, Base>
* // 'foo' | 'bar'
*/
export type KeysBy<T, U> = {
[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<Obj, Base>
* // { foo: { x: 'foo' }, bar: { x: 'bar' } }
*/
export type PickBy<T, U> = Pick<T, KeysBy<T, U>>;
/**
* 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<never>
* // unknown
*
* type X = NeverGuard<never, string>
* // string
*/
export type NeverGuard<T, U = unknown> = [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 extends keyof T> = T[U];

View File

@ -0,0 +1,6 @@
/**
*
* Extract the array values into an union type
*
**/
export type Values<T extends Array<unknown>> = T extends Array<infer U> ? U : never;

View File

@ -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<never>
* // unknown
*
* type X = Never<never, string>
* // string
*/
export type Never<T, U = unknown> = [T] extends [never] ? U : T;

View File

@ -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 extends keyof T> = T[U];

View File

@ -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<Obj, Base>
* // 'foo' | 'bar'
*/
export type KeysBy<T, U> = {
[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<Obj, Base>
* // { foo: { x: 'foo' }, bar: { x: 'bar' } }
*/
export type PickBy<T, U> = Pick<T, KeysBy<T, U>>;

View File

@ -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<S extends Literal> = `${string}${S}${string}`;
/**
* Used to make sure the given string is not empty
*/
export type NonEmpty<T extends string> = T extends '' ? never : T;
/**
* Split the given string into a tuple using the given `S` literal
*/
export type Split<T extends string, S extends Literal> = T extends `${infer A}${S}${infer B}`
? [A, ...Split<B, S>]
: T extends ''
? []
: [T];
/**
* Add a literal suffix (`S`) at the end of the given string
*/
export type Suffix<T extends string, S extends Literal> = `${T}${S}`;
/**
* Add a literal prefix (`S`) at the beginning of the given string
*/
export type Prefix<T extends string, S extends Literal> = `${S}${T}`;
/**
* Creates a record where every key is a string and every value is `T`
*/
export type Dict<T> = Record<string, T>;

View File

@ -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 unknown[], S extends Literal> = T extends [
infer F extends Literal,
...infer R
]
? R['length'] extends 0
? F
: `${F}${S}${Join<R, S>}`
: never;