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.
- package/.claude/agents/library-guide-expert.md +29 -0
- package/.claude/agents/rest-api-internals-expert.md +53 -0
- package/CLAUDE.md +139 -1
- package/README.md +2 -5
- package/docTest.js +238 -0
- package/docs/GUIDE/GUIDE_1_Initial_Setup.md +955 -0
- package/docs/GUIDE/GUIDE_2_1_The_Starting_Point.md +54 -0
- package/docs/GUIDE/GUIDE_2_2_Manipulating_And_Searching_Tables.md +750 -0
- package/docs/GUIDE/GUIDE_2_3_BelongsTo_Relationships.md +494 -0
- package/docs/GUIDE/GUIDE_2_4_HasMany_Records.md +398 -0
- package/docs/GUIDE/GUIDE_2_5_HasMany_Polymorphic.md +882 -0
- package/docs/GUIDE/GUIDE_2_6_Many_To_Many.md +709 -0
- package/docs/GUIDE/GUIDE_2_7_Pagination_And_Ordering.md +1233 -0
- package/docs/GUIDE/GUIDE_2_8_Effects_of_PUT_and_PATCH.md +796 -0
- package/{README_X_Relationship_Plugin.md → docs/GUIDE/GUIDE_2_9_Relationships_Urls.md} +1 -4
- package/docs/GUIDE/GUIDE_2_Data_And_Relations.md +66 -0
- package/docs/GUIDE/GUIDE_3_Field_Transformations.md +1246 -0
- package/docs/GUIDE/GUIDE_5_Non-Db_Stores.md +0 -0
- package/docs/GUIDE/GUIDE_7_Hooks_Data_Management_And_Plugins.md +1490 -0
- package/{README_X_SocketIO.md → docs/GUIDE/GUIDE_X_SocketIO.md} +17 -17
- package/docs/GUIDE/index.md +58 -0
- package/docs/GUIDE.md +61 -2238
- package/docs/ONBOARDING/Computed_Properties_And_Sparse_Fields.md +398 -0
- package/docs/README.md +57 -2239
- package/{README_2_Computed_and_hidden_fields.md → docs/README_VARIOUS/GUIDE_2_Computed_and_hidden_fields.md} +22 -17
- package/docs/README_VARIOUS/GUIDE_IN_DOCS.md +2277 -0
- package/{README.ORIG.md → docs/README_VARIOUS/README.ORIG.md} +8 -8
- package/{README_8_Polymorphic_Relationships.md → docs/README_VARIOUS/README_8_Polymorphic_Relationships.md} +1 -1
- package/docs/README_VARIOUS/README_IN_DOCS.ms +2277 -0
- package/{RELATIONSHIPS_ADVANCED.md → docs/README_VARIOUS/RELATIONSHIPS_ADVANCED.md} +3 -3
- package/{correct-schema-format.md → docs/README_VARIOUS/correct-schema-format.md} +13 -13
- package/{pagination.md → docs/README_VARIOUS/pagination.md} +11 -8
- package/docs/assets/css/style.scss +78 -5
- package/docs/index.md +2 -12
- package/helper-reorganization-plan.md +85 -0
- package/helper-usage-analysis.md +94 -0
- package/package.json +5 -4
- package/plugins/core/bulk-operations-plugin.js +2 -2
- package/plugins/core/connectors/express-plugin.js +90 -32
- package/plugins/core/lib/querying/knex-cross-table-search.js +609 -0
- package/plugins/core/lib/querying/knex-json-api-transformers-querying.js +491 -0
- package/plugins/core/lib/querying/knex-pagination-helpers.js +544 -0
- package/plugins/core/lib/{knex-process-includes.js → querying/knex-process-includes.js} +65 -50
- package/plugins/core/lib/querying/knex-query-helpers-base.js +74 -0
- package/plugins/core/lib/{knex-query-helpers.js → querying/knex-query-helpers.js} +416 -180
- package/plugins/core/lib/{knex-relationship-includes.js → querying/knex-relationship-includes.js} +430 -114
- package/plugins/core/lib/querying/knex-window-queries.js +328 -0
- package/plugins/core/lib/querying-writing/compile-schemas.js +328 -0
- package/plugins/core/{utils → lib/querying-writing}/connectors-query-parser.js +62 -57
- package/plugins/core/lib/{database-capabilities.js → querying-writing/database-capabilities.js} +113 -7
- package/plugins/core/lib/querying-writing/database-value-normalizers.js +369 -0
- package/plugins/core/lib/querying-writing/default-data-helpers.js +72 -0
- package/plugins/core/{utils → lib/querying-writing}/field-utils.js +41 -31
- package/plugins/core/{utils → lib/querying-writing}/knex-constants.js +1 -0
- package/plugins/core/lib/{knex-field-helpers.js → querying-writing/knex-field-helpers.js} +190 -57
- package/plugins/core/lib/querying-writing/knex-json-api-transformers.js +162 -0
- package/plugins/core/lib/{payload-validators.js → querying-writing/payload-validators.js} +297 -217
- package/plugins/core/lib/querying-writing/schema-helpers.js +497 -0
- package/plugins/core/lib/querying-writing/scope-validations.js +431 -0
- package/plugins/core/lib/{simplified-helpers.js → querying-writing/simplified-helpers.js} +216 -176
- package/plugins/core/lib/writing/knex-json-api-transformers-writing.js +110 -0
- package/plugins/core/lib/writing/many-to-many-manipulations.js +300 -0
- package/plugins/core/lib/writing/relationship-processor.js +252 -0
- package/plugins/core/rest-api-knex-plugin.js +183 -62
- package/plugins/core/rest-api-plugin-hooks/compile-resource-schemas.js +7 -0
- package/plugins/core/rest-api-plugin-hooks/register-relationship-routes.js +72 -0
- package/plugins/core/rest-api-plugin-hooks/register-scope-routes.js +102 -0
- package/plugins/core/rest-api-plugin-hooks/turn-scope-init-into-vars.js +50 -0
- package/plugins/core/rest-api-plugin-hooks/validate-include-configurations.js +39 -0
- package/plugins/core/rest-api-plugin-methods/add-route.js +23 -0
- package/plugins/core/rest-api-plugin-methods/check-permissions.js +18 -0
- package/plugins/core/rest-api-plugin-methods/common.js +605 -0
- package/plugins/core/rest-api-plugin-methods/delete-relationship.js +115 -0
- package/plugins/core/rest-api-plugin-methods/delete.js +109 -0
- package/plugins/core/rest-api-plugin-methods/enrich-attributes.js +186 -0
- package/plugins/core/rest-api-plugin-methods/get-related.js +295 -0
- package/plugins/core/rest-api-plugin-methods/get-relationship.js +62 -0
- package/plugins/core/rest-api-plugin-methods/get.js +187 -0
- package/plugins/core/rest-api-plugin-methods/patch-relationship.js +56 -0
- package/plugins/core/rest-api-plugin-methods/patch.js +193 -0
- package/plugins/core/rest-api-plugin-methods/post-relationship.js +104 -0
- package/plugins/core/rest-api-plugin-methods/post.js +157 -0
- package/plugins/core/rest-api-plugin-methods/put.js +257 -0
- package/plugins/core/rest-api-plugin-methods/query.js +208 -0
- package/plugins/core/rest-api-plugin.js +108 -2498
- package/plugins/core/socketio-plugin.js +28 -5
- package/plugins/storage/local-storage.js +2 -2
- package/tests/computed-fields.test.js +483 -0
- package/tests/cors.test.js +4 -4
- package/tests/curl.test.js +5 -4
- package/tests/custom-idproperty-relationships.test.js +891 -0
- package/tests/field-getters.test.js +353 -0
- package/tests/field-setters.test.js +310 -0
- package/tests/fixtures/api-configs.js +800 -28
- package/tests/jwt-auth.test.js +0 -2
- package/tests/nested-includes.test.js +1 -1
- package/tests/pagination-cursor-multifield.test.js +514 -0
- package/tests/pagination-enhanced.test.js +12 -9
- package/tests/polymorphic-relationships.test.js +10 -8
- package/tests/polymorphic-simple.test.js +6 -4
- package/tests/positioning-advanced.test.js +12 -12
- package/tests/positioning-extended.test.js +25 -25
- package/tests/positioning-multifilter.test.js +24 -24
- package/tests/positioning.test.js +3 -3
- package/tests/query-limits.test.js +24 -8
- package/tests/relationship-endpoints.test.js +4 -5
- package/tests/relationships.test.js +0 -1
- package/tests/socketio.test.js +12 -1
- package/tests/virtual-fields.test.js +13 -13
- package/PLAN_FOR_WEBSOCKETS.md +0 -398
- package/README_1_Initial_Setup.md +0 -393
- package/README_X_Hooks.md +0 -647
- package/TODO_rest-api-plugin-extras.todo +0 -23
- package/connectors_ideas/express-plugin.js +0 -120
- package/connectors_ideas/http-plugin.js +0 -138
- package/docs/examples/express-plugin.js +0 -366
- package/example.js +0 -301
- package/plugins/core/HELPER_MODULES.md +0 -285
- package/plugins/core/lib/compile-schemas.js +0 -245
- package/plugins/core/lib/database-value-normalizers.js +0 -192
- package/plugins/core/lib/default-data-helpers.js +0 -100
- package/plugins/core/lib/knex-cross-table-search.js +0 -442
- package/plugins/core/lib/knex-json-api-helpers.js +0 -84
- package/plugins/core/lib/knex-json-api-transformers.js +0 -449
- package/plugins/core/lib/knex-pagination-helpers.js +0 -193
- package/plugins/core/lib/knex-window-queries.js +0 -142
- package/plugins/core/lib/many-to-many-manipulations.js +0 -343
- package/plugins/core/lib/relationship-processor.js +0 -278
- package/plugins/core/lib/schema-helpers.js +0 -343
- package/plugins/core/lib/scope-validations.js +0 -252
- package/plugins/core/rest-api-relationships-plugin.js +0 -700
- package/plugins/core/utils/knex-query-helpers-base.js +0 -56
- /package/{README_X_Permissions.md → docs/GUIDE/GUIDE_4_Authentication_And_Permissions.md} +0 -0
- /package/{README_X_Positioning.md → docs/GUIDE/GUIDE_6_Positioning.md} +0 -0
- /package/{README_X_Bulk_Operations.md → docs/GUIDE/GUIDE_X_Bulk_Operations.md} +0 -0
- /package/{README_X_Cors.md → docs/GUIDE/GUIDE_X_Cors.md} +0 -0
- /package/{README_X_Multihome.md → docs/GUIDE/GUIDE_X_Multihome.md} +0 -0
- /package/{README_X_Appendices.md → docs/GUIDE/GUIDE_Y_Appendices.md} +0 -0
- /package/{QUERY_DEPTH_PROTECTION.md → docs/README_VARIOUS/QUERY_DEPTH_PROTECTION.md} +0 -0
- /package/{RELATIONSHIPS.md → docs/README_VARIOUS/RELATIONSHIPS.md} +0 -0
- /package/{WEBSOCKET_IMPLEMENTATION_STATUS.md → docs/README_VARIOUS/WEBSOCKET_IMPLEMENTATION_STATUS.md} +0 -0
- /package/{helper-functions-chart.md → docs/README_VARIOUS/helper-functions-chart.md} +0 -0
- /package/docs/{implementation-hidden-computed-fields.md → README_VARIOUS/implementation-hidden-computed-fields.md} +0 -0
- /package/docs/{include-limits-migration-guide.md → README_VARIOUS/include-limits-migration-guide.md} +0 -0
- /package/{readmeSnippets → docs/README_VARIOUS}/test_put_behavior.js +0 -0
- /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
|
-
|
|
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);
|