@wix/patterns-cms 1.1.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 (163) hide show
  1. package/dist/cjs/adapter/__tests__/cmsFieldActions.spec.js +436 -0
  2. package/dist/cjs/adapter/__tests__/cmsFieldActions.spec.js.map +1 -0
  3. package/dist/cjs/adapter/__tests__/cmsPermissions.spec.js +175 -0
  4. package/dist/cjs/adapter/__tests__/cmsPermissions.spec.js.map +1 -0
  5. package/dist/cjs/adapter/__tests__/createCmsBackend.spec.js +440 -0
  6. package/dist/cjs/adapter/__tests__/createCmsBackend.spec.js.map +1 -0
  7. package/dist/cjs/adapter/__tests__/filterUtils.spec.js +426 -0
  8. package/dist/cjs/adapter/__tests__/filterUtils.spec.js.map +1 -0
  9. package/dist/cjs/adapter/__tests__/getFieldKey.spec.js +24 -0
  10. package/dist/cjs/adapter/__tests__/getFieldKey.spec.js.map +1 -0
  11. package/dist/cjs/adapter/__tests__/loadCmsSchema.spec.js +166 -0
  12. package/dist/cjs/adapter/__tests__/loadCmsSchema.spec.js.map +1 -0
  13. package/dist/cjs/adapter/__tests__/searchUtils.spec.js +116 -0
  14. package/dist/cjs/adapter/__tests__/searchUtils.spec.js.map +1 -0
  15. package/dist/cjs/adapter/__tests__/sortUtils.spec.js +118 -0
  16. package/dist/cjs/adapter/__tests__/sortUtils.spec.js.map +1 -0
  17. package/dist/cjs/adapter/__tests__/transformCmsSchema.spec.js +210 -0
  18. package/dist/cjs/adapter/__tests__/transformCmsSchema.spec.js.map +1 -0
  19. package/dist/cjs/adapter/__tests__/wixDataQueryRecorder.js +54 -0
  20. package/dist/cjs/adapter/__tests__/wixDataQueryRecorder.js.map +1 -0
  21. package/dist/cjs/adapter/cmsBackup.js +52 -0
  22. package/dist/cjs/adapter/cmsBackup.js.map +1 -0
  23. package/dist/cjs/adapter/cmsFieldTypeMap.js +43 -0
  24. package/dist/cjs/adapter/cmsFieldTypeMap.js.map +1 -0
  25. package/dist/cjs/adapter/cmsPermissions.js +94 -0
  26. package/dist/cjs/adapter/cmsPermissions.js.map +1 -0
  27. package/dist/cjs/adapter/constants.js +20 -0
  28. package/dist/cjs/adapter/constants.js.map +1 -0
  29. package/dist/cjs/adapter/createCmsBackend.js +131 -0
  30. package/dist/cjs/adapter/createCmsBackend.js.map +1 -0
  31. package/dist/cjs/adapter/createCmsFieldActions.js +182 -0
  32. package/dist/cjs/adapter/createCmsFieldActions.js.map +1 -0
  33. package/dist/cjs/adapter/fetchExternalDbConnections.js +24 -0
  34. package/dist/cjs/adapter/fetchExternalDbConnections.js.map +1 -0
  35. package/dist/cjs/adapter/fetchUserPermissions.js +24 -0
  36. package/dist/cjs/adapter/fetchUserPermissions.js.map +1 -0
  37. package/dist/cjs/adapter/filterUtils.js +128 -0
  38. package/dist/cjs/adapter/filterUtils.js.map +1 -0
  39. package/dist/cjs/adapter/getFieldKey.js +19 -0
  40. package/dist/cjs/adapter/getFieldKey.js.map +1 -0
  41. package/dist/cjs/adapter/index.js +36 -0
  42. package/dist/cjs/adapter/index.js.map +1 -0
  43. package/dist/cjs/adapter/loadCmsSchema.js +51 -0
  44. package/dist/cjs/adapter/loadCmsSchema.js.map +1 -0
  45. package/dist/cjs/adapter/pollUntilReady.js +30 -0
  46. package/dist/cjs/adapter/pollUntilReady.js.map +1 -0
  47. package/dist/cjs/adapter/searchUtils.js +32 -0
  48. package/dist/cjs/adapter/searchUtils.js.map +1 -0
  49. package/dist/cjs/adapter/sortUtils.js +34 -0
  50. package/dist/cjs/adapter/sortUtils.js.map +1 -0
  51. package/dist/cjs/adapter/transformCmsSchema.js +75 -0
  52. package/dist/cjs/adapter/transformCmsSchema.js.map +1 -0
  53. package/dist/cjs/index.js +10 -0
  54. package/dist/cjs/index.js.map +1 -0
  55. package/dist/esm/adapter/__tests__/cmsFieldActions.spec.js +335 -0
  56. package/dist/esm/adapter/__tests__/cmsFieldActions.spec.js.map +1 -0
  57. package/dist/esm/adapter/__tests__/cmsPermissions.spec.js +173 -0
  58. package/dist/esm/adapter/__tests__/cmsPermissions.spec.js.map +1 -0
  59. package/dist/esm/adapter/__tests__/createCmsBackend.spec.js +307 -0
  60. package/dist/esm/adapter/__tests__/createCmsBackend.spec.js.map +1 -0
  61. package/dist/esm/adapter/__tests__/filterUtils.spec.js +298 -0
  62. package/dist/esm/adapter/__tests__/filterUtils.spec.js.map +1 -0
  63. package/dist/esm/adapter/__tests__/getFieldKey.spec.js +22 -0
  64. package/dist/esm/adapter/__tests__/getFieldKey.spec.js.map +1 -0
  65. package/dist/esm/adapter/__tests__/loadCmsSchema.spec.js +147 -0
  66. package/dist/esm/adapter/__tests__/loadCmsSchema.spec.js.map +1 -0
  67. package/dist/esm/adapter/__tests__/searchUtils.spec.js +109 -0
  68. package/dist/esm/adapter/__tests__/searchUtils.spec.js.map +1 -0
  69. package/dist/esm/adapter/__tests__/sortUtils.spec.js +85 -0
  70. package/dist/esm/adapter/__tests__/sortUtils.spec.js.map +1 -0
  71. package/dist/esm/adapter/__tests__/transformCmsSchema.spec.js +201 -0
  72. package/dist/esm/adapter/__tests__/transformCmsSchema.spec.js.map +1 -0
  73. package/dist/esm/adapter/__tests__/wixDataQueryRecorder.js +42 -0
  74. package/dist/esm/adapter/__tests__/wixDataQueryRecorder.js.map +1 -0
  75. package/dist/esm/adapter/cmsBackup.js +34 -0
  76. package/dist/esm/adapter/cmsBackup.js.map +1 -0
  77. package/dist/esm/adapter/cmsFieldTypeMap.js +37 -0
  78. package/dist/esm/adapter/cmsFieldTypeMap.js.map +1 -0
  79. package/dist/esm/adapter/cmsPermissions.js +91 -0
  80. package/dist/esm/adapter/cmsPermissions.js.map +1 -0
  81. package/dist/esm/adapter/constants.js +25 -0
  82. package/dist/esm/adapter/constants.js.map +1 -0
  83. package/dist/esm/adapter/createCmsBackend.js +113 -0
  84. package/dist/esm/adapter/createCmsBackend.js.map +1 -0
  85. package/dist/esm/adapter/createCmsFieldActions.js +159 -0
  86. package/dist/esm/adapter/createCmsFieldActions.js.map +1 -0
  87. package/dist/esm/adapter/fetchExternalDbConnections.js +17 -0
  88. package/dist/esm/adapter/fetchExternalDbConnections.js.map +1 -0
  89. package/dist/esm/adapter/fetchUserPermissions.js +15 -0
  90. package/dist/esm/adapter/fetchUserPermissions.js.map +1 -0
  91. package/dist/esm/adapter/filterUtils.js +126 -0
  92. package/dist/esm/adapter/filterUtils.js.map +1 -0
  93. package/dist/esm/adapter/getFieldKey.js +13 -0
  94. package/dist/esm/adapter/getFieldKey.js.map +1 -0
  95. package/dist/esm/adapter/index.js +15 -0
  96. package/dist/esm/adapter/index.js.map +1 -0
  97. package/dist/esm/adapter/loadCmsSchema.js +48 -0
  98. package/dist/esm/adapter/loadCmsSchema.js.map +1 -0
  99. package/dist/esm/adapter/pollUntilReady.js +24 -0
  100. package/dist/esm/adapter/pollUntilReady.js.map +1 -0
  101. package/dist/esm/adapter/searchUtils.js +24 -0
  102. package/dist/esm/adapter/searchUtils.js.map +1 -0
  103. package/dist/esm/adapter/sortUtils.js +21 -0
  104. package/dist/esm/adapter/sortUtils.js.map +1 -0
  105. package/dist/esm/adapter/transformCmsSchema.js +70 -0
  106. package/dist/esm/adapter/transformCmsSchema.js.map +1 -0
  107. package/dist/esm/index.js +2 -0
  108. package/dist/esm/index.js.map +1 -0
  109. package/dist/types/adapter/__tests__/cmsFieldActions.spec.d.ts +2 -0
  110. package/dist/types/adapter/__tests__/cmsFieldActions.spec.d.ts.map +1 -0
  111. package/dist/types/adapter/__tests__/cmsPermissions.spec.d.ts +2 -0
  112. package/dist/types/adapter/__tests__/cmsPermissions.spec.d.ts.map +1 -0
  113. package/dist/types/adapter/__tests__/createCmsBackend.spec.d.ts +2 -0
  114. package/dist/types/adapter/__tests__/createCmsBackend.spec.d.ts.map +1 -0
  115. package/dist/types/adapter/__tests__/filterUtils.spec.d.ts +2 -0
  116. package/dist/types/adapter/__tests__/filterUtils.spec.d.ts.map +1 -0
  117. package/dist/types/adapter/__tests__/getFieldKey.spec.d.ts +2 -0
  118. package/dist/types/adapter/__tests__/getFieldKey.spec.d.ts.map +1 -0
  119. package/dist/types/adapter/__tests__/loadCmsSchema.spec.d.ts +2 -0
  120. package/dist/types/adapter/__tests__/loadCmsSchema.spec.d.ts.map +1 -0
  121. package/dist/types/adapter/__tests__/searchUtils.spec.d.ts +2 -0
  122. package/dist/types/adapter/__tests__/searchUtils.spec.d.ts.map +1 -0
  123. package/dist/types/adapter/__tests__/sortUtils.spec.d.ts +2 -0
  124. package/dist/types/adapter/__tests__/sortUtils.spec.d.ts.map +1 -0
  125. package/dist/types/adapter/__tests__/transformCmsSchema.spec.d.ts +2 -0
  126. package/dist/types/adapter/__tests__/transformCmsSchema.spec.d.ts.map +1 -0
  127. package/dist/types/adapter/__tests__/wixDataQueryRecorder.d.ts +40 -0
  128. package/dist/types/adapter/__tests__/wixDataQueryRecorder.d.ts.map +1 -0
  129. package/dist/types/adapter/cmsBackup.d.ts +7 -0
  130. package/dist/types/adapter/cmsBackup.d.ts.map +1 -0
  131. package/dist/types/adapter/cmsFieldTypeMap.d.ts +8 -0
  132. package/dist/types/adapter/cmsFieldTypeMap.d.ts.map +1 -0
  133. package/dist/types/adapter/cmsPermissions.d.ts +21 -0
  134. package/dist/types/adapter/cmsPermissions.d.ts.map +1 -0
  135. package/dist/types/adapter/constants.d.ts +14 -0
  136. package/dist/types/adapter/constants.d.ts.map +1 -0
  137. package/dist/types/adapter/createCmsBackend.d.ts +9 -0
  138. package/dist/types/adapter/createCmsBackend.d.ts.map +1 -0
  139. package/dist/types/adapter/createCmsFieldActions.d.ts +8 -0
  140. package/dist/types/adapter/createCmsFieldActions.d.ts.map +1 -0
  141. package/dist/types/adapter/fetchExternalDbConnections.d.ts +11 -0
  142. package/dist/types/adapter/fetchExternalDbConnections.d.ts.map +1 -0
  143. package/dist/types/adapter/fetchUserPermissions.d.ts +7 -0
  144. package/dist/types/adapter/fetchUserPermissions.d.ts.map +1 -0
  145. package/dist/types/adapter/filterUtils.d.ts +14 -0
  146. package/dist/types/adapter/filterUtils.d.ts.map +1 -0
  147. package/dist/types/adapter/getFieldKey.d.ts +3 -0
  148. package/dist/types/adapter/getFieldKey.d.ts.map +1 -0
  149. package/dist/types/adapter/index.d.ts +15 -0
  150. package/dist/types/adapter/index.d.ts.map +1 -0
  151. package/dist/types/adapter/loadCmsSchema.d.ts +29 -0
  152. package/dist/types/adapter/loadCmsSchema.d.ts.map +1 -0
  153. package/dist/types/adapter/pollUntilReady.d.ts +11 -0
  154. package/dist/types/adapter/pollUntilReady.d.ts.map +1 -0
  155. package/dist/types/adapter/searchUtils.d.ts +12 -0
  156. package/dist/types/adapter/searchUtils.d.ts.map +1 -0
  157. package/dist/types/adapter/sortUtils.d.ts +11 -0
  158. package/dist/types/adapter/sortUtils.d.ts.map +1 -0
  159. package/dist/types/adapter/transformCmsSchema.d.ts +12 -0
  160. package/dist/types/adapter/transformCmsSchema.d.ts.map +1 -0
  161. package/dist/types/index.d.ts +2 -0
  162. package/dist/types/index.d.ts.map +1 -0
  163. package/package.json +123 -0
@@ -0,0 +1 @@
1
+ {"version":3,"names":["_data","require","_createCmsBackend","jest","mock","errorHandler","withErrorHandler","fn","mockFindResult","items","totalCount","queryChain","forEach","m","find","Promise","resolve","filterChain","__chains","query","filter","insert","update","remove","bulkRemove","bulkInsert","replaceReferences","backups","queryMock","COLLECTION_ID","fieldsWithRefs","title","id","type","displayName","capabilities","supportedQueryOperators","sortable","author","referenceMetadata","referencedCollectionId","tags","findWithOptions","options","describe","beforeEach","clearAllMocks","it","_id","backend","createCmsBackend","entity","get","expect","toHaveBeenCalledWith","eq","toEqual","include","rejects","toThrow","mockResolvedValue","result","create","undefined","toBe","delete","bulkDelete","offset","limit","skip","returnTotalCount","total","hasNext","searchableFieldIds","not","toHaveBeenCalled","filterableFields","price","done","filters","from","to","filterFieldMapping","fieldId","ge","le","sort","fieldName","order","ascending","descending","search","contains","and","inserted","updated","errors","originalIndex","message","code","a","succeeded","failed","rowIndex"],"sources":["../../../../src/adapter/__tests__/createCmsBackend.spec.ts"],"sourcesContent":["import { items } from '@wix/data';\nimport type { Schema } from '@wix/bex-core';\nimport { createCmsBackend } from '../createCmsBackend';\n\n// `bulkInsert`/`backup` wrap calls in errorHandler.withErrorHandler, which needs an\n// initialized Wix SDK context. In a pure-function unit test there is none, so we\n// stub the wrapper to just invoke its callback (the mapping logic is what we assert).\njest.mock('@wix/essentials', () => ({\n errorHandler: {\n withErrorHandler: (fn: () => unknown) => fn(),\n },\n}));\n\n// A chainable query stub whose terminal `.find()` resolves to a configurable\n// result. `mockFindResult` is reassigned per-test before the backend call.\n// `mock`-prefixed names are the only out-of-scope refs jest.mock() factories allow.\nlet mockFindResult: { items: unknown[]; totalCount?: number } = {\n items: [],\n totalCount: 0,\n};\n\njest.mock('@wix/data', () => {\n const queryChain: Record<string, jest.Mock> = {};\n [\n 'eq',\n 'include',\n 'skip',\n 'limit',\n 'and',\n 'ge',\n 'le',\n 'ascending',\n 'descending',\n ].forEach((m) => {\n queryChain[m] = jest.fn(() => queryChain);\n });\n queryChain.find = jest.fn(() => Promise.resolve(mockFindResult));\n\n const filterChain: Record<string, jest.Mock> = {};\n ['eq', 'contains', 'or', 'and', 'not'].forEach((m) => {\n filterChain[m] = jest.fn(() => filterChain);\n });\n\n return {\n __chains: { queryChain, filterChain },\n items: {\n query: jest.fn(() => queryChain),\n filter: jest.fn(() => filterChain),\n insert: jest.fn(),\n update: jest.fn(),\n remove: jest.fn(),\n bulkRemove: jest.fn(),\n bulkInsert: jest.fn(),\n replaceReferences: jest.fn(),\n },\n backups: {},\n };\n});\n\n// eslint-disable-next-line @typescript-eslint/no-var-requires\nconst { queryChain, filterChain } = (\n require('@wix/data') as {\n __chains: {\n queryChain: Record<string, jest.Mock>;\n filterChain: Record<string, jest.Mock>;\n };\n }\n).__chains;\n\nconst queryMock = items.query as unknown as jest.Mock;\nconst insert = items.insert as unknown as jest.Mock;\nconst update = items.update as unknown as jest.Mock;\nconst remove = items.remove as unknown as jest.Mock;\nconst bulkRemove = items.bulkRemove as unknown as jest.Mock;\nconst bulkInsert = items.bulkInsert as unknown as jest.Mock;\nconst replaceReferences = items.replaceReferences as unknown as jest.Mock;\n\nconst COLLECTION_ID = 'collection-1';\n\nconst fieldsWithRefs: Schema['fields'] = {\n title: {\n id: 'title',\n type: 'SHORT_TEXT',\n displayName: 'Title',\n capabilities: { supportedQueryOperators: [], sortable: true },\n },\n author: {\n id: 'author',\n type: 'REFERENCE',\n displayName: 'Author',\n referenceMetadata: { referencedCollectionId: 'authors' },\n capabilities: { supportedQueryOperators: [], sortable: false },\n },\n tags: {\n id: 'tags',\n type: 'MULTI_REFERENCE',\n displayName: 'Tags',\n referenceMetadata: { referencedCollectionId: 'tags-collection' },\n capabilities: { supportedQueryOperators: [], sortable: false },\n },\n};\n\ntype FindOptions = {\n searchableFieldIds?: string[];\n filterFieldMapping?: Record<string, { fieldId: string }>;\n};\n\n/** Calls `backend.find` with the per-call options arg (absent from the erased interface). */\nconst findWithOptions = (\n find: unknown,\n query: Parameters<ReturnType<typeof createCmsBackend>['find']>[0],\n options: FindOptions,\n) =>\n (find as (q: typeof query, o: FindOptions) => Promise<unknown>)(\n query,\n options,\n );\n\ndescribe('createCmsBackend', () => {\n beforeEach(() => {\n jest.clearAllMocks();\n mockFindResult = { items: [], totalCount: 0 };\n });\n\n describe('get', () => {\n it('queries by _id and returns the single matching entity', async () => {\n mockFindResult = { items: [{ _id: 'e1', title: 'Hello' }] };\n const backend = createCmsBackend(COLLECTION_ID, {\n title: fieldsWithRefs.title,\n });\n\n const entity = await backend.get('e1');\n\n expect(queryMock).toHaveBeenCalledWith(COLLECTION_ID);\n expect(queryChain.eq).toHaveBeenCalledWith('_id', 'e1');\n expect(entity).toEqual({ _id: 'e1', title: 'Hello' });\n });\n\n it('includes reference fields when the schema has them', async () => {\n mockFindResult = { items: [{ _id: 'e1' }] };\n const backend = createCmsBackend(COLLECTION_ID, fieldsWithRefs);\n\n await backend.get('e1');\n\n expect(queryChain.include).toHaveBeenCalledWith('author', 'tags');\n });\n\n it('throws when no entity is found', async () => {\n mockFindResult = { items: [] };\n const backend = createCmsBackend(COLLECTION_ID, {\n title: fieldsWithRefs.title,\n });\n\n await expect(backend.get('missing')).rejects.toThrow(\n 'Entity not found: missing',\n );\n });\n });\n\n describe('create', () => {\n it('inserts the entity and returns it with the created _id', async () => {\n insert.mockResolvedValue({ _id: 'new-1' });\n const backend = createCmsBackend(COLLECTION_ID, {\n title: fieldsWithRefs.title,\n });\n\n const result = await backend.create({ title: 'Hi' } as never);\n\n expect(insert).toHaveBeenCalledWith(COLLECTION_ID, { title: 'Hi' });\n expect(result).toEqual({ title: 'Hi', _id: 'new-1' });\n });\n\n it('syncs multi-reference fields via replaceReferences', async () => {\n insert.mockResolvedValue({ _id: 'new-1' });\n const backend = createCmsBackend(COLLECTION_ID, fieldsWithRefs);\n\n await backend.create({\n title: 'Hi',\n tags: [{ _id: 't1' }, { _id: 't2' }],\n } as never);\n\n expect(replaceReferences).toHaveBeenCalledWith(\n COLLECTION_ID,\n 'tags',\n 'new-1',\n ['t1', 't2'],\n );\n });\n });\n\n describe('update', () => {\n it('updates the entity and returns it', async () => {\n update.mockResolvedValue(undefined);\n const backend = createCmsBackend(COLLECTION_ID, {\n title: fieldsWithRefs.title,\n });\n\n const entity = { _id: 'e1', title: 'Edited' };\n const result = await backend.update(entity as never);\n\n expect(update).toHaveBeenCalledWith(COLLECTION_ID, entity);\n expect(result).toBe(entity);\n });\n });\n\n describe('delete / bulkDelete', () => {\n it('removes a single entity by id', async () => {\n remove.mockResolvedValue(undefined);\n const backend = createCmsBackend(COLLECTION_ID, {});\n\n await backend.delete('e1');\n\n expect(remove).toHaveBeenCalledWith(COLLECTION_ID, 'e1');\n });\n\n it('bulk-removes entities by ids', async () => {\n bulkRemove.mockResolvedValue(undefined);\n const backend = createCmsBackend(COLLECTION_ID, {});\n\n await backend.bulkDelete(['e1', 'e2']);\n\n expect(bulkRemove).toHaveBeenCalledWith(COLLECTION_ID, ['e1', 'e2']);\n });\n });\n\n describe('find', () => {\n it('applies skip/limit and computes total and hasNext', async () => {\n mockFindResult = {\n items: [{ _id: 'a' }, { _id: 'b' }],\n totalCount: 5,\n };\n const backend = createCmsBackend(COLLECTION_ID, {\n title: fieldsWithRefs.title,\n });\n\n const result = await backend.find({\n offset: 0,\n limit: 2,\n } as never);\n\n expect(queryChain.skip).toHaveBeenCalledWith(0);\n expect(queryChain.limit).toHaveBeenCalledWith(2);\n expect(queryChain.find).toHaveBeenCalledWith({ returnTotalCount: true });\n expect(result.items).toEqual([{ _id: 'a' }, { _id: 'b' }]);\n expect(result.total).toBe(5);\n // 0 + 2 < 5 → there is a next page.\n expect(result.hasNext).toBe(true);\n });\n\n it('reports hasNext false on the last page', async () => {\n mockFindResult = {\n items: [{ _id: 'e' }],\n totalCount: 3,\n };\n const backend = createCmsBackend(COLLECTION_ID, {\n title: fieldsWithRefs.title,\n });\n\n const result = await backend.find({ offset: 2, limit: 2 } as never);\n\n // 2 + 1 === 3 → no next page.\n expect(result.hasNext).toBe(false);\n });\n\n it('includes only reference fields that are also searchable', async () => {\n mockFindResult = { items: [], totalCount: 0 };\n const backend = createCmsBackend(COLLECTION_ID, fieldsWithRefs);\n\n // The per-call `options` arg is part of the concrete `createCmsBackend.find`\n // but not the erased `CollectionBackend.find` contract — cast to reach it.\n await findWithOptions(backend.find, { offset: 0, limit: 10 } as never, {\n searchableFieldIds: ['title', 'author'],\n });\n\n // 'author' is a reference and searchable → included; 'tags' is not searchable.\n expect(queryChain.include).toHaveBeenCalledWith('author');\n });\n\n it('does not call include when no reference field is searchable', async () => {\n mockFindResult = { items: [], totalCount: 0 };\n const backend = createCmsBackend(COLLECTION_ID, fieldsWithRefs);\n\n await findWithOptions(backend.find, { offset: 0, limit: 10 } as never, {\n searchableFieldIds: ['title'],\n });\n\n expect(queryChain.include).not.toHaveBeenCalled();\n });\n\n it('includes no reference fields when called with no options (inert default)', async () => {\n mockFindResult = { items: [], totalCount: 0 };\n const backend = createCmsBackend(COLLECTION_ID, fieldsWithRefs);\n\n // No options → default searchableFieldIds = [] → no refs included, no search.\n await backend.find({ offset: 0, limit: 10 } as never);\n\n expect(queryChain.include).not.toHaveBeenCalled();\n });\n\n // The cases below mirror auto-patterns' end-to-end coverage: the fetch path\n // must actually apply the query's filters/sort/search, not just skip/limit.\n const filterableFields: Schema['fields'] = {\n title: fieldsWithRefs.title,\n price: {\n id: 'price',\n type: 'NUMBER',\n displayName: 'Price',\n capabilities: {\n supportedQueryOperators: ['GTE', 'LTE'],\n sortable: true,\n },\n },\n done: {\n id: 'done',\n type: 'BOOLEAN',\n displayName: 'Done',\n capabilities: { supportedQueryOperators: [], sortable: false },\n },\n };\n\n it('applies a number range filter from the query', async () => {\n const backend = createCmsBackend(COLLECTION_ID, filterableFields);\n\n await findWithOptions(\n backend.find,\n {\n offset: 0,\n limit: 10,\n filters: { price: { from: 10, to: 100 } },\n } as never,\n { filterFieldMapping: { price: { fieldId: 'price' } } },\n );\n\n expect(queryChain.ge).toHaveBeenCalledWith('price', 10);\n expect(queryChain.le).toHaveBeenCalledWith('price', 100);\n });\n\n it('applies a checked boolean filter from the query', async () => {\n const backend = createCmsBackend(COLLECTION_ID, filterableFields);\n\n await findWithOptions(\n backend.find,\n {\n offset: 0,\n limit: 10,\n filters: { done: [{ id: 'checked' }] },\n } as never,\n { filterFieldMapping: { done: { fieldId: 'done' } } },\n );\n\n expect(queryChain.eq).toHaveBeenCalledWith('done', true);\n });\n\n it('applies ascending sort from the query', async () => {\n const backend = createCmsBackend(COLLECTION_ID, filterableFields);\n\n await backend.find({\n offset: 0,\n limit: 10,\n sort: [{ fieldName: 'title', order: 'asc' }],\n } as never);\n\n expect(queryChain.ascending).toHaveBeenCalledWith('title');\n });\n\n it('applies descending sort from the query', async () => {\n const backend = createCmsBackend(COLLECTION_ID, filterableFields);\n\n await backend.find({\n offset: 0,\n limit: 10,\n sort: [{ fieldName: 'title', order: 'desc' }],\n } as never);\n\n expect(queryChain.descending).toHaveBeenCalledWith('title');\n });\n\n it('applies the search term as a contains filter on searchable text fields', async () => {\n const backend = createCmsBackend(COLLECTION_ID, filterableFields);\n\n await findWithOptions(\n backend.find,\n { offset: 0, limit: 10, search: 'hello' } as never,\n { searchableFieldIds: ['title'] },\n );\n\n expect(filterChain.contains).toHaveBeenCalledWith('title', 'hello');\n expect(queryChain.and).toHaveBeenCalledWith(filterChain);\n });\n });\n\n describe('bulkInsert', () => {\n it('maps inserted/updated to succeeded, errors to failed, and surfaces error rows', async () => {\n bulkInsert.mockResolvedValue({\n inserted: 2,\n updated: 1,\n errors: [{ originalIndex: 4, message: 'bad row', code: 'INVALID' }],\n });\n const backend = createCmsBackend(COLLECTION_ID, {});\n\n const result = await backend.bulkInsert!([{ a: 1 }, { a: 2 }] as never);\n\n expect(bulkInsert).toHaveBeenCalledWith(COLLECTION_ID, [\n { a: 1 },\n { a: 2 },\n ]);\n expect(result.succeeded).toBe(3);\n expect(result.failed).toBe(1);\n expect(result.errors).toEqual([\n { rowIndex: 4, message: 'bad row', code: 'INVALID' },\n ]);\n });\n });\n});\n"],"mappings":"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","ignoreList":[]}
@@ -0,0 +1,426 @@
1
+ "use strict";
2
+
3
+ var _data = require("@wix/data");
4
+ var _bexCore = require("@wix/bex-core");
5
+ var _filterUtils = require("../filterUtils");
6
+ var _constants = require("../constants");
7
+ var _wixDataQueryRecorder = require("./wixDataQueryRecorder");
8
+ // Replace the `@wix/data` `items` builders with chainable recorders so we can
9
+ // assert which WQL operator methods the util produced.
10
+ jest.mock('@wix/data', () => {
11
+ const recorder = require('./wixDataQueryRecorder');
12
+ return {
13
+ items: {
14
+ query: jest.fn(() => recorder.createQueryRecorder()),
15
+ filter: jest.fn(() => recorder.createQueryRecorder())
16
+ }
17
+ };
18
+ });
19
+ const makeQuery = filters => ({
20
+ filters
21
+ });
22
+ describe('addFiltersToDataQuery', () => {
23
+ beforeEach(() => {
24
+ jest.clearAllMocks();
25
+ });
26
+ const numberFields = {
27
+ numberField: {
28
+ id: 'numberField',
29
+ type: 'NUMBER',
30
+ displayName: 'Number Field',
31
+ capabilities: {
32
+ supportedQueryOperators: ['GTE', 'LTE'],
33
+ sortable: true
34
+ }
35
+ }
36
+ };
37
+ it('applies a number range filter as ge (from) and le (to)', () => {
38
+ const dataQuery = _data.items.query('collectionId');
39
+ (0, _filterUtils.addFiltersToDataQuery)({
40
+ dataQuery: dataQuery,
41
+ query: makeQuery({
42
+ numberField: {
43
+ from: 5,
44
+ to: 10
45
+ }
46
+ }),
47
+ fields: numberFields,
48
+ filterFieldMapping: {
49
+ numberField: {
50
+ fieldId: 'numberField'
51
+ }
52
+ }
53
+ });
54
+ expect((0, _wixDataQueryRecorder.firstCallArgs)(dataQuery, 'ge')).toEqual(['numberField', 5]);
55
+ expect((0, _wixDataQueryRecorder.firstCallArgs)(dataQuery, 'le')).toEqual(['numberField', 10]);
56
+ });
57
+ it('ignores range props whose operator is not supported by the field', () => {
58
+ const dataQuery = _data.items.query('collectionId');
59
+ (0, _filterUtils.addFiltersToDataQuery)({
60
+ dataQuery: dataQuery,
61
+ query: makeQuery({
62
+ numberField: {
63
+ from: 5,
64
+ to: 10
65
+ }
66
+ }),
67
+ fields: {
68
+ numberField: {
69
+ id: 'numberField',
70
+ type: 'NUMBER',
71
+ displayName: 'Number Field',
72
+ // Only EQ supported → GTE/LTE range props are dropped.
73
+ capabilities: {
74
+ supportedQueryOperators: ['EQ'],
75
+ sortable: true
76
+ }
77
+ }
78
+ },
79
+ filterFieldMapping: {
80
+ numberField: {
81
+ fieldId: 'numberField'
82
+ }
83
+ }
84
+ });
85
+ expect((0, _wixDataQueryRecorder.wasCalled)(dataQuery, 'ge')).toBe(false);
86
+ expect((0, _wixDataQueryRecorder.wasCalled)(dataQuery, 'le')).toBe(false);
87
+ });
88
+ it('returns the query untouched when filterFieldMapping is absent', () => {
89
+ const dataQuery = _data.items.query('collectionId');
90
+ (0, _filterUtils.addFiltersToDataQuery)({
91
+ dataQuery: dataQuery,
92
+ query: makeQuery({
93
+ numberField: {
94
+ from: 5,
95
+ to: 10
96
+ }
97
+ }),
98
+ fields: numberFields
99
+ });
100
+ expect(dataQuery.calls).toHaveLength(0);
101
+ });
102
+ describe('BOOLEAN array filter', () => {
103
+ const booleanFields = {
104
+ booleanField: {
105
+ id: 'booleanField',
106
+ type: 'BOOLEAN',
107
+ displayName: 'Boolean Field',
108
+ capabilities: {
109
+ supportedQueryOperators: ['EQ'],
110
+ sortable: true
111
+ }
112
+ }
113
+ };
114
+ it('applies eq(field, true) when "checked" is selected', () => {
115
+ const dataQuery = _data.items.query('collectionId');
116
+ (0, _filterUtils.addFiltersToDataQuery)({
117
+ dataQuery: dataQuery,
118
+ query: makeQuery({
119
+ booleanField: [{
120
+ id: _constants.BooleanFilters.checked
121
+ }]
122
+ }),
123
+ fields: booleanFields,
124
+ filterFieldMapping: {
125
+ booleanField: {
126
+ fieldId: 'booleanField'
127
+ }
128
+ }
129
+ });
130
+ expect((0, _wixDataQueryRecorder.firstCallArgs)(dataQuery, 'eq')).toEqual(['booleanField', true]);
131
+ });
132
+ it('applies and(eq false OR eq undefined) when "checked" is not selected', () => {
133
+ const dataQuery = _data.items.query('collectionId');
134
+ (0, _filterUtils.addFiltersToDataQuery)({
135
+ dataQuery: dataQuery,
136
+ query: makeQuery({
137
+ booleanField: [{
138
+ id: _constants.BooleanFilters.unchecked
139
+ }]
140
+ }),
141
+ fields: booleanFields,
142
+ filterFieldMapping: {
143
+ booleanField: {
144
+ fieldId: 'booleanField'
145
+ }
146
+ }
147
+ });
148
+
149
+ // No direct eq(true) on the data query — the false-or-undefined branch wraps in .and().
150
+ expect((0, _wixDataQueryRecorder.wasCalled)(dataQuery, 'eq')).toBe(false);
151
+ const andArgs = (0, _wixDataQueryRecorder.firstCallArgs)(dataQuery, 'and');
152
+ expect(andArgs).toBeDefined();
153
+
154
+ // The argument is the `falseFilter.or(undefinedFilter)` recorder.
155
+ const falseFilter = andArgs[0];
156
+ const eqValues = falseFilter.calls.filter(c => c.method === 'eq').map(c => c.args[1]);
157
+ expect(eqValues).toContain(false);
158
+ expect((0, _wixDataQueryRecorder.wasCalled)(falseFilter, 'or')).toBe(true);
159
+ });
160
+ });
161
+ describe('HAS_VALUE array filter', () => {
162
+ const richContentFields = {
163
+ richField: {
164
+ id: 'richField',
165
+ type: 'RICH_CONTENT',
166
+ displayName: 'Rich Field',
167
+ capabilities: {
168
+ supportedQueryOperators: [],
169
+ sortable: false
170
+ }
171
+ }
172
+ };
173
+ it('applies isNotEmpty when only "hasValue" is selected', () => {
174
+ const dataQuery = _data.items.query('collectionId');
175
+ (0, _filterUtils.addFiltersToDataQuery)({
176
+ dataQuery: dataQuery,
177
+ query: makeQuery({
178
+ richField: [{
179
+ id: _constants.HasValueFilters.hasValue
180
+ }]
181
+ }),
182
+ fields: richContentFields,
183
+ filterFieldMapping: {
184
+ richField: {
185
+ fieldId: 'richField'
186
+ }
187
+ }
188
+ });
189
+ expect((0, _wixDataQueryRecorder.firstCallArgs)(dataQuery, 'isNotEmpty')).toEqual(['richField']);
190
+ expect((0, _wixDataQueryRecorder.wasCalled)(dataQuery, 'isEmpty')).toBe(false);
191
+ });
192
+ it('applies isEmpty when only "noValue" is selected', () => {
193
+ const dataQuery = _data.items.query('collectionId');
194
+ (0, _filterUtils.addFiltersToDataQuery)({
195
+ dataQuery: dataQuery,
196
+ query: makeQuery({
197
+ richField: [{
198
+ id: _constants.HasValueFilters.noValue
199
+ }]
200
+ }),
201
+ fields: richContentFields,
202
+ filterFieldMapping: {
203
+ richField: {
204
+ fieldId: 'richField'
205
+ }
206
+ }
207
+ });
208
+ expect((0, _wixDataQueryRecorder.firstCallArgs)(dataQuery, 'isEmpty')).toEqual(['richField']);
209
+ expect((0, _wixDataQueryRecorder.wasCalled)(dataQuery, 'isNotEmpty')).toBe(false);
210
+ });
211
+ it('applies neither when both hasValue and noValue are selected', () => {
212
+ const dataQuery = _data.items.query('collectionId');
213
+ (0, _filterUtils.addFiltersToDataQuery)({
214
+ dataQuery: dataQuery,
215
+ query: makeQuery({
216
+ richField: [{
217
+ id: _constants.HasValueFilters.hasValue
218
+ }, {
219
+ id: _constants.HasValueFilters.noValue
220
+ }]
221
+ }),
222
+ fields: richContentFields,
223
+ filterFieldMapping: {
224
+ richField: {
225
+ fieldId: 'richField'
226
+ }
227
+ }
228
+ });
229
+ expect((0, _wixDataQueryRecorder.wasCalled)(dataQuery, 'isEmpty')).toBe(false);
230
+ expect((0, _wixDataQueryRecorder.wasCalled)(dataQuery, 'isNotEmpty')).toBe(false);
231
+ });
232
+ });
233
+ it('applies hasSome for a generic (non-boolean, non-has-value) array filter', () => {
234
+ const dataQuery = _data.items.query('collectionId');
235
+ (0, _filterUtils.addFiltersToDataQuery)({
236
+ dataQuery: dataQuery,
237
+ query: makeQuery({
238
+ tagsField: [{
239
+ id: 'a'
240
+ }, {
241
+ id: 'b'
242
+ }]
243
+ }),
244
+ fields: {
245
+ tagsField: {
246
+ id: 'tagsField',
247
+ type: 'SHORT_TEXT',
248
+ displayName: 'Tags Field',
249
+ capabilities: {
250
+ supportedQueryOperators: [],
251
+ sortable: false
252
+ }
253
+ }
254
+ },
255
+ filterFieldMapping: {
256
+ tagsField: {
257
+ fieldId: 'tagsField'
258
+ }
259
+ }
260
+ });
261
+ expect((0, _wixDataQueryRecorder.firstCallArgs)(dataQuery, 'hasSome')).toEqual(['tagsField', ['a', 'b']]);
262
+ });
263
+ describe('operator object filter', () => {
264
+ const textFields = {
265
+ textField: {
266
+ id: 'textField',
267
+ type: 'SHORT_TEXT',
268
+ displayName: 'Text Field',
269
+ capabilities: {
270
+ supportedQueryOperators: [],
271
+ sortable: false
272
+ }
273
+ }
274
+ };
275
+ it('maps CONTAINS to .contains', () => {
276
+ const dataQuery = _data.items.query('collectionId');
277
+ (0, _filterUtils.addFiltersToDataQuery)({
278
+ dataQuery: dataQuery,
279
+ query: makeQuery({
280
+ textField: {
281
+ operator: _bexCore.FilterOperator.CONTAINS,
282
+ value: 'foo'
283
+ }
284
+ }),
285
+ fields: textFields,
286
+ filterFieldMapping: {
287
+ textField: {
288
+ fieldId: 'textField'
289
+ }
290
+ }
291
+ });
292
+ expect((0, _wixDataQueryRecorder.firstCallArgs)(dataQuery, 'contains')).toEqual(['textField', 'foo']);
293
+ });
294
+ it('maps IS_EMPTY to .isEmpty(field) (no value argument)', () => {
295
+ const dataQuery = _data.items.query('collectionId');
296
+ (0, _filterUtils.addFiltersToDataQuery)({
297
+ dataQuery: dataQuery,
298
+ query: makeQuery({
299
+ textField: {
300
+ operator: _bexCore.FilterOperator.IS_EMPTY
301
+ }
302
+ }),
303
+ fields: textFields,
304
+ filterFieldMapping: {
305
+ textField: {
306
+ fieldId: 'textField'
307
+ }
308
+ }
309
+ });
310
+ expect((0, _wixDataQueryRecorder.firstCallArgs)(dataQuery, 'isEmpty')).toEqual(['textField']);
311
+ });
312
+ it('maps EXISTS to .isNotEmpty(field)', () => {
313
+ const dataQuery = _data.items.query('collectionId');
314
+ (0, _filterUtils.addFiltersToDataQuery)({
315
+ dataQuery: dataQuery,
316
+ query: makeQuery({
317
+ textField: {
318
+ operator: _bexCore.FilterOperator.EXISTS
319
+ }
320
+ }),
321
+ fields: textFields,
322
+ filterFieldMapping: {
323
+ textField: {
324
+ fieldId: 'textField'
325
+ }
326
+ }
327
+ });
328
+ expect((0, _wixDataQueryRecorder.firstCallArgs)(dataQuery, 'isNotEmpty')).toEqual(['textField']);
329
+ });
330
+ it('maps NOT_CONTAINS to .not(filter().contains(...))', () => {
331
+ const dataQuery = _data.items.query('collectionId');
332
+ (0, _filterUtils.addFiltersToDataQuery)({
333
+ dataQuery: dataQuery,
334
+ query: makeQuery({
335
+ textField: {
336
+ operator: _bexCore.FilterOperator.NOT_CONTAINS,
337
+ value: 'bar'
338
+ }
339
+ }),
340
+ fields: textFields,
341
+ filterFieldMapping: {
342
+ textField: {
343
+ fieldId: 'textField'
344
+ }
345
+ }
346
+ });
347
+ const notArgs = (0, _wixDataQueryRecorder.firstCallArgs)(dataQuery, 'not');
348
+ expect(notArgs).toBeDefined();
349
+ const innerFilter = notArgs[0];
350
+ expect((0, _wixDataQueryRecorder.firstCallArgs)(innerFilter, 'contains')).toEqual(['textField', 'bar']);
351
+ });
352
+ it('queries the .formatted nested property for ADDRESS text operators', () => {
353
+ const dataQuery = _data.items.query('collectionId');
354
+ (0, _filterUtils.addFiltersToDataQuery)({
355
+ dataQuery: dataQuery,
356
+ query: makeQuery({
357
+ addressField: {
358
+ operator: _bexCore.FilterOperator.CONTAINS,
359
+ value: 'NYC'
360
+ }
361
+ }),
362
+ fields: {
363
+ addressField: {
364
+ id: 'addressField',
365
+ type: 'ADDRESS',
366
+ displayName: 'Address Field',
367
+ capabilities: {
368
+ supportedQueryOperators: [],
369
+ sortable: false
370
+ }
371
+ }
372
+ },
373
+ filterFieldMapping: {
374
+ addressField: {
375
+ fieldId: 'addressField'
376
+ }
377
+ }
378
+ });
379
+ expect((0, _wixDataQueryRecorder.firstCallArgs)(dataQuery, 'contains')).toEqual(['addressField.formatted', 'NYC']);
380
+ });
381
+ it('queries the ADDRESS field directly for existence operators (no .formatted)', () => {
382
+ const dataQuery = _data.items.query('collectionId');
383
+ (0, _filterUtils.addFiltersToDataQuery)({
384
+ dataQuery: dataQuery,
385
+ query: makeQuery({
386
+ addressField: {
387
+ operator: _bexCore.FilterOperator.IS_EMPTY
388
+ }
389
+ }),
390
+ fields: {
391
+ addressField: {
392
+ id: 'addressField',
393
+ type: 'ADDRESS',
394
+ displayName: 'Address Field',
395
+ capabilities: {
396
+ supportedQueryOperators: [],
397
+ sortable: false
398
+ }
399
+ }
400
+ },
401
+ filterFieldMapping: {
402
+ addressField: {
403
+ fieldId: 'addressField'
404
+ }
405
+ }
406
+ });
407
+ expect((0, _wixDataQueryRecorder.firstCallArgs)(dataQuery, 'isEmpty')).toEqual(['addressField']);
408
+ });
409
+ });
410
+ it('skips filters for fields not present in filterFieldMapping', () => {
411
+ const dataQuery = _data.items.query('collectionId');
412
+ (0, _filterUtils.addFiltersToDataQuery)({
413
+ dataQuery: dataQuery,
414
+ query: makeQuery({
415
+ numberField: {
416
+ from: 5,
417
+ to: 10
418
+ }
419
+ }),
420
+ fields: numberFields,
421
+ filterFieldMapping: {}
422
+ });
423
+ expect(dataQuery.calls).toHaveLength(0);
424
+ });
425
+ });
426
+ //# sourceMappingURL=filterUtils.spec.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["_data","require","_bexCore","_filterUtils","_constants","_wixDataQueryRecorder","jest","mock","recorder","items","query","fn","createQueryRecorder","filter","makeQuery","filters","describe","beforeEach","clearAllMocks","numberFields","numberField","id","type","displayName","capabilities","supportedQueryOperators","sortable","it","dataQuery","addFiltersToDataQuery","from","to","fields","filterFieldMapping","fieldId","expect","firstCallArgs","toEqual","wasCalled","toBe","calls","toHaveLength","booleanFields","booleanField","BooleanFilters","checked","unchecked","andArgs","toBeDefined","falseFilter","eqValues","c","method","map","args","toContain","richContentFields","richField","HasValueFilters","hasValue","noValue","tagsField","textFields","textField","operator","FilterOperator","CONTAINS","value","IS_EMPTY","EXISTS","NOT_CONTAINS","notArgs","innerFilter","addressField"],"sources":["../../../../src/adapter/__tests__/filterUtils.spec.ts"],"sourcesContent":["import { items } from '@wix/data';\nimport { FilterOperator } from '@wix/bex-core';\nimport type { OffsetQuery, Schema } from '@wix/bex-core';\nimport { addFiltersToDataQuery } from '../filterUtils';\nimport { BooleanFilters, HasValueFilters } from '../constants';\nimport {\n firstCallArgs,\n wasCalled,\n type QueryRecorder,\n} from './wixDataQueryRecorder';\n\n// Replace the `@wix/data` `items` builders with chainable recorders so we can\n// assert which WQL operator methods the util produced.\njest.mock('@wix/data', () => {\n const recorder = require('./wixDataQueryRecorder');\n return {\n items: {\n query: jest.fn(() => recorder.createQueryRecorder()),\n filter: jest.fn(() => recorder.createQueryRecorder()),\n },\n };\n});\n\ntype SchemaFields = Schema['fields'];\n\nconst makeQuery = (filters: Record<string, unknown>): OffsetQuery =>\n ({ filters } as unknown as OffsetQuery);\n\ndescribe('addFiltersToDataQuery', () => {\n beforeEach(() => {\n jest.clearAllMocks();\n });\n\n const numberFields: SchemaFields = {\n numberField: {\n id: 'numberField',\n type: 'NUMBER',\n displayName: 'Number Field',\n capabilities: { supportedQueryOperators: ['GTE', 'LTE'], sortable: true },\n },\n };\n\n it('applies a number range filter as ge (from) and le (to)', () => {\n const dataQuery = items.query('collectionId') as unknown as QueryRecorder;\n\n addFiltersToDataQuery({\n dataQuery: dataQuery as never,\n query: makeQuery({ numberField: { from: 5, to: 10 } }),\n fields: numberFields,\n filterFieldMapping: { numberField: { fieldId: 'numberField' } },\n });\n\n expect(firstCallArgs(dataQuery, 'ge')).toEqual(['numberField', 5]);\n expect(firstCallArgs(dataQuery, 'le')).toEqual(['numberField', 10]);\n });\n\n it('ignores range props whose operator is not supported by the field', () => {\n const dataQuery = items.query('collectionId') as unknown as QueryRecorder;\n\n addFiltersToDataQuery({\n dataQuery: dataQuery as never,\n query: makeQuery({ numberField: { from: 5, to: 10 } }),\n fields: {\n numberField: {\n id: 'numberField',\n type: 'NUMBER',\n displayName: 'Number Field',\n // Only EQ supported → GTE/LTE range props are dropped.\n capabilities: { supportedQueryOperators: ['EQ'], sortable: true },\n },\n },\n filterFieldMapping: { numberField: { fieldId: 'numberField' } },\n });\n\n expect(wasCalled(dataQuery, 'ge')).toBe(false);\n expect(wasCalled(dataQuery, 'le')).toBe(false);\n });\n\n it('returns the query untouched when filterFieldMapping is absent', () => {\n const dataQuery = items.query('collectionId') as unknown as QueryRecorder;\n\n addFiltersToDataQuery({\n dataQuery: dataQuery as never,\n query: makeQuery({ numberField: { from: 5, to: 10 } }),\n fields: numberFields,\n });\n\n expect(dataQuery.calls).toHaveLength(0);\n });\n\n describe('BOOLEAN array filter', () => {\n const booleanFields: SchemaFields = {\n booleanField: {\n id: 'booleanField',\n type: 'BOOLEAN',\n displayName: 'Boolean Field',\n capabilities: { supportedQueryOperators: ['EQ'], sortable: true },\n },\n };\n\n it('applies eq(field, true) when \"checked\" is selected', () => {\n const dataQuery = items.query('collectionId') as unknown as QueryRecorder;\n\n addFiltersToDataQuery({\n dataQuery: dataQuery as never,\n query: makeQuery({ booleanField: [{ id: BooleanFilters.checked }] }),\n fields: booleanFields,\n filterFieldMapping: { booleanField: { fieldId: 'booleanField' } },\n });\n\n expect(firstCallArgs(dataQuery, 'eq')).toEqual(['booleanField', true]);\n });\n\n it('applies and(eq false OR eq undefined) when \"checked\" is not selected', () => {\n const dataQuery = items.query('collectionId') as unknown as QueryRecorder;\n\n addFiltersToDataQuery({\n dataQuery: dataQuery as never,\n query: makeQuery({ booleanField: [{ id: BooleanFilters.unchecked }] }),\n fields: booleanFields,\n filterFieldMapping: { booleanField: { fieldId: 'booleanField' } },\n });\n\n // No direct eq(true) on the data query — the false-or-undefined branch wraps in .and().\n expect(wasCalled(dataQuery, 'eq')).toBe(false);\n const andArgs = firstCallArgs(dataQuery, 'and');\n expect(andArgs).toBeDefined();\n\n // The argument is the `falseFilter.or(undefinedFilter)` recorder.\n const falseFilter = andArgs![0] as QueryRecorder;\n const eqValues = falseFilter.calls\n .filter((c) => c.method === 'eq')\n .map((c) => c.args[1]);\n expect(eqValues).toContain(false);\n expect(wasCalled(falseFilter, 'or')).toBe(true);\n });\n });\n\n describe('HAS_VALUE array filter', () => {\n const richContentFields: SchemaFields = {\n richField: {\n id: 'richField',\n type: 'RICH_CONTENT',\n displayName: 'Rich Field',\n capabilities: { supportedQueryOperators: [], sortable: false },\n },\n };\n\n it('applies isNotEmpty when only \"hasValue\" is selected', () => {\n const dataQuery = items.query('collectionId') as unknown as QueryRecorder;\n\n addFiltersToDataQuery({\n dataQuery: dataQuery as never,\n query: makeQuery({ richField: [{ id: HasValueFilters.hasValue }] }),\n fields: richContentFields,\n filterFieldMapping: { richField: { fieldId: 'richField' } },\n });\n\n expect(firstCallArgs(dataQuery, 'isNotEmpty')).toEqual(['richField']);\n expect(wasCalled(dataQuery, 'isEmpty')).toBe(false);\n });\n\n it('applies isEmpty when only \"noValue\" is selected', () => {\n const dataQuery = items.query('collectionId') as unknown as QueryRecorder;\n\n addFiltersToDataQuery({\n dataQuery: dataQuery as never,\n query: makeQuery({ richField: [{ id: HasValueFilters.noValue }] }),\n fields: richContentFields,\n filterFieldMapping: { richField: { fieldId: 'richField' } },\n });\n\n expect(firstCallArgs(dataQuery, 'isEmpty')).toEqual(['richField']);\n expect(wasCalled(dataQuery, 'isNotEmpty')).toBe(false);\n });\n\n it('applies neither when both hasValue and noValue are selected', () => {\n const dataQuery = items.query('collectionId') as unknown as QueryRecorder;\n\n addFiltersToDataQuery({\n dataQuery: dataQuery as never,\n query: makeQuery({\n richField: [\n { id: HasValueFilters.hasValue },\n { id: HasValueFilters.noValue },\n ],\n }),\n fields: richContentFields,\n filterFieldMapping: { richField: { fieldId: 'richField' } },\n });\n\n expect(wasCalled(dataQuery, 'isEmpty')).toBe(false);\n expect(wasCalled(dataQuery, 'isNotEmpty')).toBe(false);\n });\n });\n\n it('applies hasSome for a generic (non-boolean, non-has-value) array filter', () => {\n const dataQuery = items.query('collectionId') as unknown as QueryRecorder;\n\n addFiltersToDataQuery({\n dataQuery: dataQuery as never,\n query: makeQuery({\n tagsField: [{ id: 'a' }, { id: 'b' }],\n }),\n fields: {\n tagsField: {\n id: 'tagsField',\n type: 'SHORT_TEXT',\n displayName: 'Tags Field',\n capabilities: { supportedQueryOperators: [], sortable: false },\n },\n },\n filterFieldMapping: { tagsField: { fieldId: 'tagsField' } },\n });\n\n expect(firstCallArgs(dataQuery, 'hasSome')).toEqual([\n 'tagsField',\n ['a', 'b'],\n ]);\n });\n\n describe('operator object filter', () => {\n const textFields: SchemaFields = {\n textField: {\n id: 'textField',\n type: 'SHORT_TEXT',\n displayName: 'Text Field',\n capabilities: { supportedQueryOperators: [], sortable: false },\n },\n };\n\n it('maps CONTAINS to .contains', () => {\n const dataQuery = items.query('collectionId') as unknown as QueryRecorder;\n\n addFiltersToDataQuery({\n dataQuery: dataQuery as never,\n query: makeQuery({\n textField: { operator: FilterOperator.CONTAINS, value: 'foo' },\n }),\n fields: textFields,\n filterFieldMapping: { textField: { fieldId: 'textField' } },\n });\n\n expect(firstCallArgs(dataQuery, 'contains')).toEqual([\n 'textField',\n 'foo',\n ]);\n });\n\n it('maps IS_EMPTY to .isEmpty(field) (no value argument)', () => {\n const dataQuery = items.query('collectionId') as unknown as QueryRecorder;\n\n addFiltersToDataQuery({\n dataQuery: dataQuery as never,\n query: makeQuery({\n textField: { operator: FilterOperator.IS_EMPTY },\n }),\n fields: textFields,\n filterFieldMapping: { textField: { fieldId: 'textField' } },\n });\n\n expect(firstCallArgs(dataQuery, 'isEmpty')).toEqual(['textField']);\n });\n\n it('maps EXISTS to .isNotEmpty(field)', () => {\n const dataQuery = items.query('collectionId') as unknown as QueryRecorder;\n\n addFiltersToDataQuery({\n dataQuery: dataQuery as never,\n query: makeQuery({\n textField: { operator: FilterOperator.EXISTS },\n }),\n fields: textFields,\n filterFieldMapping: { textField: { fieldId: 'textField' } },\n });\n\n expect(firstCallArgs(dataQuery, 'isNotEmpty')).toEqual(['textField']);\n });\n\n it('maps NOT_CONTAINS to .not(filter().contains(...))', () => {\n const dataQuery = items.query('collectionId') as unknown as QueryRecorder;\n\n addFiltersToDataQuery({\n dataQuery: dataQuery as never,\n query: makeQuery({\n textField: { operator: FilterOperator.NOT_CONTAINS, value: 'bar' },\n }),\n fields: textFields,\n filterFieldMapping: { textField: { fieldId: 'textField' } },\n });\n\n const notArgs = firstCallArgs(dataQuery, 'not');\n expect(notArgs).toBeDefined();\n const innerFilter = notArgs![0] as QueryRecorder;\n expect(firstCallArgs(innerFilter, 'contains')).toEqual([\n 'textField',\n 'bar',\n ]);\n });\n\n it('queries the .formatted nested property for ADDRESS text operators', () => {\n const dataQuery = items.query('collectionId') as unknown as QueryRecorder;\n\n addFiltersToDataQuery({\n dataQuery: dataQuery as never,\n query: makeQuery({\n addressField: { operator: FilterOperator.CONTAINS, value: 'NYC' },\n }),\n fields: {\n addressField: {\n id: 'addressField',\n type: 'ADDRESS',\n displayName: 'Address Field',\n capabilities: { supportedQueryOperators: [], sortable: false },\n },\n },\n filterFieldMapping: { addressField: { fieldId: 'addressField' } },\n });\n\n expect(firstCallArgs(dataQuery, 'contains')).toEqual([\n 'addressField.formatted',\n 'NYC',\n ]);\n });\n\n it('queries the ADDRESS field directly for existence operators (no .formatted)', () => {\n const dataQuery = items.query('collectionId') as unknown as QueryRecorder;\n\n addFiltersToDataQuery({\n dataQuery: dataQuery as never,\n query: makeQuery({\n addressField: { operator: FilterOperator.IS_EMPTY },\n }),\n fields: {\n addressField: {\n id: 'addressField',\n type: 'ADDRESS',\n displayName: 'Address Field',\n capabilities: { supportedQueryOperators: [], sortable: false },\n },\n },\n filterFieldMapping: { addressField: { fieldId: 'addressField' } },\n });\n\n expect(firstCallArgs(dataQuery, 'isEmpty')).toEqual(['addressField']);\n });\n });\n\n it('skips filters for fields not present in filterFieldMapping', () => {\n const dataQuery = items.query('collectionId') as unknown as QueryRecorder;\n\n addFiltersToDataQuery({\n dataQuery: dataQuery as never,\n query: makeQuery({ numberField: { from: 5, to: 10 } }),\n fields: numberFields,\n filterFieldMapping: {},\n });\n\n expect(dataQuery.calls).toHaveLength(0);\n });\n});\n"],"mappings":"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","ignoreList":[]}
@@ -0,0 +1,24 @@
1
+ "use strict";
2
+
3
+ var _getFieldKey = require("../getFieldKey");
4
+ describe('getFieldKey', () => {
5
+ it('camelCases a multi-word display name', () => {
6
+ expect((0, _getFieldKey.getFieldKey)([], 'My New Field')).toBe('myNewField');
7
+ });
8
+ it('snake_cases a display name that already contains an underscore', () => {
9
+ expect((0, _getFieldKey.getFieldKey)([], 'my_field name')).toBe('my_field_name');
10
+ });
11
+ it('strips non-ASCII-alphanumeric characters from the display name', () => {
12
+ expect((0, _getFieldKey.getFieldKey)([], 'Price ($)')).toBe('price');
13
+ });
14
+ it('returns the base suggestion when there is no collision', () => {
15
+ expect((0, _getFieldKey.getFieldKey)(['otherField'], 'New Field')).toBe('newField');
16
+ });
17
+ it('appends a numeric suffix when the base key collides', () => {
18
+ expect((0, _getFieldKey.getFieldKey)(['newField'], 'New Field')).toBe('newField1');
19
+ });
20
+ it('increments the suffix until a free key is found', () => {
21
+ expect((0, _getFieldKey.getFieldKey)(['newField', 'newField1', 'newField2'], 'New Field')).toBe('newField3');
22
+ });
23
+ });
24
+ //# sourceMappingURL=getFieldKey.spec.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["_getFieldKey","require","describe","it","expect","getFieldKey","toBe"],"sources":["../../../../src/adapter/__tests__/getFieldKey.spec.ts"],"sourcesContent":["import { getFieldKey } from '../getFieldKey';\n\ndescribe('getFieldKey', () => {\n it('camelCases a multi-word display name', () => {\n expect(getFieldKey([], 'My New Field')).toBe('myNewField');\n });\n\n it('snake_cases a display name that already contains an underscore', () => {\n expect(getFieldKey([], 'my_field name')).toBe('my_field_name');\n });\n\n it('strips non-ASCII-alphanumeric characters from the display name', () => {\n expect(getFieldKey([], 'Price ($)')).toBe('price');\n });\n\n it('returns the base suggestion when there is no collision', () => {\n expect(getFieldKey(['otherField'], 'New Field')).toBe('newField');\n });\n\n it('appends a numeric suffix when the base key collides', () => {\n expect(getFieldKey(['newField'], 'New Field')).toBe('newField1');\n });\n\n it('increments the suffix until a free key is found', () => {\n expect(\n getFieldKey(['newField', 'newField1', 'newField2'], 'New Field'),\n ).toBe('newField3');\n });\n});\n"],"mappings":";;AAAA,IAAAA,YAAA,GAAAC,OAAA;AAEAC,QAAQ,CAAC,aAAa,EAAE,MAAM;EAC5BC,EAAE,CAAC,sCAAsC,EAAE,MAAM;IAC/CC,MAAM,CAAC,IAAAC,wBAAW,EAAC,EAAE,EAAE,cAAc,CAAC,CAAC,CAACC,IAAI,CAAC,YAAY,CAAC;EAC5D,CAAC,CAAC;EAEFH,EAAE,CAAC,gEAAgE,EAAE,MAAM;IACzEC,MAAM,CAAC,IAAAC,wBAAW,EAAC,EAAE,EAAE,eAAe,CAAC,CAAC,CAACC,IAAI,CAAC,eAAe,CAAC;EAChE,CAAC,CAAC;EAEFH,EAAE,CAAC,gEAAgE,EAAE,MAAM;IACzEC,MAAM,CAAC,IAAAC,wBAAW,EAAC,EAAE,EAAE,WAAW,CAAC,CAAC,CAACC,IAAI,CAAC,OAAO,CAAC;EACpD,CAAC,CAAC;EAEFH,EAAE,CAAC,wDAAwD,EAAE,MAAM;IACjEC,MAAM,CAAC,IAAAC,wBAAW,EAAC,CAAC,YAAY,CAAC,EAAE,WAAW,CAAC,CAAC,CAACC,IAAI,CAAC,UAAU,CAAC;EACnE,CAAC,CAAC;EAEFH,EAAE,CAAC,qDAAqD,EAAE,MAAM;IAC9DC,MAAM,CAAC,IAAAC,wBAAW,EAAC,CAAC,UAAU,CAAC,EAAE,WAAW,CAAC,CAAC,CAACC,IAAI,CAAC,WAAW,CAAC;EAClE,CAAC,CAAC;EAEFH,EAAE,CAAC,iDAAiD,EAAE,MAAM;IAC1DC,MAAM,CACJ,IAAAC,wBAAW,EAAC,CAAC,UAAU,EAAE,WAAW,EAAE,WAAW,CAAC,EAAE,WAAW,CACjE,CAAC,CAACC,IAAI,CAAC,WAAW,CAAC;EACrB,CAAC,CAAC;AACJ,CAAC,CAAC","ignoreList":[]}