feat(server): add model base (#9734)

This commit is contained in:
forehalo
2025-01-17 02:03:53 +00:00
parent c2149f218b
commit 64335b9e0c
12 changed files with 105 additions and 65 deletions

View File

@@ -1,31 +1,71 @@
import { Global, Injectable, Module } from '@nestjs/common';
import {
ExistingProvider,
FactoryProvider,
Global,
Module,
} from '@nestjs/common';
import { ModuleRef } from '@nestjs/core';
import { ApplyType } from '../base';
import { FeatureModel } from './feature';
import { MODELS_SYMBOL } from './provider';
import { SessionModel } from './session';
import { UserModel } from './user';
import { VerificationTokenModel } from './verification-token';
const models = [
UserModel,
SessionModel,
VerificationTokenModel,
FeatureModel,
] as const;
const MODELS = {
user: UserModel,
session: SessionModel,
verificationToken: VerificationTokenModel,
feature: FeatureModel,
};
@Injectable()
export class Models {
constructor(
public readonly user: UserModel,
public readonly session: SessionModel,
public readonly verificationToken: VerificationTokenModel,
public readonly feature: FeatureModel
) {}
}
type ModelsType = {
[K in keyof typeof MODELS]: InstanceType<(typeof MODELS)[K]>;
};
export class Models extends ApplyType<ModelsType>() {}
const ModelsProvider: FactoryProvider = {
provide: Models,
useFactory: (ref: ModuleRef) => {
return new Proxy({} as any, {
get: (target, prop) => {
// cache
if (prop in target) {
return target[prop];
}
// find the model instance
// @ts-expect-error null detection happens right after
const Model = MODELS[prop];
if (!Model) {
return undefined;
}
const model = ref.get(Model);
if (!model) {
throw new Error(`Failed to initialize model ${Model.name}`);
}
target[prop] = model;
return model;
},
});
},
inject: [ModuleRef],
};
const ModelsSymbolProvider: ExistingProvider = {
provide: MODELS_SYMBOL,
useExisting: Models,
};
@Global()
@Module({
providers: [...models, Models],
exports: [Models],
providers: [...Object.values(MODELS), ModelsProvider, ModelsSymbolProvider],
exports: [ModelsProvider],
})
export class ModelModules {}