├── .gitignore ├── .rspec ├── .rubocop.yml ├── .travis.yml ├── Gemfile ├── LICENSE.txt ├── README.md ├── Rakefile ├── config.ru ├── graphdoc-ruby.gemspec ├── lib ├── graphdoc-ruby.rb ├── graphdoc-ruby │ ├── application.rb │ ├── config.rb │ ├── graphdoc.rb │ ├── graphql_json.rb │ ├── railtie.rb │ ├── rake_task.rb │ ├── static.rb │ ├── utils.rb │ └── version.rb └── graphdoc_ruby.rb ├── package.json ├── spec ├── graphdoc-ruby │ └── version_spec.rb └── spec_helper.rb └── yarn.lock /.gitignore: -------------------------------------------------------------------------------- 1 | /.bundle/ 2 | /.yardoc 3 | /Gemfile.lock 4 | /_yardoc/ 5 | /coverage/ 6 | /doc/ 7 | /pkg/ 8 | /spec/reports/ 9 | /tmp/ 10 | /node_modules/ 11 | 12 | # rspec failure tracking 13 | .rspec_status 14 | -------------------------------------------------------------------------------- /.rspec: -------------------------------------------------------------------------------- 1 | --format documentation 2 | --color 3 | -------------------------------------------------------------------------------- /.rubocop.yml: -------------------------------------------------------------------------------- 1 | AllCops: 2 | Exclude: 3 | - 'bin/*' 4 | - 'vendor/**/*' 5 | - '**/Rakefile' 6 | - '**/config.ru' 7 | - 'node_modules/**/*' 8 | TargetRubyVersion: 2.5 9 | DisplayCopNames: true 10 | 11 | Performance: 12 | Enabled: false 13 | 14 | Bundler: 15 | Enabled: false 16 | 17 | Naming: 18 | Enabled: false 19 | 20 | Metrics/BlockNesting: 21 | Enabled: false 22 | 23 | Metrics/ClassLength: 24 | Enabled: false 25 | 26 | Metrics/LineLength: 27 | Enabled: false 28 | 29 | Metrics/MethodLength: 30 | Enabled: false 31 | 32 | Metrics/BlockLength: 33 | Enabled: false 34 | 35 | Metrics/ModuleLength: 36 | Enabled: false 37 | 38 | Style/AsciiComments: 39 | Enabled: false 40 | 41 | Style/BlockDelimiters: 42 | Exclude: 43 | - 'spec/**/*' 44 | 45 | Style/Documentation: 46 | Enabled: false 47 | 48 | Style/BlockDelimiters: 49 | Enabled: false 50 | 51 | Style/DoubleNegation: 52 | Enabled: false 53 | 54 | Style/GuardClause: 55 | Enabled: false 56 | 57 | Style/ClassAndModuleChildren: 58 | Enabled: false 59 | 60 | Style/SpecialGlobalVars: 61 | Enabled: false 62 | 63 | Style/NumericPredicate: 64 | Enabled: false 65 | 66 | Style/Lambda: 67 | Enabled: false 68 | 69 | Layout/AlignParameters: 70 | EnforcedStyle: with_fixed_indentation 71 | 72 | Layout/MultilineMethodCallIndentation: 73 | EnforcedStyle: indented 74 | 75 | Lint/AmbiguousRegexpLiteral: 76 | Enabled: false 77 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | sudo: false 2 | language: ruby 3 | rvm: 4 | - 2.3.5 5 | before_install: gem install bundler -v 1.15.4 6 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | source 'https://rubygems.org' 4 | 5 | git_source(:github) { |repo_name| "https://github.com/#{repo_name}" } 6 | 7 | # Specify your gem's dependencies in graphdoc-ruby.gemspec 8 | gemspec 9 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2017 alpaca-tc 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Graphdoc::Ruby 2 | 3 | Mountable [graphdoc](https://github.com/2fd/graphdoc) based on rack. 4 | graphdoc is static page generator for documenting GraphQL Schema. 5 | 6 | screen 7 | 8 | ## Installation 9 | 10 | Add this line to your application's Gemfile: 11 | 12 | ```ruby 13 | gem 'graphdoc-ruby' 14 | ``` 15 | 16 | Install graphdoc to your machine: 17 | 18 | ```sh 19 | $ npm install -g @2fd/graphdoc 20 | 21 | OR 22 | 23 | $ yarn add @2fd/graphdoc 24 | ``` 25 | 26 | ## Usage 27 | 28 | ### In pure rack application 29 | 30 | ```ruby 31 | # config.ru 32 | 33 | require 'graphdoc_ruby' 34 | 35 | GraphdocRuby.configure do |config| 36 | # endpoint of GraphQL 37 | config.endpoint = 'https://graphql-pokemon.now.sh/' 38 | end 39 | 40 | run(GraphdocRuby::Application) 41 | ``` 42 | 43 | ```sh 44 | $ gem install rack 45 | $ bundle exec rackup 46 | ``` 47 | 48 | ### In rails application 49 | 50 | ```ruby 51 | # config/routes.rb 52 | Rails.application.routes.draw do 53 | mount GraphdocRuby::Application, at: 'graphdoc' 54 | end 55 | 56 | # config/initializers/graphdoc.rb 57 | GraphdocRuby.configure do |config| 58 | config.endpoint = 'https://graphql-pokemon.now.sh/' 59 | end 60 | ``` 61 | 62 | ```sh 63 | $ bundle exec rails server --port 3000 64 | $ open http://0.0.0.0:3000/graphdoc 65 | ``` 66 | 67 | ## Configuration 68 | 69 | ```ruby 70 | GraphdocRuby.configure do |config| 71 | # :endpoint 72 | # 73 | # Required: 74 | # GraphQL endpoint url or dumped schema.json path. 75 | # 76 | # Example 77 | # config.endpoint = 'https://your-application.com/graphql' 78 | # config.endpoint = Rails.root.join('tmp', 'graphql', 'schema.json') 79 | 80 | # :executable_path 81 | # 82 | # Optional: 83 | # Executable path of `graphdoc`. 84 | # (default: `Bundler.which('graphdoc')`) 85 | # 86 | # Example 87 | # config.executable_path = Rails.root.join('node_modules', '.bin', 'graphdoc') 88 | 89 | # :output_directory 90 | # 91 | # Optional: 92 | # Output path for `graphdoc`. If you disabled run_time_generation, this value must be customized. 93 | # NOTE: Do not assign private directory because output_directory folders are served via rack application. 94 | # (default: `File.join(Dir.mktmpdir, 'graphdoc')`) 95 | # 96 | # Example 97 | # config.output_directory = Rails.root.join('tmp', 'graphdoc') 98 | 99 | # :overwrite 100 | # Optional: 101 | # Overwrite files if generated html already exist. 102 | # (default: true) 103 | # 104 | # Example 105 | # config.overwrite = false 106 | 107 | # :run_time_generation 108 | # Optional: 109 | # Generate html with graphdoc on the first access. 110 | # (default: true) 111 | # 112 | # Example 113 | # config.run_time_generation = Rails.env.development? 114 | 115 | # :graphql_context 116 | # 117 | # Optional: 118 | # Context of your graphql. 119 | # (default: -> {}) 120 | # config.graphql_context = -> { { 'Authorization' => "Token #{ENV['GITHUB_ACCESS_TOKEN']}", 'User-Agent' => 'graphdoc-client' } } 121 | 122 | # :graphql_query 123 | # 124 | # Optional: 125 | # Query of your graphql. 126 | # (default: -> {}) 127 | # config.graphql_query = -> { { 'token' => ENV['SECRET_API_TOKEN'] } } 128 | 129 | # === 130 | # Integrated with [graphql-ruby](https://github.com/rmosolgo/graphql-ruby) 131 | # === 132 | # 133 | # :schema_name 134 | # 135 | # Optional: 136 | # Schema name of your graphql-ruby. It is necessary when generating schema.json. 137 | # (default: nil) 138 | # 139 | # Example 140 | # config.schema_name = 'MyApplicationSchema' 141 | end 142 | ``` 143 | 144 | ### Example Configuration 145 | 146 | #### Github 147 | 148 | ```ruby 149 | GraphdocRuby.configure do |config| 150 | # Github 151 | config.endpoint = 'https://api.github.com/graphql' 152 | 153 | config.graphql_context = -> { 154 | { 155 | 'Authorization' => "bearer #{ENV['GITHUB_ACCESS_TOKEN']}", 156 | 'User-Agent' => 'my-client', 157 | } 158 | } 159 | end 160 | ``` 161 | 162 | #### Your Rails product 163 | 164 | ```ruby 165 | # config/routes.rb 166 | Rails.application.routes.draw do 167 | namespace :admin do 168 | mount GraphdocRuby::Application, at: 'graphdoc' 169 | end 170 | end 171 | 172 | # config/initializers/graphdoc.rb 173 | GraphdocRuby.configure do |config| 174 | config.endpoint = Rails.root.join('tmp', 'graphql', 'schema.json') 175 | config.output_directory = Rails.root.join('tmp', 'graphdoc').to_s 176 | config.schema_name = 'MyApplicationSchema' 177 | config.run_time_generation = Rails.env.development? 178 | end 179 | 180 | # Capfile 181 | namespace :deploy do 182 | after :generate_graphdoc do 183 | within release_path do 184 | # Generate schema.json from MyApplicationSchema 185 | execute :rake, 'graphdoc:dump_schema' 186 | 187 | # Generate html with graphdoc from schema.json 188 | execute :rake, 'graphdoc:generate' 189 | end 190 | end 191 | 192 | after :publishing, :generate_graphdoc 193 | end 194 | ``` 195 | 196 | ## Contributing 197 | 198 | Bug reports and pull requests are welcome on GitHub at https://github.com/alpaca-tc/graphdoc-ruby. 199 | 200 | ## License 201 | 202 | The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT). 203 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | require "bundler/gem_tasks" 2 | require "rspec/core/rake_task" 3 | require 'graphdoc-ruby/rake_task' 4 | 5 | RSpec::Core::RakeTask.new(:spec) 6 | GraphdocRuby::RakeTask.new 7 | 8 | task :default => :spec 9 | -------------------------------------------------------------------------------- /config.ru: -------------------------------------------------------------------------------- 1 | require 'graphdoc_ruby' 2 | 3 | GraphdocRuby.configure do |config| 4 | # Pokemon 5 | config.endpoint = 'https://graphql-pokemon.now.sh/' 6 | 7 | # Github 8 | # config.endpoint = 'https://api.github.com/graphql' 9 | # config.graphql_context = -> { 10 | # { 11 | # 'Authorization' => "bearer XXXXXXX", 12 | # 'User-Agent' => 'my-client', 13 | # } 14 | # } 15 | end 16 | 17 | run(GraphdocRuby::Application) 18 | -------------------------------------------------------------------------------- /graphdoc-ruby.gemspec: -------------------------------------------------------------------------------- 1 | 2 | # frozen_string_literal: true 3 | 4 | lib = File.expand_path('../lib', __FILE__) 5 | $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) 6 | require 'graphdoc-ruby/version' 7 | 8 | Gem::Specification.new do |spec| 9 | spec.name = 'graphdoc-ruby' 10 | spec.version = GraphdocRuby::VERSION 11 | spec.authors = ['alpaca-tc'] 12 | spec.email = ['alpaca-tc@alpaca.tc'] 13 | 14 | spec.summary = 'Graphdoc application based on rack' 15 | spec.description = 'Graphdoc application based on rack' 16 | spec.homepage = 'https://github.com/alpaca-tc/graphdoc-ruby' 17 | spec.license = 'MIT' 18 | 19 | spec.files = `git ls-files -z`.split("\x0").reject do |f| 20 | f.match(%r{^(test|spec|features)/}) 21 | end 22 | 23 | spec.require_paths = ['lib'] 24 | 25 | spec.add_dependency 'activesupport', '>= 4.2.0' 26 | spec.add_dependency 'bundler' 27 | spec.add_dependency 'rack' 28 | 29 | spec.add_development_dependency 'pry' 30 | spec.add_development_dependency 'rake' 31 | spec.add_development_dependency 'rspec' 32 | spec.add_development_dependency 'rubocop' 33 | end 34 | -------------------------------------------------------------------------------- /lib/graphdoc-ruby.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require_relative './graphdoc_ruby' 4 | -------------------------------------------------------------------------------- /lib/graphdoc-ruby/application.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'rack/response' 4 | 5 | module GraphdocRuby 6 | class Application 7 | Semaphore = Mutex.new 8 | 9 | def self.call(env) 10 | @application ||= new 11 | @application.call(env) 12 | end 13 | 14 | def self.graphdoc 15 | config = GraphdocRuby.config 16 | config.assert_configuration! 17 | 18 | GraphdocRuby::Graphdoc.new( 19 | output: config.output_directory, 20 | executable: config.executable_path, 21 | endpoint: config.endpoint, 22 | overwrite: config.overwrite, 23 | mtime: config.mtime, 24 | query: config.evaluate_graphql_query, 25 | context: config.evaluate_graphql_context 26 | ) 27 | end 28 | 29 | def initialize 30 | generate_html if GraphdocRuby.config.run_time_generation 31 | 32 | @static = GraphdocRuby::Static.new(GraphdocRuby.config.output_directory) 33 | end 34 | 35 | def call(env) 36 | serve_static_file(env) || not_found 37 | end 38 | 39 | private 40 | 41 | def generate_html 42 | Semaphore.synchronize do 43 | if should_generate_schema_json? 44 | GraphdocRuby::GraphqlJson.write_schema_json 45 | end 46 | 47 | self.class.graphdoc.generate_document! 48 | end 49 | end 50 | 51 | def should_generate_schema_json? 52 | !GraphdocRuby::Utils.valid_url?(GraphdocRuby.config.endpoint) && !GraphdocRuby::Utils.file_exist?(GraphdocRuby.config.endpoint) 53 | end 54 | 55 | def not_found 56 | if GraphdocRuby.config.run_time_generation 57 | [404, { 'Content-Type' => 'text/html' }, ['Not found generated html']] 58 | else 59 | [404, { 'Content-Type' => 'text/html' }, ['Not found generated html. Please run `rake graphdoc:generate`']] 60 | end 61 | end 62 | 63 | def serve_static_file(env) 64 | request = Rack::Request.new(env) 65 | return unless request.get? || request.head? 66 | return redirect_to_slash_path(env) if html_access_without_slash?(env) 67 | 68 | path = request.path_info.chomp('/') 69 | match = @static.match?(path) 70 | 71 | if match 72 | request.path_info = match 73 | @static.serve(request) 74 | end 75 | end 76 | 77 | def html_access_without_slash?(env) 78 | original_path = env[Rack::REQUEST_PATH] 79 | File.extname(original_path).empty? && !original_path.end_with?('/') 80 | end 81 | 82 | # Unfortunately, html generated by graphdoc contains relative path. 83 | def redirect_to_slash_path(env) 84 | path = env[Rack::REQUEST_PATH] + '/' 85 | 86 | response = Rack::Response.new 87 | response.redirect(path) 88 | response.finish 89 | end 90 | end 91 | end 92 | -------------------------------------------------------------------------------- /lib/graphdoc-ruby/config.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'bundler' 4 | 5 | module GraphdocRuby 6 | class Config 7 | class InvalidConfiguration < StandardError; end 8 | 9 | # Required: 10 | # GraphQL endpoint url or dumped schema.json path. 11 | attr_reader :endpoint 12 | 13 | # Optional: 14 | # Executable path of `graphdoc`. 15 | # (default: `Bundler.which('graphdoc')`) 16 | attr_accessor :executable_path 17 | 18 | # Optional: 19 | # Output path for `graphdoc`. If you disabled run_time_generation, this value must be customized. 20 | # (default: `File.join(Dir.mktmpdir, 'graphdoc')`) 21 | attr_reader :output_directory 22 | 23 | # Optional: 24 | # Overwrite files if generated html already exist. 25 | # (default: true) 26 | attr_accessor :overwrite 27 | 28 | # Optional: 29 | # Generate html with graphdoc on the first access. 30 | # (default: true) 31 | attr_accessor :run_time_generation 32 | 33 | # Optional: 34 | # Context of your graphql. 35 | # (default: -> {}) 36 | attr_accessor :graphql_context 37 | 38 | # Optional: 39 | # Query of your graphql. 40 | # (default: -> {}) 41 | attr_accessor :graphql_query 42 | 43 | # Optional: 44 | # Schema name of your graphql-ruby. It is necessary when generating schema.json. 45 | # (default: nil) 46 | attr_accessor :schema_name 47 | 48 | # no doc 49 | attr_reader :mtime 50 | 51 | def initialize 52 | self.endpoint = nil 53 | self.executable_path = Bundler.which('graphdoc') 54 | self.output_directory = default_output_directory 55 | self.overwrite = true 56 | self.run_time_generation = true 57 | self.schema_name = nil 58 | self.graphql_context = -> {} 59 | self.graphql_query = -> {} 60 | 61 | @use_temporary_output_directory = true 62 | @mtime = Time.now 63 | end 64 | 65 | def endpoint=(value) 66 | @endpoint = value.to_s 67 | end 68 | 69 | def output_directory=(value) 70 | @output_directory = value.to_s 71 | @use_temporary_output_directory = false 72 | end 73 | 74 | def evaluate_graphql_context 75 | hash = graphql_context.call 76 | hash if hash.is_a?(Hash) 77 | end 78 | 79 | def evaluate_graphql_query 80 | hash = graphql_query.call 81 | hash if hash.is_a?(Hash) 82 | end 83 | 84 | def assert_configuration! 85 | unless endpoint 86 | raise InvalidConfiguration, "(endpoint: '#{endpoint}') must be GraphQL endpoint url or dumped schema.json path." 87 | end 88 | 89 | if @use_temporary_output_directory && !run_time_generation 90 | raise InvalidConfiguration, 'If you disabled run_time_generation, static `output_directory` must be set.' 91 | end 92 | 93 | unless File.executable?(executable_path) 94 | raise InvalidConfiguration, '`graphdoc` not found. Please install graphdoc (npm install -g @2fd/graphdoc)' 95 | end 96 | end 97 | 98 | private 99 | 100 | def default_output_directory 101 | File.join(Dir.mktmpdir, 'graphdoc') 102 | end 103 | end 104 | end 105 | -------------------------------------------------------------------------------- /lib/graphdoc-ruby/graphdoc.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'open3' 4 | module GraphdocRuby 5 | class Graphdoc 6 | # rubocop:disable all 7 | def initialize(output:, endpoint:, overwrite:, executable:, mtime:, query: {}, context: {}) 8 | @endpoint = endpoint 9 | @executable = executable 10 | @overwrite = overwrite 11 | @mtime = mtime 12 | 13 | @output_html = File.join(output, 'index.html') 14 | @options = ['--output', output] 15 | @options += ['--force'] if overwrite 16 | 17 | if query && !query.empty? 18 | query.each do |key_value| 19 | @options += ['--query', key_value.join('=')] 20 | end 21 | end 22 | 23 | if context && !context.empty? 24 | context.each do |key_value| 25 | @options += ['--header', key_value.join(': ')] 26 | end 27 | end 28 | end 29 | # rubocop:enable all 30 | 31 | def generate_document! 32 | return if generated? 33 | 34 | message, status = Open3.capture2e(*command) 35 | raise "Command failed. (#{command}) '#{message}'" unless status.success? 36 | end 37 | 38 | private 39 | 40 | def generated? 41 | GraphdocRuby::Utils.file_exist?(@output_html) && (!@overwrite || (@overwrite && regenerated?)) 42 | end 43 | 44 | def regenerated? 45 | File::Stat.new(@output_html).mtime >= @mtime 46 | rescue Errno::ENOENT 47 | false 48 | end 49 | 50 | def command 51 | if GraphdocRuby::Utils.valid_url?(@endpoint) 52 | [@executable, '--endpoint', @endpoint, *@options] 53 | elsif GraphdocRuby::Utils.file_exist?(@endpoint) 54 | [@executable, '--schema-file', @endpoint, *@options] 55 | else 56 | raise "Invalid endpoint given. endpoint(#{@endpoint}) must be valid URL or existing schema file" 57 | end 58 | end 59 | end 60 | end 61 | -------------------------------------------------------------------------------- /lib/graphdoc-ruby/graphql_json.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'fileutils' 4 | 5 | module GraphdocRuby 6 | class GraphqlJson 7 | def self.write_schema_json 8 | context = GraphdocRuby.config.evaluate_graphql_context || {} 9 | 10 | new( 11 | GraphdocRuby.config.schema_name, 12 | GraphdocRuby.config.endpoint, 13 | context 14 | ).write_json 15 | end 16 | 17 | def initialize(schema_name, output_file, context = {}) 18 | @schema_name = schema_name 19 | @output_file = output_file 20 | @context = context 21 | end 22 | 23 | def write_json 24 | json = schema.to_json(context: @context) 25 | 26 | directory = File.dirname(@output_file) 27 | FileUtils.mkdir_p(directory) 28 | 29 | File.write(@output_file, json) 30 | end 31 | 32 | private 33 | 34 | def schema 35 | @schema ||= Object.const_get(@schema_name.to_s) 36 | rescue StandardError 37 | raise GraphdocRuby::Config::InvalidConfiguration, "(schema_name: #{@schema_name}) must be GraphQL Schema" 38 | end 39 | end 40 | end 41 | -------------------------------------------------------------------------------- /lib/graphdoc-ruby/railtie.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module GraphdocRuby 4 | class Railtie < Rails::Railtie 5 | rake_tasks do 6 | require 'graphdoc-ruby/rake_task' 7 | 8 | GraphdocRuby::RakeTask.new 9 | end 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /lib/graphdoc-ruby/rake_task.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'graphdoc-ruby' 4 | 5 | module GraphdocRuby 6 | class RakeTask 7 | include Rake::DSL 8 | 9 | # Set the parameters of this task by passing keyword arguments 10 | # or assigning attributes inside the block 11 | def initialize 12 | dependencies = if defined?(::Rails) 13 | [:environment] 14 | else 15 | [] 16 | end 17 | 18 | define_tasks(dependencies) 19 | end 20 | 21 | private 22 | 23 | # rubocop:disable all 24 | def define_tasks(dependencies) 25 | namespace :graphdoc do 26 | desc 'Dump GraphQL schema to endpoint' 27 | task dump_schema: dependencies do 28 | require 'graphdoc-ruby/graphql_json' 29 | raise(ArgumentError, 'GraphdocRuby.config.schema_name is required.') unless GraphdocRuby.config.schema_name 30 | 31 | puts "-- Write schema.json to #{GraphdocRuby.config.endpoint}" 32 | GraphdocRuby::GraphqlJson.write_schema_json 33 | end 34 | 35 | desc 'Generate html with graphdoc' 36 | task generate: dependencies do 37 | puts "-- Generate html with graphdoc from #{GraphdocRuby.config.endpoint}" 38 | GraphdocRuby::Application.graphdoc.generate_document! 39 | puts "-- Generated html to #{GraphdocRuby.config.output_directory}" 40 | end 41 | end 42 | end 43 | # rubocop:enable all 44 | end 45 | end 46 | -------------------------------------------------------------------------------- /lib/graphdoc-ruby/static.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'rack/utils' 4 | require 'active_support/core_ext/uri' 5 | 6 | module GraphdocRuby 7 | class Static 8 | def initialize(root, headers: {}) 9 | @root = root.chomp('/') 10 | @file_server = ::Rack::File.new(@root, headers) 11 | end 12 | 13 | def match?(path) 14 | path = ::Rack::Utils.unescape_path(path) 15 | return false unless ::Rack::Utils.valid_path? path 16 | path = ::Rack::Utils.clean_path_info(path) 17 | 18 | candidate_paths = [path, "#{path}.html", "#{path}/index.html"] 19 | 20 | match = candidate_paths.detect do |candidate_path| 21 | absolute_path = File.join(@root, candidate_path.dup.force_encoding(Encoding::UTF_8)) 22 | 23 | begin 24 | File.file?(absolute_path) && File.readable?(absolute_path) 25 | rescue SystemCallError 26 | false 27 | end 28 | end 29 | 30 | ::Rack::Utils.escape_path(match) if match 31 | end 32 | 33 | def serve(request) 34 | @file_server.call(request.env) 35 | end 36 | end 37 | end 38 | -------------------------------------------------------------------------------- /lib/graphdoc-ruby/utils.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module GraphdocRuby 4 | module Utils 5 | def self.valid_url?(url) 6 | uri = URI.parse(url) 7 | uri.host 8 | rescue StandardError 9 | false 10 | end 11 | 12 | def self.file_exist?(path) 13 | File.exist?(path) 14 | end 15 | end 16 | end 17 | -------------------------------------------------------------------------------- /lib/graphdoc-ruby/version.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module GraphdocRuby 4 | VERSION = '0.1.0' 5 | end 6 | -------------------------------------------------------------------------------- /lib/graphdoc_ruby.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'rack' 4 | require 'graphdoc-ruby/utils' 5 | require 'graphdoc-ruby/graphdoc' 6 | require 'graphdoc-ruby/static' 7 | require 'graphdoc-ruby/application' 8 | require 'graphdoc-ruby/config' 9 | require 'graphdoc-ruby/graphql_json' 10 | require 'graphdoc-ruby/version' 11 | 12 | module GraphdocRuby 13 | def self.config 14 | @config ||= GraphdocRuby::Config.new 15 | end 16 | 17 | def self.configure 18 | yield(config) 19 | end 20 | end 21 | 22 | require 'graphdoc-ruby/railtie' if defined?(Rails) 23 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "graphdoc-ruby", 3 | "private": true, 4 | "dependencies": { 5 | "@2fd/graphdoc": "^2.4.0" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /spec/graphdoc-ruby/version_spec.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'spec_helper' 4 | 5 | RSpec.describe 'GraphdocRuby::VERSION' do 6 | it 'has a version number' do 7 | expect(GraphdocRuby::VERSION).not_to be nil 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /spec/spec_helper.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'bundler/setup' 4 | require 'graphdoc-ruby' 5 | 6 | RSpec.configure do |config| 7 | config.disable_monkey_patching! 8 | 9 | config.expect_with :rspec do |c| 10 | c.syntax = :expect 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /yarn.lock: -------------------------------------------------------------------------------- 1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. 2 | # yarn lockfile v1 3 | 4 | 5 | "@2fd/command@^1.1.2": 6 | version "1.1.2" 7 | resolved "https://registry.yarnpkg.com/@2fd/command/-/command-1.1.2.tgz#b831d511bdd3b4e2d88139aaddb06d3d6aa0b08a" 8 | 9 | "@2fd/graphdoc@^2.4.0": 10 | version "2.4.0" 11 | resolved "https://registry.yarnpkg.com/@2fd/graphdoc/-/graphdoc-2.4.0.tgz#ebfabd0b09487ce9db8db901a66f1917a025a808" 12 | dependencies: 13 | "@2fd/command" "^1.1.2" 14 | bluebird "^3.5.0" 15 | fs-extra "^0.30.0" 16 | glob "^7.1.0" 17 | graphql "^0.7.0" 18 | marked "^0.3.6" 19 | mustache "^2.2.1" 20 | request "^2.79.0" 21 | slug "^0.9.1" 22 | striptags "^3.0.1" 23 | word-wrap "^1.2.1" 24 | 25 | ajv@^5.1.0: 26 | version "5.5.2" 27 | resolved "https://registry.yarnpkg.com/ajv/-/ajv-5.5.2.tgz#73b5eeca3fab653e3d3f9422b341ad42205dc965" 28 | dependencies: 29 | co "^4.6.0" 30 | fast-deep-equal "^1.0.0" 31 | fast-json-stable-stringify "^2.0.0" 32 | json-schema-traverse "^0.3.0" 33 | 34 | asn1@~0.2.3: 35 | version "0.2.3" 36 | resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.3.tgz#dac8787713c9966849fc8180777ebe9c1ddf3b86" 37 | 38 | assert-plus@1.0.0, assert-plus@^1.0.0: 39 | version "1.0.0" 40 | resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" 41 | 42 | asynckit@^0.4.0: 43 | version "0.4.0" 44 | resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" 45 | 46 | aws-sign2@~0.7.0: 47 | version "0.7.0" 48 | resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8" 49 | 50 | aws4@^1.6.0: 51 | version "1.6.0" 52 | resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.6.0.tgz#83ef5ca860b2b32e4a0deedee8c771b9db57471e" 53 | 54 | balanced-match@^1.0.0: 55 | version "1.0.0" 56 | resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" 57 | 58 | bcrypt-pbkdf@^1.0.0: 59 | version "1.0.1" 60 | resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz#63bc5dcb61331b92bc05fd528953c33462a06f8d" 61 | dependencies: 62 | tweetnacl "^0.14.3" 63 | 64 | bluebird@^3.5.0: 65 | version "3.5.1" 66 | resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.5.1.tgz#d9551f9de98f1fcda1e683d17ee91a0602ee2eb9" 67 | 68 | boom@4.x.x: 69 | version "4.3.1" 70 | resolved "https://registry.yarnpkg.com/boom/-/boom-4.3.1.tgz#4f8a3005cb4a7e3889f749030fd25b96e01d2e31" 71 | dependencies: 72 | hoek "4.x.x" 73 | 74 | boom@5.x.x: 75 | version "5.2.0" 76 | resolved "https://registry.yarnpkg.com/boom/-/boom-5.2.0.tgz#5dd9da6ee3a5f302077436290cb717d3f4a54e02" 77 | dependencies: 78 | hoek "4.x.x" 79 | 80 | brace-expansion@^1.1.7: 81 | version "1.1.8" 82 | resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.8.tgz#c07b211c7c952ec1f8efd51a77ef0d1d3990a292" 83 | dependencies: 84 | balanced-match "^1.0.0" 85 | concat-map "0.0.1" 86 | 87 | caseless@~0.12.0: 88 | version "0.12.0" 89 | resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" 90 | 91 | co@^4.6.0: 92 | version "4.6.0" 93 | resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" 94 | 95 | combined-stream@^1.0.5, combined-stream@~1.0.5: 96 | version "1.0.5" 97 | resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.5.tgz#938370a57b4a51dea2c77c15d5c5fdf895164009" 98 | dependencies: 99 | delayed-stream "~1.0.0" 100 | 101 | concat-map@0.0.1: 102 | version "0.0.1" 103 | resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" 104 | 105 | core-util-is@1.0.2: 106 | version "1.0.2" 107 | resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" 108 | 109 | cryptiles@3.x.x: 110 | version "3.1.2" 111 | resolved "https://registry.yarnpkg.com/cryptiles/-/cryptiles-3.1.2.tgz#a89fbb220f5ce25ec56e8c4aa8a4fd7b5b0d29fe" 112 | dependencies: 113 | boom "5.x.x" 114 | 115 | dashdash@^1.12.0: 116 | version "1.14.1" 117 | resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0" 118 | dependencies: 119 | assert-plus "^1.0.0" 120 | 121 | delayed-stream@~1.0.0: 122 | version "1.0.0" 123 | resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" 124 | 125 | ecc-jsbn@~0.1.1: 126 | version "0.1.1" 127 | resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz#0fc73a9ed5f0d53c38193398523ef7e543777505" 128 | dependencies: 129 | jsbn "~0.1.0" 130 | 131 | extend@~3.0.1: 132 | version "3.0.1" 133 | resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.1.tgz#a755ea7bc1adfcc5a31ce7e762dbaadc5e636444" 134 | 135 | extsprintf@1.3.0: 136 | version "1.3.0" 137 | resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05" 138 | 139 | extsprintf@^1.2.0: 140 | version "1.4.0" 141 | resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.0.tgz#e2689f8f356fad62cca65a3a91c5df5f9551692f" 142 | 143 | fast-deep-equal@^1.0.0: 144 | version "1.0.0" 145 | resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-1.0.0.tgz#96256a3bc975595eb36d82e9929d060d893439ff" 146 | 147 | fast-json-stable-stringify@^2.0.0: 148 | version "2.0.0" 149 | resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz#d5142c0caee6b1189f87d3a76111064f86c8bbf2" 150 | 151 | forever-agent@~0.6.1: 152 | version "0.6.1" 153 | resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" 154 | 155 | form-data@~2.3.1: 156 | version "2.3.1" 157 | resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.1.tgz#6fb94fbd71885306d73d15cc497fe4cc4ecd44bf" 158 | dependencies: 159 | asynckit "^0.4.0" 160 | combined-stream "^1.0.5" 161 | mime-types "^2.1.12" 162 | 163 | fs-extra@^0.30.0: 164 | version "0.30.0" 165 | resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-0.30.0.tgz#f233ffcc08d4da7d432daa449776989db1df93f0" 166 | dependencies: 167 | graceful-fs "^4.1.2" 168 | jsonfile "^2.1.0" 169 | klaw "^1.0.0" 170 | path-is-absolute "^1.0.0" 171 | rimraf "^2.2.8" 172 | 173 | fs.realpath@^1.0.0: 174 | version "1.0.0" 175 | resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" 176 | 177 | getpass@^0.1.1: 178 | version "0.1.7" 179 | resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa" 180 | dependencies: 181 | assert-plus "^1.0.0" 182 | 183 | glob@^7.0.5, glob@^7.1.0: 184 | version "7.1.2" 185 | resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.2.tgz#c19c9df9a028702d678612384a6552404c636d15" 186 | dependencies: 187 | fs.realpath "^1.0.0" 188 | inflight "^1.0.4" 189 | inherits "2" 190 | minimatch "^3.0.4" 191 | once "^1.3.0" 192 | path-is-absolute "^1.0.0" 193 | 194 | graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.1.9: 195 | version "4.1.11" 196 | resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.11.tgz#0e8bdfe4d1ddb8854d64e04ea7c00e2a026e5658" 197 | 198 | graphql@^0.7.0: 199 | version "0.7.2" 200 | resolved "https://registry.yarnpkg.com/graphql/-/graphql-0.7.2.tgz#cc894a32823399b8a0cb012b9e9ecad35cd00f72" 201 | dependencies: 202 | iterall "1.0.2" 203 | 204 | har-schema@^2.0.0: 205 | version "2.0.0" 206 | resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92" 207 | 208 | har-validator@~5.0.3: 209 | version "5.0.3" 210 | resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.0.3.tgz#ba402c266194f15956ef15e0fcf242993f6a7dfd" 211 | dependencies: 212 | ajv "^5.1.0" 213 | har-schema "^2.0.0" 214 | 215 | hawk@~6.0.2: 216 | version "6.0.2" 217 | resolved "https://registry.yarnpkg.com/hawk/-/hawk-6.0.2.tgz#af4d914eb065f9b5ce4d9d11c1cb2126eecc3038" 218 | dependencies: 219 | boom "4.x.x" 220 | cryptiles "3.x.x" 221 | hoek "4.x.x" 222 | sntp "2.x.x" 223 | 224 | hoek@4.x.x: 225 | version "4.2.0" 226 | resolved "https://registry.yarnpkg.com/hoek/-/hoek-4.2.0.tgz#72d9d0754f7fe25ca2d01ad8f8f9a9449a89526d" 227 | 228 | http-signature@~1.2.0: 229 | version "1.2.0" 230 | resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1" 231 | dependencies: 232 | assert-plus "^1.0.0" 233 | jsprim "^1.2.2" 234 | sshpk "^1.7.0" 235 | 236 | inflight@^1.0.4: 237 | version "1.0.6" 238 | resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" 239 | dependencies: 240 | once "^1.3.0" 241 | wrappy "1" 242 | 243 | inherits@2: 244 | version "2.0.3" 245 | resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" 246 | 247 | is-typedarray@~1.0.0: 248 | version "1.0.0" 249 | resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" 250 | 251 | isstream@~0.1.2: 252 | version "0.1.2" 253 | resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" 254 | 255 | iterall@1.0.2: 256 | version "1.0.2" 257 | resolved "https://registry.yarnpkg.com/iterall/-/iterall-1.0.2.tgz#41a2e96ce9eda5e61c767ee5dc312373bb046e91" 258 | 259 | jsbn@~0.1.0: 260 | version "0.1.1" 261 | resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" 262 | 263 | json-schema-traverse@^0.3.0: 264 | version "0.3.1" 265 | resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz#349a6d44c53a51de89b40805c5d5e59b417d3340" 266 | 267 | json-schema@0.2.3: 268 | version "0.2.3" 269 | resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13" 270 | 271 | json-stringify-safe@~5.0.1: 272 | version "5.0.1" 273 | resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" 274 | 275 | jsonfile@^2.1.0: 276 | version "2.4.0" 277 | resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-2.4.0.tgz#3736a2b428b87bbda0cc83b53fa3d633a35c2ae8" 278 | optionalDependencies: 279 | graceful-fs "^4.1.6" 280 | 281 | jsprim@^1.2.2: 282 | version "1.4.1" 283 | resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2" 284 | dependencies: 285 | assert-plus "1.0.0" 286 | extsprintf "1.3.0" 287 | json-schema "0.2.3" 288 | verror "1.10.0" 289 | 290 | klaw@^1.0.0: 291 | version "1.3.1" 292 | resolved "https://registry.yarnpkg.com/klaw/-/klaw-1.3.1.tgz#4088433b46b3b1ba259d78785d8e96f73ba02439" 293 | optionalDependencies: 294 | graceful-fs "^4.1.9" 295 | 296 | marked@^0.3.6: 297 | version "0.3.9" 298 | resolved "https://registry.yarnpkg.com/marked/-/marked-0.3.9.tgz#54ce6a57e720c3ac6098374ec625fcbcc97ff290" 299 | 300 | mime-db@~1.30.0: 301 | version "1.30.0" 302 | resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.30.0.tgz#74c643da2dd9d6a45399963465b26d5ca7d71f01" 303 | 304 | mime-types@^2.1.12, mime-types@~2.1.17: 305 | version "2.1.17" 306 | resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.17.tgz#09d7a393f03e995a79f8af857b70a9e0ab16557a" 307 | dependencies: 308 | mime-db "~1.30.0" 309 | 310 | minimatch@^3.0.4: 311 | version "3.0.4" 312 | resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" 313 | dependencies: 314 | brace-expansion "^1.1.7" 315 | 316 | mustache@^2.2.1: 317 | version "2.3.0" 318 | resolved "https://registry.yarnpkg.com/mustache/-/mustache-2.3.0.tgz#4028f7778b17708a489930a6e52ac3bca0da41d0" 319 | 320 | oauth-sign@~0.8.2: 321 | version "0.8.2" 322 | resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.8.2.tgz#46a6ab7f0aead8deae9ec0565780b7d4efeb9d43" 323 | 324 | once@^1.3.0: 325 | version "1.4.0" 326 | resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" 327 | dependencies: 328 | wrappy "1" 329 | 330 | path-is-absolute@^1.0.0: 331 | version "1.0.1" 332 | resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" 333 | 334 | performance-now@^2.1.0: 335 | version "2.1.0" 336 | resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" 337 | 338 | punycode@^1.4.1: 339 | version "1.4.1" 340 | resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e" 341 | 342 | qs@~6.5.1: 343 | version "6.5.1" 344 | resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.1.tgz#349cdf6eef89ec45c12d7d5eb3fc0c870343a6d8" 345 | 346 | request@^2.79.0: 347 | version "2.83.0" 348 | resolved "https://registry.yarnpkg.com/request/-/request-2.83.0.tgz#ca0b65da02ed62935887808e6f510381034e3356" 349 | dependencies: 350 | aws-sign2 "~0.7.0" 351 | aws4 "^1.6.0" 352 | caseless "~0.12.0" 353 | combined-stream "~1.0.5" 354 | extend "~3.0.1" 355 | forever-agent "~0.6.1" 356 | form-data "~2.3.1" 357 | har-validator "~5.0.3" 358 | hawk "~6.0.2" 359 | http-signature "~1.2.0" 360 | is-typedarray "~1.0.0" 361 | isstream "~0.1.2" 362 | json-stringify-safe "~5.0.1" 363 | mime-types "~2.1.17" 364 | oauth-sign "~0.8.2" 365 | performance-now "^2.1.0" 366 | qs "~6.5.1" 367 | safe-buffer "^5.1.1" 368 | stringstream "~0.0.5" 369 | tough-cookie "~2.3.3" 370 | tunnel-agent "^0.6.0" 371 | uuid "^3.1.0" 372 | 373 | rimraf@^2.2.8: 374 | version "2.6.2" 375 | resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.2.tgz#2ed8150d24a16ea8651e6d6ef0f47c4158ce7a36" 376 | dependencies: 377 | glob "^7.0.5" 378 | 379 | safe-buffer@^5.0.1, safe-buffer@^5.1.1: 380 | version "5.1.1" 381 | resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.1.tgz#893312af69b2123def71f57889001671eeb2c853" 382 | 383 | slug@^0.9.1: 384 | version "0.9.1" 385 | resolved "https://registry.yarnpkg.com/slug/-/slug-0.9.1.tgz#af08f608a7c11516b61778aa800dce84c518cfda" 386 | dependencies: 387 | unicode ">= 0.3.1" 388 | 389 | sntp@2.x.x: 390 | version "2.1.0" 391 | resolved "https://registry.yarnpkg.com/sntp/-/sntp-2.1.0.tgz#2c6cec14fedc2222739caf9b5c3d85d1cc5a2cc8" 392 | dependencies: 393 | hoek "4.x.x" 394 | 395 | sshpk@^1.7.0: 396 | version "1.13.1" 397 | resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.13.1.tgz#512df6da6287144316dc4c18fe1cf1d940739be3" 398 | dependencies: 399 | asn1 "~0.2.3" 400 | assert-plus "^1.0.0" 401 | dashdash "^1.12.0" 402 | getpass "^0.1.1" 403 | optionalDependencies: 404 | bcrypt-pbkdf "^1.0.0" 405 | ecc-jsbn "~0.1.1" 406 | jsbn "~0.1.0" 407 | tweetnacl "~0.14.0" 408 | 409 | stringstream@~0.0.5: 410 | version "0.0.5" 411 | resolved "https://registry.yarnpkg.com/stringstream/-/stringstream-0.0.5.tgz#4e484cd4de5a0bbbee18e46307710a8a81621878" 412 | 413 | striptags@^3.0.1: 414 | version "3.1.1" 415 | resolved "https://registry.yarnpkg.com/striptags/-/striptags-3.1.1.tgz#c8c3e7fdd6fb4bb3a32a3b752e5b5e3e38093ebd" 416 | 417 | tough-cookie@~2.3.3: 418 | version "2.3.3" 419 | resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.3.3.tgz#0b618a5565b6dea90bf3425d04d55edc475a7561" 420 | dependencies: 421 | punycode "^1.4.1" 422 | 423 | tunnel-agent@^0.6.0: 424 | version "0.6.0" 425 | resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" 426 | dependencies: 427 | safe-buffer "^5.0.1" 428 | 429 | tweetnacl@^0.14.3, tweetnacl@~0.14.0: 430 | version "0.14.5" 431 | resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" 432 | 433 | "unicode@>= 0.3.1": 434 | version "10.0.0" 435 | resolved "https://registry.yarnpkg.com/unicode/-/unicode-10.0.0.tgz#e5d51c1db93b6c71a0b879e0b0c4af7e6fdf688e" 436 | 437 | uuid@^3.1.0: 438 | version "3.1.0" 439 | resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.1.0.tgz#3dd3d3e790abc24d7b0d3a034ffababe28ebbc04" 440 | 441 | verror@1.10.0: 442 | version "1.10.0" 443 | resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400" 444 | dependencies: 445 | assert-plus "^1.0.0" 446 | core-util-is "1.0.2" 447 | extsprintf "^1.2.0" 448 | 449 | word-wrap@^1.2.1: 450 | version "1.2.3" 451 | resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c" 452 | 453 | wrappy@1: 454 | version "1.0.2" 455 | resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" 456 | --------------------------------------------------------------------------------