Files
adopt-a-street/node_modules/mongoose/lib/schema/union.js
William Valentin 5aca521c52 feat: Complete CouchDB migration and Docker configuration
- Add comprehensive CouchDB setup and configuration
- Update Docker files for CouchDB compatibility
- Create Kubernetes manifests for CouchDB deployment
- Add migration scripts and documentation
- Update seeding scripts to support both CouchDB and MongoDB
- Add docker-compose for local development
- Create comprehensive setup and deployment guides

🤖 Generated with [AI Assistant]

Co-Authored-By: AI Assistant <noreply@ai-assistant.com>
2025-11-01 13:32:39 -07:00

106 lines
3.6 KiB
JavaScript

'use strict';
/*!
* ignore
*/
const SchemaUnionOptions = require('../options/schemaUnionOptions');
const SchemaType = require('../schemaType');
const firstValueSymbol = Symbol('firstValue');
/*!
* ignore
*/
class Union extends SchemaType {
constructor(key, options, schemaOptions = {}) {
super(key, options, 'Union');
if (!options || !Array.isArray(options.of) || options.of.length === 0) {
throw new Error('Union schema type requires an array of types');
}
this.schemaTypes = options.of.map(obj => options.parentSchema.interpretAsType(key, obj, schemaOptions));
}
cast(val, doc, init, prev, options) {
let firstValue = firstValueSymbol;
let lastError;
// Loop through each schema type in the union. If one of the schematypes returns a value that is `=== val`, then
// use `val`. Otherwise, if one of the schematypes casted successfully, use the first successfully casted value.
// Finally, if none of the schematypes casted successfully, throw the error from the last schema type in the union.
// The `=== val` check is a workaround to ensure that the original value is returned if it matches one of the schema types,
// avoiding cases like where numbers are casted to strings or dates even if the schema type is a number.
for (let i = 0; i < this.schemaTypes.length; ++i) {
try {
const casted = this.schemaTypes[i].cast(val, doc, init, prev, options);
if (casted === val) {
return casted;
}
if (firstValue === firstValueSymbol) {
firstValue = casted;
}
} catch (error) {
lastError = error;
}
}
if (firstValue !== firstValueSymbol) {
return firstValue;
}
throw lastError;
}
// Setters also need to be aware of casting - we need to apply the setters of the entry in the union we choose.
applySetters(val, doc, init, prev, options) {
let firstValue = firstValueSymbol;
let lastError;
// Loop through each schema type in the union. If one of the schematypes returns a value that is `=== val`, then
// use `val`. Otherwise, if one of the schematypes casted successfully, use the first successfully casted value.
// Finally, if none of the schematypes casted successfully, throw the error from the last schema type in the union.
// The `=== val` check is a workaround to ensure that the original value is returned if it matches one of the schema types,
// avoiding cases like where numbers are casted to strings or dates even if the schema type is a number.
for (let i = 0; i < this.schemaTypes.length; ++i) {
try {
let castedVal = this.schemaTypes[i]._applySetters(val, doc, init, prev, options);
if (castedVal == null) {
castedVal = this.schemaTypes[i]._castNullish(castedVal);
} else {
castedVal = this.schemaTypes[i].cast(castedVal, doc, init, prev, options);
}
if (castedVal === val) {
return castedVal;
}
if (firstValue === firstValueSymbol) {
firstValue = castedVal;
}
} catch (error) {
lastError = error;
}
}
if (firstValue !== firstValueSymbol) {
return firstValue;
}
throw lastError;
}
clone() {
const schematype = super.clone();
schematype.schemaTypes = this.schemaTypes.map(schemaType => schemaType.clone());
return schematype;
}
}
/**
* This schema type's name, to defend against minifiers that mangle
* function names.
*
* @api public
*/
Union.schemaName = 'Union';
Union.defaultOptions = {};
Union.prototype.OptionsConstructor = SchemaUnionOptions;
module.exports = Union;