@payloadcms/drizzle 3.91.0-internal.6e3dc85 → 4.0.0-beta.0

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 (204) hide show
  1. package/LICENSE.md +1 -1
  2. package/dist/exports/postgres.d.ts +4 -0
  3. package/dist/exports/postgres.d.ts.map +1 -1
  4. package/dist/exports/postgres.js +4 -0
  5. package/dist/exports/postgres.js.map +1 -1
  6. package/dist/exports/sqlite.d.ts +2 -0
  7. package/dist/exports/sqlite.d.ts.map +1 -1
  8. package/dist/exports/sqlite.js +2 -0
  9. package/dist/exports/sqlite.js.map +1 -1
  10. package/dist/find/buildPolymorphicJoinQuery.d.ts +2 -1
  11. package/dist/find/buildPolymorphicJoinQuery.d.ts.map +1 -1
  12. package/dist/find/buildPolymorphicJoinQuery.js +2 -1
  13. package/dist/find/buildPolymorphicJoinQuery.js.map +1 -1
  14. package/dist/find/buildPolymorphicJoinWhere.d.ts +2 -1
  15. package/dist/find/buildPolymorphicJoinWhere.d.ts.map +1 -1
  16. package/dist/find/buildPolymorphicJoinWhere.js +43 -10
  17. package/dist/find/buildPolymorphicJoinWhere.js.map +1 -1
  18. package/dist/find/createPolymorphicJoinWherePlan.js +3 -2
  19. package/dist/find/createPolymorphicJoinWherePlan.js.map +1 -1
  20. package/dist/find/traverseFields.d.ts.map +1 -1
  21. package/dist/find/traverseFields.js +2 -2
  22. package/dist/find/traverseFields.js.map +1 -1
  23. package/dist/index.d.ts +4 -11
  24. package/dist/index.d.ts.map +1 -1
  25. package/dist/index.js +2 -9
  26. package/dist/index.js.map +1 -1
  27. package/dist/migrate.d.ts.map +1 -1
  28. package/dist/migrate.js +41 -15
  29. package/dist/migrate.js.map +1 -1
  30. package/dist/migrateDown.d.ts +2 -1
  31. package/dist/migrateDown.d.ts.map +1 -1
  32. package/dist/migrateDown.js +17 -4
  33. package/dist/migrateDown.js.map +1 -1
  34. package/dist/migrateFresh.d.ts +4 -2
  35. package/dist/migrateFresh.d.ts.map +1 -1
  36. package/dist/migrateFresh.js +26 -9
  37. package/dist/migrateFresh.js.map +1 -1
  38. package/dist/migrateRefresh.d.ts +2 -1
  39. package/dist/migrateRefresh.d.ts.map +1 -1
  40. package/dist/migrateRefresh.js +20 -5
  41. package/dist/migrateRefresh.js.map +1 -1
  42. package/dist/migrateReset.d.ts +2 -1
  43. package/dist/migrateReset.d.ts.map +1 -1
  44. package/dist/migrateReset.js +18 -4
  45. package/dist/migrateReset.js.map +1 -1
  46. package/dist/migrateStatus.d.ts +2 -1
  47. package/dist/migrateStatus.d.ts.map +1 -1
  48. package/dist/migrateStatus.js +11 -6
  49. package/dist/migrateStatus.js.map +1 -1
  50. package/dist/postgres/predefinedMigrations/localize-status/index.d.ts +11 -0
  51. package/dist/postgres/predefinedMigrations/localize-status/index.d.ts.map +1 -0
  52. package/dist/postgres/predefinedMigrations/localize-status/index.js +296 -0
  53. package/dist/postgres/predefinedMigrations/localize-status/index.js.map +1 -0
  54. package/dist/postgres/predefinedMigrations/localize-status/migrateMainCollection.d.ts +13 -0
  55. package/dist/postgres/predefinedMigrations/localize-status/migrateMainCollection.d.ts.map +1 -0
  56. package/dist/postgres/predefinedMigrations/localize-status/migrateMainCollection.js +51 -0
  57. package/dist/postgres/predefinedMigrations/localize-status/migrateMainCollection.js.map +1 -0
  58. package/dist/postgres/predefinedMigrations/localize-status/migrateMainGlobal.d.ts +13 -0
  59. package/dist/postgres/predefinedMigrations/localize-status/migrateMainGlobal.d.ts.map +1 -0
  60. package/dist/postgres/predefinedMigrations/localize-status/migrateMainGlobal.js +54 -0
  61. package/dist/postgres/predefinedMigrations/localize-status/migrateMainGlobal.js.map +1 -0
  62. package/dist/postgres/predefinedMigrations/sizes-to-variants/index.d.ts +35 -0
  63. package/dist/postgres/predefinedMigrations/sizes-to-variants/index.d.ts.map +1 -0
  64. package/dist/postgres/predefinedMigrations/sizes-to-variants/index.js +185 -0
  65. package/dist/postgres/predefinedMigrations/sizes-to-variants/index.js.map +1 -0
  66. package/dist/postgres/predefinedMigrations/v2-v3/fetchAndResave/index.d.ts.map +1 -1
  67. package/dist/postgres/predefinedMigrations/v2-v3/fetchAndResave/index.js +8 -4
  68. package/dist/postgres/predefinedMigrations/v2-v3/fetchAndResave/index.js.map +1 -1
  69. package/dist/postgres/predefinedMigrations/v2-v3/fetchAndResave/traverseFields.d.ts.map +1 -1
  70. package/dist/postgres/predefinedMigrations/v2-v3/fetchAndResave/traverseFields.js.map +1 -1
  71. package/dist/postgres/predefinedMigrations/v2-v3/index.js +1 -1
  72. package/dist/postgres/predefinedMigrations/v2-v3/index.js.map +1 -1
  73. package/dist/postgres/query/assertOperatorHandlerExtensionsInstalled.d.ts +15 -0
  74. package/dist/postgres/query/assertOperatorHandlerExtensionsInstalled.d.ts.map +1 -0
  75. package/dist/postgres/query/assertOperatorHandlerExtensionsInstalled.js +25 -0
  76. package/dist/postgres/query/assertOperatorHandlerExtensionsInstalled.js.map +1 -0
  77. package/dist/postgres/query/postgresUnaccent.d.ts +13 -0
  78. package/dist/postgres/query/postgresUnaccent.d.ts.map +1 -0
  79. package/dist/postgres/query/postgresUnaccent.js +40 -0
  80. package/dist/postgres/query/postgresUnaccent.js.map +1 -0
  81. package/dist/postgres/schema/geometryColumn.d.ts +2 -2
  82. package/dist/postgres/types.d.ts +13 -2
  83. package/dist/postgres/types.d.ts.map +1 -1
  84. package/dist/postgres/types.js.map +1 -1
  85. package/dist/queries/addJoinTable.d.ts +1 -1
  86. package/dist/queries/buildOperatorConstraint.d.ts +22 -0
  87. package/dist/queries/buildOperatorConstraint.d.ts.map +1 -0
  88. package/dist/queries/buildOperatorConstraint.js +63 -0
  89. package/dist/queries/buildOperatorConstraint.js.map +1 -0
  90. package/dist/queries/buildOrderBy.d.ts +1 -1
  91. package/dist/queries/buildOrderBy.d.ts.map +1 -1
  92. package/dist/queries/buildOrderBy.js +6 -1
  93. package/dist/queries/buildOrderBy.js.map +1 -1
  94. package/dist/queries/getTableColumnFromPath.d.ts +12 -3
  95. package/dist/queries/getTableColumnFromPath.d.ts.map +1 -1
  96. package/dist/queries/getTableColumnFromPath.js +52 -29
  97. package/dist/queries/getTableColumnFromPath.js.map +1 -1
  98. package/dist/queries/operatorMap.d.ts +7 -3
  99. package/dist/queries/operatorMap.d.ts.map +1 -1
  100. package/dist/queries/operatorMap.js.map +1 -1
  101. package/dist/queries/parseParams.d.ts.map +1 -1
  102. package/dist/queries/parseParams.js +226 -36
  103. package/dist/queries/parseParams.js.map +1 -1
  104. package/dist/queries/resolveRelationshipPath.d.ts +36 -0
  105. package/dist/queries/resolveRelationshipPath.d.ts.map +1 -0
  106. package/dist/queries/resolveRelationshipPath.js +66 -0
  107. package/dist/queries/resolveRelationshipPath.js.map +1 -0
  108. package/dist/queries/validateOperatorHandlers.d.ts +8 -0
  109. package/dist/queries/validateOperatorHandlers.d.ts.map +1 -0
  110. package/dist/queries/validateOperatorHandlers.js +30 -0
  111. package/dist/queries/validateOperatorHandlers.js.map +1 -0
  112. package/dist/schema/traverseFields.d.ts.map +1 -1
  113. package/dist/schema/traverseFields.js +2 -1
  114. package/dist/schema/traverseFields.js.map +1 -1
  115. package/dist/sqlite/insert.d.ts.map +1 -1
  116. package/dist/sqlite/insert.js +4 -1
  117. package/dist/sqlite/insert.js.map +1 -1
  118. package/dist/sqlite/predefinedMigrations/localize-status/index.d.ts +28 -0
  119. package/dist/sqlite/predefinedMigrations/localize-status/index.d.ts.map +1 -0
  120. package/dist/sqlite/predefinedMigrations/localize-status/index.js +198 -0
  121. package/dist/sqlite/predefinedMigrations/localize-status/index.js.map +1 -0
  122. package/dist/sqlite/predefinedMigrations/localize-status/migrateMainCollection.d.ts +12 -0
  123. package/dist/sqlite/predefinedMigrations/localize-status/migrateMainCollection.d.ts.map +1 -0
  124. package/dist/sqlite/predefinedMigrations/localize-status/migrateMainCollection.js +24 -0
  125. package/dist/sqlite/predefinedMigrations/localize-status/migrateMainCollection.js.map +1 -0
  126. package/dist/sqlite/predefinedMigrations/localize-status/migrateMainGlobal.d.ts +12 -0
  127. package/dist/sqlite/predefinedMigrations/localize-status/migrateMainGlobal.d.ts.map +1 -0
  128. package/dist/sqlite/predefinedMigrations/localize-status/migrateMainGlobal.js +28 -0
  129. package/dist/sqlite/predefinedMigrations/localize-status/migrateMainGlobal.js.map +1 -0
  130. package/dist/sqlite/predefinedMigrations/sizes-to-variants/index.d.ts +15 -0
  131. package/dist/sqlite/predefinedMigrations/sizes-to-variants/index.d.ts.map +1 -0
  132. package/dist/sqlite/predefinedMigrations/sizes-to-variants/index.js +114 -0
  133. package/dist/sqlite/predefinedMigrations/sizes-to-variants/index.js.map +1 -0
  134. package/dist/transform/read/traverseFields.js +2 -2
  135. package/dist/transform/read/traverseFields.js.map +1 -1
  136. package/dist/transform/write/blocks.js +1 -1
  137. package/dist/transform/write/blocks.js.map +1 -1
  138. package/dist/transform/write/traverseFields.js +1 -2
  139. package/dist/transform/write/traverseFields.js.map +1 -1
  140. package/dist/types.d.ts +50 -6
  141. package/dist/types.d.ts.map +1 -1
  142. package/dist/types.js +1 -3
  143. package/dist/types.js.map +1 -1
  144. package/dist/updateJobs.d.ts.map +1 -1
  145. package/dist/updateJobs.js +37 -0
  146. package/dist/updateJobs.js.map +1 -1
  147. package/dist/upsertRow/index.d.ts.map +1 -1
  148. package/dist/upsertRow/index.js +5 -2
  149. package/dist/upsertRow/index.js.map +1 -1
  150. package/dist/upsertRow/insertArrays.d.ts.map +1 -1
  151. package/dist/upsertRow/insertArrays.js +2 -1
  152. package/dist/upsertRow/insertArrays.js.map +1 -1
  153. package/dist/utilities/buildCreateMigration.d.ts.map +1 -1
  154. package/dist/utilities/buildCreateMigration.js +12 -8
  155. package/dist/utilities/buildCreateMigration.js.map +1 -1
  156. package/dist/utilities/buildDynamicPredefinedSizesToVariantsMigration.d.ts +15 -0
  157. package/dist/utilities/buildDynamicPredefinedSizesToVariantsMigration.d.ts.map +1 -0
  158. package/dist/utilities/buildDynamicPredefinedSizesToVariantsMigration.js +110 -0
  159. package/dist/utilities/buildDynamicPredefinedSizesToVariantsMigration.js.map +1 -0
  160. package/dist/utilities/checkTruncatedIdentifiers.d.ts +1 -1
  161. package/dist/utilities/createSchemaGenerator.d.ts.map +1 -1
  162. package/dist/utilities/createSchemaGenerator.js +3 -0
  163. package/dist/utilities/createSchemaGenerator.js.map +1 -1
  164. package/dist/utilities/getPrimaryDb.d.ts +1 -1
  165. package/dist/utilities/getSizesToVariantsRenames.d.ts +54 -0
  166. package/dist/utilities/getSizesToVariantsRenames.d.ts.map +1 -0
  167. package/dist/utilities/getSizesToVariantsRenames.js +251 -0
  168. package/dist/utilities/getSizesToVariantsRenames.js.map +1 -0
  169. package/dist/utilities/getTransaction.d.ts +1 -1
  170. package/dist/utilities/getTransaction.d.ts.map +1 -1
  171. package/dist/utilities/validateExistingBlockIsIdentical.d.ts +1 -4
  172. package/dist/utilities/validateExistingBlockIsIdentical.d.ts.map +1 -1
  173. package/dist/utilities/validateExistingBlockIsIdentical.js.map +1 -1
  174. package/package.json +6 -11
  175. package/dist/exports/types-deprecated.d.ts +0 -150
  176. package/dist/exports/types-deprecated.d.ts.map +0 -1
  177. package/dist/exports/types-deprecated.js +0 -5
  178. package/dist/exports/types-deprecated.js.map +0 -1
  179. package/dist/find/buildPolymorphicJoinQuery.spec.js +0 -384
  180. package/dist/find/buildPolymorphicJoinQuery.spec.js.map +0 -1
  181. package/dist/find/buildPolymorphicJoinWhere.spec.js +0 -762
  182. package/dist/find/buildPolymorphicJoinWhere.spec.js.map +0 -1
  183. package/dist/find/chainMethods.d.ts +0 -20
  184. package/dist/find/chainMethods.d.ts.map +0 -1
  185. package/dist/find/chainMethods.js +0 -16
  186. package/dist/find/chainMethods.js.map +0 -1
  187. package/dist/find/createPolymorphicJoinWherePlan.spec.js +0 -897
  188. package/dist/find/createPolymorphicJoinWherePlan.spec.js.map +0 -1
  189. package/dist/schema/buildRawSchema.spec.js +0 -231
  190. package/dist/schema/buildRawSchema.spec.js.map +0 -1
  191. package/dist/sqlite/createJSONQuery/index.spec.js +0 -28
  192. package/dist/sqlite/createJSONQuery/index.spec.js.map +0 -1
  193. package/dist/updateOne.spec.js +0 -84
  194. package/dist/updateOne.spec.js.map +0 -1
  195. package/dist/upsertRow/conditionalUpdate.spec.js +0 -61
  196. package/dist/upsertRow/conditionalUpdate.spec.js.map +0 -1
  197. package/dist/upsertRow/handleUpsertError.spec.js +0 -42
  198. package/dist/upsertRow/handleUpsertError.spec.js.map +0 -1
  199. package/dist/utilities/checkTruncatedIdentifiers.spec.js +0 -301
  200. package/dist/utilities/checkTruncatedIdentifiers.spec.js.map +0 -1
  201. package/dist/utilities/isValidStringID.spec.js +0 -15
  202. package/dist/utilities/isValidStringID.spec.js.map +0 -1
  203. package/dist/utilities/validateIdentifierLength.spec.js +0 -19
  204. package/dist/utilities/validateIdentifierLength.spec.js.map +0 -1
@@ -1,762 +0,0 @@
1
- import { createClient } from '@libsql/client';
2
- import { like, notLike } from 'drizzle-orm';
3
- import { drizzle } from 'drizzle-orm/libsql';
4
- import { integer, sqliteTable, text } from 'drizzle-orm/sqlite-core';
5
- import { afterAll, describe, expect, it } from 'vitest';
6
- import { operatorMap } from '../queries/operatorMap.js';
7
- import { createJSONQuery } from '../sqlite/createJSONQuery/index.js';
8
- import { buildPolymorphicJoinWhere } from './buildPolymorphicJoinWhere.js';
9
- const articlesTable = sqliteTable('join_articles', {
10
- id: integer('id').primaryKey(),
11
- parent: integer('parent_id'),
12
- score: integer('score'),
13
- title: text('title')
14
- });
15
- const notesTable = sqliteTable('join_notes', {
16
- id: integer('id').primaryKey(),
17
- parent: integer('parent_id'),
18
- title: text('title')
19
- });
20
- const client = createClient({
21
- url: 'file::memory:'
22
- });
23
- const db = drizzle(client, {
24
- schema: {
25
- articlesTable,
26
- notesTable
27
- }
28
- });
29
- const textField = {
30
- name: 'title',
31
- type: 'text'
32
- };
33
- const numberField = {
34
- name: 'score',
35
- type: 'number'
36
- };
37
- const hasManySelectField = {
38
- hasMany: true,
39
- name: 'tags',
40
- options: [
41
- 'available',
42
- 'reviewed'
43
- ],
44
- type: 'select'
45
- };
46
- const adapter = {
47
- createJSONQuery,
48
- drizzle: db,
49
- idType: 'serial',
50
- name: 'sqlite',
51
- operatorHandlers: [],
52
- operators: {
53
- ...operatorMap,
54
- contains: like,
55
- like,
56
- not_like: notLike
57
- },
58
- payload: {
59
- collections: {}
60
- },
61
- tableNameMap: new Map([
62
- [
63
- 'articles_tags',
64
- 'join_articles_tags'
65
- ],
66
- [
67
- 'notes_tags',
68
- 'join_notes_tags'
69
- ]
70
- ]),
71
- tables: {
72
- join_articles: articlesTable,
73
- join_notes: notesTable
74
- }
75
- };
76
- const scalarPlan = ({ collections = [
77
- 'articles'
78
- ], columnPath, field = textField, schemaPath = columnPath })=>new Map([
79
- [
80
- schemaPath,
81
- {
82
- columnPath,
83
- fieldsByCollection: new Map(collections.map((collection)=>[
84
- collection,
85
- {
86
- field,
87
- isUUID: false,
88
- type: 'scalar'
89
- }
90
- ])),
91
- schemaPath,
92
- type: 'scalar'
93
- }
94
- ]
95
- ]);
96
- const hasManySelectPlan = (collections = [
97
- 'articles'
98
- ], schemaPath = 'tags')=>new Map([
99
- [
100
- schemaPath,
101
- {
102
- columnPath: schemaPath.replaceAll('.', '_'),
103
- fieldsByCollection: new Map(collections.map((collection)=>[
104
- collection,
105
- {
106
- field: hasManySelectField,
107
- type: 'hasManySelect'
108
- }
109
- ])),
110
- schemaPath,
111
- type: 'hasManySelect'
112
- }
113
- ]
114
- ]);
115
- const renderWhere = ({ collection = 'articles', table = articlesTable, where, wherePlan })=>{
116
- const condition = buildPolymorphicJoinWhere({
117
- adapter,
118
- collection,
119
- table,
120
- where,
121
- wherePlan
122
- });
123
- return db.select({
124
- id: table.id
125
- }).from(table).where(condition).toSQL();
126
- };
127
- afterAll(()=>client.close());
128
- describe('buildPolymorphicJoinWhere', ()=>{
129
- it('builds scalar comparisons and preserves nested AND and OR groups', ()=>{
130
- const wherePlan = scalarPlan({
131
- columnPath: 'title',
132
- collections: [
133
- 'articles',
134
- 'notes'
135
- ]
136
- });
137
- const query = renderWhere({
138
- where: {
139
- AND: [
140
- {
141
- title: {
142
- equals: 'available'
143
- }
144
- },
145
- {
146
- OR: [
147
- {
148
- title: {
149
- equals: 'reviewed'
150
- }
151
- },
152
- {
153
- title: {
154
- equals: 'published'
155
- }
156
- }
157
- ]
158
- }
159
- ]
160
- },
161
- wherePlan
162
- });
163
- expect(query.sql).toContain('where ("join_articles"."title" = ? and');
164
- expect(query.sql).toContain('or');
165
- expect(query.params).toEqual([
166
- 'available',
167
- 'reviewed',
168
- 'published'
169
- ]);
170
- });
171
- it('uses equality for a numeric like constraint', ()=>{
172
- const query = renderWhere({
173
- where: {
174
- score: {
175
- like: '5'
176
- }
177
- },
178
- wherePlan: scalarPlan({
179
- columnPath: 'score',
180
- field: numberField
181
- })
182
- });
183
- expect(query.sql).toContain('"join_articles"."score" = ?');
184
- expect(query.params).toEqual([
185
- 5
186
- ]);
187
- });
188
- it('uses SQL NULL for a scalar field that is absent from the current collection', ()=>{
189
- const query = renderWhere({
190
- collection: 'notes',
191
- table: notesTable,
192
- where: {
193
- score: {
194
- exists: false
195
- }
196
- },
197
- wherePlan: scalarPlan({
198
- columnPath: 'score',
199
- collections: [
200
- 'articles'
201
- ],
202
- field: numberField
203
- })
204
- });
205
- expect(query.sql).toContain('where null is null');
206
- expect(query.params).toEqual([]);
207
- });
208
- it.each([
209
- [
210
- 'exists',
211
- {
212
- exists: 'false'
213
- },
214
- 'where null is null',
215
- []
216
- ],
217
- [
218
- 'in',
219
- {
220
- in: '1,2'
221
- },
222
- 'where null in (?, ?)',
223
- [
224
- 1,
225
- 2
226
- ]
227
- ]
228
- ])('normalizes a REST %s value when a scalar field is absent from the current collection', (_operator, constraint, expectedSQL, expectedParams)=>{
229
- const query = renderWhere({
230
- collection: 'notes',
231
- table: notesTable,
232
- where: {
233
- score: constraint
234
- },
235
- wherePlan: scalarPlan({
236
- columnPath: 'score',
237
- collections: [
238
- 'articles'
239
- ],
240
- field: numberField
241
- })
242
- });
243
- expect(query.sql).toContain(expectedSQL);
244
- expect(query.params).toEqual(expectedParams);
245
- });
246
- it('keeps contains wildcard handling when a scalar field is absent', ()=>{
247
- const query = renderWhere({
248
- collection: 'notes',
249
- table: notesTable,
250
- where: {
251
- score: {
252
- contains: '5'
253
- }
254
- },
255
- wherePlan: scalarPlan({
256
- columnPath: 'score',
257
- collections: [
258
- 'articles'
259
- ],
260
- field: numberField
261
- })
262
- });
263
- expect(query.sql).toContain('where null like ?');
264
- expect(query.params).toEqual([
265
- '%5%'
266
- ]);
267
- });
268
- it('compares relationTo with the current collection slug', ()=>{
269
- const wherePlan = new Map([
270
- [
271
- 'relationTo',
272
- {
273
- columnPath: 'relationTo',
274
- fieldsByCollection: new Map(),
275
- schemaPath: 'relationTo',
276
- type: 'scalar'
277
- }
278
- ]
279
- ]);
280
- const query = renderWhere({
281
- collection: 'notes',
282
- table: notesTable,
283
- where: {
284
- relationTo: {
285
- equals: 'notes'
286
- }
287
- },
288
- wherePlan
289
- });
290
- expect(query.sql).toContain('where ? = ?');
291
- expect(query.params).toEqual([
292
- 'notes',
293
- 'notes'
294
- ]);
295
- });
296
- it.each([
297
- [
298
- 'exists',
299
- {
300
- exists: 'false'
301
- },
302
- 'where ? is null',
303
- [
304
- 'notes'
305
- ]
306
- ],
307
- [
308
- 'in',
309
- {
310
- in: 'articles,notes'
311
- },
312
- 'where ? in (?, ?)',
313
- [
314
- 'notes',
315
- 'articles',
316
- 'notes'
317
- ]
318
- ]
319
- ])('normalizes a REST %s value for relationTo', (_operator, constraint, expectedSQL, expectedParams)=>{
320
- const wherePlan = new Map([
321
- [
322
- 'relationTo',
323
- {
324
- columnPath: 'relationTo',
325
- fieldsByCollection: new Map(),
326
- schemaPath: 'relationTo',
327
- type: 'scalar'
328
- }
329
- ]
330
- ]);
331
- const query = renderWhere({
332
- collection: 'notes',
333
- table: notesTable,
334
- where: {
335
- relationTo: constraint
336
- },
337
- wherePlan
338
- });
339
- expect(query.sql).toContain(expectedSQL);
340
- expect(query.params).toEqual(expectedParams);
341
- });
342
- it.each([
343
- [
344
- 'equals null',
345
- {
346
- title: {
347
- equals: null
348
- }
349
- },
350
- '"join_articles"."title" is null',
351
- []
352
- ],
353
- [
354
- 'not_equals null',
355
- {
356
- title: {
357
- not_equals: null
358
- }
359
- },
360
- '"join_articles"."title" is not null',
361
- []
362
- ],
363
- [
364
- 'not_equals a value',
365
- {
366
- title: {
367
- not_equals: 'restricted'
368
- }
369
- },
370
- '"join_articles"."title" is null or "join_articles"."title" <> ?',
371
- [
372
- 'restricted'
373
- ]
374
- ],
375
- [
376
- 'in values including null',
377
- {
378
- title: {
379
- in: [
380
- 'available',
381
- null
382
- ]
383
- }
384
- },
385
- '"join_articles"."title" is null or "join_articles"."title" in (?)',
386
- [
387
- 'available'
388
- ]
389
- ]
390
- ])('keeps null semantics for %s', (_description, where, expectedSQL, expectedParams)=>{
391
- const query = renderWhere({
392
- where: where,
393
- wherePlan: scalarPlan({
394
- columnPath: 'title'
395
- })
396
- });
397
- expect(query.sql).toContain(expectedSQL);
398
- expect(query.params).toEqual(expectedParams);
399
- });
400
- it('requires every word in a scalar like comparison', ()=>{
401
- const query = renderWhere({
402
- where: {
403
- title: {
404
- like: 'available child'
405
- }
406
- },
407
- wherePlan: scalarPlan({
408
- columnPath: 'title'
409
- })
410
- });
411
- expect(query.sql).toContain('"join_articles"."title" like ? and');
412
- expect(query.params).toEqual([
413
- '%available%',
414
- '%child%'
415
- ]);
416
- });
417
- it('queries a has-many select through its value table', ()=>{
418
- const query = renderWhere({
419
- where: {
420
- tags: {
421
- contains: 'available'
422
- }
423
- },
424
- wherePlan: hasManySelectPlan()
425
- });
426
- expect(query.sql).toContain('json_group_array(join_articles_tags.value)');
427
- expect(query.sql).toContain("value = 'available'");
428
- });
429
- it.each([
430
- [
431
- 'a REST exists value',
432
- {
433
- exists: 'false'
434
- },
435
- [
436
- 'NOT EXISTS (SELECT 1 FROM json_each(',
437
- 'AS tags_alias_0)'
438
- ]
439
- ],
440
- [
441
- 'a comma-delimited REST in value',
442
- {
443
- in: 'available,reviewed'
444
- },
445
- [
446
- "tags_alias_0.value = 'available'",
447
- ' OR ',
448
- "tags_alias_0.value = 'reviewed'"
449
- ]
450
- ]
451
- ])('normalizes %s for has-many selects', (_description, constraint, fragments)=>{
452
- const query = renderWhere({
453
- where: {
454
- tags: constraint
455
- },
456
- wherePlan: hasManySelectPlan()
457
- });
458
- for (const fragment of fragments){
459
- expect(query.sql).toContain(fragment);
460
- }
461
- });
462
- it.each([
463
- [
464
- 'without a schema',
465
- undefined
466
- ],
467
- [
468
- 'with a schema',
469
- 'content'
470
- ]
471
- ])('rejects a missing has-many select value table mapping %s', (_description, schemaName)=>{
472
- const adapterWithoutValueTable = {
473
- ...adapter,
474
- schemaName,
475
- tableNameMap: new Map()
476
- };
477
- expect(()=>buildPolymorphicJoinWhere({
478
- adapter: adapterWithoutValueTable,
479
- collection: 'articles',
480
- table: articlesTable,
481
- where: {
482
- tags: {
483
- equals: 'available'
484
- }
485
- },
486
- wherePlan: hasManySelectPlan()
487
- })).toThrow('Polymorphic join collection "articles" has no value table for "tags"');
488
- });
489
- it('uses an empty JSON array when a has-many select is absent from this collection', ()=>{
490
- const query = renderWhere({
491
- collection: 'notes',
492
- table: notesTable,
493
- where: {
494
- tags: {
495
- exists: false
496
- }
497
- },
498
- wherePlan: hasManySelectPlan([
499
- 'articles'
500
- ])
501
- });
502
- expect(query.sql).toContain("json_each('[]')");
503
- expect(query.sql).not.toContain('join_notes_tags');
504
- });
505
- it('builds a false condition for an empty has-many in comparison', ()=>{
506
- const query = renderWhere({
507
- where: {
508
- tags: {
509
- in: []
510
- }
511
- },
512
- wherePlan: hasManySelectPlan()
513
- });
514
- expect(query.sql).toContain('where false');
515
- });
516
- it('builds a false condition for an empty scalar in comparison', ()=>{
517
- const query = renderWhere({
518
- where: {
519
- title: {
520
- in: []
521
- }
522
- },
523
- wherePlan: scalarPlan({
524
- columnPath: 'title'
525
- })
526
- });
527
- expect(query.sql).toContain('where false');
528
- });
529
- it.each([
530
- [
531
- 'a scalar in value that cannot be normalized',
532
- {
533
- title: {
534
- in: true
535
- }
536
- },
537
- scalarPlan({
538
- columnPath: 'title'
539
- })
540
- ],
541
- [
542
- 'an undefined scalar in value',
543
- {
544
- title: {
545
- in: undefined
546
- }
547
- },
548
- scalarPlan({
549
- columnPath: 'title'
550
- })
551
- ],
552
- [
553
- 'a has-many select in value that cannot be normalized',
554
- {
555
- tags: {
556
- in: true
557
- }
558
- },
559
- hasManySelectPlan()
560
- ]
561
- ])('rejects %s', (_description, where, wherePlan)=>{
562
- expect(()=>renderWhere({
563
- where: where,
564
- wherePlan
565
- })).toThrow(Object.keys(where)[0] === 'tags' ? 'tags.in' : 'title.in');
566
- });
567
- it.each([
568
- 'AND',
569
- 'OR'
570
- ])('rejects a value that cannot be normalized inside an %s group', (booleanOperator)=>{
571
- expect(()=>renderWhere({
572
- where: {
573
- [booleanOperator]: [
574
- {
575
- title: {
576
- in: true
577
- }
578
- },
579
- {
580
- title: {
581
- equals: 'available'
582
- }
583
- }
584
- ]
585
- },
586
- wherePlan: scalarPlan({
587
- columnPath: 'title'
588
- })
589
- })).toThrow('title.in');
590
- });
591
- it.each([
592
- [
593
- 'equals',
594
- {
595
- equals: 'available'
596
- },
597
- [
598
- "tags_alias_0.value = 'available'"
599
- ]
600
- ],
601
- [
602
- 'exists',
603
- {
604
- exists: true
605
- },
606
- [
607
- 'EXISTS (SELECT 1 FROM json_each(',
608
- 'AS tags_alias_0)'
609
- ]
610
- ],
611
- [
612
- 'in',
613
- {
614
- in: [
615
- 'available',
616
- 'reviewed'
617
- ]
618
- },
619
- [
620
- "tags_alias_0.value = 'available'",
621
- ' OR ',
622
- "tags_alias_0.value = 'reviewed'"
623
- ]
624
- ],
625
- [
626
- 'like',
627
- {
628
- like: 'avail'
629
- },
630
- [
631
- "tags_alias_0.value like '%avail%'"
632
- ]
633
- ]
634
- ])('supports the %s operator for has-many selects', (_operator, constraint, expectedSQLFragments)=>{
635
- const query = renderWhere({
636
- where: {
637
- tags: constraint
638
- },
639
- wherePlan: hasManySelectPlan()
640
- });
641
- expect(query.sql).toContain('join_articles_tags');
642
- for (const expectedSQLFragment of expectedSQLFragments){
643
- expect(query.sql).toContain(expectedSQLFragment);
644
- }
645
- expect(query.params).toEqual([]);
646
- });
647
- it('accepts a string $raw constraint', ()=>{
648
- const query = renderWhere({
649
- where: {
650
- title: {
651
- $raw: 'length(title) > 3'
652
- }
653
- },
654
- wherePlan: scalarPlan({
655
- columnPath: 'title'
656
- })
657
- });
658
- expect(query.sql).toContain('where length(title) > 3');
659
- });
660
- it.each([
661
- [
662
- 'an invalid path plan',
663
- {
664
- title: {
665
- equals: 'available'
666
- }
667
- },
668
- new Map([
669
- [
670
- 'title',
671
- {
672
- columnPath: 'title',
673
- fieldsByCollection: new Map(),
674
- schemaPath: 'title',
675
- type: 'invalid'
676
- }
677
- ]
678
- ]),
679
- 'title.equals'
680
- ],
681
- [
682
- 'a missing path plan',
683
- {
684
- title: {
685
- equals: 'available'
686
- }
687
- },
688
- new Map(),
689
- 'title'
690
- ],
691
- [
692
- 'an unsupported has-many operator',
693
- {
694
- tags: {
695
- not_equals: 'available'
696
- }
697
- },
698
- hasManySelectPlan(),
699
- 'tags.not_equals'
700
- ],
701
- [
702
- 'an unknown scalar operator',
703
- {
704
- title: {
705
- near: 'available'
706
- }
707
- },
708
- scalarPlan({
709
- columnPath: 'title'
710
- }),
711
- 'title.near'
712
- ],
713
- [
714
- 'a non-string $raw value',
715
- {
716
- title: {
717
- $raw: 1
718
- }
719
- },
720
- scalarPlan({
721
- columnPath: 'title'
722
- }),
723
- 'title.$raw'
724
- ]
725
- ])('rejects %s', (_description, where, wherePlan, errorPath)=>{
726
- expect(()=>buildPolymorphicJoinWhere({
727
- adapter,
728
- collection: 'articles',
729
- table: articlesTable,
730
- where: where,
731
- wherePlan: wherePlan
732
- })).toThrow(errorPath);
733
- });
734
- it('returns no condition for empty boolean groups', ()=>{
735
- expect(buildPolymorphicJoinWhere({
736
- adapter,
737
- collection: 'articles',
738
- table: articlesTable,
739
- where: {
740
- AND: [],
741
- OR: []
742
- },
743
- wherePlan: new Map()
744
- })).toBeUndefined();
745
- });
746
- it.each([
747
- 'AND',
748
- 'OR'
749
- ])('rejects a malformed %s group', (operator)=>{
750
- expect(()=>buildPolymorphicJoinWhere({
751
- adapter,
752
- collection: 'articles',
753
- table: articlesTable,
754
- where: {
755
- [operator]: 'not-an-array'
756
- },
757
- wherePlan: new Map()
758
- })).toThrow(operator);
759
- });
760
- });
761
-
762
- //# sourceMappingURL=buildPolymorphicJoinWhere.spec.js.map