mirror of
https://github.com/toeverything/AFFiNE.git
synced 2024-12-02 14:33:54 +03:00
feat(server): runtime service config (#7644)
This commit is contained in:
parent
67248316bd
commit
fcf0ecbaa2
@ -12,6 +12,7 @@ AFFiNE.ENV_MAP = {
|
||||
MAILER_PASSWORD: 'mailer.auth.pass',
|
||||
MAILER_SENDER: 'mailer.from.address',
|
||||
MAILER_SECURE: ['mailer.secure', 'boolean'],
|
||||
DATABASE_URL: 'database.datasourceUrl',
|
||||
OAUTH_GOOGLE_CLIENT_ID: 'plugins.oauth.providers.google.clientId',
|
||||
OAUTH_GOOGLE_CLIENT_SECRET: 'plugins.oauth.providers.google.clientSecret',
|
||||
OAUTH_GITHUB_CLIENT_ID: 'plugins.oauth.providers.github.clientId',
|
||||
|
@ -2,10 +2,18 @@ import './config';
|
||||
|
||||
import { Module } from '@nestjs/common';
|
||||
|
||||
import { ServerConfigResolver, ServerRuntimeConfigResolver } from './resolver';
|
||||
import {
|
||||
ServerConfigResolver,
|
||||
ServerRuntimeConfigResolver,
|
||||
ServerServiceConfigResolver,
|
||||
} from './resolver';
|
||||
|
||||
@Module({
|
||||
providers: [ServerConfigResolver, ServerRuntimeConfigResolver],
|
||||
providers: [
|
||||
ServerConfigResolver,
|
||||
ServerRuntimeConfigResolver,
|
||||
ServerServiceConfigResolver,
|
||||
],
|
||||
})
|
||||
export class ServerConfigModule {}
|
||||
export { ADD_ENABLED_FEATURES, ServerConfigType } from './resolver';
|
||||
|
@ -175,11 +175,42 @@ export class ServerConfigResolver {
|
||||
}
|
||||
}
|
||||
|
||||
@ObjectType()
|
||||
class ServerServiceConfig {
|
||||
@Field()
|
||||
name!: string;
|
||||
|
||||
@Field(() => GraphQLJSONObject)
|
||||
config!: any;
|
||||
}
|
||||
|
||||
interface ServerServeConfig {
|
||||
https: boolean;
|
||||
host: string;
|
||||
port: number;
|
||||
externalUrl: string;
|
||||
}
|
||||
|
||||
interface ServerMailerConfig {
|
||||
host?: string | null;
|
||||
port?: number | null;
|
||||
secure?: boolean | null;
|
||||
service?: string | null;
|
||||
sender?: string | null;
|
||||
}
|
||||
|
||||
interface ServerDatabaseConfig {
|
||||
host: string;
|
||||
port: number;
|
||||
user?: string | null;
|
||||
database: string;
|
||||
}
|
||||
|
||||
@Admin()
|
||||
@Resolver(() => ServerRuntimeConfigType)
|
||||
export class ServerRuntimeConfigResolver {
|
||||
constructor(private readonly config: Config) {}
|
||||
|
||||
@Admin()
|
||||
@Query(() => [ServerRuntimeConfigType], {
|
||||
description: 'get all server runtime configurable settings',
|
||||
})
|
||||
@ -187,7 +218,6 @@ export class ServerRuntimeConfigResolver {
|
||||
return this.config.runtime.list();
|
||||
}
|
||||
|
||||
@Admin()
|
||||
@Mutation(() => ServerRuntimeConfigType, {
|
||||
description: 'update server runtime configurable setting',
|
||||
})
|
||||
@ -198,7 +228,6 @@ export class ServerRuntimeConfigResolver {
|
||||
return await this.config.runtime.set(id as any, value);
|
||||
}
|
||||
|
||||
@Admin()
|
||||
@Mutation(() => [ServerRuntimeConfigType], {
|
||||
description: 'update multiple server runtime configurable settings',
|
||||
})
|
||||
@ -213,3 +242,57 @@ export class ServerRuntimeConfigResolver {
|
||||
return results;
|
||||
}
|
||||
}
|
||||
|
||||
@Admin()
|
||||
@Resolver(() => ServerServiceConfig)
|
||||
export class ServerServiceConfigResolver {
|
||||
constructor(private readonly config: Config) {}
|
||||
|
||||
@Query(() => [ServerServiceConfig])
|
||||
serverServiceConfigs() {
|
||||
return [
|
||||
{
|
||||
name: 'server',
|
||||
config: this.serve(),
|
||||
},
|
||||
{
|
||||
name: 'mailer',
|
||||
config: this.mail(),
|
||||
},
|
||||
{
|
||||
name: 'database',
|
||||
config: this.database(),
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
serve(): ServerServeConfig {
|
||||
return this.config.server;
|
||||
}
|
||||
|
||||
mail(): ServerMailerConfig {
|
||||
const sender =
|
||||
typeof this.config.mailer.from === 'string'
|
||||
? this.config.mailer.from
|
||||
: this.config.mailer.from?.address;
|
||||
|
||||
return {
|
||||
host: this.config.mailer.host,
|
||||
port: this.config.mailer.port,
|
||||
secure: this.config.mailer.secure,
|
||||
service: this.config.mailer.service,
|
||||
sender,
|
||||
};
|
||||
}
|
||||
|
||||
database(): ServerDatabaseConfig {
|
||||
const url = new URL(this.config.database.datasourceUrl);
|
||||
|
||||
return {
|
||||
host: url.hostname,
|
||||
port: Number(url.port),
|
||||
user: url.username,
|
||||
database: url.pathname.slice(1) ?? url.username,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
17
packages/backend/server/src/fundamentals/prisma/config.ts
Normal file
17
packages/backend/server/src/fundamentals/prisma/config.ts
Normal file
@ -0,0 +1,17 @@
|
||||
import type { Prisma } from '@prisma/client';
|
||||
|
||||
import { defineStartupConfig, ModuleConfig } from '../config';
|
||||
|
||||
interface PrismaStartupConfiguration extends Prisma.PrismaClientOptions {
|
||||
datasourceUrl: string;
|
||||
}
|
||||
|
||||
declare module '../config' {
|
||||
interface AppConfig {
|
||||
database: ModuleConfig<PrismaStartupConfiguration>;
|
||||
}
|
||||
}
|
||||
|
||||
defineStartupConfig('database', {
|
||||
datasourceUrl: '',
|
||||
});
|
@ -1,18 +1,22 @@
|
||||
import './config';
|
||||
|
||||
import { Global, Module, Provider } from '@nestjs/common';
|
||||
import { PrismaClient } from '@prisma/client';
|
||||
|
||||
import { Config } from '../config';
|
||||
import { PrismaService } from './service';
|
||||
|
||||
// only `PrismaClient` can be injected
|
||||
const clientProvider: Provider = {
|
||||
provide: PrismaClient,
|
||||
useFactory: () => {
|
||||
useFactory: (config: Config) => {
|
||||
if (PrismaService.INSTANCE) {
|
||||
return PrismaService.INSTANCE;
|
||||
}
|
||||
|
||||
return new PrismaService();
|
||||
return new PrismaService(config.database);
|
||||
},
|
||||
inject: [Config],
|
||||
};
|
||||
|
||||
@Global()
|
||||
|
@ -1,6 +1,6 @@
|
||||
import type { OnModuleDestroy, OnModuleInit } from '@nestjs/common';
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { PrismaClient } from '@prisma/client';
|
||||
import { Prisma, PrismaClient } from '@prisma/client';
|
||||
|
||||
@Injectable()
|
||||
export class PrismaService
|
||||
@ -9,8 +9,8 @@ export class PrismaService
|
||||
{
|
||||
static INSTANCE: PrismaService | null = null;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
constructor(opts: Prisma.PrismaClientOptions) {
|
||||
super(opts);
|
||||
PrismaService.INSTANCE = this;
|
||||
}
|
||||
|
||||
|
@ -541,6 +541,7 @@ type Query {
|
||||
|
||||
"""get all server runtime configurable settings"""
|
||||
serverRuntimeConfig: [ServerRuntimeConfigType!]!
|
||||
serverServiceConfigs: [ServerServiceConfig!]!
|
||||
|
||||
"""Get user by email"""
|
||||
user(email: String!): UserOrLimitedUser
|
||||
@ -663,6 +664,11 @@ type ServerRuntimeConfigType {
|
||||
value: JSON!
|
||||
}
|
||||
|
||||
type ServerServiceConfig {
|
||||
config: JSONObject!
|
||||
name: String!
|
||||
}
|
||||
|
||||
type SubscriptionAlreadyExistsDataType {
|
||||
plan: String!
|
||||
}
|
||||
|
@ -798,6 +798,7 @@ export interface Query {
|
||||
serverConfig: ServerConfigType;
|
||||
/** get all server runtime configurable settings */
|
||||
serverRuntimeConfig: Array<ServerRuntimeConfigType>;
|
||||
serverServiceConfigs: Array<ServerServiceConfig>;
|
||||
/** Get user by email */
|
||||
user: Maybe<UserOrLimitedUser>;
|
||||
/** Get user by id */
|
||||
@ -952,6 +953,12 @@ export interface ServerRuntimeConfigType {
|
||||
value: Scalars['JSON']['output'];
|
||||
}
|
||||
|
||||
export interface ServerServiceConfig {
|
||||
__typename?: 'ServerServiceConfig';
|
||||
config: Scalars['JSONObject']['output'];
|
||||
name: Scalars['String']['output'];
|
||||
}
|
||||
|
||||
export interface SubscriptionAlreadyExistsDataType {
|
||||
__typename?: 'SubscriptionAlreadyExistsDataType';
|
||||
plan: Scalars['String']['output'];
|
||||
|
Loading…
Reference in New Issue
Block a user