Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
mizdra committed Aug 23, 2023
1 parent 4ed4a14 commit ee74ea0
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 4 deletions.
7 changes: 6 additions & 1 deletion src/field-resolver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { DeepOptional, DeepReadonly, Merge } from './util.js';

export type FieldResolverOptions<Type> = {
seq: number;
// TODO: transientFieldsResolver 由来の field name も受け取れるように。FieldResolverOptions<Type, TransientFieldNames> に拡張する必要があるのでは。
get: <FieldName extends keyof Type>(fieldName: FieldName) => Promise<Type[FieldName]>;
};

Expand All @@ -23,6 +24,8 @@ export type FieldResolver<Type, Field> = Field | Lazy<Type, Field>;
export type DefaultFieldsResolver<Type> = {
[FieldName in keyof Type]: FieldResolver<Type, DeepReadonly<DeepOptional<Type>[FieldName]>>;
};
/** The type of `transientFields` option of `defineFactory` function. */
export type TransientFieldsResolver<Type> = Record<string, FieldResolver<Type, unknown>>;
/** The type of `inputFields` option of `build` method. */
export type InputFieldsResolver<Type> = {
[FieldName in keyof Type]?: FieldResolver<Type, DeepReadonly<DeepOptional<Type>[FieldName]>>;
Expand All @@ -40,10 +43,12 @@ export type ResolvedFields<FieldsResolver extends Record<string, FieldResolver<u
export async function resolveFields<
Type extends Record<string, unknown>,
_DefaultFieldsResolver extends DefaultFieldsResolver<Type> = DefaultFieldsResolver<Type>,
_TransientFieldsResolver extends TransientFieldsResolver<Type> = TransientFieldsResolver<Type>,
_InputFieldsResolver extends InputFieldsResolver<Type> = InputFieldsResolver<Type>,
>(
seq: number,
defaultFieldsResolver: _DefaultFieldsResolver,
transientFieldsResolver: _TransientFieldsResolver,
inputFieldsResolver: _InputFieldsResolver,
): Promise<Merge<ResolvedFields<_DefaultFieldsResolver>, ResolvedFields<_InputFieldsResolver>>> {
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Use any type as it is impossible to match types.
Expand All @@ -61,7 +66,7 @@ export async function resolveFields<
}

async function resolveFieldAndUpdateCache<FieldName extends keyof Type>(
fieldName: FieldName,
fieldName: FieldName, // TODO: transientFieldsResolver 由来の field name も受け取れるように
): Promise<Type[FieldName]> {
if (fieldName in fields) return fields[fieldName];

Expand Down
13 changes: 10 additions & 3 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import {
type ResolvedFields,
type DefaultFieldsResolver,
type TransientFieldsResolver,
type InputFieldsResolver,
resolveFields,
lazy,
Expand Down Expand Up @@ -32,6 +33,7 @@ export type User = {

interface BookFactoryDefineOptions {
defaultFields: DefaultFieldsResolver<Book>;
transientFields?: TransientFieldsResolver<Book>;
}
interface BookFactoryInterface<TOptions extends BookFactoryDefineOptions> {
build(): Promise<ResolvedFields<TOptions['defaultFields']>>;
Expand All @@ -44,6 +46,7 @@ interface BookFactoryInterface<TOptions extends BookFactoryDefineOptions> {

function defineBookFactoryInternal<TOptions extends BookFactoryDefineOptions>({
defaultFields: defaultFieldsResolver,
transientFields: transientFieldsResolver,
}: TOptions): BookFactoryInterface<TOptions> {
const seqKey = {};
const getSeq = () => getSequenceCounter(seqKey);
Expand All @@ -52,7 +55,7 @@ function defineBookFactoryInternal<TOptions extends BookFactoryDefineOptions>({
inputFieldsResolver?: T,
): Promise<Merge<ResolvedFields<TOptions['defaultFields']>, ResolvedFields<T>>> {
const seq = getSeq();
return resolveFields(seq, defaultFieldsResolver, inputFieldsResolver ?? ({} as T));
return resolveFields(seq, defaultFieldsResolver, transientFieldsResolver ?? {}, inputFieldsResolver ?? ({} as T));
},
resetSequence() {
resetSequence(seqKey);
Expand All @@ -76,6 +79,7 @@ export function defineBookFactory<TOptions extends BookFactoryDefineOptions>(

interface AuthorFactoryDefineOptions {
defaultFields: DefaultFieldsResolver<Author>;
transientFields?: TransientFieldsResolver<Author>;
}
interface AuthorFactoryInterface<TOptions extends AuthorFactoryDefineOptions> {
build(): Promise<ResolvedFields<TOptions['defaultFields']>>;
Expand All @@ -88,6 +92,7 @@ interface AuthorFactoryInterface<TOptions extends AuthorFactoryDefineOptions> {

function defineAuthorFactoryInternal<TOptions extends AuthorFactoryDefineOptions>({
defaultFields: defaultFieldsResolver,
transientFields: transientFieldsResolver,
}: TOptions): AuthorFactoryInterface<TOptions> {
const seqKey = {};
const getSeq = () => getSequenceCounter(seqKey);
Expand All @@ -96,7 +101,7 @@ function defineAuthorFactoryInternal<TOptions extends AuthorFactoryDefineOptions
inputFieldsResolver?: T,
): Promise<Merge<ResolvedFields<TOptions['defaultFields']>, ResolvedFields<T>>> {
const seq = getSeq();
return resolveFields(seq, defaultFieldsResolver, inputFieldsResolver ?? ({} as T));
return resolveFields(seq, defaultFieldsResolver, transientFieldsResolver ?? {}, inputFieldsResolver ?? ({} as T));
},
resetSequence() {
resetSequence(seqKey);
Expand All @@ -120,6 +125,7 @@ export function defineAuthorFactory<TOptions extends AuthorFactoryDefineOptions>

interface UserFactoryDefineOptions {
defaultFields: DefaultFieldsResolver<User>;
transientFields?: TransientFieldsResolver<User>;
}
interface UserFactoryInterface<TOptions extends UserFactoryDefineOptions> {
build(): Promise<ResolvedFields<TOptions['defaultFields']>>;
Expand All @@ -132,6 +138,7 @@ interface UserFactoryInterface<TOptions extends UserFactoryDefineOptions> {

function defineUserFactoryInternal<TOptions extends UserFactoryDefineOptions>({
defaultFields: defaultFieldsResolver,
transientFields: transientFieldsResolver,
}: TOptions): UserFactoryInterface<TOptions> {
const seqKey = {};
const getSeq = () => getSequenceCounter(seqKey);
Expand All @@ -140,7 +147,7 @@ function defineUserFactoryInternal<TOptions extends UserFactoryDefineOptions>({
inputFieldsResolver?: T,
): Promise<Merge<ResolvedFields<TOptions['defaultFields']>, ResolvedFields<T>>> {
const seq = getSeq();
return resolveFields(seq, defaultFieldsResolver, inputFieldsResolver ?? ({} as T));
return resolveFields(seq, defaultFieldsResolver, transientFieldsResolver ?? {}, inputFieldsResolver ?? ({} as T));
},
resetSequence() {
resetSequence(seqKey);
Expand Down

0 comments on commit ee74ea0

Please sign in to comment.