danger-wcc 0.0.6 → 0.1.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (31) hide show
  1. checksums.yaml +4 -4
  2. data/danger-wcc.gemspec +6 -3
  3. data/lib/version.rb +1 -1
  4. data/lib/wcc/dependencies.rb +100 -0
  5. data/lib/wcc/plugin.rb +18 -3
  6. data/lib/wcc/util/yarn_info.rb +98 -0
  7. data/lib/wcc/utils.rb +16 -4
  8. data/lib/wcc/yarn_deduplicate.rb +71 -0
  9. data/spec/fixtures/dependencies/package.json +112 -0
  10. data/spec/fixtures/dependencies/package.json.diff +28 -0
  11. data/spec/fixtures/dependencies/package.json_patch_bumps_minor.diff +13 -0
  12. data/spec/fixtures/dependencies/package.json_patch_bumps_minor.json +112 -0
  13. data/spec/fixtures/dependencies/package.json_second_level_effect.diff +17 -0
  14. data/spec/fixtures/dependencies/package.json_second_level_effect.json +133 -0
  15. data/spec/fixtures/dependencies/yarn.lock +19609 -0
  16. data/spec/fixtures/dependencies/yarn.lock_patch_bumps_minor.lock +19614 -0
  17. data/spec/fixtures/dependencies/yarn.lock_second_level_effect.lock +20022 -0
  18. data/spec/fixtures/dependencies/yarn_list_second_level_effect.txt +1243 -0
  19. data/spec/fixtures/dependencies/yarn_list_second_level_effect.txt.diff +141 -0
  20. data/spec/fixtures/dependencies/yarn_minor_version.diff +33 -0
  21. data/spec/fixtures/dependencies/yarn_minor_version.txt +1151 -0
  22. data/spec/fixtures/dependencies/yarn_old.txt +1152 -0
  23. data/spec/fixtures/dependencies/yarn_patch_bumps_minor.diff +28 -0
  24. data/spec/fixtures/yarn_deduplicate/list.a.txt +293 -0
  25. data/spec/fixtures/yarn_deduplicate/list.b.txt +295 -0
  26. data/spec/fixtures/yarn_deduplicate/list.diff +11 -0
  27. data/spec/fixtures/yarn_deduplicate/yarn.lock +20031 -0
  28. data/spec/wcc/dependencies_spec.rb +130 -0
  29. data/spec/wcc/plugin_spec.rb +7 -3
  30. data/spec/wcc/yarn_deduplicate_spec.rb +57 -0
  31. metadata +79 -20
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: a19b6ce24d61f5ff2a951f9902122eda8942c8c7
4
- data.tar.gz: e958cfa4740a01893df04a960f902ea5eb541dfc
3
+ metadata.gz: b591a61062c99e268e789682050f9e1aa87d3ac1
4
+ data.tar.gz: ee1ca7bef0b3067130959f806ca289b16c501b16
5
5
  SHA512:
6
- metadata.gz: 2779c8031e0b5dbcc595c07b9bec606c4daab6e94214fa1808909f80819b2f4c95358448adf93b4ec8462c5e1179c981489cfd4eb5be7f48291a4635189e62d3
7
- data.tar.gz: 353a0fb641903e0ce67fc874114976fcd90070a5c28c9c6d81f59682926e874d1ef67236ebe0de64e75f97572353b86fa4b0398ed91155cb0254a7e8787691f4
6
+ metadata.gz: f3e0ea9ae53ae50a0063bfeccec52b3a22cacbd45e95fde82d06c76014850debc5f7f8eb6236dee02dd93cf045d512b22920994348ce7e8a82e0d16be1c06028
7
+ data.tar.gz: d0ff16ef65a8901dfcbd3c5e276ffe692990de9a10c198a75dde29602e0ef476b41006fc71fcb741cf47c51f205f06dfec73effa52c0c7473e173594efcd5c80
data/danger-wcc.gemspec CHANGED
@@ -19,11 +19,14 @@ Gem::Specification.new do |spec|
19
19
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
20
20
  spec.require_paths = ['lib']
21
21
 
22
- spec.add_runtime_dependency 'brakeman'
22
+ spec.add_runtime_dependency 'activesupport', '> 5'
23
23
  spec.add_runtime_dependency 'danger-plugin-api', '~> 1.0'
24
- spec.add_runtime_dependency 'flay'
25
24
  spec.add_runtime_dependency 'git_diff', '~> 0.4'
26
- spec.add_runtime_dependency 'reek'
25
+
26
+ # Optional dependencies
27
+ spec.add_development_dependency 'brakeman'
28
+ spec.add_development_dependency 'flay'
29
+ spec.add_development_dependency 'reek'
27
30
 
28
31
  # General ruby development
29
32
  spec.add_development_dependency 'bundler', '~> 1.3'
data/lib/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module DangerWCC
4
- VERSION = '0.0.6'
4
+ VERSION = '0.1.3'
5
5
  end
@@ -0,0 +1,100 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'active_support'
4
+ require_relative 'utils'
5
+
6
+ class Danger::DangerWCC < Danger::Plugin
7
+ class Dependencies
8
+ include Utils
9
+
10
+ DEFAULT_OPTIONS = {
11
+ lockfile: 'yarn.lock',
12
+ severity: :warn
13
+ }.freeze
14
+
15
+ def yarn_info
16
+ @yarn_info ||=
17
+ Danger::DangerWCC::Util::YarnInfo.new(self, @options)
18
+ end
19
+
20
+ def initialize(plugin, options = {})
21
+ @plugin = plugin
22
+ @options = DEFAULT_OPTIONS.merge(options)
23
+ end
24
+
25
+ def perform
26
+ return unless File.exist?(@options[:lockfile])
27
+
28
+ find_yarn_violations
29
+ end
30
+
31
+ private
32
+
33
+ def issue_yarn_violation(package, versions)
34
+ line_index = yarn_info.find_index_in_lockfile(package, versions[1])
35
+
36
+ msg = "Dangerous change! #{package} was updated "\
37
+ "from #{versions[0]} to #{versions[1]}"\
38
+ ' without a corresponding change to package.json!'
39
+ plugin.public_send(
40
+ @options[:severity],
41
+ msg,
42
+ file: @options[:lockfile],
43
+ line: line_index
44
+ )
45
+ end
46
+
47
+ def find_yarn_violations # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
48
+ # if there are any explicit major version changes in top level deps,
49
+ # say nothing about anything b/c it'll likely be noisy
50
+ has_explicit_mods =
51
+ yarn_info.modified_yarn_dependencies
52
+ .slice(*yarn_info.package_json_changes)
53
+ .any? { |_, v| major_version_change?(v[0], v[1]) }
54
+ return if has_explicit_mods
55
+
56
+ # Do say something if top level minor version change induces dangerous
57
+ # changes in other deps
58
+
59
+ mods =
60
+ yarn_info.modified_yarn_dependencies
61
+ .select { |_, versions| dangerous_change?(versions[0], versions[1]) }
62
+
63
+ has_dangerous_top_level_changes = false
64
+ mods.slice(*yarn_info.package_json_dependencies)
65
+ .each do |package, versions|
66
+ has_dangerous_top_level_changes = true
67
+ issue_yarn_violation(package, versions)
68
+ end
69
+
70
+ # issue warnings if a sub-dependency changed without a dangerous change in
71
+ # a top level dependency
72
+ return if has_dangerous_top_level_changes
73
+
74
+ mods.except(*yarn_info.package_json_dependencies)
75
+ .each do |package, versions|
76
+ issue_yarn_violation(package, versions)
77
+ end
78
+ end
79
+
80
+ def major_version_change?(old_version, new_version)
81
+ return false unless new_version
82
+
83
+ new_version.segments[0] > old_version.segments[0]
84
+ end
85
+
86
+ def dangerous_change?(old_version, new_version)
87
+ # the package was deleted
88
+ return true unless new_version
89
+
90
+ old_segments = old_version.segments
91
+ new_segments = new_version.segments
92
+
93
+ # the major or minor version changed.
94
+ new_segments[0] > old_segments[0] ||
95
+ new_segments[1] > old_segments[1]
96
+ end
97
+ end
98
+ end
99
+
100
+ require_relative './util/yarn_info'
data/lib/wcc/plugin.rb CHANGED
@@ -7,19 +7,24 @@ require_relative 'rubocop_exceptions'
7
7
  require_relative 'commit_lint'
8
8
  require_relative 'reek'
9
9
  require_relative 'jshint'
10
+ require_relative 'dependencies'
11
+ require_relative 'yarn_deduplicate'
10
12
 
11
- class Danger::DangerWCC < Danger::Plugin
13
+ class Danger::DangerWCC < Danger::Plugin # rubocop:disable Metrics/ClassLength
12
14
  include Utils
13
15
  include Github
14
16
 
15
17
  DEFAULT_OPTIONS = {
16
18
  rubocop_exceptions: true,
17
- flay: true,
18
19
  todos: true,
19
20
  brakeman: true,
21
+ dependencies: true,
22
+ yarn_deduplicate: true,
23
+
20
24
  commit_lint: false,
21
25
  reek: false,
22
- jshint: false
26
+ jshint: false,
27
+ flay: false
23
28
  }.freeze
24
29
 
25
30
  # Runs all the included checks in the plugin
@@ -95,6 +100,16 @@ class Danger::DangerWCC < Danger::Plugin
95
100
  Jshint.new(self, options).perform
96
101
  end
97
102
 
103
+ def dependencies(options = {})
104
+ logger.info "dependencies: #{options}"
105
+ Dependencies.new(self, options).perform
106
+ end
107
+
108
+ def yarn_deduplicate(options = {})
109
+ logger.info "yarn_deduplicate: #{options}"
110
+ YarnDeduplicate.new(self, options).perform
111
+ end
112
+
98
113
  private
99
114
 
100
115
  def parse_flay_results
@@ -0,0 +1,98 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Danger::DangerWCC::Util
4
+ class YarnInfo
5
+ def yarn_lock
6
+ @yarn_lock ||= File.readlines(@options[:lockfile] || 'yarn.lock')
7
+ end
8
+
9
+ def package_json_dependencies # rubocop:disable Metrics/AbcSize
10
+ @package_json_dependencies ||=
11
+ begin
12
+ root = JSON.parse(File.read('package.json'))
13
+ (root['dependencies']&.keys || []).tap do |deps|
14
+ workspaces = root['workspaces']
15
+ next unless workspaces && !workspaces.empty?
16
+
17
+ # Add in deps from all workspaces
18
+ workspaces.each do |ws|
19
+ Dir.glob(File.join(ws, 'package.json')).each do |package_file|
20
+ d = JSON.parse(File.read(package_file))['dependencies']&.keys
21
+ deps.concat(d || [])
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
27
+
28
+ def package_json_changes
29
+ @package_json_changes ||= find_package_json_changes
30
+ end
31
+
32
+ def modified_yarn_dependencies
33
+ @modified_yarn_dependencies ||= find_modified_yarn_packages
34
+ end
35
+
36
+ attr_reader :plugin
37
+
38
+ def initialize(plugin, options = nil)
39
+ @plugin = plugin
40
+ @options = options || {}
41
+ end
42
+
43
+ def find_index_in_lockfile(package, version)
44
+ return 0 unless version
45
+
46
+ re = Regexp.new("^\"?#{Regexp.escape(package)}@", Regexp::IGNORECASE)
47
+ indexes =
48
+ yarn_lock.each_with_index
49
+ .select { |l, _i| re.match(l) }
50
+ .map { |pair| pair[1] }
51
+ idx =
52
+ indexes.find do |i|
53
+ yarn_lock[i + 1].include?("version \"#{version}\"")
54
+ end
55
+ (idx || -1) + 1
56
+ end
57
+
58
+ def parse_yarn_semver(line)
59
+ match = /(?<package>\S+)\@(?<version>\S+)/.match(line)
60
+ [match['package'], Gem::Version.new(match['version'])] if match
61
+ end
62
+
63
+ private
64
+
65
+ def find_package_json_changes
66
+ return [] unless file = plugin.find_file_in_diff('package.json')
67
+
68
+ adds = file.hunks.flat_map { |h| h.lines.select(&:addition?) }
69
+ adds.map { |l| /\"(?<package>\S+)\"\: \"\S+\"/.match(l.content) }
70
+ .compact
71
+ .map { |match| match['package'] }
72
+ end
73
+
74
+ def find_modified_yarn_packages # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
75
+ diff = plugin.run_and_diff(
76
+ 'NODE_ENV=production yarn list --depth 0 2>/dev/null'
77
+ )
78
+ diff = GitDiff.from_string(diff)
79
+
80
+ {}.tap do |modified_packages|
81
+ plugin.each_file_in_diff(diff) do |file, _diff|
82
+ file.hunks.each do |hunk|
83
+ deleted, added =
84
+ %i[deletion? addition?].map do |type|
85
+ Hash[hunk.lines.select { |l| l.public_send(type) }
86
+ .map { |l| parse_yarn_semver(l.content) }
87
+ .compact]
88
+ end
89
+ deleted.each do |(package, version)|
90
+ modified_packages[package] =
91
+ [version, added[package]]
92
+ end
93
+ end
94
+ end
95
+ end
96
+ end
97
+ end
98
+ end
data/lib/wcc/utils.rb CHANGED
@@ -22,7 +22,7 @@ module Utils
22
22
  # All the diffs in the PR parsed into GitDiff objects
23
23
  def parsed_diffs
24
24
  @parsed_diffs ||=
25
- plugin.git.diff.map do |d|
25
+ plugin.git.diff&.map do |d|
26
26
  begin
27
27
  GitDiff.from_string(d.patch)
28
28
  rescue StandardError
@@ -32,6 +32,13 @@ module Utils
32
32
  end
33
33
  end
34
34
 
35
+ def find_file_in_diff(filename)
36
+ each_file_in_diff do |file, _diff|
37
+ return file if file.b_path == filename
38
+ end
39
+ nil
40
+ end
41
+
35
42
  # Finds lines in the overall diff matching the given regex, and
36
43
  # executes a block for each matched line.
37
44
  # The results of the yield block are returned as an array.
@@ -52,17 +59,22 @@ module Utils
52
59
 
53
60
  def each_file_in_diff(passed_diff = nil)
54
61
  diffs = passed_diff ? [passed_diff] : parsed_diffs
55
- diffs.flat_map do |diff|
62
+ diffs&.flat_map do |diff|
56
63
  diff.files.flat_map do |file|
57
64
  yield(file, diff)
58
65
  end
59
66
  end
60
67
  end
61
68
 
62
- def each_addition_in_diff(passed_diff = nil)
69
+ def each_addition_in_diff(passed_diff = nil, &block)
70
+ each_line_in_diff(passed_diff, type: :addition, &block)
71
+ end
72
+
73
+ def each_line_in_diff(passed_diff = nil, type: nil)
63
74
  each_file_in_diff(passed_diff) do |file, diff|
64
75
  file.hunks.flat_map do |hunk|
65
- lines = hunk.lines.select(&:addition?)
76
+ lines = hunk.lines
77
+ lines = lines.select { |l| l.public_send("#{type}?") } if type
66
78
  lines = lines.map { |l| yield(l, hunk, file, diff) } if block_given?
67
79
  lines
68
80
  end
@@ -0,0 +1,71 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'utils'
4
+
5
+ class Danger::DangerWCC < Danger::Plugin
6
+ class YarnDeduplicate
7
+ include Utils
8
+
9
+ DEFAULT_OPTIONS = {
10
+ lockfile: 'yarn.lock',
11
+ severity: :warn
12
+ }.freeze
13
+
14
+ def yarn_info
15
+ @yarn_info ||=
16
+ Danger::DangerWCC::Util::YarnInfo.new(self, @options)
17
+ end
18
+
19
+ def initialize(plugin, options = {})
20
+ @plugin = plugin
21
+ @options = DEFAULT_OPTIONS.merge(options)
22
+ end
23
+
24
+ def perform
25
+ diff = run_yarn_deduplicate_diff
26
+
27
+ each_addition_in_diff(diff) do |line|
28
+ add_deduplicate_warning(line)
29
+ end
30
+ end
31
+
32
+ private
33
+
34
+ def run_yarn_deduplicate_diff
35
+ diff =
36
+ run_and_diff do
37
+ run('npx yarn-deduplicate -s fewer --list '\
38
+ "#{@options[:lockfile]}")
39
+ end
40
+ GitDiff.from_string(diff)
41
+ end
42
+
43
+ # rubocop:disable Layout/LineLength
44
+ DEDUPE_REGEXP = /^\+Package \"([^\"]+)\" wants (\S+) and could get (\S+), but got (\S+)$/i.freeze
45
+ # rubocop:enable Layout/LineLength
46
+
47
+ def add_deduplicate_warning(line) # rubocop:disable Metrics/MethodLength
48
+ warning = line.content.match(DEDUPE_REGEXP)
49
+ return unless warning
50
+
51
+ pkg, _semver, wanted, got = warning.captures
52
+
53
+ idx = yarn_info.find_index_in_lockfile(
54
+ pkg, got
55
+ )
56
+ msg = <<~HEREDOC
57
+ You have an opportunity to deduplicate "#{pkg}".
58
+ It's using #{got} but could use the existing version #{wanted}.
59
+
60
+ You can fix this by running :
61
+ `npx yarn-deduplicate -s fewer --packages "#{pkg}"`
62
+ HEREDOC
63
+ plugin.public_send(@options[:severity],
64
+ msg,
65
+ file: @options[:lockfile],
66
+ line: idx)
67
+ end
68
+ end
69
+ end
70
+
71
+ require_relative './util/yarn_info'
@@ -0,0 +1,112 @@
1
+ {
2
+ "name": "paper-signs",
3
+ "private": true,
4
+ "workspaces": [
5
+ ".",
6
+ "packages/*"
7
+ ],
8
+ "scripts": {
9
+ "fix-css": "stylelint app/**/*.scss --syntax scss --fix",
10
+ "fix-js": "tslint --project tsconfig.json app/assets/javascripts/**/*.ts?\\(x\\) --fix",
11
+ "fix": "yarn fix-js && yarn fix-css",
12
+ "check-types": "tsc --noemit",
13
+ "lint": "yarn lint-js && yarn lint-css",
14
+ "lint-css": "stylelint app/**/*.scss --syntax scss",
15
+ "lint-js": "tslint --project tsconfig.json app/assets/javascripts/**/*.ts?\\(x\\)",
16
+ "analyze": "RAILS_ENV=production NODE_ENV=production bin/webpack --profile --json > tmp/stats.json && webpack-bundle-analyzer tmp/stats.json public/packs --exclude server_rendering -m static",
17
+ "test": "jest && NODE_ENV=test karma start --",
18
+ "test-css": "mocha app/assets/stylesheets/true.js",
19
+ "test-watch": "NODE_ENV=test karma start --auto-watch --no-single-run",
20
+ "prepare": "contentful-ts-generator --download=false && for d in packages/*/; do (cd $d; yarn prepare) || exit -1; done"
21
+ },
22
+ "engines": {},
23
+ "dependencies": {
24
+ "@babel/core": "^7.8.3",
25
+ "@babel/plugin-proposal-class-properties": "^7.8.3",
26
+ "@babel/preset-env": "^7.8.3",
27
+ "@babel/preset-react": "^7.8.3",
28
+ "@babel/preset-typescript": "^7.8.3",
29
+ "@rails/webpacker": "^4.0.2",
30
+ "@types/algoliasearch": "^3.30.1",
31
+ "@types/algoliasearch-helper": "^2.26.1",
32
+ "@types/bootstrap": "^4.3.1",
33
+ "@types/bugsnag-js": "^3.1.0",
34
+ "@types/chai": "^4.1.7",
35
+ "@types/chai-jquery": "^1.1.38",
36
+ "@types/enzyme": "^3.1.15",
37
+ "@types/enzyme-adapter-react-16": "^1.0.3",
38
+ "@types/fontfaceobserver": "^0.0.6",
39
+ "@types/i18n-js": "^3.0.1",
40
+ "@types/lodash": "^4.14.134",
41
+ "@types/mocha": "^5.2.5",
42
+ "@types/qs": "^6.5.3",
43
+ "@types/react": "^16.9.34",
44
+ "@types/react-dom": "^16.0.9",
45
+ "@types/react-infinite-scroller": "^1.2.1",
46
+ "@types/react-instantsearch": "^5.2.1",
47
+ "@types/sinon": "^7.0.3",
48
+ "@types/webpack-env": "^1.13.9",
49
+ "@watermarkchurch/contentful-migration": "^1.0.9",
50
+ "@watermarkchurch/react-instantsearch-components": "*",
51
+ "async-toolbox": "^0.6.6",
52
+ "babel-preset-react": "^6.24.1",
53
+ "contentful-export": "^7.4.0",
54
+ "contentful-shell": "^0.2.7",
55
+ "contentful-ts-generator": "^0.2.4",
56
+ "core-js": "3",
57
+ "date-fns": "^1.30.1",
58
+ "enzyme": "^3.7.0",
59
+ "enzyme-adapter-react-16": "^1.7.0",
60
+ "fontfaceobserver": "^2.1.0",
61
+ "html-react-parser": "^0.9.1",
62
+ "i18n-js": "^3.5.1",
63
+ "identity-obj-proxy": "^3.0.0",
64
+ "inflection": "^1.12.0",
65
+ "postcss-cssnext": "^3.1.0",
66
+ "prop-types": "^15.6.2",
67
+ "qs": "^6.7.0",
68
+ "react": "^16.12.0",
69
+ "react-calendar": "^2.19.0",
70
+ "react-dom": "^16.12.0",
71
+ "react-infinite-scroller": "^1.2.2",
72
+ "react-instantsearch": "^5.3.2",
73
+ "react-svg-loader": "^3.0.3",
74
+ "react_ujs": "^2.4.4",
75
+ "sinon": "^7.2.2",
76
+ "typescript": "^3.3.3"
77
+ },
78
+ "devDependencies": {
79
+ "@percy/agent": "^0.28.0",
80
+ "@types/jest": "^25.2.1",
81
+ "@watermarkchurch/contentful-check": "*",
82
+ "@watermarkchurch/load-tester": "*",
83
+ "babel-jest": "^25.5.0",
84
+ "chai": "^4.2.0",
85
+ "chai-jquery": "^2.0.0",
86
+ "graphql-schema-diff": "^0.6.3",
87
+ "hard-source-webpack-plugin": "^0.13.1",
88
+ "jest": "^25.5.0",
89
+ "karma": "^3.1.1",
90
+ "karma-chai": "^0.1.0",
91
+ "karma-chai-jquery": "^1.0.0",
92
+ "karma-chrome-launcher": "^2.2.0",
93
+ "karma-jquery": "^0.2.3",
94
+ "karma-junit-reporter": "^1.2.0",
95
+ "karma-mocha": "^1.3.0",
96
+ "karma-mocha-reporter": "^2.2.5",
97
+ "karma-sourcemap-loader": "^0.3.7",
98
+ "karma-webpack": "^3.0.5",
99
+ "lerna": "^3.13.1",
100
+ "mocha": "^5.2.0",
101
+ "react-test-renderer": "^16.12.0",
102
+ "sass-true": "^4.0.0",
103
+ "stylelint": "^9.6.0",
104
+ "stylelint-config-sass-guidelines": "^5.2.0",
105
+ "stylelint-scss": "^3.3.2",
106
+ "ts-node": "^7.0.1",
107
+ "tslint": "^5.11.0",
108
+ "tslint-eslint-rules": "^5.4.0",
109
+ "webpack-bundle-analyzer": "^3.0.3",
110
+ "webpack-dev-server": "^3.3.1"
111
+ }
112
+ }
@@ -0,0 +1,28 @@
1
+ diff --git a/package.json b/package.json
2
+ index 74d7ad8a..ea999d34 100644
3
+ --- a/package.json
4
+ +++ b/package.json
5
+ @@ -41,7 +41,6 @@
6
+ "@types/mocha": "^5.2.5",
7
+ "@types/qs": "^6.5.3",
8
+ "@types/react": "^16.9.34",
9
+ - "@types/react-autosuggest": "^9.3.6",
10
+ "@types/react-dom": "^16.0.9",
11
+ "@types/react-infinite-scroller": "^1.2.1",
12
+ "@types/react-instantsearch": "^5.2.1",
13
+ @@ -67,7 +66,6 @@
14
+ "prop-types": "^15.6.2",
15
+ "qs": "^6.7.0",
16
+ "react": "^16.12.0",
17
+ - "react-autosuggest": "^9.4.3",
18
+ "react-calendar": "^2.19.0",
19
+ "react-dom": "^16.12.0",
20
+ "react-infinite-scroller": "^1.2.2",
21
+ @@ -78,6 +76,7 @@
22
+ "typescript": "^3.3.3"
23
+ },
24
+ "devDependencies": {
25
+ + "@percy/agent": "^0.28.0",
26
+ "@types/jest": "^25.2.1",
27
+ "@watermarkchurch/contentful-check": "*",
28
+ "@watermarkchurch/load-tester": "*",
@@ -0,0 +1,13 @@
1
+ diff --git a/package.json b/package.json
2
+ index ea999d3..efa8440 100644
3
+ --- a/package.json
4
+ +++ b/package.json
5
+ @@ -69,7 +69,7 @@
6
+ "react-calendar": "^2.19.0",
7
+ "react-dom": "^16.12.0",
8
+ "react-infinite-scroller": "^1.2.2",
9
+ - "react-instantsearch": "^5.3.2",
10
+ + "react-instantsearch": "^5.3.3",
11
+ "react-svg-loader": "^3.0.3",
12
+ "react_ujs": "^2.4.4",
13
+ "sinon": "^7.2.2",
@@ -0,0 +1,112 @@
1
+ {
2
+ "name": "paper-signs",
3
+ "private": true,
4
+ "workspaces": [
5
+ ".",
6
+ "packages/*"
7
+ ],
8
+ "scripts": {
9
+ "fix-css": "stylelint app/**/*.scss --syntax scss --fix",
10
+ "fix-js": "tslint --project tsconfig.json app/assets/javascripts/**/*.ts?\\(x\\) --fix",
11
+ "fix": "yarn fix-js && yarn fix-css",
12
+ "check-types": "tsc --noemit",
13
+ "lint": "yarn lint-js && yarn lint-css",
14
+ "lint-css": "stylelint app/**/*.scss --syntax scss",
15
+ "lint-js": "tslint --project tsconfig.json app/assets/javascripts/**/*.ts?\\(x\\)",
16
+ "analyze": "RAILS_ENV=production NODE_ENV=production bin/webpack --profile --json > tmp/stats.json && webpack-bundle-analyzer tmp/stats.json public/packs --exclude server_rendering -m static",
17
+ "test": "jest && NODE_ENV=test karma start --",
18
+ "test-css": "mocha app/assets/stylesheets/true.js",
19
+ "test-watch": "NODE_ENV=test karma start --auto-watch --no-single-run",
20
+ "prepare": "contentful-ts-generator --download=false && for d in packages/*/; do (cd $d; yarn prepare) || exit -1; done"
21
+ },
22
+ "engines": {},
23
+ "dependencies": {
24
+ "@babel/core": "^7.8.3",
25
+ "@babel/plugin-proposal-class-properties": "^7.8.3",
26
+ "@babel/preset-env": "^7.8.3",
27
+ "@babel/preset-react": "^7.8.3",
28
+ "@babel/preset-typescript": "^7.8.3",
29
+ "@rails/webpacker": "^4.0.2",
30
+ "@types/algoliasearch": "^3.30.1",
31
+ "@types/algoliasearch-helper": "^2.26.1",
32
+ "@types/bootstrap": "^4.3.1",
33
+ "@types/bugsnag-js": "^3.1.0",
34
+ "@types/chai": "^4.1.7",
35
+ "@types/chai-jquery": "^1.1.38",
36
+ "@types/enzyme": "^3.1.15",
37
+ "@types/enzyme-adapter-react-16": "^1.0.3",
38
+ "@types/fontfaceobserver": "^0.0.6",
39
+ "@types/i18n-js": "^3.0.1",
40
+ "@types/lodash": "^4.14.134",
41
+ "@types/mocha": "^5.2.5",
42
+ "@types/qs": "^6.5.3",
43
+ "@types/react": "^16.9.34",
44
+ "@types/react-dom": "^16.0.9",
45
+ "@types/react-infinite-scroller": "^1.2.1",
46
+ "@types/react-instantsearch": "^5.2.1",
47
+ "@types/sinon": "^7.0.3",
48
+ "@types/webpack-env": "^1.13.9",
49
+ "@watermarkchurch/contentful-migration": "^1.0.9",
50
+ "@watermarkchurch/react-instantsearch-components": "*",
51
+ "async-toolbox": "^0.6.6",
52
+ "babel-preset-react": "^6.24.1",
53
+ "contentful-export": "^7.4.0",
54
+ "contentful-shell": "^0.2.7",
55
+ "contentful-ts-generator": "^0.2.4",
56
+ "core-js": "3",
57
+ "date-fns": "^1.30.1",
58
+ "enzyme": "^3.7.0",
59
+ "enzyme-adapter-react-16": "^1.7.0",
60
+ "fontfaceobserver": "^2.1.0",
61
+ "html-react-parser": "^0.9.1",
62
+ "i18n-js": "^3.5.1",
63
+ "identity-obj-proxy": "^3.0.0",
64
+ "inflection": "^1.12.0",
65
+ "postcss-cssnext": "^3.1.0",
66
+ "prop-types": "^15.6.2",
67
+ "qs": "^6.7.0",
68
+ "react": "^16.12.0",
69
+ "react-calendar": "^2.19.0",
70
+ "react-dom": "^16.12.0",
71
+ "react-infinite-scroller": "^1.2.2",
72
+ "react-instantsearch": "^5.3.3",
73
+ "react-svg-loader": "^3.0.3",
74
+ "react_ujs": "^2.4.4",
75
+ "sinon": "^7.2.2",
76
+ "typescript": "^3.3.3"
77
+ },
78
+ "devDependencies": {
79
+ "@percy/agent": "^0.28.0",
80
+ "@types/jest": "^25.2.1",
81
+ "@watermarkchurch/contentful-check": "*",
82
+ "@watermarkchurch/load-tester": "*",
83
+ "babel-jest": "^25.5.0",
84
+ "chai": "^4.2.0",
85
+ "chai-jquery": "^2.0.0",
86
+ "graphql-schema-diff": "^0.6.3",
87
+ "hard-source-webpack-plugin": "^0.13.1",
88
+ "jest": "^25.5.0",
89
+ "karma": "^3.1.1",
90
+ "karma-chai": "^0.1.0",
91
+ "karma-chai-jquery": "^1.0.0",
92
+ "karma-chrome-launcher": "^2.2.0",
93
+ "karma-jquery": "^0.2.3",
94
+ "karma-junit-reporter": "^1.2.0",
95
+ "karma-mocha": "^1.3.0",
96
+ "karma-mocha-reporter": "^2.2.5",
97
+ "karma-sourcemap-loader": "^0.3.7",
98
+ "karma-webpack": "^3.0.5",
99
+ "lerna": "^3.13.1",
100
+ "mocha": "^5.2.0",
101
+ "react-test-renderer": "^16.12.0",
102
+ "sass-true": "^4.0.0",
103
+ "stylelint": "^9.6.0",
104
+ "stylelint-config-sass-guidelines": "^5.2.0",
105
+ "stylelint-scss": "^3.3.2",
106
+ "ts-node": "^7.0.1",
107
+ "tslint": "^5.11.0",
108
+ "tslint-eslint-rules": "^5.4.0",
109
+ "webpack-bundle-analyzer": "^3.0.3",
110
+ "webpack-dev-server": "^3.3.1"
111
+ }
112
+ }