refactor(server): config system (#11081)

This commit is contained in:
forehalo
2025-03-27 12:32:28 +00:00
parent 7091111f85
commit 0ea38680fa
274 changed files with 7583 additions and 5841 deletions
@@ -0,0 +1,101 @@
/* eslint-disable */
import '../src/prelude';
import '../src/app.module';
import fs from 'node:fs';
import { ProjectRoot } from '@affine-tools/utils/path';
import { Package } from '@affine-tools/utils/workspace';
import { getDescriptors, ConfigDescriptor } from '../src/base/config/register';
import { pick } from 'lodash-es';
interface PropertySchema {
description: string;
type?: 'array' | 'boolean' | 'integer' | 'number' | 'object' | 'string';
default?: any;
}
function convertDescriptorToSchemaProperty(descriptor: ConfigDescriptor<any>) {
const property: PropertySchema = {
...descriptor.schema,
description:
descriptor.schema.description +
`\n@default ${JSON.stringify(descriptor.default)}` +
(descriptor.env ? `\n@environment \`${descriptor.env[0]}\`` : '') +
(descriptor.link ? `\n@link ${descriptor.link}` : ''),
default: descriptor.default,
};
return property;
}
function generateJsonSchema(outputPath: string) {
const schema = {
$schema: 'http://json-schema.org/draft-07/schema#',
title: 'AFFiNE Application Configuration',
type: 'object',
properties: {},
};
getDescriptors().forEach(({ module, descriptors }) => {
schema.properties[module] = {
type: 'object',
description: `Configuration for ${module} module`,
properties: {},
};
descriptors.forEach(({ key, descriptor }) => {
schema.properties[module].properties[key] =
convertDescriptorToSchemaProperty(descriptor);
});
});
fs.writeFileSync(outputPath, JSON.stringify(schema, null, 2));
console.log(`Config schema generated at: ${outputPath}`);
}
function generateAdminConfigJson(outputPath: string) {
const config = {};
getDescriptors().forEach(({ module, descriptors }) => {
const modulizedConfig = {};
config[module] = modulizedConfig;
descriptors.forEach(({ key, descriptor }) => {
let type: string;
switch (descriptor.schema?.type) {
case 'number':
type = 'Number';
break;
case 'boolean':
type = 'Boolean';
break;
case 'array':
type = 'Array';
break;
case 'object':
type = 'Object';
break;
default:
type = 'String';
}
modulizedConfig[key] = {
type,
desc: descriptor.desc,
link: descriptor.link,
env: descriptor.env?.[0],
};
});
});
fs.writeFileSync(outputPath, JSON.stringify(config, null, 2));
}
function main() {
generateJsonSchema(
ProjectRoot.join('.docker', 'selfhost', 'schema.json').toString()
);
generateAdminConfigJson(
new Package('@affine/admin').join('src/config.json').toString()
);
}
main();
@@ -1,17 +1,10 @@
import { execSync } from 'node:child_process';
import { generateKeyPairSync } from 'node:crypto';
import fs from 'node:fs';
import { homedir } from 'node:os';
import path from 'node:path';
const SELF_HOST_CONFIG_DIR = '/root/.affine/config';
function generateConfigFile() {
const content = fs.readFileSync('./dist/config/affine.js', 'utf-8');
return content.replace(
/(^\/\/#.*$)|(^\/\/\s+TODO.*$)|("use\sstrict";?)|(^.*lint-disable.*$)/gm,
''
);
}
const SELF_HOST_CONFIG_DIR = `${homedir()}/.affine/config`;
function generatePrivateKey() {
const key = generateKeyPairSync('ec', {
@@ -31,15 +24,12 @@ function generatePrivateKey() {
/**
* @type {Array<{ to: string; generator: () => string }>}
*/
const configFiles = [
{ to: 'affine.js', generator: generateConfigFile },
{ to: 'private.key', generator: generatePrivateKey },
];
const files = [{ to: 'private.key', generator: generatePrivateKey }];
function prepare() {
fs.mkdirSync(SELF_HOST_CONFIG_DIR, { recursive: true });
for (const { to, generator } of configFiles) {
for (const { to, generator } of files) {
const targetFilePath = path.join(SELF_HOST_CONFIG_DIR, to);
if (!fs.existsSync(targetFilePath)) {
console.log(`creating config file [${targetFilePath}].`);