json-rest-api 1.0.22 → 1.0.23

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 (260) hide show
  1. package/CLAUDE.md +1 -2
  2. package/JSKIT_BACKEND_MIGRATION_TRACKER.txt +180 -0
  3. package/SINGLE_VALIDATION_CONTRACT_TODO.txt +172 -0
  4. package/docs/API.md +51 -14
  5. package/docs/COMPARISON.md +2 -2
  6. package/docs/GUIDE/GUIDE_1_Initial_Setup.md +28 -1
  7. package/docs/GUIDE/GUIDE_2_2_Manipulating_And_Searching_Tables.md +5 -1
  8. package/docs/GUIDE/GUIDE_2_7_Pagination_And_Ordering.md +3 -1
  9. package/docs/GUIDE/GUIDE_2_8_Effects_of_PUT_and_PATCH.md +12 -60
  10. package/docs/GUIDE/GUIDE_2_Data_And_Relations.md +2 -2
  11. package/docs/GUIDE/GUIDE_3_Field_Transformations.md +5 -1
  12. package/docs/GUIDE/GUIDE_7_Hooks_Data_Management_And_Plugins.md +2 -0
  13. package/docs/GUIDE/GUIDE_X_Autofiltering.md +355 -0
  14. package/docs/GUIDE/GUIDE_X_Fastify.md +78 -0
  15. package/docs/GUIDE/GUIDE_X_Knex_Schema_And_Migrations.md +250 -0
  16. package/docs/GUIDE/GUIDE_X_Query_Projections.md +159 -0
  17. package/docs/GUIDE/GUIDE_X_Writing_Plugins.md +199 -0
  18. package/docs/GUIDE/index.md +18 -9
  19. package/docs/QUICKSTART.md +5 -1
  20. package/docs/index.md +1 -1
  21. package/index.js +3 -2
  22. package/package.json +2 -2
  23. package/plugins/core/connectors/express-plugin.js +97 -184
  24. package/plugins/core/connectors/fastify-plugin.js +206 -0
  25. package/plugins/core/connectors/lib/connector-core.js +195 -0
  26. package/plugins/core/connectors/lib/transport-http-helpers.js +122 -0
  27. package/plugins/core/connectors/lib/transport-route-schemas.js +92 -0
  28. package/plugins/core/lib/dbIntrospection.js +1078 -0
  29. package/plugins/core/lib/dbTablesOperations.js +1104 -160
  30. package/plugins/core/lib/querying/knex-json-api-transformers-querying.js +5 -2
  31. package/plugins/core/lib/querying/knex-process-includes.js +3 -4
  32. package/plugins/core/lib/querying/knex-query-helpers.js +17 -71
  33. package/plugins/core/lib/querying/knex-relationship-includes.js +466 -206
  34. package/plugins/core/lib/querying/query-builder-utils.js +19 -0
  35. package/plugins/core/lib/querying/query-field-sort-helpers.js +135 -0
  36. package/plugins/core/lib/querying/sort-helpers.js +33 -0
  37. package/plugins/core/lib/querying/storage-adapter-utils.js +51 -0
  38. package/plugins/core/lib/querying/url-helpers.js +8 -2
  39. package/plugins/core/lib/querying-writing/compile-schemas.js +12 -1
  40. package/plugins/core/lib/querying-writing/knex-field-helpers.js +83 -13
  41. package/plugins/core/lib/querying-writing/knex-json-api-transformers.js +13 -12
  42. package/plugins/core/lib/querying-writing/query-field-helpers.js +88 -0
  43. package/plugins/core/lib/querying-writing/request-contracts.js +590 -0
  44. package/plugins/core/lib/storage/canonical-storage-mapping.js +113 -0
  45. package/plugins/core/lib/storage/storage-adapter.js +79 -2
  46. package/plugins/core/lib/storage/storage-mapping.js +204 -0
  47. package/plugins/core/rest-api-anyapi-knex-plugin.js +355 -228
  48. package/plugins/core/rest-api-autofilter-plugin.js +414 -0
  49. package/plugins/core/rest-api-knex-plugin.js +249 -211
  50. package/plugins/core/rest-api-plugin-hooks/register-relationship-routes.js +10 -5
  51. package/plugins/core/rest-api-plugin-hooks/register-scope-routes.js +12 -6
  52. package/plugins/core/rest-api-plugin-methods/apply-query-filters.js +41 -0
  53. package/plugins/core/rest-api-plugin-methods/common.js +121 -83
  54. package/plugins/core/rest-api-plugin-methods/enrich-attributes.js +6 -1
  55. package/plugins/core/rest-api-plugin-methods/get.js +23 -14
  56. package/plugins/core/rest-api-plugin-methods/patch.js +28 -12
  57. package/plugins/core/rest-api-plugin-methods/post.js +13 -8
  58. package/plugins/core/rest-api-plugin-methods/put.js +45 -21
  59. package/plugins/core/rest-api-plugin-methods/query.js +15 -53
  60. package/plugins/core/rest-api-plugin.js +2 -0
  61. package/plugins/core/rest-api-positioning-plugin.js +1 -1
  62. package/plugins/core/rest-api-query-projections-plugin.js +130 -0
  63. package/plugins/core/socketio-plugin.js +1 -3
  64. package/tests/autofilter.test.js +463 -0
  65. package/tests/custom-id-simplified-post.test.js +75 -0
  66. package/tests/custom-idproperty-relationships.test.js +33 -0
  67. package/tests/db-introspection.test.js +518 -0
  68. package/tests/db-table-operations.test.js +781 -0
  69. package/tests/fastify-plugin.test.js +141 -0
  70. package/tests/field-getters.test.js +1 -2
  71. package/tests/field-setters.test.js +0 -4
  72. package/tests/fixtures/api-configs.js +188 -219
  73. package/tests/helpers/fake-fastify.js +99 -0
  74. package/tests/http-connectors-parity.test.js +235 -0
  75. package/tests/projected-fields.test.js +319 -0
  76. package/tests/relationships.test.js +3 -3
  77. package/tests/searchschema-knex-behavior.test.js +187 -0
  78. package/tests/searchschema-merge.test.js +21 -69
  79. package/tests/storage-mapping.test.js +210 -0
  80. package/audit/00-charter.md +0 -103
  81. package/audit/01-scope-map.md +0 -84
  82. package/audit/02-coverage-matrix.csv +0 -174
  83. package/audit/03-invariants.md +0 -123
  84. package/audit/04-standards-rubric.md +0 -56
  85. package/audit/05-competitor-rubric.md +0 -77
  86. package/audit/06-findings.md +0 -160
  87. package/audit/07-risk-register.csv +0 -10
  88. package/audit/08-remediation-roadmap.md +0 -177
  89. package/audit/09-signoff-check.md +0 -23
  90. package/audit/10-final-synthesis.md +0 -29
  91. package/audit/evidence/code/all-files-json-rest-api.txt +0 -168
  92. package/audit/evidence/code/all-files-json-rest-schema.txt +0 -12
  93. package/audit/evidence/code/boundary-leak-checks.txt +0 -72
  94. package/audit/evidence/code/critical-pass1/json-rest-api__plugins__core__bulk-operations-plugin.js.txt +0 -480
  95. package/audit/evidence/code/critical-pass1/json-rest-api__plugins__core__connectors__express-plugin.js.txt +0 -532
  96. package/audit/evidence/code/critical-pass1/json-rest-api__plugins__core__connectors__lib__busboy-detector.js.txt +0 -175
  97. package/audit/evidence/code/critical-pass1/json-rest-api__plugins__core__connectors__lib__formidable-detector.js.txt +0 -138
  98. package/audit/evidence/code/critical-pass1/json-rest-api__plugins__core__connectors__lib__request-helpers.js.txt +0 -222
  99. package/audit/evidence/code/critical-pass1/json-rest-api__plugins__core__file-handling-plugin.js.txt +0 -342
  100. package/audit/evidence/code/critical-pass1/json-rest-api__plugins__core__lib__dbTablesOperations.js.txt +0 -304
  101. package/audit/evidence/code/critical-pass1/json-rest-api__plugins__core__lib__fractional-positioning.js.txt +0 -188
  102. package/audit/evidence/code/critical-pass1/json-rest-api__plugins__core__lib__querying-writing__compile-schemas.js.txt +0 -336
  103. package/audit/evidence/code/critical-pass1/json-rest-api__plugins__core__lib__querying-writing__connectors-query-parser.js.txt +0 -165
  104. package/audit/evidence/code/critical-pass1/json-rest-api__plugins__core__lib__querying-writing__database-capabilities.js.txt +0 -265
  105. package/audit/evidence/code/critical-pass1/json-rest-api__plugins__core__lib__querying-writing__database-value-normalizers.js.txt +0 -369
  106. package/audit/evidence/code/critical-pass1/json-rest-api__plugins__core__lib__querying-writing__default-data-helpers.js.txt +0 -72
  107. package/audit/evidence/code/critical-pass1/json-rest-api__plugins__core__lib__querying-writing__field-utils.js.txt +0 -139
  108. package/audit/evidence/code/critical-pass1/json-rest-api__plugins__core__lib__querying-writing__knex-constants.js.txt +0 -45
  109. package/audit/evidence/code/critical-pass1/json-rest-api__plugins__core__lib__querying-writing__knex-field-helpers.js.txt +0 -396
  110. package/audit/evidence/code/critical-pass1/json-rest-api__plugins__core__lib__querying-writing__knex-json-api-transformers.js.txt +0 -162
  111. package/audit/evidence/code/critical-pass1/json-rest-api__plugins__core__lib__querying-writing__payload-validators.js.txt +0 -1314
  112. package/audit/evidence/code/critical-pass1/json-rest-api__plugins__core__lib__querying-writing__schema-helpers.js.txt +0 -488
  113. package/audit/evidence/code/critical-pass1/json-rest-api__plugins__core__lib__querying-writing__scope-validations.js.txt +0 -484
  114. package/audit/evidence/code/critical-pass1/json-rest-api__plugins__core__lib__querying-writing__simplified-helpers.js.txt +0 -857
  115. package/audit/evidence/code/critical-pass1/json-rest-api__plugins__core__lib__querying__knex-cross-table-search.js.txt +0 -565
  116. package/audit/evidence/code/critical-pass1/json-rest-api__plugins__core__lib__querying__knex-json-api-transformers-querying.js.txt +0 -485
  117. package/audit/evidence/code/critical-pass1/json-rest-api__plugins__core__lib__querying__knex-pagination-helpers.js.txt +0 -560
  118. package/audit/evidence/code/critical-pass1/json-rest-api__plugins__core__lib__querying__knex-process-includes.js.txt +0 -167
  119. package/audit/evidence/code/critical-pass1/json-rest-api__plugins__core__lib__querying__knex-query-helpers-base.js.txt +0 -109
  120. package/audit/evidence/code/critical-pass1/json-rest-api__plugins__core__lib__querying__knex-query-helpers.js.txt +0 -1064
  121. package/audit/evidence/code/critical-pass1/json-rest-api__plugins__core__lib__querying__knex-relationship-includes.js.txt +0 -1983
  122. package/audit/evidence/code/critical-pass1/json-rest-api__plugins__core__lib__querying__knex-window-queries.js.txt +0 -328
  123. package/audit/evidence/code/critical-pass1/json-rest-api__plugins__core__lib__querying__url-helpers.js.txt +0 -119
  124. package/audit/evidence/code/critical-pass1/json-rest-api__plugins__core__lib__storage__storage-adapter.js.txt +0 -160
  125. package/audit/evidence/code/critical-pass1/json-rest-api__plugins__core__lib__writing__many-to-many-manipulations.js.txt +0 -300
  126. package/audit/evidence/code/critical-pass1/json-rest-api__plugins__core__lib__writing__relationship-processor.js.txt +0 -245
  127. package/audit/evidence/code/critical-pass1/json-rest-api__plugins__core__rest-api-access.js.txt +0 -459
  128. package/audit/evidence/code/critical-pass1/json-rest-api__plugins__core__rest-api-cors-plugin.js.txt +0 -237
  129. package/audit/evidence/code/critical-pass1/json-rest-api__plugins__core__rest-api-knex-plugin.js.txt +0 -1135
  130. package/audit/evidence/code/critical-pass1/json-rest-api__plugins__core__rest-api-multihome-plugin.js.txt +0 -314
  131. package/audit/evidence/code/critical-pass1/json-rest-api__plugins__core__rest-api-plugin-hooks__compile-resource-schemas.js.txt +0 -7
  132. package/audit/evidence/code/critical-pass1/json-rest-api__plugins__core__rest-api-plugin-hooks__register-relationship-routes.js.txt +0 -71
  133. package/audit/evidence/code/critical-pass1/json-rest-api__plugins__core__rest-api-plugin-hooks__register-scope-routes.js.txt +0 -102
  134. package/audit/evidence/code/critical-pass1/json-rest-api__plugins__core__rest-api-plugin-hooks__turn-scope-init-into-vars.js.txt +0 -49
  135. package/audit/evidence/code/critical-pass1/json-rest-api__plugins__core__rest-api-plugin-hooks__validate-include-configurations.js.txt +0 -39
  136. package/audit/evidence/code/critical-pass1/json-rest-api__plugins__core__rest-api-plugin-methods__add-route.js.txt +0 -23
  137. package/audit/evidence/code/critical-pass1/json-rest-api__plugins__core__rest-api-plugin-methods__check-permissions.js.txt +0 -13
  138. package/audit/evidence/code/critical-pass1/json-rest-api__plugins__core__rest-api-plugin-methods__common.js.txt +0 -639
  139. package/audit/evidence/code/critical-pass1/json-rest-api__plugins__core__rest-api-plugin-methods__delete-relationship.js.txt +0 -117
  140. package/audit/evidence/code/critical-pass1/json-rest-api__plugins__core__rest-api-plugin-methods__delete.js.txt +0 -104
  141. package/audit/evidence/code/critical-pass1/json-rest-api__plugins__core__rest-api-plugin-methods__enrich-attributes.js.txt +0 -199
  142. package/audit/evidence/code/critical-pass1/json-rest-api__plugins__core__rest-api-plugin-methods__get-related.js.txt +0 -353
  143. package/audit/evidence/code/critical-pass1/json-rest-api__plugins__core__rest-api-plugin-methods__get-relationship.js.txt +0 -61
  144. package/audit/evidence/code/critical-pass1/json-rest-api__plugins__core__rest-api-plugin-methods__get.js.txt +0 -184
  145. package/audit/evidence/code/critical-pass1/json-rest-api__plugins__core__rest-api-plugin-methods__patch-relationship.js.txt +0 -55
  146. package/audit/evidence/code/critical-pass1/json-rest-api__plugins__core__rest-api-plugin-methods__patch.js.txt +0 -191
  147. package/audit/evidence/code/critical-pass1/json-rest-api__plugins__core__rest-api-plugin-methods__post-relationship.js.txt +0 -110
  148. package/audit/evidence/code/critical-pass1/json-rest-api__plugins__core__rest-api-plugin-methods__post.js.txt +0 -168
  149. package/audit/evidence/code/critical-pass1/json-rest-api__plugins__core__rest-api-plugin-methods__put.js.txt +0 -253
  150. package/audit/evidence/code/critical-pass1/json-rest-api__plugins__core__rest-api-plugin-methods__query.js.txt +0 -207
  151. package/audit/evidence/code/critical-pass1/json-rest-api__plugins__core__rest-api-plugin-methods__release.js.txt +0 -12
  152. package/audit/evidence/code/critical-pass1/json-rest-api__plugins__core__rest-api-plugin.js.txt +0 -165
  153. package/audit/evidence/code/critical-pass1/json-rest-api__plugins__core__rest-api-positioning-plugin.js.txt +0 -668
  154. package/audit/evidence/code/critical-pass1/json-rest-api__plugins__core__socketio-plugin.js.txt +0 -621
  155. package/audit/evidence/code/critical-pass1/json-rest-api__plugins__storage__local-storage.js.txt +0 -218
  156. package/audit/evidence/code/critical-pass1/json-rest-api__plugins__storage__s3-storage.js.txt +0 -124
  157. package/audit/evidence/code/critical-pass1/json-rest-schema__src__CorePlugin.js.txt +0 -269
  158. package/audit/evidence/code/critical-pass1/json-rest-schema__src__Schema.js.txt +0 -242
  159. package/audit/evidence/code/critical-pass1/json-rest-schema__src__index.js.txt +0 -77
  160. package/audit/evidence/code/critical-pass1-risk-keywords.txt +0 -238
  161. package/audit/evidence/code/critical-pass1-summary.csv +0 -67
  162. package/audit/evidence/code/critical-pass2-summary.csv +0 -67
  163. package/audit/evidence/code/early-silent-zones-no-test-token.txt +0 -57
  164. package/audit/evidence/code/error-model-signals.txt +0 -98
  165. package/audit/evidence/code/git-files-json-rest-api.txt +0 -171
  166. package/audit/evidence/code/git-files-json-rest-schema.txt +0 -27
  167. package/audit/evidence/code/hook-flow-signals.txt +0 -282
  168. package/audit/evidence/code/idproperty-signals.txt +0 -157
  169. package/audit/evidence/code/import-cycles-non-anyapi.txt +0 -3
  170. package/audit/evidence/code/import-hotspots-non-anyapi.txt +0 -96
  171. package/audit/evidence/code/imports-json-rest-api.txt +0 -354
  172. package/audit/evidence/code/imports-json-rest-schema.txt +0 -15
  173. package/audit/evidence/code/in-scope-files-json-rest-api.txt +0 -160
  174. package/audit/evidence/code/in-scope-files-json-rest-schema.txt +0 -13
  175. package/audit/evidence/code/non-anyapi-core-files.txt +0 -101
  176. package/audit/evidence/code/permission-signals.txt +0 -193
  177. package/audit/evidence/code/query-include-signals.txt +0 -687
  178. package/audit/evidence/code/transaction-signals.txt +0 -28
  179. package/audit/evidence/code/validation-signals.txt +0 -650
  180. package/audit/evidence/code/write-path-signals.txt +0 -61
  181. package/audit/evidence/docs/docs-claims-signals.txt +0 -1075
  182. package/audit/evidence/docs/schema-docs-claims-signals.txt +0 -179
  183. package/audit/evidence/external/corpus-freeze.md +0 -21
  184. package/audit/evidence/external/npm-competitor-metadata.txt +0 -70
  185. package/audit/evidence/external/npm-download-signals.txt +0 -23
  186. package/audit/evidence/external/npm-jsonapi-server.txt +0 -8
  187. package/audit/evidence/external/npm-modern-jsonapi-metadata.txt +0 -38
  188. package/audit/evidence/external/readme-fortune-signals.txt +0 -26
  189. package/audit/evidence/external/readme-fortune.md +0 -165
  190. package/audit/evidence/external/readme-json-api-serializer-signals.txt +0 -80
  191. package/audit/evidence/external/readme-json-api-serializer.md +0 -690
  192. package/audit/evidence/external/readme-jsonapi-serde-server-signals.txt +0 -0
  193. package/audit/evidence/external/readme-jsonapi-serde-server.md +0 -22
  194. package/audit/evidence/external/readme-jsonapi-serializer-signals.txt +0 -63
  195. package/audit/evidence/external/readme-jsonapi-serializer.md +0 -315
  196. package/audit/evidence/external/readme-jsonapi-server-signals.txt +0 -19
  197. package/audit/evidence/external/readme-jsonapi-server.md +0 -104
  198. package/audit/evidence/external/readme-nestjs-json-api-signals.txt +0 -4
  199. package/audit/evidence/external/readme-nestjs-json-api.md +0 -94
  200. package/audit/evidence/external/readme-yaser-json-api-nestjs-signals.txt +0 -47
  201. package/audit/evidence/external/readme-yaser-json-api-nestjs.md +0 -447
  202. package/audit/evidence/external/standard-jsonapi-snippets.txt +0 -84
  203. package/audit/evidence/external/standard-rfc-snippets.txt +0 -168
  204. package/audit/evidence/external/standards-sources.txt +0 -6
  205. package/audit/evidence/runtime/baseline-commits.txt +0 -2
  206. package/audit/evidence/runtime/db-adapter-assumptions.txt +0 -3
  207. package/audit/evidence/runtime/environment.txt +0 -4
  208. package/audit/evidence/runtime/invariant-runtime-mapping.md +0 -38
  209. package/audit/evidence/runtime/probe-patch-relationship-error.exitcode +0 -1
  210. package/audit/evidence/runtime/probe-patch-relationship-error.log +0 -76
  211. package/audit/evidence/runtime/probe-patch-relationship-error.mjs +0 -67
  212. package/audit/evidence/runtime/probe-patch-relationship-referenceerror.exitcode +0 -1
  213. package/audit/evidence/runtime/probe-patch-relationship-referenceerror.log +0 -62
  214. package/audit/evidence/runtime/probe-patch-relationship-referenceerror.mjs +0 -47
  215. package/audit/evidence/runtime/test-exitcodes.txt +0 -4
  216. package/audit/evidence/runtime/test-summary.md +0 -107
  217. package/audit/evidence/runtime/trace-anchors.txt +0 -61
  218. package/audit/evidence/tests/access-multitenancy-test-signals.txt +0 -125
  219. package/audit/evidence/tests/failing-tests-summary.txt +0 -25
  220. package/audit/evidence/tests/npm-test-json-rest-api.exitcode +0 -1
  221. package/audit/evidence/tests/npm-test-json-rest-api.log +0 -5885
  222. package/audit/evidence/tests/npm-test-json-rest-schema.exitcode +0 -1
  223. package/audit/evidence/tests/npm-test-json-rest-schema.log +0 -356
  224. package/audit/evidence/tests/query-include-test-signals.txt +0 -948
  225. package/audit/evidence/tests/relationship-test-signals.txt +0 -223
  226. package/audit/evidence/tests/skipped-tests.txt +0 -10
  227. package/audit/evidence/tests/test-suite-list-non-anyapi.txt +0 -30
  228. package/audit/evidence/tests/test-suite-list.txt +0 -32
  229. package/audit/subsystems/docs-drift.md +0 -49
  230. package/audit/subsystems/pass2-cross-review.md +0 -131
  231. package/audit/subsystems/plugins-access.md +0 -51
  232. package/audit/subsystems/plugins-bulk.md +0 -50
  233. package/audit/subsystems/plugins-cors.md +0 -48
  234. package/audit/subsystems/plugins-file.md +0 -53
  235. package/audit/subsystems/plugins-multihome.md +0 -50
  236. package/audit/subsystems/plugins-positioning.md +0 -54
  237. package/audit/subsystems/plugins-socketio.md +0 -50
  238. package/audit/subsystems/query-engine.md +0 -61
  239. package/audit/subsystems/relationships.md +0 -55
  240. package/audit/subsystems/rest-orchestration.md +0 -66
  241. package/audit/subsystems/schema-core.md +0 -64
  242. package/audit/subsystems/storage-knex.md +0 -57
  243. package/audit/subsystems/tests.md +0 -48
  244. package/audit/subsystems/transport-express.md +0 -55
  245. package/audit/traces/trace-read-get.md +0 -22
  246. package/audit/traces/trace-read-query.md +0 -25
  247. package/audit/traces/trace-relationship-endpoints.md +0 -31
  248. package/audit/traces/trace-write-delete.md +0 -17
  249. package/audit/traces/trace-write-patch.md +0 -26
  250. package/audit/traces/trace-write-post.md +0 -22
  251. package/audit/traces/trace-write-put.md +0 -23
  252. package/docs/GUIDE/GUIDE_4_Authentication_And_Permissions.md +0 -707
  253. package/docs/GUIDE/GUIDE_X_Multihome.md +0 -666
  254. package/plugins/core/lib/querying-writing/payload-validators.js +0 -1314
  255. package/plugins/core/rest-api-access.js +0 -459
  256. package/plugins/core/rest-api-multihome-plugin.js +0 -314
  257. package/tests/multihome.test.js +0 -553
  258. package/tests/multihome.test.js.bak +0 -550
  259. package/tests/ownership-optout.test.js +0 -76
  260. package/tests/rest-api-access.test.js +0 -206
@@ -1,948 +0,0 @@
1
- tests/custom-idproperty-relationships.test.js:151: // Verify through GET with include
2
- tests/custom-idproperty-relationships.test.js:154: queryParams: {
3
- tests/custom-idproperty-relationships.test.js:155: include: ['country']
4
- tests/custom-idproperty-relationships.test.js:160: assert(getResult.included, 'Should have included data')
5
- tests/custom-idproperty-relationships.test.js:161: assert.equal(getResult.included.length, 1)
6
- tests/custom-idproperty-relationships.test.js:162: assert.equal(getResult.included[0].type, 'countries')
7
- tests/custom-idproperty-relationships.test.js:163: assert.equal(getResult.included[0].attributes.name, 'United States')
8
- tests/custom-idproperty-relationships.test.js:204: // Verify update via GET with include
9
- tests/custom-idproperty-relationships.test.js:207: queryParams: { include: ['country'] }
10
- tests/custom-idproperty-relationships.test.js:210: assert.equal(updated.included[0].id, country2.data.id)
11
- tests/custom-idproperty-relationships.test.js:211: assert.equal(updated.included[0].attributes.name, 'UK')
12
- tests/custom-idproperty-relationships.test.js:288: // Verify through GET with include
13
- tests/custom-idproperty-relationships.test.js:291: queryParams: { include: ['authors'] }
14
- tests/custom-idproperty-relationships.test.js:294: assert(getResult.included)
15
- tests/custom-idproperty-relationships.test.js:295: assert.equal(getResult.included.length, 2)
16
- tests/custom-idproperty-relationships.test.js:296: const includedNames = getResult.included.map(a => a.attributes.name).sort()
17
- tests/custom-idproperty-relationships.test.js:297: assert.deepEqual(includedNames, ['Author One', 'Author Two'])
18
- tests/custom-idproperty-relationships.test.js:328: queryParams: {
19
- tests/custom-idproperty-relationships.test.js:329: include: ['authors']
20
- tests/custom-idproperty-relationships.test.js:335: // With include, we should get the authors relationship data
21
- tests/custom-idproperty-relationships.test.js:342: queryParams: { include: ['authors'] }
22
- tests/custom-idproperty-relationships.test.js:345: assert.equal(updated.included.length, 2)
23
- tests/custom-idproperty-relationships.test.js:424: it('should query polymorphic reviews by type', async () => {
24
- tests/custom-idproperty-relationships.test.js:449: const bookReviews = await api.resources.reviews.query({
25
- tests/custom-idproperty-relationships.test.js:450: queryParams: {
26
- tests/custom-idproperty-relationships.test.js:467: it('should handle nested includes through custom ID relationships', async () => {
27
- tests/custom-idproperty-relationships.test.js:495: // Query with nested includes
28
- tests/custom-idproperty-relationships.test.js:496: const result = await api.resources.books.query({
29
- tests/custom-idproperty-relationships.test.js:497: queryParams: {
30
- tests/custom-idproperty-relationships.test.js:498: include: ['publisher.country', 'authors']
31
- tests/custom-idproperty-relationships.test.js:503: assert(result.included)
32
- tests/custom-idproperty-relationships.test.js:505: // Find each type in included
33
- tests/custom-idproperty-relationships.test.js:506: const includedPublisher = result.included.find(r => r.type === 'publishers')
34
- tests/custom-idproperty-relationships.test.js:507: const includedCountry = result.included.find(r => r.type === 'countries')
35
- tests/custom-idproperty-relationships.test.js:508: const includedAuthor = result.included.find(r => r.type === 'authors')
36
- tests/custom-idproperty-relationships.test.js:510: assert(includedPublisher, 'Should include publisher')
37
- tests/custom-idproperty-relationships.test.js:511: assert(includedCountry, 'Should include country')
38
- tests/custom-idproperty-relationships.test.js:512: assert(includedAuthor, 'Should include author')
39
- tests/custom-idproperty-relationships.test.js:515: assert.equal(includedPublisher.relationships.country.data.id, country.data.id)
40
- tests/custom-idproperty-relationships.test.js:518: it('should handle 3+ levels of nested includes', async () => {
41
- tests/custom-idproperty-relationships.test.js:550: const result = await api.resources.books.query({
42
- tests/custom-idproperty-relationships.test.js:551: queryParams: {
43
- tests/custom-idproperty-relationships.test.js:552: include: ['authors.country', 'publisher.country']
44
- tests/custom-idproperty-relationships.test.js:557: assert(result.included)
45
- tests/custom-idproperty-relationships.test.js:559: const types = result.included.map(r => r.type)
46
- tests/custom-idproperty-relationships.test.js:560: assert(types.includes('authors'), 'Should include authors')
47
- tests/custom-idproperty-relationships.test.js:561: assert(types.includes('publishers'), 'Should include publishers')
48
- tests/custom-idproperty-relationships.test.js:562: assert(types.includes('countries'), 'Should include countries')
49
- tests/custom-idproperty-relationships.test.js:607: it('should combine sparse fieldsets with includes using custom IDs', async () => {
50
- tests/custom-idproperty-relationships.test.js:610: queryParams: {
51
- tests/custom-idproperty-relationships.test.js:611: include: ['publisher', 'authors'],
52
- tests/custom-idproperty-relationships.test.js:625: // Check included resources have only requested fields
53
- tests/custom-idproperty-relationships.test.js:626: const publisher = result.included.find(r => r.type === 'publishers')
54
- tests/custom-idproperty-relationships.test.js:628: assert(publisher.id) // ID is always included
55
- tests/custom-idproperty-relationships.test.js:630: const author = result.included.find(r => r.type === 'authors')
56
- tests/custom-idproperty-relationships.test.js:645: it('should enforce include depth limits', async () => {
57
- tests/custom-idproperty-relationships.test.js:678: const validDepth = await api.resources.books.query({
58
- tests/custom-idproperty-relationships.test.js:679: queryParams: {
59
- tests/custom-idproperty-relationships.test.js:680: include: ['authors.country']
60
- tests/custom-idproperty-relationships.test.js:687: const maxDepth = await api.resources.books.query({
61
- tests/custom-idproperty-relationships.test.js:688: queryParams: {
62
- tests/custom-idproperty-relationships.test.js:689: include: ['publisher.country', 'authors.country']
63
- tests/custom-idproperty-relationships.test.js:704: it('should handle complex queries with filters, includes, and custom IDs', async () => {
64
- tests/custom-idproperty-relationships.test.js:764: // Complex query: US books with their publishers and authors
65
- tests/custom-idproperty-relationships.test.js:765: const result = await api.resources.books.query({
66
- tests/custom-idproperty-relationships.test.js:766: queryParams: {
67
- tests/custom-idproperty-relationships.test.js:768: include: ['publisher.country', 'authors'],
68
- tests/custom-idproperty-relationships.test.js:776: // Verify includes
69
- tests/custom-idproperty-relationships.test.js:777: const includedTypes = result.included.map(r => r.type)
70
- tests/custom-idproperty-relationships.test.js:778: assert(includedTypes.includes('publishers'))
71
- tests/custom-idproperty-relationships.test.js:779: assert(includedTypes.includes('countries'))
72
- tests/custom-idproperty-relationships.test.js:780: assert(includedTypes.includes('authors'))
73
- tests/custom-idproperty-relationships.test.js:813: queryParams: { include: ['authors'] }
74
- tests/custom-idproperty-relationships.test.js:816: assert.equal(bookWithAuthors.included.length, 3)
75
- tests/custom-idproperty-relationships.test.js:850: assert(error.message.includes('not found') || error.message.includes('404'))
76
- tests/cors.test.js:146: includeExpress: true,
77
- tests/cors.test.js:273: assert(response.headers['access-control-allow-headers'].includes('X-Custom-Header'))
78
- tests/cors.test.js:384: includeExpress: true,
79
- tests/cors.test.js:421: includeExpress: true,
80
- tests/cors.test.js:467: includeExpress: true,
81
- tests/cors.test.js:508: includeExpress: true,
82
- tests/cors.test.js:526: assert(response.body.error.includes('CORS origin not allowed'))
83
- tests/cors.test.js:587: includeExpress: true,
84
- tests/cors.test.js:614: includeExpress: true,
85
- tests/cors.test.js:641: includeExpress: true,
86
- tests/cors.test.js:668: includeExpress: true,
87
- tests/cors.test.js:697: includeExpress: true,
88
- tests/cors.test.js:774: assert(response.headers['access-control-allow-methods'].includes('PUT'))
89
- tests/cors.test.js:785: includeExpress: true,
90
- tests/cors.test.js:813: includeExpress: true,
91
- tests/curl.test.js:71: basicApi = await createBasicApi(knex, { includeExpress: true })
92
- tests/curl.test.js:216: it('should handle query parameters using CURL', async () => {
93
- tests/curl.test.js:239: it('should handle includes using CURL', async () => {
94
- tests/curl.test.js:250: const result = await executeCurl(['-s', '-H', 'Accept: application/vnd.api+json', `http://localhost:${TEST_PORT}/api/publishers/${publisherResult.data.id}?include=country`])
95
- tests/curl.test.js:258: assert(response.included, 'Should have included data')
96
- tests/curl.test.js:259: assert.equal(response.included.length, 1, 'Should include one resource')
97
- tests/curl.test.js:260: assert.equal(response.included[0].type, 'countries')
98
- tests/curl.test.js:261: assert.equal(response.included[0].id, testData.country.id)
99
- tests/curl.test.js:327: assert(result.stderr.includes('X-Custom-Header: test-value'), 'Should send custom header')
100
- tests/curl.test.js:328: assert(result.stderr.includes('User-Agent: CURL-Test/1.0'), 'Should send custom user agent')
101
- tests/curl.test.js:388: it('should handle nested includes using CURL', async () => {
102
- tests/curl.test.js:389: const result = await executeCurl(['-s', '-H', 'Accept: application/vnd.api+json', `http://localhost:${TEST_PORT}/api/books/${testData.book.id}?include=publisher.country,authors`])
103
- tests/curl.test.js:397: assert(response.included, 'Should have included data')
104
- tests/curl.test.js:399: // Should include publisher, country, and 2 authors
105
- tests/curl.test.js:400: assert.equal(response.included.length, 4, 'Should include 4 resources')
106
- tests/curl.test.js:402: const includedTypes = response.included.map(r => r.type)
107
- tests/curl.test.js:403: assert(includedTypes.includes('publishers'), 'Should include publisher')
108
- tests/curl.test.js:404: assert(includedTypes.includes('countries'), 'Should include country')
109
- tests/curl.test.js:405: assert.equal(includedTypes.filter(t => t === 'authors').length, 2, 'Should include 2 authors')
110
- tests/curl.test.js:408: it('should handle pagination using CURL', async () => {
111
- tests/curl.test.js:423: // Test pagination (URL encode square brackets)
112
- tests/curl.test.js:432: // Note: Links are now always included, using relative URLs whenreturnBasePath isn't configured
113
- tests/curl.test.js:449: it('should handle sparse fieldsets using CURL', async () => {
114
- tests/curl.test.js:450: const result = await executeCurl(['-s', '-H', 'Accept: application/vnd.api+json', `http://localhost:${TEST_PORT}/api/books/${testData.book.id}?fields%5Bbooks%5D=title&fields%5Bpublishers%5D=name&include=publisher`])
115
- tests/curl.test.js:462: const publisher = response.included.find(r => r.type === 'publishers')
116
- tests/pagination-cursor-multifield.test.js:25: // Initialize API once with cursor pagination configuration
117
- tests/pagination-cursor-multifield.test.js:36: await cleanTables(knex, ['cursor_products'])
118
- tests/pagination-cursor-multifield.test.js:58: it.skip('should handle cursor pagination with multi-field sorting without skipping records', async () => {
119
- tests/pagination-cursor-multifield.test.js:62: let cursor = null
120
- tests/pagination-cursor-multifield.test.js:65: // Collect all products through cursor pagination
121
- tests/pagination-cursor-multifield.test.js:67: const result = await api.resources.products.query({
122
- tests/pagination-cursor-multifield.test.js:68: queryParams: {
123
- tests/pagination-cursor-multifield.test.js:71: ...(cursor && { after: cursor })
124
- tests/pagination-cursor-multifield.test.js:82: if (!result.meta.pagination.hasMore) {
125
- tests/pagination-cursor-multifield.test.js:85: cursor = result.meta.pagination.cursor.next
126
- tests/pagination-cursor-multifield.test.js:107: const firstPage = await api.resources.products.query({
127
- tests/pagination-cursor-multifield.test.js:108: queryParams: {
128
- tests/pagination-cursor-multifield.test.js:115: const secondPage = await api.resources.products.query({
129
- tests/pagination-cursor-multifield.test.js:116: queryParams: {
130
- tests/pagination-cursor-multifield.test.js:119: after: firstPage.meta.pagination.cursor.next
131
- tests/pagination-cursor-multifield.test.js:132: assert(secondPageNames.includes('Apple') || secondPageNames.includes('Banana'),
132
- tests/pagination-cursor-multifield.test.js:133: 'Second page should include fruits that come after vegetables')
133
- tests/pagination-cursor-multifield.test.js:151: let cursor = null
134
- tests/pagination-cursor-multifield.test.js:156: const result = await api.resources.products.query({
135
- tests/pagination-cursor-multifield.test.js:157: queryParams: {
136
- tests/pagination-cursor-multifield.test.js:160: ...(cursor && { after: cursor })
137
- tests/pagination-cursor-multifield.test.js:169: if (!result.meta.pagination.hasMore) {
138
- tests/pagination-cursor-multifield.test.js:172: cursor = result.meta.pagination.cursor.next
139
- tests/pagination-cursor-multifield.test.js:176: assert(iterations < 20, 'Cursor pagination should converge within expected page count')
140
- tests/pagination-cursor-multifield.test.js:192: it.skip('should handle cursor pagination with numeric and text fields', async () => {
141
- tests/pagination-cursor-multifield.test.js:194: const firstPage = await api.resources.products.query({
142
- tests/pagination-cursor-multifield.test.js:195: queryParams: {
143
- tests/pagination-cursor-multifield.test.js:207: const secondPage = await api.resources.products.query({
144
- tests/pagination-cursor-multifield.test.js:208: queryParams: {
145
- tests/pagination-cursor-multifield.test.js:211: after: firstPage.meta.pagination.cursor.next
146
- tests/pagination-cursor-multifield.test.js:225: it.skip('should generate correct cursor values for multi-field sorting', async () => {
147
- tests/pagination-cursor-multifield.test.js:226: const result = await api.resources.products.query({
148
- tests/pagination-cursor-multifield.test.js:227: queryParams: {
149
- tests/pagination-cursor-multifield.test.js:234: // Check that cursor is present
150
- tests/pagination-cursor-multifield.test.js:235: assert(result.meta.pagination.cursor?.next, 'Should have next cursor')
151
- tests/pagination-cursor-multifield.test.js:237: // The cursor should be parseable (not throwing an error)
152
- tests/pagination-cursor-multifield.test.js:238: const cursor = result.meta.pagination.cursor.next
153
- tests/pagination-cursor-multifield.test.js:239: assert(typeof cursor === 'string', 'Cursor should be a string')
154
- tests/pagination-cursor-multifield.test.js:243: assert(cursor.includes('category:'), 'Cursor should include category field')
155
- tests/pagination-cursor-multifield.test.js:244: assert(cursor.includes('name:'), 'Cursor should include name field')
156
- tests/pagination-cursor-multifield.test.js:249: const firstPage = await api.resources.products.query({
157
- tests/pagination-cursor-multifield.test.js:250: queryParams: {
158
- tests/pagination-cursor-multifield.test.js:257: const secondPage = await api.resources.products.query({
159
- tests/pagination-cursor-multifield.test.js:258: queryParams: {
160
- tests/pagination-cursor-multifield.test.js:261: after: firstPage.meta.pagination.cursor.next
161
- tests/pagination-cursor-multifield.test.js:269: const previousPage = await api.resources.products.query({
162
- tests/pagination-cursor-multifield.test.js:270: queryParams: {
163
- tests/pagination-cursor-multifield.test.js:273: before: secondPage.meta.pagination.cursor?.next ||
164
- tests/pagination-cursor-multifield.test.js:274: // If no next cursor, create one from the last record
165
- tests/pagination-cursor-multifield.test.js:285: assert(!secondPageIds.some(id => previousPageIds.includes(id)),
166
- tests/pagination-cursor-multifield.test.js:292: await cleanTables(knex, ['cursor_products', 'cursor_items'])
167
- tests/pagination-cursor-multifield.test.js:315: let cursor = null
168
- tests/pagination-cursor-multifield.test.js:318: const result = await api.resources.products.query({
169
- tests/pagination-cursor-multifield.test.js:319: queryParams: {
170
- tests/pagination-cursor-multifield.test.js:322: ...(cursor && { after: cursor })
171
- tests/pagination-cursor-multifield.test.js:331: if (!result.meta.pagination.hasMore) {
172
- tests/pagination-cursor-multifield.test.js:334: cursor = result.meta.pagination.cursor.next
173
- tests/pagination-cursor-multifield.test.js:351: it.skip('should handle empty results with multi-field cursor', async () => {
174
- tests/pagination-cursor-multifield.test.js:365: const firstPage = await api.resources.products.query({
175
- tests/pagination-cursor-multifield.test.js:366: queryParams: {
176
- tests/pagination-cursor-multifield.test.js:374: assert.equal(firstPage.meta.pagination.hasMore, false)
177
- tests/pagination-cursor-multifield.test.js:375: assert(!firstPage.meta.pagination.cursor?.next, 'Should not have next cursor on last page')
178
- tests/pagination-cursor-multifield.test.js:378: it.skip('should handle special characters in multi-field cursors', async () => {
179
- tests/pagination-cursor-multifield.test.js:394: const firstPage = await api.resources.products.query({
180
- tests/pagination-cursor-multifield.test.js:395: queryParams: {
181
- tests/pagination-cursor-multifield.test.js:402: assert(firstPage.meta.pagination.cursor?.next, 'Should have cursor')
182
- tests/pagination-cursor-multifield.test.js:404: // Use the cursor to get next page - should not throw
183
- tests/pagination-cursor-multifield.test.js:405: const secondPage = await api.resources.products.query({
184
- tests/pagination-cursor-multifield.test.js:406: queryParams: {
185
- tests/pagination-cursor-multifield.test.js:409: after: firstPage.meta.pagination.cursor.next
186
- tests/pagination-cursor-multifield.test.js:438: const result = await api.resources.items.query({
187
- tests/pagination-cursor-multifield.test.js:439: queryParams: {
188
- tests/pagination-cursor-multifield.test.js:451: if (result.meta.pagination.cursor?.next) {
189
- tests/pagination-cursor-multifield.test.js:452: const secondPage = await api.resources.items.query({
190
- tests/pagination-cursor-multifield.test.js:453: queryParams: {
191
- tests/pagination-cursor-multifield.test.js:456: after: result.meta.pagination.cursor.next
192
- tests/pagination-cursor-multifield.test.js:469: await cleanTables(knex, ['cursor_products'])
193
- tests/pagination-cursor-multifield.test.js:487: const firstPage = await api.resources.products.query({
194
- tests/pagination-cursor-multifield.test.js:488: queryParams: {
195
- tests/pagination-cursor-multifield.test.js:499: // Get second page - MUST include Date (the bug would skip it)
196
- tests/pagination-cursor-multifield.test.js:500: const secondPage = await api.resources.products.query({
197
- tests/pagination-cursor-multifield.test.js:501: queryParams: {
198
- tests/pagination-cursor-multifield.test.js:504: after: firstPage.meta.pagination.cursor.next
199
- tests/pagination-cursor-multifield.test.js:512: assert(secondPageNames.includes('Date'),
200
- tests/pagination-cursor-multifield.test.js:513: 'Second page MUST include Date - this was the bug where it would be skipped')
201
- tests/ownership-optout.test.js:48: it('ownerField:false - allows create+query without user_id column present', async () => {
202
- tests/ownership-optout.test.js:53: const resultAuth = await api.resources.public_items_ownerfield.query({ simplified: false }, { auth: { userId: 1 } })
203
- tests/ownership-optout.test.js:58: const resultNoAuth = await api.resources.public_items_ownerfield.query({ simplified: false })
204
- tests/ownership-optout.test.js:63: it('ownership:false - allows create+query without user_id column present', async () => {
205
- tests/ownership-optout.test.js:67: const resultAuth = await api.resources.public_items_ownership.query({ simplified: false }, { auth: { userId: 99 } })
206
- tests/ownership-optout.test.js:71: const resultNoAuth = await api.resources.public_items_ownership.query({ simplified: false })
207
- tests/nested-includes.test.js:29: name: 'test-nested-includes'
208
- tests/nested-includes.test.js:33: queryDefaultLimit: 10,
209
- tests/nested-includes.test.js:34: queryMaxLimit: 50,
210
- tests/nested-includes.test.js:64: // Relationships are always includable via ?include=
211
- tests/nested-includes.test.js:83: // Relationships are always includable via ?include=
212
- tests/nested-includes.test.js:84: include: {
213
- tests/nested-includes.test.js:86: strategy: 'window'
214
- tests/nested-includes.test.js:106: // Relationships are always includable via ?include=
215
- tests/nested-includes.test.js:112: // Relationships are always includable via ?include=
216
- tests/nested-includes.test.js:242: it('should populate reverse relationships when using nested includes', async () => {
217
- tests/nested-includes.test.js:243: const result = await api.resources.authors.query({
218
- tests/nested-includes.test.js:244: queryParams: {
219
- tests/nested-includes.test.js:245: include: ['books', 'books.authors']
220
- tests/nested-includes.test.js:253: // Check that books are included
221
- tests/nested-includes.test.js:254: const books = result.included.filter(r => r.type === 'books')
222
- tests/nested-includes.test.js:255: assert.equal(books.length, 3, 'Should include 3 books')
223
- tests/nested-includes.test.js:257: // Check that authors are included (for the books.authors include)
224
- tests/nested-includes.test.js:258: const includedAuthors = result.included.filter(r => r.type === 'authors')
225
- tests/nested-includes.test.js:259: assert.equal(includedAuthors.length, 2, 'Should include 2 authors')
226
- tests/nested-includes.test.js:279: it('should work with window strategy limits', async () => {
227
- tests/nested-includes.test.js:280: // Create more books to test window limits
228
- tests/nested-includes.test.js:281: const publisher = await api.resources.publishers.query({ simplified: false })
229
- tests/nested-includes.test.js:285: const authorsResult = await api.resources.authors.query({ simplified: false })
230
- tests/nested-includes.test.js:306: const result = await api.resources.authors.query({
231
- tests/nested-includes.test.js:307: queryParams: {
232
- tests/nested-includes.test.js:308: include: ['books', 'books.authors'],
233
- tests/nested-includes.test.js:316: // But window limit is 5, so should only get 5
234
- tests/nested-includes.test.js:321: // The window limit should apply
235
- tests/nested-includes.test.js:324: assert(bookCount <= 5, `Author 1 should have at most 5 books (window limit), got ${bookCount}`)
236
- tests/nested-includes.test.js:326: // All included books should have their authors relationship populated
237
- tests/nested-includes.test.js:327: const books = result.included.filter(r => r.type === 'books')
238
- tests/nested-includes.test.js:328: assert(books.length >= 2, 'Should include at least 2 books')
239
- tests/nested-includes.test.js:405: it('should handle 3+ levels of nested includes', async () => {
240
- tests/nested-includes.test.js:406: const result = await api.resources.authors.query({
241
- tests/nested-includes.test.js:407: queryParams: {
242
- tests/nested-includes.test.js:408: include: ['books', 'books.publisher', 'books.publisher.country']
243
- tests/nested-includes.test.js:415: // Check all resource types are included
244
- tests/nested-includes.test.js:416: const books = result.included.filter(r => r.type === 'books')
245
- tests/nested-includes.test.js:417: const publishers = result.included.filter(r => r.type === 'publishers')
246
- tests/nested-includes.test.js:418: const countries = result.included.filter(r => r.type === 'countries')
247
- tests/nested-includes.test.js:420: assert.equal(books.length, 2, 'Should include 2 books')
248
- tests/nested-includes.test.js:421: assert.equal(publishers.length, 2, 'Should include 2 publishers')
249
- tests/nested-includes.test.js:422: // All defined relationships will be included when requested via ?include=
250
- tests/nested-includes.test.js:435: const result = await api.resources.publishers.query({
251
- tests/nested-includes.test.js:436: queryParams: {
252
- tests/nested-includes.test.js:437: include: ['books', 'books.authors', 'books.authors.country', 'country']
253
- tests/nested-includes.test.js:445: const countries = result.included.filter(r => r.type === 'countries')
254
- tests/nested-includes.test.js:450: const authors = result.included.filter(r => r.type === 'authors')
255
- tests/nested-includes.test.js:516: it('should respect sparse fieldsets with nested includes', async () => {
256
- tests/nested-includes.test.js:517: const result = await api.resources.authors.query({
257
- tests/nested-includes.test.js:518: queryParams: {
258
- tests/nested-includes.test.js:519: include: ['books', 'books.reviews'],
259
- tests/nested-includes.test.js:531: // Check sparse fieldsets are applied
260
- tests/nested-includes.test.js:535: const book = result.included.find(r => r.type === 'books')
261
- tests/nested-includes.test.js:536: assert(book, 'Should include book')
262
- tests/nested-includes.test.js:541: const review = result.included.find(r => r.type === 'reviews')
263
- tests/nested-includes.test.js:542: assert(review, 'Should include review')
264
- tests/nested-includes.test.js:590: it('should handle circular includes gracefully', async () => {
265
- tests/nested-includes.test.js:591: const result = await api.resources.books.query({
266
- tests/nested-includes.test.js:592: queryParams: {
267
- tests/nested-includes.test.js:593: include: ['authors', 'authors.books', 'authors.books.authors']
268
- tests/nested-includes.test.js:601: const books = result.data.concat(result.included.filter(r => r.type === 'books'))
269
- tests/nested-includes.test.js:602: const authors = result.included.filter(r => r.type === 'authors')
270
- tests/positioning.test.js:226: const { data: allTasks } = await api.resources.tasks.query({
271
- tests/positioning.test.js:227: queryParams: {
272
- tests/positioning.test.js:532: const { data: sorted } = await api.resources.tasks.query({
273
- tests/positioning.test.js:533: queryParams: {
274
- tests/positioning.test.js:547: const { data: reverseSorted } = await api.resources.tasks.query({
275
- tests/positioning.test.js:548: queryParams: {
276
- tests/computed-fields.test.js:73: // normallyHidden fields should not be included
277
- tests/computed-fields.test.js:110: queryParams: {
278
- tests/computed-fields.test.js:119: // Other fields should not be included
279
- tests/computed-fields.test.js:125: it('should fetch dependencies but not include them in response', async () => {
280
- tests/computed-fields.test.js:128: queryParams: {
281
- tests/computed-fields.test.js:136: // Dependencies should not be included
282
- tests/computed-fields.test.js:144: queryParams: {
283
- tests/computed-fields.test.js:160: queryParams: {
284
- tests/computed-fields.test.js:168: // Shared dependencies should not be included
285
- tests/computed-fields.test.js:175: it('should compute fields in hasMany included resources', async () => {
286
- tests/computed-fields.test.js:178: queryParams: {
287
- tests/computed-fields.test.js:179: include: ['reviews']
288
- tests/computed-fields.test.js:195: it('should apply sparse fieldsets to included resources with computed fields', async () => {
289
- tests/computed-fields.test.js:198: queryParams: {
290
- tests/computed-fields.test.js:199: include: ['reviews'],
291
- tests/computed-fields.test.js:216: // Other fields should not be included
292
- tests/computed-fields.test.js:223: it('should handle computed dependencies in included resources', async () => {
293
- tests/computed-fields.test.js:226: queryParams: {
294
- tests/computed-fields.test.js:227: include: ['reviews'],
295
- tests/computed-fields.test.js:238: // Dependencies should not be included
296
- tests/computed-fields.test.js:247: const products = await api.resources.products.query()
297
- tests/computed-fields.test.js:255: it('should apply sparse fieldsets to collections', async () => {
298
- tests/computed-fields.test.js:256: const products = await api.resources.products.query({
299
- tests/computed-fields.test.js:257: queryParams: {
300
- tests/computed-fields.test.js:269: it('should handle includes with computed fields in collections', async () => {
301
- tests/computed-fields.test.js:270: const products = await api.resources.products.query({
302
- tests/computed-fields.test.js:271: queryParams: {
303
- tests/computed-fields.test.js:272: include: ['reviews'],
304
- tests/computed-fields.test.js:293: it('should always include minimal relationship objects regardless of sparse fieldsets', async () => {
305
- tests/computed-fields.test.js:296: queryParams: {
306
- tests/computed-fields.test.js:301: // Minimal relationship objects should still be included
307
- tests/computed-fields.test.js:311: it('should include empty arrays for empty relationships', async () => {
308
- tests/computed-fields.test.js:320: queryParams: {
309
- tests/computed-fields.test.js:360: it('should reject unknown fields in sparse fieldsets', async () => {
310
- tests/computed-fields.test.js:364: queryParams: {
311
- tests/computed-fields.test.js:368: /Unknown sparse field 'unknown_field'/
312
- tests/computed-fields.test.js:372: it('should reject requests for _ids fields in sparse fieldsets', async () => {
313
- tests/computed-fields.test.js:376: queryParams: {
314
- tests/computed-fields.test.js:380: /Unknown sparse field 'reviews_ids'/
315
- tests/computed-fields.test.js:485: queryParams: {
316
- tests/queries.test.js:126: const result = await basicApi.resources.books.query({
317
- tests/queries.test.js:127: queryParams: {
318
- tests/queries.test.js:147: const result = await basicApi.resources.books.query({
319
- tests/queries.test.js:148: queryParams: {
320
- tests/queries.test.js:163: const result = await basicApi.resources.books.query({
321
- tests/queries.test.js:164: queryParams: {
322
- tests/queries.test.js:177: await basicApi.resources.countries.query({
323
- tests/queries.test.js:178: queryParams: {
324
- tests/queries.test.js:222: const result = await basicApi.resources.books.query({
325
- tests/queries.test.js:223: queryParams: {
326
- tests/queries.test.js:237: const result = await basicApi.resources.books.query({
327
- tests/queries.test.js:238: queryParams: {
328
- tests/queries.test.js:286: const result = await basicApi.resources.books.query({
329
- tests/queries.test.js:287: queryParams: {
330
- tests/queries.test.js:356: const page1 = await basicApi.resources.books.query({
331
- tests/queries.test.js:357: queryParams: {
332
- tests/queries.test.js:371: const page2 = await basicApi.resources.books.query({
333
- tests/queries.test.js:372: queryParams: {
334
- tests/queries.test.js:388: assert.equal(page1Ids.some(id => page2Ids.includes(id)), false, 'Pages should have different results')
335
- tests/queries.test.js:392: const lastPage = await basicApi.resources.books.query({
336
- tests/queries.test.js:393: queryParams: {
337
- tests/queries.test.js:406: const emptyPage = await basicApi.resources.books.query({
338
- tests/queries.test.js:407: queryParams: {
339
- tests/queries.test.js:417: it('should respect queryMaxLimit limit', async () => {
340
- tests/queries.test.js:418: // Assuming queryMaxLimit is 100 (from vars)
341
- tests/queries.test.js:419: const result = await basicApi.resources.books.query({
342
- tests/queries.test.js:420: queryParams: {
343
- tests/queries.test.js:427: assert(result.data.length <= 100, 'Should not exceed queryMaxLimit')
344
- tests/queries.test.js:480: const result = await extendedApi.resources.books.query({
345
- tests/queries.test.js:481: queryParams: {
346
- tests/queries.test.js:497: it('should filter and include relationships', async () => {
347
- tests/queries.test.js:498: const result = await extendedApi.resources.books.query({
348
- tests/queries.test.js:499: queryParams: {
349
- tests/queries.test.js:501: include: ['country']
350
- tests/queries.test.js:509: // Verify includes
351
- tests/queries.test.js:510: assert(result.included, 'Should have included data')
352
- tests/queries.test.js:511: const includedCountries = result.included.filter(r => r.type === 'countries')
353
- tests/queries.test.js:512: assert(includedCountries.length >= 1, 'Should include at least one country')
354
- tests/queries.test.js:514: // Verify included countries have the expected fields
355
- tests/queries.test.js:515: for (const country of includedCountries) {
356
- tests/socketio.test.js:184: assert(!notification.data, 'Should not include data in notification')
357
- tests/positioning-multifilter.test.js:101: const { data: p1ActiveItems } = await api.resources.items.query({
358
- tests/positioning-multifilter.test.js:102: queryParams: {
359
- tests/positioning-multifilter.test.js:112: const { data: p1ArchivedItems } = await api.resources.items.query({
360
- tests/positioning-multifilter.test.js:113: queryParams: {
361
- tests/positioning-multifilter.test.js:123: const { data: p2ActiveItems } = await api.resources.items.query({
362
- tests/positioning-multifilter.test.js:124: queryParams: {
363
- tests/positioning-multifilter.test.js:173: const { data: projectActiveItems } = await api.resources.items.query({
364
- tests/positioning-multifilter.test.js:174: queryParams: {
365
- tests/positioning-multifilter.test.js:182: const { data: projectNullStatusItems } = await api.resources.items.query({
366
- tests/positioning-multifilter.test.js:183: queryParams: {
367
- tests/positioning-multifilter.test.js:191: const { data: nullProjectActiveItems } = await api.resources.items.query({
368
- tests/positioning-multifilter.test.js:192: queryParams: {
369
- tests/positioning-multifilter.test.js:200: const { data: bothNullItems } = await api.resources.items.query({
370
- tests/positioning-multifilter.test.js:201: queryParams: {
371
- tests/positioning-multifilter.test.js:243: const { data: archivedItems } = await api.resources.items.query({
372
- tests/positioning-multifilter.test.js:244: queryParams: {
373
- tests/positioning-multifilter.test.js:262: const { data: activeItems } = await api.resources.items.query({
374
- tests/positioning-multifilter.test.js:263: queryParams: {
375
- tests/positioning-multifilter.test.js:315: const { data: p1Items } = await api.resources.items.query({
376
- tests/positioning-multifilter.test.js:316: queryParams: {
377
- tests/positioning-multifilter.test.js:327: const { data: p2Items } = await api.resources.items.query({
378
- tests/positioning-multifilter.test.js:328: queryParams: {
379
- tests/positioning-multifilter.test.js:345: const { data: p1ActiveItems } = await api.resources.items.query({
380
- tests/positioning-multifilter.test.js:346: queryParams: {
381
- tests/positioning-multifilter.test.js:355: const { data: p1ArchivedItems } = await api.resources.items.query({
382
- tests/positioning-multifilter.test.js:356: queryParams: {
383
- tests/positioning-multifilter.test.js:408: const { data: filtered } = await multiApi.resources.items.query({
384
- tests/positioning-multifilter.test.js:409: queryParams: {
385
- tests/positioning-multifilter.test.js:438: const { data: activeHighItems } = await multiApi.resources.items.query({
386
- tests/positioning-multifilter.test.js:439: queryParams: {
387
- tests/positioning-multifilter.test.js:489: const { data: activeItems } = await api.resources.items.query({
388
- tests/positioning-multifilter.test.js:490: queryParams: {
389
- tests/positioning-multifilter.test.js:548: const { data: p1Active } = await api.resources.items.query({
390
- tests/positioning-multifilter.test.js:549: queryParams: {
391
- tests/positioning-multifilter.test.js:556: const { data: p1Archived } = await api.resources.items.query({
392
- tests/positioning-multifilter.test.js:557: queryParams: {
393
- tests/positioning-multifilter.test.js:564: const { data: p2Active } = await api.resources.items.query({
394
- tests/positioning-multifilter.test.js:565: queryParams: {
395
- tests/positioning-multifilter.test.js:572: const { data: p2Archived } = await api.resources.items.query({
396
- tests/positioning-multifilter.test.js:573: queryParams: {
397
- tests/positioning-multifilter.test.js:622: const { data: emptyStatusItems } = await api.resources.items.query({
398
- tests/positioning-multifilter.test.js:623: queryParams: {
399
- tests/positioning-multifilter.test.js:633: const { data: nullStatusItems } = await api.resources.items.query({
400
- tests/positioning-multifilter.test.js:634: queryParams: {
401
- tests/positioning-multifilter.test.js:674: const { data: status1Items } = await api.resources.items.query({
402
- tests/positioning-multifilter.test.js:675: queryParams: {
403
- tests/positioning-multifilter.test.js:687: const { data: status01Items } = await api.resources.items.query({
404
- tests/positioning-multifilter.test.js:688: queryParams: {
405
- tests/virtual-fields.test.js:176: it('should respect sparse fieldsets with virtual fields on PATCH', async () => {
406
- tests/virtual-fields.test.js:179: username: 'sparseuser',
407
- tests/virtual-fields.test.js:180: email: 'sparse@example.com',
408
- tests/virtual-fields.test.js:206: queryParams: {
409
- tests/virtual-fields.test.js:223: it('should exclude virtual fields when not requested in sparse fieldsets', async () => {
410
- tests/virtual-fields.test.js:240: // Fetch with sparse fieldsets NOT including virtual fields
411
- tests/virtual-fields.test.js:243: queryParams: {
412
- tests/searchschema-merge.test.js:39: // First do a query to trigger schema compilation
413
- tests/searchschema-merge.test.js:40: await api.resources.products.query({
414
- tests/searchschema-merge.test.js:41: queryParams: {}
415
- tests/searchschema-merge.test.js:75: // Check that non-searchable fields are not included
416
- tests/searchschema-merge.test.js:80: // First do a query to trigger schema compilation
417
- tests/searchschema-merge.test.js:81: await api.resources.users.query({
418
- tests/searchschema-merge.test.js:82: queryParams: {}
419
- tests/searchschema-merge.test.js:98: // First do a query to trigger schema compilation
420
- tests/searchschema-merge.test.js:99: await api.resources.orders.query({
421
- tests/searchschema-merge.test.js:100: queryParams: {}
422
- tests/searchschema-merge.test.js:139: const nameResults = await api.resources.products.query({
423
- tests/searchschema-merge.test.js:140: queryParams: {
424
- tests/searchschema-merge.test.js:150: const priceResults = await api.resources.products.query({
425
- tests/searchschema-merge.test.js:151: queryParams: {
426
- tests/searchschema-merge.test.js:161: const statusResults = await api.resources.products.query({
427
- tests/searchschema-merge.test.js:162: queryParams: {
428
- tests/searchschema-merge.test.js:172: const skuResults = await api.resources.products.query({
429
- tests/searchschema-merge.test.js:173: queryParams: {
430
- tests/multihome.test.js:106: const resultA = await api.resources.projects.query({
431
- tests/multihome.test.js:117: const resultB = await api.resources.projects.query({
432
- tests/multihome.test.js:190: return err.message.includes('must match current context')
433
- tests/multihome.test.js:257: // Query with includes - should only see own tenant data
434
- tests/multihome.test.js:260: queryParams: {
435
- tests/multihome.test.js:261: include: ['tasks']
436
- tests/multihome.test.js:269: assert(projectWithTasks.included, 'Should have included tasks')
437
- tests/multihome.test.js:270: assert.equal(projectWithTasks.included.length, 1, 'Should include one task')
438
- tests/multihome.test.js:271: assert.equal(projectWithTasks.included[0].attributes.tenant_id, 'tenant-a')
439
- tests/multihome.test.js:291: const allSettings = await api.resources.system_settings.query({
440
- tests/multihome.test.js:322: return err.message.includes('multihome context')
441
- tests/multihome.test.js:335: assert(api.vars.multihome.excludeResources.includes('system_settings'))
442
- tests/multihome.test.js:376: const adminsA = await api.resources.users.query({
443
- tests/multihome.test.js:377: queryParams: {
444
- tests/multihome.test.js:389: const usersB = await api.resources.users.query({
445
- tests/multihome.test.js:399: it('should apply tenant filter with sorting and pagination', async () => {
446
- tests/multihome.test.js:425: // Query with pagination as tenant A
447
- tests/multihome.test.js:426: const page1 = await api.resources.projects.query({
448
- tests/multihome.test.js:427: queryParams: {
449
- tests/multihome.test.js:441: const page2 = await api.resources.projects.query({
450
- tests/multihome.test.js:442: queryParams: {
451
- tests/multihome.test.js:460: await api.resources.projects.query({
452
- tests/multihome.test.js:465: return err.message.includes('No multihome context available')
453
- tests/multihome.test.js:549: assert(err.code === 'REST_API_RESOURCE' || err.message.includes('Access denied'))
454
- tests/rest-api.test.js:129: queryParams: {
455
- tests/rest-api.test.js:130: include: ['country']
456
- tests/rest-api.test.js:142: // Verify included data
457
- tests/rest-api.test.js:143: assert(getResult.included, 'Should have included data')
458
- tests/rest-api.test.js:144: assert.equal(getResult.included.length, 1, 'Should include one resource')
459
- tests/rest-api.test.js:145: assert.equal(getResult.included[0].type, 'countries')
460
- tests/rest-api.test.js:146: assert.equal(getResult.included[0].attributes.name, 'United Kingdom')
461
- tests/rest-api.test.js:235: const queryResult = await basicApi.resources.countries.query({
462
- tests/rest-api.test.js:239: validateJsonApiStructure(queryResult, true)
463
- tests/rest-api.test.js:240: assert.equal(queryResult.data.length, 3, 'Should return 3 countries')
464
- tests/rest-api.test.js:243: const names = queryResult.data.map(c => c.attributes.name).sort()
465
- tests/bulk-operations.test.js:76: // Verify via API query
466
- tests/bulk-operations.test.js:77: const queryResult = await api.resources.authors.query({ simplified: false })
467
- tests/bulk-operations.test.js:78: assert.equal(queryResult.data.length, 3, 'Should have 3 records via query')
468
- tests/bulk-operations.test.js:95: assert(error.message.includes('validation failed') || error.message.includes('required'), 'Error should mention validation or required field')
469
- tests/bulk-operations.test.js:99: const queryResult = await api.resources.authors.query({ simplified: false })
470
- tests/bulk-operations.test.js:100: assert.equal(queryResult.data.length, 0, 'Should have no records due to rollback')
471
- tests/bulk-operations.test.js:127: assert(result.errors[0].error.message.includes('validation failed') || result.errors[0].error.message.includes('required'))
472
- tests/bulk-operations.test.js:130: const queryResult = await api.resources.authors.query({ simplified: false })
473
- tests/bulk-operations.test.js:131: assert.equal(queryResult.data.length, 3)
474
- tests/bulk-operations.test.js:173: assert(error.message.includes('limited to 100'))
475
- tests/bulk-operations.test.js:177: it('should respect atomic query parameter override', async () => {
476
- tests/bulk-operations.test.js:406: // Verify via API query
477
- tests/bulk-operations.test.js:407: const queryResult = await api.resources.authors.query({ simplified: false })
478
- tests/bulk-operations.test.js:408: assert.equal(queryResult.data.length, 2, 'Should have 2 remaining records')
479
- tests/bulk-operations.test.js:411: const remainingIds = queryResult.data.map(r => r.id)
480
- tests/bulk-operations.test.js:412: assert(!remainingIds.includes(testData.authorIds[0]))
481
- tests/bulk-operations.test.js:413: assert(remainingIds.includes(testData.authorIds[1]))
482
- tests/bulk-operations.test.js:414: assert(!remainingIds.includes(testData.authorIds[2]))
483
- tests/bulk-operations.test.js:441: const queryResult = await api.resources.authors.query({ simplified: false })
484
- tests/bulk-operations.test.js:442: assert.equal(queryResult.data.length, 2)
485
- tests/bulk-operations.test.js:463: const queryResult = await api.resources.authors.query({ simplified: false })
486
- tests/bulk-operations.test.js:464: assert.equal(queryResult.data.length, 5, 'Should still have all 5 records')
487
- tests/bulk-operations.test.js:474: assert(error.message.includes('array'))
488
- tests/bulk-operations.test.js:550: const queryResult = await api.resources.authors.query({
489
- tests/bulk-operations.test.js:552: queryParams: { page: { size: 100 } }
490
- tests/bulk-operations.test.js:554: assert.equal(queryResult.data.length, 50)
491
- tests/bulk-operations.test.js:611: const finalQuery = await api.resources.authors.query({ simplified: false })
492
- tests/bulk-operations.test.js:615: const seniorAuthors = finalQuery.data.filter(a => a.attributes.name.includes('Senior'))
493
- tests/bulk-operations.test.js:649: const allPublishers = await api.resources.publishers.query({
494
- tests/polymorphic-simple.test.js:88: it('should query all reviews', async () => {
495
- tests/polymorphic-simple.test.js:135: const result = await api.resources.reviews.query({})
496
- tests/positioning-advanced.test.js:198: const { data: tasks } = await api.resources.tasks.query({
497
- tests/positioning-advanced.test.js:199: queryParams: {
498
- tests/positioning-advanced.test.js:248: const { data: tasks } = await api.resources.tasks.query({
499
- tests/positioning-advanced.test.js:249: queryParams: {
500
- tests/positioning-advanced.test.js:298: const { data: items } = await api.resources.items.query({
501
- tests/positioning-advanced.test.js:299: queryParams: {
502
- tests/positioning-advanced.test.js:342: const { data: items } = await api.resources.items.query({
503
- tests/positioning-advanced.test.js:343: queryParams: {
504
- tests/positioning-advanced.test.js:390: const { data: tasks } = await api.resources.tasks.query({
505
- tests/positioning-advanced.test.js:391: queryParams: {
506
- tests/positioning-advanced.test.js:456: const { data: finalTasks } = await api.resources.tasks.query({
507
- tests/positioning-advanced.test.js:457: queryParams: {
508
- tests/positioning-advanced.test.js:502: const { data: allTasks } = await api.resources.tasks.query({
509
- tests/positioning-advanced.test.js:503: queryParams: {
510
- tests/positioning-advanced.test.js:518: const { data: updatedTasks } = await api.resources.tasks.query({
511
- tests/positioning-advanced.test.js:519: queryParams: {
512
- tests/positioning-advanced.test.js:551: const { data: tasks } = await api.resources.tasks.query({
513
- tests/positioning-advanced.test.js:552: queryParams: {
514
- tests/positioning-advanced.test.js:603: const { data: activeTasks } = await softDeleteApi.resources.tasks.query({
515
- tests/positioning-advanced.test.js:604: queryParams: {
516
- tests/positioning-advanced.test.js:663: const { data: v1Items } = await versionApi.resources.tasks.query({
517
- tests/positioning-advanced.test.js:664: queryParams: {
518
- tests/positioning-advanced.test.js:676: const { data: v2Items } = await versionApi.resources.tasks.query({
519
- tests/positioning-advanced.test.js:677: queryParams: {
520
- tests/positioning-extended.test.js:77: const { data: tasks } = await api.resources.tasks.query({
521
- tests/positioning-extended.test.js:78: queryParams: {
522
- tests/positioning-extended.test.js:123: const { data: tasks } = await api.resources.tasks.query({
523
- tests/positioning-extended.test.js:124: queryParams: {
524
- tests/positioning-extended.test.js:155: const { data: tasks } = await api.resources.tasks.query({
525
- tests/positioning-extended.test.js:156: queryParams: {
526
- tests/positioning-extended.test.js:183: const { data: cat2Tasks } = await api.resources.tasks.query({
527
- tests/positioning-extended.test.js:184: queryParams: {
528
- tests/positioning-extended.test.js:229: const { data: finalTasks } = await api.resources.tasks.query({
529
- tests/positioning-extended.test.js:230: queryParams: {
530
- tests/positioning-extended.test.js:273: const { data: cat1Tasks } = await api.resources.tasks.query({
531
- tests/positioning-extended.test.js:274: queryParams: {
532
- tests/positioning-extended.test.js:284: const { data: cat2Tasks } = await api.resources.tasks.query({
533
- tests/positioning-extended.test.js:285: queryParams: {
534
- tests/positioning-extended.test.js:323: const { data: allTasks } = await api.resources.tasks.query({
535
- tests/positioning-extended.test.js:324: queryParams: {
536
- tests/positioning-extended.test.js:358: const { data: tasks } = await api.resources.tasks.query({
537
- tests/positioning-extended.test.js:359: queryParams: {
538
- tests/positioning-extended.test.js:405: const { data: tasks } = await api.resources.tasks.query({
539
- tests/positioning-extended.test.js:406: queryParams: {
540
- tests/positioning-extended.test.js:462: const { data: ascTasks } = await api.resources.tasks.query({
541
- tests/positioning-extended.test.js:463: queryParams: {
542
- tests/positioning-extended.test.js:473: const { data: descTasks } = await api.resources.tasks.query({
543
- tests/positioning-extended.test.js:474: queryParams: {
544
- tests/positioning-extended.test.js:484: it('should handle pagination with position sorting', async () => {
545
- tests/positioning-extended.test.js:496: const { data: page1 } = await api.resources.tasks.query({
546
- tests/positioning-extended.test.js:497: queryParams: {
547
- tests/positioning-extended.test.js:509: const { data: page2 } = await api.resources.tasks.query({
548
- tests/positioning-extended.test.js:510: queryParams: {
549
- tests/positioning-extended.test.js:547: const { data: tasks } = await api.resources.tasks.query({
550
- tests/positioning-extended.test.js:548: queryParams: {
551
- tests/positioning-extended.test.js:590: const { data: allTasks } = await api.resources.tasks.query({
552
- tests/positioning-extended.test.js:591: queryParams: {
553
- tests/positioning-extended.test.js:655: const { data: finalTasks } = await api.resources.tasks.query({
554
- tests/positioning-extended.test.js:656: queryParams: {
555
- tests/positioning-extended.test.js:705: const { data: tasksWithCat } = await api.resources.tasks.query({
556
- tests/positioning-extended.test.js:706: queryParams: {
557
- tests/positioning-extended.test.js:716: const { data: tasksNoCat } = await api.resources.tasks.query({
558
- tests/positioning-extended.test.js:717: queryParams: {
559
- tests/positioning-extended.test.js:724: const { data: allTasks } = await api.resources.tasks.query({
560
- tests/positioning-extended.test.js:725: queryParams: {
561
- tests/positioning-extended.test.js:732: // Try querying without filter
562
- tests/positioning-extended.test.js:733: const { data: tasksNoFilter } = await api.resources.tasks.query({
563
- tests/positioning-extended.test.js:734: queryParams: {
564
- tests/positioning-extended.test.js:804: const { data: tasks } = await api.resources.tasks.query({
565
- tests/positioning-extended.test.js:805: queryParams: {
566
- tests/positioning-extended.test.js:832: const { data: tasks } = await api.resources.tasks.query({
567
- tests/positioning-extended.test.js:833: queryParams: {
568
- tests/positioning-extended.test.js:855: const { data: updatedTasks } = await api.resources.tasks.query({
569
- tests/positioning-extended.test.js:856: queryParams: {
570
- tests/positioning-extended.test.js:894: const { data: finalTasks } = await api.resources.tasks.query({
571
- tests/positioning-extended.test.js:895: queryParams: {
572
- tests/rest-api-access.test.js:127: it('filters query results by ownership for non-admin users', async () => {
573
- tests/rest-api-access.test.js:134: const queryResult = await api.resources.projects.query({
574
- tests/rest-api-access.test.js:138: validateJsonApiStructure(queryResult, true)
575
- tests/rest-api-access.test.js:139: assert.equal(queryResult.data.length, 1)
576
- tests/rest-api-access.test.js:140: assert.equal(queryResult.data[0].id, aliceProject.id)
577
- tests/rest-api-access.test.js:141: assertResourceRelationship(queryResult.data[0], 'user', {
578
- tests/rest-api-access.test.js:154: const adminQuery = await api.resources.projects.query({
579
- tests/includes.test.js:99: it('should include single belongsTo relationship', async () => {
580
- tests/includes.test.js:102: queryParams: {
581
- tests/includes.test.js:103: include: ['publisher']
582
- tests/includes.test.js:110: // Verify included array exists
583
- tests/includes.test.js:111: assert(result.included, 'Should have included data')
584
- tests/includes.test.js:112: assert.equal(result.included.length, 1, 'Should include one resource')
585
- tests/includes.test.js:114: // Verify included publisher
586
- tests/includes.test.js:115: const includedPublisher = result.included[0]
587
- tests/includes.test.js:116: assert.equal(includedPublisher.type, 'publishers')
588
- tests/includes.test.js:117: assert.equal(includedPublisher.id, testData.publisher.id)
589
- tests/includes.test.js:118: assert.equal(includedPublisher.attributes.name, 'Test Publisher')
590
- tests/includes.test.js:121: it('should include multiple relationships', async () => {
591
- tests/includes.test.js:124: queryParams: {
592
- tests/includes.test.js:125: include: ['publisher', 'authors', 'country']
593
- tests/includes.test.js:132: // Verify included array
594
- tests/includes.test.js:133: assert(result.included)
595
- tests/includes.test.js:134: assert.equal(result.included.length, 4, 'Should include 4 resources (1 publisher + 2 authors + 1 country)')
596
- tests/includes.test.js:136: // Verify each type is included
597
- tests/includes.test.js:137: const includedTypes = result.included.map(r => r.type)
598
- tests/includes.test.js:138: assert(includedTypes.includes('publishers'))
599
- tests/includes.test.js:139: assert(includedTypes.includes('authors'))
600
- tests/includes.test.js:140: assert(includedTypes.includes('countries'))
601
- tests/includes.test.js:143: const authors = result.included.filter(r => r.type === 'authors')
602
- tests/includes.test.js:149: it('should include relationships in collection queries', async () => {
603
- tests/includes.test.js:150: const result = await basicApi.resources.books.query({
604
- tests/includes.test.js:151: queryParams: {
605
- tests/includes.test.js:152: include: ['publisher', 'country']
606
- tests/includes.test.js:162: // Should have included resources
607
- tests/includes.test.js:163: assert(result.included)
608
- tests/includes.test.js:164: const includedTypes = result.included.map(r => r.type)
609
- tests/includes.test.js:165: assert(includedTypes.includes('publishers'))
610
- tests/includes.test.js:166: assert(includedTypes.includes('countries'))
611
- tests/includes.test.js:210: it('should include nested relationships', async () => {
612
- tests/includes.test.js:213: queryParams: {
613
- tests/includes.test.js:214: include: ['publisher.country']
614
- tests/includes.test.js:221: // Should include both publisher and its country
615
- tests/includes.test.js:222: assert(result.included)
616
- tests/includes.test.js:223: assert.equal(result.included.length, 2)
617
- tests/includes.test.js:226: const publisher = result.included.find(r => r.type === 'publishers')
618
- tests/includes.test.js:227: const country = result.included.find(r => r.type === 'countries')
619
- tests/includes.test.js:229: assert(publisher, 'Should include publisher')
620
- tests/includes.test.js:230: assert(country, 'Should include country')
621
- tests/includes.test.js:237: it('should handle multiple nested includes', async () => {
622
- tests/includes.test.js:263: // Query with multiple nested includes
623
- tests/includes.test.js:264: const result = await basicApi.resources.books.query({
624
- tests/includes.test.js:265: queryParams: {
625
- tests/includes.test.js:266: include: ['publisher.country', 'authors', 'country']
626
- tests/includes.test.js:273: // Should have all included resources
627
- tests/includes.test.js:274: assert(result.included)
628
- tests/includes.test.js:275: const includedTypes = result.included.map(r => r.type)
629
- tests/includes.test.js:276: assert(includedTypes.includes('publishers'))
630
- tests/includes.test.js:277: assert(includedTypes.includes('countries'))
631
- tests/includes.test.js:278: assert(includedTypes.includes('authors'))
632
- tests/includes.test.js:281: const countryResources = result.included.filter(r => r.type === 'countries')
633
- tests/includes.test.js:343: it('should include relationships with sparse fieldsets', async () => {
634
- tests/includes.test.js:346: queryParams: {
635
- tests/includes.test.js:347: include: ['publisher', 'country'],
636
- tests/includes.test.js:362: assert(!result.data.attributes.pages, 'Should not include pages')
637
- tests/includes.test.js:363: assert(!result.data.attributes.price, 'Should not include price')
638
- tests/includes.test.js:365: // Verify included resources have only requested fields
639
- tests/includes.test.js:366: const publisher = result.included.find(r => r.type === 'publishers')
640
- tests/includes.test.js:368: assert(!publisher.attributes.founded_year, 'Should not include founded_year')
641
- tests/includes.test.js:369: assert(!publisher.attributes.website, 'Should not include website')
642
- tests/includes.test.js:371: const country = result.included.find(r => r.type === 'countries')
643
- tests/includes.test.js:374: assert(!country.attributes.capital, 'Should not include capital')
644
- tests/includes.test.js:375: assert(!country.attributes.population, 'Should not include population')
645
- tests/relationship-endpoints.test.js:34: includeExpress: true
646
- tests/relationship-endpoints.test.js:135: // Verify through GET with include
647
- tests/relationship-endpoints.test.js:138: queryParams: {
648
- tests/relationship-endpoints.test.js:139: include: ['authors']
649
- tests/relationship-endpoints.test.js:144: assert(getResult.included, 'Should have included data')
650
- tests/relationship-endpoints.test.js:145: assert.equal(getResult.included.length, 2, 'Should include 2 authors')
651
- tests/field-setters.test.js:253: // No records should be created - verify with query
652
- tests/field-setters.test.js:254: const records = await api.resources.validated_data.query()
653
- tests/include-depth-validation.test.js:20: // Initialize API with custom includeDepthLimit
654
- tests/include-depth-validation.test.js:23: includeDepthLimit: 3 // Default is 3, but being explicit
655
- tests/include-depth-validation.test.js:85: it('should allow includes within depth limit', async () => {
656
- tests/include-depth-validation.test.js:87: const depth1 = await api.resources.publishers.query({
657
- tests/include-depth-validation.test.js:88: queryParams: { include: ['country'] }
658
- tests/include-depth-validation.test.js:91: assert(depth1.included, 'Should have included resources')
659
- tests/include-depth-validation.test.js:94: const depth2 = await api.resources.authors.query({
660
- tests/include-depth-validation.test.js:95: queryParams: { include: ['publisher.country'] }
661
- tests/include-depth-validation.test.js:98: // The included array may or may not be present depending on whether relationships exist
662
- tests/include-depth-validation.test.js:101: const depth3 = await api.resources.books.query({
663
- tests/include-depth-validation.test.js:102: queryParams: { include: ['publisher.country.publishers'] }
664
- tests/include-depth-validation.test.js:105: // Note: The included array might be present even if some relationships don't have data
665
- tests/include-depth-validation.test.js:108: it('should reject includes exceeding depth limit', async () => {
666
- tests/include-depth-validation.test.js:111: await api.resources.books.query({
667
- tests/include-depth-validation.test.js:112: queryParams: { include: ['publisher.country.publishers.books'] }
668
- tests/include-depth-validation.test.js:124: await api.resources.books.query({
669
- tests/include-depth-validation.test.js:125: queryParams: { include: ['publisher.country.publishers.books.authors'] }
670
- tests/include-depth-validation.test.js:136: it('should validate each include path independently', async () => {
671
- tests/include-depth-validation.test.js:139: await api.resources.books.query({
672
- tests/include-depth-validation.test.js:140: queryParams: {
673
- tests/include-depth-validation.test.js:141: include: [
674
- tests/include-depth-validation.test.js:159: it('should allow includes within depth limit', async () => {
675
- tests/include-depth-validation.test.js:160: const books = await api.resources.books.query()
676
- tests/include-depth-validation.test.js:166: queryParams: { include: ['publisher'] }
677
- tests/include-depth-validation.test.js:169: assert(depth1.included, 'Should have included resources')
678
- tests/include-depth-validation.test.js:174: queryParams: { include: ['publisher.country.publishers'] }
679
- tests/include-depth-validation.test.js:179: it('should reject includes exceeding depth limit', async () => {
680
- tests/include-depth-validation.test.js:180: const books = await api.resources.books.query()
681
- tests/include-depth-validation.test.js:187: queryParams: { include: ['publisher.country.publishers.books'] }
682
- tests/include-depth-validation.test.js:200: it('should respect custom includeDepthLimit configuration', async () => {
683
- tests/include-depth-validation.test.js:243: const depth2 = await limitedApi.resources.authors.query({
684
- tests/include-depth-validation.test.js:244: queryParams: { include: ['publisher.country'] }
685
- tests/include-depth-validation.test.js:251: await limitedApi.resources.books.query({
686
- tests/include-depth-validation.test.js:252: queryParams: { include: ['publisher.country.publishers'] }
687
- tests/include-depth-validation.test.js:265: it('should handle empty include arrays', async () => {
688
- tests/include-depth-validation.test.js:266: const result = await api.resources.books.query({
689
- tests/include-depth-validation.test.js:267: queryParams: { include: [] }
690
- tests/include-depth-validation.test.js:270: assert(!result.included, 'Should not have included resources')
691
- tests/include-depth-validation.test.js:308: const result = await api.resources.books.query({
692
- tests/include-depth-validation.test.js:309: queryParams: { include: ['publisher'] }
693
- tests/include-depth-validation.test.js:312: assert(result.included, 'Should have included resources')
694
- tests/include-depth-validation.test.js:319: await api.resources.books.query({
695
- tests/include-depth-validation.test.js:320: queryParams: { include: ['a.b.c.d'] }
696
- tests/polymorphic-relationships.test.js:158: it('should query reviews and include polymorphic reviewable resource', async () => {
697
- tests/polymorphic-relationships.test.js:186: // Query reviews with include
698
- tests/polymorphic-relationships.test.js:187: const result = await api.resources.reviews.query({
699
- tests/polymorphic-relationships.test.js:188: queryParams: {
700
- tests/polymorphic-relationships.test.js:189: include: ['reviewable']
701
- tests/polymorphic-relationships.test.js:197: // Check included resources
702
- tests/polymorphic-relationships.test.js:198: assert(result.included)
703
- tests/polymorphic-relationships.test.js:199: assert.equal(result.included.length, 1)
704
- tests/polymorphic-relationships.test.js:200: assert.equal(result.included[0].type, 'books')
705
- tests/polymorphic-relationships.test.js:201: assert.equal(result.included[0].id, book.data.id)
706
- tests/polymorphic-relationships.test.js:202: assert.equal(result.included[0].attributes.title, 'Test Book for Review')
707
- tests/polymorphic-relationships.test.js:205: it('should handle mixed polymorphic types in a single query', async () => {
708
- tests/polymorphic-relationships.test.js:251: // Query all reviews with includes
709
- tests/polymorphic-relationships.test.js:252: const result = await api.resources.reviews.query({
710
- tests/polymorphic-relationships.test.js:253: queryParams: {
711
- tests/polymorphic-relationships.test.js:254: include: ['reviewable']
712
- tests/polymorphic-relationships.test.js:261: // Check included resources
713
- tests/polymorphic-relationships.test.js:262: assert(result.included)
714
- tests/polymorphic-relationships.test.js:263: assert.equal(result.included.length, 2)
715
- tests/polymorphic-relationships.test.js:265: // Find each type in included
716
- tests/polymorphic-relationships.test.js:266: const includedBook = result.included.find(r => r.type === 'books')
717
- tests/polymorphic-relationships.test.js:267: const includedAuthor = result.included.find(r => r.type === 'authors')
718
- tests/polymorphic-relationships.test.js:269: assert(includedBook)
719
- tests/polymorphic-relationships.test.js:270: assert.equal(includedBook.attributes.title, 'German Book')
720
- tests/polymorphic-relationships.test.js:272: assert(includedAuthor)
721
- tests/polymorphic-relationships.test.js:273: assert.equal(includedAuthor.attributes.name, 'German Author')
722
- tests/polymorphic-relationships.test.js:285: it('should query books and include their reviews', async () => {
723
- tests/polymorphic-relationships.test.js:328: queryParams: {
724
- tests/polymorphic-relationships.test.js:329: include: ['reviews']
725
- tests/polymorphic-relationships.test.js:336: // Check included reviews
726
- tests/polymorphic-relationships.test.js:337: console.log('Result included:', JSON.stringify(result.included, null, 2))
727
- tests/polymorphic-relationships.test.js:338: assert(result.included)
728
- tests/polymorphic-relationships.test.js:339: assert.equal(result.included.length, 2)
729
- tests/polymorphic-relationships.test.js:340: assert(result.included.every(r => r.type === 'reviews'))
730
- tests/polymorphic-relationships.test.js:341: assert(result.included.every(r =>
731
- tests/relationships.test.js:83: // Verify through GET with include
732
- tests/relationships.test.js:86: queryParams: {
733
- tests/relationships.test.js:87: include: ['country']
734
- tests/relationships.test.js:93: assert(getResult.included, 'Should have included data')
735
- tests/relationships.test.js:94: assert.equal(getResult.included.length, 1)
736
- tests/relationships.test.js:95: assert.equal(getResult.included[0].type, 'countries')
737
- tests/relationships.test.js:96: assert.equal(getResult.included[0].attributes.name, 'United States')
738
- tests/relationships.test.js:145: queryParams: { include: ['country'] },
739
- tests/relationships.test.js:151: assert.equal(getResult.included[0].attributes.code, 'UK')
740
- tests/relationships.test.js:256: // GET book with authors included
741
- tests/relationships.test.js:259: queryParams: { include: ['authors'] },
742
- tests/relationships.test.js:267: // Verify included authors
743
- tests/relationships.test.js:268: assert(getResult.included)
744
- tests/relationships.test.js:269: assert.equal(getResult.included.length, 2)
745
- tests/relationships.test.js:270: const authorNames = getResult.included.map(a => a.attributes.name).sort()
746
- tests/relationships.test.js:348: queryParams: { include: ['authors'] },
747
- tests/relationships.test.js:419: queryParams: { include: ['authors'] },
748
- tests/relationships.test.js:501: queryParams: { include: ['authors'] },
749
- tests/relationships.test.js:565: // Verify with full includes
750
- tests/relationships.test.js:568: queryParams: {
751
- tests/relationships.test.js:569: include: ['publisher', 'publisher.country', 'authors', 'country']
752
- tests/relationships.test.js:581: // Verify included resources
753
- tests/relationships.test.js:582: assert(getResult.included)
754
- tests/relationships.test.js:583: const includedTypes = getResult.included.map(r => r.type)
755
- tests/relationships.test.js:584: assert(includedTypes.includes('publishers'))
756
- tests/relationships.test.js:585: assert(includedTypes.includes('authors'))
757
- tests/relationships.test.js:586: assert(includedTypes.includes('countries'))
758
- tests/relationships.test.js:589: const publisher = getResult.included.find(r => r.type === 'publishers')
759
- tests/relationships.test.js:669: queryParams: { include: ['publisher', 'authors'] },
760
- tests/TEST_TEMPLATE.test.js:49: * 1. NEVER query the database directly with knex('table').select()
761
- tests/TEST_TEMPLATE.test.js:52: * - Use api.resources.[resource].query() to fetch multiple items
762
- tests/field-getters.test.js:119: it('should work with sparse fieldsets', async () => {
763
- tests/field-getters.test.js:127: // Fetch with sparse fieldsets
764
- tests/field-getters.test.js:128: const sparse = await api.resources.products.get({
765
- tests/field-getters.test.js:130: queryParams: {
766
- tests/field-getters.test.js:135: assert.equal(sparse.name, 'ANOTHER WIDGET')
767
- tests/field-getters.test.js:136: assert.ok(Math.abs(sparse.total_price - 55) < 0.0001, `Expected total_price to be ~55, got ${sparse.total_price}`)
768
- tests/field-getters.test.js:137: assert.equal(sparse.description, undefined)
769
- tests/field-getters.test.js:138: assert.equal(sparse.price_str, undefined)
770
- tests/field-getters.test.js:223: it('should apply getters to included resources', async () => {
771
- tests/field-getters.test.js:244: // Fetch with includes
772
- tests/field-getters.test.js:247: queryParams: {
773
- tests/field-getters.test.js:248: include: ['reviews']
774
- tests/field-getters.test.js:255: // Review getters should apply to included resources
775
- tests/field-getters.test.js:261: it('should work with sparse fieldsets on included resources', async () => {
776
- tests/field-getters.test.js:277: queryParams: {
777
- tests/field-getters.test.js:278: include: ['reviews'],
778
- tests/pagination-enhanced.test.js:27: // Initialize API once with pagination features
779
- tests/pagination-enhanced.test.js:39: 'pagination_countries', 'pagination_publishers', 'pagination_books'
780
- tests/pagination-enhanced.test.js:63: const list = await api.resources.books.query({ simplified: false })
781
- tests/pagination-enhanced.test.js:79: const result = await api.resources.books.query({
782
- tests/pagination-enhanced.test.js:80: queryParams: {},
783
- tests/pagination-enhanced.test.js:98: it('should add self links to included resources', async () => {
784
- tests/pagination-enhanced.test.js:99: const result = await api.resources.books.query({
785
- tests/pagination-enhanced.test.js:100: queryParams: {
786
- tests/pagination-enhanced.test.js:101: include: ['country']
787
- tests/pagination-enhanced.test.js:107: assert(result.included, 'Should have included resources')
788
- tests/pagination-enhanced.test.js:109: result.included.forEach(resource => {
789
- tests/pagination-enhanced.test.js:118: const result = await api.resources.books.query({
790
- tests/pagination-enhanced.test.js:119: queryParams: {},
791
- tests/pagination-enhanced.test.js:139: 'pagination_countries', 'pagination_publishers', 'pagination_books'
792
- tests/pagination-enhanced.test.js:149: // Create 10 books for pagination testing
793
- tests/pagination-enhanced.test.js:162: it('should include pagination metadata in response', async () => {
794
- tests/pagination-enhanced.test.js:163: const result = await api.resources.books.query({
795
- tests/pagination-enhanced.test.js:164: queryParams: {
796
- tests/pagination-enhanced.test.js:172: assert(result.meta.pagination, 'Meta should have pagination')
797
- tests/pagination-enhanced.test.js:174: const pagination = result.meta.pagination
798
- tests/pagination-enhanced.test.js:175: assert.equal(pagination.page, 2)
799
- tests/pagination-enhanced.test.js:176: assert.equal(pagination.pageSize, 3)
800
- tests/pagination-enhanced.test.js:177: assert.equal(pagination.total, 10)
801
- tests/pagination-enhanced.test.js:178: assert.equal(pagination.pageCount, 4)
802
- tests/pagination-enhanced.test.js:179: assert.equal(pagination.hasMore, true)
803
- tests/pagination-enhanced.test.js:183: const result = await api.resources.books.query({
804
- tests/pagination-enhanced.test.js:184: queryParams: {
805
- tests/pagination-enhanced.test.js:190: assert.equal(result.meta.pagination.hasMore, false)
806
- tests/pagination-enhanced.test.js:191: assert.equal(result.meta.pagination.page, 4)
807
- tests/pagination-enhanced.test.js:192: assert.equal(result.meta.pagination.pageCount, 4)
808
- tests/pagination-enhanced.test.js:195: it('should include pagination links', async () => {
809
- tests/pagination-enhanced.test.js:196: const result = await api.resources.books.query({
810
- tests/pagination-enhanced.test.js:197: queryParams: {
811
- tests/pagination-enhanced.test.js:211: assert(result.links.self.includes('page[number]=2'))
812
- tests/pagination-enhanced.test.js:212: assert(result.links.self.includes('page[size]=3'))
813
- tests/pagination-enhanced.test.js:213: assert(result.links.first.includes('page[number]=1'))
814
- tests/pagination-enhanced.test.js:214: assert(result.links.last.includes('page[number]=4'))
815
- tests/pagination-enhanced.test.js:215: assert(result.links.prev.includes('page[number]=1'))
816
- tests/pagination-enhanced.test.js:216: assert(result.links.next.includes('page[number]=3'))
817
- tests/pagination-enhanced.test.js:219: it('should not include prev link on first page', async () => {
818
- tests/pagination-enhanced.test.js:220: const result = await api.resources.books.query({
819
- tests/pagination-enhanced.test.js:221: queryParams: {
820
- tests/pagination-enhanced.test.js:232: it('should not include next link on last page', async () => {
821
- tests/pagination-enhanced.test.js:233: const result = await api.resources.books.query({
822
- tests/pagination-enhanced.test.js:234: queryParams: {
823
- tests/pagination-enhanced.test.js:245: it('should preserve other query parameters in pagination links', async () => {
824
- tests/pagination-enhanced.test.js:246: const result = await api.resources.books.query({
825
- tests/pagination-enhanced.test.js:247: queryParams: {
826
- tests/pagination-enhanced.test.js:256: assert(result.links.next.includes('sort=-title'))
827
- tests/pagination-enhanced.test.js:257: assert(result.links.next.includes('page[number]=3'))
828
- tests/pagination-enhanced.test.js:258: assert(result.links.next.includes('page[size]=3'))
829
- tests/pagination-enhanced.test.js:265: 'pagination_countries', 'pagination_publishers', 'pagination_books'
830
- tests/pagination-enhanced.test.js:290: it('should support cursor-based pagination with after parameter', async () => {
831
- tests/pagination-enhanced.test.js:292: const firstPage = await api.resources.books.query({
832
- tests/pagination-enhanced.test.js:293: queryParams: {
833
- tests/pagination-enhanced.test.js:302: assert(firstPage.meta.pagination.hasMore)
834
- tests/pagination-enhanced.test.js:303: assert(firstPage.meta.pagination.cursor?.next)
835
- tests/pagination-enhanced.test.js:305: // Get next page using cursor
836
- tests/pagination-enhanced.test.js:306: const secondPage = await api.resources.books.query({
837
- tests/pagination-enhanced.test.js:307: queryParams: {
838
- tests/pagination-enhanced.test.js:310: after: firstPage.meta.pagination.cursor.next
839
- tests/pagination-enhanced.test.js:323: assert(!firstPageIds.some(id => secondPageIds.includes(id)), 'Pages should have different records')
840
- tests/pagination-enhanced.test.js:326: it('should include cursor pagination links', async () => {
841
- tests/pagination-enhanced.test.js:327: const result = await api.resources.books.query({
842
- tests/pagination-enhanced.test.js:328: queryParams: {
843
- tests/pagination-enhanced.test.js:338: assert(result.links.next.includes('page[after]='), 'Next link should include cursor parameter')
844
- tests/pagination-enhanced.test.js:341: it('should handle last page with cursor pagination', async () => {
845
- tests/pagination-enhanced.test.js:348: result = await api.resources.books.query({
846
- tests/pagination-enhanced.test.js:349: queryParams: {
847
- tests/pagination-enhanced.test.js:358: if (result.meta.pagination.cursor?.next) {
848
- tests/pagination-enhanced.test.js:359: currentCursor = result.meta.pagination.cursor.next
849
- tests/pagination-enhanced.test.js:363: // Last page should have no next cursor
850
- tests/pagination-enhanced.test.js:364: assert.equal(result.meta.pagination.hasMore, false)
851
- tests/pagination-enhanced.test.js:365: assert(!result.meta.pagination.cursor?.next)
852
- tests/pagination-enhanced.test.js:373: 'pagination_countries', 'pagination_publishers', 'pagination_books'
853
- tests/pagination-enhanced.test.js:396: it('should include count by default', async () => {
854
- tests/pagination-enhanced.test.js:397: const result = await api.resources.books.query({
855
- tests/pagination-enhanced.test.js:398: queryParams: {
856
- tests/pagination-enhanced.test.js:404: assert(result.meta.pagination.total !== undefined)
857
- tests/pagination-enhanced.test.js:405: assert.equal(result.meta.pagination.total, 20)
858
- tests/pagination-enhanced.test.js:406: assert.equal(result.meta.pagination.pageCount, 4)
859
- tests/pagination-enhanced.test.js:415: const result = await api.resources.books.query({
860
- tests/pagination-enhanced.test.js:416: queryParams: {
861
- tests/pagination-enhanced.test.js:422: assert(result.meta.pagination)
862
- tests/pagination-enhanced.test.js:423: assert.equal(result.meta.pagination.page, 1)
863
- tests/pagination-enhanced.test.js:424: assert.equal(result.meta.pagination.pageSize, 5)
864
- tests/pagination-enhanced.test.js:425: assert(result.meta.pagination.total === undefined, 'Should not include total when counts disabled')
865
- tests/pagination-enhanced.test.js:426: assert(result.meta.pagination.pageCount === undefined, 'Should not include pageCount when counts disabled')
866
- tests/pagination-enhanced.test.js:427: assert(result.meta.pagination.hasMore === undefined, 'Should not include hasMore when counts disabled')
867
- tests/pagination-enhanced.test.js:439: 'pagination_countries', 'pagination_publishers', 'pagination_books'
868
- tests/pagination-enhanced.test.js:472: it('should combine pagination with filtering and includes', async () => {
869
- tests/pagination-enhanced.test.js:473: const result = await api.resources.books.query({
870
- tests/pagination-enhanced.test.js:474: queryParams: {
871
- tests/pagination-enhanced.test.js:479: include: ['country'],
872
- tests/pagination-enhanced.test.js:487: // Check pagination worked
873
- tests/pagination-enhanced.test.js:489: assert.equal(result.meta.pagination.total, 8)
874
- tests/pagination-enhanced.test.js:490: assert.equal(result.meta.pagination.pageCount, 2)
875
- tests/pagination-enhanced.test.js:496: // Check includes worked
876
- tests/pagination-enhanced.test.js:497: assert(result.included)
877
- tests/pagination-enhanced.test.js:498: const usCountry = result.included.find(r => r.type === 'countries' && r.attributes.code === 'US')
878
- tests/pagination-enhanced.test.js:506: // Check pagination links include all parameters
879
- tests/pagination-enhanced.test.js:507: assert(result.links.next.includes(`filters[country]=${usCountryId}`))
880
- tests/pagination-enhanced.test.js:508: assert(result.links.next.includes('include=country'))
881
- tests/pagination-enhanced.test.js:509: assert(result.links.next.includes('sort=title'))
882
- tests/query-limits.test.js:34: queryDefaultLimit: 10,
883
- tests/query-limits.test.js:35: queryMaxLimit: 50,
884
- tests/query-limits.test.js:68: // Relationships are always includable via ?include=
885
- tests/query-limits.test.js:69: include: {
886
- tests/query-limits.test.js:70: strategy: 'window' // Use window strategy for per-publisher limits
887
- tests/query-limits.test.js:90: // Relationships are always includable via ?include=
888
- tests/query-limits.test.js:91: include: {
889
- tests/query-limits.test.js:93: strategy: 'window'
890
- tests/query-limits.test.js:113: // Relationships are always includable via ?include=
891
- tests/query-limits.test.js:164: it('should apply queryDefaultLimit when no page size specified', async () => {
892
- tests/query-limits.test.js:176: const result = await api.resources.countries.query({
893
- tests/query-limits.test.js:177: queryParams: {},
894
- tests/query-limits.test.js:181: // Should use queryDefaultLimit of 10
895
- tests/query-limits.test.js:185: it('should respect queryMaxLimit when page size exceeds it', async () => {
896
- tests/query-limits.test.js:196: // Query with page size exceeding max (use offset-based pagination)
897
- tests/query-limits.test.js:197: const result = await api.resources.countries.query({
898
- tests/query-limits.test.js:198: queryParams: {
899
- tests/query-limits.test.js:199: page: { size: 100, number: 1 } // Exceeds queryMaxLimit of 50
900
- tests/query-limits.test.js:204: // Should be capped at queryMaxLimit of 50
901
- tests/query-limits.test.js:205: assert.equal(result.data.length, 50, 'Should cap at queryMaxLimit of 50')
902
- tests/query-limits.test.js:239: it('should apply default limit to hasMany includes when not specified', async () => {
903
- tests/query-limits.test.js:240: // Query publishers with books (no explicit limit in include config)
904
- tests/query-limits.test.js:241: const result = await api.resources.publishers.query({
905
- tests/query-limits.test.js:242: queryParams: {
906
- tests/query-limits.test.js:243: include: ['books']
907
- tests/query-limits.test.js:252: const publisherBooks = (result.included || []).filter(r => r.type === 'books')
908
- tests/query-limits.test.js:254: // Should apply queryDefaultLimit of 10
909
- tests/query-limits.test.js:255: assert.equal(publisherBooks.length, 10, 'Should include only 10 books by default')
910
- tests/query-limits.test.js:304: const result = await api.resources.authors.query({
911
- tests/query-limits.test.js:305: queryParams: {
912
- tests/query-limits.test.js:306: include: ['books']
913
- tests/query-limits.test.js:311: const authorBooks = result.included.filter(r => r.type === 'books')
914
- tests/query-limits.test.js:375: it('should apply default limit to polymorphic hasMany includes', async () => {
915
- tests/query-limits.test.js:377: const result = await api.resources.books.query({
916
- tests/query-limits.test.js:378: queryParams: {
917
- tests/query-limits.test.js:379: include: ['reviews']
918
- tests/query-limits.test.js:384: // Without window strategy, the default strategy will limit total reviews
919
- tests/query-limits.test.js:385: const totalReviews = result.included.filter(r => r.type === 'reviews')
920
- tests/query-limits.test.js:387: // Should apply queryDefaultLimit of 10 to total reviews
921
- tests/query-limits.test.js:393: it('should throw error when include limit exceeds queryMaxLimit at resource definition', async () => {
922
- tests/query-limits.test.js:398: queryDefaultLimit: 5,
923
- tests/query-limits.test.js:399: queryMaxLimit: 20,
924
- tests/query-limits.test.js:408: // Try to create a resource with include limit exceeding max
925
- tests/query-limits.test.js:421: include: {
926
- tests/query-limits.test.js:422: limit: 25 // Exceeds queryMaxLimit of 20
927
- tests/query-limits.test.js:429: return err.message && err.message.includes('limit') && err.message.includes('exceeds queryMaxLimit')
928
- tests/query-limits.test.js:431: 'Should throw error for excessive include limit'
929
- tests/query-limits.test.js:478: it('should apply per-parent limits with window strategy', async () => {
930
- tests/query-limits.test.js:479: // Query all publishers with books (window strategy configured)
931
- tests/query-limits.test.js:480: const result = await api.resources.publishers.query({
932
- tests/query-limits.test.js:481: queryParams: {
933
- tests/query-limits.test.js:482: include: ['books']
934
- tests/query-limits.test.js:489: const publisherBooks = result.included.filter(r =>
935
- tests/query-limits.test.js:494: // Each publisher gets up to queryDefaultLimit (10) books
936
- tests/query-limits.test.js:496: `Publisher ${publisher.id} should have at most 10 books with window strategy`)
937
- tests/query-limits.test.js:499: // Total books can exceed queryDefaultLimit since each parent gets its own limit
938
- tests/query-limits.test.js:500: const totalBooks = result.included.filter(r => r.type === 'books').length
939
- tests/query-limits.test.js:501: assert(totalBooks > 10, 'Total books should exceed 10 with window strategy')
940
- tests/query-limits.test.js:508: it('should apply window limits to many-to-many relationships', async () => {
941
- tests/query-limits.test.js:559: // Query authors with books (configured with limit: 3, strategy: window)
942
- tests/query-limits.test.js:560: const result = await api.resources.authors.query({
943
- tests/query-limits.test.js:561: queryParams: {
944
- tests/query-limits.test.js:562: include: ['books']
945
- tests/query-limits.test.js:572: // Verify the books exist in the included array
946
- tests/query-limits.test.js:573: const authorBooks = result.included.filter(r =>
947
- tests/query-limits.test.js:574: r.type === 'books' && authorBookIds.includes(r.id)
948
- tests/query-limits.test.js:580: `Author ${author.id} should have exactly 3 books in included array`)