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.
Files changed (294) hide show
  1. package/LICENSE +10 -670
  2. package/LICENSE-GPL-3.0 +674 -0
  3. package/LICENSE-MIT +21 -0
  4. package/README.md +39 -30
  5. package/docs/API.md +744 -1273
  6. package/docs/GUIDE/01-getting-started.md +338 -0
  7. package/docs/GUIDE/02-resources-and-relationships.md +33 -0
  8. package/docs/GUIDE/03-running-example.md +87 -0
  9. package/docs/GUIDE/04-creating-and-querying.md +181 -0
  10. package/docs/GUIDE/05-belongs-to.md +177 -0
  11. package/docs/GUIDE/06-has-many.md +184 -0
  12. package/docs/GUIDE/07-polymorphic-relationships.md +191 -0
  13. package/docs/GUIDE/08-many-to-many.md +184 -0
  14. package/docs/GUIDE/09-pagination-and-sorting.md +149 -0
  15. package/docs/GUIDE/10-put-and-patch.md +174 -0
  16. package/docs/GUIDE/11-relationship-endpoints.md +174 -0
  17. package/docs/GUIDE/12-field-transformations.md +287 -0
  18. package/docs/GUIDE/13-hooks-and-lifecycle.md +479 -0
  19. package/docs/GUIDE/14-custom-resource-methods.md +125 -0
  20. package/docs/GUIDE/15-query-projections.md +266 -0
  21. package/docs/GUIDE/{GUIDE_X_Autofiltering.md → 16-autofiltering.md} +77 -15
  22. package/docs/GUIDE/{GUIDE_X_Row_Policies.md → 17-row-policies.md} +137 -44
  23. package/docs/GUIDE/18-labels.md +86 -0
  24. package/docs/GUIDE/19-managed-transactions.md +179 -0
  25. package/docs/GUIDE/20-transaction-outcomes.md +207 -0
  26. package/docs/GUIDE/21-schema-and-migrations.md +733 -0
  27. package/docs/GUIDE/22-version-field-migrations.md +208 -0
  28. package/docs/GUIDE/23-fastify.md +179 -0
  29. package/docs/GUIDE/24-cors.md +172 -0
  30. package/docs/GUIDE/{GUIDE_X_URL_Management.md → 25-url-management.md} +7 -1
  31. package/docs/GUIDE/26-file-uploads.md +278 -0
  32. package/docs/GUIDE/27-bulk-operations.md +277 -0
  33. package/docs/GUIDE/28-socketio.md +325 -0
  34. package/docs/GUIDE/29-writing-plugins.md +278 -0
  35. package/docs/GUIDE/30-backend-capabilities.md +103 -0
  36. package/docs/GUIDE/31-positioning.md +181 -0
  37. package/docs/GUIDE/{GUIDE_Y_Appendices.md → 32-date-and-time.md} +74 -30
  38. package/docs/GUIDE/33-migrating-to-v2.md +3838 -0
  39. package/docs/GUIDE/index.md +51 -59
  40. package/docs/QUICKSTART.md +120 -287
  41. package/docs/architecture.md +75 -0
  42. package/docs/contributing.md +178 -0
  43. package/index.d.ts +37 -0
  44. package/index.js +3 -22
  45. package/lib/enhanced-logger.js +91 -85
  46. package/lib/error-context.js +445 -5
  47. package/lib/error-formatter.js +219 -59
  48. package/lib/knex-transaction.js +70 -0
  49. package/lib/logger-types.d.ts +22 -0
  50. package/lib/missing-package.js +4 -0
  51. package/lib/rest-api-errors.js +103 -8
  52. package/lib/runtime/json-rest-api.js +172 -0
  53. package/lib/transaction-types.d.ts +59 -0
  54. package/package.json +97 -27
  55. package/plugins/core/bulk-operations-plugin.js +191 -184
  56. package/plugins/core/connectors/express-plugin.js +148 -219
  57. package/plugins/core/connectors/fastify-plugin.js +125 -82
  58. package/plugins/core/connectors/lib/busboy-detector.js +74 -156
  59. package/plugins/core/connectors/lib/connector-core.js +144 -20
  60. package/plugins/core/connectors/lib/formidable-detector.js +63 -120
  61. package/plugins/core/connectors/lib/http-validators.js +77 -0
  62. package/plugins/core/connectors/lib/multipart-helpers.js +18 -0
  63. package/plugins/core/connectors/lib/request-helpers.js +10 -1
  64. package/plugins/core/connectors/lib/transport-http-helpers.js +89 -8
  65. package/plugins/core/connectors/lib/transport-route-schemas.js +7 -4
  66. package/plugins/core/file-handling-plugin.js +87 -177
  67. package/plugins/core/lib/anyapi/anyapi-registry.js +586 -418
  68. package/plugins/core/lib/anyapi/canonical-link-store.js +507 -0
  69. package/plugins/core/lib/anyapi/canonical-relationship-reader.js +598 -0
  70. package/plugins/core/lib/anyapi/schema-utils.js +120 -56
  71. package/plugins/core/lib/anyapi/stored-definition.js +109 -0
  72. package/plugins/core/lib/anyapi/utils/descriptor-helpers.js +0 -64
  73. package/plugins/core/lib/dbIntrospection.js +228 -21
  74. package/plugins/core/lib/dbTablesOperations.js +409 -92
  75. package/plugins/core/lib/fractional-positioning.js +12 -48
  76. package/plugins/core/lib/querying/identifier-query.js +19 -0
  77. package/plugins/core/lib/querying/include-query-helpers.js +364 -0
  78. package/plugins/core/lib/querying/include-to-many.js +428 -0
  79. package/plugins/core/lib/querying/include-to-one.js +579 -0
  80. package/plugins/core/lib/querying/knex-cross-table-search.js +31 -307
  81. package/plugins/core/lib/querying/knex-json-api-transformers-querying.js +99 -401
  82. package/plugins/core/lib/querying/knex-pagination-helpers.js +48 -317
  83. package/plugins/core/lib/querying/knex-process-includes.js +5 -110
  84. package/plugins/core/lib/querying/knex-query-helpers-base.js +21 -56
  85. package/plugins/core/lib/querying/knex-query-helpers.js +298 -448
  86. package/plugins/core/lib/querying/knex-relationship-includes.js +120 -2138
  87. package/plugins/core/lib/querying/knex-window-queries.js +62 -253
  88. package/plugins/core/lib/querying/query-builder-utils.js +44 -4
  89. package/plugins/core/lib/querying/query-constraint.d.ts +12 -0
  90. package/plugins/core/lib/querying/query-constraint.js +27 -0
  91. package/plugins/core/lib/querying/query-field-sort-helpers.js +134 -37
  92. package/plugins/core/lib/querying/relationship-identifiers.js +208 -0
  93. package/plugins/core/lib/querying/sort-helpers.js +13 -1
  94. package/plugins/core/lib/querying/storage-adapter-utils.js +13 -5
  95. package/plugins/core/lib/querying/url-helpers.js +11 -4
  96. package/plugins/core/lib/querying-writing/compile-schemas.js +148 -249
  97. package/plugins/core/lib/querying-writing/connectors-query-parser.js +33 -118
  98. package/plugins/core/lib/querying-writing/database-capabilities.js +149 -223
  99. package/plugins/core/lib/querying-writing/database-value-normalizers.js +179 -194
  100. package/plugins/core/lib/querying-writing/default-data-helpers.js +15 -45
  101. package/plugins/core/lib/querying-writing/field-selection-types.d.ts +43 -0
  102. package/plugins/core/lib/querying-writing/field-utils.js +113 -92
  103. package/plugins/core/lib/querying-writing/knex-constants.d.ts +18 -0
  104. package/plugins/core/lib/querying-writing/knex-constants.js +2 -26
  105. package/plugins/core/lib/querying-writing/knex-field-helpers.js +100 -290
  106. package/plugins/core/lib/querying-writing/knex-json-api-transformers.js +31 -120
  107. package/plugins/core/lib/querying-writing/query-field-helpers.js +108 -32
  108. package/plugins/core/lib/querying-writing/query-field-types.d.ts +60 -0
  109. package/plugins/core/lib/querying-writing/relationship-contracts.js +33 -13
  110. package/plugins/core/lib/querying-writing/request-contracts.js +93 -38
  111. package/plugins/core/lib/querying-writing/resource-id-normalization.js +23 -5
  112. package/plugins/core/lib/querying-writing/response-options.js +35 -0
  113. package/plugins/core/lib/querying-writing/schema-helpers.js +203 -324
  114. package/plugins/core/lib/querying-writing/scope-validations.js +92 -290
  115. package/plugins/core/lib/querying-writing/simplified-helpers.js +113 -712
  116. package/plugins/core/lib/storage/canonical-data-helpers.js +683 -0
  117. package/plugins/core/lib/storage/canonical-storage-mapping.js +51 -20
  118. package/plugins/core/lib/storage/ordinary-data-helpers.js +710 -0
  119. package/plugins/core/lib/storage/storage-adapter.js +128 -62
  120. package/plugins/core/lib/storage/storage-mapping.js +78 -28
  121. package/plugins/core/lib/storage/storage-types.d.ts +502 -0
  122. package/plugins/core/lib/writing/many-to-many-manipulations.js +114 -284
  123. package/plugins/core/lib/writing/relationship-processor.js +94 -158
  124. package/plugins/core/lib/writing/resource-version.js +172 -0
  125. package/plugins/core/lib/writing/reverse-relationship-manipulations.js +110 -0
  126. package/plugins/core/rest-api-anyapi-knex-plugin.js +290 -2475
  127. package/plugins/core/rest-api-autofilter-plugin.js +17 -19
  128. package/plugins/core/rest-api-cors-plugin.js +52 -205
  129. package/plugins/core/rest-api-knex-plugin.js +45 -1077
  130. package/plugins/core/rest-api-label-plugin.js +25 -38
  131. package/plugins/core/rest-api-plugin-hooks/register-relationship-routes.js +5 -5
  132. package/plugins/core/rest-api-plugin-hooks/register-scope-routes.js +9 -6
  133. package/plugins/core/rest-api-plugin-hooks/turn-scope-init-into-vars.js +7 -26
  134. package/plugins/core/rest-api-plugin-hooks/validate-include-configurations.js +20 -26
  135. package/plugins/core/rest-api-plugin-methods/add-route.js +4 -6
  136. package/plugins/core/rest-api-plugin-methods/apply-query-filters.js +42 -13
  137. package/plugins/core/rest-api-plugin-methods/check-permissions.js +11 -5
  138. package/plugins/core/rest-api-plugin-methods/common.js +291 -395
  139. package/plugins/core/rest-api-plugin-methods/delete-relationship.js +49 -47
  140. package/plugins/core/rest-api-plugin-methods/delete.js +31 -25
  141. package/plugins/core/rest-api-plugin-methods/enrich-attributes.js +108 -148
  142. package/plugins/core/rest-api-plugin-methods/get-related.js +113 -305
  143. package/plugins/core/rest-api-plugin-methods/get-relationship.js +25 -18
  144. package/plugins/core/rest-api-plugin-methods/get.js +36 -68
  145. package/plugins/core/rest-api-plugin-methods/lifecycle-types.d.ts +225 -0
  146. package/plugins/core/rest-api-plugin-methods/patch-relationship.js +28 -25
  147. package/plugins/core/rest-api-plugin-methods/patch.js +46 -99
  148. package/plugins/core/rest-api-plugin-methods/post-relationship.js +49 -53
  149. package/plugins/core/rest-api-plugin-methods/post.js +51 -51
  150. package/plugins/core/rest-api-plugin-methods/put.js +69 -148
  151. package/plugins/core/rest-api-plugin-methods/query.js +37 -81
  152. package/plugins/core/rest-api-plugin-methods/release.js +2 -1
  153. package/plugins/core/rest-api-plugin.js +32 -46
  154. package/plugins/core/rest-api-positioning-plugin.js +183 -628
  155. package/plugins/core/rest-api-query-projections-plugin.js +19 -102
  156. package/plugins/core/rest-api-row-policy-plugin.js +3 -3
  157. package/plugins/core/socketio-plugin.js +364 -344
  158. package/plugins/storage/local-storage.js +40 -36
  159. package/types/anyapi.d.ts +30 -0
  160. package/types/autofilter.d.ts +57 -0
  161. package/types/bulk-methods.d.ts +63 -0
  162. package/types/errors.d.ts +118 -0
  163. package/types/fastify-options.d.ts +19 -0
  164. package/types/file-detectors.d.ts +33 -0
  165. package/types/file-storage.d.ts +48 -0
  166. package/types/hook-context.d.ts +180 -0
  167. package/types/plugin-options.d.ts +65 -0
  168. package/types/relationship-methods.d.ts +74 -0
  169. package/types/representations.d.ts +50 -0
  170. package/types/resource-methods.d.ts +95 -0
  171. package/types/resource-schema.d.ts +157 -0
  172. package/types/row-policy.d.ts +31 -0
  173. package/types/runtime.d.ts +132 -0
  174. package/types/transactions.d.ts +21 -0
  175. package/.claude/agents/library-guide-expert.md +0 -30
  176. package/.claude/agents/rest-api-internals-expert.md +0 -54
  177. package/.claude/settings.local.json +0 -70
  178. package/AGENTS.md +0 -34
  179. package/CLAUDE.md +0 -160
  180. package/CRUSH.md +0 -55
  181. package/JSKIT_BACKEND_MIGRATION_TRACKER.txt +0 -180
  182. package/SINGLE_VALIDATION_CONTRACT_TODO.txt +0 -172
  183. package/TODO.todo +0 -13
  184. package/connectors_ideas/fastify.js +0 -217
  185. package/connectors_ideas/koa-plugin.js +0 -112
  186. package/docs/.bundle/config +0 -2
  187. package/docs/COMPARISON.md +0 -433
  188. package/docs/GUIDE/GUIDE_1_Initial_Setup.md +0 -1057
  189. package/docs/GUIDE/GUIDE_2_1_The_Starting_Point.md +0 -88
  190. package/docs/GUIDE/GUIDE_2_2_Manipulating_And_Searching_Tables.md +0 -808
  191. package/docs/GUIDE/GUIDE_2_3_BelongsTo_Relationships.md +0 -491
  192. package/docs/GUIDE/GUIDE_2_4_HasMany_Records.md +0 -398
  193. package/docs/GUIDE/GUIDE_2_5_HasMany_Polymorphic.md +0 -898
  194. package/docs/GUIDE/GUIDE_2_6_Many_To_Many.md +0 -712
  195. package/docs/GUIDE/GUIDE_2_7_Pagination_And_Ordering.md +0 -1247
  196. package/docs/GUIDE/GUIDE_2_8_Effects_of_PUT_and_PATCH.md +0 -748
  197. package/docs/GUIDE/GUIDE_2_9_Relationships_Urls.md +0 -517
  198. package/docs/GUIDE/GUIDE_2_Data_And_Relations.md +0 -66
  199. package/docs/GUIDE/GUIDE_3_Field_Transformations.md +0 -1252
  200. package/docs/GUIDE/GUIDE_5_Non-Db_Resources.md +0 -1107
  201. package/docs/GUIDE/GUIDE_6_Positioning.md +0 -692
  202. package/docs/GUIDE/GUIDE_7_Hooks_Data_Management_And_Plugins.md +0 -1491
  203. package/docs/GUIDE/GUIDE_X_Bulk_Operations.md +0 -732
  204. package/docs/GUIDE/GUIDE_X_Cors.md +0 -1957
  205. package/docs/GUIDE/GUIDE_X_Fastify.md +0 -78
  206. package/docs/GUIDE/GUIDE_X_File_Uploads.md +0 -729
  207. package/docs/GUIDE/GUIDE_X_Knex_Schema_And_Migrations.md +0 -370
  208. package/docs/GUIDE/GUIDE_X_Query_Projections.md +0 -159
  209. package/docs/GUIDE/GUIDE_X_SocketIO.md +0 -1040
  210. package/docs/GUIDE/GUIDE_X_Writing_Plugins.md +0 -201
  211. package/docs/Gemfile +0 -6
  212. package/docs/Gemfile.lock +0 -308
  213. package/docs/ONBOARDING.md +0 -315
  214. package/docs/_config.yml +0 -36
  215. package/docs/_layouts/default.html +0 -123
  216. package/docs/apple-touch-icon.svg +0 -4
  217. package/docs/assets/css/style.scss +0 -392
  218. package/docs/favicon.svg +0 -4
  219. package/docs/index.md +0 -164
  220. package/docs/mini-guides/file-uploads-complete.md +0 -161
  221. package/eslint.config.js +0 -13
  222. package/examples/url-override-example.js +0 -137
  223. package/fixing_plan.md +0 -112
  224. package/plugins/core/lib/anyapi/query/anyapi-query-adapter.js +0 -657
  225. package/plugins/core/lib/querying-writing/return-record-settings.js +0 -47
  226. package/plugins/core/lib/writing/knex-json-api-transformers-writing.js +0 -110
  227. package/plugins/storage/s3-storage.js +0 -93
  228. package/quickTest.js +0 -136
  229. package/scripts/debug-anyapi-review-filter.mjs +0 -63
  230. package/scripts/inspect-anyapi-descriptor-country.mjs +0 -19
  231. package/scripts/inspect-anyapi-descriptor.mjs +0 -19
  232. package/scripts/run-docs.js +0 -133
  233. package/test-debug.js +0 -59
  234. package/tests/README.md +0 -202
  235. package/tests/TEST_TEMPLATE.test.js +0 -178
  236. package/tests/anyapi-basic.test.js +0 -105
  237. package/tests/anyapi-cursor-pagination.test.js +0 -148
  238. package/tests/anyapi-custom-idproperty.test.js +0 -163
  239. package/tests/autofilter.test.js +0 -463
  240. package/tests/bulk-operations.test.js +0 -657
  241. package/tests/computed-fields.test.js +0 -586
  242. package/tests/cors.test.js +0 -834
  243. package/tests/curl.test.js +0 -467
  244. package/tests/custom-id-mysql-returning-fallback.test.js +0 -128
  245. package/tests/custom-id-simplified-post.test.js +0 -75
  246. package/tests/custom-idproperty-relationships.test.js +0 -932
  247. package/tests/db-introspection.test.js +0 -521
  248. package/tests/db-table-operations.test.js +0 -798
  249. package/tests/fastify-plugin.test.js +0 -184
  250. package/tests/field-getters.test.js +0 -370
  251. package/tests/field-setters.test.js +0 -306
  252. package/tests/file-handling.test.js +0 -155
  253. package/tests/fixtures/api-configs.js +0 -2566
  254. package/tests/full-jsonapi-belongsto-linkage.test.js +0 -150
  255. package/tests/helpers/fake-fastify.js +0 -99
  256. package/tests/helpers/storage-mode.js +0 -65
  257. package/tests/helpers/test-utils.js +0 -203
  258. package/tests/http-connectors-parity.test.js +0 -395
  259. package/tests/id-normalization.test.js +0 -444
  260. package/tests/include-depth-validation.test.js +0 -331
  261. package/tests/includes.test.js +0 -427
  262. package/tests/local-storage.test.js +0 -96
  263. package/tests/logical-id-write-validation.test.js +0 -151
  264. package/tests/nested-includes.test.js +0 -617
  265. package/tests/pagination-boundaries.test.js +0 -154
  266. package/tests/pagination-contract.test.js +0 -122
  267. package/tests/pagination-cursor-multifield.test.js +0 -641
  268. package/tests/pagination-enhanced.test.js +0 -563
  269. package/tests/polymorphic-relationships.test.js +0 -347
  270. package/tests/polymorphic-simple.test.js +0 -148
  271. package/tests/positioning-advanced.test.js +0 -692
  272. package/tests/positioning-extended.test.js +0 -915
  273. package/tests/positioning-multifilter.test.js +0 -699
  274. package/tests/positioning.test.js +0 -560
  275. package/tests/post-commit-hooks.test.js +0 -120
  276. package/tests/projected-fields.test.js +0 -319
  277. package/tests/public-exports.test.js +0 -15
  278. package/tests/put-create-parity.test.js +0 -216
  279. package/tests/queries.test.js +0 -521
  280. package/tests/query-limits.test.js +0 -584
  281. package/tests/relationship-endpoints.test.js +0 -620
  282. package/tests/relationship-include-storage-adapter.test.js +0 -56
  283. package/tests/relationships.test.js +0 -681
  284. package/tests/rest-api.test.js +0 -337
  285. package/tests/return-record-settings.test.js +0 -184
  286. package/tests/row-policy.test.js +0 -489
  287. package/tests/s3-storage.test.js +0 -38
  288. package/tests/searchschema-knex-behavior.test.js +0 -187
  289. package/tests/searchschema-merge.test.js +0 -151
  290. package/tests/socketio.test.js +0 -860
  291. package/tests/storage-mapping.test.js +0 -362
  292. package/tests/temporal-boundaries.test.js +0 -208
  293. package/tests/test-development-guide.md +0 -370
  294. 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
+ }