diff --git a/packages/core/app/package.json b/packages/core/app/package.json index 4331c8da3..83fce1290 100644 --- a/packages/core/app/package.json +++ b/packages/core/app/package.json @@ -6,7 +6,9 @@ "main": "./lib/index.js", "types": "./lib/index.d.ts", "dependencies": { - "@nocobase/preset-nocobase": "0.14.0-alpha.3" + "@nocobase/preset-nocobase": "0.14.0-alpha.3", + "@nocobase/server": "0.14.0-alpha.3", + "@nocobase/database": "0.14.0-alpha.3" }, "devDependencies": { "@nocobase/client": "0.14.0-alpha.3" diff --git a/packages/core/app/src/config/database.ts b/packages/core/app/src/config/database.ts index d573e219c..4f80bf22a 100644 --- a/packages/core/app/src/config/database.ts +++ b/packages/core/app/src/config/database.ts @@ -1,52 +1,5 @@ -import { IDatabaseOptions } from '@nocobase/database'; +import { parseDatabaseOptionsFromEnv } from '@nocobase/database'; -function getEnvValue(key, defaultValue?) { - return process.env[key] || defaultValue; -} - -function extractSSLOptionsFromEnv() { - const sslOptions = {}; - - const ca = getEnvValue('DB_DIALECT_OPTIONS_SSL_CA'); - const key = getEnvValue('DB_DIALECT_OPTIONS_SSL_KEY'); - const cert = getEnvValue('DB_DIALECT_OPTIONS_SSL_CERT'); - const rejectUnauthorized = getEnvValue('DB_DIALECT_OPTIONS_SSL_REJECT_UNAUTHORIZED'); - - if (ca) sslOptions['ca'] = ca; - if (key) sslOptions['key'] = key; - if (cert) sslOptions['cert'] = cert; - if (rejectUnauthorized) sslOptions['rejectUnauthorized'] = rejectUnauthorized === 'true'; - - return sslOptions; -} - -const databaseOptions = { - logging: process.env.DB_LOGGING == 'on' ? customLogger : false, - dialect: process.env.DB_DIALECT as any, - storage: process.env.DB_STORAGE, - username: process.env.DB_USER, - password: process.env.DB_PASSWORD, - database: process.env.DB_DATABASE, - host: process.env.DB_HOST, - port: process.env.DB_PORT as any, - timezone: process.env.DB_TIMEZONE, - tablePrefix: process.env.DB_TABLE_PREFIX, - schema: process.env.DB_SCHEMA, - underscored: process.env.DB_UNDERSCORED === 'true', -} as IDatabaseOptions; - -const sslOptions = extractSSLOptionsFromEnv(); - -if (Object.keys(sslOptions).length) { - databaseOptions.dialectOptions = databaseOptions.dialectOptions || {}; - databaseOptions.dialectOptions['ssl'] = sslOptions; -} - -export default databaseOptions; - -function customLogger(queryString, queryObject) { - console.log(queryString); // outputs a string - if (queryObject?.bind) { - console.log(queryObject.bind); // outputs an array - } +export async function parseDatabaseOptions() { + return await parseDatabaseOptionsFromEnv(); } diff --git a/packages/core/app/src/config/index.ts b/packages/core/app/src/config/index.ts index 55b45c2d9..4167a2c4e 100644 --- a/packages/core/app/src/config/index.ts +++ b/packages/core/app/src/config/index.ts @@ -1,13 +1,15 @@ import cache from './cache'; -import database from './database'; +import { parseDatabaseOptions } from './database'; import logger from './logger'; import plugins from './plugins'; import resourcer from './resourcer'; -export default { - database, - resourcer, - plugins, - cache, - logger, -}; +export async function getConfig() { + return { + database: await parseDatabaseOptions(), + resourcer, + plugins, + cache, + logger, + }; +} diff --git a/packages/core/app/src/index.ts b/packages/core/app/src/index.ts index edf45014b..d3776c07b 100644 --- a/packages/core/app/src/index.ts +++ b/packages/core/app/src/index.ts @@ -1,6 +1,12 @@ import { Gateway } from '@nocobase/server'; -import config from './config'; +import { getConfig } from './config'; -Gateway.getInstance().run({ - mainAppOptions: config, -}); +getConfig() + .then((config) => { + return Gateway.getInstance().run({ + mainAppOptions: config, + }); + }) + .catch((e) => { + console.error(e); + }); diff --git a/packages/core/database/src/helpers.ts b/packages/core/database/src/helpers.ts new file mode 100644 index 000000000..3307a74f9 --- /dev/null +++ b/packages/core/database/src/helpers.ts @@ -0,0 +1,92 @@ +import { IDatabaseOptions } from './database'; +import fs from 'fs'; + +function getEnvValue(key, defaultValue?) { + return process.env[key] || defaultValue; +} + +function isFilePath(value) { + return fs.promises + .stat(value) + .then((stats) => stats.isFile()) + .catch((err) => { + if (err.code === 'ENOENT') { + return false; + } + + throw err; + }); +} + +function getValueOrFileContent(envVarName) { + const value = getEnvValue(envVarName); + + if (!value) { + return Promise.resolve(null); + } + + return isFilePath(value) + .then((isFile) => { + if (isFile) { + return fs.promises.readFile(value, 'utf8'); + } + return value; + }) + .catch((error) => { + console.error(`Failed to read file content for environment variable ${envVarName}.`); + throw error; + }); +} + +function extractSSLOptionsFromEnv() { + return Promise.all([ + getValueOrFileContent('DB_DIALECT_OPTIONS_SSL_MODE'), + getValueOrFileContent('DB_DIALECT_OPTIONS_SSL_CA'), + getValueOrFileContent('DB_DIALECT_OPTIONS_SSL_KEY'), + getValueOrFileContent('DB_DIALECT_OPTIONS_SSL_CERT'), + getValueOrFileContent('DB_DIALECT_OPTIONS_SSL_REJECT_UNAUTHORIZED'), + ]).then(([mode, ca, key, cert, rejectUnauthorized]) => { + const sslOptions = {}; + + if (mode) sslOptions['mode'] = mode; + if (ca) sslOptions['ca'] = ca; + if (key) sslOptions['key'] = key; + if (cert) sslOptions['cert'] = cert; + if (rejectUnauthorized) sslOptions['rejectUnauthorized'] = rejectUnauthorized === 'true'; + + return sslOptions; + }); +} + +export async function parseDatabaseOptionsFromEnv(): Promise { + const databaseOptions: IDatabaseOptions = { + logging: process.env.DB_LOGGING == 'on' ? customLogger : false, + dialect: process.env.DB_DIALECT as any, + storage: process.env.DB_STORAGE, + username: process.env.DB_USER, + password: process.env.DB_PASSWORD, + database: process.env.DB_DATABASE, + host: process.env.DB_HOST, + port: process.env.DB_PORT as any, + timezone: process.env.DB_TIMEZONE, + tablePrefix: process.env.DB_TABLE_PREFIX, + schema: process.env.DB_SCHEMA, + underscored: process.env.DB_UNDERSCORED === 'true', + }; + + const sslOptions = await extractSSLOptionsFromEnv(); + + if (Object.keys(sslOptions).length) { + databaseOptions.dialectOptions = databaseOptions.dialectOptions || {}; + databaseOptions.dialectOptions['ssl'] = sslOptions; + } + + return databaseOptions; +} + +function customLogger(queryString, queryObject) { + console.log(queryString); + if (queryObject?.bind) { + console.log(queryObject.bind); + } +} diff --git a/packages/core/database/src/index.ts b/packages/core/database/src/index.ts index b972f7e22..ea1e39604 100644 --- a/packages/core/database/src/index.ts +++ b/packages/core/database/src/index.ts @@ -41,3 +41,4 @@ export { snakeCase } from './utils'; export * from './value-parsers'; export * from './view-collection'; export * from './view/view-inference'; +export * from './helpers';