merchi_sdk_ts 0.0.1-a

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 (444) hide show
  1. package/.babelrc +13 -0
  2. package/.eslintrc.cjs +43 -0
  3. package/LICENSE +21 -0
  4. package/README.md +2 -0
  5. package/dist/constants/auto_assign_production_on_actions.js +7 -0
  6. package/dist/constants/call_to_actions.js +15 -0
  7. package/dist/constants/call_to_actions.test.js +4 -0
  8. package/dist/constants/discount_types.js +4 -0
  9. package/dist/constants/discount_types.test.js +4 -0
  10. package/dist/constants/domain_types.js +13 -0
  11. package/dist/constants/domain_types.test.js +4 -0
  12. package/dist/constants/errors.js +32 -0
  13. package/dist/constants/event_types.js +6 -0
  14. package/dist/constants/event_types.test.js +4 -0
  15. package/dist/constants/field_types.js +14 -0
  16. package/dist/constants/field_types.test.js +4 -0
  17. package/dist/constants/input_types.js +14 -0
  18. package/dist/constants/input_types.test.js +4 -0
  19. package/dist/constants/inventory_status.test.js +4 -0
  20. package/dist/constants/inventory_statuses.js +7 -0
  21. package/dist/constants/invoice_types.js +6 -0
  22. package/dist/constants/invoice_types.test.js +4 -0
  23. package/dist/constants/item_types.js +6 -0
  24. package/dist/constants/item_types.test.js +4 -0
  25. package/dist/constants/job/drafting_status.js +8 -0
  26. package/dist/constants/job/drafting_status.test.js +4 -0
  27. package/dist/constants/job/payment_status.js +8 -0
  28. package/dist/constants/job/payment_status.test.js +4 -0
  29. package/dist/constants/job/production_status.js +13 -0
  30. package/dist/constants/job/production_status.test.js +4 -0
  31. package/dist/constants/job/shipment_status.js +12 -0
  32. package/dist/constants/job/shipment_status.test.js +4 -0
  33. package/dist/constants/job/supply_chain_request_status.js +7 -0
  34. package/dist/constants/job/supply_chain_request_status.test.js +4 -0
  35. package/dist/constants/job_priorities.js +7 -0
  36. package/dist/constants/job_priorities.test.js +4 -0
  37. package/dist/constants/job_status.js +50 -0
  38. package/dist/constants/job_status.test.js +4 -0
  39. package/dist/constants/job_types.js +16 -0
  40. package/dist/constants/job_types.test.js +4 -0
  41. package/dist/constants/notification_sections.js +14 -0
  42. package/dist/constants/notification_sections.test.js +4 -0
  43. package/dist/constants/notification_types.js +98 -0
  44. package/dist/constants/notification_types.test.js +4 -0
  45. package/dist/constants/notification_urgencies.js +7 -0
  46. package/dist/constants/notification_urgencies.test.js +4 -0
  47. package/dist/constants/payment_types.js +11 -0
  48. package/dist/constants/payment_types.test.js +4 -0
  49. package/dist/constants/platform.js +5 -0
  50. package/dist/constants/platform.test.js +8 -0
  51. package/dist/constants/product_types.js +26 -0
  52. package/dist/constants/product_types.test.js +4 -0
  53. package/dist/constants/rights.js +6 -0
  54. package/dist/constants/rights.test.js +4 -0
  55. package/dist/constants/robots_meta_directives.js +1 -0
  56. package/dist/constants/robots_meta_directives.test.js +4 -0
  57. package/dist/constants/roles.js +25 -0
  58. package/dist/constants/roles.test.js +4 -0
  59. package/dist/constants/shipment_companies.js +19 -0
  60. package/dist/constants/shipment_companies.test.js +4 -0
  61. package/dist/constants/shipment_services.js +4 -0
  62. package/dist/constants/shipment_services.test.js +4 -0
  63. package/dist/constants/system_roles.js +4 -0
  64. package/dist/constants/system_roles.test.js +4 -0
  65. package/dist/constants/theme_foundations.js +7 -0
  66. package/dist/constants/theme_foundations.test.js +4 -0
  67. package/dist/constants/theme_status.js +6 -0
  68. package/dist/constants/theme_status.test.js +4 -0
  69. package/dist/constants/user_types.js +18 -0
  70. package/dist/constants/user_types.test.js +4 -0
  71. package/dist/constants/white_label_accessibilities.js +6 -0
  72. package/dist/constants/white_label_accessibilities.test.js +4 -0
  73. package/dist/cookie.js +16 -0
  74. package/dist/cookie.test.js +12 -0
  75. package/dist/entities/address.js +166 -0
  76. package/dist/entities/address.test.js +6 -0
  77. package/dist/entities/assignment.js +185 -0
  78. package/dist/entities/assignment.test.js +38 -0
  79. package/dist/entities/automatic_payment_relationship.js +77 -0
  80. package/dist/entities/automatic_payment_relationship.test.js +6 -0
  81. package/dist/entities/backup.js +44 -0
  82. package/dist/entities/backup.test.js +6 -0
  83. package/dist/entities/bank.js +116 -0
  84. package/dist/entities/bank.test.js +6 -0
  85. package/dist/entities/cart.js +203 -0
  86. package/dist/entities/cart.test.js +52 -0
  87. package/dist/entities/cart_item.js +153 -0
  88. package/dist/entities/cart_item.test.js +34 -0
  89. package/dist/entities/cart_shipment_group.js +62 -0
  90. package/dist/entities/cart_shipment_quote.js +85 -0
  91. package/dist/entities/category.js +92 -0
  92. package/dist/entities/category.test.js +52 -0
  93. package/dist/entities/company.js +648 -0
  94. package/dist/entities/company.test.js +6 -0
  95. package/dist/entities/company_invitation.js +82 -0
  96. package/dist/entities/company_invitation.test.js +6 -0
  97. package/dist/entities/component.js +209 -0
  98. package/dist/entities/component.test.js +12 -0
  99. package/dist/entities/component_tag.js +50 -0
  100. package/dist/entities/component_tag.test.js +6 -0
  101. package/dist/entities/component_version.js +80 -0
  102. package/dist/entities/component_version.test.js +6 -0
  103. package/dist/entities/country_tax.js +110 -0
  104. package/dist/entities/country_tax.test.js +11 -0
  105. package/dist/entities/discount.js +77 -0
  106. package/dist/entities/discount.test.js +20 -0
  107. package/dist/entities/discount_group.js +74 -0
  108. package/dist/entities/discount_group.test.js +6 -0
  109. package/dist/entities/domain.js +535 -0
  110. package/dist/entities/domain.test.js +75 -0
  111. package/dist/entities/domain_invitation.js +90 -0
  112. package/dist/entities/domain_invitation.test.js +6 -0
  113. package/dist/entities/domain_tag.js +100 -0
  114. package/dist/entities/domain_tag.test.js +6 -0
  115. package/dist/entities/draft.js +180 -0
  116. package/dist/entities/draft.test.js +39 -0
  117. package/dist/entities/draft_comment.js +132 -0
  118. package/dist/entities/draft_comment.test.js +6 -0
  119. package/dist/entities/draft_template.js +105 -0
  120. package/dist/entities/draft_template.test.js +6 -0
  121. package/dist/entities/email_address.js +68 -0
  122. package/dist/entities/email_address.test.js +6 -0
  123. package/dist/entities/email_counter.js +56 -0
  124. package/dist/entities/email_counter.test.js +6 -0
  125. package/dist/entities/enrolled_domain.js +85 -0
  126. package/dist/entities/enrolled_domain.test.js +6 -0
  127. package/dist/entities/exchange_rate.js +62 -0
  128. package/dist/entities/exchange_rate.test.js +6 -0
  129. package/dist/entities/file.js +383 -0
  130. package/dist/entities/file.test.js +38 -0
  131. package/dist/entities/internal_tag.js +120 -0
  132. package/dist/entities/internal_tag.test.js +6 -0
  133. package/dist/entities/inventory.js +120 -0
  134. package/dist/entities/inventory.test.js +26 -0
  135. package/dist/entities/inventory_unit_variation.js +64 -0
  136. package/dist/entities/inventory_unit_variation.test.js +6 -0
  137. package/dist/entities/invoice.js +420 -0
  138. package/dist/entities/invoice.test.js +39 -0
  139. package/dist/entities/item.js +102 -0
  140. package/dist/entities/item.test.js +17 -0
  141. package/dist/entities/job.js +744 -0
  142. package/dist/entities/job.test.js +103 -0
  143. package/dist/entities/job_comment.js +120 -0
  144. package/dist/entities/job_comment.test.js +6 -0
  145. package/dist/entities/matching_inventory.js +77 -0
  146. package/dist/entities/menu.js +78 -0
  147. package/dist/entities/menu.test.js +6 -0
  148. package/dist/entities/menu_item.js +76 -0
  149. package/dist/entities/menu_item.test.js +6 -0
  150. package/dist/entities/notification.js +234 -0
  151. package/dist/entities/notification.test.js +6 -0
  152. package/dist/entities/page.js +84 -0
  153. package/dist/entities/page.test.js +6 -0
  154. package/dist/entities/payment.js +141 -0
  155. package/dist/entities/payment.test.js +18 -0
  156. package/dist/entities/payment_device.js +87 -0
  157. package/dist/entities/payment_device.test.js +6 -0
  158. package/dist/entities/phone_number.js +98 -0
  159. package/dist/entities/phone_number.test.js +6 -0
  160. package/dist/entities/product.js +806 -0
  161. package/dist/entities/product.test.js +811 -0
  162. package/dist/entities/production_comment.js +120 -0
  163. package/dist/entities/production_comment.test.js +6 -0
  164. package/dist/entities/quote.js +208 -0
  165. package/dist/entities/quote.test.js +107 -0
  166. package/dist/entities/quote_item.js +121 -0
  167. package/dist/entities/quote_item.test.js +56 -0
  168. package/dist/entities/seo_domain_page.js +82 -0
  169. package/dist/entities/seo_domain_page.test.js +6 -0
  170. package/dist/entities/session.js +77 -0
  171. package/dist/entities/session.test.js +6 -0
  172. package/dist/entities/shipment.js +401 -0
  173. package/dist/entities/shipment.test.js +28 -0
  174. package/dist/entities/shipment_item.js +49 -0
  175. package/dist/entities/shipment_item.test.js +6 -0
  176. package/dist/entities/shipment_item_fulfillment.js +48 -0
  177. package/dist/entities/shipment_item_fulfillment.test.js +6 -0
  178. package/dist/entities/shipment_method.js +146 -0
  179. package/dist/entities/shipment_method.test.js +6 -0
  180. package/dist/entities/shipment_method_variation.js +104 -0
  181. package/dist/entities/shipment_method_variation.test.js +6 -0
  182. package/dist/entities/short_url.js +95 -0
  183. package/dist/entities/short_url.test.js +6 -0
  184. package/dist/entities/subscription_plan.js +172 -0
  185. package/dist/entities/subscription_plan.test.js +6 -0
  186. package/dist/entities/supply_domain.js +73 -0
  187. package/dist/entities/supply_domain.test.js +6 -0
  188. package/dist/entities/system_role.js +50 -0
  189. package/dist/entities/system_role.test.js +6 -0
  190. package/dist/entities/theme.js +614 -0
  191. package/dist/entities/theme.test.js +39 -0
  192. package/dist/entities/theme_css_setting.js +67 -0
  193. package/dist/entities/theme_css_setting.test.js +6 -0
  194. package/dist/entities/user.js +749 -0
  195. package/dist/entities/user.test.js +157 -0
  196. package/dist/entities/user_company.js +78 -0
  197. package/dist/entities/user_company.test.js +6 -0
  198. package/dist/entities/variation.js +147 -0
  199. package/dist/entities/variation.test.js +6 -0
  200. package/dist/entities/variation_field.js +313 -0
  201. package/dist/entities/variation_field.test.js +69 -0
  202. package/dist/entities/variation_fields_option.js +190 -0
  203. package/dist/entities/variation_fields_option.test.js +47 -0
  204. package/dist/entities/variation_option.js +129 -0
  205. package/dist/entities/variation_option.test.js +6 -0
  206. package/dist/entities/variations_group.js +111 -0
  207. package/dist/entities/variations_group.test.js +6 -0
  208. package/dist/entity.js +888 -0
  209. package/dist/merchi.js +259 -0
  210. package/dist/merchi.test.js +35 -0
  211. package/dist/request.js +132 -0
  212. package/dist/request.test.js +46 -0
  213. package/dist/test_util.js +19 -0
  214. package/dist/toasts.js +27 -0
  215. package/dist/toasts.test.js +46 -0
  216. package/dist/util/float.js +24 -0
  217. package/dist/util/query_string.js +11 -0
  218. package/dist/util/query_string.test.js +6 -0
  219. package/dist/util/validation.js +3 -0
  220. package/dist/util/validation.test.js +12 -0
  221. package/dist/uuid.js +8 -0
  222. package/dist/uuid.test.js +13 -0
  223. package/jest.config.js +17 -0
  224. package/package.json +44 -0
  225. package/src/constants/auto_assign_production_on_actions.ts +6 -0
  226. package/src/constants/call_to_actions.test.ts +5 -0
  227. package/src/constants/call_to_actions.ts +14 -0
  228. package/src/constants/discount_types.test.ts +5 -0
  229. package/src/constants/discount_types.ts +3 -0
  230. package/src/constants/domain_types.test.ts +5 -0
  231. package/src/constants/domain_types.ts +12 -0
  232. package/src/constants/errors.ts +32 -0
  233. package/src/constants/event_types.test.ts +5 -0
  234. package/src/constants/event_types.ts +5 -0
  235. package/src/constants/field_types.test.ts +5 -0
  236. package/src/constants/field_types.ts +13 -0
  237. package/src/constants/input_types.test.ts +5 -0
  238. package/src/constants/input_types.ts +13 -0
  239. package/src/constants/inventory_status.test.ts +5 -0
  240. package/src/constants/inventory_statuses.ts +6 -0
  241. package/src/constants/invoice_types.test.ts +5 -0
  242. package/src/constants/invoice_types.ts +5 -0
  243. package/src/constants/item_types.test.ts +5 -0
  244. package/src/constants/item_types.ts +5 -0
  245. package/src/constants/job/drafting_status.test.ts +5 -0
  246. package/src/constants/job/drafting_status.ts +7 -0
  247. package/src/constants/job/payment_status.test.ts +5 -0
  248. package/src/constants/job/payment_status.ts +7 -0
  249. package/src/constants/job/production_status.test.ts +5 -0
  250. package/src/constants/job/production_status.ts +12 -0
  251. package/src/constants/job/shipment_status.test.ts +5 -0
  252. package/src/constants/job/shipment_status.ts +11 -0
  253. package/src/constants/job/supply_chain_request_status.test.ts +5 -0
  254. package/src/constants/job/supply_chain_request_status.ts +6 -0
  255. package/src/constants/job_priorities.test.ts +5 -0
  256. package/src/constants/job_priorities.ts +6 -0
  257. package/src/constants/job_status.test.ts +5 -0
  258. package/src/constants/job_status.ts +49 -0
  259. package/src/constants/job_types.test.ts +5 -0
  260. package/src/constants/job_types.ts +15 -0
  261. package/src/constants/notification_sections.test.ts +5 -0
  262. package/src/constants/notification_sections.ts +13 -0
  263. package/src/constants/notification_types.test.ts +5 -0
  264. package/src/constants/notification_types.ts +97 -0
  265. package/src/constants/notification_urgencies.test.ts +5 -0
  266. package/src/constants/notification_urgencies.ts +7 -0
  267. package/src/constants/payment_types.test.ts +5 -0
  268. package/src/constants/payment_types.ts +10 -0
  269. package/src/constants/platform.test.ts +15 -0
  270. package/src/constants/platform.ts +6 -0
  271. package/src/constants/product_types.test.ts +6 -0
  272. package/src/constants/product_types.ts +25 -0
  273. package/src/constants/rights.test.ts +5 -0
  274. package/src/constants/rights.ts +5 -0
  275. package/src/constants/robots_meta_directives.test.ts +5 -0
  276. package/src/constants/robots_meta_directives.ts +11 -0
  277. package/src/constants/roles.test.ts +5 -0
  278. package/src/constants/roles.ts +38 -0
  279. package/src/constants/shipment_companies.test.ts +5 -0
  280. package/src/constants/shipment_companies.ts +18 -0
  281. package/src/constants/shipment_services.test.ts +5 -0
  282. package/src/constants/shipment_services.ts +3 -0
  283. package/src/constants/system_roles.test.ts +5 -0
  284. package/src/constants/system_roles.ts +3 -0
  285. package/src/constants/theme_foundations.test.ts +5 -0
  286. package/src/constants/theme_foundations.ts +6 -0
  287. package/src/constants/theme_status.test.ts +5 -0
  288. package/src/constants/theme_status.ts +5 -0
  289. package/src/constants/user_types.test.ts +5 -0
  290. package/src/constants/user_types.ts +17 -0
  291. package/src/constants/white_label_accessibilities.test.ts +5 -0
  292. package/src/constants/white_label_accessibilities.ts +6 -0
  293. package/src/cookie.test.ts +11 -0
  294. package/src/cookie.ts +16 -0
  295. package/src/entities/address.test.ts +7 -0
  296. package/src/entities/address.ts +65 -0
  297. package/src/entities/assignment.test.ts +39 -0
  298. package/src/entities/assignment.ts +92 -0
  299. package/src/entities/automatic_payment_relationship.test.ts +8 -0
  300. package/src/entities/automatic_payment_relationship.ts +26 -0
  301. package/src/entities/backup.test.ts +7 -0
  302. package/src/entities/backup.ts +14 -0
  303. package/src/entities/bank.test.ts +7 -0
  304. package/src/entities/bank.ts +45 -0
  305. package/src/entities/cart.test.ts +50 -0
  306. package/src/entities/cart.ts +89 -0
  307. package/src/entities/cart_item.test.ts +33 -0
  308. package/src/entities/cart_item.ts +77 -0
  309. package/src/entities/cart_shipment_group.ts +21 -0
  310. package/src/entities/cart_shipment_quote.ts +33 -0
  311. package/src/entities/category.test.ts +57 -0
  312. package/src/entities/category.ts +37 -0
  313. package/src/entities/company.test.ts +7 -0
  314. package/src/entities/company.ts +275 -0
  315. package/src/entities/company_invitation.test.ts +7 -0
  316. package/src/entities/company_invitation.ts +33 -0
  317. package/src/entities/component.test.ts +14 -0
  318. package/src/entities/component.ts +92 -0
  319. package/src/entities/component_tag.test.ts +7 -0
  320. package/src/entities/component_tag.ts +17 -0
  321. package/src/entities/component_version.test.ts +7 -0
  322. package/src/entities/component_version.ts +30 -0
  323. package/src/entities/country_tax.test.ts +13 -0
  324. package/src/entities/country_tax.ts +46 -0
  325. package/src/entities/discount.test.ts +18 -0
  326. package/src/entities/discount.ts +34 -0
  327. package/src/entities/discount_group.test.ts +7 -0
  328. package/src/entities/discount_group.ts +28 -0
  329. package/src/entities/domain.test.ts +79 -0
  330. package/src/entities/domain.ts +246 -0
  331. package/src/entities/domain_invitation.test.ts +7 -0
  332. package/src/entities/domain_invitation.ts +36 -0
  333. package/src/entities/domain_tag.test.ts +7 -0
  334. package/src/entities/domain_tag.ts +42 -0
  335. package/src/entities/draft.test.ts +43 -0
  336. package/src/entities/draft.ts +88 -0
  337. package/src/entities/draft_comment.test.ts +7 -0
  338. package/src/entities/draft_comment.ts +54 -0
  339. package/src/entities/draft_template.test.ts +7 -0
  340. package/src/entities/draft_template.ts +40 -0
  341. package/src/entities/email_address.test.ts +7 -0
  342. package/src/entities/email_address.ts +24 -0
  343. package/src/entities/email_counter.test.ts +7 -0
  344. package/src/entities/email_counter.ts +20 -0
  345. package/src/entities/enrolled_domain.test.ts +7 -0
  346. package/src/entities/enrolled_domain.ts +40 -0
  347. package/src/entities/exchange_rate.test.ts +7 -0
  348. package/src/entities/exchange_rate.ts +22 -0
  349. package/src/entities/file.test.ts +43 -0
  350. package/src/entities/file.ts +172 -0
  351. package/src/entities/internal_tag.test.ts +7 -0
  352. package/src/entities/internal_tag.ts +51 -0
  353. package/src/entities/inventory.test.ts +28 -0
  354. package/src/entities/inventory.ts +56 -0
  355. package/src/entities/inventory_unit_variation.test.ts +7 -0
  356. package/src/entities/inventory_unit_variation.ts +29 -0
  357. package/src/entities/invoice.test.ts +43 -0
  358. package/src/entities/invoice.ts +179 -0
  359. package/src/entities/item.test.ts +19 -0
  360. package/src/entities/item.ts +44 -0
  361. package/src/entities/job.test.ts +95 -0
  362. package/src/entities/job.ts +349 -0
  363. package/src/entities/job_comment.test.ts +7 -0
  364. package/src/entities/job_comment.ts +50 -0
  365. package/src/entities/matching_inventory.ts +29 -0
  366. package/src/entities/menu.test.ts +7 -0
  367. package/src/entities/menu.ts +30 -0
  368. package/src/entities/menu_item.test.ts +7 -0
  369. package/src/entities/menu_item.ts +29 -0
  370. package/src/entities/notification.test.ts +7 -0
  371. package/src/entities/notification.ts +99 -0
  372. package/src/entities/page.test.ts +7 -0
  373. package/src/entities/page.ts +32 -0
  374. package/src/entities/payment.test.ts +19 -0
  375. package/src/entities/payment.ts +65 -0
  376. package/src/entities/payment_device.test.ts +7 -0
  377. package/src/entities/payment_device.ts +30 -0
  378. package/src/entities/phone_number.test.ts +7 -0
  379. package/src/entities/phone_number.ts +36 -0
  380. package/src/entities/product.test.ts +750 -0
  381. package/src/entities/product.ts +427 -0
  382. package/src/entities/production_comment.test.ts +7 -0
  383. package/src/entities/production_comment.ts +50 -0
  384. package/src/entities/quote.test.ts +98 -0
  385. package/src/entities/quote.ts +140 -0
  386. package/src/entities/quote_item.test.ts +50 -0
  387. package/src/entities/quote_item.ts +71 -0
  388. package/src/entities/seo_domain_page.test.ts +7 -0
  389. package/src/entities/seo_domain_page.ts +33 -0
  390. package/src/entities/session.test.ts +7 -0
  391. package/src/entities/session.ts +28 -0
  392. package/src/entities/shipment.test.ts +24 -0
  393. package/src/entities/shipment.ts +185 -0
  394. package/src/entities/shipment_item.test.ts +7 -0
  395. package/src/entities/shipment_item.ts +15 -0
  396. package/src/entities/shipment_item_fulfillment.test.ts +8 -0
  397. package/src/entities/shipment_item_fulfillment.ts +15 -0
  398. package/src/entities/shipment_method.test.ts +7 -0
  399. package/src/entities/shipment_method.ts +61 -0
  400. package/src/entities/shipment_method_variation.test.ts +7 -0
  401. package/src/entities/shipment_method_variation.ts +39 -0
  402. package/src/entities/short_url.test.ts +7 -0
  403. package/src/entities/short_url.ts +36 -0
  404. package/src/entities/subscription_plan.test.ts +7 -0
  405. package/src/entities/subscription_plan.ts +73 -0
  406. package/src/entities/supply_domain.test.ts +7 -0
  407. package/src/entities/supply_domain.ts +27 -0
  408. package/src/entities/system_role.test.ts +7 -0
  409. package/src/entities/system_role.ts +17 -0
  410. package/src/entities/theme.test.ts +38 -0
  411. package/src/entities/theme.ts +267 -0
  412. package/src/entities/theme_css_setting.test.ts +7 -0
  413. package/src/entities/theme_css_setting.ts +23 -0
  414. package/src/entities/user.test.ts +154 -0
  415. package/src/entities/user.ts +394 -0
  416. package/src/entities/user_company.test.ts +7 -0
  417. package/src/entities/user_company.ts +27 -0
  418. package/src/entities/variation.test.ts +7 -0
  419. package/src/entities/variation.ts +61 -0
  420. package/src/entities/variation_field.test.ts +76 -0
  421. package/src/entities/variation_field.ts +169 -0
  422. package/src/entities/variation_fields_option.test.ts +46 -0
  423. package/src/entities/variation_fields_option.ts +95 -0
  424. package/src/entities/variation_option.test.ts +7 -0
  425. package/src/entities/variation_option.ts +52 -0
  426. package/src/entities/variations_group.test.ts +7 -0
  427. package/src/entities/variations_group.ts +41 -0
  428. package/src/entity.ts +1002 -0
  429. package/src/merchi.test.ts +25 -0
  430. package/src/merchi.ts +379 -0
  431. package/src/request.test.ts +43 -0
  432. package/src/request.ts +124 -0
  433. package/src/test_util.ts +18 -0
  434. package/src/toasts.test.ts +38 -0
  435. package/src/toasts.ts +34 -0
  436. package/src/util/float.ts +12 -0
  437. package/src/util/query_string.test.ts +7 -0
  438. package/src/util/query_string.ts +11 -0
  439. package/src/util/validation.test.ts +16 -0
  440. package/src/util/validation.ts +2 -0
  441. package/src/uuid.test.ts +15 -0
  442. package/src/uuid.ts +8 -0
  443. package/tsconfig.json +23 -0
  444. package/webpack.config.cjs +27 -0
package/src/entity.ts ADDED
@@ -0,0 +1,1002 @@
1
+ import 'reflect-metadata';
2
+ // eslint-disable-next-line no-unused-vars
3
+ import { RequestOptions } from './request';
4
+ // eslint-disable-next-line no-unused-vars
5
+ import { Merchi } from './merchi';
6
+ // eslint-disable-next-line no-unused-vars
7
+ import { NotificationType } from './constants/notification_types';
8
+ // eslint-disable-next-line no-unused-vars
9
+ import { NotificationSection } from './constants/notification_sections';
10
+ // eslint-disable-next-line no-unused-vars
11
+ import { Role } from './constants/roles';
12
+ // eslint-disable-next-line no-unused-vars
13
+ import { DomainType } from './constants/domain_types';
14
+ // eslint-disable-next-line no-unused-vars
15
+ import { ProductType } from './constants/product_types';
16
+ import { generateUUID } from './uuid';
17
+
18
+ function toUnixTimestamp(date: Date) {
19
+ return parseInt(String(date.getTime() / 1000)).toFixed(0);
20
+ }
21
+
22
+ interface Counter {
23
+ value: number;
24
+ }
25
+
26
+ interface PropertyOptions {
27
+ embeddedByDefault?: boolean;
28
+ jsonName?: string;
29
+ type?: any;
30
+ arrayType?: string;
31
+ }
32
+
33
+ export interface EmbedDescriptor {
34
+ [property: string]: {} | EmbedDescriptor;
35
+ }
36
+
37
+ export interface NestedIncludeArchivedDescriptor {
38
+ [property: string]: {} | boolean | NestedIncludeArchivedDescriptor;
39
+ }
40
+
41
+ export type IncludeArchivedDescriptor = boolean | NestedIncludeArchivedDescriptor;
42
+
43
+ interface FromJsonOptions {
44
+ arrayValueStrict?: boolean;
45
+ makeDirty?: boolean;
46
+ }
47
+
48
+ interface CreateOptions {
49
+ withRights?: boolean;
50
+ embed?: EmbedDescriptor;
51
+ }
52
+
53
+ interface SaveOptions {
54
+ withRights?: boolean;
55
+ embed?: EmbedDescriptor;
56
+ }
57
+
58
+ interface DeleteOptions {
59
+ withRights?: boolean;
60
+ }
61
+
62
+ interface GetOptions {
63
+ embed?: EmbedDescriptor;
64
+ includeArchived?: IncludeArchivedDescriptor;
65
+ withRights?: boolean;
66
+ }
67
+
68
+ export enum SerialiseMethod {
69
+ // eslint-disable-next-line no-unused-vars
70
+ TO_DICT = 'to_dict',
71
+ // eslint-disable-next-line no-unused-vars
72
+ ONLY_ID = 'only_id',
73
+ }
74
+
75
+ interface ListOptions {
76
+ as?: string;
77
+ asRole?: Role;
78
+ businessDomainsOnly?: boolean;
79
+ categoryId?: number;
80
+ clientId?: number;
81
+ clientCompanyId?: number;
82
+ clientOnly?: boolean;
83
+ companyCustomerId?: number;
84
+ companyId?: number;
85
+ companySupplierId?: number;
86
+ componentId?: number;
87
+ dateFrom?: Date;
88
+ dateTo?: Date;
89
+ domainRoles?: Role[];
90
+ domainTypes?: DomainType[];
91
+ doesNotHaveAdminDomain?: boolean;
92
+ embed?: EmbedDescriptor;
93
+ entityTypes?: number[];
94
+ exclude?: number[];
95
+ excludeComponents?: string[];
96
+ excludeDomains?: number[];
97
+ groupBuyForJobId?: number;
98
+ groupBuyOnly?: boolean;
99
+ inbound?: boolean;
100
+ includeOnly?: number[];
101
+ inDomain?: number;
102
+ inDomainName?: string;
103
+ inDomainRoles?: number[];
104
+ isMaster?: boolean;
105
+ isOrder?: boolean;
106
+ isPrivate?: boolean;
107
+ jobNotifiable?: number;
108
+ limit?: number;
109
+ managedDomainsOnly?: boolean;
110
+ managedOnly?: boolean;
111
+ managerId?: number;
112
+ masterProduct?: number;
113
+ memberOnly?: boolean;
114
+ merchiOnly?: boolean;
115
+ notificationJob?: number;
116
+ notificationRecipient?: number;
117
+ notificationType?: NotificationType;
118
+ offset?: number;
119
+ orClientId?: number;
120
+ orClientCompanyId?: number;
121
+ order?: string;
122
+ originalOf?: number;
123
+ platformCategoryId?: number;
124
+ productTypes?: ProductType[];
125
+ publicOnly?: boolean;
126
+ q?: string;
127
+ receiverId?: number;
128
+ relatedAssignment?: number;
129
+ relatedComponent?: number;
130
+ relatedDraft?: number;
131
+ relatedJob?: number;
132
+ relatedProduct?: number;
133
+ relatedUser?: number;
134
+ savedByUser?: number;
135
+ section?: NotificationSection;
136
+ senderRole?: Role;
137
+ serialiseMethod?: SerialiseMethod;
138
+ shopifyOnly?: boolean;
139
+ sort?: string;
140
+ state?: string;
141
+ supplierResellOnly?: boolean;
142
+ tab?: string;
143
+ tags?: number[];
144
+ tagsInternal?: number[];
145
+ tagNames?: string[];
146
+ teamOnly?: boolean;
147
+ withRights?: boolean;
148
+ }
149
+
150
+ export interface ListMetadata {
151
+ canCreate?: boolean;
152
+ available: number;
153
+ count: number;
154
+ limit: number;
155
+ offset: number;
156
+ }
157
+
158
+ export interface ListResponse<T> {
159
+ items: T[];
160
+ metadata: ListMetadata;
161
+ }
162
+
163
+ interface SerialiseOptions {
164
+ existing?: FormData;
165
+ excludeOld?: boolean;
166
+ _prefix?: string;
167
+ }
168
+
169
+ interface PropertyInfo {
170
+ property: string; // this is the json name, e.g. 'id'
171
+ attribute: string; // this is the js attribute name, e.g. '_id'
172
+ type: Function; // e.g. Number
173
+ arrayType?: Entity; // if type is an array, arrayType is the element type
174
+ dirty: boolean; // true if out of date with server
175
+ currentValue?: any; // type is actually `this.type | undefined`
176
+ updatingOrder: boolean;
177
+ embeddedByDefault: boolean;
178
+ }
179
+
180
+ export class Entity {
181
+ private static jsonNameKey = Symbol('jsonName');
182
+ private static arrayTypeKey = Symbol('arrayType');
183
+ private static extraOptionsKey = Symbol('extraOptions');
184
+ private static propertiesSetKey = Symbol('propertiesSet');
185
+
186
+ protected static resourceName: string;
187
+ protected static singularName: string;
188
+ protected static pluralName: string;
189
+ protected static primaryKey = 'id';
190
+
191
+ // these will be set by the parent Merchi object
192
+ public merchi!: Merchi;
193
+ public static merchi: Merchi;
194
+
195
+ public isDirty = false;
196
+ // maps json names like 'id' to information about that property
197
+ public propertiesMap: Map<string, PropertyInfo>;
198
+ public readonly backObjects: Set<Entity> = new Set();
199
+
200
+ public key = generateUUID();
201
+
202
+ protected isSingleEntityProperty(info: PropertyInfo) {
203
+ // the choice of 'Product' below is unimportant -- all Entities should
204
+ // have the same prototype but i don't know how to get instanceof
205
+ // working, so i just compare prototypes directly.
206
+ return (
207
+ info.type.prototype === this.merchi.Product.prototype ||
208
+ info.type.prototype instanceof Entity
209
+ );
210
+ }
211
+
212
+ protected static property(options?: PropertyOptions) {
213
+ return function (target: Entity, propertyKey: string) {
214
+ if (!options) {
215
+ options = {};
216
+ }
217
+ const arrayType = options.arrayType;
218
+ const jsonName = options.jsonName || propertyKey;
219
+ let properties = Reflect.getMetadata(Entity.propertiesSetKey,
220
+ target.constructor);
221
+ properties = properties || new Set();
222
+ properties.add(propertyKey);
223
+ Reflect.defineMetadata(Entity.propertiesSetKey, properties,
224
+ target.constructor);
225
+ Reflect.defineMetadata(Entity.jsonNameKey, jsonName, target,
226
+ propertyKey);
227
+ Reflect.defineMetadata(Entity.arrayTypeKey, arrayType, target,
228
+ propertyKey);
229
+ Reflect.defineMetadata(Entity.extraOptionsKey, options, target,
230
+ propertyKey);
231
+ };
232
+ }
233
+
234
+ protected makePropertiesMap() {
235
+ const map = new Map();
236
+ const self = this;
237
+ const properties = Reflect.getMetadata(Entity.propertiesSetKey,
238
+ this.constructor);
239
+ properties.forEach(function(attributeName: any) {
240
+ const jsonName = Reflect.getMetadata(Entity.jsonNameKey, self,
241
+ attributeName);
242
+ const propertyType = Reflect.getMetadata('design:type', self,
243
+ attributeName);
244
+ // the array type is needed because 'design:type' breaks down
245
+ // with recursive classes, and also, does not contain the type
246
+ // of an arrays elements, which we need
247
+ const arrayType = Reflect.getMetadata(Entity.arrayTypeKey, self,
248
+ attributeName);
249
+ const realArrayType = self.getEntityClass(arrayType);
250
+ const options: PropertyOptions =
251
+ Reflect.getMetadata(Entity.extraOptionsKey, self, attributeName);
252
+ if (arrayType !== undefined) {
253
+ /* istanbul ignore next */
254
+ if (propertyType !== Object && propertyType !== Array) {
255
+ /* istanbul ignore next */
256
+ throw new Error('array type can only be given for arrays');
257
+ }
258
+ }
259
+ let type;
260
+ if (options.type === undefined) {
261
+ type = propertyType;
262
+ } else {
263
+ type = options.type;
264
+ if (typeof type === 'string') {
265
+ type = self.getEntityClass(type);
266
+ }
267
+ if (type.prototype instanceof Entity) {
268
+ type = self.merchi.setupClass(type);
269
+ }
270
+ }
271
+ const normallyEmbeddedByDefault = !(realArrayType ||
272
+ type.prototype instanceof Entity);
273
+ const embeddedByDefault = options.embeddedByDefault !== undefined ?
274
+ options.embeddedByDefault : normallyEmbeddedByDefault;
275
+ /* istanbul ignore next */
276
+ if (type === Object) {
277
+ /* istanbul ignore next */
278
+ const resource = (self.constructor as typeof Entity).resourceName;
279
+ const err = 'Bad attribute type ' +
280
+ `${resource}.${attributeName}: ${type}`;
281
+ throw new Error(err);
282
+ }
283
+ const propertyInfo: PropertyInfo = {property: jsonName,
284
+ attribute: attributeName,
285
+ type: type,
286
+ arrayType: realArrayType,
287
+ embeddedByDefault: embeddedByDefault,
288
+ dirty: true,
289
+ updatingOrder: false};
290
+ map.set(jsonName, propertyInfo);
291
+ });
292
+ return map;
293
+ }
294
+
295
+ public constructor(merchi?: Merchi) {
296
+ /* istanbul ignore next */
297
+ if (merchi !== undefined) {
298
+ this.merchi = merchi;
299
+ }
300
+ this.propertiesMap = this.makePropertiesMap();
301
+ this.setupProperties();
302
+ }
303
+
304
+ public getPrimaryKeyValue = () => {
305
+ const name: string = (this.constructor as typeof Entity).primaryKey;
306
+ const info = this.propertiesMap.get(name);
307
+ /* istanbul ignore next */
308
+ if (info !== undefined) {
309
+ return info.currentValue;
310
+ }
311
+ /* istanbul ignore next */
312
+ return undefined;
313
+ };
314
+
315
+ private setupProperties = () => {
316
+ const properties: any = {};
317
+ const makeSetSingle = (info: PropertyInfo) => {
318
+ const get = () => {
319
+ return info.currentValue;
320
+ };
321
+ const set = (newValue?: Entity) => {
322
+ info.currentValue = newValue;
323
+ this.addBackObject(newValue);
324
+ this.markDirty(info.property, newValue);
325
+ };
326
+ return { get: get,
327
+ set: set};
328
+ };
329
+ const makeSetScalar = (info: PropertyInfo) => {
330
+ const get = () => {
331
+ return info.currentValue;
332
+ };
333
+ const set = (newValue: any) => {
334
+ info.currentValue = newValue;
335
+ this.markDirty(info.property, newValue);
336
+ };
337
+ return { get: get,
338
+ set: set};
339
+ };
340
+ const makeSetArray = (info: PropertyInfo) => {
341
+ const get = () => {
342
+ return info.currentValue;
343
+ };
344
+ const set = (newValue?: Entity[]) => {
345
+ info.currentValue = newValue;
346
+ this.addBackObjectList(newValue);
347
+ this.markDirty(info.property, newValue);
348
+ };
349
+ return { get: get,
350
+ set: set};
351
+ };
352
+ for (const info of this.propertiesMap.values()) {
353
+ if (info.type.prototype instanceof Entity) {
354
+ properties[info.attribute] = makeSetSingle(info);
355
+ } else if (info.arrayType) {
356
+ properties[info.attribute] = makeSetArray(info);
357
+ } else {
358
+ properties[info.attribute] = makeSetScalar(info);
359
+ }
360
+ }
361
+ Object.defineProperties(this, properties);
362
+ };
363
+
364
+ public static get<T extends typeof Entity>(this: T, key: number | string,
365
+ options?: GetOptions):
366
+ Promise<InstanceType<T>>{
367
+ const resource = `/${this.resourceName}/${String(key)}/`;
368
+ const fetchOptions: RequestOptions = {};
369
+ fetchOptions.query = [];
370
+ if (options && options.embed) {
371
+ fetchOptions.query.push(['embed', JSON.stringify(options.embed)]);
372
+ }
373
+ if (options && options.includeArchived) {
374
+ fetchOptions.query.push(['include_archived',
375
+ JSON.stringify(options.includeArchived)]);
376
+ }
377
+ if (!(options && options.withRights)) {
378
+ fetchOptions.query.push(['skip_rights', 'y']);
379
+ }
380
+ return this.merchi.authenticatedFetch(resource, fetchOptions).
381
+ then((data: any) => {
382
+ const result: InstanceType<T> = (new this()) as InstanceType<T>;
383
+ result.fromJson(data[this.singularName]);
384
+ return result;
385
+ });
386
+ }
387
+
388
+ public static list<T extends typeof Entity>(this: T, options?: ListOptions):
389
+ Promise<ListResponse<InstanceType<T>>> {
390
+ const resource = `/${this.resourceName}/`;
391
+ const fetchOptions: RequestOptions = {};
392
+ fetchOptions.query = [];
393
+ if (options) {
394
+ if (options.embed) {
395
+ fetchOptions.query.push(['embed', JSON.stringify(options.embed)]);
396
+ }
397
+ if (options.offset !== undefined) {
398
+ fetchOptions.query.push(['offset', options.offset.toString()]);
399
+ }
400
+ if (options.limit !== undefined) {
401
+ fetchOptions.query.push(['limit', options.limit.toString()]);
402
+ }
403
+ if (options.q !== undefined) {
404
+ fetchOptions.query.push(['q', options.q]);
405
+ }
406
+ if (options.sort !== undefined) {
407
+ fetchOptions.query.push(['sort', options.sort]);
408
+ }
409
+ if (options.order !== undefined) {
410
+ fetchOptions.query.push(['order', options.order]);
411
+ }
412
+ if (options.serialiseMethod !== undefined) {
413
+ fetchOptions.query.push(['serialise_method', options.serialiseMethod]);
414
+ }
415
+ if (options.tab !== undefined) {
416
+ fetchOptions.query.push(['tab', options.tab]);
417
+ }
418
+ if (options.as !== undefined) {
419
+ fetchOptions.query.push(['as', options.as]);
420
+ }
421
+ if (options.state !== undefined) {
422
+ fetchOptions.query.push(['state', options.state]);
423
+ }
424
+ if (options.categoryId !== undefined) {
425
+ fetchOptions.query.push(['category_id', options.categoryId.toString()]);
426
+ }
427
+ if (options.platformCategoryId !== undefined) {
428
+ fetchOptions.query.push(['platform_category_id', options.platformCategoryId.toString()]);
429
+ }
430
+ if (options.inDomain !== undefined) {
431
+ fetchOptions.query.push(['in_domain', options.inDomain.toString()]);
432
+ }
433
+ if (options.inDomainName !== undefined) {
434
+ fetchOptions.query.push(['in_domain_name', options.inDomainName.toString()]);
435
+ }
436
+ if (options.inDomainRoles !== undefined) {
437
+ fetchOptions.query.push(['in_domain_roles',
438
+ JSON.stringify(options.inDomainRoles)]);
439
+ }
440
+ if (options.isPrivate !== undefined) {
441
+ fetchOptions.query.push(['is_private', options.isPrivate.toString()]);
442
+ }
443
+ if (options.asRole !== undefined) {
444
+ fetchOptions.query.push(['as_role', options.asRole.toString()]);
445
+ }
446
+ if (options.groupBuyOnly !== undefined) {
447
+ fetchOptions.query.push(
448
+ ['group_buy_only', options.groupBuyOnly.toString()]);
449
+ }
450
+ if (options.publicOnly !== undefined) {
451
+ fetchOptions.query.push(['public_only', options.publicOnly.toString()]);
452
+ }
453
+ if (options.managedOnly !== undefined) {
454
+ fetchOptions.query.push(['managed_only',
455
+ options.managedOnly.toString()]);
456
+ }
457
+ if (options.doesNotHaveAdminDomain !== undefined) {
458
+ fetchOptions.query.push(['does_not_have_admin_domain',
459
+ options.doesNotHaveAdminDomain.toString()]);
460
+ }
461
+ if (options.clientOnly !== undefined) {
462
+ fetchOptions.query.push(['client_only',
463
+ options.clientOnly.toString()]);
464
+ }
465
+ if (options.teamOnly !== undefined) {
466
+ fetchOptions.query.push(['team_only',
467
+ options.teamOnly.toString()]);
468
+ }
469
+ if (options.memberOnly !== undefined) {
470
+ fetchOptions.query.push(['member_only', options.memberOnly.toString()]);
471
+ }
472
+ if (options.merchiOnly !== undefined) {
473
+ fetchOptions.query.push(['merchi_only', options.merchiOnly.toString()]);
474
+ }
475
+ if (options.supplierResellOnly !== undefined) {
476
+ fetchOptions.query.push(
477
+ ['supplier_resell_only', options.supplierResellOnly.toString()]
478
+ );
479
+ }
480
+ if (options.shopifyOnly !== undefined) {
481
+ fetchOptions.query.push(['shopify_only', options.shopifyOnly.toString()]);
482
+ }
483
+ if (options.inbound !== undefined) {
484
+ fetchOptions.query.push(['inbound', options.inbound.toString()]);
485
+ }
486
+ if (options.isMaster !== undefined) {
487
+ fetchOptions.query.push(['is_master', options.isMaster.toString()]);
488
+ }
489
+ if (options.domainRoles !== undefined) {
490
+ fetchOptions.query.push(['domain_roles',
491
+ options.domainRoles.join(',')]);
492
+ }
493
+ if (options.domainTypes !== undefined) {
494
+ fetchOptions.query.push(['domain_types',
495
+ options.domainTypes.join(',')]);
496
+ }
497
+ if (options.entityTypes !== undefined) {
498
+ fetchOptions.query.push(['entity_types',
499
+ options.entityTypes.join(',')]);
500
+ }
501
+ if (options.productTypes !== undefined) {
502
+ fetchOptions.query.push(['product_types',
503
+ options.productTypes.join(',')]);
504
+ }
505
+ if (options.managedDomainsOnly !== undefined) {
506
+ fetchOptions.query.push(['managed_domains_only',
507
+ options.managedDomainsOnly.toString()]);
508
+ }
509
+ if (options.businessDomainsOnly !== undefined) {
510
+ fetchOptions.query.push(['business_domains_only',
511
+ options.businessDomainsOnly.toString()]);
512
+ }
513
+ if (options.dateFrom !== undefined) {
514
+ fetchOptions.query.push(['date_from',
515
+ toUnixTimestamp(options.dateFrom)]);
516
+ }
517
+ if (options.dateTo !== undefined) {
518
+ fetchOptions.query.push(['date_to', toUnixTimestamp(options.dateTo)]);
519
+ }
520
+ if (options.originalOf !== undefined) {
521
+ fetchOptions.query.push(['original_of',
522
+ options.originalOf.toString()]);
523
+ }
524
+ if (options.relatedComponent !== undefined) {
525
+ fetchOptions.query.push(['related_component',
526
+ options.relatedComponent.toString()]);
527
+ }
528
+ if (options.relatedAssignment !== undefined) {
529
+ fetchOptions.query.push(['related_assignment',
530
+ options.relatedAssignment.toString()]);
531
+ }
532
+ if (options.relatedDraft !== undefined) {
533
+ fetchOptions.query.push(['related_draft',
534
+ options.relatedDraft.toString()]);
535
+ }
536
+ if (options.relatedJob !== undefined) {
537
+ fetchOptions.query.push(['related_job', options.relatedJob.toString()]);
538
+ }
539
+ if (options.relatedProduct !== undefined) {
540
+ fetchOptions.query.push(['related_product',
541
+ options.relatedProduct.toString()]);
542
+ }
543
+ if (options.jobNotifiable !== undefined) {
544
+ fetchOptions.query.push(['job_notifiable',
545
+ options.jobNotifiable.toString()]);
546
+ }
547
+ if (options.notificationType !== undefined) {
548
+ fetchOptions.query.push(['notification_type',
549
+ options.notificationType.toString()]);
550
+ }
551
+ if (options.notificationRecipient !== undefined) {
552
+ fetchOptions.query.push(['notification_recipient',
553
+ options.notificationRecipient.toString()]);
554
+ }
555
+ if (options.notificationJob !== undefined) {
556
+ fetchOptions.query.push(['notification_job',
557
+ options.notificationJob.toString()]);
558
+ }
559
+ if (options.relatedUser !== undefined) {
560
+ fetchOptions.query.push(['related_user',
561
+ options.relatedUser.toString()]);
562
+ }
563
+ if (options.clientId !== undefined) {
564
+ fetchOptions.query.push(['client_id', options.clientId.toString()]);
565
+ }
566
+ if (options.managerId !== undefined) {
567
+ fetchOptions.query.push(['manager_id', options.managerId.toString()]);
568
+ }
569
+ if (options.masterProduct !== undefined) {
570
+ fetchOptions.query.push(['master_product', options.masterProduct.toString()]);
571
+ }
572
+ if (options.clientCompanyId !== undefined) {
573
+ fetchOptions.query.push(['client_company_id',
574
+ options.clientCompanyId.toString()]);
575
+ }
576
+ if (options.savedByUser !== undefined) {
577
+ fetchOptions.query.push(['saved_by_user',
578
+ options.savedByUser.toString()]);
579
+ }
580
+ if (options.receiverId !== undefined) {
581
+ fetchOptions.query.push(['receiver_id', options.receiverId.toString()]);
582
+ }
583
+ if (options.companyCustomerId !== undefined) {
584
+ fetchOptions.query.push(['company_customer_id', options.companyCustomerId.toString()]);
585
+ }
586
+ if (options.companyId !== undefined) {
587
+ fetchOptions.query.push(['company_id', options.companyId.toString()]);
588
+ }
589
+ if (options.companySupplierId !== undefined) {
590
+ fetchOptions.query.push(['company_supplier_id', options.companySupplierId.toString()]);
591
+ }
592
+ if (options.componentId !== undefined) {
593
+ fetchOptions.query.push(['component_id',
594
+ options.componentId.toString()]);
595
+ }
596
+ if (options.groupBuyForJobId !== undefined) {
597
+ fetchOptions.query.push(['group_buy_for_job_id',
598
+ options.groupBuyForJobId.toString()]);
599
+ }
600
+ if (options.section !== undefined) {
601
+ fetchOptions.query.push(['section', options.section.toString()]);
602
+ }
603
+ if (options.senderRole !== undefined) {
604
+ fetchOptions.query.push(['sender_role', options.senderRole.toString()]);
605
+ }
606
+ if (options.isOrder) {
607
+ fetchOptions.query.push(['is_order', 'true']);
608
+ }
609
+ if (options.tags !== undefined) {
610
+ fetchOptions.query.push(['tags', options.tags.join(',')]);
611
+ }
612
+ if (options.tagsInternal !== undefined) {
613
+ fetchOptions.query.push(['tags_internal', options.tagsInternal.join(',')]);
614
+ }
615
+ if (options.tagNames !== undefined) {
616
+ fetchOptions.query.push(['tag_names', options.tagNames.join(',')]);
617
+ }
618
+ if (options.exclude !== undefined) {
619
+ fetchOptions.query.push(['exclude', options.exclude.join(',')]);
620
+ }
621
+ if (options.excludeComponents !== undefined) {
622
+ fetchOptions.query.push(
623
+ ['exclude_components', options.excludeComponents.join(',')]);
624
+ }
625
+ if (options.excludeDomains !== undefined) {
626
+ fetchOptions.query.push(
627
+ ['exclude_domains', options.excludeDomains.join(',')]);
628
+ }
629
+ if (options.includeOnly !== undefined) {
630
+ fetchOptions.query.push(['include_only', options.includeOnly.join(',')]);
631
+ }
632
+ if (options.orClientId !== undefined) {
633
+ fetchOptions.query.push(['or_client_id', options.orClientId.toString()]);
634
+ }
635
+ if (options.orClientCompanyId !== undefined) {
636
+ fetchOptions.query.push(
637
+ ['or_client_company_id', options.orClientCompanyId.toString()]);
638
+ }
639
+ }
640
+ if (!(options && options.withRights)) {
641
+ fetchOptions.query.push(['skip_rights', 'y']);
642
+ }
643
+ return this.merchi.authenticatedFetch(resource, fetchOptions).then((data: any) => {
644
+ const metadata = {canCreate: data.canCreate,
645
+ available: data.available,
646
+ count: data.count,
647
+ limit: data.limit,
648
+ offset: data.offset};
649
+ const pluralName = this.pluralName;
650
+ const singularName = this.singularName;
651
+ const items: any[] = data[pluralName];
652
+ const entities = [];
653
+ for (const item of items) {
654
+ const entity: InstanceType<T> = (new this()) as InstanceType<T>;
655
+ entity.fromJson(item[singularName]);
656
+ entities.push(entity);
657
+ }
658
+ return {items: entities,
659
+ metadata: metadata};
660
+ });
661
+ }
662
+
663
+ public save = (options?: SaveOptions) => {
664
+ const primaryKey: number | string = this.getPrimaryKeyValue();
665
+ const constructor = this.constructor as typeof Entity;
666
+ const resourceName: string = constructor.resourceName;
667
+ const singularName: string = constructor.singularName;
668
+ const resource = `/${resourceName}/${String(primaryKey)}/`;
669
+ const data = this.toFormData();
670
+ const fetchOptions: RequestOptions = {method: 'PATCH',
671
+ body: data};
672
+ fetchOptions.query = [];
673
+ if (options && options.embed) {
674
+ fetchOptions.query.push(['embed', JSON.stringify(options.embed)]);
675
+ }
676
+ if (!(options && options.withRights)) {
677
+ fetchOptions.query.push(['skip_rights', 'y']);
678
+ }
679
+ return this.merchi.authenticatedFetch(resource, fetchOptions).then((data: any) => {
680
+ this.fromJson(data[singularName]);
681
+ this.cleanDirty();
682
+ return this;
683
+ });
684
+ };
685
+
686
+ public createFactory = (
687
+ {resourceName = (this.constructor as typeof Entity).resourceName}
688
+ ) => (options?: CreateOptions) => {
689
+ const resource = `/${resourceName}/`;
690
+ const data = this.toFormData();
691
+ const singularName = (this.constructor as typeof Entity).singularName;
692
+ const fetchOptions: RequestOptions = {method: 'POST',
693
+ body: data};
694
+
695
+ fetchOptions.query = [];
696
+ if (options && options.embed) {
697
+ fetchOptions.query.push(['embed', JSON.stringify(options.embed)]);
698
+ }
699
+ if (!(options && options.withRights)) {
700
+ fetchOptions.query.push(['skip_rights', 'y']);
701
+ }
702
+ return this.merchi.authenticatedFetch(resource, fetchOptions).
703
+ then((data: any) => {
704
+ this.fromJson(data[singularName]);
705
+ this.cleanDirty();
706
+ return this;});
707
+ };
708
+
709
+ public create = this.createFactory({});
710
+
711
+ private getEntityClass = (name: string) => {
712
+ if (name === undefined) {
713
+ return undefined;
714
+ }
715
+ return (this.merchi as any)[name];
716
+ };
717
+
718
+ public cleanDirty = () => {
719
+ // remove all dirty records of this entity, makes it untouched
720
+ // entity
721
+ this.isDirty = false;
722
+ for (const entry of this.propertiesMap.entries()) {
723
+ const propertyInfo = entry[1];
724
+ propertyInfo.dirty = false;
725
+ if (propertyInfo.currentValue !== undefined) {
726
+ if (propertyInfo.arrayType) {
727
+ propertyInfo.currentValue.map((v: any) => v.cleanDirty());
728
+ } else if (this.isSingleEntityProperty(propertyInfo)) {
729
+ if (propertyInfo.currentValue) {
730
+ propertyInfo.currentValue.cleanDirty();
731
+ }
732
+ }
733
+ }
734
+ }
735
+ };
736
+
737
+
738
+ public fromJson = (json: any, options?: FromJsonOptions) => {
739
+ options = options || {};
740
+ const { makeDirty = false, arrayValueStrict = true } = options;
741
+ options = { makeDirty, arrayValueStrict };
742
+ for (const key in json) {
743
+ const value: any = (json as any)[key];
744
+ if (value === undefined) continue;
745
+ const propertyInfo = this.propertiesMap.get(key);
746
+ if (propertyInfo !== undefined) {
747
+ propertyInfo.dirty = makeDirty;
748
+ if (propertyInfo.arrayType) {
749
+ // ignore array value if it is not an array and we did expect it
750
+ if (!arrayValueStrict && !Array.isArray(value)) continue;
751
+ const newValue: any = value.map((item: any, index: number) => {
752
+ const currentValue: any = propertyInfo.currentValue;
753
+ // if property already have an array of entities as relationship,
754
+ // try to merge with json one by one, this behavior may need to be
755
+ // configurable in the future.
756
+ if (currentValue && currentValue[index]) {
757
+ return currentValue[index].fromJson(item, options);
758
+ }
759
+ const nested = new (propertyInfo.arrayType as any)(this.merchi);
760
+ return nested.fromJson(item, options);
761
+ });
762
+ propertyInfo.currentValue = newValue;
763
+ } else if (this.isSingleEntityProperty(propertyInfo)) {
764
+ // if property already have a entity as relationship, try to merge
765
+ // with json first, this behavior may need to be configurable in the
766
+ // future.
767
+ if (propertyInfo.currentValue) {
768
+ propertyInfo.currentValue.fromJson(value, options);
769
+ } else {
770
+ const nested = new (propertyInfo.type as any)(this.merchi);
771
+ propertyInfo.currentValue = nested.fromJson(value, options);
772
+ }
773
+ } else {
774
+ propertyInfo.currentValue = value;
775
+ if (propertyInfo.type === Date && !!value) {
776
+ propertyInfo.currentValue = new Date(value * 1000);
777
+ }
778
+ }
779
+ }
780
+ }
781
+ return this;
782
+ };
783
+
784
+ public toJson = () => {
785
+ const json: any = {};
786
+ for (const entry of this.propertiesMap.entries()) {
787
+ const propertyName = entry[0];
788
+ const propertyInfo = entry[1];
789
+ if (propertyInfo.currentValue !== undefined) {
790
+ if (propertyInfo.arrayType) {
791
+ const array = propertyInfo.currentValue.map((v: any) => v.toJson());
792
+ json[propertyName] = array;
793
+ } else if (this.isSingleEntityProperty(propertyInfo)) {
794
+ if (propertyInfo.currentValue === null) {
795
+ json[propertyName] = null;
796
+ } else {
797
+ json[propertyName] = propertyInfo.currentValue.toJson();
798
+ }
799
+ } else {
800
+ const value = propertyInfo.currentValue;
801
+ json[propertyName] = value;
802
+ if (propertyInfo.type === Date && !!value) {
803
+ json[propertyName] = value.getTime() / 1000;
804
+ }
805
+ }
806
+ }
807
+ }
808
+ return json;
809
+ };
810
+
811
+ protected forEachProperty = (fn: (i: PropertyInfo) => void) => {
812
+ for (const info of this.propertiesMap.values()) {
813
+ fn(info);
814
+ }
815
+ };
816
+
817
+ public toFormData = (options?: SerialiseOptions,
818
+ fileIndex?: Counter): FormData => {
819
+ if (options === undefined) {
820
+ options = {};
821
+ }
822
+ const result = options.existing || new FormData();
823
+ const prefix = options._prefix || '';
824
+ const excludeOld = options.excludeOld === undefined ?
825
+ true : options.excludeOld;
826
+ if (fileIndex === undefined) {
827
+ fileIndex = {value: 0};
828
+ }
829
+ const appendData = (name: string, value: any) => {
830
+ /* istanbul ignore next */
831
+ if (name === undefined || value === undefined) {
832
+ /* istanbul ignore next */
833
+ return;
834
+ }
835
+ if (prefix) {
836
+ name = prefix + '-' + name;
837
+ }
838
+ result.set(name, value);
839
+ };
840
+ if ((this as any).fileData !== undefined) {
841
+ result.set(String(fileIndex.value), (this as any).fileData);
842
+ appendData('fileDataIndex', fileIndex.value);
843
+ fileIndex.value++;
844
+ }
845
+ const processArrayProperty = (info: PropertyInfo, value: Entity[]) => {
846
+ const remoteCount = value.length;
847
+ const initialLength = Array.from((result as any).entries()).length;
848
+ if (remoteCount === 0 && info.dirty) {
849
+ appendData(info.property + '-count', 0);
850
+ return;
851
+ }
852
+
853
+ let isDirty = false;
854
+ for (const item of value) {
855
+ if (item.isDirty) {
856
+ isDirty = true;
857
+ break;
858
+ }
859
+ }
860
+ isDirty = isDirty || info.dirty;
861
+ if (!isDirty && excludeOld) {
862
+ return;
863
+ }
864
+ for (let i = 0; i < remoteCount; ++i) {
865
+ let innerPrefix = info.property + '-' + i;
866
+ if (prefix) {
867
+ innerPrefix = prefix + '-' + innerPrefix;
868
+ }
869
+ value[i].toFormData(
870
+ {existing: result, _prefix: innerPrefix, excludeOld: excludeOld},
871
+ fileIndex);
872
+ }
873
+ const finalLength = Array.from((result as any).entries()).length;
874
+ if ((finalLength - initialLength) > 0) {
875
+ appendData(info.property + '-count', remoteCount);
876
+ if (info.updatingOrder) {
877
+ appendData(info.property + '-*updateOrder', 'true');
878
+ }
879
+ }
880
+ };
881
+ const processSingleEntityProperty = (info: PropertyInfo, value: Entity) => {
882
+ const primaryKey: string = (this.constructor as typeof Entity).primaryKey;
883
+ let innerPrefix = info.property + '-0';
884
+ if (prefix) {
885
+ innerPrefix = prefix + '-' + innerPrefix;
886
+ }
887
+ if (value === null) {
888
+ if (info.dirty || !excludeOld) {
889
+ appendData(info.property + '-0-' + primaryKey, '-1');
890
+ appendData(info.property + '-count', 1);
891
+ }
892
+ return;
893
+ }
894
+ if (!(info.dirty || (value.isDirty)) && excludeOld) {
895
+ return;
896
+ }
897
+ const initialLength = Array.from((result as any).entries()).length;
898
+ value.toFormData(
899
+ {existing: result, _prefix: innerPrefix, excludeOld: excludeOld},
900
+ fileIndex);
901
+ const finalLength = Array.from((result as any).entries()).length;
902
+ if ((finalLength - initialLength) > 0) {
903
+ appendData(info.property + '-count', 1);
904
+ }
905
+ };
906
+ const processScalarProperty = (info: PropertyInfo, value: any) => {
907
+ const primaryKey: string = (this.constructor as typeof Entity).primaryKey;
908
+ if (!excludeOld ||
909
+ info.dirty ||
910
+ (info.property === primaryKey && value)) {
911
+ if (info.type === Date && !!value) {
912
+ value = value.getTime() / 1000;
913
+ }
914
+ appendData(info.property, value);
915
+ }
916
+ };
917
+ const processProperty = (info: PropertyInfo) => {
918
+ const value = (this as any)[info.attribute];
919
+ if (value === undefined) {
920
+ return;
921
+ } else if (info.arrayType) {
922
+ processArrayProperty(info, value);
923
+ } else if (this.isSingleEntityProperty(info)) {
924
+ processSingleEntityProperty(info, value);
925
+ } else {
926
+ processScalarProperty(info, value);
927
+ }
928
+ };
929
+ this.forEachProperty(processProperty);
930
+ return result;
931
+ };
932
+
933
+ protected addBackObject = (remote?: Entity) => {
934
+ if (remote !== undefined) {
935
+ remote.backObjects.add(this);
936
+ }
937
+ };
938
+
939
+ protected addBackObjectList = (remotes?: Entity[]) => {
940
+ if (remotes !== undefined) {
941
+ remotes.forEach(this.addBackObject);
942
+ }
943
+ };
944
+
945
+ public updateOrder = (property: string) => {
946
+ (this.propertiesMap.get(property) as PropertyInfo).updatingOrder = true;
947
+ };
948
+
949
+ protected markDirty = (property: string, newValue: any) => {
950
+ if (newValue === undefined) {
951
+ return;
952
+ }
953
+ (this.propertiesMap.get(property) as PropertyInfo).dirty = true;
954
+ const openSet: Entity[] = []; /* Queue (BFS) */
955
+ const closedSet = new Set();
956
+ openSet.push(this);
957
+ while (openSet.length > 0) {
958
+ const current = openSet.shift() as Entity;
959
+ if (!closedSet.has(current)) {
960
+ current.isDirty = true;
961
+ closedSet.add(current);
962
+ for (const child of current.backObjects) openSet.push(child);
963
+ }
964
+ }
965
+ };
966
+
967
+ public delete = (options?: DeleteOptions) => {
968
+ const primaryKey: number = this.getPrimaryKeyValue();
969
+ const resourceName: string = (this.constructor as any).resourceName;
970
+ const resource = `/${resourceName}/${String(primaryKey)}/`;
971
+ const fetchOptions: RequestOptions = {method: 'DELETE'};
972
+ fetchOptions.query = [];
973
+ if (!(options && options.withRights)) {
974
+ fetchOptions.query.push(['skip_rights', 'y']);
975
+ }
976
+ if (this.merchi.sessionToken) {
977
+ fetchOptions.query.push(['session_token', this.merchi.sessionToken]);
978
+ }
979
+ return this.merchi.authenticatedFetch(resource, fetchOptions, true).then(
980
+ () => {return this;});
981
+ };
982
+
983
+ public recover = (options?: SaveOptions) => {
984
+ const primaryKey: number | string = this.getPrimaryKeyValue();
985
+ const constructor = this.constructor as typeof Entity;
986
+ const resourceName: string = constructor.resourceName;
987
+ const singularName: string = constructor.singularName;
988
+ const resource = `/unarchive/${resourceName}/${String(primaryKey)}/`;
989
+ const fetchOptions: RequestOptions = {method: 'POST'};
990
+ fetchOptions.query = [];
991
+ if (options && options.embed) {
992
+ fetchOptions.query.push(['embed', JSON.stringify(options.embed)]);
993
+ }
994
+ if (!(options && options.withRights)) {
995
+ fetchOptions.query.push(['skip_rights', 'y']);
996
+ }
997
+ return this.merchi.authenticatedFetch(resource, fetchOptions).then((data: any) => {
998
+ this.fromJson(data[singularName]);
999
+ return this;
1000
+ });
1001
+ };
1002
+ }