Add support for individual database environment variables (#9344)

* Add support for individual database environment variables

- Add DATABASE_HOST, DATABASE_PORT, DATABASE_NAME, DATABASE_USER, DATABASE_PASSWORD env vars
- Implement mutual exclusivity validation between DATABASE_URL and individual components
- Add effectiveDatabaseUrl getter to construct URL from individual components
- Update database connection logic to use new configuration options
- Ensure backward compatibility with existing DATABASE_URL configuration

Resolves: https://github.com/outline/outline/discussions/9158

* Refactor database configuration methods

- Move effectiveDatabaseUrl method from env.ts to database.ts as getEffectiveDatabaseUrl function
- Remove validateDatabaseConfiguration method from env.ts as validation is handled by decorators
- Maintain clean separation of concerns between environment and database modules

* Pass database options directly to Sequelize constructor

- Replace URL construction with direct Sequelize configuration object
- Support both DATABASE_URL string and individual component object configurations
- Maintain common Sequelize options for both configuration types
- Improve error messaging for different configuration scenarios

* remove spurious comments

* tsc

---------

Co-authored-by: codegen-sh[bot] <131295404+codegen-sh[bot]@users.noreply.github.com>
Co-authored-by: Tom Moor <tom@getoutline.com>
This commit is contained in:
codegen-sh[bot]
2025-05-31 11:30:28 -04:00
committed by GitHub
parent 7a5480f12f
commit cd0acc40bb
3 changed files with 128 additions and 10 deletions
+30
View File
@@ -57,3 +57,33 @@ export function CannotUseWith(
});
};
}
export function CannotUseWithAny(
properties: string[],
validationOptions?: ValidationOptions
) {
return function (object: Object, propertyName: string) {
registerDecorator({
name: "cannotUseWithAny",
target: object.constructor,
propertyName,
constraints: properties,
options: validationOptions,
validator: {
validate<T>(value: T, args: ValidationArguments) {
if (value === undefined) {
return true;
}
const obj = args.object as unknown as T;
const forbiddenProperties = args.constraints as (keyof T)[];
return forbiddenProperties.every((prop) => obj[prop] === undefined);
},
defaultMessage(args: ValidationArguments) {
return `${propertyName} cannot be used with any of: ${args.constraints.join(
", "
)}.`;
},
},
});
};
}