potassium 6.5.0 → 6.6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (74) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +20 -0
  3. data/README.md +30 -1
  4. data/docs/CONTRIBUTING.md +2 -2
  5. data/lib/potassium/assets/.circleci/config.yml.erb +11 -1
  6. data/lib/potassium/assets/.eslintrc.json +15 -9
  7. data/lib/potassium/assets/.rubocop.yml +1 -0
  8. data/lib/potassium/assets/Aptfile +5 -0
  9. data/lib/potassium/assets/README.yml +30 -6
  10. data/lib/potassium/assets/active_admin/admin-component.vue +22 -30
  11. data/lib/potassium/assets/app/javascript/{app.spec.js → components/app.spec.ts} +1 -1
  12. data/lib/potassium/assets/app/javascript/components/app.vue +9 -0
  13. data/lib/potassium/assets/app/javascript/types/vue.d.ts +5 -0
  14. data/lib/potassium/assets/app/jobs/shrine_promote_job.rb +14 -0
  15. data/lib/potassium/assets/app/mailers/application_mailer.rb +1 -1
  16. data/lib/potassium/assets/app/mailers/example_mailer.rb +6 -0
  17. data/lib/potassium/assets/app/serializers/base_serializer.rb +3 -0
  18. data/lib/potassium/assets/app/serializers/concerns/image_handling_attributes.rb +20 -0
  19. data/lib/potassium/assets/app/uploaders/cover_image_uploader.rb +52 -0
  20. data/lib/potassium/assets/app/views/example_mailer/example_mail.html.mjml +7 -0
  21. data/lib/potassium/assets/app/views/layouts/default_mail.html.mjml +49 -0
  22. data/lib/potassium/assets/config/initializers/shrine/plugins/image_handling_utilities.rb +143 -0
  23. data/lib/potassium/assets/config/mailer.rb.erb +0 -2
  24. data/lib/potassium/assets/config/shrine.rb +15 -0
  25. data/lib/potassium/assets/config/webpack/rules/css.js +5 -0
  26. data/lib/potassium/assets/config/webpack/rules/index.js +11 -0
  27. data/lib/potassium/assets/config/webpack/rules/jquery.js +11 -0
  28. data/lib/potassium/assets/config/webpack/rules/typescript.js +32 -0
  29. data/lib/potassium/assets/config/webpack/rules/vue.js +19 -0
  30. data/lib/potassium/assets/config/webpack/webpack.config.js +4 -0
  31. data/lib/potassium/assets/public/mails/platanus-logo.png +0 -0
  32. data/lib/potassium/assets/tsconfig.json +31 -0
  33. data/lib/potassium/cli/commands/create.rb +3 -1
  34. data/lib/potassium/cli_options.rb +15 -3
  35. data/lib/potassium/platanus_config.rb +20 -0
  36. data/lib/potassium/recipes/admin.rb +11 -0
  37. data/lib/potassium/recipes/api.rb +6 -85
  38. data/lib/potassium/recipes/coverage.rb +31 -0
  39. data/lib/potassium/recipes/file_storage.rb +50 -0
  40. data/lib/potassium/recipes/front_end.rb +82 -110
  41. data/lib/potassium/recipes/google_tag_manager.rb +1 -1
  42. data/lib/potassium/recipes/mailer.rb +22 -10
  43. data/lib/potassium/recipes/mjml.rb +31 -0
  44. data/lib/potassium/recipes/node.rb +11 -13
  45. data/lib/potassium/recipes/style.rb +9 -2
  46. data/lib/potassium/recipes/vue_admin.rb +38 -8
  47. data/lib/potassium/templates/application.rb +1 -0
  48. data/lib/potassium/version.rb +8 -3
  49. data/spec/features/api_spec.rb +6 -1
  50. data/spec/features/coverage_spec.rb +17 -0
  51. data/spec/features/file_storage_spec.rb +102 -26
  52. data/spec/features/front_end_spec.rb +14 -48
  53. data/spec/features/mailer_spec.rb +79 -33
  54. data/spec/features/mjml_spec.rb +53 -0
  55. data/spec/features/vue_admin_spec.rb +0 -10
  56. data/spec/support/shared_examples.rb +5 -0
  57. metadata +28 -21
  58. data/lib/potassium/assets/active_admin/admin_application.js +0 -14
  59. data/lib/potassium/assets/active_admin/init_activeadmin_vue.rb +0 -10
  60. data/lib/potassium/assets/app/graphql/graphql_controller.rb +0 -55
  61. data/lib/potassium/assets/app/graphql/mutations/login_mutation.rb +0 -23
  62. data/lib/potassium/assets/app/graphql/queries/base_query.rb +0 -4
  63. data/lib/potassium/assets/app/graphql/types/base/base_argument.rb +0 -4
  64. data/lib/potassium/assets/app/graphql/types/base/base_enum.rb +0 -4
  65. data/lib/potassium/assets/app/graphql/types/base/base_field.rb +0 -5
  66. data/lib/potassium/assets/app/graphql/types/base/base_input_object.rb +0 -5
  67. data/lib/potassium/assets/app/graphql/types/base/base_interface.rb +0 -7
  68. data/lib/potassium/assets/app/graphql/types/base/base_object.rb +0 -5
  69. data/lib/potassium/assets/app/graphql/types/base/base_scalar.rb +0 -4
  70. data/lib/potassium/assets/app/graphql/types/base/base_union.rb +0 -4
  71. data/lib/potassium/assets/app/graphql/types/mutation_type.rb +0 -10
  72. data/lib/potassium/assets/app/graphql/types/query_type.rb +0 -13
  73. data/lib/potassium/assets/config/graphql_playground.rb +0 -20
  74. data/spec/features/graphql_spec.rb +0 -71
@@ -1,55 +0,0 @@
1
- class GraphqlController < ApplicationController
2
- # If accessing from outside this domain, nullify the session
3
- # This allows for outside API access while preventing CSRF attacks,
4
- # but you'll have to authenticate your user separately
5
- # protect_from_forgery with: :null_session
6
-
7
- def execute
8
- variables = prepare_variables(params[:variables])
9
- query = params[:query]
10
- operation_name = params[:operationName]
11
- context = { current_user: get_current_user }
12
- result = GqlSampleSchema.execute(query, variables: variables, context: context, operation_name: operation_name)
13
- render json: result
14
- rescue => e
15
- raise e unless Rails.env.development?
16
- handle_error_in_development e
17
- end
18
-
19
- private
20
-
21
- # Handle variables in form data, JSON body, or a blank value
22
- def prepare_variables(variables_param)
23
- case variables_param
24
- when String
25
- if variables_param.present?
26
- JSON.parse(variables_param) || {}
27
- else
28
- {}
29
- end
30
- when Hash
31
- variables_param
32
- when ActionController::Parameters
33
- variables_param.to_unsafe_hash # GraphQL-Ruby will validate name and type of incoming variables.
34
- when nil
35
- {}
36
- else
37
- raise ArgumentError, "Unexpected parameter: #{variables_param}"
38
- end
39
- end
40
-
41
- def handle_error_in_development(e)
42
- logger.error e.message
43
- logger.error e.backtrace.join("\n")
44
-
45
- render json: { errors: [{ message: e.message, backtrace: e.backtrace }], data: {} }, status: 500
46
- end
47
-
48
- def get_current_user
49
- if request.headers['Authorization']
50
- _, token = request.headers['Authorization'].split
51
- decoded_token = JWT.decode token, ENV['HMAC_SECRET'], true, { algorithm: 'HS256' }
52
- User.find(decoded_token.first["id"])
53
- end
54
- end
55
- end
@@ -1,23 +0,0 @@
1
- require 'jwt'
2
-
3
- class Mutations::LoginMutation < Mutations::BaseMutation
4
- null true
5
-
6
- argument :email, String, required: true
7
- argument :password, String, required: true
8
-
9
-
10
- field :token, String, null: true
11
-
12
- def resolve(email:, password:)
13
- user = User.find_by(email: email)
14
- if user&.valid_password?(password)
15
- payload = { id: user.id, email: user.email, exp: (Time.zone.now + 24.hours).to_i }
16
- token = JWT.encode payload, ENV['HMAC_SECRET'], 'HS256'
17
- return { token: token }
18
- end
19
- GraphQL::ExecutionError.new("User or Password invalid")
20
- rescue ActiveRecord::RecordInvalid => e
21
- GraphQL::ExecutionError.new("Invalid input: #{e.record.errors.full_messages.join(', ')}")
22
- end
23
- end
@@ -1,4 +0,0 @@
1
- module Queries
2
- class BaseQuery < GraphQL::Schema::Resolver
3
- end
4
- end
@@ -1,4 +0,0 @@
1
- module Types::Base
2
- class BaseArgument < GraphQL::Schema::Argument
3
- end
4
- end
@@ -1,4 +0,0 @@
1
- module Types::Base
2
- class BaseEnum < GraphQL::Schema::Enum
3
- end
4
- end
@@ -1,5 +0,0 @@
1
- module Types::Base
2
- class BaseField < GraphQL::Schema::Field
3
- argument_class Types::Base::BaseArgument
4
- end
5
- end
@@ -1,5 +0,0 @@
1
- module Types::Base
2
- class BaseInputObject < GraphQL::Schema::InputObject
3
- argument_class Types::Base::BaseArgument
4
- end
5
- end
@@ -1,7 +0,0 @@
1
- module Types::Base
2
- module BaseInterface
3
- include GraphQL::Schema::Interface
4
-
5
- field_class Types::Base::BaseField
6
- end
7
- end
@@ -1,5 +0,0 @@
1
- module Types::Base
2
- class BaseObject < GraphQL::Schema::Object
3
- field_class Types::Base::BaseField
4
- end
5
- end
@@ -1,4 +0,0 @@
1
- module Types::Base
2
- class BaseScalar < GraphQL::Schema::Scalar
3
- end
4
- end
@@ -1,4 +0,0 @@
1
- module Types::Base
2
- class BaseUnion < GraphQL::Schema::Union
3
- end
4
- end
@@ -1,10 +0,0 @@
1
- module Types
2
- class MutationType < Types::Base::BaseObject
3
- # TODO: remove me
4
- field :test_field, String, null: false,
5
- description: "An example field added by the generator"
6
- def test_field
7
- "Hello World"
8
- end
9
- end
10
- end
@@ -1,13 +0,0 @@
1
- module Types
2
- class QueryType < Types::Base::BaseObject
3
- # Add root-level fields here.
4
- # They will be entry points for queries on your schema.
5
-
6
- # TODO: remove me
7
- field :test_field, String, null: false,
8
- description: "An example field added by the generator"
9
- def test_field
10
- "Hello World!"
11
- end
12
- end
13
- end
@@ -1,20 +0,0 @@
1
- # config/initializers/graphql_playground.rb
2
- # All config options have a default that should work out of the box
3
- if Rails.env.development?
4
- GraphqlPlayground::Rails.configure do |config|
5
- # config.headers = {
6
- # 'X-Auth-Header' => ->(view_context) { "123" }
7
- # }
8
- # config.title = "Playground"
9
- # config.csrf = true
10
- # config.playground_version = "latest"
11
- # # Ideally the assets would be added to your projects `vendor/assets` directories
12
- # config.favicon = "/assets/playground.ico"
13
- # config.playground_js_url = "/assets/playground.js"
14
- # config.playground_css_url = "/assets/playground.css"
15
- # # see: https://github.com/prisma-labs/graphql-playground#settings
16
- config.settings = {
17
- "schema.polling.enable": false
18
- }
19
- end
20
- end
@@ -1,71 +0,0 @@
1
- require "spec_helper"
2
-
3
- RSpec.describe "GraphQL" do
4
- context 'when using only graphql' do
5
- before :all do
6
- drop_dummy_database
7
- remove_project_directory
8
- create_dummy_project("api" => :graphql)
9
- end
10
-
11
- it "adds graphql related gems to Gemfile" do
12
- gemfile_content = IO.read("#{project_path}/Gemfile")
13
- expect(gemfile_content).to include("gem 'graphql'")
14
- expect(gemfile_content).to include("gem 'graphql_playground-rails'")
15
- expect(gemfile_content).not_to include("gem 'graphiql'")
16
- end
17
-
18
- it 'installs and sets up graphql' do
19
- schema = IO.read(
20
- "#{project_path}/app/graphql/#{PotassiumTestHelpers::APP_NAME.dasherize.tr('-', '_')}_schema.rb"
21
- )
22
- expect(schema).to include(
23
- "class #{PotassiumTestHelpers::APP_NAME.titleize.delete(' ')}Schema < GraphQL::Schema"
24
- )
25
-
26
- base_mutation = IO.read("#{project_path}/app/graphql/mutations/base_mutation.rb")
27
- expect(base_mutation).to include('Types::Base::Base')
28
- expect(base_mutation).not_to include('input_object_class')
29
- expect(base_mutation).not_to include('RelayClassic')
30
-
31
- controller = IO.read("#{project_path}/app/controllers/graphql_controller.rb")
32
- expect(controller).to include('skip_before_action :verify_authenticity_token')
33
- end
34
-
35
- it 'sets up graphql playground' do
36
- routes = IO.read("#{project_path}/config/routes.rb")
37
- expect(routes).to include(
38
- 'mount GraphqlPlayground::Rails::Engine, at: "/graphiql", graphql_path: "/graphql"'
39
- )
40
- config = IO.read("#{project_path}/config/initializers/graphql_playground.rb")
41
- expect(config).to include('GraphqlPlayground::Rails.configure do |config|')
42
- end
43
- end
44
-
45
- context 'when using authentication' do
46
- before :all do
47
- drop_dummy_database
48
- remove_project_directory
49
- create_dummy_project("api" => :graphql, "devise": true)
50
- end
51
-
52
- it 'gathers jwt gem' do
53
- gemfile_content = IO.read("#{project_path}/Gemfile")
54
- expect(gemfile_content).to include("gem 'jwt'")
55
- end
56
-
57
- it 'Adds auth related mutation and controller' do
58
- controller = IO.read("#{project_path}/app/controllers/graphql_controller.rb")
59
- expect(controller).to include('get_current_user')
60
- expect(controller).to include(
61
- "#{PotassiumTestHelpers::APP_NAME.titleize.delete(' ')}Schema.execute"
62
- )
63
-
64
- mutation_type = IO.read("#{project_path}/app/graphql/types/mutation_type.rb")
65
- expect(mutation_type).to include('field :login, mutation: Mutations::LoginMutation')
66
-
67
- login_mutation = IO.read("#{project_path}/app/graphql/mutations/login_mutation.rb")
68
- expect(login_mutation).to include('class Mutations::LoginMutation < Mutations::BaseMutation')
69
- end
70
- end
71
- end