mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-08-12 14:40:22 +08:00
fix(server): config defaults (#11879)
This commit is contained in:
@@ -507,8 +507,7 @@
|
|||||||
"properties": {
|
"properties": {
|
||||||
"name": {
|
"name": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"description": "A recognizable name for the server. Will be shown when connected with AFFiNE Desktop.\n@default \"AFFiNE Cloud\"",
|
"description": "A recognizable name for the server. Will be shown when connected with AFFiNE Desktop.\n@default undefined"
|
||||||
"default": "AFFiNE Cloud"
|
|
||||||
},
|
},
|
||||||
"externalUrl": {
|
"externalUrl": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
@@ -532,7 +531,7 @@
|
|||||||
},
|
},
|
||||||
"path": {
|
"path": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"description": "Subpath where the server get deployed if there is.\n@default \"\"\n@environment `AFFINE_SERVER_SUB_PATH`",
|
"description": "Subpath where the server get deployed if there is one.(e.g. /affine)\n@default \"\"\n@environment `AFFINE_SERVER_SUB_PATH`",
|
||||||
"default": ""
|
"default": ""
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -185,3 +185,28 @@ test('should clone from original config without modifications', t => {
|
|||||||
|
|
||||||
t.not(newConfig.auth.allowSignup, config.auth.allowSignup);
|
t.not(newConfig.auth.allowSignup, config.auth.allowSignup);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('should override with undefined fields', async t => {
|
||||||
|
await using module = await createModule({
|
||||||
|
imports: [ConfigModule],
|
||||||
|
});
|
||||||
|
|
||||||
|
const config = module.get(Config);
|
||||||
|
const configFactory = module.get(ConfigFactory);
|
||||||
|
|
||||||
|
configFactory.override({
|
||||||
|
copilot: {
|
||||||
|
providers: {
|
||||||
|
// @ts-expect-error undefined field
|
||||||
|
unknown: {
|
||||||
|
apiKey: '123',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
// @ts-expect-error undefined field
|
||||||
|
t.deepEqual(config.copilot.providers.unknown, {
|
||||||
|
apiKey: '123',
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ export const OVERRIDE_CONFIG_TOKEN = Symbol('OVERRIDE_CONFIG_TOKEN');
|
|||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class ConfigFactory {
|
export class ConfigFactory {
|
||||||
#original: AppConfig;
|
readonly #original: AppConfig;
|
||||||
readonly #config: AppConfig;
|
readonly #config: AppConfig;
|
||||||
get config() {
|
get config() {
|
||||||
return this.#config;
|
return this.#config;
|
||||||
@@ -18,8 +18,8 @@ export class ConfigFactory {
|
|||||||
@Optional()
|
@Optional()
|
||||||
private readonly overrides: DeepPartial<AppConfig> = {}
|
private readonly overrides: DeepPartial<AppConfig> = {}
|
||||||
) {
|
) {
|
||||||
this.#config = this.loadDefault();
|
this.#original = this.loadDefault();
|
||||||
this.#original = structuredClone(this.#config);
|
this.#config = structuredClone(this.#original);
|
||||||
}
|
}
|
||||||
|
|
||||||
clone() {
|
clone() {
|
||||||
@@ -28,8 +28,8 @@ export class ConfigFactory {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override(updates: DeepPartial<AppConfig>) {
|
override(updates: DeepPartial<AppConfig>) {
|
||||||
|
override(this.#original, updates);
|
||||||
override(this.#config, updates);
|
override(this.#config, updates);
|
||||||
this.#original = structuredClone(this.#config);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
validate(updates: Array<{ module: string; key: string; value: any }>) {
|
validate(updates: Array<{ module: string; key: string; value: any }>) {
|
||||||
|
|||||||
@@ -57,6 +57,10 @@ function typeFromShape(shape: z.ZodType<any>): ConfigType {
|
|||||||
return 'array';
|
return 'array';
|
||||||
case z.ZodObject:
|
case z.ZodObject:
|
||||||
return 'object';
|
return 'object';
|
||||||
|
case z.ZodOptional:
|
||||||
|
case z.ZodNullable:
|
||||||
|
// @ts-expect-error checked
|
||||||
|
return typeFromShape(shape.unwrap());
|
||||||
default:
|
default:
|
||||||
return 'any';
|
return 'any';
|
||||||
}
|
}
|
||||||
@@ -251,6 +255,14 @@ export function override(config: AppConfig, update: DeepPartial<AppConfig>) {
|
|||||||
return right;
|
return right;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// EDGE CASE:
|
||||||
|
// the right value is primitive and we're still not finding the key in descriptors,
|
||||||
|
// which means the overrides has keys not defined
|
||||||
|
// that's where we should return
|
||||||
|
if (typeof right !== 'object') {
|
||||||
|
return left;
|
||||||
|
}
|
||||||
|
|
||||||
// go deeper
|
// go deeper
|
||||||
return mergeWith(left, right, (left, right, key) => {
|
return mergeWith(left, right, (left, right, key) => {
|
||||||
return merge(left, right, path === '' ? key : `${path}.${key}`);
|
return merge(left, right, path === '' ? key : `${path}.${key}`);
|
||||||
|
|||||||
@@ -23,7 +23,8 @@ declare global {
|
|||||||
defineModuleConfig('server', {
|
defineModuleConfig('server', {
|
||||||
name: {
|
name: {
|
||||||
desc: 'A recognizable name for the server. Will be shown when connected with AFFiNE Desktop.',
|
desc: 'A recognizable name for the server. Will be shown when connected with AFFiNE Desktop.',
|
||||||
default: '',
|
default: undefined,
|
||||||
|
shape: z.string().optional(),
|
||||||
},
|
},
|
||||||
externalUrl: {
|
externalUrl: {
|
||||||
desc: `Base url of AFFiNE server, used for generating external urls.
|
desc: `Base url of AFFiNE server, used for generating external urls.
|
||||||
|
|||||||
@@ -174,7 +174,7 @@
|
|||||||
},
|
},
|
||||||
"path": {
|
"path": {
|
||||||
"type": "String",
|
"type": "String",
|
||||||
"desc": "Subpath where the server get deployed if there is.",
|
"desc": "Subpath where the server get deployed if there is one.(e.g. /affine)",
|
||||||
"env": "AFFINE_SERVER_SUB_PATH"
|
"env": "AFFINE_SERVER_SUB_PATH"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in New Issue
Block a user