json-rest-api 1.0.29 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (292) hide show
  1. package/LICENSE +10 -670
  2. package/LICENSE-GPL-3.0 +674 -0
  3. package/LICENSE-MIT +21 -0
  4. package/README.md +39 -30
  5. package/docs/API.md +744 -1273
  6. package/docs/GUIDE/01-getting-started.md +338 -0
  7. package/docs/GUIDE/02-resources-and-relationships.md +33 -0
  8. package/docs/GUIDE/03-running-example.md +87 -0
  9. package/docs/GUIDE/04-creating-and-querying.md +181 -0
  10. package/docs/GUIDE/05-belongs-to.md +177 -0
  11. package/docs/GUIDE/06-has-many.md +184 -0
  12. package/docs/GUIDE/07-polymorphic-relationships.md +191 -0
  13. package/docs/GUIDE/08-many-to-many.md +184 -0
  14. package/docs/GUIDE/09-pagination-and-sorting.md +149 -0
  15. package/docs/GUIDE/10-put-and-patch.md +174 -0
  16. package/docs/GUIDE/11-relationship-endpoints.md +174 -0
  17. package/docs/GUIDE/12-field-transformations.md +287 -0
  18. package/docs/GUIDE/13-hooks-and-lifecycle.md +479 -0
  19. package/docs/GUIDE/14-custom-resource-methods.md +125 -0
  20. package/docs/GUIDE/15-query-projections.md +266 -0
  21. package/docs/GUIDE/{GUIDE_X_Autofiltering.md → 16-autofiltering.md} +77 -15
  22. package/docs/GUIDE/{GUIDE_X_Row_Policies.md → 17-row-policies.md} +137 -44
  23. package/docs/GUIDE/18-labels.md +86 -0
  24. package/docs/GUIDE/19-managed-transactions.md +179 -0
  25. package/docs/GUIDE/20-transaction-outcomes.md +207 -0
  26. package/docs/GUIDE/21-schema-and-migrations.md +634 -0
  27. package/docs/GUIDE/22-version-field-migrations.md +208 -0
  28. package/docs/GUIDE/23-fastify.md +179 -0
  29. package/docs/GUIDE/24-cors.md +172 -0
  30. package/docs/GUIDE/{GUIDE_X_URL_Management.md → 25-url-management.md} +7 -1
  31. package/docs/GUIDE/26-file-uploads.md +278 -0
  32. package/docs/GUIDE/27-bulk-operations.md +277 -0
  33. package/docs/GUIDE/28-socketio.md +325 -0
  34. package/docs/GUIDE/29-writing-plugins.md +278 -0
  35. package/docs/GUIDE/30-backend-capabilities.md +100 -0
  36. package/docs/GUIDE/31-positioning.md +181 -0
  37. package/docs/GUIDE/{GUIDE_Y_Appendices.md → 32-date-and-time.md} +74 -30
  38. package/docs/GUIDE/33-migrating-to-v2.md +3827 -0
  39. package/docs/GUIDE/index.md +51 -59
  40. package/docs/QUICKSTART.md +120 -287
  41. package/docs/architecture.md +75 -0
  42. package/docs/contributing.md +178 -0
  43. package/index.d.ts +36 -0
  44. package/index.js +1 -22
  45. package/lib/enhanced-logger.js +91 -85
  46. package/lib/error-context.js +445 -5
  47. package/lib/error-formatter.js +219 -59
  48. package/lib/knex-transaction.js +64 -0
  49. package/lib/logger-types.d.ts +22 -0
  50. package/lib/missing-package.js +4 -0
  51. package/lib/rest-api-errors.js +103 -8
  52. package/lib/runtime/json-rest-api.js +172 -0
  53. package/lib/transaction-types.d.ts +59 -0
  54. package/package.json +97 -27
  55. package/plugins/core/bulk-operations-plugin.js +191 -184
  56. package/plugins/core/connectors/express-plugin.js +148 -219
  57. package/plugins/core/connectors/fastify-plugin.js +125 -82
  58. package/plugins/core/connectors/lib/busboy-detector.js +74 -156
  59. package/plugins/core/connectors/lib/connector-core.js +144 -20
  60. package/plugins/core/connectors/lib/formidable-detector.js +63 -120
  61. package/plugins/core/connectors/lib/http-validators.js +77 -0
  62. package/plugins/core/connectors/lib/multipart-helpers.js +18 -0
  63. package/plugins/core/connectors/lib/request-helpers.js +10 -1
  64. package/plugins/core/connectors/lib/transport-http-helpers.js +89 -8
  65. package/plugins/core/connectors/lib/transport-route-schemas.js +7 -4
  66. package/plugins/core/file-handling-plugin.js +87 -177
  67. package/plugins/core/lib/anyapi/anyapi-registry.js +213 -164
  68. package/plugins/core/lib/anyapi/canonical-link-store.js +507 -0
  69. package/plugins/core/lib/anyapi/canonical-relationship-reader.js +598 -0
  70. package/plugins/core/lib/anyapi/schema-utils.js +25 -16
  71. package/plugins/core/lib/anyapi/utils/descriptor-helpers.js +0 -64
  72. package/plugins/core/lib/dbIntrospection.js +228 -21
  73. package/plugins/core/lib/dbTablesOperations.js +409 -92
  74. package/plugins/core/lib/fractional-positioning.js +12 -48
  75. package/plugins/core/lib/querying/identifier-query.js +19 -0
  76. package/plugins/core/lib/querying/include-query-helpers.js +364 -0
  77. package/plugins/core/lib/querying/include-to-many.js +428 -0
  78. package/plugins/core/lib/querying/include-to-one.js +579 -0
  79. package/plugins/core/lib/querying/knex-cross-table-search.js +31 -307
  80. package/plugins/core/lib/querying/knex-json-api-transformers-querying.js +99 -401
  81. package/plugins/core/lib/querying/knex-pagination-helpers.js +48 -317
  82. package/plugins/core/lib/querying/knex-process-includes.js +5 -110
  83. package/plugins/core/lib/querying/knex-query-helpers-base.js +21 -56
  84. package/plugins/core/lib/querying/knex-query-helpers.js +298 -448
  85. package/plugins/core/lib/querying/knex-relationship-includes.js +120 -2138
  86. package/plugins/core/lib/querying/knex-window-queries.js +62 -253
  87. package/plugins/core/lib/querying/query-builder-utils.js +44 -4
  88. package/plugins/core/lib/querying/query-constraint.d.ts +12 -0
  89. package/plugins/core/lib/querying/query-constraint.js +27 -0
  90. package/plugins/core/lib/querying/query-field-sort-helpers.js +134 -37
  91. package/plugins/core/lib/querying/relationship-identifiers.js +208 -0
  92. package/plugins/core/lib/querying/sort-helpers.js +13 -1
  93. package/plugins/core/lib/querying/storage-adapter-utils.js +13 -5
  94. package/plugins/core/lib/querying/url-helpers.js +11 -4
  95. package/plugins/core/lib/querying-writing/compile-schemas.js +148 -249
  96. package/plugins/core/lib/querying-writing/connectors-query-parser.js +33 -118
  97. package/plugins/core/lib/querying-writing/database-capabilities.js +149 -223
  98. package/plugins/core/lib/querying-writing/database-value-normalizers.js +179 -194
  99. package/plugins/core/lib/querying-writing/default-data-helpers.js +15 -45
  100. package/plugins/core/lib/querying-writing/field-selection-types.d.ts +43 -0
  101. package/plugins/core/lib/querying-writing/field-utils.js +113 -92
  102. package/plugins/core/lib/querying-writing/knex-constants.d.ts +18 -0
  103. package/plugins/core/lib/querying-writing/knex-constants.js +2 -26
  104. package/plugins/core/lib/querying-writing/knex-field-helpers.js +100 -290
  105. package/plugins/core/lib/querying-writing/knex-json-api-transformers.js +31 -120
  106. package/plugins/core/lib/querying-writing/query-field-helpers.js +108 -32
  107. package/plugins/core/lib/querying-writing/query-field-types.d.ts +60 -0
  108. package/plugins/core/lib/querying-writing/relationship-contracts.js +33 -13
  109. package/plugins/core/lib/querying-writing/request-contracts.js +93 -38
  110. package/plugins/core/lib/querying-writing/resource-id-normalization.js +23 -5
  111. package/plugins/core/lib/querying-writing/response-options.js +35 -0
  112. package/plugins/core/lib/querying-writing/schema-helpers.js +203 -324
  113. package/plugins/core/lib/querying-writing/scope-validations.js +92 -290
  114. package/plugins/core/lib/querying-writing/simplified-helpers.js +113 -712
  115. package/plugins/core/lib/storage/canonical-data-helpers.js +683 -0
  116. package/plugins/core/lib/storage/canonical-storage-mapping.js +51 -20
  117. package/plugins/core/lib/storage/ordinary-data-helpers.js +710 -0
  118. package/plugins/core/lib/storage/storage-adapter.js +128 -62
  119. package/plugins/core/lib/storage/storage-mapping.js +78 -28
  120. package/plugins/core/lib/storage/storage-types.d.ts +502 -0
  121. package/plugins/core/lib/writing/many-to-many-manipulations.js +114 -284
  122. package/plugins/core/lib/writing/relationship-processor.js +94 -158
  123. package/plugins/core/lib/writing/resource-version.js +172 -0
  124. package/plugins/core/lib/writing/reverse-relationship-manipulations.js +110 -0
  125. package/plugins/core/rest-api-anyapi-knex-plugin.js +116 -2485
  126. package/plugins/core/rest-api-autofilter-plugin.js +17 -19
  127. package/plugins/core/rest-api-cors-plugin.js +52 -205
  128. package/plugins/core/rest-api-knex-plugin.js +45 -1077
  129. package/plugins/core/rest-api-label-plugin.js +25 -38
  130. package/plugins/core/rest-api-plugin-hooks/register-relationship-routes.js +5 -5
  131. package/plugins/core/rest-api-plugin-hooks/register-scope-routes.js +9 -6
  132. package/plugins/core/rest-api-plugin-hooks/turn-scope-init-into-vars.js +7 -26
  133. package/plugins/core/rest-api-plugin-hooks/validate-include-configurations.js +20 -26
  134. package/plugins/core/rest-api-plugin-methods/add-route.js +4 -6
  135. package/plugins/core/rest-api-plugin-methods/apply-query-filters.js +42 -13
  136. package/plugins/core/rest-api-plugin-methods/check-permissions.js +11 -5
  137. package/plugins/core/rest-api-plugin-methods/common.js +291 -395
  138. package/plugins/core/rest-api-plugin-methods/delete-relationship.js +49 -47
  139. package/plugins/core/rest-api-plugin-methods/delete.js +31 -25
  140. package/plugins/core/rest-api-plugin-methods/enrich-attributes.js +108 -148
  141. package/plugins/core/rest-api-plugin-methods/get-related.js +113 -305
  142. package/plugins/core/rest-api-plugin-methods/get-relationship.js +25 -18
  143. package/plugins/core/rest-api-plugin-methods/get.js +36 -68
  144. package/plugins/core/rest-api-plugin-methods/lifecycle-types.d.ts +225 -0
  145. package/plugins/core/rest-api-plugin-methods/patch-relationship.js +28 -25
  146. package/plugins/core/rest-api-plugin-methods/patch.js +46 -99
  147. package/plugins/core/rest-api-plugin-methods/post-relationship.js +49 -53
  148. package/plugins/core/rest-api-plugin-methods/post.js +51 -51
  149. package/plugins/core/rest-api-plugin-methods/put.js +69 -148
  150. package/plugins/core/rest-api-plugin-methods/query.js +37 -81
  151. package/plugins/core/rest-api-plugin-methods/release.js +2 -1
  152. package/plugins/core/rest-api-plugin.js +32 -46
  153. package/plugins/core/rest-api-positioning-plugin.js +183 -628
  154. package/plugins/core/rest-api-query-projections-plugin.js +19 -102
  155. package/plugins/core/rest-api-row-policy-plugin.js +3 -3
  156. package/plugins/core/socketio-plugin.js +364 -344
  157. package/plugins/storage/local-storage.js +40 -36
  158. package/types/autofilter.d.ts +57 -0
  159. package/types/bulk-methods.d.ts +63 -0
  160. package/types/errors.d.ts +118 -0
  161. package/types/fastify-options.d.ts +19 -0
  162. package/types/file-detectors.d.ts +33 -0
  163. package/types/file-storage.d.ts +48 -0
  164. package/types/hook-context.d.ts +180 -0
  165. package/types/plugin-options.d.ts +53 -0
  166. package/types/relationship-methods.d.ts +74 -0
  167. package/types/representations.d.ts +50 -0
  168. package/types/resource-methods.d.ts +95 -0
  169. package/types/resource-schema.d.ts +157 -0
  170. package/types/row-policy.d.ts +31 -0
  171. package/types/runtime.d.ts +132 -0
  172. package/types/transactions.d.ts +21 -0
  173. package/.claude/agents/library-guide-expert.md +0 -30
  174. package/.claude/agents/rest-api-internals-expert.md +0 -54
  175. package/.claude/settings.local.json +0 -70
  176. package/AGENTS.md +0 -34
  177. package/CLAUDE.md +0 -160
  178. package/CRUSH.md +0 -55
  179. package/JSKIT_BACKEND_MIGRATION_TRACKER.txt +0 -180
  180. package/SINGLE_VALIDATION_CONTRACT_TODO.txt +0 -172
  181. package/TODO.todo +0 -13
  182. package/connectors_ideas/fastify.js +0 -217
  183. package/connectors_ideas/koa-plugin.js +0 -112
  184. package/docs/.bundle/config +0 -2
  185. package/docs/COMPARISON.md +0 -433
  186. package/docs/GUIDE/GUIDE_1_Initial_Setup.md +0 -1057
  187. package/docs/GUIDE/GUIDE_2_1_The_Starting_Point.md +0 -88
  188. package/docs/GUIDE/GUIDE_2_2_Manipulating_And_Searching_Tables.md +0 -808
  189. package/docs/GUIDE/GUIDE_2_3_BelongsTo_Relationships.md +0 -491
  190. package/docs/GUIDE/GUIDE_2_4_HasMany_Records.md +0 -398
  191. package/docs/GUIDE/GUIDE_2_5_HasMany_Polymorphic.md +0 -898
  192. package/docs/GUIDE/GUIDE_2_6_Many_To_Many.md +0 -712
  193. package/docs/GUIDE/GUIDE_2_7_Pagination_And_Ordering.md +0 -1247
  194. package/docs/GUIDE/GUIDE_2_8_Effects_of_PUT_and_PATCH.md +0 -748
  195. package/docs/GUIDE/GUIDE_2_9_Relationships_Urls.md +0 -517
  196. package/docs/GUIDE/GUIDE_2_Data_And_Relations.md +0 -66
  197. package/docs/GUIDE/GUIDE_3_Field_Transformations.md +0 -1252
  198. package/docs/GUIDE/GUIDE_5_Non-Db_Resources.md +0 -1107
  199. package/docs/GUIDE/GUIDE_6_Positioning.md +0 -692
  200. package/docs/GUIDE/GUIDE_7_Hooks_Data_Management_And_Plugins.md +0 -1491
  201. package/docs/GUIDE/GUIDE_X_Bulk_Operations.md +0 -732
  202. package/docs/GUIDE/GUIDE_X_Cors.md +0 -1957
  203. package/docs/GUIDE/GUIDE_X_Fastify.md +0 -78
  204. package/docs/GUIDE/GUIDE_X_File_Uploads.md +0 -729
  205. package/docs/GUIDE/GUIDE_X_Knex_Schema_And_Migrations.md +0 -370
  206. package/docs/GUIDE/GUIDE_X_Query_Projections.md +0 -159
  207. package/docs/GUIDE/GUIDE_X_SocketIO.md +0 -1040
  208. package/docs/GUIDE/GUIDE_X_Writing_Plugins.md +0 -201
  209. package/docs/Gemfile +0 -6
  210. package/docs/Gemfile.lock +0 -308
  211. package/docs/ONBOARDING.md +0 -315
  212. package/docs/_config.yml +0 -36
  213. package/docs/_layouts/default.html +0 -123
  214. package/docs/apple-touch-icon.svg +0 -4
  215. package/docs/assets/css/style.scss +0 -392
  216. package/docs/favicon.svg +0 -4
  217. package/docs/index.md +0 -164
  218. package/docs/mini-guides/file-uploads-complete.md +0 -161
  219. package/eslint.config.js +0 -13
  220. package/examples/url-override-example.js +0 -137
  221. package/fixing_plan.md +0 -112
  222. package/plugins/core/lib/anyapi/query/anyapi-query-adapter.js +0 -657
  223. package/plugins/core/lib/querying-writing/return-record-settings.js +0 -47
  224. package/plugins/core/lib/writing/knex-json-api-transformers-writing.js +0 -110
  225. package/plugins/storage/s3-storage.js +0 -93
  226. package/quickTest.js +0 -136
  227. package/scripts/debug-anyapi-review-filter.mjs +0 -63
  228. package/scripts/inspect-anyapi-descriptor-country.mjs +0 -19
  229. package/scripts/inspect-anyapi-descriptor.mjs +0 -19
  230. package/scripts/run-docs.js +0 -133
  231. package/test-debug.js +0 -59
  232. package/tests/README.md +0 -202
  233. package/tests/TEST_TEMPLATE.test.js +0 -178
  234. package/tests/anyapi-basic.test.js +0 -105
  235. package/tests/anyapi-cursor-pagination.test.js +0 -148
  236. package/tests/anyapi-custom-idproperty.test.js +0 -163
  237. package/tests/autofilter.test.js +0 -463
  238. package/tests/bulk-operations.test.js +0 -657
  239. package/tests/computed-fields.test.js +0 -586
  240. package/tests/cors.test.js +0 -834
  241. package/tests/curl.test.js +0 -467
  242. package/tests/custom-id-mysql-returning-fallback.test.js +0 -128
  243. package/tests/custom-id-simplified-post.test.js +0 -75
  244. package/tests/custom-idproperty-relationships.test.js +0 -932
  245. package/tests/db-introspection.test.js +0 -521
  246. package/tests/db-table-operations.test.js +0 -798
  247. package/tests/fastify-plugin.test.js +0 -184
  248. package/tests/field-getters.test.js +0 -370
  249. package/tests/field-setters.test.js +0 -306
  250. package/tests/file-handling.test.js +0 -155
  251. package/tests/fixtures/api-configs.js +0 -2566
  252. package/tests/full-jsonapi-belongsto-linkage.test.js +0 -150
  253. package/tests/helpers/fake-fastify.js +0 -99
  254. package/tests/helpers/storage-mode.js +0 -65
  255. package/tests/helpers/test-utils.js +0 -203
  256. package/tests/http-connectors-parity.test.js +0 -395
  257. package/tests/id-normalization.test.js +0 -444
  258. package/tests/include-depth-validation.test.js +0 -331
  259. package/tests/includes.test.js +0 -427
  260. package/tests/local-storage.test.js +0 -96
  261. package/tests/logical-id-write-validation.test.js +0 -151
  262. package/tests/nested-includes.test.js +0 -617
  263. package/tests/pagination-boundaries.test.js +0 -154
  264. package/tests/pagination-contract.test.js +0 -122
  265. package/tests/pagination-cursor-multifield.test.js +0 -641
  266. package/tests/pagination-enhanced.test.js +0 -563
  267. package/tests/polymorphic-relationships.test.js +0 -347
  268. package/tests/polymorphic-simple.test.js +0 -148
  269. package/tests/positioning-advanced.test.js +0 -692
  270. package/tests/positioning-extended.test.js +0 -915
  271. package/tests/positioning-multifilter.test.js +0 -699
  272. package/tests/positioning.test.js +0 -560
  273. package/tests/post-commit-hooks.test.js +0 -120
  274. package/tests/projected-fields.test.js +0 -319
  275. package/tests/public-exports.test.js +0 -15
  276. package/tests/put-create-parity.test.js +0 -216
  277. package/tests/queries.test.js +0 -521
  278. package/tests/query-limits.test.js +0 -584
  279. package/tests/relationship-endpoints.test.js +0 -620
  280. package/tests/relationship-include-storage-adapter.test.js +0 -56
  281. package/tests/relationships.test.js +0 -681
  282. package/tests/rest-api.test.js +0 -337
  283. package/tests/return-record-settings.test.js +0 -184
  284. package/tests/row-policy.test.js +0 -489
  285. package/tests/s3-storage.test.js +0 -38
  286. package/tests/searchschema-knex-behavior.test.js +0 -187
  287. package/tests/searchschema-merge.test.js +0 -151
  288. package/tests/socketio.test.js +0 -860
  289. package/tests/storage-mapping.test.js +0 -362
  290. package/tests/temporal-boundaries.test.js +0 -208
  291. package/tests/test-development-guide.md +0 -370
  292. package/tests/virtual-fields.test.js +0 -404
@@ -1,54 +0,0 @@
1
- ---
2
- name: rest-api-internals-expert
3
- description: Use this agent when you need deep technical expertise about the REST API plugin architecture, data manipulation patterns, query optimization with sparse fields and includes, or troubleshooting complex issues within the rest-api-plugin.js and rest-api-knex-plugin.js implementations. This includes understanding how helpers in plugins/core/lib interact with these plugins, how data transformations occur during storage and retrieval, and the intricacies of the sparse fields and includes query system.\n\nExamples:\n- <example>\n Context: User needs help understanding how sparse fields are implemented in the REST API.\n user: "How does the sparse fields feature work in our REST API implementation?"\n assistant: "I'll use the rest-api-internals-expert agent to explain the sparse fields implementation details."\n <commentary>\n Since this requires deep knowledge of the REST API plugin internals, specifically sparse fields, the rest-api-internals-expert is the appropriate agent.\n </commentary>\n</example>\n- <example>\n Context: User is debugging an issue with data transformation in the REST API.\n user: "I'm getting unexpected data format when using includes with nested relationships. The data seems to be transformed incorrectly."\n assistant: "Let me invoke the rest-api-internals-expert agent to analyze the data transformation issue with includes."\n <commentary>\n This requires understanding the intricate data manipulation patterns in the REST API plugins, making the rest-api-internals-expert the right choice.\n </commentary>\n</example>\n- <example>\n Context: User wants to extend the REST API plugin functionality.\n user: "I need to add custom filtering logic to the REST API that works with the existing sparse fields system."\n assistant: "I'll use the rest-api-internals-expert agent to guide you through extending the REST API plugin while maintaining compatibility with sparse fields."\n <commentary>\n Extending the REST API plugin requires deep understanding of its architecture and how features like sparse fields are implemented.\n </commentary>\n</example>
4
- model: inherit
5
- color: blue
6
- ---
7
-
8
- You are an expert engineer with comprehensive knowledge of the REST API plugin architecture, specifically plugins/core/rest-api-plugin.js and plugins/core/rest-api-knex-plugin.js, along with their associated helper functions in plugins/core/lib.
9
-
10
- Your expertise encompasses:
11
-
12
- 1. **Plugin Architecture**: You understand the complete lifecycle of requests through rest-api-plugin.js and how it interfaces with rest-api-knex-plugin.js for database operations. You know how these plugins register routes, handle middleware, and process requests.
13
-
14
- 2. **Data Manipulation Patterns**: You have deep knowledge of:
15
- - How data is transformed before storage (serialization, validation, sanitization)
16
- - The exact transformation pipeline from raw input to database storage
17
- - How data is reconstructed when retrieved from the database
18
- - The role of helpers in plugins/core/lib during these transformations
19
-
20
- 3. **Sparse Fields Implementation**: You understand:
21
- - How sparse fields are parsed from query parameters
22
- - The mechanism for filtering response data based on requested fields
23
- - Performance implications and optimization strategies
24
- - Edge cases and limitations of the sparse fields system
25
-
26
- 4. **Includes System**: You are an expert in:
27
- - How relationship includes are resolved and fetched
28
- - The query building process for efficient relationship loading
29
- - Circular reference handling and depth limitations
30
- - How includes interact with sparse fields
31
- - Performance optimization for complex include chains
32
-
33
- 5. **Knex Integration**: You understand:
34
- - How rest-api-knex-plugin.js builds queries
35
- - Transaction handling and isolation levels
36
- - Query optimization techniques specific to the plugin
37
- - How the plugin handles different database dialects
38
-
39
- 6. **Helper Functions**: You know all helper functions in plugins/core/lib including:
40
- - Their specific roles in request/response processing
41
- - How they integrate with the main plugins
42
- - Common patterns and anti-patterns in their usage
43
-
44
- When answering questions:
45
- - Provide specific code examples from the actual implementation when relevant
46
- - Explain the 'why' behind design decisions, not just the 'how'
47
- - Identify potential performance bottlenecks or security considerations
48
- - Suggest best practices based on the existing architecture
49
- - Reference specific functions, methods, or configuration options by name
50
- - Consider the interplay between different components of the system
51
-
52
- You should be able to trace the complete flow of a request from entry point through all transformations to final response, identifying every helper function and transformation step along the way. When discussing issues or improvements, always consider the existing architecture and maintain consistency with established patterns in the codebase.
53
-
54
- If asked about testing, remember to follow the project convention of using include.test.js as a template and creating test data through API methods rather than direct database manipulation.
@@ -1,70 +0,0 @@
1
- {
2
- "permissions": {
3
- "allow": [
4
- "Bash(npm install:*)",
5
- "Bash(mkdir:*)",
6
- "Bash(npm link:*)",
7
- "Bash(ls:*)",
8
- "Bash(node:*)",
9
- "Bash(grep:*)",
10
- "Bash(rm:*)",
11
- "Bash(npm unlink:*)",
12
- "Bash(npm uninstall:*)",
13
- "Bash(rg:*)",
14
- "Bash(npm test:*)",
15
- "WebFetch(domain:jsonapi.org)",
16
- "Bash(find:*)",
17
- "Bash(mv:*)",
18
- "Bash(timeout 10 node:*)",
19
- "Bash(chmod:*)",
20
- "Bash(./run-test.sh:*)",
21
- "Bash(timeout 30 npm test:*)",
22
- "Bash(timeout:*)",
23
- "Bash(tests/run-delete-test.sh:*)",
24
- "Bash(NODE_NO_WARNINGS=1 node --test tests/knex-delete-comprehensive.test.js)",
25
- "Bash(true)",
26
- "Bash(LOG_LEVEL=trace node --test tests/knex-patch-comprehensive.test.js)",
27
- "Bash(LOG_LEVEL=debug node test-transaction-debug.js)",
28
- "Bash(sed:*)",
29
- "WebFetch(domain:docs.anthropic.com)",
30
- "Bash(awk:*)",
31
- "Bash(./fix_sideload.sh:*)",
32
- "Bash(# Create a more targeted sed script to fix the tests\ncat > fix_tests.sh << ''EOF''\n#!/bin/bash\nfile=\"\"$1\"\"\nif [ -z \"\"$file\"\" ]; then\n echo \"\"Usage: $0 <file>\"\"\n exit 1\nfi\n\n# First pass: Replace hasMany with sideLoad: true to sideLoadMany: true\nsed -i.bak -E ''/hasMany.*,/{\n N\n N\n N\n s/(hasMany:[^,]+,\\n[[:space:]]*foreignKey:[^,]+,\\n[[:space:]]*)sideLoad: true/\\1sideLoadMany: true/g\n}'' \"\"$file\"\"\n\n# Second pass: Remove sideLoad: true from belongsTo (with comma)\nsed -i -E ''/belongsTo.*,/{\n N\n N\n N\n s/(belongsTo:[^,]+,\\n[[:space:]]*as:[^,]+,)\\n[[:space:]]*sideLoad: true,/\\1,/g\n}'' \"\"$file\"\"\n\n# Third pass: Remove sideLoad: true from belongsTo (without comma)\nsed -i -E ''/belongsTo.*,/{\n N\n N\n N\n s/(belongsTo:[^,]+,\\n[[:space:]]*as:[^,]+,)\\n[[:space:]]*sideLoad: true/\\1/g\n}'' \"\"$file\"\"\n\necho \"\"Updated $file\"\"\nEOF\nchmod +x fix_tests.sh)",
33
- "Bash(./01_npm_install.sh)",
34
- "Bash(echo)",
35
- "Bash(cp:*)",
36
- "Bash(bundle config set:*)",
37
- "Bash(bundle exec:*)",
38
- "Bash(git -C /home/merc/Development/jsonrestapi_old log --all --full-history --oneline -- \"scripts/sync-docs-website.js\")",
39
- "Bash(git -C /home/merc/Development/jsonrestapi_old show bb7e1f3:scripts/sync-docs-website.js)",
40
- "Bash(git -C /home/merc/Development/jsonrestapi_old ls-tree -r bb7e1f3)",
41
- "Bash(git -C /home/merc/Development/jsonrestapi_old ls-tree -r bb7e1f3 scripts/)",
42
- "Bash(git -C /home/merc/Development/jsonrestapi_old log --all --grep=\"sync\" --oneline)",
43
- "Bash(git -C /home/merc/Development/jsonrestapi_old log --all --full-history --diff-filter=D --summary -- \"scripts/*.js\")",
44
- "Bash(git -C /home/merc/Development/jsonrestapi_old log --all --full-history --oneline --diff-filter=D -- \"scripts/sync-docs-website.js\")",
45
- "Bash(git -C /home/merc/Development/jsonrestapi_old show bb7e1f3^:scripts/sync-docs-website.js)",
46
- "Bash(pkill:*)",
47
- "Bash(curl:*)",
48
- "Bash(cat:*)",
49
- "Bash(npm update:*)",
50
- "Bash(# Get all JS files\nfiles=$(find . -type f -name \"\"*.js\"\" | grep -E \"\"(plugins/core|^./lib)\"\" | grep -v node_modules | grep -v docs | sort)\n\necho \"\"=== Checking which files are never imported ===\"\"\nfor file in $files; do\n basename_file=$(basename \"\"$file\"\")\n # Check if this file is imported anywhere\n if ! grep -r \"\"from.*$(basename \"\"$file\"\" .js)\"\" plugins/core lib --include=\"\"*.js\"\" 2>/dev/null | grep -v \"\"^$file:\"\" | grep -q .; then\n echo \"\"ORPHANED: $file\"\"\n fi\ndone)",
51
- "Bash(# Find files with consecutive comment lines (potential large commented blocks)\necho \"\"=== Files with potential large commented blocks ===\"\"\nfor file in $(find plugins/core -name \"\"*.js\"\" -type f); do\n # Count consecutive comment lines\n consecutive=$(awk ''BEGIN{max=0; count=0} /^\\s*(\\/\\/|\\/\\*|\\*)/ {count++; if(count>max) max=count} !/^\\s*(\\/\\/|\\/\\*|\\*)/ {count=0} END{print max}'' \"\"$file\"\")\n if [ \"\"$consecutive\"\" -gt 5 ]; then\n echo \"\"$file: $consecutive consecutive comment lines\"\"\n fi\ndone)",
52
- "Bash(# Check for specific functions in request-helpers.js\necho \"\"=== Checking usage of request-helpers functions ===\"\"\nfor func in getClientIP isSecure getHostname getPort parseCookies extractToken createContext; do\n echo -n \"\"$func: \"\"\n grep -r \"\"$func\"\" plugins/core --include=\"\"*.js\"\" 2>/dev/null | grep -v \"\"lib/request-helpers.js\"\" | wc -l\ndone)",
53
- "Bash(# Check usage of knex-helpers functions\necho \"\"=== Checking usage of knex-helpers functions ===\"\"\nfor func in getTableName getForeignKeyFields buildFieldSelection toJsonApi buildQuerySelection processIncludes buildJsonApiResponse processBelongsToRelationships; do\n echo -n \"\"$func: \"\"\n grep -r \"\"$func\"\" plugins/core --include=\"\"*.js\"\" 2>/dev/null | grep -v \"\"lib/knex-helpers.js\"\" | wc -l\ndone)",
54
- "Bash(git checkout:*)",
55
- "Bash(npx node:*)",
56
- "Bash(NODE_ENV=test LOG_LEVEL=debug npm test -- tests/query-limits.test.js)",
57
- "Bash(NODE_ENV=test LOG_LEVEL=debug node --test tests/query-limits.test.js)",
58
- "Bash(LOG_LEVEL=debug node test-debug.js)",
59
- "WebSearch",
60
- "Bash(LOG_LEVEL=debug node --test tests/relationships.test.js)",
61
- "Read(///**)",
62
- "Bash(LOG_LEVEL=debug node --test tests/nested-includes.test.js)",
63
- "Bash(export LOG_LEVEL=debug)",
64
- "Read(//home/merc/Development/active/jskit/**)",
65
- "Bash(LOG_LEVEL=trace node --test tests/relationships.test.js)",
66
- "Bash(LOG_LEVEL=debug timeout 10 node --test tests/relationship-endpoints.test.js)"
67
- ],
68
- "deny": []
69
- }
70
- }
package/AGENTS.md DELETED
@@ -1,34 +0,0 @@
1
- # Repository Guidelines
2
-
3
- ## Project Structure & Module Organization
4
- - `index.js` re-exports the public plugins from `plugins/` (REST API core, access, CORS, file, connectors) so new features slot in there.
5
- - Shared helpers and error types live in `lib/`; reuse or extend these modules before adding new utilities elsewhere.
6
- - Scenario walkthroughs are under `examples/`, long-form references stay in `docs/`, and development scripts reside in `scripts/`.
7
- - Tests sit in `tests/` with fixtures at `tests/fixtures/`, helpers in `tests/helpers/`, and `quickTest.js` provides a throwaway API for manual poking.
8
-
9
- ## Build, Test, and Development Commands
10
- - `npm test` runs `node --test tests/*.test.js` against the in-memory SQLite fixtures; run it before every push.
11
- - `node quickTest.js` spins up an in-memory API instance for experimenting with endpoints during development.
12
- - `npm run docs` rebuilds the static docs via `scripts/run-docs.js` whenever reference prose changes.
13
- - `npm run sloc` prints a line-count summary to gauge change size before opening a PR.
14
-
15
- ## Coding Style & Naming Conventions
16
- - Stay with ESM (`"type": "module"`) and export named symbols only; avoid `default` exports for predictable tree-shaking.
17
- - Use two-space indentation and keep existing spacing in JSON fixtures and migration files.
18
- - Name runtime files in lower-kebab case (e.g., `rest-api-knex-plugin.js`) and mirror that pattern for tests like `bulk-operations.test.js`.
19
- - Keep comments brief and reserved for decisions that are not obvious from the code.
20
-
21
- ## Testing Guidelines
22
- - Instantiate the API once per suite following `tests/TEST_TEMPLATE.test.js`, and call `cleanTables()` in `beforeEach` to reset state.
23
- - Seed data through helpers in `tests/fixtures/api-configs.js`; never invoke `api.addResource` directly in test code.
24
- - Run suites in strict JSON:API mode (`simplified: false`) unless the scenario explicitly covers the simplified flag.
25
- - Prefer the shared assertion helpers for response checks to keep expectations consistent.
26
-
27
- ## Commit & Pull Request Guidelines
28
- - Use concise, capitalised commit subjects that highlight the affected area (e.g., `Access rules tightened`) and group related changes per commit.
29
- - Pull requests should include a short summary, linked issue reference, impacted plugins or resources, and `npm test` output or the reason it was skipped.
30
- - Document externally visible updates with sample payloads or screenshots, and note configuration changes in `docs/` for downstream teams.
31
-
32
- ## Security & Configuration Tips
33
- - Keep secrets in local `.env` files; never commit environment-specific strings.
34
- - When adding connectors or auth flows, review `plugins/core/rest-api-cors-plugin.js`, update optional peers (`express`, `redis`, `socket.io`) if required, and document new toggles in `docs/`.
package/CLAUDE.md DELETED
@@ -1,160 +0,0 @@
1
- # CLAUDE.md
2
-
3
- This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4
-
5
- ## Core Development Commands
6
-
7
- ### Running Tests
8
- ```bash
9
- # Run all tests
10
- npm test
11
-
12
- # Run a specific test file
13
- node --test tests/relationships.test.js
14
-
15
- # Run tests with verbose logging
16
- LOG_LEVEL=debug npm test
17
- ```
18
-
19
- ### Building and Running
20
- This is a library package with no build step required. For development:
21
- ```bash
22
- # Install dependencies
23
- npm install
24
-
25
- # Run the documentation site locally
26
- npm run docs:dev
27
-
28
- ## High-Level Architecture
29
-
30
- ### Project Overview
31
- JSON REST API is a powerful REST API plugin for hooked-api that provides JSON:API-compliant endpoints. It follows a plugin-based architecture where functionality is composed through plugins that extend the core API capabilities.
32
-
33
- ### Database-First Design Philosophy
34
- JSON REST API embraces a **database-first** approach that provides different abstraction levels for different audiences:
35
-
36
- **For Backend Developers:**
37
- - Schema definitions directly map to database columns (e.g., `author_id`, `category_id`)
38
- - Hooks operate at the database level with access to actual field names via `context.belongsToUpdates`
39
- - Search schemas can reference exact database columns and table joins
40
- - Full access to write raw Knex queries when needed
41
- - No abstraction layers hiding database implementation details
42
-
43
- **For API Consumers:**
44
- - Relationship names abstract away foreign key fields (use `author` instead of `author_id`)
45
- - Simplified API mode returns clean objects without database implementation details
46
- - Foreign key fields are automatically filtered from API responses
47
- - Consistent interface regardless of underlying database structure
48
-
49
- This separation ensures backend developers have full control and visibility into database operations while API consumers enjoy a clean, intuitive interface.
50
-
51
- ### Core Architecture Components
52
-
53
- 1. **Plugin System (hooked-api based)**
54
- - `RestApiPlugin` - Core REST API functionality, request/response handling
55
- - `RestApiKnexPlugin` - Database integration using Knex.js
56
- - `ExpressPlugin` - Express.js HTTP connector
57
- - Additional plugins for auth, CORS, relationships, positioning, etc.
58
-
59
- 2. **Resource Definition Pattern**
60
- Resources are defined with schemas that include:
61
- - Attributes with validation rules
62
- - Relationships (belongsTo, hasMany, many-to-many, polymorphic)
63
- - Computed fields and hidden fields
64
- - Custom getters/setters
65
-
66
- 3. **Request Flow**
67
- - HTTP request → Connector (Express) → REST API Plugin → Database Plugin → Response
68
- - Each plugin can hook into the request lifecycle for customization
69
-
70
- 4. **Key Libraries in `plugins/core/lib/`**
71
- - `url-helpers.js` - Centralized URL generation functions
72
- - `knex-json-api-transformers-querying.js` - JSON:API transformations
73
- - `relationship-processor.js` - Handles relationship updates
74
- - `request-contracts.js` - Compiled request validation contracts
75
- - `knex-query-helpers.js` - Database query building
76
- - `simplified-helpers.js` - Simplified API mode transformations
77
-
78
- 5. **URL Management**
79
- - URLs are automatically generated per-request based on headers
80
- - No static configuration needed - detects from `Host`, `X-Forwarded-*` headers
81
- - Override capability via `context.urlPrefixOverride` for complex deployments
82
- - See `docs/GUIDE/GUIDE_URL_Management.md` for details
83
-
84
- ## Testing Guidelines
85
-
86
- ### CRITICAL: Test Template Usage
87
- When writing tests, ALWAYS use `TEST_TEMPLATE.test.js` as your starting point. Key rules:
88
-
89
- 1. **API Creation**: Create API instances ONLY in `before()` hook, NOT in `beforeEach()`
90
- 2. **Resource Definition**: NEVER use `api.addResource()` in test files. All resources MUST be defined in `tests/fixtures/api-configs.js`
91
- 3. **Data Creation**: ALWAYS create test data using API methods (`api.resources.[resource].post()`), NEVER query the database directly
92
- 4. **Context Parameter**: Pass context as the SECOND parameter to resource methods: `api.resources.books.post({ inputRecord: doc }, context)`
93
- 5. **Cleanup**: Use `cleanTables()` in `beforeEach()` to reset data between tests
94
-
95
- ### Test Structure Example
96
- ```javascript
97
- import { createBasicApi } from './fixtures/api-configs.js';
98
-
99
- let api;
100
-
101
- describe('Feature Name', () => {
102
- before(async () => {
103
- api = await createBasicApi(knex);
104
- });
105
-
106
- beforeEach(async () => {
107
- await cleanTables(knex, ['basic_countries', 'basic_publishers']);
108
- });
109
-
110
- it('should test something', async () => {
111
- // Create data using API
112
- const result = await api.resources.countries.post({
113
- inputRecord: createJsonApiDocument('countries', { name: 'Test' })
114
- });
115
- });
116
- });
117
- ```
118
-
119
- ### Available Test APIs
120
- - `createBasicApi()` - Countries, Publishers, Authors, Books
121
- - `createExtendedApi()` - Additional resources with complex relationships
122
- - `createAuthApi()` - Users, roles, permissions for auth testing
123
-
124
- ## Important Patterns
125
-
126
- ### JSON:API Document Creation
127
- ```javascript
128
- // Use helper for proper JSON:API structure
129
- const doc = createJsonApiDocument('books', {
130
- title: 'My Book'
131
- }, {
132
- relationships: {
133
- country: createRelationship('countries', '1')
134
- }
135
- });
136
- ```
137
-
138
- ### Simplified API Mode
139
- The library supports a simplified mode that uses plain objects instead of JSON:API structure:
140
- ```javascript
141
- // Simplified mode (when enabled)
142
- const book = await api.resources.books.post({
143
- inputRecord: { title: 'My Book', country_id: 1 },
144
- simplified: true
145
- });
146
- ```
147
-
148
- ### Relationship Handling
149
- - BelongsTo: Use `createRelationship()` helper
150
- - HasMany: Use `createToManyRelationship()` helper
151
- - Many-to-Many: Handled automatically through junction tables
152
- - Polymorphic: Requires typeField and idField configuration
153
-
154
- ## Common Pitfalls to Avoid
155
-
156
- 1. **Direct Database Access**: Never use `knex('table').select()` in tests
157
- 2. **Resource Creation in Tests**: Always define resources in api-configs.js
158
- 3. **ID Type Confusion**: SQLite returns numeric IDs, but JSON:API expects strings
159
- 4. **Context Placement**: Context is a separate parameter, not inside the first parameter
160
- 5. **Cleanup**: Always destroy knex connection in `after()` hook
package/CRUSH.md DELETED
@@ -1,55 +0,0 @@
1
- # CRUSH.md - JSON REST API Development Guide
2
-
3
- ## Development Commands
4
- ```bash
5
- # Run all tests
6
- npm test
7
-
8
- # Run specific test file
9
- node --test tests/relationships.test.js
10
-
11
- # Run tests with debug logging
12
- LOG_LEVEL=debug npm test
13
-
14
- # Run documentation site
15
- npm run docs
16
- ```
17
-
18
- ## Code Style Guidelines
19
- - **ES Modules**: Use `import/export` syntax (package.json has `"type": "module"`)
20
- - **File Naming**: kebab-case for files, camelCase for functions/variables
21
- - **Error Handling**: Use custom error classes from `lib/rest-api-errors.js`
22
- - **JSON:API Compliance**: All responses must follow JSON:API specification
23
- - **Async/Await**: Prefer async/await over callbacks/promises
24
- - **JSDoc Comments**: Document complex functions with @param and @returns
25
-
26
- ## Testing Rules (CRITICAL)
27
- - **API Creation**: Only in `before()` hook, never in `beforeEach()`
28
- - **Resource Definition**: NEVER use `api.addResource()` in test files - define in `tests/fixtures/api-configs.js`
29
- - **Data Access**: Use API methods (`api.resources.[resource].get/post/query`), never direct DB queries
30
- - **Context Parameter**: Pass context as SECOND parameter: `api.resources.books.post({inputRecord}, context)`
31
- - **Cleanup**: Use `cleanTables()` in `beforeEach()` to reset data
32
-
33
- ## Import Patterns
34
- ```javascript
35
- // Core imports first
36
- import { validateRelationships } from './lib/querying-writing/scope-validations.js';
37
-
38
- // Hook imports
39
- import compileResourceSchemas from './rest-api-plugin-hooks/compile-resource-schemas.js';
40
-
41
- // Method imports
42
- import queryMethod from './rest-api-plugin-methods/query.js';
43
- ```
44
-
45
- ## Error Handling
46
- - Use `RestApiValidationError` for validation failures
47
- - Use `RestApiResourceError` for resource-related errors
48
- - Use `RestApiPayloadError` for malformed payloads
49
- - Always include descriptive error messages
50
-
51
- ## JSON:API Helpers
52
- - Use `createJsonApiDocument()` for creating request payloads
53
- - Use `createRelationship()` for belongsTo relationships
54
- - Use `createToManyRelationship()` for hasMany relationships
55
- - Use `validateJsonApiStructure()` to validate responses
@@ -1,180 +0,0 @@
1
- JSKIT Backend Migration Tracker
2
-
3
- Scope
4
- - Move DB, schema, casting, and normalization ownership out of jskit-ai.
5
- - Enrich json-rest-schema and json-rest-api so they can natively cover the required capability set.
6
- - Do not add compatibility runtimes.
7
- - Do not bend json-rest-api or json-rest-schema around jskit-ai shapes unless the capability is a clean native addition.
8
-
9
- Status Legend
10
- - done
11
- - in_progress
12
- - pending
13
- - blocked
14
-
15
- Execution Rule
16
- - Complete one numbered point at a time.
17
- - After each point, write a full report:
18
- - what changed
19
- - how it worked before
20
- - how it works now
21
- - relevant code snippets
22
- - Stop and wait for the next user prompt before starting the next numbered point.
23
-
24
- Work List
25
-
26
- 0. [done] Create and maintain this tracker as the canonical work ledger.
27
- Notes:
28
- - This file is the progress source of truth for the migration work.
29
- - Status changes must be recorded here before moving to the next point.
30
-
31
- 1. [done] Tighten json-rest-schema scalar semantics.
32
- Deliverables:
33
- - make `id` represent the real external/resource ID contract
34
- - tighten boolean parsing
35
- - tighten number/integer parsing where schema should reject invalid inputs instead of silently coercing
36
-
37
- 2. [done] Define a native json-rest-schema create/replace/patch validation contract.
38
- Deliverables:
39
- - explicit operation mode semantics
40
- - presence-aware field handling
41
- - patch behavior that preserves omission and only normalizes touched fields
42
- - switch json-rest-api call sites to the explicit schema contract
43
- Notes:
44
- - verification blocker removed by deleting stale DB-helper tests from `json-rest-schema`
45
- - DB-helper coverage now lives in `json-rest-api`, which owns `createKnexTable()` and `generateKnexMigration()`
46
- - verified end-to-end against a local symlinked `json-rest-schema@1.0.13`; `json-rest-api` test suite passes with the new schema contract
47
-
48
- 3. [done] Add transport-schema export from json-rest-schema.
49
- Deliverables:
50
- - export usable by JSON Schema / Ajv style consumers
51
- - enough structure for pre-handler validation in connectors such as Fastify
52
- Notes:
53
- - added `schema.toJsonSchema({ mode, additionalProperties })` in `json-rest-schema`
54
- - export is draft-07, mode-aware, and transport-facing rather than a clone of every in-process coercion path
55
- - custom transport export hooks are supported through `handler.toJsonSchema`
56
- - unknown external metadata keys are ignored; custom registered validators without a transport hook fail loudly
57
-
58
- 4. [done] Extend json-rest-schema field metadata only where it remains schema-level meaning.
59
- Deliverables:
60
- - preserve useful passive metadata such as nullability, defaults, precision, scale, unsigned, enum values, and temporal precision
61
- Notes:
62
- - made `enum` a first-class built-in rule in `json-rest-schema`
63
- - added canonical passive metadata support for `temporalPrecision`
64
- - transport export now preserves passive schema metadata under `x-json-rest-schema.metadata`
65
- - passive metadata remains schema-owned metadata; no DB-specific runtime logic was added to `json-rest-schema`
66
-
67
- 5. [done] Add repository/storage mapping in json-rest-api.
68
- Deliverables:
69
- - API field to DB column mapping
70
- - virtual/non-column fields
71
- - write serializers where persistence formatting is required
72
- Notes:
73
- - added `field.storage = { column, serialize }` as the native repository/storage surface in `json-rest-api`
74
- - storage metadata is compiled once into `schemaInfo.storageInfo`
75
- - Knex writes now translate logical attributes to storage columns through the compiled mapping
76
- - table creation and migration generation now respect storage column overrides
77
- - JSON:API transformers translate storage rows back to logical field names before response shaping
78
- - storage adapters now own row/id/select translation used by Knex callers, reducing repeated mapping helpers
79
- - runtime row access now uses the same logical field path for `id` as for other fields: `getFieldValue(record, 'id')`
80
- - include handling and relationship links now use logical record IDs consistently, including custom-id resources
81
- - direct DB helper surfaces now support logical `id` fields mapped to custom storage columns without duplicate-column drift
82
- - verified with dedicated storage-mapping tests and the full `json-rest-api` suite
83
-
84
- 6. [done] Add DB introspection snapshot support in json-rest-api.
85
- Deliverables:
86
- - column type and shape introspection
87
- - enum/set values
88
- - indexes
89
- - foreign keys
90
- - check constraints
91
- - precision/scale/temporal precision
92
- Notes:
93
- - added `introspectKnexTableSnapshot(knex, { tableName, idColumn })` as the native normalized snapshot helper
94
- - snapshot support is dialect-aware for `better-sqlite3`/SQLite and `mysql2`
95
- - SQLite captures named check constraints and foreign keys from table SQL, while indexes/columns/foreign-key actions come from PRAGMA metadata
96
- - `RestApiKnexPlugin` now exposes `api.resources.{resource}.introspectKnexTableSnapshot()` for table-backed resources
97
- - verified with real SQLite snapshot tests, MySQL raw-double snapshot tests, and a public scope-method test
98
-
99
- 7. [done] Add deterministic migration generation and diffing in json-rest-api.
100
- Deliverables:
101
- - create and alter support
102
- - named/composite indexes
103
- - FK rules
104
- - enum/set handling
105
- - defaults and safety warnings for destructive changes
106
- Notes:
107
- - `dbTablesOperations` now normalizes table-level metadata (`indexes`, `foreignKeys`, `checkConstraints`) and uses one contract for live table creation, create-migration generation, and snapshot diffing
108
- - field-level `unique` / `index` / `references` are compiled into deterministic named indexes and foreign keys instead of relying on ad hoc column builder side effects
109
- - added `generateKnexMigrationDiff(tableName, currentSnapshot, schema, options)` returning `{ migration, warnings, plan }`
110
- - additive diff generation supports columns, indexes, and foreign keys; destructive or unsupported changes stay explicit as warnings
111
- - `RestApiKnexPlugin` now exposes `generateKnexMigration()` and `generateKnexMigrationDiff()` on table-backed scopes and threads table-level metadata through `schemaInfo`
112
-
113
- 8. [done] Preserve and clarify the pass-through searchSchema contract in json-rest-api.
114
- Deliverables:
115
- - searchSchema validates allowed filter keys and normalizes values only
116
- - filter meaning remains backend-owned and server-defined
117
- - arbitrary public filter keys are supported when the backend maps them intentionally
118
- - regression coverage for shared merge/validation behavior and invalid filter keys
119
- Notes:
120
- - did not introduce a generic filter DSL
121
- - documented that searchSchema keys are public filter names, not a portable operator language
122
- - verified that alias filters (`oneOf`) and custom backend filters (`applyFilter`) work as intended in the Knex path, where their execution semantics are owned by the backend
123
-
124
- 9. [done] Add declarative autofiltering/scoping in json-rest-api.
125
- Deliverables:
126
- - public
127
- - workspace
128
- - user
129
- - workspace_user
130
- Notes:
131
- - replaced the purpose-specific multihome surface with a generic `AutoFilterPlugin`
132
- - resources now declare `autofilter` presets or inline filters, while the plugin resolves scope values from configured resolver functions
133
- - `workspace`, `user`, `workspace_user`, and `public` are example presets, not built-in auth meanings
134
- - the plugin scopes collection queries and single-record lookups, stamps scoped fields on `POST`/`PUT`, and rejects inconsistent scoped updates
135
- - scoped `belongsTo` relationships are supported by injecting or validating JSON:API relationship identifiers before write validation
136
- - auth/admission semantics remain out of scope for `json-rest-api`; core keeps `checkPermissions` hooks as a neutral extension point only
137
- - shipped `AccessPlugin` was removed before this point so scoping does not inherit built-in auth assumptions
138
-
139
- 10. [done] Add SQL-backed query projections and stable list behavior in json-rest-api.
140
- Deliverables:
141
- - SQL-backed output-only query fields via an optional plugin
142
- - sparse-field and include support for declared query fields
143
- - deterministic ordered-list / cursor behavior with stable tie-breakers
144
- Notes:
145
- - added an optional `QueryProjectionsPlugin` that compiles resource-level `queryFields`, separate from normal schema fields and response-layer computed fields
146
- - query fields are selected by default, can be requested in sparse fieldsets, and are stripped from write input
147
- - query fields can drive sorting and cursor pagination; `id` is appended as a deterministic tie-breaker
148
- - query-field selection is supported on the Knex path and the AnyAPI Knex path, including included resources
149
- - documented as a separate advanced guide so it does not blur with response-layer computed fields
150
-
151
- 11. [done] Add a Fastify-oriented connector layer in json-rest-api.
152
- Deliverables:
153
- - consume exported schema before request handling
154
- - no jskit-ai compatibility shim
155
- Notes:
156
- - added `FastifyPlugin` as a transport connector that registers REST routes on a supplied Fastify instance
157
- - resource `POST`/`PUT`/`PATCH` routes now attach transport-facing JSON Schemas built from `schema.toJsonSchema({ mode })`, wrapped in the JSON:API document envelope
158
- - connector-level transport schemas strip output-only/computed fields and direct `belongsTo` foreign keys from `data.attributes`, matching the existing transport write contract
159
- - connector registers an `application/vnd.api+json` parser and rejects unsupported write content types before route handlers run
160
- - no jskit-ai compatibility shim or duplicate hand-written field validation layer was added
161
-
162
- 12. [pending] Remove the corresponding DB/schema/normalization ownership from jskit-ai and verify parity.
163
- Deliverables:
164
- - no jskit-ai-owned DB/schema normalization path remains for the migrated surface
165
- - verification notes for anything still intentionally left outside scope
166
-
167
- ADDENDUM ITEMS TO POINT 12:
168
-
169
- * This is the reason we did points 1 to 11 (!).
170
- * Needs to be done with a lot of care, since it's harder than it looks
171
- * You MUST read AGENTS.md in jskit-ai VERY carefully, follow it VERY carefully. One of the previous attempts (4 failed in total) was unsuccessful because this step was missed. That file has important instructions on how to avoid repeated helpers and a pointer to important function maps
172
- * There must be NOTHING left of the in house DB stuff. jskit is only a user of what json-rest-api offers.
173
- * NO SHIMS. NO COMPATIBILITY LAYERS. NO LAYERS AT ALL. NO RUNTIMES.
174
- * In an earlier attempt, you made a runtime that mimiked the repository's functions. NO. Repository functions will use json-rest-api's functions to do what they need to do
175
- * A repository should be simple. It can have helper functions, but if it has a LOT of helper functions, there is a problem -- interrupt and let's talk. This happened in the workspace repository
176
- * Multi homing is to be done with the generic filtering option of json-rest-api
177
- * Take a LOT of care with the definiton of the resource file. Do NOT keep the old Type + Normalisation flow. That is GONE. We now have json-rest-schema, and that's what you need to use. One of the 4 failed attempts failed because you were stubborn about reusing that paradigm
178
- * The resource file (which is what is used by the server, AND by the client) needs to be clean, and contain the right information (schemas, relationships, etc). It's a DATA ONLY file.
179
- * The goal is to devoid jskit of any db logic/layering/
180
-