mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-02-13 04:48:53 +00:00
refactor(server): config system (#11081)
This commit is contained in:
134
packages/backend/server/src/env.ts
Normal file
134
packages/backend/server/src/env.ts
Normal file
@@ -0,0 +1,134 @@
|
||||
import { resolve } from 'node:path';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
|
||||
import pkg from '../package.json' with { type: 'json' };
|
||||
|
||||
declare global {
|
||||
namespace globalThis {
|
||||
// oxlint-disable-next-line no-var
|
||||
var env: Readonly<Env>;
|
||||
// oxlint-disable-next-line no-var
|
||||
var readEnv: <T>(key: string, defaultValue: T, availableValues?: T[]) => T;
|
||||
}
|
||||
}
|
||||
|
||||
export enum Flavor {
|
||||
AllInOne = 'allinone',
|
||||
Graphql = 'graphql',
|
||||
Sync = 'sync',
|
||||
Renderer = 'renderer',
|
||||
Doc = 'doc',
|
||||
Script = 'script',
|
||||
}
|
||||
|
||||
export enum Namespace {
|
||||
Dev = 'dev',
|
||||
Beta = 'beta',
|
||||
Production = 'production',
|
||||
}
|
||||
|
||||
export enum NodeEnv {
|
||||
Development = 'development',
|
||||
Test = 'test',
|
||||
Production = 'production',
|
||||
}
|
||||
|
||||
export enum DeploymentType {
|
||||
Affine = 'affine',
|
||||
Selfhosted = 'selfhosted',
|
||||
}
|
||||
|
||||
export enum Platform {
|
||||
GCP = 'gcp',
|
||||
Unknown = 'unknown',
|
||||
}
|
||||
|
||||
export type AppEnv = {
|
||||
NODE_ENV: NodeEnv;
|
||||
NAMESPACE: Namespace;
|
||||
DEPLOYMENT_TYPE: DeploymentType;
|
||||
version: string;
|
||||
};
|
||||
|
||||
globalThis.readEnv = function readEnv<T>(
|
||||
env: string,
|
||||
defaultValue: T,
|
||||
availableValues?: T[]
|
||||
) {
|
||||
const value = process.env[env];
|
||||
if (value === undefined) {
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
if (availableValues && !availableValues.includes(value as any)) {
|
||||
throw new Error(
|
||||
`Invalid value "${value}" for environment variable ${env}, expected one of ${JSON.stringify(
|
||||
availableValues
|
||||
)}`
|
||||
);
|
||||
}
|
||||
|
||||
return value as T;
|
||||
};
|
||||
|
||||
export class Env implements AppEnv {
|
||||
NODE_ENV = readEnv('NODE_ENV', NodeEnv.Production, Object.values(NodeEnv));
|
||||
NAMESPACE = readEnv(
|
||||
'AFFINE_ENV',
|
||||
Namespace.Production,
|
||||
Object.values(Namespace)
|
||||
);
|
||||
DEPLOYMENT_TYPE = readEnv(
|
||||
'DEPLOYMENT_TYPE',
|
||||
DeploymentType.Affine,
|
||||
Object.values(DeploymentType)
|
||||
);
|
||||
FLAVOR = readEnv('SERVER_FLAVOR', Flavor.AllInOne, Object.values(Flavor));
|
||||
platform = readEnv('DEPLOYMENT_PLATFORM', Platform.Unknown);
|
||||
version = pkg.version;
|
||||
projectRoot = resolve(fileURLToPath(import.meta.url), '../../');
|
||||
|
||||
get selfhosted() {
|
||||
return this.DEPLOYMENT_TYPE === DeploymentType.Selfhosted;
|
||||
}
|
||||
|
||||
isFlavor(flavor: Flavor) {
|
||||
return this.FLAVOR === flavor || this.FLAVOR === Flavor.AllInOne;
|
||||
}
|
||||
|
||||
get flavors() {
|
||||
return {
|
||||
graphql: this.isFlavor(Flavor.Graphql),
|
||||
sync: this.isFlavor(Flavor.Sync),
|
||||
renderer: this.isFlavor(Flavor.Renderer),
|
||||
doc: this.isFlavor(Flavor.Doc),
|
||||
script: this.isFlavor(Flavor.Script),
|
||||
};
|
||||
}
|
||||
|
||||
get namespaces() {
|
||||
return {
|
||||
canary: this.NAMESPACE === Namespace.Dev,
|
||||
beta: this.NAMESPACE === Namespace.Beta,
|
||||
production: this.NAMESPACE === Namespace.Production,
|
||||
};
|
||||
}
|
||||
|
||||
get testing() {
|
||||
return this.NODE_ENV === NodeEnv.Test;
|
||||
}
|
||||
|
||||
get dev() {
|
||||
return this.NODE_ENV === NodeEnv.Development;
|
||||
}
|
||||
|
||||
get prod() {
|
||||
return this.NODE_ENV === NodeEnv.Production;
|
||||
}
|
||||
|
||||
get gcp() {
|
||||
return this.platform === Platform.GCP;
|
||||
}
|
||||
}
|
||||
|
||||
globalThis.env = new Env();
|
||||
Reference in New Issue
Block a user