@depup/payload 3.82.1-depup.0 → 3.86.0-depup.5

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 (196) hide show
  1. package/README.md +15 -13
  2. package/bin.js +11 -0
  3. package/changes.json +25 -17
  4. package/dist/admin/fields/Row.d.ts +2 -2
  5. package/dist/admin/fields/Row.d.ts.map +1 -1
  6. package/dist/admin/fields/Row.js.map +1 -1
  7. package/dist/admin/forms/Field.d.ts +1 -3
  8. package/dist/admin/forms/Field.d.ts.map +1 -1
  9. package/dist/admin/forms/Field.js.map +1 -1
  10. package/dist/admin/views/index.d.ts +5 -1
  11. package/dist/admin/views/index.d.ts.map +1 -1
  12. package/dist/admin/views/index.js.map +1 -1
  13. package/dist/bin/generateImportMap/index.d.ts.map +1 -1
  14. package/dist/bin/generateImportMap/index.js +1 -0
  15. package/dist/bin/generateImportMap/index.js.map +1 -1
  16. package/dist/bin/generateImportMap/iterateCollections.d.ts.map +1 -1
  17. package/dist/bin/generateImportMap/iterateCollections.js +11 -0
  18. package/dist/bin/generateImportMap/iterateCollections.js.map +1 -1
  19. package/dist/bin/index.d.ts.map +1 -1
  20. package/dist/bin/index.js +3 -1
  21. package/dist/bin/index.js.map +1 -1
  22. package/dist/collections/config/sanitize.d.ts +5 -0
  23. package/dist/collections/config/sanitize.d.ts.map +1 -1
  24. package/dist/collections/config/sanitize.js +21 -0
  25. package/dist/collections/config/sanitize.js.map +1 -1
  26. package/dist/collections/config/sanitize.spec.js +120 -0
  27. package/dist/collections/config/sanitize.spec.js.map +1 -0
  28. package/dist/collections/config/types.d.ts +24 -1
  29. package/dist/collections/config/types.d.ts.map +1 -1
  30. package/dist/collections/config/types.js.map +1 -1
  31. package/dist/collections/operations/create.d.ts.map +1 -1
  32. package/dist/collections/operations/create.js +1 -0
  33. package/dist/collections/operations/create.js.map +1 -1
  34. package/dist/collections/operations/delete.d.ts.map +1 -1
  35. package/dist/collections/operations/delete.js +3 -0
  36. package/dist/collections/operations/delete.js.map +1 -1
  37. package/dist/collections/operations/restoreVersion.d.ts.map +1 -1
  38. package/dist/collections/operations/restoreVersion.js +1 -0
  39. package/dist/collections/operations/restoreVersion.js.map +1 -1
  40. package/dist/collections/operations/update.d.ts.map +1 -1
  41. package/dist/collections/operations/update.js +7 -2
  42. package/dist/collections/operations/update.js.map +1 -1
  43. package/dist/collections/operations/utilities/copyDataWithFreshRowIDs.d.ts +9 -0
  44. package/dist/collections/operations/utilities/copyDataWithFreshRowIDs.d.ts.map +1 -0
  45. package/dist/collections/operations/utilities/copyDataWithFreshRowIDs.js +170 -0
  46. package/dist/collections/operations/utilities/copyDataWithFreshRowIDs.js.map +1 -0
  47. package/dist/collections/operations/utilities/update.d.ts.map +1 -1
  48. package/dist/collections/operations/utilities/update.js +16 -8
  49. package/dist/collections/operations/utilities/update.js.map +1 -1
  50. package/dist/config/build.js +5 -4
  51. package/dist/config/build.js.map +1 -1
  52. package/dist/config/definePlugin.d.ts +41 -0
  53. package/dist/config/definePlugin.d.ts.map +1 -0
  54. package/dist/config/definePlugin.js +34 -0
  55. package/dist/config/definePlugin.js.map +1 -0
  56. package/dist/config/orderable/index.d.ts.map +1 -1
  57. package/dist/config/orderable/index.js +23 -0
  58. package/dist/config/orderable/index.js.map +1 -1
  59. package/dist/config/types.d.ts +30 -2
  60. package/dist/config/types.d.ts.map +1 -1
  61. package/dist/config/types.js.map +1 -1
  62. package/dist/email/normalizeSendEmailOptions.d.ts +13 -0
  63. package/dist/email/normalizeSendEmailOptions.d.ts.map +1 -0
  64. package/dist/email/normalizeSendEmailOptions.js +20 -0
  65. package/dist/email/normalizeSendEmailOptions.js.map +1 -0
  66. package/dist/email/types.d.ts +7 -2
  67. package/dist/email/types.d.ts.map +1 -1
  68. package/dist/email/types.js.map +1 -1
  69. package/dist/errors/APIError.d.ts +2 -1
  70. package/dist/errors/APIError.d.ts.map +1 -1
  71. package/dist/errors/APIError.js +1 -3
  72. package/dist/errors/APIError.js.map +1 -1
  73. package/dist/errors/ValidationError.d.ts +3 -1
  74. package/dist/errors/ValidationError.d.ts.map +1 -1
  75. package/dist/errors/ValidationError.js +1 -3
  76. package/dist/errors/ValidationError.js.map +1 -1
  77. package/dist/fields/config/sanitize.d.ts.map +1 -1
  78. package/dist/fields/config/sanitize.js +3 -0
  79. package/dist/fields/config/sanitize.js.map +1 -1
  80. package/dist/fields/config/sanitize.spec.js +66 -0
  81. package/dist/fields/config/sanitize.spec.js.map +1 -1
  82. package/dist/fields/config/types.d.ts +3 -2
  83. package/dist/fields/config/types.d.ts.map +1 -1
  84. package/dist/fields/config/types.js.map +1 -1
  85. package/dist/fields/hooks/beforeValidate/promise.js +2 -2
  86. package/dist/fields/hooks/beforeValidate/promise.js.map +1 -1
  87. package/dist/globals/operations/restoreVersion.d.ts.map +1 -1
  88. package/dist/globals/operations/restoreVersion.js +1 -0
  89. package/dist/globals/operations/restoreVersion.js.map +1 -1
  90. package/dist/index.bundled.d.ts +484 -115
  91. package/dist/index.d.ts +19 -1
  92. package/dist/index.d.ts.map +1 -1
  93. package/dist/index.js +16 -2
  94. package/dist/index.js.map +1 -1
  95. package/dist/queues/config/collection.d.ts.map +1 -1
  96. package/dist/queues/config/collection.js +0 -1
  97. package/dist/queues/config/collection.js.map +1 -1
  98. package/dist/queues/endpoints/run.d.ts.map +1 -1
  99. package/dist/queues/endpoints/run.js +0 -3
  100. package/dist/queues/endpoints/run.js.map +1 -1
  101. package/dist/queues/errors/calculateBackoffWaitUntil.d.ts.map +1 -1
  102. package/dist/queues/errors/calculateBackoffWaitUntil.js +5 -13
  103. package/dist/queues/errors/calculateBackoffWaitUntil.js.map +1 -1
  104. package/dist/queues/errors/handleWorkflowError.d.ts.map +1 -1
  105. package/dist/queues/errors/handleWorkflowError.js +9 -1
  106. package/dist/queues/errors/handleWorkflowError.js.map +1 -1
  107. package/dist/queues/operations/handleSchedules/countRunnableOrActiveJobsForQueue.d.ts.map +1 -1
  108. package/dist/queues/operations/handleSchedules/countRunnableOrActiveJobsForQueue.js +2 -1
  109. package/dist/queues/operations/handleSchedules/countRunnableOrActiveJobsForQueue.js.map +1 -1
  110. package/dist/queues/operations/handleSchedules/defaultAfterSchedule.js +1 -1
  111. package/dist/queues/operations/handleSchedules/defaultAfterSchedule.js.map +1 -1
  112. package/dist/queues/operations/handleSchedules/index.d.ts.map +1 -1
  113. package/dist/queues/operations/handleSchedules/index.js +4 -1
  114. package/dist/queues/operations/handleSchedules/index.js.map +1 -1
  115. package/dist/queues/operations/runJobs/index.d.ts.map +1 -1
  116. package/dist/queues/operations/runJobs/index.js +44 -26
  117. package/dist/queues/operations/runJobs/index.js.map +1 -1
  118. package/dist/queues/operations/runJobs/runJSONJob/index.d.ts.map +1 -1
  119. package/dist/queues/operations/runJobs/runJSONJob/index.js +1 -0
  120. package/dist/queues/operations/runJobs/runJSONJob/index.js.map +1 -1
  121. package/dist/queues/utilities/updateJob.d.ts.map +1 -1
  122. package/dist/queues/utilities/updateJob.js +2 -1
  123. package/dist/queues/utilities/updateJob.js.map +1 -1
  124. package/dist/types/index.d.ts +4 -6
  125. package/dist/types/index.d.ts.map +1 -1
  126. package/dist/types/index.js.map +1 -1
  127. package/dist/uploads/checkFileAccess.d.ts.map +1 -1
  128. package/dist/uploads/checkFileAccess.js +30 -9
  129. package/dist/uploads/checkFileAccess.js.map +1 -1
  130. package/dist/uploads/checkFileRestrictions.d.ts.map +1 -1
  131. package/dist/uploads/checkFileRestrictions.js +48 -8
  132. package/dist/uploads/checkFileRestrictions.js.map +1 -1
  133. package/dist/uploads/fetchAPI-multipart/isEligibleRequest.d.ts.map +1 -1
  134. package/dist/uploads/fetchAPI-multipart/isEligibleRequest.js +2 -1
  135. package/dist/uploads/fetchAPI-multipart/isEligibleRequest.js.map +1 -1
  136. package/dist/uploads/fetchAPI-multipart/isEligibleRequest.spec.js +29 -0
  137. package/dist/uploads/fetchAPI-multipart/isEligibleRequest.spec.js.map +1 -0
  138. package/dist/uploads/fetchAPI-multipart/processMultipart.d.ts.map +1 -1
  139. package/dist/uploads/fetchAPI-multipart/processMultipart.js +11 -2
  140. package/dist/uploads/fetchAPI-multipart/processMultipart.js.map +1 -1
  141. package/dist/uploads/generateFileData.d.ts +2 -1
  142. package/dist/uploads/generateFileData.d.ts.map +1 -1
  143. package/dist/uploads/generateFileData.js +5 -2
  144. package/dist/uploads/generateFileData.js.map +1 -1
  145. package/dist/uploads/getSafeFilename.d.ts +9 -4
  146. package/dist/uploads/getSafeFilename.d.ts.map +1 -1
  147. package/dist/uploads/getSafeFilename.js +5 -5
  148. package/dist/uploads/getSafeFilename.js.map +1 -1
  149. package/dist/uploads/types.d.ts +4 -0
  150. package/dist/uploads/types.d.ts.map +1 -1
  151. package/dist/uploads/types.js.map +1 -1
  152. package/dist/utilities/addDataAndFileToRequest.d.ts.map +1 -1
  153. package/dist/utilities/addDataAndFileToRequest.js +16 -3
  154. package/dist/utilities/addDataAndFileToRequest.js.map +1 -1
  155. package/dist/utilities/addDataAndFileToRequest.spec.js +41 -0
  156. package/dist/utilities/addDataAndFileToRequest.spec.js.map +1 -0
  157. package/dist/utilities/createPayloadRequest.d.ts.map +1 -1
  158. package/dist/utilities/createPayloadRequest.js +1 -0
  159. package/dist/utilities/createPayloadRequest.js.map +1 -1
  160. package/dist/utilities/filterDataToSelectedLocales.d.ts.map +1 -1
  161. package/dist/utilities/filterDataToSelectedLocales.js +74 -31
  162. package/dist/utilities/filterDataToSelectedLocales.js.map +1 -1
  163. package/dist/utilities/filterDataToSelectedLocales.spec.js +337 -0
  164. package/dist/utilities/filterDataToSelectedLocales.spec.js.map +1 -1
  165. package/dist/utilities/formatErrors.d.ts +1 -1
  166. package/dist/utilities/formatErrors.d.ts.map +1 -1
  167. package/dist/utilities/formatErrors.js +4 -7
  168. package/dist/utilities/formatErrors.js.map +1 -1
  169. package/dist/utilities/formatErrors.spec.js +101 -0
  170. package/dist/utilities/formatErrors.spec.js.map +1 -0
  171. package/dist/utilities/isURLAllowed.d.ts.map +1 -1
  172. package/dist/utilities/isURLAllowed.js +9 -3
  173. package/dist/utilities/isURLAllowed.js.map +1 -1
  174. package/dist/utilities/isURLAllowed.spec.js +78 -0
  175. package/dist/utilities/isURLAllowed.spec.js.map +1 -0
  176. package/dist/utilities/parseParams/index.d.ts +1 -1
  177. package/dist/utilities/parseParams/index.d.ts.map +1 -1
  178. package/dist/utilities/parseParams/index.js +3 -0
  179. package/dist/utilities/parseParams/index.js.map +1 -1
  180. package/dist/utilities/parseParams/index.spec.js +24 -0
  181. package/dist/utilities/parseParams/index.spec.js.map +1 -1
  182. package/dist/utilities/profiling.d.ts +12 -0
  183. package/dist/utilities/profiling.d.ts.map +1 -0
  184. package/dist/utilities/profiling.js +56 -0
  185. package/dist/utilities/profiling.js.map +1 -0
  186. package/dist/utilities/profiling.spec.js +53 -0
  187. package/dist/utilities/profiling.spec.js.map +1 -0
  188. package/dist/versions/saveVersion.js +1 -1
  189. package/dist/versions/saveVersion.js.map +1 -1
  190. package/dist/versions/schedule/job.d.ts.map +1 -1
  191. package/dist/versions/schedule/job.js +4 -1
  192. package/dist/versions/schedule/job.js.map +1 -1
  193. package/dist/versions/updateLatestVersion.d.ts.map +1 -1
  194. package/dist/versions/updateLatestVersion.js +55 -8
  195. package/dist/versions/updateLatestVersion.js.map +1 -1
  196. package/package.json +42 -35
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/utilities/filterDataToSelectedLocales.spec.ts"],"sourcesContent":["import type { Field } from '../fields/config/types.js'\n\nimport { describe, expect, it } from 'vitest'\n\nimport { filterDataToSelectedLocales } from './filterDataToSelectedLocales.js'\n\ndescribe('filterDataToSelectedLocales', () => {\n const selectedLocales = ['en']\n const configBlockReferences = []\n\n describe('block metadata preservation', () => {\n it('should preserve blockType, id, and blockName on non-localized blocks', () => {\n const fields: Field[] = [\n {\n name: 'layout',\n type: 'blocks',\n blocks: [\n {\n slug: 'content',\n fields: [\n {\n name: 'richText',\n type: 'richText',\n localized: true,\n },\n ],\n },\n ],\n },\n ]\n\n const docWithLocales = {\n layout: [\n {\n blockType: 'content',\n id: 'abc123',\n blockName: 'My Block',\n richText: { en: 'English', es: 'Spanish' },\n },\n ],\n }\n\n const result = filterDataToSelectedLocales({\n configBlockReferences: [],\n docWithLocales,\n fields,\n selectedLocales,\n })\n\n expect(result.layout).toHaveLength(1)\n expect(result.layout[0].blockType).toBe('content')\n expect(result.layout[0].id).toBe('abc123')\n expect(result.layout[0].blockName).toBe('My Block')\n expect(result.layout[0].richText).toEqual({ en: 'English' })\n })\n\n it('should preserve blockType and id when block has no blockName', () => {\n const fields: Field[] = [\n {\n name: 'layout',\n type: 'blocks',\n blocks: [\n {\n slug: 'text',\n fields: [\n {\n name: 'text',\n type: 'text',\n localized: true,\n },\n ],\n },\n ],\n },\n ]\n\n const docWithLocales = {\n layout: [\n {\n blockType: 'text',\n id: 'def456',\n text: { en: 'English', es: 'Spanish' },\n },\n ],\n }\n\n const result = filterDataToSelectedLocales({\n configBlockReferences: [],\n docWithLocales,\n fields,\n selectedLocales,\n })\n\n expect(result.layout).toHaveLength(1)\n expect(result.layout[0].blockType).toBe('text')\n expect(result.layout[0].id).toBe('def456')\n expect(result.layout[0].text).toEqual({ en: 'English' })\n })\n\n it('should preserve blockType and id with configBlockReferences', () => {\n const fields: Field[] = [\n {\n name: 'layout',\n type: 'blocks',\n blocks: [],\n blockReferences: ['content'],\n },\n ]\n\n const result = filterDataToSelectedLocales({\n configBlockReferences: [\n {\n slug: 'content',\n fields: [\n {\n name: 'body',\n type: 'text',\n localized: true,\n },\n ],\n },\n ],\n docWithLocales: {\n layout: [\n {\n blockType: 'content',\n id: 'ref123',\n body: { en: 'English', es: 'Spanish' },\n },\n ],\n },\n fields,\n selectedLocales,\n })\n\n expect(result.layout).toHaveLength(1)\n expect(result.layout[0].blockType).toBe('content')\n expect(result.layout[0].id).toBe('ref123')\n expect(result.layout[0].body).toEqual({ en: 'English' })\n })\n })\n\n describe('simple fields', () => {\n it('should filter localized field values to selected locales', () => {\n const fields: Field[] = [\n {\n name: 'title',\n type: 'text',\n localized: true,\n },\n ]\n\n const docWithLocales = {\n title: {\n en: 'English Title',\n es: 'Spanish Title',\n de: 'German Title',\n },\n }\n\n const result = filterDataToSelectedLocales({\n configBlockReferences: [],\n docWithLocales,\n fields,\n selectedLocales,\n })\n\n expect(result.title).toEqual({ en: 'English Title' })\n })\n\n it('should pass through non-localized fields as-is', () => {\n const fields: Field[] = [\n {\n name: 'slug',\n type: 'text',\n },\n ]\n\n const docWithLocales = {\n slug: 'my-slug',\n }\n\n const result = filterDataToSelectedLocales({\n configBlockReferences: [],\n docWithLocales,\n fields,\n selectedLocales,\n })\n\n expect(result.slug).toBe('my-slug')\n })\n })\n})\n"],"names":["describe","expect","it","filterDataToSelectedLocales","selectedLocales","configBlockReferences","fields","name","type","blocks","slug","localized","docWithLocales","layout","blockType","id","blockName","richText","en","es","result","toHaveLength","toBe","toEqual","text","blockReferences","body","title","de"],"mappings":"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"}
1
+ {"version":3,"sources":["../../src/utilities/filterDataToSelectedLocales.spec.ts"],"sourcesContent":["import type { Field } from '../fields/config/types.js'\n\nimport { describe, expect, it } from 'vitest'\n\nimport { filterDataToSelectedLocales } from './filterDataToSelectedLocales.js'\n\ndescribe('filterDataToSelectedLocales', () => {\n const selectedLocales = ['en']\n const configBlockReferences = []\n\n describe('block metadata preservation', () => {\n it('should preserve blockType, id, and blockName on non-localized blocks', () => {\n const fields: Field[] = [\n {\n name: 'layout',\n type: 'blocks',\n blocks: [\n {\n slug: 'content',\n fields: [\n {\n name: 'richText',\n type: 'richText',\n localized: true,\n },\n ],\n },\n ],\n },\n ]\n\n const docWithLocales = {\n layout: [\n {\n blockType: 'content',\n id: 'abc123',\n blockName: 'My Block',\n richText: { en: 'English', es: 'Spanish' },\n },\n ],\n }\n\n const result = filterDataToSelectedLocales({\n configBlockReferences: [],\n docWithLocales,\n fields,\n selectedLocales,\n })\n\n expect(result.layout).toHaveLength(1)\n expect(result.layout[0].blockType).toBe('content')\n expect(result.layout[0].id).toBe('abc123')\n expect(result.layout[0].blockName).toBe('My Block')\n expect(result.layout[0].richText).toEqual({ en: 'English' })\n })\n\n it('should preserve blockType and id when block has no blockName', () => {\n const fields: Field[] = [\n {\n name: 'layout',\n type: 'blocks',\n blocks: [\n {\n slug: 'text',\n fields: [\n {\n name: 'text',\n type: 'text',\n localized: true,\n },\n ],\n },\n ],\n },\n ]\n\n const docWithLocales = {\n layout: [\n {\n blockType: 'text',\n id: 'def456',\n text: { en: 'English', es: 'Spanish' },\n },\n ],\n }\n\n const result = filterDataToSelectedLocales({\n configBlockReferences: [],\n docWithLocales,\n fields,\n selectedLocales,\n })\n\n expect(result.layout).toHaveLength(1)\n expect(result.layout[0].blockType).toBe('text')\n expect(result.layout[0].id).toBe('def456')\n expect(result.layout[0].text).toEqual({ en: 'English' })\n })\n\n it('should preserve blockType and id with configBlockReferences', () => {\n const fields: Field[] = [\n {\n name: 'layout',\n type: 'blocks',\n blocks: [],\n blockReferences: ['content'],\n },\n ]\n\n const result = filterDataToSelectedLocales({\n configBlockReferences: [\n {\n slug: 'content',\n flattenedFields: [],\n fields: [\n {\n name: 'body',\n type: 'text',\n localized: true,\n },\n ],\n },\n ],\n docWithLocales: {\n layout: [\n {\n blockType: 'content',\n id: 'ref123',\n body: { en: 'English', es: 'Spanish' },\n },\n ],\n },\n fields,\n selectedLocales,\n })\n\n expect(result.layout).toHaveLength(1)\n expect(result.layout[0].blockType).toBe('content')\n expect(result.layout[0].id).toBe('ref123')\n expect(result.layout[0].body).toEqual({ en: 'English' })\n })\n })\n\n describe('localized arrays', () => {\n it('should filter localized array to selected locales and recurse into rows', () => {\n const fields: Field[] = [\n {\n name: 'items',\n type: 'array',\n localized: true,\n fields: [\n {\n name: 'title',\n type: 'text',\n },\n ],\n },\n ]\n\n const docWithLocales = {\n items: {\n en: [{ title: 'English Item' }],\n es: [{ title: 'Spanish Item' }],\n de: [{ title: 'German Item' }],\n },\n }\n\n const result = filterDataToSelectedLocales({\n configBlockReferences: [],\n docWithLocales,\n fields,\n selectedLocales,\n })\n\n expect(result.items).toEqual({\n en: [{ title: 'English Item' }],\n })\n })\n\n it('should handle non-localized array with localized children', () => {\n const fields: Field[] = [\n {\n name: 'items',\n type: 'array',\n fields: [\n {\n name: 'label',\n type: 'text',\n localized: true,\n },\n {\n name: 'value',\n type: 'text',\n },\n ],\n },\n ]\n\n const docWithLocales = {\n items: [\n { label: { en: 'English', es: 'Spanish' }, value: 'one' },\n { label: { en: 'English 2', es: 'Spanish 2' }, value: 'two' },\n ],\n }\n\n const result = filterDataToSelectedLocales({\n configBlockReferences: [],\n docWithLocales,\n fields,\n selectedLocales,\n })\n\n expect(result.items).toEqual([\n { label: { en: 'English' }, value: 'one' },\n { label: { en: 'English 2' }, value: 'two' },\n ])\n })\n })\n\n describe('localized blocks', () => {\n it('should filter localized blocks field to selected locales', () => {\n const fields: Field[] = [\n {\n name: 'layout',\n type: 'blocks',\n localized: true,\n blocks: [\n {\n slug: 'hero',\n fields: [\n {\n name: 'heading',\n type: 'text',\n },\n ],\n },\n ],\n },\n ]\n\n const docWithLocales = {\n layout: {\n en: [{ blockType: 'hero', id: '1', blockName: 'Hero EN', heading: 'Hello' }],\n es: [{ blockType: 'hero', id: '2', blockName: 'Hero ES', heading: 'Hola' }],\n de: [{ blockType: 'hero', id: '3', blockName: 'Hero DE', heading: 'Hallo' }],\n },\n }\n\n const result = filterDataToSelectedLocales({\n configBlockReferences: [],\n docWithLocales,\n fields,\n selectedLocales,\n })\n\n expect(result.layout).toEqual({\n en: [{ blockType: 'hero', id: '1', blockName: 'Hero EN', heading: 'Hello' }],\n })\n })\n\n it('should filter localized blocks with multiple selected locales', () => {\n const fields: Field[] = [\n {\n name: 'layout',\n type: 'blocks',\n localized: true,\n blocks: [\n {\n slug: 'text',\n fields: [\n {\n name: 'body',\n type: 'text',\n },\n ],\n },\n ],\n },\n ]\n\n const docWithLocales = {\n layout: {\n en: [{ blockType: 'text', id: '1', blockName: 'Text EN', body: 'English' }],\n es: [{ blockType: 'text', id: '2', blockName: 'Text ES', body: 'Spanish' }],\n de: [{ blockType: 'text', id: '3', blockName: 'Text DE', body: 'German' }],\n },\n }\n\n const result = filterDataToSelectedLocales({\n configBlockReferences: [],\n docWithLocales,\n fields,\n selectedLocales: ['en', 'es'],\n })\n\n expect(result.layout).toEqual({\n en: [{ blockType: 'text', id: '1', blockName: 'Text EN', body: 'English' }],\n es: [{ blockType: 'text', id: '2', blockName: 'Text ES', body: 'Spanish' }],\n })\n })\n })\n\n describe('localized groups', () => {\n it('should filter localized group to selected locales and recurse into children', () => {\n const fields: Field[] = [\n {\n name: 'meta',\n type: 'group',\n localized: true,\n fields: [\n {\n name: 'title',\n type: 'text',\n },\n {\n name: 'description',\n type: 'text',\n },\n ],\n },\n ]\n\n const docWithLocales = {\n meta: {\n en: { title: 'English Title', description: 'English Desc' },\n es: { title: 'Spanish Title', description: 'Spanish Desc' },\n de: { title: 'German Title', description: 'German Desc' },\n },\n }\n\n const result = filterDataToSelectedLocales({\n configBlockReferences: [],\n docWithLocales,\n fields,\n selectedLocales,\n })\n\n expect(result.meta).toEqual({\n en: { title: 'English Title', description: 'English Desc' },\n })\n })\n\n it('should handle non-localized group with localized children', () => {\n const fields: Field[] = [\n {\n name: 'seo',\n type: 'group',\n fields: [\n {\n name: 'title',\n type: 'text',\n localized: true,\n },\n {\n name: 'slug',\n type: 'text',\n },\n ],\n },\n ]\n\n const docWithLocales = {\n seo: {\n title: { en: 'English SEO', es: 'Spanish SEO' },\n slug: 'my-page',\n },\n }\n\n const result = filterDataToSelectedLocales({\n configBlockReferences: [],\n docWithLocales,\n fields,\n selectedLocales,\n })\n\n expect(result.seo).toEqual({\n title: { en: 'English SEO' },\n slug: 'my-page',\n })\n })\n })\n\n describe('simple fields', () => {\n it('should filter localized field values to selected locales', () => {\n const fields: Field[] = [\n {\n name: 'title',\n type: 'text',\n localized: true,\n },\n ]\n\n const docWithLocales = {\n title: {\n en: 'English Title',\n es: 'Spanish Title',\n de: 'German Title',\n },\n }\n\n const result = filterDataToSelectedLocales({\n configBlockReferences: [],\n docWithLocales,\n fields,\n selectedLocales,\n })\n\n expect(result.title).toEqual({ en: 'English Title' })\n })\n\n it('should pass through non-localized fields as-is', () => {\n const fields: Field[] = [\n {\n name: 'slug',\n type: 'text',\n },\n ]\n\n const docWithLocales = {\n slug: 'my-slug',\n }\n\n const result = filterDataToSelectedLocales({\n configBlockReferences: [],\n docWithLocales,\n fields,\n selectedLocales,\n })\n\n expect(result.slug).toBe('my-slug')\n })\n })\n})\n"],"names":["describe","expect","it","filterDataToSelectedLocales","selectedLocales","configBlockReferences","fields","name","type","blocks","slug","localized","docWithLocales","layout","blockType","id","blockName","richText","en","es","result","toHaveLength","toBe","toEqual","text","blockReferences","flattenedFields","body","items","title","de","label","value","heading","meta","description","seo"],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  import type { ErrorResult } from '../config/types.js';
2
- import type { APIError } from '../errors/APIError.js';
2
+ import { APIError } from '../errors/APIError.js';
3
3
  export declare const formatErrors: (incoming: {
4
4
  [key: string]: unknown;
5
5
  } | APIError) => ErrorResult;
@@ -1 +1 @@
1
- {"version":3,"file":"formatErrors.d.ts","sourceRoot":"","sources":["../../src/utilities/formatErrors.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAA;AACrD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAA;AAKrD,eAAO,MAAM,YAAY,aAAc;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;CAAE,GAAG,QAAQ,KAAG,WA8D9E,CAAA"}
1
+ {"version":3,"file":"formatErrors.d.ts","sourceRoot":"","sources":["../../src/utilities/formatErrors.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAA;AAErD,OAAO,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAA;AAGhD,eAAO,MAAM,YAAY,aAAc;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;CAAE,GAAG,QAAQ,KAAG,WA4D9E,CAAA"}
@@ -1,12 +1,9 @@
1
- import { APIErrorName } from '../errors/APIError.js';
2
- import { ValidationErrorName } from '../errors/ValidationError.js';
1
+ import { APIError } from '../errors/APIError.js';
2
+ import { ValidationError } from '../errors/ValidationError.js';
3
3
  export const formatErrors = (incoming)=>{
4
4
  if (incoming) {
5
- // Cannot use `instanceof` to check error type: https://github.com/microsoft/TypeScript/issues/13965
6
- // Instead, get the prototype of the incoming error and check its constructor name
7
- const proto = Object.getPrototypeOf(incoming);
8
5
  // Payload 'ValidationError' and 'APIError'
9
- if ((proto.constructor.name === ValidationErrorName || proto.constructor.name === APIErrorName) && incoming.data) {
6
+ if ((incoming instanceof ValidationError || incoming instanceof APIError) && incoming.data) {
10
7
  return {
11
8
  errors: [
12
9
  {
@@ -18,7 +15,7 @@ export const formatErrors = (incoming)=>{
18
15
  };
19
16
  }
20
17
  // Mongoose 'ValidationError': https://mongoosejs.com/docs/api/error.html#Error.ValidationError
21
- if (proto.constructor.name === ValidationErrorName && 'errors' in incoming && incoming.errors) {
18
+ if ('name' in incoming && incoming.name === 'ValidationError' && 'errors' in incoming && incoming.errors) {
22
19
  return {
23
20
  errors: Object.keys(incoming.errors).reduce((acc, key)=>{
24
21
  acc.push({
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/utilities/formatErrors.ts"],"sourcesContent":["import type { ErrorResult } from '../config/types.js'\nimport type { APIError } from '../errors/APIError.js'\n\nimport { APIErrorName } from '../errors/APIError.js'\nimport { ValidationErrorName } from '../errors/ValidationError.js'\n\nexport const formatErrors = (incoming: { [key: string]: unknown } | APIError): ErrorResult => {\n if (incoming) {\n // Cannot use `instanceof` to check error type: https://github.com/microsoft/TypeScript/issues/13965\n // Instead, get the prototype of the incoming error and check its constructor name\n const proto = Object.getPrototypeOf(incoming)\n\n // Payload 'ValidationError' and 'APIError'\n if (\n (proto.constructor.name === ValidationErrorName || proto.constructor.name === APIErrorName) &&\n incoming.data\n ) {\n return {\n errors: [\n {\n name: incoming.name as string,\n data: incoming.data as Record<string, unknown>,\n message: incoming.message as string,\n },\n ],\n }\n }\n\n // Mongoose 'ValidationError': https://mongoosejs.com/docs/api/error.html#Error.ValidationError\n if (proto.constructor.name === ValidationErrorName && 'errors' in incoming && incoming.errors) {\n return {\n errors: Object.keys(incoming.errors).reduce(\n (acc, key) => {\n acc.push({\n field: (incoming.errors as any)[key].path,\n message: (incoming.errors as any)[key].message,\n })\n return acc\n },\n [] as { field: string; message: string }[],\n ),\n }\n }\n\n if (Array.isArray(incoming.message)) {\n return {\n errors: incoming.message,\n }\n }\n\n if (incoming.name) {\n return {\n errors: [\n {\n message: incoming.message as string,\n },\n ],\n }\n }\n }\n\n return {\n errors: [\n {\n message: 'An unknown error occurred.',\n },\n ],\n }\n}\n"],"names":["APIErrorName","ValidationErrorName","formatErrors","incoming","proto","Object","getPrototypeOf","name","data","errors","message","keys","reduce","acc","key","push","field","path","Array","isArray"],"mappings":"AAGA,SAASA,YAAY,QAAQ,wBAAuB;AACpD,SAASC,mBAAmB,QAAQ,+BAA8B;AAElE,OAAO,MAAMC,eAAe,CAACC;IAC3B,IAAIA,UAAU;QACZ,oGAAoG;QACpG,kFAAkF;QAClF,MAAMC,QAAQC,OAAOC,cAAc,CAACH;QAEpC,2CAA2C;QAC3C,IACE,AAACC,CAAAA,MAAM,WAAW,CAACG,IAAI,KAAKN,uBAAuBG,MAAM,WAAW,CAACG,IAAI,KAAKP,YAAW,KACzFG,SAASK,IAAI,EACb;YACA,OAAO;gBACLC,QAAQ;oBACN;wBACEF,MAAMJ,SAASI,IAAI;wBACnBC,MAAML,SAASK,IAAI;wBACnBE,SAASP,SAASO,OAAO;oBAC3B;iBACD;YACH;QACF;QAEA,+FAA+F;QAC/F,IAAIN,MAAM,WAAW,CAACG,IAAI,KAAKN,uBAAuB,YAAYE,YAAYA,SAASM,MAAM,EAAE;YAC7F,OAAO;gBACLA,QAAQJ,OAAOM,IAAI,CAACR,SAASM,MAAM,EAAEG,MAAM,CACzC,CAACC,KAAKC;oBACJD,IAAIE,IAAI,CAAC;wBACPC,OAAO,AAACb,SAASM,MAAM,AAAQ,CAACK,IAAI,CAACG,IAAI;wBACzCP,SAAS,AAACP,SAASM,MAAM,AAAQ,CAACK,IAAI,CAACJ,OAAO;oBAChD;oBACA,OAAOG;gBACT,GACA,EAAE;YAEN;QACF;QAEA,IAAIK,MAAMC,OAAO,CAAChB,SAASO,OAAO,GAAG;YACnC,OAAO;gBACLD,QAAQN,SAASO,OAAO;YAC1B;QACF;QAEA,IAAIP,SAASI,IAAI,EAAE;YACjB,OAAO;gBACLE,QAAQ;oBACN;wBACEC,SAASP,SAASO,OAAO;oBAC3B;iBACD;YACH;QACF;IACF;IAEA,OAAO;QACLD,QAAQ;YACN;gBACEC,SAAS;YACX;SACD;IACH;AACF,EAAC"}
1
+ {"version":3,"sources":["../../src/utilities/formatErrors.ts"],"sourcesContent":["import type { ErrorResult } from '../config/types.js'\n\nimport { APIError } from '../errors/APIError.js'\nimport { ValidationError } from '../errors/ValidationError.js'\n\nexport const formatErrors = (incoming: { [key: string]: unknown } | APIError): ErrorResult => {\n if (incoming) {\n // Payload 'ValidationError' and 'APIError'\n if ((incoming instanceof ValidationError || incoming instanceof APIError) && incoming.data) {\n return {\n errors: [\n {\n name: incoming.name,\n data: incoming.data as Record<string, unknown>,\n message: incoming.message,\n },\n ],\n }\n }\n\n // Mongoose 'ValidationError': https://mongoosejs.com/docs/api/error.html#Error.ValidationError\n if (\n 'name' in incoming &&\n incoming.name === 'ValidationError' &&\n 'errors' in incoming &&\n incoming.errors\n ) {\n return {\n errors: Object.keys(incoming.errors).reduce(\n (acc, key) => {\n acc.push({\n field: (incoming.errors as any)[key].path,\n message: (incoming.errors as any)[key].message,\n })\n return acc\n },\n [] as { field: string; message: string }[],\n ),\n }\n }\n\n if (Array.isArray(incoming.message)) {\n return {\n errors: incoming.message,\n }\n }\n\n if (incoming.name) {\n return {\n errors: [\n {\n message: incoming.message as string,\n },\n ],\n }\n }\n }\n\n return {\n errors: [\n {\n message: 'An unknown error occurred.',\n },\n ],\n }\n}\n"],"names":["APIError","ValidationError","formatErrors","incoming","data","errors","name","message","Object","keys","reduce","acc","key","push","field","path","Array","isArray"],"mappings":"AAEA,SAASA,QAAQ,QAAQ,wBAAuB;AAChD,SAASC,eAAe,QAAQ,+BAA8B;AAE9D,OAAO,MAAMC,eAAe,CAACC;IAC3B,IAAIA,UAAU;QACZ,2CAA2C;QAC3C,IAAI,AAACA,CAAAA,oBAAoBF,mBAAmBE,oBAAoBH,QAAO,KAAMG,SAASC,IAAI,EAAE;YAC1F,OAAO;gBACLC,QAAQ;oBACN;wBACEC,MAAMH,SAASG,IAAI;wBACnBF,MAAMD,SAASC,IAAI;wBACnBG,SAASJ,SAASI,OAAO;oBAC3B;iBACD;YACH;QACF;QAEA,+FAA+F;QAC/F,IACE,UAAUJ,YACVA,SAASG,IAAI,KAAK,qBAClB,YAAYH,YACZA,SAASE,MAAM,EACf;YACA,OAAO;gBACLA,QAAQG,OAAOC,IAAI,CAACN,SAASE,MAAM,EAAEK,MAAM,CACzC,CAACC,KAAKC;oBACJD,IAAIE,IAAI,CAAC;wBACPC,OAAO,AAACX,SAASE,MAAM,AAAQ,CAACO,IAAI,CAACG,IAAI;wBACzCR,SAAS,AAACJ,SAASE,MAAM,AAAQ,CAACO,IAAI,CAACL,OAAO;oBAChD;oBACA,OAAOI;gBACT,GACA,EAAE;YAEN;QACF;QAEA,IAAIK,MAAMC,OAAO,CAACd,SAASI,OAAO,GAAG;YACnC,OAAO;gBACLF,QAAQF,SAASI,OAAO;YAC1B;QACF;QAEA,IAAIJ,SAASG,IAAI,EAAE;YACjB,OAAO;gBACLD,QAAQ;oBACN;wBACEE,SAASJ,SAASI,OAAO;oBAC3B;iBACD;YACH;QACF;IACF;IAEA,OAAO;QACLF,QAAQ;YACN;gBACEE,SAAS;YACX;SACD;IACH;AACF,EAAC"}
@@ -0,0 +1,101 @@
1
+ import { describe, expect, it } from 'vitest';
2
+ import { APIError } from '../errors/APIError.js';
3
+ import { ValidationError } from '../errors/ValidationError.js';
4
+ import { formatErrors } from './formatErrors.js';
5
+ describe('formatErrors', ()=>{
6
+ it('should format a Payload ValidationError', ()=>{
7
+ const err = new ValidationError({
8
+ errors: [
9
+ {
10
+ message: 'Field is required',
11
+ path: 'title'
12
+ }
13
+ ]
14
+ });
15
+ const result = formatErrors(err);
16
+ expect(result.errors).toHaveLength(1);
17
+ expect(result.errors[0]).toMatchObject({
18
+ name: 'ValidationError',
19
+ message: expect.stringContaining('title'),
20
+ data: {
21
+ errors: [
22
+ {
23
+ message: 'Field is required',
24
+ path: 'title'
25
+ }
26
+ ]
27
+ }
28
+ });
29
+ });
30
+ it('should format a Payload APIError', ()=>{
31
+ const err = new APIError('Something went wrong', 400, {
32
+ detail: 'bad input'
33
+ }, true);
34
+ const result = formatErrors(err);
35
+ expect(result.errors).toHaveLength(1);
36
+ expect(result.errors[0]).toMatchObject({
37
+ name: 'APIError',
38
+ message: 'Something went wrong',
39
+ data: {
40
+ detail: 'bad input'
41
+ }
42
+ });
43
+ });
44
+ it('should format a Mongoose-style ValidationError', ()=>{
45
+ const mongooseError = {
46
+ name: 'ValidationError',
47
+ errors: {
48
+ email: {
49
+ path: 'email',
50
+ message: 'is invalid'
51
+ }
52
+ }
53
+ };
54
+ const result = formatErrors(mongooseError);
55
+ expect(result.errors).toHaveLength(1);
56
+ expect(result.errors[0]).toMatchObject({
57
+ field: 'email',
58
+ message: 'is invalid'
59
+ });
60
+ });
61
+ it('should format an array message error', ()=>{
62
+ const err = {
63
+ message: [
64
+ {
65
+ message: 'item one'
66
+ },
67
+ {
68
+ message: 'item two'
69
+ }
70
+ ]
71
+ };
72
+ const result = formatErrors(err);
73
+ expect(result.errors).toHaveLength(2);
74
+ expect(result.errors[0]).toMatchObject({
75
+ message: 'item one'
76
+ });
77
+ expect(result.errors[1]).toMatchObject({
78
+ message: 'item two'
79
+ });
80
+ });
81
+ it('should format a named non-Payload error', ()=>{
82
+ const err = new Error('Unexpected failure');
83
+ const result = formatErrors(err);
84
+ expect(result.errors).toHaveLength(1);
85
+ expect(result.errors[0].message).toBe('Unexpected failure');
86
+ });
87
+ it('should format a Payload APIError with no data', ()=>{
88
+ const err = new APIError('Server error');
89
+ const result = formatErrors(err);
90
+ expect(result.errors).toHaveLength(1);
91
+ expect(result.errors[0]).toStrictEqual({
92
+ message: 'Server error'
93
+ });
94
+ });
95
+ it('should return unknown error for null/undefined input', ()=>{
96
+ expect(formatErrors(null).errors[0].message).toBe('An unknown error occurred.');
97
+ expect(formatErrors(undefined).errors[0].message).toBe('An unknown error occurred.');
98
+ });
99
+ });
100
+
101
+ //# sourceMappingURL=formatErrors.spec.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/utilities/formatErrors.spec.ts"],"sourcesContent":["import { describe, expect, it } from 'vitest'\n\nimport { APIError } from '../errors/APIError.js'\nimport { ValidationError } from '../errors/ValidationError.js'\nimport { formatErrors } from './formatErrors.js'\n\ndescribe('formatErrors', () => {\n it('should format a Payload ValidationError', () => {\n const err = new ValidationError({\n errors: [{ message: 'Field is required', path: 'title' }],\n })\n\n const result = formatErrors(err)\n\n expect(result.errors).toHaveLength(1)\n expect(result.errors[0]).toMatchObject({\n name: 'ValidationError',\n message: expect.stringContaining('title'),\n data: { errors: [{ message: 'Field is required', path: 'title' }] },\n })\n })\n\n it('should format a Payload APIError', () => {\n const err = new APIError('Something went wrong', 400, { detail: 'bad input' }, true)\n\n const result = formatErrors(err)\n\n expect(result.errors).toHaveLength(1)\n expect(result.errors[0]).toMatchObject({\n name: 'APIError',\n message: 'Something went wrong',\n data: { detail: 'bad input' },\n })\n })\n\n it('should format a Mongoose-style ValidationError', () => {\n const mongooseError = {\n name: 'ValidationError',\n errors: {\n email: { path: 'email', message: 'is invalid' },\n },\n }\n\n const result = formatErrors(mongooseError as any)\n\n expect(result.errors).toHaveLength(1)\n expect(result.errors[0]).toMatchObject({ field: 'email', message: 'is invalid' })\n })\n\n it('should format an array message error', () => {\n const err = { message: [{ message: 'item one' }, { message: 'item two' }] }\n\n const result = formatErrors(err as any)\n\n expect(result.errors).toHaveLength(2)\n expect(result.errors[0]).toMatchObject({ message: 'item one' })\n expect(result.errors[1]).toMatchObject({ message: 'item two' })\n })\n\n it('should format a named non-Payload error', () => {\n const err = new Error('Unexpected failure')\n\n const result = formatErrors(err as any)\n\n expect(result.errors).toHaveLength(1)\n expect(result.errors[0]!.message).toBe('Unexpected failure')\n })\n\n it('should format a Payload APIError with no data', () => {\n const err = new APIError('Server error')\n\n const result = formatErrors(err)\n\n expect(result.errors).toHaveLength(1)\n expect(result.errors[0]).toStrictEqual({ message: 'Server error' })\n })\n\n it('should return unknown error for null/undefined input', () => {\n expect(formatErrors(null as any).errors[0]!.message).toBe('An unknown error occurred.')\n expect(formatErrors(undefined as any).errors[0]!.message).toBe('An unknown error occurred.')\n })\n})\n"],"names":["describe","expect","it","APIError","ValidationError","formatErrors","err","errors","message","path","result","toHaveLength","toMatchObject","name","stringContaining","data","detail","mongooseError","email","field","Error","toBe","toStrictEqual","undefined"],"mappings":"AAAA,SAASA,QAAQ,EAAEC,MAAM,EAAEC,EAAE,QAAQ,SAAQ;AAE7C,SAASC,QAAQ,QAAQ,wBAAuB;AAChD,SAASC,eAAe,QAAQ,+BAA8B;AAC9D,SAASC,YAAY,QAAQ,oBAAmB;AAEhDL,SAAS,gBAAgB;IACvBE,GAAG,2CAA2C;QAC5C,MAAMI,MAAM,IAAIF,gBAAgB;YAC9BG,QAAQ;gBAAC;oBAAEC,SAAS;oBAAqBC,MAAM;gBAAQ;aAAE;QAC3D;QAEA,MAAMC,SAASL,aAAaC;QAE5BL,OAAOS,OAAOH,MAAM,EAAEI,YAAY,CAAC;QACnCV,OAAOS,OAAOH,MAAM,CAAC,EAAE,EAAEK,aAAa,CAAC;YACrCC,MAAM;YACNL,SAASP,OAAOa,gBAAgB,CAAC;YACjCC,MAAM;gBAAER,QAAQ;oBAAC;wBAAEC,SAAS;wBAAqBC,MAAM;oBAAQ;iBAAE;YAAC;QACpE;IACF;IAEAP,GAAG,oCAAoC;QACrC,MAAMI,MAAM,IAAIH,SAAS,wBAAwB,KAAK;YAAEa,QAAQ;QAAY,GAAG;QAE/E,MAAMN,SAASL,aAAaC;QAE5BL,OAAOS,OAAOH,MAAM,EAAEI,YAAY,CAAC;QACnCV,OAAOS,OAAOH,MAAM,CAAC,EAAE,EAAEK,aAAa,CAAC;YACrCC,MAAM;YACNL,SAAS;YACTO,MAAM;gBAAEC,QAAQ;YAAY;QAC9B;IACF;IAEAd,GAAG,kDAAkD;QACnD,MAAMe,gBAAgB;YACpBJ,MAAM;YACNN,QAAQ;gBACNW,OAAO;oBAAET,MAAM;oBAASD,SAAS;gBAAa;YAChD;QACF;QAEA,MAAME,SAASL,aAAaY;QAE5BhB,OAAOS,OAAOH,MAAM,EAAEI,YAAY,CAAC;QACnCV,OAAOS,OAAOH,MAAM,CAAC,EAAE,EAAEK,aAAa,CAAC;YAAEO,OAAO;YAASX,SAAS;QAAa;IACjF;IAEAN,GAAG,wCAAwC;QACzC,MAAMI,MAAM;YAAEE,SAAS;gBAAC;oBAAEA,SAAS;gBAAW;gBAAG;oBAAEA,SAAS;gBAAW;aAAE;QAAC;QAE1E,MAAME,SAASL,aAAaC;QAE5BL,OAAOS,OAAOH,MAAM,EAAEI,YAAY,CAAC;QACnCV,OAAOS,OAAOH,MAAM,CAAC,EAAE,EAAEK,aAAa,CAAC;YAAEJ,SAAS;QAAW;QAC7DP,OAAOS,OAAOH,MAAM,CAAC,EAAE,EAAEK,aAAa,CAAC;YAAEJ,SAAS;QAAW;IAC/D;IAEAN,GAAG,2CAA2C;QAC5C,MAAMI,MAAM,IAAIc,MAAM;QAEtB,MAAMV,SAASL,aAAaC;QAE5BL,OAAOS,OAAOH,MAAM,EAAEI,YAAY,CAAC;QACnCV,OAAOS,OAAOH,MAAM,CAAC,EAAE,CAAEC,OAAO,EAAEa,IAAI,CAAC;IACzC;IAEAnB,GAAG,iDAAiD;QAClD,MAAMI,MAAM,IAAIH,SAAS;QAEzB,MAAMO,SAASL,aAAaC;QAE5BL,OAAOS,OAAOH,MAAM,EAAEI,YAAY,CAAC;QACnCV,OAAOS,OAAOH,MAAM,CAAC,EAAE,EAAEe,aAAa,CAAC;YAAEd,SAAS;QAAe;IACnE;IAEAN,GAAG,wDAAwD;QACzDD,OAAOI,aAAa,MAAaE,MAAM,CAAC,EAAE,CAAEC,OAAO,EAAEa,IAAI,CAAC;QAC1DpB,OAAOI,aAAakB,WAAkBhB,MAAM,CAAC,EAAE,CAAEC,OAAO,EAAEa,IAAI,CAAC;IACjE;AACF"}
@@ -1 +1 @@
1
- {"version":3,"file":"isURLAllowed.d.ts","sourceRoot":"","sources":["../../src/utilities/isURLAllowed.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAA;AAEpD,eAAO,MAAM,YAAY,QAAS,MAAM,aAAa,SAAS,KAAG,OAgChE,CAAA"}
1
+ {"version":3,"file":"isURLAllowed.d.ts","sourceRoot":"","sources":["../../src/utilities/isURLAllowed.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAA;AAIpD,eAAO,MAAM,YAAY,QAAS,MAAM,aAAa,SAAS,KAAG,OAqChE,CAAA"}
@@ -1,3 +1,4 @@
1
+ import { escapeRegExp } from './escapeRegExp.js';
1
2
  export const isURLAllowed = (url, allowList)=>{
2
3
  try {
3
4
  const parsedUrl = new URL(url);
@@ -12,9 +13,14 @@ export const isURLAllowed = (url, allowList)=>{
12
13
  return typeof value === 'string' && parsedUrl.protocol === `${value}:`;
13
14
  }
14
15
  if (key === 'pathname') {
15
- // Convert wildcards to a regex
16
- const regexPattern = value.replace(/\*\*/g, '.*') // Match any path
17
- .replace(/\*/g, '[^/]*') // Match any part of a path segment
16
+ // Translate a small glob syntax to a regex. The pattern is escaped
17
+ // first so that metacharacters in the configured value (e.g. `.`)
18
+ // match literally and cannot broaden what the allow-list accepts.
19
+ // Wildcards become `\*` once escaped, so they are restored afterwards
20
+ // — translating `**` before `*` is safe because the resulting `.*`
21
+ // no longer contains an escaped `\*` for the next replace to match.
22
+ const regexPattern = escapeRegExp(value).replace(/\\\*\\\*/g, '.*') // `**` → match any path
23
+ .replace(/\\\*/g, '[^/]*') // `*` → match any part of a path segment
18
24
  .replace(/\/$/, '(/)?') // Allow optional trailing slash
19
25
  ;
20
26
  const regex = new RegExp(`^${regexPattern}$`);
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/utilities/isURLAllowed.ts"],"sourcesContent":["import type { AllowList } from '../uploads/types.js'\n\nexport const isURLAllowed = (url: string, allowList: AllowList): boolean => {\n try {\n const parsedUrl = new URL(url)\n\n return allowList.some((allowItem) => {\n return Object.entries(allowItem).every(([key, value]) => {\n // Skip undefined or null values\n if (!value) {\n return true\n }\n // Compare protocol with colon\n if (key === 'protocol') {\n return typeof value === 'string' && parsedUrl.protocol === `${value}:`\n }\n\n if (key === 'pathname') {\n // Convert wildcards to a regex\n const regexPattern = value\n .replace(/\\*\\*/g, '.*') // Match any path\n .replace(/\\*/g, '[^/]*') // Match any part of a path segment\n .replace(/\\/$/, '(/)?') // Allow optional trailing slash\n const regex = new RegExp(`^${regexPattern}$`)\n return regex.test(parsedUrl.pathname)\n }\n\n // Default comparison for all other properties (hostname, port, search)\n return parsedUrl[key as keyof URL] === value\n })\n })\n } catch {\n return false // If the URL is invalid, deny by default\n }\n}\n"],"names":["isURLAllowed","url","allowList","parsedUrl","URL","some","allowItem","Object","entries","every","key","value","protocol","regexPattern","replace","regex","RegExp","test","pathname"],"mappings":"AAEA,OAAO,MAAMA,eAAe,CAACC,KAAaC;IACxC,IAAI;QACF,MAAMC,YAAY,IAAIC,IAAIH;QAE1B,OAAOC,UAAUG,IAAI,CAAC,CAACC;YACrB,OAAOC,OAAOC,OAAO,CAACF,WAAWG,KAAK,CAAC,CAAC,CAACC,KAAKC,MAAM;gBAClD,gCAAgC;gBAChC,IAAI,CAACA,OAAO;oBACV,OAAO;gBACT;gBACA,8BAA8B;gBAC9B,IAAID,QAAQ,YAAY;oBACtB,OAAO,OAAOC,UAAU,YAAYR,UAAUS,QAAQ,KAAK,GAAGD,MAAM,CAAC,CAAC;gBACxE;gBAEA,IAAID,QAAQ,YAAY;oBACtB,+BAA+B;oBAC/B,MAAMG,eAAeF,MAClBG,OAAO,CAAC,SAAS,MAAM,iBAAiB;qBACxCA,OAAO,CAAC,OAAO,SAAS,mCAAmC;qBAC3DA,OAAO,CAAC,OAAO,QAAQ,gCAAgC;;oBAC1D,MAAMC,QAAQ,IAAIC,OAAO,CAAC,CAAC,EAAEH,aAAa,CAAC,CAAC;oBAC5C,OAAOE,MAAME,IAAI,CAACd,UAAUe,QAAQ;gBACtC;gBAEA,uEAAuE;gBACvE,OAAOf,SAAS,CAACO,IAAiB,KAAKC;YACzC;QACF;IACF,EAAE,OAAM;QACN,OAAO,MAAM,yCAAyC;;IACxD;AACF,EAAC"}
1
+ {"version":3,"sources":["../../src/utilities/isURLAllowed.ts"],"sourcesContent":["import type { AllowList } from '../uploads/types.js'\n\nimport { escapeRegExp } from './escapeRegExp.js'\n\nexport const isURLAllowed = (url: string, allowList: AllowList): boolean => {\n try {\n const parsedUrl = new URL(url)\n\n return allowList.some((allowItem) => {\n return Object.entries(allowItem).every(([key, value]) => {\n // Skip undefined or null values\n if (!value) {\n return true\n }\n // Compare protocol with colon\n if (key === 'protocol') {\n return typeof value === 'string' && parsedUrl.protocol === `${value}:`\n }\n\n if (key === 'pathname') {\n // Translate a small glob syntax to a regex. The pattern is escaped\n // first so that metacharacters in the configured value (e.g. `.`)\n // match literally and cannot broaden what the allow-list accepts.\n // Wildcards become `\\*` once escaped, so they are restored afterwards\n // — translating `**` before `*` is safe because the resulting `.*`\n // no longer contains an escaped `\\*` for the next replace to match.\n const regexPattern = escapeRegExp(value)\n .replace(/\\\\\\*\\\\\\*/g, '.*') // `**` → match any path\n .replace(/\\\\\\*/g, '[^/]*') // `*` → match any part of a path segment\n .replace(/\\/$/, '(/)?') // Allow optional trailing slash\n const regex = new RegExp(`^${regexPattern}$`)\n return regex.test(parsedUrl.pathname)\n }\n\n // Default comparison for all other properties (hostname, port, search)\n return parsedUrl[key as keyof URL] === value\n })\n })\n } catch {\n return false // If the URL is invalid, deny by default\n }\n}\n"],"names":["escapeRegExp","isURLAllowed","url","allowList","parsedUrl","URL","some","allowItem","Object","entries","every","key","value","protocol","regexPattern","replace","regex","RegExp","test","pathname"],"mappings":"AAEA,SAASA,YAAY,QAAQ,oBAAmB;AAEhD,OAAO,MAAMC,eAAe,CAACC,KAAaC;IACxC,IAAI;QACF,MAAMC,YAAY,IAAIC,IAAIH;QAE1B,OAAOC,UAAUG,IAAI,CAAC,CAACC;YACrB,OAAOC,OAAOC,OAAO,CAACF,WAAWG,KAAK,CAAC,CAAC,CAACC,KAAKC,MAAM;gBAClD,gCAAgC;gBAChC,IAAI,CAACA,OAAO;oBACV,OAAO;gBACT;gBACA,8BAA8B;gBAC9B,IAAID,QAAQ,YAAY;oBACtB,OAAO,OAAOC,UAAU,YAAYR,UAAUS,QAAQ,KAAK,GAAGD,MAAM,CAAC,CAAC;gBACxE;gBAEA,IAAID,QAAQ,YAAY;oBACtB,mEAAmE;oBACnE,kEAAkE;oBAClE,kEAAkE;oBAClE,sEAAsE;oBACtE,mEAAmE;oBACnE,oEAAoE;oBACpE,MAAMG,eAAed,aAAaY,OAC/BG,OAAO,CAAC,aAAa,MAAM,wBAAwB;qBACnDA,OAAO,CAAC,SAAS,SAAS,yCAAyC;qBACnEA,OAAO,CAAC,OAAO,QAAQ,gCAAgC;;oBAC1D,MAAMC,QAAQ,IAAIC,OAAO,CAAC,CAAC,EAAEH,aAAa,CAAC,CAAC;oBAC5C,OAAOE,MAAME,IAAI,CAACd,UAAUe,QAAQ;gBACtC;gBAEA,uEAAuE;gBACvE,OAAOf,SAAS,CAACO,IAAiB,KAAKC;YACzC;QACF;IACF,EAAE,OAAM;QACN,OAAO,MAAM,yCAAyC;;IACxD;AACF,EAAC"}
@@ -0,0 +1,78 @@
1
+ import { describe, expect, it } from 'vitest';
2
+ import { isURLAllowed } from './isURLAllowed.js';
3
+ describe('isURLAllowed', ()=>{
4
+ describe('hostname matching', ()=>{
5
+ const allowList = [
6
+ {
7
+ hostname: 'cdn.example.com'
8
+ }
9
+ ];
10
+ it('should allow an exactly matching hostname', ()=>{
11
+ expect(isURLAllowed('https://cdn.example.com/file.png', allowList)).toBe(true);
12
+ });
13
+ it('should deny a different hostname', ()=>{
14
+ expect(isURLAllowed('https://attacker.com/file.png', allowList)).toBe(false);
15
+ });
16
+ it('should deny a userinfo `@` trick (hostname is the real authority)', ()=>{
17
+ expect(isURLAllowed('https://cdn.example.com@attacker.com/file.png', allowList)).toBe(false);
18
+ });
19
+ it('should deny an invalid URL', ()=>{
20
+ expect(isURLAllowed('not a url', allowList)).toBe(false);
21
+ });
22
+ });
23
+ describe('pathname matching', ()=>{
24
+ it('should treat a literal dot as a literal, not a wildcard', ()=>{
25
+ const allowList = [
26
+ {
27
+ hostname: 'cdn.example.com',
28
+ pathname: '/files/report.json'
29
+ }
30
+ ];
31
+ expect(isURLAllowed('https://cdn.example.com/files/report.json', allowList)).toBe(true);
32
+ // Previously the unescaped `.` matched any character, widening the allow-list.
33
+ expect(isURLAllowed('https://cdn.example.com/files/reportXjson', allowList)).toBe(false);
34
+ });
35
+ it('should not let other regex metacharacters broaden the match', ()=>{
36
+ const allowList = [
37
+ {
38
+ hostname: 'cdn.example.com',
39
+ pathname: '/a+b/(c)'
40
+ }
41
+ ];
42
+ expect(isURLAllowed('https://cdn.example.com/a+b/(c)', allowList)).toBe(true);
43
+ expect(isURLAllowed('https://cdn.example.com/aaab/c', allowList)).toBe(false);
44
+ });
45
+ it('should match a single segment with `*` but not across slashes', ()=>{
46
+ const allowList = [
47
+ {
48
+ hostname: 'cdn.example.com',
49
+ pathname: '/uploads/*'
50
+ }
51
+ ];
52
+ expect(isURLAllowed('https://cdn.example.com/uploads/photo.png', allowList)).toBe(true);
53
+ expect(isURLAllowed('https://cdn.example.com/uploads/nested/photo.png', allowList)).toBe(false);
54
+ });
55
+ it('should match across slashes with `**`', ()=>{
56
+ const allowList = [
57
+ {
58
+ hostname: 'cdn.example.com',
59
+ pathname: '/uploads/**'
60
+ }
61
+ ];
62
+ expect(isURLAllowed('https://cdn.example.com/uploads/photo.png', allowList)).toBe(true);
63
+ expect(isURLAllowed('https://cdn.example.com/uploads/nested/photo.png', allowList)).toBe(true);
64
+ });
65
+ it('should allow an optional trailing slash', ()=>{
66
+ const allowList = [
67
+ {
68
+ hostname: 'cdn.example.com',
69
+ pathname: '/assets/'
70
+ }
71
+ ];
72
+ expect(isURLAllowed('https://cdn.example.com/assets', allowList)).toBe(true);
73
+ expect(isURLAllowed('https://cdn.example.com/assets/', allowList)).toBe(true);
74
+ });
75
+ });
76
+ });
77
+
78
+ //# sourceMappingURL=isURLAllowed.spec.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/utilities/isURLAllowed.spec.ts"],"sourcesContent":["import { describe, expect, it } from 'vitest'\n\nimport type { AllowList } from '../uploads/types.js'\n\nimport { isURLAllowed } from './isURLAllowed.js'\n\ndescribe('isURLAllowed', () => {\n describe('hostname matching', () => {\n const allowList: AllowList = [{ hostname: 'cdn.example.com' }]\n\n it('should allow an exactly matching hostname', () => {\n expect(isURLAllowed('https://cdn.example.com/file.png', allowList)).toBe(true)\n })\n\n it('should deny a different hostname', () => {\n expect(isURLAllowed('https://attacker.com/file.png', allowList)).toBe(false)\n })\n\n it('should deny a userinfo `@` trick (hostname is the real authority)', () => {\n expect(isURLAllowed('https://cdn.example.com@attacker.com/file.png', allowList)).toBe(false)\n })\n\n it('should deny an invalid URL', () => {\n expect(isURLAllowed('not a url', allowList)).toBe(false)\n })\n })\n\n describe('pathname matching', () => {\n it('should treat a literal dot as a literal, not a wildcard', () => {\n const allowList: AllowList = [{ hostname: 'cdn.example.com', pathname: '/files/report.json' }]\n\n expect(isURLAllowed('https://cdn.example.com/files/report.json', allowList)).toBe(true)\n // Previously the unescaped `.` matched any character, widening the allow-list.\n expect(isURLAllowed('https://cdn.example.com/files/reportXjson', allowList)).toBe(false)\n })\n\n it('should not let other regex metacharacters broaden the match', () => {\n const allowList: AllowList = [{ hostname: 'cdn.example.com', pathname: '/a+b/(c)' }]\n\n expect(isURLAllowed('https://cdn.example.com/a+b/(c)', allowList)).toBe(true)\n expect(isURLAllowed('https://cdn.example.com/aaab/c', allowList)).toBe(false)\n })\n\n it('should match a single segment with `*` but not across slashes', () => {\n const allowList: AllowList = [{ hostname: 'cdn.example.com', pathname: '/uploads/*' }]\n\n expect(isURLAllowed('https://cdn.example.com/uploads/photo.png', allowList)).toBe(true)\n expect(isURLAllowed('https://cdn.example.com/uploads/nested/photo.png', allowList)).toBe(\n false,\n )\n })\n\n it('should match across slashes with `**`', () => {\n const allowList: AllowList = [{ hostname: 'cdn.example.com', pathname: '/uploads/**' }]\n\n expect(isURLAllowed('https://cdn.example.com/uploads/photo.png', allowList)).toBe(true)\n expect(isURLAllowed('https://cdn.example.com/uploads/nested/photo.png', allowList)).toBe(true)\n })\n\n it('should allow an optional trailing slash', () => {\n const allowList: AllowList = [{ hostname: 'cdn.example.com', pathname: '/assets/' }]\n\n expect(isURLAllowed('https://cdn.example.com/assets', allowList)).toBe(true)\n expect(isURLAllowed('https://cdn.example.com/assets/', allowList)).toBe(true)\n })\n })\n})\n"],"names":["describe","expect","it","isURLAllowed","allowList","hostname","toBe","pathname"],"mappings":"AAAA,SAASA,QAAQ,EAAEC,MAAM,EAAEC,EAAE,QAAQ,SAAQ;AAI7C,SAASC,YAAY,QAAQ,oBAAmB;AAEhDH,SAAS,gBAAgB;IACvBA,SAAS,qBAAqB;QAC5B,MAAMI,YAAuB;YAAC;gBAAEC,UAAU;YAAkB;SAAE;QAE9DH,GAAG,6CAA6C;YAC9CD,OAAOE,aAAa,oCAAoCC,YAAYE,IAAI,CAAC;QAC3E;QAEAJ,GAAG,oCAAoC;YACrCD,OAAOE,aAAa,iCAAiCC,YAAYE,IAAI,CAAC;QACxE;QAEAJ,GAAG,qEAAqE;YACtED,OAAOE,aAAa,iDAAiDC,YAAYE,IAAI,CAAC;QACxF;QAEAJ,GAAG,8BAA8B;YAC/BD,OAAOE,aAAa,aAAaC,YAAYE,IAAI,CAAC;QACpD;IACF;IAEAN,SAAS,qBAAqB;QAC5BE,GAAG,2DAA2D;YAC5D,MAAME,YAAuB;gBAAC;oBAAEC,UAAU;oBAAmBE,UAAU;gBAAqB;aAAE;YAE9FN,OAAOE,aAAa,6CAA6CC,YAAYE,IAAI,CAAC;YAClF,+EAA+E;YAC/EL,OAAOE,aAAa,6CAA6CC,YAAYE,IAAI,CAAC;QACpF;QAEAJ,GAAG,+DAA+D;YAChE,MAAME,YAAuB;gBAAC;oBAAEC,UAAU;oBAAmBE,UAAU;gBAAW;aAAE;YAEpFN,OAAOE,aAAa,mCAAmCC,YAAYE,IAAI,CAAC;YACxEL,OAAOE,aAAa,kCAAkCC,YAAYE,IAAI,CAAC;QACzE;QAEAJ,GAAG,iEAAiE;YAClE,MAAME,YAAuB;gBAAC;oBAAEC,UAAU;oBAAmBE,UAAU;gBAAa;aAAE;YAEtFN,OAAOE,aAAa,6CAA6CC,YAAYE,IAAI,CAAC;YAClFL,OAAOE,aAAa,oDAAoDC,YAAYE,IAAI,CACtF;QAEJ;QAEAJ,GAAG,yCAAyC;YAC1C,MAAME,YAAuB;gBAAC;oBAAEC,UAAU;oBAAmBE,UAAU;gBAAc;aAAE;YAEvFN,OAAOE,aAAa,6CAA6CC,YAAYE,IAAI,CAAC;YAClFL,OAAOE,aAAa,oDAAoDC,YAAYE,IAAI,CAAC;QAC3F;QAEAJ,GAAG,2CAA2C;YAC5C,MAAME,YAAuB;gBAAC;oBAAEC,UAAU;oBAAmBE,UAAU;gBAAW;aAAE;YAEpFN,OAAOE,aAAa,kCAAkCC,YAAYE,IAAI,CAAC;YACvEL,OAAOE,aAAa,mCAAmCC,YAAYE,IAAI,CAAC;QAC1E;IACF;AACF"}
@@ -21,7 +21,7 @@ type RawParams = {
21
21
  sort?: string | string[];
22
22
  trash?: string;
23
23
  unpublishAllLocales?: string;
24
- where?: Where;
24
+ where?: string | Where;
25
25
  };
26
26
  type ParsedParams = {
27
27
  autosave?: boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/utilities/parseParams/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,YAAY,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,sBAAsB,CAAA;AACtF,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAA;AAS1D,KAAK,SAAS,GAAG;IACf,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,KAAK,CAAC,EAAE,UAAU,CAAA;IAClB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,iBAAiB,CAAC,EAAE,MAAM,CAAA;IAC1B,qBAAqB,CAAC,EAAE,MAAM,CAAA;IAC9B,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAA;IACxB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,mBAAmB,CAAC,EAAE,MAAM,CAAA;IAC5B,KAAK,CAAC,EAAE,KAAK,CAAA;CACd,CAAA;AAED,KAAK,YAAY,GAAG;IAClB,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAC9B,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,cAAc,CAAC,EAAE,OAAO,CAAA;IACxB,KAAK,CAAC,EAAE,SAAS,CAAA;IACjB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,YAAY,CAAC,EAAE,OAAO,CAAA;IACtB,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,QAAQ,CAAC,EAAE,YAAY,CAAA;IACvB,iBAAiB,CAAC,EAAE,OAAO,CAAA;IAC3B,qBAAqB,CAAC,EAAE,MAAM,CAAA;IAC9B,MAAM,CAAC,EAAE,UAAU,CAAA;IACnB,eAAe,CAAC,EAAE,MAAM,EAAE,CAAA;IAC1B,IAAI,CAAC,EAAE,MAAM,EAAE,CAAA;IACf,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,mBAAmB,CAAC,EAAE,OAAO,CAAA;IAC7B,KAAK,CAAC,EAAE,KAAK,CAAA;CACd,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;AAE3B,eAAO,MAAM,aAAa,UAOzB,CAAA;AAED,eAAO,MAAM,YAAY,UAA6B,CAAA;AAEtD;;;;;;GAMG;AACH,eAAO,MAAM,WAAW,WAAY,SAAS,KAAG,YAuC/C,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/utilities/parseParams/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,YAAY,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,sBAAsB,CAAA;AACtF,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAA;AAS1D,KAAK,SAAS,GAAG;IACf,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,KAAK,CAAC,EAAE,UAAU,CAAA;IAClB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,iBAAiB,CAAC,EAAE,MAAM,CAAA;IAC1B,qBAAqB,CAAC,EAAE,MAAM,CAAA;IAC9B,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAA;IACxB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,mBAAmB,CAAC,EAAE,MAAM,CAAA;IAC5B,KAAK,CAAC,EAAE,MAAM,GAAG,KAAK,CAAA;CACvB,CAAA;AAED,KAAK,YAAY,GAAG;IAClB,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAC9B,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,cAAc,CAAC,EAAE,OAAO,CAAA;IACxB,KAAK,CAAC,EAAE,SAAS,CAAA;IACjB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,YAAY,CAAC,EAAE,OAAO,CAAA;IACtB,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,QAAQ,CAAC,EAAE,YAAY,CAAA;IACvB,iBAAiB,CAAC,EAAE,OAAO,CAAA;IAC3B,qBAAqB,CAAC,EAAE,MAAM,CAAA;IAC9B,MAAM,CAAC,EAAE,UAAU,CAAA;IACnB,eAAe,CAAC,EAAE,MAAM,EAAE,CAAA;IAC1B,IAAI,CAAC,EAAE,MAAM,EAAE,CAAA;IACf,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,mBAAmB,CAAC,EAAE,OAAO,CAAA;IAC7B,KAAK,CAAC,EAAE,KAAK,CAAA;CACd,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;AAE3B,eAAO,MAAM,aAAa,UAOzB,CAAA;AAED,eAAO,MAAM,YAAY,UAA6B,CAAA;AAEtD;;;;;;GAMG;AACH,eAAO,MAAM,WAAW,WAAY,SAAS,KAAG,YA2C/C,CAAA"}
@@ -53,6 +53,9 @@ export const numberParams = [
53
53
  if ('data' in params && typeof params.data === 'string' && params.data.length > 0) {
54
54
  parsedParams.data = JSON.parse(params.data);
55
55
  }
56
+ if ('where' in params && typeof params.where === 'string' && params.where.length > 0) {
57
+ parsedParams.where = JSON.parse(params.where);
58
+ }
56
59
  return parsedParams;
57
60
  };
58
61
 
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/utilities/parseParams/index.ts"],"sourcesContent":["import type { JoinQuery, PopulateType, SelectType, Where } from '../../types/index.js'\nimport type { JoinParams } from '../sanitizeJoinParams.js'\n\nimport { isNumber } from '../isNumber.js'\nimport { parseBooleanString } from '../parseBooleanString.js'\nimport { sanitizeJoinParams } from '../sanitizeJoinParams.js'\nimport { sanitizePopulateParam } from '../sanitizePopulateParam.js'\nimport { sanitizeSelectParam } from '../sanitizeSelectParam.js'\nimport { sanitizeSortParams } from '../sanitizeSortParams.js'\n\ntype RawParams = {\n [key: string]: unknown\n autosave?: string\n data?: string\n depth?: string\n draft?: string\n field?: string\n flattenLocales?: string\n joins?: JoinParams\n limit?: string\n overrideLock?: string\n page?: string\n pagination?: string\n populate?: unknown\n publishAllLocales?: string\n publishSpecificLocale?: string\n select?: unknown\n selectedLocales?: string\n sort?: string | string[]\n trash?: string\n unpublishAllLocales?: string\n where?: Where\n}\n\ntype ParsedParams = {\n autosave?: boolean\n data?: Record<string, unknown>\n depth?: number\n draft?: boolean\n field?: string\n flattenLocales?: boolean\n joins?: JoinQuery\n limit?: number\n overrideLock?: boolean\n page?: number\n pagination?: boolean\n populate?: PopulateType\n publishAllLocales?: boolean\n publishSpecificLocale?: string\n select?: SelectType\n selectedLocales?: string[]\n sort?: string[]\n trash?: boolean\n unpublishAllLocales?: boolean\n where?: Where\n} & Record<string, unknown>\n\nexport const booleanParams = [\n 'autosave',\n 'draft',\n 'trash',\n 'overrideLock',\n 'pagination',\n 'flattenLocales',\n]\n\nexport const numberParams = ['depth', 'limit', 'page']\n\n/**\n * Takes raw query parameters and parses them into the correct types that Payload expects.\n * Examples:\n * a. `draft` provided as a string of \"true\" is converted to a boolean\n * b. `depth` provided as a string of \"0\" is converted to a number\n * c. `sort` provided as a comma-separated string or array is converted to an array of strings\n */\nexport const parseParams = (params: RawParams): ParsedParams => {\n const parsedParams = (params || {}) as ParsedParams\n\n // iterate through known params to make this very fast\n for (const key of booleanParams) {\n if (key in params) {\n parsedParams[key] = parseBooleanString(params[key] as boolean | string)\n }\n }\n\n for (const key of numberParams) {\n if (key in params) {\n if (isNumber(params[key])) {\n parsedParams[key] = Number(params[key])\n }\n }\n }\n\n if ('populate' in params) {\n parsedParams.populate = sanitizePopulateParam(params.populate)\n }\n\n if ('select' in params) {\n parsedParams.select = sanitizeSelectParam(params.select)\n }\n\n if ('joins' in params) {\n parsedParams.joins = sanitizeJoinParams(params.joins as JoinParams)\n }\n\n if ('sort' in params) {\n parsedParams.sort = sanitizeSortParams(params.sort)\n }\n\n if ('data' in params && typeof params.data === 'string' && params.data.length > 0) {\n parsedParams.data = JSON.parse(params.data)\n }\n\n return parsedParams\n}\n"],"names":["isNumber","parseBooleanString","sanitizeJoinParams","sanitizePopulateParam","sanitizeSelectParam","sanitizeSortParams","booleanParams","numberParams","parseParams","params","parsedParams","key","Number","populate","select","joins","sort","data","length","JSON","parse"],"mappings":"AAGA,SAASA,QAAQ,QAAQ,iBAAgB;AACzC,SAASC,kBAAkB,QAAQ,2BAA0B;AAC7D,SAASC,kBAAkB,QAAQ,2BAA0B;AAC7D,SAASC,qBAAqB,QAAQ,8BAA6B;AACnE,SAASC,mBAAmB,QAAQ,4BAA2B;AAC/D,SAASC,kBAAkB,QAAQ,2BAA0B;AAiD7D,OAAO,MAAMC,gBAAgB;IAC3B;IACA;IACA;IACA;IACA;IACA;CACD,CAAA;AAED,OAAO,MAAMC,eAAe;IAAC;IAAS;IAAS;CAAO,CAAA;AAEtD;;;;;;CAMC,GACD,OAAO,MAAMC,cAAc,CAACC;IAC1B,MAAMC,eAAgBD,UAAU,CAAC;IAEjC,sDAAsD;IACtD,KAAK,MAAME,OAAOL,cAAe;QAC/B,IAAIK,OAAOF,QAAQ;YACjBC,YAAY,CAACC,IAAI,GAAGV,mBAAmBQ,MAAM,CAACE,IAAI;QACpD;IACF;IAEA,KAAK,MAAMA,OAAOJ,aAAc;QAC9B,IAAII,OAAOF,QAAQ;YACjB,IAAIT,SAASS,MAAM,CAACE,IAAI,GAAG;gBACzBD,YAAY,CAACC,IAAI,GAAGC,OAAOH,MAAM,CAACE,IAAI;YACxC;QACF;IACF;IAEA,IAAI,cAAcF,QAAQ;QACxBC,aAAaG,QAAQ,GAAGV,sBAAsBM,OAAOI,QAAQ;IAC/D;IAEA,IAAI,YAAYJ,QAAQ;QACtBC,aAAaI,MAAM,GAAGV,oBAAoBK,OAAOK,MAAM;IACzD;IAEA,IAAI,WAAWL,QAAQ;QACrBC,aAAaK,KAAK,GAAGb,mBAAmBO,OAAOM,KAAK;IACtD;IAEA,IAAI,UAAUN,QAAQ;QACpBC,aAAaM,IAAI,GAAGX,mBAAmBI,OAAOO,IAAI;IACpD;IAEA,IAAI,UAAUP,UAAU,OAAOA,OAAOQ,IAAI,KAAK,YAAYR,OAAOQ,IAAI,CAACC,MAAM,GAAG,GAAG;QACjFR,aAAaO,IAAI,GAAGE,KAAKC,KAAK,CAACX,OAAOQ,IAAI;IAC5C;IAEA,OAAOP;AACT,EAAC"}
1
+ {"version":3,"sources":["../../../src/utilities/parseParams/index.ts"],"sourcesContent":["import type { JoinQuery, PopulateType, SelectType, Where } from '../../types/index.js'\nimport type { JoinParams } from '../sanitizeJoinParams.js'\n\nimport { isNumber } from '../isNumber.js'\nimport { parseBooleanString } from '../parseBooleanString.js'\nimport { sanitizeJoinParams } from '../sanitizeJoinParams.js'\nimport { sanitizePopulateParam } from '../sanitizePopulateParam.js'\nimport { sanitizeSelectParam } from '../sanitizeSelectParam.js'\nimport { sanitizeSortParams } from '../sanitizeSortParams.js'\n\ntype RawParams = {\n [key: string]: unknown\n autosave?: string\n data?: string\n depth?: string\n draft?: string\n field?: string\n flattenLocales?: string\n joins?: JoinParams\n limit?: string\n overrideLock?: string\n page?: string\n pagination?: string\n populate?: unknown\n publishAllLocales?: string\n publishSpecificLocale?: string\n select?: unknown\n selectedLocales?: string\n sort?: string | string[]\n trash?: string\n unpublishAllLocales?: string\n where?: string | Where\n}\n\ntype ParsedParams = {\n autosave?: boolean\n data?: Record<string, unknown>\n depth?: number\n draft?: boolean\n field?: string\n flattenLocales?: boolean\n joins?: JoinQuery\n limit?: number\n overrideLock?: boolean\n page?: number\n pagination?: boolean\n populate?: PopulateType\n publishAllLocales?: boolean\n publishSpecificLocale?: string\n select?: SelectType\n selectedLocales?: string[]\n sort?: string[]\n trash?: boolean\n unpublishAllLocales?: boolean\n where?: Where\n} & Record<string, unknown>\n\nexport const booleanParams = [\n 'autosave',\n 'draft',\n 'trash',\n 'overrideLock',\n 'pagination',\n 'flattenLocales',\n]\n\nexport const numberParams = ['depth', 'limit', 'page']\n\n/**\n * Takes raw query parameters and parses them into the correct types that Payload expects.\n * Examples:\n * a. `draft` provided as a string of \"true\" is converted to a boolean\n * b. `depth` provided as a string of \"0\" is converted to a number\n * c. `sort` provided as a comma-separated string or array is converted to an array of strings\n */\nexport const parseParams = (params: RawParams): ParsedParams => {\n const parsedParams = (params || {}) as ParsedParams\n\n // iterate through known params to make this very fast\n for (const key of booleanParams) {\n if (key in params) {\n parsedParams[key] = parseBooleanString(params[key] as boolean | string)\n }\n }\n\n for (const key of numberParams) {\n if (key in params) {\n if (isNumber(params[key])) {\n parsedParams[key] = Number(params[key])\n }\n }\n }\n\n if ('populate' in params) {\n parsedParams.populate = sanitizePopulateParam(params.populate)\n }\n\n if ('select' in params) {\n parsedParams.select = sanitizeSelectParam(params.select)\n }\n\n if ('joins' in params) {\n parsedParams.joins = sanitizeJoinParams(params.joins as JoinParams)\n }\n\n if ('sort' in params) {\n parsedParams.sort = sanitizeSortParams(params.sort)\n }\n\n if ('data' in params && typeof params.data === 'string' && params.data.length > 0) {\n parsedParams.data = JSON.parse(params.data)\n }\n\n if ('where' in params && typeof params.where === 'string' && params.where.length > 0) {\n parsedParams.where = JSON.parse(params.where) as Where\n }\n\n return parsedParams\n}\n"],"names":["isNumber","parseBooleanString","sanitizeJoinParams","sanitizePopulateParam","sanitizeSelectParam","sanitizeSortParams","booleanParams","numberParams","parseParams","params","parsedParams","key","Number","populate","select","joins","sort","data","length","JSON","parse","where"],"mappings":"AAGA,SAASA,QAAQ,QAAQ,iBAAgB;AACzC,SAASC,kBAAkB,QAAQ,2BAA0B;AAC7D,SAASC,kBAAkB,QAAQ,2BAA0B;AAC7D,SAASC,qBAAqB,QAAQ,8BAA6B;AACnE,SAASC,mBAAmB,QAAQ,4BAA2B;AAC/D,SAASC,kBAAkB,QAAQ,2BAA0B;AAiD7D,OAAO,MAAMC,gBAAgB;IAC3B;IACA;IACA;IACA;IACA;IACA;CACD,CAAA;AAED,OAAO,MAAMC,eAAe;IAAC;IAAS;IAAS;CAAO,CAAA;AAEtD;;;;;;CAMC,GACD,OAAO,MAAMC,cAAc,CAACC;IAC1B,MAAMC,eAAgBD,UAAU,CAAC;IAEjC,sDAAsD;IACtD,KAAK,MAAME,OAAOL,cAAe;QAC/B,IAAIK,OAAOF,QAAQ;YACjBC,YAAY,CAACC,IAAI,GAAGV,mBAAmBQ,MAAM,CAACE,IAAI;QACpD;IACF;IAEA,KAAK,MAAMA,OAAOJ,aAAc;QAC9B,IAAII,OAAOF,QAAQ;YACjB,IAAIT,SAASS,MAAM,CAACE,IAAI,GAAG;gBACzBD,YAAY,CAACC,IAAI,GAAGC,OAAOH,MAAM,CAACE,IAAI;YACxC;QACF;IACF;IAEA,IAAI,cAAcF,QAAQ;QACxBC,aAAaG,QAAQ,GAAGV,sBAAsBM,OAAOI,QAAQ;IAC/D;IAEA,IAAI,YAAYJ,QAAQ;QACtBC,aAAaI,MAAM,GAAGV,oBAAoBK,OAAOK,MAAM;IACzD;IAEA,IAAI,WAAWL,QAAQ;QACrBC,aAAaK,KAAK,GAAGb,mBAAmBO,OAAOM,KAAK;IACtD;IAEA,IAAI,UAAUN,QAAQ;QACpBC,aAAaM,IAAI,GAAGX,mBAAmBI,OAAOO,IAAI;IACpD;IAEA,IAAI,UAAUP,UAAU,OAAOA,OAAOQ,IAAI,KAAK,YAAYR,OAAOQ,IAAI,CAACC,MAAM,GAAG,GAAG;QACjFR,aAAaO,IAAI,GAAGE,KAAKC,KAAK,CAACX,OAAOQ,IAAI;IAC5C;IAEA,IAAI,WAAWR,UAAU,OAAOA,OAAOY,KAAK,KAAK,YAAYZ,OAAOY,KAAK,CAACH,MAAM,GAAG,GAAG;QACpFR,aAAaW,KAAK,GAAGF,KAAKC,KAAK,CAACX,OAAOY,KAAK;IAC9C;IAEA,OAAOX;AACT,EAAC"}
@@ -300,6 +300,30 @@ describe('parseParams', ()=>{
300
300
  });
301
301
  expect(result.where).toBe(where);
302
302
  });
303
+ it('should parse where when it is a JSON string', ()=>{
304
+ const where = {
305
+ read: {
306
+ equals: false
307
+ }
308
+ };
309
+ const result = parseParams({
310
+ where: JSON.stringify(where)
311
+ });
312
+ expect(result.where).toEqual(where);
313
+ });
314
+ it('should not process empty string where', ()=>{
315
+ const result = parseParams({
316
+ where: ''
317
+ });
318
+ expect(result.where).toBe('');
319
+ });
320
+ it('should throw error for invalid JSON where', ()=>{
321
+ expect(()=>{
322
+ parseParams({
323
+ where: 'invalid-json'
324
+ });
325
+ }).toThrow();
326
+ });
303
327
  });
304
328
  describe('edge cases', ()=>{
305
329
  it('should handle empty params object', ()=>{
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/utilities/parseParams/index.spec.ts"],"sourcesContent":["import * as qs from 'qs-esm'\nimport { describe, it, expect } from 'vitest'\nimport { parseParams, booleanParams, numberParams } from './index.js'\n\ndescribe('parseParams', () => {\n describe('boolean parameters', () => {\n booleanParams.forEach((param) => {\n describe(param, () => {\n it('should parse string \"true\" to boolean true', () => {\n const result = parseParams({ [param]: 'true' })\n expect(result[param]).toBe(true)\n })\n\n it('should parse string \"false\" to boolean false', () => {\n const result = parseParams({ [param]: 'false' })\n expect(result[param]).toBe(false)\n })\n\n it('should parse boolean true to boolean true', () => {\n const result = parseParams({ [param]: true })\n expect(result[param]).toBe(true)\n })\n\n it('should parse boolean false to boolean false', () => {\n const result = parseParams({ [param]: false })\n expect(result[param]).toBe(false)\n })\n\n it('should return undefined for truthy strings (not exact \"true\")', () => {\n const result = parseParams({ [param]: '1' })\n expect(result[param]).toBeUndefined()\n })\n\n it('should return undefined for falsy strings (not exact \"false\")', () => {\n const result = parseParams({ [param]: '0' })\n expect(result[param]).toBeUndefined()\n })\n\n it('should return undefined for empty string', () => {\n const result = parseParams({ [param]: '' })\n expect(result[param]).toBeUndefined()\n })\n })\n })\n })\n\n describe('number parameters', () => {\n numberParams.forEach((param) => {\n describe(param, () => {\n it('should parse valid number string to number', () => {\n const result = parseParams({ [param]: '42' })\n expect(result[param]).toBe(42)\n })\n\n it('should parse zero string to zero', () => {\n const result = parseParams({ [param]: '0' })\n expect(result[param]).toBe(0)\n })\n\n it('should parse negative number string to negative number', () => {\n const result = parseParams({ [param]: '-5' })\n expect(result[param]).toBe(-5)\n })\n\n it('should parse decimal number string to decimal number', () => {\n const result = parseParams({ [param]: '3.14' })\n expect(result[param]).toBe(3.14)\n })\n\n it('should not parse invalid number strings', () => {\n const result = parseParams({ [param]: 'not-a-number' })\n expect(result[param]).toBe('not-a-number') // remains as string\n })\n\n it('should not parse empty string', () => {\n const result = parseParams({ [param]: '' })\n expect(result[param]).toBe('') // remains as string\n })\n\n it('should handle already numeric values', () => {\n const result = parseParams({ [param]: 123 })\n expect(result[param]).toBe(123)\n })\n })\n })\n })\n\n describe('sort parameter', () => {\n it('should parse comma-separated string to array', () => {\n const result = parseParams({ sort: 'name,createdAt,-updatedAt' })\n expect(result.sort).toEqual(['name', 'createdAt', '-updatedAt'])\n })\n\n it('should parse single value string to array with one element', () => {\n const result = parseParams({ sort: 'name' })\n expect(result.sort).toEqual(['name'])\n })\n\n it('should handle empty string', () => {\n const result = parseParams({ sort: '' })\n expect(result.sort).toEqual([''])\n })\n\n it('should handle comma-separated string with spaces', () => {\n const result = parseParams({ sort: 'name, createdAt , -updatedAt' })\n expect(result.sort).toEqual(['name', ' createdAt ', ' -updatedAt'])\n })\n\n it('should parse array of strings', () => {\n const result = parseParams({ sort: ['name', '-createdAt'] })\n expect(result.sort).toEqual(['name', '-createdAt'])\n })\n\n it('should return undefined for non-string sort values', () => {\n const result = parseParams({ sort: 123 as any })\n expect(result.sort).toBeUndefined()\n })\n\n it('should return undefined for array with non-string sort values', () => {\n const result = parseParams({ sort: ['name', 123] as any })\n expect(result.sort).toBeUndefined()\n })\n\n it('should handle qs-esm array sort parsing', () => {\n const query = qs.stringify({ sort: ['title', '-createdAt'] })\n const parsed = qs.parse(query)\n const result = parseParams(parsed)\n expect(result.sort).toEqual(['title', '-createdAt'])\n })\n\n it('should return undefined for null sort values', () => {\n const result = parseParams({ sort: null as any })\n expect(result.sort).toBeUndefined()\n })\n })\n\n describe('data parameter', () => {\n it('should parse valid JSON string', () => {\n const data = { name: 'test', value: 42 }\n const result = parseParams({ data: JSON.stringify(data) })\n expect(result.data).toEqual(data)\n })\n\n it('should parse empty object JSON string', () => {\n const result = parseParams({ data: '{}' })\n expect(result.data).toEqual({})\n })\n\n it('should parse array JSON string', () => {\n const data = [1, 2, 3]\n const result = parseParams({ data: JSON.stringify(data) })\n expect(result.data).toEqual(data)\n })\n\n it('should not process empty string', () => {\n const result = parseParams({ data: '' })\n expect(result.data).toBe('') // empty string is not processed, remains as string\n })\n\n it('should throw error for invalid JSON', () => {\n expect(() => {\n parseParams({ data: 'invalid-json' })\n }).toThrow()\n })\n\n it('should not process non-string data values', () => {\n const result = parseParams({ data: { already: 'parsed' } as any })\n expect(result.data).toEqual({ already: 'parsed' })\n })\n })\n\n describe('special parameters', () => {\n it('should handle populate parameter', () => {\n const result = parseParams({ populate: 'field1,field2' })\n expect(result).toHaveProperty('populate')\n // Note: actual sanitization logic is tested in sanitizePopulateParam tests\n })\n\n it('should handle select parameter', () => {\n const result = parseParams({ select: 'field1,field2' })\n expect(result).toHaveProperty('select')\n // Note: actual sanitization logic is tested in sanitizeSelectParam tests\n })\n\n it('should handle joins parameter', () => {\n const joins = { collection: 'posts' }\n const result = parseParams({ joins })\n expect(result).toHaveProperty('joins')\n // Note: actual sanitization logic is tested in sanitizeJoinParams tests\n })\n })\n\n describe('selectedLocales parameter', () => {\n it('should pass through selectedLocales as-is', () => {\n const selectedLocales = 'en,es,fr'\n const result = parseParams({ selectedLocales })\n expect(result.selectedLocales).toBe(selectedLocales)\n })\n })\n\n describe('publishSpecificLocale parameter', () => {\n it('should pass through publishSpecificLocale as-is', () => {\n const publishSpecificLocale = 'en'\n const result = parseParams({ publishSpecificLocale })\n expect(result.publishSpecificLocale).toBe(publishSpecificLocale)\n })\n })\n\n describe('field parameter', () => {\n it('should pass through field as-is', () => {\n const field = 'myField'\n const result = parseParams({ field })\n expect(result.field).toBe(field)\n })\n })\n\n describe('where parameter', () => {\n it('should pass through where as-is', () => {\n const where = { name: { equals: 'test' } }\n const result = parseParams({ where })\n expect(result.where).toBe(where)\n })\n })\n\n describe('edge cases', () => {\n it('should handle empty params object', () => {\n const result = parseParams({})\n expect(result).toEqual({})\n })\n\n it('should throw error for null params (current implementation bug)', () => {\n expect(() => {\n parseParams(null as any)\n }).toThrow(TypeError)\n })\n\n it('should throw error for undefined params (current implementation bug)', () => {\n expect(() => {\n parseParams(undefined as any)\n }).toThrow(TypeError)\n })\n\n it('should preserve unknown parameters', () => {\n const result = parseParams({ customParam: 'customValue' })\n expect(result.customParam).toBe('customValue')\n })\n\n it('should handle mixed parameter types', () => {\n const result = parseParams({\n draft: 'true',\n depth: '5',\n sort: 'name,createdAt',\n data: '{\"test\": true}',\n customParam: 'custom',\n })\n\n expect(result.draft).toBe(true)\n expect(result.depth).toBe(5)\n expect(result.sort).toEqual(['name', 'createdAt'])\n expect(result.data).toEqual({ test: true })\n expect(result.customParam).toBe('custom')\n })\n })\n\n describe('parameter preservation', () => {\n it('should not modify parameters that are not in known lists', () => {\n const params = {\n unknownBoolean: 'true',\n unknownNumber: '42',\n unknownString: 'test',\n }\n const result = parseParams(params)\n\n expect(result.unknownBoolean).toBe('true') // should remain string\n expect(result.unknownNumber).toBe('42') // should remain string\n expect(result.unknownString).toBe('test')\n })\n\n it('should only process parameters that exist in the input', () => {\n const result = parseParams({ draft: 'true' })\n\n expect(result.draft).toBe(true)\n expect(result).not.toHaveProperty('autosave')\n expect(result).not.toHaveProperty('depth')\n expect(result).not.toHaveProperty('sort')\n })\n })\n})\n"],"names":["qs","describe","it","expect","parseParams","booleanParams","numberParams","forEach","param","result","toBe","toBeUndefined","sort","toEqual","query","stringify","parsed","parse","data","name","value","JSON","toThrow","already","populate","toHaveProperty","select","joins","collection","selectedLocales","publishSpecificLocale","field","where","equals","TypeError","undefined","customParam","draft","depth","test","params","unknownBoolean","unknownNumber","unknownString","not"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../src/utilities/parseParams/index.spec.ts"],"sourcesContent":["import * as qs from 'qs-esm'\nimport { describe, it, expect } from 'vitest'\nimport { parseParams, booleanParams, numberParams } from './index.js'\n\ndescribe('parseParams', () => {\n describe('boolean parameters', () => {\n booleanParams.forEach((param) => {\n describe(param, () => {\n it('should parse string \"true\" to boolean true', () => {\n const result = parseParams({ [param]: 'true' })\n expect(result[param]).toBe(true)\n })\n\n it('should parse string \"false\" to boolean false', () => {\n const result = parseParams({ [param]: 'false' })\n expect(result[param]).toBe(false)\n })\n\n it('should parse boolean true to boolean true', () => {\n const result = parseParams({ [param]: true })\n expect(result[param]).toBe(true)\n })\n\n it('should parse boolean false to boolean false', () => {\n const result = parseParams({ [param]: false })\n expect(result[param]).toBe(false)\n })\n\n it('should return undefined for truthy strings (not exact \"true\")', () => {\n const result = parseParams({ [param]: '1' })\n expect(result[param]).toBeUndefined()\n })\n\n it('should return undefined for falsy strings (not exact \"false\")', () => {\n const result = parseParams({ [param]: '0' })\n expect(result[param]).toBeUndefined()\n })\n\n it('should return undefined for empty string', () => {\n const result = parseParams({ [param]: '' })\n expect(result[param]).toBeUndefined()\n })\n })\n })\n })\n\n describe('number parameters', () => {\n numberParams.forEach((param) => {\n describe(param, () => {\n it('should parse valid number string to number', () => {\n const result = parseParams({ [param]: '42' })\n expect(result[param]).toBe(42)\n })\n\n it('should parse zero string to zero', () => {\n const result = parseParams({ [param]: '0' })\n expect(result[param]).toBe(0)\n })\n\n it('should parse negative number string to negative number', () => {\n const result = parseParams({ [param]: '-5' })\n expect(result[param]).toBe(-5)\n })\n\n it('should parse decimal number string to decimal number', () => {\n const result = parseParams({ [param]: '3.14' })\n expect(result[param]).toBe(3.14)\n })\n\n it('should not parse invalid number strings', () => {\n const result = parseParams({ [param]: 'not-a-number' })\n expect(result[param]).toBe('not-a-number') // remains as string\n })\n\n it('should not parse empty string', () => {\n const result = parseParams({ [param]: '' })\n expect(result[param]).toBe('') // remains as string\n })\n\n it('should handle already numeric values', () => {\n const result = parseParams({ [param]: 123 })\n expect(result[param]).toBe(123)\n })\n })\n })\n })\n\n describe('sort parameter', () => {\n it('should parse comma-separated string to array', () => {\n const result = parseParams({ sort: 'name,createdAt,-updatedAt' })\n expect(result.sort).toEqual(['name', 'createdAt', '-updatedAt'])\n })\n\n it('should parse single value string to array with one element', () => {\n const result = parseParams({ sort: 'name' })\n expect(result.sort).toEqual(['name'])\n })\n\n it('should handle empty string', () => {\n const result = parseParams({ sort: '' })\n expect(result.sort).toEqual([''])\n })\n\n it('should handle comma-separated string with spaces', () => {\n const result = parseParams({ sort: 'name, createdAt , -updatedAt' })\n expect(result.sort).toEqual(['name', ' createdAt ', ' -updatedAt'])\n })\n\n it('should parse array of strings', () => {\n const result = parseParams({ sort: ['name', '-createdAt'] })\n expect(result.sort).toEqual(['name', '-createdAt'])\n })\n\n it('should return undefined for non-string sort values', () => {\n const result = parseParams({ sort: 123 as any })\n expect(result.sort).toBeUndefined()\n })\n\n it('should return undefined for array with non-string sort values', () => {\n const result = parseParams({ sort: ['name', 123] as any })\n expect(result.sort).toBeUndefined()\n })\n\n it('should handle qs-esm array sort parsing', () => {\n const query = qs.stringify({ sort: ['title', '-createdAt'] })\n const parsed = qs.parse(query)\n const result = parseParams(parsed)\n expect(result.sort).toEqual(['title', '-createdAt'])\n })\n\n it('should return undefined for null sort values', () => {\n const result = parseParams({ sort: null as any })\n expect(result.sort).toBeUndefined()\n })\n })\n\n describe('data parameter', () => {\n it('should parse valid JSON string', () => {\n const data = { name: 'test', value: 42 }\n const result = parseParams({ data: JSON.stringify(data) })\n expect(result.data).toEqual(data)\n })\n\n it('should parse empty object JSON string', () => {\n const result = parseParams({ data: '{}' })\n expect(result.data).toEqual({})\n })\n\n it('should parse array JSON string', () => {\n const data = [1, 2, 3]\n const result = parseParams({ data: JSON.stringify(data) })\n expect(result.data).toEqual(data)\n })\n\n it('should not process empty string', () => {\n const result = parseParams({ data: '' })\n expect(result.data).toBe('') // empty string is not processed, remains as string\n })\n\n it('should throw error for invalid JSON', () => {\n expect(() => {\n parseParams({ data: 'invalid-json' })\n }).toThrow()\n })\n\n it('should not process non-string data values', () => {\n const result = parseParams({ data: { already: 'parsed' } as any })\n expect(result.data).toEqual({ already: 'parsed' })\n })\n })\n\n describe('special parameters', () => {\n it('should handle populate parameter', () => {\n const result = parseParams({ populate: 'field1,field2' })\n expect(result).toHaveProperty('populate')\n // Note: actual sanitization logic is tested in sanitizePopulateParam tests\n })\n\n it('should handle select parameter', () => {\n const result = parseParams({ select: 'field1,field2' })\n expect(result).toHaveProperty('select')\n // Note: actual sanitization logic is tested in sanitizeSelectParam tests\n })\n\n it('should handle joins parameter', () => {\n const joins = { collection: 'posts' }\n const result = parseParams({ joins })\n expect(result).toHaveProperty('joins')\n // Note: actual sanitization logic is tested in sanitizeJoinParams tests\n })\n })\n\n describe('selectedLocales parameter', () => {\n it('should pass through selectedLocales as-is', () => {\n const selectedLocales = 'en,es,fr'\n const result = parseParams({ selectedLocales })\n expect(result.selectedLocales).toBe(selectedLocales)\n })\n })\n\n describe('publishSpecificLocale parameter', () => {\n it('should pass through publishSpecificLocale as-is', () => {\n const publishSpecificLocale = 'en'\n const result = parseParams({ publishSpecificLocale })\n expect(result.publishSpecificLocale).toBe(publishSpecificLocale)\n })\n })\n\n describe('field parameter', () => {\n it('should pass through field as-is', () => {\n const field = 'myField'\n const result = parseParams({ field })\n expect(result.field).toBe(field)\n })\n })\n\n describe('where parameter', () => {\n it('should pass through where as-is', () => {\n const where = { name: { equals: 'test' } }\n const result = parseParams({ where })\n expect(result.where).toBe(where)\n })\n\n it('should parse where when it is a JSON string', () => {\n const where = { read: { equals: false } }\n const result = parseParams({ where: JSON.stringify(where) })\n expect(result.where).toEqual(where)\n })\n\n it('should not process empty string where', () => {\n const result = parseParams({ where: '' })\n expect(result.where).toBe('')\n })\n\n it('should throw error for invalid JSON where', () => {\n expect(() => {\n parseParams({ where: 'invalid-json' })\n }).toThrow()\n })\n })\n\n describe('edge cases', () => {\n it('should handle empty params object', () => {\n const result = parseParams({})\n expect(result).toEqual({})\n })\n\n it('should throw error for null params (current implementation bug)', () => {\n expect(() => {\n parseParams(null as any)\n }).toThrow(TypeError)\n })\n\n it('should throw error for undefined params (current implementation bug)', () => {\n expect(() => {\n parseParams(undefined as any)\n }).toThrow(TypeError)\n })\n\n it('should preserve unknown parameters', () => {\n const result = parseParams({ customParam: 'customValue' })\n expect(result.customParam).toBe('customValue')\n })\n\n it('should handle mixed parameter types', () => {\n const result = parseParams({\n draft: 'true',\n depth: '5',\n sort: 'name,createdAt',\n data: '{\"test\": true}',\n customParam: 'custom',\n })\n\n expect(result.draft).toBe(true)\n expect(result.depth).toBe(5)\n expect(result.sort).toEqual(['name', 'createdAt'])\n expect(result.data).toEqual({ test: true })\n expect(result.customParam).toBe('custom')\n })\n })\n\n describe('parameter preservation', () => {\n it('should not modify parameters that are not in known lists', () => {\n const params = {\n unknownBoolean: 'true',\n unknownNumber: '42',\n unknownString: 'test',\n }\n const result = parseParams(params)\n\n expect(result.unknownBoolean).toBe('true') // should remain string\n expect(result.unknownNumber).toBe('42') // should remain string\n expect(result.unknownString).toBe('test')\n })\n\n it('should only process parameters that exist in the input', () => {\n const result = parseParams({ draft: 'true' })\n\n expect(result.draft).toBe(true)\n expect(result).not.toHaveProperty('autosave')\n expect(result).not.toHaveProperty('depth')\n expect(result).not.toHaveProperty('sort')\n })\n })\n})\n"],"names":["qs","describe","it","expect","parseParams","booleanParams","numberParams","forEach","param","result","toBe","toBeUndefined","sort","toEqual","query","stringify","parsed","parse","data","name","value","JSON","toThrow","already","populate","toHaveProperty","select","joins","collection","selectedLocales","publishSpecificLocale","field","where","equals","read","TypeError","undefined","customParam","draft","depth","test","params","unknownBoolean","unknownNumber","unknownString","not"],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ type ProfileEntry = {
2
+ calls: number;
3
+ duration: number;
4
+ name: string;
5
+ };
6
+ export declare const timeSync: <T>(name: string, fn: () => T) => T;
7
+ export declare const timeAsync: <T>(name: string, fn: () => Promise<T>) => Promise<T>;
8
+ export declare const clearProfiles: () => void;
9
+ export declare const printProfileResults: () => void;
10
+ export declare const getProfileResults: () => ProfileEntry[];
11
+ export {};
12
+ //# sourceMappingURL=profiling.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"profiling.d.ts","sourceRoot":"","sources":["../../src/utilities/profiling.ts"],"names":[],"mappings":"AAAA,KAAK,YAAY,GAAG;IAClB,KAAK,EAAE,MAAM,CAAA;IACb,QAAQ,EAAE,MAAM,CAAA;IAChB,IAAI,EAAE,MAAM,CAAA;CACb,CAAA;AAKD,eAAO,MAAM,QAAQ,GAAI,CAAC,QAAQ,MAAM,MAAM,MAAM,CAAC,KAAG,CAavD,CAAA;AAED,eAAO,MAAM,SAAS,GAAU,CAAC,QAAQ,MAAM,MAAM,MAAM,OAAO,CAAC,CAAC,CAAC,KAAG,OAAO,CAAC,CAAC,CAahF,CAAA;AAED,eAAO,MAAM,aAAa,YAEzB,CAAA;AAED,eAAO,MAAM,mBAAmB,YAgB/B,CAAA;AAED,eAAO,MAAM,iBAAiB,sBAE7B,CAAA"}