@warp-drive/legacy 5.9.0-alpha.21 → 5.9.0-alpha.22

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 (467) hide show
  1. package/dist/-private-DQ6Iap2t.js +193 -0
  2. package/dist/-private-DQ6Iap2t.js.map +1 -0
  3. package/dist/-private-DccRZQsm.js +904 -0
  4. package/dist/-private-DccRZQsm.js.map +1 -0
  5. package/dist/adapter/-private.d.ts +33 -0
  6. package/dist/adapter/-private.d.ts.map +1 -0
  7. package/dist/adapter/-private.js +3 -1
  8. package/dist/adapter/error.d.ts +2 -0
  9. package/dist/adapter/error.js +422 -453
  10. package/dist/adapter/error.js.map +1 -0
  11. package/{declarations → dist}/adapter/json-api.d.ts +30 -29
  12. package/dist/adapter/json-api.d.ts.map +1 -0
  13. package/dist/adapter/json-api.js +265 -143
  14. package/dist/adapter/json-api.js.map +1 -0
  15. package/dist/adapter/rest.d.ts +2 -0
  16. package/dist/adapter/rest.js +937 -1136
  17. package/dist/adapter/rest.js.map +1 -0
  18. package/dist/adapter-CARrK3-8.d.ts +784 -0
  19. package/dist/adapter-CARrK3-8.d.ts.map +1 -0
  20. package/dist/adapter-XgLAkYVs.js +1130 -0
  21. package/dist/adapter-XgLAkYVs.js.map +1 -0
  22. package/dist/adapter.d.ts +2 -0
  23. package/dist/adapter.js +1 -1248
  24. package/dist/compat/-private.d.ts +2 -0
  25. package/dist/compat/-private.js +3 -1
  26. package/dist/compat/builders.d.ts +169 -0
  27. package/dist/compat/builders.d.ts.map +1 -0
  28. package/dist/compat/builders.js +205 -245
  29. package/dist/compat/builders.js.map +1 -0
  30. package/dist/compat/extensions.d.ts +2 -0
  31. package/dist/compat/extensions.js +265 -304
  32. package/dist/compat/extensions.js.map +1 -0
  33. package/dist/compat/utils.d.ts +151 -0
  34. package/dist/compat/utils.d.ts.map +1 -0
  35. package/dist/compat/utils.js +187 -206
  36. package/dist/compat/utils.js.map +1 -0
  37. package/dist/compat-BbNNmTM-.d.ts +1386 -0
  38. package/dist/compat-BbNNmTM-.d.ts.map +1 -0
  39. package/dist/compat-g__Pfy2S.js +734 -0
  40. package/dist/compat-g__Pfy2S.js.map +1 -0
  41. package/dist/compat.d.ts +2 -0
  42. package/dist/compat.js +1 -1036
  43. package/dist/error-CzkyXr1Q.d.ts +435 -0
  44. package/dist/error-CzkyXr1Q.d.ts.map +1 -0
  45. package/dist/errors-LQhmDVdd.js +2134 -0
  46. package/dist/errors-LQhmDVdd.js.map +1 -0
  47. package/dist/extensions-DumNm4dA.d.ts +102 -0
  48. package/dist/extensions-DumNm4dA.d.ts.map +1 -0
  49. package/dist/index.d.ts +243 -0
  50. package/dist/index.d.ts.map +1 -0
  51. package/dist/index.js +267 -339
  52. package/dist/index.js.map +1 -0
  53. package/dist/json-BXNPTlcH.js +1106 -0
  54. package/dist/json-BXNPTlcH.js.map +1 -0
  55. package/dist/model/-private.d.ts +3 -0
  56. package/dist/model/-private.js +3 -1
  57. package/dist/model/migration-support.d.ts +335 -0
  58. package/dist/model/migration-support.d.ts.map +1 -0
  59. package/dist/model/migration-support.js +504 -575
  60. package/dist/model/migration-support.js.map +1 -0
  61. package/dist/model-62hn5_PD.d.ts +3107 -0
  62. package/dist/model-62hn5_PD.d.ts.map +1 -0
  63. package/dist/model-BtIEHqYZ.js +683 -0
  64. package/dist/model-BtIEHqYZ.js.map +1 -0
  65. package/dist/model-fragments-Dpn9285r.js +334 -0
  66. package/dist/model-fragments-Dpn9285r.js.map +1 -0
  67. package/dist/model-fragments.d.ts +294 -0
  68. package/dist/model-fragments.d.ts.map +1 -0
  69. package/dist/model-fragments.js +2 -94
  70. package/dist/model.d.ts +404 -0
  71. package/dist/model.d.ts.map +1 -0
  72. package/dist/model.js +3 -670
  73. package/{declarations/adapter/rest.d.ts → dist/rest-0NhtexIq.d.ts} +183 -173
  74. package/dist/rest-0NhtexIq.d.ts.map +1 -0
  75. package/dist/runtime-BPCpkOf1-BgO3Lyjx.js +53 -0
  76. package/dist/runtime-BPCpkOf1-BgO3Lyjx.js.map +1 -0
  77. package/dist/schema-provider-DsKuB5Wb.js +1929 -0
  78. package/dist/schema-provider-DsKuB5Wb.js.map +1 -0
  79. package/{declarations → dist}/serializer/json-api.d.ts +3 -0
  80. package/dist/serializer/json-api.d.ts.map +1 -0
  81. package/dist/serializer/json-api.js +527 -519
  82. package/dist/serializer/json-api.js.map +1 -0
  83. package/{declarations → dist}/serializer/json.d.ts +3 -0
  84. package/dist/serializer/json.d.ts.map +1 -0
  85. package/dist/serializer/json.js +3 -6
  86. package/{declarations/serializer/-private/embedded-records-mixin.d.ts → dist/serializer/rest.d.ts} +56 -1
  87. package/dist/serializer/rest.d.ts.map +1 -0
  88. package/dist/serializer/rest.js +958 -1199
  89. package/dist/serializer/rest.js.map +1 -0
  90. package/dist/serializer/transform.d.ts +313 -0
  91. package/dist/serializer/transform.d.ts.map +1 -0
  92. package/dist/serializer/transform.js +283 -308
  93. package/dist/serializer/transform.js.map +1 -0
  94. package/dist/serializer.d.ts +151 -0
  95. package/dist/serializer.d.ts.map +1 -0
  96. package/dist/serializer.js +205 -205
  97. package/dist/serializer.js.map +1 -0
  98. package/dist/store-C4qYzXei.js +473 -0
  99. package/dist/store-C4qYzXei.js.map +1 -0
  100. package/dist/store.d.ts +13 -0
  101. package/dist/store.d.ts.map +1 -0
  102. package/dist/store.js +1 -641
  103. package/dist/unpkg/dev/-private-CrEyBE-B.js +189 -0
  104. package/dist/unpkg/dev/-private-CrEyBE-B.js.map +1 -0
  105. package/dist/unpkg/dev/-private-vOhxVExH.js +896 -0
  106. package/dist/unpkg/dev/-private-vOhxVExH.js.map +1 -0
  107. package/dist/unpkg/dev/adapter/-private.js +3 -1
  108. package/dist/unpkg/dev/adapter/error.js +421 -452
  109. package/dist/unpkg/dev/adapter/error.js.map +1 -0
  110. package/dist/unpkg/dev/adapter/json-api.js +239 -257
  111. package/dist/unpkg/dev/adapter/json-api.js.map +1 -0
  112. package/dist/unpkg/dev/adapter/rest.js +935 -1134
  113. package/dist/unpkg/dev/adapter/rest.js.map +1 -0
  114. package/dist/unpkg/dev/adapter-Cw0uSl8d.js +1129 -0
  115. package/dist/unpkg/dev/adapter-Cw0uSl8d.js.map +1 -0
  116. package/dist/unpkg/dev/adapter.js +1 -1247
  117. package/dist/unpkg/dev/compat/-private.js +3 -1
  118. package/dist/unpkg/dev/compat/builders.js +204 -247
  119. package/dist/unpkg/dev/compat/builders.js.map +1 -0
  120. package/dist/unpkg/dev/compat/extensions.js +264 -303
  121. package/dist/unpkg/dev/compat/extensions.js.map +1 -0
  122. package/dist/unpkg/dev/compat/utils.js +186 -205
  123. package/dist/unpkg/dev/compat/utils.js.map +1 -0
  124. package/dist/unpkg/dev/compat-CeyxXB7K.js +825 -0
  125. package/dist/unpkg/dev/compat-CeyxXB7K.js.map +1 -0
  126. package/dist/unpkg/dev/compat.js +1 -1178
  127. package/dist/unpkg/dev/errors-1javxsPo.js +2127 -0
  128. package/dist/unpkg/dev/errors-1javxsPo.js.map +1 -0
  129. package/dist/unpkg/dev/index.js +266 -344
  130. package/dist/unpkg/dev/index.js.map +1 -0
  131. package/dist/unpkg/dev/json-DDJji3V3.js +1104 -0
  132. package/dist/unpkg/dev/json-DDJji3V3.js.map +1 -0
  133. package/dist/unpkg/dev/model/-private.js +3 -1
  134. package/dist/unpkg/dev/model/migration-support.js +481 -549
  135. package/dist/unpkg/dev/model/migration-support.js.map +1 -0
  136. package/dist/unpkg/dev/model-C9Xb1R1x.js +655 -0
  137. package/dist/unpkg/dev/model-C9Xb1R1x.js.map +1 -0
  138. package/dist/unpkg/dev/model-fragments-Dpn9285r.js +334 -0
  139. package/dist/unpkg/dev/model-fragments-Dpn9285r.js.map +1 -0
  140. package/dist/unpkg/dev/model-fragments.js +2 -94
  141. package/dist/unpkg/dev/model.js +3 -681
  142. package/dist/unpkg/dev/runtime-BPCpkOf1-BgO3Lyjx.js +53 -0
  143. package/dist/unpkg/dev/runtime-BPCpkOf1-BgO3Lyjx.js.map +1 -0
  144. package/dist/unpkg/dev/schema-provider-Dy6c1J5f.js +1834 -0
  145. package/dist/unpkg/dev/schema-provider-Dy6c1J5f.js.map +1 -0
  146. package/dist/unpkg/dev/serializer/json-api.js +514 -634
  147. package/dist/unpkg/dev/serializer/json-api.js.map +1 -0
  148. package/dist/unpkg/dev/serializer/json.js +3 -4
  149. package/dist/unpkg/dev/serializer/rest.js +954 -1196
  150. package/dist/unpkg/dev/serializer/rest.js.map +1 -0
  151. package/dist/unpkg/dev/serializer/transform.js +283 -308
  152. package/dist/unpkg/dev/serializer/transform.js.map +1 -0
  153. package/dist/unpkg/dev/serializer.js +205 -205
  154. package/dist/unpkg/dev/serializer.js.map +1 -0
  155. package/dist/unpkg/dev/store-D_V8-HQl.js +472 -0
  156. package/dist/unpkg/dev/store-D_V8-HQl.js.map +1 -0
  157. package/dist/unpkg/dev/store.js +1 -649
  158. package/dist/unpkg/dev/util-dSKEgQDp.js +12 -0
  159. package/dist/unpkg/dev/util-dSKEgQDp.js.map +1 -0
  160. package/dist/unpkg/dev/utils-DYC9utVJ.js +11 -0
  161. package/dist/unpkg/dev/utils-DYC9utVJ.js.map +1 -0
  162. package/dist/unpkg/dev-deprecated/-private-CrEyBE-B.js +189 -0
  163. package/dist/unpkg/dev-deprecated/-private-CrEyBE-B.js.map +1 -0
  164. package/dist/unpkg/dev-deprecated/-private-vOhxVExH.js +896 -0
  165. package/dist/unpkg/dev-deprecated/-private-vOhxVExH.js.map +1 -0
  166. package/dist/unpkg/dev-deprecated/adapter/-private.js +3 -1
  167. package/dist/unpkg/dev-deprecated/adapter/error.js +421 -452
  168. package/dist/unpkg/dev-deprecated/adapter/error.js.map +1 -0
  169. package/dist/unpkg/dev-deprecated/adapter/json-api.js +239 -257
  170. package/dist/unpkg/dev-deprecated/adapter/json-api.js.map +1 -0
  171. package/dist/unpkg/dev-deprecated/adapter/rest.js +935 -1134
  172. package/dist/unpkg/dev-deprecated/adapter/rest.js.map +1 -0
  173. package/dist/unpkg/dev-deprecated/adapter-Cw0uSl8d.js +1129 -0
  174. package/dist/unpkg/dev-deprecated/adapter-Cw0uSl8d.js.map +1 -0
  175. package/dist/unpkg/dev-deprecated/adapter.js +1 -1247
  176. package/dist/unpkg/dev-deprecated/compat/-private.js +3 -1
  177. package/dist/unpkg/dev-deprecated/compat/builders.js +204 -247
  178. package/dist/unpkg/dev-deprecated/compat/builders.js.map +1 -0
  179. package/dist/unpkg/dev-deprecated/compat/extensions.js +264 -303
  180. package/dist/unpkg/dev-deprecated/compat/extensions.js.map +1 -0
  181. package/dist/unpkg/dev-deprecated/compat/utils.js +186 -205
  182. package/dist/unpkg/dev-deprecated/compat/utils.js.map +1 -0
  183. package/dist/unpkg/dev-deprecated/compat-DmAgB2NS.js +825 -0
  184. package/dist/unpkg/dev-deprecated/compat-DmAgB2NS.js.map +1 -0
  185. package/dist/unpkg/dev-deprecated/compat.js +1 -1178
  186. package/dist/unpkg/dev-deprecated/errors-C4_aOhY5.js +2128 -0
  187. package/dist/unpkg/dev-deprecated/errors-C4_aOhY5.js.map +1 -0
  188. package/dist/unpkg/dev-deprecated/index.js +266 -343
  189. package/dist/unpkg/dev-deprecated/index.js.map +1 -0
  190. package/dist/unpkg/dev-deprecated/json-DDJji3V3.js +1104 -0
  191. package/dist/unpkg/dev-deprecated/json-DDJji3V3.js.map +1 -0
  192. package/dist/unpkg/dev-deprecated/model/-private.js +3 -1
  193. package/dist/unpkg/dev-deprecated/model/migration-support.js +492 -566
  194. package/dist/unpkg/dev-deprecated/model/migration-support.js.map +1 -0
  195. package/dist/unpkg/dev-deprecated/model-CvSMYkgs.js +660 -0
  196. package/dist/unpkg/dev-deprecated/model-CvSMYkgs.js.map +1 -0
  197. package/dist/unpkg/dev-deprecated/model-fragments-Dpn9285r.js +334 -0
  198. package/dist/unpkg/dev-deprecated/model-fragments-Dpn9285r.js.map +1 -0
  199. package/dist/unpkg/dev-deprecated/model-fragments.js +2 -94
  200. package/dist/unpkg/dev-deprecated/model.js +3 -685
  201. package/dist/unpkg/dev-deprecated/runtime-BPCpkOf1-BgO3Lyjx.js +53 -0
  202. package/dist/unpkg/dev-deprecated/runtime-BPCpkOf1-BgO3Lyjx.js.map +1 -0
  203. package/dist/unpkg/dev-deprecated/schema-provider-Cqttza94.js +1835 -0
  204. package/dist/unpkg/dev-deprecated/schema-provider-Cqttza94.js.map +1 -0
  205. package/dist/unpkg/dev-deprecated/serializer/json-api.js +514 -634
  206. package/dist/unpkg/dev-deprecated/serializer/json-api.js.map +1 -0
  207. package/dist/unpkg/dev-deprecated/serializer/json.js +3 -4
  208. package/dist/unpkg/dev-deprecated/serializer/rest.js +954 -1196
  209. package/dist/unpkg/dev-deprecated/serializer/rest.js.map +1 -0
  210. package/dist/unpkg/dev-deprecated/serializer/transform.js +283 -308
  211. package/dist/unpkg/dev-deprecated/serializer/transform.js.map +1 -0
  212. package/dist/unpkg/dev-deprecated/serializer.js +205 -205
  213. package/dist/unpkg/dev-deprecated/serializer.js.map +1 -0
  214. package/dist/unpkg/dev-deprecated/store-BX7GvXC_.js +472 -0
  215. package/dist/unpkg/dev-deprecated/store-BX7GvXC_.js.map +1 -0
  216. package/dist/unpkg/dev-deprecated/store.js +1 -649
  217. package/dist/unpkg/dev-deprecated/util-9mgEBJ3W.js +18 -0
  218. package/dist/unpkg/dev-deprecated/util-9mgEBJ3W.js.map +1 -0
  219. package/dist/unpkg/dev-deprecated/utils-Cl86-e7F.js +17 -0
  220. package/dist/unpkg/dev-deprecated/utils-Cl86-e7F.js.map +1 -0
  221. package/dist/unpkg/prod/-private-B4bxoTuK.js +160 -0
  222. package/dist/unpkg/prod/-private-B4bxoTuK.js.map +1 -0
  223. package/dist/unpkg/prod/-private-SfXkkHKd.js +745 -0
  224. package/dist/unpkg/prod/-private-SfXkkHKd.js.map +1 -0
  225. package/dist/unpkg/prod/adapter/-private.js +3 -1
  226. package/dist/unpkg/prod/adapter/error.js +418 -447
  227. package/dist/unpkg/prod/adapter/error.js.map +1 -0
  228. package/dist/unpkg/prod/adapter/json-api.js +236 -252
  229. package/dist/unpkg/prod/adapter/json-api.js.map +1 -0
  230. package/dist/unpkg/prod/adapter/rest.js +911 -1097
  231. package/dist/unpkg/prod/adapter/rest.js.map +1 -0
  232. package/dist/unpkg/prod/adapter-Wnk7jizX.js +1111 -0
  233. package/dist/unpkg/prod/adapter-Wnk7jizX.js.map +1 -0
  234. package/dist/unpkg/prod/adapter.js +1 -1214
  235. package/dist/unpkg/prod/compat/-private.js +3 -1
  236. package/dist/unpkg/prod/compat/builders.js +165 -182
  237. package/dist/unpkg/prod/compat/builders.js.map +1 -0
  238. package/dist/unpkg/prod/compat/extensions.js +252 -283
  239. package/dist/unpkg/prod/compat/extensions.js.map +1 -0
  240. package/dist/unpkg/prod/compat/utils.js +183 -200
  241. package/dist/unpkg/prod/compat/utils.js.map +1 -0
  242. package/dist/unpkg/prod/compat-CJ87MzDn.js +547 -0
  243. package/dist/unpkg/prod/compat-CJ87MzDn.js.map +1 -0
  244. package/dist/unpkg/prod/compat.js +1 -742
  245. package/dist/unpkg/prod/errors-Co7YWHoA.js +1977 -0
  246. package/dist/unpkg/prod/errors-Co7YWHoA.js.map +1 -0
  247. package/dist/unpkg/prod/index.js +245 -308
  248. package/dist/unpkg/prod/index.js.map +1 -0
  249. package/dist/unpkg/prod/json-BD1kRTfB.js +1080 -0
  250. package/dist/unpkg/prod/json-BD1kRTfB.js.map +1 -0
  251. package/dist/unpkg/prod/model/-private.js +3 -1
  252. package/dist/unpkg/prod/model/migration-support.js +477 -542
  253. package/dist/unpkg/prod/model/migration-support.js.map +1 -0
  254. package/dist/unpkg/prod/model-BzoOmtka.js +603 -0
  255. package/dist/unpkg/prod/model-BzoOmtka.js.map +1 -0
  256. package/dist/unpkg/prod/model-fragments-Dpn9285r.js +334 -0
  257. package/dist/unpkg/prod/model-fragments-Dpn9285r.js.map +1 -0
  258. package/dist/unpkg/prod/model-fragments.js +2 -94
  259. package/dist/unpkg/prod/model.js +3 -596
  260. package/dist/unpkg/prod/runtime-BPCpkOf1-BgO3Lyjx.js +53 -0
  261. package/dist/unpkg/prod/runtime-BPCpkOf1-BgO3Lyjx.js.map +1 -0
  262. package/dist/unpkg/prod/schema-provider-CKZcqWyP.js +1622 -0
  263. package/dist/unpkg/prod/schema-provider-CKZcqWyP.js.map +1 -0
  264. package/dist/unpkg/prod/serializer/json-api.js +497 -592
  265. package/dist/unpkg/prod/serializer/json-api.js.map +1 -0
  266. package/dist/unpkg/prod/serializer/json.js +3 -4
  267. package/dist/unpkg/prod/serializer/rest.js +938 -1166
  268. package/dist/unpkg/prod/serializer/rest.js.map +1 -0
  269. package/dist/unpkg/prod/serializer/transform.js +283 -308
  270. package/dist/unpkg/prod/serializer/transform.js.map +1 -0
  271. package/dist/unpkg/prod/serializer.js +205 -205
  272. package/dist/unpkg/prod/serializer.js.map +1 -0
  273. package/dist/unpkg/prod/store-RGGc1ilN.js +392 -0
  274. package/dist/unpkg/prod/store-RGGc1ilN.js.map +1 -0
  275. package/dist/unpkg/prod/store.js +1 -517
  276. package/dist/unpkg/prod/util-dSKEgQDp.js +12 -0
  277. package/dist/unpkg/prod/util-dSKEgQDp.js.map +1 -0
  278. package/dist/unpkg/prod/utils-DYC9utVJ.js +11 -0
  279. package/dist/unpkg/prod/utils-DYC9utVJ.js.map +1 -0
  280. package/dist/unpkg/prod-deprecated/-private-B4bxoTuK.js +160 -0
  281. package/dist/unpkg/prod-deprecated/-private-B4bxoTuK.js.map +1 -0
  282. package/dist/unpkg/prod-deprecated/-private-SfXkkHKd.js +745 -0
  283. package/dist/unpkg/prod-deprecated/-private-SfXkkHKd.js.map +1 -0
  284. package/dist/unpkg/prod-deprecated/adapter/-private.js +3 -1
  285. package/dist/unpkg/prod-deprecated/adapter/error.js +418 -447
  286. package/dist/unpkg/prod-deprecated/adapter/error.js.map +1 -0
  287. package/dist/unpkg/prod-deprecated/adapter/json-api.js +236 -252
  288. package/dist/unpkg/prod-deprecated/adapter/json-api.js.map +1 -0
  289. package/dist/unpkg/prod-deprecated/adapter/rest.js +911 -1097
  290. package/dist/unpkg/prod-deprecated/adapter/rest.js.map +1 -0
  291. package/{declarations/adapter.d.ts → dist/unpkg/prod-deprecated/adapter-Wnk7jizX.js} +445 -110
  292. package/dist/unpkg/prod-deprecated/adapter-Wnk7jizX.js.map +1 -0
  293. package/dist/unpkg/prod-deprecated/adapter.js +1 -1214
  294. package/dist/unpkg/prod-deprecated/compat/-private.js +3 -1
  295. package/dist/unpkg/prod-deprecated/compat/builders.js +165 -182
  296. package/dist/unpkg/prod-deprecated/compat/builders.js.map +1 -0
  297. package/dist/unpkg/prod-deprecated/compat/extensions.js +252 -283
  298. package/dist/unpkg/prod-deprecated/compat/extensions.js.map +1 -0
  299. package/dist/unpkg/prod-deprecated/compat/utils.js +183 -200
  300. package/dist/unpkg/prod-deprecated/compat/utils.js.map +1 -0
  301. package/dist/unpkg/prod-deprecated/compat-CJ87MzDn.js +547 -0
  302. package/dist/unpkg/prod-deprecated/compat-CJ87MzDn.js.map +1 -0
  303. package/dist/unpkg/prod-deprecated/compat.js +1 -742
  304. package/dist/unpkg/prod-deprecated/errors-C-opde61.js +1978 -0
  305. package/dist/unpkg/prod-deprecated/errors-C-opde61.js.map +1 -0
  306. package/dist/unpkg/prod-deprecated/index.js +245 -307
  307. package/dist/unpkg/prod-deprecated/index.js.map +1 -0
  308. package/dist/unpkg/prod-deprecated/json-BD1kRTfB.js +1080 -0
  309. package/dist/unpkg/prod-deprecated/json-BD1kRTfB.js.map +1 -0
  310. package/dist/unpkg/prod-deprecated/model/-private.js +3 -1
  311. package/dist/unpkg/prod-deprecated/model/migration-support.js +488 -559
  312. package/dist/unpkg/prod-deprecated/model/migration-support.js.map +1 -0
  313. package/dist/unpkg/prod-deprecated/model-C0bTXzGn.js +604 -0
  314. package/dist/unpkg/prod-deprecated/model-C0bTXzGn.js.map +1 -0
  315. package/dist/unpkg/prod-deprecated/model-fragments-Dpn9285r.js +334 -0
  316. package/dist/unpkg/prod-deprecated/model-fragments-Dpn9285r.js.map +1 -0
  317. package/dist/unpkg/prod-deprecated/model-fragments.js +2 -94
  318. package/dist/unpkg/prod-deprecated/model.js +3 -599
  319. package/dist/unpkg/prod-deprecated/runtime-BPCpkOf1-BgO3Lyjx.js +53 -0
  320. package/dist/unpkg/prod-deprecated/runtime-BPCpkOf1-BgO3Lyjx.js.map +1 -0
  321. package/dist/unpkg/prod-deprecated/schema-provider-lH3qP5tw.js +1635 -0
  322. package/dist/unpkg/prod-deprecated/schema-provider-lH3qP5tw.js.map +1 -0
  323. package/dist/unpkg/prod-deprecated/serializer/json-api.js +497 -592
  324. package/dist/unpkg/prod-deprecated/serializer/json-api.js.map +1 -0
  325. package/dist/unpkg/prod-deprecated/serializer/json.js +3 -4
  326. package/dist/unpkg/prod-deprecated/serializer/rest.js +938 -1166
  327. package/dist/unpkg/prod-deprecated/serializer/rest.js.map +1 -0
  328. package/dist/unpkg/prod-deprecated/serializer/transform.js +283 -308
  329. package/dist/unpkg/prod-deprecated/serializer/transform.js.map +1 -0
  330. package/dist/unpkg/prod-deprecated/serializer.js +205 -205
  331. package/dist/unpkg/prod-deprecated/serializer.js.map +1 -0
  332. package/dist/unpkg/prod-deprecated/store-0L2CkYzh.js +392 -0
  333. package/dist/unpkg/prod-deprecated/store-0L2CkYzh.js.map +1 -0
  334. package/dist/unpkg/prod-deprecated/store.js +1 -517
  335. package/dist/unpkg/prod-deprecated/util-CQQdHX3n.js +14 -0
  336. package/dist/unpkg/prod-deprecated/util-CQQdHX3n.js.map +1 -0
  337. package/dist/unpkg/prod-deprecated/utils-BMI_JwFP.js +13 -0
  338. package/dist/unpkg/prod-deprecated/utils-BMI_JwFP.js.map +1 -0
  339. package/dist/util-Bnx8nm-D.js +29 -0
  340. package/dist/util-Bnx8nm-D.js.map +1 -0
  341. package/dist/utils-ZAytYep8.js +28 -0
  342. package/dist/utils-ZAytYep8.js.map +1 -0
  343. package/package.json +13 -13
  344. package/declarations/adapter/-private/build-url-mixin.d.ts +0 -189
  345. package/declarations/adapter/-private/fastboot-interface.d.ts +0 -8
  346. package/declarations/adapter/-private/utils/continue-on-reject.d.ts +0 -1
  347. package/declarations/adapter/-private/utils/determine-body-promise.d.ts +0 -4
  348. package/declarations/adapter/-private/utils/fetch.d.ts +0 -8
  349. package/declarations/adapter/-private/utils/parse-response-headers.d.ts +0 -1
  350. package/declarations/adapter/-private/utils/serialize-into-hash.d.ts +0 -6
  351. package/declarations/adapter/-private/utils/serialize-query-params.d.ts +0 -5
  352. package/declarations/adapter/-private.d.ts +0 -5
  353. package/declarations/adapter/error.d.ts +0 -431
  354. package/declarations/compat/-private.d.ts +0 -13
  355. package/declarations/compat/builders/find-all.d.ts +0 -34
  356. package/declarations/compat/builders/find-record.d.ts +0 -56
  357. package/declarations/compat/builders/query.d.ts +0 -66
  358. package/declarations/compat/builders/save-record.d.ts +0 -34
  359. package/declarations/compat/builders/utils.d.ts +0 -3
  360. package/declarations/compat/builders.d.ts +0 -14
  361. package/declarations/compat/extensions.d.ts +0 -99
  362. package/declarations/compat/legacy-network-handler/fetch-manager.d.ts +0 -55
  363. package/declarations/compat/legacy-network-handler/identifier-has-id.d.ts +0 -2
  364. package/declarations/compat/legacy-network-handler/legacy-data-fetch.d.ts +0 -11
  365. package/declarations/compat/legacy-network-handler/legacy-data-utils.d.ts +0 -5
  366. package/declarations/compat/legacy-network-handler/legacy-network-handler.d.ts +0 -9
  367. package/declarations/compat/legacy-network-handler/minimum-adapter-interface.d.ts +0 -528
  368. package/declarations/compat/legacy-network-handler/minimum-serializer-interface.d.ts +0 -220
  369. package/declarations/compat/legacy-network-handler/serializer-response.d.ts +0 -6
  370. package/declarations/compat/legacy-network-handler/snapshot-record-array.d.ts +0 -110
  371. package/declarations/compat/legacy-network-handler/snapshot.d.ts +0 -255
  372. package/declarations/compat/utils.d.ts +0 -148
  373. package/declarations/compat.d.ts +0 -189
  374. package/declarations/index.d.ts +0 -244
  375. package/declarations/model/-private/attr.d.ts +0 -191
  376. package/declarations/model/-private/belongs-to.d.ts +0 -195
  377. package/declarations/model/-private/debug/assert-polymorphic-type.d.ts +0 -5
  378. package/declarations/model/-private/errors.d.ts +0 -289
  379. package/declarations/model/-private/has-many.d.ts +0 -162
  380. package/declarations/model/-private/hooks.d.ts +0 -36
  381. package/declarations/model/-private/legacy-relationships-support.d.ts +0 -47
  382. package/declarations/model/-private/model-for-mixin.d.ts +0 -3
  383. package/declarations/model/-private/model-methods.d.ts +0 -39
  384. package/declarations/model/-private/model.d.ts +0 -1279
  385. package/declarations/model/-private/notify-changes.d.ts +0 -4
  386. package/declarations/model/-private/promise-belongs-to.d.ts +0 -40
  387. package/declarations/model/-private/promise-many-array.d.ts +0 -130
  388. package/declarations/model/-private/record-state.d.ts +0 -58
  389. package/declarations/model/-private/references/belongs-to.d.ts +0 -488
  390. package/declarations/model/-private/references/has-many.d.ts +0 -498
  391. package/declarations/model/-private/schema-provider.d.ts +0 -66
  392. package/declarations/model/-private/type-utils.d.ts +0 -57
  393. package/declarations/model/-private/util.d.ts +0 -5
  394. package/declarations/model/-private.d.ts +0 -8
  395. package/declarations/model/migration-support.d.ts +0 -306
  396. package/declarations/model-fragments/extensions/fragment-array.d.ts +0 -54
  397. package/declarations/model-fragments/extensions/fragment.d.ts +0 -50
  398. package/declarations/model-fragments/hooks/model-for.d.ts +0 -27
  399. package/declarations/model-fragments/index.d.ts +0 -13
  400. package/declarations/model-fragments/instance-initializers/fragment-extensions.d.ts +0 -15
  401. package/declarations/model-fragments/utilities/with-array-defaults.d.ts +0 -56
  402. package/declarations/model-fragments/utilities/with-fragment-array-defaults.d.ts +0 -38
  403. package/declarations/model-fragments/utilities/with-fragment-defaults.d.ts +0 -34
  404. package/declarations/model-fragments/utilities/with-legacy.d.ts +0 -11
  405. package/declarations/model-fragments.d.ts +0 -9
  406. package/declarations/model.d.ts +0 -49
  407. package/declarations/serializer/-private/transforms/boolean.d.ts +0 -60
  408. package/declarations/serializer/-private/transforms/date.d.ts +0 -42
  409. package/declarations/serializer/-private/transforms/number.d.ts +0 -42
  410. package/declarations/serializer/-private/transforms/string.d.ts +0 -42
  411. package/declarations/serializer/-private/transforms/transform.d.ts +0 -118
  412. package/declarations/serializer/-private/utils.d.ts +0 -27
  413. package/declarations/serializer/rest.d.ts +0 -51
  414. package/declarations/serializer/transform.d.ts +0 -5
  415. package/declarations/serializer.d.ts +0 -252
  416. package/declarations/store/-private.d.ts +0 -223
  417. package/declarations/store.d.ts +0 -10
  418. package/dist/-private-BG3bMiKp.js +0 -1211
  419. package/dist/errors-DZKA206g.js +0 -2589
  420. package/dist/hooks-BvOqJBei.js +0 -105
  421. package/dist/json-DU8m1pGf.js +0 -1336
  422. package/dist/model-for-CXkJw59V.js +0 -297
  423. package/dist/runtime-BPCpkOf1-BKOwiRJp.js +0 -65
  424. package/dist/schema-provider-DtPOp0d7.js +0 -2382
  425. package/dist/serialize-into-hash-DPZYoF-i.js +0 -261
  426. package/dist/unpkg/dev/-private-DtjBbEgy.js +0 -1206
  427. package/dist/unpkg/dev/errors-DngRU-If.js +0 -2585
  428. package/dist/unpkg/dev/hooks-UuiLxWxS.js +0 -104
  429. package/dist/unpkg/dev/json-K2Y9z6MN.js +0 -1333
  430. package/dist/unpkg/dev/model-for-CXkJw59V.js +0 -297
  431. package/dist/unpkg/dev/runtime-BPCpkOf1-BKOwiRJp.js +0 -65
  432. package/dist/unpkg/dev/schema-provider-0D7f-QOn.js +0 -2272
  433. package/dist/unpkg/dev/serialize-into-hash-B2xDbuo5.js +0 -259
  434. package/dist/unpkg/dev/util-DvanW33H.js +0 -20
  435. package/dist/unpkg/dev/utils-BhvS1iTS.js +0 -8
  436. package/dist/unpkg/dev-deprecated/-private-DtjBbEgy.js +0 -1206
  437. package/dist/unpkg/dev-deprecated/errors-Bzidntpi.js +0 -2588
  438. package/dist/unpkg/dev-deprecated/hooks-DVXhMW14.js +0 -104
  439. package/dist/unpkg/dev-deprecated/json-K2Y9z6MN.js +0 -1333
  440. package/dist/unpkg/dev-deprecated/model-for-CXkJw59V.js +0 -297
  441. package/dist/unpkg/dev-deprecated/runtime-BPCpkOf1-BKOwiRJp.js +0 -65
  442. package/dist/unpkg/dev-deprecated/schema-provider-ZwO5_fZw.js +0 -2292
  443. package/dist/unpkg/dev-deprecated/serialize-into-hash-B2xDbuo5.js +0 -259
  444. package/dist/unpkg/dev-deprecated/util-CWr5WQOT.js +0 -24
  445. package/dist/unpkg/dev-deprecated/utils-C9PJehtL.js +0 -12
  446. package/dist/unpkg/prod/-private-BdyZaGEh.js +0 -971
  447. package/dist/unpkg/prod/errors-B-PWeYlW.js +0 -2337
  448. package/dist/unpkg/prod/hooks-Bx-zBziU.js +0 -72
  449. package/dist/unpkg/prod/json-Qewu-UN9.js +0 -1300
  450. package/dist/unpkg/prod/model-for-CXkJw59V.js +0 -297
  451. package/dist/unpkg/prod/runtime-BPCpkOf1-BKOwiRJp.js +0 -65
  452. package/dist/unpkg/prod/schema-provider-BgRqk8i9.js +0 -1951
  453. package/dist/unpkg/prod/serialize-into-hash-DGlzQteF.js +0 -215
  454. package/dist/unpkg/prod/util-DvanW33H.js +0 -20
  455. package/dist/unpkg/prod/utils-BhvS1iTS.js +0 -8
  456. package/dist/unpkg/prod-deprecated/-private-BdyZaGEh.js +0 -971
  457. package/dist/unpkg/prod-deprecated/errors-Dl2J9d1D.js +0 -2340
  458. package/dist/unpkg/prod-deprecated/hooks-Cm60wWTf.js +0 -72
  459. package/dist/unpkg/prod-deprecated/json-Qewu-UN9.js +0 -1300
  460. package/dist/unpkg/prod-deprecated/model-for-CXkJw59V.js +0 -297
  461. package/dist/unpkg/prod-deprecated/runtime-BPCpkOf1-BKOwiRJp.js +0 -65
  462. package/dist/unpkg/prod-deprecated/schema-provider-Dh6tRqVI.js +0 -1980
  463. package/dist/unpkg/prod-deprecated/serialize-into-hash-DGlzQteF.js +0 -215
  464. package/dist/unpkg/prod-deprecated/util-B6cn-i93.js +0 -23
  465. package/dist/unpkg/prod-deprecated/utils-BUWwQwCh.js +0 -11
  466. package/dist/util-Dul6TZts.js +0 -35
  467. package/dist/utils-Cqw9eRj5.js +0 -23
@@ -1,1209 +1,1010 @@
1
- import { getOwner } from '@ember/application';
2
- import { warn } from '@ember/debug';
3
- import { computed } from '@ember/object';
4
- import { Adapter, BuildURLMixin } from '../adapter.js';
5
- import { b as serializeIntoHash, d as determineBodyPromise, g as getFetchFunction, s as serializeQueryParams, p as parseResponseHeaders } from "../serialize-into-hash-DPZYoF-i.js";
6
- import { InvalidError, ServerError, ConflictError, NotFoundError, ForbiddenError, UnauthorizedError, AdapterError, TimeoutError, AbortError } from './error.js';
7
- import { macroCondition, getGlobalConfig } from '@embroider/macros';
8
- import { d as decorateMethodV2 } from "../runtime-BPCpkOf1-BKOwiRJp.js";
9
-
10
- /* eslint-disable @typescript-eslint/no-unsafe-member-access */
11
- /* eslint-disable @typescript-eslint/no-unsafe-assignment */
12
- /* eslint-disable @typescript-eslint/no-unsafe-return */
13
-
1
+ import { n as decorateMethodV2 } from "../runtime-BPCpkOf1-BgO3Lyjx.js";
2
+ import { n as BuildURLMixin, t as Adapter } from "../adapter-XgLAkYVs.js";
3
+ import { AbortError, AdapterError, ConflictError, ForbiddenError, InvalidError, NotFoundError, ServerError, TimeoutError, UnauthorizedError } from "./error.js";
4
+ import { a as determineBodyPromise, i as serializeQueryParams, n as getFetchFunction, o as parseResponseHeaders, t as serializeIntoHash } from "../-private-DQ6Iap2t.js";
5
+ import { getOwner } from "@ember/application";
6
+ import { warn } from "@ember/debug";
7
+ import { getGlobalConfig, macroCondition } from "@embroider/macros";
8
+ import { computed } from "@ember/object";
9
+
10
+ //#region src/adapter/rest.ts
11
+ /**
12
+ * The query params built by {@link RESTAdapter.buildQuery | buildQuery} for a
13
+ * `findAll`/`findRecord` request.
14
+ */
15
+ /**
16
+ * The options passed to the native `fetch` API by {@link RESTAdapter._fetchRequest | _fetchRequest}.
17
+ */
18
+ /**
19
+ * The options passed to jQuery's `$.ajax` by {@link RESTAdapter._ajaxRequest | _ajaxRequest}.
20
+ */
21
+ /**
22
+ * A minimal description of an in-flight request, used for building
23
+ * error messages when a request fails.
24
+ */
14
25
  const AdapterWithBuildURLMixin = Adapter.extend(BuildURLMixin);
15
-
16
26
  /**
17
- * :::danger
18
- ⚠️ **This is LEGACY documentation** for a feature that is no longer encouraged to be used.
19
- If starting a new app or thinking of implementing a new adapter, consider writing a
20
- {@link Handler} instead to be used with the {@link RequestManager}
21
- :::
22
-
23
- The REST adapter allows your store to communicate with an HTTP server by
24
- transmitting JSON via XHR.
25
-
26
- This adapter is designed around the idea that the JSON exchanged with
27
- the server should be conventional. It builds URLs in a manner that follows
28
- the structure of most common REST-style web services.
29
-
30
- ## Success and failure
31
-
32
- The REST adapter will consider a success any response with a status code
33
- of the 2xx family ("Success"), as well as 304 ("Not Modified"). Any other
34
- status code will be considered a failure.
35
-
36
- On success, the request promise will be resolved with the full response
37
- payload.
38
-
39
- Failed responses with status code 422 ("Unprocessable Entity") will be
40
- considered "invalid". The response will be discarded, except for the
41
- `errors` key. The request promise will be rejected with a `InvalidError`.
42
- This error object will encapsulate the saved `errors` value.
43
-
44
- Any other status codes will be treated as an "adapter error". The request
45
- promise will be rejected, similarly to the "invalid" case, but with
46
- an instance of `AdapterError` instead.
47
-
48
- ## JSON Structure
49
-
50
- The REST adapter expects the JSON returned from your server to follow
51
- these conventions.
52
-
53
- ### Object Root
54
-
55
- The JSON payload should be an object that contains the record inside a
56
- root property. For example, in response to a `GET` request for
57
- `/posts/1`, the JSON should look like this:
58
-
59
- ```js
60
- {
61
- "posts": {
62
- "id": 1,
63
- "title": "I'm Running to Reform the W3C",
64
- "author": "Yehuda Katz"
65
- }
66
- }
67
- ```
68
-
69
- Similarly, in response to a `GET` request for `/posts`, the JSON should
70
- look like this:
71
-
72
- ```js
73
- {
74
- "posts": [
75
- {
76
- "id": 1,
77
- "title": "I'm Running to Reform the W3C",
78
- "author": "Yehuda Katz"
79
- },
80
- {
81
- "id": 2,
82
- "title": "Rails is omakase",
83
- "author": "D2H"
84
- }
85
- ]
86
- }
87
- ```
88
-
89
- Note that the object root can be pluralized for both a single-object response
90
- and an array response: the REST adapter is not strict on this. Further, if the
91
- HTTP server responds to a `GET` request to `/posts/1` (e.g. the response to a
92
- `findRecord` query) with more than one object in the array, WarpDrive will
93
- only display the object with the matching ID.
94
-
95
- ### Conventional Names
96
-
97
- Attribute names in your JSON payload should be the camelCased versions of
98
- the attributes in your Ember.js models.
99
-
100
- For example, if you have a `Person` model:
101
-
102
- ```js [app/models/person.js]
103
- import { Model, attr } from '@warp-drive/legacy/model';
104
-
105
- export default Model.extend({
106
- firstName: attr('string'),
107
- lastName: attr('string'),
108
- occupation: attr('string')
109
- });
110
- ```
111
-
112
- The JSON returned should look like this:
113
-
114
- ```js
115
- {
116
- "people": {
117
- "id": 5,
118
- "firstName": "Zaphod",
119
- "lastName": "Beeblebrox",
120
- "occupation": "President"
121
- }
122
- }
123
- ```
124
-
125
- #### Relationships
126
-
127
- Relationships are usually represented by ids to the record in the
128
- relationship. The related records can then be sideloaded in the
129
- response under a key for the type.
130
-
131
- ```js
132
- {
133
- "posts": {
134
- "id": 5,
135
- "title": "I'm Running to Reform the W3C",
136
- "author": "Yehuda Katz",
137
- "comments": [1, 2]
138
- },
139
- "comments": [{
140
- "id": 1,
141
- "author": "User 1",
142
- "message": "First!",
143
- }, {
144
- "id": 2,
145
- "author": "User 2",
146
- "message": "Good Luck!",
147
- }]
148
- }
149
- ```
150
-
151
- If the records in the relationship are not known when the response
152
- is serialized it's also possible to represent the relationship as a
153
- URL using the `links` key in the response. WarpDrive will fetch
154
- this URL to resolve the relationship when it is accessed for the
155
- first time.
156
-
157
- ```js
158
- {
159
- "posts": {
160
- "id": 5,
161
- "title": "I'm Running to Reform the W3C",
162
- "author": "Yehuda Katz",
163
- "links": {
164
- "comments": "/posts/5/comments"
165
- }
166
- }
167
- }
168
- ```
169
-
170
- ### Errors
171
-
172
- If a response is considered a failure, the JSON payload is expected to include
173
- a top-level key `errors`, detailing any specific issues. For example:
27
+ * :::danger
28
+ ⚠️ **This is LEGACY documentation** for a feature that is no longer encouraged to be used.
29
+ If starting a new app or thinking of implementing a new adapter, consider writing a
30
+ {@link Handler} instead to be used with the {@link RequestManager}
31
+ :::
174
32
 
175
- ```js
176
- {
177
- "errors": {
178
- "msg": "Something went wrong"
179
- }
180
- }
181
- ```
33
+ The REST adapter allows your store to communicate with an HTTP server by
34
+ transmitting JSON via XHR.
182
35
 
183
- This adapter does not make any assumptions as to the format of the `errors`
184
- object. It will simply be passed along as is, wrapped in an instance
185
- of `InvalidError` or `AdapterError`. The serializer can interpret it
186
- afterwards.
36
+ This adapter is designed around the idea that the JSON exchanged with
37
+ the server should be conventional. It builds URLs in a manner that follows
38
+ the structure of most common REST-style web services.
187
39
 
188
- ## Customization
40
+ ## Success and failure
189
41
 
190
- ### Endpoint path customization
42
+ The REST adapter will consider a success any response with a status code
43
+ of the 2xx family ("Success"), as well as 304 ("Not Modified"). Any other
44
+ status code will be considered a failure.
191
45
 
192
- Endpoint paths can be prefixed with a `namespace` by setting the namespace
193
- property on the adapter:
46
+ On success, the request promise will be resolved with the full response
47
+ payload.
194
48
 
195
- ```js [app/adapters/application.js]
196
- import { RESTAdapter } from '@warp-drive/legacy/adapter/rest';
49
+ Failed responses with status code 422 ("Unprocessable Entity") will be
50
+ considered "invalid". The response will be discarded, except for the
51
+ `errors` key. The request promise will be rejected with a `InvalidError`.
52
+ This error object will encapsulate the saved `errors` value.
197
53
 
198
- export default class ApplicationAdapter extends RESTAdapter {
199
- namespace = 'api/1';
200
- }
201
- ```
202
- Requests for the `Person` model would now target `/api/1/people/1`.
54
+ Any other status codes will be treated as an "adapter error". The request
55
+ promise will be rejected, similarly to the "invalid" case, but with
56
+ an instance of `AdapterError` instead.
203
57
 
204
- ### Host customization
58
+ ## JSON Structure
205
59
 
206
- An adapter can target other hosts by setting the `host` property.
60
+ The REST adapter expects the JSON returned from your server to follow
61
+ these conventions.
207
62
 
208
- ```js [app/adapters/application.js]
209
- import { RESTAdapter } from '@warp-drive/legacy/adapter/rest';
63
+ ### Object Root
210
64
 
211
- export default class ApplicationAdapter extends RESTAdapter {
212
- host = 'https://api.example.com';
213
- }
214
- ```
65
+ The JSON payload should be an object that contains the record inside a
66
+ root property. For example, in response to a `GET` request for
67
+ `/posts/1`, the JSON should look like this:
215
68
 
216
- ### Headers customization
217
-
218
- Some APIs require HTTP headers, e.g. to provide an API key. Arbitrary
219
- headers can be set as key/value pairs on the `RESTAdapter`'s `headers`
220
- object and WarpDrive will send them along with each ajax request.
221
-
222
-
223
- ```js [app/adapters/application.js]
224
- import { RESTAdapter } from '@warp-drive/legacy/adapter/rest';
225
-
226
- export default class ApplicationAdapter extends RESTAdapter {
227
- get headers() {
228
- return {
229
- 'API_KEY': 'secret key',
230
- 'ANOTHER_HEADER': 'Some header value'
231
- };
232
- }
233
- }
234
- ```
235
-
236
- @public
237
- */
238
- class RESTAdapter extends AdapterWithBuildURLMixin {
239
- /**
240
- * @private
241
- */
242
-
243
- /**
244
- * @private
245
- */
246
-
247
- /**
248
- * See "Host customization" above.
249
- */
250
-
251
- /**
252
- * See "Namespace customization" above.
253
- */
254
-
255
- /**
256
- This property allows ajax to still be used instead when `false`.
257
- @default true
258
- @public
259
- */
260
- useFetch = true;
261
-
262
- /**
263
- * The `Content-Type` header used when serializing request bodies
264
- * that don't otherwise specify one.
265
- */
266
- _defaultContentType = 'application/json; charset=utf-8';
267
-
268
- /**
269
- * The FastBoot service instance, if running in a FastBoot environment.
270
- * Lazily looked up on first access.
271
- */
272
- get fastboot() {
273
- // Avoid computed property override deprecation in fastboot as suggested by:
274
- // https://deprecations.emberjs.com/v3.x/#toc_computed-property-override
275
- const fastboot = this._fastboot;
276
- if (fastboot) {
277
- return fastboot;
278
- }
279
- return this._fastboot = getOwner(this).lookup('service:fastboot');
280
- }
281
-
282
- /**
283
- * Sets the FastBoot service instance to use.
284
- */
285
- static {
286
- decorateMethodV2(this.prototype, "fastboot", [computed()]);
287
- }
288
- set fastboot(value) {
289
- this._fastboot = value;
290
- }
291
-
292
- /**
293
- By default, the RESTAdapter will send the query params sorted alphabetically to the
294
- server.
295
- For example:
296
- ```js
297
- store.query('posts', { sort: 'price', category: 'pets' });
298
- ```
299
- will generate a requests like this `/posts?category=pets&sort=price`, even if the
300
- parameters were specified in a different order.
301
- That way the generated URL will be deterministic and that simplifies caching mechanisms
302
- in the backend.
303
- Setting `sortQueryParams` to a falsey value will respect the original order.
304
- In case you want to sort the query parameters with a different criteria, set
305
- `sortQueryParams` to your custom sort function.
306
- ```js [app/adapters/application.js]
307
- import { RESTAdapter } from '@warp-drive/legacy/adapter/rest';
308
- export default class ApplicationAdapter extends RESTAdapter {
309
- sortQueryParams(params) {
310
- let sortedKeys = Object.keys(params).sort().reverse();
311
- let len = sortedKeys.length, newParams = {};
312
- for (let i = 0; i < len; i++) {
313
- newParams[sortedKeys[i]] = params[sortedKeys[i]];
314
- }
315
- return newParams;
316
- }
317
- }
318
- ```
319
- @public
320
- */
321
- sortQueryParams(obj) {
322
- const keys = Object.keys(obj);
323
- const len = keys.length;
324
- if (len < 2) {
325
- return obj;
326
- }
327
- const newQueryParams = {};
328
- const sortedKeys = keys.sort();
329
- for (let i = 0; i < len; i++) {
330
- newQueryParams[sortedKeys[i]] = obj[sortedKeys[i]];
331
- }
332
- return newQueryParams;
333
- }
334
-
335
- /**
336
- By default the RESTAdapter will send each find request coming from a `store.find`
337
- or from accessing a relationship separately to the server. If your server supports passing
338
- ids as a query string, you can set coalesceFindRequests to true to coalesce all find requests
339
- within a single runloop.
340
- For example, if you have an initial payload of:
341
- ```javascript
342
- {
343
- post: {
344
- id: 1,
345
- comments: [1, 2]
346
- }
347
- }
348
- ```
349
- By default calling `post.comments` will trigger the following requests(assuming the
350
- comments haven't been loaded before):
351
- ```
352
- GET /comments/1
353
- GET /comments/2
354
- ```
355
- If you set coalesceFindRequests to `true` it will instead trigger the following request:
356
- ```
357
- GET /comments?ids[]=1&ids[]=2
358
- ```
359
- Setting coalesceFindRequests to `true` also works for `store.find` requests and `belongsTo`
360
- relationships accessed within the same runloop. If you set `coalesceFindRequests: true`
361
- ```javascript
362
- store.findRecord('comment', 1);
363
- store.findRecord('comment', 2);
364
- ```
365
- will also send a request to: `GET /comments?ids[]=1&ids[]=2`
366
- Note: Requests coalescing rely on URL building strategy. So if you override `buildURL` in your app
367
- `groupRecordsForFindMany` more likely should be overridden as well in order for coalescing to work.
368
- @public
369
- */
370
- get coalesceFindRequests() {
371
- const coalesceFindRequests = this._coalesceFindRequests;
372
- if (typeof coalesceFindRequests === 'boolean') {
373
- return coalesceFindRequests;
374
- }
375
- return this._coalesceFindRequests = false;
376
- }
377
- set coalesceFindRequests(value) {
378
- this._coalesceFindRequests = value;
379
- }
380
-
381
- /**
382
- Endpoint paths can be prefixed with a `namespace` by setting the namespace
383
- property on the adapter:
384
- ```js [app/adapters/application.js]
385
- import { RESTAdapter } from '@warp-drive/legacy/adapter/rest';
386
- export default class ApplicationAdapter extends RESTAdapter {
387
- namespace = 'api/1';
388
- }
389
- ```
390
- Requests for the `Post` model would now target `/api/1/post/`.
391
- @public
392
- */
393
-
394
- /**
395
- An adapter can target other hosts by setting the `host` property.
396
- ```js [app/adapters/application.js]
397
- import { RESTAdapter } from '@warp-drive/legacy/adapter/rest';
398
- export default class ApplicationAdapter extends RESTAdapter {
399
- host = 'https://api.example.com';
400
- }
401
- ```
402
- Requests for the `Post` model would now target `https://api.example.com/post/`.
403
- @public
404
- */
69
+ ```js
70
+ {
71
+ "posts": {
72
+ "id": 1,
73
+ "title": "I'm Running to Reform the W3C",
74
+ "author": "Yehuda Katz"
75
+ }
76
+ }
77
+ ```
78
+
79
+ Similarly, in response to a `GET` request for `/posts`, the JSON should
80
+ look like this:
81
+
82
+ ```js
83
+ {
84
+ "posts": [
85
+ {
86
+ "id": 1,
87
+ "title": "I'm Running to Reform the W3C",
88
+ "author": "Yehuda Katz"
89
+ },
90
+ {
91
+ "id": 2,
92
+ "title": "Rails is omakase",
93
+ "author": "D2H"
94
+ }
95
+ ]
96
+ }
97
+ ```
405
98
 
406
- /**
407
- Some APIs require HTTP headers, e.g. to provide an API
408
- key. Arbitrary headers can be set as key/value pairs on the
409
- `RESTAdapter`'s `headers` object and WarpDrive will send them
410
- along with each ajax request..
411
- ```js [app/adapters/application.js]
412
- import { RESTAdapter } from '@warp-drive/legacy/adapter/rest';
413
- export default class ApplicationAdapter extends RESTAdapter {
414
- get headers() {
415
- return {
416
- 'API_KEY': 'secret key',
417
- 'ANOTHER_HEADER': 'Some header value'
418
- };
419
- }
420
- }
421
- ```
422
- @public
423
- */
99
+ Note that the object root can be pluralized for both a single-object response
100
+ and an array response: the REST adapter is not strict on this. Further, if the
101
+ HTTP server responds to a `GET` request to `/posts/1` (e.g. the response to a
102
+ `findRecord` query) with more than one object in the array, WarpDrive will
103
+ only display the object with the matching ID.
424
104
 
425
- /**
426
- Called by the store in order to fetch the JSON for a given
427
- type and ID.
428
- The `findRecord` method makes an Ajax request to a URL computed by
429
- `buildURL`, and returns a promise for the resulting payload.
430
- This method performs an HTTP `GET` request with the id provided as part of the query string.
431
- @since 1.13.0
432
- @public
433
- */
434
- findRecord(store, type, id, snapshot) {
435
- const url = this.buildURL(type.modelName, id, snapshot, 'findRecord');
436
- const query = this.buildQuery(snapshot);
437
- return this.ajax(url, 'GET', {
438
- data: query
439
- });
440
- }
105
+ ### Conventional Names
441
106
 
442
- /**
443
- Called by the store in order to fetch a JSON array for all
444
- of the records for a given type.
445
- The `findAll` method makes an Ajax (HTTP GET) request to a URL computed by `buildURL`, and returns a
446
- promise for the resulting payload.
447
- @public
448
- */
449
- findAll(store, type, neverUsed, snapshotRecordArray) {
450
- const query = this.buildQuery(snapshotRecordArray);
451
- const url = this.buildURL(type.modelName, null, snapshotRecordArray, 'findAll');
452
- return this.ajax(url, 'GET', {
453
- data: query
454
- });
455
- }
107
+ Attribute names in your JSON payload should be the camelCased versions of
108
+ the attributes in your Ember.js models.
456
109
 
457
- /**
458
- Called by the store in order to fetch a JSON array for
459
- the records that match a particular query.
460
- The `query` method makes an Ajax (HTTP GET) request to a URL
461
- computed by `buildURL`, and returns a promise for the resulting
462
- payload.
463
- The `query` argument is a simple JavaScript object that will be passed directly
464
- to the server as parameters.
465
- @public
466
- */
467
- query(store, type, query) {
468
- const url = this.buildURL(type.modelName, null, null, 'query', query);
469
- if (this.sortQueryParams) {
470
- query = this.sortQueryParams(query);
471
- }
472
- return this.ajax(url, 'GET', {
473
- data: query
474
- });
475
- }
110
+ For example, if you have a `Person` model:
476
111
 
477
- /**
478
- Called by the store in order to fetch a JSON object for
479
- the record that matches a particular query.
480
- The `queryRecord` method makes an Ajax (HTTP GET) request to a URL
481
- computed by `buildURL`, and returns a promise for the resulting
482
- payload.
483
- The `query` argument is a simple JavaScript object that will be passed directly
484
- to the server as parameters.
485
- @since 1.13.0
486
- @public
487
- */
488
- queryRecord(store, type, query, adapterOptions) {
489
- const url = this.buildURL(type.modelName, null, null, 'queryRecord', query);
490
- if (this.sortQueryParams) {
491
- query = this.sortQueryParams(query);
492
- }
493
- return this.ajax(url, 'GET', {
494
- data: query
495
- });
496
- }
112
+ ```js [app/models/person.js]
113
+ import { Model, attr } from '@warp-drive/legacy/model';
497
114
 
498
- /**
499
- Called by the store in order to fetch several records together if `coalesceFindRequests` is true
500
- For example, if the original payload looks like:
501
- ```js
502
- {
503
- "id": 1,
504
- "title": "Rails is omakase",
505
- "comments": [ 1, 2, 3 ]
506
- }
507
- ```
508
- The IDs will be passed as a URL-encoded Array of IDs, in this form:
509
- ```
510
- ids[]=1&ids[]=2&ids[]=3
511
- ```
512
- Many servers, such as Rails and PHP, will automatically convert this URL-encoded array
513
- into an Array for you on the server-side. If you want to encode the
514
- IDs, differently, just override this (one-line) method.
515
- The `findMany` method makes an Ajax (HTTP GET) request to a URL computed by `buildURL`, and returns a
516
- promise for the resulting payload.
517
- @public
518
- */
519
- findMany(store, type, ids, snapshots) {
520
- const url = this.buildURL(type.modelName, ids, snapshots, 'findMany');
521
- return this.ajax(url, 'GET', {
522
- data: {
523
- ids: ids
524
- }
525
- });
526
- }
115
+ export default Model.extend({
116
+ firstName: attr('string'),
117
+ lastName: attr('string'),
118
+ occupation: attr('string')
119
+ });
120
+ ```
527
121
 
528
- /**
529
- Called by the store in order to fetch a JSON array for
530
- the unloaded records in a has-many relationship that were originally
531
- specified as a URL (inside of `links`).
532
- For example, if your original payload looks like this:
533
- ```js
534
- {
535
- "post": {
536
- "id": 1,
537
- "title": "Rails is omakase",
538
- "links": { "comments": "/posts/1/comments" }
539
- }
540
- }
541
- ```
542
- This method will be called with the parent record and `/posts/1/comments`.
543
- The `findHasMany` method will make an Ajax (HTTP GET) request to the originally specified URL.
544
- The format of your `links` value will influence the final request URL via the `urlPrefix` method:
545
- * Links beginning with `//`, `http://`, `https://`, will be used as is, with no further manipulation.
546
- * Links beginning with a single `/` will have the current adapter's `host` value prepended to it.
547
- * Links with no beginning `/` will have a parentURL prepended to it, via the current adapter's `buildURL`.
548
- @public
549
- */
550
- findHasMany(store, snapshot, url, relationship) {
551
- const id = snapshot.id;
552
- const type = snapshot.modelName;
553
- macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
554
- if (!test) {
555
- throw new Error(`Attempted to fetch the hasMany relationship for ${type}, but the record has no id`);
556
- }
557
- })(typeof id === 'string' && id.length > 0) : {};
558
- url = this.urlPrefix(url, this.buildURL(type, id, snapshot, 'findHasMany'));
559
- return this.ajax(url, 'GET');
560
- }
122
+ The JSON returned should look like this:
561
123
 
562
- /**
563
- Called by the store in order to fetch the JSON for the unloaded record in a
564
- belongs-to relationship that was originally specified as a URL (inside of
565
- `links`).
566
- For example, if your original payload looks like this:
567
- ```js
568
- {
569
- "person": {
570
- "id": 1,
571
- "name": "Tom Dale",
572
- "links": { "group": "/people/1/group" }
573
- }
574
- }
575
- ```
576
- This method will be called with the parent record and `/people/1/group`.
577
- The `findBelongsTo` method will make an Ajax (HTTP GET) request to the originally specified URL.
578
- The format of your `links` value will influence the final request URL via the `urlPrefix` method:
579
- * Links beginning with `//`, `http://`, `https://`, will be used as is, with no further manipulation.
580
- * Links beginning with a single `/` will have the current adapter's `host` value prepended to it.
581
- * Links with no beginning `/` will have a parentURL prepended to it, via the current adapter's `buildURL`.
582
- @public
583
- */
584
- findBelongsTo(store, snapshot, url, relationship) {
585
- const id = snapshot.id;
586
- const type = snapshot.modelName;
587
- macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
588
- if (!test) {
589
- throw new Error(`Attempted to fetch the belongsTo relationship for ${type}, but the record has no id`);
590
- }
591
- })(typeof id === 'string' && id.length > 0) : {};
592
- url = this.urlPrefix(url, this.buildURL(type, id, snapshot, 'findBelongsTo'));
593
- return this.ajax(url, 'GET');
594
- }
124
+ ```js
125
+ {
126
+ "people": {
127
+ "id": 5,
128
+ "firstName": "Zaphod",
129
+ "lastName": "Beeblebrox",
130
+ "occupation": "President"
131
+ }
132
+ }
133
+ ```
134
+
135
+ #### Relationships
136
+
137
+ Relationships are usually represented by ids to the record in the
138
+ relationship. The related records can then be sideloaded in the
139
+ response under a key for the type.
140
+
141
+ ```js
142
+ {
143
+ "posts": {
144
+ "id": 5,
145
+ "title": "I'm Running to Reform the W3C",
146
+ "author": "Yehuda Katz",
147
+ "comments": [1, 2]
148
+ },
149
+ "comments": [{
150
+ "id": 1,
151
+ "author": "User 1",
152
+ "message": "First!",
153
+ }, {
154
+ "id": 2,
155
+ "author": "User 2",
156
+ "message": "Good Luck!",
157
+ }]
158
+ }
159
+ ```
160
+
161
+ If the records in the relationship are not known when the response
162
+ is serialized it's also possible to represent the relationship as a
163
+ URL using the `links` key in the response. WarpDrive will fetch
164
+ this URL to resolve the relationship when it is accessed for the
165
+ first time.
166
+
167
+ ```js
168
+ {
169
+ "posts": {
170
+ "id": 5,
171
+ "title": "I'm Running to Reform the W3C",
172
+ "author": "Yehuda Katz",
173
+ "links": {
174
+ "comments": "/posts/5/comments"
175
+ }
176
+ }
177
+ }
178
+ ```
595
179
 
596
- /**
597
- Called by the store when a newly created record is
598
- saved via the `save` method on a model record instance.
599
- The `createRecord` method serializes the record and makes an Ajax (HTTP POST) request
600
- to a URL computed by `buildURL`.
601
- See `serialize` for information on how to customize the serialized form
602
- of a record.
603
- @public
604
- */
605
- createRecord(store, type, snapshot) {
606
- const url = this.buildURL(type.modelName, null, snapshot, 'createRecord');
607
- const data = serializeIntoHash(store, type, snapshot);
608
- return this.ajax(url, 'POST', {
609
- data
610
- });
611
- }
180
+ ### Errors
612
181
 
613
- /**
614
- Called by the store when an existing record is saved
615
- via the `save` method on a model record instance.
616
- The `updateRecord` method serializes the record and makes an Ajax (HTTP PUT) request
617
- to a URL computed by `buildURL`.
618
- See `serialize` for information on how to customize the serialized form
619
- of a record.
620
- @public
621
- */
622
- updateRecord(store, schema, snapshot) {
623
- const data = serializeIntoHash(store, schema, snapshot, {});
624
- const type = snapshot.modelName;
625
- const id = snapshot.id;
626
- macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
627
- if (!test) {
628
- throw new Error(`Attempted to update the ${type} record, but the record has no id`);
629
- }
630
- })(typeof id === 'string' && id.length > 0) : {};
631
- const url = this.buildURL(type, id, snapshot, 'updateRecord');
632
- return this.ajax(url, 'PUT', {
633
- data
634
- });
635
- }
182
+ If a response is considered a failure, the JSON payload is expected to include
183
+ a top-level key `errors`, detailing any specific issues. For example:
636
184
 
637
- /**
638
- Called by the store when a record is deleted.
639
- The `deleteRecord` method makes an Ajax (HTTP DELETE) request to a URL computed by `buildURL`.
640
- @public
641
- */
642
- deleteRecord(store, schema, snapshot) {
643
- const type = snapshot.modelName;
644
- const id = snapshot.id;
645
- macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
646
- if (!test) {
647
- throw new Error(`Attempted to delete the ${type} record, but the record has no id`);
648
- }
649
- })(typeof id === 'string' && id.length > 0) : {};
650
- return this.ajax(this.buildURL(type, id, snapshot, 'deleteRecord'), 'DELETE');
651
- }
185
+ ```js
186
+ {
187
+ "errors": {
188
+ "msg": "Something went wrong"
189
+ }
190
+ }
191
+ ```
652
192
 
653
- /**
654
- @private
655
- */
656
- _stripIDFromURL(store, snapshot) {
657
- const type = snapshot.modelName;
658
- const id = snapshot.id;
659
- macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
660
- if (!test) {
661
- throw new Error(`Attempted to strip the url from the ${type} record for coalescing, but the record has no id`);
662
- }
663
- })(typeof id === 'string' && id.length > 0) : {};
664
- const url = this.buildURL(type, id, snapshot);
665
- const expandedURL = url.split('/');
666
- // Case when the url is of the format ...something/:id
667
- // We are decodeURIComponent-ing the lastSegment because if it represents
668
- // the id, it has been encodeURIComponent-ified within `buildURL`. If we
669
- // don't do this, then records with id having special characters are not
670
- // coalesced correctly (see GH #4190 for the reported bug)
671
- const lastSegment = expandedURL[expandedURL.length - 1];
672
- if (decodeURIComponent(lastSegment) === id) {
673
- expandedURL[expandedURL.length - 1] = '';
674
- } else if (id && endsWith(lastSegment, '?id=' + id)) {
675
- //Case when the url is of the format ...something?id=:id
676
- expandedURL[expandedURL.length - 1] = lastSegment.substring(0, lastSegment.length - id.length - 1);
677
- }
678
- return expandedURL.join('/');
679
- }
193
+ This adapter does not make any assumptions as to the format of the `errors`
194
+ object. It will simply be passed along as is, wrapped in an instance
195
+ of `InvalidError` or `AdapterError`. The serializer can interpret it
196
+ afterwards.
680
197
 
681
- /**
682
- * The maximum URL length to allow when coalescing `findRecord` requests
683
- * into a single `findMany` request via {@link RESTAdapter.groupRecordsForFindMany | groupRecordsForFindMany}.
684
- * Requests that would exceed this length are split into multiple groups.
685
- *
686
- * See http://stackoverflow.com/questions/417142/what-is-the-maximum-length-of-a-url-in-different-browsers
687
- */
688
- maxURLLength = 2048;
198
+ ## Customization
689
199
 
690
- /**
691
- Organize records into groups, each of which is to be passed to separate
692
- calls to `findMany`.
693
- This implementation groups together records that have the same base URL but
694
- differing ids. For example `/comments/1` and `/comments/2` will be grouped together
695
- because we know findMany can coalesce them together as `/comments?ids[]=1&ids[]=2`
696
- It also supports urls where ids are passed as a query param, such as `/comments?id=1`
697
- but not those where there is more than 1 query param such as `/comments?id=2&name=David`
698
- Currently only the query param of `id` is supported. If you need to support others, please
699
- override this or the `_stripIDFromURL` method.
700
- It does not group records that have differing base urls, such as for example: `/posts/1/comments/2`
701
- and `/posts/2/comments/3`
702
- @public
703
- @return an array of arrays of records, each of which is to be
704
- loaded separately by `findMany`.
705
- */
706
- groupRecordsForFindMany(store, snapshots) {
707
- const groups = new Map();
708
- const maxURLLength = this.maxURLLength;
709
- snapshots.forEach(snapshot => {
710
- const baseUrl = this._stripIDFromURL(store, snapshot);
711
- if (!groups.has(baseUrl)) {
712
- groups.set(baseUrl, []);
713
- }
714
- groups.get(baseUrl).push(snapshot);
715
- });
716
- const groupsArray = [];
717
- groups.forEach((group, key) => {
718
- const paramNameLength = '&ids%5B%5D='.length;
719
- const splitGroups = splitGroupToFitInUrl(store, this, group, maxURLLength, paramNameLength);
720
- splitGroups.forEach(splitGroup => groupsArray.push(splitGroup));
721
- });
722
- return groupsArray;
723
- }
200
+ ### Endpoint path customization
724
201
 
725
- /**
726
- Takes an ajax response, and returns the json payload or an error.
727
- By default this hook just returns the json payload passed to it.
728
- You might want to override it in two cases:
729
- 1. Your API might return useful results in the response headers.
730
- Response headers are passed in as the second argument.
731
- 2. Your API might return errors as successful responses with status code
732
- 200 and an Errors text or object. You can return a `InvalidError` or a
733
- `AdapterError` (or a sub class) from this hook and it will automatically
734
- reject the promise and put your record into the invalid or error state.
735
- Returning a `InvalidError` from this method will cause the
736
- record to transition into the `invalid` state and make the
737
- `errors` object available on the record. When returning an
738
- `InvalidError` the store will attempt to normalize the error data
739
- returned from the server using the serializer's `extractErrors`
740
- method.
741
- @since 1.13.0
742
- @public
743
- */
744
- handleResponse(status, headers, payload, requestData) {
745
- if (this.isSuccess(status, headers, payload)) {
746
- return payload;
747
- } else if (this.isInvalid(status, headers, payload)) {
748
- const errorPayload = payload ?? {};
749
- return new InvalidError(typeof errorPayload === 'object' && 'errors' in errorPayload ? errorPayload.errors : undefined);
750
- }
751
- const errors = this.normalizeErrorResponse(status, headers, payload);
752
- const detailedMessage = this.generatedDetailedMessage(status, headers, payload, requestData);
753
- switch (status) {
754
- case 401:
755
- return new UnauthorizedError(errors, detailedMessage);
756
- case 403:
757
- return new ForbiddenError(errors, detailedMessage);
758
- case 404:
759
- return new NotFoundError(errors, detailedMessage);
760
- case 409:
761
- return new ConflictError(errors, detailedMessage);
762
- default:
763
- if (status >= 500) {
764
- return new ServerError(errors, detailedMessage);
765
- }
766
- }
767
- return new AdapterError(errors, detailedMessage);
768
- }
202
+ Endpoint paths can be prefixed with a `namespace` by setting the namespace
203
+ property on the adapter:
769
204
 
770
- /**
771
- Default `handleResponse` implementation uses this hook to decide if the
772
- response is a success.
773
- @since 1.13.0
774
- @public
775
- */
776
- isSuccess(status, _headers, _payload) {
777
- return status >= 200 && status < 300 || status === 304;
778
- }
205
+ ```js [app/adapters/application.js]
206
+ import { RESTAdapter } from '@warp-drive/legacy/adapter/rest';
779
207
 
780
- /**
781
- Default `handleResponse` implementation uses this hook to decide if the
782
- response is an invalid error.
783
- @since 1.13.0
784
- @public
785
- */
786
- isInvalid(status, _headers, _payload) {
787
- return status === 422;
788
- }
208
+ export default class ApplicationAdapter extends RESTAdapter {
209
+ namespace = 'api/1';
210
+ }
211
+ ```
212
+ Requests for the `Person` model would now target `/api/1/people/1`.
789
213
 
790
- /**
791
- Takes a URL, an HTTP method and a hash of data, and makes an
792
- HTTP request.
793
- When the server responds with a payload, WarpDrive will call into `extractSingle`
794
- or `extractArray` (depending on whether the original query was for one record or
795
- many records).
796
- By default, `ajax` method has the following behavior:
797
- * It sets the response `dataType` to `"json"`
798
- * If the HTTP method is not `"GET"`, it sets the `Content-Type` to be
799
- `application/json; charset=utf-8`
800
- * If the HTTP method is not `"GET"`, it stringifies the data passed in. The
801
- data is the serialized record in the case of a save.
802
- * Registers success and failure handlers.
803
- @private
804
- */
805
- async ajax(url, type, options = {}) {
806
- const requestData = {
807
- url: url,
808
- method: type
809
- };
810
- if (this.useFetch) {
811
- // @ts-expect-error poorly typed
812
- const hash = this.ajaxOptions(url, type, options);
813
- const response = await this._fetchRequest(hash);
814
- const payload = await determineBodyPromise(response, requestData);
815
- if (response.ok && !(payload instanceof Error)) {
816
- return fetchSuccessHandler(this, payload, response, requestData);
817
- } else {
818
- // eslint-disable-next-line @typescript-eslint/only-throw-error
819
- throw fetchErrorHandler(this, payload, response, null, requestData);
820
- }
821
- } else {
822
- return execjQAjax(this, requestData, options);
823
- }
824
- }
214
+ ### Host customization
825
215
 
826
- /**
827
- @private
828
- @param options jQuery ajax options to be used for the ajax request
829
- */
830
- _ajaxRequest(options) {
831
- macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
832
- if (!test) {
833
- throw new Error('You must install jQuery globally when `useFetch` is false');
834
- }
835
- })(typeof jQuery !== 'undefined') : {};
836
- void jQuery.ajax(options);
837
- }
838
- /**
839
- @private
840
- */
841
- _fetchRequest(options) {
842
- const fetchFunction = getFetchFunction();
843
- return fetchFunction(options.url, options);
844
- }
845
- /**
846
- @private
847
- */
848
- _ajax(options) {
849
- if (this.useFetch) {
850
- void this._fetchRequest(options);
851
- } else {
852
- this._ajaxRequest(options);
853
- }
854
- }
216
+ An adapter can target other hosts by setting the `host` property.
855
217
 
856
- /**
857
- @private
858
- */
859
- ajaxOptions(url, method, options) {
860
- let reqOptions = Object.assign({
861
- url,
862
- method,
863
- type: method
864
- }, options);
865
- if (this.headers !== undefined) {
866
- // @ts-expect-error poorly typed
867
- reqOptions.headers = {
868
- ...this.headers,
869
- ...reqOptions.headers
870
- };
871
- } else if (!options.headers) {
872
- reqOptions.headers = {};
873
- }
218
+ ```js [app/adapters/application.js]
219
+ import { RESTAdapter } from '@warp-drive/legacy/adapter/rest';
874
220
 
875
- // @ts-expect-error poorly typed
876
- const contentType = reqOptions.contentType || this._defaultContentType;
877
- if (this.useFetch) {
878
- // @ts-expect-error poorly typed
879
- if (reqOptions.data && reqOptions.type !== 'GET' && reqOptions.headers) {
880
- if (!reqOptions.headers['Content-Type'] && !reqOptions.headers['content-type']) {
881
- reqOptions.headers['content-type'] = contentType;
882
- }
883
- }
884
- // @ts-expect-error poorly typed
885
- reqOptions = fetchOptions(reqOptions);
886
- } else {
887
- // GET requests without a body should not have a content-type header
888
- // and may be unexpected by a server
889
- // @ts-expect-error poorly typed
890
- if (reqOptions.data && reqOptions.type !== 'GET') {
891
- reqOptions = {
892
- ...reqOptions,
893
- contentType
894
- };
895
- }
896
- // @ts-expect-error poorly typed
897
- reqOptions = ajaxOptions(reqOptions, this);
898
- }
899
- reqOptions.url = this._ajaxURL(reqOptions.url);
900
- return reqOptions;
901
- }
221
+ export default class ApplicationAdapter extends RESTAdapter {
222
+ host = 'https://api.example.com';
223
+ }
224
+ ```
902
225
 
903
- /**
904
- * @private
905
- */
906
- _ajaxURL(url) {
907
- if (this.fastboot?.isFastBoot) {
908
- const httpRegex = /^https?:\/\//;
909
- const protocolRelativeRegex = /^\/\//;
910
- const protocol = this.fastboot.request.protocol;
911
- const host = this.fastboot.request.host;
912
- if (protocolRelativeRegex.test(url)) {
913
- return `${protocol}${url}`;
914
- } else if (!httpRegex.test(url)) {
915
- try {
916
- return `${protocol}//${host}${url}`;
917
- } catch (fbError) {
918
- throw new Error('You are using WarpDrive with no host defined in your adapter. This will attempt to use the host of the FastBoot request, which is not configured for the current host of this request. Please set the hostWhitelist property for in your environment.js. FastBoot Error: ' + fbError.message);
919
- }
920
- }
921
- }
922
- return url;
923
- }
226
+ ### Headers customization
924
227
 
925
- /**
926
- @private
927
- */
928
- parseErrorResponse(responseText) {
929
- let json = responseText;
930
- try {
931
- json = JSON.parse(responseText);
932
- } catch {
933
- // ignored
934
- }
935
- return json;
936
- }
228
+ Some APIs require HTTP headers, e.g. to provide an API key. Arbitrary
229
+ headers can be set as key/value pairs on the `RESTAdapter`'s `headers`
230
+ object and WarpDrive will send them along with each ajax request.
937
231
 
938
- /**
939
- @private
940
- @return errors payload
941
- */
942
- normalizeErrorResponse(status, _headers, payload) {
943
- if (payload && typeof payload === 'object' && 'errors' in payload && Array.isArray(payload.errors)) {
944
- return payload.errors;
945
- } else {
946
- return [{
947
- status: `${status}`,
948
- // Set to a string per the JSON API spec: https://jsonapi.org/format/#errors
949
- title: 'The backend responded with an error',
950
- // Detail is intended to be a string, but backends be non-compliant.
951
- // stringifying gives the user a more friendly error in this situation, whereas
952
- // they'd instead receive [object Object].
953
- // JSON.stringify will convert *anything* to a string without erroring.
954
- detail: typeof payload === 'string' ? payload : JSON.stringify(payload)
955
- }];
956
- }
957
- }
958
232
 
959
- /**
960
- Generates a detailed ("friendly") error message, with plenty
961
- of information for debugging (good luck!)
962
- @private
963
- @return detailed error message
964
- */
965
- generatedDetailedMessage(status, headers, payload, requestData) {
966
- let shortenedPayload;
967
- const payloadContentType = headers['content-type'] || 'Empty Content-Type';
968
- if (payloadContentType === 'text/html' && typeof payload === 'string' && payload.length > 250) {
969
- shortenedPayload = '[Omitted Lengthy HTML]';
970
- } else if (typeof payload === 'object' && payload !== null) {
971
- shortenedPayload = JSON.stringify(payload, null, 2);
972
- } else {
973
- shortenedPayload = payload;
974
- }
975
- const requestDescription = requestData.method + ' ' + requestData.url;
976
- const payloadDescription = 'Payload (' + payloadContentType + ')';
977
- return ['Ember Data Request ' + requestDescription + ' returned a ' + status, payloadDescription, shortenedPayload].join('\n');
978
- }
233
+ ```js [app/adapters/application.js]
234
+ import { RESTAdapter } from '@warp-drive/legacy/adapter/rest';
979
235
 
980
- /**
981
- Used by `findAll` and `findRecord` to build the query's `data` hash
982
- supplied to the ajax method.
983
- @since 2.5.0
984
- @public
985
- */
986
- buildQuery(snapshot) {
987
- const query = {};
988
- if (snapshot) {
989
- const {
990
- include
991
- } = snapshot;
992
- if (include) {
993
- // note: if user passed in an array, this will serialize like `?include[]=foo&include[]=bar`
994
- // but if user passed in a string, this will serialize like `?include=foo,bar`
995
- // users that want consistent behavior should override this method
996
- query.include = include;
997
- }
998
- }
999
- return query;
1000
- }
236
+ export default class ApplicationAdapter extends RESTAdapter {
237
+ get headers() {
238
+ return {
239
+ 'API_KEY': 'secret key',
240
+ 'ANOTHER_HEADER': 'Some header value'
241
+ };
1001
242
  }
243
+ }
244
+ ```
1002
245
 
1003
- // eslint-disable-next-line @typescript-eslint/no-empty-object-type
1004
-
246
+ @public
247
+ */
248
+ var RESTAdapter = class extends AdapterWithBuildURLMixin {
249
+ /**
250
+ * @private
251
+ */
252
+ /**
253
+ * @private
254
+ */
255
+ /**
256
+ * See "Host customization" above.
257
+ */
258
+ /**
259
+ * See "Namespace customization" above.
260
+ */
261
+ /**
262
+ This property allows ajax to still be used instead when `false`.
263
+ @default true
264
+ @public
265
+ */
266
+ useFetch = true;
267
+ /**
268
+ * The `Content-Type` header used when serializing request bodies
269
+ * that don't otherwise specify one.
270
+ */
271
+ _defaultContentType = "application/json; charset=utf-8";
272
+ /**
273
+ * The FastBoot service instance, if running in a FastBoot environment.
274
+ * Lazily looked up on first access.
275
+ */
276
+ get fastboot() {
277
+ const fastboot = this._fastboot;
278
+ if (fastboot) return fastboot;
279
+ return this._fastboot = getOwner(this).lookup("service:fastboot");
280
+ }
281
+ /**
282
+ * Sets the FastBoot service instance to use.
283
+ */
284
+ static {
285
+ decorateMethodV2(this.prototype, "fastboot", [computed()]);
286
+ }
287
+ set fastboot(value) {
288
+ this._fastboot = value;
289
+ }
290
+ /**
291
+ By default, the RESTAdapter will send the query params sorted alphabetically to the
292
+ server.
293
+ For example:
294
+ ```js
295
+ store.query('posts', { sort: 'price', category: 'pets' });
296
+ ```
297
+ will generate a requests like this `/posts?category=pets&sort=price`, even if the
298
+ parameters were specified in a different order.
299
+ That way the generated URL will be deterministic and that simplifies caching mechanisms
300
+ in the backend.
301
+ Setting `sortQueryParams` to a falsey value will respect the original order.
302
+ In case you want to sort the query parameters with a different criteria, set
303
+ `sortQueryParams` to your custom sort function.
304
+ ```js [app/adapters/application.js]
305
+ import { RESTAdapter } from '@warp-drive/legacy/adapter/rest';
306
+ export default class ApplicationAdapter extends RESTAdapter {
307
+ sortQueryParams(params) {
308
+ let sortedKeys = Object.keys(params).sort().reverse();
309
+ let len = sortedKeys.length, newParams = {};
310
+ for (let i = 0; i < len; i++) {
311
+ newParams[sortedKeys[i]] = params[sortedKeys[i]];
312
+ }
313
+ return newParams;
314
+ }
315
+ }
316
+ ```
317
+ @public
318
+ */
319
+ sortQueryParams(obj) {
320
+ const keys = Object.keys(obj);
321
+ const len = keys.length;
322
+ if (len < 2) return obj;
323
+ const newQueryParams = {};
324
+ const sortedKeys = keys.sort();
325
+ for (let i = 0; i < len; i++) newQueryParams[sortedKeys[i]] = obj[sortedKeys[i]];
326
+ return newQueryParams;
327
+ }
328
+ /**
329
+ By default the RESTAdapter will send each find request coming from a `store.find`
330
+ or from accessing a relationship separately to the server. If your server supports passing
331
+ ids as a query string, you can set coalesceFindRequests to true to coalesce all find requests
332
+ within a single runloop.
333
+ For example, if you have an initial payload of:
334
+ ```javascript
335
+ {
336
+ post: {
337
+ id: 1,
338
+ comments: [1, 2]
339
+ }
340
+ }
341
+ ```
342
+ By default calling `post.comments` will trigger the following requests(assuming the
343
+ comments haven't been loaded before):
344
+ ```
345
+ GET /comments/1
346
+ GET /comments/2
347
+ ```
348
+ If you set coalesceFindRequests to `true` it will instead trigger the following request:
349
+ ```
350
+ GET /comments?ids[]=1&ids[]=2
351
+ ```
352
+ Setting coalesceFindRequests to `true` also works for `store.find` requests and `belongsTo`
353
+ relationships accessed within the same runloop. If you set `coalesceFindRequests: true`
354
+ ```javascript
355
+ store.findRecord('comment', 1);
356
+ store.findRecord('comment', 2);
357
+ ```
358
+ will also send a request to: `GET /comments?ids[]=1&ids[]=2`
359
+ Note: Requests coalescing rely on URL building strategy. So if you override `buildURL` in your app
360
+ `groupRecordsForFindMany` more likely should be overridden as well in order for coalescing to work.
361
+ @public
362
+ */
363
+ get coalesceFindRequests() {
364
+ const coalesceFindRequests = this._coalesceFindRequests;
365
+ if (typeof coalesceFindRequests === "boolean") return coalesceFindRequests;
366
+ return this._coalesceFindRequests = false;
367
+ }
368
+ set coalesceFindRequests(value) {
369
+ this._coalesceFindRequests = value;
370
+ }
371
+ /**
372
+ Endpoint paths can be prefixed with a `namespace` by setting the namespace
373
+ property on the adapter:
374
+ ```js [app/adapters/application.js]
375
+ import { RESTAdapter } from '@warp-drive/legacy/adapter/rest';
376
+ export default class ApplicationAdapter extends RESTAdapter {
377
+ namespace = 'api/1';
378
+ }
379
+ ```
380
+ Requests for the `Post` model would now target `/api/1/post/`.
381
+ @public
382
+ */
383
+ /**
384
+ An adapter can target other hosts by setting the `host` property.
385
+ ```js [app/adapters/application.js]
386
+ import { RESTAdapter } from '@warp-drive/legacy/adapter/rest';
387
+ export default class ApplicationAdapter extends RESTAdapter {
388
+ host = 'https://api.example.com';
389
+ }
390
+ ```
391
+ Requests for the `Post` model would now target `https://api.example.com/post/`.
392
+ @public
393
+ */
394
+ /**
395
+ Some APIs require HTTP headers, e.g. to provide an API
396
+ key. Arbitrary headers can be set as key/value pairs on the
397
+ `RESTAdapter`'s `headers` object and WarpDrive will send them
398
+ along with each ajax request..
399
+ ```js [app/adapters/application.js]
400
+ import { RESTAdapter } from '@warp-drive/legacy/adapter/rest';
401
+ export default class ApplicationAdapter extends RESTAdapter {
402
+ get headers() {
403
+ return {
404
+ 'API_KEY': 'secret key',
405
+ 'ANOTHER_HEADER': 'Some header value'
406
+ };
407
+ }
408
+ }
409
+ ```
410
+ @public
411
+ */
412
+ /**
413
+ Called by the store in order to fetch the JSON for a given
414
+ type and ID.
415
+ The `findRecord` method makes an Ajax request to a URL computed by
416
+ `buildURL`, and returns a promise for the resulting payload.
417
+ This method performs an HTTP `GET` request with the id provided as part of the query string.
418
+ @since 1.13.0
419
+ @public
420
+ */
421
+ findRecord(store, type, id, snapshot) {
422
+ const url = this.buildURL(type.modelName, id, snapshot, "findRecord");
423
+ const query = this.buildQuery(snapshot);
424
+ return this.ajax(url, "GET", { data: query });
425
+ }
426
+ /**
427
+ Called by the store in order to fetch a JSON array for all
428
+ of the records for a given type.
429
+ The `findAll` method makes an Ajax (HTTP GET) request to a URL computed by `buildURL`, and returns a
430
+ promise for the resulting payload.
431
+ @public
432
+ */
433
+ findAll(store, type, neverUsed, snapshotRecordArray) {
434
+ const query = this.buildQuery(snapshotRecordArray);
435
+ const url = this.buildURL(type.modelName, null, snapshotRecordArray, "findAll");
436
+ return this.ajax(url, "GET", { data: query });
437
+ }
438
+ /**
439
+ Called by the store in order to fetch a JSON array for
440
+ the records that match a particular query.
441
+ The `query` method makes an Ajax (HTTP GET) request to a URL
442
+ computed by `buildURL`, and returns a promise for the resulting
443
+ payload.
444
+ The `query` argument is a simple JavaScript object that will be passed directly
445
+ to the server as parameters.
446
+ @public
447
+ */
448
+ query(store, type, query) {
449
+ const url = this.buildURL(type.modelName, null, null, "query", query);
450
+ if (this.sortQueryParams) query = this.sortQueryParams(query);
451
+ return this.ajax(url, "GET", { data: query });
452
+ }
453
+ /**
454
+ Called by the store in order to fetch a JSON object for
455
+ the record that matches a particular query.
456
+ The `queryRecord` method makes an Ajax (HTTP GET) request to a URL
457
+ computed by `buildURL`, and returns a promise for the resulting
458
+ payload.
459
+ The `query` argument is a simple JavaScript object that will be passed directly
460
+ to the server as parameters.
461
+ @since 1.13.0
462
+ @public
463
+ */
464
+ queryRecord(store, type, query, adapterOptions) {
465
+ const url = this.buildURL(type.modelName, null, null, "queryRecord", query);
466
+ if (this.sortQueryParams) query = this.sortQueryParams(query);
467
+ return this.ajax(url, "GET", { data: query });
468
+ }
469
+ /**
470
+ Called by the store in order to fetch several records together if `coalesceFindRequests` is true
471
+ For example, if the original payload looks like:
472
+ ```js
473
+ {
474
+ "id": 1,
475
+ "title": "Rails is omakase",
476
+ "comments": [ 1, 2, 3 ]
477
+ }
478
+ ```
479
+ The IDs will be passed as a URL-encoded Array of IDs, in this form:
480
+ ```
481
+ ids[]=1&ids[]=2&ids[]=3
482
+ ```
483
+ Many servers, such as Rails and PHP, will automatically convert this URL-encoded array
484
+ into an Array for you on the server-side. If you want to encode the
485
+ IDs, differently, just override this (one-line) method.
486
+ The `findMany` method makes an Ajax (HTTP GET) request to a URL computed by `buildURL`, and returns a
487
+ promise for the resulting payload.
488
+ @public
489
+ */
490
+ findMany(store, type, ids, snapshots) {
491
+ const url = this.buildURL(type.modelName, ids, snapshots, "findMany");
492
+ return this.ajax(url, "GET", { data: { ids } });
493
+ }
494
+ /**
495
+ Called by the store in order to fetch a JSON array for
496
+ the unloaded records in a has-many relationship that were originally
497
+ specified as a URL (inside of `links`).
498
+ For example, if your original payload looks like this:
499
+ ```js
500
+ {
501
+ "post": {
502
+ "id": 1,
503
+ "title": "Rails is omakase",
504
+ "links": { "comments": "/posts/1/comments" }
505
+ }
506
+ }
507
+ ```
508
+ This method will be called with the parent record and `/posts/1/comments`.
509
+ The `findHasMany` method will make an Ajax (HTTP GET) request to the originally specified URL.
510
+ The format of your `links` value will influence the final request URL via the `urlPrefix` method:
511
+ * Links beginning with `//`, `http://`, `https://`, will be used as is, with no further manipulation.
512
+ * Links beginning with a single `/` will have the current adapter's `host` value prepended to it.
513
+ * Links with no beginning `/` will have a parentURL prepended to it, via the current adapter's `buildURL`.
514
+ @public
515
+ */
516
+ findHasMany(store, snapshot, url, relationship) {
517
+ const id = snapshot.id;
518
+ const type = snapshot.modelName;
519
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) && ((test) => {
520
+ if (!test) throw new Error(`Attempted to fetch the hasMany relationship for ${type}, but the record has no id`);
521
+ })(typeof id === "string" && id.length > 0);
522
+ url = this.urlPrefix(url, this.buildURL(type, id, snapshot, "findHasMany"));
523
+ return this.ajax(url, "GET");
524
+ }
525
+ /**
526
+ Called by the store in order to fetch the JSON for the unloaded record in a
527
+ belongs-to relationship that was originally specified as a URL (inside of
528
+ `links`).
529
+ For example, if your original payload looks like this:
530
+ ```js
531
+ {
532
+ "person": {
533
+ "id": 1,
534
+ "name": "Tom Dale",
535
+ "links": { "group": "/people/1/group" }
536
+ }
537
+ }
538
+ ```
539
+ This method will be called with the parent record and `/people/1/group`.
540
+ The `findBelongsTo` method will make an Ajax (HTTP GET) request to the originally specified URL.
541
+ The format of your `links` value will influence the final request URL via the `urlPrefix` method:
542
+ * Links beginning with `//`, `http://`, `https://`, will be used as is, with no further manipulation.
543
+ * Links beginning with a single `/` will have the current adapter's `host` value prepended to it.
544
+ * Links with no beginning `/` will have a parentURL prepended to it, via the current adapter's `buildURL`.
545
+ @public
546
+ */
547
+ findBelongsTo(store, snapshot, url, relationship) {
548
+ const id = snapshot.id;
549
+ const type = snapshot.modelName;
550
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) && ((test) => {
551
+ if (!test) throw new Error(`Attempted to fetch the belongsTo relationship for ${type}, but the record has no id`);
552
+ })(typeof id === "string" && id.length > 0);
553
+ url = this.urlPrefix(url, this.buildURL(type, id, snapshot, "findBelongsTo"));
554
+ return this.ajax(url, "GET");
555
+ }
556
+ /**
557
+ Called by the store when a newly created record is
558
+ saved via the `save` method on a model record instance.
559
+ The `createRecord` method serializes the record and makes an Ajax (HTTP POST) request
560
+ to a URL computed by `buildURL`.
561
+ See `serialize` for information on how to customize the serialized form
562
+ of a record.
563
+ @public
564
+ */
565
+ createRecord(store, type, snapshot) {
566
+ const url = this.buildURL(type.modelName, null, snapshot, "createRecord");
567
+ const data = serializeIntoHash(store, type, snapshot);
568
+ return this.ajax(url, "POST", { data });
569
+ }
570
+ /**
571
+ Called by the store when an existing record is saved
572
+ via the `save` method on a model record instance.
573
+ The `updateRecord` method serializes the record and makes an Ajax (HTTP PUT) request
574
+ to a URL computed by `buildURL`.
575
+ See `serialize` for information on how to customize the serialized form
576
+ of a record.
577
+ @public
578
+ */
579
+ updateRecord(store, schema, snapshot) {
580
+ const data = serializeIntoHash(store, schema, snapshot, {});
581
+ const type = snapshot.modelName;
582
+ const id = snapshot.id;
583
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) && ((test) => {
584
+ if (!test) throw new Error(`Attempted to update the ${type} record, but the record has no id`);
585
+ })(typeof id === "string" && id.length > 0);
586
+ const url = this.buildURL(type, id, snapshot, "updateRecord");
587
+ return this.ajax(url, "PUT", { data });
588
+ }
589
+ /**
590
+ Called by the store when a record is deleted.
591
+ The `deleteRecord` method makes an Ajax (HTTP DELETE) request to a URL computed by `buildURL`.
592
+ @public
593
+ */
594
+ deleteRecord(store, schema, snapshot) {
595
+ const type = snapshot.modelName;
596
+ const id = snapshot.id;
597
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) && ((test) => {
598
+ if (!test) throw new Error(`Attempted to delete the ${type} record, but the record has no id`);
599
+ })(typeof id === "string" && id.length > 0);
600
+ return this.ajax(this.buildURL(type, id, snapshot, "deleteRecord"), "DELETE");
601
+ }
602
+ /**
603
+ @private
604
+ */
605
+ _stripIDFromURL(store, snapshot) {
606
+ const type = snapshot.modelName;
607
+ const id = snapshot.id;
608
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) && ((test) => {
609
+ if (!test) throw new Error(`Attempted to strip the url from the ${type} record for coalescing, but the record has no id`);
610
+ })(typeof id === "string" && id.length > 0);
611
+ const expandedURL = this.buildURL(type, id, snapshot).split("/");
612
+ const lastSegment = expandedURL[expandedURL.length - 1];
613
+ if (decodeURIComponent(lastSegment) === id) expandedURL[expandedURL.length - 1] = "";
614
+ else if (id && endsWith(lastSegment, "?id=" + id)) expandedURL[expandedURL.length - 1] = lastSegment.substring(0, lastSegment.length - id.length - 1);
615
+ return expandedURL.join("/");
616
+ }
617
+ /**
618
+ * The maximum URL length to allow when coalescing `findRecord` requests
619
+ * into a single `findMany` request via {@link RESTAdapter.groupRecordsForFindMany | groupRecordsForFindMany}.
620
+ * Requests that would exceed this length are split into multiple groups.
621
+ *
622
+ * See http://stackoverflow.com/questions/417142/what-is-the-maximum-length-of-a-url-in-different-browsers
623
+ */
624
+ maxURLLength = 2048;
625
+ /**
626
+ Organize records into groups, each of which is to be passed to separate
627
+ calls to `findMany`.
628
+ This implementation groups together records that have the same base URL but
629
+ differing ids. For example `/comments/1` and `/comments/2` will be grouped together
630
+ because we know findMany can coalesce them together as `/comments?ids[]=1&ids[]=2`
631
+ It also supports urls where ids are passed as a query param, such as `/comments?id=1`
632
+ but not those where there is more than 1 query param such as `/comments?id=2&name=David`
633
+ Currently only the query param of `id` is supported. If you need to support others, please
634
+ override this or the `_stripIDFromURL` method.
635
+ It does not group records that have differing base urls, such as for example: `/posts/1/comments/2`
636
+ and `/posts/2/comments/3`
637
+ @public
638
+ @return an array of arrays of records, each of which is to be
639
+ loaded separately by `findMany`.
640
+ */
641
+ groupRecordsForFindMany(store, snapshots) {
642
+ const groups = /* @__PURE__ */ new Map();
643
+ const maxURLLength = this.maxURLLength;
644
+ snapshots.forEach((snapshot) => {
645
+ const baseUrl = this._stripIDFromURL(store, snapshot);
646
+ if (!groups.has(baseUrl)) groups.set(baseUrl, []);
647
+ groups.get(baseUrl).push(snapshot);
648
+ });
649
+ const groupsArray = [];
650
+ groups.forEach((group, key) => {
651
+ splitGroupToFitInUrl(store, this, group, maxURLLength, 11).forEach((splitGroup) => groupsArray.push(splitGroup));
652
+ });
653
+ return groupsArray;
654
+ }
655
+ /**
656
+ Takes an ajax response, and returns the json payload or an error.
657
+ By default this hook just returns the json payload passed to it.
658
+ You might want to override it in two cases:
659
+ 1. Your API might return useful results in the response headers.
660
+ Response headers are passed in as the second argument.
661
+ 2. Your API might return errors as successful responses with status code
662
+ 200 and an Errors text or object. You can return a `InvalidError` or a
663
+ `AdapterError` (or a sub class) from this hook and it will automatically
664
+ reject the promise and put your record into the invalid or error state.
665
+ Returning a `InvalidError` from this method will cause the
666
+ record to transition into the `invalid` state and make the
667
+ `errors` object available on the record. When returning an
668
+ `InvalidError` the store will attempt to normalize the error data
669
+ returned from the server using the serializer's `extractErrors`
670
+ method.
671
+ @since 1.13.0
672
+ @public
673
+ */
674
+ handleResponse(status, headers, payload, requestData) {
675
+ if (this.isSuccess(status, headers, payload)) return payload;
676
+ else if (this.isInvalid(status, headers, payload)) {
677
+ const errorPayload = payload ?? {};
678
+ return new InvalidError(typeof errorPayload === "object" && "errors" in errorPayload ? errorPayload.errors : void 0);
679
+ }
680
+ const errors = this.normalizeErrorResponse(status, headers, payload);
681
+ const detailedMessage = this.generatedDetailedMessage(status, headers, payload, requestData);
682
+ switch (status) {
683
+ case 401: return new UnauthorizedError(errors, detailedMessage);
684
+ case 403: return new ForbiddenError(errors, detailedMessage);
685
+ case 404: return new NotFoundError(errors, detailedMessage);
686
+ case 409: return new ConflictError(errors, detailedMessage);
687
+ default: if (status >= 500) return new ServerError(errors, detailedMessage);
688
+ }
689
+ return new AdapterError(errors, detailedMessage);
690
+ }
691
+ /**
692
+ Default `handleResponse` implementation uses this hook to decide if the
693
+ response is a success.
694
+ @since 1.13.0
695
+ @public
696
+ */
697
+ isSuccess(status, _headers, _payload) {
698
+ return status >= 200 && status < 300 || status === 304;
699
+ }
700
+ /**
701
+ Default `handleResponse` implementation uses this hook to decide if the
702
+ response is an invalid error.
703
+ @since 1.13.0
704
+ @public
705
+ */
706
+ isInvalid(status, _headers, _payload) {
707
+ return status === 422;
708
+ }
709
+ /**
710
+ Takes a URL, an HTTP method and a hash of data, and makes an
711
+ HTTP request.
712
+ When the server responds with a payload, WarpDrive will call into `extractSingle`
713
+ or `extractArray` (depending on whether the original query was for one record or
714
+ many records).
715
+ By default, `ajax` method has the following behavior:
716
+ * It sets the response `dataType` to `"json"`
717
+ * If the HTTP method is not `"GET"`, it sets the `Content-Type` to be
718
+ `application/json; charset=utf-8`
719
+ * If the HTTP method is not `"GET"`, it stringifies the data passed in. The
720
+ data is the serialized record in the case of a save.
721
+ * Registers success and failure handlers.
722
+ @private
723
+ */
724
+ async ajax(url, type, options = {}) {
725
+ const requestData = {
726
+ url,
727
+ method: type
728
+ };
729
+ if (this.useFetch) {
730
+ const hash = this.ajaxOptions(url, type, options);
731
+ const response = await this._fetchRequest(hash);
732
+ const payload = await determineBodyPromise(response, requestData);
733
+ if (response.ok && !(payload instanceof Error)) return fetchSuccessHandler(this, payload, response, requestData);
734
+ else throw fetchErrorHandler(this, payload, response, null, requestData);
735
+ } else return execjQAjax(this, requestData, options);
736
+ }
737
+ /**
738
+ @private
739
+ @param options jQuery ajax options to be used for the ajax request
740
+ */
741
+ _ajaxRequest(options) {
742
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) && ((test) => {
743
+ if (!test) throw new Error("You must install jQuery globally when `useFetch` is false");
744
+ })(typeof jQuery !== "undefined");
745
+ jQuery.ajax(options);
746
+ }
747
+ /**
748
+ @private
749
+ */
750
+ _fetchRequest(options) {
751
+ return getFetchFunction()(options.url, options);
752
+ }
753
+ /**
754
+ @private
755
+ */
756
+ _ajax(options) {
757
+ if (this.useFetch) this._fetchRequest(options);
758
+ else this._ajaxRequest(options);
759
+ }
760
+ /**
761
+ @private
762
+ */
763
+ ajaxOptions(url, method, options) {
764
+ let reqOptions = Object.assign({
765
+ url,
766
+ method,
767
+ type: method
768
+ }, options);
769
+ if (this.headers !== void 0) reqOptions.headers = {
770
+ ...this.headers,
771
+ ...reqOptions.headers
772
+ };
773
+ else if (!options.headers) reqOptions.headers = {};
774
+ const contentType = reqOptions.contentType || this._defaultContentType;
775
+ if (this.useFetch) {
776
+ if (reqOptions.data && reqOptions.type !== "GET" && reqOptions.headers) {
777
+ if (!reqOptions.headers["Content-Type"] && !reqOptions.headers["content-type"]) reqOptions.headers["content-type"] = contentType;
778
+ }
779
+ reqOptions = fetchOptions(reqOptions, this);
780
+ } else {
781
+ if (reqOptions.data && reqOptions.type !== "GET") reqOptions = {
782
+ ...reqOptions,
783
+ contentType
784
+ };
785
+ reqOptions = ajaxOptions(reqOptions, this);
786
+ }
787
+ reqOptions.url = this._ajaxURL(reqOptions.url);
788
+ return reqOptions;
789
+ }
790
+ /**
791
+ * @private
792
+ */
793
+ _ajaxURL(url) {
794
+ if (this.fastboot?.isFastBoot) {
795
+ const httpRegex = /^https?:\/\//;
796
+ const protocolRelativeRegex = /^\/\//;
797
+ const protocol = this.fastboot.request.protocol;
798
+ const host = this.fastboot.request.host;
799
+ if (protocolRelativeRegex.test(url)) return `${protocol}${url}`;
800
+ else if (!httpRegex.test(url)) try {
801
+ return `${protocol}//${host}${url}`;
802
+ } catch (fbError) {
803
+ throw new Error("You are using WarpDrive with no host defined in your adapter. This will attempt to use the host of the FastBoot request, which is not configured for the current host of this request. Please set the hostWhitelist property for in your environment.js. FastBoot Error: " + fbError.message);
804
+ }
805
+ }
806
+ return url;
807
+ }
808
+ /**
809
+ @private
810
+ */
811
+ parseErrorResponse(responseText) {
812
+ let json = responseText;
813
+ try {
814
+ json = JSON.parse(responseText);
815
+ } catch {}
816
+ return json;
817
+ }
818
+ /**
819
+ @private
820
+ @return errors payload
821
+ */
822
+ normalizeErrorResponse(status, _headers, payload) {
823
+ if (payload && typeof payload === "object" && "errors" in payload && Array.isArray(payload.errors)) return payload.errors;
824
+ else return [{
825
+ status: `${status}`,
826
+ title: "The backend responded with an error",
827
+ detail: typeof payload === "string" ? payload : JSON.stringify(payload)
828
+ }];
829
+ }
830
+ /**
831
+ Generates a detailed ("friendly") error message, with plenty
832
+ of information for debugging (good luck!)
833
+ @private
834
+ @return detailed error message
835
+ */
836
+ generatedDetailedMessage(status, headers, payload, requestData) {
837
+ let shortenedPayload;
838
+ const payloadContentType = headers["content-type"] || "Empty Content-Type";
839
+ if (payloadContentType === "text/html" && typeof payload === "string" && payload.length > 250) shortenedPayload = "[Omitted Lengthy HTML]";
840
+ else if (typeof payload === "object" && payload !== null) shortenedPayload = JSON.stringify(payload, null, 2);
841
+ else shortenedPayload = payload;
842
+ const requestDescription = requestData.method + " " + requestData.url;
843
+ const payloadDescription = "Payload (" + payloadContentType + ")";
844
+ return [
845
+ "Ember Data Request " + requestDescription + " returned a " + status,
846
+ payloadDescription,
847
+ shortenedPayload
848
+ ].join("\n");
849
+ }
850
+ /**
851
+ Used by `findAll` and `findRecord` to build the query's `data` hash
852
+ supplied to the ajax method.
853
+ @since 2.5.0
854
+ @public
855
+ */
856
+ buildQuery(snapshot) {
857
+ const query = {};
858
+ if (snapshot) {
859
+ const { include } = snapshot;
860
+ if (include) query.include = include;
861
+ }
862
+ return query;
863
+ }
864
+ };
1005
865
  function ajaxSuccess(adapter, payload, requestData, responseData) {
1006
- let response;
1007
- try {
1008
- response = adapter.handleResponse(responseData.status, responseData.headers, payload, requestData);
1009
- } catch (error) {
1010
- // eslint-disable-next-line @typescript-eslint/prefer-promise-reject-errors
1011
- return Promise.reject(error);
1012
- }
1013
- if (response && response.isAdapterError) {
1014
- // eslint-disable-next-line @typescript-eslint/prefer-promise-reject-errors
1015
- return Promise.reject(response);
1016
- } else {
1017
- return response;
1018
- }
866
+ let response;
867
+ try {
868
+ response = adapter.handleResponse(responseData.status, responseData.headers, payload, requestData);
869
+ } catch (error) {
870
+ return Promise.reject(error);
871
+ }
872
+ if (response && response.isAdapterError) return Promise.reject(response);
873
+ else return response;
1019
874
  }
1020
875
  function ajaxError(adapter, payload, requestData, responseData) {
1021
- let error;
1022
- if (responseData.errorThrown instanceof Error && payload !== '') {
1023
- error = responseData.errorThrown;
1024
- } else if (responseData.textStatus === 'timeout') {
1025
- error = new TimeoutError();
1026
- } else if (responseData.textStatus === 'abort' || responseData.status === 0) {
1027
- error = handleAbort(requestData, responseData);
1028
- } else {
1029
- try {
1030
- error = adapter.handleResponse(responseData.status, responseData.headers, payload || responseData.errorThrown, requestData);
1031
- } catch (e) {
1032
- error = e;
1033
- }
1034
- }
1035
- return error;
876
+ let error;
877
+ if (responseData.errorThrown instanceof Error && payload !== "") error = responseData.errorThrown;
878
+ else if (responseData.textStatus === "timeout") error = new TimeoutError();
879
+ else if (responseData.textStatus === "abort" || responseData.status === 0) error = handleAbort(requestData, responseData);
880
+ else try {
881
+ error = adapter.handleResponse(responseData.status, responseData.headers, payload || responseData.errorThrown, requestData);
882
+ } catch (e) {
883
+ error = e;
884
+ }
885
+ return error;
1036
886
  }
1037
-
1038
- // Adapter abort error to include any relevent info, e.g. request/response:
1039
887
  function handleAbort(requestData, responseData) {
1040
- const {
1041
- method,
1042
- url,
1043
- errorThrown
1044
- } = requestData;
1045
- const {
1046
- status
1047
- } = responseData;
1048
- const msg = `Request failed: ${method} ${url} ${String(errorThrown ?? '')}`;
1049
- const errors = [{
1050
- title: 'Adapter Error',
1051
- detail: msg.trim(),
1052
- status
1053
- }];
1054
- return new AbortError(errors);
888
+ const { method, url, errorThrown } = requestData;
889
+ const { status } = responseData;
890
+ const errors = [{
891
+ title: "Adapter Error",
892
+ detail: `Request failed: ${method} ${url} ${String(errorThrown ?? "")}`.trim(),
893
+ status
894
+ }];
895
+ return new AbortError(errors);
1055
896
  }
1056
-
1057
- //From http://stackoverflow.com/questions/280634/endswith-in-javascript
1058
897
  function endsWith(string, suffix) {
1059
- if (typeof String.prototype.endsWith !== 'function') {
1060
- return string.includes(suffix, string.length - suffix.length);
1061
- } else {
1062
- return string.endsWith(suffix);
1063
- }
898
+ if (typeof String.prototype.endsWith !== "function") return string.includes(suffix, string.length - suffix.length);
899
+ else return string.endsWith(suffix);
1064
900
  }
1065
901
  function fetchSuccessHandler(adapter, payload, response, requestData) {
1066
- const responseData = fetchResponseData(response);
1067
- return ajaxSuccess(adapter, payload, requestData, responseData);
902
+ return ajaxSuccess(adapter, payload, requestData, fetchResponseData(response));
1068
903
  }
1069
904
  function fetchErrorHandler(adapter, payload, response, errorThrown, requestData) {
1070
- const responseData = fetchResponseData(response);
1071
- if (responseData.status === 200 && payload instanceof Error) {
1072
- responseData.errorThrown = payload;
1073
- // @ts-expect-error poorly typed
1074
- payload = responseData.errorThrown.payload;
1075
- } else {
1076
- responseData.errorThrown = errorThrown;
1077
- if (typeof payload === 'string') {
1078
- payload = adapter.parseErrorResponse(payload);
1079
- }
1080
- }
1081
- return ajaxError(adapter, payload, requestData, responseData);
905
+ const responseData = fetchResponseData(response);
906
+ if (responseData.status === 200 && payload instanceof Error) {
907
+ responseData.errorThrown = payload;
908
+ payload = responseData.errorThrown.payload;
909
+ } else {
910
+ responseData.errorThrown = errorThrown;
911
+ if (typeof payload === "string") payload = adapter.parseErrorResponse(payload);
912
+ }
913
+ return ajaxError(adapter, payload, requestData, responseData);
1082
914
  }
1083
915
  function ajaxSuccessHandler(adapter, payload, jqXHR, requestData) {
1084
- const responseData = ajaxResponseData(jqXHR);
1085
- return ajaxSuccess(adapter, payload, requestData, responseData);
916
+ return ajaxSuccess(adapter, payload, requestData, ajaxResponseData(jqXHR));
1086
917
  }
1087
918
  function ajaxErrorHandler(adapter, jqXHR, errorThrown, requestData) {
1088
- const responseData = ajaxResponseData(jqXHR);
1089
- responseData.errorThrown = errorThrown;
1090
- const payload = adapter.parseErrorResponse(jqXHR.responseText);
1091
- if (macroCondition(getGlobalConfig().WarpDrive.env.DEBUG)) {
1092
- const message = `The server returned an empty string for ${requestData.method} ${requestData.url}, which cannot be parsed into a valid JSON. Return either null or {}.`;
1093
- const validJSONString = !(responseData.textStatus === 'parsererror' && payload === '');
1094
- warn(message, validJSONString, {
1095
- id: 'ds.adapter.returned-empty-string-as-JSON'
1096
- });
1097
- }
1098
- return ajaxError(adapter, payload, requestData, responseData);
919
+ const responseData = ajaxResponseData(jqXHR);
920
+ responseData.errorThrown = errorThrown;
921
+ const payload = adapter.parseErrorResponse(jqXHR.responseText);
922
+ if (macroCondition(getGlobalConfig().WarpDrive.env.DEBUG)) {
923
+ const message = `The server returned an empty string for ${requestData.method} ${requestData.url}, which cannot be parsed into a valid JSON. Return either null or {}.`;
924
+ const validJSONString = !(responseData.textStatus === "parsererror" && payload === "");
925
+ warn(message, validJSONString, { id: "ds.adapter.returned-empty-string-as-JSON" });
926
+ }
927
+ return ajaxError(adapter, payload, requestData, responseData);
1099
928
  }
1100
929
  function fetchResponseData(response) {
1101
- return {
1102
- status: response.status,
1103
- textStatus: response.statusText,
1104
- headers: headersToObject(response.headers)
1105
- };
930
+ return {
931
+ status: response.status,
932
+ textStatus: response.statusText,
933
+ headers: headersToObject(response.headers)
934
+ };
1106
935
  }
1107
936
  function ajaxResponseData(jqXHR) {
1108
- return {
1109
- status: jqXHR.status,
1110
- textStatus: jqXHR.statusText,
1111
- headers: parseResponseHeaders(jqXHR.getAllResponseHeaders())
1112
- };
937
+ return {
938
+ status: jqXHR.status,
939
+ textStatus: jqXHR.statusText,
940
+ headers: parseResponseHeaders(jqXHR.getAllResponseHeaders())
941
+ };
1113
942
  }
1114
943
  function headersToObject(headers) {
1115
- const headersObject = {};
1116
- if (headers) {
1117
- headers.forEach((value, key) => headersObject[key] = value);
1118
- }
1119
- return headersObject;
944
+ const headersObject = {};
945
+ if (headers) headers.forEach((value, key) => headersObject[key] = value);
946
+ return headersObject;
1120
947
  }
1121
-
1122
948
  /**
1123
- * Helper function that translates the options passed to `jQuery.ajax` into a format that `fetch` expects.
1124
- *
1125
- * @private
1126
- */
949
+ * Helper function that translates the options passed to `jQuery.ajax` into a format that `fetch` expects.
950
+ *
951
+ * @private
952
+ */
1127
953
  function fetchOptions(options, adapter) {
1128
- options.credentials = options.credentials || 'same-origin';
1129
- if (options.data) {
1130
- // GET and HEAD requests can't have a `body`
1131
- if (options.method === 'GET' || options.method === 'HEAD') {
1132
- // If no options are passed, WarpDrive sets `data` to an empty object, which we test for.
1133
- if (Object.keys(options.data).length && options.url) {
1134
- // Test if there are already query params in the url (mimics jQuey.ajax).
1135
- const queryParamDelimiter = options.url.includes('?') ? '&' : '?';
1136
- options.url += `${queryParamDelimiter}${serializeQueryParams(options.data)}`;
1137
- }
1138
- } else {
1139
- // NOTE: a request's body cannot be an object, so we stringify it if it is.
1140
- // JSON.stringify removes keys with values of `undefined` (mimics jQuery.ajax).
1141
- // If the data is not a POJO (it's a String, FormData, etc), we just set it.
1142
- // If the data is a string, we assume it's a stringified object.
1143
-
1144
- /* We check for Objects this way because we want the logic inside the consequent to run
1145
- * if `options.data` is a POJO, not if it is a data structure whose `typeof` returns "object"
1146
- * when it's not (Array, FormData, etc). The reason we don't use `options.data.constructor`
1147
- * to check is in case `data` is an object with no prototype (e.g. created with null).
1148
- */
1149
- if (Object.prototype.toString.call(options.data) === '[object Object]') {
1150
- options.body = JSON.stringify(options.data);
1151
- } else {
1152
- // @ts-expect-error poorly typed
1153
- options.body = options.data;
1154
- }
1155
- }
1156
- }
1157
- return options;
954
+ options.credentials = options.credentials || "same-origin";
955
+ if (options.data) {
956
+ if (options.method === "GET" || options.method === "HEAD") {
957
+ if (Object.keys(options.data).length && options.url) {
958
+ const queryParamDelimiter = options.url.includes("?") ? "&" : "?";
959
+ options.url += `${queryParamDelimiter}${serializeQueryParams(options.data)}`;
960
+ }
961
+ } else if (Object.prototype.toString.call(options.data) === "[object Object]") options.body = JSON.stringify(options.data);
962
+ else options.body = options.data;
963
+ }
964
+ return options;
1158
965
  }
1159
966
  function ajaxOptions(options, adapter) {
1160
- options.dataType = 'json';
1161
- options.context = adapter;
1162
- if (options.data && options.type !== 'GET') {
1163
- options.data = JSON.stringify(options.data);
1164
- }
1165
- options.beforeSend = function (xhr) {
1166
- if (options.headers) {
1167
- Object.keys(options.headers).forEach(key => {
1168
- const headerValue = options.headers && options.headers[key];
1169
- const isString = value => typeof value === 'string';
1170
- if (isString(headerValue)) {
1171
- xhr.setRequestHeader(key, headerValue);
1172
- }
1173
- });
1174
- }
1175
- };
1176
- return options;
967
+ options.dataType = "json";
968
+ options.context = adapter;
969
+ if (options.data && options.type !== "GET") options.data = JSON.stringify(options.data);
970
+ options.beforeSend = function(xhr) {
971
+ if (options.headers) Object.keys(options.headers).forEach((key) => {
972
+ const headerValue = options.headers && options.headers[key];
973
+ const isString = (value) => typeof value === "string";
974
+ if (isString(headerValue)) xhr.setRequestHeader(key, headerValue);
975
+ });
976
+ };
977
+ return options;
1177
978
  }
1178
979
  function execjQAjax(adapter, requestData, options) {
1179
- const hash = adapter.ajaxOptions(requestData.url, requestData.method, options);
1180
- return new Promise((resolve, reject) => {
1181
- hash.success = function (payload, textStatus, jqXHR) {
1182
- const response = ajaxSuccessHandler(adapter, payload, jqXHR, requestData);
1183
- resolve(response);
1184
- };
1185
- hash.error = function (jqXHR, textStatus, errorThrown) {
1186
- const error = ajaxErrorHandler(adapter, jqXHR, errorThrown, requestData);
1187
- // eslint-disable-next-line @typescript-eslint/prefer-promise-reject-errors
1188
- reject(error);
1189
- };
1190
- adapter._ajax(hash);
1191
- });
980
+ const hash = adapter.ajaxOptions(requestData.url, requestData.method, options);
981
+ return new Promise((resolve, reject) => {
982
+ hash.success = function(payload, textStatus, jqXHR) {
983
+ resolve(ajaxSuccessHandler(adapter, payload, jqXHR, requestData));
984
+ };
985
+ hash.error = function(jqXHR, textStatus, errorThrown) {
986
+ reject(ajaxErrorHandler(adapter, jqXHR, errorThrown, requestData));
987
+ };
988
+ adapter._ajax(hash);
989
+ });
1192
990
  }
1193
991
  function splitGroupToFitInUrl(store, adapter, group, maxURLLength, paramNameLength) {
1194
- let idsSize = 0;
1195
- const baseUrl = adapter._stripIDFromURL(store, group[0]);
1196
- const splitGroups = [[]];
1197
- group.forEach(snapshot => {
1198
- const additionalLength = encodeURIComponent(snapshot.id).length + paramNameLength;
1199
- if (baseUrl.length + idsSize + additionalLength >= maxURLLength) {
1200
- idsSize = 0;
1201
- splitGroups.push([]);
1202
- }
1203
- idsSize += additionalLength;
1204
- const lastGroupIndex = splitGroups.length - 1;
1205
- splitGroups[lastGroupIndex].push(snapshot);
1206
- });
1207
- return splitGroups;
992
+ let idsSize = 0;
993
+ const baseUrl = adapter._stripIDFromURL(store, group[0]);
994
+ const splitGroups = [[]];
995
+ group.forEach((snapshot) => {
996
+ const additionalLength = encodeURIComponent(snapshot.id).length + paramNameLength;
997
+ if (baseUrl.length + idsSize + additionalLength >= maxURLLength) {
998
+ idsSize = 0;
999
+ splitGroups.push([]);
1000
+ }
1001
+ idsSize += additionalLength;
1002
+ const lastGroupIndex = splitGroups.length - 1;
1003
+ splitGroups[lastGroupIndex].push(snapshot);
1004
+ });
1005
+ return splitGroups;
1208
1006
  }
1209
- export { RESTAdapter, fetchOptions };
1007
+
1008
+ //#endregion
1009
+ export { RESTAdapter, fetchOptions };
1010
+ //# sourceMappingURL=rest.js.map