mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-07-15 00:56:26 +08:00
85 lines
2.1 KiB
TypeScript
85 lines
2.1 KiB
TypeScript
import { PrismaService } from '../../prisma';
|
|
import { Feature, FeatureSchema, FeatureType } from './types';
|
|
|
|
class FeatureConfig {
|
|
readonly config: Feature;
|
|
|
|
constructor(data: any) {
|
|
const config = FeatureSchema.safeParse(data);
|
|
if (config.success) {
|
|
this.config = config.data;
|
|
} else {
|
|
throw new Error(`Invalid quota config: ${config.error.message}`);
|
|
}
|
|
}
|
|
|
|
/// feature name of quota
|
|
get name() {
|
|
return this.config.feature;
|
|
}
|
|
}
|
|
|
|
export class CopilotFeatureConfig extends FeatureConfig {
|
|
override config!: Feature & { feature: FeatureType.Copilot };
|
|
constructor(data: any) {
|
|
super(data);
|
|
|
|
if (this.config.feature !== FeatureType.Copilot) {
|
|
throw new Error('Invalid feature config: type is not Copilot');
|
|
}
|
|
}
|
|
}
|
|
|
|
export class EarlyAccessFeatureConfig extends FeatureConfig {
|
|
override config!: Feature & { feature: FeatureType.EarlyAccess };
|
|
|
|
constructor(data: any) {
|
|
super(data);
|
|
|
|
if (this.config.feature !== FeatureType.EarlyAccess) {
|
|
throw new Error('Invalid feature config: type is not EarlyAccess');
|
|
}
|
|
}
|
|
}
|
|
|
|
const FeatureConfigMap = {
|
|
[FeatureType.Copilot]: CopilotFeatureConfig,
|
|
[FeatureType.EarlyAccess]: EarlyAccessFeatureConfig,
|
|
};
|
|
|
|
export type FeatureConfigType<F extends FeatureType> = InstanceType<
|
|
(typeof FeatureConfigMap)[F]
|
|
>;
|
|
|
|
const FeatureCache = new Map<number, FeatureConfigType<FeatureType>>();
|
|
|
|
export async function getFeature(prisma: PrismaService, featureId: number) {
|
|
const cachedQuota = FeatureCache.get(featureId);
|
|
|
|
if (cachedQuota) {
|
|
return cachedQuota;
|
|
}
|
|
|
|
const feature = await prisma.features.findFirst({
|
|
where: {
|
|
id: featureId,
|
|
},
|
|
});
|
|
if (!feature) {
|
|
// this should unreachable
|
|
throw new Error(`Quota config ${featureId} not found`);
|
|
}
|
|
const ConfigClass = FeatureConfigMap[feature.feature as FeatureType];
|
|
|
|
if (!ConfigClass) {
|
|
throw new Error(`Feature config ${featureId} not found`);
|
|
}
|
|
|
|
const config = new ConfigClass(feature);
|
|
// we always edit quota config as a new quota config
|
|
// so we can cache it by featureId
|
|
FeatureCache.set(featureId, config);
|
|
|
|
return config;
|
|
}
|