json-rest-api 1.0.7 → 1.0.8

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 (146) hide show
  1. package/.claude/agents/library-guide-expert.md +29 -0
  2. package/.claude/agents/rest-api-internals-expert.md +53 -0
  3. package/CLAUDE.md +139 -1
  4. package/README.md +2 -5
  5. package/docTest.js +238 -0
  6. package/docs/GUIDE/GUIDE_1_Initial_Setup.md +955 -0
  7. package/docs/GUIDE/GUIDE_2_1_The_Starting_Point.md +54 -0
  8. package/docs/GUIDE/GUIDE_2_2_Manipulating_And_Searching_Tables.md +750 -0
  9. package/docs/GUIDE/GUIDE_2_3_BelongsTo_Relationships.md +494 -0
  10. package/docs/GUIDE/GUIDE_2_4_HasMany_Records.md +398 -0
  11. package/docs/GUIDE/GUIDE_2_5_HasMany_Polymorphic.md +882 -0
  12. package/docs/GUIDE/GUIDE_2_6_Many_To_Many.md +709 -0
  13. package/docs/GUIDE/GUIDE_2_7_Pagination_And_Ordering.md +1233 -0
  14. package/docs/GUIDE/GUIDE_2_8_Effects_of_PUT_and_PATCH.md +796 -0
  15. package/{README_X_Relationship_Plugin.md → docs/GUIDE/GUIDE_2_9_Relationships_Urls.md} +1 -4
  16. package/docs/GUIDE/GUIDE_2_Data_And_Relations.md +66 -0
  17. package/docs/GUIDE/GUIDE_3_Field_Transformations.md +1246 -0
  18. package/docs/GUIDE/GUIDE_5_Non-Db_Stores.md +0 -0
  19. package/docs/GUIDE/GUIDE_7_Hooks_Data_Management_And_Plugins.md +1490 -0
  20. package/{README_X_SocketIO.md → docs/GUIDE/GUIDE_X_SocketIO.md} +17 -17
  21. package/docs/GUIDE/index.md +58 -0
  22. package/docs/GUIDE.md +61 -2238
  23. package/docs/ONBOARDING/Computed_Properties_And_Sparse_Fields.md +398 -0
  24. package/docs/README.md +57 -2239
  25. package/{README_2_Computed_and_hidden_fields.md → docs/README_VARIOUS/GUIDE_2_Computed_and_hidden_fields.md} +22 -17
  26. package/docs/README_VARIOUS/GUIDE_IN_DOCS.md +2277 -0
  27. package/{README.ORIG.md → docs/README_VARIOUS/README.ORIG.md} +8 -8
  28. package/{README_8_Polymorphic_Relationships.md → docs/README_VARIOUS/README_8_Polymorphic_Relationships.md} +1 -1
  29. package/docs/README_VARIOUS/README_IN_DOCS.ms +2277 -0
  30. package/{RELATIONSHIPS_ADVANCED.md → docs/README_VARIOUS/RELATIONSHIPS_ADVANCED.md} +3 -3
  31. package/{correct-schema-format.md → docs/README_VARIOUS/correct-schema-format.md} +13 -13
  32. package/{pagination.md → docs/README_VARIOUS/pagination.md} +11 -8
  33. package/docs/assets/css/style.scss +78 -5
  34. package/docs/index.md +2 -12
  35. package/helper-reorganization-plan.md +85 -0
  36. package/helper-usage-analysis.md +94 -0
  37. package/package.json +5 -4
  38. package/plugins/core/bulk-operations-plugin.js +2 -2
  39. package/plugins/core/connectors/express-plugin.js +90 -32
  40. package/plugins/core/lib/querying/knex-cross-table-search.js +609 -0
  41. package/plugins/core/lib/querying/knex-json-api-transformers-querying.js +491 -0
  42. package/plugins/core/lib/querying/knex-pagination-helpers.js +544 -0
  43. package/plugins/core/lib/{knex-process-includes.js → querying/knex-process-includes.js} +65 -50
  44. package/plugins/core/lib/querying/knex-query-helpers-base.js +74 -0
  45. package/plugins/core/lib/{knex-query-helpers.js → querying/knex-query-helpers.js} +416 -180
  46. package/plugins/core/lib/{knex-relationship-includes.js → querying/knex-relationship-includes.js} +430 -114
  47. package/plugins/core/lib/querying/knex-window-queries.js +328 -0
  48. package/plugins/core/lib/querying-writing/compile-schemas.js +328 -0
  49. package/plugins/core/{utils → lib/querying-writing}/connectors-query-parser.js +62 -57
  50. package/plugins/core/lib/{database-capabilities.js → querying-writing/database-capabilities.js} +113 -7
  51. package/plugins/core/lib/querying-writing/database-value-normalizers.js +369 -0
  52. package/plugins/core/lib/querying-writing/default-data-helpers.js +72 -0
  53. package/plugins/core/{utils → lib/querying-writing}/field-utils.js +41 -31
  54. package/plugins/core/{utils → lib/querying-writing}/knex-constants.js +1 -0
  55. package/plugins/core/lib/{knex-field-helpers.js → querying-writing/knex-field-helpers.js} +190 -57
  56. package/plugins/core/lib/querying-writing/knex-json-api-transformers.js +162 -0
  57. package/plugins/core/lib/{payload-validators.js → querying-writing/payload-validators.js} +297 -217
  58. package/plugins/core/lib/querying-writing/schema-helpers.js +497 -0
  59. package/plugins/core/lib/querying-writing/scope-validations.js +431 -0
  60. package/plugins/core/lib/{simplified-helpers.js → querying-writing/simplified-helpers.js} +216 -176
  61. package/plugins/core/lib/writing/knex-json-api-transformers-writing.js +110 -0
  62. package/plugins/core/lib/writing/many-to-many-manipulations.js +300 -0
  63. package/plugins/core/lib/writing/relationship-processor.js +252 -0
  64. package/plugins/core/rest-api-knex-plugin.js +183 -62
  65. package/plugins/core/rest-api-plugin-hooks/compile-resource-schemas.js +7 -0
  66. package/plugins/core/rest-api-plugin-hooks/register-relationship-routes.js +72 -0
  67. package/plugins/core/rest-api-plugin-hooks/register-scope-routes.js +102 -0
  68. package/plugins/core/rest-api-plugin-hooks/turn-scope-init-into-vars.js +50 -0
  69. package/plugins/core/rest-api-plugin-hooks/validate-include-configurations.js +39 -0
  70. package/plugins/core/rest-api-plugin-methods/add-route.js +23 -0
  71. package/plugins/core/rest-api-plugin-methods/check-permissions.js +18 -0
  72. package/plugins/core/rest-api-plugin-methods/common.js +605 -0
  73. package/plugins/core/rest-api-plugin-methods/delete-relationship.js +115 -0
  74. package/plugins/core/rest-api-plugin-methods/delete.js +109 -0
  75. package/plugins/core/rest-api-plugin-methods/enrich-attributes.js +186 -0
  76. package/plugins/core/rest-api-plugin-methods/get-related.js +295 -0
  77. package/plugins/core/rest-api-plugin-methods/get-relationship.js +62 -0
  78. package/plugins/core/rest-api-plugin-methods/get.js +187 -0
  79. package/plugins/core/rest-api-plugin-methods/patch-relationship.js +56 -0
  80. package/plugins/core/rest-api-plugin-methods/patch.js +193 -0
  81. package/plugins/core/rest-api-plugin-methods/post-relationship.js +104 -0
  82. package/plugins/core/rest-api-plugin-methods/post.js +157 -0
  83. package/plugins/core/rest-api-plugin-methods/put.js +257 -0
  84. package/plugins/core/rest-api-plugin-methods/query.js +208 -0
  85. package/plugins/core/rest-api-plugin.js +108 -2498
  86. package/plugins/core/socketio-plugin.js +28 -5
  87. package/plugins/storage/local-storage.js +2 -2
  88. package/tests/computed-fields.test.js +483 -0
  89. package/tests/cors.test.js +4 -4
  90. package/tests/curl.test.js +5 -4
  91. package/tests/custom-idproperty-relationships.test.js +891 -0
  92. package/tests/field-getters.test.js +353 -0
  93. package/tests/field-setters.test.js +310 -0
  94. package/tests/fixtures/api-configs.js +800 -28
  95. package/tests/jwt-auth.test.js +0 -2
  96. package/tests/nested-includes.test.js +1 -1
  97. package/tests/pagination-cursor-multifield.test.js +514 -0
  98. package/tests/pagination-enhanced.test.js +12 -9
  99. package/tests/polymorphic-relationships.test.js +10 -8
  100. package/tests/polymorphic-simple.test.js +6 -4
  101. package/tests/positioning-advanced.test.js +12 -12
  102. package/tests/positioning-extended.test.js +25 -25
  103. package/tests/positioning-multifilter.test.js +24 -24
  104. package/tests/positioning.test.js +3 -3
  105. package/tests/query-limits.test.js +24 -8
  106. package/tests/relationship-endpoints.test.js +4 -5
  107. package/tests/relationships.test.js +0 -1
  108. package/tests/socketio.test.js +12 -1
  109. package/tests/virtual-fields.test.js +13 -13
  110. package/PLAN_FOR_WEBSOCKETS.md +0 -398
  111. package/README_1_Initial_Setup.md +0 -393
  112. package/README_X_Hooks.md +0 -647
  113. package/TODO_rest-api-plugin-extras.todo +0 -23
  114. package/connectors_ideas/express-plugin.js +0 -120
  115. package/connectors_ideas/http-plugin.js +0 -138
  116. package/docs/examples/express-plugin.js +0 -366
  117. package/example.js +0 -301
  118. package/plugins/core/HELPER_MODULES.md +0 -285
  119. package/plugins/core/lib/compile-schemas.js +0 -245
  120. package/plugins/core/lib/database-value-normalizers.js +0 -192
  121. package/plugins/core/lib/default-data-helpers.js +0 -100
  122. package/plugins/core/lib/knex-cross-table-search.js +0 -442
  123. package/plugins/core/lib/knex-json-api-helpers.js +0 -84
  124. package/plugins/core/lib/knex-json-api-transformers.js +0 -449
  125. package/plugins/core/lib/knex-pagination-helpers.js +0 -193
  126. package/plugins/core/lib/knex-window-queries.js +0 -142
  127. package/plugins/core/lib/many-to-many-manipulations.js +0 -343
  128. package/plugins/core/lib/relationship-processor.js +0 -278
  129. package/plugins/core/lib/schema-helpers.js +0 -343
  130. package/plugins/core/lib/scope-validations.js +0 -252
  131. package/plugins/core/rest-api-relationships-plugin.js +0 -700
  132. package/plugins/core/utils/knex-query-helpers-base.js +0 -56
  133. /package/{README_X_Permissions.md → docs/GUIDE/GUIDE_4_Authentication_And_Permissions.md} +0 -0
  134. /package/{README_X_Positioning.md → docs/GUIDE/GUIDE_6_Positioning.md} +0 -0
  135. /package/{README_X_Bulk_Operations.md → docs/GUIDE/GUIDE_X_Bulk_Operations.md} +0 -0
  136. /package/{README_X_Cors.md → docs/GUIDE/GUIDE_X_Cors.md} +0 -0
  137. /package/{README_X_Multihome.md → docs/GUIDE/GUIDE_X_Multihome.md} +0 -0
  138. /package/{README_X_Appendices.md → docs/GUIDE/GUIDE_Y_Appendices.md} +0 -0
  139. /package/{QUERY_DEPTH_PROTECTION.md → docs/README_VARIOUS/QUERY_DEPTH_PROTECTION.md} +0 -0
  140. /package/{RELATIONSHIPS.md → docs/README_VARIOUS/RELATIONSHIPS.md} +0 -0
  141. /package/{WEBSOCKET_IMPLEMENTATION_STATUS.md → docs/README_VARIOUS/WEBSOCKET_IMPLEMENTATION_STATUS.md} +0 -0
  142. /package/{helper-functions-chart.md → docs/README_VARIOUS/helper-functions-chart.md} +0 -0
  143. /package/docs/{implementation-hidden-computed-fields.md → README_VARIOUS/implementation-hidden-computed-fields.md} +0 -0
  144. /package/docs/{include-limits-migration-guide.md → README_VARIOUS/include-limits-migration-guide.md} +0 -0
  145. /package/{readmeSnippets → docs/README_VARIOUS}/test_put_behavior.js +0 -0
  146. /package/{readmeSnippets → docs/README_VARIOUS}/test_put_fields_without_defaults.js +0 -0
@@ -80,13 +80,12 @@ await api.addResource('products', {
80
80
  name: { type: 'string', required: true },
81
81
  price: { type: 'number', required: true },
82
82
  cost: { type: 'number', required: true, normallyHidden: true },
83
- tax_rate: { type: 'number', required: true }
84
- },
85
-
86
- // Computed fields are defined separately from schema
87
- computed: {
83
+ tax_rate: { type: 'number', required: true },
84
+
85
+ // Computed fields are defined in the schema with computed: true
88
86
  profit_margin: {
89
87
  type: 'number',
88
+ computed: true, // Mark as computed field
90
89
  dependencies: ['price', 'cost'], // Fields needed for computation
91
90
  compute: ({ attributes }) => {
92
91
  if (attributes.price && attributes.cost) {
@@ -98,6 +97,7 @@ await api.addResource('products', {
98
97
 
99
98
  display_name: {
100
99
  type: 'string',
100
+ computed: true, // Mark as computed field
101
101
  dependencies: ['name', 'price'],
102
102
  compute: ({ attributes }) => {
103
103
  return `${attributes.name} - $${attributes.price}`;
@@ -112,9 +112,12 @@ await api.addResource('products', {
112
112
  The compute function receives a rich context object:
113
113
 
114
114
  ```javascript
115
- computed: {
115
+ schema: {
116
+ field1: { type: 'string' },
117
+ field2: { type: 'string' },
116
118
  advanced_calculation: {
117
119
  type: 'string',
120
+ computed: true, // Mark as computed field
118
121
  dependencies: ['field1', 'field2'],
119
122
  compute: async (context) => {
120
123
  // Available in context:
@@ -149,11 +152,10 @@ await api.addResource('products', {
149
152
  name: { type: 'string' },
150
153
  price: { type: 'number' },
151
154
  cost: { type: 'number', normallyHidden: true },
152
- tax_rate: { type: 'number', normallyHidden: true }
153
- },
154
- computed: {
155
+ tax_rate: { type: 'number', normallyHidden: true },
155
156
  profit_margin: {
156
157
  type: 'number',
158
+ computed: true, // Mark as computed field
157
159
  dependencies: ['price', 'cost'],
158
160
  compute: ({ attributes }) => {
159
161
  return ((attributes.price - attributes.cost) / attributes.price * 100).toFixed(2);
@@ -208,13 +210,12 @@ await api.addResource('products', {
208
210
 
209
211
  // Internal fields - never exposed
210
212
  supplier_code: { type: 'string', hidden: true },
211
- warehouse_location: { type: 'string', hidden: true }
212
- },
213
-
214
- computed: {
213
+ warehouse_location: { type: 'string', hidden: true },
214
+
215
215
  // Sale price after discount
216
216
  sale_price: {
217
217
  type: 'number',
218
+ computed: true,
218
219
  dependencies: ['list_price', 'discount_percent'],
219
220
  compute: ({ attributes }) => {
220
221
  const discount = attributes.discount_percent || 0;
@@ -225,6 +226,7 @@ await api.addResource('products', {
225
226
  // Profit margin (requires hidden cost fields)
226
227
  profit_margin: {
227
228
  type: 'number',
229
+ computed: true,
228
230
  dependencies: ['list_price', 'base_cost', 'shipping_cost', 'discount_percent'],
229
231
  compute: ({ attributes }) => {
230
232
  const salePrice = attributes.list_price * (1 - (attributes.discount_percent || 0) / 100);
@@ -237,6 +239,7 @@ await api.addResource('products', {
237
239
  // Display title for UI
238
240
  display_title: {
239
241
  type: 'string',
242
+ computed: true,
240
243
  dependencies: ['name', 'sku', 'discount_percent'],
241
244
  compute: ({ attributes }) => {
242
245
  let title = `${attributes.name} (${attributes.sku})`;
@@ -298,13 +301,12 @@ await api.addResource('users', {
298
301
  // Stats fields (updated by background jobs)
299
302
  post_count: { type: 'number', default: 0 },
300
303
  comment_count: { type: 'number', default: 0 },
301
- last_login_at: { type: 'datetime', normallyHidden: true }
302
- },
303
-
304
- computed: {
304
+ last_login_at: { type: 'datetime', normallyHidden: true },
305
+
305
306
  // Full name from parts
306
307
  full_name: {
307
308
  type: 'string',
309
+ computed: true,
308
310
  dependencies: ['first_name', 'last_name'],
309
311
  compute: ({ attributes }) => {
310
312
  const parts = [attributes.first_name, attributes.last_name].filter(Boolean);
@@ -315,6 +317,7 @@ await api.addResource('users', {
315
317
  // Age calculation (requires hidden date_of_birth)
316
318
  age: {
317
319
  type: 'number',
320
+ computed: true,
318
321
  dependencies: ['date_of_birth'],
319
322
  compute: ({ attributes }) => {
320
323
  if (!attributes.date_of_birth) return null;
@@ -332,6 +335,7 @@ await api.addResource('users', {
332
335
  // Member duration
333
336
  member_for_days: {
334
337
  type: 'number',
338
+ computed: true,
335
339
  dependencies: ['created_at'],
336
340
  compute: ({ attributes }) => {
337
341
  const created = new Date(attributes.created_at);
@@ -344,6 +348,7 @@ await api.addResource('users', {
344
348
  // Activity level based on posts and comments
345
349
  activity_level: {
346
350
  type: 'string',
351
+ computed: true,
347
352
  dependencies: ['post_count', 'comment_count', 'created_at'],
348
353
  compute: ({ attributes }) => {
349
354
  const total = (attributes.post_count || 0) + (attributes.comment_count || 0);