alchemy_cms 7.4.16 → 8.0.0.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 (364) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +87 -77
  3. data/Gemfile +13 -7
  4. data/README.md +13 -5
  5. data/alchemy_cms.gemspec +14 -5
  6. data/app/assets/builds/alchemy/admin/page-select.css +1 -1
  7. data/app/assets/builds/alchemy/admin/print.css +1 -1
  8. data/app/assets/builds/alchemy/admin.css +2 -2
  9. data/app/assets/builds/alchemy/custom-properties.css +1 -1
  10. data/app/assets/builds/alchemy/welcome.css +1 -1
  11. data/app/assets/builds/tinymce/skins/content/alchemy/content.min.css +1 -1
  12. data/app/assets/builds/tinymce/skins/ui/alchemy/content.min.css +1 -0
  13. data/app/assets/builds/tinymce/skins/ui/alchemy/skin.min.css +1 -1
  14. data/app/assets/config/alchemy_manifest.js +0 -2
  15. data/app/assets/images/alchemy/icons-sprite.svg +1 -0
  16. data/app/components/alchemy/admin/resource/applied_filter.rb +29 -0
  17. data/app/components/alchemy/admin/resource/checkbox_filter.rb +36 -0
  18. data/app/components/alchemy/admin/resource/datepicker_filter.rb +42 -0
  19. data/app/components/alchemy/admin/resource/select_filter.rb +43 -0
  20. data/app/components/alchemy/admin/toolbar_button.rb +6 -3
  21. data/app/components/alchemy/ingredients/datetime_view.rb +2 -4
  22. data/app/components/alchemy/ingredients/number_view.rb +18 -0
  23. data/app/controllers/alchemy/admin/attachments_controller.rb +8 -15
  24. data/app/controllers/alchemy/admin/clipboard_controller.rb +2 -6
  25. data/app/controllers/alchemy/admin/elements_controller.rb +1 -1
  26. data/app/controllers/alchemy/admin/languages_controller.rb +1 -4
  27. data/app/controllers/alchemy/admin/pages_controller.rb +15 -17
  28. data/app/controllers/alchemy/admin/pictures_controller.rb +9 -5
  29. data/app/controllers/alchemy/admin/resources_controller.rb +16 -106
  30. data/app/controllers/alchemy/api/nodes_controller.rb +1 -1
  31. data/app/controllers/alchemy/api/pages_controller.rb +0 -2
  32. data/app/controllers/alchemy/attachments_controller.rb +43 -14
  33. data/app/controllers/alchemy/messages_controller.rb +1 -1
  34. data/app/controllers/alchemy/pages_controller.rb +7 -2
  35. data/app/controllers/concerns/alchemy/admin/resource_filter.rb +92 -0
  36. data/app/decorators/alchemy/element_editor.rb +5 -48
  37. data/app/decorators/alchemy/ingredient_editor.rb +4 -62
  38. data/app/helpers/alchemy/admin/base_helper.rb +14 -84
  39. data/app/helpers/alchemy/admin/elements_helper.rb +4 -4
  40. data/app/helpers/alchemy/admin/pages_helper.rb +1 -1
  41. data/app/helpers/alchemy/base_helper.rb +0 -30
  42. data/app/helpers/alchemy/elements_block_helper.rb +0 -14
  43. data/app/helpers/alchemy/pages_helper.rb +2 -2
  44. data/{lib → app/helpers}/alchemy/resources_helper.rb +6 -46
  45. data/app/javascript/alchemy_admin/components/action.js +2 -0
  46. data/app/javascript/alchemy_admin/components/alchemy_html_element.js +3 -3
  47. data/app/javascript/alchemy_admin/components/datepicker.js +10 -2
  48. data/app/javascript/alchemy_admin/components/element_editor/delete_element_button.js +7 -7
  49. data/app/javascript/alchemy_admin/components/element_editor.js +1 -1
  50. data/app/javascript/alchemy_admin/components/index.js +1 -3
  51. data/app/javascript/alchemy_admin/components/remote_select.js +4 -1
  52. data/app/javascript/alchemy_admin/components/tags_autocomplete.js +5 -1
  53. data/app/javascript/alchemy_admin/components/tinymce.js +4 -2
  54. data/app/javascript/alchemy_admin/components/update_check.js +42 -0
  55. data/app/javascript/alchemy_admin/components/uploader/file_upload.js +15 -8
  56. data/app/javascript/alchemy_admin/components/uploader/progress.js +12 -6
  57. data/app/javascript/alchemy_admin/components/uploader.js +4 -2
  58. data/app/javascript/alchemy_admin/confirm_dialog.js +27 -57
  59. data/app/javascript/alchemy_admin/dirty.js +3 -2
  60. data/app/javascript/alchemy_admin/i18n.js +15 -16
  61. data/app/javascript/alchemy_admin/initializer.js +1 -49
  62. data/app/javascript/alchemy_admin/link_dialog.js +1 -6
  63. data/app/javascript/alchemy_admin/utils/ajax.js +51 -44
  64. data/app/javascript/alchemy_admin.js +3 -8
  65. data/app/models/alchemy/admin/filters/base.rb +38 -0
  66. data/app/models/alchemy/admin/filters/checkbox.rb +24 -0
  67. data/app/models/alchemy/admin/filters/datepicker.rb +53 -0
  68. data/app/models/alchemy/admin/filters/select.rb +70 -0
  69. data/app/models/alchemy/admin/resource_name.rb +27 -0
  70. data/app/models/alchemy/attachment.rb +49 -37
  71. data/app/models/alchemy/base_record.rb +2 -0
  72. data/app/models/alchemy/element/definitions.rb +1 -1
  73. data/app/models/alchemy/element/element_ingredients.rb +6 -6
  74. data/app/models/alchemy/element/presenters.rb +3 -12
  75. data/app/models/alchemy/element.rb +9 -27
  76. data/app/models/alchemy/element_definition.rb +160 -0
  77. data/app/models/alchemy/ingredient.rb +11 -44
  78. data/app/models/alchemy/ingredient_definition.rb +134 -0
  79. data/app/models/alchemy/ingredient_validator.rb +7 -3
  80. data/app/models/alchemy/ingredients/number.rb +19 -0
  81. data/app/models/alchemy/language/code.rb +0 -1
  82. data/app/models/alchemy/language.rb +0 -14
  83. data/app/models/alchemy/message.rb +3 -7
  84. data/app/models/alchemy/node.rb +1 -22
  85. data/app/models/alchemy/page/{page_layouts.rb → definitions.rb} +12 -19
  86. data/app/models/alchemy/page/fixed_attributes.rb +1 -1
  87. data/app/models/alchemy/page/page_elements.rb +13 -14
  88. data/app/models/alchemy/page/page_naming.rb +0 -1
  89. data/app/models/alchemy/page/page_natures.rb +7 -7
  90. data/app/models/alchemy/page/page_scopes.rb +1 -1
  91. data/app/models/alchemy/page.rb +11 -33
  92. data/app/models/alchemy/page_definition.rb +115 -0
  93. data/app/models/alchemy/picture.rb +71 -88
  94. data/app/models/alchemy/picture_variant.rb +115 -5
  95. data/{lib → app/models}/alchemy/resource.rb +4 -18
  96. data/{lib → app/models}/alchemy/searchable_resource.rb +15 -0
  97. data/app/models/alchemy/site/layout.rb +5 -6
  98. data/app/models/alchemy/site.rb +0 -15
  99. data/app/models/alchemy/storage_adapter/active_storage/attachment_url.rb +41 -0
  100. data/app/models/alchemy/storage_adapter/active_storage/picture_url.rb +55 -0
  101. data/app/models/alchemy/storage_adapter/active_storage/preprocessor.rb +40 -0
  102. data/app/models/alchemy/storage_adapter/active_storage.rb +173 -0
  103. data/app/models/alchemy/{attachment/url.rb → storage_adapter/dragonfly/attachment_url.rb} +12 -12
  104. data/app/models/alchemy/{picture/url.rb → storage_adapter/dragonfly/picture_url.rb} +28 -12
  105. data/app/models/alchemy/{picture → storage_adapter/dragonfly}/preprocessor.rb +4 -4
  106. data/app/models/alchemy/storage_adapter/dragonfly.rb +183 -0
  107. data/app/models/alchemy/storage_adapter.rb +74 -0
  108. data/app/models/concerns/alchemy/picture_thumbnails.rb +19 -6
  109. data/app/serializers/alchemy/element_serializer.rb +0 -1
  110. data/app/serializers/alchemy/page_tree_serializer.rb +1 -17
  111. data/app/services/alchemy/dragonfly_to_image_processing.rb +100 -0
  112. data/app/stylesheets/alchemy/_defaults.scss +3 -0
  113. data/app/stylesheets/alchemy/_extends.scss +69 -0
  114. data/app/{assets/stylesheets → stylesheets}/alchemy/_mixins.scss +33 -49
  115. data/app/stylesheets/alchemy/_variables.scss +5 -0
  116. data/app/{assets/stylesheets → stylesheets}/alchemy/admin/archive.scss +20 -37
  117. data/app/{assets/stylesheets → stylesheets}/alchemy/admin/base.scss +16 -14
  118. data/app/stylesheets/alchemy/admin/buttons.scss +160 -0
  119. data/app/{assets/stylesheets → stylesheets}/alchemy/admin/clipboard.scss +2 -2
  120. data/app/{assets/stylesheets → stylesheets}/alchemy/admin/dashboard.scss +13 -16
  121. data/app/{assets/stylesheets → stylesheets}/alchemy/admin/dialogs.scss +23 -16
  122. data/app/{assets/stylesheets → stylesheets}/alchemy/admin/elements.scss +150 -105
  123. data/app/{assets/stylesheets → stylesheets}/alchemy/admin/errors.scss +5 -5
  124. data/app/stylesheets/alchemy/admin/filters.scss +58 -0
  125. data/app/{assets/stylesheets → stylesheets}/alchemy/admin/flatpickr.scss +53 -60
  126. data/app/{assets/stylesheets → stylesheets}/alchemy/admin/form_fields.scss +21 -7
  127. data/app/{assets/stylesheets → stylesheets}/alchemy/admin/forms.scss +31 -19
  128. data/app/{assets/stylesheets → stylesheets}/alchemy/admin/frame.scss +20 -16
  129. data/app/stylesheets/alchemy/admin/hints.scss +5 -0
  130. data/app/{assets/stylesheets → stylesheets}/alchemy/admin/icons.scss +10 -1
  131. data/app/{assets/stylesheets → stylesheets}/alchemy/admin/image_library.scss +10 -8
  132. data/app/{assets/stylesheets → stylesheets}/alchemy/admin/images.scss +1 -1
  133. data/app/stylesheets/alchemy/admin/labels.scss +5 -0
  134. data/app/{assets/stylesheets → stylesheets}/alchemy/admin/lists.scss +3 -3
  135. data/app/{assets/stylesheets → stylesheets}/alchemy/admin/navigation.scss +61 -55
  136. data/app/{assets/stylesheets → stylesheets}/alchemy/admin/nodes.scss +21 -18
  137. data/app/{assets/stylesheets → stylesheets}/alchemy/admin/notices.scss +18 -18
  138. data/app/{assets/stylesheets → stylesheets}/alchemy/admin/page-select.scss +2 -2
  139. data/app/stylesheets/alchemy/admin/pagination.scss +144 -0
  140. data/app/{assets/stylesheets → stylesheets}/alchemy/admin/preview_window.scss +8 -6
  141. data/app/{assets/stylesheets → stylesheets}/alchemy/admin/print.scss +1 -1
  142. data/app/{assets/stylesheets → stylesheets}/alchemy/admin/resource_info.scss +8 -5
  143. data/app/{assets/stylesheets → stylesheets}/alchemy/admin/search.scss +9 -6
  144. data/app/{assets/stylesheets → stylesheets}/alchemy/admin/selects.scss +49 -37
  145. data/app/{assets/stylesheets → stylesheets}/alchemy/admin/shoelace.scss +5 -6
  146. data/app/{assets/stylesheets → stylesheets}/alchemy/admin/sitemap.scss +38 -33
  147. data/app/{assets/stylesheets → stylesheets}/alchemy/admin/tables.scss +6 -4
  148. data/app/{assets/stylesheets → stylesheets}/alchemy/admin/tags.scss +6 -4
  149. data/app/{assets/stylesheets → stylesheets}/alchemy/admin/toolbar.scss +12 -6
  150. data/app/{assets/stylesheets → stylesheets}/alchemy/admin/typography.scss +2 -2
  151. data/app/{assets/stylesheets → stylesheets}/alchemy/admin/upload.scss +7 -5
  152. data/app/stylesheets/alchemy/admin.scss +44 -0
  153. data/app/stylesheets/alchemy/custom-properties.css +244 -0
  154. data/app/stylesheets/alchemy/welcome.scss +75 -0
  155. data/app/{assets/stylesheets → stylesheets}/tinymce/skins/content/alchemy/content.scss +8 -9
  156. data/app/stylesheets/tinymce/skins/ui/alchemy/content.scss +1 -0
  157. data/app/{assets/stylesheets → stylesheets}/tinymce/skins/ui/alchemy/skin.scss +133 -136
  158. data/app/views/alchemy/admin/attachments/_files_list.html.erb +2 -2
  159. data/app/views/alchemy/admin/attachments/_overlay_file_list.html.erb +1 -1
  160. data/app/views/alchemy/admin/{elements/_clipboard_button.html.erb → clipboard/_button.html.erb} +3 -5
  161. data/app/views/alchemy/admin/clipboard/_update_nested_element_button.turbo_stream.erb +11 -0
  162. data/app/views/alchemy/admin/clipboard/clear.turbo_stream.erb +4 -0
  163. data/app/views/alchemy/admin/clipboard/index.html.erb +15 -13
  164. data/app/views/alchemy/admin/clipboard/insert.turbo_stream.erb +18 -0
  165. data/app/views/alchemy/admin/clipboard/remove.turbo_stream.erb +9 -0
  166. data/app/views/alchemy/admin/dashboard/info.html.erb +17 -31
  167. data/app/views/alchemy/admin/elements/_element.html.erb +4 -8
  168. data/app/views/alchemy/admin/elements/_form.html.erb +1 -1
  169. data/app/views/alchemy/admin/elements/_header.html.erb +1 -0
  170. data/app/views/alchemy/admin/elements/_toolbar.html.erb +4 -6
  171. data/app/views/alchemy/admin/elements/create.turbo_stream.erb +2 -1
  172. data/app/views/alchemy/admin/elements/index.html.erb +2 -2
  173. data/app/views/alchemy/admin/ingredients/_file_fields.html.erb +3 -16
  174. data/app/views/alchemy/admin/ingredients/_picture_fields.html.erb +1 -10
  175. data/app/views/alchemy/admin/languages/_form.html.erb +1 -1
  176. data/app/views/alchemy/admin/languages/_table.html.erb +1 -1
  177. data/app/views/alchemy/admin/languages/index.html.erb +5 -2
  178. data/app/views/alchemy/admin/layoutpages/index.html.erb +1 -12
  179. data/app/views/alchemy/admin/pages/_form.html.erb +2 -2
  180. data/app/views/alchemy/admin/pages/_page.html.erb +2 -3
  181. data/app/views/alchemy/admin/pages/_toolbar.html.erb +1 -15
  182. data/app/views/alchemy/admin/pages/index.html.erb +1 -1
  183. data/app/views/alchemy/admin/pages/info.html.erb +1 -1
  184. data/app/views/alchemy/admin/partials/_remote_search_form.html.erb +9 -12
  185. data/app/views/alchemy/admin/partials/_search_form.html.erb +4 -10
  186. data/app/views/alchemy/admin/pictures/_archive.html.erb +4 -7
  187. data/app/views/alchemy/admin/pictures/_archive_overlay.html.erb +2 -1
  188. data/app/views/alchemy/admin/pictures/_filter_and_size_bar.html.erb +1 -1
  189. data/app/views/alchemy/admin/pictures/_form.html.erb +1 -1
  190. data/app/views/alchemy/admin/pictures/index.html.erb +2 -7
  191. data/app/views/alchemy/admin/resources/_applied_filters.html.erb +8 -0
  192. data/app/views/alchemy/admin/resources/_filter_bar.html.erb +11 -21
  193. data/app/views/alchemy/admin/resources/_pagination.html.erb +6 -0
  194. data/app/views/alchemy/admin/resources/_per_page_select.html.erb +4 -2
  195. data/app/views/alchemy/admin/resources/_resource_table.html.erb +1 -1
  196. data/app/views/alchemy/admin/resources/_table_header.html.erb +1 -15
  197. data/app/views/alchemy/admin/sites/index.html.erb +5 -1
  198. data/app/views/alchemy/admin/styleguide/index.html.erb +8 -0
  199. data/app/views/alchemy/admin/tags/index.html.erb +1 -1
  200. data/app/views/alchemy/admin/tinymce/_setup.html.erb +7 -7
  201. data/app/{javascript/alchemy_admin/locales/en.js → views/alchemy/admin/translations/_en.js} +5 -2
  202. data/app/views/alchemy/admin/uploader/_button.html.erb +1 -1
  203. data/app/views/alchemy/admin/uploader/_setup.html.erb +4 -4
  204. data/app/views/alchemy/ingredients/_number_editor.html.erb +24 -0
  205. data/app/views/alchemy/ingredients/_page_editor.html.erb +1 -0
  206. data/app/views/alchemy/ingredients/_richtext_editor.html.erb +1 -0
  207. data/app/views/alchemy/ingredients/_select_editor.html.erb +2 -1
  208. data/app/views/alchemy/no_index.html.erb +31 -0
  209. data/app/views/alchemy/welcome.html.erb +12 -10
  210. data/app/views/kaminari/alchemy/_first_page.html.erb +5 -3
  211. data/app/views/kaminari/alchemy/_last_page.html.erb +5 -3
  212. data/app/views/kaminari/alchemy/_next_page.html.erb +5 -3
  213. data/app/views/kaminari/alchemy/_paginator.html.erb +18 -13
  214. data/app/views/kaminari/alchemy/_prev_page.html.erb +5 -3
  215. data/app/views/layouts/alchemy/admin.html.erb +5 -9
  216. data/bun.lockb +0 -0
  217. data/bundles/remixicon.mjs +153 -0
  218. data/config/alchemy/config.yml +3 -2
  219. data/config/initializers/dragonfly.rb +0 -1
  220. data/config/initializers/mime_types.rb +1 -0
  221. data/config/locales/alchemy.en.yml +32 -14
  222. data/config/routes.rb +0 -2
  223. data/eslint.config.js +2 -1
  224. data/lib/alchemy/admin/preview_url.rb +4 -5
  225. data/lib/alchemy/cache_digests/template_tracker.rb +6 -9
  226. data/lib/alchemy/config_missing.rb +14 -0
  227. data/lib/alchemy/configuration/base_option.rb +24 -0
  228. data/lib/alchemy/configuration/boolean_option.rb +16 -0
  229. data/lib/alchemy/configuration/class_option.rb +15 -0
  230. data/lib/alchemy/configuration/class_set_option.rb +46 -0
  231. data/lib/alchemy/configuration/integer_list_option.rb +13 -0
  232. data/lib/alchemy/configuration/integer_option.rb +12 -0
  233. data/lib/alchemy/configuration/list_option.rb +22 -0
  234. data/lib/alchemy/configuration/regexp_option.rb +11 -0
  235. data/lib/alchemy/configuration/string_list_option.rb +13 -0
  236. data/lib/alchemy/configuration/string_option.rb +11 -0
  237. data/lib/alchemy/configuration.rb +115 -0
  238. data/lib/alchemy/configuration_methods.rb +3 -1
  239. data/lib/alchemy/configurations/default_language.rb +12 -0
  240. data/lib/alchemy/configurations/default_site.rb +10 -0
  241. data/lib/alchemy/configurations/format_matchers.rb +11 -0
  242. data/lib/alchemy/configurations/mailer.rb +16 -0
  243. data/lib/alchemy/configurations/main.rb +216 -0
  244. data/lib/alchemy/configurations/preview.rb +32 -0
  245. data/lib/alchemy/configurations/sitemap.rb +10 -0
  246. data/lib/alchemy/configurations/uploader.rb +34 -0
  247. data/lib/alchemy/controller_actions.rb +1 -2
  248. data/lib/alchemy/engine.rb +65 -17
  249. data/lib/alchemy/hints.rb +3 -7
  250. data/lib/alchemy/name_conversions.rb +0 -6
  251. data/lib/alchemy/on_page_layout.rb +2 -2
  252. data/lib/alchemy/permissions.rb +0 -10
  253. data/lib/alchemy/propshaft/tinymce_asset.rb +15 -0
  254. data/lib/alchemy/seeder.rb +6 -12
  255. data/lib/alchemy/tasks/usage.rb +4 -4
  256. data/lib/alchemy/test_support/config_stubbing.rb +1 -7
  257. data/lib/alchemy/test_support/factories/attachment_factory.rb +13 -2
  258. data/lib/alchemy/test_support/factories/language_factory.rb +5 -9
  259. data/lib/alchemy/test_support/factories/page_factory.rb +2 -4
  260. data/lib/alchemy/test_support/factories/picture_factory.rb +30 -2
  261. data/lib/alchemy/test_support/factories/site_factory.rb +2 -2
  262. data/lib/alchemy/test_support/having_crop_action_examples.rb +2 -2
  263. data/lib/alchemy/test_support/having_picture_thumbnails_examples.rb +80 -26
  264. data/lib/alchemy/test_support/shared_ingredient_examples.rb +5 -5
  265. data/lib/alchemy/upgrader/.keep +0 -0
  266. data/lib/alchemy/upgrader/eight_zero.rb +14 -0
  267. data/lib/alchemy/upgrader.rb +33 -20
  268. data/lib/alchemy/version.rb +1 -1
  269. data/lib/alchemy.rb +192 -170
  270. data/lib/alchemy_cms.rb +1 -7
  271. data/lib/generators/alchemy/ingredient/ingredient_generator.rb +0 -3
  272. data/lib/generators/alchemy/install/files/_article.html.erb +6 -4
  273. data/lib/generators/alchemy/install/files/alchemy.en.yml +22 -3
  274. data/lib/generators/alchemy/install/files/application.html.erb +5 -0
  275. data/lib/generators/alchemy/install/install_generator.rb +5 -14
  276. data/lib/generators/alchemy/install/templates/alchemy.rb.tt +196 -0
  277. data/lib/generators/alchemy/install/templates/dragonfly.rb.tt +0 -1
  278. data/lib/generators/alchemy/install/templates/elements.yml.tt +3 -1
  279. data/lib/generators/alchemy/install/templates/menus.yml.tt +1 -1
  280. data/lib/generators/alchemy/install/templates/page_layouts.yml.tt +2 -2
  281. data/lib/generators/alchemy/page_layouts/page_layouts_generator.rb +2 -2
  282. data/lib/tasks/alchemy/assets.rake +14 -0
  283. data/lib/tasks/alchemy/upgrade.rake +12 -47
  284. data/lib/tasks/alchemy/usage.rake +0 -2
  285. data/vendor/javascript/tinymce.min.js +1 -1
  286. data/vitest.config.js +21 -0
  287. metadata +184 -183
  288. data/app/assets/builds/alchemy/admin/page-select.css.map +0 -1
  289. data/app/assets/builds/alchemy/admin/print.css.map +0 -1
  290. data/app/assets/builds/alchemy/admin.css.map +0 -1
  291. data/app/assets/builds/alchemy/custom-properties.css.map +0 -1
  292. data/app/assets/builds/alchemy/welcome.css.map +0 -1
  293. data/app/assets/builds/tinymce/skins/content/alchemy/content.min.css.map +0 -1
  294. data/app/assets/builds/tinymce/skins/ui/alchemy/skin.min.css.map +0 -1
  295. data/app/assets/javascripts/alchemy/admin.js +0 -10
  296. data/app/assets/stylesheets/alchemy/_defaults.scss +0 -3
  297. data/app/assets/stylesheets/alchemy/_deprecated_variables.scss +0 -45
  298. data/app/assets/stylesheets/alchemy/_deprecation.scss +0 -17
  299. data/app/assets/stylesheets/alchemy/_extends.scss +0 -62
  300. data/app/assets/stylesheets/alchemy/_variables.scss +0 -201
  301. data/app/assets/stylesheets/alchemy/admin/buttons.scss +0 -123
  302. data/app/assets/stylesheets/alchemy/admin/hints.scss +0 -5
  303. data/app/assets/stylesheets/alchemy/admin/labels.scss +0 -3
  304. data/app/assets/stylesheets/alchemy/admin/pagination.scss +0 -92
  305. data/app/assets/stylesheets/alchemy/admin.scss +0 -42
  306. data/app/assets/stylesheets/alchemy/custom-properties.css +0 -98
  307. data/app/assets/stylesheets/alchemy/welcome.scss +0 -57
  308. data/app/assets/stylesheets/tinymce/skins/ui/alchemy/content.css +0 -711
  309. data/app/assets/stylesheets/tinymce/skins/ui/alchemy/content.inline.css +0 -705
  310. data/app/assets/stylesheets/tinymce/skins/ui/alchemy/content.inline.min.css +0 -7
  311. data/app/assets/stylesheets/tinymce/skins/ui/alchemy/content.min.css +0 -7
  312. data/app/assets/stylesheets/tinymce/skins/ui/alchemy/content.mobile.css +0 -29
  313. data/app/assets/stylesheets/tinymce/skins/ui/alchemy/content.mobile.min.css +0 -7
  314. data/app/assets/stylesheets/tinymce/skins/ui/alchemy/skin.mobile.css +0 -677
  315. data/app/assets/stylesheets/tinymce/skins/ui/alchemy/skin.mobile.min.css +0 -7
  316. data/app/controllers/alchemy/elements_controller.rb +0 -32
  317. data/app/models/alchemy/element/dom_id.rb +0 -31
  318. data/app/models/alchemy/picture/calculations.rb +0 -49
  319. data/app/models/alchemy/picture/transformations.rb +0 -115
  320. data/app/views/alchemy/admin/attachments/destroy.js.erb +0 -1
  321. data/app/views/alchemy/admin/clipboard/clear.js.erb +0 -3
  322. data/app/views/alchemy/admin/clipboard/insert.js.erb +0 -29
  323. data/app/views/alchemy/admin/clipboard/remove.js.erb +0 -10
  324. data/app/views/alchemy/admin/resources/_filter.html.erb +0 -12
  325. data/app/views/alchemy/admin/resources/_resource.html.erb +0 -34
  326. data/app/views/alchemy/admin/resources/_table.html.erb +0 -29
  327. data/app/views/alchemy/elements/show.html.erb +0 -1
  328. data/app/views/alchemy/elements/show.js.erb +0 -1
  329. data/app/views/alchemy/ingredients/_audio_view.html.erb +0 -1
  330. data/app/views/alchemy/ingredients/_boolean_view.html.erb +0 -1
  331. data/app/views/alchemy/ingredients/_datetime_view.html.erb +0 -3
  332. data/app/views/alchemy/ingredients/_file_view.html.erb +0 -4
  333. data/app/views/alchemy/ingredients/_headline_view.html.erb +0 -4
  334. data/app/views/alchemy/ingredients/_html_view.html.erb +0 -1
  335. data/app/views/alchemy/ingredients/_link_view.html.erb +0 -4
  336. data/app/views/alchemy/ingredients/_node_view.html.erb +0 -1
  337. data/app/views/alchemy/ingredients/_page_view.html.erb +0 -1
  338. data/app/views/alchemy/ingredients/_picture_view.html.erb +0 -4
  339. data/app/views/alchemy/ingredients/_richtext_view.html.erb +0 -3
  340. data/app/views/alchemy/ingredients/_select_view.html.erb +0 -1
  341. data/app/views/alchemy/ingredients/_text_view.html.erb +0 -4
  342. data/app/views/alchemy/ingredients/_video_view.html.erb +0 -3
  343. data/babel.config.js +0 -12
  344. data/config/initializers/assets.rb +0 -4
  345. data/lib/alchemy/config.rb +0 -114
  346. data/lib/alchemy/element_definition.rb +0 -73
  347. data/lib/alchemy/page_layout.rb +0 -73
  348. data/lib/alchemy/resource_filter.rb +0 -40
  349. data/lib/alchemy/upgrader/seven_point_four.rb +0 -26
  350. data/lib/alchemy/upgrader/seven_point_three.rb +0 -52
  351. data/lib/generators/alchemy/ingredient/templates/view.html.erb +0 -1
  352. data/lib/generators/alchemy/install/files/alchemy_admin.js +0 -1
  353. data/lib/generators/alchemy/install/files/all.js +0 -11
  354. data/lib/generators/alchemy/install/files/article.css +0 -25
  355. data/vendor/assets/images/remixicon.symbol.svg +0 -11
  356. /data/app/{assets/stylesheets → stylesheets}/alchemy/_fonts.scss +0 -0
  357. /data/app/{assets/stylesheets → stylesheets}/alchemy/admin/attachment-select.scss +0 -0
  358. /data/app/{assets/stylesheets → stylesheets}/alchemy/admin/attachments.scss +0 -0
  359. /data/app/{assets/stylesheets → stylesheets}/alchemy/admin/flash.scss +0 -0
  360. /data/app/{assets/stylesheets → stylesheets}/alchemy/admin/list_filter.scss +0 -0
  361. /data/app/{assets/stylesheets → stylesheets}/alchemy/admin/node-select.scss +0 -0
  362. /data/app/{assets/stylesheets → stylesheets}/alchemy/admin/spinner.scss +0 -0
  363. /data/app/{assets/stylesheets → stylesheets}/tinymce/skins/skintool.json +0 -0
  364. /data/app/{assets/stylesheets → stylesheets}/tinymce/skins/ui/alchemy/fonts/tinymce-mobile.woff +0 -0
@@ -44,11 +44,6 @@ module Alchemy
44
44
  can :read, Alchemy::Page, Alchemy::Page.published.not_restricted.from_current_site do |p|
45
45
  p.public? && !p.restricted? && p.site == Alchemy::Current.site
46
46
  end
47
-
48
- can :read, Alchemy::Node, Alchemy::Node.available_to_guests do |node|
49
- node.language.public? && node.language.site_id == Alchemy::Current.site&.id &&
50
- (node.page.nil? || (node.page.public? && !node.page.restricted?))
51
- end
52
47
  end
53
48
  end
54
49
 
@@ -72,11 +67,6 @@ module Alchemy
72
67
  can :read, Alchemy::Page, Alchemy::Page.published.from_current_site do |p|
73
68
  p.public? && p.site == Alchemy::Current.site
74
69
  end
75
-
76
- can :read, Alchemy::Node, Alchemy::Node.available_to_members do |node|
77
- node.language.public? && node.language.site_id == Alchemy::Current.site&.id &&
78
- (node.page.nil? || node.page.public?)
79
- end
80
70
  end
81
71
  end
82
72
 
@@ -0,0 +1,15 @@
1
+ require "propshaft/asset"
2
+
3
+ module Alchemy
4
+ module Propshaft
5
+ module TinymceAsset
6
+ # Allow TinyMCE assets to be accessed (in development mode) without a digest
7
+ def fresh?(digest)
8
+ super ||
9
+ (digest.blank? && logical_path.to_s.starts_with?("tinymce/"))
10
+ end
11
+ end
12
+ end
13
+ end
14
+
15
+ Propshaft::Asset.prepend Alchemy::Propshaft::TinymceAsset
@@ -68,7 +68,7 @@ module Alchemy
68
68
  "Please use `rake db:reset' if you want to rebuild your database.", :skip
69
69
  false
70
70
  else
71
- users = load_yaml_file(user_seeds_file)
71
+ users = YAML.load_file(user_seeds_file)
72
72
  users.each do |draft|
73
73
  user = Alchemy.user_class.create!(draft)
74
74
  log "Created user: #{user.try(:email) || user.try(:login) || user.id}"
@@ -83,15 +83,9 @@ module Alchemy
83
83
  end
84
84
 
85
85
  def page_yml
86
- @_page_yml ||= load_yaml_file(
87
- page_seeds_file
88
- )
89
- end
90
-
91
- def load_yaml_file(file)
92
- YAML.safe_load_file(
93
- file,
94
- permitted_classes: [Date, Symbol],
86
+ @_page_yml ||= YAML.safe_load(
87
+ page_seeds_file.read,
88
+ permitted_classes: [Date],
95
89
  aliases: true
96
90
  )
97
91
  end
@@ -122,7 +116,7 @@ module Alchemy
122
116
  # If no languages are present, create a default language based
123
117
  # on the host app's Alchemy configuration.
124
118
  def create_default_language!
125
- default_language = Alchemy::Config.get(:default_language)
119
+ default_language = Alchemy.config.default_language
126
120
  if default_language
127
121
  Alchemy::Language.create!(
128
122
  name: default_language["name"],
@@ -140,7 +134,7 @@ module Alchemy
140
134
  end
141
135
 
142
136
  def create_default_site!
143
- default_site = Alchemy::Config.get(:default_site)
137
+ default_site = Alchemy.config.default_site
144
138
  if default_site
145
139
  Alchemy::Site.create!(name: default_site["name"], host: default_site["host"])
146
140
  else
@@ -11,8 +11,8 @@ module Alchemy
11
11
  .group(:name)
12
12
  .order("count DESC, name ASC")
13
13
  .map { |e| {"name" => e.name, "count" => e.count} }
14
- Alchemy::Element.definitions.reject { |definition| res.map { |e| e["name"] }.include? definition["name"] }.sort_by { |d| d["name"] }.each do |definition|
15
- res << {"name" => definition["name"], "count" => 0}
14
+ Alchemy::Element.definitions.reject { |definition| res.map { |e| e["name"] }.include?(definition.name) }.sort_by(&:name).each do |definition|
15
+ res << {"name" => definition.name, "count" => 0}
16
16
  end
17
17
  res
18
18
  end
@@ -23,8 +23,8 @@ module Alchemy
23
23
  .group(:page_layout)
24
24
  .order("count DESC, page_layout ASC")
25
25
  .map { |p| {"page_layout" => p.page_layout, "count" => p.count} }
26
- Alchemy::PageLayout.all.reject { |page_layout| res.map { |p| p["page_layout"] }.include? page_layout["name"] }.sort_by { |d| d["name"] }.each do |page_layout|
27
- res << {"page_layout" => page_layout["name"], "count" => 0}
26
+ Alchemy::PageDefinition.all.reject { |page_layout| res.map { |p| p["page_layout"] }.include?(page_layout.name) }.sort_by(&:name).each do |page_layout|
27
+ res << {"page_layout" => page_layout.name, "count" => 0}
28
28
  end
29
29
  res
30
30
  end
@@ -17,13 +17,7 @@ module Alchemy
17
17
  # @param value [Object] The value you want to return instead of the original one
18
18
  #
19
19
  def stub_alchemy_config(key, value)
20
- allow(Alchemy::Config).to receive(:get) do |arg|
21
- if arg == key
22
- value
23
- else
24
- Alchemy::Config.show[arg.to_s]
25
- end
26
- end
20
+ allow(Alchemy.config).to receive(key).and_return(value)
27
21
  end
28
22
  end
29
23
  end
@@ -2,9 +2,20 @@
2
2
 
3
3
  FactoryBot.define do
4
4
  factory :alchemy_attachment, class: "Alchemy::Attachment" do
5
- file do
6
- File.new(Alchemy::Engine.root.join("lib", "alchemy", "test_support", "fixtures", "image.png"))
5
+ transient do
6
+ file do
7
+ Rack::Test::UploadedFile.new(
8
+ Alchemy::Engine.root.join("lib", "alchemy", "test_support", "fixtures", "image.png")
9
+ )
10
+ end
7
11
  end
12
+
13
+ after(:build) do |attachment, acc|
14
+ if acc.file
15
+ attachment.file = acc.file
16
+ end
17
+ end
18
+
8
19
  name { "image" }
9
20
  file_name { "image.png" }
10
21
  end
@@ -3,11 +3,10 @@
3
3
  FactoryBot.define do
4
4
  factory :alchemy_language, class: "Alchemy::Language" do
5
5
  name { "Your Language" }
6
- language_code { "en" }
7
- locale { ::I18n.default_locale }
6
+ code { ::I18n.available_locales.first.to_s }
8
7
  default { true }
9
8
  frontpage_name { "Intro" }
10
- page_layout { Alchemy::Config.get(:default_language)["page_layout"] }
9
+ page_layout { Alchemy.config.default_language.page_layout }
11
10
 
12
11
  public { true }
13
12
 
@@ -15,23 +14,20 @@ FactoryBot.define do
15
14
 
16
15
  trait :klingon do
17
16
  name { "Klingon" }
18
- language_code { "kl" }
19
- locale { :kl }
17
+ code { "kl" }
20
18
  frontpage_name { "Tuq" }
21
19
  default { false }
22
20
  end
23
21
 
24
22
  trait :english do
25
23
  name { "English" }
26
- language_code { "en" }
27
- locale { :en }
24
+ code { "en" }
28
25
  default { false }
29
26
  end
30
27
 
31
28
  trait :german do
32
29
  name { "Deutsch" }
33
- language_code { "de" }
34
- locale { :de }
30
+ code { "de" }
35
31
  default { false }
36
32
  end
37
33
  end
@@ -12,7 +12,7 @@ FactoryBot.define do
12
12
 
13
13
  parent do
14
14
  Alchemy::Page.find_by(language_root: true, language: language) ||
15
- FactoryBot.create(:alchemy_page, :language_root, language: language)
15
+ FactoryBot.create(:alchemy_page, :public, :language_root, language: language)
16
16
  end
17
17
 
18
18
  # This speeds up creating of pages dramatically.
@@ -23,7 +23,6 @@ FactoryBot.define do
23
23
  name { language&.frontpage_name || "Intro" }
24
24
  page_layout { language&.page_layout || "index" }
25
25
  language_root { true }
26
- public_on { Time.current }
27
26
  parent { nil }
28
27
  end
29
28
 
@@ -33,7 +32,6 @@ FactoryBot.define do
33
32
  public_on { Time.current }
34
33
  public_until { nil }
35
34
  end
36
- published_at { Time.current }
37
35
  after(:build) do |page, evaluator|
38
36
  page.build_public_version(
39
37
  public_on: evaluator.public_on,
@@ -42,7 +40,7 @@ FactoryBot.define do
42
40
  end
43
41
  after(:create) do |page|
44
42
  if page.autogenerate_elements
45
- page.definition["autogenerate"].each do |name|
43
+ page.definition.autogenerate.each do |name|
46
44
  create(
47
45
  :alchemy_element,
48
46
  name: name,
@@ -2,9 +2,37 @@
2
2
 
3
3
  FactoryBot.define do
4
4
  factory :alchemy_picture, class: "Alchemy::Picture" do
5
- image_file do
6
- File.new(Alchemy::Engine.root.join("lib", "alchemy", "test_support", "fixtures", "image.png"))
5
+ transient do
6
+ image_file do
7
+ Rack::Test::UploadedFile.new(
8
+ Alchemy::Engine.root.join("lib", "alchemy", "test_support", "fixtures", "image.png")
9
+ )
10
+ end
7
11
  end
12
+
13
+ after(:build) do |picture, acc|
14
+ if acc.image_file
15
+ case Alchemy.storage_adapter.name
16
+ when :active_storage
17
+ filename = acc.image_file.original_filename
18
+ content_type = Marcel::MimeType.for(extension: File.extname(filename))
19
+ picture.image_file.attach(
20
+ io: acc.image_file.open,
21
+ filename:,
22
+ content_type:,
23
+ identify: false,
24
+ metadata: {
25
+ width: 1,
26
+ height: 1
27
+ }
28
+ )
29
+ when :dragonfly
30
+ picture.image_file = acc.image_file
31
+ picture.image_file_size = acc.image_file.size
32
+ end
33
+ end
34
+ end
35
+
8
36
  name { "image" }
9
37
  upload_hash { Time.current.hash }
10
38
  end
@@ -8,8 +8,8 @@ FactoryBot.define do
8
8
  trait :default do
9
9
  public { true }
10
10
 
11
- name { Alchemy::Config.get(:default_site)["name"] }
12
- host { Alchemy::Config.get(:default_site)["host"] }
11
+ name { Alchemy.config.default_site.name }
12
+ host { Alchemy.config.default_site.host }
13
13
  end
14
14
 
15
15
  trait :public do
@@ -30,8 +30,8 @@ RSpec.shared_examples_for "having crop action" do |args|
30
30
  let(:settings) { {} }
31
31
 
32
32
  before do
33
- picture.image_file_width = 300
34
- picture.image_file_height = 250
33
+ allow(picture).to receive(:image_file_width) { 300 }
34
+ allow(picture).to receive(:image_file_height) { 250 }
35
35
  allow(croppable_resource).to receive(:settings) { settings }
36
36
  expect(Alchemy::Picture).to receive(:find_by) { picture }
37
37
  end
@@ -86,8 +86,8 @@ RSpec.shared_examples_for "having picture thumbnails" do
86
86
  allow(record).to receive(:settings) { {} }
87
87
  end
88
88
 
89
- it "adds them to the url" do
90
- expect(picture_url).to match(/\?foo=baz/)
89
+ it "does not add them to the url" do
90
+ expect(picture_url).to_not match(/\?foo=baz/)
91
91
  end
92
92
  end
93
93
  end
@@ -112,7 +112,7 @@ RSpec.shared_examples_for "having picture thumbnails" do
112
112
  describe "#picture_url_options" do
113
113
  subject(:picture_url_options) { record.picture_url_options }
114
114
 
115
- let(:picture) { build_stubbed(:alchemy_picture) }
115
+ let(:picture) { build(:alchemy_picture) }
116
116
 
117
117
  it { is_expected.to be_a(HashWithIndifferentAccess) }
118
118
 
@@ -418,7 +418,7 @@ RSpec.shared_examples_for "having picture thumbnails" do
418
418
  end
419
419
 
420
420
  context "with picture assigned" do
421
- let(:picture) { build_stubbed(:alchemy_picture) }
421
+ let(:picture) { build(:alchemy_picture) }
422
422
 
423
423
  let(:default_mask) do
424
424
  [
@@ -432,8 +432,8 @@ RSpec.shared_examples_for "having picture thumbnails" do
432
432
  let(:settings) { {} }
433
433
 
434
434
  before do
435
- picture.image_file_width = 300
436
- picture.image_file_height = 250
435
+ allow(picture).to receive(:image_file_width) { 300 }
436
+ allow(picture).to receive(:image_file_height) { 250 }
437
437
  allow(record).to receive(:settings) { settings }
438
438
  end
439
439
 
@@ -555,8 +555,8 @@ RSpec.shared_examples_for "having picture thumbnails" do
555
555
  let(:settings) { {crop: true, size: size} }
556
556
 
557
557
  before do
558
- picture.image_file_width = 200
559
- picture.image_file_height = 100
558
+ allow(picture).to receive(:image_file_width) { 200 }
559
+ allow(picture).to receive(:image_file_height) { 100 }
560
560
  end
561
561
 
562
562
  context "size 200x50" do
@@ -619,45 +619,99 @@ RSpec.shared_examples_for "having picture thumbnails" do
619
619
  end
620
620
 
621
621
  describe "#allow_image_cropping?" do
622
- let(:picture) do
623
- stub_model(Alchemy::Picture, image_file_width: 400, image_file_height: 300)
622
+ let(:picture) { Alchemy::Picture.new }
623
+ let(:image_file_width) { 400 }
624
+ let(:image_file_height) { 300 }
625
+ let(:crop) { false }
626
+ let(:size) { "400x300" }
627
+ let(:upsample) { false }
628
+
629
+ before do
630
+ allow(picture).to receive(:image_file_width) { image_file_width }
631
+ allow(picture).to receive(:image_file_height) { image_file_height }
632
+ allow(record).to receive(:settings) { {crop:, size:, upsample:} }
624
633
  end
625
634
 
626
635
  subject { record.allow_image_cropping? }
627
636
 
628
- it { is_expected.to be_falsy }
637
+ shared_context "with image file" do
638
+ before do
639
+ if Alchemy.storage_adapter.dragonfly?
640
+ expect(picture).to receive(:image_file) { fixture_file_upload("image.png") }
641
+ elsif Alchemy.storage_adapter.active_storage?
642
+ expect(picture.image_file).to receive(:attached?) { true }
643
+ end
644
+ end
645
+ end
629
646
 
630
- context "with picture assigned" do
647
+ shared_context "without image file" do
631
648
  before do
632
- allow(record).to receive(:picture) { picture }
649
+ if Alchemy.storage_adapter.dragonfly?
650
+ expect(picture).to receive(:image_file) { nil }
651
+ elsif Alchemy.storage_adapter.active_storage?
652
+ expect(picture.image_file).to receive(:attached?) { false }
653
+ end
633
654
  end
655
+ end
656
+
657
+ context "with crop set to false" do
658
+ let(:crop) { false }
634
659
 
635
660
  it { is_expected.to be_falsy }
661
+ end
662
+
663
+ context "with crop set to true" do
664
+ let(:crop) { true }
636
665
 
637
- context "and with image larger than crop size" do
666
+ context "with picture assigned" do
638
667
  before do
639
- allow(picture).to receive(:can_be_cropped_to?) { true }
668
+ allow(record).to receive(:picture) { picture }
640
669
  end
641
670
 
642
- it { is_expected.to be_falsy }
671
+ context "and image smaller or equal to crop size" do
672
+ context "if picture.image_file is nil" do
673
+ include_context "without image file"
643
674
 
644
- context "with crop set to true" do
645
- before do
646
- allow(record).to receive(:settings) { {crop: true} }
675
+ it { is_expected.to be_falsy }
647
676
  end
648
677
 
649
- context "if picture.image_file is nil" do
650
- before do
651
- expect(picture).to receive(:image_file) { nil }
652
- end
678
+ context "if picture.image_file is present" do
679
+ include_context "with image file"
653
680
 
654
681
  it { is_expected.to be_falsy }
682
+
683
+ context "but with upsample set to true" do
684
+ let(:upsample) { true }
685
+
686
+ it { is_expected.to be(true) }
687
+ end
655
688
  end
689
+ end
656
690
 
657
- context "if picture.image_file is present" do
658
- let(:picture) { build_stubbed(:alchemy_picture) }
691
+ context "and with image larger than crop size" do
692
+ let(:image_file_width) { 1201 }
693
+ let(:image_file_height) { 481 }
694
+
695
+ it { is_expected.to be_falsy }
659
696
 
660
- it { is_expected.to be(true) }
697
+ context "with crop set to true" do
698
+ context "if picture.image_file is nil" do
699
+ include_context "without image file"
700
+
701
+ it { is_expected.to be_falsy }
702
+ end
703
+
704
+ context "if picture.image_file is present" do
705
+ include_context "with image file"
706
+
707
+ it { is_expected.to be(true) }
708
+
709
+ context "with size setting being nil" do
710
+ let(:size) { nil }
711
+
712
+ it { is_expected.to be_falsey }
713
+ end
714
+ end
661
715
  end
662
716
  end
663
717
  end
@@ -29,11 +29,11 @@ RSpec.shared_examples_for "an alchemy ingredient" do
29
29
  context "with element" do
30
30
  before do
31
31
  expect(element).to receive(:ingredient_definition_for).at_least(:once) do
32
- {
32
+ Alchemy::IngredientDefinition.new(
33
33
  settings: {
34
34
  linkable: true
35
35
  }
36
- }.with_indifferent_access
36
+ )
37
37
  end
38
38
  end
39
39
 
@@ -47,19 +47,19 @@ RSpec.shared_examples_for "an alchemy ingredient" do
47
47
  context "without element" do
48
48
  let(:element) { nil }
49
49
 
50
- it { is_expected.to eq({}) }
50
+ it { is_expected.to be_a(Alchemy::IngredientDefinition) }
51
51
  end
52
52
 
53
53
  context "with element" do
54
54
  let(:definition) do
55
- {
55
+ Alchemy::IngredientDefinition.new(
56
56
  role: "headline",
57
57
  type: "Text",
58
58
  default: "Hello World",
59
59
  settings: {
60
60
  linkable: true
61
61
  }
62
- }.with_indifferent_access
62
+ )
63
63
  end
64
64
 
65
65
  before do
File without changes
@@ -0,0 +1,14 @@
1
+ module Alchemy
2
+ class Upgrader
3
+ module EightZero
4
+ def mention_alchemy_config_initializer
5
+ todo <<~TEXT, "Configuration has changed to initializer"
6
+ Check the new configuration file `./config/initializers/alchemy.rb` and
7
+ update values from your `config/alchemy/config.yml` file.
8
+
9
+ Then you can safely remove the `config/alchemy/config.yml` file.
10
+ TEXT
11
+ end
12
+ end
13
+ end
14
+ end
@@ -1,29 +1,42 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "alchemy/shell"
4
+ require "thor"
4
5
 
5
6
  module Alchemy
6
7
  class Upgrader
7
- extend Alchemy::Shell
8
-
9
- Dir["#{File.dirname(__FILE__)}/upgrader/*.rb"].sort.each { |f| require f }
10
-
11
- class << self
12
- def copy_new_config_file
13
- desc "Copy configuration file."
14
- config_file = Rails.root.join("config/alchemy/config.yml")
15
- default_config = File.join(File.dirname(__FILE__), "../../config/alchemy/config.yml")
16
- if !File.exist? config_file
17
- log "No configuration file found. Creating it."
18
- FileUtils.cp default_config, Rails.root.join("config/alchemy/config.yml")
19
- elsif FileUtils.identical? default_config, config_file
20
- log "Configuration file already present.", :skip
21
- else
22
- log "Custom configuration file found."
23
- FileUtils.cp default_config, Rails.root.join("config/alchemy/config.yml.defaults")
24
- log "Copied new default configuration file."
25
- todo "Check the default configuration file (./config/alchemy/config.yml.defaults) for new configuration options and insert them into your config file.", "Configuration has changed"
26
- end
8
+ include Alchemy::Shell
9
+ include Thor::Base
10
+ include Thor::Actions
11
+
12
+ Dir["#{File.dirname(__FILE__)}/upgrader/*.rb"].sort.each { require(_1) }
13
+
14
+ VERSION_MODULE_MAP = {
15
+ "8.0" => "Alchemy::Upgrader::EightZero"
16
+ }
17
+
18
+ source_root Alchemy::Engine.root.join("lib/generators/alchemy/install")
19
+
20
+ def initialize(version)
21
+ super()
22
+ self.class.include VERSION_MODULE_MAP[version.to_s].constantize
23
+ end
24
+
25
+ def update_config
26
+ desc "Copy configuration file."
27
+ @default_config = Alchemy::Configurations::Main.new
28
+ template("templates/alchemy.rb.tt", "config/initializers/alchemy.rb")
29
+ end
30
+
31
+ def run_migrations
32
+ ActiveRecord::Migration.check_all_pending!
33
+ rescue ActiveRecord::PendingMigrationError
34
+ desc "Pending Database migrations."
35
+ if yes?("Run database migrations now? (y/N)")
36
+ log "Migrating Database..."
37
+ Rake::Task["db:migrate"].invoke
38
+ else
39
+ log "Don't forget to run database migrations later with rake `db:migrate`.", :skip
27
40
  end
28
41
  end
29
42
  end
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Alchemy
4
- VERSION = "7.4.16"
4
+ VERSION = "8.0.0.a"
5
5
 
6
6
  def self.version
7
7
  VERSION