@payloadcms/drizzle 4.0.0-canary.34 → 4.0.0-canary.36

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 (29) hide show
  1. package/package.json +3 -3
  2. package/dist/find/buildPolymorphicJoinQuery.spec.js +0 -384
  3. package/dist/find/buildPolymorphicJoinQuery.spec.js.map +0 -1
  4. package/dist/find/buildPolymorphicJoinWhere.spec.js +0 -805
  5. package/dist/find/buildPolymorphicJoinWhere.spec.js.map +0 -1
  6. package/dist/find/createPolymorphicJoinWherePlan.spec.js +0 -778
  7. package/dist/find/createPolymorphicJoinWherePlan.spec.js.map +0 -1
  8. package/dist/postgres/query/assertOperatorHandlerExtensionsInstalled.spec.js +0 -91
  9. package/dist/postgres/query/assertOperatorHandlerExtensionsInstalled.spec.js.map +0 -1
  10. package/dist/postgres/query/postgresUnaccent.spec.js +0 -71
  11. package/dist/postgres/query/postgresUnaccent.spec.js.map +0 -1
  12. package/dist/queries/buildOperatorConstraint.spec.js +0 -348
  13. package/dist/queries/buildOperatorConstraint.spec.js.map +0 -1
  14. package/dist/queries/validateOperatorHandlers.spec.js +0 -142
  15. package/dist/queries/validateOperatorHandlers.spec.js.map +0 -1
  16. package/dist/schema/buildRawSchema.spec.js +0 -290
  17. package/dist/schema/buildRawSchema.spec.js.map +0 -1
  18. package/dist/updateOne.spec.js +0 -84
  19. package/dist/updateOne.spec.js.map +0 -1
  20. package/dist/upsertRow/conditionalUpdate.spec.js +0 -61
  21. package/dist/upsertRow/conditionalUpdate.spec.js.map +0 -1
  22. package/dist/upsertRow/handleUpsertError.spec.js +0 -42
  23. package/dist/upsertRow/handleUpsertError.spec.js.map +0 -1
  24. package/dist/utilities/checkTruncatedIdentifiers.spec.js +0 -301
  25. package/dist/utilities/checkTruncatedIdentifiers.spec.js.map +0 -1
  26. package/dist/utilities/isValidStringID.spec.js +0 -15
  27. package/dist/utilities/isValidStringID.spec.js.map +0 -1
  28. package/dist/utilities/validateIdentifierLength.spec.js +0 -19
  29. package/dist/utilities/validateIdentifierLength.spec.js.map +0 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@payloadcms/drizzle",
3
- "version": "4.0.0-canary.34",
3
+ "version": "4.0.0-canary.36",
4
4
  "description": "A library of shared functions used by different payload database adapters",
5
5
  "homepage": "https://payloadcms.com",
6
6
  "repository": {
@@ -55,10 +55,10 @@
55
55
  "@types/pg": "8.20.0",
56
56
  "@types/to-snake-case": "1.0.0",
57
57
  "@payloadcms/eslint-config": "3.28.0",
58
- "payload": "4.0.0-canary.34"
58
+ "payload": "4.0.0-canary.36"
59
59
  },
60
60
  "peerDependencies": {
61
- "payload": "4.0.0-canary.34"
61
+ "payload": "4.0.0-canary.36"
62
62
  },
63
63
  "scripts": {
64
64
  "build": "pnpm build:swc && pnpm build:types",
@@ -1,384 +0,0 @@
1
- import { createClient } from '@libsql/client';
2
- import { getTableName, like, notLike } from 'drizzle-orm';
3
- import { drizzle } from 'drizzle-orm/libsql';
4
- import { integer, sqliteTable, text } from 'drizzle-orm/sqlite-core';
5
- import { flattenAllFields } from 'payload';
6
- import toSnakeCase from 'to-snake-case';
7
- import { afterAll, describe, expect, it } from 'vitest';
8
- import { operatorMap } from '../queries/operatorMap.js';
9
- import { createJSONQuery } from '../sqlite/createJSONQuery/index.js';
10
- import { buildPolymorphicJoinQuery } from './buildPolymorphicJoinQuery.js';
11
- const parentsTable = sqliteTable('join_parents', {
12
- id: integer('id').primaryKey()
13
- });
14
- const articlesTable = sqliteTable('join_articles', {
15
- id: integer('id').primaryKey(),
16
- createdAt: text('created_at'),
17
- details_rank: integer('details_rank'),
18
- parent: integer('parent_id'),
19
- score: integer('score'),
20
- title: text('title')
21
- });
22
- const notesTable = sqliteTable('join_notes', {
23
- id: integer('id').primaryKey(),
24
- parent: integer('parent_id'),
25
- title: text('title')
26
- });
27
- const tableWithoutID = sqliteTable('join_without_id', {
28
- parent: integer('parent_id')
29
- });
30
- const tableWithoutParent = sqliteTable('join_without_parent', {
31
- id: integer('id').primaryKey()
32
- });
33
- const client = createClient({
34
- url: 'file::memory:'
35
- });
36
- const db = drizzle(client, {
37
- schema: {
38
- articlesTable,
39
- notesTable,
40
- parentsTable,
41
- tableWithoutID,
42
- tableWithoutParent
43
- }
44
- });
45
- const createAdapter = (fixtures)=>{
46
- const collections = {};
47
- const tableNameMap = new Map();
48
- const tables = {};
49
- for (const [slug, fixture] of Object.entries(fixtures)){
50
- const tableName = getTableName(fixture.table);
51
- collections[slug] = {
52
- config: {
53
- fields: fixture.fields,
54
- flattenedFields: flattenAllFields({
55
- fields: fixture.fields
56
- })
57
- }
58
- };
59
- tableNameMap.set(toSnakeCase(slug), tableName);
60
- tables[tableName] = fixture.table;
61
- }
62
- return {
63
- createJSONQuery,
64
- drizzle: db,
65
- idType: 'serial',
66
- name: 'sqlite',
67
- operatorHandlers: [],
68
- operators: {
69
- ...operatorMap,
70
- contains: like,
71
- like,
72
- not_like: notLike
73
- },
74
- payload: {
75
- collections
76
- },
77
- tableNameMap,
78
- tables
79
- };
80
- };
81
- const adapter = createAdapter({
82
- articles: {
83
- fields: [
84
- {
85
- name: 'createdAt',
86
- type: 'date'
87
- },
88
- {
89
- name: 'details',
90
- type: 'group',
91
- fields: [
92
- {
93
- name: 'rank',
94
- type: 'number'
95
- }
96
- ]
97
- },
98
- {
99
- name: 'parent',
100
- relationTo: 'join-parents',
101
- type: 'relationship'
102
- },
103
- {
104
- name: 'score',
105
- type: 'number'
106
- },
107
- {
108
- name: 'title',
109
- type: 'text'
110
- }
111
- ],
112
- table: articlesTable
113
- },
114
- notes: {
115
- fields: [
116
- {
117
- name: 'parent',
118
- relationTo: 'join-parents',
119
- type: 'relationship'
120
- },
121
- {
122
- name: 'title',
123
- type: 'text'
124
- }
125
- ],
126
- table: notesTable
127
- }
128
- });
129
- const joinField = {
130
- collection: [
131
- 'articles',
132
- 'notes'
133
- ],
134
- name: 'children',
135
- on: 'parent',
136
- type: 'join'
137
- };
138
- const buildQuery = ({ adapter: adapterArg = adapter, field = joinField, limit = 0, page, path = '', shouldCount = false, sort, where } = {})=>buildPolymorphicJoinQuery({
139
- adapter: adapterArg,
140
- currentTableName: getTableName(parentsTable),
141
- field,
142
- limit,
143
- page,
144
- path,
145
- shouldCount,
146
- sort,
147
- where
148
- });
149
- const renderQuery = (query)=>{
150
- const selection = {
151
- documents: query.documents
152
- };
153
- if (query.count) {
154
- selection.count = query.count;
155
- }
156
- return db.select(selection).from(parentsTable).toSQL();
157
- };
158
- afterAll(()=>client.close());
159
- describe('buildPolymorphicJoinQuery', ()=>{
160
- it('combines every target into one fixed polymorphic document projection', ()=>{
161
- const result = buildQuery({
162
- path: 'content.'
163
- });
164
- const query = renderQuery(result);
165
- expect(result.columnName).toBe('content_children');
166
- expect(result.count).toBeUndefined();
167
- expect(query.sql).toContain('union all');
168
- expect(query.sql).toContain('select "id"');
169
- expect(query.sql).toContain('from "join_articles" union all');
170
- expect(query.sql).toContain('from "join_notes"');
171
- expect(query.sql).toContain('as "parent"');
172
- expect(query.sql).toContain('as "relationTo"');
173
- expect(query.sql).toContain("json_object('id',");
174
- expect(query.sql).toContain("'relationTo',");
175
- expect(query.params).toContain('articles');
176
- expect(query.params).toContain('notes');
177
- });
178
- it('sorts by createdAt descending by default when one target has timestamps', ()=>{
179
- const query = renderQuery(buildQuery());
180
- expect(query.sql).toContain('"created_at" as "sortPath" from "join_articles"');
181
- expect(query.sql).toContain('? as "sortPath" from "join_notes"');
182
- expect(query.sql).toContain('order by "sortPath" desc');
183
- expect(query.params).toContain(null);
184
- });
185
- it('uses id ascending by default when no target has a createdAt field', ()=>{
186
- const adapterWithoutTimestamps = createAdapter({
187
- articles: {
188
- fields: [
189
- {
190
- name: 'parent',
191
- relationTo: 'join-parents',
192
- type: 'relationship'
193
- }
194
- ],
195
- table: articlesTable
196
- },
197
- notes: {
198
- fields: [
199
- {
200
- name: 'parent',
201
- relationTo: 'join-parents',
202
- type: 'relationship'
203
- }
204
- ],
205
- table: notesTable
206
- }
207
- });
208
- const query = renderQuery(buildQuery({
209
- adapter: adapterWithoutTimestamps
210
- }));
211
- expect(query.sql).toContain('"id" as "sortPath" from "join_articles"');
212
- expect(query.sql).toContain('"id" as "sortPath" from "join_notes"');
213
- expect(query.sql).toContain('order by "sortPath" asc');
214
- });
215
- it('supports an explicit ascending nested sort and substitutes null when it is absent', ()=>{
216
- const query = renderQuery(buildQuery({
217
- sort: 'details.rank'
218
- }));
219
- expect(query.sql).toContain('"details_rank" as "sortPath" from "join_articles"');
220
- expect(query.sql).toContain('? as "sortPath" from "join_notes"');
221
- expect(query.sql).toContain('order by "sortPath" asc');
222
- expect(query.params).toContain(null);
223
- });
224
- it('applies the shared where clause independently to each target branch', ()=>{
225
- const query = renderQuery(buildQuery({
226
- where: {
227
- AND: [
228
- {
229
- title: {
230
- equals: 'available'
231
- }
232
- },
233
- {
234
- relationTo: {
235
- equals: 'articles'
236
- }
237
- }
238
- ]
239
- }
240
- }));
241
- expect(query.sql.match(/"title" = \?/g)).toHaveLength(2);
242
- expect(query.sql).toContain('? = ?');
243
- expect(query.params.filter((value)=>value === 'available')).toHaveLength(2);
244
- expect(query.params).toContain('articles');
245
- expect(query.params).toContain('notes');
246
- });
247
- it('adds a correlated count only when requested', ()=>{
248
- const result = buildQuery({
249
- shouldCount: true
250
- });
251
- const query = renderQuery(result);
252
- expect(result.count).toBeDefined();
253
- expect(query.sql).toContain('select count(*) from');
254
- expect(query.sql).toContain('"join_parents"."id" = "children_subquery"."parent"');
255
- });
256
- it('adds limit and page offset to the document query', ()=>{
257
- const query = renderQuery(buildQuery({
258
- limit: 11,
259
- page: 3
260
- }));
261
- expect(query.sql).toContain('LIMIT ? OFFSET ?');
262
- expect(query.params.slice(-2)).toEqual([
263
- 11,
264
- 22
265
- ]);
266
- });
267
- it('does not add limit or offset when limit is zero', ()=>{
268
- const query = renderQuery(buildQuery({
269
- limit: 0,
270
- page: 3
271
- }));
272
- const normalizedSQL = query.sql.toLowerCase();
273
- expect(normalizedSQL).not.toContain(' limit ');
274
- expect(normalizedSQL).not.toContain(' offset ');
275
- });
276
- it('rejects a join field with a non-polymorphic collection', ()=>{
277
- const scalarJoinField = {
278
- ...joinField,
279
- collection: 'articles'
280
- };
281
- expect(()=>buildQuery({
282
- field: scalarJoinField
283
- })).toThrow('A polymorphic join requires a collection array');
284
- });
285
- it('rejects a polymorphic join with no target collections', ()=>{
286
- const emptyJoinField = {
287
- ...joinField,
288
- collection: []
289
- };
290
- expect(()=>buildQuery({
291
- field: emptyJoinField
292
- })).toThrow('A polymorphic join requires at least one collection');
293
- });
294
- it('rejects multiple sort fields with a descriptive error', ()=>{
295
- expect(()=>buildQuery({
296
- sort: [
297
- 'title',
298
- '-createdAt'
299
- ]
300
- })).toThrow('Polymorphic joins do not support multiple sort fields');
301
- });
302
- it('throws a descriptive error when a target collection is not configured', ()=>{
303
- const missingCollectionField = {
304
- ...joinField,
305
- collection: [
306
- 'articles',
307
- 'missing'
308
- ]
309
- };
310
- expect(()=>buildQuery({
311
- field: missingCollectionField
312
- })).toThrow('Unknown polymorphic join collection "missing"');
313
- });
314
- it('throws a descriptive error when a configured collection has no database table', ()=>{
315
- const adapterWithoutTable = createAdapter({
316
- articles: {
317
- fields: [
318
- {
319
- name: 'parent',
320
- relationTo: 'join-parents',
321
- type: 'relationship'
322
- }
323
- ],
324
- table: articlesTable
325
- }
326
- });
327
- adapterWithoutTable.tables = {};
328
- const singleCollectionField = {
329
- ...joinField,
330
- collection: [
331
- 'articles'
332
- ]
333
- };
334
- expect(()=>buildQuery({
335
- adapter: adapterWithoutTable,
336
- field: singleCollectionField
337
- })).toThrow('Polymorphic join collection "articles" has no database table');
338
- });
339
- it.each([
340
- [
341
- 'id',
342
- createAdapter({
343
- articles: {
344
- fields: [
345
- {
346
- name: 'parent',
347
- relationTo: 'join-parents',
348
- type: 'relationship'
349
- }
350
- ],
351
- table: tableWithoutID
352
- }
353
- })
354
- ],
355
- [
356
- 'parent',
357
- createAdapter({
358
- articles: {
359
- fields: [
360
- {
361
- name: 'parent',
362
- relationTo: 'join-parents',
363
- type: 'relationship'
364
- }
365
- ],
366
- table: tableWithoutParent
367
- }
368
- })
369
- ]
370
- ])('rejects a target whose table has no %s column', (column, adapterArg)=>{
371
- const singleCollectionField = {
372
- ...joinField,
373
- collection: [
374
- 'articles'
375
- ]
376
- };
377
- expect(()=>buildQuery({
378
- adapter: adapterArg,
379
- field: singleCollectionField
380
- })).toThrow(`Polymorphic join collection "articles" has no "${column}" column`);
381
- });
382
- });
383
-
384
- //# sourceMappingURL=buildPolymorphicJoinQuery.spec.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../src/find/buildPolymorphicJoinQuery.spec.ts"],"sourcesContent":["import type { Client } from '@libsql/client'\nimport type { SQL } from 'drizzle-orm'\nimport type { Field, FlattenedJoinField, Where } from 'payload'\n\nimport { createClient } from '@libsql/client'\nimport { getTableName, like, notLike } from 'drizzle-orm'\nimport { drizzle } from 'drizzle-orm/libsql'\nimport { integer, sqliteTable, text } from 'drizzle-orm/sqlite-core'\nimport { flattenAllFields } from 'payload'\nimport toSnakeCase from 'to-snake-case'\nimport { afterAll, describe, expect, it } from 'vitest'\n\nimport type { DrizzleAdapter, GenericTable } from '../types.js'\n\nimport { operatorMap } from '../queries/operatorMap.js'\nimport { createJSONQuery } from '../sqlite/createJSONQuery/index.js'\nimport { buildPolymorphicJoinQuery } from './buildPolymorphicJoinQuery.js'\n\nconst parentsTable = sqliteTable('join_parents', {\n id: integer('id').primaryKey(),\n})\n\nconst articlesTable = sqliteTable('join_articles', {\n id: integer('id').primaryKey(),\n createdAt: text('created_at'),\n details_rank: integer('details_rank'),\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 tableWithoutID = sqliteTable('join_without_id', {\n parent: integer('parent_id'),\n})\n\nconst tableWithoutParent = sqliteTable('join_without_parent', {\n id: integer('id').primaryKey(),\n})\n\nconst client: Client = createClient({ url: 'file::memory:' })\nconst db = drizzle(client, {\n schema: { articlesTable, notesTable, parentsTable, tableWithoutID, tableWithoutParent },\n})\n\ntype CollectionFixture = {\n fields: Field[]\n table: GenericTable\n}\n\nconst createAdapter = (fixtures: Record<string, CollectionFixture>): DrizzleAdapter => {\n const collections: Record<\n string,\n { config: { fields: Field[]; flattenedFields: ReturnType<typeof flattenAllFields> } }\n > = {}\n const tableNameMap = new Map<string, string>()\n const tables: Record<string, GenericTable> = {}\n\n for (const [slug, fixture] of Object.entries(fixtures)) {\n const tableName = getTableName(fixture.table)\n\n collections[slug] = {\n config: {\n fields: fixture.fields,\n flattenedFields: flattenAllFields({ fields: fixture.fields }),\n },\n }\n tableNameMap.set(toSnakeCase(slug), tableName)\n tables[tableName] = fixture.table\n }\n\n return {\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,\n tables,\n } as unknown as DrizzleAdapter\n}\n\nconst adapter = createAdapter({\n articles: {\n fields: [\n { name: 'createdAt', type: 'date' },\n {\n name: 'details',\n type: 'group',\n fields: [{ name: 'rank', type: 'number' }],\n },\n { name: 'parent', relationTo: 'join-parents', type: 'relationship' },\n { name: 'score', type: 'number' },\n { name: 'title', type: 'text' },\n ],\n table: articlesTable,\n },\n notes: {\n fields: [\n { name: 'parent', relationTo: 'join-parents', type: 'relationship' },\n { name: 'title', type: 'text' },\n ],\n table: notesTable,\n },\n})\n\nconst joinField = {\n collection: ['articles', 'notes'],\n name: 'children',\n on: 'parent',\n type: 'join',\n} as unknown as FlattenedJoinField\n\nconst buildQuery = ({\n adapter: adapterArg = adapter,\n field = joinField,\n limit = 0,\n page,\n path = '',\n shouldCount = false,\n sort,\n where,\n}: {\n adapter?: DrizzleAdapter\n field?: FlattenedJoinField\n limit?: number\n page?: number\n path?: string\n shouldCount?: boolean\n sort?: string | string[]\n where?: Where\n} = {}) =>\n buildPolymorphicJoinQuery({\n adapter: adapterArg,\n currentTableName: getTableName(parentsTable),\n field,\n limit,\n page,\n path,\n shouldCount,\n sort,\n where,\n })\n\nconst renderQuery = (query: ReturnType<typeof buildPolymorphicJoinQuery>) => {\n const selection: Record<string, SQL.Aliased> = { documents: query.documents }\n\n if (query.count) {\n selection.count = query.count\n }\n\n return db.select(selection).from(parentsTable).toSQL()\n}\n\nafterAll(() => client.close())\n\ndescribe('buildPolymorphicJoinQuery', () => {\n it('combines every target into one fixed polymorphic document projection', () => {\n const result = buildQuery({ path: 'content.' })\n const query = renderQuery(result)\n\n expect(result.columnName).toBe('content_children')\n expect(result.count).toBeUndefined()\n expect(query.sql).toContain('union all')\n expect(query.sql).toContain('select \"id\"')\n expect(query.sql).toContain('from \"join_articles\" union all')\n expect(query.sql).toContain('from \"join_notes\"')\n expect(query.sql).toContain('as \"parent\"')\n expect(query.sql).toContain('as \"relationTo\"')\n expect(query.sql).toContain(\"json_object('id',\")\n expect(query.sql).toContain(\"'relationTo',\")\n expect(query.params).toContain('articles')\n expect(query.params).toContain('notes')\n })\n\n it('sorts by createdAt descending by default when one target has timestamps', () => {\n const query = renderQuery(buildQuery())\n\n expect(query.sql).toContain('\"created_at\" as \"sortPath\" from \"join_articles\"')\n expect(query.sql).toContain('? as \"sortPath\" from \"join_notes\"')\n expect(query.sql).toContain('order by \"sortPath\" desc')\n expect(query.params).toContain(null)\n })\n\n it('uses id ascending by default when no target has a createdAt field', () => {\n const adapterWithoutTimestamps = createAdapter({\n articles: {\n fields: [{ name: 'parent', relationTo: 'join-parents', type: 'relationship' }],\n table: articlesTable,\n },\n notes: {\n fields: [{ name: 'parent', relationTo: 'join-parents', type: 'relationship' }],\n table: notesTable,\n },\n })\n const query = renderQuery(buildQuery({ adapter: adapterWithoutTimestamps }))\n\n expect(query.sql).toContain('\"id\" as \"sortPath\" from \"join_articles\"')\n expect(query.sql).toContain('\"id\" as \"sortPath\" from \"join_notes\"')\n expect(query.sql).toContain('order by \"sortPath\" asc')\n })\n\n it('supports an explicit ascending nested sort and substitutes null when it is absent', () => {\n const query = renderQuery(buildQuery({ sort: 'details.rank' }))\n\n expect(query.sql).toContain('\"details_rank\" as \"sortPath\" from \"join_articles\"')\n expect(query.sql).toContain('? as \"sortPath\" from \"join_notes\"')\n expect(query.sql).toContain('order by \"sortPath\" asc')\n expect(query.params).toContain(null)\n })\n\n it('applies the shared where clause independently to each target branch', () => {\n const query = renderQuery(\n buildQuery({\n where: {\n AND: [{ title: { equals: 'available' } }, { relationTo: { equals: 'articles' } }],\n },\n }),\n )\n\n expect(query.sql.match(/\"title\" = \\?/g)).toHaveLength(2)\n expect(query.sql).toContain('? = ?')\n expect(query.params.filter((value) => value === 'available')).toHaveLength(2)\n expect(query.params).toContain('articles')\n expect(query.params).toContain('notes')\n })\n\n it('adds a correlated count only when requested', () => {\n const result = buildQuery({ shouldCount: true })\n const query = renderQuery(result)\n\n expect(result.count).toBeDefined()\n expect(query.sql).toContain('select count(*) from')\n expect(query.sql).toContain('\"join_parents\".\"id\" = \"children_subquery\".\"parent\"')\n })\n\n it('adds limit and page offset to the document query', () => {\n const query = renderQuery(buildQuery({ limit: 11, page: 3 }))\n\n expect(query.sql).toContain('LIMIT ? OFFSET ?')\n expect(query.params.slice(-2)).toEqual([11, 22])\n })\n\n it('does not add limit or offset when limit is zero', () => {\n const query = renderQuery(buildQuery({ limit: 0, page: 3 }))\n const normalizedSQL = query.sql.toLowerCase()\n\n expect(normalizedSQL).not.toContain(' limit ')\n expect(normalizedSQL).not.toContain(' offset ')\n })\n\n it('rejects a join field with a non-polymorphic collection', () => {\n const scalarJoinField = {\n ...joinField,\n collection: 'articles',\n } as unknown as FlattenedJoinField\n\n expect(() => buildQuery({ field: scalarJoinField })).toThrow(\n 'A polymorphic join requires a collection array',\n )\n })\n\n it('rejects a polymorphic join with no target collections', () => {\n const emptyJoinField = { ...joinField, collection: [] } as unknown as FlattenedJoinField\n\n expect(() => buildQuery({ field: emptyJoinField })).toThrow(\n 'A polymorphic join requires at least one collection',\n )\n })\n\n it('rejects multiple sort fields with a descriptive error', () => {\n expect(() => buildQuery({ sort: ['title', '-createdAt'] })).toThrow(\n 'Polymorphic joins do not support multiple sort fields',\n )\n })\n\n it('throws a descriptive error when a target collection is not configured', () => {\n const missingCollectionField = {\n ...joinField,\n collection: ['articles', 'missing'],\n } as unknown as FlattenedJoinField\n\n expect(() => buildQuery({ field: missingCollectionField })).toThrow(\n 'Unknown polymorphic join collection \"missing\"',\n )\n })\n\n it('throws a descriptive error when a configured collection has no database table', () => {\n const adapterWithoutTable = createAdapter({\n articles: {\n fields: [{ name: 'parent', relationTo: 'join-parents', type: 'relationship' }],\n table: articlesTable,\n },\n })\n\n adapterWithoutTable.tables = {}\n\n const singleCollectionField = {\n ...joinField,\n collection: ['articles'],\n } as unknown as FlattenedJoinField\n\n expect(() =>\n buildQuery({ adapter: adapterWithoutTable, field: singleCollectionField }),\n ).toThrow('Polymorphic join collection \"articles\" has no database table')\n })\n\n it.each([\n [\n 'id',\n createAdapter({\n articles: {\n fields: [{ name: 'parent', relationTo: 'join-parents', type: 'relationship' }],\n table: tableWithoutID,\n },\n }),\n ],\n [\n 'parent',\n createAdapter({\n articles: {\n fields: [{ name: 'parent', relationTo: 'join-parents', type: 'relationship' }],\n table: tableWithoutParent,\n },\n }),\n ],\n ] as const)('rejects a target whose table has no %s column', (column, adapterArg) => {\n const singleCollectionField = {\n ...joinField,\n collection: ['articles'],\n } as unknown as FlattenedJoinField\n\n expect(() => buildQuery({ adapter: adapterArg, field: singleCollectionField })).toThrow(\n `Polymorphic join collection \"articles\" has no \"${column}\" column`,\n )\n })\n})\n"],"names":["createClient","getTableName","like","notLike","drizzle","integer","sqliteTable","text","flattenAllFields","toSnakeCase","afterAll","describe","expect","it","operatorMap","createJSONQuery","buildPolymorphicJoinQuery","parentsTable","id","primaryKey","articlesTable","createdAt","details_rank","parent","score","title","notesTable","tableWithoutID","tableWithoutParent","client","url","db","schema","createAdapter","fixtures","collections","tableNameMap","Map","tables","slug","fixture","Object","entries","tableName","table","config","fields","flattenedFields","set","idType","name","operatorHandlers","operators","contains","not_like","payload","adapter","articles","type","relationTo","notes","joinField","collection","on","buildQuery","adapterArg","field","limit","page","path","shouldCount","sort","where","currentTableName","renderQuery","query","selection","documents","count","select","from","toSQL","close","result","columnName","toBe","toBeUndefined","sql","toContain","params","adapterWithoutTimestamps","AND","equals","match","toHaveLength","filter","value","toBeDefined","slice","toEqual","normalizedSQL","toLowerCase","not","scalarJoinField","toThrow","emptyJoinField","missingCollectionField","adapterWithoutTable","singleCollectionField","each","column"],"mappings":"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"}