danger-wcc 0.0.4 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (56) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +22 -15
  3. data/danger-wcc.gemspec +3 -3
  4. data/lib/version.rb +1 -1
  5. data/lib/wcc/commit_lint.rb +2 -1
  6. data/lib/wcc/commit_lint/commit_check.rb +0 -1
  7. data/lib/wcc/commit_lint/empty_line_check.rb +0 -1
  8. data/lib/wcc/commit_lint/subject_cap_check.rb +0 -1
  9. data/lib/wcc/commit_lint/subject_length_check.rb +0 -1
  10. data/lib/wcc/commit_lint/subject_period_check.rb +0 -1
  11. data/lib/wcc/commit_lint/subject_words_check.rb +0 -1
  12. data/lib/wcc/defaults.reek +8 -8
  13. data/lib/wcc/dependencies.rb +100 -0
  14. data/lib/wcc/jshint.rb +2 -2
  15. data/lib/wcc/plugin.rb +30 -12
  16. data/lib/wcc/reek.rb +2 -2
  17. data/lib/wcc/rubocop_exceptions.rb +13 -8
  18. data/lib/wcc/todos.rb +5 -4
  19. data/lib/wcc/util/yarn_info.rb +98 -0
  20. data/lib/wcc/utils.rb +18 -8
  21. data/lib/wcc/yarn_deduplicate.rb +71 -0
  22. data/spec/fixtures/dependencies/package.json +112 -0
  23. data/spec/fixtures/dependencies/package.json.diff +28 -0
  24. data/spec/fixtures/dependencies/package.json_patch_bumps_minor.diff +13 -0
  25. data/spec/fixtures/dependencies/package.json_patch_bumps_minor.json +112 -0
  26. data/spec/fixtures/dependencies/package.json_second_level_effect.diff +17 -0
  27. data/spec/fixtures/dependencies/package.json_second_level_effect.json +133 -0
  28. data/spec/fixtures/dependencies/yarn.lock +19609 -0
  29. data/spec/fixtures/dependencies/yarn.lock_patch_bumps_minor.lock +19614 -0
  30. data/spec/fixtures/dependencies/yarn.lock_second_level_effect.lock +20022 -0
  31. data/spec/fixtures/dependencies/yarn_list_second_level_effect.txt +1243 -0
  32. data/spec/fixtures/dependencies/yarn_list_second_level_effect.txt.diff +141 -0
  33. data/spec/fixtures/dependencies/yarn_minor_version.diff +33 -0
  34. data/spec/fixtures/dependencies/yarn_minor_version.txt +1151 -0
  35. data/spec/fixtures/dependencies/yarn_old.txt +1152 -0
  36. data/spec/fixtures/dependencies/yarn_patch_bumps_minor.diff +28 -0
  37. data/spec/fixtures/exception_inline_disabled_rule.diff +12 -0
  38. data/spec/fixtures/rubocop_exception.rb +3 -0
  39. data/spec/fixtures/yarn_deduplicate/list.a.txt +293 -0
  40. data/spec/fixtures/yarn_deduplicate/list.b.txt +295 -0
  41. data/spec/fixtures/yarn_deduplicate/list.diff +11 -0
  42. data/spec/fixtures/yarn_deduplicate/yarn.lock +20031 -0
  43. data/spec/fixtures_helper.rb +0 -1
  44. data/spec/spec_helper.rb +1 -1
  45. data/spec/wcc/commit_lint_spec.rb +6 -10
  46. data/spec/wcc/dependencies_spec.rb +130 -0
  47. data/spec/wcc/github_spec.rb +13 -7
  48. data/spec/wcc/jshint_spec.rb +1 -1
  49. data/spec/wcc/plugin_spec.rb +22 -17
  50. data/spec/wcc/reek_spec.rb +1 -1
  51. data/spec/wcc/rubocop_exceptions_spec.rb +34 -15
  52. data/spec/wcc/todos_spec.rb +10 -10
  53. data/spec/wcc/utils_spec.rb +2 -2
  54. data/spec/wcc/yarn_deduplicate_spec.rb +57 -0
  55. data/spec/wcc_spec.rb +1 -1
  56. metadata +71 -10
data/lib/wcc/todos.rb CHANGED
@@ -6,8 +6,8 @@ class Danger::DangerWCC < Danger::Plugin
6
6
  class Todos
7
7
  include Utils
8
8
 
9
- TODO_REGEX = /^\+.*\#.*TODO:?/i
10
- LINK_REGEX = /\#.*(https?\:\/\/\S+)/i
9
+ TODO_REGEX = /^\+.*\#.*TODO:?/i.freeze
10
+ LINK_REGEX = /\#.*(https?\:\/\/\S+)/i.freeze
11
11
 
12
12
  def initialize(plugin, options = {})
13
13
  @plugin = plugin
@@ -26,11 +26,11 @@ class Danger::DangerWCC < Danger::Plugin
26
26
  if result[:link]
27
27
  plugin.message "TODO added in #{result[:file_link]} "\
28
28
  "referencing [#{result[:link]}](#{result[:link]})",
29
- file: result[:file], line: result[:line]
29
+ file: result[:file], line: result[:line]
30
30
  else
31
31
  plugin.warn "TODO added in #{result[:file_link]} - "\
32
32
  'is there a card associated with that?',
33
- file: result[:file], line: result[:line]
33
+ file: result[:file], line: result[:line]
34
34
  end
35
35
  end
36
36
 
@@ -72,6 +72,7 @@ class Danger::DangerWCC < Danger::Plugin
72
72
  def max(a, b)
73
73
  return a if b.nil?
74
74
  return b if a.nil?
75
+
75
76
  a > b ? a : b
76
77
  end
77
78
  end
@@ -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
@@ -1,4 +1,3 @@
1
-
2
1
  # frozen_string_literal: true
3
2
 
4
3
  require 'git_diff'
@@ -13,6 +12,7 @@ module Utils
13
12
 
14
13
  def logger
15
14
  return @logger if @logger
15
+
16
16
  @logger = Logger.new(STDERR)
17
17
  @logger.level = ENV['DANGER_LOG_LEVEL'] ||
18
18
  (plugin.verbose ? Logger::INFO : Logger::ERROR)
@@ -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
@@ -102,12 +114,10 @@ module Utils
102
114
  def with_revision(revision)
103
115
  Dir.mktmpdir do |dir|
104
116
  logger.debug "Checking out revision #{revision} into #{dir}"
105
- system "git worktree add #{dir} #{revision.strip}"
117
+ system "git --work-tree=#{dir} checkout #{revision.strip} -- ."
106
118
 
107
119
  yield(dir)
108
120
  end
109
- ensure
110
- system 'git worktree prune'
111
121
  end
112
122
 
113
123
  # Creates a git-format diff of the two strings by writing them to temp files
@@ -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
+ }