Skip to content

Commit

Permalink
Merge pull request #21 from mizdra/refactoring
Browse files Browse the repository at this point in the history
Refactoring
  • Loading branch information
mizdra authored Aug 27, 2023
2 parents 5843bc5 + e6c8ae9 commit 2767ab9
Show file tree
Hide file tree
Showing 3 changed files with 74 additions and 123 deletions.
49 changes: 49 additions & 0 deletions src/factory.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import { ResolvedFields, DefaultFieldsResolver, InputFieldsResolver, resolveFields } from './field-resolver.js';
import { getSequenceCounter, resetSequence } from './sequence.js';
import { Merge } from './util.js';

export interface TypeFactoryDefineOptions<
Type extends Record<string, unknown>,
TransientFields extends Record<string, unknown>,
> {
defaultFields: DefaultFieldsResolver<Type & TransientFields>;
}
export interface TypeFactoryInterface<
Type extends Record<string, unknown>,
TransientFields extends Record<string, unknown>,
Options extends TypeFactoryDefineOptions<Type, TransientFields>,
> {
build(): Promise<Pick<Merge<ResolvedFields<Options['defaultFields']>, ResolvedFields<{}>>, keyof Type>>;
build<const T extends InputFieldsResolver<Type & TransientFields>>(
inputFieldsResolver: T,
): Promise<Pick<Merge<ResolvedFields<Options['defaultFields']>, ResolvedFields<T>>, keyof Type>>;
resetSequence(): void;
}

export function defineTypeFactoryInternal<
Type extends Record<string, unknown>,
TransientFields extends Record<string, unknown>,
Options extends TypeFactoryDefineOptions<Type, TransientFields>,
>(
typeFieldNames: readonly (keyof Type)[],
{ defaultFields: defaultFieldsResolver }: Options,
): TypeFactoryInterface<Type, TransientFields, Options> {
const seqKey = {};
const getSeq = () => getSequenceCounter(seqKey);
return {
async build<const T extends InputFieldsResolver<Type & TransientFields>>(
inputFieldsResolver?: T,
): Promise<Pick<Merge<ResolvedFields<Options['defaultFields']>, ResolvedFields<T>>, keyof Type>> {
const seq = getSeq();
return resolveFields<Type, TransientFields, Options['defaultFields'], T>(
typeFieldNames,
seq,
defaultFieldsResolver,
inputFieldsResolver ?? ({} as T),
);
},
resetSequence() {
resetSequence(seqKey);
},
};
}
7 changes: 1 addition & 6 deletions src/field-resolver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,7 @@ export type DefaultFieldsResolver<TypeWithTransientFields> = {
>;
};
/** The type of `inputFields` option of `build` method. */
export type InputFieldsResolver<TypeWithTransientFields> = {
[FieldName in keyof TypeWithTransientFields]?: FieldResolver<
TypeWithTransientFields,
DeepReadonly<DeepOptional<TypeWithTransientFields>[FieldName]>
>;
};
export type InputFieldsResolver<TypeWithTransientFields> = Partial<DefaultFieldsResolver<TypeWithTransientFields>>;

// eslint-disable-next-line @typescript-eslint/no-unused-vars
export type ResolvedField<T extends FieldResolver<unknown, unknown>> = T extends FieldResolver<infer _, infer R>
Expand Down
141 changes: 24 additions & 117 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,6 @@
import {
type ResolvedFields,
type DefaultFieldsResolver,
type InputFieldsResolver,
resolveFields,
lazy,
} from './field-resolver.js';
import { getSequenceCounter, resetSequence, resetAllSequence } from './sequence.js';
import { type Merge } from './util.js';
import { TypeFactoryDefineOptions, TypeFactoryInterface, defineTypeFactoryInternal } from './factory.js';
import { lazy } from './field-resolver.js';
import { resetAllSequence } from './sequence.js';

export { resetAllSequence, lazy };

Expand All @@ -32,43 +26,14 @@ const UserFieldNames = ['id', 'firstName', 'lastName', 'fullName'] as const;

// ---------- Book ----------

export interface BookFactoryDefineOptions<TransientFields extends Record<string, unknown>> {
defaultFields: DefaultFieldsResolver<Book & TransientFields>;
}
export interface BookFactoryInterface<
export type BookFactoryDefineOptions<TransientFields extends Record<string, unknown>> = TypeFactoryDefineOptions<
Book,
TransientFields
>;
export type BookFactoryInterface<
TransientFields extends Record<string, unknown>,
Options extends BookFactoryDefineOptions<TransientFields>,
> {
build(): Promise<Pick<Merge<ResolvedFields<Options['defaultFields']>, ResolvedFields<{}>>, keyof Book>>;
build<const T extends InputFieldsResolver<Book & TransientFields>>(
inputFieldsResolver: T,
): Promise<Pick<Merge<ResolvedFields<Options['defaultFields']>, ResolvedFields<T>>, keyof Book>>;
resetSequence(): void;
}

function defineBookFactoryInternal<
TransientFields extends Record<string, unknown>,
Options extends BookFactoryDefineOptions<TransientFields>,
>({ defaultFields: defaultFieldsResolver }: Options): BookFactoryInterface<TransientFields, Options> {
const seqKey = {};
const getSeq = () => getSequenceCounter(seqKey);
return {
async build<const T extends InputFieldsResolver<Book & TransientFields>>(
inputFieldsResolver?: T,
): Promise<Pick<Merge<ResolvedFields<Options['defaultFields']>, ResolvedFields<T>>, keyof Book>> {
const seq = getSeq();
return resolveFields<Book, TransientFields, Options['defaultFields'], T>(
BookFieldNames,
seq,
defaultFieldsResolver,
inputFieldsResolver ?? ({} as T),
);
},
resetSequence() {
resetSequence(seqKey);
},
};
}
> = TypeFactoryInterface<Book, TransientFields, Options>;

/**
* Define factory for {@link Book} model.
Expand All @@ -79,48 +44,19 @@ function defineBookFactoryInternal<
export function defineBookFactory<Options extends BookFactoryDefineOptions<{}>>(
options: Options,
): BookFactoryInterface<{}, Options> {
return defineBookFactoryInternal(options);
return defineTypeFactoryInternal<Book, {}, Options>(BookFieldNames, options);
}

// ---------- Author ----------

export interface AuthorFactoryDefineOptions<TransientFields extends Record<string, unknown>> {
defaultFields: DefaultFieldsResolver<Author & TransientFields>;
}
export interface AuthorFactoryInterface<
TransientFields extends Record<string, unknown>,
Options extends AuthorFactoryDefineOptions<TransientFields>,
> {
build(): Promise<Pick<Merge<ResolvedFields<Options['defaultFields']>, ResolvedFields<{}>>, keyof Author>>;
build<const T extends InputFieldsResolver<Author & TransientFields>>(
inputFieldsResolver: T,
): Promise<Pick<Merge<ResolvedFields<Options['defaultFields']>, ResolvedFields<T>>, keyof Author>>;
resetSequence(): void;
}

function defineAuthorFactoryInternal<
export type AuthorFactoryDefineOptions<TransientFields extends Record<string, unknown>> = TypeFactoryDefineOptions<
Author,
TransientFields
>;
export type AuthorFactoryInterface<
TransientFields extends Record<string, unknown>,
Options extends AuthorFactoryDefineOptions<TransientFields>,
>({ defaultFields: defaultFieldsResolver }: Options): AuthorFactoryInterface<TransientFields, Options> {
const seqKey = {};
const getSeq = () => getSequenceCounter(seqKey);
return {
async build<const T extends InputFieldsResolver<Author & TransientFields>>(
inputFieldsResolver?: T,
): Promise<Pick<Merge<ResolvedFields<Options['defaultFields']>, ResolvedFields<T>>, keyof Author>> {
const seq = getSeq();
return resolveFields<Author, TransientFields, Options['defaultFields'], T>(
AuthorFieldNames,
seq,
defaultFieldsResolver,
inputFieldsResolver ?? ({} as T),
);
},
resetSequence() {
resetSequence(seqKey);
},
};
}
> = TypeFactoryInterface<Author, TransientFields, Options>;

/**
* Define factory for {@link Author} model.
Expand All @@ -131,48 +67,19 @@ function defineAuthorFactoryInternal<
export function defineAuthorFactory<Options extends AuthorFactoryDefineOptions<{}>>(
options: Options,
): AuthorFactoryInterface<{}, Options> {
return defineAuthorFactoryInternal(options);
return defineTypeFactoryInternal<Author, {}, Options>(AuthorFieldNames, options);
}

// ---------- User ----------

export interface UserFactoryDefineOptions<TransientFields extends Record<string, unknown>> {
defaultFields: DefaultFieldsResolver<User & TransientFields>;
}
export interface UserFactoryInterface<
export type UserFactoryDefineOptions<TransientFields extends Record<string, unknown>> = TypeFactoryDefineOptions<
User,
TransientFields
>;
export type UserFactoryInterface<
TransientFields extends Record<string, unknown>,
Options extends UserFactoryDefineOptions<TransientFields>,
> {
build(): Promise<Pick<Merge<ResolvedFields<Options['defaultFields']>, ResolvedFields<{}>>, keyof User>>;
build<const T extends InputFieldsResolver<User & TransientFields>>(
inputFieldsResolver: T,
): Promise<Pick<Merge<ResolvedFields<Options['defaultFields']>, ResolvedFields<T>>, keyof User>>;
resetSequence(): void;
}

function defineUserFactoryInternal<
TransientFields extends Record<string, unknown>,
Options extends UserFactoryDefineOptions<TransientFields>,
>({ defaultFields: defaultFieldsResolver }: Options): UserFactoryInterface<TransientFields, Options> {
const seqKey = {};
const getSeq = () => getSequenceCounter(seqKey);
return {
async build<const T extends InputFieldsResolver<User & TransientFields>>(
inputFieldsResolver?: T,
): Promise<Pick<Merge<ResolvedFields<Options['defaultFields']>, ResolvedFields<T>>, keyof User>> {
const seq = getSeq();
return resolveFields<User, TransientFields, Options['defaultFields'], T>(
UserFieldNames,
seq,
defaultFieldsResolver,
inputFieldsResolver ?? ({} as T),
);
},
resetSequence() {
resetSequence(seqKey);
},
};
}
> = TypeFactoryInterface<User, TransientFields, Options>;

/**
* Define factory for {@link User} model.
Expand All @@ -183,5 +90,5 @@ function defineUserFactoryInternal<
export function defineUserFactory<Options extends UserFactoryDefineOptions<{}>>(
options: Options,
): UserFactoryInterface<{}, Options> {
return defineUserFactoryInternal(options);
return defineTypeFactoryInternal<User, {}, Options>(UserFieldNames, options);
}

0 comments on commit 2767ab9

Please sign in to comment.