json-rest-api 1.0.29 → 2.1.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.
- package/LICENSE +10 -670
- package/LICENSE-GPL-3.0 +674 -0
- package/LICENSE-MIT +21 -0
- package/README.md +39 -30
- package/docs/API.md +744 -1273
- package/docs/GUIDE/01-getting-started.md +338 -0
- package/docs/GUIDE/02-resources-and-relationships.md +33 -0
- package/docs/GUIDE/03-running-example.md +87 -0
- package/docs/GUIDE/04-creating-and-querying.md +181 -0
- package/docs/GUIDE/05-belongs-to.md +177 -0
- package/docs/GUIDE/06-has-many.md +184 -0
- package/docs/GUIDE/07-polymorphic-relationships.md +191 -0
- package/docs/GUIDE/08-many-to-many.md +184 -0
- package/docs/GUIDE/09-pagination-and-sorting.md +149 -0
- package/docs/GUIDE/10-put-and-patch.md +174 -0
- package/docs/GUIDE/11-relationship-endpoints.md +174 -0
- package/docs/GUIDE/12-field-transformations.md +287 -0
- package/docs/GUIDE/13-hooks-and-lifecycle.md +479 -0
- package/docs/GUIDE/14-custom-resource-methods.md +125 -0
- package/docs/GUIDE/15-query-projections.md +266 -0
- package/docs/GUIDE/{GUIDE_X_Autofiltering.md → 16-autofiltering.md} +77 -15
- package/docs/GUIDE/{GUIDE_X_Row_Policies.md → 17-row-policies.md} +137 -44
- package/docs/GUIDE/18-labels.md +86 -0
- package/docs/GUIDE/19-managed-transactions.md +179 -0
- package/docs/GUIDE/20-transaction-outcomes.md +207 -0
- package/docs/GUIDE/21-schema-and-migrations.md +733 -0
- package/docs/GUIDE/22-version-field-migrations.md +208 -0
- package/docs/GUIDE/23-fastify.md +179 -0
- package/docs/GUIDE/24-cors.md +172 -0
- package/docs/GUIDE/{GUIDE_X_URL_Management.md → 25-url-management.md} +7 -1
- package/docs/GUIDE/26-file-uploads.md +278 -0
- package/docs/GUIDE/27-bulk-operations.md +277 -0
- package/docs/GUIDE/28-socketio.md +325 -0
- package/docs/GUIDE/29-writing-plugins.md +278 -0
- package/docs/GUIDE/30-backend-capabilities.md +103 -0
- package/docs/GUIDE/31-positioning.md +181 -0
- package/docs/GUIDE/{GUIDE_Y_Appendices.md → 32-date-and-time.md} +74 -30
- package/docs/GUIDE/33-migrating-to-v2.md +3838 -0
- package/docs/GUIDE/index.md +51 -59
- package/docs/QUICKSTART.md +120 -287
- package/docs/architecture.md +75 -0
- package/docs/contributing.md +178 -0
- package/index.d.ts +37 -0
- package/index.js +3 -22
- package/lib/enhanced-logger.js +91 -85
- package/lib/error-context.js +445 -5
- package/lib/error-formatter.js +219 -59
- package/lib/knex-transaction.js +70 -0
- package/lib/logger-types.d.ts +22 -0
- package/lib/missing-package.js +4 -0
- package/lib/rest-api-errors.js +103 -8
- package/lib/runtime/json-rest-api.js +172 -0
- package/lib/transaction-types.d.ts +59 -0
- package/package.json +97 -27
- package/plugins/core/bulk-operations-plugin.js +191 -184
- package/plugins/core/connectors/express-plugin.js +148 -219
- package/plugins/core/connectors/fastify-plugin.js +125 -82
- package/plugins/core/connectors/lib/busboy-detector.js +74 -156
- package/plugins/core/connectors/lib/connector-core.js +144 -20
- package/plugins/core/connectors/lib/formidable-detector.js +63 -120
- package/plugins/core/connectors/lib/http-validators.js +77 -0
- package/plugins/core/connectors/lib/multipart-helpers.js +18 -0
- package/plugins/core/connectors/lib/request-helpers.js +10 -1
- package/plugins/core/connectors/lib/transport-http-helpers.js +89 -8
- package/plugins/core/connectors/lib/transport-route-schemas.js +7 -4
- package/plugins/core/file-handling-plugin.js +87 -177
- package/plugins/core/lib/anyapi/anyapi-registry.js +586 -418
- package/plugins/core/lib/anyapi/canonical-link-store.js +507 -0
- package/plugins/core/lib/anyapi/canonical-relationship-reader.js +598 -0
- package/plugins/core/lib/anyapi/schema-utils.js +120 -56
- package/plugins/core/lib/anyapi/stored-definition.js +109 -0
- package/plugins/core/lib/anyapi/utils/descriptor-helpers.js +0 -64
- package/plugins/core/lib/dbIntrospection.js +228 -21
- package/plugins/core/lib/dbTablesOperations.js +409 -92
- package/plugins/core/lib/fractional-positioning.js +12 -48
- package/plugins/core/lib/querying/identifier-query.js +19 -0
- package/plugins/core/lib/querying/include-query-helpers.js +364 -0
- package/plugins/core/lib/querying/include-to-many.js +428 -0
- package/plugins/core/lib/querying/include-to-one.js +579 -0
- package/plugins/core/lib/querying/knex-cross-table-search.js +31 -307
- package/plugins/core/lib/querying/knex-json-api-transformers-querying.js +99 -401
- package/plugins/core/lib/querying/knex-pagination-helpers.js +48 -317
- package/plugins/core/lib/querying/knex-process-includes.js +5 -110
- package/plugins/core/lib/querying/knex-query-helpers-base.js +21 -56
- package/plugins/core/lib/querying/knex-query-helpers.js +298 -448
- package/plugins/core/lib/querying/knex-relationship-includes.js +120 -2138
- package/plugins/core/lib/querying/knex-window-queries.js +62 -253
- package/plugins/core/lib/querying/query-builder-utils.js +44 -4
- package/plugins/core/lib/querying/query-constraint.d.ts +12 -0
- package/plugins/core/lib/querying/query-constraint.js +27 -0
- package/plugins/core/lib/querying/query-field-sort-helpers.js +134 -37
- package/plugins/core/lib/querying/relationship-identifiers.js +208 -0
- package/plugins/core/lib/querying/sort-helpers.js +13 -1
- package/plugins/core/lib/querying/storage-adapter-utils.js +13 -5
- package/plugins/core/lib/querying/url-helpers.js +11 -4
- package/plugins/core/lib/querying-writing/compile-schemas.js +148 -249
- package/plugins/core/lib/querying-writing/connectors-query-parser.js +33 -118
- package/plugins/core/lib/querying-writing/database-capabilities.js +149 -223
- package/plugins/core/lib/querying-writing/database-value-normalizers.js +179 -194
- package/plugins/core/lib/querying-writing/default-data-helpers.js +15 -45
- package/plugins/core/lib/querying-writing/field-selection-types.d.ts +43 -0
- package/plugins/core/lib/querying-writing/field-utils.js +113 -92
- package/plugins/core/lib/querying-writing/knex-constants.d.ts +18 -0
- package/plugins/core/lib/querying-writing/knex-constants.js +2 -26
- package/plugins/core/lib/querying-writing/knex-field-helpers.js +100 -290
- package/plugins/core/lib/querying-writing/knex-json-api-transformers.js +31 -120
- package/plugins/core/lib/querying-writing/query-field-helpers.js +108 -32
- package/plugins/core/lib/querying-writing/query-field-types.d.ts +60 -0
- package/plugins/core/lib/querying-writing/relationship-contracts.js +33 -13
- package/plugins/core/lib/querying-writing/request-contracts.js +93 -38
- package/plugins/core/lib/querying-writing/resource-id-normalization.js +23 -5
- package/plugins/core/lib/querying-writing/response-options.js +35 -0
- package/plugins/core/lib/querying-writing/schema-helpers.js +203 -324
- package/plugins/core/lib/querying-writing/scope-validations.js +92 -290
- package/plugins/core/lib/querying-writing/simplified-helpers.js +113 -712
- package/plugins/core/lib/storage/canonical-data-helpers.js +683 -0
- package/plugins/core/lib/storage/canonical-storage-mapping.js +51 -20
- package/plugins/core/lib/storage/ordinary-data-helpers.js +710 -0
- package/plugins/core/lib/storage/storage-adapter.js +128 -62
- package/plugins/core/lib/storage/storage-mapping.js +78 -28
- package/plugins/core/lib/storage/storage-types.d.ts +502 -0
- package/plugins/core/lib/writing/many-to-many-manipulations.js +114 -284
- package/plugins/core/lib/writing/relationship-processor.js +94 -158
- package/plugins/core/lib/writing/resource-version.js +172 -0
- package/plugins/core/lib/writing/reverse-relationship-manipulations.js +110 -0
- package/plugins/core/rest-api-anyapi-knex-plugin.js +290 -2475
- package/plugins/core/rest-api-autofilter-plugin.js +17 -19
- package/plugins/core/rest-api-cors-plugin.js +52 -205
- package/plugins/core/rest-api-knex-plugin.js +45 -1077
- package/plugins/core/rest-api-label-plugin.js +25 -38
- package/plugins/core/rest-api-plugin-hooks/register-relationship-routes.js +5 -5
- package/plugins/core/rest-api-plugin-hooks/register-scope-routes.js +9 -6
- package/plugins/core/rest-api-plugin-hooks/turn-scope-init-into-vars.js +7 -26
- package/plugins/core/rest-api-plugin-hooks/validate-include-configurations.js +20 -26
- package/plugins/core/rest-api-plugin-methods/add-route.js +4 -6
- package/plugins/core/rest-api-plugin-methods/apply-query-filters.js +42 -13
- package/plugins/core/rest-api-plugin-methods/check-permissions.js +11 -5
- package/plugins/core/rest-api-plugin-methods/common.js +291 -395
- package/plugins/core/rest-api-plugin-methods/delete-relationship.js +49 -47
- package/plugins/core/rest-api-plugin-methods/delete.js +31 -25
- package/plugins/core/rest-api-plugin-methods/enrich-attributes.js +108 -148
- package/plugins/core/rest-api-plugin-methods/get-related.js +113 -305
- package/plugins/core/rest-api-plugin-methods/get-relationship.js +25 -18
- package/plugins/core/rest-api-plugin-methods/get.js +36 -68
- package/plugins/core/rest-api-plugin-methods/lifecycle-types.d.ts +225 -0
- package/plugins/core/rest-api-plugin-methods/patch-relationship.js +28 -25
- package/plugins/core/rest-api-plugin-methods/patch.js +46 -99
- package/plugins/core/rest-api-plugin-methods/post-relationship.js +49 -53
- package/plugins/core/rest-api-plugin-methods/post.js +51 -51
- package/plugins/core/rest-api-plugin-methods/put.js +69 -148
- package/plugins/core/rest-api-plugin-methods/query.js +37 -81
- package/plugins/core/rest-api-plugin-methods/release.js +2 -1
- package/plugins/core/rest-api-plugin.js +32 -46
- package/plugins/core/rest-api-positioning-plugin.js +183 -628
- package/plugins/core/rest-api-query-projections-plugin.js +19 -102
- package/plugins/core/rest-api-row-policy-plugin.js +3 -3
- package/plugins/core/socketio-plugin.js +364 -344
- package/plugins/storage/local-storage.js +40 -36
- package/types/anyapi.d.ts +30 -0
- package/types/autofilter.d.ts +57 -0
- package/types/bulk-methods.d.ts +63 -0
- package/types/errors.d.ts +118 -0
- package/types/fastify-options.d.ts +19 -0
- package/types/file-detectors.d.ts +33 -0
- package/types/file-storage.d.ts +48 -0
- package/types/hook-context.d.ts +180 -0
- package/types/plugin-options.d.ts +65 -0
- package/types/relationship-methods.d.ts +74 -0
- package/types/representations.d.ts +50 -0
- package/types/resource-methods.d.ts +95 -0
- package/types/resource-schema.d.ts +157 -0
- package/types/row-policy.d.ts +31 -0
- package/types/runtime.d.ts +132 -0
- package/types/transactions.d.ts +21 -0
- package/.claude/agents/library-guide-expert.md +0 -30
- package/.claude/agents/rest-api-internals-expert.md +0 -54
- package/.claude/settings.local.json +0 -70
- package/AGENTS.md +0 -34
- package/CLAUDE.md +0 -160
- package/CRUSH.md +0 -55
- package/JSKIT_BACKEND_MIGRATION_TRACKER.txt +0 -180
- package/SINGLE_VALIDATION_CONTRACT_TODO.txt +0 -172
- package/TODO.todo +0 -13
- package/connectors_ideas/fastify.js +0 -217
- package/connectors_ideas/koa-plugin.js +0 -112
- package/docs/.bundle/config +0 -2
- package/docs/COMPARISON.md +0 -433
- package/docs/GUIDE/GUIDE_1_Initial_Setup.md +0 -1057
- package/docs/GUIDE/GUIDE_2_1_The_Starting_Point.md +0 -88
- package/docs/GUIDE/GUIDE_2_2_Manipulating_And_Searching_Tables.md +0 -808
- package/docs/GUIDE/GUIDE_2_3_BelongsTo_Relationships.md +0 -491
- package/docs/GUIDE/GUIDE_2_4_HasMany_Records.md +0 -398
- package/docs/GUIDE/GUIDE_2_5_HasMany_Polymorphic.md +0 -898
- package/docs/GUIDE/GUIDE_2_6_Many_To_Many.md +0 -712
- package/docs/GUIDE/GUIDE_2_7_Pagination_And_Ordering.md +0 -1247
- package/docs/GUIDE/GUIDE_2_8_Effects_of_PUT_and_PATCH.md +0 -748
- package/docs/GUIDE/GUIDE_2_9_Relationships_Urls.md +0 -517
- package/docs/GUIDE/GUIDE_2_Data_And_Relations.md +0 -66
- package/docs/GUIDE/GUIDE_3_Field_Transformations.md +0 -1252
- package/docs/GUIDE/GUIDE_5_Non-Db_Resources.md +0 -1107
- package/docs/GUIDE/GUIDE_6_Positioning.md +0 -692
- package/docs/GUIDE/GUIDE_7_Hooks_Data_Management_And_Plugins.md +0 -1491
- package/docs/GUIDE/GUIDE_X_Bulk_Operations.md +0 -732
- package/docs/GUIDE/GUIDE_X_Cors.md +0 -1957
- package/docs/GUIDE/GUIDE_X_Fastify.md +0 -78
- package/docs/GUIDE/GUIDE_X_File_Uploads.md +0 -729
- package/docs/GUIDE/GUIDE_X_Knex_Schema_And_Migrations.md +0 -370
- package/docs/GUIDE/GUIDE_X_Query_Projections.md +0 -159
- package/docs/GUIDE/GUIDE_X_SocketIO.md +0 -1040
- package/docs/GUIDE/GUIDE_X_Writing_Plugins.md +0 -201
- package/docs/Gemfile +0 -6
- package/docs/Gemfile.lock +0 -308
- package/docs/ONBOARDING.md +0 -315
- package/docs/_config.yml +0 -36
- package/docs/_layouts/default.html +0 -123
- package/docs/apple-touch-icon.svg +0 -4
- package/docs/assets/css/style.scss +0 -392
- package/docs/favicon.svg +0 -4
- package/docs/index.md +0 -164
- package/docs/mini-guides/file-uploads-complete.md +0 -161
- package/eslint.config.js +0 -13
- package/examples/url-override-example.js +0 -137
- package/fixing_plan.md +0 -112
- package/plugins/core/lib/anyapi/query/anyapi-query-adapter.js +0 -657
- package/plugins/core/lib/querying-writing/return-record-settings.js +0 -47
- package/plugins/core/lib/writing/knex-json-api-transformers-writing.js +0 -110
- package/plugins/storage/s3-storage.js +0 -93
- package/quickTest.js +0 -136
- package/scripts/debug-anyapi-review-filter.mjs +0 -63
- package/scripts/inspect-anyapi-descriptor-country.mjs +0 -19
- package/scripts/inspect-anyapi-descriptor.mjs +0 -19
- package/scripts/run-docs.js +0 -133
- package/test-debug.js +0 -59
- package/tests/README.md +0 -202
- package/tests/TEST_TEMPLATE.test.js +0 -178
- package/tests/anyapi-basic.test.js +0 -105
- package/tests/anyapi-cursor-pagination.test.js +0 -148
- package/tests/anyapi-custom-idproperty.test.js +0 -163
- package/tests/autofilter.test.js +0 -463
- package/tests/bulk-operations.test.js +0 -657
- package/tests/computed-fields.test.js +0 -586
- package/tests/cors.test.js +0 -834
- package/tests/curl.test.js +0 -467
- package/tests/custom-id-mysql-returning-fallback.test.js +0 -128
- package/tests/custom-id-simplified-post.test.js +0 -75
- package/tests/custom-idproperty-relationships.test.js +0 -932
- package/tests/db-introspection.test.js +0 -521
- package/tests/db-table-operations.test.js +0 -798
- package/tests/fastify-plugin.test.js +0 -184
- package/tests/field-getters.test.js +0 -370
- package/tests/field-setters.test.js +0 -306
- package/tests/file-handling.test.js +0 -155
- package/tests/fixtures/api-configs.js +0 -2566
- package/tests/full-jsonapi-belongsto-linkage.test.js +0 -150
- package/tests/helpers/fake-fastify.js +0 -99
- package/tests/helpers/storage-mode.js +0 -65
- package/tests/helpers/test-utils.js +0 -203
- package/tests/http-connectors-parity.test.js +0 -395
- package/tests/id-normalization.test.js +0 -444
- package/tests/include-depth-validation.test.js +0 -331
- package/tests/includes.test.js +0 -427
- package/tests/local-storage.test.js +0 -96
- package/tests/logical-id-write-validation.test.js +0 -151
- package/tests/nested-includes.test.js +0 -617
- package/tests/pagination-boundaries.test.js +0 -154
- package/tests/pagination-contract.test.js +0 -122
- package/tests/pagination-cursor-multifield.test.js +0 -641
- package/tests/pagination-enhanced.test.js +0 -563
- package/tests/polymorphic-relationships.test.js +0 -347
- package/tests/polymorphic-simple.test.js +0 -148
- package/tests/positioning-advanced.test.js +0 -692
- package/tests/positioning-extended.test.js +0 -915
- package/tests/positioning-multifilter.test.js +0 -699
- package/tests/positioning.test.js +0 -560
- package/tests/post-commit-hooks.test.js +0 -120
- package/tests/projected-fields.test.js +0 -319
- package/tests/public-exports.test.js +0 -15
- package/tests/put-create-parity.test.js +0 -216
- package/tests/queries.test.js +0 -521
- package/tests/query-limits.test.js +0 -584
- package/tests/relationship-endpoints.test.js +0 -620
- package/tests/relationship-include-storage-adapter.test.js +0 -56
- package/tests/relationships.test.js +0 -681
- package/tests/rest-api.test.js +0 -337
- package/tests/return-record-settings.test.js +0 -184
- package/tests/row-policy.test.js +0 -489
- package/tests/s3-storage.test.js +0 -38
- package/tests/searchschema-knex-behavior.test.js +0 -187
- package/tests/searchschema-merge.test.js +0 -151
- package/tests/socketio.test.js +0 -860
- package/tests/storage-mapping.test.js +0 -362
- package/tests/temporal-boundaries.test.js +0 -208
- package/tests/test-development-guide.md +0 -370
- package/tests/virtual-fields.test.js +0 -404
|
@@ -0,0 +1,502 @@
|
|
|
1
|
+
import type { JsonApiDocument, JsonApiLinks, JsonApiRelationship, JsonApiResource } from '../../../../types/representations.js'
|
|
2
|
+
import type { SelectionParams } from '../../../../types/resource-methods.js'
|
|
3
|
+
import { RELATIONSHIPS_KEY } from '../querying-writing/knex-constants.js'
|
|
4
|
+
import { queryConstraint } from '../querying/query-constraint.js'
|
|
5
|
+
import type { TransactionContext } from '../../../../lib/transaction-types.js'
|
|
6
|
+
import type { Knex } from 'knex'
|
|
7
|
+
|
|
8
|
+
// Internal boundary types. Values remain unknown until their schema/driver owns conversion.
|
|
9
|
+
export type StorageRow = Record<string, unknown>
|
|
10
|
+
export type StorageQuery = Knex.QueryBuilder<StorageRow, StorageRow[]>
|
|
11
|
+
export type StorageDatabase = Knex<StorageRow, StorageRow[]>
|
|
12
|
+
export interface MandatoryQueryConstraint {
|
|
13
|
+
scopeName: string
|
|
14
|
+
values?: StorageRow
|
|
15
|
+
idsQuery?: StorageQuery
|
|
16
|
+
}
|
|
17
|
+
export type SelectColumn = string | Knex.Raw<unknown> | StorageQuery | Record<string, string>
|
|
18
|
+
export type SelectColumns = SelectColumn[] | Record<string, string> | null | undefined
|
|
19
|
+
export type SelectTranslator = (field: string, alias?: string | null) => string
|
|
20
|
+
export type StorageNaming = 'snake_case' | 'exact'
|
|
21
|
+
|
|
22
|
+
export interface StorageConfig {
|
|
23
|
+
naming?: 'snake' | 'snake_case' | 'snakeCase' | 'exact' | 'field' | 'verbatim'
|
|
24
|
+
[option: string]: unknown
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export interface StorageContext {
|
|
28
|
+
scopeName?: string
|
|
29
|
+
[key: string]: unknown
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export interface StorageWriteOptions {
|
|
33
|
+
context?: StorageContext | null
|
|
34
|
+
operation?: string | null
|
|
35
|
+
databaseClient?: string
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export interface StorageSerializerDetails extends StorageWriteOptions {
|
|
39
|
+
fieldName?: string
|
|
40
|
+
columnName?: string
|
|
41
|
+
definition: StorageFieldDefinition
|
|
42
|
+
schemaInfo?: Partial<StorageSchemaInfo>
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export interface StorageFieldDefinition {
|
|
46
|
+
type?: string
|
|
47
|
+
dataType?: string
|
|
48
|
+
temporalPrecision?: number
|
|
49
|
+
virtual?: boolean
|
|
50
|
+
computed?: boolean
|
|
51
|
+
hidden?: boolean
|
|
52
|
+
normallyHidden?: boolean
|
|
53
|
+
belongsTo?: string
|
|
54
|
+
as?: string
|
|
55
|
+
belongsToPolymorphic?: unknown
|
|
56
|
+
actualField?: string
|
|
57
|
+
isRelationship?: boolean
|
|
58
|
+
storage?: {
|
|
59
|
+
column?: string
|
|
60
|
+
serialize?: (value: unknown, details: StorageSerializerDetails) => unknown
|
|
61
|
+
}
|
|
62
|
+
[option: string]: unknown
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export interface FieldStorage {
|
|
66
|
+
column: string
|
|
67
|
+
serialize: NonNullable<StorageFieldDefinition['storage']>['serialize'] | null
|
|
68
|
+
persisted: boolean
|
|
69
|
+
definition: StorageFieldDefinition
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export interface StorageInfo {
|
|
73
|
+
idColumn: string
|
|
74
|
+
storage: StorageConfig & { naming: StorageNaming }
|
|
75
|
+
fields: Record<string, FieldStorage>
|
|
76
|
+
columns: Record<string, string>
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
export interface CanonicalFieldSlot {
|
|
80
|
+
slot: string
|
|
81
|
+
slotType: string
|
|
82
|
+
alias?: string
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
export interface CanonicalDescriptor {
|
|
86
|
+
tenant: string
|
|
87
|
+
resource: string
|
|
88
|
+
idProperty?: string
|
|
89
|
+
canonical: {
|
|
90
|
+
tableName: string
|
|
91
|
+
tenantColumn: string
|
|
92
|
+
resourceColumn: string
|
|
93
|
+
logicalIdColumn?: string
|
|
94
|
+
}
|
|
95
|
+
fields?: Record<string, CanonicalFieldSlot>
|
|
96
|
+
schema?: Record<string, StorageFieldDefinition>
|
|
97
|
+
reverseAttributes?: Record<string, string>
|
|
98
|
+
canonicalFieldMap?: Record<string, string | {
|
|
99
|
+
slot?: string
|
|
100
|
+
slotColumn?: string
|
|
101
|
+
idSlot?: string
|
|
102
|
+
typeSlot?: string
|
|
103
|
+
}>
|
|
104
|
+
belongsTo?: Record<string, { idColumn: string; typeColumn: string; target: string }>
|
|
105
|
+
polymorphicBelongsTo?: Record<string, {
|
|
106
|
+
typeField: string
|
|
107
|
+
idField: string
|
|
108
|
+
typeColumn?: string
|
|
109
|
+
idColumn?: string
|
|
110
|
+
types: string[]
|
|
111
|
+
}>
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
export interface StorageSchemaInfo {
|
|
115
|
+
tableName: string
|
|
116
|
+
idProperty?: string
|
|
117
|
+
schemaStructure: Record<string, StorageFieldDefinition>
|
|
118
|
+
searchSchemaStructure?: Record<string, StorageFieldDefinition>
|
|
119
|
+
computed?: Record<string, StorageFieldDefinition>
|
|
120
|
+
storage?: StorageConfig
|
|
121
|
+
storageInfo?: StorageInfo
|
|
122
|
+
descriptor?: CanonicalDescriptor
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
export interface ResourceConversionSchema extends StorageSchemaInfo {
|
|
126
|
+
foreignKeyFields: ReadonlySet<string>
|
|
127
|
+
schemaRelationships?: Record<string, StorageFieldDefinition & {
|
|
128
|
+
belongsToPolymorphic?: { typeField: string; idField: string; types?: readonly string[] }
|
|
129
|
+
}>
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
export interface ResourceConversionScope {
|
|
133
|
+
vars: { schemaInfo: ResourceConversionSchema }
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
export interface StorageAdapter {
|
|
137
|
+
isCanonical(): boolean
|
|
138
|
+
getTableName(): string
|
|
139
|
+
getIdColumn(): string
|
|
140
|
+
translateColumn(field: string): string
|
|
141
|
+
translateFilterValue(field: string, value: unknown): unknown
|
|
142
|
+
translateCursorValue(field: string, value: unknown): unknown
|
|
143
|
+
applyResourceScope(query: StorageQuery, tableAlias?: string): StorageQuery
|
|
144
|
+
toStorageRow(attributes: StorageRow, options?: StorageWriteOptions): StorageRow
|
|
145
|
+
getFieldValue(record: StorageRow | null | undefined, fieldName: string): unknown
|
|
146
|
+
// Some internal callers pass a Knex instance through this option; neither handle is owned here.
|
|
147
|
+
buildBaseQuery(options?: { transaction?: StorageDatabase | null; tableAlias?: string }): StorageQuery
|
|
148
|
+
selectColumns(builder: StorageQuery, columns: SelectColumns): StorageQuery
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
export interface StorageAdapterOptions {
|
|
152
|
+
knex: StorageDatabase
|
|
153
|
+
schemaInfo: StorageSchemaInfo
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
export interface BaseStorageAdapterOptions {
|
|
157
|
+
knex: StorageDatabase
|
|
158
|
+
tableName: string
|
|
159
|
+
idColumn: string
|
|
160
|
+
translateColumn: StorageAdapter['translateColumn']
|
|
161
|
+
translateFilterValue?: StorageAdapter['translateFilterValue']
|
|
162
|
+
translateCursorValue?: StorageAdapter['translateCursorValue']
|
|
163
|
+
applyResourceScope?: StorageAdapter['applyResourceScope']
|
|
164
|
+
toStorageRow?: StorageAdapter['toStorageRow']
|
|
165
|
+
getFieldValue?: StorageAdapter['getFieldValue']
|
|
166
|
+
isCanonical?: boolean
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
export interface StorageHookParams {
|
|
170
|
+
context?: {
|
|
171
|
+
knexQuery?: { scopeName?: string; tableName?: string; storageAdapter?: StorageAdapter }
|
|
172
|
+
storageAdapter?: StorageAdapter
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
export interface StorageResource {
|
|
177
|
+
vars?: { schemaInfo?: StorageSchemaInfo; storageAdapter?: StorageAdapter }
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
export interface StorageAdapterLookupOptions {
|
|
181
|
+
knex: StorageDatabase
|
|
182
|
+
getResource: (scopeName: string) => StorageResource | null | undefined
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
// Hook state may be cleared; entering filtering always requires a live builder.
|
|
186
|
+
export interface QueryFilteringState {
|
|
187
|
+
query?: StorageQuery | null
|
|
188
|
+
filters?: Record<string, unknown>
|
|
189
|
+
schemaInfo?: StorageSchemaInfo
|
|
190
|
+
scopeName?: string
|
|
191
|
+
tableName?: string
|
|
192
|
+
db?: StorageDatabase
|
|
193
|
+
queryPurpose?: string
|
|
194
|
+
adapter?: StorageAdapter
|
|
195
|
+
storageAdapter?: StorageAdapter
|
|
196
|
+
isAnyApi?: boolean
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
// Attributes have passed setters; their values need not be public JSON values.
|
|
200
|
+
export interface StorageInputRecord {
|
|
201
|
+
data: {
|
|
202
|
+
id?: string | number
|
|
203
|
+
type?: string
|
|
204
|
+
attributes?: StorageRow
|
|
205
|
+
relationships?: Record<string, unknown>
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
export interface DataWriteContext extends TransactionContext, StorageContext {
|
|
210
|
+
db: StorageDatabase
|
|
211
|
+
schemaInfo: DataOperationSchema
|
|
212
|
+
storageAdapter?: StorageAdapter
|
|
213
|
+
inputRecord: StorageInputRecord
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
export interface DataIdentityContext extends TransactionContext, StorageContext {
|
|
217
|
+
db: StorageDatabase
|
|
218
|
+
schemaInfo: DataOperationSchema
|
|
219
|
+
storageAdapter?: StorageAdapter
|
|
220
|
+
id: string | number
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
export interface DataWriteHelpers<UpdateResult, DeleteResult> {
|
|
224
|
+
dataExists: (request: { scopeName: string, context: DataIdentityContext }) => Promise<boolean>
|
|
225
|
+
// POST preserves backend-dependent insert results; do not assume a scalar type here.
|
|
226
|
+
dataPost: (request: { scopeName: string, context: DataWriteContext }) => Promise<unknown>
|
|
227
|
+
dataPut: (request: {
|
|
228
|
+
scopeName: string
|
|
229
|
+
context: DataWriteContext & DataIdentityContext & { isCreate: boolean }
|
|
230
|
+
}) => Promise<UpdateResult>
|
|
231
|
+
dataPatch: (request: {
|
|
232
|
+
scopeName: string
|
|
233
|
+
context: DataWriteContext & DataIdentityContext
|
|
234
|
+
}) => Promise<UpdateResult>
|
|
235
|
+
dataDelete: (request: { scopeName: string, context: DataIdentityContext }) => Promise<DeleteResult>
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
export type OrdinaryDataWriteHelpers = DataWriteHelpers<void, { success: true }>
|
|
239
|
+
export type CanonicalDataWriteHelpers = DataWriteHelpers<number, number>
|
|
240
|
+
|
|
241
|
+
// Read helpers assemble resource-shaped values before final output normalization.
|
|
242
|
+
export interface DataResource extends JsonApiResource {
|
|
243
|
+
__$jsonrestapi_computed_deps$__?: string[]
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
export type DataDocument<T> = JsonApiDocument<T>
|
|
247
|
+
|
|
248
|
+
export interface DataStorageRow extends StorageRow {
|
|
249
|
+
[RELATIONSHIPS_KEY]?: Record<string, JsonApiRelationship>
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
export interface DataReadContext extends TransactionContext, StorageContext {
|
|
253
|
+
scopeName: string
|
|
254
|
+
[queryConstraint]?: MandatoryQueryConstraint
|
|
255
|
+
db: StorageDatabase
|
|
256
|
+
schemaInfo: DataOperationSchema
|
|
257
|
+
storageAdapter?: StorageAdapter
|
|
258
|
+
id?: string | number
|
|
259
|
+
queryParams?: {
|
|
260
|
+
filters?: StorageRow
|
|
261
|
+
fields?: SelectionParams['fields']
|
|
262
|
+
include?: string[]
|
|
263
|
+
sort?: string[]
|
|
264
|
+
page?: { size?: number; number?: number; before?: string; after?: string }
|
|
265
|
+
}
|
|
266
|
+
knexQuery?: QueryFilteringState | null
|
|
267
|
+
computedDependencies?: string[]
|
|
268
|
+
returnMeta?: {
|
|
269
|
+
queryString?: string
|
|
270
|
+
paginationMeta?: object
|
|
271
|
+
paginationLinks?: JsonApiLinks | null
|
|
272
|
+
[key: string]: unknown
|
|
273
|
+
}
|
|
274
|
+
sortableFields?: string[]
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
export interface DataReadRequest {
|
|
278
|
+
scopeName: string
|
|
279
|
+
context: DataReadContext
|
|
280
|
+
runHooks?: (name: 'knexQueryFiltering') => unknown | Promise<unknown>
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
export type QueryBuilderResult = StorageQuery | { query: QueryBuilderResult }
|
|
284
|
+
|
|
285
|
+
export interface DataMinimalRequest extends DataReadRequest {
|
|
286
|
+
filters?: StorageRow
|
|
287
|
+
queryPurpose?: string
|
|
288
|
+
applyQueryFilters?: (params: QueryFilteringState & { query: StorageQuery }) => Promise<{ query: QueryBuilderResult } | null | undefined>
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
export interface DataMinimalReader {
|
|
292
|
+
(request: DataMinimalRequest & { ids: Array<string | number> }): Promise<DataResource[]>
|
|
293
|
+
(request: DataMinimalRequest & {
|
|
294
|
+
ids?: undefined
|
|
295
|
+
context: DataReadContext & { id: string | number }
|
|
296
|
+
}): Promise<DataResource | null>
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
export interface DataReadHelpers<GetResult> {
|
|
300
|
+
dataGetMinimal: DataMinimalReader
|
|
301
|
+
dataGet: (request: DataReadRequest & {
|
|
302
|
+
context: DataReadContext & { id: string | number }
|
|
303
|
+
}) => Promise<GetResult>
|
|
304
|
+
dataQuery: (request: DataReadRequest & {
|
|
305
|
+
runHooks: NonNullable<DataReadRequest['runHooks']>
|
|
306
|
+
context: DataReadContext & {
|
|
307
|
+
queryParams: NonNullable<DataReadContext['queryParams']>
|
|
308
|
+
}
|
|
309
|
+
}) => Promise<DataDocument<DataResource[]>>
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
export type OrdinaryDataReadHelpers = DataReadHelpers<DataDocument<DataResource>>
|
|
313
|
+
export type CanonicalDataReadHelpers = DataReadHelpers<DataDocument<DataResource> | null>
|
|
314
|
+
|
|
315
|
+
export interface DatabaseInfo {
|
|
316
|
+
client: string
|
|
317
|
+
version: string
|
|
318
|
+
error?: string
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
export interface CapabilityLogger {
|
|
322
|
+
warn(message: string, details: unknown): unknown
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
export type InsertResultMode = 'insert-id' | 'rows' | 'driver-defined'
|
|
326
|
+
|
|
327
|
+
export interface TemporalStorageCapabilities {
|
|
328
|
+
dateMinYear: number
|
|
329
|
+
dateTimeMinYear: number
|
|
330
|
+
maxYear: number
|
|
331
|
+
dateTimeFractionDigits: number
|
|
332
|
+
timeFractionDigits: number | null
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
export interface SchemaCapabilities {
|
|
336
|
+
recognizedDialect: boolean
|
|
337
|
+
fieldAlteration: 'standalone' | 'sqlite-rebuild' | 'transaction'
|
|
338
|
+
callerFieldAlteration: 'forbidden' | 'foreign-keys-off' | 'savepoint'
|
|
339
|
+
temporalColumnFractionDigits: number | null
|
|
340
|
+
setValues: boolean
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
export interface SerializationCapabilities {
|
|
344
|
+
readonly customSerializerResult: 'synchronous'
|
|
345
|
+
readonly structuredTypes: readonly string[]
|
|
346
|
+
readonly structuredEncoding: 'json'
|
|
347
|
+
readonly wholeDocumentPredicates: false
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
export interface RelationshipCapabilities {
|
|
351
|
+
readonly attributeKinds: readonly string[]
|
|
352
|
+
readonly declaredCardinalities: {
|
|
353
|
+
readonly hasOne: 'one'
|
|
354
|
+
readonly hasMany: 'many'
|
|
355
|
+
readonly manyToMany: 'many'
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
export interface DatabaseCapabilities {
|
|
360
|
+
dbInfo: DatabaseInfo
|
|
361
|
+
windowFunctions: boolean
|
|
362
|
+
insertResult: InsertResultMode
|
|
363
|
+
serialization: SerializationCapabilities
|
|
364
|
+
relationships: RelationshipCapabilities
|
|
365
|
+
temporal: { native: TemporalStorageCapabilities; text: TemporalStorageCapabilities }
|
|
366
|
+
schema: SchemaCapabilities
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
export interface PivotRelationship {
|
|
370
|
+
through: string
|
|
371
|
+
foreignKey: string
|
|
372
|
+
otherKey: string
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
export interface RelatedQueryRequest {
|
|
376
|
+
scopeName: string
|
|
377
|
+
context: TransactionContext & { db: StorageDatabase; id: string | number; relationshipName: string }
|
|
378
|
+
relDef: PivotRelationship
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
// Wrap thenable builders so awaiting the helper does not execute its subquery.
|
|
382
|
+
export type DataRelatedIdsQuery = (request: RelatedQueryRequest) => Promise<{ query: StorageQuery }>
|
|
383
|
+
export type CanonicalDataRelatedIdsQuery = (request: Omit<RelatedQueryRequest, 'relDef'> & { relDef?: unknown }) => Promise<{ query: StorageQuery }>
|
|
384
|
+
|
|
385
|
+
export interface CanonicalLinkContext extends TransactionContext {
|
|
386
|
+
db?: StorageDatabase
|
|
387
|
+
id: string | number
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
export interface CanonicalLinkRequest {
|
|
391
|
+
scopeName: string
|
|
392
|
+
relName: string
|
|
393
|
+
context: CanonicalLinkContext
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
export interface CanonicalLinkMutation extends CanonicalLinkRequest {
|
|
397
|
+
relData: Array<{ type: string; id: string | number }>
|
|
398
|
+
relDef?: unknown
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
export interface CanonicalLinkHelpers {
|
|
402
|
+
attachMany(request: CanonicalLinkMutation): Promise<void>
|
|
403
|
+
syncMany(request: CanonicalLinkMutation & { isUpdate: boolean }): Promise<void>
|
|
404
|
+
removeMany(request: CanonicalLinkMutation): Promise<void>
|
|
405
|
+
listMany(request: CanonicalLinkRequest): Promise<Array<{ type: string; id: string | null }>>
|
|
406
|
+
fetchManyToManyRows(request: {
|
|
407
|
+
scopeName: string
|
|
408
|
+
relName: string
|
|
409
|
+
parentIds: Array<string | number>
|
|
410
|
+
context: Omit<CanonicalLinkContext, 'id'>
|
|
411
|
+
}): Promise<Array<{ parentId: string; childId: string; childType: string }>>
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
export interface DataOperationSchema extends ResourceConversionSchema {
|
|
415
|
+
idProperty: string
|
|
416
|
+
queryFields?: Record<string, import('../querying-writing/query-field-types.js').CompiledQueryField>
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
export interface DataOperationScope {
|
|
420
|
+
checkPermissions(request: { method: 'query', originalContext: DataReadContext }): Promise<unknown>
|
|
421
|
+
applyQueryFilters(request: QueryFilteringState, context: DataReadContext): Promise<{ query: QueryBuilderResult } | null | undefined>
|
|
422
|
+
name?: string
|
|
423
|
+
scopeName?: string
|
|
424
|
+
vars: {
|
|
425
|
+
schemaInfo: DataOperationSchema
|
|
426
|
+
defaultSort?: string[]
|
|
427
|
+
enablePaginationCounts?: boolean
|
|
428
|
+
queryDefaultLimit?: number
|
|
429
|
+
queryMaxLimit?: number
|
|
430
|
+
[option: string]: unknown
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
export interface DataOperationApi {
|
|
435
|
+
resources: Record<string, DataOperationScope>
|
|
436
|
+
knex: { instance: StorageDatabase }
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
export interface DataSortDescriptor {
|
|
440
|
+
field: string
|
|
441
|
+
direction: string
|
|
442
|
+
column?: string
|
|
443
|
+
resultColumn?: string
|
|
444
|
+
actualField?: string
|
|
445
|
+
referenceField?: string
|
|
446
|
+
definition?: StorageFieldDefinition | null
|
|
447
|
+
isRelationship: boolean
|
|
448
|
+
queryFieldRuntime?: import('../querying-writing/query-field-types.js').ProjectionRuntime
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
export interface DataSortRequest {
|
|
452
|
+
query: StorageQuery
|
|
453
|
+
sort?: unknown
|
|
454
|
+
schemaInfo: StorageSchemaInfo
|
|
455
|
+
sortableFields?: string[]
|
|
456
|
+
storageAdapter: StorageAdapter
|
|
457
|
+
defaultSort?: string[]
|
|
458
|
+
scopeName: string
|
|
459
|
+
context: DataReadContext
|
|
460
|
+
before?: boolean
|
|
461
|
+
queryFieldRuntimeByField: Map<string, import('../querying-writing/query-field-types.js').ProjectionRuntime>
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
export interface OrdinaryDataDependencies {
|
|
465
|
+
api: DataOperationApi
|
|
466
|
+
scopes: Record<string, DataOperationScope>
|
|
467
|
+
knex: StorageDatabase
|
|
468
|
+
log: import('../../../../types/runtime.js').RuntimeLogger
|
|
469
|
+
getScopeStorageAdapter(scopeName: string): StorageAdapter | null
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
export interface DataCursorOptions {
|
|
473
|
+
schemaInfo?: StorageSchemaInfo | null
|
|
474
|
+
definitions?: Record<string, StorageFieldDefinition | null | undefined>
|
|
475
|
+
before?: boolean
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
export interface CanonicalDataDependencies {
|
|
479
|
+
api: DataOperationApi
|
|
480
|
+
knex: StorageDatabase
|
|
481
|
+
getScopeStorageAdapter(scopeName: string): StorageAdapter | null
|
|
482
|
+
getDescriptor(scopeName: string): CanonicalDescriptor
|
|
483
|
+
linkStore: {
|
|
484
|
+
invalidateDeletedLinkTargets(scopeName: string, context: DataIdentityContext): Promise<void>
|
|
485
|
+
deleteResourceLinks(request: { descriptor: CanonicalDescriptor, scopeName: string, id: string | number, db: StorageDatabase }): Promise<void>
|
|
486
|
+
}
|
|
487
|
+
buildIncludes(request: { parentResources: DataResource[], descriptor: CanonicalDescriptor, context: DataReadContext }): Promise<DataResource[]>
|
|
488
|
+
attachReverseRelationships(request: { resources: DataResource[], descriptor: CanonicalDescriptor, context: DataReadContext }): Promise<void>
|
|
489
|
+
attachManyToManyRelationships(request: { resources: DataResource[], descriptor: CanonicalDescriptor, context: DataReadContext }): Promise<void>
|
|
490
|
+
applyBuiltInAnyApiQueryFilters(context: DataReadContext): Promise<void>
|
|
491
|
+
}
|
|
492
|
+
|
|
493
|
+
export interface CanonicalDataSortRequest {
|
|
494
|
+
query: StorageQuery
|
|
495
|
+
sort?: string[]
|
|
496
|
+
descriptor: CanonicalDescriptor
|
|
497
|
+
scope: DataOperationScope
|
|
498
|
+
tableAlias: string
|
|
499
|
+
context: DataReadContext
|
|
500
|
+
before?: boolean
|
|
501
|
+
queryFieldRuntimeByField: Map<string, import('../querying-writing/query-field-types.js').ProjectionRuntime>
|
|
502
|
+
}
|