@kaspernj/api-maker 1.0.2011 → 1.0.2013

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 (413) hide show
  1. package/{.eslintrc.cjs → .eslintrc.js} +10 -1
  2. package/README.md +35 -0
  3. package/android/build.gradle +43 -0
  4. package/android/src/main/AndroidManifest.xml +2 -0
  5. package/android/src/main/java/expo/modules/api_maker/ApiMakerModule.kt +50 -0
  6. package/android/src/main/java/expo/modules/api_maker/ApiMakerView.kt +30 -0
  7. package/build/api.js +120 -0
  8. package/build/attribute-not-loaded-error.js +2 -0
  9. package/build/base-component.js +5 -0
  10. package/build/base-error.js +33 -0
  11. package/build/base-model/attribute.js +25 -0
  12. package/build/base-model/column.js +11 -0
  13. package/build/base-model/reflection.js +14 -0
  14. package/build/base-model/scope.js +11 -0
  15. package/build/base-model.js +828 -0
  16. package/build/bootstrap/attribute-row.js +135 -0
  17. package/build/bootstrap/attribute-rows.js +31 -0
  18. package/build/bootstrap/card.js +138 -0
  19. package/build/bootstrap/checkbox.js +97 -0
  20. package/build/bootstrap/checkboxes.js +183 -0
  21. package/build/bootstrap/index.js +2 -0
  22. package/build/bootstrap/input.js +129 -0
  23. package/build/bootstrap/invalid-feedback.js +27 -0
  24. package/build/bootstrap/paginate.js +150 -0
  25. package/build/bootstrap/radio-buttons.js +72 -0
  26. package/build/bootstrap/select.js +88 -0
  27. package/build/bootstrap/sort-link.js +131 -0
  28. package/build/cable-connection-pool.js +128 -0
  29. package/build/cable-subscription-pool.js +207 -0
  30. package/build/cable-subscription.js +21 -0
  31. package/build/cache-key-generator.js +81 -0
  32. package/build/can-can.js +134 -0
  33. package/build/channels-consumer.js +9 -0
  34. package/build/collection-loader.js +48 -0
  35. package/build/collection.js +280 -0
  36. package/build/command-submit-data.js +81 -0
  37. package/build/commands-pool.js +195 -0
  38. package/build/compose.js +9 -0
  39. package/build/config.js +62 -0
  40. package/build/custom-error.js +5 -0
  41. package/build/data-set-to-attributes.js +10 -0
  42. package/build/deserializer.js +56 -0
  43. package/build/destroy-error.js +5 -0
  44. package/build/devise.js +112 -0
  45. package/build/draggable-sort/controller.js +136 -0
  46. package/build/draggable-sort/index.js +114 -0
  47. package/build/draggable-sort/item.js +188 -0
  48. package/build/error-logger.js +101 -0
  49. package/build/error-messages.js +13 -0
  50. package/build/event-connection.js +32 -0
  51. package/build/event-emitter-listener.js +15 -0
  52. package/build/event-model-class.js +24 -0
  53. package/build/events.js +5 -0
  54. package/build/flash-message.js +79 -0
  55. package/build/form.js +83 -0
  56. package/build/history-expo.js +20 -0
  57. package/build/history-react-native.js +20 -0
  58. package/build/history.js +3 -0
  59. package/build/index.js +3 -0
  60. package/build/inputs/attachment.js +133 -0
  61. package/build/inputs/auto-submit.js +36 -0
  62. package/build/inputs/checkbox.js +138 -0
  63. package/build/inputs/checkboxes.js +112 -0
  64. package/build/inputs/id-for-component.js +15 -0
  65. package/build/inputs/input-wrapper.js +19 -0
  66. package/build/inputs/input.js +243 -0
  67. package/build/inputs/money.js +179 -0
  68. package/build/inputs/name-for-component.js +13 -0
  69. package/build/inputs/select.js +93 -0
  70. package/build/instance-of-class-name.js +23 -0
  71. package/build/is-expo.js +22 -0
  72. package/build/key-value-store.js +53 -0
  73. package/build/link.js +73 -0
  74. package/build/logger.js +30 -0
  75. package/build/modal.js +38 -0
  76. package/build/model-class-require.js +13 -0
  77. package/build/model-events.js +30 -0
  78. package/build/model-name.js +28 -0
  79. package/build/model-prop-type.js +101 -0
  80. package/build/model-recipes-loader.js +32 -0
  81. package/build/model-recipes-model-loader.js +357 -0
  82. package/build/models-response-reader.js +40 -0
  83. package/build/models.js +8 -0
  84. package/build/money-formatter.js +78 -0
  85. package/build/not-loaded-error.js +2 -0
  86. package/build/params.js +61 -0
  87. package/build/preloaded.js +38 -0
  88. package/build/resize-observer.js +11 -0
  89. package/build/result.js +13 -0
  90. package/build/router/route.js +270 -0
  91. package/build/router/switch.js +72 -0
  92. package/build/router.js +59 -0
  93. package/build/routes-native.js +202 -0
  94. package/build/routes.js +50 -0
  95. package/build/run-last.js +35 -0
  96. package/build/serializer.js +63 -0
  97. package/build/services.js +20 -0
  98. package/build/session-status-updater.js +134 -0
  99. package/build/source-maps-loader.js +184 -0
  100. package/build/super-admin/config-reader.js +85 -0
  101. package/build/super-admin/edit-page/edit-attribute-checkbox.js +85 -0
  102. package/build/super-admin/edit-page/edit-attribute-content.js +55 -0
  103. package/build/super-admin/edit-page/edit-attribute-input.js +79 -0
  104. package/build/super-admin/edit-page/edit-attribute.js +77 -0
  105. package/build/super-admin/edit-page.js +123 -0
  106. package/build/super-admin/has-edit-config.js +12 -0
  107. package/build/super-admin/index-page.js +25 -0
  108. package/build/super-admin/index.js +181 -0
  109. package/build/super-admin/layout/header/index.js +161 -0
  110. package/build/super-admin/layout/index.js +164 -0
  111. package/build/super-admin/layout/menu/index.js +206 -0
  112. package/build/super-admin/layout/menu/menu-content.js +46 -0
  113. package/build/super-admin/layout/menu/menu-item.js +84 -0
  114. package/build/super-admin/layout/no-access.js +27 -0
  115. package/build/super-admin/model-class-table.js +61 -0
  116. package/build/super-admin/models.js +8 -0
  117. package/build/super-admin/show-nav.js +51 -0
  118. package/build/super-admin/show-page/belongs-to-attribute-row.js +29 -0
  119. package/build/super-admin/show-page/index.js +141 -0
  120. package/build/super-admin/show-reflection-actions.js +47 -0
  121. package/build/super-admin/show-reflection-link.js +48 -0
  122. package/build/super-admin/show-reflection-page.js +48 -0
  123. package/build/table/column-content.js +117 -0
  124. package/build/table/column-identifier.js +18 -0
  125. package/build/table/column-visible.js +7 -0
  126. package/build/table/components/column.js +21 -0
  127. package/build/table/components/flat-list.js +21 -0
  128. package/build/table/components/header.js +26 -0
  129. package/build/table/components/row.js +26 -0
  130. package/build/table/filters/attribute-element.js +44 -0
  131. package/build/table/filters/filter-form.js +402 -0
  132. package/build/table/filters/filter.js +90 -0
  133. package/build/table/filters/index.js +184 -0
  134. package/build/table/filters/load-search-modal.js +175 -0
  135. package/build/table/filters/reflection-element.js +37 -0
  136. package/build/table/filters/save-search-modal.js +88 -0
  137. package/build/table/filters/scope-element.js +42 -0
  138. package/build/table/header-column-content.js +68 -0
  139. package/build/table/header-column.js +144 -0
  140. package/build/table/header-select.js +105 -0
  141. package/build/table/model-callback-args.js +10 -0
  142. package/build/table/model-column.js +97 -0
  143. package/build/table/model-row.js +193 -0
  144. package/build/table/select-calculator.js +63 -0
  145. package/build/table/settings/column-row.js +97 -0
  146. package/build/table/settings/download-action.js +79 -0
  147. package/build/table/settings/index.js +92 -0
  148. package/build/table/table-settings.js +219 -0
  149. package/build/table/table.js +972 -0
  150. package/build/table/use-sorting.js +34 -0
  151. package/build/table/widths.js +75 -0
  152. package/build/table/worker-plugins-check-all-checkbox.js +125 -0
  153. package/build/table/worker-plugins-checkbox.js +115 -0
  154. package/build/translated-attributes.js +10 -0
  155. package/build/translated-collections.js +12 -0
  156. package/build/updated-attribute.js +76 -0
  157. package/build/url-encode.js +15 -0
  158. package/build/use-breakpoint.js +71 -0
  159. package/build/use-can-can.js +55 -0
  160. package/build/use-collection.js +225 -0
  161. package/build/use-created-event.js +52 -0
  162. package/build/use-current-user.js +76 -0
  163. package/build/use-destroyed-event.js +60 -0
  164. package/build/use-event-emitter.js +13 -0
  165. package/build/use-event-listener.js +16 -0
  166. package/build/use-input.js +137 -0
  167. package/build/use-model-event.js +60 -0
  168. package/build/use-model.js +169 -0
  169. package/build/use-resize-observer.js +23 -0
  170. package/build/use-router.js +104 -0
  171. package/build/use-screen-layout.js +39 -0
  172. package/build/use-styles.js +41 -0
  173. package/build/use-updated-event.js +60 -0
  174. package/build/use-validation-errors.js +30 -0
  175. package/build/utils/card.js +51 -0
  176. package/build/utils/checkbox.js +78 -0
  177. package/build/utils/checkboxes.js +163 -0
  178. package/build/utils/default-style.js +18 -0
  179. package/build/utils/icon.js +23 -0
  180. package/build/utils/invalid-feedback.js +19 -0
  181. package/build/utils/modal.js +62 -0
  182. package/build/utils/text.js +44 -0
  183. package/build/validation-error.js +28 -0
  184. package/build/validation-errors.js +98 -0
  185. package/build/with-api-maker.js +29 -0
  186. package/build/with-collection.js +14 -0
  187. package/build/with-current-user.js +10 -0
  188. package/build/with-model.js +15 -0
  189. package/build/with-router.js +22 -0
  190. package/expo-module.config.json +17 -0
  191. package/ios/ApiMaker.podspec +29 -0
  192. package/ios/ApiMakerModule.swift +48 -0
  193. package/ios/ApiMakerView.swift +38 -0
  194. package/package.json +49 -46
  195. package/src/{api.mjs → api.js} +38 -37
  196. package/src/base-component.jsx +5 -0
  197. package/src/{base-error.mjs → base-error.js} +4 -6
  198. package/src/base-model/attribute.js +33 -0
  199. package/src/base-model/column.js +13 -0
  200. package/src/base-model/reflection.js +15 -0
  201. package/src/base-model/scope.js +12 -0
  202. package/src/{base-model.mjs → base-model.js} +302 -144
  203. package/src/bootstrap/attribute-row.jsx +135 -0
  204. package/src/bootstrap/attribute-rows.jsx +27 -0
  205. package/src/bootstrap/card.jsx +149 -0
  206. package/src/bootstrap/checkbox.jsx +86 -0
  207. package/src/bootstrap/checkboxes.jsx +185 -0
  208. package/src/bootstrap/index.js +0 -0
  209. package/src/bootstrap/input.jsx +173 -0
  210. package/src/bootstrap/invalid-feedback.jsx +31 -0
  211. package/src/bootstrap/paginate.jsx +187 -0
  212. package/src/bootstrap/radio-buttons.jsx +87 -0
  213. package/src/bootstrap/select.jsx +110 -0
  214. package/src/bootstrap/sort-link.jsx +106 -0
  215. package/src/{cable-connection-pool.mjs → cable-connection-pool.js} +16 -36
  216. package/src/{cable-subscription-pool.mjs → cable-subscription-pool.js} +26 -21
  217. package/src/{cable-subscription.mjs → cable-subscription.js} +6 -4
  218. package/src/cache-key-generator.js +100 -0
  219. package/src/{can-can.mjs → can-can.js} +13 -12
  220. package/src/channels-consumer.js +10 -0
  221. package/src/collection-loader.jsx +58 -224
  222. package/src/{collection.mjs → collection.js} +98 -44
  223. package/src/{command-submit-data.mjs → command-submit-data.js} +2 -7
  224. package/src/{commands-pool.mjs → commands-pool.js} +57 -41
  225. package/src/compose.js +11 -0
  226. package/src/{config.mjs → config.js} +6 -2
  227. package/src/{custom-error.mjs → custom-error.js} +1 -1
  228. package/src/data-set-to-attributes.js +13 -0
  229. package/src/{deserializer.mjs → deserializer.js} +3 -3
  230. package/src/destroy-error.js +7 -0
  231. package/src/devise.js +129 -0
  232. package/src/draggable-sort/controller.js +137 -0
  233. package/src/draggable-sort/index.jsx +108 -0
  234. package/src/draggable-sort/item.jsx +174 -0
  235. package/src/{error-logger.mjs → error-logger.js} +12 -7
  236. package/src/{error-messages.mjs → error-messages.js} +1 -0
  237. package/src/event-connection.jsx +1 -1
  238. package/src/event-emitter-listener.jsx +8 -27
  239. package/src/event-model-class.jsx +2 -4
  240. package/src/events.js +7 -0
  241. package/src/flash-message.js +70 -0
  242. package/src/form.jsx +91 -0
  243. package/src/history-expo.js +23 -0
  244. package/src/history-react-native.js +25 -0
  245. package/src/history.js +3 -0
  246. package/src/index.js +3 -0
  247. package/src/inputs/attachment.jsx +108 -0
  248. package/src/inputs/auto-submit.js +37 -0
  249. package/src/inputs/checkbox.jsx +125 -0
  250. package/src/inputs/checkboxes.jsx +116 -0
  251. package/src/inputs/id-for-component.js +15 -0
  252. package/src/inputs/input-wrapper.jsx +16 -0
  253. package/src/inputs/input.jsx +260 -0
  254. package/src/inputs/money.jsx +187 -0
  255. package/src/inputs/name-for-component.js +15 -0
  256. package/src/inputs/select.jsx +104 -0
  257. package/src/is-expo.js +18 -0
  258. package/src/{key-value-store.mjs → key-value-store.js} +1 -1
  259. package/src/link.jsx +54 -9
  260. package/src/logger.js +38 -0
  261. package/src/modal.jsx +37 -0
  262. package/src/model-class-require.js +17 -0
  263. package/src/{model-events.mjs → model-events.js} +1 -1
  264. package/src/{model-name.mjs → model-name.js} +8 -8
  265. package/src/{model-recipes-loader.mjs → model-recipes-loader.js} +1 -1
  266. package/src/{model-recipes-model-loader.mjs → model-recipes-model-loader.js} +5 -5
  267. package/src/{models-response-reader.mjs → models-response-reader.js} +3 -4
  268. package/src/models.js +7 -0
  269. package/src/{models.mjs.erb → models.js.erb} +6 -3
  270. package/src/{money-formatter.mjs → money-formatter.js} +5 -4
  271. package/src/{params.mjs → params.js} +17 -7
  272. package/src/{preloaded.mjs → preloaded.js} +2 -2
  273. package/src/resize-observer.jsx +10 -0
  274. package/src/result.js +13 -0
  275. package/src/router/route.jsx +246 -0
  276. package/src/router/switch.jsx +76 -0
  277. package/src/router.jsx +23 -21
  278. package/src/{routes-native.mjs → routes-native.js} +12 -6
  279. package/src/{routes.mjs → routes.js} +1 -1
  280. package/src/run-last.js +39 -0
  281. package/src/{serializer.mjs → serializer.js} +2 -2
  282. package/src/{services.mjs → services.js} +1 -1
  283. package/src/session-status-updater.js +172 -0
  284. package/src/{source-maps-loader.mjs → source-maps-loader.js} +54 -28
  285. package/src/super-admin/config-reader.jsx +93 -0
  286. package/src/super-admin/edit-page/edit-attribute-checkbox.jsx +81 -0
  287. package/src/super-admin/edit-page/edit-attribute-content.jsx +57 -0
  288. package/src/super-admin/edit-page/edit-attribute-input.jsx +71 -0
  289. package/src/super-admin/edit-page/edit-attribute.jsx +81 -0
  290. package/src/super-admin/edit-page.jsx +117 -0
  291. package/src/super-admin/has-edit-config.js +15 -0
  292. package/src/super-admin/index-page.jsx +23 -0
  293. package/src/super-admin/index.jsx +197 -0
  294. package/src/super-admin/layout/header/index.jsx +144 -0
  295. package/src/super-admin/layout/header/style.scss +45 -0
  296. package/src/super-admin/layout/index.jsx +154 -0
  297. package/src/super-admin/layout/menu/index.jsx +171 -0
  298. package/src/super-admin/layout/menu/menu-content.jsx +43 -0
  299. package/src/super-admin/layout/menu/menu-item.jsx +70 -0
  300. package/src/super-admin/layout/menu/style.scss +11 -0
  301. package/src/super-admin/layout/no-access.jsx +26 -0
  302. package/src/super-admin/model-class-table.jsx +66 -0
  303. package/src/super-admin/models.js +11 -0
  304. package/src/super-admin/show-nav.jsx +44 -0
  305. package/src/super-admin/show-page/belongs-to-attribute-row.jsx +30 -0
  306. package/src/super-admin/show-page/index.jsx +141 -0
  307. package/src/super-admin/show-reflection-actions.jsx +49 -0
  308. package/src/super-admin/show-reflection-link.jsx +40 -0
  309. package/src/super-admin/show-reflection-page.jsx +47 -0
  310. package/src/super-admin/stylesheets/variables.scss +11 -0
  311. package/src/table/column-content.jsx +122 -0
  312. package/src/table/column-identifier.js +23 -0
  313. package/src/table/column-visible.js +7 -0
  314. package/src/table/components/column.jsx +19 -0
  315. package/src/table/components/flat-list.jsx +19 -0
  316. package/src/table/components/header.jsx +21 -0
  317. package/src/table/components/row.jsx +23 -0
  318. package/src/table/filters/attribute-element.jsx +47 -0
  319. package/src/table/filters/filter-form.jsx +407 -0
  320. package/src/table/filters/filter.jsx +70 -0
  321. package/src/table/filters/index.jsx +170 -0
  322. package/src/table/filters/load-search-modal.jsx +146 -0
  323. package/src/table/filters/reflection-element.jsx +38 -0
  324. package/src/table/filters/save-search-modal.jsx +74 -0
  325. package/src/table/filters/scope-element.jsx +44 -0
  326. package/src/table/header-column-content.jsx +55 -0
  327. package/src/table/header-column.jsx +129 -0
  328. package/src/table/header-select.jsx +73 -0
  329. package/src/table/model-callback-args.js +10 -0
  330. package/src/table/model-column.jsx +82 -0
  331. package/src/table/model-row.jsx +136 -0
  332. package/src/table/select-calculator.js +65 -0
  333. package/src/table/settings/column-row.jsx +93 -0
  334. package/src/table/settings/download-action.jsx +68 -0
  335. package/src/table/settings/index.jsx +65 -0
  336. package/src/table/table-settings.js +263 -0
  337. package/src/table/table.jsx +950 -0
  338. package/src/table/use-sorting.js +35 -0
  339. package/src/table/variables.scss +11 -0
  340. package/src/table/widths.jsx +87 -0
  341. package/src/table/worker-plugins-check-all-checkbox.jsx +112 -0
  342. package/src/table/worker-plugins-checkbox.jsx +104 -0
  343. package/src/translated-attributes.js +11 -0
  344. package/src/{translated-collections.mjs → translated-collections.js} +3 -2
  345. package/src/updated-attribute.jsx +1 -1
  346. package/src/url-encode.js +18 -0
  347. package/src/use-breakpoint.js +87 -0
  348. package/src/use-can-can.js +55 -0
  349. package/src/use-collection.js +280 -0
  350. package/src/use-created-event.js +55 -0
  351. package/src/use-current-user.js +88 -0
  352. package/src/use-destroyed-event.js +60 -0
  353. package/src/use-event-emitter.js +15 -0
  354. package/src/use-event-listener.js +19 -0
  355. package/src/use-input.js +157 -0
  356. package/src/use-model-event.js +60 -0
  357. package/src/use-model.js +189 -0
  358. package/src/use-resize-observer.js +24 -0
  359. package/src/use-router.jsx +128 -0
  360. package/src/use-screen-layout.js +49 -0
  361. package/src/use-styles.js +50 -0
  362. package/src/use-updated-event.js +60 -0
  363. package/src/use-validation-errors.js +33 -0
  364. package/src/utils/card.jsx +49 -0
  365. package/src/utils/checkbox.jsx +80 -0
  366. package/src/utils/checkboxes.jsx +158 -0
  367. package/src/utils/default-style.jsx +25 -0
  368. package/src/utils/icon.jsx +21 -0
  369. package/src/utils/invalid-feedback.jsx +20 -0
  370. package/src/utils/modal.jsx +60 -0
  371. package/src/utils/text.jsx +38 -0
  372. package/src/{validation-error.mjs → validation-error.js} +9 -5
  373. package/src/{validation-errors.mjs → validation-errors.js} +15 -27
  374. package/src/with-api-maker.jsx +31 -0
  375. package/src/with-collection.jsx +17 -0
  376. package/src/with-current-user.jsx +7 -25
  377. package/src/with-model.jsx +16 -0
  378. package/src/with-router.jsx +7 -129
  379. package/__tests__/base-model.test.js +0 -71
  380. package/__tests__/cable-connection-pool.test.js +0 -227
  381. package/__tests__/cable-subscription-pool.test.js +0 -26
  382. package/__tests__/can-can.test.js +0 -34
  383. package/__tests__/collection.test.js +0 -51
  384. package/__tests__/custom-error.test.js +0 -13
  385. package/__tests__/model-name.test.js +0 -34
  386. package/__tests__/model-prop-type.test.js +0 -113
  387. package/__tests__/params.test.js +0 -40
  388. package/__tests__/routes-native.test.js +0 -103
  389. package/__tests__/routes.test.js +0 -46
  390. package/__tests__/serializer.test.js +0 -30
  391. package/__tests__/support/task.js +0 -27
  392. package/__tests__/support/user.js +0 -32
  393. package/index.js +0 -1
  394. package/jest.config.js +0 -4
  395. package/src/can-can-loader.jsx +0 -54
  396. package/src/channels-consumer.mjs +0 -3
  397. package/src/destroy-error.mjs +0 -7
  398. package/src/devise.mjs +0 -122
  399. package/src/event-created.jsx +0 -65
  400. package/src/event-destroyed.jsx +0 -29
  401. package/src/event-listener.jsx +0 -38
  402. package/src/event-updated.jsx +0 -74
  403. package/src/logger.mjs +0 -25
  404. package/src/model-class-require.mjs +0 -10
  405. package/src/model-load-wrapper.jsx +0 -116
  406. package/src/result.mjs +0 -29
  407. package/src/session-status-updater.mjs +0 -116
  408. package/webpack.config.js +0 -15
  409. /package/src/{attribute-not-loaded-error.mjs → attribute-not-loaded-error.js} +0 -0
  410. /package/src/{instance-of-class-name.mjs → instance-of-class-name.js} +0 -0
  411. /package/src/{model-prop-type.mjs → model-prop-type.js} +0 -0
  412. /package/src/{not-loaded-error.mjs → not-loaded-error.js} +0 -0
  413. /package/src/{translated-collections-data.mjs.erb → translated-collections-data.js.erb} +0 -0
@@ -0,0 +1,60 @@
1
+ import {useCallback, useLayoutEffect, useMemo} from "react"
2
+ import debounceFunction from "debounce"
3
+ import ModelEvents from "./model-events"
4
+ import useShape from "set-state-compare/src/use-shape"
5
+
6
+ const apiMakerUseModelEvent = (model, event, onCallback, props) => {
7
+ const {active = true, debounce, onConnected, ...restProps} = props || {}
8
+
9
+ if (Object.keys(restProps).length > 0) {
10
+ throw new Error(`Unknown props given to apiMakerUseModelEvent: ${Object.keys(restProps).join(", ")}`)
11
+ }
12
+
13
+ const s = useShape({active, debounce, model, onCallback})
14
+
15
+ const debounceCallback = useMemo(() => {
16
+ if (typeof debounce == "number") {
17
+ return debounceFunction(s.p.onCallback, debounce)
18
+ } else {
19
+ return debounceFunction(s.p.onCallback)
20
+ }
21
+ }, [debounce])
22
+
23
+ s.updateMeta({debounceCallback})
24
+
25
+ const onCallbackCallback = useCallback((...args) => {
26
+ if (!s.p.active) {
27
+ return
28
+ }
29
+
30
+ if (s.p.debounce) {
31
+ s.m.debounceCallback(...args)
32
+ } else {
33
+ s.p.onCallback(...args)
34
+ }
35
+ }, [])
36
+
37
+ useLayoutEffect(() => {
38
+ let connectEvent, onConnectedListener
39
+
40
+ if (model) {
41
+ connectEvent = ModelEvents.connect(model, event, onCallbackCallback)
42
+
43
+ if (onConnected) {
44
+ onConnectedListener = connectEvent.events.addListener("connected", onConnected)
45
+ }
46
+ }
47
+
48
+ return () => {
49
+ if (onConnectedListener) {
50
+ connectEvent.events.removeListener("connected", onConnected)
51
+ }
52
+
53
+ if (connectEvent) {
54
+ connectEvent.unsubscribe()
55
+ }
56
+ }
57
+ }, [model?.id()])
58
+ }
59
+
60
+ export default apiMakerUseModelEvent
@@ -0,0 +1,189 @@
1
+ import {useCallback, useLayoutEffect, useMemo} from "react"
2
+ import Devise from "./devise"
3
+ import * as inflection from "inflection"
4
+ import ModelEvents from "./model-events"
5
+ import useQueryParams from "on-location-changed/build/use-query-params"
6
+ import useShape from "set-state-compare/src/use-shape"
7
+
8
+ const useModel = (modelClassArg, argsArg = {}) => {
9
+ const queryParams = useQueryParams()
10
+ let args, modelClass
11
+
12
+ if (typeof argsArg == "function") {
13
+ args = argsArg({modelClass})
14
+ } else {
15
+ args = argsArg
16
+ }
17
+
18
+ const s = useShape(args)
19
+
20
+ s.useStates({
21
+ model: undefined,
22
+ notFound: undefined
23
+ })
24
+
25
+ if ("active" in s.props && !s.props.active) {
26
+ s.meta.active = false
27
+ } else {
28
+ s.meta.active = true
29
+ }
30
+
31
+ if (typeof modelClassArg == "object") {
32
+ modelClass = modelClassArg.callback({queryParams})
33
+ } else {
34
+ modelClass = modelClassArg
35
+ }
36
+
37
+ const paramsVariableName = `${modelClass.modelName().paramKey()}_id`
38
+ let modelId
39
+
40
+ if (args.loadByQueryParam) {
41
+ modelId = args.loadByQueryParam({queryParams})
42
+ } else if (!args.query) {
43
+ if (!args.match) throw new Error("Both 'loadByQueryParam' and 'match' wasn't given")
44
+
45
+ modelId = args.match.params[paramsVariableName] || args.match.params.id
46
+ }
47
+
48
+ const modelVariableName = inflection.camelize(modelClass.modelClassData().name, true)
49
+ const cacheArgs = [modelId]
50
+
51
+ const loadExistingModel = useCallback(async () => {
52
+ let query
53
+
54
+ if (s.m.modelId) {
55
+ query = modelClass.ransack({id_eq: s.m.modelId})
56
+ } else if (s.m.args.query) {
57
+ query = s.m.args.query.clone()
58
+ } else {
59
+ throw new Error(`No model ID was given: ${s.m.modelId} by '${paramsVariableName}' in query params: ${Object.keys(s.props.match.params).join(", ")}`)
60
+ }
61
+
62
+ if (s.props.abilities) query.abilities(s.p.abilities)
63
+ if (s.props.preload) query.preload(s.p.preload)
64
+ if (s.props.select) query.select(s.p.select)
65
+
66
+ const model = await query.first()
67
+
68
+ s.set({model, notFound: !model})
69
+ }, [])
70
+
71
+ const loadNewModel = useCallback(async () => {
72
+ const ModelClass = modelClass
73
+ const paramKey = ModelClass.modelName().paramKey()
74
+ const modelDataFromParams = s.m.queryParams[paramKey] || {}
75
+
76
+ let defaults = {}
77
+
78
+ if (s.props.newIfNoId?.defaults) {
79
+ defaults = await s.props.newIfNoId.defaults()
80
+ }
81
+
82
+ const modelData = Object.assign(defaults, s.props.newAttributes, modelDataFromParams)
83
+ const model = new ModelClass({
84
+ isNewRecord: true,
85
+ data: {a: modelData}
86
+ })
87
+
88
+ s.set({model})
89
+ }, [])
90
+
91
+ const loadModel = useCallback(async () => {
92
+ if (!s.m.active) {
93
+ // Not active - don't do anything
94
+ } else if (s.props.newIfNoId && !s.m.modelId) {
95
+ return await loadNewModel()
96
+ } else if (!s.props.optional || s.m.modelId | s.m.args.query) {
97
+ return await loadExistingModel()
98
+ }
99
+ }, [])
100
+
101
+ const onDestroyed = useCallback(({model}) => {
102
+ const forwardArgs = {model}
103
+
104
+ forwardArgs[s.m.modelVariableName] = model
105
+
106
+ s.p.onDestroyed(forwardArgs)
107
+ }, [])
108
+
109
+ const onSignedIn = useCallback(() => {
110
+ loadModel()
111
+ }, [])
112
+
113
+ const onSignedOut = useCallback(() => {
114
+ loadModel()
115
+ }, [])
116
+
117
+ if (args.cacheArgs) {
118
+ cacheArgs.push(...args.cacheArgs)
119
+ }
120
+
121
+ s.updateMeta({args, modelId, modelVariableName, queryParams})
122
+
123
+ useMemo(
124
+ () => { loadModel() },
125
+ cacheArgs
126
+ )
127
+
128
+ useLayoutEffect(() => {
129
+ let reloadModelCallback
130
+
131
+ if (args.events) {
132
+ reloadModelCallback = args.events.addListener("reloadModel", loadModel)
133
+ }
134
+
135
+ return () => {
136
+ if (reloadModelCallback) {
137
+ args.events.removeListener("reloadModel", loadModel)
138
+ }
139
+ }
140
+ }, [args.events])
141
+
142
+ useLayoutEffect(() => {
143
+ let connectUpdated
144
+
145
+ if (s.s.model && args.eventUpdated) {
146
+ connectUpdated = ModelEvents.connectUpdated(s.s.model, loadModel)
147
+ }
148
+
149
+ return () => {
150
+ connectUpdated?.unsubscribe()
151
+ }
152
+ }, [args.eventUpdated, s.s.model?.id()])
153
+
154
+ useLayoutEffect(() => {
155
+ Devise.events().addListener("onDeviseSignIn", onSignedIn)
156
+ Devise.events().addListener("onDeviseSignOut", onSignedOut)
157
+
158
+ return () => {
159
+ Devise.events().removeListener("onDeviseSignIn", onSignedIn)
160
+ Devise.events().removeListener("onDeviseSignOut", onSignedOut)
161
+ }
162
+ })
163
+
164
+ useLayoutEffect(() => {
165
+ let connectDestroyed
166
+
167
+ if (s.s.model && args.onDestroyed) {
168
+ connectDestroyed = ModelEvents.connectDestroyed(s.s.model, onDestroyed)
169
+ }
170
+
171
+ return () => {
172
+ connectDestroyed?.unsubscribe()
173
+ }
174
+ }, [args.onDestroyed, s.s.model?.id()])
175
+
176
+ const result = {
177
+ model: s.s.model,
178
+ modelId,
179
+ notFound: s.s.notFound
180
+ }
181
+
182
+ result[modelVariableName] = s.s.model
183
+ result[`${modelVariableName}Id`] = modelId
184
+ result[`${modelVariableName}NotFound`] = s.s.notFound
185
+
186
+ return result
187
+ }
188
+
189
+ export default useModel
@@ -0,0 +1,24 @@
1
+ import {useCallback, useLayoutEffect, useMemo} from "react"
2
+ import useShape from "set-state-compare/src/use-shape"
3
+
4
+ const useResizeObserver = (element, callback) => {
5
+ const s = useShape({callback})
6
+ const onResize = useCallback((...args) => {
7
+ s.p.callback(...args)
8
+ }, [])
9
+ const observer = useMemo(() => new ResizeObserver(onResize), [])
10
+
11
+ useLayoutEffect(() => {
12
+ if (element) {
13
+ observer.observe(element)
14
+ }
15
+
16
+ return () => {
17
+ if (element) {
18
+ observer.disconnect()
19
+ }
20
+ }
21
+ }, [element])
22
+ }
23
+
24
+ export default useResizeObserver
@@ -0,0 +1,128 @@
1
+ import config from "./config"
2
+ import escapeStringRegexp from "escape-string-regexp"
3
+ import * as inflection from "inflection"
4
+ import PropTypes from "prop-types"
5
+ import propTypesExact from "prop-types-exact"
6
+ import {useCallback, useMemo} from "react"
7
+ import useShape from "set-state-compare/src/use-shape"
8
+
9
+ const useRouterPropTypes = propTypesExact({
10
+ locales: PropTypes.array.isRequired,
11
+ path: PropTypes.string,
12
+ routeDefinitions: PropTypes.object.isRequired,
13
+ routes: PropTypes.object.isRequired
14
+ })
15
+
16
+ const useRouter = (props) => {
17
+ PropTypes.checkPropTypes(useRouterPropTypes, props, "prop", "useRouter")
18
+
19
+ const s = useShape(props)
20
+
21
+ const findRouteParams = useCallback((routeDefinition) => {
22
+ const result = []
23
+ const parts = routeDefinition.path.split("/")
24
+
25
+ for (const part of parts) {
26
+ if (part.match(/^:([a-z_]+)$/))
27
+ result.push(part)
28
+ }
29
+
30
+ return result
31
+ }, [])
32
+
33
+ const getPath = useCallback(() => {
34
+ let path = s.p.path || window.location.pathname
35
+
36
+ path = path.replace(/[/]+$/, "")
37
+
38
+ return path
39
+ }, [])
40
+
41
+ const getRouteDefinitions = useCallback(() => s.p.routeDefinitions || config.getRouteDefinitions(), [])
42
+ const getRoutes = useCallback(() => s.p.routes || config.getRoutes(), [])
43
+
44
+ const parseRouteDefinitions = useCallback(() => {
45
+ const routeDefinitions = getRouteDefinitions()
46
+ const routes = getRoutes()
47
+ const regex = /:([A-z\d_]+)/
48
+ const parsedRouteDefinitions = []
49
+
50
+ for (const locale of s.p.locales) {
51
+ for (const routeDefinition of routeDefinitions.routes) {
52
+ const routePathName = `${inflection.camelize(routeDefinition.name, true)}Path`
53
+ const params = findRouteParams(routeDefinition)
54
+
55
+ params.push({locale})
56
+
57
+ if (!(routePathName in routes))
58
+ throw new Error(`${routePathName} not found in routes: ${Object.keys(routes, ", ")}`)
59
+
60
+ const routePath = routes[routePathName](...params).replace(/[/]+$/, "")
61
+ const groups = []
62
+ let pathRegexString = "^"
63
+
64
+ pathRegexString += escapeStringRegexp(routePath)
65
+
66
+ while (true) {
67
+ const match = pathRegexString.match(regex)
68
+
69
+ if (!match) break
70
+
71
+ const variableName = match[1]
72
+
73
+ groups.push(variableName)
74
+
75
+ pathRegexString = pathRegexString.replace(match[0], "([^/]+)")
76
+ }
77
+
78
+ pathRegexString += "$"
79
+
80
+ const pathRegex = new RegExp(pathRegexString)
81
+
82
+ parsedRouteDefinitions.push({groups, pathRegex, routeDefinition})
83
+ }
84
+ }
85
+
86
+ return parsedRouteDefinitions
87
+ }, [])
88
+
89
+ const parsedRouteDefinitions = useMemo(() => parseRouteDefinitions(), [])
90
+
91
+ s.updateMeta({parsedRouteDefinitions})
92
+
93
+ const findMatchingRoute = useCallback(() => {
94
+ const path = getPath()
95
+
96
+ for (const parsedRouteDefinition of s.m.parsedRouteDefinitions) {
97
+ const match = path.match(parsedRouteDefinition.pathRegex)
98
+ let matched, params
99
+
100
+ if (match) {
101
+ matched = true
102
+ params = {}
103
+
104
+ for (const groupKey in parsedRouteDefinition.groups) {
105
+ const groupName = parsedRouteDefinition.groups[groupKey]
106
+
107
+ params[groupName] = match[Number(groupKey) + 1]
108
+ }
109
+ }
110
+
111
+ if (path == "" && parsedRouteDefinition.routeDefinition.path == "/") matched = true
112
+ if (matched) {
113
+ return {params, parsedRouteDefinition}
114
+ }
115
+ }
116
+ }, [])
117
+
118
+ const matchingRoute = findMatchingRoute()
119
+ const params = matchingRoute?.params || {}
120
+ const match = {
121
+ matchingRoute,
122
+ params
123
+ }
124
+
125
+ return {match}
126
+ }
127
+
128
+ export default useRouter
@@ -0,0 +1,49 @@
1
+ import {Platform, useWindowDimensions} from "react-native"
2
+
3
+ const getWindowLayout = (width) => {
4
+ if (width <= 575) {
5
+ return "xs"
6
+ } else if (width <= 767) {
7
+ return "sm"
8
+ } else if (width <= 991) {
9
+ return "md"
10
+ } else if (width <= 1199) {
11
+ return "lg"
12
+ } else if (width <= 1399) {
13
+ return "xl"
14
+ } else if (width >= 1400) {
15
+ return "xxl"
16
+ } else {
17
+ console.error(`Couldn't determine window layout from width: ${width}`)
18
+ }
19
+ }
20
+
21
+ const useScreenLayout = () => {
22
+ if (Platform.OS == "web") {
23
+ const shared = useMemo(() => ({}))
24
+
25
+ shared.width = window.innerWidth
26
+
27
+ const [screenLayout, setScreenLayout] = useState(() => getWindowLayout(shared.width))
28
+
29
+ const onResize = useCallback(() => {
30
+ const newWindowLayout = getWindowLayout(window.innerWidth)
31
+
32
+ if (shared.screenlayout != newWindowLayout) {
33
+ setScreenLayout(newWindowLayout)
34
+ }
35
+ }, [])
36
+
37
+ useEventListener(window, "resize", onResize)
38
+
39
+ shared.screenLayout = screenLayout
40
+
41
+ return shared.screenLayout
42
+ } else {
43
+ const windowDimensions = useWindowDimensions()
44
+
45
+ return getWindowLayout(windowDimensions.width)
46
+ }
47
+ }
48
+
49
+ export default useScreenLayout
@@ -0,0 +1,50 @@
1
+ import config from "./config"
2
+ import {digg} from "diggerize"
3
+ import * as inflection from "inflection"
4
+ import useBreakpoint from "./use-breakpoint"
5
+ import {useMemo} from "react"
6
+
7
+ const useStyles = (styles, args, dependencies = []) => {
8
+ const breakpoint = useBreakpoint()
9
+ const breakpointName = digg(breakpoint, "name")
10
+ const actualDependencies = [...dependencies, breakpointName]
11
+
12
+ const listOfStyles = useMemo(() => {
13
+ const listOfStyles = []
14
+ const breakpointsReverse = [...config.getBreakPoints()].reverse()
15
+
16
+ for (const arg of args) {
17
+ if (typeof arg == "string") {
18
+ if (!(arg in styles)) {
19
+ throw new Error(`No such styling '${arg}' in given styles: ${Object.keys(styles).join(", ")}`)
20
+ }
21
+
22
+ listOfStyles.push(styles[arg])
23
+
24
+ for (const breakpointData of breakpointsReverse) {
25
+ const breakpointName = breakpointData[0]
26
+ const breakpointStyleNameUp = `${arg}${inflection.camelize(breakpointName)}Up`
27
+ const breakpointStyleNameDown = `${arg}${inflection.camelize(breakpointName)}Down`
28
+ const breakpointIsUp = digg(breakpoint, `${breakpointName}Up`)
29
+ const breakpointIsDown = digg(breakpoint, `${breakpointName}Down`)
30
+
31
+ if (breakpointStyleNameUp in styles && breakpointIsUp) {
32
+ listOfStyles.push(styles[breakpointStyleNameUp])
33
+ }
34
+
35
+ if (breakpointStyleNameDown in styles && breakpointIsDown) {
36
+ listOfStyles.push(styles[breakpointStyleNameDown])
37
+ }
38
+ }
39
+ } else {
40
+ throw new Error(`Unhandled type: ${typeof arg}`)
41
+ }
42
+ }
43
+
44
+ return listOfStyles
45
+ }, actualDependencies)
46
+
47
+ return listOfStyles
48
+ }
49
+
50
+ export default useStyles
@@ -0,0 +1,60 @@
1
+ import {useCallback, useLayoutEffect, useMemo} from "react"
2
+ import debounceFunction from "debounce"
3
+ import ModelEvents from "./model-events"
4
+ import useShape from "set-state-compare/src/use-shape"
5
+
6
+ const apiMakerUseUpdatedEvent = (model, onUpdated, props = {}) => {
7
+ const {active = true, debounce, onConnected, ...restProps} = props
8
+
9
+ if (Object.keys(restProps).length > 0) {
10
+ throw new Error(`Unknown props given to useUpdatedEvent: ${Object.keys(restProps).join(", ")}`)
11
+ }
12
+
13
+ const s = useShape({active, debounce, model, onUpdated})
14
+
15
+ const debounceCallback = useMemo(() => {
16
+ if (typeof debounce == "number") {
17
+ return debounceFunction(s.p.onUpdated, debounce)
18
+ } else {
19
+ return debounceFunction(s.p.onUpdated)
20
+ }
21
+ }, [debounce])
22
+
23
+ s.updateMeta({debounceCallback})
24
+
25
+ const onUpdatedCallback = useCallback((...args) => {
26
+ if (!s.p.active) {
27
+ return
28
+ }
29
+
30
+ if (s.p.debounce) {
31
+ s.m.debounceCallback(...args)
32
+ } else {
33
+ s.p.onUpdated(...args)
34
+ }
35
+ }, [])
36
+
37
+ useLayoutEffect(() => {
38
+ let connectUpdated, onConnectedListener
39
+
40
+ if (model) {
41
+ connectUpdated = ModelEvents.connectUpdated(model, onUpdatedCallback)
42
+
43
+ if (onConnected) {
44
+ onConnectedListener = connectUpdated.events.addListener("connected", onConnected)
45
+ }
46
+ }
47
+
48
+ return () => {
49
+ if (onConnectedListener) {
50
+ connectUpdated.events.removeListener("connected", onConnected)
51
+ }
52
+
53
+ if (connectUpdated) {
54
+ connectUpdated.unsubscribe()
55
+ }
56
+ }
57
+ }, [model?.id()])
58
+ }
59
+
60
+ export default apiMakerUseUpdatedEvent
@@ -0,0 +1,33 @@
1
+ import events from "./events"
2
+ import {useCallback} from "react"
3
+ import useEventEmitter from "./use-event-emitter"
4
+ import useShape from "set-state-compare/src/use-shape"
5
+
6
+ const useValidationErrors = (callback) => {
7
+ const s = useShape({callback})
8
+
9
+ s.useStates({validationErrors: []})
10
+
11
+ const onValidationErrors = useCallback((validationErrors) => {
12
+ const matchedValidationErrors = []
13
+
14
+ for (const validationError of validationErrors.getValidationErrors()) {
15
+ if (s.p.callback(validationError)) {
16
+ validationError.setHandled()
17
+ matchedValidationErrors.push(validationError)
18
+ }
19
+ }
20
+
21
+ s.set({
22
+ validationErrors: matchedValidationErrors
23
+ })
24
+ }, [])
25
+
26
+ useEventEmitter(events, "onValidationErrors", onValidationErrors)
27
+
28
+ return {
29
+ validationErrors: s.s.validationErrors
30
+ }
31
+ }
32
+
33
+ export default useValidationErrors
@@ -0,0 +1,49 @@
1
+ import BaseComponent from "../base-component"
2
+ import memo from "set-state-compare/src/memo"
3
+ import PropTypes from "prop-types"
4
+ import propTypesExact from "prop-types-exact"
5
+ import {shapeComponent} from "set-state-compare/src/shape-component"
6
+ import Text from "./text"
7
+
8
+ export default memo(shapeComponent(class ApiMakerUtilsCard extends BaseComponent {
9
+ static propTypes = propTypesExact({
10
+ children: PropTypes.node,
11
+ controls: PropTypes.node,
12
+ dataSet: PropTypes.object,
13
+ header: PropTypes.string,
14
+ style: PropTypes.object
15
+ })
16
+
17
+ render() {
18
+ const {children, controls, dataSet, header, style} = this.props
19
+ const {component, ...restDataSet} = dataSet || {}
20
+ const actualDataSet = Object.assign(
21
+ {component: classNames("api-maker/utils/card", component)},
22
+ restDataSet
23
+ )
24
+ const actualStyle = Object.assign(
25
+ {
26
+ backgroundColor: "#fff",
27
+ borderRadius: 15,
28
+ padding: 30
29
+ },
30
+ style
31
+ )
32
+
33
+ return (
34
+ <View dataSet={actualDataSet} style={actualStyle}>
35
+ {controls &&
36
+ <View style={{position: "absolute", top: 15, right: 15}}>
37
+ {controls}
38
+ </View>
39
+ }
40
+ {header &&
41
+ <Text style={{fontSize: 24}}>
42
+ {header}
43
+ </Text>
44
+ }
45
+ {children}
46
+ </View>
47
+ )
48
+ }
49
+ }))