@dbos-inc/dbos-sdk 3.0.43-preview → 3.0.45-preview.g34e483ff45
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dbos-config.schema.json +50 -15
- package/dist/dbos-config.schema.json +50 -15
- package/dist/src/client.d.ts.map +1 -1
- package/dist/src/client.js +5 -11
- package/dist/src/client.js.map +1 -1
- package/dist/src/dbos-executor.d.ts +10 -10
- package/dist/src/dbos-executor.d.ts.map +1 -1
- package/dist/src/dbos-executor.js +8 -9
- package/dist/src/dbos-executor.js.map +1 -1
- package/dist/src/dbos-runtime/cli.d.ts +1 -15
- package/dist/src/dbos-runtime/cli.d.ts.map +1 -1
- package/dist/src/dbos-runtime/cli.js +74 -106
- package/dist/src/dbos-runtime/cli.js.map +1 -1
- package/dist/src/dbos-runtime/config.d.ts +29 -74
- package/dist/src/dbos-runtime/config.d.ts.map +1 -1
- package/dist/src/dbos-runtime/config.js +163 -462
- package/dist/src/dbos-runtime/config.js.map +1 -1
- package/dist/src/dbos-runtime/debug.d.ts.map +1 -1
- package/dist/src/dbos-runtime/debug.js +2 -1
- package/dist/src/dbos-runtime/debug.js.map +1 -1
- package/dist/src/dbos-runtime/migrate.d.ts +1 -3
- package/dist/src/dbos-runtime/migrate.d.ts.map +1 -1
- package/dist/src/dbos-runtime/migrate.js +16 -36
- package/dist/src/dbos-runtime/migrate.js.map +1 -1
- package/dist/src/dbos-runtime/reset.d.ts +2 -2
- package/dist/src/dbos-runtime/reset.d.ts.map +1 -1
- package/dist/src/dbos-runtime/reset.js +5 -2
- package/dist/src/dbos-runtime/reset.js.map +1 -1
- package/dist/src/dbos-runtime/runtime.js +1 -1
- package/dist/src/dbos-runtime/runtime.js.map +1 -1
- package/dist/src/dbos.d.ts +1 -7
- package/dist/src/dbos.d.ts.map +1 -1
- package/dist/src/dbos.js +17 -39
- package/dist/src/dbos.js.map +1 -1
- package/dist/src/index.d.ts +1 -1
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +3 -2
- package/dist/src/index.js.map +1 -1
- package/dist/src/system_database.d.ts +5 -6
- package/dist/src/system_database.d.ts.map +1 -1
- package/dist/src/system_database.js +24 -25
- package/dist/src/system_database.js.map +1 -1
- package/dist/src/telemetry/exporters.d.ts +2 -2
- package/dist/src/telemetry/exporters.d.ts.map +1 -1
- package/dist/src/telemetry/exporters.js +12 -15
- package/dist/src/telemetry/exporters.js.map +1 -1
- package/dist/src/user_database.d.ts +1 -1
- package/dist/src/user_database.d.ts.map +1 -1
- package/dist/src/user_database.js +11 -14
- package/dist/src/user_database.js.map +1 -1
- package/dist/src/utils.d.ts +2 -1
- package/dist/src/utils.d.ts.map +1 -1
- package/dist/src/utils.js +20 -4
- package/dist/src/utils.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +3 -3
- package/dist/src/dbos-runtime/configure.d.ts +0 -2
- package/dist/src/dbos-runtime/configure.d.ts.map +0 -1
- package/dist/src/dbos-runtime/configure.js +0 -42
- package/dist/src/dbos-runtime/configure.js.map +0 -1
@@ -3,8 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
4
4
|
};
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
6
|
-
exports.
|
7
|
-
const error_1 = require("../error");
|
6
|
+
exports.overwriteConfigForDBOSCloud = exports.translateRuntimeConfig = exports.getRuntimeConfig = exports.translateDbosConfig = exports.getDbosConfig = exports.getDatabaseUrl = exports.getSystemDatabaseUrl = exports.writeConfigFile = exports.readConfigFile = exports.substituteEnvVars = exports.dbosConfigFilePath = void 0;
|
8
7
|
const utils_1 = require("../utils");
|
9
8
|
const yaml_1 = __importDefault(require("yaml"));
|
10
9
|
const runtime_1 = require("./runtime");
|
@@ -12,9 +11,9 @@ const user_database_1 = require("../user_database");
|
|
12
11
|
const fs_1 = require("fs");
|
13
12
|
const ajv_1 = __importDefault(require("ajv"));
|
14
13
|
const path_1 = __importDefault(require("path"));
|
15
|
-
const validator_1 = __importDefault(require("validator"));
|
16
|
-
const logs_1 = require("../telemetry/logs");
|
17
14
|
const dbos_config_schema_json_1 = __importDefault(require("../../dbos-config.schema.json"));
|
15
|
+
const assert_1 = __importDefault(require("assert"));
|
16
|
+
const validator_1 = __importDefault(require("validator"));
|
18
17
|
exports.dbosConfigFilePath = 'dbos-config.yaml';
|
19
18
|
const ajv = new ajv_1.default({ allErrors: true, verbose: true, allowUnionTypes: true });
|
20
19
|
/*
|
@@ -58,61 +57,14 @@ function readConfigFile(dirPath) {
|
|
58
57
|
}
|
59
58
|
}
|
60
59
|
exports.readConfigFile = readConfigFile;
|
61
|
-
/**
|
62
|
-
* Loads config file as a ConfigFile.
|
63
|
-
* @param {string} configFilePath - The path to the config file to be loaded.
|
64
|
-
* @returns
|
65
|
-
*/
|
66
|
-
function loadConfigFile(configFilePath) {
|
67
|
-
try {
|
68
|
-
const configFileContent = (0, utils_1.readFileSync)(configFilePath);
|
69
|
-
const interpolatedConfig = substituteEnvVars(configFileContent);
|
70
|
-
const configFile = yaml_1.default.parse(interpolatedConfig);
|
71
|
-
if (!configFile) {
|
72
|
-
throw new Error(`${configFilePath} is empty `);
|
73
|
-
}
|
74
|
-
const schemaValidator = ajv.compile(dbos_config_schema_json_1.default);
|
75
|
-
if (!schemaValidator(configFile)) {
|
76
|
-
const errorMessages = prettyPrintAjvErrors(schemaValidator);
|
77
|
-
throw new Error(`${configFilePath} failed schema validation. ${errorMessages}`);
|
78
|
-
}
|
79
|
-
if (!configFile.database) {
|
80
|
-
configFile.database = {}; // Create an empty database object if it doesn't exist
|
81
|
-
}
|
82
|
-
// Handle strings in the config file and convert them to arrays
|
83
|
-
if (configFile.telemetry?.OTLPExporter?.logsEndpoint &&
|
84
|
-
typeof configFile.telemetry.OTLPExporter.logsEndpoint === 'string') {
|
85
|
-
configFile.telemetry.OTLPExporter.logsEndpoint = [configFile.telemetry.OTLPExporter.logsEndpoint];
|
86
|
-
}
|
87
|
-
if (configFile.telemetry?.OTLPExporter?.tracesEndpoint &&
|
88
|
-
typeof configFile.telemetry.OTLPExporter.tracesEndpoint === 'string') {
|
89
|
-
configFile.telemetry.OTLPExporter.tracesEndpoint = [configFile.telemetry.OTLPExporter.tracesEndpoint];
|
90
|
-
}
|
91
|
-
return configFile;
|
92
|
-
}
|
93
|
-
catch (e) {
|
94
|
-
if (e instanceof Error) {
|
95
|
-
throw new error_1.DBOSInitializationError(`Failed to load config from ${configFilePath}: ${e.message}`);
|
96
|
-
}
|
97
|
-
else {
|
98
|
-
throw e;
|
99
|
-
}
|
100
|
-
}
|
101
|
-
}
|
102
|
-
exports.loadConfigFile = loadConfigFile;
|
103
|
-
/**
|
104
|
-
* Writes a YAML.Document object to configFilePath.
|
105
|
-
* @param {YAML.Document} configFile - The config file to be written.
|
106
|
-
* @param {string} configFilePath - The path to the config file to be written to.
|
107
|
-
*/
|
108
60
|
function writeConfigFile(configFile, configFilePath) {
|
109
61
|
try {
|
110
|
-
const configFileContent =
|
62
|
+
const configFileContent = yaml_1.default.stringify(configFile);
|
111
63
|
(0, fs_1.writeFileSync)(configFilePath, configFileContent);
|
112
64
|
}
|
113
65
|
catch (e) {
|
114
66
|
if (e instanceof Error) {
|
115
|
-
throw new
|
67
|
+
throw new Error(`Failed to write config to ${configFilePath}: ${e.message}`);
|
116
68
|
}
|
117
69
|
else {
|
118
70
|
throw e;
|
@@ -120,457 +72,206 @@ function writeConfigFile(configFile, configFilePath) {
|
|
120
72
|
}
|
121
73
|
}
|
122
74
|
exports.writeConfigFile = writeConfigFile;
|
123
|
-
function
|
124
|
-
|
125
|
-
|
126
|
-
return appName;
|
127
|
-
}
|
128
|
-
const packageJson = JSON.parse((0, utils_1.readFileSync)(path_1.default.join(process.cwd(), 'package.json')).toString());
|
129
|
-
appName = packageJson.name;
|
130
|
-
if (appName === undefined) {
|
131
|
-
throw new error_1.DBOSInitializationError('Error: cannot find a valid package.json file. Please run this command in an application root directory.');
|
132
|
-
}
|
133
|
-
return appName;
|
134
|
-
}
|
135
|
-
/**
|
136
|
-
* Build a PoolConfig object.
|
137
|
-
*
|
138
|
-
* If configFile.database_url is provided, set it directly in poolConfig.connectionString and backfill the other poolConfig options.
|
139
|
-
* Backfilling allows the rest of the code to access database parameters easily.
|
140
|
-
* We configure the ORMs with the connection string
|
141
|
-
* We still need to extract pool size and connectionTimeoutMillis from the config file and give them manually to the ORMs.
|
142
|
-
*
|
143
|
-
* If configFile.database_url is not provided, we build the connection string from the configFile.database object.
|
144
|
-
*
|
145
|
-
* In debug mode, apply overrides from DBOS_DBHOST, DBOS_DBPORT, DBOS_DBUSER, and DBOS_DBPASSWORD.
|
146
|
-
*
|
147
|
-
* Default configuration:
|
148
|
-
* - Hostname: localhost
|
149
|
-
* - Port: 5432
|
150
|
-
* - Username: postgres
|
151
|
-
* - Password: $PGPASSWORD
|
152
|
-
* - Database name: transformed application name. The name is either the one provided in the config file or the one found in package.json.
|
153
|
-
*
|
154
|
-
* @param configFile - The configuration to be used.
|
155
|
-
* @param cliOptions - Optional CLI options.
|
156
|
-
* @returns PoolConfig - The constructed PoolConfig object.
|
157
|
-
*/
|
158
|
-
function constructPoolConfig(configFile, cliOptions) {
|
159
|
-
// FIXME: this is not a good place to set the app name
|
160
|
-
const appName = retrieveApplicationName(configFile);
|
161
|
-
const isDebugMode = process.env.DBOS_DEBUG_WORKFLOW_ID !== undefined;
|
162
|
-
if (!cliOptions?.silent) {
|
163
|
-
const logger = new logs_1.GlobalLogger();
|
164
|
-
if (isDebugMode) {
|
165
|
-
logger.info('Loading database connection parameters from debug environment variables');
|
166
|
-
}
|
167
|
-
else if (configFile.database_url) {
|
168
|
-
logger.info('Loading database connection parameters from database_url');
|
169
|
-
}
|
170
|
-
else if (configFile.database?.hostname) {
|
171
|
-
logger.info('Loading database connection parameters from dbos-config.yaml');
|
172
|
-
}
|
173
|
-
else {
|
174
|
-
logger.info('Using default database connection parameters');
|
175
|
-
}
|
75
|
+
function getSystemDatabaseUrl(configFileOrString) {
|
76
|
+
if (typeof configFileOrString === 'string') {
|
77
|
+
return convertUserDbUrl(configFileOrString);
|
176
78
|
}
|
177
|
-
|
178
|
-
|
179
|
-
let connectionTimeoutMillis = 10000;
|
180
|
-
let ssl = false;
|
181
|
-
// If a database_url is found, parse it to backfill the poolConfig
|
182
|
-
if (configFile.database_url) {
|
183
|
-
const url = new URL(configFile.database_url);
|
184
|
-
// If in debug mode, apply the debug overrides
|
185
|
-
if (isDebugMode) {
|
186
|
-
if (process.env.DBOS_DBHOST) {
|
187
|
-
url.hostname = process.env.DBOS_DBHOST;
|
188
|
-
}
|
189
|
-
if (process.env.DBOS_DBPORT) {
|
190
|
-
url.port = process.env.DBOS_DBPORT;
|
191
|
-
}
|
192
|
-
if (process.env.DBOS_DBUSER) {
|
193
|
-
url.username = process.env.DBOS_DBUSER;
|
194
|
-
}
|
195
|
-
if (process.env.DBOS_DBPASSWORD) {
|
196
|
-
url.password = process.env.DBOS_DBPASSWORD;
|
197
|
-
}
|
198
|
-
configFile.database_url = url.toString();
|
199
|
-
}
|
200
|
-
connectionString = configFile.database_url;
|
201
|
-
databaseName = url.pathname.substring(1);
|
202
|
-
const queryParams = url.searchParams;
|
203
|
-
if (queryParams.has('connect_timeout')) {
|
204
|
-
connectionTimeoutMillis = parseInt(queryParams.get('connect_timeout'), 10) * 1000;
|
205
|
-
}
|
206
|
-
const sslMode = queryParams.get('sslmode');
|
207
|
-
const sslRootCert = queryParams.get('sslrootcert');
|
208
|
-
ssl = getSSLFromParams(sslMode, sslRootCert);
|
209
|
-
// Validate required fields
|
210
|
-
const missingFields = [];
|
211
|
-
if (!url.username)
|
212
|
-
missingFields.push('username');
|
213
|
-
if (!url.hostname)
|
214
|
-
missingFields.push('hostname');
|
215
|
-
if (!databaseName)
|
216
|
-
missingFields.push('database name');
|
217
|
-
if (missingFields.length > 0) {
|
218
|
-
throw new Error(`Invalid database URL: missing required field(s): ${missingFields.join(', ')}`);
|
219
|
-
}
|
220
|
-
// Backfill the poolConfig
|
221
|
-
configFile.database = {
|
222
|
-
...configFile.database,
|
223
|
-
hostname: url.hostname,
|
224
|
-
port: url.port ? parseInt(url.port, 10) : 5432,
|
225
|
-
username: url.username,
|
226
|
-
password: url.password,
|
227
|
-
app_db_name: databaseName,
|
228
|
-
};
|
229
|
-
if (!cliOptions?.silent) {
|
230
|
-
const logger = new logs_1.GlobalLogger();
|
231
|
-
let logConnectionString = `postgresql://${configFile.database.username}:***@${configFile.database.hostname}:${configFile.database.port}/${databaseName}`;
|
232
|
-
const logQueryParamsArray = Object.entries(url.searchParams.entries()).map(([key, value]) => `${key}=${value}`);
|
233
|
-
if (logQueryParamsArray.length > 0) {
|
234
|
-
logConnectionString += `?${logQueryParamsArray.join('&')}`;
|
235
|
-
}
|
236
|
-
logger.info(`Using database connection string: ${logConnectionString}`);
|
237
|
-
}
|
79
|
+
if (configFileOrString.system_database_url) {
|
80
|
+
return configFileOrString.system_database_url;
|
238
81
|
}
|
239
|
-
|
240
|
-
|
241
|
-
configFile.database ??= {};
|
242
|
-
configFile.database.hostname = process.env.DBOS_DBHOST || configFile.database.hostname || 'localhost';
|
243
|
-
const dbos_dbport = process.env.DBOS_DBPORT ? parseInt(process.env.DBOS_DBPORT) : undefined;
|
244
|
-
configFile.database.port = dbos_dbport || configFile.database.port || 5432;
|
245
|
-
configFile.database.username = process.env.DBOS_DBUSER || configFile.database.username || 'postgres';
|
246
|
-
configFile.database.password =
|
247
|
-
process.env.DBOS_DBPASSWORD || configFile.database.password || process.env.PGPASSWORD || 'dbos';
|
248
|
-
connectionTimeoutMillis = configFile.database.connectionTimeoutMillis || 10000;
|
249
|
-
databaseName = configFile.database.app_db_name;
|
250
|
-
// Construct the database name from the application name, if needed
|
251
|
-
if (databaseName === undefined || databaseName === '') {
|
252
|
-
databaseName = appName.toLowerCase().replaceAll('-', '_').replaceAll(' ', '_');
|
253
|
-
if (databaseName.match(/^\d/)) {
|
254
|
-
databaseName = '_' + databaseName; // Append an underscore if the name starts with a digit
|
255
|
-
}
|
256
|
-
}
|
257
|
-
connectionString = `postgresql://${configFile.database.username}:${configFile.database.password}@${configFile.database.hostname}:${configFile.database.port}/${databaseName}`;
|
258
|
-
// Build connection string query parameters
|
259
|
-
const queryParams = [];
|
260
|
-
queryParams.push(`connect_timeout=${connectionTimeoutMillis / 1000}`);
|
261
|
-
// SSL configuration
|
262
|
-
ssl = parseSSLConfig(configFile.database);
|
263
|
-
if (ssl === false) {
|
264
|
-
queryParams.push(`sslmode=disable`);
|
265
|
-
}
|
266
|
-
else if (ssl && 'ca' in ssl) {
|
267
|
-
queryParams.push(`sslmode=verify-full`);
|
268
|
-
queryParams.push(`sslrootcert=${configFile.database.ssl_ca}`);
|
269
|
-
}
|
270
|
-
else {
|
271
|
-
queryParams.push(`sslmode=no-verify`);
|
272
|
-
}
|
273
|
-
if (queryParams.length > 0) {
|
274
|
-
connectionString += `?${queryParams.join('&')}`;
|
275
|
-
}
|
276
|
-
if (!cliOptions?.silent) {
|
277
|
-
const logger = new logs_1.GlobalLogger();
|
278
|
-
let logConnectionString = `postgresql://${configFile.database.username}:***@${configFile.database.hostname}:${configFile.database.port}/${databaseName}`;
|
279
|
-
if (queryParams.length > 0) {
|
280
|
-
logConnectionString += `?${queryParams.join('&')}`;
|
281
|
-
}
|
282
|
-
logger.info(`Using database connection string: ${logConnectionString}`);
|
283
|
-
}
|
82
|
+
if (process.env.DBOS_SYSTEM_DATABASE_URL) {
|
83
|
+
return process.env.DBOS_SYSTEM_DATABASE_URL;
|
284
84
|
}
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
user: configFile.database.username,
|
293
|
-
password: configFile.database.password,
|
294
|
-
database: databaseName,
|
295
|
-
max: cliOptions?.userDbPoolSize || 20,
|
296
|
-
};
|
297
|
-
if (!poolConfig.database) {
|
298
|
-
throw new error_1.DBOSInitializationError(`DBOS configuration (${exports.dbosConfigFilePath}) does not contain application database name`);
|
85
|
+
const databaseUrl = getDatabaseUrl(configFileOrString);
|
86
|
+
return convertUserDbUrl(databaseUrl);
|
87
|
+
function convertUserDbUrl(databaseUrl) {
|
88
|
+
const url = new URL(databaseUrl);
|
89
|
+
const database = url.pathname.slice(1);
|
90
|
+
url.pathname = `/${database}_dbos_sys`;
|
91
|
+
return url.toString();
|
299
92
|
}
|
300
|
-
return poolConfig;
|
301
93
|
}
|
302
|
-
exports.
|
303
|
-
|
304
|
-
|
305
|
-
*
|
306
|
-
* @param sslmode
|
307
|
-
* @param sslrootcert
|
308
|
-
* @returns
|
309
|
-
*/
|
310
|
-
function getSSLFromParams(sslmode, sslrootcert) {
|
311
|
-
if (!sslmode || sslmode === 'disable') {
|
94
|
+
exports.getSystemDatabaseUrl = getSystemDatabaseUrl;
|
95
|
+
function isValidDBname(dbName) {
|
96
|
+
if (dbName.length < 1 || dbName.length > 63) {
|
312
97
|
return false;
|
313
98
|
}
|
314
|
-
|
315
|
-
|
316
|
-
ssl.rejectUnauthorized = false;
|
317
|
-
}
|
318
|
-
else if (sslmode === 'verify-ca' || sslmode === 'verify-full') {
|
319
|
-
ssl.rejectUnauthorized = sslmode === 'verify-full';
|
320
|
-
if (sslrootcert) {
|
321
|
-
try {
|
322
|
-
ssl.ca = (0, utils_1.readFileSync)(path_1.default.resolve(sslrootcert)).toString();
|
323
|
-
}
|
324
|
-
catch (err) {
|
325
|
-
throw new Error(`Failed to read sslrootcert from "${sslrootcert}": ${err.message}`);
|
326
|
-
}
|
327
|
-
}
|
328
|
-
else {
|
329
|
-
throw new Error(`sslmode=${sslmode} requires sslrootcert`);
|
330
|
-
}
|
331
|
-
}
|
332
|
-
return ssl;
|
333
|
-
}
|
334
|
-
function parseSSLConfig(dbConfig) {
|
335
|
-
// Details on Postgres SSL/TLS modes: https://www.postgresql.org/docs/current/libpq-ssl.html#LIBPQ-SSL-PROTECTION
|
336
|
-
if (dbConfig.ssl === false) {
|
337
|
-
// If SSL is set to false, do not use TLS
|
99
|
+
if (dbName.match(/^\d/)) {
|
100
|
+
// Cannot start with a digit
|
338
101
|
return false;
|
339
102
|
}
|
340
|
-
|
341
|
-
|
342
|
-
|
103
|
+
return validator_1.default.matches(dbName, '^[a-z0-9_]+$');
|
104
|
+
}
|
105
|
+
function getDatabaseUrl(configFile) {
|
106
|
+
const databaseUrl = configFile.database_url || process.env.DBOS_DATABASE_URL || defaultDatabaseUrl(configFile.name);
|
107
|
+
const url = new URL(databaseUrl);
|
108
|
+
const dbName = url.pathname.slice(1);
|
109
|
+
const missingFields = [];
|
110
|
+
if (!url.username)
|
111
|
+
missingFields.push('username');
|
112
|
+
if (!url.hostname)
|
113
|
+
missingFields.push('hostname');
|
114
|
+
if (!dbName)
|
115
|
+
missingFields.push('database name');
|
116
|
+
if (missingFields.length > 0) {
|
117
|
+
throw new Error(`Invalid database URL: missing required field(s): ${missingFields.join(', ')}`);
|
118
|
+
}
|
119
|
+
(0, assert_1.default)(isValidDBname(dbName), `Database name "${dbName}" in database_url is invalid.`);
|
120
|
+
if (process.env.DBOS_DEBUG_WORKFLOW_ID !== undefined) {
|
121
|
+
// If in debug mode, apply the debug overrides
|
122
|
+
url.hostname = process.env.DBOS_DBHOST || url.hostname;
|
123
|
+
url.port = process.env.DBOS_DBPORT || url.port;
|
124
|
+
url.username = process.env.DBOS_DBUSER || url.username;
|
125
|
+
url.password = process.env.DBOS_DBPASSWORD || url.password;
|
126
|
+
return url.toString();
|
343
127
|
}
|
344
|
-
|
345
|
-
|
346
|
-
|
128
|
+
else {
|
129
|
+
return databaseUrl;
|
130
|
+
}
|
131
|
+
function defaultDatabaseUrl(appName) {
|
132
|
+
(0, assert_1.default)(appName, 'Application name must be defined to construct a valid database URL.');
|
133
|
+
const host = process.env.PGHOST || 'localhost';
|
134
|
+
const port = process.env.PGPORT || '5432';
|
135
|
+
const username = process.env.PGUSER || 'postgres';
|
136
|
+
const password = process.env.PGPASSWORD || 'dbos';
|
137
|
+
const database = toDbName(appName);
|
138
|
+
const timeout = process.env.PGCONNECT_TIMEOUT || '10';
|
139
|
+
const sslmode = process.env.PGSSLMODE || (host === 'localhost' ? 'disable' : 'allow');
|
140
|
+
return `postgresql://${username}:${password}@${host}:${port}/${database}?connect_timeout=${timeout}&sslmode=${sslmode}`;
|
141
|
+
}
|
142
|
+
function toDbName(appName) {
|
143
|
+
const dbName = appName.toLowerCase().replaceAll('-', '_').replaceAll(' ', '_');
|
144
|
+
return dbName.match(/^\d/) ? '_' + dbName : dbName;
|
347
145
|
}
|
348
|
-
// Otherwise, connect to Postgres using TLS but do not verify the server certificate. (equivalent to require)
|
349
|
-
return { rejectUnauthorized: false };
|
350
146
|
}
|
351
|
-
exports.
|
352
|
-
function
|
353
|
-
|
354
|
-
|
355
|
-
|
356
|
-
|
357
|
-
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
-
|
362
|
-
|
363
|
-
|
364
|
-
|
365
|
-
|
366
|
-
|
147
|
+
exports.getDatabaseUrl = getDatabaseUrl;
|
148
|
+
function getDbosConfig(config, options = {}) {
|
149
|
+
(0, assert_1.default)(config.language === undefined || config.language === 'node', `Config file specifies invalid language ${config.language}`);
|
150
|
+
const userDbClient = config.database?.app_db_client ?? user_database_1.UserDatabaseName.KNEX;
|
151
|
+
(0, assert_1.default)(isValidUserDbClient(userDbClient), `Invalid app_db_client ${userDbClient} in config file`);
|
152
|
+
return translateDbosConfig({
|
153
|
+
name: config.name,
|
154
|
+
databaseUrl: config.database_url,
|
155
|
+
systemDatabaseUrl: config.system_database_url,
|
156
|
+
userDatabaseClient: userDbClient,
|
157
|
+
logLevel: options.logLevel ?? config.telemetry?.logs?.logLevel,
|
158
|
+
addContextMetadata: config.telemetry?.logs?.addContextMetadata,
|
159
|
+
otlpTracesEndpoints: toArray(config.telemetry?.OTLPExporter?.tracesEndpoint),
|
160
|
+
otlpLogsEndpoints: toArray(config.telemetry?.OTLPExporter?.logsEndpoint),
|
161
|
+
runAdminServer: config.runtimeConfig?.runAdminServer,
|
162
|
+
}, options.forceConsole);
|
367
163
|
}
|
368
|
-
|
369
|
-
|
370
|
-
|
371
|
-
* */
|
372
|
-
function parseConfigFile(cliOptions) {
|
373
|
-
if (cliOptions?.appDir) {
|
374
|
-
process.chdir(cliOptions.appDir);
|
375
|
-
}
|
376
|
-
const configFilePath = cliOptions?.configfile ?? exports.dbosConfigFilePath;
|
377
|
-
const configFile = loadConfigFile(configFilePath);
|
378
|
-
if (!configFile) {
|
379
|
-
throw new error_1.DBOSInitializationError(`DBOS configuration file ${configFilePath} is empty`);
|
380
|
-
}
|
381
|
-
return processConfigFile(configFile, cliOptions);
|
164
|
+
exports.getDbosConfig = getDbosConfig;
|
165
|
+
function toArray(endpoint) {
|
166
|
+
return endpoint ? (Array.isArray(endpoint) ? endpoint : [endpoint]) : [];
|
382
167
|
}
|
383
|
-
|
384
|
-
|
385
|
-
|
386
|
-
|
387
|
-
}
|
388
|
-
|
389
|
-
|
390
|
-
|
391
|
-
|
392
|
-
|
393
|
-
|
394
|
-
|
395
|
-
|
396
|
-
|
397
|
-
|
398
|
-
|
399
|
-
const logs = {
|
400
|
-
...configFile.telemetry?.logs,
|
401
|
-
logLevel: cliOptions?.loglevel ?? configFile.telemetry?.logs?.logLevel ?? 'info',
|
402
|
-
forceConsole: cliOptions?.forceConsole ?? configFile.telemetry?.logs?.forceConsole,
|
403
|
-
};
|
404
|
-
const traceEndpointSet = (0, utils_1.toStringSet)(configFile.telemetry?.OTLPExporter?.tracesEndpoint);
|
405
|
-
const logEndpointSet = (0, utils_1.toStringSet)(configFile.telemetry?.OTLPExporter?.logsEndpoint);
|
406
|
-
/************************************/
|
407
|
-
/* Build final DBOS configuration */
|
408
|
-
/************************************/
|
409
|
-
utils_1.globalParams.appVersion = getAppVersion(cliOptions?.appVersion);
|
410
|
-
const dbosConfig = {
|
411
|
-
poolConfig: poolConfig,
|
412
|
-
userDbclient: configFile.database?.app_db_client || user_database_1.UserDatabaseName.KNEX,
|
413
|
-
databaseUrl: configFile.database_url,
|
168
|
+
function isValidUserDbClient(name) {
|
169
|
+
return Object.values(user_database_1.UserDatabaseName).includes(name);
|
170
|
+
}
|
171
|
+
function translateDbosConfig(options, forceConsole = false) {
|
172
|
+
const databaseUrl = getDatabaseUrl({ database_url: options.databaseUrl, name: options.name });
|
173
|
+
const systemDatabaseUrl = getSystemDatabaseUrl({
|
174
|
+
database_url: options.databaseUrl,
|
175
|
+
system_database_url: options.systemDatabaseUrl,
|
176
|
+
name: options.name,
|
177
|
+
});
|
178
|
+
return {
|
179
|
+
databaseUrl,
|
180
|
+
userDbPoolSize: options.userDatabasePoolSize,
|
181
|
+
systemDatabaseUrl,
|
182
|
+
sysDbPoolSize: options.systemDatabasePoolSize,
|
183
|
+
userDbClient: options.userDatabaseClient,
|
414
184
|
telemetry: {
|
415
|
-
logs
|
185
|
+
logs: {
|
186
|
+
logLevel: options.logLevel || 'info',
|
187
|
+
addContextMetadata: options.addContextMetadata,
|
188
|
+
forceConsole,
|
189
|
+
},
|
416
190
|
OTLPExporter: {
|
417
|
-
tracesEndpoint:
|
418
|
-
logsEndpoint:
|
191
|
+
tracesEndpoint: options.otlpTracesEndpoints,
|
192
|
+
logsEndpoint: options.otlpLogsEndpoints,
|
419
193
|
},
|
420
194
|
},
|
421
|
-
system_database: configFile.database?.sys_db_name ?? `${poolConfig.database}_dbos_sys`,
|
422
|
-
http: configFile.http,
|
423
195
|
};
|
424
|
-
|
425
|
-
|
426
|
-
|
196
|
+
}
|
197
|
+
exports.translateDbosConfig = translateDbosConfig;
|
198
|
+
function getRuntimeConfig(config, options = {}) {
|
199
|
+
return translateRuntimeConfig(config.runtimeConfig, options.port);
|
200
|
+
}
|
201
|
+
exports.getRuntimeConfig = getRuntimeConfig;
|
202
|
+
function translateRuntimeConfig(config = {}, port) {
|
427
203
|
const entrypoints = new Set();
|
428
|
-
|
429
|
-
|
430
|
-
}
|
431
|
-
else {
|
204
|
+
config.entrypoints?.forEach((entry) => entrypoints.add(entry));
|
205
|
+
if (entrypoints.size === 0) {
|
432
206
|
entrypoints.add(runtime_1.defaultEntryPoint);
|
433
207
|
}
|
434
|
-
|
435
|
-
|
208
|
+
port ??= config.port ?? 3000;
|
209
|
+
return {
|
436
210
|
entrypoints: [...entrypoints],
|
437
|
-
port:
|
438
|
-
runAdminServer: true,
|
439
|
-
admin_port:
|
440
|
-
start:
|
441
|
-
setup:
|
211
|
+
port: port,
|
212
|
+
runAdminServer: config.runAdminServer ?? true,
|
213
|
+
admin_port: config.admin_port ?? port + 1,
|
214
|
+
start: config.start ?? [],
|
215
|
+
setup: config.setup ?? [],
|
442
216
|
};
|
443
|
-
return [dbosConfig, runtimeConfig];
|
444
217
|
}
|
445
|
-
exports.
|
446
|
-
function
|
447
|
-
|
448
|
-
|
218
|
+
exports.translateRuntimeConfig = translateRuntimeConfig;
|
219
|
+
function overwriteConfigForDBOSCloud(providedDBOSConfig, providedRuntimeConfig, configFile) {
|
220
|
+
// Load the DBOS configuration file and force the use of:
|
221
|
+
// 1. Use the application name from the file. This is a defensive measure to ensure the application name is whatever it was registered with in the cloud
|
222
|
+
// 2. use the database URL from environment var
|
223
|
+
// 3. OTLP traces endpoints (add the config data to the provided config)
|
224
|
+
// 4. Force admin_port and runAdminServer
|
225
|
+
const appName = configFile.name ?? providedDBOSConfig.name;
|
226
|
+
let databaseUrl = process.env.DBOS_DATABASE_URL;
|
227
|
+
if (!databaseUrl) {
|
228
|
+
databaseUrl = configFile.database_url;
|
449
229
|
}
|
450
|
-
if (
|
451
|
-
|
230
|
+
if (!databaseUrl) {
|
231
|
+
databaseUrl = providedDBOSConfig.databaseUrl;
|
452
232
|
}
|
453
|
-
|
454
|
-
|
455
|
-
|
456
|
-
if (dbName.length < 1 || dbName.length > 63) {
|
457
|
-
return false;
|
233
|
+
let systemDatabaseUrl = process.env.DBOS_SYSTEM_DATABASE_URL;
|
234
|
+
if (!systemDatabaseUrl && process.env.DBOS_DATABASE_URL) {
|
235
|
+
systemDatabaseUrl = getSystemDatabaseUrl(process.env.DBOS_DATABASE_URL);
|
458
236
|
}
|
459
|
-
if (
|
460
|
-
|
461
|
-
return false;
|
237
|
+
if (!systemDatabaseUrl) {
|
238
|
+
systemDatabaseUrl = configFile.system_database_url;
|
462
239
|
}
|
463
|
-
|
464
|
-
|
465
|
-
/*
|
466
|
-
This function takes a DBOSConfig and ensure that 'public' fields take precedence over 'internal' fields.
|
467
|
-
It assumes that the DBOSConfig was passed programmatically and thus does not need to consider CLI options.
|
468
|
-
|
469
|
-
- Application Name: check there is no inconsistency between the provided name and the one in dbos-config.yaml, if any
|
470
|
-
- Database configuration: Ignore provided poolConfig and reconstructs it from the databaseUrl field and constructPoolConfig()
|
471
|
-
*/
|
472
|
-
function translatePublicDBOSconfig(config, isDebugging) {
|
473
|
-
let appName = config.name;
|
474
|
-
// Opportunistically grab the name from the config file if none was provided
|
475
|
-
try {
|
476
|
-
const configFile = loadConfigFile(exports.dbosConfigFilePath);
|
477
|
-
if (configFile?.name && !appName) {
|
478
|
-
appName = configFile.name;
|
479
|
-
}
|
240
|
+
if (!systemDatabaseUrl) {
|
241
|
+
systemDatabaseUrl = providedDBOSConfig.systemDatabaseUrl;
|
480
242
|
}
|
481
|
-
|
482
|
-
|
483
|
-
|
484
|
-
|
243
|
+
const logsSet = new Set(providedDBOSConfig.telemetry.OTLPExporter?.logsEndpoint);
|
244
|
+
const logsEndpoint = configFile.telemetry?.OTLPExporter?.logsEndpoint;
|
245
|
+
if (logsEndpoint) {
|
246
|
+
if (Array.isArray(logsEndpoint)) {
|
247
|
+
logsEndpoint.forEach((endpoint) => logsSet.add(endpoint));
|
248
|
+
}
|
249
|
+
else {
|
250
|
+
logsSet.add(logsEndpoint);
|
485
251
|
}
|
486
252
|
}
|
487
|
-
|
488
|
-
const
|
489
|
-
|
490
|
-
|
491
|
-
|
492
|
-
application: {},
|
493
|
-
env: {},
|
494
|
-
}, { silent: true, userDbPoolSize: config.userDbPoolSize });
|
495
|
-
const translatedConfig = {
|
496
|
-
name: appName,
|
497
|
-
poolConfig: poolConfig,
|
498
|
-
userDbclient: config.userDbclient || user_database_1.UserDatabaseName.KNEX,
|
499
|
-
databaseUrl: config.databaseUrl,
|
500
|
-
telemetry: {
|
501
|
-
logs: {
|
502
|
-
logLevel: config.logLevel || 'info',
|
503
|
-
addContextMetadata: config.addContextMetadata,
|
504
|
-
forceConsole: isDebugging === undefined ? false : isDebugging,
|
505
|
-
},
|
506
|
-
OTLPExporter: {
|
507
|
-
tracesEndpoint: config.otlpTracesEndpoints || [],
|
508
|
-
logsEndpoint: config.otlpLogsEndpoints || [],
|
509
|
-
},
|
510
|
-
},
|
511
|
-
system_database: config.sysDbName || `${poolConfig.database}_dbos_sys`,
|
512
|
-
sysDbPoolSize: config.sysDbPoolSize || 20,
|
513
|
-
};
|
514
|
-
const runtimeConfig = {
|
515
|
-
port: 3000,
|
516
|
-
admin_port: config.adminPort || 3001,
|
517
|
-
runAdminServer: config.runAdminServer === undefined ? true : config.runAdminServer,
|
518
|
-
entrypoints: [],
|
519
|
-
start: [],
|
520
|
-
setup: [],
|
521
|
-
};
|
522
|
-
return [translatedConfig, runtimeConfig];
|
523
|
-
}
|
524
|
-
exports.translatePublicDBOSconfig = translatePublicDBOSconfig;
|
525
|
-
function overwrite_config(providedDBOSConfig, providedRuntimeConfig, configFile) {
|
526
|
-
if (configFile === undefined) {
|
527
|
-
try {
|
528
|
-
configFile = loadConfigFile(exports.dbosConfigFilePath);
|
253
|
+
const tracesSet = new Set(providedDBOSConfig.telemetry.OTLPExporter?.tracesEndpoint);
|
254
|
+
const tracesEndpoint = configFile.telemetry?.OTLPExporter?.tracesEndpoint;
|
255
|
+
if (tracesEndpoint) {
|
256
|
+
if (Array.isArray(tracesEndpoint)) {
|
257
|
+
tracesEndpoint.forEach((endpoint) => tracesSet.add(endpoint));
|
529
258
|
}
|
530
|
-
|
531
|
-
|
532
|
-
return [providedDBOSConfig, providedRuntimeConfig];
|
533
|
-
}
|
534
|
-
else {
|
535
|
-
throw e;
|
536
|
-
}
|
259
|
+
else {
|
260
|
+
tracesSet.add(tracesEndpoint);
|
537
261
|
}
|
538
262
|
}
|
539
|
-
// Load the DBOS configuration file and force the use of:
|
540
|
-
// 1. Use the application name from the file. This is a defensive measure to ensure the application name is whatever it was registered with in the cloud
|
541
|
-
// 2. The database connection parameters (sub the file data to the provided config)
|
542
|
-
// 3. OTLP traces endpoints (add the config data to the provided config)
|
543
|
-
// 4. Force admin_port and runAdminServer
|
544
|
-
const appName = configFile.name || providedDBOSConfig.name;
|
545
|
-
if (configFile.database?.ssl_ca) {
|
546
|
-
configFile.database_url = `postgresql://${configFile.database.username}:${configFile.database.password}@${configFile.database.hostname}:${configFile.database.port}/${configFile.database.app_db_name}?connect_timeout=10&sslmode=verify-full&sslrootcert=${configFile.database.ssl_ca}`;
|
547
|
-
}
|
548
|
-
else {
|
549
|
-
configFile.database_url = `postgresql://${configFile.database?.username}:${configFile.database?.password}@${configFile.database?.hostname}:${configFile.database?.port}/${configFile.database?.app_db_name}?connect_timeout=10&sslmode=no-verify`;
|
550
|
-
}
|
551
|
-
const poolConfig = constructPoolConfig(configFile);
|
552
|
-
const providedTraceEndpointSet = (0, utils_1.toStringSet)(providedDBOSConfig.telemetry.OTLPExporter?.tracesEndpoint);
|
553
|
-
const configTraceEndpointSet = (0, utils_1.toStringSet)(configFile.telemetry?.OTLPExporter?.tracesEndpoint);
|
554
|
-
for (const endpoint of configTraceEndpointSet) {
|
555
|
-
providedTraceEndpointSet.add(endpoint);
|
556
|
-
}
|
557
|
-
const providedLogEndpointSet = (0, utils_1.toStringSet)(providedDBOSConfig.telemetry?.OTLPExporter?.logsEndpoint);
|
558
|
-
const configLogEndpointSet = (0, utils_1.toStringSet)(configFile.telemetry?.OTLPExporter?.logsEndpoint);
|
559
|
-
for (const endpoint of configLogEndpointSet) {
|
560
|
-
providedLogEndpointSet.add(endpoint);
|
561
|
-
}
|
562
263
|
const overwritenDBOSConfig = {
|
563
264
|
...providedDBOSConfig,
|
564
265
|
name: appName,
|
565
|
-
|
266
|
+
databaseUrl,
|
267
|
+
systemDatabaseUrl,
|
566
268
|
telemetry: {
|
567
269
|
logs: providedDBOSConfig.telemetry.logs,
|
568
270
|
OTLPExporter: {
|
569
|
-
tracesEndpoint: Array.from(
|
570
|
-
logsEndpoint: Array.from(
|
271
|
+
tracesEndpoint: Array.from(tracesSet),
|
272
|
+
logsEndpoint: Array.from(logsSet),
|
571
273
|
},
|
572
274
|
},
|
573
|
-
system_database: configFile.database?.sys_db_name || poolConfig.database + '_dbos_sys', // Unexpected, but possible
|
574
275
|
};
|
575
276
|
const overwriteDBOSRuntimeConfig = {
|
576
277
|
admin_port: 3001,
|
@@ -582,5 +283,5 @@ function overwrite_config(providedDBOSConfig, providedRuntimeConfig, configFile)
|
|
582
283
|
};
|
583
284
|
return [overwritenDBOSConfig, overwriteDBOSRuntimeConfig];
|
584
285
|
}
|
585
|
-
exports.
|
286
|
+
exports.overwriteConfigForDBOSCloud = overwriteConfigForDBOSCloud;
|
586
287
|
//# sourceMappingURL=config.js.map
|