@payloadcms/drizzle 4.0.0-internal.314c594 → 4.0.0-internal.31ba7ee

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.
Files changed (98) hide show
  1. package/dist/find/buildPolymorphicJoinQuery.d.ts +38 -0
  2. package/dist/find/buildPolymorphicJoinQuery.d.ts.map +1 -0
  3. package/dist/find/buildPolymorphicJoinQuery.js +135 -0
  4. package/dist/find/buildPolymorphicJoinQuery.js.map +1 -0
  5. package/dist/find/buildPolymorphicJoinWhere.d.ts +20 -0
  6. package/dist/find/buildPolymorphicJoinWhere.d.ts.map +1 -0
  7. package/dist/find/buildPolymorphicJoinWhere.js +301 -0
  8. package/dist/find/buildPolymorphicJoinWhere.js.map +1 -0
  9. package/dist/find/createPolymorphicJoinWherePlan.d.ts +37 -0
  10. package/dist/find/createPolymorphicJoinWherePlan.d.ts.map +1 -0
  11. package/dist/find/createPolymorphicJoinWherePlan.js +191 -0
  12. package/dist/find/createPolymorphicJoinWherePlan.js.map +1 -0
  13. package/dist/find/traverseFields.d.ts.map +1 -1
  14. package/dist/find/traverseFields.js +19 -191
  15. package/dist/find/traverseFields.js.map +1 -1
  16. package/dist/migrate.d.ts.map +1 -1
  17. package/dist/migrate.js +41 -15
  18. package/dist/migrate.js.map +1 -1
  19. package/dist/migrateDown.d.ts +2 -1
  20. package/dist/migrateDown.d.ts.map +1 -1
  21. package/dist/migrateDown.js +17 -4
  22. package/dist/migrateDown.js.map +1 -1
  23. package/dist/migrateFresh.d.ts +4 -2
  24. package/dist/migrateFresh.d.ts.map +1 -1
  25. package/dist/migrateFresh.js +26 -9
  26. package/dist/migrateFresh.js.map +1 -1
  27. package/dist/migrateRefresh.d.ts +2 -1
  28. package/dist/migrateRefresh.d.ts.map +1 -1
  29. package/dist/migrateRefresh.js +20 -5
  30. package/dist/migrateRefresh.js.map +1 -1
  31. package/dist/migrateReset.d.ts +2 -1
  32. package/dist/migrateReset.d.ts.map +1 -1
  33. package/dist/migrateReset.js +18 -4
  34. package/dist/migrateReset.js.map +1 -1
  35. package/dist/migrateStatus.d.ts +2 -1
  36. package/dist/migrateStatus.d.ts.map +1 -1
  37. package/dist/migrateStatus.js +11 -6
  38. package/dist/migrateStatus.js.map +1 -1
  39. package/dist/postgres/createJSONQuery/index.js +3 -3
  40. package/dist/postgres/createJSONQuery/index.js.map +1 -1
  41. package/dist/postgres/predefinedMigrations/v2-v3/fetchAndResave/index.d.ts.map +1 -1
  42. package/dist/postgres/predefinedMigrations/v2-v3/fetchAndResave/index.js +8 -4
  43. package/dist/postgres/predefinedMigrations/v2-v3/fetchAndResave/index.js.map +1 -1
  44. package/dist/postgres/predefinedMigrations/v2-v3/index.js +1 -1
  45. package/dist/postgres/predefinedMigrations/v2-v3/index.js.map +1 -1
  46. package/dist/queries/getTableColumnFromPath.d.ts.map +1 -1
  47. package/dist/queries/getTableColumnFromPath.js +9 -0
  48. package/dist/queries/getTableColumnFromPath.js.map +1 -1
  49. package/dist/queries/parseParams.d.ts.map +1 -1
  50. package/dist/queries/parseParams.js +59 -2
  51. package/dist/queries/parseParams.js.map +1 -1
  52. package/dist/sqlite/createJSONQuery/convertPathToJSONTraversal.js +3 -2
  53. package/dist/sqlite/createJSONQuery/convertPathToJSONTraversal.js.map +1 -1
  54. package/dist/sqlite/createJSONQuery/index.d.ts.map +1 -1
  55. package/dist/sqlite/createJSONQuery/index.js +6 -5
  56. package/dist/sqlite/createJSONQuery/index.js.map +1 -1
  57. package/dist/sqlite/insert.d.ts.map +1 -1
  58. package/dist/sqlite/insert.js +4 -1
  59. package/dist/sqlite/insert.js.map +1 -1
  60. package/dist/transform/write/traverseFields.d.ts.map +1 -1
  61. package/dist/transform/write/traverseFields.js +8 -14
  62. package/dist/transform/write/traverseFields.js.map +1 -1
  63. package/dist/updateOne.d.ts.map +1 -1
  64. package/dist/updateOne.js +41 -1
  65. package/dist/updateOne.js.map +1 -1
  66. package/dist/upsertRow/index.d.ts +1 -1
  67. package/dist/upsertRow/index.d.ts.map +1 -1
  68. package/dist/upsertRow/index.js +25 -5
  69. package/dist/upsertRow/index.js.map +1 -1
  70. package/dist/utilities/buildCreateMigration.d.ts.map +1 -1
  71. package/dist/utilities/buildCreateMigration.js +12 -8
  72. package/dist/utilities/buildCreateMigration.js.map +1 -1
  73. package/dist/utilities/createSchemaGenerator.d.ts.map +1 -1
  74. package/dist/utilities/createSchemaGenerator.js +3 -0
  75. package/dist/utilities/createSchemaGenerator.js.map +1 -1
  76. package/dist/utilities/parseJSONPathSegment.d.ts +9 -0
  77. package/dist/utilities/parseJSONPathSegment.d.ts.map +1 -0
  78. package/dist/utilities/parseJSONPathSegment.js +17 -0
  79. package/dist/utilities/parseJSONPathSegment.js.map +1 -0
  80. package/package.json +3 -3
  81. package/dist/postgres/query/assertOperatorHandlerExtensionsInstalled.spec.js +0 -91
  82. package/dist/postgres/query/assertOperatorHandlerExtensionsInstalled.spec.js.map +0 -1
  83. package/dist/postgres/query/postgresUnaccent.spec.js +0 -71
  84. package/dist/postgres/query/postgresUnaccent.spec.js.map +0 -1
  85. package/dist/queries/buildOperatorConstraint.spec.js +0 -348
  86. package/dist/queries/buildOperatorConstraint.spec.js.map +0 -1
  87. package/dist/queries/validateOperatorHandlers.spec.js +0 -142
  88. package/dist/queries/validateOperatorHandlers.spec.js.map +0 -1
  89. package/dist/schema/buildRawSchema.spec.js +0 -290
  90. package/dist/schema/buildRawSchema.spec.js.map +0 -1
  91. package/dist/upsertRow/handleUpsertError.spec.js +0 -42
  92. package/dist/upsertRow/handleUpsertError.spec.js.map +0 -1
  93. package/dist/utilities/checkTruncatedIdentifiers.spec.js +0 -301
  94. package/dist/utilities/checkTruncatedIdentifiers.spec.js.map +0 -1
  95. package/dist/utilities/isValidStringID.spec.js +0 -15
  96. package/dist/utilities/isValidStringID.spec.js.map +0 -1
  97. package/dist/utilities/validateIdentifierLength.spec.js +0 -19
  98. package/dist/utilities/validateIdentifierLength.spec.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/queries/parseParams.ts"],"sourcesContent":["import type { SQL, Table } from 'drizzle-orm'\nimport type { FlattenedField, HasManyRelationshipOperator, Operator, Sort, Where } from 'payload'\n\nimport {\n aliasedTable,\n and,\n eq,\n exists,\n getTableName,\n isNotNull,\n isNull,\n like,\n notExists,\n notInArray,\n or,\n sql,\n} from 'drizzle-orm'\nimport { PgUUID } from 'drizzle-orm/pg-core'\nimport { APIError, QueryError } from 'payload'\nimport {\n hasManyRelationshipOperatorSet,\n isNestedRelationshipQuery,\n validOperatorSet,\n} from 'payload/shared'\nimport toSnakeCase from 'to-snake-case'\n\nimport type { DrizzleAdapter, GenericColumn } from '../types.js'\nimport type { BuildQueryJoinAliases } from './buildQuery.js'\nimport type { DrizzleResolvedOperator } from './operatorMap.js'\n\nimport { escapeSQLValue } from '../utilities/escapeSQLValue.js'\nimport { getNameFromDrizzleTable } from '../utilities/getNameFromDrizzleTable.js'\nimport { isValidStringID } from '../utilities/isValidStringID.js'\nimport { DistinctSymbol, isRawConstraint } from '../utilities/rawConstraint.js'\nimport { buildAndOrConditions } from './buildAndOrConditions.js'\nimport { buildOperatorConstraint } from './buildOperatorConstraint.js'\nimport { getTableAlias } from './getTableAlias.js'\nimport { getTableColumnFromPath } from './getTableColumnFromPath.js'\nimport { resolveRelationshipPath } from './resolveRelationshipPath.js'\nimport { sanitizeQueryValue } from './sanitizeQueryValue.js'\n\nexport type QueryContext = { rawSort?: SQL; sort: Sort }\n\ntype Args = {\n adapter: DrizzleAdapter\n aliasTable?: Table\n context: QueryContext\n fields: FlattenedField[]\n joins: BuildQueryJoinAliases\n locale?: string\n parentIsLocalized: boolean\n selectFields: Record<string, GenericColumn>\n selectLocale?: boolean\n tableName: string\n where: Where\n}\n\nexport function parseParams({\n adapter,\n aliasTable,\n context,\n fields,\n joins,\n locale,\n parentIsLocalized,\n selectFields,\n selectLocale,\n tableName,\n where,\n}: Args): SQL {\n let result: SQL\n const constraints: SQL[] = []\n\n if (typeof where === 'object' && Object.keys(where).length > 0) {\n // We need to determine if the whereKey is an AND, OR, or a schema path\n for (const relationOrPath of Object.keys(where)) {\n if (relationOrPath) {\n const condition = where[relationOrPath]\n let conditionOperator: typeof and | typeof or\n if (relationOrPath.toLowerCase() === 'and') {\n conditionOperator = and\n } else if (relationOrPath.toLowerCase() === 'or') {\n conditionOperator = or\n }\n if (Array.isArray(condition)) {\n const builtConditions = buildAndOrConditions({\n adapter,\n aliasTable,\n context,\n fields,\n joins,\n locale,\n parentIsLocalized,\n selectFields,\n selectLocale,\n tableName,\n where: condition,\n })\n if (builtConditions.length > 0) {\n result = conditionOperator(...builtConditions)\n }\n } else {\n // It's a path - and there can be multiple comparisons on a single path.\n // For example - title like 'test' and title not equal to 'tester'\n // So we need to loop on keys again here to handle each operator independently\n const pathOperators = where[relationOrPath]\n if (typeof pathOperators === 'object') {\n for (let operator of Object.keys(pathOperators)) {\n if (validOperatorSet.has(operator as Operator)) {\n const val = where[relationOrPath][operator]\n const originalOperator = operator as Operator\n\n if (\n hasManyRelationshipOperatorSet.has(operator as HasManyRelationshipOperator) &&\n isNestedRelationshipQuery(val) &&\n !isRawConstraint(val)\n ) {\n const relationshipPath = resolveRelationshipPath({\n adapter,\n fields,\n locale,\n parentIsLocalized,\n path: relationOrPath.replace(/__/g, '.'),\n })\n\n if (\n relationshipPath?.field.hasMany &&\n typeof relationshipPath.field.relationTo === 'string'\n ) {\n constraints.push(\n buildHasManyRelationshipCondition({\n adapter,\n aliasTable,\n fields,\n locale,\n operator: operator as HasManyRelationshipOperator,\n parentIsLocalized,\n relationOrPath,\n tableName,\n where: val,\n }),\n )\n continue\n }\n }\n\n const {\n columnName,\n columns,\n constraints: queryConstraints,\n field,\n getNotNullColumnByValue,\n pathSegments,\n rawColumn,\n table,\n } = getTableColumnFromPath({\n adapter,\n aliasTable,\n collectionPath: relationOrPath,\n fields,\n joins,\n locale,\n parentIsLocalized,\n pathSegments: relationOrPath.replace(/__/g, '.').split('.'),\n selectFields,\n selectLocale,\n tableName,\n value: val,\n })\n\n const resolvedColumn =\n rawColumn ||\n (aliasTable && tableName === getNameFromDrizzleTable(table)\n ? aliasTable[columnName]\n : table[columnName])\n\n if (val === DistinctSymbol) {\n selectFields['_selected'] = resolvedColumn\n break\n }\n\n queryConstraints.forEach(({ columnName: col, table: constraintTable, value }) => {\n if (typeof value === 'string' && value.indexOf('%') > -1) {\n constraints.push(adapter.operators.like(constraintTable[col], value))\n } else {\n constraints.push(adapter.operators.equals(constraintTable[col], value))\n }\n })\n\n if (\n (['json', 'richText'].includes(field.type) ||\n (field.type === 'blocks' && adapter.blocksAsJSON)) &&\n Array.isArray(pathSegments) &&\n pathSegments.length > 1\n ) {\n if (adapter.name === 'postgres') {\n const constraint = adapter.createJSONQuery({\n column: rawColumn || table[columnName],\n operator,\n pathSegments,\n value: val,\n })\n\n constraints.push(sql.raw(constraint))\n break\n }\n\n const segments = pathSegments.slice(1)\n segments.unshift(table[columnName].name)\n\n if (field.type === 'richText') {\n // use the table name from the nearest join to handle blocks, arrays, etc. or use the tableName arg\n const jsonTable =\n joins.length === 0\n ? tableName\n : joins[joins.length - 1].table[\n Object.getOwnPropertySymbols(joins[joins.length - 1].table)[0]\n ]\n const jsonQuery = adapter.createJSONQuery({\n operator,\n pathSegments: segments,\n table: jsonTable,\n treatAsArray: ['children'],\n treatRootAsArray: true,\n value: val,\n })\n\n constraints.push(sql.raw(jsonQuery))\n break\n }\n\n const jsonQuery = adapter.convertPathToJSONTraversal(pathSegments)\n const operatorKeys: Record<string, { operator: string; wildcard: string }> = {\n contains: { operator: 'like', wildcard: '%' },\n equals: { operator: '=', wildcard: '' },\n exists: { operator: val === true ? 'is not null' : 'is null', wildcard: '' },\n in: { operator: 'in', wildcard: '' },\n like: { operator: 'like', wildcard: '%' },\n not_equals: { operator: '<>', wildcard: '' },\n not_in: { operator: 'not in', wildcard: '' },\n not_like: { operator: 'not like', wildcard: '%' },\n }\n\n let formattedValue = val\n if (\n adapter.name === 'sqlite' &&\n operator === 'equals' &&\n (typeof val === 'number' || typeof val === 'boolean')\n ) {\n formattedValue = val\n } else if (['in', 'not_in'].includes(operator) && Array.isArray(val)) {\n formattedValue = `(${val.map((v) => `${escapeSQLValue(v)}`).join(',')})`\n } else {\n formattedValue = `'${operatorKeys[operator].wildcard}${escapeSQLValue(val)}${operatorKeys[operator].wildcard}'`\n }\n if (operator === 'exists') {\n formattedValue = ''\n }\n\n let jsonQuerySelector = `${table[columnName].name}${jsonQuery}`\n\n if (adapter.name === 'sqlite' && operator === 'not_like') {\n jsonQuerySelector = `COALESCE(${table[columnName].name}${jsonQuery}, '')`\n }\n\n const rawSQLQuery = `${jsonQuerySelector} ${operatorKeys[operator].operator} ${formattedValue}`\n\n constraints.push(sql.raw(rawSQLQuery))\n\n break\n }\n\n if (getNotNullColumnByValue) {\n const columnName = getNotNullColumnByValue(val)\n if (columnName) {\n constraints.push(isNotNull(table[columnName]))\n } else {\n throw new QueryError([{ path: relationOrPath }])\n }\n break\n }\n\n if (\n operator === 'like' &&\n (field.type === 'number' ||\n field.type === 'relationship' ||\n field.type === 'upload' ||\n table[columnName].columnType === 'PgUUID')\n ) {\n operator = 'equals'\n }\n\n if (operator === 'like') {\n constraints.push(\n and(\n ...val.split(' ').map((word) =>\n buildOperatorConstraint({\n adapter,\n column: table[columnName],\n field,\n locale,\n originalOperator,\n path: relationOrPath,\n resolvedOperator: 'like',\n value: `%${word}%`,\n }),\n ),\n ),\n )\n break\n }\n\n const sanitizedQueryValue = sanitizeQueryValue({\n adapter,\n columns,\n field,\n isUUID: table?.[columnName] instanceof PgUUID,\n operator,\n relationOrPath,\n val,\n })\n\n if (sanitizedQueryValue === null) {\n break\n }\n\n const {\n columns: queryColumns,\n operator: queryOperator,\n value: queryValue,\n } = sanitizedQueryValue\n\n // Handle polymorphic relationships by value\n if (queryColumns) {\n if (!queryColumns.length) {\n break\n }\n\n let wrapOperator = or\n\n if (queryValue === null && ['equals', 'not_equals'].includes(operator)) {\n if (operator === 'equals') {\n wrapOperator = and\n }\n\n constraints.push(\n wrapOperator(\n ...queryColumns.map(({ rawColumn }) =>\n operator === 'equals' ? isNull(rawColumn) : isNotNull(rawColumn),\n ),\n ),\n )\n break\n }\n\n if (['not_equals', 'not_in'].includes(operator)) {\n wrapOperator = and\n }\n\n constraints.push(\n wrapOperator(\n ...queryColumns.map(({ rawColumn, value }) =>\n buildOperatorConstraint({\n adapter,\n column: rawColumn,\n field,\n locale,\n originalOperator,\n path: relationOrPath,\n resolvedOperator: queryOperator as DrizzleResolvedOperator,\n value,\n }),\n ),\n ),\n )\n\n break\n }\n\n if (queryOperator === 'not_equals' && queryValue !== null) {\n constraints.push(\n or(\n isNull(resolvedColumn),\n buildOperatorConstraint({\n adapter,\n column: resolvedColumn,\n field,\n locale,\n originalOperator,\n path: relationOrPath,\n resolvedOperator: 'not_equals',\n value: queryValue,\n }),\n ),\n )\n break\n }\n\n if (\n (field.type === 'relationship' || field.type === 'upload') &&\n Array.isArray(queryValue) &&\n queryOperator === 'not_in'\n ) {\n constraints.push(\n sql`(${notInArray(table[columnName], queryValue)} OR\n ${table[columnName]}\n IS\n NULL)`,\n )\n\n break\n }\n\n if (operator === 'equals' && queryValue === null) {\n constraints.push(isNull(resolvedColumn))\n break\n }\n\n if (operator === 'not_equals' && queryValue === null) {\n constraints.push(isNotNull(resolvedColumn))\n break\n }\n\n if (field.type === 'point' && adapter.name === 'postgres') {\n switch (operator) {\n case 'intersects': {\n constraints.push(\n sql`ST_Intersects(${table[columnName]}, ST_GeomFromGeoJSON(${JSON.stringify(queryValue)}))`,\n )\n break\n }\n\n case 'near': {\n const [lng, lat, maxDistance, minDistance] = queryValue as number[]\n const geoConstraints: SQL[] = []\n\n if (typeof maxDistance === 'number' && !Number.isNaN(maxDistance)) {\n geoConstraints.push(\n sql`ST_DWithin(${table[columnName]}::geography, ST_SetSRID(ST_MakePoint(${lng}, ${lat}), 4326)::geography, ${maxDistance})`,\n )\n }\n\n if (typeof minDistance === 'number' && !Number.isNaN(minDistance)) {\n geoConstraints.push(\n sql`ST_Distance(${table[columnName]}::geography, ST_SetSRID(ST_MakePoint(${lng}, ${lat}), 4326)::geography) >= ${minDistance}`,\n )\n }\n if (geoConstraints.length) {\n context.sort = relationOrPath\n context.rawSort = sql`${table[columnName]} <-> ST_SetSRID(ST_MakePoint(${lng}, ${lat}), 4326)`\n constraints.push(and(...geoConstraints))\n }\n break\n }\n\n case 'within': {\n constraints.push(\n sql`ST_Within(${table[columnName]}, ST_GeomFromGeoJSON(${JSON.stringify(queryValue)}))`,\n )\n break\n }\n\n default:\n break\n }\n break\n }\n\n const orConditions: SQL<unknown>[] = []\n let resolvedQueryValue = queryValue\n if (\n operator === 'in' &&\n Array.isArray(queryValue) &&\n queryValue.some((v) => v === null)\n ) {\n orConditions.push(isNull(resolvedColumn))\n resolvedQueryValue = queryValue.filter((v) => v !== null)\n }\n\n if (\n operator === 'contains' &&\n Array.isArray(queryValue) &&\n 'hasMany' in field &&\n field.hasMany &&\n ['number', 'select', 'text'].includes(field.type)\n ) {\n // Create OR conditions for each value in the array\n orConditions.push(\n ...queryValue.map((val) =>\n buildOperatorConstraint({\n adapter,\n column: resolvedColumn,\n field,\n locale,\n originalOperator,\n path: relationOrPath,\n resolvedOperator: queryOperator as DrizzleResolvedOperator,\n value: val,\n }),\n ),\n )\n // Set constraint to combine all OR conditions\n const constraint = orConditions.length > 0 ? or(...orConditions) : undefined\n if (constraint) {\n constraints.push(constraint)\n }\n break\n }\n\n let constraint = buildOperatorConstraint({\n adapter,\n column: resolvedColumn,\n field,\n locale,\n originalOperator,\n path: relationOrPath,\n resolvedOperator: queryOperator as DrizzleResolvedOperator,\n value: resolvedQueryValue,\n })\n\n if (\n adapter.limitedBoundParameters &&\n (operator === 'in' || operator === 'not_in') &&\n relationOrPath === 'id' &&\n Array.isArray(queryValue)\n ) {\n let isInvalid = false\n for (const val of queryValue) {\n if (typeof val === 'number' || val === null) {\n continue\n }\n if (typeof val === 'string') {\n if (!isValidStringID(val)) {\n isInvalid = true\n break\n } else {\n continue\n }\n }\n isInvalid = true\n break\n }\n\n if (isInvalid) {\n throw new APIError(`Invalid ID value in ${JSON.stringify(queryValue)}`)\n }\n\n constraints.push(\n sql.raw(\n `\"${getTableName(resolvedColumn.table)}\".\"${resolvedColumn.name}\" ${operator === 'in' ? 'IN' : 'NOT IN'} (${queryValue\n .map((e) => {\n if (e === null) {\n return `NULL`\n }\n\n if (typeof e === 'number') {\n return e\n }\n\n return `'${e}'`\n })\n .join(',')})`,\n ),\n )\n break\n }\n\n if (orConditions.length) {\n orConditions.push(constraint)\n constraint = or(...orConditions)\n }\n constraints.push(constraint)\n }\n }\n }\n }\n }\n }\n }\n if (constraints.length > 0) {\n if (result) {\n result = and(result, ...constraints)\n } else {\n result = and(...constraints)\n }\n }\n if (constraints.length === 1 && !result) {\n ;[result] = constraints\n }\n\n return result\n}\n\n/**\n * Builds a SQL condition for an operator containing a nested has-many relationship query.\n *\n * `contains`: at least one related document matches.\n * `not_equals`: no related documents match.\n * `equals`: all related documents match; an empty relationship also matches.\n *\n * A normal dotted relationship query adds joins to the parent query. That cannot implement\n * the negative cases, because they must inspect all relationship rows before deciding whether to\n * include the parent. A correlated `EXISTS` subquery keeps that decision scoped to one parent.\n *\n * @example\n * ```ts\n * // Find burgers with no unhealthy ingredients.\n * const where = {\n * ingredients: {\n * not_equals: {\n * isHealthy: { equals: false },\n * },\n * },\n * }\n * ```\n */\nfunction buildHasManyRelationshipCondition({\n adapter,\n aliasTable,\n fields,\n locale,\n operator,\n parentIsLocalized,\n relationOrPath,\n tableName,\n where,\n}: {\n adapter: DrizzleAdapter\n aliasTable?: Table\n fields: FlattenedField[]\n locale?: string\n operator: HasManyRelationshipOperator\n parentIsLocalized: boolean\n relationOrPath: string\n tableName: string\n where: Where\n}): SQL {\n const relationshipFieldPath = relationOrPath.replace(/__/g, '.')\n\n if (!where || typeof where !== 'object' || Array.isArray(where)) {\n throw new QueryError([{ path: `${relationshipFieldPath}.${operator}` }])\n }\n\n const relationshipPath = resolveRelationshipPath({\n adapter,\n fields,\n locale,\n parentIsLocalized,\n path: relationshipFieldPath,\n })\n\n if (!relationshipPath) {\n throw new QueryError([{ path: `${relationshipFieldPath}.${operator}` }])\n }\n\n const relationshipField = relationshipPath.field\n\n if (!relationshipField.hasMany || typeof relationshipField.relationTo !== 'string') {\n throw new QueryError([{ path: `${relationshipFieldPath}.${operator}` }])\n }\n\n // Every related document matches an empty query, including when there are no related documents.\n if (operator === 'equals' && Object.keys(where).length === 0) {\n return sql`true`\n }\n\n const relationshipTableName = `${tableName}${adapter.relationshipsSuffix}`\n const relatedCollection = adapter.payload.collections[relationshipField.relationTo]\n const relatedTableName = adapter.tableNameMap.get(toSnakeCase(relatedCollection.config.slug))\n const relationshipLocale = relationshipPath.locale\n const { newAliasTable: relationshipTable } = getTableAlias({\n adapter,\n tableName: relationshipTableName,\n })\n const { newAliasTable: relatedTable } = getTableAlias({\n adapter,\n tableName: relatedTableName,\n })\n\n // Parse the nested `where` exactly like a normal query, but start from the related collection\n // and keep its joins inside the subquery.\n const nestedJoins: BuildQueryJoinAliases = []\n const relatedDocumentWhere =\n Object.keys(where).length > 0\n ? parseParams({\n adapter,\n aliasTable: relatedTable,\n context: { sort: undefined },\n fields: relatedCollection.config.flattenedFields,\n joins: nestedJoins,\n locale: relationshipLocale,\n parentIsLocalized: false,\n selectFields: {},\n tableName: relatedTableName,\n where,\n })\n : undefined\n\n // Correlate relationship rows back to the parent document currently being considered by the\n // outer query. The stored path distinguishes this field from other relationships on the parent.\n const outerTable = aliasTable ?? aliasedTable(adapter.tables[tableName], tableName)\n const relationshipRowConstraints: SQL[] = [\n eq(relationshipTable.parent, outerTable.id),\n relationshipPath.path.includes('%')\n ? like(relationshipTable.path, relationshipPath.path)\n : eq(relationshipTable.path, relationshipPath.path),\n ]\n\n if (relationshipLocale && relationshipLocale !== 'all' && relationshipPath.isLocalized) {\n relationshipRowConstraints.push(eq(relationshipTable.locale, relationshipLocale))\n }\n\n const relatedDocumentConstraints = [\n eq(relatedTable.id, relationshipTable[`${relationshipField.relationTo}ID`]),\n ]\n\n if (relatedDocumentWhere) {\n relatedDocumentConstraints.push(relatedDocumentWhere)\n }\n\n let relatedDocumentSubquery = (adapter.drizzle as any)\n .select({ id: relatedTable.id })\n .from(relatedTable)\n .$dynamic()\n\n for (const join of nestedJoins) {\n relatedDocumentSubquery = relatedDocumentSubquery[join.type ?? 'leftJoin'](\n join.table,\n join.condition,\n )\n }\n\n relatedDocumentSubquery = relatedDocumentSubquery.where(and(...relatedDocumentConstraints))\n\n const buildRelationshipRowsSubquery = (relatedDocumentCheck: SQL) =>\n (adapter.drizzle as any)\n .select({ id: relationshipTable.parent })\n .from(relationshipTable)\n .where(and(...relationshipRowConstraints, relatedDocumentCheck))\n\n switch (operator) {\n case 'contains':\n return exists(buildRelationshipRowsSubquery(exists(relatedDocumentSubquery)))\n\n case 'equals':\n // All related documents match when no relationship row points to one that fails.\n return notExists(buildRelationshipRowsSubquery(notExists(relatedDocumentSubquery)))\n\n case 'not_equals':\n return notExists(buildRelationshipRowsSubquery(exists(relatedDocumentSubquery)))\n }\n}\n"],"names":["aliasedTable","and","eq","exists","getTableName","isNotNull","isNull","like","notExists","notInArray","or","sql","PgUUID","APIError","QueryError","hasManyRelationshipOperatorSet","isNestedRelationshipQuery","validOperatorSet","toSnakeCase","escapeSQLValue","getNameFromDrizzleTable","isValidStringID","DistinctSymbol","isRawConstraint","buildAndOrConditions","buildOperatorConstraint","getTableAlias","getTableColumnFromPath","resolveRelationshipPath","sanitizeQueryValue","parseParams","adapter","aliasTable","context","fields","joins","locale","parentIsLocalized","selectFields","selectLocale","tableName","where","result","constraints","Object","keys","length","relationOrPath","condition","conditionOperator","toLowerCase","Array","isArray","builtConditions","pathOperators","operator","has","val","originalOperator","relationshipPath","path","replace","field","hasMany","relationTo","push","buildHasManyRelationshipCondition","columnName","columns","queryConstraints","getNotNullColumnByValue","pathSegments","rawColumn","table","collectionPath","split","value","resolvedColumn","forEach","col","constraintTable","indexOf","operators","equals","includes","type","blocksAsJSON","name","constraint","createJSONQuery","column","raw","segments","slice","unshift","jsonTable","getOwnPropertySymbols","jsonQuery","treatAsArray","treatRootAsArray","convertPathToJSONTraversal","operatorKeys","contains","wildcard","in","not_equals","not_in","not_like","formattedValue","map","v","join","jsonQuerySelector","rawSQLQuery","columnType","word","resolvedOperator","sanitizedQueryValue","isUUID","queryColumns","queryOperator","queryValue","wrapOperator","JSON","stringify","lng","lat","maxDistance","minDistance","geoConstraints","Number","isNaN","sort","rawSort","orConditions","resolvedQueryValue","some","filter","undefined","limitedBoundParameters","isInvalid","e","relationshipFieldPath","relationshipField","relationshipTableName","relationshipsSuffix","relatedCollection","payload","collections","relatedTableName","tableNameMap","get","config","slug","relationshipLocale","newAliasTable","relationshipTable","relatedTable","nestedJoins","relatedDocumentWhere","flattenedFields","outerTable","tables","relationshipRowConstraints","parent","id","isLocalized","relatedDocumentConstraints","relatedDocumentSubquery","drizzle","select","from","$dynamic","buildRelationshipRowsSubquery","relatedDocumentCheck"],"mappings":"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"}
1
+ {"version":3,"sources":["../../src/queries/parseParams.ts"],"sourcesContent":["import type { SQL, Table } from 'drizzle-orm'\nimport type { FlattenedField, HasManyRelationshipOperator, Operator, Sort, Where } from 'payload'\n\nimport {\n aliasedTable,\n and,\n eq,\n exists,\n getTableName,\n isNotNull,\n isNull,\n like,\n notExists,\n notInArray,\n or,\n sql,\n} from 'drizzle-orm'\nimport { PgUUID } from 'drizzle-orm/pg-core'\nimport { APIError, getFieldByPath, QueryError } from 'payload'\nimport {\n hasManyRelationshipOperatorSet,\n isNestedRelationshipQuery,\n validOperatorSet,\n} from 'payload/shared'\nimport toSnakeCase from 'to-snake-case'\n\nimport type { DrizzleAdapter, GenericColumn } from '../types.js'\nimport type { BuildQueryJoinAliases } from './buildQuery.js'\nimport type { DrizzleResolvedOperator } from './operatorMap.js'\n\nimport { escapeSQLValue } from '../utilities/escapeSQLValue.js'\nimport { getNameFromDrizzleTable } from '../utilities/getNameFromDrizzleTable.js'\nimport { isValidStringID } from '../utilities/isValidStringID.js'\nimport { DistinctSymbol, isRawConstraint } from '../utilities/rawConstraint.js'\nimport { buildAndOrConditions } from './buildAndOrConditions.js'\nimport { buildOperatorConstraint } from './buildOperatorConstraint.js'\nimport { getTableAlias } from './getTableAlias.js'\nimport { getTableColumnFromPath } from './getTableColumnFromPath.js'\nimport { resolveRelationshipPath } from './resolveRelationshipPath.js'\nimport { sanitizeQueryValue } from './sanitizeQueryValue.js'\n\nexport type QueryContext = { rawSort?: SQL; sort: Sort }\n\ntype Args = {\n adapter: DrizzleAdapter\n aliasTable?: Table\n context: QueryContext\n fields: FlattenedField[]\n joins: BuildQueryJoinAliases\n locale?: string\n parentIsLocalized: boolean\n selectFields: Record<string, GenericColumn>\n selectLocale?: boolean\n tableName: string\n where: Where\n}\n\nexport function parseParams({\n adapter,\n aliasTable,\n context,\n fields,\n joins,\n locale,\n parentIsLocalized,\n selectFields,\n selectLocale,\n tableName,\n where,\n}: Args): SQL {\n let result: SQL\n const constraints: SQL[] = []\n\n if (typeof where === 'object' && Object.keys(where).length > 0) {\n // We need to determine if the whereKey is an AND, OR, or a schema path\n for (const relationOrPath of Object.keys(where)) {\n if (relationOrPath) {\n const condition = where[relationOrPath]\n let conditionOperator: typeof and | typeof or\n if (relationOrPath.toLowerCase() === 'and') {\n conditionOperator = and\n } else if (relationOrPath.toLowerCase() === 'or') {\n conditionOperator = or\n }\n if (Array.isArray(condition)) {\n const builtConditions = buildAndOrConditions({\n adapter,\n aliasTable,\n context,\n fields,\n joins,\n locale,\n parentIsLocalized,\n selectFields,\n selectLocale,\n tableName,\n where: condition,\n })\n if (builtConditions.length > 0) {\n result = conditionOperator(...builtConditions)\n }\n } else {\n // It's a path - and there can be multiple comparisons on a single path.\n // For example - title like 'test' and title not equal to 'tester'\n // So we need to loop on keys again here to handle each operator independently\n const pathOperators = where[relationOrPath]\n if (typeof pathOperators === 'object') {\n for (let operator of Object.keys(pathOperators)) {\n if (validOperatorSet.has(operator as Operator)) {\n const val = where[relationOrPath][operator]\n const originalOperator = operator as Operator\n\n if (\n hasManyRelationshipOperatorSet.has(operator as HasManyRelationshipOperator) &&\n isNestedRelationshipQuery(val) &&\n !isRawConstraint(val)\n ) {\n const relationshipPath = resolveRelationshipPath({\n adapter,\n fields,\n locale,\n parentIsLocalized,\n path: relationOrPath.replace(/__/g, '.'),\n })\n\n if (\n relationshipPath?.field.hasMany &&\n typeof relationshipPath.field.relationTo === 'string'\n ) {\n constraints.push(\n buildHasManyRelationshipCondition({\n adapter,\n aliasTable,\n fields,\n locale,\n operator: operator as HasManyRelationshipOperator,\n parentIsLocalized,\n relationOrPath,\n tableName,\n where: val,\n }),\n )\n continue\n }\n\n // A join points to many related documents. Expanding the nested query into\n // prefixed dot-paths reuses the join's shared table alias, so every condition is\n // evaluated against the same joined row (same-document `contains` semantics).\n if (operator === 'contains' && !relationshipPath) {\n const joinField = getFieldByPath({\n fields,\n path: relationOrPath.replace(/__/g, '.'),\n })?.field\n\n if (joinField?.type === 'join') {\n constraints.push(\n parseParams({\n adapter,\n aliasTable,\n context,\n fields,\n joins,\n locale,\n parentIsLocalized,\n selectFields,\n selectLocale,\n tableName,\n where: prefixJoinContainsWhere({\n prefix: relationOrPath,\n where: val,\n }),\n }),\n )\n continue\n }\n }\n }\n\n const {\n columnName,\n columns,\n constraints: queryConstraints,\n field,\n getNotNullColumnByValue,\n pathSegments,\n rawColumn,\n table,\n } = getTableColumnFromPath({\n adapter,\n aliasTable,\n collectionPath: relationOrPath,\n fields,\n joins,\n locale,\n parentIsLocalized,\n pathSegments: relationOrPath.replace(/__/g, '.').split('.'),\n selectFields,\n selectLocale,\n tableName,\n value: val,\n })\n\n const resolvedColumn =\n rawColumn ||\n (aliasTable && tableName === getNameFromDrizzleTable(table)\n ? aliasTable[columnName]\n : table[columnName])\n\n if (val === DistinctSymbol) {\n selectFields['_selected'] = resolvedColumn\n break\n }\n\n queryConstraints.forEach(({ columnName: col, table: constraintTable, value }) => {\n if (typeof value === 'string' && value.indexOf('%') > -1) {\n constraints.push(adapter.operators.like(constraintTable[col], value))\n } else {\n constraints.push(adapter.operators.equals(constraintTable[col], value))\n }\n })\n\n if (\n (['json', 'richText'].includes(field.type) ||\n (field.type === 'blocks' && adapter.blocksAsJSON)) &&\n Array.isArray(pathSegments) &&\n pathSegments.length > 1\n ) {\n if (adapter.name === 'postgres') {\n const constraint = adapter.createJSONQuery({\n column: rawColumn || table[columnName],\n operator,\n pathSegments,\n value: val,\n })\n\n constraints.push(sql.raw(constraint))\n break\n }\n\n const segments = pathSegments.slice(1)\n segments.unshift(table[columnName].name)\n\n if (field.type === 'richText') {\n // use the table name from the nearest join to handle blocks, arrays, etc. or use the tableName arg\n const jsonTable =\n joins.length === 0\n ? tableName\n : joins[joins.length - 1].table[\n Object.getOwnPropertySymbols(joins[joins.length - 1].table)[0]\n ]\n const jsonQuery = adapter.createJSONQuery({\n operator,\n pathSegments: segments,\n table: jsonTable,\n treatAsArray: ['children'],\n treatRootAsArray: true,\n value: val,\n })\n\n constraints.push(sql.raw(jsonQuery))\n break\n }\n\n const jsonQuery = adapter.convertPathToJSONTraversal(pathSegments)\n const operatorKeys: Record<string, { operator: string; wildcard: string }> = {\n contains: { operator: 'like', wildcard: '%' },\n equals: { operator: '=', wildcard: '' },\n exists: { operator: val === true ? 'is not null' : 'is null', wildcard: '' },\n in: { operator: 'in', wildcard: '' },\n like: { operator: 'like', wildcard: '%' },\n not_equals: { operator: '<>', wildcard: '' },\n not_in: { operator: 'not in', wildcard: '' },\n not_like: { operator: 'not like', wildcard: '%' },\n }\n\n let formattedValue = val\n if (\n adapter.name === 'sqlite' &&\n operator === 'equals' &&\n (typeof val === 'number' || typeof val === 'boolean')\n ) {\n formattedValue = val\n } else if (['in', 'not_in'].includes(operator) && Array.isArray(val)) {\n formattedValue = `(${val\n .map((v) => {\n const escaped = escapeSQLValue(v)\n return typeof v === 'string' ? `'${escaped}'` : String(escaped)\n })\n .join(',')})`\n } else {\n formattedValue = `'${operatorKeys[operator].wildcard}${escapeSQLValue(val)}${operatorKeys[operator].wildcard}'`\n }\n if (operator === 'exists') {\n formattedValue = ''\n }\n\n let jsonQuerySelector = `${table[columnName].name}${jsonQuery}`\n\n if (adapter.name === 'sqlite' && operator === 'not_like') {\n jsonQuerySelector = `COALESCE(${table[columnName].name}${jsonQuery}, '')`\n }\n\n const rawSQLQuery = `${jsonQuerySelector} ${operatorKeys[operator].operator} ${formattedValue}`\n\n constraints.push(sql.raw(rawSQLQuery))\n\n break\n }\n\n if (getNotNullColumnByValue) {\n const columnName = getNotNullColumnByValue(val)\n if (columnName) {\n constraints.push(isNotNull(table[columnName]))\n } else {\n throw new QueryError([{ path: relationOrPath }])\n }\n break\n }\n\n if (\n operator === 'like' &&\n (field.type === 'number' ||\n field.type === 'relationship' ||\n field.type === 'upload' ||\n table[columnName].columnType === 'PgUUID')\n ) {\n operator = 'equals'\n }\n\n if (operator === 'like') {\n constraints.push(\n and(\n ...val.split(' ').map((word) =>\n buildOperatorConstraint({\n adapter,\n column: table[columnName],\n field,\n locale,\n originalOperator,\n path: relationOrPath,\n resolvedOperator: 'like',\n value: `%${word}%`,\n }),\n ),\n ),\n )\n break\n }\n\n const sanitizedQueryValue = sanitizeQueryValue({\n adapter,\n columns,\n field,\n isUUID: table?.[columnName] instanceof PgUUID,\n operator,\n relationOrPath,\n val,\n })\n\n if (sanitizedQueryValue === null) {\n break\n }\n\n const {\n columns: queryColumns,\n operator: queryOperator,\n value: queryValue,\n } = sanitizedQueryValue\n\n // Handle polymorphic relationships by value\n if (queryColumns) {\n if (!queryColumns.length) {\n break\n }\n\n let wrapOperator = or\n\n if (queryValue === null && ['equals', 'not_equals'].includes(operator)) {\n if (operator === 'equals') {\n wrapOperator = and\n }\n\n constraints.push(\n wrapOperator(\n ...queryColumns.map(({ rawColumn }) =>\n operator === 'equals' ? isNull(rawColumn) : isNotNull(rawColumn),\n ),\n ),\n )\n break\n }\n\n if (['not_equals', 'not_in'].includes(operator)) {\n wrapOperator = and\n }\n\n constraints.push(\n wrapOperator(\n ...queryColumns.map(({ rawColumn, value }) =>\n buildOperatorConstraint({\n adapter,\n column: rawColumn,\n field,\n locale,\n originalOperator,\n path: relationOrPath,\n resolvedOperator: queryOperator as DrizzleResolvedOperator,\n value,\n }),\n ),\n ),\n )\n\n break\n }\n\n if (queryOperator === 'not_equals' && queryValue !== null) {\n constraints.push(\n or(\n isNull(resolvedColumn),\n buildOperatorConstraint({\n adapter,\n column: resolvedColumn,\n field,\n locale,\n originalOperator,\n path: relationOrPath,\n resolvedOperator: 'not_equals',\n value: queryValue,\n }),\n ),\n )\n break\n }\n\n if (\n (field.type === 'relationship' || field.type === 'upload') &&\n Array.isArray(queryValue) &&\n queryOperator === 'not_in'\n ) {\n constraints.push(\n sql`(${notInArray(table[columnName], queryValue)} OR\n ${table[columnName]}\n IS\n NULL)`,\n )\n\n break\n }\n\n if (operator === 'equals' && queryValue === null) {\n constraints.push(isNull(resolvedColumn))\n break\n }\n\n if (operator === 'not_equals' && queryValue === null) {\n constraints.push(isNotNull(resolvedColumn))\n break\n }\n\n if (field.type === 'point' && adapter.name === 'postgres') {\n switch (operator) {\n case 'intersects': {\n constraints.push(\n sql`ST_Intersects(${table[columnName]}, ST_GeomFromGeoJSON(${JSON.stringify(queryValue)}))`,\n )\n break\n }\n\n case 'near': {\n const [lng, lat, maxDistance, minDistance] = queryValue as number[]\n const geoConstraints: SQL[] = []\n\n if (typeof maxDistance === 'number' && !Number.isNaN(maxDistance)) {\n geoConstraints.push(\n sql`ST_DWithin(${table[columnName]}::geography, ST_SetSRID(ST_MakePoint(${lng}, ${lat}), 4326)::geography, ${maxDistance})`,\n )\n }\n\n if (typeof minDistance === 'number' && !Number.isNaN(minDistance)) {\n geoConstraints.push(\n sql`ST_Distance(${table[columnName]}::geography, ST_SetSRID(ST_MakePoint(${lng}, ${lat}), 4326)::geography) >= ${minDistance}`,\n )\n }\n if (geoConstraints.length) {\n context.sort = relationOrPath\n context.rawSort = sql`${table[columnName]} <-> ST_SetSRID(ST_MakePoint(${lng}, ${lat}), 4326)`\n constraints.push(and(...geoConstraints))\n }\n break\n }\n\n case 'within': {\n constraints.push(\n sql`ST_Within(${table[columnName]}, ST_GeomFromGeoJSON(${JSON.stringify(queryValue)}))`,\n )\n break\n }\n\n default:\n break\n }\n break\n }\n\n const orConditions: SQL<unknown>[] = []\n let resolvedQueryValue = queryValue\n if (\n operator === 'in' &&\n Array.isArray(queryValue) &&\n queryValue.some((v) => v === null)\n ) {\n orConditions.push(isNull(resolvedColumn))\n resolvedQueryValue = queryValue.filter((v) => v !== null)\n }\n\n if (\n operator === 'contains' &&\n Array.isArray(queryValue) &&\n 'hasMany' in field &&\n field.hasMany &&\n ['number', 'select', 'text'].includes(field.type)\n ) {\n // Create OR conditions for each value in the array\n orConditions.push(\n ...queryValue.map((val) =>\n buildOperatorConstraint({\n adapter,\n column: resolvedColumn,\n field,\n locale,\n originalOperator,\n path: relationOrPath,\n resolvedOperator: queryOperator as DrizzleResolvedOperator,\n value: val,\n }),\n ),\n )\n // Set constraint to combine all OR conditions\n const constraint = orConditions.length > 0 ? or(...orConditions) : undefined\n if (constraint) {\n constraints.push(constraint)\n }\n break\n }\n\n let constraint = buildOperatorConstraint({\n adapter,\n column: resolvedColumn,\n field,\n locale,\n originalOperator,\n path: relationOrPath,\n resolvedOperator: queryOperator as DrizzleResolvedOperator,\n value: resolvedQueryValue,\n })\n\n if (\n adapter.limitedBoundParameters &&\n (operator === 'in' || operator === 'not_in') &&\n relationOrPath === 'id' &&\n Array.isArray(queryValue)\n ) {\n let isInvalid = false\n for (const val of queryValue) {\n if (typeof val === 'number' || val === null) {\n continue\n }\n if (typeof val === 'string') {\n if (!isValidStringID(val)) {\n isInvalid = true\n break\n } else {\n continue\n }\n }\n isInvalid = true\n break\n }\n\n if (isInvalid) {\n throw new APIError(`Invalid ID value in ${JSON.stringify(queryValue)}`)\n }\n\n constraints.push(\n sql.raw(\n `\"${getTableName(resolvedColumn.table)}\".\"${resolvedColumn.name}\" ${operator === 'in' ? 'IN' : 'NOT IN'} (${queryValue\n .map((e) => {\n if (e === null) {\n return `NULL`\n }\n\n if (typeof e === 'number') {\n return e\n }\n\n return `'${e}'`\n })\n .join(',')})`,\n ),\n )\n break\n }\n\n if (orConditions.length) {\n orConditions.push(constraint)\n constraint = or(...orConditions)\n }\n constraints.push(constraint)\n }\n }\n }\n }\n }\n }\n }\n if (constraints.length > 0) {\n if (result) {\n result = and(result, ...constraints)\n } else {\n result = and(...constraints)\n }\n }\n if (constraints.length === 1 && !result) {\n ;[result] = constraints\n }\n\n return result\n}\n\n/**\n * Prefixes every field path in a join's nested `contains` query with the join field's path, so the\n * query can be resolved through the join's shared table alias.\n *\n * @example\n * ```ts\n * prefixJoinContainsWhere({ prefix: 'comments', where: { and: [{ text: { equals: 'hi' } }] } })\n * // => { and: [{ 'comments.text': { equals: 'hi' } }] }\n * ```\n */\nfunction prefixJoinContainsWhere({ prefix, where }: { prefix: string; where: Where }): Where {\n const prefixedWhere: Where = {}\n\n for (const [key, value] of Object.entries(where)) {\n if (['and', 'or'].includes(key.toLowerCase()) && Array.isArray(value)) {\n prefixedWhere[key] = value.map((nestedWhere) =>\n prefixJoinContainsWhere({ prefix, where: nestedWhere }),\n )\n } else {\n prefixedWhere[`${prefix}.${key}`] = value\n }\n }\n\n return prefixedWhere\n}\n\n/**\n * Builds a SQL condition for an operator containing a nested has-many relationship query.\n *\n * `contains`: at least one related document matches.\n * `not_equals`: no related documents match.\n * `equals`: all related documents match; an empty relationship also matches.\n *\n * A normal dotted relationship query adds joins to the parent query. That cannot implement\n * the negative cases, because they must inspect all relationship rows before deciding whether to\n * include the parent. A correlated `EXISTS` subquery keeps that decision scoped to one parent.\n *\n * @example\n * ```ts\n * // Find burgers with no unhealthy ingredients.\n * const where = {\n * ingredients: {\n * not_equals: {\n * isHealthy: { equals: false },\n * },\n * },\n * }\n * ```\n */\nfunction buildHasManyRelationshipCondition({\n adapter,\n aliasTable,\n fields,\n locale,\n operator,\n parentIsLocalized,\n relationOrPath,\n tableName,\n where,\n}: {\n adapter: DrizzleAdapter\n aliasTable?: Table\n fields: FlattenedField[]\n locale?: string\n operator: HasManyRelationshipOperator\n parentIsLocalized: boolean\n relationOrPath: string\n tableName: string\n where: Where\n}): SQL {\n const relationshipFieldPath = relationOrPath.replace(/__/g, '.')\n\n if (!where || typeof where !== 'object' || Array.isArray(where)) {\n throw new QueryError([{ path: `${relationshipFieldPath}.${operator}` }])\n }\n\n const relationshipPath = resolveRelationshipPath({\n adapter,\n fields,\n locale,\n parentIsLocalized,\n path: relationshipFieldPath,\n })\n\n if (!relationshipPath) {\n throw new QueryError([{ path: `${relationshipFieldPath}.${operator}` }])\n }\n\n const relationshipField = relationshipPath.field\n\n if (!relationshipField.hasMany || typeof relationshipField.relationTo !== 'string') {\n throw new QueryError([{ path: `${relationshipFieldPath}.${operator}` }])\n }\n\n // Every related document matches an empty query, including when there are no related documents.\n if (operator === 'equals' && Object.keys(where).length === 0) {\n return sql`true`\n }\n\n const relationshipTableName = `${tableName}${adapter.relationshipsSuffix}`\n const relatedCollection = adapter.payload.collections[relationshipField.relationTo]\n const relatedTableName = adapter.tableNameMap.get(toSnakeCase(relatedCollection.config.slug))\n const relationshipLocale = relationshipPath.locale\n const { newAliasTable: relationshipTable } = getTableAlias({\n adapter,\n tableName: relationshipTableName,\n })\n const { newAliasTable: relatedTable } = getTableAlias({\n adapter,\n tableName: relatedTableName,\n })\n\n // Parse the nested `where` exactly like a normal query, but start from the related collection\n // and keep its joins inside the subquery.\n const nestedJoins: BuildQueryJoinAliases = []\n const relatedDocumentWhere =\n Object.keys(where).length > 0\n ? parseParams({\n adapter,\n aliasTable: relatedTable,\n context: { sort: undefined },\n fields: relatedCollection.config.flattenedFields,\n joins: nestedJoins,\n locale: relationshipLocale,\n parentIsLocalized: false,\n selectFields: {},\n tableName: relatedTableName,\n where,\n })\n : undefined\n\n // Correlate relationship rows back to the parent document currently being considered by the\n // outer query. The stored path distinguishes this field from other relationships on the parent.\n const outerTable = aliasTable ?? aliasedTable(adapter.tables[tableName], tableName)\n const relationshipRowConstraints: SQL[] = [\n eq(relationshipTable.parent, outerTable.id),\n relationshipPath.path.includes('%')\n ? like(relationshipTable.path, relationshipPath.path)\n : eq(relationshipTable.path, relationshipPath.path),\n ]\n\n if (relationshipLocale && relationshipLocale !== 'all' && relationshipPath.isLocalized) {\n relationshipRowConstraints.push(eq(relationshipTable.locale, relationshipLocale))\n }\n\n const relatedDocumentConstraints = [\n eq(relatedTable.id, relationshipTable[`${relationshipField.relationTo}ID`]),\n ]\n\n if (relatedDocumentWhere) {\n relatedDocumentConstraints.push(relatedDocumentWhere)\n }\n\n let relatedDocumentSubquery = (adapter.drizzle as any)\n .select({ id: relatedTable.id })\n .from(relatedTable)\n .$dynamic()\n\n for (const join of nestedJoins) {\n relatedDocumentSubquery = relatedDocumentSubquery[join.type ?? 'leftJoin'](\n join.table,\n join.condition,\n )\n }\n\n relatedDocumentSubquery = relatedDocumentSubquery.where(and(...relatedDocumentConstraints))\n\n const buildRelationshipRowsSubquery = (relatedDocumentCheck: SQL) =>\n (adapter.drizzle as any)\n .select({ id: relationshipTable.parent })\n .from(relationshipTable)\n .where(and(...relationshipRowConstraints, relatedDocumentCheck))\n\n switch (operator) {\n case 'contains':\n return exists(buildRelationshipRowsSubquery(exists(relatedDocumentSubquery)))\n\n case 'equals':\n // All related documents match when no relationship row points to one that fails.\n return notExists(buildRelationshipRowsSubquery(notExists(relatedDocumentSubquery)))\n\n case 'not_equals':\n return notExists(buildRelationshipRowsSubquery(exists(relatedDocumentSubquery)))\n }\n}\n"],"names":["aliasedTable","and","eq","exists","getTableName","isNotNull","isNull","like","notExists","notInArray","or","sql","PgUUID","APIError","getFieldByPath","QueryError","hasManyRelationshipOperatorSet","isNestedRelationshipQuery","validOperatorSet","toSnakeCase","escapeSQLValue","getNameFromDrizzleTable","isValidStringID","DistinctSymbol","isRawConstraint","buildAndOrConditions","buildOperatorConstraint","getTableAlias","getTableColumnFromPath","resolveRelationshipPath","sanitizeQueryValue","parseParams","adapter","aliasTable","context","fields","joins","locale","parentIsLocalized","selectFields","selectLocale","tableName","where","result","constraints","Object","keys","length","relationOrPath","condition","conditionOperator","toLowerCase","Array","isArray","builtConditions","pathOperators","operator","has","val","originalOperator","relationshipPath","path","replace","field","hasMany","relationTo","push","buildHasManyRelationshipCondition","joinField","type","prefixJoinContainsWhere","prefix","columnName","columns","queryConstraints","getNotNullColumnByValue","pathSegments","rawColumn","table","collectionPath","split","value","resolvedColumn","forEach","col","constraintTable","indexOf","operators","equals","includes","blocksAsJSON","name","constraint","createJSONQuery","column","raw","segments","slice","unshift","jsonTable","getOwnPropertySymbols","jsonQuery","treatAsArray","treatRootAsArray","convertPathToJSONTraversal","operatorKeys","contains","wildcard","in","not_equals","not_in","not_like","formattedValue","map","v","escaped","String","join","jsonQuerySelector","rawSQLQuery","columnType","word","resolvedOperator","sanitizedQueryValue","isUUID","queryColumns","queryOperator","queryValue","wrapOperator","JSON","stringify","lng","lat","maxDistance","minDistance","geoConstraints","Number","isNaN","sort","rawSort","orConditions","resolvedQueryValue","some","filter","undefined","limitedBoundParameters","isInvalid","e","prefixedWhere","key","entries","nestedWhere","relationshipFieldPath","relationshipField","relationshipTableName","relationshipsSuffix","relatedCollection","payload","collections","relatedTableName","tableNameMap","get","config","slug","relationshipLocale","newAliasTable","relationshipTable","relatedTable","nestedJoins","relatedDocumentWhere","flattenedFields","outerTable","tables","relationshipRowConstraints","parent","id","isLocalized","relatedDocumentConstraints","relatedDocumentSubquery","drizzle","select","from","$dynamic","buildRelationshipRowsSubquery","relatedDocumentCheck"],"mappings":"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"}
@@ -1,11 +1,12 @@
1
- import { sanitizePathSegment } from '../../utilities/sanitizePathSegment.js';
1
+ import { parseJSONPathSegment } from '../../utilities/parseJSONPathSegment.js';
2
2
  export const convertPathToJSONTraversal = (incomingSegments)=>{
3
3
  const segments = [
4
4
  ...incomingSegments
5
5
  ];
6
6
  segments.shift();
7
7
  return segments.reduce((res, segment, i)=>{
8
- const formattedSegment = Number.isNaN(parseInt(segment)) ? `'${sanitizePathSegment(segment)}'` : segment;
8
+ const parsedSegment = parseJSONPathSegment(segment);
9
+ const formattedSegment = parsedSegment.type === 'objectKey' ? `'${parsedSegment.value}'` : parsedSegment.value;
9
10
  const isLast = i === segments.length - 1;
10
11
  return `${res}${isLast ? '->>' : '->'}${formattedSegment}`;
11
12
  }, '');
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/sqlite/createJSONQuery/convertPathToJSONTraversal.ts"],"sourcesContent":["import { sanitizePathSegment } from '../../utilities/sanitizePathSegment.js'\n\nexport const convertPathToJSONTraversal = (incomingSegments: string[]): string => {\n const segments = [...incomingSegments]\n segments.shift()\n\n return segments.reduce((res, segment, i) => {\n const formattedSegment = Number.isNaN(parseInt(segment))\n ? `'${sanitizePathSegment(segment)}'`\n : segment\n const isLast = i === segments.length - 1\n return `${res}${isLast ? '->>' : '->'}${formattedSegment}`\n }, '')\n}\n"],"names":["sanitizePathSegment","convertPathToJSONTraversal","incomingSegments","segments","shift","reduce","res","segment","i","formattedSegment","Number","isNaN","parseInt","isLast","length"],"mappings":"AAAA,SAASA,mBAAmB,QAAQ,yCAAwC;AAE5E,OAAO,MAAMC,6BAA6B,CAACC;IACzC,MAAMC,WAAW;WAAID;KAAiB;IACtCC,SAASC,KAAK;IAEd,OAAOD,SAASE,MAAM,CAAC,CAACC,KAAKC,SAASC;QACpC,MAAMC,mBAAmBC,OAAOC,KAAK,CAACC,SAASL,YAC3C,CAAC,CAAC,EAAEP,oBAAoBO,SAAS,CAAC,CAAC,GACnCA;QACJ,MAAMM,SAASL,MAAML,SAASW,MAAM,GAAG;QACvC,OAAO,GAAGR,MAAMO,SAAS,QAAQ,OAAOJ,kBAAkB;IAC5D,GAAG;AACL,EAAC"}
1
+ {"version":3,"sources":["../../../src/sqlite/createJSONQuery/convertPathToJSONTraversal.ts"],"sourcesContent":["import { parseJSONPathSegment } from '../../utilities/parseJSONPathSegment.js'\n\nexport const convertPathToJSONTraversal = (incomingSegments: string[]): string => {\n const segments = [...incomingSegments]\n segments.shift()\n\n return segments.reduce((res, segment, i) => {\n const parsedSegment = parseJSONPathSegment(segment)\n const formattedSegment =\n parsedSegment.type === 'objectKey' ? `'${parsedSegment.value}'` : parsedSegment.value\n const isLast = i === segments.length - 1\n return `${res}${isLast ? '->>' : '->'}${formattedSegment}`\n }, '')\n}\n"],"names":["parseJSONPathSegment","convertPathToJSONTraversal","incomingSegments","segments","shift","reduce","res","segment","i","parsedSegment","formattedSegment","type","value","isLast","length"],"mappings":"AAAA,SAASA,oBAAoB,QAAQ,0CAAyC;AAE9E,OAAO,MAAMC,6BAA6B,CAACC;IACzC,MAAMC,WAAW;WAAID;KAAiB;IACtCC,SAASC,KAAK;IAEd,OAAOD,SAASE,MAAM,CAAC,CAACC,KAAKC,SAASC;QACpC,MAAMC,gBAAgBT,qBAAqBO;QAC3C,MAAMG,mBACJD,cAAcE,IAAI,KAAK,cAAc,CAAC,CAAC,EAAEF,cAAcG,KAAK,CAAC,CAAC,CAAC,GAAGH,cAAcG,KAAK;QACvF,MAAMC,SAASL,MAAML,SAASW,MAAM,GAAG;QACvC,OAAO,GAAGR,MAAMO,SAAS,QAAQ,OAAOH,kBAAkB;IAC5D,GAAG;AACL,EAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/sqlite/createJSONQuery/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAA;AA8GzD,eAAO,MAAM,eAAe,iGASzB,mBAAmB,KAAG,MA0BxB,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/sqlite/createJSONQuery/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAA;AAgHzD,eAAO,MAAM,eAAe,iGASzB,mBAAmB,KAAG,MA2BxB,CAAA"}
@@ -16,7 +16,7 @@ const fromArray = ({ isRoot, operator, pathSegments, table, treatAsArray, value
16
16
  })}
17
17
  )`;
18
18
  };
19
- const createConstraint = ({ alias, operator, pathSegments, value })=>{
19
+ const createConstraint = ({ alias, operator, pathSegments, rootColumn, value })=>{
20
20
  const newAlias = `${pathSegments[0]}_alias_${pathSegments.length - 1}`;
21
21
  if (operator === 'exists' && value === false) {
22
22
  operator = 'not_exists';
@@ -27,7 +27,7 @@ const createConstraint = ({ alias, operator, pathSegments, value })=>{
27
27
  }
28
28
  if (operator === 'exists') {
29
29
  if (pathSegments.length === 1) {
30
- return `EXISTS (SELECT 1 FROM json_each("${sanitizePathSegment(pathSegments[0])}") AS ${newAlias})`;
30
+ return `EXISTS (SELECT 1 FROM json_each(${rootColumn ?? `"${sanitizePathSegment(pathSegments[0])}"`}) AS ${newAlias})`;
31
31
  }
32
32
  return `EXISTS (
33
33
  SELECT 1
@@ -37,7 +37,7 @@ const createConstraint = ({ alias, operator, pathSegments, value })=>{
37
37
  }
38
38
  if (operator === 'not_exists') {
39
39
  if (pathSegments.length === 1) {
40
- return `NOT EXISTS (SELECT 1 FROM json_each("${sanitizePathSegment(pathSegments[0])}") AS ${newAlias})`;
40
+ return `NOT EXISTS (SELECT 1 FROM json_each(${rootColumn ?? `"${sanitizePathSegment(pathSegments[0])}"`}) AS ${newAlias})`;
41
41
  }
42
42
  return `NOT EXISTS (
43
43
  SELECT 1
@@ -63,7 +63,7 @@ const createConstraint = ({ alias, operator, pathSegments, value })=>{
63
63
  formattedOperator = '=';
64
64
  }
65
65
  if (pathSegments.length === 1) {
66
- return `EXISTS (SELECT 1 FROM json_each("${sanitizePathSegment(pathSegments[0])}") AS ${newAlias} WHERE ${newAlias}.value ${formattedOperator} '${formattedValue}')`;
66
+ return `EXISTS (SELECT 1 FROM json_each(${rootColumn ?? `"${sanitizePathSegment(pathSegments[0])}"`}) AS ${newAlias} WHERE ${newAlias}.value ${formattedOperator} '${formattedValue}')`;
67
67
  }
68
68
  return `EXISTS (
69
69
  SELECT 1
@@ -86,7 +86,7 @@ export const createJSONQuery = ({ column, operator, pathSegments, rawColumn, tab
86
86
  value: v
87
87
  })} ${i === value.length - 1 ? '' : ` ${operator === 'in' ? 'OR' : 'AND'} `}`;
88
88
  }
89
- return sql;
89
+ return `(${sql})`;
90
90
  }
91
91
  if (treatAsArray?.includes(pathSegments[1]) && table) {
92
92
  return fromArray({
@@ -101,6 +101,7 @@ export const createJSONQuery = ({ column, operator, pathSegments, rawColumn, tab
101
101
  alias: table,
102
102
  operator,
103
103
  pathSegments,
104
+ rootColumn: typeof column === 'string' ? column : column ? `"${column.name}"` : undefined,
104
105
  treatAsArray,
105
106
  value: value
106
107
  });
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/sqlite/createJSONQuery/index.ts"],"sourcesContent":["import type { CreateJSONQueryArgs } from '../../types.js'\n\nimport { escapeSQLValue } from '../../utilities/escapeSQLValue.js'\nimport { sanitizePathSegment } from '../../utilities/sanitizePathSegment.js'\n\ntype FromArrayArgs = {\n isRoot?: true\n operator: string\n pathSegments: string[]\n table: string\n treatAsArray?: string[]\n value: boolean | number | string\n}\n\nconst fromArray = ({\n isRoot,\n operator,\n pathSegments,\n table,\n treatAsArray,\n value,\n}: FromArrayArgs) => {\n const newPathSegments = pathSegments.slice(1)\n const sanitizedSegment = sanitizePathSegment(pathSegments[isRoot ? 0 : 1])\n const alias = `${sanitizedSegment}_alias_${newPathSegments.length}`\n\n return `EXISTS (\n SELECT 1\n FROM json_each(${table}.${sanitizePathSegment(pathSegments[0])}) AS ${alias}\n WHERE ${createJSONQuery({\n operator,\n pathSegments: newPathSegments,\n table: alias,\n treatAsArray,\n value,\n })}\n )`\n}\n\ntype CreateConstraintArgs = {\n alias?: string\n operator: string\n pathSegments: string[]\n treatAsArray?: string[]\n value: boolean | number | string\n}\n\nconst createConstraint = ({\n alias,\n operator,\n pathSegments,\n value,\n}: CreateConstraintArgs): string => {\n const newAlias = `${pathSegments[0]}_alias_${pathSegments.length - 1}`\n\n if (operator === 'exists' && value === false) {\n operator = 'not_exists'\n value = true\n } else if (operator === 'not_exists' && value === false) {\n operator = 'exists'\n value = true\n }\n\n if (operator === 'exists') {\n if (pathSegments.length === 1) {\n return `EXISTS (SELECT 1 FROM json_each(\"${sanitizePathSegment(pathSegments[0])}\") AS ${newAlias})`\n }\n\n return `EXISTS (\n SELECT 1\n FROM json_each(${alias}.value -> '${sanitizePathSegment(pathSegments[0])}') AS ${newAlias}\n WHERE ${newAlias}.key = '${sanitizePathSegment(pathSegments[1])}'\n )`\n }\n\n if (operator === 'not_exists') {\n if (pathSegments.length === 1) {\n return `NOT EXISTS (SELECT 1 FROM json_each(\"${sanitizePathSegment(pathSegments[0])}\") AS ${newAlias})`\n }\n\n return `NOT EXISTS (\n SELECT 1\n FROM json_each(${alias}.value -> '${sanitizePathSegment(pathSegments[0])}') AS ${newAlias}\n WHERE ${newAlias}.key = '${sanitizePathSegment(pathSegments[1])}'\n )`\n }\n\n let formattedValue = escapeSQLValue(value)\n let formattedOperator = operator\n if (['contains', 'like'].includes(operator)) {\n formattedOperator = 'like'\n formattedValue = `%${value}%`\n } else if (['not_like', 'notlike'].includes(operator)) {\n formattedOperator = 'not like'\n formattedValue = `%${value}%`\n } else if (operator === 'equals') {\n formattedOperator = '='\n }\n\n if (pathSegments.length === 1) {\n return `EXISTS (SELECT 1 FROM json_each(\"${sanitizePathSegment(pathSegments[0])}\") AS ${newAlias} WHERE ${newAlias}.value ${formattedOperator} '${formattedValue}')`\n }\n\n return `EXISTS (\n SELECT 1\n FROM json_each(${alias}.value -> '${sanitizePathSegment(pathSegments[0])}') AS ${newAlias}\n WHERE COALESCE(${newAlias}.value ->> '${sanitizePathSegment(pathSegments[1])}', '') ${formattedOperator} '${formattedValue}'\n )`\n}\n\nexport const createJSONQuery = ({\n column,\n operator,\n pathSegments,\n rawColumn,\n table,\n treatAsArray,\n treatRootAsArray,\n value,\n}: CreateJSONQueryArgs): string => {\n if ((operator === 'in' || operator === 'not_in') && Array.isArray(value)) {\n let sql = ''\n for (const [i, v] of value.entries()) {\n sql = `${sql}${createJSONQuery({ column, operator: operator === 'in' ? 'equals' : 'not_equals', pathSegments, rawColumn, table, treatAsArray, treatRootAsArray, value: v })} ${i === value.length - 1 ? '' : ` ${operator === 'in' ? 'OR' : 'AND'} `}`\n }\n return sql\n }\n\n if (treatAsArray?.includes(pathSegments[1]) && table) {\n return fromArray({\n operator,\n pathSegments,\n table,\n treatAsArray,\n value: value as CreateConstraintArgs['value'],\n })\n }\n\n return createConstraint({\n alias: table,\n operator,\n pathSegments,\n treatAsArray,\n value: value as CreateConstraintArgs['value'],\n })\n}\n"],"names":["escapeSQLValue","sanitizePathSegment","fromArray","isRoot","operator","pathSegments","table","treatAsArray","value","newPathSegments","slice","sanitizedSegment","alias","length","createJSONQuery","createConstraint","newAlias","formattedValue","formattedOperator","includes","column","rawColumn","treatRootAsArray","Array","isArray","sql","i","v","entries"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../src/sqlite/createJSONQuery/index.ts"],"sourcesContent":["import type { CreateJSONQueryArgs } from '../../types.js'\n\nimport { escapeSQLValue } from '../../utilities/escapeSQLValue.js'\nimport { sanitizePathSegment } from '../../utilities/sanitizePathSegment.js'\n\ntype FromArrayArgs = {\n isRoot?: true\n operator: string\n pathSegments: string[]\n table: string\n treatAsArray?: string[]\n value: boolean | number | string\n}\n\nconst fromArray = ({\n isRoot,\n operator,\n pathSegments,\n table,\n treatAsArray,\n value,\n}: FromArrayArgs) => {\n const newPathSegments = pathSegments.slice(1)\n const sanitizedSegment = sanitizePathSegment(pathSegments[isRoot ? 0 : 1])\n const alias = `${sanitizedSegment}_alias_${newPathSegments.length}`\n\n return `EXISTS (\n SELECT 1\n FROM json_each(${table}.${sanitizePathSegment(pathSegments[0])}) AS ${alias}\n WHERE ${createJSONQuery({\n operator,\n pathSegments: newPathSegments,\n table: alias,\n treatAsArray,\n value,\n })}\n )`\n}\n\ntype CreateConstraintArgs = {\n alias?: string\n operator: string\n pathSegments: string[]\n rootColumn?: string\n treatAsArray?: string[]\n value: boolean | number | string\n}\n\nconst createConstraint = ({\n alias,\n operator,\n pathSegments,\n rootColumn,\n value,\n}: CreateConstraintArgs): string => {\n const newAlias = `${pathSegments[0]}_alias_${pathSegments.length - 1}`\n\n if (operator === 'exists' && value === false) {\n operator = 'not_exists'\n value = true\n } else if (operator === 'not_exists' && value === false) {\n operator = 'exists'\n value = true\n }\n\n if (operator === 'exists') {\n if (pathSegments.length === 1) {\n return `EXISTS (SELECT 1 FROM json_each(${rootColumn ?? `\"${sanitizePathSegment(pathSegments[0])}\"`}) AS ${newAlias})`\n }\n\n return `EXISTS (\n SELECT 1\n FROM json_each(${alias}.value -> '${sanitizePathSegment(pathSegments[0])}') AS ${newAlias}\n WHERE ${newAlias}.key = '${sanitizePathSegment(pathSegments[1])}'\n )`\n }\n\n if (operator === 'not_exists') {\n if (pathSegments.length === 1) {\n return `NOT EXISTS (SELECT 1 FROM json_each(${rootColumn ?? `\"${sanitizePathSegment(pathSegments[0])}\"`}) AS ${newAlias})`\n }\n\n return `NOT EXISTS (\n SELECT 1\n FROM json_each(${alias}.value -> '${sanitizePathSegment(pathSegments[0])}') AS ${newAlias}\n WHERE ${newAlias}.key = '${sanitizePathSegment(pathSegments[1])}'\n )`\n }\n\n let formattedValue = escapeSQLValue(value)\n let formattedOperator = operator\n if (['contains', 'like'].includes(operator)) {\n formattedOperator = 'like'\n formattedValue = `%${value}%`\n } else if (['not_like', 'notlike'].includes(operator)) {\n formattedOperator = 'not like'\n formattedValue = `%${value}%`\n } else if (operator === 'equals') {\n formattedOperator = '='\n }\n\n if (pathSegments.length === 1) {\n return `EXISTS (SELECT 1 FROM json_each(${rootColumn ?? `\"${sanitizePathSegment(pathSegments[0])}\"`}) AS ${newAlias} WHERE ${newAlias}.value ${formattedOperator} '${formattedValue}')`\n }\n\n return `EXISTS (\n SELECT 1\n FROM json_each(${alias}.value -> '${sanitizePathSegment(pathSegments[0])}') AS ${newAlias}\n WHERE COALESCE(${newAlias}.value ->> '${sanitizePathSegment(pathSegments[1])}', '') ${formattedOperator} '${formattedValue}'\n )`\n}\n\nexport const createJSONQuery = ({\n column,\n operator,\n pathSegments,\n rawColumn,\n table,\n treatAsArray,\n treatRootAsArray,\n value,\n}: CreateJSONQueryArgs): string => {\n if ((operator === 'in' || operator === 'not_in') && Array.isArray(value)) {\n let sql = ''\n for (const [i, v] of value.entries()) {\n sql = `${sql}${createJSONQuery({ column, operator: operator === 'in' ? 'equals' : 'not_equals', pathSegments, rawColumn, table, treatAsArray, treatRootAsArray, value: v })} ${i === value.length - 1 ? '' : ` ${operator === 'in' ? 'OR' : 'AND'} `}`\n }\n return `(${sql})`\n }\n\n if (treatAsArray?.includes(pathSegments[1]) && table) {\n return fromArray({\n operator,\n pathSegments,\n table,\n treatAsArray,\n value: value as CreateConstraintArgs['value'],\n })\n }\n\n return createConstraint({\n alias: table,\n operator,\n pathSegments,\n rootColumn: typeof column === 'string' ? column : column ? `\"${column.name}\"` : undefined,\n treatAsArray,\n value: value as CreateConstraintArgs['value'],\n })\n}\n"],"names":["escapeSQLValue","sanitizePathSegment","fromArray","isRoot","operator","pathSegments","table","treatAsArray","value","newPathSegments","slice","sanitizedSegment","alias","length","createJSONQuery","createConstraint","rootColumn","newAlias","formattedValue","formattedOperator","includes","column","rawColumn","treatRootAsArray","Array","isArray","sql","i","v","entries","name","undefined"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"insert.d.ts","sourceRoot":"","sources":["../../src/sqlite/insert.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAqB,MAAM,EAAE,MAAM,YAAY,CAAA;AAE3D,eAAO,MAAM,MAAM,EAAE,MAkCpB,CAAA"}
1
+ {"version":3,"file":"insert.d.ts","sourceRoot":"","sources":["../../src/sqlite/insert.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAqB,MAAM,EAAE,MAAM,YAAY,CAAA;AAE3D,eAAO,MAAM,MAAM,EAAE,MAoCpB,CAAA"}
@@ -1,9 +1,12 @@
1
+ import { getTableColumns } from 'drizzle-orm';
1
2
  export const insert = async function({ db, onConflictDoUpdate, tableName, values }) {
2
3
  const table = this.tables[tableName];
3
4
  // Batch insert if limitedBoundParameters: true
4
5
  if (this.limitedBoundParameters && Array.isArray(values)) {
5
6
  const results = [];
6
- const colsPerRow = Object.keys(values[0]).length;
7
+ // Drizzle emits a value for every table column per row, not just the keys present on the row —
8
+ // omitted columns fall back to their default / defaultFn, which is also a bound parameter
9
+ const colsPerRow = Math.max(1, Object.keys(getTableColumns(table)).length);
7
10
  const maxParams = 100;
8
11
  const maxRowsPerBatch = Math.max(1, Math.floor(maxParams / colsPerRow));
9
12
  for(let i = 0; i < values.length; i += maxRowsPerBatch){
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/sqlite/insert.ts"],"sourcesContent":["import type { BaseSQLiteAdapter, Insert } from './types.js'\n\nexport const insert: Insert = async function (\n // Here 'this' is not a parameter. See:\n // https://www.typescriptlang.org/docs/handbook/2/classes.html#this-parameters\n this: BaseSQLiteAdapter,\n { db, onConflictDoUpdate, tableName, values },\n): Promise<Record<string, unknown>[]> {\n const table = this.tables[tableName]\n\n // Batch insert if limitedBoundParameters: true\n if (this.limitedBoundParameters && Array.isArray(values)) {\n const results: Record<string, unknown>[] = []\n const colsPerRow = Object.keys(values[0]).length\n const maxParams = 100\n const maxRowsPerBatch = Math.max(1, Math.floor(maxParams / colsPerRow))\n\n for (let i = 0; i < values.length; i += maxRowsPerBatch) {\n const batch = values.slice(i, i + maxRowsPerBatch)\n\n const batchResult = onConflictDoUpdate\n ? await db.insert(table).values(batch).onConflictDoUpdate(onConflictDoUpdate).returning()\n : await db.insert(table).values(batch).returning()\n\n results.push(...(batchResult as Record<string, unknown>[]))\n }\n\n return results\n }\n\n const result = onConflictDoUpdate\n ? await db.insert(table).values(values).onConflictDoUpdate(onConflictDoUpdate).returning()\n : await db.insert(table).values(values).returning()\n\n // See https://github.com/payloadcms/payload/pull/11831#discussion_r2010431908\n return result as Record<string, unknown>[]\n}\n"],"names":["insert","db","onConflictDoUpdate","tableName","values","table","tables","limitedBoundParameters","Array","isArray","results","colsPerRow","Object","keys","length","maxParams","maxRowsPerBatch","Math","max","floor","i","batch","slice","batchResult","returning","push","result"],"mappings":"AAEA,OAAO,MAAMA,SAAiB,eAI5B,EAAEC,EAAE,EAAEC,kBAAkB,EAAEC,SAAS,EAAEC,MAAM,EAAE;IAE7C,MAAMC,QAAQ,IAAI,CAACC,MAAM,CAACH,UAAU;IAEpC,+CAA+C;IAC/C,IAAI,IAAI,CAACI,sBAAsB,IAAIC,MAAMC,OAAO,CAACL,SAAS;QACxD,MAAMM,UAAqC,EAAE;QAC7C,MAAMC,aAAaC,OAAOC,IAAI,CAACT,MAAM,CAAC,EAAE,EAAEU,MAAM;QAChD,MAAMC,YAAY;QAClB,MAAMC,kBAAkBC,KAAKC,GAAG,CAAC,GAAGD,KAAKE,KAAK,CAACJ,YAAYJ;QAE3D,IAAK,IAAIS,IAAI,GAAGA,IAAIhB,OAAOU,MAAM,EAAEM,KAAKJ,gBAAiB;YACvD,MAAMK,QAAQjB,OAAOkB,KAAK,CAACF,GAAGA,IAAIJ;YAElC,MAAMO,cAAcrB,qBAChB,MAAMD,GAAGD,MAAM,CAACK,OAAOD,MAAM,CAACiB,OAAOnB,kBAAkB,CAACA,oBAAoBsB,SAAS,KACrF,MAAMvB,GAAGD,MAAM,CAACK,OAAOD,MAAM,CAACiB,OAAOG,SAAS;YAElDd,QAAQe,IAAI,IAAKF;QACnB;QAEA,OAAOb;IACT;IAEA,MAAMgB,SAASxB,qBACX,MAAMD,GAAGD,MAAM,CAACK,OAAOD,MAAM,CAACA,QAAQF,kBAAkB,CAACA,oBAAoBsB,SAAS,KACtF,MAAMvB,GAAGD,MAAM,CAACK,OAAOD,MAAM,CAACA,QAAQoB,SAAS;IAEnD,8EAA8E;IAC9E,OAAOE;AACT,EAAC"}
1
+ {"version":3,"sources":["../../src/sqlite/insert.ts"],"sourcesContent":["import { getTableColumns } from 'drizzle-orm'\n\nimport type { BaseSQLiteAdapter, Insert } from './types.js'\n\nexport const insert: Insert = async function (\n // Here 'this' is not a parameter. See:\n // https://www.typescriptlang.org/docs/handbook/2/classes.html#this-parameters\n this: BaseSQLiteAdapter,\n { db, onConflictDoUpdate, tableName, values },\n): Promise<Record<string, unknown>[]> {\n const table = this.tables[tableName]\n\n // Batch insert if limitedBoundParameters: true\n if (this.limitedBoundParameters && Array.isArray(values)) {\n const results: Record<string, unknown>[] = []\n // Drizzle emits a value for every table column per row, not just the keys present on the row —\n // omitted columns fall back to their default / defaultFn, which is also a bound parameter\n const colsPerRow = Math.max(1, Object.keys(getTableColumns(table)).length)\n const maxParams = 100\n const maxRowsPerBatch = Math.max(1, Math.floor(maxParams / colsPerRow))\n\n for (let i = 0; i < values.length; i += maxRowsPerBatch) {\n const batch = values.slice(i, i + maxRowsPerBatch)\n\n const batchResult = onConflictDoUpdate\n ? await db.insert(table).values(batch).onConflictDoUpdate(onConflictDoUpdate).returning()\n : await db.insert(table).values(batch).returning()\n\n results.push(...(batchResult as Record<string, unknown>[]))\n }\n\n return results\n }\n\n const result = onConflictDoUpdate\n ? await db.insert(table).values(values).onConflictDoUpdate(onConflictDoUpdate).returning()\n : await db.insert(table).values(values).returning()\n\n // See https://github.com/payloadcms/payload/pull/11831#discussion_r2010431908\n return result as Record<string, unknown>[]\n}\n"],"names":["getTableColumns","insert","db","onConflictDoUpdate","tableName","values","table","tables","limitedBoundParameters","Array","isArray","results","colsPerRow","Math","max","Object","keys","length","maxParams","maxRowsPerBatch","floor","i","batch","slice","batchResult","returning","push","result"],"mappings":"AAAA,SAASA,eAAe,QAAQ,cAAa;AAI7C,OAAO,MAAMC,SAAiB,eAI5B,EAAEC,EAAE,EAAEC,kBAAkB,EAAEC,SAAS,EAAEC,MAAM,EAAE;IAE7C,MAAMC,QAAQ,IAAI,CAACC,MAAM,CAACH,UAAU;IAEpC,+CAA+C;IAC/C,IAAI,IAAI,CAACI,sBAAsB,IAAIC,MAAMC,OAAO,CAACL,SAAS;QACxD,MAAMM,UAAqC,EAAE;QAC7C,+FAA+F;QAC/F,0FAA0F;QAC1F,MAAMC,aAAaC,KAAKC,GAAG,CAAC,GAAGC,OAAOC,IAAI,CAAChB,gBAAgBM,QAAQW,MAAM;QACzE,MAAMC,YAAY;QAClB,MAAMC,kBAAkBN,KAAKC,GAAG,CAAC,GAAGD,KAAKO,KAAK,CAACF,YAAYN;QAE3D,IAAK,IAAIS,IAAI,GAAGA,IAAIhB,OAAOY,MAAM,EAAEI,KAAKF,gBAAiB;YACvD,MAAMG,QAAQjB,OAAOkB,KAAK,CAACF,GAAGA,IAAIF;YAElC,MAAMK,cAAcrB,qBAChB,MAAMD,GAAGD,MAAM,CAACK,OAAOD,MAAM,CAACiB,OAAOnB,kBAAkB,CAACA,oBAAoBsB,SAAS,KACrF,MAAMvB,GAAGD,MAAM,CAACK,OAAOD,MAAM,CAACiB,OAAOG,SAAS;YAElDd,QAAQe,IAAI,IAAKF;QACnB;QAEA,OAAOb;IACT;IAEA,MAAMgB,SAASxB,qBACX,MAAMD,GAAGD,MAAM,CAACK,OAAOD,MAAM,CAACA,QAAQF,kBAAkB,CAACA,oBAAoBsB,SAAS,KACtF,MAAMvB,GAAGD,MAAM,CAACK,OAAOD,MAAM,CAACA,QAAQoB,SAAS;IAEnD,8EAA8E;IAC9E,OAAOE;AACT,EAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"traverseFields.d.ts","sourceRoot":"","sources":["../../../src/transform/write/traverseFields.ts"],"names":[],"mappings":"AACA,OAAO,EAAY,KAAK,cAAc,EAAE,MAAM,SAAS,CAAA;AAIvD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAA;AACpD,OAAO,KAAK,EACV,cAAc,EACd,oBAAoB,EACpB,oBAAoB,EACpB,WAAW,EACX,YAAY,EACb,MAAM,YAAY,CAAA;AAWnB,KAAK,IAAI,GAAG;IACV,OAAO,EAAE,cAAc,CAAA;IACvB;;OAEG;IACH,MAAM,EAAE,WAAW,CAAC,QAAQ,CAAC,CAAA;IAC7B;;;OAGG;IACH,YAAY,EAAE,WAAW,CAAC,cAAc,CAAC,CAAA;IACzC;;OAEG;IACH,aAAa,EAAE,MAAM,CAAA;IACrB,MAAM,EAAE,WAAW,CAAC,QAAQ,CAAC,CAAA;IAC7B,cAAc,EAAE,GAAG,CAAC,MAAM,CAAC,CAAA;IAC3B;;;OAGG;IACH,YAAY,EAAE,MAAM,CAAA;IACpB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAC7B,kBAAkB,CAAC,EAAE,OAAO,CAAA;IAC5B,eAAe,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAA;IAC3C;;;OAGG;IACH,WAAW,EAAE,MAAM,CAAA;IACnB,MAAM,EAAE,cAAc,EAAE,CAAA;IACxB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB;;OAEG;IACH,kBAAkB,CAAC,EAAE,OAAO,CAAA;IAC5B,OAAO,EAAE;QACP,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KAC1C,CAAA;IACD,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAA;IAClC,eAAe,EAAE,cAAc,EAAE,CAAA;IACjC,iBAAiB,EAAE,OAAO,CAAA;IAC1B;;OAEG;IACH,eAAe,EAAE,MAAM,CAAA;IACvB,IAAI,EAAE,MAAM,CAAA;IACZ,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAA;IACxC,qBAAqB,EAAE,oBAAoB,EAAE,CAAA;IAC7C,qBAAqB,EAAE,oBAAoB,EAAE,CAAA;IAC7C,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAC5B,OAAO,EAAE;QACP,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAA;KAC/C,CAAA;IACD,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAA;IAChC,aAAa,EAAE,YAAY,EAAE,CAAA;IAC7B;;;OAGG;IACH,wBAAwB,CAAC,EAAE,MAAM,CAAA;CAClC,CAAA;AAED,eAAO,MAAM,cAAc,sYA6BxB,IAAI,SAmvBN,CAAA"}
1
+ {"version":3,"file":"traverseFields.d.ts","sourceRoot":"","sources":["../../../src/transform/write/traverseFields.ts"],"names":[],"mappings":"AACA,OAAO,EAAY,KAAK,cAAc,EAAE,MAAM,SAAS,CAAA;AAIvD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAA;AACpD,OAAO,KAAK,EACV,cAAc,EACd,oBAAoB,EACpB,oBAAoB,EACpB,WAAW,EACX,YAAY,EACb,MAAM,YAAY,CAAA;AAWnB,KAAK,IAAI,GAAG;IACV,OAAO,EAAE,cAAc,CAAA;IACvB;;OAEG;IACH,MAAM,EAAE,WAAW,CAAC,QAAQ,CAAC,CAAA;IAC7B;;;OAGG;IACH,YAAY,EAAE,WAAW,CAAC,cAAc,CAAC,CAAA;IACzC;;OAEG;IACH,aAAa,EAAE,MAAM,CAAA;IACrB,MAAM,EAAE,WAAW,CAAC,QAAQ,CAAC,CAAA;IAC7B,cAAc,EAAE,GAAG,CAAC,MAAM,CAAC,CAAA;IAC3B;;;OAGG;IACH,YAAY,EAAE,MAAM,CAAA;IACpB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAC7B,kBAAkB,CAAC,EAAE,OAAO,CAAA;IAC5B,eAAe,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAA;IAC3C;;;OAGG;IACH,WAAW,EAAE,MAAM,CAAA;IACnB,MAAM,EAAE,cAAc,EAAE,CAAA;IACxB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB;;OAEG;IACH,kBAAkB,CAAC,EAAE,OAAO,CAAA;IAC5B,OAAO,EAAE;QACP,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KAC1C,CAAA;IACD,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAA;IAClC,eAAe,EAAE,cAAc,EAAE,CAAA;IACjC,iBAAiB,EAAE,OAAO,CAAA;IAC1B;;OAEG;IACH,eAAe,EAAE,MAAM,CAAA;IACvB,IAAI,EAAE,MAAM,CAAA;IACZ,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAA;IACxC,qBAAqB,EAAE,oBAAoB,EAAE,CAAA;IAC7C,qBAAqB,EAAE,oBAAoB,EAAE,CAAA;IAC7C,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAC5B,OAAO,EAAE;QACP,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAA;KAC/C,CAAA;IACD,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAA;IAChC,aAAa,EAAE,YAAY,EAAE,CAAA;IAC7B;;;OAGG;IACH,wBAAwB,CAAC,EAAE,MAAM,CAAA;CAClC,CAAA;AAED,eAAO,MAAM,cAAc,sYA6BxB,IAAI,SAuuBN,CAAA"}
@@ -1,6 +1,6 @@
1
1
  import { sql } from 'drizzle-orm';
2
2
  import { APIError } from 'payload';
3
- import { fieldIsVirtual, fieldShouldBeLocalized } from 'payload/shared';
3
+ import { expandOwnDottedKey, fieldIsVirtual, fieldShouldBeLocalized } from 'payload/shared';
4
4
  import toSnakeCase from 'to-snake-case';
5
5
  import { isArrayOfRows } from '../../utilities/isArrayOfRows.js';
6
6
  import { resolveBlockTableName } from '../../utilities/validateExistingBlockIsIdentical.js';
@@ -509,6 +509,9 @@ export const traverseFields = ({ adapter, arrays, arraysToPush, baseTableName, b
509
509
  return;
510
510
  }
511
511
  if (field.type === 'select' && field.hasMany) {
512
+ if (fieldData === undefined) {
513
+ return;
514
+ }
512
515
  const selectTableName = adapter.tableNameMap.get(`${parentTableName}_${columnName}`);
513
516
  if (!selects[selectTableName]) {
514
517
  selects[selectTableName] = [];
@@ -607,19 +610,10 @@ export const traverseFields = ({ adapter, arrays, arraysToPush, baseTableName, b
607
610
  // Handle dot-notation paths when no fields matched
608
611
  if (!fieldsMatched) {
609
612
  Object.keys(data).forEach((key)=>{
610
- if (key.includes('.')) {
611
- // Split on first dot only
612
- const firstDotIndex = key.indexOf('.');
613
- const fieldName = key.substring(0, firstDotIndex);
614
- const remainingPath = key.substring(firstDotIndex + 1);
615
- // Create nested structure for this field
616
- if (!data[fieldName]) {
617
- data[fieldName] = {};
618
- }
619
- const nestedData = data[fieldName];
620
- // Move the value to the nested structure
621
- nestedData[remainingPath] = data[key];
622
- delete data[key];
613
+ if (expandOwnDottedKey({
614
+ key,
615
+ target: data
616
+ })) {
623
617
  // Recursively process the newly created nested structure
624
618
  // The field traversal will naturally handle it if the field exists in the schema
625
619
  traverseFields({