Initial commit - Event Planner application

This commit is contained in:
mberlin
2026-03-18 14:55:56 -03:00
commit 86d779eb4d
7548 changed files with 1006324 additions and 0 deletions

324
node_modules/@mikro-orm/sql/query/ObjectCriteriaNode.js generated vendored Normal file
View File

@@ -0,0 +1,324 @@
import {
ALIAS_REPLACEMENT,
GroupOperator,
QueryFlag,
raw,
RawQueryFragment,
ReferenceKind,
Utils,
} from '@mikro-orm/core';
import { CriteriaNode } from './CriteriaNode.js';
import { JoinType, QueryType } from './enums.js';
const COLLECTION_OPERATORS = ['$some', '$none', '$every', '$size'];
/**
* @internal
*/
export class ObjectCriteriaNode extends CriteriaNode {
process(qb, options) {
const matchPopulateJoins =
options?.matchPopulateJoins ||
(this.prop && [ReferenceKind.MANY_TO_ONE, ReferenceKind.ONE_TO_ONE].includes(this.prop.kind));
const nestedAlias = qb.getAliasForJoinPath(this.getPath(options), { ...options, matchPopulateJoins });
const ownerAlias = options?.alias || qb.alias;
const keys = Utils.getObjectQueryKeys(this.payload);
let alias = options?.alias;
if (nestedAlias) {
alias = nestedAlias;
}
if (this.shouldAutoJoin(qb, nestedAlias)) {
if (keys.some(k => COLLECTION_OPERATORS.includes(k))) {
if (![ReferenceKind.MANY_TO_MANY, ReferenceKind.ONE_TO_MANY].includes(this.prop.kind)) {
// ignore collection operators when used on a non-relational property - this can happen when they get into
// populateWhere via `infer` on m:n properties with select-in strategy
if (this.parent?.parent) {
// we validate only usage on top level
return {};
}
throw new Error(
`Collection operators can be used only inside a collection property context, but it was used for ${this.getPath()}.`,
);
}
const $and = [];
const knownKey =
[ReferenceKind.SCALAR, ReferenceKind.MANY_TO_ONE, ReferenceKind.EMBEDDED].includes(this.prop.kind) ||
(this.prop.kind === ReferenceKind.ONE_TO_ONE && this.prop.owner);
const parentMeta = this.metadata.find(this.parent.entityName);
const primaryKeys = parentMeta.primaryKeys.map(pk => {
return [QueryType.SELECT, QueryType.COUNT].includes(qb.type) ? `${knownKey ? alias : ownerAlias}.${pk}` : pk;
});
for (const key of keys) {
if (typeof key !== 'string' || !COLLECTION_OPERATORS.includes(key)) {
throw new Error('Mixing collection operators with other filters is not allowed.');
}
const payload = this.payload[key].unwrap();
const qb2 = qb.clone(true, ['schema']);
const joinAlias = qb2.getNextAlias(this.prop.targetMeta.class);
const sub = qb2
.from(parentMeta.class)
// eslint-disable-next-line no-unexpected-multiline
[key === '$size' ? 'leftJoin' : 'innerJoin'](this.key, joinAlias)
.select(parentMeta.primaryKeys);
if (key === '$size') {
const sizeCondition = typeof payload === 'number' ? { $eq: payload } : payload;
const pks = this.prop.referencedColumnNames;
const countExpr = raw(
`count(${pks.map(() => '??').join(', ')})`,
pks.map(pk => `${joinAlias}.${pk}`),
);
sub.groupBy(parentMeta.primaryKeys);
sub.having({
$and: Object.keys(sizeCondition).map(op => ({ [countExpr]: { [op]: sizeCondition[op] } })),
});
} else if (key === '$every') {
sub.where({ $not: { [this.key]: payload } });
} else {
sub.where({ [this.key]: payload });
}
const op = ['$size', '$some'].includes(key) ? '$in' : '$nin';
$and.push({
[Utils.getPrimaryKeyHash(primaryKeys)]: { [op]: sub.getNativeQuery().toRaw() },
});
}
if ($and.length === 1) {
return $and[0];
}
return { $and };
}
alias = this.autoJoin(qb, ownerAlias, options);
}
if (this.prop && nestedAlias) {
const toOneProperty = [ReferenceKind.MANY_TO_ONE, ReferenceKind.ONE_TO_ONE].includes(this.prop.kind);
// if the property is nullable and the filter is strict, we need to use left join, so we mimic the inner join behaviour
// with an exclusive condition on the join columns:
// - if the owning column is null, the row is missing, we don't apply the filter
// - if the target column is not null, the row is matched, we apply the filter
if (toOneProperty && this.prop.nullable && this.isStrict()) {
const key = this.prop.owner ? this.prop.name : this.prop.referencedPKs;
qb.andWhere({
$or: [
{ [ownerAlias + '.' + key]: null },
{ [nestedAlias + '.' + Utils.getPrimaryKeyHash(this.prop.referencedPKs)]: { $ne: null } },
],
});
}
}
return keys.reduce((o, field) => {
const childNode = this.payload[field];
const payload = childNode.process(qb, { ...options, alias: this.prop ? alias : ownerAlias });
const operator = Utils.isOperator(field);
const isRawField = RawQueryFragment.isKnownFragmentSymbol(field);
// we need to keep the prefixing for formulas otherwise we would lose aliasing context when nesting inside group operators
const virtual = childNode.prop?.persist === false && !childNode.prop?.formula && !!options?.type;
// if key is missing, we are inside group operator and we need to prefix with alias
const primaryKey = this.key && this.metadata.find(this.entityName)?.primaryKeys.includes(field);
const isToOne =
childNode.prop && [ReferenceKind.MANY_TO_ONE, ReferenceKind.ONE_TO_ONE].includes(childNode.prop.kind);
if (childNode.shouldInline(payload)) {
const childAlias = qb.getAliasForJoinPath(childNode.getPath(), { preferNoBranch: isToOne, ...options });
const a = qb.helper.isTableNameAliasRequired(qb.type) ? alias : undefined;
this.inlineChildPayload(o, payload, field, a, childAlias);
} else if (childNode.shouldRename(payload)) {
this.inlineCondition(childNode.renameFieldToPK(qb, alias), o, payload);
} else if (isRawField) {
const rawField = RawQueryFragment.getKnownFragment(field);
o[raw(rawField.sql.replaceAll(ALIAS_REPLACEMENT, alias), rawField.params)] = payload;
} else if (!childNode.validate && !childNode.prop && !field.includes('.') && !operator) {
// wrap unknown fields in raw() to prevent alias prefixing (e.g. raw SQL aliases in HAVING)
// use '??' placeholder to properly quote the identifier
o[raw('??', [field])] = payload;
} else if (
primaryKey ||
virtual ||
operator ||
field.includes('.') ||
![QueryType.SELECT, QueryType.COUNT].includes(qb.type)
) {
this.inlineCondition(field.replaceAll(ALIAS_REPLACEMENT, alias), o, payload);
} else {
this.inlineCondition(`${alias ?? qb.alias}.${field}`, o, payload);
}
return o;
}, {});
}
isStrict() {
return (
this.strict ||
Utils.getObjectQueryKeys(this.payload).some(key => {
return this.payload[key].isStrict();
})
);
}
unwrap() {
return Utils.getObjectQueryKeys(this.payload).reduce((o, field) => {
o[field] = this.payload[field].unwrap();
return o;
}, {});
}
willAutoJoin(qb, alias, options) {
const nestedAlias = qb.getAliasForJoinPath(this.getPath(options), options);
const ownerAlias = alias || qb.alias;
const keys = Utils.getObjectQueryKeys(this.payload);
if (nestedAlias) {
alias = nestedAlias;
}
if (this.shouldAutoJoin(qb, nestedAlias)) {
return !keys.some(k => COLLECTION_OPERATORS.includes(k));
}
return keys.some(field => {
const childNode = this.payload[field];
return childNode.willAutoJoin(qb, this.prop ? alias : ownerAlias, options);
});
}
shouldInline(payload) {
const rawField = RawQueryFragment.isKnownFragmentSymbol(this.key);
const scalar = Utils.isPrimaryKey(payload) || payload instanceof RegExp || payload instanceof Date || rawField;
const operator =
Utils.isObject(payload) &&
Utils.getObjectQueryKeys(payload).every(k => {
if (k === '$not' && Utils.isPlainObject(payload[k])) {
// $not wrapping non-operator conditions (entity props) should be inlined
return Utils.getObjectQueryKeys(payload[k]).every(ik => Utils.isOperator(ik, false));
}
return Utils.isOperator(k, false);
});
return !!this.prop && this.prop.kind !== ReferenceKind.SCALAR && !scalar && !operator;
}
getChildKey(k, prop, childAlias, alias) {
const idx = prop.referencedPKs.indexOf(k);
return idx !== -1 && !childAlias && ![ReferenceKind.ONE_TO_MANY, ReferenceKind.MANY_TO_MANY].includes(prop.kind)
? this.aliased(prop.joinColumns[idx], alias)
: k;
}
inlineArrayChildPayload(obj, payload, k, prop, childAlias, alias) {
const key = this.getChildKey(k, prop, childAlias);
const value = payload.map(child =>
Utils.getObjectQueryKeys(child).reduce((inner, childKey) => {
const key =
RawQueryFragment.isKnownFragmentSymbol(childKey) || this.isPrefixed(childKey) || Utils.isOperator(childKey)
? childKey
: this.aliased(childKey, childAlias);
inner[key] = child[childKey];
return inner;
}, {}),
);
this.inlineCondition(key, obj, value);
}
inlineChildPayload(o, payload, field, alias, childAlias) {
const prop = this.metadata.find(this.entityName).properties[field];
for (const k of Utils.getObjectQueryKeys(payload)) {
if (RawQueryFragment.isKnownFragmentSymbol(k)) {
o[k] = payload[k];
} else if (
k === '$not' &&
Utils.isPlainObject(payload[k]) &&
Utils.getObjectQueryKeys(payload[k]).some(ik => !Utils.isOperator(ik, false))
) {
// $not wraps entity conditions (from auto-join), inline at current level
this.inlineCondition(k, o, payload[k]);
} else if (Utils.isOperator(k, false)) {
const tmp = payload[k];
delete payload[k];
o[this.aliased(field, alias)] = { [k]: tmp, ...o[this.aliased(field, alias)] };
} else if (k in GroupOperator && Array.isArray(payload[k])) {
this.inlineArrayChildPayload(o, payload[k], k, prop, childAlias, alias);
} else if (this.isPrefixed(k) || Utils.isOperator(k) || !childAlias) {
const key = this.getChildKey(k, prop, childAlias, alias);
this.inlineCondition(key, o, payload[k]);
} else {
o[this.aliased(k, childAlias)] = payload[k];
}
}
}
inlineCondition(key, o, value) {
if (!(key in o)) {
o[key] = value;
return;
}
/* v8 ignore next */
if (key === '$and') {
o.$and.push({ [key]: value });
return;
}
const $and = o.$and ?? [];
$and.push({ [key]: o[key] }, { [key]: value });
delete o[key];
o.$and = $and;
}
shouldAutoJoin(qb, nestedAlias) {
if (!this.prop || !this.parent) {
return false;
}
const keys = Utils.getObjectQueryKeys(this.payload);
if (keys.every(k => typeof k === 'string' && k.includes('.') && k.startsWith(`${qb.alias}.`))) {
return false;
}
if (keys.some(k => COLLECTION_OPERATORS.includes(k))) {
return true;
}
const meta = this.metadata.find(this.entityName);
const embeddable = this.prop.kind === ReferenceKind.EMBEDDED;
const knownKey =
[ReferenceKind.SCALAR, ReferenceKind.MANY_TO_ONE, ReferenceKind.EMBEDDED].includes(this.prop.kind) ||
(this.prop.kind === ReferenceKind.ONE_TO_ONE && this.prop.owner);
const operatorKeys =
knownKey &&
keys.every(key => {
if (key === '$not') {
// $not wraps conditions like $and/$or, check if it wraps entity property conditions (needs auto-join)
// vs simple operator conditions on the FK (doesn't need auto-join)
const childPayload = this.payload[key].payload;
if (Utils.isPlainObject(childPayload)) {
return Utils.getObjectQueryKeys(childPayload).every(k => Utils.isOperator(k, false));
}
}
return Utils.isOperator(key, false);
});
const primaryKeys =
knownKey &&
keys.every(key => {
if (typeof key !== 'string' || !meta.primaryKeys.includes(key)) {
return false;
}
if (
!Utils.isPlainObject(this.payload[key].payload) ||
![ReferenceKind.ONE_TO_ONE, ReferenceKind.MANY_TO_ONE].includes(meta.properties[key].kind)
) {
return true;
}
return Utils.getObjectQueryKeys(this.payload[key].payload).every(
k => typeof k === 'string' && meta.properties[key].targetMeta.primaryKeys.includes(k),
);
});
return !primaryKeys && !nestedAlias && !operatorKeys && !embeddable;
}
autoJoin(qb, alias, options) {
const nestedAlias = qb.getNextAlias(this.prop?.pivotEntity ?? this.entityName);
const rawField = RawQueryFragment.isKnownFragmentSymbol(this.key);
const scalar =
Utils.isPrimaryKey(this.payload) || this.payload instanceof RegExp || this.payload instanceof Date || rawField;
const operator =
Utils.isPlainObject(this.payload) &&
Utils.getObjectQueryKeys(this.payload).every(k => Utils.isOperator(k, false));
const field = `${alias}.${this.prop.name}`;
const method = qb.hasFlag(QueryFlag.INFER_POPULATE) ? 'joinAndSelect' : 'join';
const path = this.getPath();
if (this.prop.kind === ReferenceKind.MANY_TO_MANY && (scalar || operator)) {
qb.join(field, nestedAlias, undefined, JoinType.pivotJoin, path);
} else {
const prev = qb.state.fields?.slice();
const toOneProperty = [ReferenceKind.MANY_TO_ONE, ReferenceKind.ONE_TO_ONE].includes(this.prop.kind);
const joinType = toOneProperty && !this.prop.nullable ? JoinType.innerJoin : JoinType.leftJoin;
qb[method](field, nestedAlias, undefined, joinType, path);
if (!qb.hasFlag(QueryFlag.INFER_POPULATE)) {
qb.state.fields = prev;
}
}
if (options?.type !== 'orderBy') {
qb.scheduleFilterCheck(path);
}
return nestedAlias;
}
isPrefixed(field) {
return !!/\w+\./.exec(field);
}
}