mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-08-09 13:15:51 +08:00
feat(server): runtime service config (#7644)
This commit is contained in:
@@ -12,6 +12,7 @@ AFFiNE.ENV_MAP = {
|
|||||||
MAILER_PASSWORD: 'mailer.auth.pass',
|
MAILER_PASSWORD: 'mailer.auth.pass',
|
||||||
MAILER_SENDER: 'mailer.from.address',
|
MAILER_SENDER: 'mailer.from.address',
|
||||||
MAILER_SECURE: ['mailer.secure', 'boolean'],
|
MAILER_SECURE: ['mailer.secure', 'boolean'],
|
||||||
|
DATABASE_URL: 'database.datasourceUrl',
|
||||||
OAUTH_GOOGLE_CLIENT_ID: 'plugins.oauth.providers.google.clientId',
|
OAUTH_GOOGLE_CLIENT_ID: 'plugins.oauth.providers.google.clientId',
|
||||||
OAUTH_GOOGLE_CLIENT_SECRET: 'plugins.oauth.providers.google.clientSecret',
|
OAUTH_GOOGLE_CLIENT_SECRET: 'plugins.oauth.providers.google.clientSecret',
|
||||||
OAUTH_GITHUB_CLIENT_ID: 'plugins.oauth.providers.github.clientId',
|
OAUTH_GITHUB_CLIENT_ID: 'plugins.oauth.providers.github.clientId',
|
||||||
|
|||||||
@@ -2,10 +2,18 @@ import './config';
|
|||||||
|
|
||||||
import { Module } from '@nestjs/common';
|
import { Module } from '@nestjs/common';
|
||||||
|
|
||||||
import { ServerConfigResolver, ServerRuntimeConfigResolver } from './resolver';
|
import {
|
||||||
|
ServerConfigResolver,
|
||||||
|
ServerRuntimeConfigResolver,
|
||||||
|
ServerServiceConfigResolver,
|
||||||
|
} from './resolver';
|
||||||
|
|
||||||
@Module({
|
@Module({
|
||||||
providers: [ServerConfigResolver, ServerRuntimeConfigResolver],
|
providers: [
|
||||||
|
ServerConfigResolver,
|
||||||
|
ServerRuntimeConfigResolver,
|
||||||
|
ServerServiceConfigResolver,
|
||||||
|
],
|
||||||
})
|
})
|
||||||
export class ServerConfigModule {}
|
export class ServerConfigModule {}
|
||||||
export { ADD_ENABLED_FEATURES, ServerConfigType } from './resolver';
|
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)
|
@Resolver(() => ServerRuntimeConfigType)
|
||||||
export class ServerRuntimeConfigResolver {
|
export class ServerRuntimeConfigResolver {
|
||||||
constructor(private readonly config: Config) {}
|
constructor(private readonly config: Config) {}
|
||||||
|
|
||||||
@Admin()
|
|
||||||
@Query(() => [ServerRuntimeConfigType], {
|
@Query(() => [ServerRuntimeConfigType], {
|
||||||
description: 'get all server runtime configurable settings',
|
description: 'get all server runtime configurable settings',
|
||||||
})
|
})
|
||||||
@@ -187,7 +218,6 @@ export class ServerRuntimeConfigResolver {
|
|||||||
return this.config.runtime.list();
|
return this.config.runtime.list();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Admin()
|
|
||||||
@Mutation(() => ServerRuntimeConfigType, {
|
@Mutation(() => ServerRuntimeConfigType, {
|
||||||
description: 'update server runtime configurable setting',
|
description: 'update server runtime configurable setting',
|
||||||
})
|
})
|
||||||
@@ -198,7 +228,6 @@ export class ServerRuntimeConfigResolver {
|
|||||||
return await this.config.runtime.set(id as any, value);
|
return await this.config.runtime.set(id as any, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Admin()
|
|
||||||
@Mutation(() => [ServerRuntimeConfigType], {
|
@Mutation(() => [ServerRuntimeConfigType], {
|
||||||
description: 'update multiple server runtime configurable settings',
|
description: 'update multiple server runtime configurable settings',
|
||||||
})
|
})
|
||||||
@@ -213,3 +242,57 @@ export class ServerRuntimeConfigResolver {
|
|||||||
return results;
|
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,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -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 { Global, Module, Provider } from '@nestjs/common';
|
||||||
import { PrismaClient } from '@prisma/client';
|
import { PrismaClient } from '@prisma/client';
|
||||||
|
|
||||||
|
import { Config } from '../config';
|
||||||
import { PrismaService } from './service';
|
import { PrismaService } from './service';
|
||||||
|
|
||||||
// only `PrismaClient` can be injected
|
// only `PrismaClient` can be injected
|
||||||
const clientProvider: Provider = {
|
const clientProvider: Provider = {
|
||||||
provide: PrismaClient,
|
provide: PrismaClient,
|
||||||
useFactory: () => {
|
useFactory: (config: Config) => {
|
||||||
if (PrismaService.INSTANCE) {
|
if (PrismaService.INSTANCE) {
|
||||||
return PrismaService.INSTANCE;
|
return PrismaService.INSTANCE;
|
||||||
}
|
}
|
||||||
|
|
||||||
return new PrismaService();
|
return new PrismaService(config.database);
|
||||||
},
|
},
|
||||||
|
inject: [Config],
|
||||||
};
|
};
|
||||||
|
|
||||||
@Global()
|
@Global()
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import type { OnModuleDestroy, OnModuleInit } from '@nestjs/common';
|
import type { OnModuleDestroy, OnModuleInit } from '@nestjs/common';
|
||||||
import { Injectable } from '@nestjs/common';
|
import { Injectable } from '@nestjs/common';
|
||||||
import { PrismaClient } from '@prisma/client';
|
import { Prisma, PrismaClient } from '@prisma/client';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class PrismaService
|
export class PrismaService
|
||||||
@@ -9,8 +9,8 @@ export class PrismaService
|
|||||||
{
|
{
|
||||||
static INSTANCE: PrismaService | null = null;
|
static INSTANCE: PrismaService | null = null;
|
||||||
|
|
||||||
constructor() {
|
constructor(opts: Prisma.PrismaClientOptions) {
|
||||||
super();
|
super(opts);
|
||||||
PrismaService.INSTANCE = this;
|
PrismaService.INSTANCE = this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -541,6 +541,7 @@ type Query {
|
|||||||
|
|
||||||
"""get all server runtime configurable settings"""
|
"""get all server runtime configurable settings"""
|
||||||
serverRuntimeConfig: [ServerRuntimeConfigType!]!
|
serverRuntimeConfig: [ServerRuntimeConfigType!]!
|
||||||
|
serverServiceConfigs: [ServerServiceConfig!]!
|
||||||
|
|
||||||
"""Get user by email"""
|
"""Get user by email"""
|
||||||
user(email: String!): UserOrLimitedUser
|
user(email: String!): UserOrLimitedUser
|
||||||
@@ -663,6 +664,11 @@ type ServerRuntimeConfigType {
|
|||||||
value: JSON!
|
value: JSON!
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type ServerServiceConfig {
|
||||||
|
config: JSONObject!
|
||||||
|
name: String!
|
||||||
|
}
|
||||||
|
|
||||||
type SubscriptionAlreadyExistsDataType {
|
type SubscriptionAlreadyExistsDataType {
|
||||||
plan: String!
|
plan: String!
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -798,6 +798,7 @@ export interface Query {
|
|||||||
serverConfig: ServerConfigType;
|
serverConfig: ServerConfigType;
|
||||||
/** get all server runtime configurable settings */
|
/** get all server runtime configurable settings */
|
||||||
serverRuntimeConfig: Array<ServerRuntimeConfigType>;
|
serverRuntimeConfig: Array<ServerRuntimeConfigType>;
|
||||||
|
serverServiceConfigs: Array<ServerServiceConfig>;
|
||||||
/** Get user by email */
|
/** Get user by email */
|
||||||
user: Maybe<UserOrLimitedUser>;
|
user: Maybe<UserOrLimitedUser>;
|
||||||
/** Get user by id */
|
/** Get user by id */
|
||||||
@@ -952,6 +953,12 @@ export interface ServerRuntimeConfigType {
|
|||||||
value: Scalars['JSON']['output'];
|
value: Scalars['JSON']['output'];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface ServerServiceConfig {
|
||||||
|
__typename?: 'ServerServiceConfig';
|
||||||
|
config: Scalars['JSONObject']['output'];
|
||||||
|
name: Scalars['String']['output'];
|
||||||
|
}
|
||||||
|
|
||||||
export interface SubscriptionAlreadyExistsDataType {
|
export interface SubscriptionAlreadyExistsDataType {
|
||||||
__typename?: 'SubscriptionAlreadyExistsDataType';
|
__typename?: 'SubscriptionAlreadyExistsDataType';
|
||||||
plan: Scalars['String']['output'];
|
plan: Scalars['String']['output'];
|
||||||
|
|||||||
Reference in New Issue
Block a user