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