@payloadcms/drizzle 4.0.0-canary.33 → 4.0.0-canary.34
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.
- package/dist/find/buildPolymorphicJoinQuery.d.ts +38 -0
- package/dist/find/buildPolymorphicJoinQuery.d.ts.map +1 -0
- package/dist/find/buildPolymorphicJoinQuery.js +135 -0
- package/dist/find/buildPolymorphicJoinQuery.js.map +1 -0
- package/dist/find/buildPolymorphicJoinQuery.spec.js +384 -0
- package/dist/find/buildPolymorphicJoinQuery.spec.js.map +1 -0
- package/dist/find/buildPolymorphicJoinWhere.d.ts +20 -0
- package/dist/find/buildPolymorphicJoinWhere.d.ts.map +1 -0
- package/dist/find/buildPolymorphicJoinWhere.js +301 -0
- package/dist/find/buildPolymorphicJoinWhere.js.map +1 -0
- package/dist/find/buildPolymorphicJoinWhere.spec.js +805 -0
- package/dist/find/buildPolymorphicJoinWhere.spec.js.map +1 -0
- package/dist/find/createPolymorphicJoinWherePlan.d.ts +37 -0
- package/dist/find/createPolymorphicJoinWherePlan.d.ts.map +1 -0
- package/dist/find/createPolymorphicJoinWherePlan.js +191 -0
- package/dist/find/createPolymorphicJoinWherePlan.js.map +1 -0
- package/dist/find/createPolymorphicJoinWherePlan.spec.js +778 -0
- package/dist/find/createPolymorphicJoinWherePlan.spec.js.map +1 -0
- package/dist/find/traverseFields.d.ts.map +1 -1
- package/dist/find/traverseFields.js +19 -191
- package/dist/find/traverseFields.js.map +1 -1
- package/dist/postgres/createJSONQuery/index.js +3 -3
- package/dist/postgres/createJSONQuery/index.js.map +1 -1
- package/dist/queries/getTableColumnFromPath.d.ts.map +1 -1
- package/dist/queries/getTableColumnFromPath.js +9 -0
- package/dist/queries/getTableColumnFromPath.js.map +1 -1
- package/dist/queries/parseParams.d.ts.map +1 -1
- package/dist/queries/parseParams.js +59 -2
- package/dist/queries/parseParams.js.map +1 -1
- package/dist/sqlite/createJSONQuery/convertPathToJSONTraversal.js +3 -2
- package/dist/sqlite/createJSONQuery/convertPathToJSONTraversal.js.map +1 -1
- package/dist/sqlite/createJSONQuery/index.d.ts.map +1 -1
- package/dist/sqlite/createJSONQuery/index.js +6 -5
- package/dist/sqlite/createJSONQuery/index.js.map +1 -1
- package/dist/transform/write/traverseFields.d.ts.map +1 -1
- package/dist/transform/write/traverseFields.js +5 -14
- package/dist/transform/write/traverseFields.js.map +1 -1
- package/dist/updateOne.d.ts.map +1 -1
- package/dist/updateOne.js +41 -1
- package/dist/updateOne.js.map +1 -1
- package/dist/updateOne.spec.js +84 -0
- package/dist/updateOne.spec.js.map +1 -0
- package/dist/upsertRow/conditionalUpdate.spec.js +61 -0
- package/dist/upsertRow/conditionalUpdate.spec.js.map +1 -0
- package/dist/upsertRow/index.d.ts +1 -1
- package/dist/upsertRow/index.d.ts.map +1 -1
- package/dist/upsertRow/index.js +25 -5
- package/dist/upsertRow/index.js.map +1 -1
- package/dist/utilities/parseJSONPathSegment.d.ts +9 -0
- package/dist/utilities/parseJSONPathSegment.d.ts.map +1 -0
- package/dist/utilities/parseJSONPathSegment.js +17 -0
- package/dist/utilities/parseJSONPathSegment.js.map +1 -0
- package/package.json +3 -3
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/find/buildPolymorphicJoinWhere.spec.ts"],"sourcesContent":["import type { Client } from '@libsql/client'\nimport type { FlattenedField, Where } from 'payload'\n\nimport { createClient } from '@libsql/client'\nimport { like, notLike } from 'drizzle-orm'\nimport { drizzle } from 'drizzle-orm/libsql'\nimport { integer, sqliteTable, text } from 'drizzle-orm/sqlite-core'\nimport { afterAll, describe, expect, it, vi } from 'vitest'\n\nimport type { DrizzleAdapter, DrizzleOperandTransformHandler } from '../types.js'\nimport type { PolymorphicJoinWherePlan } from './createPolymorphicJoinWherePlan.js'\n\nimport { operatorMap } from '../queries/operatorMap.js'\nimport { createJSONQuery } from '../sqlite/createJSONQuery/index.js'\nimport { buildPolymorphicJoinWhere } from './buildPolymorphicJoinWhere.js'\n\nconst articlesTable = sqliteTable('join_articles', {\n id: integer('id').primaryKey(),\n parent: integer('parent_id'),\n score: integer('score'),\n title: text('title'),\n})\n\nconst notesTable = sqliteTable('join_notes', {\n id: integer('id').primaryKey(),\n parent: integer('parent_id'),\n title: text('title'),\n})\n\nconst client: Client = createClient({ url: 'file::memory:' })\nconst db = drizzle(client, { schema: { articlesTable, notesTable } })\nconst textField = { name: 'title', type: 'text' } as FlattenedField\nconst numberField = { name: 'score', type: 'number' } as FlattenedField\nconst hasManySelectField = {\n hasMany: true,\n name: 'tags',\n options: ['available', 'reviewed'],\n type: 'select',\n} as FlattenedField\n\nconst adapter = {\n createJSONQuery,\n drizzle: db,\n idType: 'serial',\n name: 'sqlite',\n operatorHandlers: [],\n operators: {\n ...operatorMap,\n contains: like,\n like,\n not_like: notLike,\n },\n payload: { collections: {} },\n tableNameMap: new Map([\n ['articles_tags', 'join_articles_tags'],\n ['notes_tags', 'join_notes_tags'],\n ]),\n tables: {\n join_articles: articlesTable,\n join_notes: notesTable,\n },\n} as unknown as DrizzleAdapter\n\nconst scalarPlan = ({\n collections = ['articles'],\n columnPath,\n field = textField,\n schemaPath = columnPath,\n}: {\n collections?: string[]\n columnPath: string\n field?: FlattenedField\n schemaPath?: string\n}): PolymorphicJoinWherePlan =>\n new Map([\n [\n schemaPath,\n {\n columnPath,\n fieldsByCollection: new Map(\n collections.map((collection) => [\n collection,\n { field, isUUID: false, type: 'scalar' as const },\n ]),\n ),\n schemaPath,\n type: 'scalar',\n },\n ],\n ])\n\nconst hasManySelectPlan = (\n collections = ['articles'],\n schemaPath = 'tags',\n): PolymorphicJoinWherePlan =>\n new Map([\n [\n schemaPath,\n {\n columnPath: schemaPath.replaceAll('.', '_'),\n fieldsByCollection: new Map(\n collections.map((collection) => [\n collection,\n { field: hasManySelectField, type: 'hasManySelect' as const },\n ]),\n ),\n schemaPath,\n type: 'hasManySelect',\n },\n ],\n ])\n\nconst renderWhere = ({\n collection = 'articles',\n table = articlesTable,\n where,\n wherePlan,\n}: {\n collection?: string\n table?: typeof articlesTable | typeof notesTable\n where: Where\n wherePlan: PolymorphicJoinWherePlan\n}) => {\n const condition = buildPolymorphicJoinWhere({\n adapter,\n collection,\n table,\n where,\n wherePlan,\n })\n\n return db.select({ id: table.id }).from(table).where(condition).toSQL()\n}\n\nafterAll(() => client.close())\n\ndescribe('buildPolymorphicJoinWhere', () => {\n it('builds scalar comparisons and preserves nested AND and OR groups', () => {\n const wherePlan = scalarPlan({ columnPath: 'title', collections: ['articles', 'notes'] })\n const query = renderWhere({\n where: {\n AND: [\n { title: { equals: 'available' } },\n { OR: [{ title: { equals: 'reviewed' } }, { title: { equals: 'published' } }] },\n ],\n },\n wherePlan,\n })\n\n expect(query.sql).toContain('where (\"join_articles\".\"title\" = ? and')\n expect(query.sql).toContain('or')\n expect(query.params).toEqual(['available', 'reviewed', 'published'])\n })\n\n it('treats a numeric like comparison as equality', () => {\n const query = renderWhere({\n where: { score: { like: '5' } },\n wherePlan: scalarPlan({ columnPath: 'score', field: numberField }),\n })\n\n expect(query.sql).toContain('\"join_articles\".\"score\" = ?')\n expect(query.params).toEqual([5])\n })\n\n it('uses SQL NULL for a scalar field that is absent from the current collection', () => {\n const query = renderWhere({\n collection: 'notes',\n table: notesTable,\n where: { score: { exists: false } },\n wherePlan: scalarPlan({ columnPath: 'score', collections: ['articles'], field: numberField }),\n })\n\n expect(query.sql).toContain('where null is null')\n expect(query.params).toEqual([])\n })\n\n it.each([\n ['exists', { exists: 'false' }, 'where null is null', []],\n ['in', { in: '1,2' }, 'where null in (?, ?)', [1, 2]],\n ] as const)(\n 'normalizes a REST %s value when a scalar field is absent from the current collection',\n (_operator, constraint, expectedSQL, expectedParams) => {\n const query = renderWhere({\n collection: 'notes',\n table: notesTable,\n where: { score: constraint } as unknown as Where,\n wherePlan: scalarPlan({\n columnPath: 'score',\n collections: ['articles'],\n field: numberField,\n }),\n })\n\n expect(query.sql).toContain(expectedSQL)\n expect(query.params).toEqual(expectedParams)\n },\n )\n\n it('keeps contains wildcard handling when a scalar field is absent', () => {\n const query = renderWhere({\n collection: 'notes',\n table: notesTable,\n where: { score: { contains: '5' } },\n wherePlan: scalarPlan({ columnPath: 'score', collections: ['articles'], field: numberField }),\n })\n\n expect(query.sql).toContain('where null like ?')\n expect(query.params).toEqual(['%5%'])\n })\n\n it('compares relationTo with the current collection slug', () => {\n const wherePlan: PolymorphicJoinWherePlan = new Map([\n [\n 'relationTo',\n {\n columnPath: 'relationTo',\n fieldsByCollection: new Map(),\n schemaPath: 'relationTo',\n type: 'scalar',\n },\n ],\n ])\n const query = renderWhere({\n collection: 'notes',\n table: notesTable,\n where: { relationTo: { equals: 'notes' } },\n wherePlan,\n })\n\n expect(query.sql).toContain('where ? = ?')\n expect(query.params).toEqual(['notes', 'notes'])\n })\n\n it.each([\n ['exists', { exists: 'false' }, 'where ? is null', ['notes']],\n ['in', { in: 'articles,notes' }, 'where ? in (?, ?)', ['notes', 'articles', 'notes']],\n ] as const)(\n 'normalizes a REST %s value for relationTo',\n (_operator, constraint, expectedSQL, expectedParams) => {\n const wherePlan: PolymorphicJoinWherePlan = new Map([\n [\n 'relationTo',\n {\n columnPath: 'relationTo',\n fieldsByCollection: new Map(),\n schemaPath: 'relationTo',\n type: 'scalar',\n },\n ],\n ])\n const query = renderWhere({\n collection: 'notes',\n table: notesTable,\n where: { relationTo: constraint } as unknown as Where,\n wherePlan,\n })\n\n expect(query.sql).toContain(expectedSQL)\n expect(query.params).toEqual(expectedParams)\n },\n )\n\n it.each([\n ['equals null', { title: { equals: null } }, '\"join_articles\".\"title\" is null', []],\n ['not_equals null', { title: { not_equals: null } }, '\"join_articles\".\"title\" is not null', []],\n [\n 'not_equals a value',\n { title: { not_equals: 'restricted' } },\n '\"join_articles\".\"title\" is null or \"join_articles\".\"title\" <> ?',\n ['restricted'],\n ],\n [\n 'in values including null',\n { title: { in: ['available', null] } },\n '\"join_articles\".\"title\" is null or \"join_articles\".\"title\" in (?)',\n ['available'],\n ],\n ] as const)('keeps null semantics for %s', (_description, where, expectedSQL, expectedParams) => {\n const query = renderWhere({\n where: where as unknown as Where,\n wherePlan: scalarPlan({ columnPath: 'title' }),\n })\n\n expect(query.sql).toContain(expectedSQL)\n expect(query.params).toEqual(expectedParams)\n })\n\n it('requires every word in a scalar like comparison', () => {\n const query = renderWhere({\n where: { title: { like: 'available child' } },\n wherePlan: scalarPlan({ columnPath: 'title' }),\n })\n\n expect(query.sql).toContain('\"join_articles\".\"title\" like ? and')\n expect(query.params).toEqual(['%available%', '%child%'])\n })\n\n it('applies configured operator handlers to scalar comparisons', () => {\n const transformOperands = vi.fn(({ column, value }) => ({\n column,\n value: `handled-${String(value)}`,\n }))\n const handler: DrizzleOperandTransformHandler = {\n name: 'prefix-value',\n operators: ['equals'],\n transformOperands,\n }\n const adapterWithHandler = {\n ...adapter,\n operatorHandlers: [handler],\n } as DrizzleAdapter\n const condition = buildPolymorphicJoinWhere({\n adapter: adapterWithHandler,\n collection: 'articles',\n table: articlesTable,\n where: { title: { equals: 'available' } },\n wherePlan: scalarPlan({ columnPath: 'title' }),\n })\n const query = db.select({ id: articlesTable.id }).from(articlesTable).where(condition).toSQL()\n\n expect(transformOperands).toHaveBeenCalledWith(\n expect.objectContaining({ path: 'title', resolvedOperator: 'equals', storage: 'column' }),\n )\n expect(query.params).toEqual(['handled-available'])\n })\n\n it('queries a has-many select through its value table', () => {\n const query = renderWhere({\n where: { tags: { contains: 'available' } },\n wherePlan: hasManySelectPlan(),\n })\n\n expect(query.sql).toContain('json_group_array(join_articles_tags.value)')\n expect(query.sql).toContain(\"value = 'available'\")\n })\n\n it.each([\n [\n 'a REST exists value',\n { exists: 'false' },\n ['NOT EXISTS (SELECT 1 FROM json_each(', 'AS tags_alias_0)'],\n ],\n [\n 'a comma-delimited REST in value',\n { in: 'available,reviewed' },\n [\"tags_alias_0.value = 'available'\", ' OR ', \"tags_alias_0.value = 'reviewed'\"],\n ],\n ] as const)('normalizes %s for has-many selects', (_description, constraint, fragments) => {\n const query = renderWhere({\n where: { tags: constraint } as unknown as Where,\n wherePlan: hasManySelectPlan(),\n })\n\n for (const fragment of fragments) {\n expect(query.sql).toContain(fragment)\n }\n })\n\n it.each([\n ['without a schema', undefined],\n ['with a schema', 'content'],\n ] as const)(\n 'rejects a missing has-many select value table mapping %s',\n (_description, schemaName) => {\n const adapterWithoutValueTable = {\n ...adapter,\n schemaName,\n tableNameMap: new Map(),\n } as unknown as DrizzleAdapter\n\n expect(() =>\n buildPolymorphicJoinWhere({\n adapter: adapterWithoutValueTable,\n collection: 'articles',\n table: articlesTable,\n where: { tags: { equals: 'available' } },\n wherePlan: hasManySelectPlan(),\n }),\n ).toThrow('Polymorphic join collection \"articles\" has no value table for \"tags\"')\n },\n )\n\n it('uses an empty JSON array when a has-many select is absent from this collection', () => {\n const query = renderWhere({\n collection: 'notes',\n table: notesTable,\n where: { tags: { exists: false } },\n wherePlan: hasManySelectPlan(['articles']),\n })\n\n expect(query.sql).toContain(\"json_each('[]')\")\n expect(query.sql).not.toContain('join_notes_tags')\n })\n\n it('builds a false condition for an empty has-many in comparison', () => {\n const query = renderWhere({\n where: { tags: { in: [] } },\n wherePlan: hasManySelectPlan(),\n })\n\n expect(query.sql).toContain('where false')\n })\n\n it('builds a false condition for an empty scalar in comparison', () => {\n const query = renderWhere({\n where: { title: { in: [] } },\n wherePlan: scalarPlan({ columnPath: 'title' }),\n })\n\n expect(query.sql).toContain('where false')\n })\n\n it.each([\n [\n 'a scalar in value that cannot be normalized',\n { title: { in: true } },\n scalarPlan({ columnPath: 'title' }),\n ],\n [\n 'an undefined scalar in value',\n { title: { in: undefined } },\n scalarPlan({ columnPath: 'title' }),\n ],\n [\n 'a has-many select in value that cannot be normalized',\n { tags: { in: true } },\n hasManySelectPlan(),\n ],\n ] as const)('rejects %s', (_description, where, wherePlan) => {\n expect(() =>\n renderWhere({\n where: where as unknown as Where,\n wherePlan,\n }),\n ).toThrow(Object.keys(where)[0] === 'tags' ? 'tags.in' : 'title.in')\n })\n\n it.each(['AND', 'OR'] as const)(\n 'rejects a value that cannot be normalized inside an %s group',\n (booleanOperator) => {\n expect(() =>\n renderWhere({\n where: {\n [booleanOperator]: [{ title: { in: true } }, { title: { equals: 'available' } }],\n } as unknown as Where,\n wherePlan: scalarPlan({ columnPath: 'title' }),\n }),\n ).toThrow('title.in')\n },\n )\n\n it.each([\n ['equals', { equals: 'available' }, [\"tags_alias_0.value = 'available'\"]],\n ['exists', { exists: true }, ['EXISTS (SELECT 1 FROM json_each(', 'AS tags_alias_0)']],\n [\n 'in',\n { in: ['available', 'reviewed'] },\n [\"tags_alias_0.value = 'available'\", ' OR ', \"tags_alias_0.value = 'reviewed'\"],\n ],\n ['like', { like: 'avail' }, [\"tags_alias_0.value like '%avail%'\"]],\n ] as const)(\n 'supports the %s operator for has-many selects',\n (_operator, constraint, expectedSQLFragments) => {\n const query = renderWhere({\n where: { tags: constraint } as unknown as Where,\n wherePlan: hasManySelectPlan(),\n })\n\n expect(query.sql).toContain('join_articles_tags')\n for (const expectedSQLFragment of expectedSQLFragments) {\n expect(query.sql).toContain(expectedSQLFragment)\n }\n expect(query.params).toEqual([])\n },\n )\n\n it('accepts a string $raw constraint', () => {\n const query = renderWhere({\n where: { title: { $raw: 'length(title) > 3' } } as unknown as Where,\n wherePlan: scalarPlan({ columnPath: 'title' }),\n })\n\n expect(query.sql).toContain('where length(title) > 3')\n })\n\n it.each([\n [\n 'an invalid path plan',\n { title: { equals: 'available' } },\n new Map([\n [\n 'title',\n {\n columnPath: 'title',\n fieldsByCollection: new Map(),\n schemaPath: 'title',\n type: 'invalid' as const,\n },\n ],\n ]),\n 'title.equals',\n ],\n ['a missing path plan', { title: { equals: 'available' } }, new Map(), 'title'],\n [\n 'an unsupported has-many operator',\n { tags: { not_equals: 'available' } },\n hasManySelectPlan(),\n 'tags.not_equals',\n ],\n [\n 'an unknown scalar operator',\n { title: { near: 'available' } },\n scalarPlan({ columnPath: 'title' }),\n 'title.near',\n ],\n [\n 'a non-string $raw value',\n { title: { $raw: 1 } },\n scalarPlan({ columnPath: 'title' }),\n 'title.$raw',\n ],\n ] as const)('rejects %s', (_description, where, wherePlan, errorPath) => {\n expect(() =>\n buildPolymorphicJoinWhere({\n adapter,\n collection: 'articles',\n table: articlesTable,\n where: where as unknown as Where,\n wherePlan: wherePlan as PolymorphicJoinWherePlan,\n }),\n ).toThrow(errorPath)\n })\n\n it('returns no condition for empty boolean groups', () => {\n expect(\n buildPolymorphicJoinWhere({\n adapter,\n collection: 'articles',\n table: articlesTable,\n where: { AND: [], OR: [] },\n wherePlan: new Map(),\n }),\n ).toBeUndefined()\n })\n\n it.each(['AND', 'OR'] as const)('rejects a malformed %s group', (operator) => {\n expect(() =>\n buildPolymorphicJoinWhere({\n adapter,\n collection: 'articles',\n table: articlesTable,\n where: { [operator]: 'not-an-array' } as unknown as Where,\n wherePlan: new Map(),\n }),\n ).toThrow(operator)\n })\n})\n"],"names":["createClient","like","notLike","drizzle","integer","sqliteTable","text","afterAll","describe","expect","it","vi","operatorMap","createJSONQuery","buildPolymorphicJoinWhere","articlesTable","id","primaryKey","parent","score","title","notesTable","client","url","db","schema","textField","name","type","numberField","hasManySelectField","hasMany","options","adapter","idType","operatorHandlers","operators","contains","not_like","payload","collections","tableNameMap","Map","tables","join_articles","join_notes","scalarPlan","columnPath","field","schemaPath","fieldsByCollection","map","collection","isUUID","hasManySelectPlan","replaceAll","renderWhere","table","where","wherePlan","condition","select","from","toSQL","close","query","AND","equals","OR","sql","toContain","params","toEqual","exists","each","in","_operator","constraint","expectedSQL","expectedParams","relationTo","not_equals","_description","transformOperands","fn","column","value","String","handler","adapterWithHandler","toHaveBeenCalledWith","objectContaining","path","resolvedOperator","storage","tags","fragments","fragment","undefined","schemaName","adapterWithoutValueTable","toThrow","not","Object","keys","booleanOperator","expectedSQLFragments","expectedSQLFragment","$raw","near","errorPath","toBeUndefined","operator"],"mappings":"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"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { type FlattenedField, type Where } from 'payload';
|
|
2
|
+
import type { DrizzleAdapter } from '../types.js';
|
|
3
|
+
export type ScalarWhereField = {
|
|
4
|
+
field: FlattenedField;
|
|
5
|
+
isUUID: boolean;
|
|
6
|
+
type: 'scalar';
|
|
7
|
+
};
|
|
8
|
+
type CollectionWhereField = {
|
|
9
|
+
field: FlattenedField;
|
|
10
|
+
type: 'hasManySelect';
|
|
11
|
+
} | ScalarWhereField;
|
|
12
|
+
export type WherePathPlan = {
|
|
13
|
+
columnPath: string;
|
|
14
|
+
fieldsByCollection: Map<string, CollectionWhereField>;
|
|
15
|
+
schemaPath: string;
|
|
16
|
+
type: 'hasManySelect' | 'invalid' | 'scalar';
|
|
17
|
+
};
|
|
18
|
+
export type PolymorphicJoinWherePlan = Map<string, WherePathPlan>;
|
|
19
|
+
/**
|
|
20
|
+
* Analyzes every leaf path in a polymorphic join where clause before SQL is built. Each plan entry
|
|
21
|
+
* records the flattened column path, the compatible field shape for each target collection, and
|
|
22
|
+
* whether the path uses a scalar column or a has-many select value table. A field may be absent
|
|
23
|
+
* from some target collections; those branches compare against SQL NULL or an empty JSON array.
|
|
24
|
+
*
|
|
25
|
+
* Paths are marked as invalid when their storage shapes conflict, require localized or separate-row
|
|
26
|
+
* traversal, have no matching field, lack a required column, or collide after path flattening.
|
|
27
|
+
*
|
|
28
|
+
* @returns A plan keyed by each unique schema path in `where`.
|
|
29
|
+
* @throws If a target collection or its mapped database table is not available in the adapter.
|
|
30
|
+
*/
|
|
31
|
+
export declare const createPolymorphicJoinWherePlan: ({ adapter, collections, where, }: {
|
|
32
|
+
adapter: DrizzleAdapter;
|
|
33
|
+
collections: string[];
|
|
34
|
+
where: Where;
|
|
35
|
+
}) => PolymorphicJoinWherePlan;
|
|
36
|
+
export {};
|
|
37
|
+
//# sourceMappingURL=createPolymorphicJoinWherePlan.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"createPolymorphicJoinWherePlan.d.ts","sourceRoot":"","sources":["../../src/find/createPolymorphicJoinWherePlan.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,cAAc,EAAkB,KAAK,KAAK,EAAE,MAAM,SAAS,CAAA;AAGzE,OAAO,KAAK,EAAE,cAAc,EAAgB,MAAM,aAAa,CAAA;AAK/D,MAAM,MAAM,gBAAgB,GAAG;IAC7B,KAAK,EAAE,cAAc,CAAA;IACrB,MAAM,EAAE,OAAO,CAAA;IACf,IAAI,EAAE,QAAQ,CAAA;CACf,CAAA;AAED,KAAK,oBAAoB,GAAG;IAAE,KAAK,EAAE,cAAc,CAAC;IAAC,IAAI,EAAE,eAAe,CAAA;CAAE,GAAG,gBAAgB,CAAA;AAE/F,MAAM,MAAM,aAAa,GAAG;IAC1B,UAAU,EAAE,MAAM,CAAA;IAClB,kBAAkB,EAAE,GAAG,CAAC,MAAM,EAAE,oBAAoB,CAAC,CAAA;IACrD,UAAU,EAAE,MAAM,CAAA;IAClB,IAAI,EAAE,eAAe,GAAG,SAAS,GAAG,QAAQ,CAAA;CAC7C,CAAA;AAED,MAAM,MAAM,wBAAwB,GAAG,GAAG,CAAC,MAAM,EAAE,aAAa,CAAC,CAAA;AAEjE;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,8BAA8B,qCAIxC;IACD,OAAO,EAAE,cAAc,CAAA;IACvB,WAAW,EAAE,MAAM,EAAE,CAAA;IACrB,KAAK,EAAE,KAAK,CAAA;CACb,KAAG,wBAoIH,CAAA"}
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
import { getFieldByPath } from 'payload';
|
|
2
|
+
import toSnakeCase from 'to-snake-case';
|
|
3
|
+
import { isUUIDType } from '../utilities/isUUIDType.js';
|
|
4
|
+
import { sanitizePathSegment } from '../utilities/sanitizePathSegment.js';
|
|
5
|
+
/**
|
|
6
|
+
* Analyzes every leaf path in a polymorphic join where clause before SQL is built. Each plan entry
|
|
7
|
+
* records the flattened column path, the compatible field shape for each target collection, and
|
|
8
|
+
* whether the path uses a scalar column or a has-many select value table. A field may be absent
|
|
9
|
+
* from some target collections; those branches compare against SQL NULL or an empty JSON array.
|
|
10
|
+
*
|
|
11
|
+
* Paths are marked as invalid when their storage shapes conflict, require localized or separate-row
|
|
12
|
+
* traversal, have no matching field, lack a required column, or collide after path flattening.
|
|
13
|
+
*
|
|
14
|
+
* @returns A plan keyed by each unique schema path in `where`.
|
|
15
|
+
* @throws If a target collection or its mapped database table is not available in the adapter.
|
|
16
|
+
*/ export const createPolymorphicJoinWherePlan = ({ adapter, collections, where })=>{
|
|
17
|
+
const collectionContexts = collections.map((collection)=>{
|
|
18
|
+
const collectionConfig = adapter.payload.collections[collection]?.config;
|
|
19
|
+
if (!collectionConfig) {
|
|
20
|
+
throw new Error(`Unknown polymorphic join collection "${collection}"`);
|
|
21
|
+
}
|
|
22
|
+
const tableName = adapter.tableNameMap.get(toSnakeCase(collection));
|
|
23
|
+
const table = tableName ? adapter.tables[tableName] : undefined;
|
|
24
|
+
if (!table) {
|
|
25
|
+
throw new Error(`Polymorphic join collection "${collection}" has no database table`);
|
|
26
|
+
}
|
|
27
|
+
return {
|
|
28
|
+
collection,
|
|
29
|
+
collectionConfig,
|
|
30
|
+
table
|
|
31
|
+
};
|
|
32
|
+
});
|
|
33
|
+
const schemaPathsByColumnPath = new Map();
|
|
34
|
+
const schemaPaths = new Set(getWhereSchemaPaths(where));
|
|
35
|
+
for (const schemaPath of schemaPaths){
|
|
36
|
+
const columnPath = getColumnPath(schemaPath);
|
|
37
|
+
const paths = schemaPathsByColumnPath.get(columnPath) ?? new Set();
|
|
38
|
+
paths.add(schemaPath);
|
|
39
|
+
schemaPathsByColumnPath.set(columnPath, paths);
|
|
40
|
+
}
|
|
41
|
+
const plan = new Map();
|
|
42
|
+
for (const schemaPath of schemaPaths){
|
|
43
|
+
const columnPath = getColumnPath(schemaPath);
|
|
44
|
+
const fieldsByCollection = new Map();
|
|
45
|
+
let isFieldPresent = schemaPath === 'id' || schemaPath === 'relationTo';
|
|
46
|
+
let hasManySelect = false;
|
|
47
|
+
let hasUnsupportedFieldShape = false;
|
|
48
|
+
const scalarQueryValueSignatures = new Set();
|
|
49
|
+
for (const { collection, collectionConfig, table } of collectionContexts){
|
|
50
|
+
const fieldAtPath = getFieldByPath({
|
|
51
|
+
fields: collectionConfig.flattenedFields,
|
|
52
|
+
path: schemaPath
|
|
53
|
+
});
|
|
54
|
+
if (schemaPath === 'id') {
|
|
55
|
+
const idColumn = table['id'];
|
|
56
|
+
if (!idColumn) {
|
|
57
|
+
hasUnsupportedFieldShape = true;
|
|
58
|
+
} else {
|
|
59
|
+
scalarQueryValueSignatures.add(`id:${idColumn.getSQLType()}`);
|
|
60
|
+
fieldsByCollection.set(collection, {
|
|
61
|
+
type: 'scalar',
|
|
62
|
+
field: fieldAtPath?.field ?? {
|
|
63
|
+
name: 'id',
|
|
64
|
+
type: isUUIDType(adapter.idType) ? 'text' : 'number'
|
|
65
|
+
},
|
|
66
|
+
isUUID: !fieldAtPath && isUUIDType(adapter.idType)
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
continue;
|
|
70
|
+
}
|
|
71
|
+
if (!fieldAtPath) {
|
|
72
|
+
if (pathHasUnsupportedNestedContainer({
|
|
73
|
+
fields: collectionConfig.flattenedFields,
|
|
74
|
+
path: schemaPath
|
|
75
|
+
})) {
|
|
76
|
+
hasUnsupportedFieldShape = true;
|
|
77
|
+
}
|
|
78
|
+
continue;
|
|
79
|
+
}
|
|
80
|
+
isFieldPresent = true;
|
|
81
|
+
if (fieldAtPath.pathHasLocalized || pathHasSeparateRows({
|
|
82
|
+
fields: collectionConfig.flattenedFields,
|
|
83
|
+
path: schemaPath
|
|
84
|
+
})) {
|
|
85
|
+
hasUnsupportedFieldShape = true;
|
|
86
|
+
continue;
|
|
87
|
+
}
|
|
88
|
+
if (fieldAtPath.field.type === 'select' && fieldAtPath.field.hasMany) {
|
|
89
|
+
hasManySelect = true;
|
|
90
|
+
fieldsByCollection.set(collection, {
|
|
91
|
+
type: 'hasManySelect',
|
|
92
|
+
field: fieldAtPath.field
|
|
93
|
+
});
|
|
94
|
+
continue;
|
|
95
|
+
}
|
|
96
|
+
const fieldColumn = table[columnPath];
|
|
97
|
+
if (!fieldColumn) {
|
|
98
|
+
hasUnsupportedFieldShape = true;
|
|
99
|
+
continue;
|
|
100
|
+
}
|
|
101
|
+
fieldsByCollection.set(collection, {
|
|
102
|
+
type: 'scalar',
|
|
103
|
+
field: fieldAtPath.field,
|
|
104
|
+
isUUID: fieldColumn.columnType === 'PgUUID'
|
|
105
|
+
});
|
|
106
|
+
scalarQueryValueSignatures.add(getScalarQueryValueSignature({
|
|
107
|
+
column: fieldColumn,
|
|
108
|
+
field: fieldAtPath.field
|
|
109
|
+
}));
|
|
110
|
+
}
|
|
111
|
+
const hasColumnPathCollision = (schemaPathsByColumnPath.get(columnPath)?.size ?? 0) > 1;
|
|
112
|
+
const isInvalid = hasColumnPathCollision || !isFieldPresent || hasUnsupportedFieldShape || hasManySelect && scalarQueryValueSignatures.size > 0 || scalarQueryValueSignatures.size > 1;
|
|
113
|
+
plan.set(schemaPath, {
|
|
114
|
+
type: isInvalid ? 'invalid' : hasManySelect ? 'hasManySelect' : 'scalar',
|
|
115
|
+
columnPath,
|
|
116
|
+
fieldsByCollection,
|
|
117
|
+
schemaPath
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
return plan;
|
|
121
|
+
};
|
|
122
|
+
const textQueryFieldTypes = new Set([
|
|
123
|
+
'code',
|
|
124
|
+
'email',
|
|
125
|
+
'slug',
|
|
126
|
+
'text',
|
|
127
|
+
'textarea'
|
|
128
|
+
]);
|
|
129
|
+
const getScalarQueryValueSignature = ({ column, field })=>{
|
|
130
|
+
if (field.type === 'select' || field.type === 'radio') {
|
|
131
|
+
const optionValues = field.options.map((option)=>typeof option === 'string' ? option : option.value);
|
|
132
|
+
return `${field.type}:${JSON.stringify(optionValues)}`;
|
|
133
|
+
}
|
|
134
|
+
if (textQueryFieldTypes.has(field.type)) {
|
|
135
|
+
return 'text';
|
|
136
|
+
}
|
|
137
|
+
return `${field.type}:${column.getSQLType()}`;
|
|
138
|
+
};
|
|
139
|
+
const getWhereSchemaPaths = (where)=>{
|
|
140
|
+
const paths = [];
|
|
141
|
+
for(const key in where){
|
|
142
|
+
if ([
|
|
143
|
+
'AND',
|
|
144
|
+
'OR'
|
|
145
|
+
].includes(key.toUpperCase())) {
|
|
146
|
+
if (Array.isArray(where[key])) {
|
|
147
|
+
for (const nestedWhere of where[key]){
|
|
148
|
+
paths.push(...getWhereSchemaPaths(nestedWhere));
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
} else {
|
|
152
|
+
paths.push(key);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
return paths;
|
|
156
|
+
};
|
|
157
|
+
const getColumnPath = (schemaPath)=>schemaPath.split('.').map((segment)=>sanitizePathSegment(segment)).join('_');
|
|
158
|
+
const pathHasSeparateRows = ({ fields, path })=>{
|
|
159
|
+
const pathSegments = path.split('.');
|
|
160
|
+
for(let segmentIndex = 1; segmentIndex < pathSegments.length; segmentIndex++){
|
|
161
|
+
const fieldAtParentPath = getFieldByPath({
|
|
162
|
+
fields,
|
|
163
|
+
path: pathSegments.slice(0, segmentIndex).join('.')
|
|
164
|
+
});
|
|
165
|
+
if (fieldAtParentPath?.field.type === 'array' || fieldAtParentPath?.field.type === 'blocks') {
|
|
166
|
+
return true;
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
return false;
|
|
170
|
+
};
|
|
171
|
+
const pathHasUnsupportedNestedContainer = ({ fields, path })=>{
|
|
172
|
+
const pathSegments = path.split('.');
|
|
173
|
+
for(let segmentIndex = 1; segmentIndex < pathSegments.length; segmentIndex++){
|
|
174
|
+
const fieldAtParentPath = getFieldByPath({
|
|
175
|
+
fields,
|
|
176
|
+
path: pathSegments.slice(0, segmentIndex).join('.')
|
|
177
|
+
});
|
|
178
|
+
if (!fieldAtParentPath) {
|
|
179
|
+
return false;
|
|
180
|
+
}
|
|
181
|
+
if (![
|
|
182
|
+
'group',
|
|
183
|
+
'tab'
|
|
184
|
+
].includes(fieldAtParentPath.field.type)) {
|
|
185
|
+
return true;
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
return false;
|
|
189
|
+
};
|
|
190
|
+
|
|
191
|
+
//# sourceMappingURL=createPolymorphicJoinWherePlan.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/find/createPolymorphicJoinWherePlan.ts"],"sourcesContent":["import type { Column } from 'drizzle-orm'\n\nimport { type FlattenedField, getFieldByPath, type Where } from 'payload'\nimport toSnakeCase from 'to-snake-case'\n\nimport type { DrizzleAdapter, GenericTable } from '../types.js'\n\nimport { isUUIDType } from '../utilities/isUUIDType.js'\nimport { sanitizePathSegment } from '../utilities/sanitizePathSegment.js'\n\nexport type ScalarWhereField = {\n field: FlattenedField\n isUUID: boolean\n type: 'scalar'\n}\n\ntype CollectionWhereField = { field: FlattenedField; type: 'hasManySelect' } | ScalarWhereField\n\nexport type WherePathPlan = {\n columnPath: string\n fieldsByCollection: Map<string, CollectionWhereField>\n schemaPath: string\n type: 'hasManySelect' | 'invalid' | 'scalar'\n}\n\nexport type PolymorphicJoinWherePlan = Map<string, WherePathPlan>\n\n/**\n * Analyzes every leaf path in a polymorphic join where clause before SQL is built. Each plan entry\n * records the flattened column path, the compatible field shape for each target collection, and\n * whether the path uses a scalar column or a has-many select value table. A field may be absent\n * from some target collections; those branches compare against SQL NULL or an empty JSON array.\n *\n * Paths are marked as invalid when their storage shapes conflict, require localized or separate-row\n * traversal, have no matching field, lack a required column, or collide after path flattening.\n *\n * @returns A plan keyed by each unique schema path in `where`.\n * @throws If a target collection or its mapped database table is not available in the adapter.\n */\nexport const createPolymorphicJoinWherePlan = ({\n adapter,\n collections,\n where,\n}: {\n adapter: DrizzleAdapter\n collections: string[]\n where: Where\n}): PolymorphicJoinWherePlan => {\n const collectionContexts = collections.map((collection) => {\n const collectionConfig = adapter.payload.collections[collection]?.config\n\n if (!collectionConfig) {\n throw new Error(`Unknown polymorphic join collection \"${collection}\"`)\n }\n\n const tableName = adapter.tableNameMap.get(toSnakeCase(collection))\n const table = tableName ? (adapter.tables[tableName] as GenericTable | undefined) : undefined\n\n if (!table) {\n throw new Error(`Polymorphic join collection \"${collection}\" has no database table`)\n }\n\n return { collection, collectionConfig, table }\n })\n const schemaPathsByColumnPath = new Map<string, Set<string>>()\n const schemaPaths = new Set(getWhereSchemaPaths(where))\n\n for (const schemaPath of schemaPaths) {\n const columnPath = getColumnPath(schemaPath)\n const paths = schemaPathsByColumnPath.get(columnPath) ?? new Set<string>()\n\n paths.add(schemaPath)\n schemaPathsByColumnPath.set(columnPath, paths)\n }\n\n const plan: PolymorphicJoinWherePlan = new Map()\n\n for (const schemaPath of schemaPaths) {\n const columnPath = getColumnPath(schemaPath)\n const fieldsByCollection = new Map<string, CollectionWhereField>()\n let isFieldPresent = schemaPath === 'id' || schemaPath === 'relationTo'\n let hasManySelect = false\n let hasUnsupportedFieldShape = false\n const scalarQueryValueSignatures = new Set<string>()\n\n for (const { collection, collectionConfig, table } of collectionContexts) {\n const fieldAtPath = getFieldByPath({\n fields: collectionConfig.flattenedFields,\n path: schemaPath,\n })\n\n if (schemaPath === 'id') {\n const idColumn = table['id'] as Column | undefined\n\n if (!idColumn) {\n hasUnsupportedFieldShape = true\n } else {\n scalarQueryValueSignatures.add(`id:${idColumn.getSQLType()}`)\n fieldsByCollection.set(collection, {\n type: 'scalar',\n field:\n fieldAtPath?.field ??\n ({\n name: 'id',\n type: isUUIDType(adapter.idType) ? 'text' : 'number',\n } as FlattenedField),\n isUUID: !fieldAtPath && isUUIDType(adapter.idType),\n })\n }\n\n continue\n }\n\n if (!fieldAtPath) {\n if (\n pathHasUnsupportedNestedContainer({\n fields: collectionConfig.flattenedFields,\n path: schemaPath,\n })\n ) {\n hasUnsupportedFieldShape = true\n }\n\n continue\n }\n\n isFieldPresent = true\n\n if (\n fieldAtPath.pathHasLocalized ||\n pathHasSeparateRows({ fields: collectionConfig.flattenedFields, path: schemaPath })\n ) {\n hasUnsupportedFieldShape = true\n continue\n }\n\n if (fieldAtPath.field.type === 'select' && fieldAtPath.field.hasMany) {\n hasManySelect = true\n fieldsByCollection.set(collection, {\n type: 'hasManySelect',\n field: fieldAtPath.field,\n })\n continue\n }\n\n const fieldColumn = table[columnPath] as Column | undefined\n\n if (!fieldColumn) {\n hasUnsupportedFieldShape = true\n continue\n }\n\n fieldsByCollection.set(collection, {\n type: 'scalar',\n field: fieldAtPath.field,\n isUUID: fieldColumn.columnType === 'PgUUID',\n })\n scalarQueryValueSignatures.add(\n getScalarQueryValueSignature({ column: fieldColumn, field: fieldAtPath.field }),\n )\n }\n\n const hasColumnPathCollision = (schemaPathsByColumnPath.get(columnPath)?.size ?? 0) > 1\n const isInvalid =\n hasColumnPathCollision ||\n !isFieldPresent ||\n hasUnsupportedFieldShape ||\n (hasManySelect && scalarQueryValueSignatures.size > 0) ||\n scalarQueryValueSignatures.size > 1\n\n plan.set(schemaPath, {\n type: isInvalid ? 'invalid' : hasManySelect ? 'hasManySelect' : 'scalar',\n columnPath,\n fieldsByCollection,\n schemaPath,\n })\n }\n\n return plan\n}\n\nconst textQueryFieldTypes = new Set<FlattenedField['type']>([\n 'code',\n 'email',\n 'slug',\n 'text',\n 'textarea',\n])\n\nconst getScalarQueryValueSignature = ({\n column,\n field,\n}: {\n column: Column\n field: FlattenedField\n}): string => {\n if (field.type === 'select' || field.type === 'radio') {\n const optionValues = field.options.map((option) =>\n typeof option === 'string' ? option : option.value,\n )\n\n return `${field.type}:${JSON.stringify(optionValues)}`\n }\n\n if (textQueryFieldTypes.has(field.type)) {\n return 'text'\n }\n\n return `${field.type}:${column.getSQLType()}`\n}\n\nconst getWhereSchemaPaths = (where: Where): string[] => {\n const paths: string[] = []\n\n for (const key in where) {\n if (['AND', 'OR'].includes(key.toUpperCase())) {\n if (Array.isArray(where[key])) {\n for (const nestedWhere of where[key]) {\n paths.push(...getWhereSchemaPaths(nestedWhere))\n }\n }\n } else {\n paths.push(key)\n }\n }\n\n return paths\n}\n\nconst getColumnPath = (schemaPath: string): string =>\n schemaPath\n .split('.')\n .map((segment) => sanitizePathSegment(segment))\n .join('_')\n\nconst pathHasSeparateRows = ({ fields, path }: { fields: FlattenedField[]; path: string }) => {\n const pathSegments = path.split('.')\n\n for (let segmentIndex = 1; segmentIndex < pathSegments.length; segmentIndex++) {\n const fieldAtParentPath = getFieldByPath({\n fields,\n path: pathSegments.slice(0, segmentIndex).join('.'),\n })\n\n if (fieldAtParentPath?.field.type === 'array' || fieldAtParentPath?.field.type === 'blocks') {\n return true\n }\n }\n\n return false\n}\n\nconst pathHasUnsupportedNestedContainer = ({\n fields,\n path,\n}: {\n fields: FlattenedField[]\n path: string\n}) => {\n const pathSegments = path.split('.')\n\n for (let segmentIndex = 1; segmentIndex < pathSegments.length; segmentIndex++) {\n const fieldAtParentPath = getFieldByPath({\n fields,\n path: pathSegments.slice(0, segmentIndex).join('.'),\n })\n\n if (!fieldAtParentPath) {\n return false\n }\n\n if (!['group', 'tab'].includes(fieldAtParentPath.field.type)) {\n return true\n }\n }\n\n return false\n}\n"],"names":["getFieldByPath","toSnakeCase","isUUIDType","sanitizePathSegment","createPolymorphicJoinWherePlan","adapter","collections","where","collectionContexts","map","collection","collectionConfig","payload","config","Error","tableName","tableNameMap","get","table","tables","undefined","schemaPathsByColumnPath","Map","schemaPaths","Set","getWhereSchemaPaths","schemaPath","columnPath","getColumnPath","paths","add","set","plan","fieldsByCollection","isFieldPresent","hasManySelect","hasUnsupportedFieldShape","scalarQueryValueSignatures","fieldAtPath","fields","flattenedFields","path","idColumn","getSQLType","type","field","name","idType","isUUID","pathHasUnsupportedNestedContainer","pathHasLocalized","pathHasSeparateRows","hasMany","fieldColumn","columnType","getScalarQueryValueSignature","column","hasColumnPathCollision","size","isInvalid","textQueryFieldTypes","optionValues","options","option","value","JSON","stringify","has","key","includes","toUpperCase","Array","isArray","nestedWhere","push","split","segment","join","pathSegments","segmentIndex","length","fieldAtParentPath","slice"],"mappings":"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"}
|