@medusajs/utils
Version:
Medusa utilities functions shared by Medusa core and Modules
133 lines • 5.2 kB
TypeScript
import { DMLSchema, IDmlEntity, IDmlEntityConfig, InferDmlEntityNameFromConfig, Prettify, SnakeCase } from "@medusajs/types";
import { PrimaryKeyModifier } from "../../dml/properties/primary-key";
/**
* Utils
*/
type FlattenUnion<T> = T extends {
[K in keyof T]: infer U;
} ? {
[K in keyof T]: U;
} : never;
type UnionToIntersection<U> = (U extends any ? (k: U) => void : never) extends (k: infer I) => void ? I : never;
type UnionToOvlds<U> = UnionToIntersection<U extends any ? (f: U) => void : never>;
type PopUnion<U> = UnionToOvlds<U> extends (a: infer A) => void ? A : never;
type IsUnion<T> = [T] extends [UnionToIntersection<T>] ? false : true;
type UnionToArray<T, A extends unknown[] = []> = IsUnion<T> extends true ? UnionToArray<Exclude<T, PopUnion<T>>, [PopUnion<T>, ...A]> : [T, ...A];
/**
* End of utils
*/
/**
* Linkable keys
*/
type InferLinkableKeyName<Key, Property, DmlConfig extends IDmlEntityConfig> = Property extends PrimaryKeyModifier<any, any> ? `${Lowercase<SnakeCase<InferDmlEntityNameFromConfig<DmlConfig>>>}_${Key & string}` : never;
type InferSchemaLinkableKeys<T> = T extends IDmlEntity<infer Schema, infer Config> ? {
[K in keyof Schema as Schema[K] extends PrimaryKeyModifier<any, any> ? InferLinkableKeyName<K, Schema[K], Config> : never]: Capitalize<InferDmlEntityNameFromConfig<Config>>;
} : {};
type InferSchemasLinkableKeys<T extends IDmlEntity<any, any>[]> = {
[K in keyof T]: InferSchemaLinkableKeys<T[K]>;
};
type AggregateSchemasLinkableKeys<T extends IDmlEntity<any, any>[]> = {
[K in keyof InferSchemasLinkableKeys<T>]: InferSchemasLinkableKeys<T>[K];
};
/**
* From an array of DmlEntity, returns a formatted object with the linkable keys
*
* @example:
*
* const user = model.define("user", {
* id: model.id(),
* name: model.text(),
* })
*
* const car = model.define("car", {
* id: model.id(),
* number_plate: model.text().primaryKey(),
* test: model.text(),
* })
*
* const linkableKeys = buildLinkableKeysFromDmlObjects([user, car]) // { user_id: 'user', car_number_plate: 'car' }
*
*/
export type InferLinkableKeys<T extends IDmlEntity<any, any>[]> = UnionToIntersection<FlattenUnion<AggregateSchemasLinkableKeys<T>>[0]>;
/**
* End Linkable keys
*/
/**
* Links config
*/
/**
* From a union infer an Array and return the last element
*/
type InferLastLink<ServiceName extends string, DmlEntity> = UnionToArray<InferSchemaLinksConfig<ServiceName, DmlEntity>[keyof InferSchemaLinksConfig<ServiceName, DmlEntity>]> extends [...any, infer V] ? V : never;
type InferLastPrimaryKey<ServiceName extends string, DmlEntity> = InferLastLink<ServiceName, DmlEntity> extends {
primaryKey: infer PrimaryKey;
} ? PrimaryKey : string;
type InferLastLinkable<ServiceName extends string, DmlEntity> = InferLastLink<ServiceName, DmlEntity> extends {
linkable: infer Linkable;
} ? Linkable : string;
type InferPrimaryKeyNameOrNever<Schema extends DMLSchema, Key extends keyof Schema> = Schema[Key] extends PrimaryKeyModifier<any, any> ? Key : never;
type InferSchemaLinksConfig<ServiceName extends string, T> = T extends IDmlEntity<infer Schema, infer Config> ? {
[K in keyof Schema as InferPrimaryKeyNameOrNever<Schema, K>]: {
serviceName: ServiceName;
field: T extends IDmlEntity<any, infer Config> ? InferDmlEntityNameFromConfig<Config> : string;
linkable: InferLinkableKeyName<K, Schema[K], Config>;
primaryKey: K;
};
} : {};
/**
* From an array of DmlEntity, returns a formatted links object.
* the toJSON of each object representation will return the last linkable definition
* as the default. To specify a specific linkable, you can chain until the desired linkable property.
*
*
* @example:
*
* const user = model.define("user", {
* id: model.id(),
* name: model.text(),
* })
*
* const car = model.define("car", {
* id: model.id(),
* number_plate: model.text().primaryKey(),
* test: model.text(),
* })
*
* const linkConfig = buildLinkConfigFromModelObjects([user, car])
* // {
* // user: {
* // id: {
* // serviceName: 'userService',
* // field: 'user',
* // linkable: 'user_id',
* // primaryKey: 'id'
* // },
* // toJSON() { ... }
* // },
* // car: {
* // number_plate: {
* // serviceName: 'userService',
* // field: 'car',
* // linkable: 'car_number_plate',
* // primaryKey: 'number_plate'
* // },
* // toJSON() { ... }
* // }
* // }
*
*/
export type InfersLinksConfig<ServiceName extends string, T extends Record<string, IDmlEntity<any, any>>> = Prettify<{
[K in keyof T as T[K] extends IDmlEntity<any, infer Config> ? InferDmlEntityNameFromConfig<Config> : never]: Prettify<InferSchemaLinksConfig<ServiceName, T[K]> & {
toJSON: () => {
serviceName: ServiceName;
field: T[K] extends IDmlEntity<any, infer Config> ? InferDmlEntityNameFromConfig<Config> : string;
linkable: InferLastLinkable<ServiceName, T[K]>;
primaryKey: InferLastPrimaryKey<ServiceName, T[K]>;
};
}>;
}>;
export {};
/**
* End Links config
*/
//# sourceMappingURL=links-config.d.ts.map