Some checks failed
Build & Deploy / 🔍 Prepare (push) Successful in 20s
Build & Deploy / 🧪 QA (push) Failing after 34s
Build & Deploy / 🏗️ Build (push) Has started running
Build & Deploy / 🚀 Deploy (push) Has been cancelled
Build & Deploy / 🧪 Smoke Test (push) Has been cancelled
Build & Deploy / ⚡ Lighthouse (push) Has been cancelled
Build & Deploy / 🔔 Notify (push) Has been cancelled
631 lines
34 KiB
Plaintext
631 lines
34 KiB
Plaintext
import { and, asc, count, desc, eq, getTableName, or, sql } from 'drizzle-orm';
|
|
import { appendVersionToQueryKey, buildVersionCollectionFields, combineQueries, getFieldByPath, getQueryDraftsSort } from 'payload';
|
|
import { fieldIsVirtual, fieldShouldBeLocalized, hasDraftsEnabled } from 'payload/shared';
|
|
import toSnakeCase from 'to-snake-case';
|
|
import { buildQuery } from '../queries/buildQuery.js';
|
|
import { getTableAlias } from '../queries/getTableAlias.js';
|
|
import { operatorMap } from '../queries/operatorMap.js';
|
|
import { getArrayRelationName } from '../utilities/getArrayRelationName.js';
|
|
import { getNameFromDrizzleTable } from '../utilities/getNameFromDrizzleTable.js';
|
|
import { jsonAggBuildObject } from '../utilities/json.js';
|
|
import { rawConstraint } from '../utilities/rawConstraint.js';
|
|
import { InternalBlockTableNameIndex, resolveBlockTableName } from '../utilities/validateExistingBlockIsIdentical.js';
|
|
const flattenAllWherePaths = (where, paths)=>{
|
|
for(const k in where){
|
|
if ([
|
|
'AND',
|
|
'OR'
|
|
].includes(k.toUpperCase())) {
|
|
if (Array.isArray(where[k])) {
|
|
for (const whereField of where[k]){
|
|
flattenAllWherePaths(whereField, paths);
|
|
}
|
|
}
|
|
} else {
|
|
// TODO: explore how to support arrays/relationship querying.
|
|
paths.push({
|
|
path: k.split('.').join('_'),
|
|
ref: where
|
|
});
|
|
}
|
|
}
|
|
};
|
|
const buildSQLWhere = (where, alias)=>{
|
|
for(const k in where){
|
|
if ([
|
|
'AND',
|
|
'OR'
|
|
].includes(k.toUpperCase())) {
|
|
if (Array.isArray(where[k])) {
|
|
const op = 'AND' === k.toUpperCase() ? and : or;
|
|
const accumulated = [];
|
|
for (const whereField of where[k]){
|
|
accumulated.push(buildSQLWhere(whereField, alias));
|
|
}
|
|
return op(...accumulated);
|
|
}
|
|
} else {
|
|
let payloadOperator = Object.keys(where[k])[0];
|
|
const value = where[k][payloadOperator];
|
|
if (payloadOperator === '$raw') {
|
|
return sql.raw(value);
|
|
}
|
|
// Handle exists: false -> use isNull instead of isNotNull
|
|
// This logic is duplicated from sanitizeQueryValue.ts because buildSQLWhere
|
|
// is a simplified WHERE builder for polymorphic joins that doesn't have access
|
|
// to field definitions needed by sanitizeQueryValue
|
|
if (payloadOperator === 'exists' && value === false) {
|
|
payloadOperator = 'isNull';
|
|
}
|
|
return operatorMap[payloadOperator](sql.raw(`"${alias}"."${k.split('.').join('_')}"`), value);
|
|
}
|
|
}
|
|
};
|
|
export const traverseFields = ({ _locales, adapter, collectionSlug, currentArgs, currentTableName, depth, draftsEnabled, fields, forceWithFields, joinQuery = {}, joins, locale, parentIsLocalized = false, path, select, selectAllOnCurrentLevel = false, selectMode, tablePath, topLevelArgs, topLevelTableName, versions, withTabledFields })=>{
|
|
fields.forEach((field)=>{
|
|
if (fieldIsVirtual(field)) {
|
|
return;
|
|
}
|
|
const isFieldLocalized = fieldShouldBeLocalized({
|
|
field,
|
|
parentIsLocalized
|
|
});
|
|
// handle simple relationship
|
|
if (depth > 0 && (field.type === 'upload' || field.type === 'relationship') && !field.hasMany && typeof field.relationTo === 'string') {
|
|
if (isFieldLocalized) {
|
|
_locales.with[`${path}${field.name}`] = true;
|
|
} else {
|
|
currentArgs.with[`${path}${field.name}`] = true;
|
|
}
|
|
}
|
|
switch(field.type){
|
|
case 'array':
|
|
{
|
|
const arraySelect = selectAllOnCurrentLevel ? true : select?.[field.name];
|
|
if (select) {
|
|
if (selectMode === 'include' && typeof arraySelect === 'undefined' || selectMode === 'exclude' && arraySelect === false) {
|
|
break;
|
|
}
|
|
}
|
|
const withArray = {
|
|
columns: typeof arraySelect === 'object' ? {
|
|
id: true,
|
|
_order: true
|
|
} : {
|
|
_parentID: false
|
|
},
|
|
orderBy: ({ _order }, { asc })=>[
|
|
asc(_order)
|
|
],
|
|
with: {}
|
|
};
|
|
const arrayTableName = adapter.tableNameMap.get(`${currentTableName}_${tablePath}${toSnakeCase(field.name)}`);
|
|
if (typeof arraySelect === 'object') {
|
|
if (adapter.tables[arrayTableName]._locale) {
|
|
withArray.columns._locale = true;
|
|
}
|
|
if (adapter.tables[arrayTableName]._uuid) {
|
|
withArray.columns._uuid = true;
|
|
}
|
|
}
|
|
const arrayTableNameWithLocales = `${arrayTableName}${adapter.localesSuffix}`;
|
|
if (adapter.tables[arrayTableNameWithLocales]) {
|
|
withArray.with._locales = {
|
|
columns: typeof arraySelect === 'object' ? {
|
|
_locale: true
|
|
} : {
|
|
id: false,
|
|
_parentID: false
|
|
},
|
|
with: {}
|
|
};
|
|
}
|
|
const relationName = getArrayRelationName({
|
|
field,
|
|
path: `${path}${field.name}`,
|
|
tableName: arrayTableName
|
|
});
|
|
currentArgs.with[relationName] = withArray;
|
|
traverseFields({
|
|
_locales: withArray.with._locales,
|
|
adapter,
|
|
currentArgs: withArray,
|
|
currentTableName: arrayTableName,
|
|
depth,
|
|
draftsEnabled,
|
|
fields: field.flattenedFields,
|
|
forceWithFields,
|
|
joinQuery,
|
|
locale,
|
|
parentIsLocalized: parentIsLocalized || field.localized,
|
|
path: '',
|
|
select: typeof arraySelect === 'object' ? arraySelect : undefined,
|
|
selectMode,
|
|
tablePath: '',
|
|
topLevelArgs,
|
|
topLevelTableName,
|
|
withTabledFields
|
|
});
|
|
if (typeof arraySelect === 'object' && withArray.with._locales && Object.keys(withArray.with._locales).length === 1) {
|
|
delete withArray.with._locales;
|
|
}
|
|
break;
|
|
}
|
|
case 'blocks':
|
|
{
|
|
const blocksSelect = selectAllOnCurrentLevel ? true : select?.[field.name];
|
|
if (select) {
|
|
if (selectMode === 'include' && !blocksSelect || selectMode === 'exclude' && blocksSelect === false) {
|
|
break;
|
|
}
|
|
}
|
|
if (adapter.blocksAsJSON) {
|
|
if (select || selectAllOnCurrentLevel) {
|
|
const fieldPath = `${path}${field.name}`;
|
|
if ((isFieldLocalized || parentIsLocalized) && _locales) {
|
|
_locales.columns[fieldPath] = true;
|
|
} else if (adapter.tables[currentTableName]?.[fieldPath]) {
|
|
currentArgs.columns[fieldPath] = true;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
;
|
|
(field.blockReferences ?? field.blocks).forEach((_block)=>{
|
|
const block = typeof _block === 'string' ? adapter.payload.blocks[_block] : _block;
|
|
const blockKey = `_blocks_${block.slug}${!block[InternalBlockTableNameIndex] ? '' : `_${block[InternalBlockTableNameIndex]}`}`;
|
|
let blockSelect;
|
|
let blockSelectMode = selectMode;
|
|
if (selectMode === 'include' && blocksSelect === true) {
|
|
blockSelect = true;
|
|
}
|
|
if (typeof blocksSelect === 'object') {
|
|
if (typeof blocksSelect[block.slug] === 'object') {
|
|
blockSelect = blocksSelect[block.slug];
|
|
} else if (selectMode === 'include' && typeof blocksSelect[block.slug] === 'undefined' || selectMode === 'exclude' && blocksSelect[block.slug] === false) {
|
|
blockSelect = {};
|
|
blockSelectMode = 'include';
|
|
} else if (selectMode === 'include' && Boolean(blocksSelect[block.slug])) {
|
|
blockSelect = true;
|
|
}
|
|
}
|
|
if (!topLevelArgs[blockKey]) {
|
|
const withBlock = {
|
|
columns: typeof blockSelect === 'object' ? {
|
|
id: true,
|
|
_order: true,
|
|
_path: true
|
|
} : {
|
|
_parentID: false
|
|
},
|
|
orderBy: ({ _order }, { asc })=>[
|
|
asc(_order)
|
|
],
|
|
with: {}
|
|
};
|
|
const tableName = resolveBlockTableName(block, adapter.tableNameMap.get(`${topLevelTableName}_blocks_${toSnakeCase(block.slug)}`));
|
|
if (typeof blockSelect === 'object') {
|
|
if (adapter.tables[tableName]._locale) {
|
|
withBlock.columns._locale = true;
|
|
}
|
|
if (adapter.tables[tableName]._uuid) {
|
|
withBlock.columns._uuid = true;
|
|
}
|
|
}
|
|
if (adapter.tables[`${tableName}${adapter.localesSuffix}`]) {
|
|
withBlock.with._locales = {
|
|
with: {}
|
|
};
|
|
if (typeof blockSelect === 'object') {
|
|
withBlock.with._locales.columns = {
|
|
_locale: true
|
|
};
|
|
}
|
|
}
|
|
topLevelArgs.with[blockKey] = withBlock;
|
|
traverseFields({
|
|
_locales: withBlock.with._locales,
|
|
adapter,
|
|
currentArgs: withBlock,
|
|
currentTableName: tableName,
|
|
depth,
|
|
draftsEnabled,
|
|
fields: block.flattenedFields,
|
|
forceWithFields: blockSelect === true,
|
|
joinQuery,
|
|
locale,
|
|
parentIsLocalized: parentIsLocalized || field.localized,
|
|
path: '',
|
|
select: typeof blockSelect === 'object' ? blockSelect : undefined,
|
|
selectMode: blockSelectMode,
|
|
tablePath: '',
|
|
topLevelArgs,
|
|
topLevelTableName,
|
|
withTabledFields
|
|
});
|
|
if (typeof blockSelect === 'object' && withBlock.with._locales && Object.keys(withBlock.with._locales.columns).length === 1) {
|
|
delete withBlock.with._locales;
|
|
}
|
|
}
|
|
});
|
|
break;
|
|
}
|
|
case 'group':
|
|
case 'tab':
|
|
{
|
|
const fieldSelect = select?.[field.name];
|
|
if (fieldSelect === false) {
|
|
break;
|
|
}
|
|
traverseFields({
|
|
_locales,
|
|
adapter,
|
|
collectionSlug,
|
|
currentArgs,
|
|
currentTableName,
|
|
depth,
|
|
draftsEnabled,
|
|
fields: field.flattenedFields,
|
|
forceWithFields,
|
|
joinQuery,
|
|
joins,
|
|
locale,
|
|
parentIsLocalized: parentIsLocalized || field.localized,
|
|
path: `${path}${field.name}_`,
|
|
select: typeof fieldSelect === 'object' ? fieldSelect : undefined,
|
|
selectAllOnCurrentLevel: selectAllOnCurrentLevel || fieldSelect === true || selectMode === 'exclude' && typeof fieldSelect === 'undefined',
|
|
selectMode,
|
|
tablePath: `${tablePath}${toSnakeCase(field.name)}_`,
|
|
topLevelArgs,
|
|
topLevelTableName,
|
|
versions,
|
|
withTabledFields
|
|
});
|
|
break;
|
|
}
|
|
case 'join':
|
|
{
|
|
// when `joinsQuery` is false, do not join
|
|
if (joinQuery === false) {
|
|
break;
|
|
}
|
|
if (select && selectMode === 'include' && !select[field.name] || selectMode === 'exclude' && select[field.name] === false) {
|
|
break;
|
|
}
|
|
const joinSchemaPath = `${path.replaceAll('_', '.')}${field.name}`;
|
|
if (joinQuery[joinSchemaPath] === false) {
|
|
break;
|
|
}
|
|
const { count: shouldCount = false, limit: limitArg = field.defaultLimit ?? 10, page, sort = field.defaultSort, where } = joinQuery[joinSchemaPath] || {};
|
|
let limit = limitArg;
|
|
if (limit !== 0) {
|
|
// get an additional document and slice it later to determine if there is a next page
|
|
limit += 1;
|
|
}
|
|
const columnName = `${path.replaceAll('.', '_')}${field.name}`;
|
|
const db = adapter.drizzle;
|
|
if (Array.isArray(field.collection)) {
|
|
let currentQuery = null;
|
|
const onPath = field.on.split('.').join('_');
|
|
if (Array.isArray(sort)) {
|
|
throw new Error('Not implemented');
|
|
}
|
|
let sanitizedSort = sort;
|
|
if (!sanitizedSort) {
|
|
if (field.collection.some((collection)=>adapter.payload.collections[collection].config.fields.some((f)=>f.type === 'date' && f.name === 'createdAt'))) {
|
|
sanitizedSort = '-createdAt';
|
|
} else {
|
|
sanitizedSort = 'id';
|
|
}
|
|
}
|
|
const sortOrder = sanitizedSort.startsWith('-') ? desc : asc;
|
|
sanitizedSort = sanitizedSort.replace('-', '');
|
|
const sortPath = sanitizedSort.split('.').join('_');
|
|
const wherePaths = [];
|
|
if (where) {
|
|
flattenAllWherePaths(where, wherePaths);
|
|
}
|
|
for (const collection of field.collection){
|
|
const joinCollectionTableName = adapter.tableNameMap.get(toSnakeCase(collection));
|
|
const table = adapter.tables[joinCollectionTableName];
|
|
const sortColumn = table[sortPath];
|
|
const selectFields = {
|
|
id: adapter.tables[joinCollectionTableName].id,
|
|
parent: sql`${adapter.tables[joinCollectionTableName][onPath]}`.as(onPath),
|
|
relationTo: sql`${collection}`.as('relationTo'),
|
|
sortPath: sql`${sortColumn ? sortColumn : null}`.as('sortPath')
|
|
};
|
|
const collectionQueryWhere = [];
|
|
// Select for WHERE and Fallback NULL
|
|
for (const { path, ref } of wherePaths){
|
|
const collectioConfig = adapter.payload.collections[collection].config;
|
|
const field = getFieldByPath({
|
|
fields: collectioConfig.flattenedFields,
|
|
path
|
|
});
|
|
if (field && field.field.type === 'select' && field.field.hasMany) {
|
|
let tableName = adapter.tableNameMap.get(`${toSnakeCase(collection)}_${toSnakeCase(path)}`);
|
|
let parentTable = getTableName(table);
|
|
if (adapter.schemaName) {
|
|
tableName = `"${adapter.schemaName}"."${tableName}"`;
|
|
parentTable = `"${adapter.schemaName}"."${parentTable}"`;
|
|
}
|
|
if (adapter.name === 'postgres') {
|
|
selectFields[path] = sql.raw(`(select jsonb_agg(${tableName}.value) from ${tableName} where ${tableName}.parent_id = ${parentTable}.id)`).as(path);
|
|
} else {
|
|
selectFields[path] = sql.raw(`(select json_group_array(${tableName}.value) from ${tableName} where ${tableName}.parent_id = ${parentTable}.id)`).as(path);
|
|
}
|
|
const constraint = ref[path];
|
|
const operator = Object.keys(constraint)[0];
|
|
const value = Object.values(constraint)[0];
|
|
const query = adapter.createJSONQuery({
|
|
column: `"${path}"`,
|
|
operator,
|
|
pathSegments: [
|
|
field.field.name
|
|
],
|
|
table: parentTable,
|
|
value
|
|
});
|
|
ref[path] = {
|
|
$raw: query
|
|
};
|
|
} else if (adapter.tables[joinCollectionTableName][path]) {
|
|
selectFields[path] = sql`${adapter.tables[joinCollectionTableName][path]}`.as(path);
|
|
// Allow to filter by collectionSlug
|
|
} else if (path !== 'relationTo') {
|
|
// For timestamp fields like deletedAt, we need to cast to timestamp in Postgres
|
|
// SQLite doesn't require explicit type casting for UNION queries
|
|
if (path === 'deletedAt' && adapter.name === 'postgres') {
|
|
selectFields[path] = sql`null::timestamp with time zone`.as(path);
|
|
} else {
|
|
selectFields[path] = sql`null`.as(path);
|
|
}
|
|
}
|
|
}
|
|
let query = db.select(selectFields).from(adapter.tables[joinCollectionTableName]);
|
|
if (collectionQueryWhere.length) {
|
|
query = query.where(and(...collectionQueryWhere));
|
|
}
|
|
if (currentQuery === null) {
|
|
currentQuery = query;
|
|
} else {
|
|
currentQuery = currentQuery.unionAll(query);
|
|
}
|
|
}
|
|
const subQueryAlias = `${columnName}_subquery`;
|
|
let sqlWhere = eq(sql.raw(`"${currentTableName}"."id"`), sql.raw(`"${subQueryAlias}"."${onPath}"`));
|
|
if (where && Object.keys(where).length > 0) {
|
|
sqlWhere = and(sqlWhere, buildSQLWhere(where, subQueryAlias));
|
|
}
|
|
if (shouldCount) {
|
|
currentArgs.extras[`${columnName}_count`] = sql`${db.select({
|
|
count: count()
|
|
}).from(sql`${currentQuery.as(subQueryAlias)}`).where(sqlWhere)}`.as(`${columnName}_count`);
|
|
}
|
|
currentQuery = currentQuery.orderBy(sortOrder(sql`"sortPath"`));
|
|
if (page && limit !== 0) {
|
|
const offset = (page - 1) * limit;
|
|
if (offset > 0) {
|
|
currentQuery = currentQuery.offset(offset);
|
|
}
|
|
}
|
|
if (limit) {
|
|
currentQuery = currentQuery.limit(limit);
|
|
}
|
|
currentArgs.extras[columnName] = sql`${db.select({
|
|
id: jsonAggBuildObject(adapter, {
|
|
id: sql.raw(`"${subQueryAlias}"."id"`),
|
|
relationTo: sql.raw(`"${subQueryAlias}"."relationTo"`)
|
|
})
|
|
}).from(sql`${currentQuery.as(subQueryAlias)}`).where(sqlWhere)}`.as(columnName);
|
|
} else {
|
|
const useDrafts = (versions || draftsEnabled) && hasDraftsEnabled(adapter.payload.collections[field.collection].config);
|
|
const fields = useDrafts ? buildVersionCollectionFields(adapter.payload.config, adapter.payload.collections[field.collection].config, true) : adapter.payload.collections[field.collection].config.flattenedFields;
|
|
const joinCollectionTableName = adapter.tableNameMap.get(useDrafts ? `_${toSnakeCase(field.collection)}${adapter.versionsSuffix}` : toSnakeCase(field.collection));
|
|
const joins = [];
|
|
const currentIDColumn = versions ? adapter.tables[currentTableName].parent : adapter.tables[currentTableName].id;
|
|
let joinQueryWhere;
|
|
const currentIDRaw = sql.raw(`"${getNameFromDrizzleTable(currentIDColumn.table)}"."${currentIDColumn.name}"`);
|
|
if (Array.isArray(field.targetField.relationTo)) {
|
|
joinQueryWhere = {
|
|
[field.on]: {
|
|
equals: {
|
|
relationTo: collectionSlug,
|
|
value: rawConstraint(currentIDRaw)
|
|
}
|
|
}
|
|
};
|
|
} else {
|
|
joinQueryWhere = {
|
|
[field.on]: {
|
|
equals: rawConstraint(currentIDRaw)
|
|
}
|
|
};
|
|
}
|
|
if (where && Object.keys(where).length) {
|
|
joinQueryWhere = {
|
|
and: [
|
|
joinQueryWhere,
|
|
where
|
|
]
|
|
};
|
|
}
|
|
if (useDrafts) {
|
|
joinQueryWhere = combineQueries(appendVersionToQueryKey(joinQueryWhere), {
|
|
latest: {
|
|
equals: true
|
|
}
|
|
});
|
|
}
|
|
const columnName = `${path.replaceAll('.', '_')}${field.name}`;
|
|
const subQueryAlias = `${columnName}_alias`;
|
|
const { newAliasTable } = getTableAlias({
|
|
adapter,
|
|
tableName: joinCollectionTableName
|
|
});
|
|
const { orderBy, selectFields, where: subQueryWhere } = buildQuery({
|
|
adapter,
|
|
aliasTable: newAliasTable,
|
|
fields,
|
|
joins,
|
|
locale,
|
|
parentIsLocalized,
|
|
selectLocale: true,
|
|
sort: useDrafts ? getQueryDraftsSort({
|
|
collectionConfig: adapter.payload.collections[field.collection].config,
|
|
sort
|
|
}) : sort,
|
|
tableName: joinCollectionTableName,
|
|
where: joinQueryWhere
|
|
});
|
|
for(let key in selectFields){
|
|
const val = selectFields[key];
|
|
if (val.table && getNameFromDrizzleTable(val.table) === joinCollectionTableName) {
|
|
delete selectFields[key];
|
|
key = key.split('.').pop();
|
|
selectFields[key] = newAliasTable[key];
|
|
}
|
|
}
|
|
if (useDrafts) {
|
|
selectFields.parent = newAliasTable.parent;
|
|
}
|
|
let query = db.select(selectFields).from(newAliasTable).where(subQueryWhere).orderBy(()=>orderBy.map(({ column, order })=>order(column))).$dynamic();
|
|
joins.forEach(({ type, condition, table })=>{
|
|
query = query[type ?? 'leftJoin'](table, condition);
|
|
});
|
|
if (page && limit !== 0) {
|
|
const offset = (page - 1) * limit - 1;
|
|
if (offset > 0) {
|
|
query = query.offset(offset);
|
|
}
|
|
}
|
|
if (limit !== 0) {
|
|
query = query.limit(limit);
|
|
}
|
|
const subQuery = query.as(subQueryAlias);
|
|
if (shouldCount) {
|
|
let countSubquery = db.select(selectFields).from(newAliasTable).where(subQueryWhere).$dynamic();
|
|
joins.forEach(({ type, condition, table })=>{
|
|
countSubquery = countSubquery[type ?? 'leftJoin'](table, condition);
|
|
});
|
|
currentArgs.extras[`${columnName}_count`] = sql`${db.select({
|
|
count: count()
|
|
}).from(sql`${countSubquery.as(`${subQueryAlias}_count_subquery`)}`)}`.as(`${subQueryAlias}_count`);
|
|
}
|
|
currentArgs.extras[columnName] = sql`${db.select({
|
|
result: jsonAggBuildObject(adapter, {
|
|
id: sql.raw(`"${subQueryAlias}".${useDrafts ? 'parent_id' : 'id'}`),
|
|
...selectFields._locale && {
|
|
locale: sql.raw(`"${subQueryAlias}".${selectFields._locale.name}`)
|
|
}
|
|
})
|
|
}).from(sql`${subQuery}`)}`.as(subQueryAlias);
|
|
}
|
|
break;
|
|
}
|
|
case 'point':
|
|
{
|
|
if (adapter.name === 'sqlite') {
|
|
break;
|
|
}
|
|
const args = isFieldLocalized ? _locales : currentArgs;
|
|
if (!args.columns) {
|
|
args.columns = {};
|
|
}
|
|
if (!args.extras) {
|
|
args.extras = {};
|
|
}
|
|
const name = `${path}${field.name}`;
|
|
// Drizzle handles that poorly. See https://github.com/drizzle-team/drizzle-orm/issues/2526
|
|
// Additionally, this way we format the column value straight in the database using ST_AsGeoJSON
|
|
args.columns[name] = false;
|
|
let shouldSelect = false;
|
|
if (select || selectAllOnCurrentLevel) {
|
|
if (selectAllOnCurrentLevel || selectMode === 'include' && Boolean(select[field.name]) || selectMode === 'exclude' && typeof select[field.name] === 'undefined') {
|
|
shouldSelect = true;
|
|
}
|
|
} else {
|
|
shouldSelect = true;
|
|
}
|
|
const tableName = fieldShouldBeLocalized({
|
|
field,
|
|
parentIsLocalized
|
|
}) ? `${currentTableName}${adapter.localesSuffix}` : currentTableName;
|
|
if (shouldSelect) {
|
|
args.extras[name] = sql.raw(`ST_AsGeoJSON("${adapter.tables[tableName][name].name}")::jsonb`).as(name);
|
|
}
|
|
break;
|
|
}
|
|
case 'select':
|
|
{
|
|
if (select && !selectAllOnCurrentLevel) {
|
|
if (selectMode === 'include' && !select[field.name] || selectMode === 'exclude' && select[field.name] === false) {
|
|
break;
|
|
}
|
|
}
|
|
if (field.hasMany) {
|
|
const withSelect = {
|
|
columns: {
|
|
id: false,
|
|
order: false,
|
|
parent: false
|
|
},
|
|
orderBy: ({ order }, { asc })=>[
|
|
asc(order)
|
|
]
|
|
};
|
|
currentArgs.with[`${path}${field.name}`] = withSelect;
|
|
break;
|
|
}
|
|
if (select || selectAllOnCurrentLevel) {
|
|
const fieldPath = `${path}${field.name}`;
|
|
if ((isFieldLocalized || parentIsLocalized) && _locales) {
|
|
_locales.columns[fieldPath] = true;
|
|
} else if (adapter.tables[currentTableName]?.[fieldPath]) {
|
|
currentArgs.columns[fieldPath] = true;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
{
|
|
if (forceWithFields) {
|
|
if ((field.type === 'relationship' || field.type === 'upload') && (field.hasMany || Array.isArray(field.relationTo))) {
|
|
withTabledFields.rels = true;
|
|
}
|
|
if (field.type === 'number' && field.hasMany) {
|
|
withTabledFields.numbers = true;
|
|
}
|
|
if (field.type === 'text' && field.hasMany) {
|
|
withTabledFields.texts = true;
|
|
}
|
|
}
|
|
if (!select && !selectAllOnCurrentLevel) {
|
|
break;
|
|
}
|
|
if (selectAllOnCurrentLevel || selectMode === 'include' && Boolean(select[field.name]) || selectMode === 'exclude' && typeof select[field.name] === 'undefined') {
|
|
const fieldPath = `${path}${field.name}`;
|
|
if ((isFieldLocalized || parentIsLocalized) && _locales) {
|
|
_locales.columns[fieldPath] = true;
|
|
} else if (adapter.tables[currentTableName]?.[fieldPath]) {
|
|
currentArgs.columns[fieldPath] = true;
|
|
}
|
|
if (!withTabledFields.rels && (field.type === 'relationship' || field.type === 'upload') && (field.hasMany || Array.isArray(field.relationTo))) {
|
|
withTabledFields.rels = true;
|
|
}
|
|
if (!withTabledFields.numbers && field.type === 'number' && field.hasMany) {
|
|
withTabledFields.numbers = true;
|
|
}
|
|
if (!withTabledFields.texts && field.type === 'text' && field.hasMany) {
|
|
withTabledFields.texts = true;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
});
|
|
return topLevelArgs;
|
|
};
|
|
|
|
//# sourceMappingURL=traverseFields.js.map |