@payloadcms/drizzle 4.0.0-canary.35 → 4.0.0-canary.37
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/migrate.d.ts.map +1 -1
- package/dist/migrate.js +2 -0
- package/dist/migrate.js.map +1 -1
- package/dist/migrateDown.d.ts.map +1 -1
- package/dist/migrateDown.js +1 -0
- package/dist/migrateDown.js.map +1 -1
- package/dist/migrateFresh.d.ts.map +1 -1
- package/dist/migrateFresh.js +1 -0
- package/dist/migrateFresh.js.map +1 -1
- package/dist/migrateRefresh.d.ts.map +1 -1
- package/dist/migrateRefresh.js +2 -0
- package/dist/migrateRefresh.js.map +1 -1
- package/dist/migrateReset.d.ts.map +1 -1
- package/dist/migrateReset.js +2 -0
- package/dist/migrateReset.js.map +1 -1
- package/dist/postgres/predefinedMigrations/v2-v3/fetchAndResave/index.d.ts.map +1 -1
- package/dist/postgres/predefinedMigrations/v2-v3/fetchAndResave/index.js +8 -4
- package/dist/postgres/predefinedMigrations/v2-v3/fetchAndResave/index.js.map +1 -1
- package/dist/sqlite/insert.d.ts.map +1 -1
- package/dist/sqlite/insert.js +4 -1
- package/dist/sqlite/insert.js.map +1 -1
- package/package.json +3 -3
- package/dist/find/buildPolymorphicJoinQuery.spec.js +0 -384
- package/dist/find/buildPolymorphicJoinQuery.spec.js.map +0 -1
- package/dist/find/buildPolymorphicJoinWhere.spec.js +0 -805
- package/dist/find/buildPolymorphicJoinWhere.spec.js.map +0 -1
- package/dist/find/createPolymorphicJoinWherePlan.spec.js +0 -778
- package/dist/find/createPolymorphicJoinWherePlan.spec.js.map +0 -1
- package/dist/postgres/query/assertOperatorHandlerExtensionsInstalled.spec.js +0 -91
- package/dist/postgres/query/assertOperatorHandlerExtensionsInstalled.spec.js.map +0 -1
- package/dist/postgres/query/postgresUnaccent.spec.js +0 -71
- package/dist/postgres/query/postgresUnaccent.spec.js.map +0 -1
- package/dist/queries/buildOperatorConstraint.spec.js +0 -348
- package/dist/queries/buildOperatorConstraint.spec.js.map +0 -1
- package/dist/queries/validateOperatorHandlers.spec.js +0 -142
- package/dist/queries/validateOperatorHandlers.spec.js.map +0 -1
- package/dist/schema/buildRawSchema.spec.js +0 -290
- package/dist/schema/buildRawSchema.spec.js.map +0 -1
- package/dist/updateOne.spec.js +0 -84
- package/dist/updateOne.spec.js.map +0 -1
- package/dist/upsertRow/conditionalUpdate.spec.js +0 -61
- package/dist/upsertRow/conditionalUpdate.spec.js.map +0 -1
- package/dist/upsertRow/handleUpsertError.spec.js +0 -42
- package/dist/upsertRow/handleUpsertError.spec.js.map +0 -1
- package/dist/utilities/checkTruncatedIdentifiers.spec.js +0 -301
- package/dist/utilities/checkTruncatedIdentifiers.spec.js.map +0 -1
- package/dist/utilities/isValidStringID.spec.js +0 -15
- package/dist/utilities/isValidStringID.spec.js.map +0 -1
- package/dist/utilities/validateIdentifierLength.spec.js +0 -19
- package/dist/utilities/validateIdentifierLength.spec.js.map +0 -1
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/find/createPolymorphicJoinWherePlan.spec.ts"],"sourcesContent":["import type { Field, FlattenedField, Where } from 'payload'\n\nimport { getTableName } from 'drizzle-orm'\nimport { pgEnum, pgTable, serial } from 'drizzle-orm/pg-core'\nimport { integer, sqliteTable, text } from 'drizzle-orm/sqlite-core'\nimport { flattenAllFields } from 'payload'\nimport toSnakeCase from 'to-snake-case'\nimport { describe, expect, it } from 'vitest'\n\nimport type { DrizzleAdapter, GenericTable } from '../types.js'\n\nimport { createPolymorphicJoinWherePlan } from './createPolymorphicJoinWherePlan.js'\n\ntype CollectionFixture = {\n fields: Field[]\n table: GenericTable\n}\n\nconst articlesTable = sqliteTable('join_articles', {\n id: integer('id').primaryKey(),\n details_status: text('details_status_flat'),\n score: integer('score'),\n status: text('status'),\n title: text('title'),\n variantSelect: text('variant_select'),\n variantValue: text('variant_value'),\n})\n\nconst notesTable = sqliteTable('join_notes', {\n id: integer('id').primaryKey(),\n details_status: text('details_status_flat'),\n status: text('status'),\n title: text('title'),\n variantSelect: integer('variant_select'),\n variantTags: text('variant_tags'),\n variantValue: integer('variant_value'),\n})\n\nconst articleSelectEnum = pgEnum('join_plan_article_select', ['available', 'reviewed'])\nconst articleRadioEnum = pgEnum('join_plan_article_radio', ['draft', 'published'])\nconst noteSelectEnum = pgEnum('join_plan_note_select', ['available', 'reviewed'])\nconst noteRadioEnum = pgEnum('join_plan_note_radio', ['draft', 'published'])\n\nconst postgresArticlesTable = pgTable('join_plan_articles', {\n id: serial('id').primaryKey(),\n variantRadio: articleRadioEnum('variant_radio'),\n variantSelect: articleSelectEnum('variant_select'),\n})\n\nconst postgresNotesTable = pgTable('join_plan_notes', {\n id: serial('id').primaryKey(),\n variantRadio: noteRadioEnum('variant_radio'),\n variantSelect: noteSelectEnum('variant_select'),\n})\n\nconst articleFields: Field[] = [\n { name: 'title', type: 'text' },\n { name: 'score', type: 'number' },\n {\n name: 'details',\n type: 'group',\n fields: [\n { name: 'status', type: 'text' },\n { hasMany: true, name: 'tags', options: ['available'], type: 'select' },\n ],\n },\n { name: 'details_status', type: 'text' },\n { name: 'status', type: 'text' },\n { hasMany: true, name: 'variantTags', options: ['available'], type: 'select' },\n { name: 'variantSelect', options: ['available'], type: 'select' },\n { name: 'variantValue', type: 'text' },\n { localized: true, name: 'localizedTitle', type: 'text' },\n {\n name: 'entries',\n type: 'array',\n fields: [{ hasMany: true, name: 'tags', options: ['available'], type: 'select' }],\n },\n {\n name: 'content',\n type: 'blocks',\n blocks: [\n {\n slug: 'hero',\n fields: [{ hasMany: true, name: 'tags', options: ['available'], type: 'select' }],\n },\n ],\n },\n]\n\nconst noteFields: Field[] = [\n { name: 'title', type: 'text' },\n {\n name: 'details',\n type: 'group',\n fields: [\n { name: 'status', type: 'text' },\n { hasMany: true, name: 'tags', options: ['available'], type: 'select' },\n ],\n },\n { name: 'details_status', type: 'text' },\n { name: 'status', type: 'text' },\n { name: 'variantTags', options: ['available'], type: 'select' },\n { name: 'variantSelect', options: ['available'], type: 'select' },\n { name: 'variantValue', type: 'number' },\n]\n\nconst articleEnumFields: Field[] = [\n {\n name: 'variantSelect',\n options: ['available', { label: 'Reviewed', value: 'reviewed' }],\n type: 'select',\n },\n { name: 'variantRadio', options: ['draft', 'published'], type: 'radio' },\n]\n\nconst noteEnumFields: Field[] = [\n {\n name: 'variantSelect',\n options: [{ label: 'Available', value: 'available' }, 'reviewed'],\n type: 'select',\n },\n {\n name: 'variantRadio',\n options: [\n { label: 'Draft', value: 'draft' },\n { label: 'Published', value: 'published' },\n ],\n type: 'radio',\n },\n]\n\nconst createAdapter = (fixtures: Record<string, CollectionFixture>): DrizzleAdapter => {\n const collections: Record<\n string,\n { config: { fields: Field[]; flattenedFields: FlattenedField[] } }\n > = {}\n const tableNameMap = new Map<string, string>()\n const tables: Record<string, GenericTable | undefined> = {}\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 idType: 'serial',\n payload: { collections },\n tableNameMap,\n tables,\n } as unknown as DrizzleAdapter\n}\n\nconst adapter = createAdapter({\n articles: { fields: articleFields, table: articlesTable },\n notes: { fields: noteFields, table: notesTable },\n})\n\nconst createPlan = (where: Where, collections = ['articles', 'notes']) =>\n createPolymorphicJoinWherePlan({ adapter, collections, where })\n\ndescribe('createPolymorphicJoinWherePlan', () => {\n it('creates one scalar plan per unique field in nested boolean clauses', () => {\n const plan = createPlan({\n AND: [\n { title: { equals: 'available' } },\n { 'details.status': { equals: 'reviewed' } },\n { OR: [{ score: { greater_than: 1 } }, { title: { not_equals: 'restricted' } }] },\n ],\n })\n\n expect([...plan.keys()]).toEqual(['title', 'details.status', 'score'])\n expect(plan.get('title')).toMatchObject({\n columnPath: 'title',\n schemaPath: 'title',\n type: 'scalar',\n })\n expect([...plan.get('title').fieldsByCollection.keys()]).toEqual(['articles', 'notes'])\n expect(plan.get('details.status')).toMatchObject({\n columnPath: 'details_status',\n type: 'scalar',\n })\n expect([...plan.get('score').fieldsByCollection.keys()]).toEqual(['articles'])\n })\n\n it('creates scalar plans for id and relationTo without configured fields', () => {\n const plan = createPlan({\n id: { in: [1, 2] },\n relationTo: { equals: 'articles' },\n })\n\n expect(plan.get('id')).toMatchObject({ columnPath: 'id', type: 'scalar' })\n expect([...plan.get('id').fieldsByCollection.keys()]).toEqual(['articles', 'notes'])\n expect(plan.get('relationTo')).toMatchObject({ columnPath: 'relationTo', type: 'scalar' })\n expect(plan.get('relationTo').fieldsByCollection.size).toBe(0)\n })\n\n it('uses a synthetic UUID field context for an id path without a configured id field', () => {\n const uuidTable = sqliteTable('uuid_articles', {\n id: text('id').primaryKey(),\n })\n const uuidAdapter = createAdapter({ articles: { fields: [], table: uuidTable } })\n\n uuidAdapter.idType = 'uuid'\n\n const idPlan = createPolymorphicJoinWherePlan({\n adapter: uuidAdapter,\n collections: ['articles'],\n where: { id: { equals: '01991f04-1780-7000-8000-000000000001' } },\n }).get('id')\n\n expect(idPlan.fieldsByCollection.get('articles')).toMatchObject({\n field: { name: 'id', type: 'text' },\n isUUID: true,\n type: 'scalar',\n })\n })\n\n it('keeps a scalar path valid when it is absent from one target collection', () => {\n const scorePlan = createPlan({ score: { equals: 5 } }).get('score')\n\n expect(scorePlan.type).toBe('scalar')\n expect([...scorePlan.fieldsByCollection.keys()]).toEqual(['articles'])\n })\n\n it('creates a hasManySelect plan when the field uses separate value rows', () => {\n const tagsPlan = createPlan({ 'details.tags': { contains: 'available' } }).get('details.tags')\n\n expect(tagsPlan).toMatchObject({\n columnPath: 'details_tags',\n schemaPath: 'details.tags',\n type: 'hasManySelect',\n })\n expect([...tagsPlan.fieldsByCollection.values()]).toEqual([\n expect.objectContaining({\n field: expect.objectContaining({ name: 'tags' }),\n type: 'hasManySelect',\n }),\n expect.objectContaining({\n field: expect.objectContaining({ name: 'tags' }),\n type: 'hasManySelect',\n }),\n ])\n })\n\n it('accepts matching select fields even when their database column types differ', () => {\n const selectPlan = createPlan({ variantSelect: { equals: 'available' } }).get('variantSelect')\n\n expect(selectPlan.type).toBe('scalar')\n expect([...selectPlan.fieldsByCollection.keys()]).toEqual(['articles', 'notes'])\n })\n\n it('accepts text and textarea fields that use the same query value coercion', () => {\n const fieldsWithTextarea = noteFields.map((field) =>\n field.name === 'title' ? { ...field, type: 'textarea' as const } : field,\n )\n const compatibleAdapter = createAdapter({\n articles: { fields: articleFields, table: articlesTable },\n notes: { fields: fieldsWithTextarea, table: notesTable },\n })\n const titlePlan = createPolymorphicJoinWherePlan({\n adapter: compatibleAdapter,\n collections: ['articles', 'notes'],\n where: { title: { equals: 'available' } },\n }).get('title')\n\n expect(titlePlan.type).toBe('scalar')\n })\n\n it.each([\n ['select', 'variantSelect', 'available'],\n ['radio', 'variantRadio', 'draft'],\n ] as const)(\n 'accepts PostgreSQL %s fields with separate enum types and matching option values',\n (_fieldType, schemaPath, value) => {\n const postgresAdapter = createAdapter({\n articles: { fields: articleEnumFields, table: postgresArticlesTable },\n notes: { fields: noteEnumFields, table: postgresNotesTable },\n })\n const fieldPlan = createPolymorphicJoinWherePlan({\n adapter: postgresAdapter,\n collections: ['articles', 'notes'],\n where: { [schemaPath]: { equals: value } },\n }).get(schemaPath)\n\n expect(fieldPlan.type).toBe('scalar')\n expect([...fieldPlan.fieldsByCollection.keys()]).toEqual(['articles', 'notes'])\n },\n )\n\n it.each([\n ['select', 'variantSelect', ['available', 'restricted']],\n ['select', 'variantSelect', ['reviewed', 'available']],\n ['radio', 'variantRadio', ['draft', 'restricted']],\n ['radio', 'variantRadio', ['published', 'draft']],\n ] as const)(\n 'rejects PostgreSQL %s fields whose option values differ or use a different order',\n (fieldType, schemaPath, options) => {\n const noteFieldsWithDifferentOptions = noteEnumFields.map((field) =>\n field.name === schemaPath ? { ...field, options: [...options], type: fieldType } : field,\n ) as Field[]\n const postgresAdapter = createAdapter({\n articles: { fields: articleEnumFields, table: postgresArticlesTable },\n notes: { fields: noteFieldsWithDifferentOptions, table: postgresNotesTable },\n })\n const fieldPlan = createPolymorphicJoinWherePlan({\n adapter: postgresAdapter,\n collections: ['articles', 'notes'],\n where: { [schemaPath]: { equals: options[0] } },\n }).get(schemaPath)\n\n expect(fieldPlan.type).toBe('invalid')\n },\n )\n\n it.each([\n ['a field that is absent from every collection', { unknown: { equals: 'value' } }, 'unknown'],\n ['incompatible scalar field types', { variantValue: { equals: 'value' } }, 'variantValue'],\n [\n 'a has-many select mixed with a scalar select',\n { variantTags: { contains: 'available' } },\n 'variantTags',\n ],\n ['a localized field', { localizedTitle: { equals: 'value' } }, 'localizedTitle'],\n ['a field stored in array rows', { 'entries.tags': { equals: 'value' } }, 'entries.tags'],\n [\n 'a field stored in block rows',\n { 'content.hero.tags': { equals: 'value' } },\n 'content.hero.tags',\n ],\n ] as const)('marks %s as invalid', (_description, where, schemaPath) => {\n expect(createPlan(where as Where).get(schemaPath)).toMatchObject({ type: 'invalid' })\n })\n\n it('marks both schema paths as invalid when they resolve to the same flattened column path', () => {\n const plan = createPlan({\n 'details.status': { equals: 'available' },\n details_status: { equals: 'available' },\n })\n\n expect(plan.get('details.status')).toMatchObject({\n columnPath: 'details_status',\n type: 'invalid',\n })\n expect(plan.get('details_status')).toMatchObject({\n columnPath: 'details_status',\n type: 'invalid',\n })\n })\n\n it('marks a configured scalar field as invalid when its table column is missing', () => {\n const tableWithoutTitle = sqliteTable('articles_without_title', {\n id: integer('id').primaryKey(),\n })\n const adapterWithoutTitle = createAdapter({\n articles: { fields: [{ name: 'title', type: 'text' }], table: tableWithoutTitle },\n })\n const plan = createPolymorphicJoinWherePlan({\n adapter: adapterWithoutTitle,\n collections: ['articles'],\n where: { title: { equals: 'available' } },\n })\n\n expect(plan.get('title')).toMatchObject({ type: 'invalid' })\n })\n\n it('marks an id path as invalid when a target table has no id column', () => {\n const tableWithoutID = sqliteTable('articles_without_id', {\n title: text('title'),\n })\n const adapterWithoutID = createAdapter({\n articles: { fields: [{ name: 'title', type: 'text' }], table: tableWithoutID },\n })\n const plan = createPolymorphicJoinWherePlan({\n adapter: adapterWithoutID,\n collections: ['articles'],\n where: { id: { equals: 1 } },\n })\n\n expect(plan.get('id')).toMatchObject({ type: 'invalid' })\n })\n\n it('marks every requested path as invalid when there are no target collections', () => {\n expect(createPlan({ title: { equals: 'available' } }, []).get('title')).toMatchObject({\n type: 'invalid',\n })\n })\n\n it('throws a descriptive error when a target collection is not configured', () => {\n expect(() => createPlan({ title: { equals: 'available' } }, ['missing'])).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: { fields: [{ name: 'title', type: 'text' }], table: articlesTable },\n })\n\n adapterWithoutTable.tables = {}\n\n expect(() =>\n createPolymorphicJoinWherePlan({\n adapter: adapterWithoutTable,\n collections: ['articles'],\n where: { title: { equals: 'available' } },\n }),\n ).toThrow('Polymorphic join collection \"articles\" has no database table')\n })\n})\n"],"names":["getTableName","pgEnum","pgTable","serial","integer","sqliteTable","text","flattenAllFields","toSnakeCase","describe","expect","it","createPolymorphicJoinWherePlan","articlesTable","id","primaryKey","details_status","score","status","title","variantSelect","variantValue","notesTable","variantTags","articleSelectEnum","articleRadioEnum","noteSelectEnum","noteRadioEnum","postgresArticlesTable","variantRadio","postgresNotesTable","articleFields","name","type","fields","hasMany","options","localized","blocks","slug","noteFields","articleEnumFields","label","value","noteEnumFields","createAdapter","fixtures","collections","tableNameMap","Map","tables","fixture","Object","entries","tableName","table","config","flattenedFields","set","idType","payload","adapter","articles","notes","createPlan","where","plan","AND","equals","OR","greater_than","not_equals","keys","toEqual","get","toMatchObject","columnPath","schemaPath","fieldsByCollection","in","relationTo","size","toBe","uuidTable","uuidAdapter","idPlan","field","isUUID","scorePlan","tagsPlan","contains","values","objectContaining","selectPlan","fieldsWithTextarea","map","compatibleAdapter","titlePlan","each","_fieldType","postgresAdapter","fieldPlan","fieldType","noteFieldsWithDifferentOptions","unknown","localizedTitle","_description","tableWithoutTitle","adapterWithoutTitle","tableWithoutID","adapterWithoutID","toThrow","adapterWithoutTable"],"mappings":"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"}
|
|
@@ -1,91 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it, vi } from 'vitest';
|
|
2
|
-
import { assertOperatorHandlerExtensionsInstalled } from './assertOperatorHandlerExtensionsInstalled.js';
|
|
3
|
-
const transformHandler = (overrides = {})=>({
|
|
4
|
-
name: 'transform',
|
|
5
|
-
operators: [
|
|
6
|
-
'contains'
|
|
7
|
-
],
|
|
8
|
-
transformOperands: ({ column, value })=>({
|
|
9
|
-
column,
|
|
10
|
-
value
|
|
11
|
-
}),
|
|
12
|
-
...overrides
|
|
13
|
-
});
|
|
14
|
-
const drizzleWithInstalledExtensions = (installedExtensions)=>({
|
|
15
|
-
execute: vi.fn().mockResolvedValue({
|
|
16
|
-
rows: installedExtensions.map((extname)=>({
|
|
17
|
-
extname
|
|
18
|
-
}))
|
|
19
|
-
})
|
|
20
|
-
});
|
|
21
|
-
describe('assertOperatorHandlerExtensionsInstalled', ()=>{
|
|
22
|
-
it('does not query the database when no handler declares requiredExtensions', async ()=>{
|
|
23
|
-
const drizzle = drizzleWithInstalledExtensions([]);
|
|
24
|
-
await expect(assertOperatorHandlerExtensionsInstalled({
|
|
25
|
-
drizzle: drizzle,
|
|
26
|
-
operatorHandlers: [
|
|
27
|
-
transformHandler({
|
|
28
|
-
requiredExtensions: undefined
|
|
29
|
-
})
|
|
30
|
-
]
|
|
31
|
-
})).resolves.toBeUndefined();
|
|
32
|
-
expect(drizzle.execute).not.toHaveBeenCalled();
|
|
33
|
-
});
|
|
34
|
-
it('does not throw for a handler requiring an extension installed in the database', async ()=>{
|
|
35
|
-
const drizzle = drizzleWithInstalledExtensions([
|
|
36
|
-
'unaccent'
|
|
37
|
-
]);
|
|
38
|
-
await expect(assertOperatorHandlerExtensionsInstalled({
|
|
39
|
-
drizzle: drizzle,
|
|
40
|
-
operatorHandlers: [
|
|
41
|
-
transformHandler({
|
|
42
|
-
requiredExtensions: [
|
|
43
|
-
'unaccent'
|
|
44
|
-
]
|
|
45
|
-
})
|
|
46
|
-
]
|
|
47
|
-
})).resolves.toBeUndefined();
|
|
48
|
-
});
|
|
49
|
-
it('throws for a handler requiring an extension absent from the database, naming the handler and the missing extension', async ()=>{
|
|
50
|
-
const drizzle = drizzleWithInstalledExtensions([]);
|
|
51
|
-
await expect(assertOperatorHandlerExtensionsInstalled({
|
|
52
|
-
drizzle: drizzle,
|
|
53
|
-
operatorHandlers: [
|
|
54
|
-
transformHandler({
|
|
55
|
-
name: 'postgres-unaccent',
|
|
56
|
-
requiredExtensions: [
|
|
57
|
-
'unaccent'
|
|
58
|
-
]
|
|
59
|
-
})
|
|
60
|
-
]
|
|
61
|
-
})).rejects.toThrow(/postgres-unaccent/);
|
|
62
|
-
await expect(assertOperatorHandlerExtensionsInstalled({
|
|
63
|
-
drizzle: drizzle,
|
|
64
|
-
operatorHandlers: [
|
|
65
|
-
transformHandler({
|
|
66
|
-
name: 'postgres-unaccent',
|
|
67
|
-
requiredExtensions: [
|
|
68
|
-
'unaccent'
|
|
69
|
-
]
|
|
70
|
-
})
|
|
71
|
-
]
|
|
72
|
-
})).rejects.toThrow(/unaccent/);
|
|
73
|
-
});
|
|
74
|
-
it('does not throw when the extension is installed even though it is not declared in any config option', async ()=>{
|
|
75
|
-
const drizzle = drizzleWithInstalledExtensions([
|
|
76
|
-
'unaccent'
|
|
77
|
-
]);
|
|
78
|
-
await expect(assertOperatorHandlerExtensionsInstalled({
|
|
79
|
-
drizzle: drizzle,
|
|
80
|
-
operatorHandlers: [
|
|
81
|
-
transformHandler({
|
|
82
|
-
requiredExtensions: [
|
|
83
|
-
'unaccent'
|
|
84
|
-
]
|
|
85
|
-
})
|
|
86
|
-
]
|
|
87
|
-
})).resolves.toBeUndefined();
|
|
88
|
-
});
|
|
89
|
-
});
|
|
90
|
-
|
|
91
|
-
//# sourceMappingURL=assertOperatorHandlerExtensionsInstalled.spec.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/postgres/query/assertOperatorHandlerExtensionsInstalled.spec.ts"],"sourcesContent":["import { describe, expect, it, vi } from 'vitest'\n\nimport type { PostgresOperatorHandler } from '../types.js'\n\nimport { assertOperatorHandlerExtensionsInstalled } from './assertOperatorHandlerExtensionsInstalled.js'\n\nconst transformHandler = (\n overrides: Partial<PostgresOperatorHandler> = {},\n): PostgresOperatorHandler =>\n ({\n name: 'transform',\n operators: ['contains'],\n transformOperands: ({ column, value }) => ({ column, value }),\n ...overrides,\n }) as PostgresOperatorHandler\n\nconst drizzleWithInstalledExtensions = (installedExtensions: string[]) => ({\n execute: vi.fn().mockResolvedValue({\n rows: installedExtensions.map((extname) => ({ extname })),\n }),\n})\n\ndescribe('assertOperatorHandlerExtensionsInstalled', () => {\n it('does not query the database when no handler declares requiredExtensions', async () => {\n const drizzle = drizzleWithInstalledExtensions([])\n\n await expect(\n assertOperatorHandlerExtensionsInstalled({\n drizzle: drizzle as any,\n operatorHandlers: [transformHandler({ requiredExtensions: undefined })],\n }),\n ).resolves.toBeUndefined()\n\n expect(drizzle.execute).not.toHaveBeenCalled()\n })\n\n it('does not throw for a handler requiring an extension installed in the database', async () => {\n const drizzle = drizzleWithInstalledExtensions(['unaccent'])\n\n await expect(\n assertOperatorHandlerExtensionsInstalled({\n drizzle: drizzle as any,\n operatorHandlers: [transformHandler({ requiredExtensions: ['unaccent'] })],\n }),\n ).resolves.toBeUndefined()\n })\n\n it('throws for a handler requiring an extension absent from the database, naming the handler and the missing extension', async () => {\n const drizzle = drizzleWithInstalledExtensions([])\n\n await expect(\n assertOperatorHandlerExtensionsInstalled({\n drizzle: drizzle as any,\n operatorHandlers: [\n transformHandler({ name: 'postgres-unaccent', requiredExtensions: ['unaccent'] }),\n ],\n }),\n ).rejects.toThrow(/postgres-unaccent/)\n\n await expect(\n assertOperatorHandlerExtensionsInstalled({\n drizzle: drizzle as any,\n operatorHandlers: [\n transformHandler({ name: 'postgres-unaccent', requiredExtensions: ['unaccent'] }),\n ],\n }),\n ).rejects.toThrow(/unaccent/)\n })\n\n it('does not throw when the extension is installed even though it is not declared in any config option', async () => {\n const drizzle = drizzleWithInstalledExtensions(['unaccent'])\n\n await expect(\n assertOperatorHandlerExtensionsInstalled({\n drizzle: drizzle as any,\n operatorHandlers: [transformHandler({ requiredExtensions: ['unaccent'] })],\n }),\n ).resolves.toBeUndefined()\n })\n})\n"],"names":["describe","expect","it","vi","assertOperatorHandlerExtensionsInstalled","transformHandler","overrides","name","operators","transformOperands","column","value","drizzleWithInstalledExtensions","installedExtensions","execute","fn","mockResolvedValue","rows","map","extname","drizzle","operatorHandlers","requiredExtensions","undefined","resolves","toBeUndefined","not","toHaveBeenCalled","rejects","toThrow"],"mappings":"AAAA,SAASA,QAAQ,EAAEC,MAAM,EAAEC,EAAE,EAAEC,EAAE,QAAQ,SAAQ;AAIjD,SAASC,wCAAwC,QAAQ,gDAA+C;AAExG,MAAMC,mBAAmB,CACvBC,YAA8C,CAAC,CAAC,GAE/C,CAAA;QACCC,MAAM;QACNC,WAAW;YAAC;SAAW;QACvBC,mBAAmB,CAAC,EAAEC,MAAM,EAAEC,KAAK,EAAE,GAAM,CAAA;gBAAED;gBAAQC;YAAM,CAAA;QAC3D,GAAGL,SAAS;IACd,CAAA;AAEF,MAAMM,iCAAiC,CAACC,sBAAmC,CAAA;QACzEC,SAASX,GAAGY,EAAE,GAAGC,iBAAiB,CAAC;YACjCC,MAAMJ,oBAAoBK,GAAG,CAAC,CAACC,UAAa,CAAA;oBAAEA;gBAAQ,CAAA;QACxD;IACF,CAAA;AAEAnB,SAAS,4CAA4C;IACnDE,GAAG,2EAA2E;QAC5E,MAAMkB,UAAUR,+BAA+B,EAAE;QAEjD,MAAMX,OACJG,yCAAyC;YACvCgB,SAASA;YACTC,kBAAkB;gBAAChB,iBAAiB;oBAAEiB,oBAAoBC;gBAAU;aAAG;QACzE,IACAC,QAAQ,CAACC,aAAa;QAExBxB,OAAOmB,QAAQN,OAAO,EAAEY,GAAG,CAACC,gBAAgB;IAC9C;IAEAzB,GAAG,iFAAiF;QAClF,MAAMkB,UAAUR,+BAA+B;YAAC;SAAW;QAE3D,MAAMX,OACJG,yCAAyC;YACvCgB,SAASA;YACTC,kBAAkB;gBAAChB,iBAAiB;oBAAEiB,oBAAoB;wBAAC;qBAAW;gBAAC;aAAG;QAC5E,IACAE,QAAQ,CAACC,aAAa;IAC1B;IAEAvB,GAAG,sHAAsH;QACvH,MAAMkB,UAAUR,+BAA+B,EAAE;QAEjD,MAAMX,OACJG,yCAAyC;YACvCgB,SAASA;YACTC,kBAAkB;gBAChBhB,iBAAiB;oBAAEE,MAAM;oBAAqBe,oBAAoB;wBAAC;qBAAW;gBAAC;aAChF;QACH,IACAM,OAAO,CAACC,OAAO,CAAC;QAElB,MAAM5B,OACJG,yCAAyC;YACvCgB,SAASA;YACTC,kBAAkB;gBAChBhB,iBAAiB;oBAAEE,MAAM;oBAAqBe,oBAAoB;wBAAC;qBAAW;gBAAC;aAChF;QACH,IACAM,OAAO,CAACC,OAAO,CAAC;IACpB;IAEA3B,GAAG,sGAAsG;QACvG,MAAMkB,UAAUR,+BAA+B;YAAC;SAAW;QAE3D,MAAMX,OACJG,yCAAyC;YACvCgB,SAASA;YACTC,kBAAkB;gBAAChB,iBAAiB;oBAAEiB,oBAAoB;wBAAC;qBAAW;gBAAC;aAAG;QAC5E,IACAE,QAAQ,CAACC,aAAa;IAC1B;AACF"}
|
|
@@ -1,71 +0,0 @@
|
|
|
1
|
-
import { is, sql } from 'drizzle-orm';
|
|
2
|
-
import { PgUUID } from 'drizzle-orm/pg-core';
|
|
3
|
-
import { describe, expect, it } from 'vitest';
|
|
4
|
-
import { postgresUnaccent } from './postgresUnaccent.js';
|
|
5
|
-
describe('postgresUnaccent', ()=>{
|
|
6
|
-
it('returns a handler with the expected name and operators', ()=>{
|
|
7
|
-
const handler = postgresUnaccent();
|
|
8
|
-
expect(handler.name).toBe('postgres-unaccent');
|
|
9
|
-
expect(handler.operators).toEqual([
|
|
10
|
-
'contains',
|
|
11
|
-
'like',
|
|
12
|
-
'not_like'
|
|
13
|
-
]);
|
|
14
|
-
});
|
|
15
|
-
it('declares fieldTypes restricted to text and textarea', ()=>{
|
|
16
|
-
const handler = postgresUnaccent();
|
|
17
|
-
expect(handler.fieldTypes).toEqual([
|
|
18
|
-
'text',
|
|
19
|
-
'textarea'
|
|
20
|
-
]);
|
|
21
|
-
});
|
|
22
|
-
it('declares requiredExtensions of unaccent', ()=>{
|
|
23
|
-
const handler = postgresUnaccent();
|
|
24
|
-
expect(handler.requiredExtensions).toEqual([
|
|
25
|
-
'unaccent'
|
|
26
|
-
]);
|
|
27
|
-
});
|
|
28
|
-
it('wraps the column and value in a parameterized unaccent(...) SQL expression', ()=>{
|
|
29
|
-
const handler = postgresUnaccent();
|
|
30
|
-
const column = sql`"title"`;
|
|
31
|
-
const result = handler.transformOperands({
|
|
32
|
-
adapter: {},
|
|
33
|
-
column,
|
|
34
|
-
field: {
|
|
35
|
-
name: 'title',
|
|
36
|
-
type: 'text'
|
|
37
|
-
},
|
|
38
|
-
originalOperator: 'contains',
|
|
39
|
-
path: 'title',
|
|
40
|
-
resolvedOperator: 'contains',
|
|
41
|
-
storage: 'column',
|
|
42
|
-
value: '%acido%'
|
|
43
|
-
});
|
|
44
|
-
expect(is(result.column, Object)).toBe(true);
|
|
45
|
-
expect(result.column.queryChunks[0].value[0]).toBe('unaccent(');
|
|
46
|
-
expect(result.column.queryChunks[1]).toBe(column);
|
|
47
|
-
expect(result.value.queryChunks[0].value[0]).toBe('unaccent(');
|
|
48
|
-
expect(result.value.queryChunks[1]).toBe('%acido%');
|
|
49
|
-
});
|
|
50
|
-
it('returns the operands unchanged when the column is a native PgUUID column', ()=>{
|
|
51
|
-
const handler = postgresUnaccent();
|
|
52
|
-
const uuidColumn = Object.create(PgUUID.prototype);
|
|
53
|
-
const result = handler.transformOperands({
|
|
54
|
-
adapter: {},
|
|
55
|
-
column: uuidColumn,
|
|
56
|
-
field: {
|
|
57
|
-
name: 'id',
|
|
58
|
-
type: 'text'
|
|
59
|
-
},
|
|
60
|
-
originalOperator: 'contains',
|
|
61
|
-
path: 'id',
|
|
62
|
-
resolvedOperator: 'contains',
|
|
63
|
-
storage: 'column',
|
|
64
|
-
value: '%acido%'
|
|
65
|
-
});
|
|
66
|
-
expect(result.column).toBe(uuidColumn);
|
|
67
|
-
expect(result.value).toBe('%acido%');
|
|
68
|
-
});
|
|
69
|
-
});
|
|
70
|
-
|
|
71
|
-
//# sourceMappingURL=postgresUnaccent.spec.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/postgres/query/postgresUnaccent.spec.ts"],"sourcesContent":["import { is, sql } from 'drizzle-orm'\nimport { PgUUID } from 'drizzle-orm/pg-core'\nimport { describe, expect, it } from 'vitest'\n\nimport { postgresUnaccent } from './postgresUnaccent.js'\n\ndescribe('postgresUnaccent', () => {\n it('returns a handler with the expected name and operators', () => {\n const handler = postgresUnaccent()\n\n expect(handler.name).toBe('postgres-unaccent')\n expect(handler.operators).toEqual(['contains', 'like', 'not_like'])\n })\n\n it('declares fieldTypes restricted to text and textarea', () => {\n const handler = postgresUnaccent()\n\n expect(handler.fieldTypes).toEqual(['text', 'textarea'])\n })\n\n it('declares requiredExtensions of unaccent', () => {\n const handler = postgresUnaccent()\n\n expect(handler.requiredExtensions).toEqual(['unaccent'])\n })\n\n it('wraps the column and value in a parameterized unaccent(...) SQL expression', () => {\n const handler = postgresUnaccent()\n const column = sql`\"title\"`\n\n const result = handler.transformOperands({\n adapter: {} as any,\n column,\n field: { name: 'title', type: 'text' } as any,\n originalOperator: 'contains',\n path: 'title',\n resolvedOperator: 'contains',\n storage: 'column',\n value: '%acido%',\n })\n\n expect(is(result.column, Object)).toBe(true)\n expect((result.column as any).queryChunks[0].value[0]).toBe('unaccent(')\n expect((result.column as any).queryChunks[1]).toBe(column)\n\n expect((result.value as any).queryChunks[0].value[0]).toBe('unaccent(')\n expect((result.value as any).queryChunks[1]).toBe('%acido%')\n })\n\n it('returns the operands unchanged when the column is a native PgUUID column', () => {\n const handler = postgresUnaccent()\n const uuidColumn = Object.create(PgUUID.prototype)\n\n const result = handler.transformOperands({\n adapter: {} as any,\n column: uuidColumn,\n field: { name: 'id', type: 'text' } as any,\n originalOperator: 'contains',\n path: 'id',\n resolvedOperator: 'contains',\n storage: 'column',\n value: '%acido%',\n })\n\n expect(result.column).toBe(uuidColumn)\n expect(result.value).toBe('%acido%')\n })\n})\n"],"names":["is","sql","PgUUID","describe","expect","it","postgresUnaccent","handler","name","toBe","operators","toEqual","fieldTypes","requiredExtensions","column","result","transformOperands","adapter","field","type","originalOperator","path","resolvedOperator","storage","value","Object","queryChunks","uuidColumn","create","prototype"],"mappings":"AAAA,SAASA,EAAE,EAAEC,GAAG,QAAQ,cAAa;AACrC,SAASC,MAAM,QAAQ,sBAAqB;AAC5C,SAASC,QAAQ,EAAEC,MAAM,EAAEC,EAAE,QAAQ,SAAQ;AAE7C,SAASC,gBAAgB,QAAQ,wBAAuB;AAExDH,SAAS,oBAAoB;IAC3BE,GAAG,0DAA0D;QAC3D,MAAME,UAAUD;QAEhBF,OAAOG,QAAQC,IAAI,EAAEC,IAAI,CAAC;QAC1BL,OAAOG,QAAQG,SAAS,EAAEC,OAAO,CAAC;YAAC;YAAY;YAAQ;SAAW;IACpE;IAEAN,GAAG,uDAAuD;QACxD,MAAME,UAAUD;QAEhBF,OAAOG,QAAQK,UAAU,EAAED,OAAO,CAAC;YAAC;YAAQ;SAAW;IACzD;IAEAN,GAAG,2CAA2C;QAC5C,MAAME,UAAUD;QAEhBF,OAAOG,QAAQM,kBAAkB,EAAEF,OAAO,CAAC;YAAC;SAAW;IACzD;IAEAN,GAAG,8EAA8E;QAC/E,MAAME,UAAUD;QAChB,MAAMQ,SAASb,GAAG,CAAC,OAAO,CAAC;QAE3B,MAAMc,SAASR,QAAQS,iBAAiB,CAAC;YACvCC,SAAS,CAAC;YACVH;YACAI,OAAO;gBAAEV,MAAM;gBAASW,MAAM;YAAO;YACrCC,kBAAkB;YAClBC,MAAM;YACNC,kBAAkB;YAClBC,SAAS;YACTC,OAAO;QACT;QAEApB,OAAOJ,GAAGe,OAAOD,MAAM,EAAEW,SAAShB,IAAI,CAAC;QACvCL,OAAO,AAACW,OAAOD,MAAM,CAASY,WAAW,CAAC,EAAE,CAACF,KAAK,CAAC,EAAE,EAAEf,IAAI,CAAC;QAC5DL,OAAO,AAACW,OAAOD,MAAM,CAASY,WAAW,CAAC,EAAE,EAAEjB,IAAI,CAACK;QAEnDV,OAAO,AAACW,OAAOS,KAAK,CAASE,WAAW,CAAC,EAAE,CAACF,KAAK,CAAC,EAAE,EAAEf,IAAI,CAAC;QAC3DL,OAAO,AAACW,OAAOS,KAAK,CAASE,WAAW,CAAC,EAAE,EAAEjB,IAAI,CAAC;IACpD;IAEAJ,GAAG,4EAA4E;QAC7E,MAAME,UAAUD;QAChB,MAAMqB,aAAaF,OAAOG,MAAM,CAAC1B,OAAO2B,SAAS;QAEjD,MAAMd,SAASR,QAAQS,iBAAiB,CAAC;YACvCC,SAAS,CAAC;YACVH,QAAQa;YACRT,OAAO;gBAAEV,MAAM;gBAAMW,MAAM;YAAO;YAClCC,kBAAkB;YAClBC,MAAM;YACNC,kBAAkB;YAClBC,SAAS;YACTC,OAAO;QACT;QAEApB,OAAOW,OAAOD,MAAM,EAAEL,IAAI,CAACkB;QAC3BvB,OAAOW,OAAOS,KAAK,EAAEf,IAAI,CAAC;IAC5B;AACF"}
|
|
@@ -1,348 +0,0 @@
|
|
|
1
|
-
import { sql } from 'drizzle-orm';
|
|
2
|
-
import { describe, expect, it, vi } from 'vitest';
|
|
3
|
-
import { buildOperatorConstraint } from './buildOperatorConstraint.js';
|
|
4
|
-
const textField = {
|
|
5
|
-
name: 'title',
|
|
6
|
-
type: 'text'
|
|
7
|
-
};
|
|
8
|
-
const numberField = {
|
|
9
|
-
name: 'age',
|
|
10
|
-
type: 'number'
|
|
11
|
-
};
|
|
12
|
-
describe('buildOperatorConstraint', ()=>{
|
|
13
|
-
it('calls the default operator unchanged when no handlers are configured', ()=>{
|
|
14
|
-
const sentinel = sql`sentinel`;
|
|
15
|
-
const containsOperator = vi.fn().mockReturnValue(sentinel);
|
|
16
|
-
const adapter = {
|
|
17
|
-
operatorHandlers: [],
|
|
18
|
-
operators: {
|
|
19
|
-
contains: containsOperator
|
|
20
|
-
}
|
|
21
|
-
};
|
|
22
|
-
const column = 'col';
|
|
23
|
-
const result = buildOperatorConstraint({
|
|
24
|
-
adapter,
|
|
25
|
-
column,
|
|
26
|
-
field: textField,
|
|
27
|
-
originalOperator: 'contains',
|
|
28
|
-
path: 'title',
|
|
29
|
-
resolvedOperator: 'contains',
|
|
30
|
-
value: 'acido'
|
|
31
|
-
});
|
|
32
|
-
expect(containsOperator).toHaveBeenCalledWith(column, 'acido');
|
|
33
|
-
expect(result).toBe(sentinel);
|
|
34
|
-
});
|
|
35
|
-
it('applies operand-transform handlers in configuration order before the default operator runs', ()=>{
|
|
36
|
-
const calls = [];
|
|
37
|
-
const containsOperator = vi.fn(()=>sql`result`);
|
|
38
|
-
const handlerA = {
|
|
39
|
-
name: 'handler-a',
|
|
40
|
-
operators: [
|
|
41
|
-
'contains'
|
|
42
|
-
],
|
|
43
|
-
transformOperands: ({ column, value })=>{
|
|
44
|
-
calls.push('a');
|
|
45
|
-
return {
|
|
46
|
-
column: `${column}-a`,
|
|
47
|
-
value: `${value}-a`
|
|
48
|
-
};
|
|
49
|
-
}
|
|
50
|
-
};
|
|
51
|
-
const handlerB = {
|
|
52
|
-
name: 'handler-b',
|
|
53
|
-
operators: [
|
|
54
|
-
'contains'
|
|
55
|
-
],
|
|
56
|
-
transformOperands: ({ column, value })=>{
|
|
57
|
-
calls.push('b');
|
|
58
|
-
return {
|
|
59
|
-
column: `${column}-b`,
|
|
60
|
-
value: `${value}-b`
|
|
61
|
-
};
|
|
62
|
-
}
|
|
63
|
-
};
|
|
64
|
-
const adapter = {
|
|
65
|
-
operatorHandlers: [
|
|
66
|
-
handlerA,
|
|
67
|
-
handlerB
|
|
68
|
-
],
|
|
69
|
-
operators: {
|
|
70
|
-
contains: containsOperator
|
|
71
|
-
}
|
|
72
|
-
};
|
|
73
|
-
buildOperatorConstraint({
|
|
74
|
-
adapter,
|
|
75
|
-
column: 'base-column',
|
|
76
|
-
field: textField,
|
|
77
|
-
originalOperator: 'contains',
|
|
78
|
-
path: 'title',
|
|
79
|
-
resolvedOperator: 'contains',
|
|
80
|
-
value: 'acido'
|
|
81
|
-
});
|
|
82
|
-
expect(calls).toEqual([
|
|
83
|
-
'a',
|
|
84
|
-
'b'
|
|
85
|
-
]);
|
|
86
|
-
expect(containsOperator).toHaveBeenCalledWith('base-column-a-b', 'acido-a-b');
|
|
87
|
-
});
|
|
88
|
-
it('skips a handler whose operators list excludes the resolved operator', ()=>{
|
|
89
|
-
const transformOperands = vi.fn(({ column, value })=>({
|
|
90
|
-
column,
|
|
91
|
-
value
|
|
92
|
-
}));
|
|
93
|
-
const adapter = {
|
|
94
|
-
operatorHandlers: [
|
|
95
|
-
{
|
|
96
|
-
name: 'like-only',
|
|
97
|
-
operators: [
|
|
98
|
-
'like'
|
|
99
|
-
],
|
|
100
|
-
transformOperands
|
|
101
|
-
}
|
|
102
|
-
],
|
|
103
|
-
operators: {
|
|
104
|
-
contains: vi.fn(()=>sql`result`)
|
|
105
|
-
}
|
|
106
|
-
};
|
|
107
|
-
buildOperatorConstraint({
|
|
108
|
-
adapter,
|
|
109
|
-
column: 'col',
|
|
110
|
-
field: textField,
|
|
111
|
-
originalOperator: 'contains',
|
|
112
|
-
path: 'title',
|
|
113
|
-
resolvedOperator: 'contains',
|
|
114
|
-
value: 'acido'
|
|
115
|
-
});
|
|
116
|
-
expect(transformOperands).not.toHaveBeenCalled();
|
|
117
|
-
});
|
|
118
|
-
it("skips a handler whose fieldTypes excludes the field's type even when operators matches", ()=>{
|
|
119
|
-
const transformOperands = vi.fn(({ column, value })=>({
|
|
120
|
-
column,
|
|
121
|
-
value
|
|
122
|
-
}));
|
|
123
|
-
const adapter = {
|
|
124
|
-
operatorHandlers: [
|
|
125
|
-
{
|
|
126
|
-
name: 'text-only',
|
|
127
|
-
operators: [
|
|
128
|
-
'contains'
|
|
129
|
-
],
|
|
130
|
-
fieldTypes: [
|
|
131
|
-
'text'
|
|
132
|
-
],
|
|
133
|
-
transformOperands
|
|
134
|
-
}
|
|
135
|
-
],
|
|
136
|
-
operators: {
|
|
137
|
-
contains: vi.fn(()=>sql`result`)
|
|
138
|
-
}
|
|
139
|
-
};
|
|
140
|
-
buildOperatorConstraint({
|
|
141
|
-
adapter,
|
|
142
|
-
column: 'col',
|
|
143
|
-
field: numberField,
|
|
144
|
-
originalOperator: 'contains',
|
|
145
|
-
path: 'age',
|
|
146
|
-
resolvedOperator: 'contains',
|
|
147
|
-
value: 5
|
|
148
|
-
});
|
|
149
|
-
expect(transformOperands).not.toHaveBeenCalled();
|
|
150
|
-
});
|
|
151
|
-
it('runs a handler with no fieldTypes for every field type', ()=>{
|
|
152
|
-
const transformOperands = vi.fn(({ column, value })=>({
|
|
153
|
-
column,
|
|
154
|
-
value
|
|
155
|
-
}));
|
|
156
|
-
const adapter = {
|
|
157
|
-
operatorHandlers: [
|
|
158
|
-
{
|
|
159
|
-
name: 'universal',
|
|
160
|
-
operators: [
|
|
161
|
-
'contains'
|
|
162
|
-
],
|
|
163
|
-
transformOperands
|
|
164
|
-
}
|
|
165
|
-
],
|
|
166
|
-
operators: {
|
|
167
|
-
contains: vi.fn(()=>sql`result`)
|
|
168
|
-
}
|
|
169
|
-
};
|
|
170
|
-
buildOperatorConstraint({
|
|
171
|
-
adapter,
|
|
172
|
-
column: 'col',
|
|
173
|
-
field: numberField,
|
|
174
|
-
originalOperator: 'contains',
|
|
175
|
-
path: 'age',
|
|
176
|
-
resolvedOperator: 'contains',
|
|
177
|
-
value: 5
|
|
178
|
-
});
|
|
179
|
-
expect(transformOperands).toHaveBeenCalled();
|
|
180
|
-
});
|
|
181
|
-
it('gives a single matching replacement handler the operands after every transform has run, and uses its result instead of the default operator', ()=>{
|
|
182
|
-
const containsOperator = vi.fn();
|
|
183
|
-
const sentinel = sql`replacement`;
|
|
184
|
-
const build = vi.fn().mockReturnValue(sentinel);
|
|
185
|
-
const transformOperands = vi.fn(({ column, value })=>({
|
|
186
|
-
column: `${column}-t`,
|
|
187
|
-
value: `${value}-t`
|
|
188
|
-
}));
|
|
189
|
-
const adapter = {
|
|
190
|
-
operatorHandlers: [
|
|
191
|
-
{
|
|
192
|
-
name: 'transform',
|
|
193
|
-
operators: [
|
|
194
|
-
'contains'
|
|
195
|
-
],
|
|
196
|
-
transformOperands
|
|
197
|
-
},
|
|
198
|
-
{
|
|
199
|
-
name: 'replace',
|
|
200
|
-
operators: [
|
|
201
|
-
'contains'
|
|
202
|
-
],
|
|
203
|
-
build
|
|
204
|
-
}
|
|
205
|
-
],
|
|
206
|
-
operators: {
|
|
207
|
-
contains: containsOperator
|
|
208
|
-
}
|
|
209
|
-
};
|
|
210
|
-
const result = buildOperatorConstraint({
|
|
211
|
-
adapter,
|
|
212
|
-
column: 'col',
|
|
213
|
-
field: textField,
|
|
214
|
-
originalOperator: 'contains',
|
|
215
|
-
path: 'title',
|
|
216
|
-
resolvedOperator: 'contains',
|
|
217
|
-
value: 'acido'
|
|
218
|
-
});
|
|
219
|
-
expect(build).toHaveBeenCalledWith(expect.objectContaining({
|
|
220
|
-
column: 'col-t',
|
|
221
|
-
value: 'acido-t'
|
|
222
|
-
}));
|
|
223
|
-
expect(containsOperator).not.toHaveBeenCalled();
|
|
224
|
-
expect(result).toBe(sentinel);
|
|
225
|
-
});
|
|
226
|
-
it('passes originalOperator, resolvedOperator, field, path, and locale to handlers', ()=>{
|
|
227
|
-
let capturedContext;
|
|
228
|
-
const transformOperands = vi.fn((context)=>{
|
|
229
|
-
capturedContext = context;
|
|
230
|
-
return {
|
|
231
|
-
column: context.column,
|
|
232
|
-
value: context.value
|
|
233
|
-
};
|
|
234
|
-
});
|
|
235
|
-
const adapter = {
|
|
236
|
-
operatorHandlers: [
|
|
237
|
-
{
|
|
238
|
-
name: 'observe',
|
|
239
|
-
operators: [
|
|
240
|
-
'like'
|
|
241
|
-
],
|
|
242
|
-
transformOperands
|
|
243
|
-
}
|
|
244
|
-
],
|
|
245
|
-
operators: {
|
|
246
|
-
like: vi.fn(()=>sql`result`)
|
|
247
|
-
}
|
|
248
|
-
};
|
|
249
|
-
buildOperatorConstraint({
|
|
250
|
-
adapter,
|
|
251
|
-
column: 'col',
|
|
252
|
-
field: textField,
|
|
253
|
-
locale: 'es',
|
|
254
|
-
originalOperator: 'like',
|
|
255
|
-
path: 'title',
|
|
256
|
-
resolvedOperator: 'like',
|
|
257
|
-
value: '%nino%'
|
|
258
|
-
});
|
|
259
|
-
expect(capturedContext).toMatchObject({
|
|
260
|
-
field: textField,
|
|
261
|
-
locale: 'es',
|
|
262
|
-
originalOperator: 'like',
|
|
263
|
-
path: 'title',
|
|
264
|
-
resolvedOperator: 'like'
|
|
265
|
-
});
|
|
266
|
-
});
|
|
267
|
-
it('wraps a handler error with the handler name, path, and resolved operator, retaining the original error as the cause', ()=>{
|
|
268
|
-
const originalError = new Error('boom');
|
|
269
|
-
const transformOperands = vi.fn(()=>{
|
|
270
|
-
throw originalError;
|
|
271
|
-
});
|
|
272
|
-
const adapter = {
|
|
273
|
-
operatorHandlers: [
|
|
274
|
-
{
|
|
275
|
-
name: 'explode',
|
|
276
|
-
operators: [
|
|
277
|
-
'contains'
|
|
278
|
-
],
|
|
279
|
-
transformOperands
|
|
280
|
-
}
|
|
281
|
-
],
|
|
282
|
-
operators: {
|
|
283
|
-
contains: vi.fn()
|
|
284
|
-
}
|
|
285
|
-
};
|
|
286
|
-
let thrown;
|
|
287
|
-
try {
|
|
288
|
-
buildOperatorConstraint({
|
|
289
|
-
adapter,
|
|
290
|
-
column: 'col',
|
|
291
|
-
field: textField,
|
|
292
|
-
originalOperator: 'contains',
|
|
293
|
-
path: 'title',
|
|
294
|
-
resolvedOperator: 'contains',
|
|
295
|
-
value: 'acido'
|
|
296
|
-
});
|
|
297
|
-
} catch (error) {
|
|
298
|
-
thrown = error;
|
|
299
|
-
}
|
|
300
|
-
expect(thrown).toBeInstanceOf(Error);
|
|
301
|
-
const error = thrown;
|
|
302
|
-
expect(error.message).toContain('explode');
|
|
303
|
-
expect(error.message).toContain('title');
|
|
304
|
-
expect(error.message).toContain('contains');
|
|
305
|
-
expect(error.cause).toBe(originalError);
|
|
306
|
-
});
|
|
307
|
-
it('throws a configuration error when a transform handler returns operands missing column or value, before any default operator or replacement runs', ()=>{
|
|
308
|
-
const transformOperands = vi.fn().mockReturnValue({
|
|
309
|
-
column: 'only-column'
|
|
310
|
-
});
|
|
311
|
-
const containsOperator = vi.fn();
|
|
312
|
-
const build = vi.fn();
|
|
313
|
-
const adapter = {
|
|
314
|
-
operatorHandlers: [
|
|
315
|
-
{
|
|
316
|
-
name: 'broken',
|
|
317
|
-
operators: [
|
|
318
|
-
'contains'
|
|
319
|
-
],
|
|
320
|
-
transformOperands
|
|
321
|
-
},
|
|
322
|
-
{
|
|
323
|
-
name: 'replace',
|
|
324
|
-
operators: [
|
|
325
|
-
'contains'
|
|
326
|
-
],
|
|
327
|
-
build
|
|
328
|
-
}
|
|
329
|
-
],
|
|
330
|
-
operators: {
|
|
331
|
-
contains: containsOperator
|
|
332
|
-
}
|
|
333
|
-
};
|
|
334
|
-
expect(()=>buildOperatorConstraint({
|
|
335
|
-
adapter,
|
|
336
|
-
column: 'col',
|
|
337
|
-
field: textField,
|
|
338
|
-
originalOperator: 'contains',
|
|
339
|
-
path: 'title',
|
|
340
|
-
resolvedOperator: 'contains',
|
|
341
|
-
value: 'acido'
|
|
342
|
-
})).toThrow(/broken/);
|
|
343
|
-
expect(containsOperator).not.toHaveBeenCalled();
|
|
344
|
-
expect(build).not.toHaveBeenCalled();
|
|
345
|
-
});
|
|
346
|
-
});
|
|
347
|
-
|
|
348
|
-
//# sourceMappingURL=buildOperatorConstraint.spec.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/queries/buildOperatorConstraint.spec.ts"],"sourcesContent":["import type { Column } from 'drizzle-orm'\nimport type { FlattenedField } from 'payload'\n\nimport { sql } from 'drizzle-orm'\nimport { describe, expect, it, vi } from 'vitest'\n\nimport type { DrizzleAdapter, DrizzleOperandTransformHandler } from '../types.js'\n\nimport { buildOperatorConstraint } from './buildOperatorConstraint.js'\n\nconst textField = { name: 'title', type: 'text' } as unknown as FlattenedField\nconst numberField = { name: 'age', type: 'number' } as unknown as FlattenedField\n\ndescribe('buildOperatorConstraint', () => {\n it('calls the default operator unchanged when no handlers are configured', () => {\n const sentinel = sql`sentinel`\n const containsOperator = vi.fn().mockReturnValue(sentinel)\n const adapter = {\n operatorHandlers: [],\n operators: { contains: containsOperator },\n } as unknown as DrizzleAdapter\n const column = 'col' as unknown as Column\n\n const result = buildOperatorConstraint({\n adapter,\n column,\n field: textField,\n originalOperator: 'contains',\n path: 'title',\n resolvedOperator: 'contains',\n value: 'acido',\n })\n\n expect(containsOperator).toHaveBeenCalledWith(column, 'acido')\n expect(result).toBe(sentinel)\n })\n\n it('applies operand-transform handlers in configuration order before the default operator runs', () => {\n const calls: string[] = []\n const containsOperator = vi.fn(() => sql`result`)\n\n const handlerA: DrizzleOperandTransformHandler = {\n name: 'handler-a',\n operators: ['contains'],\n transformOperands: ({ column, value }) => {\n calls.push('a')\n return { column: `${column}-a` as unknown as Column, value: `${value}-a` }\n },\n }\n const handlerB: DrizzleOperandTransformHandler = {\n name: 'handler-b',\n operators: ['contains'],\n transformOperands: ({ column, value }) => {\n calls.push('b')\n return { column: `${column}-b` as unknown as Column, value: `${value}-b` }\n },\n }\n\n const adapter = {\n operatorHandlers: [handlerA, handlerB],\n operators: { contains: containsOperator },\n } as unknown as DrizzleAdapter\n\n buildOperatorConstraint({\n adapter,\n column: 'base-column' as unknown as Column,\n field: textField,\n originalOperator: 'contains',\n path: 'title',\n resolvedOperator: 'contains',\n value: 'acido',\n })\n\n expect(calls).toEqual(['a', 'b'])\n expect(containsOperator).toHaveBeenCalledWith('base-column-a-b', 'acido-a-b')\n })\n\n it('skips a handler whose operators list excludes the resolved operator', () => {\n const transformOperands = vi.fn(({ column, value }) => ({ column, value }))\n const adapter = {\n operatorHandlers: [{ name: 'like-only', operators: ['like'], transformOperands }],\n operators: { contains: vi.fn(() => sql`result`) },\n } as unknown as DrizzleAdapter\n\n buildOperatorConstraint({\n adapter,\n column: 'col' as unknown as Column,\n field: textField,\n originalOperator: 'contains',\n path: 'title',\n resolvedOperator: 'contains',\n value: 'acido',\n })\n\n expect(transformOperands).not.toHaveBeenCalled()\n })\n\n it(\"skips a handler whose fieldTypes excludes the field's type even when operators matches\", () => {\n const transformOperands = vi.fn(({ column, value }) => ({ column, value }))\n const adapter = {\n operatorHandlers: [\n { name: 'text-only', operators: ['contains'], fieldTypes: ['text'], transformOperands },\n ],\n operators: { contains: vi.fn(() => sql`result`) },\n } as unknown as DrizzleAdapter\n\n buildOperatorConstraint({\n adapter,\n column: 'col' as unknown as Column,\n field: numberField,\n originalOperator: 'contains',\n path: 'age',\n resolvedOperator: 'contains',\n value: 5,\n })\n\n expect(transformOperands).not.toHaveBeenCalled()\n })\n\n it('runs a handler with no fieldTypes for every field type', () => {\n const transformOperands = vi.fn(({ column, value }) => ({ column, value }))\n const adapter = {\n operatorHandlers: [{ name: 'universal', operators: ['contains'], transformOperands }],\n operators: { contains: vi.fn(() => sql`result`) },\n } as unknown as DrizzleAdapter\n\n buildOperatorConstraint({\n adapter,\n column: 'col' as unknown as Column,\n field: numberField,\n originalOperator: 'contains',\n path: 'age',\n resolvedOperator: 'contains',\n value: 5,\n })\n\n expect(transformOperands).toHaveBeenCalled()\n })\n\n it('gives a single matching replacement handler the operands after every transform has run, and uses its result instead of the default operator', () => {\n const containsOperator = vi.fn()\n const sentinel = sql`replacement`\n const build = vi.fn().mockReturnValue(sentinel)\n const transformOperands = vi.fn(({ column, value }) => ({\n column: `${column}-t` as unknown as Column,\n value: `${value}-t`,\n }))\n\n const adapter = {\n operatorHandlers: [\n { name: 'transform', operators: ['contains'], transformOperands },\n { name: 'replace', operators: ['contains'], build },\n ],\n operators: { contains: containsOperator },\n } as unknown as DrizzleAdapter\n\n const result = buildOperatorConstraint({\n adapter,\n column: 'col' as unknown as Column,\n field: textField,\n originalOperator: 'contains',\n path: 'title',\n resolvedOperator: 'contains',\n value: 'acido',\n })\n\n expect(build).toHaveBeenCalledWith(\n expect.objectContaining({ column: 'col-t', value: 'acido-t' }),\n )\n expect(containsOperator).not.toHaveBeenCalled()\n expect(result).toBe(sentinel)\n })\n\n it('passes originalOperator, resolvedOperator, field, path, and locale to handlers', () => {\n let capturedContext: any\n const transformOperands = vi.fn((context) => {\n capturedContext = context\n return { column: context.column, value: context.value }\n })\n\n const adapter = {\n operatorHandlers: [{ name: 'observe', operators: ['like'], transformOperands }],\n operators: { like: vi.fn(() => sql`result`) },\n } as unknown as DrizzleAdapter\n\n buildOperatorConstraint({\n adapter,\n column: 'col' as unknown as Column,\n field: textField,\n locale: 'es',\n originalOperator: 'like',\n path: 'title',\n resolvedOperator: 'like',\n value: '%nino%',\n })\n\n expect(capturedContext).toMatchObject({\n field: textField,\n locale: 'es',\n originalOperator: 'like',\n path: 'title',\n resolvedOperator: 'like',\n })\n })\n\n it('wraps a handler error with the handler name, path, and resolved operator, retaining the original error as the cause', () => {\n const originalError = new Error('boom')\n const transformOperands = vi.fn(() => {\n throw originalError\n })\n\n const adapter = {\n operatorHandlers: [{ name: 'explode', operators: ['contains'], transformOperands }],\n operators: { contains: vi.fn() },\n } as unknown as DrizzleAdapter\n\n let thrown: unknown\n try {\n buildOperatorConstraint({\n adapter,\n column: 'col' as unknown as Column,\n field: textField,\n originalOperator: 'contains',\n path: 'title',\n resolvedOperator: 'contains',\n value: 'acido',\n })\n } catch (error) {\n thrown = error\n }\n\n expect(thrown).toBeInstanceOf(Error)\n const error = thrown as Error\n expect(error.message).toContain('explode')\n expect(error.message).toContain('title')\n expect(error.message).toContain('contains')\n expect(error.cause).toBe(originalError)\n })\n\n it('throws a configuration error when a transform handler returns operands missing column or value, before any default operator or replacement runs', () => {\n const transformOperands = vi.fn().mockReturnValue({ column: 'only-column' })\n const containsOperator = vi.fn()\n const build = vi.fn()\n\n const adapter = {\n operatorHandlers: [\n { name: 'broken', operators: ['contains'], transformOperands },\n { name: 'replace', operators: ['contains'], build },\n ],\n operators: { contains: containsOperator },\n } as unknown as DrizzleAdapter\n\n expect(() =>\n buildOperatorConstraint({\n adapter,\n column: 'col' as unknown as Column,\n field: textField,\n originalOperator: 'contains',\n path: 'title',\n resolvedOperator: 'contains',\n value: 'acido',\n }),\n ).toThrow(/broken/)\n\n expect(containsOperator).not.toHaveBeenCalled()\n expect(build).not.toHaveBeenCalled()\n })\n})\n"],"names":["sql","describe","expect","it","vi","buildOperatorConstraint","textField","name","type","numberField","sentinel","containsOperator","fn","mockReturnValue","adapter","operatorHandlers","operators","contains","column","result","field","originalOperator","path","resolvedOperator","value","toHaveBeenCalledWith","toBe","calls","handlerA","transformOperands","push","handlerB","toEqual","not","toHaveBeenCalled","fieldTypes","build","objectContaining","capturedContext","context","like","locale","toMatchObject","originalError","Error","thrown","error","toBeInstanceOf","message","toContain","cause","toThrow"],"mappings":"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"}
|