@payloadcms/drizzle 3.80.0-canary.1 → 3.80.0-canary.2

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.
@@ -1 +1 @@
1
- {"version":3,"file":"sanitizeQueryValue.d.ts","sourceRoot":"","sources":["../../src/queries/sanitizeQueryValue.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,aAAa,CAAA;AAEtC,OAAO,EAA4C,KAAK,KAAK,EAAE,KAAK,UAAU,EAAE,MAAM,SAAS,CAAA;AAI/F,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;AAMjD,KAAK,sBAAsB,GAAG;IAC5B,OAAO,EAAE,cAAc,CAAA;IACvB,OAAO,CAAC,EAAE;QACR,MAAM,EAAE,QAAQ,GAAG,MAAM,GAAG,MAAM,CAAA;QAClC,SAAS,EAAE,GAAG,CAAC,OAAO,CAAC,CAAA;KACxB,EAAE,CAAA;IACH,KAAK,EAAE,KAAK,GAAG,UAAU,CAAA;IACzB,MAAM,EAAE,OAAO,CAAA;IACf,QAAQ,EAAE,MAAM,CAAA;IAChB,cAAc,EAAE,MAAM,CAAA;IACtB,GAAG,EAAE,GAAG,CAAA;CACT,CAAA;AAED,KAAK,eAAe,GAAG;IACrB,SAAS,EAAE,GAAG,CAAC,OAAO,CAAC,CAAA;IACvB,KAAK,EAAE,OAAO,CAAA;CACf,CAAA;AAED,eAAO,MAAM,kBAAkB,qFAQ5B,sBAAsB,KAAG;IAC1B,OAAO,CAAC,EAAE,eAAe,EAAE,CAAA;IAC3B,QAAQ,EAAE,MAAM,CAAA;IAChB,KAAK,EAAE,OAAO,CAAA;CAsPf,CAAA"}
1
+ {"version":3,"file":"sanitizeQueryValue.d.ts","sourceRoot":"","sources":["../../src/queries/sanitizeQueryValue.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,aAAa,CAAA;AAEtC,OAAO,EAA4C,KAAK,KAAK,EAAE,KAAK,UAAU,EAAE,MAAM,SAAS,CAAA;AAI/F,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;AAMjD,KAAK,sBAAsB,GAAG;IAC5B,OAAO,EAAE,cAAc,CAAA;IACvB,OAAO,CAAC,EAAE;QACR,MAAM,EAAE,QAAQ,GAAG,MAAM,GAAG,MAAM,CAAA;QAClC,SAAS,EAAE,GAAG,CAAC,OAAO,CAAC,CAAA;KACxB,EAAE,CAAA;IACH,KAAK,EAAE,KAAK,GAAG,UAAU,CAAA;IACzB,MAAM,EAAE,OAAO,CAAA;IACf,QAAQ,EAAE,MAAM,CAAA;IAChB,cAAc,EAAE,MAAM,CAAA;IACtB,GAAG,EAAE,GAAG,CAAA;CACT,CAAA;AAED,KAAK,eAAe,GAAG;IACrB,SAAS,EAAE,GAAG,CAAC,OAAO,CAAC,CAAA;IACvB,KAAK,EAAE,OAAO,CAAA;CACf,CAAA;AAED,eAAO,MAAM,kBAAkB,qFAQ5B,sBAAsB,KAAG;IAC1B,OAAO,CAAC,EAAE,eAAe,EAAE,CAAA;IAC3B,QAAQ,EAAE,MAAM,CAAA;IAChB,KAAK,EAAE,OAAO,CAAA;CAuPf,CAAA"}
@@ -185,8 +185,9 @@ export const sanitizeQueryValue = ({ adapter, columns, field, isUUID, operator:
185
185
  }
186
186
  }
187
187
  }
188
- // For hasMany relationship/upload fields, contains should use equals operator
189
- if ('hasMany' in field && field.hasMany && operator === 'contains' && (field.type === 'relationship' || field.type === 'upload')) {
188
+ // hasMany relationship/upload/select fields are stored as separate rows in a join table.
189
+ // The JOIN already gives us individual rows, so "contains" becomes an equality check on each row's value.
190
+ if ('hasMany' in field && field.hasMany && operator === 'contains' && (field.type === 'relationship' || field.type === 'upload' || field.type === 'select')) {
190
191
  operator = 'equals';
191
192
  }
192
193
  if (operator === 'near' && field.type === 'point' && typeof formattedValue === 'string') {
@@ -202,7 +203,6 @@ export const sanitizeQueryValue = ({ adapter, columns, field, isUUID, operator:
202
203
  // Handle array values for hasMany text/number/select fields
203
204
  if (Array.isArray(formattedValue) && 'hasMany' in field && field.hasMany && [
204
205
  'number',
205
- 'select',
206
206
  'text'
207
207
  ].includes(field.type)) {
208
208
  // For hasMany text/number/select fields with array values, wrap each element with % for LIKE matching
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/queries/sanitizeQueryValue.ts"],"sourcesContent":["import type { SQL } from 'drizzle-orm'\n\nimport { APIError, createArrayFromCommaDelineated, type Field, type TabAsField } from 'payload'\nimport { fieldAffectsData } from 'payload/shared'\nimport { validate as uuidValidate } from 'uuid'\n\nimport type { DrizzleAdapter } from '../types.js'\n\nimport { getCollectionIdType } from '../utilities/getCollectionIdType.js'\nimport { isPolymorphicRelationship } from '../utilities/isPolymorphicRelationship.js'\nimport { isRawConstraint } from '../utilities/rawConstraint.js'\n\ntype SanitizeQueryValueArgs = {\n adapter: DrizzleAdapter\n columns?: {\n idType: 'number' | 'text' | 'uuid'\n rawColumn: SQL<unknown>\n }[]\n field: Field | TabAsField\n isUUID: boolean\n operator: string\n relationOrPath: string\n val: any\n}\n\ntype SanitizedColumn = {\n rawColumn: SQL<unknown>\n value: unknown\n}\n\nexport const sanitizeQueryValue = ({\n adapter,\n columns,\n field,\n isUUID,\n operator: operatorArg,\n relationOrPath,\n val,\n}: SanitizeQueryValueArgs): {\n columns?: SanitizedColumn[]\n operator: string\n value: unknown\n} => {\n let operator = operatorArg\n let formattedValue = val\n let formattedColumns: SanitizedColumn[]\n\n if (!fieldAffectsData(field)) {\n return { operator, value: formattedValue }\n }\n\n if (isRawConstraint(val)) {\n return { operator, value: val.value }\n }\n if (\n (field.type === 'relationship' || field.type === 'upload') &&\n !relationOrPath.endsWith('relationTo') &&\n Array.isArray(formattedValue)\n ) {\n const allPossibleIDTypes: (number | string)[] = []\n formattedValue.forEach((val) => {\n if (adapter.idType !== 'uuid' && typeof val === 'string') {\n allPossibleIDTypes.push(val, parseInt(val))\n } else if (typeof val === 'string') {\n allPossibleIDTypes.push(val)\n } else {\n allPossibleIDTypes.push(val, String(val))\n }\n })\n formattedValue = allPossibleIDTypes\n }\n\n // Cast incoming values as proper searchable types\n if (field.type === 'checkbox' && typeof val === 'string') {\n if (val.toLowerCase() === 'true') {\n formattedValue = true\n }\n if (val.toLowerCase() === 'false') {\n formattedValue = false\n }\n }\n\n if (['all', 'in', 'not_in'].includes(operator)) {\n if (typeof formattedValue === 'string') {\n formattedValue = createArrayFromCommaDelineated(formattedValue)\n\n if (field.type === 'number') {\n formattedValue = formattedValue.map((arrayVal) => parseFloat(arrayVal))\n }\n } else if (typeof formattedValue === 'number') {\n formattedValue = [formattedValue]\n }\n\n if (!Array.isArray(formattedValue)) {\n return null\n }\n }\n\n if (field.type === 'number' && typeof formattedValue === 'string') {\n formattedValue = Number(val)\n\n if (Number.isNaN(formattedValue)) {\n formattedValue = null\n }\n }\n\n if (isUUID && typeof formattedValue === 'string') {\n if (!uuidValidate(val)) {\n formattedValue = null\n }\n }\n\n // Helper function to convert a single date value to ISO string\n const convertDateToISO = (item: unknown): unknown => {\n if (typeof item === 'string') {\n if (item === 'null' || item === '') {\n return null\n }\n const date = new Date(item)\n return Number.isNaN(date.getTime()) ? undefined : date.toISOString()\n } else if (typeof item === 'number') {\n return new Date(item).toISOString()\n } else if (item instanceof Date) {\n return item.toISOString()\n }\n return item\n }\n\n if (field.type === 'date' && operator !== 'exists') {\n if (Array.isArray(formattedValue)) {\n // Handle arrays of dates for 'in' and 'not_in' operators\n formattedValue = formattedValue.map(convertDateToISO).filter((item) => item !== undefined)\n } else {\n const converted = convertDateToISO(val)\n if (converted === undefined) {\n return { operator, value: undefined }\n }\n formattedValue = converted\n }\n }\n\n if (field.type === 'relationship' || field.type === 'upload') {\n if (val === 'null') {\n formattedValue = null\n } else if (!(formattedValue === null || typeof formattedValue === 'boolean')) {\n // convert the value to the idType of the relationship\n let idType: 'number' | 'text'\n if (typeof field.relationTo === 'string') {\n idType = getCollectionIdType({\n adapter,\n collection: adapter.payload.collections[field.relationTo],\n })\n } else {\n if (isPolymorphicRelationship(val)) {\n if (operator !== 'equals') {\n throw new APIError(\n `Only 'equals' operator is supported for polymorphic relationship object notation. Given - ${operator}`,\n )\n }\n idType = getCollectionIdType({\n adapter,\n collection: adapter.payload.collections[val.relationTo],\n })\n\n if (isRawConstraint(val.value)) {\n return {\n operator,\n value: val.value.value,\n }\n }\n return {\n operator,\n value: idType === 'number' ? Number(val.value) : String(val.value),\n }\n }\n\n formattedColumns = columns\n .map(({ idType, rawColumn }) => {\n let formattedValue: number | number[] | string | string[]\n\n if (Array.isArray(val)) {\n formattedValue = val\n .map((eachVal) => {\n let formattedValue: number | string\n\n if (idType === 'number') {\n formattedValue = Number(eachVal)\n\n if (Number.isNaN(formattedValue)) {\n return null\n }\n } else {\n if (idType === 'uuid' && !uuidValidate(eachVal)) {\n return null\n }\n\n formattedValue = String(eachVal)\n }\n\n return formattedValue\n })\n .filter(Boolean) as number[] | string[]\n } else if (idType === 'number') {\n formattedValue = Number(val)\n\n if (Number.isNaN(formattedValue)) {\n return null\n }\n } else {\n formattedValue = String(val)\n }\n\n return {\n rawColumn,\n value: formattedValue,\n }\n })\n .filter(Boolean)\n }\n if (Array.isArray(formattedValue)) {\n formattedValue = formattedValue.map((value) => {\n if (idType === 'number') {\n return Number(value)\n }\n if (idType === 'text') {\n return String(value)\n }\n return value\n })\n } else {\n if (idType === 'number') {\n formattedValue = Number(val)\n }\n if (idType === 'text') {\n formattedValue = String(val)\n }\n }\n }\n }\n\n // For hasMany relationship/upload fields, contains should use equals operator\n if (\n 'hasMany' in field &&\n field.hasMany &&\n operator === 'contains' &&\n (field.type === 'relationship' || field.type === 'upload')\n ) {\n operator = 'equals'\n }\n\n if (operator === 'near' && field.type === 'point' && typeof formattedValue === 'string') {\n const [lng, lat, maxDistance, minDistance] = formattedValue.split(',')\n\n formattedValue = [Number(lng), Number(lat), Number(maxDistance), Number(minDistance)]\n }\n\n if (operator === 'contains') {\n // Handle array values for hasMany text/number/select fields\n if (\n Array.isArray(formattedValue) &&\n 'hasMany' in field &&\n field.hasMany &&\n ['number', 'select', 'text'].includes(field.type)\n ) {\n // For hasMany text/number/select fields with array values, wrap each element with % for LIKE matching\n formattedValue = formattedValue.map((val) => `%${val}%`)\n } else if (!Array.isArray(formattedValue)) {\n // For non-array values, wrap with % for LIKE matching\n formattedValue = `%${formattedValue}%`\n }\n }\n\n if (operator === 'exists') {\n formattedValue = val === 'true' || val === true\n\n if (formattedValue) {\n operator = 'exists'\n } else {\n operator = 'isNull'\n }\n }\n\n return {\n columns: formattedColumns,\n operator,\n value: formattedValue,\n }\n}\n"],"names":["APIError","createArrayFromCommaDelineated","fieldAffectsData","validate","uuidValidate","getCollectionIdType","isPolymorphicRelationship","isRawConstraint","sanitizeQueryValue","adapter","columns","field","isUUID","operator","operatorArg","relationOrPath","val","formattedValue","formattedColumns","value","type","endsWith","Array","isArray","allPossibleIDTypes","forEach","idType","push","parseInt","String","toLowerCase","includes","map","arrayVal","parseFloat","Number","isNaN","convertDateToISO","item","date","Date","getTime","undefined","toISOString","filter","converted","relationTo","collection","payload","collections","rawColumn","eachVal","Boolean","hasMany","lng","lat","maxDistance","minDistance","split"],"mappings":"AAEA,SAASA,QAAQ,EAAEC,8BAA8B,QAAqC,UAAS;AAC/F,SAASC,gBAAgB,QAAQ,iBAAgB;AACjD,SAASC,YAAYC,YAAY,QAAQ,OAAM;AAI/C,SAASC,mBAAmB,QAAQ,sCAAqC;AACzE,SAASC,yBAAyB,QAAQ,4CAA2C;AACrF,SAASC,eAAe,QAAQ,gCAA+B;AAoB/D,OAAO,MAAMC,qBAAqB,CAAC,EACjCC,OAAO,EACPC,OAAO,EACPC,KAAK,EACLC,MAAM,EACNC,UAAUC,WAAW,EACrBC,cAAc,EACdC,GAAG,EACoB;IAKvB,IAAIH,WAAWC;IACf,IAAIG,iBAAiBD;IACrB,IAAIE;IAEJ,IAAI,CAAChB,iBAAiBS,QAAQ;QAC5B,OAAO;YAAEE;YAAUM,OAAOF;QAAe;IAC3C;IAEA,IAAIV,gBAAgBS,MAAM;QACxB,OAAO;YAAEH;YAAUM,OAAOH,IAAIG,KAAK;QAAC;IACtC;IACA,IACE,AAACR,CAAAA,MAAMS,IAAI,KAAK,kBAAkBT,MAAMS,IAAI,KAAK,QAAO,KACxD,CAACL,eAAeM,QAAQ,CAAC,iBACzBC,MAAMC,OAAO,CAACN,iBACd;QACA,MAAMO,qBAA0C,EAAE;QAClDP,eAAeQ,OAAO,CAAC,CAACT;YACtB,IAAIP,QAAQiB,MAAM,KAAK,UAAU,OAAOV,QAAQ,UAAU;gBACxDQ,mBAAmBG,IAAI,CAACX,KAAKY,SAASZ;YACxC,OAAO,IAAI,OAAOA,QAAQ,UAAU;gBAClCQ,mBAAmBG,IAAI,CAACX;YAC1B,OAAO;gBACLQ,mBAAmBG,IAAI,CAACX,KAAKa,OAAOb;YACtC;QACF;QACAC,iBAAiBO;IACnB;IAEA,kDAAkD;IAClD,IAAIb,MAAMS,IAAI,KAAK,cAAc,OAAOJ,QAAQ,UAAU;QACxD,IAAIA,IAAIc,WAAW,OAAO,QAAQ;YAChCb,iBAAiB;QACnB;QACA,IAAID,IAAIc,WAAW,OAAO,SAAS;YACjCb,iBAAiB;QACnB;IACF;IAEA,IAAI;QAAC;QAAO;QAAM;KAAS,CAACc,QAAQ,CAAClB,WAAW;QAC9C,IAAI,OAAOI,mBAAmB,UAAU;YACtCA,iBAAiBhB,+BAA+BgB;YAEhD,IAAIN,MAAMS,IAAI,KAAK,UAAU;gBAC3BH,iBAAiBA,eAAee,GAAG,CAAC,CAACC,WAAaC,WAAWD;YAC/D;QACF,OAAO,IAAI,OAAOhB,mBAAmB,UAAU;YAC7CA,iBAAiB;gBAACA;aAAe;QACnC;QAEA,IAAI,CAACK,MAAMC,OAAO,CAACN,iBAAiB;YAClC,OAAO;QACT;IACF;IAEA,IAAIN,MAAMS,IAAI,KAAK,YAAY,OAAOH,mBAAmB,UAAU;QACjEA,iBAAiBkB,OAAOnB;QAExB,IAAImB,OAAOC,KAAK,CAACnB,iBAAiB;YAChCA,iBAAiB;QACnB;IACF;IAEA,IAAIL,UAAU,OAAOK,mBAAmB,UAAU;QAChD,IAAI,CAACb,aAAaY,MAAM;YACtBC,iBAAiB;QACnB;IACF;IAEA,+DAA+D;IAC/D,MAAMoB,mBAAmB,CAACC;QACxB,IAAI,OAAOA,SAAS,UAAU;YAC5B,IAAIA,SAAS,UAAUA,SAAS,IAAI;gBAClC,OAAO;YACT;YACA,MAAMC,OAAO,IAAIC,KAAKF;YACtB,OAAOH,OAAOC,KAAK,CAACG,KAAKE,OAAO,MAAMC,YAAYH,KAAKI,WAAW;QACpE,OAAO,IAAI,OAAOL,SAAS,UAAU;YACnC,OAAO,IAAIE,KAAKF,MAAMK,WAAW;QACnC,OAAO,IAAIL,gBAAgBE,MAAM;YAC/B,OAAOF,KAAKK,WAAW;QACzB;QACA,OAAOL;IACT;IAEA,IAAI3B,MAAMS,IAAI,KAAK,UAAUP,aAAa,UAAU;QAClD,IAAIS,MAAMC,OAAO,CAACN,iBAAiB;YACjC,yDAAyD;YACzDA,iBAAiBA,eAAee,GAAG,CAACK,kBAAkBO,MAAM,CAAC,CAACN,OAASA,SAASI;QAClF,OAAO;YACL,MAAMG,YAAYR,iBAAiBrB;YACnC,IAAI6B,cAAcH,WAAW;gBAC3B,OAAO;oBAAE7B;oBAAUM,OAAOuB;gBAAU;YACtC;YACAzB,iBAAiB4B;QACnB;IACF;IAEA,IAAIlC,MAAMS,IAAI,KAAK,kBAAkBT,MAAMS,IAAI,KAAK,UAAU;QAC5D,IAAIJ,QAAQ,QAAQ;YAClBC,iBAAiB;QACnB,OAAO,IAAI,CAAEA,CAAAA,mBAAmB,QAAQ,OAAOA,mBAAmB,SAAQ,GAAI;YAC5E,sDAAsD;YACtD,IAAIS;YACJ,IAAI,OAAOf,MAAMmC,UAAU,KAAK,UAAU;gBACxCpB,SAASrB,oBAAoB;oBAC3BI;oBACAsC,YAAYtC,QAAQuC,OAAO,CAACC,WAAW,CAACtC,MAAMmC,UAAU,CAAC;gBAC3D;YACF,OAAO;gBACL,IAAIxC,0BAA0BU,MAAM;oBAClC,IAAIH,aAAa,UAAU;wBACzB,MAAM,IAAIb,SACR,CAAC,0FAA0F,EAAEa,UAAU;oBAE3G;oBACAa,SAASrB,oBAAoB;wBAC3BI;wBACAsC,YAAYtC,QAAQuC,OAAO,CAACC,WAAW,CAACjC,IAAI8B,UAAU,CAAC;oBACzD;oBAEA,IAAIvC,gBAAgBS,IAAIG,KAAK,GAAG;wBAC9B,OAAO;4BACLN;4BACAM,OAAOH,IAAIG,KAAK,CAACA,KAAK;wBACxB;oBACF;oBACA,OAAO;wBACLN;wBACAM,OAAOO,WAAW,WAAWS,OAAOnB,IAAIG,KAAK,IAAIU,OAAOb,IAAIG,KAAK;oBACnE;gBACF;gBAEAD,mBAAmBR,QAChBsB,GAAG,CAAC,CAAC,EAAEN,MAAM,EAAEwB,SAAS,EAAE;oBACzB,IAAIjC;oBAEJ,IAAIK,MAAMC,OAAO,CAACP,MAAM;wBACtBC,iBAAiBD,IACdgB,GAAG,CAAC,CAACmB;4BACJ,IAAIlC;4BAEJ,IAAIS,WAAW,UAAU;gCACvBT,iBAAiBkB,OAAOgB;gCAExB,IAAIhB,OAAOC,KAAK,CAACnB,iBAAiB;oCAChC,OAAO;gCACT;4BACF,OAAO;gCACL,IAAIS,WAAW,UAAU,CAACtB,aAAa+C,UAAU;oCAC/C,OAAO;gCACT;gCAEAlC,iBAAiBY,OAAOsB;4BAC1B;4BAEA,OAAOlC;wBACT,GACC2B,MAAM,CAACQ;oBACZ,OAAO,IAAI1B,WAAW,UAAU;wBAC9BT,iBAAiBkB,OAAOnB;wBAExB,IAAImB,OAAOC,KAAK,CAACnB,iBAAiB;4BAChC,OAAO;wBACT;oBACF,OAAO;wBACLA,iBAAiBY,OAAOb;oBAC1B;oBAEA,OAAO;wBACLkC;wBACA/B,OAAOF;oBACT;gBACF,GACC2B,MAAM,CAACQ;YACZ;YACA,IAAI9B,MAAMC,OAAO,CAACN,iBAAiB;gBACjCA,iBAAiBA,eAAee,GAAG,CAAC,CAACb;oBACnC,IAAIO,WAAW,UAAU;wBACvB,OAAOS,OAAOhB;oBAChB;oBACA,IAAIO,WAAW,QAAQ;wBACrB,OAAOG,OAAOV;oBAChB;oBACA,OAAOA;gBACT;YACF,OAAO;gBACL,IAAIO,WAAW,UAAU;oBACvBT,iBAAiBkB,OAAOnB;gBAC1B;gBACA,IAAIU,WAAW,QAAQ;oBACrBT,iBAAiBY,OAAOb;gBAC1B;YACF;QACF;IACF;IAEA,8EAA8E;IAC9E,IACE,aAAaL,SACbA,MAAM0C,OAAO,IACbxC,aAAa,cACZF,CAAAA,MAAMS,IAAI,KAAK,kBAAkBT,MAAMS,IAAI,KAAK,QAAO,GACxD;QACAP,WAAW;IACb;IAEA,IAAIA,aAAa,UAAUF,MAAMS,IAAI,KAAK,WAAW,OAAOH,mBAAmB,UAAU;QACvF,MAAM,CAACqC,KAAKC,KAAKC,aAAaC,YAAY,GAAGxC,eAAeyC,KAAK,CAAC;QAElEzC,iBAAiB;YAACkB,OAAOmB;YAAMnB,OAAOoB;YAAMpB,OAAOqB;YAAcrB,OAAOsB;SAAa;IACvF;IAEA,IAAI5C,aAAa,YAAY;QAC3B,4DAA4D;QAC5D,IACES,MAAMC,OAAO,CAACN,mBACd,aAAaN,SACbA,MAAM0C,OAAO,IACb;YAAC;YAAU;YAAU;SAAO,CAACtB,QAAQ,CAACpB,MAAMS,IAAI,GAChD;YACA,sGAAsG;YACtGH,iBAAiBA,eAAee,GAAG,CAAC,CAAChB,MAAQ,CAAC,CAAC,EAAEA,IAAI,CAAC,CAAC;QACzD,OAAO,IAAI,CAACM,MAAMC,OAAO,CAACN,iBAAiB;YACzC,sDAAsD;YACtDA,iBAAiB,CAAC,CAAC,EAAEA,eAAe,CAAC,CAAC;QACxC;IACF;IAEA,IAAIJ,aAAa,UAAU;QACzBI,iBAAiBD,QAAQ,UAAUA,QAAQ;QAE3C,IAAIC,gBAAgB;YAClBJ,WAAW;QACb,OAAO;YACLA,WAAW;QACb;IACF;IAEA,OAAO;QACLH,SAASQ;QACTL;QACAM,OAAOF;IACT;AACF,EAAC"}
1
+ {"version":3,"sources":["../../src/queries/sanitizeQueryValue.ts"],"sourcesContent":["import type { SQL } from 'drizzle-orm'\n\nimport { APIError, createArrayFromCommaDelineated, type Field, type TabAsField } from 'payload'\nimport { fieldAffectsData } from 'payload/shared'\nimport { validate as uuidValidate } from 'uuid'\n\nimport type { DrizzleAdapter } from '../types.js'\n\nimport { getCollectionIdType } from '../utilities/getCollectionIdType.js'\nimport { isPolymorphicRelationship } from '../utilities/isPolymorphicRelationship.js'\nimport { isRawConstraint } from '../utilities/rawConstraint.js'\n\ntype SanitizeQueryValueArgs = {\n adapter: DrizzleAdapter\n columns?: {\n idType: 'number' | 'text' | 'uuid'\n rawColumn: SQL<unknown>\n }[]\n field: Field | TabAsField\n isUUID: boolean\n operator: string\n relationOrPath: string\n val: any\n}\n\ntype SanitizedColumn = {\n rawColumn: SQL<unknown>\n value: unknown\n}\n\nexport const sanitizeQueryValue = ({\n adapter,\n columns,\n field,\n isUUID,\n operator: operatorArg,\n relationOrPath,\n val,\n}: SanitizeQueryValueArgs): {\n columns?: SanitizedColumn[]\n operator: string\n value: unknown\n} => {\n let operator = operatorArg\n let formattedValue = val\n let formattedColumns: SanitizedColumn[]\n\n if (!fieldAffectsData(field)) {\n return { operator, value: formattedValue }\n }\n\n if (isRawConstraint(val)) {\n return { operator, value: val.value }\n }\n if (\n (field.type === 'relationship' || field.type === 'upload') &&\n !relationOrPath.endsWith('relationTo') &&\n Array.isArray(formattedValue)\n ) {\n const allPossibleIDTypes: (number | string)[] = []\n formattedValue.forEach((val) => {\n if (adapter.idType !== 'uuid' && typeof val === 'string') {\n allPossibleIDTypes.push(val, parseInt(val))\n } else if (typeof val === 'string') {\n allPossibleIDTypes.push(val)\n } else {\n allPossibleIDTypes.push(val, String(val))\n }\n })\n formattedValue = allPossibleIDTypes\n }\n\n // Cast incoming values as proper searchable types\n if (field.type === 'checkbox' && typeof val === 'string') {\n if (val.toLowerCase() === 'true') {\n formattedValue = true\n }\n if (val.toLowerCase() === 'false') {\n formattedValue = false\n }\n }\n\n if (['all', 'in', 'not_in'].includes(operator)) {\n if (typeof formattedValue === 'string') {\n formattedValue = createArrayFromCommaDelineated(formattedValue)\n\n if (field.type === 'number') {\n formattedValue = formattedValue.map((arrayVal) => parseFloat(arrayVal))\n }\n } else if (typeof formattedValue === 'number') {\n formattedValue = [formattedValue]\n }\n\n if (!Array.isArray(formattedValue)) {\n return null\n }\n }\n\n if (field.type === 'number' && typeof formattedValue === 'string') {\n formattedValue = Number(val)\n\n if (Number.isNaN(formattedValue)) {\n formattedValue = null\n }\n }\n\n if (isUUID && typeof formattedValue === 'string') {\n if (!uuidValidate(val)) {\n formattedValue = null\n }\n }\n\n // Helper function to convert a single date value to ISO string\n const convertDateToISO = (item: unknown): unknown => {\n if (typeof item === 'string') {\n if (item === 'null' || item === '') {\n return null\n }\n const date = new Date(item)\n return Number.isNaN(date.getTime()) ? undefined : date.toISOString()\n } else if (typeof item === 'number') {\n return new Date(item).toISOString()\n } else if (item instanceof Date) {\n return item.toISOString()\n }\n return item\n }\n\n if (field.type === 'date' && operator !== 'exists') {\n if (Array.isArray(formattedValue)) {\n // Handle arrays of dates for 'in' and 'not_in' operators\n formattedValue = formattedValue.map(convertDateToISO).filter((item) => item !== undefined)\n } else {\n const converted = convertDateToISO(val)\n if (converted === undefined) {\n return { operator, value: undefined }\n }\n formattedValue = converted\n }\n }\n\n if (field.type === 'relationship' || field.type === 'upload') {\n if (val === 'null') {\n formattedValue = null\n } else if (!(formattedValue === null || typeof formattedValue === 'boolean')) {\n // convert the value to the idType of the relationship\n let idType: 'number' | 'text'\n if (typeof field.relationTo === 'string') {\n idType = getCollectionIdType({\n adapter,\n collection: adapter.payload.collections[field.relationTo],\n })\n } else {\n if (isPolymorphicRelationship(val)) {\n if (operator !== 'equals') {\n throw new APIError(\n `Only 'equals' operator is supported for polymorphic relationship object notation. Given - ${operator}`,\n )\n }\n idType = getCollectionIdType({\n adapter,\n collection: adapter.payload.collections[val.relationTo],\n })\n\n if (isRawConstraint(val.value)) {\n return {\n operator,\n value: val.value.value,\n }\n }\n return {\n operator,\n value: idType === 'number' ? Number(val.value) : String(val.value),\n }\n }\n\n formattedColumns = columns\n .map(({ idType, rawColumn }) => {\n let formattedValue: number | number[] | string | string[]\n\n if (Array.isArray(val)) {\n formattedValue = val\n .map((eachVal) => {\n let formattedValue: number | string\n\n if (idType === 'number') {\n formattedValue = Number(eachVal)\n\n if (Number.isNaN(formattedValue)) {\n return null\n }\n } else {\n if (idType === 'uuid' && !uuidValidate(eachVal)) {\n return null\n }\n\n formattedValue = String(eachVal)\n }\n\n return formattedValue\n })\n .filter(Boolean) as number[] | string[]\n } else if (idType === 'number') {\n formattedValue = Number(val)\n\n if (Number.isNaN(formattedValue)) {\n return null\n }\n } else {\n formattedValue = String(val)\n }\n\n return {\n rawColumn,\n value: formattedValue,\n }\n })\n .filter(Boolean)\n }\n if (Array.isArray(formattedValue)) {\n formattedValue = formattedValue.map((value) => {\n if (idType === 'number') {\n return Number(value)\n }\n if (idType === 'text') {\n return String(value)\n }\n return value\n })\n } else {\n if (idType === 'number') {\n formattedValue = Number(val)\n }\n if (idType === 'text') {\n formattedValue = String(val)\n }\n }\n }\n }\n\n // hasMany relationship/upload/select fields are stored as separate rows in a join table.\n // The JOIN already gives us individual rows, so \"contains\" becomes an equality check on each row's value.\n if (\n 'hasMany' in field &&\n field.hasMany &&\n operator === 'contains' &&\n (field.type === 'relationship' || field.type === 'upload' || field.type === 'select')\n ) {\n operator = 'equals'\n }\n\n if (operator === 'near' && field.type === 'point' && typeof formattedValue === 'string') {\n const [lng, lat, maxDistance, minDistance] = formattedValue.split(',')\n\n formattedValue = [Number(lng), Number(lat), Number(maxDistance), Number(minDistance)]\n }\n\n if (operator === 'contains') {\n // Handle array values for hasMany text/number/select fields\n if (\n Array.isArray(formattedValue) &&\n 'hasMany' in field &&\n field.hasMany &&\n ['number', 'text'].includes(field.type)\n ) {\n // For hasMany text/number/select fields with array values, wrap each element with % for LIKE matching\n formattedValue = formattedValue.map((val) => `%${val}%`)\n } else if (!Array.isArray(formattedValue)) {\n // For non-array values, wrap with % for LIKE matching\n formattedValue = `%${formattedValue}%`\n }\n }\n\n if (operator === 'exists') {\n formattedValue = val === 'true' || val === true\n\n if (formattedValue) {\n operator = 'exists'\n } else {\n operator = 'isNull'\n }\n }\n\n return {\n columns: formattedColumns,\n operator,\n value: formattedValue,\n }\n}\n"],"names":["APIError","createArrayFromCommaDelineated","fieldAffectsData","validate","uuidValidate","getCollectionIdType","isPolymorphicRelationship","isRawConstraint","sanitizeQueryValue","adapter","columns","field","isUUID","operator","operatorArg","relationOrPath","val","formattedValue","formattedColumns","value","type","endsWith","Array","isArray","allPossibleIDTypes","forEach","idType","push","parseInt","String","toLowerCase","includes","map","arrayVal","parseFloat","Number","isNaN","convertDateToISO","item","date","Date","getTime","undefined","toISOString","filter","converted","relationTo","collection","payload","collections","rawColumn","eachVal","Boolean","hasMany","lng","lat","maxDistance","minDistance","split"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@payloadcms/drizzle",
3
- "version": "3.80.0-canary.1",
3
+ "version": "3.80.0-canary.2",
4
4
  "description": "A library of shared functions used by different payload database adapters",
5
5
  "homepage": "https://payloadcms.com",
6
6
  "repository": {
@@ -60,10 +60,10 @@
60
60
  "@types/pg": "8.10.2",
61
61
  "@types/to-snake-case": "1.0.0",
62
62
  "@payloadcms/eslint-config": "3.28.0",
63
- "payload": "3.80.0-canary.1"
63
+ "payload": "3.80.0-canary.2"
64
64
  },
65
65
  "peerDependencies": {
66
- "payload": "3.80.0-canary.1"
66
+ "payload": "3.80.0-canary.2"
67
67
  },
68
68
  "scripts": {
69
69
  "build": "pnpm build:swc && pnpm build:types",