json-rest-api 1.0.22 → 1.0.24

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 (290) hide show
  1. package/CLAUDE.md +1 -2
  2. package/JSKIT_BACKEND_MIGRATION_TRACKER.txt +180 -0
  3. package/README.md +22 -1
  4. package/SINGLE_VALIDATION_CONTRACT_TODO.txt +172 -0
  5. package/docs/API.md +196 -38
  6. package/docs/COMPARISON.md +2 -2
  7. package/docs/GUIDE/GUIDE_1_Initial_Setup.md +111 -5
  8. package/docs/GUIDE/GUIDE_2_2_Manipulating_And_Searching_Tables.md +5 -1
  9. package/docs/GUIDE/GUIDE_2_7_Pagination_And_Ordering.md +3 -1
  10. package/docs/GUIDE/GUIDE_2_8_Effects_of_PUT_and_PATCH.md +12 -60
  11. package/docs/GUIDE/GUIDE_2_Data_And_Relations.md +2 -2
  12. package/docs/GUIDE/GUIDE_3_Field_Transformations.md +5 -1
  13. package/docs/GUIDE/GUIDE_7_Hooks_Data_Management_And_Plugins.md +2 -0
  14. package/docs/GUIDE/GUIDE_X_Autofiltering.md +355 -0
  15. package/docs/GUIDE/GUIDE_X_Fastify.md +78 -0
  16. package/docs/GUIDE/GUIDE_X_Knex_Schema_And_Migrations.md +370 -0
  17. package/docs/GUIDE/GUIDE_X_Query_Projections.md +159 -0
  18. package/docs/GUIDE/GUIDE_X_Writing_Plugins.md +199 -0
  19. package/docs/GUIDE/index.md +18 -9
  20. package/docs/QUICKSTART.md +5 -1
  21. package/docs/index.md +1 -1
  22. package/index.js +3 -2
  23. package/lib/enhanced-logger.js +1 -1
  24. package/package.json +6 -2
  25. package/plugins/core/bulk-operations-plugin.js +26 -34
  26. package/plugins/core/connectors/express-plugin.js +97 -190
  27. package/plugins/core/connectors/fastify-plugin.js +206 -0
  28. package/plugins/core/connectors/lib/busboy-detector.js +4 -4
  29. package/plugins/core/connectors/lib/connector-core.js +195 -0
  30. package/plugins/core/connectors/lib/transport-http-helpers.js +122 -0
  31. package/plugins/core/connectors/lib/transport-route-schemas.js +92 -0
  32. package/plugins/core/lib/anyapi/schema-utils.js +43 -4
  33. package/plugins/core/lib/anyapi/utils/descriptor-helpers.js +4 -1
  34. package/plugins/core/lib/dbIntrospection.js +1078 -0
  35. package/plugins/core/lib/dbTablesOperations.js +1111 -160
  36. package/plugins/core/lib/querying/knex-cross-table-search.js +0 -7
  37. package/plugins/core/lib/querying/knex-json-api-transformers-querying.js +5 -3
  38. package/plugins/core/lib/querying/knex-process-includes.js +3 -4
  39. package/plugins/core/lib/querying/knex-query-helpers.js +21 -76
  40. package/plugins/core/lib/querying/knex-relationship-includes.js +468 -215
  41. package/plugins/core/lib/querying/query-builder-utils.js +19 -0
  42. package/plugins/core/lib/querying/query-field-sort-helpers.js +135 -0
  43. package/plugins/core/lib/querying/sort-helpers.js +33 -0
  44. package/plugins/core/lib/querying/storage-adapter-utils.js +51 -0
  45. package/plugins/core/lib/querying/url-helpers.js +8 -2
  46. package/plugins/core/lib/querying-writing/compile-schemas.js +20 -5
  47. package/plugins/core/lib/querying-writing/knex-field-helpers.js +83 -14
  48. package/plugins/core/lib/querying-writing/knex-json-api-transformers.js +13 -12
  49. package/plugins/core/lib/querying-writing/query-field-helpers.js +88 -0
  50. package/plugins/core/lib/querying-writing/request-contracts.js +590 -0
  51. package/plugins/core/lib/querying-writing/resource-id-normalization.js +131 -0
  52. package/plugins/core/lib/querying-writing/schema-helpers.js +0 -2
  53. package/plugins/core/lib/querying-writing/simplified-helpers.js +4 -11
  54. package/plugins/core/lib/storage/canonical-storage-mapping.js +133 -0
  55. package/plugins/core/lib/storage/storage-adapter.js +82 -4
  56. package/plugins/core/lib/storage/storage-mapping.js +274 -0
  57. package/plugins/core/lib/writing/many-to-many-manipulations.js +4 -2
  58. package/plugins/core/rest-api-anyapi-knex-plugin.js +531 -312
  59. package/plugins/core/rest-api-autofilter-plugin.js +414 -0
  60. package/plugins/core/rest-api-knex-plugin.js +271 -226
  61. package/plugins/core/rest-api-plugin-hooks/register-relationship-routes.js +10 -5
  62. package/plugins/core/rest-api-plugin-hooks/register-scope-routes.js +12 -6
  63. package/plugins/core/rest-api-plugin-hooks/turn-scope-init-into-vars.js +1 -0
  64. package/plugins/core/rest-api-plugin-methods/apply-query-filters.js +41 -0
  65. package/plugins/core/rest-api-plugin-methods/common.js +148 -92
  66. package/plugins/core/rest-api-plugin-methods/delete-relationship.js +11 -2
  67. package/plugins/core/rest-api-plugin-methods/delete.js +6 -1
  68. package/plugins/core/rest-api-plugin-methods/enrich-attributes.js +6 -1
  69. package/plugins/core/rest-api-plugin-methods/get-related.js +7 -2
  70. package/plugins/core/rest-api-plugin-methods/get-relationship.js +7 -2
  71. package/plugins/core/rest-api-plugin-methods/get.js +29 -14
  72. package/plugins/core/rest-api-plugin-methods/patch-relationship.js +10 -3
  73. package/plugins/core/rest-api-plugin-methods/patch.js +56 -12
  74. package/plugins/core/rest-api-plugin-methods/post-relationship.js +11 -2
  75. package/plugins/core/rest-api-plugin-methods/post.js +21 -8
  76. package/plugins/core/rest-api-plugin-methods/put.js +73 -21
  77. package/plugins/core/rest-api-plugin-methods/query.js +15 -53
  78. package/plugins/core/rest-api-plugin-methods/release.js +0 -2
  79. package/plugins/core/rest-api-plugin.js +6 -0
  80. package/plugins/core/rest-api-positioning-plugin.js +2 -5
  81. package/plugins/core/rest-api-query-projections-plugin.js +130 -0
  82. package/plugins/core/socketio-plugin.js +1 -4
  83. package/plugins/storage/local-storage.js +1 -1
  84. package/plugins/storage/s3-storage.js +5 -2
  85. package/quickTest.js +1 -0
  86. package/scripts/run-docs.js +80 -84
  87. package/test-debug.js +1 -1
  88. package/tests/README.md +7 -0
  89. package/tests/anyapi-basic.test.js +3 -0
  90. package/tests/autofilter.test.js +463 -0
  91. package/tests/custom-id-mysql-returning-fallback.test.js +128 -0
  92. package/tests/custom-id-simplified-post.test.js +75 -0
  93. package/tests/custom-idproperty-relationships.test.js +33 -0
  94. package/tests/db-introspection.test.js +521 -0
  95. package/tests/db-table-operations.test.js +786 -0
  96. package/tests/fastify-plugin.test.js +156 -0
  97. package/tests/field-getters.test.js +1 -2
  98. package/tests/field-setters.test.js +0 -4
  99. package/tests/fixtures/api-configs.js +278 -176
  100. package/tests/helpers/fake-fastify.js +99 -0
  101. package/tests/http-connectors-parity.test.js +235 -0
  102. package/tests/id-normalization.test.js +444 -0
  103. package/tests/logical-id-write-validation.test.js +151 -0
  104. package/tests/pagination-cursor-multifield.test.js +11 -11
  105. package/tests/projected-fields.test.js +319 -0
  106. package/tests/relationships.test.js +3 -3
  107. package/tests/searchschema-knex-behavior.test.js +187 -0
  108. package/tests/searchschema-merge.test.js +21 -69
  109. package/tests/storage-mapping.test.js +259 -0
  110. package/audit/00-charter.md +0 -103
  111. package/audit/01-scope-map.md +0 -84
  112. package/audit/02-coverage-matrix.csv +0 -174
  113. package/audit/03-invariants.md +0 -123
  114. package/audit/04-standards-rubric.md +0 -56
  115. package/audit/05-competitor-rubric.md +0 -77
  116. package/audit/06-findings.md +0 -160
  117. package/audit/07-risk-register.csv +0 -10
  118. package/audit/08-remediation-roadmap.md +0 -177
  119. package/audit/09-signoff-check.md +0 -23
  120. package/audit/10-final-synthesis.md +0 -29
  121. package/audit/evidence/code/all-files-json-rest-api.txt +0 -168
  122. package/audit/evidence/code/all-files-json-rest-schema.txt +0 -12
  123. package/audit/evidence/code/boundary-leak-checks.txt +0 -72
  124. package/audit/evidence/code/critical-pass1/json-rest-api__plugins__core__bulk-operations-plugin.js.txt +0 -480
  125. package/audit/evidence/code/critical-pass1/json-rest-api__plugins__core__connectors__express-plugin.js.txt +0 -532
  126. package/audit/evidence/code/critical-pass1/json-rest-api__plugins__core__connectors__lib__busboy-detector.js.txt +0 -175
  127. package/audit/evidence/code/critical-pass1/json-rest-api__plugins__core__connectors__lib__formidable-detector.js.txt +0 -138
  128. package/audit/evidence/code/critical-pass1/json-rest-api__plugins__core__connectors__lib__request-helpers.js.txt +0 -222
  129. package/audit/evidence/code/critical-pass1/json-rest-api__plugins__core__file-handling-plugin.js.txt +0 -342
  130. package/audit/evidence/code/critical-pass1/json-rest-api__plugins__core__lib__dbTablesOperations.js.txt +0 -304
  131. package/audit/evidence/code/critical-pass1/json-rest-api__plugins__core__lib__fractional-positioning.js.txt +0 -188
  132. package/audit/evidence/code/critical-pass1/json-rest-api__plugins__core__lib__querying-writing__compile-schemas.js.txt +0 -336
  133. package/audit/evidence/code/critical-pass1/json-rest-api__plugins__core__lib__querying-writing__connectors-query-parser.js.txt +0 -165
  134. package/audit/evidence/code/critical-pass1/json-rest-api__plugins__core__lib__querying-writing__database-capabilities.js.txt +0 -265
  135. package/audit/evidence/code/critical-pass1/json-rest-api__plugins__core__lib__querying-writing__database-value-normalizers.js.txt +0 -369
  136. package/audit/evidence/code/critical-pass1/json-rest-api__plugins__core__lib__querying-writing__default-data-helpers.js.txt +0 -72
  137. package/audit/evidence/code/critical-pass1/json-rest-api__plugins__core__lib__querying-writing__field-utils.js.txt +0 -139
  138. package/audit/evidence/code/critical-pass1/json-rest-api__plugins__core__lib__querying-writing__knex-constants.js.txt +0 -45
  139. package/audit/evidence/code/critical-pass1/json-rest-api__plugins__core__lib__querying-writing__knex-field-helpers.js.txt +0 -396
  140. package/audit/evidence/code/critical-pass1/json-rest-api__plugins__core__lib__querying-writing__knex-json-api-transformers.js.txt +0 -162
  141. package/audit/evidence/code/critical-pass1/json-rest-api__plugins__core__lib__querying-writing__payload-validators.js.txt +0 -1314
  142. package/audit/evidence/code/critical-pass1/json-rest-api__plugins__core__lib__querying-writing__schema-helpers.js.txt +0 -488
  143. package/audit/evidence/code/critical-pass1/json-rest-api__plugins__core__lib__querying-writing__scope-validations.js.txt +0 -484
  144. package/audit/evidence/code/critical-pass1/json-rest-api__plugins__core__lib__querying-writing__simplified-helpers.js.txt +0 -857
  145. package/audit/evidence/code/critical-pass1/json-rest-api__plugins__core__lib__querying__knex-cross-table-search.js.txt +0 -565
  146. package/audit/evidence/code/critical-pass1/json-rest-api__plugins__core__lib__querying__knex-json-api-transformers-querying.js.txt +0 -485
  147. package/audit/evidence/code/critical-pass1/json-rest-api__plugins__core__lib__querying__knex-pagination-helpers.js.txt +0 -560
  148. package/audit/evidence/code/critical-pass1/json-rest-api__plugins__core__lib__querying__knex-process-includes.js.txt +0 -167
  149. package/audit/evidence/code/critical-pass1/json-rest-api__plugins__core__lib__querying__knex-query-helpers-base.js.txt +0 -109
  150. package/audit/evidence/code/critical-pass1/json-rest-api__plugins__core__lib__querying__knex-query-helpers.js.txt +0 -1064
  151. package/audit/evidence/code/critical-pass1/json-rest-api__plugins__core__lib__querying__knex-relationship-includes.js.txt +0 -1983
  152. package/audit/evidence/code/critical-pass1/json-rest-api__plugins__core__lib__querying__knex-window-queries.js.txt +0 -328
  153. package/audit/evidence/code/critical-pass1/json-rest-api__plugins__core__lib__querying__url-helpers.js.txt +0 -119
  154. package/audit/evidence/code/critical-pass1/json-rest-api__plugins__core__lib__storage__storage-adapter.js.txt +0 -160
  155. package/audit/evidence/code/critical-pass1/json-rest-api__plugins__core__lib__writing__many-to-many-manipulations.js.txt +0 -300
  156. package/audit/evidence/code/critical-pass1/json-rest-api__plugins__core__lib__writing__relationship-processor.js.txt +0 -245
  157. package/audit/evidence/code/critical-pass1/json-rest-api__plugins__core__rest-api-access.js.txt +0 -459
  158. package/audit/evidence/code/critical-pass1/json-rest-api__plugins__core__rest-api-cors-plugin.js.txt +0 -237
  159. package/audit/evidence/code/critical-pass1/json-rest-api__plugins__core__rest-api-knex-plugin.js.txt +0 -1135
  160. package/audit/evidence/code/critical-pass1/json-rest-api__plugins__core__rest-api-multihome-plugin.js.txt +0 -314
  161. package/audit/evidence/code/critical-pass1/json-rest-api__plugins__core__rest-api-plugin-hooks__compile-resource-schemas.js.txt +0 -7
  162. package/audit/evidence/code/critical-pass1/json-rest-api__plugins__core__rest-api-plugin-hooks__register-relationship-routes.js.txt +0 -71
  163. package/audit/evidence/code/critical-pass1/json-rest-api__plugins__core__rest-api-plugin-hooks__register-scope-routes.js.txt +0 -102
  164. package/audit/evidence/code/critical-pass1/json-rest-api__plugins__core__rest-api-plugin-hooks__turn-scope-init-into-vars.js.txt +0 -49
  165. package/audit/evidence/code/critical-pass1/json-rest-api__plugins__core__rest-api-plugin-hooks__validate-include-configurations.js.txt +0 -39
  166. package/audit/evidence/code/critical-pass1/json-rest-api__plugins__core__rest-api-plugin-methods__add-route.js.txt +0 -23
  167. package/audit/evidence/code/critical-pass1/json-rest-api__plugins__core__rest-api-plugin-methods__check-permissions.js.txt +0 -13
  168. package/audit/evidence/code/critical-pass1/json-rest-api__plugins__core__rest-api-plugin-methods__common.js.txt +0 -639
  169. package/audit/evidence/code/critical-pass1/json-rest-api__plugins__core__rest-api-plugin-methods__delete-relationship.js.txt +0 -117
  170. package/audit/evidence/code/critical-pass1/json-rest-api__plugins__core__rest-api-plugin-methods__delete.js.txt +0 -104
  171. package/audit/evidence/code/critical-pass1/json-rest-api__plugins__core__rest-api-plugin-methods__enrich-attributes.js.txt +0 -199
  172. package/audit/evidence/code/critical-pass1/json-rest-api__plugins__core__rest-api-plugin-methods__get-related.js.txt +0 -353
  173. package/audit/evidence/code/critical-pass1/json-rest-api__plugins__core__rest-api-plugin-methods__get-relationship.js.txt +0 -61
  174. package/audit/evidence/code/critical-pass1/json-rest-api__plugins__core__rest-api-plugin-methods__get.js.txt +0 -184
  175. package/audit/evidence/code/critical-pass1/json-rest-api__plugins__core__rest-api-plugin-methods__patch-relationship.js.txt +0 -55
  176. package/audit/evidence/code/critical-pass1/json-rest-api__plugins__core__rest-api-plugin-methods__patch.js.txt +0 -191
  177. package/audit/evidence/code/critical-pass1/json-rest-api__plugins__core__rest-api-plugin-methods__post-relationship.js.txt +0 -110
  178. package/audit/evidence/code/critical-pass1/json-rest-api__plugins__core__rest-api-plugin-methods__post.js.txt +0 -168
  179. package/audit/evidence/code/critical-pass1/json-rest-api__plugins__core__rest-api-plugin-methods__put.js.txt +0 -253
  180. package/audit/evidence/code/critical-pass1/json-rest-api__plugins__core__rest-api-plugin-methods__query.js.txt +0 -207
  181. package/audit/evidence/code/critical-pass1/json-rest-api__plugins__core__rest-api-plugin-methods__release.js.txt +0 -12
  182. package/audit/evidence/code/critical-pass1/json-rest-api__plugins__core__rest-api-plugin.js.txt +0 -165
  183. package/audit/evidence/code/critical-pass1/json-rest-api__plugins__core__rest-api-positioning-plugin.js.txt +0 -668
  184. package/audit/evidence/code/critical-pass1/json-rest-api__plugins__core__socketio-plugin.js.txt +0 -621
  185. package/audit/evidence/code/critical-pass1/json-rest-api__plugins__storage__local-storage.js.txt +0 -218
  186. package/audit/evidence/code/critical-pass1/json-rest-api__plugins__storage__s3-storage.js.txt +0 -124
  187. package/audit/evidence/code/critical-pass1/json-rest-schema__src__CorePlugin.js.txt +0 -269
  188. package/audit/evidence/code/critical-pass1/json-rest-schema__src__Schema.js.txt +0 -242
  189. package/audit/evidence/code/critical-pass1/json-rest-schema__src__index.js.txt +0 -77
  190. package/audit/evidence/code/critical-pass1-risk-keywords.txt +0 -238
  191. package/audit/evidence/code/critical-pass1-summary.csv +0 -67
  192. package/audit/evidence/code/critical-pass2-summary.csv +0 -67
  193. package/audit/evidence/code/early-silent-zones-no-test-token.txt +0 -57
  194. package/audit/evidence/code/error-model-signals.txt +0 -98
  195. package/audit/evidence/code/git-files-json-rest-api.txt +0 -171
  196. package/audit/evidence/code/git-files-json-rest-schema.txt +0 -27
  197. package/audit/evidence/code/hook-flow-signals.txt +0 -282
  198. package/audit/evidence/code/idproperty-signals.txt +0 -157
  199. package/audit/evidence/code/import-cycles-non-anyapi.txt +0 -3
  200. package/audit/evidence/code/import-hotspots-non-anyapi.txt +0 -96
  201. package/audit/evidence/code/imports-json-rest-api.txt +0 -354
  202. package/audit/evidence/code/imports-json-rest-schema.txt +0 -15
  203. package/audit/evidence/code/in-scope-files-json-rest-api.txt +0 -160
  204. package/audit/evidence/code/in-scope-files-json-rest-schema.txt +0 -13
  205. package/audit/evidence/code/non-anyapi-core-files.txt +0 -101
  206. package/audit/evidence/code/permission-signals.txt +0 -193
  207. package/audit/evidence/code/query-include-signals.txt +0 -687
  208. package/audit/evidence/code/transaction-signals.txt +0 -28
  209. package/audit/evidence/code/validation-signals.txt +0 -650
  210. package/audit/evidence/code/write-path-signals.txt +0 -61
  211. package/audit/evidence/docs/docs-claims-signals.txt +0 -1075
  212. package/audit/evidence/docs/schema-docs-claims-signals.txt +0 -179
  213. package/audit/evidence/external/corpus-freeze.md +0 -21
  214. package/audit/evidence/external/npm-competitor-metadata.txt +0 -70
  215. package/audit/evidence/external/npm-download-signals.txt +0 -23
  216. package/audit/evidence/external/npm-jsonapi-server.txt +0 -8
  217. package/audit/evidence/external/npm-modern-jsonapi-metadata.txt +0 -38
  218. package/audit/evidence/external/readme-fortune-signals.txt +0 -26
  219. package/audit/evidence/external/readme-fortune.md +0 -165
  220. package/audit/evidence/external/readme-json-api-serializer-signals.txt +0 -80
  221. package/audit/evidence/external/readme-json-api-serializer.md +0 -690
  222. package/audit/evidence/external/readme-jsonapi-serde-server-signals.txt +0 -0
  223. package/audit/evidence/external/readme-jsonapi-serde-server.md +0 -22
  224. package/audit/evidence/external/readme-jsonapi-serializer-signals.txt +0 -63
  225. package/audit/evidence/external/readme-jsonapi-serializer.md +0 -315
  226. package/audit/evidence/external/readme-jsonapi-server-signals.txt +0 -19
  227. package/audit/evidence/external/readme-jsonapi-server.md +0 -104
  228. package/audit/evidence/external/readme-nestjs-json-api-signals.txt +0 -4
  229. package/audit/evidence/external/readme-nestjs-json-api.md +0 -94
  230. package/audit/evidence/external/readme-yaser-json-api-nestjs-signals.txt +0 -47
  231. package/audit/evidence/external/readme-yaser-json-api-nestjs.md +0 -447
  232. package/audit/evidence/external/standard-jsonapi-snippets.txt +0 -84
  233. package/audit/evidence/external/standard-rfc-snippets.txt +0 -168
  234. package/audit/evidence/external/standards-sources.txt +0 -6
  235. package/audit/evidence/runtime/baseline-commits.txt +0 -2
  236. package/audit/evidence/runtime/db-adapter-assumptions.txt +0 -3
  237. package/audit/evidence/runtime/environment.txt +0 -4
  238. package/audit/evidence/runtime/invariant-runtime-mapping.md +0 -38
  239. package/audit/evidence/runtime/probe-patch-relationship-error.exitcode +0 -1
  240. package/audit/evidence/runtime/probe-patch-relationship-error.log +0 -76
  241. package/audit/evidence/runtime/probe-patch-relationship-error.mjs +0 -67
  242. package/audit/evidence/runtime/probe-patch-relationship-referenceerror.exitcode +0 -1
  243. package/audit/evidence/runtime/probe-patch-relationship-referenceerror.log +0 -62
  244. package/audit/evidence/runtime/probe-patch-relationship-referenceerror.mjs +0 -47
  245. package/audit/evidence/runtime/test-exitcodes.txt +0 -4
  246. package/audit/evidence/runtime/test-summary.md +0 -107
  247. package/audit/evidence/runtime/trace-anchors.txt +0 -61
  248. package/audit/evidence/tests/access-multitenancy-test-signals.txt +0 -125
  249. package/audit/evidence/tests/failing-tests-summary.txt +0 -25
  250. package/audit/evidence/tests/npm-test-json-rest-api.exitcode +0 -1
  251. package/audit/evidence/tests/npm-test-json-rest-api.log +0 -5885
  252. package/audit/evidence/tests/npm-test-json-rest-schema.exitcode +0 -1
  253. package/audit/evidence/tests/npm-test-json-rest-schema.log +0 -356
  254. package/audit/evidence/tests/query-include-test-signals.txt +0 -948
  255. package/audit/evidence/tests/relationship-test-signals.txt +0 -223
  256. package/audit/evidence/tests/skipped-tests.txt +0 -10
  257. package/audit/evidence/tests/test-suite-list-non-anyapi.txt +0 -30
  258. package/audit/evidence/tests/test-suite-list.txt +0 -32
  259. package/audit/subsystems/docs-drift.md +0 -49
  260. package/audit/subsystems/pass2-cross-review.md +0 -131
  261. package/audit/subsystems/plugins-access.md +0 -51
  262. package/audit/subsystems/plugins-bulk.md +0 -50
  263. package/audit/subsystems/plugins-cors.md +0 -48
  264. package/audit/subsystems/plugins-file.md +0 -53
  265. package/audit/subsystems/plugins-multihome.md +0 -50
  266. package/audit/subsystems/plugins-positioning.md +0 -54
  267. package/audit/subsystems/plugins-socketio.md +0 -50
  268. package/audit/subsystems/query-engine.md +0 -61
  269. package/audit/subsystems/relationships.md +0 -55
  270. package/audit/subsystems/rest-orchestration.md +0 -66
  271. package/audit/subsystems/schema-core.md +0 -64
  272. package/audit/subsystems/storage-knex.md +0 -57
  273. package/audit/subsystems/tests.md +0 -48
  274. package/audit/subsystems/transport-express.md +0 -55
  275. package/audit/traces/trace-read-get.md +0 -22
  276. package/audit/traces/trace-read-query.md +0 -25
  277. package/audit/traces/trace-relationship-endpoints.md +0 -31
  278. package/audit/traces/trace-write-delete.md +0 -17
  279. package/audit/traces/trace-write-patch.md +0 -26
  280. package/audit/traces/trace-write-post.md +0 -22
  281. package/audit/traces/trace-write-put.md +0 -23
  282. package/docs/GUIDE/GUIDE_4_Authentication_And_Permissions.md +0 -707
  283. package/docs/GUIDE/GUIDE_X_Multihome.md +0 -666
  284. package/plugins/core/lib/querying-writing/payload-validators.js +0 -1314
  285. package/plugins/core/rest-api-access.js +0 -459
  286. package/plugins/core/rest-api-multihome-plugin.js +0 -314
  287. package/tests/multihome.test.js +0 -553
  288. package/tests/multihome.test.js.bak +0 -550
  289. package/tests/ownership-optout.test.js +0 -76
  290. package/tests/rest-api-access.test.js +0 -206
@@ -1,690 +0,0 @@
1
- # json-api-serializer
2
-
3
- [![Build Status](https://travis-ci.org/danivek/json-api-serializer.svg?branch=master)](https://travis-ci.org/danivek/json-api-serializer)
4
- [![Coverage Status](https://coveralls.io/repos/github/danivek/json-api-serializer/badge.svg?branch=master)](https://coveralls.io/github/danivek/json-api-serializer?branch=master)
5
- [![npm](https://img.shields.io/npm/v/json-api-serializer.svg)](https://www.npmjs.org/package/json-api-serializer)
6
-
7
- A Node.js/browser framework agnostic library for serializing your data to [JSON API](http://jsonapi.org/) compliant responses (a specification for building APIs in JSON).
8
-
9
- ## Installation
10
-
11
- ```bash
12
- npm install --save json-api-serializer
13
- ```
14
-
15
- ## Documentation
16
-
17
- ### Register
18
-
19
- ```javascript
20
- var JSONAPISerializer = require("json-api-serializer");
21
- var Serializer = new JSONAPISerializer();
22
- Serializer.register(type, options);
23
- ```
24
-
25
- **Serialization options:**
26
-
27
- * **id** (optional): The key to use as the reference. Default = 'id'.
28
- * **blacklist** (optional): An array of blacklisted attributes. Default = [].
29
- * **whitelist** (optional): An array of whitelisted attributes. Default = [].
30
- * **jsonapiObject** (optional): Enable/Disable [JSON API Object](http://jsonapi.org/format/#document-jsonapi-object). Default = true.
31
- * **links** (optional): Describes the links inside data. It can be:
32
- * An _object_ (values can be string or function).
33
- * A _function_ with one argument `function(data) { ... }` or with two arguments `function(data, extraData) { ... }`
34
- * **topLevelMeta** (optional): Describes the top-level meta. It can be:
35
- * An _object_ (values can be string or function).
36
- * A _function_ with one argument `function(extraData) { ... }` or with two arguments `function(data, extraData) { ... }`
37
- * **topLevelLinks** (optional): Describes the top-level links. It can be:
38
- * An _object_ (values can be string or function).
39
- * A _function_ with one argument `function(extraData) { ... }` or with two arguments `function(data, extraData) { ... }`
40
- * **meta** (optional): Describes resource-level meta. It can be:
41
- * An _object_ (values can be string or function).
42
- * A _function_ with one argument `function(data) { ... }` or with two arguments `function(data, extraData) { ... }`
43
- * **relationships** (optional): An object defining some relationships
44
- * relationship: The property in data to use as a relationship
45
- * **type**: A _string_ or a _function_ `function(relationshipData, data) { ... }` for the type to use for serializing the relationship (type need to be register).
46
- * **alternativeKey** (optional): An alternative key (string or path) to use if relationship key not exist (example: 'author_id' as an alternative key for 'author' relationship). See [issue #12](https://github.com/danivek/json-api-serializer/issues/12).
47
- * **schema** (optional): A custom schema for serializing the relationship. If no schema define, it use the default one.
48
- * **links** (optional): Describes the links for the relationship. It can be:
49
- * An _object_ (values can be string or function).
50
- * A _function_ with one argument `function(data) { ... }` or with two arguments `function(data, extraData) { ... }`
51
- * **meta** (optional): Describes meta that contains non-standard meta-information about the relationship. It can be:
52
- * An _object_ (values can be string or function).
53
- * A _function_ with one argument `function(data) { ... }` or with two arguments `function(data, extraData) { ... }`
54
- * **deserialize** (optional): Describes the function which should be used to deserialize a related property which is not included in the JSON:API document. It should be:
55
- * A _function_ with one argument `function(data) { ... }`which defines the format to which a relation should be deserialized. By default, the ID of the related object is returned, which would be equal to `function(data) {return data.id}`. See [issue #65](https://github.com/danivek/json-api-serializer/issues/65).
56
- * **convertCase** (optional): Case conversion for serializing data. Value can be : `kebab-case`, `snake_case`, `camelCase`
57
- * **beforeSerialize** (optional): A _function_ with one argument `beforeSerialize(data) => newData` to transform data before serialization.
58
-
59
- **Deserialization options:**
60
-
61
- * **unconvertCase** (optional): Case conversion for deserializing data. Value can be : `kebab-case`, `snake_case`, `camelCase`
62
- * **blacklistOnDeserialize** (optional): An array of blacklisted attributes. Default = [].
63
- * **whitelistOnDeserialize** (optional): An array of whitelisted attributes. Default = [].
64
- * **afterDeserialize** (optional): A _function_ with one argument `afterDeserialize(data) => newData` to transform data after deserialization.
65
-
66
- **Global options:**
67
-
68
- To avoid repeating the same options for each type, it's possible to add global options on `JSONAPISerializer` instance:
69
-
70
- When using convertCase, a LRU cache is utilized for optimization. The default size of the cache is 5000 per conversion type. The size of the cache can be set with the `convertCaseCacheSize` option. Passing in 0 will result in a LRU cache of infinite size.
71
-
72
- ```javascript
73
- var JSONAPISerializer = require("json-api-serializer");
74
- var Serializer = new JSONAPISerializer({
75
- convertCase: "kebab-case",
76
- unconvertCase: "camelCase",
77
- convertCaseCacheSize: 0
78
- });
79
- ```
80
-
81
- ## Usage
82
-
83
- input data (can be an object or an array of objects)
84
-
85
- ```javascript
86
- // Data
87
- var data = [
88
- {
89
- id: "1",
90
- title: "JSON API paints my bikeshed!",
91
- body: "The shortest article. Ever.",
92
- created: "2015-05-22T14:56:29.000Z",
93
- updated: "2015-05-22T14:56:28.000Z",
94
- author: {
95
- id: "1",
96
- firstName: "Kaley",
97
- lastName: "Maggio",
98
- email: "Kaley-Maggio@example.com",
99
- age: "80",
100
- gender: "male"
101
- },
102
- tags: ["1", "2"],
103
- photos: [
104
- "***",
105
- "***",
106
- "***"
107
- ],
108
- comments: [
109
- {
110
- _id: "1",
111
- body: "First !",
112
- created: "2015-08-14T18:42:16.475Z"
113
- },
114
- {
115
- _id: "2",
116
- body: "I Like !",
117
- created: "2015-09-14T18:42:12.475Z"
118
- },
119
- {
120
- _id: "3",
121
- body: "Awesome",
122
- created: "2015-09-15T18:42:12.475Z"
123
- }
124
- ]
125
- }
126
- ];
127
- ```
128
-
129
- ### Register
130
-
131
- Register your resources types :
132
-
133
- ```javascript
134
- var JSONAPISerializer = require("json-api-serializer");
135
- var Serializer = new JSONAPISerializer();
136
-
137
- // Register 'article' type
138
- Serializer.register("article", {
139
- id: "id", // The attributes to use as the reference. Default = 'id'.
140
- blacklist: ["updated"], // An array of blacklisted attributes. Default = []
141
- links: {
142
- // An object or a function that describes links.
143
- self: function(data) {
144
- // Can be a function or a string value ex: { self: '/articles/1'}
145
- return "/articles/" + data.id;
146
- }
147
- },
148
- relationships: {
149
- // An object defining some relationships.
150
- author: {
151
- type: "people", // The type of the resource
152
- links: function(data) {
153
- // An object or a function that describes Relationships links
154
- return {
155
- self: "/articles/" + data.id + "/relationships/author",
156
- related: "/articles/" + data.id + "/author"
157
- };
158
- }
159
- },
160
- tags: {
161
- type: "tag"
162
- },
163
- photos: {
164
- type: "photo"
165
- },
166
- comments: {
167
- type: "comment",
168
- schema: "only-body" // A custom schema
169
- }
170
- },
171
- topLevelMeta: function(data, extraData) {
172
- // An object or a function that describes top level meta.
173
- return {
174
- count: extraData.count,
175
- total: data.length
176
- };
177
- },
178
- topLevelLinks: {
179
- // An object or a function that describes top level links.
180
- self: "/articles" // Can be a function (with extra data argument) or a string value
181
- }
182
- });
183
-
184
- // Register 'people' type
185
- Serializer.register("people", {
186
- id: "id",
187
- links: {
188
- self: function(data) {
189
- return "/peoples/" + data.id;
190
- }
191
- }
192
- });
193
-
194
- // Register 'tag' type
195
- Serializer.register("tag", {
196
- id: "id"
197
- });
198
-
199
- // Register 'photo' type
200
- Serializer.register("photo", {
201
- id: "id"
202
- });
203
-
204
- // Register 'comment' type with a custom schema
205
- Serializer.register("comment", "only-body", {
206
- id: "_id"
207
- });
208
- ```
209
-
210
- ### Serialize
211
-
212
- Serialize it with the corresponding resource type, data and optional extra data :
213
-
214
- ```javascript
215
- // Synchronously (blocking)
216
- const result = Serializer.serialize('article', data, {count: 2});
217
-
218
- // Asynchronously (non-blocking)
219
- Serializer.serializeAsync('article', data, {count: 2})
220
- .then((result) => {
221
- ...
222
- });
223
- ```
224
-
225
- The output data will be :
226
-
227
- ```JSON
228
- {
229
- "jsonapi": {
230
- "version": "1.0"
231
- },
232
- "meta": {
233
- "count": 2,
234
- "total": 1
235
- },
236
- "links": {
237
- "self": "/articles"
238
- },
239
- "data": [{
240
- "type": "article",
241
- "id": "1",
242
- "attributes": {
243
- "title": "JSON API paints my bikeshed!",
244
- "body": "The shortest article. Ever.",
245
- "created": "2015-05-22T14:56:29.000Z"
246
- },
247
- "relationships": {
248
- "author": {
249
- "data": {
250
- "type": "people",
251
- "id": "1"
252
- },
253
- "links": {
254
- "self": "/articles/1/relationships/author",
255
- "related": "/articles/1/author"
256
- }
257
- },
258
- "tags": {
259
- "data": [{
260
- "type": "tag",
261
- "id": "1"
262
- }, {
263
- "type": "tag",
264
- "id": "2"
265
- }]
266
- },
267
- "photos": {
268
- "data": [{
269
- "type": "photo",
270
- "id": "***"
271
- }, {
272
- "type": "photo",
273
- "id": "***"
274
- }, {
275
- "type": "photo",
276
- "id": "***"
277
- }]
278
- },
279
- "comments": {
280
- "data": [{
281
- "type": "comment",
282
- "id": "1"
283
- }, {
284
- "type": "comment",
285
- "id": "2"
286
- }, {
287
- "type": "comment",
288
- "id": "3"
289
- }]
290
- }
291
- },
292
- "links": {
293
- "self": "/articles/1"
294
- }
295
- }],
296
- "included": [{
297
- "type": "people",
298
- "id": "1",
299
- "attributes": {
300
- "firstName": "Kaley",
301
- "lastName": "Maggio",
302
- "email": "Kaley-Maggio@example.com",
303
- "age": "80",
304
- "gender": "male"
305
- },
306
- "links": {
307
- "self": "/peoples/1"
308
- }
309
- }, {
310
- "type": "comment",
311
- "id": "1",
312
- "attributes": {
313
- "body": "First !"
314
- }
315
- }, {
316
- "type": "comment",
317
- "id": "2",
318
- "attributes": {
319
- "body": "I Like !"
320
- }
321
- }, {
322
- "type": "comment",
323
- "id": "3",
324
- "attributes": {
325
- "body": "Awesome"
326
- }
327
- }]
328
- }
329
- ```
330
-
331
- There is an available argument `excludeData` that will exclude the `data`
332
- property from the serialized object. This can be used in cases where you may
333
- want to only include the `topLevelMeta` in your response, such as a `DELETE`
334
- response with only a `meta` property, or other cases defined in the
335
- JSON:API spec.
336
-
337
- ```javascript
338
- // Synchronously (blocking)
339
- const result = Serializer.serialize('article', data, 'default', {count: 2}, true);
340
-
341
- // Asynchronously (non-blocking)
342
- Serializer.serializeAsync('article', data, 'default', {count: 2}, true)
343
- .then((result) => {
344
- ...
345
- });
346
- ```
347
-
348
- #### Override schema options
349
-
350
- On each individual call to `serialize` or `serializeAsync`, there is an parameter to override the options of any registered type. For example on a call to serialize, if a whitelist was not defined on the registered schema options, a whitelist (or any other options) for that type can be provided. This parameter is an object, where the key are the registered type names, and the values are the objects to override the registered schema.
351
-
352
- In the following example, only the attribute `name` will be serialized on the article, and if there is a relationship for `person`, it will be serialized with `camelCase` even if the registered schema has a different value.
353
- ```
354
- const result = Serializer.serialize('article', data, 'default', {count: 2}, true), {
355
- article: {
356
- whitelist: ['name']
357
- },
358
- person: {
359
- convertCase: 'camelCase'
360
- }
361
- };
362
- ```
363
-
364
-
365
- Some others examples are available in [tests folders](https://github.com/danivek/json-api-serializer/blob/master/test/)
366
-
367
- ### Deserialize
368
-
369
- input data (can be an simple object or an array of objects)
370
-
371
- ```javascript
372
- var data = {
373
- data: {
374
- type: 'article',
375
- id: '1',
376
- attributes: {
377
- title: 'JSON API paints my bikeshed!',
378
- body: 'The shortest article. Ever.',
379
- created: '2015-05-22T14:56:29.000Z'
380
- },
381
- relationships: {
382
- author: {
383
- data: {
384
- type: 'people',
385
- id: '1'
386
- }
387
- },
388
- comments: {
389
- data: [{
390
- type: 'comment',
391
- id: '1'
392
- }, {
393
- type: 'comment',
394
- id: '2'
395
- }]
396
- }
397
- }
398
- }
399
- };
400
-
401
- // Synchronously (blocking)
402
- Serializer.deserialize('article', data);
403
-
404
- // Asynchronously (non-blocking)
405
- Serializer.deserializeAsync('article', data)
406
- .then((result) => {
407
- // ...
408
- });
409
- ```
410
-
411
- ```JSON
412
- {
413
- "id": "1",
414
- "title": "JSON API paints my bikeshed!",
415
- "body": "The shortest article. Ever.",
416
- "created": "2015-05-22T14:56:29.000Z",
417
- "author": "1",
418
- "comments": [
419
- "1",
420
- "2"
421
- ]
422
- }
423
- ```
424
-
425
- ### serializeError
426
-
427
- Serializes any error into a JSON API error document.
428
-
429
- Input data can be:
430
- - An instance of `Error` or an array of `Error` instances.
431
- - A [JSON API error object](http://jsonapi.org/format/#error-objects) or an array of [JSON API error objects](http://jsonapi.org/format/#error-objects).
432
-
433
- Using an instance of `Error`:
434
-
435
- ```javascript
436
- const error = new Error('An error occurred');
437
- error.id = 123
438
- error.links = { about: 'https://example.com/errors/123' }
439
- error.status = 500; // or `statusCode`
440
- error.code = 'xyz'
441
- error.meta = { time: Date.now() }
442
-
443
- Serializer.serializeError(error);
444
- ```
445
-
446
- The result will be:
447
-
448
- ```JSON
449
- {
450
- "errors": [
451
- {
452
- "id": 123,
453
- "links": {
454
- "about": "https://example.com/errors/123"
455
- },
456
- "status": "500",
457
- "code": "xyz",
458
- "title": "Error",
459
- "detail": "An error occurred",
460
- "meta": {
461
- "time": 1593561258853
462
- }
463
- }
464
- ]
465
- }
466
- ```
467
-
468
- Using an instance of a class that inherits from `Error`:
469
-
470
- ```js
471
- class MyCustomError extends Error {
472
- constructor(message = 'Something went wrong') {
473
- super(message)
474
- this.id = 123
475
- this.links = {
476
- about: 'https://example.com/errors/123'
477
- }
478
- this.status = 500 // or `statusCode`
479
- this.code = 'xyz'
480
- this.meta = {
481
- time: Date.now()
482
- }
483
- }
484
- }
485
-
486
- Serializer.serializeError(new MyCustomError());
487
- ```
488
-
489
- The result will be:
490
-
491
- ```JSON
492
- {
493
- "errors": [
494
- {
495
- "id": 123,
496
- "links": {
497
- "about": "https://example.com/errors/123"
498
- },
499
- "status": "500",
500
- "code": "xyz",
501
- "title": "MyCustomError",
502
- "detail": "Something went wrong",
503
- "meta": {
504
- "time": 1593561258853
505
- }
506
- }
507
- ]
508
- }
509
- ```
510
-
511
- Using a POJO:
512
-
513
- ```js
514
- Serializer.serializeError({
515
- id: 123,
516
- links: {
517
- about: 'https://example.com/errors/123'
518
- },
519
- status: 500, // or `statusCode`
520
- code: 'xyz',
521
- title: 'UserNotFound',
522
- detail: 'Unable to find a user with the provided ID',
523
- meta: {
524
- time: Date.now()
525
- }
526
- });
527
- ```
528
-
529
- The result will be:
530
-
531
- ```JSON
532
- {
533
- "errors": [
534
- {
535
- "id": 123,
536
- "links": {
537
- "about": "https://example.com/errors/123"
538
- },
539
- "status": "500",
540
- "code": "xyz",
541
- "title": "UserNotFound",
542
- "detail": "Unable to find a user with the provided ID",
543
- "meta": {
544
- "time": 1593561258853
545
- }
546
- }
547
- ]
548
- }
549
- ```
550
-
551
- ## Custom schemas
552
-
553
- It is possible to define multiple custom schemas for a resource type :
554
-
555
- ```javascript
556
- Serializer.register(type, "customSchema", options);
557
- ```
558
-
559
- Then you can apply this schema on the primary data when serialize or deserialize :
560
-
561
- ```javascript
562
- Serializer.serialize("article", data, "customSchema", { count: 2 });
563
- Serializer.serializeAsync("article", data, "customSchema", { count: 2 });
564
- Serializer.deserialize("article", jsonapiData, "customSchema");
565
- Serializer.deserializeAsync("article", jsonapiData, "customSchema");
566
- ```
567
-
568
- Or if you want to apply this schema on a relationship data, define this schema on relationships options with the key `schema` :
569
-
570
- Example :
571
-
572
- ```javascript
573
- relationships: {
574
- comments: {
575
- type: "comment";
576
- schema: "customSchema";
577
- }
578
- }
579
- ```
580
-
581
- ## Mixed data (dynamic type)
582
-
583
- ### Serialize
584
-
585
- If your data contains one or multiple objects of different types, it's possible to define a configuration object instead of the type-string as the first argument of `serialize` and `serializeAsync` with these options:
586
-
587
- * **type** (required): A _string_ for the path to the key to use to determine type or a _function_ deriving a type-string from each data-item.
588
- * **jsonapiObject** (optional): Enable/Disable [JSON API Object](http://jsonapi.org/format/#document-jsonapi-object). Default = true.
589
- * **topLevelMeta** (optional): Describes the top-level meta. It can be:
590
- * An _object_ (values can be string or function).
591
- * A _function_ with one argument `function(extraData) { ... }` or with two arguments `function(data, extraData) { ... }`
592
- * **topLevelLinks** (optional): Describes the top-level links. It can be:
593
- * An _object_ (values can be string or function).
594
- * A _function_ with one argument `function(extraData) { ... }` or with two arguments `function(data, extraData) { ... }`
595
-
596
- Example :
597
-
598
- ```javascript
599
- const typeConfig = {
600
- // Same as type: 'type'
601
- type: data => data.type // Can be very complex to determine different types of items.
602
- };
603
-
604
- Serializer.serializeAsync(typeConfig, data, { count: 2 }).then(result => {
605
- // ...
606
- });
607
- ```
608
-
609
- ### Deserialize
610
-
611
- If your data contains one or multiple objects of different types, it's possible to define a configuration object instead of the type-string as the first argument of `deserialize` with these options:
612
-
613
- * **type** (required): A _string_ for the path to the key to use to determine type or a _function_ deriving a type-string from each data-item.
614
-
615
- Example :
616
-
617
- ```javascript
618
- const typeConfig = {
619
- // Same as type: 'type'
620
- type: data => data.type // Can be very complex to determine different types of items.
621
- };
622
-
623
- const deserialized = Serializer.deserializeAsync(typeConfig, data).then(result => {
624
- // ...
625
- });
626
- ```
627
-
628
- ## Custom serialization and deserialization
629
-
630
- If your data requires some specific transformations, those can be applied using `beforeSerialize` and `afterDeserialize`
631
-
632
- Example for composite primary keys:
633
-
634
- ```javascript
635
- Serializer.register('translation', {
636
- beforeSerialize: (data) => {
637
- // Exclude pk1 and pk2 from data
638
- const { pk1, pk2, ...attributes } = data;
639
-
640
- // Compute external id
641
- const id = `${pk1}-${pk2}`;
642
-
643
- // Return data with id
644
- return {
645
- ...attributes,
646
- id
647
- };
648
- },
649
- afterDeserialize: (data) => {
650
- // Exclude id from data
651
- const { id, ...attributes } = data;
652
-
653
- // Recover PKs
654
- const [pk1, pk2] = id.split('-');
655
-
656
- // Return data with PKs
657
- return {
658
- ...attributes,
659
- pk1,
660
- pk2,
661
- };
662
- },
663
- });
664
- ```
665
-
666
- ## Benchmark
667
-
668
- ```bash
669
- Platform info:
670
- ==============
671
- Darwin 18.7.0 x64
672
- Node.JS: 10.16.3
673
- V8: 6.8.275.32-node.54
674
- Intel(R) Core(TM) i7-4770HQ CPU @ 2.20GHz × 8
675
-
676
- Suite:
677
- ==============
678
- serializeAsync x 80,043 ops/sec ±0.74% (78 runs sampled)
679
- serialize x 135,669 ops/sec ±1.12% (88 runs sampled)
680
- serializeConvertCase x 98,785 ops/sec ±2.34% (88 runs sampled)
681
- deserializeAsync x 172,832 ops/sec ±0.41% (82 runs sampled)
682
- deserialize x 393,979 ops/sec ±0.32% (91 runs sampled)
683
- deserializeConvertCase x 119,021 ops/sec ±1.76% (95 runs sampled)
684
- serializeError x 276,346 ops/sec ±1.07% (86 runs sampled)
685
- serializeError with a JSON API error object x 15,783,113 ops/sec ±1.74% (88 runs sampled)
686
- ```
687
-
688
- ## License
689
-
690
- [MIT](https://github.com/danivek/json-api-serializer/blob/master/LICENSE)
@@ -1,22 +0,0 @@
1
- # JSON:API Serde - Server
2
-
3
- [![Test](https://github.com/DASPRiD/jsonapi-serde-js/actions/workflows/test.yml/badge.svg)](https://github.com/DASPRiD/jsonapi-serde-js/actions/workflows/test.yml)
4
- [![codecov](https://codecov.io/gh/DASPRiD/jsonapi-serde-js/graph/badge.svg?token=UfRUzGqiN3&component=server)](https://codecov.io/gh/DASPRiD/jsonapi-serde-js)
5
-
6
- ---
7
-
8
- JSON:API Serde is a framework-agnostic [JSON:API](https://jsonapi.org) serialization and deserialization library.
9
-
10
- ## Documentation
11
-
12
- To check out docs, visit [jsonapi-serde.js.org](https://jsonapi-serde.js.org).
13
-
14
- ## Changelog
15
-
16
- Detailed changes for each release are documented in the [CHANGELOG](https://github.com/dasprid/jsonapi-serde-js/blob/main/packages/server/CHANGELOG.md)
17
-
18
- ## License
19
-
20
- [BSD-3-Clause](https://github.com/dasprid/jsonapi-serde-js/blob/main/LICENSE)
21
-
22
- Copyright (c) 2025-present, Ben Scholzen 'DASPRiD'