@iamjulianacosta/mobx-data 1.1.0 → 1.4.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 (203) hide show
  1. package/README.md +273 -102
  2. package/dist/{CacheHandler-BTU_rYkv.js → CacheHandler-BhfbVHed.js} +17 -20
  3. package/dist/CacheHandler-BhfbVHed.js.map +1 -0
  4. package/dist/{CacheHandler-CXgY9IJo.cjs → CacheHandler-Q5VXOgh9.cjs} +2 -2
  5. package/dist/CacheHandler-Q5VXOgh9.cjs.map +1 -0
  6. package/dist/EmbeddedRecordsMixin-6mSCXsJ3.js +173 -0
  7. package/dist/EmbeddedRecordsMixin-6mSCXsJ3.js.map +1 -0
  8. package/dist/EmbeddedRecordsMixin-BkF7MdbY.cjs +2 -0
  9. package/dist/EmbeddedRecordsMixin-BkF7MdbY.cjs.map +1 -0
  10. package/dist/{JsonApiSerializer-BLoE046A.js → JsonApiSerializer-BV61cFAZ.js} +3 -3
  11. package/dist/JsonApiSerializer-BV61cFAZ.js.map +1 -0
  12. package/dist/{JsonApiSerializer-DKemcyw-.cjs → JsonApiSerializer-Dt_Y_FIo.cjs} +2 -2
  13. package/dist/JsonApiSerializer-Dt_Y_FIo.cjs.map +1 -0
  14. package/dist/JsonSerializer-BzUCyUSf.cjs +2 -0
  15. package/dist/JsonSerializer-BzUCyUSf.cjs.map +1 -0
  16. package/dist/JsonSerializer-CFqo6GjC.js +98 -0
  17. package/dist/JsonSerializer-CFqo6GjC.js.map +1 -0
  18. package/dist/MdqlMemoryExecutor-BUlsalKm.cjs +2 -0
  19. package/dist/MdqlMemoryExecutor-BUlsalKm.cjs.map +1 -0
  20. package/dist/MdqlMemoryExecutor-BWMP31zG.js +127 -0
  21. package/dist/MdqlMemoryExecutor-BWMP31zG.js.map +1 -0
  22. package/dist/{MemoryAdapter-Bp-BGHH3.js → MemoryAdapter-BW1HKixm.js} +2 -2
  23. package/dist/{MemoryAdapter-Bp-BGHH3.js.map → MemoryAdapter-BW1HKixm.js.map} +1 -1
  24. package/dist/{MemoryAdapter-DH-gzSSl.cjs → MemoryAdapter-C8iXAa2v.cjs} +2 -2
  25. package/dist/{MemoryAdapter-DH-gzSSl.cjs.map → MemoryAdapter-C8iXAa2v.cjs.map} +1 -1
  26. package/dist/{ODataAdapter-RQUjVTcf.js → ODataAdapter-CeBJblLQ.js} +25 -22
  27. package/dist/ODataAdapter-CeBJblLQ.js.map +1 -0
  28. package/dist/{ODataAdapter-CrDFvBEZ.cjs → ODataAdapter-DdE6MWkG.cjs} +2 -2
  29. package/dist/ODataAdapter-DdE6MWkG.cjs.map +1 -0
  30. package/dist/RestAdapter-D7GSrsJo.cjs +2 -0
  31. package/dist/RestAdapter-D7GSrsJo.cjs.map +1 -0
  32. package/dist/{RestAdapter-D6bGIHZT.js → RestAdapter-DYUoyV5h.js} +112 -77
  33. package/dist/RestAdapter-DYUoyV5h.js.map +1 -0
  34. package/dist/SchemaService-C_pkh-vI.js +180 -0
  35. package/dist/SchemaService-C_pkh-vI.js.map +1 -0
  36. package/dist/SchemaService-DbJLoYb9.cjs +2 -0
  37. package/dist/SchemaService-DbJLoYb9.cjs.map +1 -0
  38. package/dist/Serializer-Bap9U-kR.cjs +2 -0
  39. package/dist/Serializer-Bap9U-kR.cjs.map +1 -0
  40. package/dist/{Serializer-FxJbsZ50.js → Serializer-Ca6w_QNQ.js} +63 -49
  41. package/dist/Serializer-Ca6w_QNQ.js.map +1 -0
  42. package/dist/adapter/index.cjs +1 -1
  43. package/dist/adapter/index.js +2 -2
  44. package/dist/createStore-7PecKT54.cjs +2 -0
  45. package/dist/createStore-7PecKT54.cjs.map +1 -0
  46. package/dist/createStore-BfmRfZ_2.js +1229 -0
  47. package/dist/createStore-BfmRfZ_2.js.map +1 -0
  48. package/dist/date-Bj4O2W1F.js.map +1 -1
  49. package/dist/date-CRCe-9gf.cjs.map +1 -1
  50. package/dist/decorators-CKneHgoF.js +56 -0
  51. package/dist/decorators-CKneHgoF.js.map +1 -0
  52. package/dist/decorators-DCVYKzrL.cjs +2 -0
  53. package/dist/decorators-DCVYKzrL.cjs.map +1 -0
  54. package/dist/index.cjs +1 -1
  55. package/dist/index.cjs.map +1 -1
  56. package/dist/index.d.ts +2 -1
  57. package/dist/index.d.ts.map +1 -1
  58. package/dist/index.js +100 -90
  59. package/dist/index.js.map +1 -1
  60. package/dist/inspector/ConsoleInspector.d.ts +49 -0
  61. package/dist/inspector/ConsoleInspector.d.ts.map +1 -0
  62. package/dist/inspector/DevToolsBridge.d.ts +21 -0
  63. package/dist/inspector/DevToolsBridge.d.ts.map +1 -0
  64. package/dist/inspector/QueryParser.d.ts +21 -0
  65. package/dist/inspector/QueryParser.d.ts.map +1 -0
  66. package/dist/inspector/StoreInspector.d.ts +31 -0
  67. package/dist/inspector/StoreInspector.d.ts.map +1 -0
  68. package/dist/inspector/index.cjs +17 -0
  69. package/dist/inspector/index.cjs.map +1 -0
  70. package/dist/inspector/index.d.ts +9 -0
  71. package/dist/inspector/index.d.ts.map +1 -0
  72. package/dist/inspector/index.js +896 -0
  73. package/dist/inspector/index.js.map +1 -0
  74. package/dist/inspector/integration.d.ts +15 -0
  75. package/dist/inspector/integration.d.ts.map +1 -0
  76. package/dist/inspector/serialization.d.ts +7 -0
  77. package/dist/inspector/serialization.d.ts.map +1 -0
  78. package/dist/inspector/types.d.ts +139 -0
  79. package/dist/inspector/types.d.ts.map +1 -0
  80. package/dist/json-api/index.cjs +1 -1
  81. package/dist/json-api/index.js +1 -1
  82. package/dist/mdql/MdqlMemoryExecutor.d.ts +17 -0
  83. package/dist/mdql/MdqlMemoryExecutor.d.ts.map +1 -0
  84. package/dist/mdql/MdqlQueryBuilder.d.ts +38 -0
  85. package/dist/mdql/MdqlQueryBuilder.d.ts.map +1 -0
  86. package/dist/mdql/MdqlValidator.d.ts +13 -0
  87. package/dist/mdql/MdqlValidator.d.ts.map +1 -0
  88. package/dist/mdql/index.d.ts +6 -0
  89. package/dist/mdql/index.d.ts.map +1 -0
  90. package/dist/mdql/types.d.ts +48 -0
  91. package/dist/mdql/types.d.ts.map +1 -0
  92. package/dist/model/Model.d.ts +4 -0
  93. package/dist/model/Model.d.ts.map +1 -1
  94. package/dist/model/Snapshot.d.ts +2 -0
  95. package/dist/model/Snapshot.d.ts.map +1 -1
  96. package/dist/model/index.cjs +1 -1
  97. package/dist/model/index.js +1 -1
  98. package/dist/odata/ODataAdapter.d.ts.map +1 -1
  99. package/dist/odata/index.cjs +1 -1
  100. package/dist/odata/index.js +1 -1
  101. package/dist/relationships-BgM0NKdb.cjs +2 -0
  102. package/dist/relationships-BgM0NKdb.cjs.map +1 -0
  103. package/dist/{relationships-BEXANmWg.js → relationships-DvSi8fVN.js} +37 -28
  104. package/dist/relationships-DvSi8fVN.js.map +1 -0
  105. package/dist/request/CacheHandler.d.ts.map +1 -1
  106. package/dist/request/index.cjs +1 -1
  107. package/dist/request/index.js +1 -1
  108. package/dist/schema/SchemaService.d.ts +38 -1
  109. package/dist/schema/SchemaService.d.ts.map +1 -1
  110. package/dist/schema/decorators.d.ts +20 -1
  111. package/dist/schema/decorators.d.ts.map +1 -1
  112. package/dist/schema/index.cjs +1 -1
  113. package/dist/schema/index.d.ts +1 -1
  114. package/dist/schema/index.d.ts.map +1 -1
  115. package/dist/schema/index.js +10 -8
  116. package/dist/schema/types.d.ts +31 -0
  117. package/dist/schema/types.d.ts.map +1 -1
  118. package/dist/serializer/JsonSerializer.d.ts +2 -0
  119. package/dist/serializer/JsonSerializer.d.ts.map +1 -1
  120. package/dist/serializer/Serializer.d.ts +9 -0
  121. package/dist/serializer/Serializer.d.ts.map +1 -1
  122. package/dist/serializer/index.cjs +1 -1
  123. package/dist/serializer/index.js +6 -5
  124. package/dist/serializer/index.js.map +1 -1
  125. package/dist/store/Store.d.ts +3 -0
  126. package/dist/store/Store.d.ts.map +1 -1
  127. package/dist/store/createStore.d.ts +12 -0
  128. package/dist/store/createStore.d.ts.map +1 -0
  129. package/dist/store/index.cjs +1 -1
  130. package/dist/store/index.d.ts +1 -0
  131. package/dist/store/index.d.ts.map +1 -1
  132. package/dist/store/index.js +5 -4
  133. package/dist/types-CC2fG3FP.js +8 -0
  134. package/dist/types-CC2fG3FP.js.map +1 -0
  135. package/dist/types-DCLy5XYj.cjs +2 -0
  136. package/dist/types-DCLy5XYj.cjs.map +1 -0
  137. package/package.json +7 -1
  138. package/src/index.ts +3 -0
  139. package/src/inspector/ConsoleInspector.ts +470 -0
  140. package/src/inspector/DevToolsBridge.ts +214 -0
  141. package/src/inspector/QueryParser.ts +343 -0
  142. package/src/inspector/StoreInspector.ts +162 -0
  143. package/src/inspector/index.ts +20 -0
  144. package/src/inspector/integration.ts +56 -0
  145. package/src/inspector/serialization.ts +100 -0
  146. package/src/inspector/types.ts +161 -0
  147. package/src/mdql/MdqlMemoryExecutor.ts +229 -0
  148. package/src/mdql/MdqlQueryBuilder.ts +170 -0
  149. package/src/mdql/MdqlValidator.ts +193 -0
  150. package/src/mdql/index.ts +21 -0
  151. package/src/mdql/types.ts +107 -0
  152. package/src/model/Model.ts +15 -0
  153. package/src/model/Snapshot.ts +3 -0
  154. package/src/odata/ODataAdapter.ts +4 -1
  155. package/src/request/CacheHandler.ts +2 -6
  156. package/src/schema/SchemaService.ts +123 -1
  157. package/src/schema/decorators.ts +29 -0
  158. package/src/schema/index.ts +1 -1
  159. package/src/schema/types.ts +34 -0
  160. package/src/serializer/JsonSerializer.ts +14 -2
  161. package/src/serializer/Serializer.ts +24 -1
  162. package/src/store/Store.ts +57 -14
  163. package/src/store/createStore.ts +39 -0
  164. package/src/store/index.ts +1 -0
  165. package/dist/CacheHandler-BTU_rYkv.js.map +0 -1
  166. package/dist/CacheHandler-CXgY9IJo.cjs.map +0 -1
  167. package/dist/EmbeddedRecordsMixin-CBvqNdgC.cjs +0 -2
  168. package/dist/EmbeddedRecordsMixin-CBvqNdgC.cjs.map +0 -1
  169. package/dist/EmbeddedRecordsMixin-VoHluHCT.js +0 -261
  170. package/dist/EmbeddedRecordsMixin-VoHluHCT.js.map +0 -1
  171. package/dist/JsonApiSerializer-BLoE046A.js.map +0 -1
  172. package/dist/JsonApiSerializer-DKemcyw-.cjs.map +0 -1
  173. package/dist/ODataAdapter-CrDFvBEZ.cjs.map +0 -1
  174. package/dist/ODataAdapter-RQUjVTcf.js.map +0 -1
  175. package/dist/RestAdapter-CSoJg7D2.cjs +0 -2
  176. package/dist/RestAdapter-CSoJg7D2.cjs.map +0 -1
  177. package/dist/RestAdapter-D6bGIHZT.js.map +0 -1
  178. package/dist/SchemaService-DZwkFgZu.js +0 -102
  179. package/dist/SchemaService-DZwkFgZu.js.map +0 -1
  180. package/dist/SchemaService-Di_yjVzU.cjs +0 -2
  181. package/dist/SchemaService-Di_yjVzU.cjs.map +0 -1
  182. package/dist/Serializer-95gi5edy.cjs +0 -2
  183. package/dist/Serializer-95gi5edy.cjs.map +0 -1
  184. package/dist/Serializer-FxJbsZ50.js.map +0 -1
  185. package/dist/Store-Bm5JivTc.js +0 -957
  186. package/dist/Store-Bm5JivTc.js.map +0 -1
  187. package/dist/Store-DX9D0Mmy.cjs +0 -2
  188. package/dist/Store-DX9D0Mmy.cjs.map +0 -1
  189. package/dist/cache-utils-B2wFhisx.js +0 -39
  190. package/dist/cache-utils-B2wFhisx.js.map +0 -1
  191. package/dist/cache-utils-CSwsqOi3.cjs +0 -2
  192. package/dist/cache-utils-CSwsqOi3.cjs.map +0 -1
  193. package/dist/decorators-HQ1KnRdh.cjs +0 -2
  194. package/dist/decorators-HQ1KnRdh.cjs.map +0 -1
  195. package/dist/decorators-Zr35qr6A.js +0 -50
  196. package/dist/decorators-Zr35qr6A.js.map +0 -1
  197. package/dist/relationships-B55LBaCW.cjs +0 -2
  198. package/dist/relationships-B55LBaCW.cjs.map +0 -1
  199. package/dist/relationships-BEXANmWg.js.map +0 -1
  200. package/dist/types-C9NB2gRj.js +0 -7
  201. package/dist/types-C9NB2gRj.js.map +0 -1
  202. package/dist/types-uWOXMPWW.cjs +0 -2
  203. package/dist/types-uWOXMPWW.cjs.map +0 -1
@@ -1,261 +0,0 @@
1
- import { injectable as _ } from "tsyringe";
2
- import R from "pluralize";
3
- import { S as g } from "./Serializer-FxJbsZ50.js";
4
- var v = Object.getOwnPropertyDescriptor, w = (t, a, i, s) => {
5
- for (var r = s > 1 ? void 0 : s ? v(a, i) : a, e = t.length - 1, n; e >= 0; e--)
6
- (n = t[e]) && (r = n(r) || r);
7
- return r;
8
- };
9
- let z = class extends g {
10
- static dispatchMethodName(t) {
11
- switch (t) {
12
- case "findRecord":
13
- return "normalizeFindRecordResponse";
14
- case "findAll":
15
- return "normalizeFindAllResponse";
16
- case "query":
17
- return "normalizeQueryResponse";
18
- case "queryRecord":
19
- return "normalizeQueryRecordResponse";
20
- case "createRecord":
21
- return "normalizeCreateRecordResponse";
22
- case "updateRecord":
23
- return "normalizeUpdateRecordResponse";
24
- case "deleteRecord":
25
- return "normalizeDeleteRecordResponse";
26
- default:
27
- return null;
28
- }
29
- }
30
- /**
31
- * Normalizes a single flat JSON object into a `NormalizedResource`.
32
- * Returns `null` for absent or non-object payloads.
33
- */
34
- normalize(t, a, i, s) {
35
- if (i == null || typeof i != "object")
36
- return null;
37
- const r = i, e = this.extractId(a, r), n = this.extractAttributes(a, r), o = this.extractRelationships(a, r), l = {
38
- type: a.modelName,
39
- id: e,
40
- attributes: n
41
- };
42
- return o && Object.keys(o).length > 0 && (l.relationships = o), l;
43
- }
44
- /**
45
- * Entry point for normalization.
46
- *
47
- * Checks whether a subclass has overridden the relevant per-operation hook
48
- * (e.g. `normalizeFindRecordResponse`). If so, calls it; otherwise falls
49
- * through to `_buildDocument`.
50
- */
51
- normalizeResponse(t, a, i, s, r) {
52
- const e = z.dispatchMethodName(r);
53
- if (e) {
54
- const n = this[e], o = g.prototype[e];
55
- if (typeof n == "function" && n !== o)
56
- return n.call(
57
- this,
58
- t,
59
- a,
60
- i,
61
- s,
62
- r
63
- );
64
- }
65
- return this._buildDocument(t, a, i, s, r);
66
- }
67
- /**
68
- * Builds a `NormalizedDocument` from a raw payload.
69
- * Arrays are normalized item by item; plain objects are normalized as a
70
- * single resource.
71
- */
72
- _buildDocument(t, a, i, s, r) {
73
- return i == null ? { data: null } : Array.isArray(i) ? { data: i.map((o) => this.normalize(t, a, o)).filter((o) => o !== null) } : { data: this.normalize(t, a, i) };
74
- }
75
- /**
76
- * Serializes a snapshot to a flat JSON object.
77
- * Includes `id` when `options.includeId` is `true`.
78
- */
79
- serialize(t, a) {
80
- const i = {};
81
- return a != null && a.includeId && t.id !== null && (i[this.primaryKey] = t.id), t.eachAttribute((s, r) => {
82
- this.serializeAttribute(t, i, s, r);
83
- }), t.eachRelationship((s, r) => {
84
- r.kind === "belongsTo" ? this.serializeBelongsTo(t, i, r) : this.serializeHasMany(t, i, r);
85
- }), i;
86
- }
87
- };
88
- z = w([
89
- _()
90
- ], z);
91
- var M = Object.getOwnPropertyDescriptor, x = (t, a, i, s) => {
92
- for (var r = s > 1 ? void 0 : s ? M(a, i) : a, e = t.length - 1, n; e >= 0; e--)
93
- (n = t[e]) && (r = n(r) || r);
94
- return r;
95
- };
96
- let A = class extends z {
97
- /**
98
- * Returns the plural payload key for a model name.
99
- * e.g. `'post'` → `'posts'`
100
- */
101
- payloadKeyFromModelName(t) {
102
- return R.plural(t);
103
- }
104
- /**
105
- * Returns the model name for a payload root key.
106
- * e.g. `'posts'` → `'post'`
107
- */
108
- modelNameFromPayloadKey(t) {
109
- return R.singular(t);
110
- }
111
- /**
112
- * Builds a `NormalizedDocument` from a root-key REST payload.
113
- *
114
- * - Looks for the model data under the singular or plural root key.
115
- * - Treats every other non-reserved key as a sideloaded type.
116
- * - Preserves `meta` and `links` from the root.
117
- */
118
- _buildDocument(t, a, i, s, r) {
119
- if (i == null || typeof i != "object")
120
- return { data: null };
121
- const e = i, n = a.modelName, o = this.payloadKeyFromModelName(n);
122
- let l = null;
123
- const u = /* @__PURE__ */ new Set();
124
- if (n in e) {
125
- u.add(n);
126
- const d = e[n];
127
- Array.isArray(d) ? l = d.map((c) => this.normalize(t, a, c)).filter((c) => c !== null) : l = this.normalize(t, a, d);
128
- } else if (o in e) {
129
- u.add(o);
130
- const d = e[o];
131
- Array.isArray(d) ? l = d.map((c) => this.normalize(t, a, c)).filter((c) => c !== null) : l = this.normalize(t, a, d);
132
- }
133
- const m = [];
134
- for (const [d, c] of Object.entries(e)) {
135
- if (u.has(d) || d === "meta" || d === "links")
136
- continue;
137
- const y = {
138
- modelName: this.modelNameFromPayloadKey(d),
139
- attributes: /* @__PURE__ */ new Map(),
140
- relationships: /* @__PURE__ */ new Map()
141
- };
142
- if (Array.isArray(c))
143
- for (const h of c) {
144
- const b = this.normalize(t, y, h);
145
- b && m.push(b);
146
- }
147
- else if (c && typeof c == "object") {
148
- const h = this.normalize(t, y, c);
149
- h && m.push(h);
150
- }
151
- }
152
- const f = { data: l };
153
- return m.length > 0 && (f.included = m), e.meta && typeof e.meta == "object" && (f.meta = e.meta), e.links && typeof e.links == "object" && (f.links = e.links), f;
154
- }
155
- };
156
- A = x([
157
- _()
158
- ], A);
159
- function I(t) {
160
- class a extends t {
161
- constructor() {
162
- super(...arguments), this.pendingIncluded = [];
163
- }
164
- /**
165
- * Intercepts raw payload hashes to extract embedded records.
166
- *
167
- * For each relationship configured with `embedded: 'always'`:
168
- * - Recursively normalizes the embedded object(s) and adds them to
169
- * `pendingIncluded`.
170
- * - Replaces the embedded value in the hash with the extracted id(s) so
171
- * `super.normalize` treats it as a plain id reference.
172
- */
173
- normalize(s, r, e, n) {
174
- if (!e || typeof e != "object" || Array.isArray(e))
175
- return super.normalize(s, r, e, n);
176
- const o = e, l = this.attrs ?? {}, u = { ...o };
177
- for (const [m, f] of r.relationships) {
178
- const d = l[m];
179
- if (!d || d.embedded !== "always")
180
- continue;
181
- const c = u[m];
182
- if (c != null) {
183
- if (f.kind === "hasMany" && Array.isArray(c)) {
184
- const p = [];
185
- for (const y of c) {
186
- const h = this.extractEmbeddedResource(s, f, y);
187
- h && h.id !== null && (p.push(h.id), this.pendingIncluded.push(h));
188
- }
189
- u[m] = p;
190
- } else if (f.kind === "belongsTo" && typeof c == "object" && !Array.isArray(c)) {
191
- const p = this.extractEmbeddedResource(s, f, c);
192
- p && p.id !== null && (this.pendingIncluded.push(p), u[m] = p.id);
193
- }
194
- }
195
- }
196
- return super.normalize(s, r, u, n);
197
- }
198
- /**
199
- * Resets `pendingIncluded`, delegates to `super.normalizeResponse`, then
200
- * appends any extracted embedded resources to `document.included`.
201
- */
202
- normalizeResponse(s, r, e, n, o) {
203
- this.pendingIncluded = [];
204
- const l = super.normalizeResponse(s, r, e, n, o);
205
- if (this.pendingIncluded.length > 0) {
206
- const u = l.included ? [...l.included] : [];
207
- u.push(...this.pendingIncluded), l.included = u, this.pendingIncluded = [];
208
- }
209
- return l;
210
- }
211
- /**
212
- * When `serialize: 'records'` is configured, writes the full related
213
- * record objects instead of just ids.
214
- */
215
- serializeHasMany(s, r, e) {
216
- var o;
217
- const n = (o = this.attrs) == null ? void 0 : o[e.name];
218
- if ((n == null ? void 0 : n.serialize) === "records") {
219
- const l = s.hasMany(e.name);
220
- r[this.keyForRelationship(e.name)] = l ?? [];
221
- return;
222
- }
223
- super.serializeHasMany(s, r, e);
224
- }
225
- /**
226
- * When `serialize: 'records'` is configured, writes the full related
227
- * record object instead of just the id.
228
- */
229
- serializeBelongsTo(s, r, e) {
230
- var o;
231
- const n = (o = this.attrs) == null ? void 0 : o[e.name];
232
- if ((n == null ? void 0 : n.serialize) === "records") {
233
- const l = s.belongsTo(e.name);
234
- r[this.keyForRelationship(e.name)] = l ?? null;
235
- return;
236
- }
237
- super.serializeBelongsTo(s, r, e);
238
- }
239
- /**
240
- * Normalizes a single embedded resource object using the related model's
241
- * type as a placeholder `ModelClassMeta`.
242
- */
243
- extractEmbeddedResource(s, r, e) {
244
- if (!e || typeof e != "object" || Array.isArray(e))
245
- return null;
246
- const n = {
247
- modelName: r.type,
248
- attributes: /* @__PURE__ */ new Map(),
249
- relationships: /* @__PURE__ */ new Map()
250
- };
251
- return this.normalize(s, n, e);
252
- }
253
- }
254
- return a;
255
- }
256
- export {
257
- I as E,
258
- z as J,
259
- A as R
260
- };
261
- //# sourceMappingURL=EmbeddedRecordsMixin-VoHluHCT.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"EmbeddedRecordsMixin-VoHluHCT.js","sources":["../src/serializer/JsonSerializer.ts","../src/serializer/RestSerializer.ts","../src/serializer/EmbeddedRecordsMixin.ts"],"sourcesContent":["/**\n * Flat-JSON serializer for simple REST APIs.\n *\n * `JsonSerializer` expects payloads to be plain JSON objects or arrays with\n * no root-key wrapping. It is the lowest-level concrete serializer and the\n * base that `RestSerializer` extends.\n *\n * Normalization:\n * - Array payload → `{ data: [NormalizedResource, …] }`\n * - Object payload → `{ data: NormalizedResource }`\n * - `null` / `undefined` → `{ data: null }`\n *\n * Serialization:\n * - Iterates `@attr` → writes via `serializeAttribute`\n * - Iterates `@belongsTo` / `@hasMany` → writes via `serializeBelongsTo` /\n * `serializeHasMany`\n *\n * `normalizeResponse` automatically dispatches to the correct per-operation\n * hook (`normalizeFindRecordResponse`, etc.) when a subclass overrides them.\n * If no override exists it falls through to `_buildDocument`.\n */\n\nimport { injectable } from 'tsyringe';\nimport {\n Serializer,\n type ModelClassMeta,\n type NormalizeRequestType,\n type NormalizedDocument,\n type NormalizedResource,\n type SerializerSnapshot,\n} from './Serializer.js';\n\n@injectable()\nexport class JsonSerializer extends Serializer {\n static dispatchMethodName(\n requestType: NormalizeRequestType,\n ): keyof Serializer | null {\n switch (requestType) {\n case 'findRecord':\n return 'normalizeFindRecordResponse';\n case 'findAll':\n return 'normalizeFindAllResponse';\n case 'query':\n return 'normalizeQueryResponse';\n case 'queryRecord':\n return 'normalizeQueryRecordResponse';\n case 'createRecord':\n return 'normalizeCreateRecordResponse';\n case 'updateRecord':\n return 'normalizeUpdateRecordResponse';\n case 'deleteRecord':\n return 'normalizeDeleteRecordResponse';\n default:\n return null;\n }\n }\n\n /**\n * Normalizes a single flat JSON object into a `NormalizedResource`.\n * Returns `null` for absent or non-object payloads.\n */\n override normalize(\n _store: unknown,\n modelClass: ModelClassMeta,\n payload: unknown,\n _prop?: string,\n ): NormalizedResource | null {\n if (payload === null || payload === undefined) {\n return null;\n }\n if (typeof payload !== 'object') {\n return null;\n }\n const hash = payload as Record<string, unknown>;\n const id = this.extractId(modelClass, hash);\n const attributes = this.extractAttributes(modelClass, hash);\n const relationships = this.extractRelationships(modelClass, hash);\n\n const resource: NormalizedResource = {\n type: modelClass.modelName,\n id,\n attributes,\n };\n if (relationships && Object.keys(relationships).length > 0) {\n resource.relationships = relationships;\n }\n return resource;\n }\n\n /**\n * Entry point for normalization.\n *\n * Checks whether a subclass has overridden the relevant per-operation hook\n * (e.g. `normalizeFindRecordResponse`). If so, calls it; otherwise falls\n * through to `_buildDocument`.\n */\n override normalizeResponse(\n store: unknown,\n modelClass: ModelClassMeta,\n payload: unknown,\n id: string | null,\n requestType: NormalizeRequestType,\n ): NormalizedDocument {\n const methodName = JsonSerializer.dispatchMethodName(requestType);\n if (methodName) {\n const override = (this as unknown as Record<string, unknown>)[methodName];\n const baseImpl = (Serializer.prototype as unknown as Record<string, unknown>)[\n methodName\n ];\n if (typeof override === 'function' && override !== baseImpl) {\n return (override as (...args: unknown[]) => NormalizedDocument).call(\n this,\n store,\n modelClass,\n payload,\n id,\n requestType,\n );\n }\n }\n return this._buildDocument(store, modelClass, payload, id, requestType);\n }\n\n /**\n * Builds a `NormalizedDocument` from a raw payload.\n * Arrays are normalized item by item; plain objects are normalized as a\n * single resource.\n */\n protected _buildDocument(\n store: unknown,\n modelClass: ModelClassMeta,\n payload: unknown,\n _id: string | null,\n _requestType: NormalizeRequestType,\n ): NormalizedDocument {\n if (payload === null || payload === undefined) {\n return { data: null };\n }\n if (Array.isArray(payload)) {\n const data = payload\n .map((p) => this.normalize(store, modelClass, p))\n .filter((r): r is NormalizedResource => r !== null);\n return { data };\n }\n const data = this.normalize(store, modelClass, payload);\n return { data };\n }\n\n /**\n * Serializes a snapshot to a flat JSON object.\n * Includes `id` when `options.includeId` is `true`.\n */\n override serialize(\n snapshot: SerializerSnapshot,\n options?: { includeId?: boolean },\n ): Record<string, unknown> {\n const json: Record<string, unknown> = {};\n if (options?.includeId && snapshot.id !== null) {\n json[this.primaryKey] = snapshot.id;\n }\n snapshot.eachAttribute((key, meta) => {\n this.serializeAttribute(snapshot, json, key, meta);\n });\n snapshot.eachRelationship((_key, rel) => {\n if (rel.kind === 'belongsTo') {\n this.serializeBelongsTo(snapshot, json, rel);\n } else {\n this.serializeHasMany(snapshot, json, rel);\n }\n });\n return json;\n }\n}\n","/**\n * REST serializer for root-key payloads with optional sideloading.\n *\n * `RestSerializer` expects the primary data to be wrapped under a root key\n * that matches either the singular or plural model name:\n *\n * ```json\n * { \"post\": { \"id\": \"1\", \"title\": \"Hello\" } }\n * { \"posts\": [{ \"id\": \"1\", … }, { \"id\": \"2\", … }] }\n * ```\n *\n * Any additional keys in the payload are treated as sideloaded (compound)\n * data. `meta` and `links` keys are reserved and forwarded to the document.\n *\n * Sideloaded types are inferred from the payload key via `modelNameFromPayloadKey`\n * (default: singularization).\n *\n * Extends `JsonSerializer` so it inherits flat `normalize` and `serialize`\n * behaviour and only overrides document-level parsing via `_buildDocument`.\n */\n\nimport { injectable } from 'tsyringe';\nimport pluralize from 'pluralize';\nimport {\n type ModelClassMeta,\n type NormalizeRequestType,\n type NormalizedDocument,\n type NormalizedResource,\n} from './Serializer.js';\nimport { JsonSerializer } from './JsonSerializer.js';\n\n@injectable()\nexport class RestSerializer extends JsonSerializer {\n /**\n * Returns the plural payload key for a model name.\n * e.g. `'post'` → `'posts'`\n */\n payloadKeyFromModelName(modelName: string): string {\n return pluralize.plural(modelName);\n }\n\n /**\n * Returns the model name for a payload root key.\n * e.g. `'posts'` → `'post'`\n */\n modelNameFromPayloadKey(key: string): string {\n return pluralize.singular(key);\n }\n\n /**\n * Builds a `NormalizedDocument` from a root-key REST payload.\n *\n * - Looks for the model data under the singular or plural root key.\n * - Treats every other non-reserved key as a sideloaded type.\n * - Preserves `meta` and `links` from the root.\n */\n protected override _buildDocument(\n store: unknown,\n modelClass: ModelClassMeta,\n payload: unknown,\n _id: string | null,\n _requestType: NormalizeRequestType,\n ): NormalizedDocument {\n if (payload === null || payload === undefined || typeof payload !== 'object') {\n return { data: null };\n }\n const hash = payload as Record<string, unknown>;\n const singular = modelClass.modelName;\n const plural = this.payloadKeyFromModelName(singular);\n\n let data: NormalizedResource | NormalizedResource[] | null = null;\n const primaryKeys = new Set<string>();\n\n if (singular in hash) {\n primaryKeys.add(singular);\n const raw = hash[singular];\n if (Array.isArray(raw)) {\n data = raw\n .map((entry) => this.normalize(store, modelClass, entry))\n .filter((resource): resource is NormalizedResource => resource !== null);\n } else {\n data = this.normalize(store, modelClass, raw);\n }\n } else if (plural in hash) {\n primaryKeys.add(plural);\n const raw = hash[plural];\n if (Array.isArray(raw)) {\n data = raw\n .map((entry) => this.normalize(store, modelClass, entry))\n .filter((resource): resource is NormalizedResource => resource !== null);\n } else {\n data = this.normalize(store, modelClass, raw);\n }\n }\n\n // Collect sideloaded records from all remaining root keys.\n const included: NormalizedResource[] = [];\n for (const [key, value] of Object.entries(hash)) {\n if (primaryKeys.has(key)) {\n continue;\n }\n if (key === 'meta' || key === 'links') {\n continue;\n }\n const sideloadType = this.modelNameFromPayloadKey(key);\n const sideloadClass: ModelClassMeta = {\n modelName: sideloadType,\n attributes: new Map(),\n relationships: new Map(),\n };\n if (Array.isArray(value)) {\n for (const item of value) {\n const normalized = this.normalize(store, sideloadClass, item);\n if (normalized) {\n included.push(normalized);\n }\n }\n } else if (value && typeof value === 'object') {\n const normalized = this.normalize(store, sideloadClass, value);\n if (normalized) {\n included.push(normalized);\n }\n }\n }\n\n const doc: NormalizedDocument = { data };\n if (included.length > 0) {\n doc.included = included;\n }\n if (hash.meta && typeof hash.meta === 'object') {\n doc.meta = hash.meta as Record<string, unknown>;\n }\n if (hash.links && typeof hash.links === 'object') {\n doc.links = hash.links as Record<string, string>;\n }\n return doc;\n }\n}\n","/**\n * Mixin that adds support for embedded (nested) records in REST payloads.\n *\n * Apply with:\n * ```ts\n * class PostSerializer extends EmbeddedRecordsMixin(RestSerializer) {\n * attrs = {\n * comments: { embedded: 'always' },\n * author: { embedded: 'always', serialize: 'records' },\n * };\n * }\n * ```\n *\n * ## How it works\n *\n * ### Deserialization\n * When `embedded: 'always'` is set for a relationship, `normalize()` intercepts\n * the raw payload before passing it to `super.normalize()`:\n * - For `hasMany`: replaces the nested array with a plain id array and queues\n * each nested object as an `included` resource.\n * - For `belongsTo`: replaces the nested object with the extracted id and\n * queues the nested object as an `included` resource.\n *\n * Queued resources are collected during `normalizeResponse()` and appended to\n * `document.included` so the `Store` can push them into the identity map.\n *\n * ### Serialization\n * When `serialize: 'records'` is set, `serializeHasMany` / `serializeBelongsTo`\n * write the full related record(s) into the payload instead of just ids.\n *\n * ## Configuration\n *\n * Each entry in `attrs` is an `EmbeddedAttrConfig`:\n * - `embedded: 'always'` — enable embedded deserialization.\n * - `serialize: 'records'` — write full records on serialize.\n * - `serialize: 'ids'` — write id array on serialize (default).\n * - `serialize: false` — omit relationship from serialized payload.\n * - `deserialize: 'records'` — same as `embedded: 'always'`.\n * - `deserialize: false` — ignore this relationship during normalization.\n */\n\nimport type { RelationshipDef } from '@mobx-data/schema';\nimport type {\n ModelClassMeta,\n NormalizeRequestType,\n NormalizedDocument,\n NormalizedResource,\n SerializerSnapshot,\n} from './Serializer.js';\n\n/** Per-relationship embedding configuration. */\nexport interface EmbeddedAttrConfig {\n /** `'always'` to deserialize embedded records; `'never'` to skip. */\n embedded?: 'always' | 'never';\n /** `'records'` to serialize full objects; `'ids'` for ids only; `false` to omit. */\n serialize?: 'records' | 'ids' | false;\n /** `'records'` to deserialize embedded objects; `'ids'` for plain ids; `false` to skip. */\n deserialize?: 'records' | 'ids' | false;\n}\n\n/** Map of relationship name → embedding config. */\nexport interface EmbeddedRecordsAttrs {\n [key: string]: EmbeddedAttrConfig;\n}\n\n/**\n * The minimal serializer interface required by the mixin.\n * Any class extending `JsonSerializer` satisfies this.\n */\nexport interface JsonSerializerLike {\n attrs?: EmbeddedRecordsAttrs;\n primaryKey: string;\n normalize(\n store: unknown,\n modelClass: ModelClassMeta,\n payload: unknown,\n prop?: string,\n ): NormalizedResource | null;\n normalizeResponse(\n store: unknown,\n modelClass: ModelClassMeta,\n payload: unknown,\n id: string | null,\n requestType: NormalizeRequestType,\n ): NormalizedDocument;\n serialize(\n snapshot: SerializerSnapshot,\n options?: { includeId?: boolean },\n ): Record<string, unknown>;\n serializeHasMany(\n snapshot: SerializerSnapshot,\n json: Record<string, unknown>,\n relationship: RelationshipDef,\n ): void;\n serializeBelongsTo(\n snapshot: SerializerSnapshot,\n json: Record<string, unknown>,\n relationship: RelationshipDef,\n ): void;\n keyForAttribute(key: string): string;\n keyForRelationship(key: string): string;\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype Constructor<T> = new (...args: any[]) => T;\n\n/**\n * Returns a new class that extends `Base` with embedded-record support.\n * `Base` must be (or extend) `JsonSerializer`.\n */\nexport function EmbeddedRecordsMixin<\n TBase extends Constructor<JsonSerializerLike>,\n>(Base: TBase): TBase {\n class WithEmbeddedRecords extends Base {\n override attrs?: EmbeddedRecordsAttrs;\n\n /** Accumulates extracted embedded resources during a `normalizeResponse` call. */\n private pendingIncluded: NormalizedResource[] = [];\n\n /**\n * Intercepts raw payload hashes to extract embedded records.\n *\n * For each relationship configured with `embedded: 'always'`:\n * - Recursively normalizes the embedded object(s) and adds them to\n * `pendingIncluded`.\n * - Replaces the embedded value in the hash with the extracted id(s) so\n * `super.normalize` treats it as a plain id reference.\n */\n override normalize(\n store: unknown,\n modelClass: ModelClassMeta,\n payload: unknown,\n prop?: string,\n ): NormalizedResource | null {\n if (!payload || typeof payload !== 'object' || Array.isArray(payload)) {\n return super.normalize(store, modelClass, payload, prop);\n }\n const src = payload as Record<string, unknown>;\n const attrs = this.attrs ?? {};\n const hash: Record<string, unknown> = { ...src };\n\n for (const [name, rel] of modelClass.relationships) {\n const cfg = attrs[name];\n if (!cfg || cfg.embedded !== 'always') {\n continue;\n }\n const raw = hash[name];\n if (raw === undefined || raw === null) {\n continue;\n }\n\n if (rel.kind === 'hasMany' && Array.isArray(raw)) {\n const ids: string[] = [];\n for (const item of raw) {\n const extracted = this.extractEmbeddedResource(store, rel, item);\n if (extracted && extracted.id !== null) {\n ids.push(extracted.id);\n this.pendingIncluded.push(extracted);\n }\n }\n hash[name] = ids;\n } else if (\n rel.kind === 'belongsTo'\n && typeof raw === 'object'\n && !Array.isArray(raw)\n ) {\n const extracted = this.extractEmbeddedResource(store, rel, raw);\n if (extracted && extracted.id !== null) {\n this.pendingIncluded.push(extracted);\n hash[name] = extracted.id;\n }\n }\n }\n\n return super.normalize(store, modelClass, hash, prop);\n }\n\n /**\n * Resets `pendingIncluded`, delegates to `super.normalizeResponse`, then\n * appends any extracted embedded resources to `document.included`.\n */\n override normalizeResponse(\n store: unknown,\n modelClass: ModelClassMeta,\n payload: unknown,\n id: string | null,\n requestType: NormalizeRequestType,\n ): NormalizedDocument {\n this.pendingIncluded = [];\n const doc = super.normalizeResponse(store, modelClass, payload, id, requestType);\n if (this.pendingIncluded.length > 0) {\n const included = doc.included ? [...doc.included] : [];\n included.push(...this.pendingIncluded);\n doc.included = included;\n this.pendingIncluded = [];\n }\n return doc;\n }\n\n /**\n * When `serialize: 'records'` is configured, writes the full related\n * record objects instead of just ids.\n */\n override serializeHasMany(\n snapshot: SerializerSnapshot,\n json: Record<string, unknown>,\n relationship: RelationshipDef,\n ): void {\n const cfg = this.attrs?.[relationship.name];\n if (cfg?.serialize === 'records') {\n const records = snapshot.hasMany(relationship.name) as unknown[];\n json[this.keyForRelationship(relationship.name)] = records ?? [];\n return;\n }\n super.serializeHasMany(snapshot, json, relationship);\n }\n\n /**\n * When `serialize: 'records'` is configured, writes the full related\n * record object instead of just the id.\n */\n override serializeBelongsTo(\n snapshot: SerializerSnapshot,\n json: Record<string, unknown>,\n relationship: RelationshipDef,\n ): void {\n const cfg = this.attrs?.[relationship.name];\n if (cfg?.serialize === 'records') {\n const record = snapshot.belongsTo(relationship.name);\n json[this.keyForRelationship(relationship.name)] = record ?? null;\n return;\n }\n super.serializeBelongsTo(snapshot, json, relationship);\n }\n\n /**\n * Normalizes a single embedded resource object using the related model's\n * type as a placeholder `ModelClassMeta`.\n */\n private extractEmbeddedResource(\n store: unknown,\n rel: RelationshipDef,\n item: unknown,\n ): NormalizedResource | null {\n if (!item || typeof item !== 'object' || Array.isArray(item)) {\n return null;\n }\n const embeddedClass: ModelClassMeta = {\n modelName: rel.type,\n attributes: new Map(),\n relationships: new Map(),\n };\n return this.normalize(store, embeddedClass, item);\n }\n }\n return WithEmbeddedRecords as unknown as TBase;\n}\n"],"names":["JsonSerializer","Serializer","requestType","_store","modelClass","payload","_prop","hash","id","attributes","relationships","resource","store","methodName","override","baseImpl","_id","_requestType","p","r","data","snapshot","options","json","key","meta","_key","rel","__decorateClass","injectable","RestSerializer","modelName","pluralize","singular","plural","primaryKeys","raw","entry","included","value","sideloadClass","item","normalized","doc","EmbeddedRecordsMixin","Base","WithEmbeddedRecords","prop","src","attrs","name","cfg","ids","extracted","relationship","_a","records","record","embeddedClass"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"JsonApiSerializer-BLoE046A.js","sources":["../src/json-api/JsonApiAdapter.ts","../src/json-api/JsonApiSerializer.ts"],"sourcesContent":["/**\n * Adapter that implements the [JSON:API](https://jsonapi.org) specification.\n *\n * Extends `RestAdapter` with the following differences:\n *\n * - **MIME types** — `Accept` and `Content-Type` headers are set to\n * `application/vnd.api+json` as required by the spec.\n * - **PATCH for updates** — `updateRecord` uses `PATCH` instead of `PUT`.\n * - **`coalesceFindRequests: true`** — the store coalesces separate\n * `findRecord` calls into a single `findMany` request.\n *\n * URL construction is inherited from `RestAdapter` / `Adapter` unchanged;\n * override `pathForType` or `urlFor*` methods to customize.\n */\n\nimport { injectable } from 'tsyringe';\nimport { RestAdapter, type AdapterSnapshot } from '@mobx-data/adapter';\n\n@injectable()\nexport class JsonApiAdapter extends RestAdapter {\n /** Always coalesce `findRecord` calls into a single `findMany` request. */\n override coalesceFindRequests = true;\n\n /** Returns JSON:API `Accept` header alongside any custom headers. */\n override defaultHeaders(): Record<string, string> {\n return {\n Accept: 'application/vnd.api+json',\n ...this.headers,\n };\n }\n\n /** Returns JSON:API `Content-Type` header for mutation requests. */\n override mutationHeaders(): Record<string, string> {\n return {\n 'Content-Type': 'application/vnd.api+json',\n ...this.defaultHeaders(),\n };\n }\n\n /**\n * Sends a PATCH request to update a record (JSON:API mandates PATCH, not PUT).\n */\n override async updateRecord(\n _store: unknown,\n modelName: string,\n snapshot: AdapterSnapshot,\n ): Promise<unknown> {\n const url = this.buildURL(modelName, snapshot.id, snapshot, 'updateRecord');\n return this._fetchJSON(url, {\n method: 'PATCH',\n headers: this.mutationHeaders(),\n body: JSON.stringify(this._serializeForUpdate(snapshot)),\n });\n }\n\n /**\n * Sends a PATCH request with only the changed attributes (partial update).\n * Produces a JSON:API document with only the dirty attribute keys.\n */\n override async patchRecord(\n _store: unknown,\n modelName: string,\n snapshot: AdapterSnapshot,\n ): Promise<unknown> {\n const url = this.buildURL(modelName, snapshot.id, snapshot, 'updateRecord');\n const changed = snapshot.changedAttributes();\n const attributes: Record<string, unknown> = {};\n for (const [key, [, current]] of Object.entries(changed)) {\n attributes[key] = current;\n }\n const body = {\n data: {\n type: modelName,\n id: snapshot.id,\n attributes,\n },\n };\n return this._fetchJSON(url, {\n method: 'PATCH',\n headers: this.mutationHeaders(),\n body: JSON.stringify(body),\n });\n }\n\n /**\n * Extracts the raw data object from the snapshot for use as the PATCH body.\n * Subclasses may override this to produce a full JSON:API `{ data: … }` document.\n */\n protected _serializeForUpdate(snapshot: AdapterSnapshot): Record<string, unknown> {\n const rec = snapshot.record as { _data?: Record<string, unknown> };\n return rec._data ? { ...rec._data } : {};\n }\n}\n","/**\n * Serializer that implements the [JSON:API](https://jsonapi.org) specification.\n *\n * ## Normalization\n *\n * Parses a JSON:API compound document `{ data, included, meta, links }` into\n * a `NormalizedDocument`.\n *\n * For each resource object:\n * - `type` is converted from JSON:API plural form to model name via\n * `modelNameFromPayloadKey` (singularization).\n * - `id` is coerced to a string.\n * - `attributes` are copied directly.\n * - `relationships` data refs (`{ type, id }`) are normalized the same way.\n *\n * Side-loaded records in `included` are normalized individually, each using\n * its own `type` as the model class placeholder.\n *\n * ## Serialization\n *\n * Produces a JSON:API resource object wrapped in `{ data: … }`:\n *\n * ```json\n * {\n * \"data\": {\n * \"type\": \"posts\",\n * \"attributes\": { \"title\": \"Hello\" },\n * \"relationships\": {\n * \"author\": { \"data\": { \"type\": \"users\", \"id\": \"1\" } }\n * }\n * }\n * }\n * ```\n *\n * `id` is included when `options.includeId` is `true`.\n */\n\nimport { injectable } from 'tsyringe';\nimport pluralize from 'pluralize';\nimport {\n Serializer,\n type ModelClassMeta,\n type NormalizeRequestType,\n type NormalizedDocument,\n type NormalizedResource,\n type SerializerSnapshot,\n} from '@mobx-data/serializer';\n\n/** Internal shape of a raw JSON:API resource object. */\ninterface JsonApiResource {\n type: string;\n id?: string | number | null;\n attributes?: Record<string, unknown>;\n relationships?: Record<string, {\n data:\n | { type: string; id: string | number }\n | Array<{ type: string; id: string | number }>\n | null;\n }>;\n}\n\n@injectable()\nexport class JsonApiSerializer extends Serializer {\n /**\n * Returns the plural JSON:API `type` string for a model name.\n * e.g. `'post'` → `'posts'`\n */\n payloadKeyFromModelName(modelName: string): string {\n return pluralize.plural(modelName);\n }\n\n /**\n * Returns the model name for a JSON:API `type` string.\n * e.g. `'posts'` → `'post'`\n */\n modelNameFromPayloadKey(key: string): string {\n return pluralize.singular(key);\n }\n\n /**\n * Normalizes a single JSON:API resource object into a `NormalizedResource`.\n * Returns `null` for absent, non-object, or type-less payloads.\n */\n override normalize(\n _store: unknown,\n _modelClass: ModelClassMeta,\n payload: unknown,\n _prop?: string,\n ): NormalizedResource | null {\n if (!payload || typeof payload !== 'object' || Array.isArray(payload)) {\n return null;\n }\n const resource = payload as JsonApiResource;\n if (!resource.type) {\n return null;\n }\n const normalized: NormalizedResource = {\n type: this.modelNameFromPayloadKey(resource.type),\n id: resource.id === null || resource.id === undefined ? null : String(resource.id),\n };\n if (resource.attributes) {\n normalized.attributes = { ...resource.attributes };\n }\n if (resource.relationships) {\n const relationships: NonNullable<NormalizedResource['relationships']> = {};\n for (const [name, rel] of Object.entries(resource.relationships)) {\n if (rel.data === null) {\n relationships[name] = { data: null };\n } else if (Array.isArray(rel.data)) {\n relationships[name] = {\n data: rel.data.map((ref) => ({\n type: this.modelNameFromPayloadKey(ref.type),\n id: String(ref.id),\n })),\n };\n } else {\n relationships[name] = {\n data: {\n type: this.modelNameFromPayloadKey(rel.data.type),\n id: String(rel.data.id),\n },\n };\n }\n }\n normalized.relationships = relationships;\n }\n return normalized;\n }\n\n /**\n * Normalizes a full JSON:API compound document.\n *\n * - `data` (single or array) → primary resources\n * - `included` → side-loaded resources pushed to `normalizedDoc.included`\n * - `meta` and `links` → forwarded as-is\n */\n override normalizeResponse(\n store: unknown,\n modelClass: ModelClassMeta,\n payload: unknown,\n _id: string | null,\n _requestType: NormalizeRequestType,\n ): NormalizedDocument {\n if (!payload || typeof payload !== 'object') {\n return { data: null };\n }\n const doc = payload as {\n data?: JsonApiResource | JsonApiResource[] | null;\n included?: JsonApiResource[];\n meta?: Record<string, unknown>;\n links?: Record<string, string>;\n };\n\n let data: NormalizedResource | NormalizedResource[] | null = null;\n if (doc.data === null || doc.data === undefined) {\n data = null;\n } else if (Array.isArray(doc.data)) {\n data = doc.data\n .map((resource) => this.normalize(store, modelClass, resource))\n .filter((resource): resource is NormalizedResource => resource !== null);\n } else {\n data = this.normalize(store, modelClass, doc.data);\n }\n\n const normalizedDoc: NormalizedDocument = { data };\n if (doc.included && doc.included.length > 0) {\n const included: NormalizedResource[] = [];\n for (const resource of doc.included) {\n const placeholder: ModelClassMeta = {\n modelName: this.modelNameFromPayloadKey(resource.type),\n attributes: new Map(),\n relationships: new Map(),\n };\n const normalized = this.normalize(store, placeholder, resource);\n if (normalized) {\n included.push(normalized);\n }\n }\n normalizedDoc.included = included;\n }\n if (doc.meta) {\n normalizedDoc.meta = doc.meta;\n }\n if (doc.links) {\n normalizedDoc.links = doc.links;\n }\n return normalizedDoc;\n }\n\n /**\n * Serializes a record snapshot to a JSON:API `{ data: … }` document.\n *\n * Attributes are placed in `data.attributes`; relationships are placed in\n * `data.relationships` with proper `{ data: { type, id } }` structure.\n * `id` is included in `data` when `options.includeId` is `true`.\n */\n override serialize(\n snapshot: SerializerSnapshot,\n options?: { includeId?: boolean },\n ): Record<string, unknown> {\n const attributes: Record<string, unknown> = {};\n snapshot.eachAttribute((key) => {\n attributes[this.keyForAttribute(key)] = snapshot.attr(key);\n });\n\n const relationships: Record<string, { data: unknown }> = {};\n snapshot.eachRelationship((_key, rel) => {\n const { name } = rel;\n const payloadKey = this.keyForRelationship(name);\n const payloadType = this.payloadKeyFromModelName(rel.type);\n if (rel.kind === 'belongsTo') {\n const target = snapshot.belongsTo(name) as\n | { id: string; type?: string }\n | null\n | undefined;\n relationships[payloadKey] = target && target.id != null\n ? { data: { type: payloadType, id: String(target.id) } }\n : { data: null };\n } else {\n const targets = (snapshot.hasMany(name) as Array<{\n id: string; type?: string;\n }> | null) ?? [];\n relationships[payloadKey] = {\n data: targets.map((target) => ({\n type: payloadType,\n id: String(target.id),\n })),\n };\n }\n });\n\n const data: Record<string, unknown> = {\n type: this.payloadKeyFromModelName(snapshot.modelName),\n attributes,\n };\n if (options?.includeId && snapshot.id !== null) {\n data.id = snapshot.id;\n }\n if (Object.keys(relationships).length > 0) {\n data.relationships = relationships;\n }\n\n return { data };\n }\n}\n"],"names":["JsonApiAdapter","RestAdapter","_store","modelName","snapshot","url","changed","attributes","key","current","body","rec","__decorateClass","injectable","JsonApiSerializer","Serializer","pluralize","_modelClass","payload","_prop","resource","normalized","relationships","name","rel","ref","store","modelClass","_id","_requestType","doc","data","normalizedDoc","included","placeholder","options","_key","payloadKey","payloadType","target","targets"],"mappings":";;;;;;;;;AAmBO,IAAMA,IAAN,cAA6BC,EAAY;AAAA,EAAzC,cAAA;AAAA,UAAA,GAAA,SAAA,GAEL,KAAS,uBAAuB;AAAA,EAAA;AAAA;AAAA,EAGvB,iBAAyC;AAChD,WAAO;AAAA,MACL,QAAQ;AAAA,MACR,GAAG,KAAK;AAAA,IAAA;AAAA,EAEZ;AAAA;AAAA,EAGS,kBAA0C;AACjD,WAAO;AAAA,MACL,gBAAgB;AAAA,MAChB,GAAG,KAAK,eAAA;AAAA,IAAe;AAAA,EAE3B;AAAA;AAAA;AAAA;AAAA,EAKA,MAAe,aACbC,GACAC,GACAC,GACkB;AAClB,UAAMC,IAAM,KAAK,SAASF,GAAWC,EAAS,IAAIA,GAAU,cAAc;AAC1E,WAAO,KAAK,WAAWC,GAAK;AAAA,MAC1B,QAAQ;AAAA,MACR,SAAS,KAAK,gBAAA;AAAA,MACd,MAAM,KAAK,UAAU,KAAK,oBAAoBD,CAAQ,CAAC;AAAA,IAAA,CACxD;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAe,YACbF,GACAC,GACAC,GACkB;AAClB,UAAMC,IAAM,KAAK,SAASF,GAAWC,EAAS,IAAIA,GAAU,cAAc,GACpEE,IAAUF,EAAS,kBAAA,GACnBG,IAAsC,CAAA;AAC5C,eAAW,CAACC,GAAK,GAAGC,CAAO,CAAC,KAAK,OAAO,QAAQH,CAAO;AACrD,MAAAC,EAAWC,CAAG,IAAIC;AAEpB,UAAMC,IAAO;AAAA,MACX,MAAM;AAAA,QACJ,MAAMP;AAAA,QACN,IAAIC,EAAS;AAAA,QACb,YAAAG;AAAA,MAAA;AAAA,IACF;AAEF,WAAO,KAAK,WAAWF,GAAK;AAAA,MAC1B,QAAQ;AAAA,MACR,SAAS,KAAK,gBAAA;AAAA,MACd,MAAM,KAAK,UAAUK,CAAI;AAAA,IAAA,CAC1B;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA,EAMU,oBAAoBN,GAAoD;AAChF,UAAMO,IAAMP,EAAS;AACrB,WAAOO,EAAI,QAAQ,EAAE,GAAGA,EAAI,MAAA,IAAU,CAAA;AAAA,EACxC;AACF;AAzEaX,IAANY,EAAA;AAAA,EADNC,EAAA;AAAW,GACCb,CAAA;;;;;;AC2CN,IAAMc,IAAN,cAAgCC,EAAW;AAAA;AAAA;AAAA;AAAA;AAAA,EAKhD,wBAAwBZ,GAA2B;AACjD,WAAOa,EAAU,OAAOb,CAAS;AAAA,EACnC;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,wBAAwBK,GAAqB;AAC3C,WAAOQ,EAAU,SAASR,CAAG;AAAA,EAC/B;AAAA;AAAA;AAAA;AAAA;AAAA,EAMS,UACPN,GACAe,GACAC,GACAC,GAC2B;AAC3B,QAAI,CAACD,KAAW,OAAOA,KAAY,YAAY,MAAM,QAAQA,CAAO;AAClE,aAAO;AAET,UAAME,IAAWF;AACjB,QAAI,CAACE,EAAS;AACZ,aAAO;AAET,UAAMC,IAAiC;AAAA,MACrC,MAAM,KAAK,wBAAwBD,EAAS,IAAI;AAAA,MAChD,IAAIA,EAAS,OAAO,QAAQA,EAAS,OAAO,SAAY,OAAO,OAAOA,EAAS,EAAE;AAAA,IAAA;AAKnF,QAHIA,EAAS,eACXC,EAAW,aAAa,EAAE,GAAGD,EAAS,WAAA,IAEpCA,EAAS,eAAe;AAC1B,YAAME,IAAkE,CAAA;AACxE,iBAAW,CAACC,GAAMC,CAAG,KAAK,OAAO,QAAQJ,EAAS,aAAa;AAC7D,QAAII,EAAI,SAAS,OACfF,EAAcC,CAAI,IAAI,EAAE,MAAM,KAAA,IACrB,MAAM,QAAQC,EAAI,IAAI,IAC/BF,EAAcC,CAAI,IAAI;AAAA,UACpB,MAAMC,EAAI,KAAK,IAAI,CAACC,OAAS;AAAA,YAC3B,MAAM,KAAK,wBAAwBA,EAAI,IAAI;AAAA,YAC3C,IAAI,OAAOA,EAAI,EAAE;AAAA,UAAA,EACjB;AAAA,QAAA,IAGJH,EAAcC,CAAI,IAAI;AAAA,UACpB,MAAM;AAAA,YACJ,MAAM,KAAK,wBAAwBC,EAAI,KAAK,IAAI;AAAA,YAChD,IAAI,OAAOA,EAAI,KAAK,EAAE;AAAA,UAAA;AAAA,QACxB;AAIN,MAAAH,EAAW,gBAAgBC;AAAA,IAC7B;AACA,WAAOD;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASS,kBACPK,GACAC,GACAT,GACAU,GACAC,GACoB;AACpB,QAAI,CAACX,KAAW,OAAOA,KAAY;AACjC,aAAO,EAAE,MAAM,KAAA;AAEjB,UAAMY,IAAMZ;AAOZ,QAAIa,IAAyD;AAC7D,IAAID,EAAI,SAAS,QAAQA,EAAI,SAAS,SACpCC,IAAO,OACE,MAAM,QAAQD,EAAI,IAAI,IAC/BC,IAAOD,EAAI,KACR,IAAI,CAACV,MAAa,KAAK,UAAUM,GAAOC,GAAYP,CAAQ,CAAC,EAC7D,OAAO,CAACA,MAA6CA,MAAa,IAAI,IAEzEW,IAAO,KAAK,UAAUL,GAAOC,GAAYG,EAAI,IAAI;AAGnD,UAAME,IAAoC,EAAE,MAAAD,EAAA;AAC5C,QAAID,EAAI,YAAYA,EAAI,SAAS,SAAS,GAAG;AAC3C,YAAMG,IAAiC,CAAA;AACvC,iBAAWb,KAAYU,EAAI,UAAU;AACnC,cAAMI,IAA8B;AAAA,UAClC,WAAW,KAAK,wBAAwBd,EAAS,IAAI;AAAA,UACrD,gCAAgB,IAAA;AAAA,UAChB,mCAAmB,IAAA;AAAA,QAAI,GAEnBC,IAAa,KAAK,UAAUK,GAAOQ,GAAad,CAAQ;AAC9D,QAAIC,KACFY,EAAS,KAAKZ,CAAU;AAAA,MAE5B;AACA,MAAAW,EAAc,WAAWC;AAAA,IAC3B;AACA,WAAIH,EAAI,SACNE,EAAc,OAAOF,EAAI,OAEvBA,EAAI,UACNE,EAAc,QAAQF,EAAI,QAErBE;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASS,UACP5B,GACA+B,GACyB;AACzB,UAAM5B,IAAsC,CAAA;AAC5C,IAAAH,EAAS,cAAc,CAACI,MAAQ;AAC9B,MAAAD,EAAW,KAAK,gBAAgBC,CAAG,CAAC,IAAIJ,EAAS,KAAKI,CAAG;AAAA,IAC3D,CAAC;AAED,UAAMc,IAAmD,CAAA;AACzD,IAAAlB,EAAS,iBAAiB,CAACgC,GAAMZ,MAAQ;AACvC,YAAM,EAAE,MAAAD,MAASC,GACXa,IAAa,KAAK,mBAAmBd,CAAI,GACzCe,IAAc,KAAK,wBAAwBd,EAAI,IAAI;AACzD,UAAIA,EAAI,SAAS,aAAa;AAC5B,cAAMe,IAASnC,EAAS,UAAUmB,CAAI;AAItC,QAAAD,EAAce,CAAU,IAAIE,KAAUA,EAAO,MAAM,OAC/C,EAAE,MAAM,EAAE,MAAMD,GAAa,IAAI,OAAOC,EAAO,EAAE,EAAA,MACjD,EAAE,MAAM,KAAA;AAAA,MACd,OAAO;AACL,cAAMC,IAAWpC,EAAS,QAAQmB,CAAI,KAExB,CAAA;AACd,QAAAD,EAAce,CAAU,IAAI;AAAA,UAC1B,MAAMG,EAAQ,IAAI,CAACD,OAAY;AAAA,YAC7B,MAAMD;AAAA,YACN,IAAI,OAAOC,EAAO,EAAE;AAAA,UAAA,EACpB;AAAA,QAAA;AAAA,MAEN;AAAA,IACF,CAAC;AAED,UAAMR,IAAgC;AAAA,MACpC,MAAM,KAAK,wBAAwB3B,EAAS,SAAS;AAAA,MACrD,YAAAG;AAAA,IAAA;AAEF,WAAI4B,KAAA,QAAAA,EAAS,aAAa/B,EAAS,OAAO,SACxC2B,EAAK,KAAK3B,EAAS,KAEjB,OAAO,KAAKkB,CAAa,EAAE,SAAS,MACtCS,EAAK,gBAAgBT,IAGhB,EAAE,MAAAS,EAAA;AAAA,EACX;AACF;AAtLajB,IAANF,EAAA;AAAA,EADNC,EAAA;AAAW,GACCC,CAAA;"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"JsonApiSerializer-DKemcyw-.cjs","sources":["../src/json-api/JsonApiAdapter.ts","../src/json-api/JsonApiSerializer.ts"],"sourcesContent":["/**\n * Adapter that implements the [JSON:API](https://jsonapi.org) specification.\n *\n * Extends `RestAdapter` with the following differences:\n *\n * - **MIME types** — `Accept` and `Content-Type` headers are set to\n * `application/vnd.api+json` as required by the spec.\n * - **PATCH for updates** — `updateRecord` uses `PATCH` instead of `PUT`.\n * - **`coalesceFindRequests: true`** — the store coalesces separate\n * `findRecord` calls into a single `findMany` request.\n *\n * URL construction is inherited from `RestAdapter` / `Adapter` unchanged;\n * override `pathForType` or `urlFor*` methods to customize.\n */\n\nimport { injectable } from 'tsyringe';\nimport { RestAdapter, type AdapterSnapshot } from '@mobx-data/adapter';\n\n@injectable()\nexport class JsonApiAdapter extends RestAdapter {\n /** Always coalesce `findRecord` calls into a single `findMany` request. */\n override coalesceFindRequests = true;\n\n /** Returns JSON:API `Accept` header alongside any custom headers. */\n override defaultHeaders(): Record<string, string> {\n return {\n Accept: 'application/vnd.api+json',\n ...this.headers,\n };\n }\n\n /** Returns JSON:API `Content-Type` header for mutation requests. */\n override mutationHeaders(): Record<string, string> {\n return {\n 'Content-Type': 'application/vnd.api+json',\n ...this.defaultHeaders(),\n };\n }\n\n /**\n * Sends a PATCH request to update a record (JSON:API mandates PATCH, not PUT).\n */\n override async updateRecord(\n _store: unknown,\n modelName: string,\n snapshot: AdapterSnapshot,\n ): Promise<unknown> {\n const url = this.buildURL(modelName, snapshot.id, snapshot, 'updateRecord');\n return this._fetchJSON(url, {\n method: 'PATCH',\n headers: this.mutationHeaders(),\n body: JSON.stringify(this._serializeForUpdate(snapshot)),\n });\n }\n\n /**\n * Sends a PATCH request with only the changed attributes (partial update).\n * Produces a JSON:API document with only the dirty attribute keys.\n */\n override async patchRecord(\n _store: unknown,\n modelName: string,\n snapshot: AdapterSnapshot,\n ): Promise<unknown> {\n const url = this.buildURL(modelName, snapshot.id, snapshot, 'updateRecord');\n const changed = snapshot.changedAttributes();\n const attributes: Record<string, unknown> = {};\n for (const [key, [, current]] of Object.entries(changed)) {\n attributes[key] = current;\n }\n const body = {\n data: {\n type: modelName,\n id: snapshot.id,\n attributes,\n },\n };\n return this._fetchJSON(url, {\n method: 'PATCH',\n headers: this.mutationHeaders(),\n body: JSON.stringify(body),\n });\n }\n\n /**\n * Extracts the raw data object from the snapshot for use as the PATCH body.\n * Subclasses may override this to produce a full JSON:API `{ data: … }` document.\n */\n protected _serializeForUpdate(snapshot: AdapterSnapshot): Record<string, unknown> {\n const rec = snapshot.record as { _data?: Record<string, unknown> };\n return rec._data ? { ...rec._data } : {};\n }\n}\n","/**\n * Serializer that implements the [JSON:API](https://jsonapi.org) specification.\n *\n * ## Normalization\n *\n * Parses a JSON:API compound document `{ data, included, meta, links }` into\n * a `NormalizedDocument`.\n *\n * For each resource object:\n * - `type` is converted from JSON:API plural form to model name via\n * `modelNameFromPayloadKey` (singularization).\n * - `id` is coerced to a string.\n * - `attributes` are copied directly.\n * - `relationships` data refs (`{ type, id }`) are normalized the same way.\n *\n * Side-loaded records in `included` are normalized individually, each using\n * its own `type` as the model class placeholder.\n *\n * ## Serialization\n *\n * Produces a JSON:API resource object wrapped in `{ data: … }`:\n *\n * ```json\n * {\n * \"data\": {\n * \"type\": \"posts\",\n * \"attributes\": { \"title\": \"Hello\" },\n * \"relationships\": {\n * \"author\": { \"data\": { \"type\": \"users\", \"id\": \"1\" } }\n * }\n * }\n * }\n * ```\n *\n * `id` is included when `options.includeId` is `true`.\n */\n\nimport { injectable } from 'tsyringe';\nimport pluralize from 'pluralize';\nimport {\n Serializer,\n type ModelClassMeta,\n type NormalizeRequestType,\n type NormalizedDocument,\n type NormalizedResource,\n type SerializerSnapshot,\n} from '@mobx-data/serializer';\n\n/** Internal shape of a raw JSON:API resource object. */\ninterface JsonApiResource {\n type: string;\n id?: string | number | null;\n attributes?: Record<string, unknown>;\n relationships?: Record<string, {\n data:\n | { type: string; id: string | number }\n | Array<{ type: string; id: string | number }>\n | null;\n }>;\n}\n\n@injectable()\nexport class JsonApiSerializer extends Serializer {\n /**\n * Returns the plural JSON:API `type` string for a model name.\n * e.g. `'post'` → `'posts'`\n */\n payloadKeyFromModelName(modelName: string): string {\n return pluralize.plural(modelName);\n }\n\n /**\n * Returns the model name for a JSON:API `type` string.\n * e.g. `'posts'` → `'post'`\n */\n modelNameFromPayloadKey(key: string): string {\n return pluralize.singular(key);\n }\n\n /**\n * Normalizes a single JSON:API resource object into a `NormalizedResource`.\n * Returns `null` for absent, non-object, or type-less payloads.\n */\n override normalize(\n _store: unknown,\n _modelClass: ModelClassMeta,\n payload: unknown,\n _prop?: string,\n ): NormalizedResource | null {\n if (!payload || typeof payload !== 'object' || Array.isArray(payload)) {\n return null;\n }\n const resource = payload as JsonApiResource;\n if (!resource.type) {\n return null;\n }\n const normalized: NormalizedResource = {\n type: this.modelNameFromPayloadKey(resource.type),\n id: resource.id === null || resource.id === undefined ? null : String(resource.id),\n };\n if (resource.attributes) {\n normalized.attributes = { ...resource.attributes };\n }\n if (resource.relationships) {\n const relationships: NonNullable<NormalizedResource['relationships']> = {};\n for (const [name, rel] of Object.entries(resource.relationships)) {\n if (rel.data === null) {\n relationships[name] = { data: null };\n } else if (Array.isArray(rel.data)) {\n relationships[name] = {\n data: rel.data.map((ref) => ({\n type: this.modelNameFromPayloadKey(ref.type),\n id: String(ref.id),\n })),\n };\n } else {\n relationships[name] = {\n data: {\n type: this.modelNameFromPayloadKey(rel.data.type),\n id: String(rel.data.id),\n },\n };\n }\n }\n normalized.relationships = relationships;\n }\n return normalized;\n }\n\n /**\n * Normalizes a full JSON:API compound document.\n *\n * - `data` (single or array) → primary resources\n * - `included` → side-loaded resources pushed to `normalizedDoc.included`\n * - `meta` and `links` → forwarded as-is\n */\n override normalizeResponse(\n store: unknown,\n modelClass: ModelClassMeta,\n payload: unknown,\n _id: string | null,\n _requestType: NormalizeRequestType,\n ): NormalizedDocument {\n if (!payload || typeof payload !== 'object') {\n return { data: null };\n }\n const doc = payload as {\n data?: JsonApiResource | JsonApiResource[] | null;\n included?: JsonApiResource[];\n meta?: Record<string, unknown>;\n links?: Record<string, string>;\n };\n\n let data: NormalizedResource | NormalizedResource[] | null = null;\n if (doc.data === null || doc.data === undefined) {\n data = null;\n } else if (Array.isArray(doc.data)) {\n data = doc.data\n .map((resource) => this.normalize(store, modelClass, resource))\n .filter((resource): resource is NormalizedResource => resource !== null);\n } else {\n data = this.normalize(store, modelClass, doc.data);\n }\n\n const normalizedDoc: NormalizedDocument = { data };\n if (doc.included && doc.included.length > 0) {\n const included: NormalizedResource[] = [];\n for (const resource of doc.included) {\n const placeholder: ModelClassMeta = {\n modelName: this.modelNameFromPayloadKey(resource.type),\n attributes: new Map(),\n relationships: new Map(),\n };\n const normalized = this.normalize(store, placeholder, resource);\n if (normalized) {\n included.push(normalized);\n }\n }\n normalizedDoc.included = included;\n }\n if (doc.meta) {\n normalizedDoc.meta = doc.meta;\n }\n if (doc.links) {\n normalizedDoc.links = doc.links;\n }\n return normalizedDoc;\n }\n\n /**\n * Serializes a record snapshot to a JSON:API `{ data: … }` document.\n *\n * Attributes are placed in `data.attributes`; relationships are placed in\n * `data.relationships` with proper `{ data: { type, id } }` structure.\n * `id` is included in `data` when `options.includeId` is `true`.\n */\n override serialize(\n snapshot: SerializerSnapshot,\n options?: { includeId?: boolean },\n ): Record<string, unknown> {\n const attributes: Record<string, unknown> = {};\n snapshot.eachAttribute((key) => {\n attributes[this.keyForAttribute(key)] = snapshot.attr(key);\n });\n\n const relationships: Record<string, { data: unknown }> = {};\n snapshot.eachRelationship((_key, rel) => {\n const { name } = rel;\n const payloadKey = this.keyForRelationship(name);\n const payloadType = this.payloadKeyFromModelName(rel.type);\n if (rel.kind === 'belongsTo') {\n const target = snapshot.belongsTo(name) as\n | { id: string; type?: string }\n | null\n | undefined;\n relationships[payloadKey] = target && target.id != null\n ? { data: { type: payloadType, id: String(target.id) } }\n : { data: null };\n } else {\n const targets = (snapshot.hasMany(name) as Array<{\n id: string; type?: string;\n }> | null) ?? [];\n relationships[payloadKey] = {\n data: targets.map((target) => ({\n type: payloadType,\n id: String(target.id),\n })),\n };\n }\n });\n\n const data: Record<string, unknown> = {\n type: this.payloadKeyFromModelName(snapshot.modelName),\n attributes,\n };\n if (options?.includeId && snapshot.id !== null) {\n data.id = snapshot.id;\n }\n if (Object.keys(relationships).length > 0) {\n data.relationships = relationships;\n }\n\n return { data };\n }\n}\n"],"names":["JsonApiAdapter","RestAdapter","_store","modelName","snapshot","url","changed","attributes","key","current","body","rec","__decorateClass","injectable","JsonApiSerializer","Serializer","pluralize","_modelClass","payload","_prop","resource","normalized","relationships","name","rel","ref","store","modelClass","_id","_requestType","doc","data","normalizedDoc","included","placeholder","options","_key","payloadKey","payloadType","target","targets"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"ODataAdapter-CrDFvBEZ.cjs","sources":["../src/odata/ODataAdapter.ts"],"sourcesContent":["import { injectable } from 'tsyringe';\nimport pluralize from 'pluralize';\nimport { pascalCase } from 'change-case';\nimport { RestAdapter } from '@mobx-data/adapter';\nimport type { AdapterSnapshot } from '@mobx-data/adapter';\n\n/** All OData v4 system query option names (both bare and $-prefixed forms are checked). */\nconst ODATA_SYSTEM_QUERY_OPTIONS = new Set([\n '$filter',\n '$select',\n '$orderby',\n '$top',\n '$skip',\n '$expand',\n '$count',\n '$search',\n '$format',\n '$skiptoken',\n]);\n\n/**\n * OData v4 adapter.\n *\n * Extends `RestAdapter` with OData-specific conventions:\n * - Entity-set names are PascalCase plural (`user` → `Users`).\n * - Single-entity URLs use key-in-parentheses syntax (`Users(1)`, `Users('abc')`).\n * - Mutations use PATCH instead of PUT.\n * - Accept / Content-Type headers carry the `odata.metadata=minimal` parameter.\n * - System query options (`$filter`, `$expand`, etc.) are passed through verbatim;\n * bare names are auto-prefixed (`filter` → `$filter`).\n */\n@injectable()\nexport class ODataAdapter extends RestAdapter {\n /** OData protocol version sent in `OData-Version` and `OData-MaxVersion` headers. */\n odataVersion: string = '4.0';\n\n static isNumericKey(id: string): boolean {\n return /^-?\\d+(?:\\.\\d+)?$/.test(id);\n }\n\n static escapeODataString(value: string): string {\n return value.replace(/'/g, \"''\");\n }\n\n override defaultHeaders(): Record<string, string> {\n return {\n Accept: 'application/json;odata.metadata=minimal',\n 'OData-Version': this.odataVersion,\n 'OData-MaxVersion': this.odataVersion,\n ...this.headers,\n };\n }\n\n override mutationHeaders(): Record<string, string> {\n return {\n 'Content-Type': 'application/json;odata.metadata=minimal',\n ...this.defaultHeaders(),\n };\n }\n\n /**\n * Maps a camelCase/dasherized model name to a PascalCase plural entity-set name.\n * @example `pathForType('orderItem')` → `'OrderItems'`\n */\n override pathForType(modelName: string): string {\n return pascalCase(pluralize.plural(modelName));\n }\n\n /**\n * Encodes a record id as an OData key literal.\n * Numeric ids are returned bare (`1`); string ids are single-quoted with\n * inner apostrophes escaped (`o'brien` → `'o''brien'`).\n *\n * Override this method when the service uses a non-default key format (e.g. GUIDs).\n */\n encodeKey(id: string): string {\n if (ODataAdapter.isNumericKey(id)) {\n return id;\n }\n return `'${ODataAdapter.escapeODataString(id)}'`;\n }\n\n override urlForFindRecord(\n id: string,\n modelName: string,\n _snapshot: AdapterSnapshot,\n ): string {\n return this._composeURL(`${this.pathForType(modelName)}(${this.encodeKey(id)})`);\n }\n\n override urlForUpdateRecord(\n id: string,\n modelName: string,\n _snapshot: AdapterSnapshot,\n ): string {\n return this._composeURL(`${this.pathForType(modelName)}(${this.encodeKey(id)})`);\n }\n\n override urlForDeleteRecord(\n id: string,\n modelName: string,\n _snapshot: AdapterSnapshot,\n ): string {\n return this._composeURL(`${this.pathForType(modelName)}(${this.encodeKey(id)})`);\n }\n\n /**\n * Fetches multiple records by id using a single request.\n * Builds a `$filter=id eq X or id eq Y` expression so only one HTTP round-trip\n * is needed regardless of how many ids are requested.\n */\n override async findMany(\n _store: unknown,\n modelName: string,\n ids: string[],\n snapshots: AdapterSnapshot[],\n ): Promise<unknown> {\n const base = this.buildURL(modelName, ids, snapshots, 'findMany');\n const filter = ids.map((id) => `id eq ${this.encodeKey(id)}`).join(' or ');\n const url = `${base}?${this._toQueryString({ $filter: filter })}`;\n return this._fetchJSON(url, {\n method: 'GET',\n headers: this.defaultHeaders(),\n });\n }\n\n override async query(\n _store: unknown,\n modelName: string,\n query: Record<string, unknown>,\n ): Promise<unknown> {\n const base = this.buildURL(modelName, null, null, 'query', query);\n const normalized = this._normalizeQuery(query);\n const url = `${base}${this._appendQuery(normalized)}`;\n return this._fetchJSON(url, {\n method: 'GET',\n headers: this.defaultHeaders(),\n });\n }\n\n /**\n * Queries for a single record by appending `$top=1` to whatever filter is provided.\n * The caller is responsible for picking the first element from the returned `value` array.\n */\n override async queryRecord(\n _store: unknown,\n modelName: string,\n query: Record<string, unknown>,\n ): Promise<unknown> {\n const base = this.buildURL(modelName, null, null, 'queryRecord', query);\n const normalized = { ...this._normalizeQuery(query), $top: 1 };\n const url = `${base}${this._appendQuery(normalized)}`;\n return this._fetchJSON(url, {\n method: 'GET',\n headers: this.defaultHeaders(),\n });\n }\n\n /** Sends a PATCH request (partial update) as required by the OData v4 spec. */\n override async updateRecord(\n _store: unknown,\n modelName: string,\n snapshot: AdapterSnapshot,\n ): Promise<unknown> {\n const url = this.buildURL(modelName, snapshot.id, snapshot, 'updateRecord');\n return this._fetchJSON(url, {\n method: 'PATCH',\n headers: this.mutationHeaders(),\n body: JSON.stringify(this._serializeSnapshot(snapshot)),\n });\n }\n\n /** Sends a PATCH request with only the changed attributes (partial update). */\n override async patchRecord(\n _store: unknown,\n modelName: string,\n snapshot: AdapterSnapshot,\n ): Promise<unknown> {\n const url = this.buildURL(modelName, snapshot.id, snapshot, 'updateRecord');\n const changed = snapshot.changedAttributes();\n const partial: Record<string, unknown> = {};\n for (const [key, [, current]] of Object.entries(changed)) {\n partial[key] = current;\n }\n return this._fetchJSON(url, {\n method: 'PATCH',\n headers: this.mutationHeaders(),\n body: JSON.stringify(partial),\n });\n }\n\n /** Extracts the raw attribute map from the snapshot's internal record. */\n protected _serializeSnapshot(snapshot: AdapterSnapshot): Record<string, unknown> {\n const record = snapshot.record as { _data?: Record<string, unknown> };\n const data = record._data;\n const body: Record<string, unknown> = {};\n if (data) {\n Object.assign(body, data);\n }\n return body;\n }\n\n /**\n * Normalises a query hash so every OData system option has its `$` prefix.\n * Bare names (`filter`, `top`, `expand`) are prefixed automatically.\n * Custom (non-system) keys are forwarded verbatim.\n * `null` and `undefined` values are dropped.\n */\n protected _normalizeQuery(\n query: Record<string, unknown>,\n ): Record<string, unknown> {\n const normalized: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(query)) {\n if (value === undefined || value === null) {\n continue;\n }\n if (ODATA_SYSTEM_QUERY_OPTIONS.has(key)) {\n normalized[key] = value;\n } else if (ODATA_SYSTEM_QUERY_OPTIONS.has(`$${key}`)) {\n normalized[`$${key}`] = value;\n } else {\n normalized[key] = value;\n }\n }\n return normalized;\n }\n\n /** Serialises a key→value map to a `key=value&…` query string (percent-encoded). */\n protected _toQueryString(query: Record<string, unknown>): string {\n const parts: string[] = [];\n for (const [key, value] of Object.entries(query)) {\n if (value === undefined || value === null) {\n continue;\n }\n parts.push(`${encodeURIComponent(key)}=${encodeURIComponent(String(value))}`);\n }\n return parts.join('&');\n }\n\n /** Returns `?key=value&…` when the query is non-empty, or an empty string. */\n protected _appendQuery(query: Record<string, unknown>): string {\n const queryString = this._toQueryString(query);\n return queryString ? `?${queryString}` : '';\n }\n}\n"],"names":["ODATA_SYSTEM_QUERY_OPTIONS","ODataAdapter","RestAdapter","id","value","modelName","pascalCase","pluralize","_snapshot","_store","ids","snapshots","base","filter","url","query","normalized","snapshot","changed","partial","key","current","data","body","parts","queryString","__decorateClass","injectable"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"ODataAdapter-RQUjVTcf.js","sources":["../src/odata/ODataAdapter.ts"],"sourcesContent":["import { injectable } from 'tsyringe';\nimport pluralize from 'pluralize';\nimport { pascalCase } from 'change-case';\nimport { RestAdapter } from '@mobx-data/adapter';\nimport type { AdapterSnapshot } from '@mobx-data/adapter';\n\n/** All OData v4 system query option names (both bare and $-prefixed forms are checked). */\nconst ODATA_SYSTEM_QUERY_OPTIONS = new Set([\n '$filter',\n '$select',\n '$orderby',\n '$top',\n '$skip',\n '$expand',\n '$count',\n '$search',\n '$format',\n '$skiptoken',\n]);\n\n/**\n * OData v4 adapter.\n *\n * Extends `RestAdapter` with OData-specific conventions:\n * - Entity-set names are PascalCase plural (`user` → `Users`).\n * - Single-entity URLs use key-in-parentheses syntax (`Users(1)`, `Users('abc')`).\n * - Mutations use PATCH instead of PUT.\n * - Accept / Content-Type headers carry the `odata.metadata=minimal` parameter.\n * - System query options (`$filter`, `$expand`, etc.) are passed through verbatim;\n * bare names are auto-prefixed (`filter` → `$filter`).\n */\n@injectable()\nexport class ODataAdapter extends RestAdapter {\n /** OData protocol version sent in `OData-Version` and `OData-MaxVersion` headers. */\n odataVersion: string = '4.0';\n\n static isNumericKey(id: string): boolean {\n return /^-?\\d+(?:\\.\\d+)?$/.test(id);\n }\n\n static escapeODataString(value: string): string {\n return value.replace(/'/g, \"''\");\n }\n\n override defaultHeaders(): Record<string, string> {\n return {\n Accept: 'application/json;odata.metadata=minimal',\n 'OData-Version': this.odataVersion,\n 'OData-MaxVersion': this.odataVersion,\n ...this.headers,\n };\n }\n\n override mutationHeaders(): Record<string, string> {\n return {\n 'Content-Type': 'application/json;odata.metadata=minimal',\n ...this.defaultHeaders(),\n };\n }\n\n /**\n * Maps a camelCase/dasherized model name to a PascalCase plural entity-set name.\n * @example `pathForType('orderItem')` → `'OrderItems'`\n */\n override pathForType(modelName: string): string {\n return pascalCase(pluralize.plural(modelName));\n }\n\n /**\n * Encodes a record id as an OData key literal.\n * Numeric ids are returned bare (`1`); string ids are single-quoted with\n * inner apostrophes escaped (`o'brien` → `'o''brien'`).\n *\n * Override this method when the service uses a non-default key format (e.g. GUIDs).\n */\n encodeKey(id: string): string {\n if (ODataAdapter.isNumericKey(id)) {\n return id;\n }\n return `'${ODataAdapter.escapeODataString(id)}'`;\n }\n\n override urlForFindRecord(\n id: string,\n modelName: string,\n _snapshot: AdapterSnapshot,\n ): string {\n return this._composeURL(`${this.pathForType(modelName)}(${this.encodeKey(id)})`);\n }\n\n override urlForUpdateRecord(\n id: string,\n modelName: string,\n _snapshot: AdapterSnapshot,\n ): string {\n return this._composeURL(`${this.pathForType(modelName)}(${this.encodeKey(id)})`);\n }\n\n override urlForDeleteRecord(\n id: string,\n modelName: string,\n _snapshot: AdapterSnapshot,\n ): string {\n return this._composeURL(`${this.pathForType(modelName)}(${this.encodeKey(id)})`);\n }\n\n /**\n * Fetches multiple records by id using a single request.\n * Builds a `$filter=id eq X or id eq Y` expression so only one HTTP round-trip\n * is needed regardless of how many ids are requested.\n */\n override async findMany(\n _store: unknown,\n modelName: string,\n ids: string[],\n snapshots: AdapterSnapshot[],\n ): Promise<unknown> {\n const base = this.buildURL(modelName, ids, snapshots, 'findMany');\n const filter = ids.map((id) => `id eq ${this.encodeKey(id)}`).join(' or ');\n const url = `${base}?${this._toQueryString({ $filter: filter })}`;\n return this._fetchJSON(url, {\n method: 'GET',\n headers: this.defaultHeaders(),\n });\n }\n\n override async query(\n _store: unknown,\n modelName: string,\n query: Record<string, unknown>,\n ): Promise<unknown> {\n const base = this.buildURL(modelName, null, null, 'query', query);\n const normalized = this._normalizeQuery(query);\n const url = `${base}${this._appendQuery(normalized)}`;\n return this._fetchJSON(url, {\n method: 'GET',\n headers: this.defaultHeaders(),\n });\n }\n\n /**\n * Queries for a single record by appending `$top=1` to whatever filter is provided.\n * The caller is responsible for picking the first element from the returned `value` array.\n */\n override async queryRecord(\n _store: unknown,\n modelName: string,\n query: Record<string, unknown>,\n ): Promise<unknown> {\n const base = this.buildURL(modelName, null, null, 'queryRecord', query);\n const normalized = { ...this._normalizeQuery(query), $top: 1 };\n const url = `${base}${this._appendQuery(normalized)}`;\n return this._fetchJSON(url, {\n method: 'GET',\n headers: this.defaultHeaders(),\n });\n }\n\n /** Sends a PATCH request (partial update) as required by the OData v4 spec. */\n override async updateRecord(\n _store: unknown,\n modelName: string,\n snapshot: AdapterSnapshot,\n ): Promise<unknown> {\n const url = this.buildURL(modelName, snapshot.id, snapshot, 'updateRecord');\n return this._fetchJSON(url, {\n method: 'PATCH',\n headers: this.mutationHeaders(),\n body: JSON.stringify(this._serializeSnapshot(snapshot)),\n });\n }\n\n /** Sends a PATCH request with only the changed attributes (partial update). */\n override async patchRecord(\n _store: unknown,\n modelName: string,\n snapshot: AdapterSnapshot,\n ): Promise<unknown> {\n const url = this.buildURL(modelName, snapshot.id, snapshot, 'updateRecord');\n const changed = snapshot.changedAttributes();\n const partial: Record<string, unknown> = {};\n for (const [key, [, current]] of Object.entries(changed)) {\n partial[key] = current;\n }\n return this._fetchJSON(url, {\n method: 'PATCH',\n headers: this.mutationHeaders(),\n body: JSON.stringify(partial),\n });\n }\n\n /** Extracts the raw attribute map from the snapshot's internal record. */\n protected _serializeSnapshot(snapshot: AdapterSnapshot): Record<string, unknown> {\n const record = snapshot.record as { _data?: Record<string, unknown> };\n const data = record._data;\n const body: Record<string, unknown> = {};\n if (data) {\n Object.assign(body, data);\n }\n return body;\n }\n\n /**\n * Normalises a query hash so every OData system option has its `$` prefix.\n * Bare names (`filter`, `top`, `expand`) are prefixed automatically.\n * Custom (non-system) keys are forwarded verbatim.\n * `null` and `undefined` values are dropped.\n */\n protected _normalizeQuery(\n query: Record<string, unknown>,\n ): Record<string, unknown> {\n const normalized: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(query)) {\n if (value === undefined || value === null) {\n continue;\n }\n if (ODATA_SYSTEM_QUERY_OPTIONS.has(key)) {\n normalized[key] = value;\n } else if (ODATA_SYSTEM_QUERY_OPTIONS.has(`$${key}`)) {\n normalized[`$${key}`] = value;\n } else {\n normalized[key] = value;\n }\n }\n return normalized;\n }\n\n /** Serialises a key→value map to a `key=value&…` query string (percent-encoded). */\n protected _toQueryString(query: Record<string, unknown>): string {\n const parts: string[] = [];\n for (const [key, value] of Object.entries(query)) {\n if (value === undefined || value === null) {\n continue;\n }\n parts.push(`${encodeURIComponent(key)}=${encodeURIComponent(String(value))}`);\n }\n return parts.join('&');\n }\n\n /** Returns `?key=value&…` when the query is non-empty, or an empty string. */\n protected _appendQuery(query: Record<string, unknown>): string {\n const queryString = this._toQueryString(query);\n return queryString ? `?${queryString}` : '';\n }\n}\n"],"names":["ODATA_SYSTEM_QUERY_OPTIONS","ODataAdapter","RestAdapter","id","value","modelName","pascalCase","pluralize","_snapshot","_store","ids","snapshots","base","filter","url","query","normalized","snapshot","changed","partial","key","current","data","body","parts","queryString","__decorateClass","injectable"],"mappings":"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"}
@@ -1,2 +0,0 @@
1
- "use strict";const p=require("tsyringe"),_=require("pluralize"),y=require("./cache-utils-CSwsqOi3.cjs"),F=new RegExp("([\\p{Ll}\\d])(\\p{Lu})","gu"),L=new RegExp("(\\p{Lu})([\\p{Lu}][\\p{Ll}])","gu"),U=new RegExp("(\\d)\\p{Ll}|(\\p{L})\\d","u"),b=/[^\p{L}\d]+/giu,i="$1\0$2",l="";function d(a){let e=a.trim();e=e.replace(F,i).replace(L,i),e=e.replace(b,"\0");let r=0,t=e.length;for(;e.charAt(r)==="\0";)r++;if(r===t)return[];for(;e.charAt(t-1)==="\0";)t--;return e.slice(r,t).split(/\0/g)}function A(a){const e=d(a);for(let r=0;r<e.length;r++){const t=e[r],s=U.exec(t);if(s){const c=s.index+(s[1]??s[2]).length;e.splice(r,1,t.slice(0,c),t.slice(c))}}return e}function T(a,e){const[r,t,s]=f(a,e);return r+t.map(h(e==null?void 0:e.locale)).join((e==null?void 0:e.delimiter)??" ")+s}function S(a,e){const[r,t,s]=f(a,e),c=h(e==null?void 0:e.locale),n=C(e==null?void 0:e.locale),o=E(c,n);return r+t.map(o).join("")+s}function m(a,e){return T(a,{delimiter:"-",...e})}function h(a){return a===!1?e=>e.toLowerCase():e=>e.toLocaleLowerCase(a)}function C(a){return e=>e.toLocaleUpperCase(a)}function E(a,e){return(r,t)=>{const s=r[0];return(t>0&&s>="0"&&s<="9"?"_"+s:e(s))+a(r.slice(1))}}function f(a,e={}){const r=e.split??(e.separateNumbers?A:d),t=e.prefixCharacters??l,s=e.suffixCharacters??l;let c=0,n=a.length;for(;c<a.length;){const o=a.charAt(c);if(!t.includes(o))break;c++}for(;n>c;){const o=n-1,u=a.charAt(o);if(!s.includes(u))break;n=o}return[a.slice(0,c),r(a.slice(c,n)),a.slice(n)]}class R{constructor(){this.namespace="",this.host="",this.headers={},this.coalesceFindRequests=!1}patchRecord(e,r,t){return this.updateRecord(e,r,t)}pathForType(e){return _.plural(m(e))}_composeURL(e){const r=this.namespace.replace(/^\/+|\/+$/g,""),t=this.host?this.host.replace(/\/+$/,""):"",s=[];return t&&s.push(t),r&&s.push(r),s.push(e),t?s.join("/"):`/${s.filter(Boolean).join("/")}`}buildURL(e,r,t,s,c={}){switch(s){case"findRecord":return this.urlForFindRecord(r,e,t);case"findAll":return this.urlForFindAll(e,t??[]);case"findMany":return this.urlForFindMany(r??[],e,t??[]);case"query":return this.urlForQuery(c,e);case"queryRecord":return this.urlForQueryRecord(c,e);case"createRecord":return this.urlForCreateRecord(e,t);case"updateRecord":return this.urlForUpdateRecord(r,e,t);case"deleteRecord":return this.urlForDeleteRecord(r,e,t)}}urlForFindRecord(e,r,t){return this._composeURL(`${this.pathForType(r)}/${encodeURIComponent(e)}`)}urlForFindAll(e,r){return this._composeURL(this.pathForType(e))}urlForFindMany(e,r,t){return this._composeURL(this.pathForType(r))}urlForQuery(e,r){return this._composeURL(this.pathForType(r))}urlForQueryRecord(e,r){return this._composeURL(this.pathForType(r))}urlForCreateRecord(e,r){return this._composeURL(this.pathForType(e))}urlForUpdateRecord(e,r,t){return this._composeURL(`${this.pathForType(r)}/${encodeURIComponent(e)}`)}urlForDeleteRecord(e,r,t){return this._composeURL(`${this.pathForType(r)}/${encodeURIComponent(e)}`)}groupRecordsForFindMany(e,r){return[r]}shouldReloadRecord(e,r){return!1}shouldBackgroundReloadRecord(e,r){return!0}shouldReloadAll(e,r){return!1}shouldBackgroundReloadAll(e,r){return!0}}var g=Object.getOwnPropertyDescriptor,O=(a,e,r,t)=>{for(var s=t>1?void 0:t?g(e,r):e,c=a.length-1,n;c>=0;c--)(n=a[c])&&(s=n(s)||s);return s};exports.RestAdapter=class extends R{static serializeSnapshotToObject(e){const r={},s=e.record._data;if(s)for(const[c,n]of Object.entries(s))c==="__proto__"||c==="constructor"||c==="prototype"||(r[c]=n);return r}static toQueryString(e){const r=[];for(const[t,s]of Object.entries(e))s!=null&&r.push(`${encodeURIComponent(t)}=${encodeURIComponent(String(s))}`);return r.length>0?`?${r.join("&")}`:""}defaultHeaders(){return{Accept:"application/json",...this.headers}}mutationHeaders(){return{"Content-Type":"application/json",...this.defaultHeaders()}}async _fetchJSON(e,r){const t=await fetch(e,r);if(!t.ok){let n=null;try{n=await t.json()}catch{}throw Object.assign(new Error(`Request failed: ${t.status}`),{status:t.status,body:n})}if(t.status===204)return null;const s=await t.text();if(!s)return null;let c;try{c=JSON.parse(s)}catch{c=s}if(c!==null&&typeof c=="object"){const n={};t.headers.forEach((o,u)=>{n[u.toLowerCase()]=o}),y.attachResponseHeaders(c,n)}return c}async findRecord(e,r,t,s,c){let n=this.buildURL(r,t,s,"findRecord");return c!=null&&c.include&&(n+=`${n.includes("?")?"&":"?"}include=${encodeURIComponent(c.include)}`),this._fetchJSON(n,{method:"GET",headers:this.defaultHeaders()})}async findAll(e,r,t,s,c){let n=this.buildURL(r,null,s,"findAll");return c!=null&&c.include&&(n+=`${n.includes("?")?"&":"?"}include=${encodeURIComponent(c.include)}`),this._fetchJSON(n,{method:"GET",headers:this.defaultHeaders()})}async findMany(e,r,t,s){const c=this.buildURL(r,t,s,"findMany"),n=c.includes("?")?"&":"?",o=`${c}${n}ids=${t.map(encodeURIComponent).join(",")}`;return this._fetchJSON(o,{method:"GET",headers:this.defaultHeaders()})}async query(e,r,t){const c=`${this.buildURL(r,null,null,"query",t)}${exports.RestAdapter.toQueryString(t)}`;return this._fetchJSON(c,{method:"GET",headers:this.defaultHeaders()})}async queryRecord(e,r,t){const c=`${this.buildURL(r,null,null,"queryRecord",t)}${exports.RestAdapter.toQueryString(t)}`;return this._fetchJSON(c,{method:"GET",headers:this.defaultHeaders()})}async createRecord(e,r,t){const s=this.buildURL(r,null,t,"createRecord");return this._fetchJSON(s,{method:"POST",headers:this.mutationHeaders(),body:JSON.stringify(exports.RestAdapter.serializeSnapshotToObject(t))})}async updateRecord(e,r,t){const s=this.buildURL(r,t.id,t,"updateRecord");return this._fetchJSON(s,{method:"PUT",headers:this.mutationHeaders(),body:JSON.stringify(exports.RestAdapter.serializeSnapshotToObject(t))})}async patchRecord(e,r,t){const s=this.buildURL(r,t.id,t,"updateRecord"),c=t.changedAttributes(),n={};for(const[o,[,u]]of Object.entries(c))n[o]=u;return this._fetchJSON(s,{method:"PATCH",headers:this.mutationHeaders(),body:JSON.stringify(n)})}async deleteRecord(e,r,t){const s=this.buildURL(r,t.id,t,"deleteRecord");return this._fetchJSON(s,{method:"DELETE",headers:this.defaultHeaders()})}};exports.RestAdapter=O([p.injectable()],exports.RestAdapter);exports.Adapter=R;exports.pascalCase=S;
2
- //# sourceMappingURL=RestAdapter-CSoJg7D2.cjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"RestAdapter-CSoJg7D2.cjs","sources":["../node_modules/.pnpm/change-case@5.4.4/node_modules/change-case/dist/index.js","../src/adapter/Adapter.ts","../src/adapter/RestAdapter.ts"],"sourcesContent":["// Regexps involved with splitting words in various case formats.\nconst SPLIT_LOWER_UPPER_RE = /([\\p{Ll}\\d])(\\p{Lu})/gu;\nconst SPLIT_UPPER_UPPER_RE = /(\\p{Lu})([\\p{Lu}][\\p{Ll}])/gu;\n// Used to iterate over the initial split result and separate numbers.\nconst SPLIT_SEPARATE_NUMBER_RE = /(\\d)\\p{Ll}|(\\p{L})\\d/u;\n// Regexp involved with stripping non-word characters from the result.\nconst DEFAULT_STRIP_REGEXP = /[^\\p{L}\\d]+/giu;\n// The replacement value for splits.\nconst SPLIT_REPLACE_VALUE = \"$1\\0$2\";\n// The default characters to keep after transforming case.\nconst DEFAULT_PREFIX_SUFFIX_CHARACTERS = \"\";\n/**\n * Split any cased input strings into an array of words.\n */\nexport function split(value) {\n let result = value.trim();\n result = result\n .replace(SPLIT_LOWER_UPPER_RE, SPLIT_REPLACE_VALUE)\n .replace(SPLIT_UPPER_UPPER_RE, SPLIT_REPLACE_VALUE);\n result = result.replace(DEFAULT_STRIP_REGEXP, \"\\0\");\n let start = 0;\n let end = result.length;\n // Trim the delimiter from around the output string.\n while (result.charAt(start) === \"\\0\")\n start++;\n if (start === end)\n return [];\n while (result.charAt(end - 1) === \"\\0\")\n end--;\n return result.slice(start, end).split(/\\0/g);\n}\n/**\n * Split the input string into an array of words, separating numbers.\n */\nexport function splitSeparateNumbers(value) {\n const words = split(value);\n for (let i = 0; i < words.length; i++) {\n const word = words[i];\n const match = SPLIT_SEPARATE_NUMBER_RE.exec(word);\n if (match) {\n const offset = match.index + (match[1] ?? match[2]).length;\n words.splice(i, 1, word.slice(0, offset), word.slice(offset));\n }\n }\n return words;\n}\n/**\n * Convert a string to space separated lower case (`foo bar`).\n */\nexport function noCase(input, options) {\n const [prefix, words, suffix] = splitPrefixSuffix(input, options);\n return (prefix +\n words.map(lowerFactory(options?.locale)).join(options?.delimiter ?? \" \") +\n suffix);\n}\n/**\n * Convert a string to camel case (`fooBar`).\n */\nexport function camelCase(input, options) {\n const [prefix, words, suffix] = splitPrefixSuffix(input, options);\n const lower = lowerFactory(options?.locale);\n const upper = upperFactory(options?.locale);\n const transform = options?.mergeAmbiguousCharacters\n ? capitalCaseTransformFactory(lower, upper)\n : pascalCaseTransformFactory(lower, upper);\n return (prefix +\n words\n .map((word, index) => {\n if (index === 0)\n return lower(word);\n return transform(word, index);\n })\n .join(options?.delimiter ?? \"\") +\n suffix);\n}\n/**\n * Convert a string to pascal case (`FooBar`).\n */\nexport function pascalCase(input, options) {\n const [prefix, words, suffix] = splitPrefixSuffix(input, options);\n const lower = lowerFactory(options?.locale);\n const upper = upperFactory(options?.locale);\n const transform = options?.mergeAmbiguousCharacters\n ? capitalCaseTransformFactory(lower, upper)\n : pascalCaseTransformFactory(lower, upper);\n return prefix + words.map(transform).join(options?.delimiter ?? \"\") + suffix;\n}\n/**\n * Convert a string to pascal snake case (`Foo_Bar`).\n */\nexport function pascalSnakeCase(input, options) {\n return capitalCase(input, { delimiter: \"_\", ...options });\n}\n/**\n * Convert a string to capital case (`Foo Bar`).\n */\nexport function capitalCase(input, options) {\n const [prefix, words, suffix] = splitPrefixSuffix(input, options);\n const lower = lowerFactory(options?.locale);\n const upper = upperFactory(options?.locale);\n return (prefix +\n words\n .map(capitalCaseTransformFactory(lower, upper))\n .join(options?.delimiter ?? \" \") +\n suffix);\n}\n/**\n * Convert a string to constant case (`FOO_BAR`).\n */\nexport function constantCase(input, options) {\n const [prefix, words, suffix] = splitPrefixSuffix(input, options);\n return (prefix +\n words.map(upperFactory(options?.locale)).join(options?.delimiter ?? \"_\") +\n suffix);\n}\n/**\n * Convert a string to dot case (`foo.bar`).\n */\nexport function dotCase(input, options) {\n return noCase(input, { delimiter: \".\", ...options });\n}\n/**\n * Convert a string to kebab case (`foo-bar`).\n */\nexport function kebabCase(input, options) {\n return noCase(input, { delimiter: \"-\", ...options });\n}\n/**\n * Convert a string to path case (`foo/bar`).\n */\nexport function pathCase(input, options) {\n return noCase(input, { delimiter: \"/\", ...options });\n}\n/**\n * Convert a string to path case (`Foo bar`).\n */\nexport function sentenceCase(input, options) {\n const [prefix, words, suffix] = splitPrefixSuffix(input, options);\n const lower = lowerFactory(options?.locale);\n const upper = upperFactory(options?.locale);\n const transform = capitalCaseTransformFactory(lower, upper);\n return (prefix +\n words\n .map((word, index) => {\n if (index === 0)\n return transform(word);\n return lower(word);\n })\n .join(options?.delimiter ?? \" \") +\n suffix);\n}\n/**\n * Convert a string to snake case (`foo_bar`).\n */\nexport function snakeCase(input, options) {\n return noCase(input, { delimiter: \"_\", ...options });\n}\n/**\n * Convert a string to header case (`Foo-Bar`).\n */\nexport function trainCase(input, options) {\n return capitalCase(input, { delimiter: \"-\", ...options });\n}\nfunction lowerFactory(locale) {\n return locale === false\n ? (input) => input.toLowerCase()\n : (input) => input.toLocaleLowerCase(locale);\n}\nfunction upperFactory(locale) {\n return locale === false\n ? (input) => input.toUpperCase()\n : (input) => input.toLocaleUpperCase(locale);\n}\nfunction capitalCaseTransformFactory(lower, upper) {\n return (word) => `${upper(word[0])}${lower(word.slice(1))}`;\n}\nfunction pascalCaseTransformFactory(lower, upper) {\n return (word, index) => {\n const char0 = word[0];\n const initial = index > 0 && char0 >= \"0\" && char0 <= \"9\" ? \"_\" + char0 : upper(char0);\n return initial + lower(word.slice(1));\n };\n}\nfunction splitPrefixSuffix(input, options = {}) {\n const splitFn = options.split ?? (options.separateNumbers ? splitSeparateNumbers : split);\n const prefixCharacters = options.prefixCharacters ?? DEFAULT_PREFIX_SUFFIX_CHARACTERS;\n const suffixCharacters = options.suffixCharacters ?? DEFAULT_PREFIX_SUFFIX_CHARACTERS;\n let prefixIndex = 0;\n let suffixIndex = input.length;\n while (prefixIndex < input.length) {\n const char = input.charAt(prefixIndex);\n if (!prefixCharacters.includes(char))\n break;\n prefixIndex++;\n }\n while (suffixIndex > prefixIndex) {\n const index = suffixIndex - 1;\n const char = input.charAt(index);\n if (!suffixCharacters.includes(char))\n break;\n suffixIndex = index;\n }\n return [\n input.slice(0, prefixIndex),\n splitFn(input.slice(prefixIndex, suffixIndex)),\n input.slice(suffixIndex),\n ];\n}\n//# sourceMappingURL=index.js.map","/**\n * Abstract base class for all adapters.\n *\n * An adapter translates store operations (findRecord, createRecord, …) into\n * concrete network requests and returns raw payloads that the serializer layer\n * then normalises. Concrete subclasses (`RestAdapter`, `ODataAdapter`, …)\n * override the abstract CRUD methods and may also override the URL-building\n * helpers to produce protocol-specific URLs.\n *\n * URL construction follows an Ember Data–style pipeline:\n * `buildURL` → `urlForFindRecord` / `urlForQuery` / … → `_composeURL`\n *\n * Configuration surface:\n * - `host` – base URL prefix (e.g. `https://api.example.com`)\n * - `namespace` – path segment appended after the host (e.g. `v2`)\n * - `headers` – headers merged into every request\n * - `coalesceFindRequests` – when `true` the store batches separate\n * `findRecord` calls into a single `findMany` call\n */\n\nimport pluralize from 'pluralize';\nimport { kebabCase } from 'change-case';\n\n/** Union of all operation names the store can issue to an adapter. */\nexport type AdapterRequestType =\n | 'findRecord'\n | 'findAll'\n | 'findMany'\n | 'query'\n | 'queryRecord'\n | 'createRecord'\n | 'updateRecord'\n | 'deleteRecord';\n\n/**\n * A frozen view of a model record passed to the adapter.\n * Adapters read but do not mutate snapshots.\n */\nexport interface AdapterSnapshot {\n /** The record's server-assigned id, or `null` for new records. */\n id: string | null;\n /** The model's registered `modelName`. */\n modelName: string;\n /** Returns the current value for an attribute key. */\n attr(key: string): unknown;\n /** Returns the `belongsTo` relationship value (or just its id when `{ id: true }`). */\n belongsTo(key: string, options?: { id: boolean }): unknown;\n /** Returns the `hasMany` relationship values (or just ids when `{ ids: true }`). */\n hasMany(key: string, options?: { ids: boolean }): unknown;\n /** Returns `{ [key]: [oldValue, newValue] }` for attributes that differ from the server state. */\n changedAttributes(): Record<string, [unknown, unknown]>;\n /** Reference to the live record instance. */\n record: unknown;\n}\n\nexport abstract class Adapter {\n /** Base URL prepended to every generated URL. Empty string = relative URLs. */\n namespace: string = '';\n /** Host prefix, e.g. `https://api.example.com`. */\n host: string = '';\n /** Extra headers merged into every request via `defaultHeaders()`. */\n headers: Record<string, string> = {};\n /**\n * When `true` the store will coalesce multiple `findRecord` calls for the\n * same model type into a single `findMany` network request.\n */\n coalesceFindRequests: boolean = false;\n\n /** Fetches a single record by id. */\n abstract findRecord(\n store: unknown,\n modelName: string,\n id: string,\n snapshot: AdapterSnapshot,\n options?: { include?: string },\n ): Promise<unknown>;\n\n /** Fetches all records of a given model type. */\n abstract findAll(\n store: unknown,\n modelName: string,\n sinceToken: string | null,\n snapshotArray: AdapterSnapshot[],\n options?: { include?: string },\n ): Promise<unknown>;\n\n /** Fetches multiple records by id in a single request. */\n abstract findMany(\n store: unknown,\n modelName: string,\n ids: string[],\n snapshots: AdapterSnapshot[],\n ): Promise<unknown>;\n\n /** Executes an arbitrary server-side query, returning an array of records. */\n abstract query(\n store: unknown,\n modelName: string,\n query: Record<string, unknown>,\n ): Promise<unknown>;\n\n /** Like `query` but returns at most one record. */\n abstract queryRecord(\n store: unknown,\n modelName: string,\n query: Record<string, unknown>,\n ): Promise<unknown>;\n\n /** Persists a new record to the server (POST). */\n abstract createRecord(\n store: unknown,\n modelName: string,\n snapshot: AdapterSnapshot,\n ): Promise<unknown>;\n\n /** Persists all attributes of an existing record (PUT). */\n abstract updateRecord(\n store: unknown,\n modelName: string,\n snapshot: AdapterSnapshot,\n ): Promise<unknown>;\n\n /**\n * Persists only the changed attributes of an existing record (PATCH).\n * Default implementation delegates to `updateRecord`.\n * Override in subclasses to send a partial payload via HTTP PATCH.\n */\n patchRecord(\n store: unknown,\n modelName: string,\n snapshot: AdapterSnapshot,\n ): Promise<unknown> {\n return this.updateRecord(store, modelName, snapshot);\n }\n\n /** Removes a record from the server (DELETE). */\n abstract deleteRecord(\n store: unknown,\n modelName: string,\n snapshot: AdapterSnapshot,\n ): Promise<unknown>;\n\n /**\n * Returns the URL path segment for a given model name.\n * Default: dasherized, pluralized form — e.g. `userPost` → `user-posts`.\n */\n pathForType(modelName: string): string {\n return pluralize.plural(kebabCase(modelName));\n }\n\n /**\n * Assembles a full URL from `host`, `namespace`, and the supplied `path`.\n * Returns an absolute URL when `host` is set, otherwise a root-relative path.\n */\n protected _composeURL(path: string): string {\n const ns = this.namespace.replace(/^\\/+|\\/+$/g, '');\n const hostPrefix = this.host ? this.host.replace(/\\/+$/, '') : '';\n const parts: string[] = [];\n if (hostPrefix) {\n parts.push(hostPrefix);\n }\n if (ns) {\n parts.push(ns);\n }\n parts.push(path);\n if (hostPrefix) {\n return parts.join('/');\n }\n return `/${parts.filter(Boolean).join('/')}`;\n }\n\n /**\n * Dispatches to the appropriate `urlFor*` method based on `requestType`.\n *\n * @param modelName - Registered model name.\n * @param id - Record id(s), or `null` for collection requests.\n * @param snapshot - Snapshot(s) for the request.\n * @param requestType - Operation being performed.\n * @param query - Query parameters (used for `query` / `queryRecord`).\n */\n buildURL(\n modelName: string,\n id: string | string[] | null,\n snapshot: AdapterSnapshot | AdapterSnapshot[] | null,\n requestType: AdapterRequestType,\n query: Record<string, unknown> = {},\n ): string {\n switch (requestType) {\n case 'findRecord':\n return this.urlForFindRecord(id as string, modelName, snapshot as AdapterSnapshot);\n case 'findAll':\n return this.urlForFindAll(modelName, (snapshot as AdapterSnapshot[]) ?? []);\n case 'findMany':\n return this.urlForFindMany(\n (id as string[]) ?? [],\n modelName,\n (snapshot as AdapterSnapshot[]) ?? [],\n );\n case 'query':\n return this.urlForQuery(query, modelName);\n case 'queryRecord':\n return this.urlForQueryRecord(query, modelName);\n case 'createRecord':\n return this.urlForCreateRecord(modelName, snapshot as AdapterSnapshot);\n case 'updateRecord':\n return this.urlForUpdateRecord(\n id as string,\n modelName,\n snapshot as AdapterSnapshot,\n );\n case 'deleteRecord':\n return this.urlForDeleteRecord(\n id as string,\n modelName,\n snapshot as AdapterSnapshot,\n );\n }\n }\n\n /** URL for a `findRecord` request. Default: `<collection>/<id>`. */\n urlForFindRecord(id: string, modelName: string, _snapshot: AdapterSnapshot): string {\n return this._composeURL(`${this.pathForType(modelName)}/${encodeURIComponent(id)}`);\n }\n\n /** URL for a `findAll` request. Default: `<collection>`. */\n urlForFindAll(modelName: string, _snapshots: AdapterSnapshot[]): string {\n return this._composeURL(this.pathForType(modelName));\n }\n\n /** URL for a `findMany` request. Default: `<collection>` (ids appended by the adapter). */\n urlForFindMany(\n _ids: string[],\n modelName: string,\n _snapshots: AdapterSnapshot[],\n ): string {\n return this._composeURL(this.pathForType(modelName));\n }\n\n /** URL for a `query` request. Default: `<collection>`. */\n urlForQuery(_query: Record<string, unknown>, modelName: string): string {\n return this._composeURL(this.pathForType(modelName));\n }\n\n /** URL for a `queryRecord` request. Default: `<collection>`. */\n urlForQueryRecord(_query: Record<string, unknown>, modelName: string): string {\n return this._composeURL(this.pathForType(modelName));\n }\n\n /** URL for a `createRecord` request. Default: `<collection>`. */\n urlForCreateRecord(modelName: string, _snapshot: AdapterSnapshot): string {\n return this._composeURL(this.pathForType(modelName));\n }\n\n /** URL for an `updateRecord` request. Default: `<collection>/<id>`. */\n urlForUpdateRecord(\n id: string,\n modelName: string,\n _snapshot: AdapterSnapshot,\n ): string {\n return this._composeURL(`${this.pathForType(modelName)}/${encodeURIComponent(id)}`);\n }\n\n /** URL for a `deleteRecord` request. Default: `<collection>/<id>`. */\n urlForDeleteRecord(\n id: string,\n modelName: string,\n _snapshot: AdapterSnapshot,\n ): string {\n return this._composeURL(`${this.pathForType(modelName)}/${encodeURIComponent(id)}`);\n }\n\n /**\n * Groups snapshots into batches for `findMany`.\n * Default implementation puts all snapshots in a single batch.\n */\n groupRecordsForFindMany(\n _store: unknown,\n snapshots: AdapterSnapshot[],\n ): AdapterSnapshot[][] {\n return [snapshots];\n }\n\n /**\n * Returns `true` when the store should bypass the cache and reload this\n * record immediately. Default: always `false`.\n */\n shouldReloadRecord(_store: unknown, _snapshot: AdapterSnapshot): boolean {\n return false;\n }\n\n /**\n * Returns `true` when the store should schedule a background reload for\n * this record after returning the cached version. Default: always `true`.\n */\n shouldBackgroundReloadRecord(\n _store: unknown,\n _snapshot: AdapterSnapshot,\n ): boolean {\n return true;\n }\n\n /**\n * Returns `true` when the store should reload the full collection on every\n * `findAll` call. Default: always `false`.\n */\n shouldReloadAll(_store: unknown, _snapshotRecordArray: AdapterSnapshot[]): boolean {\n return false;\n }\n\n /**\n * Returns `true` when the store should schedule a background reload after\n * returning a cached collection. Default: always `true`.\n */\n shouldBackgroundReloadAll(\n _store: unknown,\n _snapshotRecordArray: AdapterSnapshot[],\n ): boolean {\n return true;\n }\n}\n","/**\n * HTTP/REST adapter that communicates with a JSON REST API.\n *\n * `RestAdapter` is the default concrete adapter. It uses the Fetch API and\n * maps each store operation to a conventional HTTP verb:\n *\n * | Operation | Method |\n * |----------------|--------|\n * | findRecord | GET |\n * | findAll | GET |\n * | findMany | GET |\n * | query | GET |\n * | queryRecord | GET |\n * | createRecord | POST |\n * | updateRecord | PUT |\n * | deleteRecord | DELETE |\n *\n * Subclasses (e.g. `JsonApiAdapter`, `ODataAdapter`) override individual\n * methods to adjust headers, HTTP verbs, or body serialization without\n * reimplementing the full adapter.\n */\n\nimport { injectable } from 'tsyringe';\nimport { Adapter, type AdapterSnapshot } from './Adapter.js';\nimport { attachResponseHeaders } from '../cache/cache-utils.js';\n\n@injectable()\nexport class RestAdapter extends Adapter {\n static serializeSnapshotToObject(\n snapshot: AdapterSnapshot,\n ): Record<string, unknown> {\n const body: Record<string, unknown> = {};\n const record = snapshot.record as { _data?: Record<string, unknown> };\n const data = record._data;\n if (data) {\n for (const [key, value] of Object.entries(data)) {\n if (key === '__proto__' || key === 'constructor' || key === 'prototype') {\n continue;\n }\n body[key] = value;\n }\n }\n return body;\n }\n\n static toQueryString(query: Record<string, unknown>): string {\n const parts: string[] = [];\n for (const [key, value] of Object.entries(query)) {\n if (value === undefined || value === null) {\n continue;\n }\n parts.push(\n `${encodeURIComponent(key)}=${encodeURIComponent(String(value))}`,\n );\n }\n return parts.length > 0 ? `?${parts.join('&')}` : '';\n }\n\n /** Headers sent with every read (GET) request. */\n defaultHeaders(): Record<string, string> {\n return {\n Accept: 'application/json',\n ...this.headers,\n };\n }\n\n /** Headers sent with every write (POST / PUT / DELETE) request. */\n mutationHeaders(): Record<string, string> {\n return {\n 'Content-Type': 'application/json',\n ...this.defaultHeaders(),\n };\n }\n\n /**\n * Low-level fetch wrapper used by all operation methods.\n *\n * - Throws an enriched `Error` (with `status` and `body` properties) for\n * any non-2xx response.\n * - Returns `null` for 204 No Content responses.\n * - Attempts JSON parsing; falls back to the raw text string on failure.\n */\n async _fetchJSON(\n url: string,\n init: RequestInit,\n ): Promise<unknown> {\n const response = await fetch(url, init);\n if (!response.ok) {\n let body: unknown = null;\n try {\n body = await response.json();\n } catch {\n /* ignore */\n }\n const error = Object.assign(\n new Error(`Request failed: ${response.status}`),\n { status: response.status, body },\n );\n throw error;\n }\n if (response.status === 204) {\n return null;\n }\n const text = await response.text();\n if (!text) {\n return null;\n }\n let result: unknown;\n try {\n result = JSON.parse(text);\n } catch {\n result = text;\n }\n if (result !== null && typeof result === 'object') {\n const headers: Record<string, string> = {};\n response.headers.forEach((value, key) => {\n headers[key.toLowerCase()] = value;\n });\n attachResponseHeaders(result, headers);\n }\n return result;\n }\n\n override async findRecord(\n _store: unknown,\n modelName: string,\n id: string,\n snapshot: AdapterSnapshot,\n options?: { include?: string },\n ): Promise<unknown> {\n let url = this.buildURL(modelName, id, snapshot, 'findRecord');\n if (options?.include) {\n url += `${url.includes('?') ? '&' : '?'}include=${encodeURIComponent(options.include)}`;\n }\n return this._fetchJSON(url, {\n method: 'GET',\n headers: this.defaultHeaders(),\n });\n }\n\n override async findAll(\n _store: unknown,\n modelName: string,\n _sinceToken: string | null,\n snapshotArray: AdapterSnapshot[],\n options?: { include?: string },\n ): Promise<unknown> {\n let url = this.buildURL(modelName, null, snapshotArray, 'findAll');\n if (options?.include) {\n url += `${url.includes('?') ? '&' : '?'}include=${encodeURIComponent(options.include)}`;\n }\n return this._fetchJSON(url, {\n method: 'GET',\n headers: this.defaultHeaders(),\n });\n }\n\n /**\n * Fetches multiple records by appending an `ids` query parameter.\n * e.g. `/posts?ids=1,2,3`\n */\n override async findMany(\n _store: unknown,\n modelName: string,\n ids: string[],\n snapshots: AdapterSnapshot[],\n ): Promise<unknown> {\n const url = this.buildURL(modelName, ids, snapshots, 'findMany');\n const separator = url.includes('?') ? '&' : '?';\n const fullUrl = `${url}${separator}ids=${ids.map(encodeURIComponent).join(',')}`;\n return this._fetchJSON(fullUrl, {\n method: 'GET',\n headers: this.defaultHeaders(),\n });\n }\n\n override async query(\n _store: unknown,\n modelName: string,\n query: Record<string, unknown>,\n ): Promise<unknown> {\n const base = this.buildURL(modelName, null, null, 'query', query);\n const url = `${base}${RestAdapter.toQueryString(query)}`;\n return this._fetchJSON(url, {\n method: 'GET',\n headers: this.defaultHeaders(),\n });\n }\n\n override async queryRecord(\n _store: unknown,\n modelName: string,\n query: Record<string, unknown>,\n ): Promise<unknown> {\n const base = this.buildURL(modelName, null, null, 'queryRecord', query);\n const url = `${base}${RestAdapter.toQueryString(query)}`;\n return this._fetchJSON(url, {\n method: 'GET',\n headers: this.defaultHeaders(),\n });\n }\n\n override async createRecord(\n _store: unknown,\n modelName: string,\n snapshot: AdapterSnapshot,\n ): Promise<unknown> {\n const url = this.buildURL(modelName, null, snapshot, 'createRecord');\n return this._fetchJSON(url, {\n method: 'POST',\n headers: this.mutationHeaders(),\n body: JSON.stringify(RestAdapter.serializeSnapshotToObject(snapshot)),\n });\n }\n\n override async updateRecord(\n _store: unknown,\n modelName: string,\n snapshot: AdapterSnapshot,\n ): Promise<unknown> {\n const url = this.buildURL(modelName, snapshot.id, snapshot, 'updateRecord');\n return this._fetchJSON(url, {\n method: 'PUT',\n headers: this.mutationHeaders(),\n body: JSON.stringify(RestAdapter.serializeSnapshotToObject(snapshot)),\n });\n }\n\n override async patchRecord(\n _store: unknown,\n modelName: string,\n snapshot: AdapterSnapshot,\n ): Promise<unknown> {\n const url = this.buildURL(modelName, snapshot.id, snapshot, 'updateRecord');\n const changed = snapshot.changedAttributes();\n const partial: Record<string, unknown> = {};\n for (const [key, [, current]] of Object.entries(changed)) {\n partial[key] = current;\n }\n return this._fetchJSON(url, {\n method: 'PATCH',\n headers: this.mutationHeaders(),\n body: JSON.stringify(partial),\n });\n }\n\n override async deleteRecord(\n _store: unknown,\n modelName: string,\n snapshot: AdapterSnapshot,\n ): Promise<unknown> {\n const url = this.buildURL(modelName, snapshot.id, snapshot, 'deleteRecord');\n return this._fetchJSON(url, {\n method: 'DELETE',\n headers: this.defaultHeaders(),\n });\n }\n}\n"],"names":["SPLIT_LOWER_UPPER_RE","SPLIT_UPPER_UPPER_RE","SPLIT_SEPARATE_NUMBER_RE","DEFAULT_STRIP_REGEXP","SPLIT_REPLACE_VALUE","DEFAULT_PREFIX_SUFFIX_CHARACTERS","split","value","result","start","end","splitSeparateNumbers","words","i","word","match","offset","noCase","input","options","prefix","suffix","splitPrefixSuffix","lowerFactory","pascalCase","lower","upper","upperFactory","transform","pascalCaseTransformFactory","kebabCase","locale","index","char0","splitFn","prefixCharacters","suffixCharacters","prefixIndex","suffixIndex","char","Adapter","store","modelName","snapshot","pluralize","path","ns","hostPrefix","parts","id","requestType","query","_snapshot","_snapshots","_ids","_query","_store","snapshots","_snapshotRecordArray","RestAdapter","body","data","key","url","init","response","text","headers","attachResponseHeaders","_sinceToken","snapshotArray","ids","separator","fullUrl","changed","partial","current","__decorateClass","injectable"],"mappings":"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","x_google_ignoreList":[0]}