ntq_tools 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: cbeb5958ef479f90d380f74d13512a988936a16636845f8873360a3160412b31
4
+ data.tar.gz: a36e413a12bab5fcd370c60e059bf6767c42fdf16ffcddbed73356e829a0145a
5
+ SHA512:
6
+ metadata.gz: e3e4cfedca1eeaa752ca79fdac1d6c577d88cdcc7cf20b247bd843265c66f4409424dd7921d2000f9939e0ba6433c31d9c06413c980b5515f01aa18376b80e63
7
+ data.tar.gz: e4b558b3b6869bedc70c052af4ead39a5e5d06ca334ab18f46df0a22321076b691e85bcf8c7157b52241f7eecd936eed589a0dd1e2ad232d202b3f823a0c37b6
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright 2023 Kevin
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,28 @@
1
+ # NtqTools
2
+ Short description and motivation.
3
+
4
+ ## Usage
5
+ How to use my plugin.
6
+
7
+ ## Installation
8
+ Add this line to your application's Gemfile:
9
+
10
+ ```ruby
11
+ gem "ntq_tools", git: "https://github.com/9troisquarts/ntq_tools"
12
+ ```
13
+
14
+ And then execute:
15
+ ```bash
16
+ $ bundle
17
+ ```
18
+
19
+ Or install it yourself as:
20
+ ```bash
21
+ $ gem install ntq_tools
22
+ ```
23
+
24
+ ## Contributing
25
+ Contribution directions go here.
26
+
27
+ ## License
28
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
data/Rakefile ADDED
@@ -0,0 +1,8 @@
1
+ require "bundler/setup"
2
+
3
+ APP_RAKEFILE = File.expand_path("test/dummy/Rakefile", __dir__)
4
+ load "rails/tasks/engine.rake"
5
+
6
+ load "rails/tasks/statistics.rake"
7
+
8
+ require "bundler/gem_tasks"
@@ -0,0 +1 @@
1
+ //= link_directory ../stylesheets/ntq_tools .css
@@ -0,0 +1,15 @@
1
+ /*
2
+ * This is a manifest file that'll be compiled into application.css, which will include all the files
3
+ * listed below.
4
+ *
5
+ * Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
6
+ * or any plugin's vendor/assets/stylesheets directory can be referenced here using a relative path.
7
+ *
8
+ * You're free to add application-wide styles to this file and they'll appear at the bottom of the
9
+ * compiled file so the styles you add here take precedence over styles defined in any other CSS/SCSS
10
+ * files in this directory. Styles in this file should be added after the last require_* statement.
11
+ * It is generally better to create a new file per style scope.
12
+ *
13
+ *= require_tree .
14
+ *= require_self
15
+ */
@@ -0,0 +1,4 @@
1
+ module NtqTools
2
+ class ApplicationController < ActionController::Base
3
+ end
4
+ end
@@ -0,0 +1,46 @@
1
+ module NtqTools
2
+ class ImpersonationController < ::ApplicationController
3
+
4
+ before_action :check_impersonation_enabled, except: [:config]
5
+ before_action :model_name_is_valid?, only: [:sign_in]
6
+
7
+ def index
8
+ data = {}
9
+ NtqTools.impersonation_user_models.each do |model|
10
+ data[model.underscore] = model.constantize.all.map{|user| {
11
+ id: user.id,
12
+ label: label_for_user(user),
13
+ }}
14
+ end
15
+ render json: { data: data }
16
+ end
17
+
18
+ def signin
19
+ @resource = params[:model_name].camelize.constantize.find params[:id]
20
+ sign_in(@resource)
21
+ return redirect_to @resource.after_impersonation_path if @resource.respond_to?(:after_impersonation_path)
22
+
23
+ redirect_to after_sign_in_path_for(@resource)
24
+ end
25
+
26
+ private
27
+
28
+ def label_for_user(user, config = nil)
29
+ return user.impersonation_label if user.respond_to?(:impersonation_label)
30
+
31
+ return user.full_name if user.respond_to?(:full_name)
32
+
33
+ return user.email if user.respond_to?(:email)
34
+
35
+ user.id
36
+ end
37
+
38
+ def model_name_is_valid?
39
+ return render json: {}, status: 404 unless params[:model_name].present? && NtqTools.impersonation_user_models.include?(params[:model_name].camelize)
40
+ end
41
+
42
+ def check_impersonation_enabled
43
+ return render json: {}, status: 404 unless NtqTools.impersonation_enabled && NtqTools.impersonation_user_models.present?
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,29 @@
1
+ require 'ntq_tools/translations/translation_tool'
2
+ module NtqTools
3
+ class TranslationsController < NtqTools::ApplicationController
4
+ skip_before_action :verify_authenticity_token
5
+ before_action :check_presence_of_key
6
+
7
+ def show
8
+ return render json: { data: nil }, status: 404 unless I18n.exists?(params[:key].to_s)
9
+
10
+ render json: {
11
+ data: I18n.t(params[:key])
12
+ }, status: 200
13
+ end
14
+
15
+ def update
16
+ return render json: { status: "NOK", message: "value is missing" }, status: 400 unless params[:value].present?
17
+
18
+ NtqTools::Translations::TranslationTool.modify(params[:key].to_s, { "#{I18n.locale}": params[:value] })
19
+
20
+ render json: { data: true }, status: 200
21
+ end
22
+
23
+ private
24
+
25
+ def check_presence_of_key
26
+ return render json: { status: "NOK", message: "key params is missing" }, status: 400 unless params[:key].present?
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,4 @@
1
+ module NtqTools
2
+ module ApplicationHelper
3
+ end
4
+ end
@@ -0,0 +1,4 @@
1
+ module NtqTools
2
+ class ApplicationJob < ActiveJob::Base
3
+ end
4
+ end
@@ -0,0 +1,6 @@
1
+ module NtqTools
2
+ class ApplicationMailer < ActionMailer::Base
3
+ default from: "from@example.com"
4
+ layout "mailer"
5
+ end
6
+ end
@@ -0,0 +1,5 @@
1
+ module NtqTools
2
+ class ApplicationRecord < ActiveRecord::Base
3
+ self.abstract_class = true
4
+ end
5
+ end
@@ -0,0 +1,15 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>Ntq tools</title>
5
+ <%= csrf_meta_tags %>
6
+ <%= csp_meta_tag %>
7
+
8
+ <%= stylesheet_link_tag "ntq_tools/application", media: "all" %>
9
+ </head>
10
+ <body>
11
+
12
+ <%= yield %>
13
+
14
+ </body>
15
+ </html>
data/config/routes.rb ADDED
@@ -0,0 +1,8 @@
1
+ NtqTools::Engine.routes.draw do
2
+ resource :translation, only: [:update, :show]
3
+
4
+ if NtqTools.impersonation_enabled && NtqTools.impersonation_user_models.any? && defined?(Devise)
5
+ get '/impersonation/users' => "impersonation#index"
6
+ get "/impersonation/:model_name/:id/sign_in" => "impersonation#signin"
7
+ end
8
+ end
@@ -0,0 +1,221 @@
1
+ module NtqTools
2
+ module Generators
3
+ SKIPPED_ATTRIBUTE_NAMES = %w[created_at updated_at]
4
+ class GraphqlScaffoldGenerator < Rails::Generators::NamedBase
5
+ source_root File.expand_path('../templates', __dir__)
6
+
7
+ def create_type_file
8
+ singular_name = plural_name.singularize
9
+ return unless defined?(class_name.constantize) && class_name.constantize.respond_to?(:columns_hash)
10
+
11
+ definition = []
12
+ class_name.constantize.columns_hash.map do |k, v|
13
+ next if SKIPPED_ATTRIBUTE_NAMES.include?(k)
14
+
15
+ case v.type
16
+ when :string, :text
17
+ definition << "field :#{k}, String"
18
+ when :integer
19
+ definition << if k.include?('_id') || k == 'id'
20
+ "field :#{k}, ID"
21
+ else
22
+ "field :#{k}, Integer"
23
+ end
24
+ when :boolean
25
+ definition << "field :#{k}, Boolean"
26
+ when :decimal
27
+ definition << "field :#{k}, Float"
28
+ when :date, :datetime
29
+ definition << "field :#{k}, Types::TimeType"
30
+ else
31
+ raise "Type non défini: #{v.type.inspect}"
32
+ end
33
+ end
34
+
35
+ attributes = []
36
+ class_name.constantize.columns_hash.map do |k, v|
37
+ next if SKIPPED_ATTRIBUTE_NAMES.include?(k)
38
+
39
+ case v.type
40
+ when :string, :text
41
+ attributes << "argument :#{k}, String, required: false"
42
+ when :integer
43
+ attributes << if k.include?('_id') || k == 'id'
44
+ "argument :#{k}, ID, required: false"
45
+ else
46
+ "argument :#{k}, Integer, required: false"
47
+ end
48
+ when :boolean
49
+ attributes << "argument :#{k}, Boolean, required: false"
50
+ when :decimal
51
+ attributes << "argument :#{k}, Float, required: false"
52
+ when :date, :datetime
53
+ attributes << "argument :#{k}, Types::TimeType, required: false"
54
+ else
55
+ raise "Type non défini: #{v.type.inspect}"
56
+ end
57
+ end
58
+
59
+ associations = []
60
+ %i[belongs_to has_one].each do |association_type|
61
+ class_name.constantize.reflect_on_all_associations(association_type).each do |asso|
62
+ class_name = asso.options.dig(:class_name) || asso.name.to_s.singularize.camelcase
63
+ associations << "field :#{asso.name}, Types::#{class_name}Type"
64
+ end
65
+ end
66
+ [:has_many].each do |association_type|
67
+ class_name.constantize.reflect_on_all_associations(association_type).each do |asso|
68
+ class_name = asso.options.dig(:class_name) || asso.name.to_s.singularize.camelcase
69
+ next if class_name == 'PaperTrail::Version'
70
+
71
+ associations << "field :#{asso.name}, [Types::#{class_name}Type]"
72
+ end
73
+ end
74
+
75
+ # Type file
76
+ create_file "app/graphql/types/#{plural_name}/#{singular_name}_type.rb", <<~FILE
77
+ module Types
78
+ module #{plural_name.camelcase}
79
+ class #{singular_name.camelcase}Type < BaseObject
80
+ include Resolvers::TimestampsFields
81
+
82
+ #{definition.join('
83
+ ')}
84
+
85
+ ## Associations
86
+
87
+ #{associations.join('
88
+ ')}
89
+ end
90
+ end
91
+ end
92
+ FILE
93
+
94
+ # Attributes file
95
+ create_file "app/graphql/input_object/#{singular_name}_attributes.rb", <<~FILE
96
+ module InputObject
97
+ class #{singular_name.camelcase}Attributes < AttributesInputObject
98
+ #{attributes.join('
99
+ ')}
100
+ end
101
+ end
102
+ FILE
103
+
104
+ # Attributes file
105
+ create_file "app/graphql/input_object/search_#{plural_name}_attributes.rb", <<~FILE
106
+ module InputObject
107
+ class Search#{plural_name.camelcase}Attributes < AttributesInputObject
108
+
109
+ end
110
+ end
111
+ FILE
112
+
113
+ # Create mutation
114
+ create_file "app/graphql/mutations/#{plural_name}/create_#{singular_name}.rb", <<~FILE
115
+ module Mutations
116
+ class #{plural_name.camelcase}::Create#{singular_name.camelcase} < BaseMutation
117
+ field :flash_messages, [Types::JsonType], null: false
118
+
119
+ argument :attributes, InputObject::#{singular_name.camelcase}Attributes, required: true
120
+
121
+ def authorized?(attributes:)
122
+ context[:current_user].can?(:create, #{singular_name})
123
+ end
124
+
125
+ def resolve(attributes:)
126
+ #{singular_name} = ::#{singular_name.camelcase}.new
127
+ #{singular_name}.attributes = attributes
128
+ #{singular_name}.save!
129
+ {
130
+ #{singular_name}: #{singular_name},
131
+ flash_messages: [
132
+ {
133
+ type: 'success',
134
+ message: I18n.t(:'flashes.#{plural_name}.create.success')
135
+ }
136
+ ]
137
+ }
138
+ end
139
+ end
140
+ end
141
+ FILE
142
+
143
+ # Update mutation
144
+ create_file "app/graphql/mutations/#{plural_name}/update_#{singular_name}.rb", <<~FILE
145
+ module Mutations
146
+ class #{plural_name.camelcase}::Update#{singular_name.camelcase} < BaseMutation
147
+ field :flash_messages, [Types::JsonType], null: false
148
+
149
+ argument :id, ID, required: true
150
+ argument :attributes, InputObject::#{singular_name.camelcase}Attributes, required: true
151
+
152
+ def authorized?(attributes:, id:)
153
+ #{singular_name} = ::#{singular_name.camelcase}.find id
154
+ context[:current_user].can?(:update, #{singular_name})
155
+ end
156
+
157
+ def resolve(attributes:, id:)
158
+ #{singular_name} = ::#{singular_name.camelcase}.find id
159
+ #{singular_name}.attributes = attributes
160
+ #{singular_name}.save!
161
+ {
162
+ flash_messages: [
163
+ #{singular_name}: #{singular_name},
164
+ {
165
+ type: 'success',
166
+ message: I18n.t(:'flashes.#{plural_name}.update.success')
167
+ }
168
+ ]
169
+ }
170
+ end
171
+ end
172
+ end
173
+ FILE
174
+
175
+ # Delete mutation
176
+ create_file "app/graphql/mutations/#{plural_name}/delete_#{singular_name}.rb", <<~FILE
177
+ module Mutations
178
+ class #{plural_name.camelcase}::Delete#{singular_name.camelcase} < BaseMutation
179
+ field :flash_messages, [Types::JsonType], null: false
180
+
181
+ argument :id, ID, required: true
182
+
183
+ def authorized?(id:)
184
+ #{singular_name} = ::#{singular_name.camelcase}.find id
185
+ context[:current_user].can?(:destroy, #{singular_name})
186
+ end
187
+
188
+ def resolve(id:)
189
+ #{singular_name} = ::#{singular_name.camelcase}.find id
190
+ #{singular_name}.destroy!
191
+ {
192
+ flash_messages: [
193
+ {
194
+ type: 'success',
195
+ message: I18n.t(:'flashes.#{plural_name}.delete.success')
196
+ }
197
+ ]
198
+ }
199
+ end
200
+ end
201
+ end
202
+ FILE
203
+
204
+ puts 'Do you want to create the payload file ? (y/n)'
205
+ input = $stdin.gets.strip
206
+ if input == 'y'
207
+ create_file "app/graphql/types/#{singular_name}/#{singular_name}_list_payload.rb", <<~FILE
208
+ module Types
209
+ module #{singular_name.camelcase}
210
+ class #{singular_name.camelcase}ListPayload < BaseObject
211
+ field :#{plural_name}, [#{singular_name.camelcase}::#{singular_name.camelcase}Type], null: true
212
+ field :pagination, PaginationType, null: true
213
+ end
214
+ end
215
+ end
216
+ FILE
217
+ end
218
+ end
219
+ end
220
+ end
221
+ end
@@ -0,0 +1,11 @@
1
+ module NtqTools
2
+ module Generators
3
+ class InstallGenerator < Rails::Generators::Base
4
+ source_root File.expand_path("../../templates", __FILE__)
5
+
6
+ def copy_initializer_file
7
+ template "ntq_tools.rb", "config/initializers/ntq_tools.rb"
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,9 @@
1
+ NtqTools.setup do |config|
2
+
3
+ # Impersonation allow to sign in as user without password or Oauth
4
+ ## impersonation_label can be defined on model for customizing the select label
5
+ ## after_impersonation_path can be defined for specifying path redirection of resource
6
+ config.impersonation_enabled = true
7
+ config.impersonation_user_models = ["User"]
8
+
9
+ end
@@ -0,0 +1,7 @@
1
+ module NtqTools
2
+ class Engine < ::Rails::Engine
3
+ isolate_namespace NtqTools
4
+
5
+ config.autoload_paths << File.expand_path("../../lib", __FILE__)
6
+ end
7
+ end
@@ -0,0 +1,15 @@
1
+ module NtqTools
2
+ module Translations
3
+ module HashUtils
4
+ def dig_set(obj, keys, value)
5
+ key = keys.first
6
+ if keys.length == 1
7
+ obj[key] = value
8
+ else
9
+ obj[key] = {} unless obj[key]
10
+ dig_set(obj[key], keys.slice(1..-1), value)
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,92 @@
1
+ require 'ntq_tools/translations/yaml_tool'
2
+ require 'yaml'
3
+
4
+ module NtqTools
5
+ module Translations
6
+ class TranslationTool
7
+ @@yamls_by_language = nil
8
+
9
+ def self.load_files(file_pathnames)
10
+ @@yamls_by_language = {}
11
+ I18n.available_locales.each do |locale|
12
+ @@yamls_by_language[locale.to_s] = {} unless @@yamls_by_language[locale.to_s]
13
+
14
+ locales_file = file_pathnames.select{|path| path.include?("#{locale}.yml")}
15
+ locales_file.each do |path|
16
+ next if @@yamls_by_language[locale.to_s][path]
17
+
18
+ @@yamls_by_language[locale.to_s][path] = YamlTool.new(path)
19
+ end
20
+ end
21
+ end
22
+
23
+ def self.path_for_scope(locale, scope = nil)
24
+ filename = [scope, locale.to_s, "yml"].reject(&:blank?).join(".")
25
+ "#{::Rails.root}/config/locales/#{filename}"
26
+ end
27
+
28
+ def self.file_exists_for_scope?(locale, scope = nil)
29
+ File.exists?(path_for_scope(locale, scope))
30
+ end
31
+
32
+ def self.create_locale_file(locale, scope = nil)
33
+ puts "Creating a file at #{path_for_scope(locale, scope)}"
34
+ path = path_for_scope(locale, scope)
35
+ File.open(path, "w+") { |file| file.write({ "#{locale.to_s}": nil }.to_yaml) }
36
+ @@yamls_by_language[locale.to_s] = {} unless @@yamls_by_language[locale.to_s]
37
+ @@yamls_by_language[locale.to_s][path] = YamlTool.new(path)
38
+ true
39
+ end
40
+
41
+ def self.key_is_in_file(file, locale, key)
42
+ key = [locale.to_s, key].join('.') if file.get_value(locale.to_s)
43
+ file.get_value(key).present?
44
+ end
45
+
46
+ def self.search_key_for_locale(locale, searched_key)
47
+ files = @@yamls_by_language[locale.to_s] || []
48
+ files.each do |pathname, file|
49
+ found = key_is_in_file(file, locale, searched_key)
50
+
51
+ return file if found
52
+
53
+ k = searched_key.split(".")
54
+ if k[0..-2].length > 0
55
+ file = search_key_for_locale(locale, k[0..-2].join("."))
56
+ return file if file
57
+ end
58
+ end
59
+ nil
60
+ end
61
+
62
+ def self.modify(key, values)
63
+ puts key
64
+ puts values.inspect
65
+ config_folder = "#{::Rails.root}/config/locales/*.yml"
66
+ file_pathnames = Dir[config_folder]
67
+ return unless file_pathnames && file_pathnames.size > 0
68
+
69
+ load_files(file_pathnames) unless @@yamls_by_language
70
+
71
+ available_locales = I18n.available_locales.map(&:to_s)
72
+
73
+ default_scope = search_key_for_locale(I18n.default_locale, key)&.filename
74
+ default_scope = "" unless default_scope
75
+
76
+ values.each do |locale, v|
77
+ next unless available_locales.include?(locale.to_s) || v.blank?
78
+
79
+ scope = search_key_for_locale(locale, key)&.filename
80
+ if !scope
81
+ create_locale_file(locale, default_scope) unless file_exists_for_scope?(locale, default_scope)
82
+ scope = default_scope
83
+ end
84
+ yaml = @@yamls_by_language[locale.to_s][path_for_scope(locale, scope)]
85
+ key = [locale.to_s, key].join('.') if yaml.get_value(locale.to_s)
86
+ yaml.set_value(key, v) if yaml
87
+ end
88
+
89
+ end
90
+ end
91
+ end
92
+ end
@@ -0,0 +1,40 @@
1
+ require 'yaml'
2
+ require 'ntq_tools/translations/hash_utils'
3
+
4
+ module NtqTools
5
+ module Translations
6
+ class YamlTool
7
+ include HashUtils
8
+
9
+ attr_accessor :filepath, :file, :content, :filename
10
+
11
+ def initialize(filepath)
12
+ @filepath = filepath
13
+ @file = File.open(filepath)
14
+ @content = YAML.load(@file.read)
15
+ name = filepath.split("/").last.split(".")
16
+ name = name.size <= 2 ? nil : name.first
17
+ @filename = name
18
+ end
19
+
20
+ def write_content
21
+ return false unless @content
22
+
23
+ File.write(filepath, @content.to_yaml)
24
+ true
25
+ end
26
+
27
+ def get_value(key)
28
+ keys = (key.is_a?(Array) ? key : key.split('.')).map(&:to_s)
29
+ @content.dig(*keys)
30
+ end
31
+
32
+ def set_value(key, value)
33
+ keys = (key.is_a?(Array) ? key : key.split('.')).map(&:to_s)
34
+ new_content = dig_set(@content, keys, value)
35
+ write_content
36
+ new_content
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,3 @@
1
+ module NtqTools
2
+ VERSION = "0.3.0"
3
+ end
data/lib/ntq_tools.rb ADDED
@@ -0,0 +1,16 @@
1
+ require "ntq_tools/version"
2
+ require "ntq_tools/engine"
3
+
4
+ module NtqTools
5
+
6
+ mattr_accessor :impersonation_enabled
7
+ @@impersonation_enabled = false
8
+
9
+ mattr_accessor :impersonation_user_models
10
+ @@impersonation_user_models = []
11
+
12
+ def self.setup
13
+ yield self
14
+ end
15
+
16
+ end
@@ -0,0 +1,4 @@
1
+ # desc "Explaining what the task does"
2
+ # task :ntq_tools do
3
+ # # Task goes here
4
+ # end
metadata ADDED
@@ -0,0 +1,104 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ntq_tools
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.3.0
5
+ platform: ruby
6
+ authors:
7
+ - Kevin
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2023-02-24 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rails
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "<"
18
+ - !ruby/object:Gem::Version
19
+ version: '8'
20
+ - - ">="
21
+ - !ruby/object:Gem::Version
22
+ version: '6'
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - "<"
28
+ - !ruby/object:Gem::Version
29
+ version: '8'
30
+ - - ">="
31
+ - !ruby/object:Gem::Version
32
+ version: '6'
33
+ - !ruby/object:Gem::Dependency
34
+ name: missing_translation
35
+ requirement: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - "<"
38
+ - !ruby/object:Gem::Version
39
+ version: 1.0.0
40
+ type: :runtime
41
+ prerelease: false
42
+ version_requirements: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - "<"
45
+ - !ruby/object:Gem::Version
46
+ version: 1.0.0
47
+ description: Boite à outil de 9troisquarts
48
+ email:
49
+ - kevin@9troisquarts.com
50
+ executables: []
51
+ extensions: []
52
+ extra_rdoc_files: []
53
+ files:
54
+ - MIT-LICENSE
55
+ - README.md
56
+ - Rakefile
57
+ - app/assets/config/ntq_tools_manifest.js
58
+ - app/assets/stylesheets/ntq_tools/application.css
59
+ - app/controllers/ntq_tools/application_controller.rb
60
+ - app/controllers/ntq_tools/impersonation_controller.rb
61
+ - app/controllers/ntq_tools/translations_controller.rb
62
+ - app/helpers/ntq_tools/application_helper.rb
63
+ - app/jobs/ntq_tools/application_job.rb
64
+ - app/mailers/ntq_tools/application_mailer.rb
65
+ - app/models/ntq_tools/application_record.rb
66
+ - app/views/layouts/ntq_tools/application.html.erb
67
+ - config/routes.rb
68
+ - lib/generators/ntq_tools/graphql_scaffold_generator.rb
69
+ - lib/generators/ntq_tools/install_generator.rb
70
+ - lib/generators/templates/ntq_tools.rb
71
+ - lib/ntq_tools.rb
72
+ - lib/ntq_tools/engine.rb
73
+ - lib/ntq_tools/translations/hash_utils.rb
74
+ - lib/ntq_tools/translations/translation_tool.rb
75
+ - lib/ntq_tools/translations/yaml_tool.rb
76
+ - lib/ntq_tools/version.rb
77
+ - lib/tasks/ntq_tools_tasks.rake
78
+ homepage: https://github.com
79
+ licenses:
80
+ - MIT
81
+ metadata:
82
+ homepage_uri: https://github.com
83
+ source_code_uri: https://github.com
84
+ changelog_uri: https://github.com
85
+ post_install_message:
86
+ rdoc_options: []
87
+ require_paths:
88
+ - lib
89
+ required_ruby_version: !ruby/object:Gem::Requirement
90
+ requirements:
91
+ - - ">="
92
+ - !ruby/object:Gem::Version
93
+ version: '0'
94
+ required_rubygems_version: !ruby/object:Gem::Requirement
95
+ requirements:
96
+ - - ">="
97
+ - !ruby/object:Gem::Version
98
+ version: '0'
99
+ requirements: []
100
+ rubygems_version: 3.3.7
101
+ signing_key:
102
+ specification_version: 4
103
+ summary: Toolkit 9tq
104
+ test_files: []