json-rest-api 1.0.22 → 1.0.23
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CLAUDE.md +1 -2
- package/JSKIT_BACKEND_MIGRATION_TRACKER.txt +180 -0
- package/SINGLE_VALIDATION_CONTRACT_TODO.txt +172 -0
- package/docs/API.md +51 -14
- package/docs/COMPARISON.md +2 -2
- package/docs/GUIDE/GUIDE_1_Initial_Setup.md +28 -1
- package/docs/GUIDE/GUIDE_2_2_Manipulating_And_Searching_Tables.md +5 -1
- package/docs/GUIDE/GUIDE_2_7_Pagination_And_Ordering.md +3 -1
- package/docs/GUIDE/GUIDE_2_8_Effects_of_PUT_and_PATCH.md +12 -60
- package/docs/GUIDE/GUIDE_2_Data_And_Relations.md +2 -2
- package/docs/GUIDE/GUIDE_3_Field_Transformations.md +5 -1
- package/docs/GUIDE/GUIDE_7_Hooks_Data_Management_And_Plugins.md +2 -0
- package/docs/GUIDE/GUIDE_X_Autofiltering.md +355 -0
- package/docs/GUIDE/GUIDE_X_Fastify.md +78 -0
- package/docs/GUIDE/GUIDE_X_Knex_Schema_And_Migrations.md +250 -0
- package/docs/GUIDE/GUIDE_X_Query_Projections.md +159 -0
- package/docs/GUIDE/GUIDE_X_Writing_Plugins.md +199 -0
- package/docs/GUIDE/index.md +18 -9
- package/docs/QUICKSTART.md +5 -1
- package/docs/index.md +1 -1
- package/index.js +3 -2
- package/package.json +2 -2
- package/plugins/core/connectors/express-plugin.js +97 -184
- package/plugins/core/connectors/fastify-plugin.js +206 -0
- package/plugins/core/connectors/lib/connector-core.js +195 -0
- package/plugins/core/connectors/lib/transport-http-helpers.js +122 -0
- package/plugins/core/connectors/lib/transport-route-schemas.js +92 -0
- package/plugins/core/lib/dbIntrospection.js +1078 -0
- package/plugins/core/lib/dbTablesOperations.js +1104 -160
- package/plugins/core/lib/querying/knex-json-api-transformers-querying.js +5 -2
- package/plugins/core/lib/querying/knex-process-includes.js +3 -4
- package/plugins/core/lib/querying/knex-query-helpers.js +17 -71
- package/plugins/core/lib/querying/knex-relationship-includes.js +466 -206
- package/plugins/core/lib/querying/query-builder-utils.js +19 -0
- package/plugins/core/lib/querying/query-field-sort-helpers.js +135 -0
- package/plugins/core/lib/querying/sort-helpers.js +33 -0
- package/plugins/core/lib/querying/storage-adapter-utils.js +51 -0
- package/plugins/core/lib/querying/url-helpers.js +8 -2
- package/plugins/core/lib/querying-writing/compile-schemas.js +12 -1
- package/plugins/core/lib/querying-writing/knex-field-helpers.js +83 -13
- package/plugins/core/lib/querying-writing/knex-json-api-transformers.js +13 -12
- package/plugins/core/lib/querying-writing/query-field-helpers.js +88 -0
- package/plugins/core/lib/querying-writing/request-contracts.js +590 -0
- package/plugins/core/lib/storage/canonical-storage-mapping.js +113 -0
- package/plugins/core/lib/storage/storage-adapter.js +79 -2
- package/plugins/core/lib/storage/storage-mapping.js +204 -0
- package/plugins/core/rest-api-anyapi-knex-plugin.js +355 -228
- package/plugins/core/rest-api-autofilter-plugin.js +414 -0
- package/plugins/core/rest-api-knex-plugin.js +249 -211
- package/plugins/core/rest-api-plugin-hooks/register-relationship-routes.js +10 -5
- package/plugins/core/rest-api-plugin-hooks/register-scope-routes.js +12 -6
- package/plugins/core/rest-api-plugin-methods/apply-query-filters.js +41 -0
- package/plugins/core/rest-api-plugin-methods/common.js +121 -83
- package/plugins/core/rest-api-plugin-methods/enrich-attributes.js +6 -1
- package/plugins/core/rest-api-plugin-methods/get.js +23 -14
- package/plugins/core/rest-api-plugin-methods/patch.js +28 -12
- package/plugins/core/rest-api-plugin-methods/post.js +13 -8
- package/plugins/core/rest-api-plugin-methods/put.js +45 -21
- package/plugins/core/rest-api-plugin-methods/query.js +15 -53
- package/plugins/core/rest-api-plugin.js +2 -0
- package/plugins/core/rest-api-positioning-plugin.js +1 -1
- package/plugins/core/rest-api-query-projections-plugin.js +130 -0
- package/plugins/core/socketio-plugin.js +1 -3
- package/tests/autofilter.test.js +463 -0
- package/tests/custom-id-simplified-post.test.js +75 -0
- package/tests/custom-idproperty-relationships.test.js +33 -0
- package/tests/db-introspection.test.js +518 -0
- package/tests/db-table-operations.test.js +781 -0
- package/tests/fastify-plugin.test.js +141 -0
- package/tests/field-getters.test.js +1 -2
- package/tests/field-setters.test.js +0 -4
- package/tests/fixtures/api-configs.js +188 -219
- package/tests/helpers/fake-fastify.js +99 -0
- package/tests/http-connectors-parity.test.js +235 -0
- package/tests/projected-fields.test.js +319 -0
- package/tests/relationships.test.js +3 -3
- package/tests/searchschema-knex-behavior.test.js +187 -0
- package/tests/searchschema-merge.test.js +21 -69
- package/tests/storage-mapping.test.js +210 -0
- package/audit/00-charter.md +0 -103
- package/audit/01-scope-map.md +0 -84
- package/audit/02-coverage-matrix.csv +0 -174
- package/audit/03-invariants.md +0 -123
- package/audit/04-standards-rubric.md +0 -56
- package/audit/05-competitor-rubric.md +0 -77
- package/audit/06-findings.md +0 -160
- package/audit/07-risk-register.csv +0 -10
- package/audit/08-remediation-roadmap.md +0 -177
- package/audit/09-signoff-check.md +0 -23
- package/audit/10-final-synthesis.md +0 -29
- package/audit/evidence/code/all-files-json-rest-api.txt +0 -168
- package/audit/evidence/code/all-files-json-rest-schema.txt +0 -12
- package/audit/evidence/code/boundary-leak-checks.txt +0 -72
- package/audit/evidence/code/critical-pass1/json-rest-api__plugins__core__bulk-operations-plugin.js.txt +0 -480
- package/audit/evidence/code/critical-pass1/json-rest-api__plugins__core__connectors__express-plugin.js.txt +0 -532
- package/audit/evidence/code/critical-pass1/json-rest-api__plugins__core__connectors__lib__busboy-detector.js.txt +0 -175
- package/audit/evidence/code/critical-pass1/json-rest-api__plugins__core__connectors__lib__formidable-detector.js.txt +0 -138
- package/audit/evidence/code/critical-pass1/json-rest-api__plugins__core__connectors__lib__request-helpers.js.txt +0 -222
- package/audit/evidence/code/critical-pass1/json-rest-api__plugins__core__file-handling-plugin.js.txt +0 -342
- package/audit/evidence/code/critical-pass1/json-rest-api__plugins__core__lib__dbTablesOperations.js.txt +0 -304
- package/audit/evidence/code/critical-pass1/json-rest-api__plugins__core__lib__fractional-positioning.js.txt +0 -188
- package/audit/evidence/code/critical-pass1/json-rest-api__plugins__core__lib__querying-writing__compile-schemas.js.txt +0 -336
- package/audit/evidence/code/critical-pass1/json-rest-api__plugins__core__lib__querying-writing__connectors-query-parser.js.txt +0 -165
- package/audit/evidence/code/critical-pass1/json-rest-api__plugins__core__lib__querying-writing__database-capabilities.js.txt +0 -265
- package/audit/evidence/code/critical-pass1/json-rest-api__plugins__core__lib__querying-writing__database-value-normalizers.js.txt +0 -369
- package/audit/evidence/code/critical-pass1/json-rest-api__plugins__core__lib__querying-writing__default-data-helpers.js.txt +0 -72
- package/audit/evidence/code/critical-pass1/json-rest-api__plugins__core__lib__querying-writing__field-utils.js.txt +0 -139
- package/audit/evidence/code/critical-pass1/json-rest-api__plugins__core__lib__querying-writing__knex-constants.js.txt +0 -45
- package/audit/evidence/code/critical-pass1/json-rest-api__plugins__core__lib__querying-writing__knex-field-helpers.js.txt +0 -396
- package/audit/evidence/code/critical-pass1/json-rest-api__plugins__core__lib__querying-writing__knex-json-api-transformers.js.txt +0 -162
- package/audit/evidence/code/critical-pass1/json-rest-api__plugins__core__lib__querying-writing__payload-validators.js.txt +0 -1314
- package/audit/evidence/code/critical-pass1/json-rest-api__plugins__core__lib__querying-writing__schema-helpers.js.txt +0 -488
- package/audit/evidence/code/critical-pass1/json-rest-api__plugins__core__lib__querying-writing__scope-validations.js.txt +0 -484
- package/audit/evidence/code/critical-pass1/json-rest-api__plugins__core__lib__querying-writing__simplified-helpers.js.txt +0 -857
- package/audit/evidence/code/critical-pass1/json-rest-api__plugins__core__lib__querying__knex-cross-table-search.js.txt +0 -565
- package/audit/evidence/code/critical-pass1/json-rest-api__plugins__core__lib__querying__knex-json-api-transformers-querying.js.txt +0 -485
- package/audit/evidence/code/critical-pass1/json-rest-api__plugins__core__lib__querying__knex-pagination-helpers.js.txt +0 -560
- package/audit/evidence/code/critical-pass1/json-rest-api__plugins__core__lib__querying__knex-process-includes.js.txt +0 -167
- package/audit/evidence/code/critical-pass1/json-rest-api__plugins__core__lib__querying__knex-query-helpers-base.js.txt +0 -109
- package/audit/evidence/code/critical-pass1/json-rest-api__plugins__core__lib__querying__knex-query-helpers.js.txt +0 -1064
- package/audit/evidence/code/critical-pass1/json-rest-api__plugins__core__lib__querying__knex-relationship-includes.js.txt +0 -1983
- package/audit/evidence/code/critical-pass1/json-rest-api__plugins__core__lib__querying__knex-window-queries.js.txt +0 -328
- package/audit/evidence/code/critical-pass1/json-rest-api__plugins__core__lib__querying__url-helpers.js.txt +0 -119
- package/audit/evidence/code/critical-pass1/json-rest-api__plugins__core__lib__storage__storage-adapter.js.txt +0 -160
- package/audit/evidence/code/critical-pass1/json-rest-api__plugins__core__lib__writing__many-to-many-manipulations.js.txt +0 -300
- package/audit/evidence/code/critical-pass1/json-rest-api__plugins__core__lib__writing__relationship-processor.js.txt +0 -245
- package/audit/evidence/code/critical-pass1/json-rest-api__plugins__core__rest-api-access.js.txt +0 -459
- package/audit/evidence/code/critical-pass1/json-rest-api__plugins__core__rest-api-cors-plugin.js.txt +0 -237
- package/audit/evidence/code/critical-pass1/json-rest-api__plugins__core__rest-api-knex-plugin.js.txt +0 -1135
- package/audit/evidence/code/critical-pass1/json-rest-api__plugins__core__rest-api-multihome-plugin.js.txt +0 -314
- package/audit/evidence/code/critical-pass1/json-rest-api__plugins__core__rest-api-plugin-hooks__compile-resource-schemas.js.txt +0 -7
- package/audit/evidence/code/critical-pass1/json-rest-api__plugins__core__rest-api-plugin-hooks__register-relationship-routes.js.txt +0 -71
- package/audit/evidence/code/critical-pass1/json-rest-api__plugins__core__rest-api-plugin-hooks__register-scope-routes.js.txt +0 -102
- package/audit/evidence/code/critical-pass1/json-rest-api__plugins__core__rest-api-plugin-hooks__turn-scope-init-into-vars.js.txt +0 -49
- package/audit/evidence/code/critical-pass1/json-rest-api__plugins__core__rest-api-plugin-hooks__validate-include-configurations.js.txt +0 -39
- package/audit/evidence/code/critical-pass1/json-rest-api__plugins__core__rest-api-plugin-methods__add-route.js.txt +0 -23
- package/audit/evidence/code/critical-pass1/json-rest-api__plugins__core__rest-api-plugin-methods__check-permissions.js.txt +0 -13
- package/audit/evidence/code/critical-pass1/json-rest-api__plugins__core__rest-api-plugin-methods__common.js.txt +0 -639
- package/audit/evidence/code/critical-pass1/json-rest-api__plugins__core__rest-api-plugin-methods__delete-relationship.js.txt +0 -117
- package/audit/evidence/code/critical-pass1/json-rest-api__plugins__core__rest-api-plugin-methods__delete.js.txt +0 -104
- package/audit/evidence/code/critical-pass1/json-rest-api__plugins__core__rest-api-plugin-methods__enrich-attributes.js.txt +0 -199
- package/audit/evidence/code/critical-pass1/json-rest-api__plugins__core__rest-api-plugin-methods__get-related.js.txt +0 -353
- package/audit/evidence/code/critical-pass1/json-rest-api__plugins__core__rest-api-plugin-methods__get-relationship.js.txt +0 -61
- package/audit/evidence/code/critical-pass1/json-rest-api__plugins__core__rest-api-plugin-methods__get.js.txt +0 -184
- package/audit/evidence/code/critical-pass1/json-rest-api__plugins__core__rest-api-plugin-methods__patch-relationship.js.txt +0 -55
- package/audit/evidence/code/critical-pass1/json-rest-api__plugins__core__rest-api-plugin-methods__patch.js.txt +0 -191
- package/audit/evidence/code/critical-pass1/json-rest-api__plugins__core__rest-api-plugin-methods__post-relationship.js.txt +0 -110
- package/audit/evidence/code/critical-pass1/json-rest-api__plugins__core__rest-api-plugin-methods__post.js.txt +0 -168
- package/audit/evidence/code/critical-pass1/json-rest-api__plugins__core__rest-api-plugin-methods__put.js.txt +0 -253
- package/audit/evidence/code/critical-pass1/json-rest-api__plugins__core__rest-api-plugin-methods__query.js.txt +0 -207
- package/audit/evidence/code/critical-pass1/json-rest-api__plugins__core__rest-api-plugin-methods__release.js.txt +0 -12
- package/audit/evidence/code/critical-pass1/json-rest-api__plugins__core__rest-api-plugin.js.txt +0 -165
- package/audit/evidence/code/critical-pass1/json-rest-api__plugins__core__rest-api-positioning-plugin.js.txt +0 -668
- package/audit/evidence/code/critical-pass1/json-rest-api__plugins__core__socketio-plugin.js.txt +0 -621
- package/audit/evidence/code/critical-pass1/json-rest-api__plugins__storage__local-storage.js.txt +0 -218
- package/audit/evidence/code/critical-pass1/json-rest-api__plugins__storage__s3-storage.js.txt +0 -124
- package/audit/evidence/code/critical-pass1/json-rest-schema__src__CorePlugin.js.txt +0 -269
- package/audit/evidence/code/critical-pass1/json-rest-schema__src__Schema.js.txt +0 -242
- package/audit/evidence/code/critical-pass1/json-rest-schema__src__index.js.txt +0 -77
- package/audit/evidence/code/critical-pass1-risk-keywords.txt +0 -238
- package/audit/evidence/code/critical-pass1-summary.csv +0 -67
- package/audit/evidence/code/critical-pass2-summary.csv +0 -67
- package/audit/evidence/code/early-silent-zones-no-test-token.txt +0 -57
- package/audit/evidence/code/error-model-signals.txt +0 -98
- package/audit/evidence/code/git-files-json-rest-api.txt +0 -171
- package/audit/evidence/code/git-files-json-rest-schema.txt +0 -27
- package/audit/evidence/code/hook-flow-signals.txt +0 -282
- package/audit/evidence/code/idproperty-signals.txt +0 -157
- package/audit/evidence/code/import-cycles-non-anyapi.txt +0 -3
- package/audit/evidence/code/import-hotspots-non-anyapi.txt +0 -96
- package/audit/evidence/code/imports-json-rest-api.txt +0 -354
- package/audit/evidence/code/imports-json-rest-schema.txt +0 -15
- package/audit/evidence/code/in-scope-files-json-rest-api.txt +0 -160
- package/audit/evidence/code/in-scope-files-json-rest-schema.txt +0 -13
- package/audit/evidence/code/non-anyapi-core-files.txt +0 -101
- package/audit/evidence/code/permission-signals.txt +0 -193
- package/audit/evidence/code/query-include-signals.txt +0 -687
- package/audit/evidence/code/transaction-signals.txt +0 -28
- package/audit/evidence/code/validation-signals.txt +0 -650
- package/audit/evidence/code/write-path-signals.txt +0 -61
- package/audit/evidence/docs/docs-claims-signals.txt +0 -1075
- package/audit/evidence/docs/schema-docs-claims-signals.txt +0 -179
- package/audit/evidence/external/corpus-freeze.md +0 -21
- package/audit/evidence/external/npm-competitor-metadata.txt +0 -70
- package/audit/evidence/external/npm-download-signals.txt +0 -23
- package/audit/evidence/external/npm-jsonapi-server.txt +0 -8
- package/audit/evidence/external/npm-modern-jsonapi-metadata.txt +0 -38
- package/audit/evidence/external/readme-fortune-signals.txt +0 -26
- package/audit/evidence/external/readme-fortune.md +0 -165
- package/audit/evidence/external/readme-json-api-serializer-signals.txt +0 -80
- package/audit/evidence/external/readme-json-api-serializer.md +0 -690
- package/audit/evidence/external/readme-jsonapi-serde-server-signals.txt +0 -0
- package/audit/evidence/external/readme-jsonapi-serde-server.md +0 -22
- package/audit/evidence/external/readme-jsonapi-serializer-signals.txt +0 -63
- package/audit/evidence/external/readme-jsonapi-serializer.md +0 -315
- package/audit/evidence/external/readme-jsonapi-server-signals.txt +0 -19
- package/audit/evidence/external/readme-jsonapi-server.md +0 -104
- package/audit/evidence/external/readme-nestjs-json-api-signals.txt +0 -4
- package/audit/evidence/external/readme-nestjs-json-api.md +0 -94
- package/audit/evidence/external/readme-yaser-json-api-nestjs-signals.txt +0 -47
- package/audit/evidence/external/readme-yaser-json-api-nestjs.md +0 -447
- package/audit/evidence/external/standard-jsonapi-snippets.txt +0 -84
- package/audit/evidence/external/standard-rfc-snippets.txt +0 -168
- package/audit/evidence/external/standards-sources.txt +0 -6
- package/audit/evidence/runtime/baseline-commits.txt +0 -2
- package/audit/evidence/runtime/db-adapter-assumptions.txt +0 -3
- package/audit/evidence/runtime/environment.txt +0 -4
- package/audit/evidence/runtime/invariant-runtime-mapping.md +0 -38
- package/audit/evidence/runtime/probe-patch-relationship-error.exitcode +0 -1
- package/audit/evidence/runtime/probe-patch-relationship-error.log +0 -76
- package/audit/evidence/runtime/probe-patch-relationship-error.mjs +0 -67
- package/audit/evidence/runtime/probe-patch-relationship-referenceerror.exitcode +0 -1
- package/audit/evidence/runtime/probe-patch-relationship-referenceerror.log +0 -62
- package/audit/evidence/runtime/probe-patch-relationship-referenceerror.mjs +0 -47
- package/audit/evidence/runtime/test-exitcodes.txt +0 -4
- package/audit/evidence/runtime/test-summary.md +0 -107
- package/audit/evidence/runtime/trace-anchors.txt +0 -61
- package/audit/evidence/tests/access-multitenancy-test-signals.txt +0 -125
- package/audit/evidence/tests/failing-tests-summary.txt +0 -25
- package/audit/evidence/tests/npm-test-json-rest-api.exitcode +0 -1
- package/audit/evidence/tests/npm-test-json-rest-api.log +0 -5885
- package/audit/evidence/tests/npm-test-json-rest-schema.exitcode +0 -1
- package/audit/evidence/tests/npm-test-json-rest-schema.log +0 -356
- package/audit/evidence/tests/query-include-test-signals.txt +0 -948
- package/audit/evidence/tests/relationship-test-signals.txt +0 -223
- package/audit/evidence/tests/skipped-tests.txt +0 -10
- package/audit/evidence/tests/test-suite-list-non-anyapi.txt +0 -30
- package/audit/evidence/tests/test-suite-list.txt +0 -32
- package/audit/subsystems/docs-drift.md +0 -49
- package/audit/subsystems/pass2-cross-review.md +0 -131
- package/audit/subsystems/plugins-access.md +0 -51
- package/audit/subsystems/plugins-bulk.md +0 -50
- package/audit/subsystems/plugins-cors.md +0 -48
- package/audit/subsystems/plugins-file.md +0 -53
- package/audit/subsystems/plugins-multihome.md +0 -50
- package/audit/subsystems/plugins-positioning.md +0 -54
- package/audit/subsystems/plugins-socketio.md +0 -50
- package/audit/subsystems/query-engine.md +0 -61
- package/audit/subsystems/relationships.md +0 -55
- package/audit/subsystems/rest-orchestration.md +0 -66
- package/audit/subsystems/schema-core.md +0 -64
- package/audit/subsystems/storage-knex.md +0 -57
- package/audit/subsystems/tests.md +0 -48
- package/audit/subsystems/transport-express.md +0 -55
- package/audit/traces/trace-read-get.md +0 -22
- package/audit/traces/trace-read-query.md +0 -25
- package/audit/traces/trace-relationship-endpoints.md +0 -31
- package/audit/traces/trace-write-delete.md +0 -17
- package/audit/traces/trace-write-patch.md +0 -26
- package/audit/traces/trace-write-post.md +0 -22
- package/audit/traces/trace-write-put.md +0 -23
- package/docs/GUIDE/GUIDE_4_Authentication_And_Permissions.md +0 -707
- package/docs/GUIDE/GUIDE_X_Multihome.md +0 -666
- package/plugins/core/lib/querying-writing/payload-validators.js +0 -1314
- package/plugins/core/rest-api-access.js +0 -459
- package/plugins/core/rest-api-multihome-plugin.js +0 -314
- package/tests/multihome.test.js +0 -553
- package/tests/multihome.test.js.bak +0 -550
- package/tests/ownership-optout.test.js +0 -76
- package/tests/rest-api-access.test.js +0 -206
package/CLAUDE.md
CHANGED
|
@@ -71,7 +71,7 @@ This separation ensures backend developers have full control and visibility into
|
|
|
71
71
|
- `url-helpers.js` - Centralized URL generation functions
|
|
72
72
|
- `knex-json-api-transformers-querying.js` - JSON:API transformations
|
|
73
73
|
- `relationship-processor.js` - Handles relationship updates
|
|
74
|
-
- `
|
|
74
|
+
- `request-contracts.js` - Compiled request validation contracts
|
|
75
75
|
- `knex-query-helpers.js` - Database query building
|
|
76
76
|
- `simplified-helpers.js` - Simplified API mode transformations
|
|
77
77
|
|
|
@@ -158,4 +158,3 @@ const book = await api.resources.books.post({
|
|
|
158
158
|
3. **ID Type Confusion**: SQLite returns numeric IDs, but JSON:API expects strings
|
|
159
159
|
4. **Context Placement**: Context is a separate parameter, not inside the first parameter
|
|
160
160
|
5. **Cleanup**: Always destroy knex connection in `after()` hook
|
|
161
|
-
|
|
@@ -0,0 +1,180 @@
|
|
|
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
|
+
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
Single Validation Contract TODO
|
|
2
|
+
|
|
3
|
+
Goal
|
|
4
|
+
- Make `json-rest-schema` the single authored validation contract in `json-rest-api`.
|
|
5
|
+
- Keep plain JSON Schema only as a derived transport artifact for connectors.
|
|
6
|
+
- Remove the split between:
|
|
7
|
+
- resource/search validation via `json-rest-schema`
|
|
8
|
+
- hand-written JSON:API/query validators in `plugins/core/lib/querying-writing/payload-validators.js`
|
|
9
|
+
|
|
10
|
+
Current audit status
|
|
11
|
+
- [done] Audit the live validation paths and identify the actual indirection.
|
|
12
|
+
|
|
13
|
+
Root cause
|
|
14
|
+
- Validation is split across three places:
|
|
15
|
+
1. `plugins/core/lib/querying-writing/compile-schemas.js`
|
|
16
|
+
- compiles resource and search schemas with `createSchema(...)`
|
|
17
|
+
2. `plugins/core/lib/querying-writing/payload-validators.js`
|
|
18
|
+
- manually validates JSON:API request envelopes and query parameter objects
|
|
19
|
+
3. `plugins/core/connectors/lib/transport-route-schemas.js`
|
|
20
|
+
- separately builds connector-facing JSON Schemas from `schemaInfo`
|
|
21
|
+
- This duplicates contract meaning across runtime and transport.
|
|
22
|
+
- Route methods still call imperative payload validators before calling
|
|
23
|
+
`schemaInstance.create()`, `schemaInstance.replace()`, or `schemaInstance.patch()`.
|
|
24
|
+
- `setupCommonRequest()` in `plugins/core/rest-api-plugin-methods/common.js`
|
|
25
|
+
also repeats some checks that are already transport-contract concerns.
|
|
26
|
+
|
|
27
|
+
What the neat end state looks like
|
|
28
|
+
- Authored contract:
|
|
29
|
+
- `json-rest-schema` only
|
|
30
|
+
- Derived transport schema:
|
|
31
|
+
- plain JSON Schema, generated from the same compiled contract
|
|
32
|
+
- Runtime write validation:
|
|
33
|
+
- uses the same compiled contract as Fastify pre-validation
|
|
34
|
+
- Remaining imperative checks:
|
|
35
|
+
- only stateful/business checks that are not schema concerns
|
|
36
|
+
- examples: permission checks, record existence, relationship access, complete-replace semantics
|
|
37
|
+
|
|
38
|
+
What should stay imperative
|
|
39
|
+
- `validateRelationshipAccess()` in `plugins/core/rest-api-plugin-methods/common.js`
|
|
40
|
+
- `validateCompleteReplacePayload()` in `plugins/core/rest-api-plugin-methods/common.js`
|
|
41
|
+
- path/body cross-source checks such as URL id vs body id consistency
|
|
42
|
+
- permission and data existence checks
|
|
43
|
+
|
|
44
|
+
What should stop existing
|
|
45
|
+
- `validateGetPayload()`
|
|
46
|
+
- `validateQueryPayload()`
|
|
47
|
+
- `validatePostPayload()`
|
|
48
|
+
- `validatePutPayload()`
|
|
49
|
+
- `validatePatchPayload()`
|
|
50
|
+
- duplicate route/body/query syntax checks spread across route methods and `setupCommonRequest()`
|
|
51
|
+
|
|
52
|
+
Work list
|
|
53
|
+
|
|
54
|
+
1. [done] Define one compiled request-contract surface for resource `get/query/post/put/patch`.
|
|
55
|
+
Target files:
|
|
56
|
+
- `plugins/core/lib/querying-writing/compile-schemas.js`
|
|
57
|
+
- `plugins/core/connectors/lib/transport-route-schemas.js`
|
|
58
|
+
Deliverables:
|
|
59
|
+
- compile request contracts once per scope
|
|
60
|
+
- store them on `scope.vars.schemaInfo` or an adjacent compiled-contract object
|
|
61
|
+
- separate:
|
|
62
|
+
- write document contracts (`post`, `put`, `patch`)
|
|
63
|
+
- query/get contracts (`get`, `query`)
|
|
64
|
+
- relationship route contracts
|
|
65
|
+
Status:
|
|
66
|
+
- resource route contracts now compile once in `request-contracts.js`
|
|
67
|
+
- relationship route contracts are still separate and remain pending work
|
|
68
|
+
|
|
69
|
+
2. [done] Replace manual write-document validation with compiled schema contracts.
|
|
70
|
+
Target files:
|
|
71
|
+
- `plugins/core/lib/querying-writing/payload-validators.js`
|
|
72
|
+
- `plugins/core/rest-api-plugin-methods/post.js`
|
|
73
|
+
- `plugins/core/rest-api-plugin-methods/put.js`
|
|
74
|
+
- `plugins/core/rest-api-plugin-methods/patch.js`
|
|
75
|
+
Deliverables:
|
|
76
|
+
- one compiled JSON:API document contract per write mode
|
|
77
|
+
- `data.type` constrained to the scope name inside the contract
|
|
78
|
+
- `data.id` required/optional according to mode
|
|
79
|
+
- `attributes` contract derived from `schemaInstance.toJsonSchema({ mode })`
|
|
80
|
+
- relationship identifier contracts derived from `schemaRelationships` and `belongsTo` metadata
|
|
81
|
+
- `included` rules expressed once in the contract rather than repeated manually
|
|
82
|
+
|
|
83
|
+
3. [done] Replace manual GET/query parameter validation with compiled schema contracts.
|
|
84
|
+
Target files:
|
|
85
|
+
- `plugins/core/lib/querying-writing/payload-validators.js`
|
|
86
|
+
- `plugins/core/rest-api-plugin-methods/get.js`
|
|
87
|
+
- `plugins/core/rest-api-plugin-methods/query.js`
|
|
88
|
+
Deliverables:
|
|
89
|
+
- a compiled `get` contract for:
|
|
90
|
+
- `id`
|
|
91
|
+
- `queryParams.include`
|
|
92
|
+
- `queryParams.fields`
|
|
93
|
+
- a compiled `query` contract for:
|
|
94
|
+
- `include`
|
|
95
|
+
- `fields`
|
|
96
|
+
- `filters`
|
|
97
|
+
- `sort`
|
|
98
|
+
- `page`
|
|
99
|
+
- include-depth validation and sortable-field restrictions represented in the compiled contract, not duplicated in ad hoc code
|
|
100
|
+
Notes:
|
|
101
|
+
- `searchSchemaInstance` should remain the value contract for `filters`
|
|
102
|
+
- the query contract should validate the envelope/shape, not duplicate filter semantics
|
|
103
|
+
|
|
104
|
+
4. [done] Collapse Fastify pre-validation and in-process validation onto the same source for resource write routes.
|
|
105
|
+
Target files:
|
|
106
|
+
- `plugins/core/connectors/lib/transport-route-schemas.js`
|
|
107
|
+
- `plugins/core/connectors/fastify-plugin.js`
|
|
108
|
+
- route methods in `plugins/core/rest-api-plugin-methods/`
|
|
109
|
+
Deliverables:
|
|
110
|
+
- Fastify consumes transport JSON Schema exported from the compiled request contract
|
|
111
|
+
- route methods consume the same compiled contract directly for runtime validation
|
|
112
|
+
- no second hand-written envelope contract path
|
|
113
|
+
|
|
114
|
+
5. [done] Shrink `setupCommonRequest()` to non-schema responsibilities.
|
|
115
|
+
Target file:
|
|
116
|
+
- `plugins/core/rest-api-plugin-methods/common.js`
|
|
117
|
+
Deliverables:
|
|
118
|
+
- keep simplified-mode conversion, transaction setup, context wiring
|
|
119
|
+
- keep stateful/business checks only
|
|
120
|
+
- remove syntax/envelope checks that belong in the compiled contract
|
|
121
|
+
- keep only cross-input checks that a single schema cannot express cleanly
|
|
122
|
+
|
|
123
|
+
6. [done] Delete `payload-validators.js`.
|
|
124
|
+
Target file:
|
|
125
|
+
- `plugins/core/lib/querying-writing/payload-validators.js`
|
|
126
|
+
Deliverables:
|
|
127
|
+
- no route method imports it anymore
|
|
128
|
+
- helper logic worth keeping is either:
|
|
129
|
+
- absorbed into compiled contracts
|
|
130
|
+
- or moved into narrowly named stateful helpers
|
|
131
|
+
|
|
132
|
+
7. [done] Tighten tests around the single-contract flow.
|
|
133
|
+
Target areas:
|
|
134
|
+
- `tests/fastify-plugin.test.js`
|
|
135
|
+
- route method coverage exercised by the existing REST suites
|
|
136
|
+
- add one focused contract test suite if needed
|
|
137
|
+
Deliverables:
|
|
138
|
+
- prove Fastify pre-validation and runtime validation reject the same bad inputs
|
|
139
|
+
- cover:
|
|
140
|
+
- wrong `data.type`
|
|
141
|
+
- missing/invalid `data.id`
|
|
142
|
+
- invalid relationships
|
|
143
|
+
- invalid query/include/page/sort shapes
|
|
144
|
+
- verify there is no drift between transport schema and runtime schema behavior
|
|
145
|
+
|
|
146
|
+
8. [done] Proof cleanup.
|
|
147
|
+
Deliverables:
|
|
148
|
+
- `rg` proof that route methods no longer import `payload-validators.js`
|
|
149
|
+
- `rg` proof that `validateGetPayload`, `validateQueryPayload`, `validatePostPayload`,
|
|
150
|
+
`validatePutPayload`, and `validatePatchPayload` are gone
|
|
151
|
+
- `npm test`
|
|
152
|
+
|
|
153
|
+
Current state
|
|
154
|
+
- Resource `get/query/post/put/patch` now use one compiled contract source.
|
|
155
|
+
- Fastify transport schemas for those resource routes are derived from the same compiled contract.
|
|
156
|
+
- `payload-validators.js` is deleted.
|
|
157
|
+
- `npm test` passes.
|
|
158
|
+
- The main remaining simplification is the separate relationship-route contract path.
|
|
159
|
+
|
|
160
|
+
File map for the next implementation pass
|
|
161
|
+
- Remaining relationship-route cleanup:
|
|
162
|
+
- `plugins/core/rest-api-plugin-methods/post-relationship.js`
|
|
163
|
+
- `plugins/core/rest-api-plugin-methods/patch-relationship.js`
|
|
164
|
+
- `plugins/core/rest-api-plugin-methods/delete-relationship.js`
|
|
165
|
+
- Transport schema generator to reuse, not duplicate:
|
|
166
|
+
- `plugins/core/connectors/lib/transport-route-schemas.js`
|
|
167
|
+
|
|
168
|
+
Explicit non-goals
|
|
169
|
+
- Do not move permission checks into schemas.
|
|
170
|
+
- Do not move DB existence checks into schemas.
|
|
171
|
+
- Do not turn `searchSchema` into a generic filter DSL.
|
|
172
|
+
- Do not add a compatibility layer that preserves both manual validators and compiled contracts.
|
package/docs/API.md
CHANGED
|
@@ -4,13 +4,15 @@ This reference provides comprehensive documentation for all methods, parameters,
|
|
|
4
4
|
|
|
5
5
|
## Important Notes
|
|
6
6
|
|
|
7
|
-
1. **Context Parameter**: The `context` parameter shown in method signatures is typically managed internally by the framework. When using the API programmatically, you usually don't need to provide it unless you're implementing custom
|
|
7
|
+
1. **Context Parameter**: The `context` parameter shown in method signatures is typically managed internally by the framework. When using the API programmatically, you usually don't need to provide it unless you're implementing custom request identity/auth context or other request-specific data.
|
|
8
8
|
|
|
9
|
-
2. **
|
|
9
|
+
2. **App-Owned Auth Context**: `json-rest-api` does not define authentication semantics. If you use `context.auth` in hooks, treat it as application-owned data supplied by your transport or surrounding stack.
|
|
10
|
+
|
|
11
|
+
3. **Simplified Mode Defaults**:
|
|
10
12
|
- `simplifiedApi`: `true` (default for programmatic API calls)
|
|
11
13
|
- `simplifiedTransport`: `false` (default for HTTP transport)
|
|
12
14
|
|
|
13
|
-
|
|
15
|
+
4. **All parameters must be passed within a single params object** as the first argument to each method.
|
|
14
16
|
|
|
15
17
|
## Table of Contents
|
|
16
18
|
|
|
@@ -1400,7 +1402,7 @@ Each API method has its own specific hook execution order. Here's the exact sequ
|
|
|
1400
1402
|
|
|
1401
1403
|
1. **Processing Hooks**: Only POST, PUT, and PATCH have `beforeProcessing` hooks
|
|
1402
1404
|
2. **Schema Validation**: Only POST, PUT, and PATCH have schema validation hooks
|
|
1403
|
-
3. **Permission
|
|
1405
|
+
3. **Permission Hooks**: GET uses `checkDataPermissions`, while relationship methods use `checkPermissions`
|
|
1404
1406
|
4. **Query Filtering**: Only QUERY method triggers `knexQueryFiltering` hooks
|
|
1405
1407
|
5. **Enrichment**: Only GET and QUERY have `enrichRecord` hooks
|
|
1406
1408
|
6. **Relationships**: Only GET has `enrichRecordWithRelationships`
|
|
@@ -1421,7 +1423,7 @@ Each hook receives a context object with different properties based on the hook
|
|
|
1421
1423
|
queryParams: {...},
|
|
1422
1424
|
simplified: true
|
|
1423
1425
|
},
|
|
1424
|
-
auth: {...}, //
|
|
1426
|
+
auth: {...}, // App-provided auth/identity context if present
|
|
1425
1427
|
transaction: {...}, // Database transaction
|
|
1426
1428
|
schemaInfo: {...}, // Resource schema
|
|
1427
1429
|
db: {...} // Database connection
|
|
@@ -1490,7 +1492,7 @@ api.resource('articles').hook('afterSchemaValidate', async (context) => {
|
|
|
1490
1492
|
}
|
|
1491
1493
|
```
|
|
1492
1494
|
|
|
1493
|
-
**Purpose:**
|
|
1495
|
+
**Purpose:** Permission or visibility checks implemented by your app hooks. Throw an error to deny the operation.
|
|
1494
1496
|
|
|
1495
1497
|
**Example:**
|
|
1496
1498
|
```javascript
|
|
@@ -2243,13 +2245,9 @@ api.addResource({
|
|
|
2243
2245
|
}
|
|
2244
2246
|
},
|
|
2245
2247
|
|
|
2246
|
-
//
|
|
2247
|
-
|
|
2248
|
-
|
|
2249
|
-
read: ['*'],
|
|
2250
|
-
update: ['author', 'editor', 'admin'],
|
|
2251
|
-
delete: ['admin']
|
|
2252
|
-
},
|
|
2248
|
+
// No built-in permissions option exists here.
|
|
2249
|
+
// Use permission hooks for access decisions, and optional plugins
|
|
2250
|
+
// such as AutoFilterPlugin for dataset scoping.
|
|
2253
2251
|
|
|
2254
2252
|
// Soft delete configuration
|
|
2255
2253
|
softDelete: {
|
|
@@ -2499,6 +2497,45 @@ try {
|
|
|
2499
2497
|
|
|
2500
2498
|
**Important:** When you provide a transaction, you're responsible for committing/rolling back. When you don't provide one, the library auto-commits.
|
|
2501
2499
|
|
|
2500
|
+
### Knex Schema Helpers
|
|
2501
|
+
|
|
2502
|
+
When a resource is backed by `RestApiKnexPlugin`, its scope also exposes table-management helpers:
|
|
2503
|
+
|
|
2504
|
+
```javascript
|
|
2505
|
+
await api.resources.articles.createKnexTable()
|
|
2506
|
+
|
|
2507
|
+
const snapshot = await api.resources.articles.introspectKnexTableSnapshot()
|
|
2508
|
+
const createMigration = await api.resources.articles.generateKnexMigration()
|
|
2509
|
+
const diff = await api.resources.articles.generateKnexMigrationDiff()
|
|
2510
|
+
```
|
|
2511
|
+
|
|
2512
|
+
Available helpers:
|
|
2513
|
+
|
|
2514
|
+
- `createKnexTable()`
|
|
2515
|
+
- `addKnexFields({ fields })`
|
|
2516
|
+
- `alterKnexFields({ fields })`
|
|
2517
|
+
- `introspectKnexTableSnapshot()`
|
|
2518
|
+
- `generateKnexMigration()`
|
|
2519
|
+
- `generateKnexMigrationDiff()`
|
|
2520
|
+
|
|
2521
|
+
`generateKnexMigrationDiff()` returns:
|
|
2522
|
+
|
|
2523
|
+
```javascript
|
|
2524
|
+
{
|
|
2525
|
+
migration,
|
|
2526
|
+
warnings,
|
|
2527
|
+
plan
|
|
2528
|
+
}
|
|
2529
|
+
```
|
|
2530
|
+
|
|
2531
|
+
Important boundaries:
|
|
2532
|
+
|
|
2533
|
+
- this is a live-table snapshot diff, not migration-history reconstruction
|
|
2534
|
+
- `addKnexFields()` and `alterKnexFields()` are field-only helpers
|
|
2535
|
+
- indexes, foreign keys, and check constraints belong on the full table schema surface
|
|
2536
|
+
|
|
2537
|
+
For full examples and dialect notes, see [Knex Schema and Migrations](GUIDE/GUIDE_X_Knex_Schema_And_Migrations.md).
|
|
2538
|
+
|
|
2502
2539
|
### Batch Operations
|
|
2503
2540
|
|
|
2504
2541
|
Process multiple operations efficiently:
|
|
@@ -2746,4 +2783,4 @@ api.resource('articles').hook('knexQueryFiltering', async (context) => {
|
|
|
2746
2783
|
query.whereRaw("metadata->>'key' = ?", [filters.metadata_key]);
|
|
2747
2784
|
}
|
|
2748
2785
|
});
|
|
2749
|
-
```
|
|
2786
|
+
```
|
package/docs/COMPARISON.md
CHANGED
|
@@ -30,7 +30,7 @@ json-rest-api is a full-featured, plugin-based JSON:API implementation built on
|
|
|
30
30
|
| WebSocket support | ✅ | ❌ | ❌ | ❌ | ❌ |
|
|
31
31
|
| Bulk operations | ✅ | ❌ | ❌ | ❌ | ❌ |
|
|
32
32
|
| Positioning/sorting | ✅ | ❌ | ❌ | ❌ | ❌ |
|
|
33
|
-
|
|
|
33
|
+
| Permission hooks / app-owned auth integration | ✅ | ❌ | ⚠️ | ❌ | ❌ |
|
|
34
34
|
| **Developer Experience** |
|
|
35
35
|
| TypeScript support | ✅ | ✅ | ✅ | ❌ | ❌ |
|
|
36
36
|
| Active maintenance | ✅ (2025) | ✅ (2024) | ✅ (2024) | 🟡 (2022) | ❌ (2022) |
|
|
@@ -430,4 +430,4 @@ json-rest-api stands out as the most comprehensive JSON:API solution for Node.js
|
|
|
430
430
|
4. **Active Development**: Regular updates and community support
|
|
431
431
|
5. **Production Ready**: Battle-tested with extensive test coverage
|
|
432
432
|
|
|
433
|
-
For teams building JSON:API services in 2025, json-rest-api offers the best combination of compliance, features, and developer experience.
|
|
433
|
+
For teams building JSON:API services in 2025, json-rest-api offers the best combination of compliance, features, and developer experience.
|
|
@@ -928,6 +928,32 @@ Each resource (added via `api.addResource()`) gets these methods automatically:
|
|
|
928
928
|
await api.resources.countries.createKnexTable();
|
|
929
929
|
```
|
|
930
930
|
|
|
931
|
+
- **`api.resources.{resourceName}.introspectKnexTableSnapshot()`** - Returns a normalized snapshot of the live physical table
|
|
932
|
+
```javascript
|
|
933
|
+
const snapshot = await api.resources.countries.introspectKnexTableSnapshot();
|
|
934
|
+
```
|
|
935
|
+
|
|
936
|
+
- **`api.resources.{resourceName}.generateKnexMigration()`** - Generates a Knex create migration string for the resource
|
|
937
|
+
```javascript
|
|
938
|
+
const migration = await api.resources.countries.generateKnexMigration();
|
|
939
|
+
```
|
|
940
|
+
|
|
941
|
+
- **`api.resources.{resourceName}.generateKnexMigrationDiff()`** - Generates an additive diff migration from the live table snapshot
|
|
942
|
+
```javascript
|
|
943
|
+
const diff = await api.resources.countries.generateKnexMigrationDiff();
|
|
944
|
+
```
|
|
945
|
+
|
|
946
|
+
- **`api.resources.{resourceName}.addKnexFields({ fields })`** / **`alterKnexFields({ fields })`** - Column-only helpers for existing tables
|
|
947
|
+
```javascript
|
|
948
|
+
await api.resources.countries.addKnexFields({
|
|
949
|
+
fields: {
|
|
950
|
+
iso3: { type: 'string', maxLength: 3 }
|
|
951
|
+
}
|
|
952
|
+
});
|
|
953
|
+
```
|
|
954
|
+
|
|
955
|
+
For full examples of snapshots, migration generation, diffing, and table metadata such as indexes / foreign keys / checks, see [Knex Schema and Migrations](GUIDE_X_Knex_Schema_And_Migrations.md).
|
|
956
|
+
|
|
931
957
|
|
|
932
958
|
## API Namespaces (internal, for plugin developers)
|
|
933
959
|
|
|
@@ -943,6 +969,7 @@ These helpers and methods provide a complete toolkit for:
|
|
|
943
969
|
- Managing database transactions
|
|
944
970
|
- Generating proper URLs and links
|
|
945
971
|
- Accessing the underlying database when needed
|
|
972
|
+
- Inspecting live tables and generating Knex migrations when using table-backed resources
|
|
946
973
|
- Integrating with web frameworks like Express
|
|
947
974
|
|
|
948
|
-
The architecture ensures clean separation between HTTP transport, business logic, and data persistence layers.
|
|
975
|
+
The architecture ensures clean separation between HTTP transport, business logic, and data persistence layers.
|
|
@@ -306,6 +306,10 @@ The `searchSchema` gives you:
|
|
|
306
306
|
* Flexibility to extend: Add virtual fields or complex filters via searchSchema while basic fields use `search: true`
|
|
307
307
|
* Best of both worlds: Explicit control for complex cases, automatic setup for simple ones
|
|
308
308
|
|
|
309
|
+
`searchSchema` also defines the public filter names your API accepts. Those keys do not need to match database columns or even resource field names. Treat `searchSchema` as an allowlist plus normalization layer for filter input: the actual meaning of each key is still implemented by the backend through mappings such as `actualField`, multi-field rules such as `oneOf`, standard operators, or custom `applyFilter` logic. It is not a portable filter DSL.
|
|
310
|
+
|
|
311
|
+
The merge rules and validation surface are shared across storage backends. Advanced execution semantics are still backend-owned. In practice, that means alias filters such as `oneOf` and custom `applyFilter` functions should be validated against the backend you actually run, and the SQL-heavy examples in this chapter assume the Knex-backed query layer.
|
|
312
|
+
|
|
309
313
|
`searchSchema` also gives you the ability to define a search field that will search in multiple fields. For example:
|
|
310
314
|
|
|
311
315
|
```javascript
|
|
@@ -801,4 +805,4 @@ GET /api/countries?filter[search]=united+states&fields[countries]=code
|
|
|
801
805
|
|
|
802
806
|
---
|
|
803
807
|
|
|
804
|
-
[Previous: 2.1 The starting point](./GUIDE_2_1_The_Starting_Point.md) | [Back to Guide](./README.md) | [Next: 2.3 `belongsTo` Relationships](./GUIDE_2_3_BelongsTo_Relationships.md)
|
|
808
|
+
[Previous: 2.1 The starting point](./GUIDE_2_1_The_Starting_Point.md) | [Back to Guide](./README.md) | [Next: 2.3 `belongsTo` Relationships](./GUIDE_2_3_BelongsTo_Relationships.md)
|
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
Pagination and ordering are essential features for working with large datasets. The json-rest-api library provides powerful pagination that applies not just to main resources, but also to included relationships. This means you can limit and order both parent records AND their children independently.
|
|
4
4
|
|
|
5
|
+
For derived fields that must participate in `ORDER BY` and cursor pagination, see [Query Projections](GUIDE_X_Query_Projections.md). Regular computed fields are response-layer only and are not the right tool for stable SQL ordering.
|
|
6
|
+
|
|
5
7
|
Let's create a comprehensive example with posts, comments, and tags to demonstrate all pagination and ordering features:
|
|
6
8
|
|
|
7
9
|
```javascript
|
|
@@ -1233,4 +1235,4 @@ The pagination and ordering system is designed to be efficient and predictable:
|
|
|
1233
1235
|
|
|
1234
1236
|
---
|
|
1235
1237
|
|
|
1236
|
-
[Previous: 2.6 Many to Many Relationships](./GUIDE_2_6_Many_To_Many.md) | [Back to Guide](./README.md)
|
|
1238
|
+
[Previous: 2.6 Many to Many Relationships](./GUIDE_2_6_Many_To_Many.md) | [Back to Guide](./README.md)
|