webpacker 3.0.2 → 3.1.0
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.
- checksums.yaml +4 -4
- data/.eslintignore +1 -0
- data/.travis.yml +10 -0
- data/CHANGELOG.md +110 -0
- data/Gemfile.lock +69 -67
- data/MIT-LICENSE +1 -1
- data/README.md +86 -30
- data/docs/assets.md +4 -4
- data/docs/cloud9.md +310 -0
- data/docs/css.md +32 -3
- data/docs/deployment.md +42 -4
- data/docs/docker.md +49 -0
- data/docs/env.md +5 -5
- data/docs/folder-structure.md +2 -2
- data/docs/testing.md +14 -34
- data/docs/troubleshooting.md +40 -4
- data/docs/typescript.md +2 -2
- data/docs/webpack-dev-server.md +21 -4
- data/docs/webpack.md +103 -25
- data/gemfiles/Gemfile-rails-edge +13 -0
- data/gemfiles/Gemfile-rails.4.2.x +10 -0
- data/gemfiles/Gemfile-rails.5.0.x +10 -0
- data/gemfiles/Gemfile-rails.5.1.x +10 -0
- data/lib/install/angular.rb +5 -5
- data/lib/install/config/webpacker.yml +7 -0
- data/lib/install/elm.rb +7 -7
- data/lib/install/examples/vue/hello_vue.js +30 -4
- data/lib/install/react.rb +5 -5
- data/lib/install/template.rb +19 -9
- data/lib/install/vue.rb +4 -4
- data/lib/tasks/installers.rake +2 -2
- data/lib/tasks/webpacker.rake +7 -6
- data/lib/tasks/webpacker/check_binstubs.rake +3 -3
- data/lib/tasks/webpacker/compile.rake +15 -8
- data/lib/tasks/webpacker/install.rake +4 -4
- data/lib/tasks/webpacker/verify_install.rake +1 -1
- data/lib/webpacker/compiler.rb +6 -6
- data/lib/webpacker/dev_server.rb +2 -2
- data/lib/webpacker/dev_server_proxy.rb +2 -1
- data/lib/webpacker/dev_server_runner.rb +4 -4
- data/lib/webpacker/helper.rb +3 -3
- data/lib/webpacker/manifest.rb +2 -2
- data/lib/webpacker/railtie.rb +41 -2
- data/lib/webpacker/runner.rb +1 -1
- data/lib/webpacker/version.rb +1 -1
- data/package.json +29 -21
- data/package/asset_host.js +4 -5
- data/package/config.js +7 -1
- data/package/config_types/__tests__/config_list.js +123 -0
- data/package/config_types/__tests__/config_object.js +43 -0
- data/package/config_types/config_list.js +83 -0
- data/package/config_types/config_object.js +55 -0
- data/package/config_types/index.js +7 -0
- data/package/environment.js +64 -40
- data/package/environments/development.js +31 -34
- data/package/environments/production.js +14 -11
- data/package/index.js +7 -2
- data/package/{loaders → rules}/babel.js +6 -4
- data/package/{loaders → rules}/coffee.js +3 -1
- data/package/rules/css.js +39 -0
- data/package/rules/elm.js +23 -0
- data/package/rules/erb.js +11 -0
- data/package/{loaders → rules}/file.js +1 -1
- data/package/rules/index.js +23 -0
- data/package/rules/sass.js +15 -0
- data/package/{loaders → rules}/typescript.js +3 -1
- data/package/rules/url.js +13 -0
- data/package/rules/vue.js +13 -0
- data/package/utils/__tests__/deep_assign.js +11 -0
- data/package/utils/__tests__/deep_merge.js +10 -0
- data/package/utils/__tests__/objectify.js +9 -0
- data/package/utils/deep_assign.js +22 -0
- data/package/utils/deep_merge.js +23 -0
- data/package/utils/helpers.js +32 -0
- data/package/utils/objectify.js +4 -0
- data/test/command_test.rb +1 -1
- data/test/compiler_test.rb +5 -1
- data/test/configuration_test.rb +1 -1
- data/test/dev_server_test.rb +1 -1
- data/test/helper_test.rb +15 -10
- data/test/manifest_test.rb +1 -1
- data/test/rake_tasks_test.rb +29 -0
- data/test/test_app/Rakefile +3 -0
- data/test/test_app/config/application.rb +11 -0
- data/test/test_app/config/environment.rb +4 -0
- data/test/{webpacker_test_helper.rb → test_helper.rb} +3 -14
- data/webpacker.gemspec +1 -1
- data/yarn.lock +1552 -829
- metadata +43 -16
- data/package/loaders/elm.js +0 -19
- data/package/loaders/erb.js +0 -9
- data/package/loaders/style.js +0 -31
- data/package/loaders/vue.js +0 -12
- data/test/test_app/config/secrets.yml +0 -5
@@ -9,8 +9,9 @@ class Webpacker::DevServerProxy < Rack::Proxy
|
|
9
9
|
end
|
10
10
|
|
11
11
|
def perform_request(env)
|
12
|
-
if env["PATH_INFO"]
|
12
|
+
if env["PATH_INFO"].start_with?("/#{public_output_uri_path}") && Webpacker.dev_server.running?
|
13
13
|
env["HTTP_HOST"] = env["HTTP_X_FORWARDED_HOST"] = env["HTTP_X_FORWARDED_SERVER"] = Webpacker.dev_server.host_with_port
|
14
|
+
env["SCRIPT_NAME"] = ""
|
14
15
|
|
15
16
|
super(env)
|
16
17
|
else
|
@@ -18,10 +18,11 @@ module Webpacker
|
|
18
18
|
|
19
19
|
@hostname = dev_server["host"]
|
20
20
|
@port = dev_server["port"]
|
21
|
+
@pretty = dev_server.fetch("pretty", true)
|
21
22
|
|
22
23
|
rescue Errno::ENOENT, NoMethodError
|
23
|
-
$stdout.puts "
|
24
|
-
$stdout.puts "Please run bundle exec rails webpacker:install to install
|
24
|
+
$stdout.puts "webpack dev_server configuration not found in #{@config_file}."
|
25
|
+
$stdout.puts "Please run bundle exec rails webpacker:install to install Webpacker"
|
25
26
|
exit!
|
26
27
|
end
|
27
28
|
|
@@ -38,10 +39,9 @@ module Webpacker
|
|
38
39
|
env = { "NODE_PATH" => @node_modules_path.shellescape }
|
39
40
|
cmd = [
|
40
41
|
"#{@node_modules_path}/.bin/webpack-dev-server",
|
41
|
-
"--progress",
|
42
|
-
"--color",
|
43
42
|
"--config", @webpack_config
|
44
43
|
]
|
44
|
+
cmd += ["--progress", "--color"] if @pretty
|
45
45
|
|
46
46
|
Dir.chdir(@app_path) do
|
47
47
|
exec env, *cmd
|
data/lib/webpacker/helper.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
module Webpacker::Helper
|
2
|
-
# Computes the full path for a given
|
2
|
+
# Computes the full path for a given Webpacker asset.
|
3
3
|
# Return relative path using manifest.json and passes it to asset_url helper
|
4
4
|
# This will use asset_path internally, so most of their behaviors will be the same.
|
5
5
|
#
|
@@ -9,7 +9,7 @@ module Webpacker::Helper
|
|
9
9
|
def asset_pack_path(name, **options)
|
10
10
|
asset_path(Webpacker.manifest.lookup!(name), **options)
|
11
11
|
end
|
12
|
-
# Creates a script tag that references the named pack file, as compiled by
|
12
|
+
# Creates a script tag that references the named pack file, as compiled by webpack per the entries list
|
13
13
|
# in config/webpack/shared.js. By default, this list is auto-generated to match everything in
|
14
14
|
# app/javascript/packs/*.js. In production mode, the digested reference is automatically looked up.
|
15
15
|
#
|
@@ -21,7 +21,7 @@ module Webpacker::Helper
|
|
21
21
|
javascript_include_tag(*sources_from_pack_manifest(names, type: :javascript), **options)
|
22
22
|
end
|
23
23
|
|
24
|
-
# Creates a link tag that references the named pack file, as compiled by
|
24
|
+
# Creates a link tag that references the named pack file, as compiled by webpack per the entries list
|
25
25
|
# in config/webpack/shared.js. By default, this list is auto-generated to match everything in
|
26
26
|
# app/javascript/packs/*.js. In production mode, the digested reference is automatically looked up.
|
27
27
|
#
|
data/lib/webpacker/manifest.rb
CHANGED
@@ -49,9 +49,9 @@ class Webpacker::Manifest
|
|
49
49
|
Webpacker can't find #{bundle_name} in #{config.public_manifest_path}. Possible causes:
|
50
50
|
1. You want to set webpacker.yml value of compile to true for your environment
|
51
51
|
unless you are using the `webpack -w` or the webpack-dev-server.
|
52
|
-
2.
|
52
|
+
2. webpack has not yet re-run to reflect updates.
|
53
53
|
3. You have misconfigured Webpacker's config/webpacker.yml file.
|
54
|
-
4. Your
|
54
|
+
4. Your webpack configuration is not creating a manifest.
|
55
55
|
Your manifest contains:
|
56
56
|
#{JSON.pretty_generate(@data)}
|
57
57
|
MSG
|
data/lib/webpacker/railtie.rb
CHANGED
@@ -4,6 +4,45 @@ require "webpacker/helper"
|
|
4
4
|
require "webpacker/dev_server_proxy"
|
5
5
|
|
6
6
|
class Webpacker::Engine < ::Rails::Engine
|
7
|
+
# Allows Webpacker config values to be set via Rails env config files
|
8
|
+
config.webpacker = ActiveSupport::OrderedOptions.new
|
9
|
+
config.webpacker.check_yarn_integrity = false
|
10
|
+
|
11
|
+
# ================================
|
12
|
+
# Check Yarn Integrity Initializer
|
13
|
+
# ================================
|
14
|
+
#
|
15
|
+
# development (on by default):
|
16
|
+
#
|
17
|
+
# to turn off:
|
18
|
+
# - edit config/environments/development.rb
|
19
|
+
# - add `config.webpacker.check_yarn_integrity = false`
|
20
|
+
#
|
21
|
+
# production (off by default):
|
22
|
+
#
|
23
|
+
# to turn on:
|
24
|
+
# - edit config/environments/production.rb
|
25
|
+
# - add `config.webpacker.check_yarn_integrity = false`
|
26
|
+
initializer "webpacker.yarn_check" do |app|
|
27
|
+
if File.exist?("yarn.lock") && app.config.webpacker.check_yarn_integrity
|
28
|
+
ok = system("yarn check --integrity")
|
29
|
+
|
30
|
+
if !ok
|
31
|
+
warn "\n\n"
|
32
|
+
warn "========================================"
|
33
|
+
warn " Your Yarn packages are out of date!"
|
34
|
+
warn " Please run `yarn install` to update."
|
35
|
+
warn "========================================"
|
36
|
+
warn "\n\n"
|
37
|
+
warn "To disable this check, please add `config.webpacker.check_yarn_integrity = false`"
|
38
|
+
warn "to your Rails development config file (config/environments/development.rb)."
|
39
|
+
warn "\n\n"
|
40
|
+
|
41
|
+
exit(1)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
7
46
|
initializer "webpacker.proxy" do |app|
|
8
47
|
if Rails.env.development?
|
9
48
|
app.middleware.insert_before 0,
|
@@ -12,7 +51,7 @@ class Webpacker::Engine < ::Rails::Engine
|
|
12
51
|
end
|
13
52
|
end
|
14
53
|
|
15
|
-
initializer "webpacker.helper" do
|
54
|
+
initializer "webpacker.helper" do
|
16
55
|
ActiveSupport.on_load :action_controller do
|
17
56
|
ActionController::Base.helper Webpacker::Helper
|
18
57
|
end
|
@@ -23,7 +62,7 @@ class Webpacker::Engine < ::Rails::Engine
|
|
23
62
|
end
|
24
63
|
|
25
64
|
initializer "webpacker.logger" do
|
26
|
-
config.after_initialize do
|
65
|
+
config.after_initialize do
|
27
66
|
if ::Rails.logger.respond_to?(:tagged)
|
28
67
|
Webpacker.logger = ::Rails.logger
|
29
68
|
else
|
data/lib/webpacker/runner.rb
CHANGED
@@ -14,7 +14,7 @@ module Webpacker
|
|
14
14
|
@webpack_config = File.join(@app_path, "config/webpack/#{ENV["NODE_ENV"]}.js")
|
15
15
|
|
16
16
|
unless File.exist?(@webpack_config)
|
17
|
-
puts "
|
17
|
+
$stderr.puts "webpack config #{@webpack_config} not found, please run 'bundle exec rails webpacker:install' to install Webpacker with default configs or add the missing config file for your custom environment."
|
18
18
|
exit!
|
19
19
|
end
|
20
20
|
end
|
data/lib/webpacker/version.rb
CHANGED
data/package.json
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
{
|
2
2
|
"name": "@rails/webpacker",
|
3
|
-
"version": "3.0
|
4
|
-
"description": "Use
|
3
|
+
"version": "3.1.0",
|
4
|
+
"description": "Use webpack to manage app-like JavaScript modules in Rails",
|
5
5
|
"main": "package/index.js",
|
6
6
|
"files": [
|
7
7
|
"package"
|
@@ -17,38 +17,46 @@
|
|
17
17
|
"babel-plugin-transform-class-properties": "^6.24.1",
|
18
18
|
"babel-plugin-transform-object-rest-spread": "^6.26.0",
|
19
19
|
"babel-polyfill": "^6.26.0",
|
20
|
-
"babel-preset-env": "^1.6.
|
21
|
-
"
|
22
|
-
"
|
23
|
-
"
|
24
|
-
"
|
25
|
-
"
|
20
|
+
"babel-preset-env": "^1.6.1",
|
21
|
+
"case-sensitive-paths-webpack-plugin": "^2.1.1",
|
22
|
+
"coffee-loader": "^0.9.0",
|
23
|
+
"compression-webpack-plugin": "^1.0.1",
|
24
|
+
"css-loader": "^0.28.7",
|
25
|
+
"extract-text-webpack-plugin": "^3.0.2",
|
26
|
+
"file-loader": "^1.1.5",
|
26
27
|
"glob": "^7.1.2",
|
27
|
-
"js-yaml": "^3.
|
28
|
-
"node-sass": "^4.
|
28
|
+
"js-yaml": "^3.10.0",
|
29
|
+
"node-sass": "^4.7.2",
|
29
30
|
"path-complete-extname": "^0.1.0",
|
30
31
|
"postcss-cssnext": "^3.0.2",
|
31
|
-
"postcss-loader": "^2.0.
|
32
|
+
"postcss-loader": "^2.0.9",
|
32
33
|
"postcss-smart-import": "^0.7.5",
|
33
34
|
"rails-erb-loader": "^5.2.1",
|
34
|
-
"resolve-url-loader": "^2.1.0",
|
35
35
|
"sass-loader": "^6.0.6",
|
36
|
-
"style-loader": "^0.
|
37
|
-
"
|
38
|
-
"webpack
|
36
|
+
"style-loader": "^0.19.0",
|
37
|
+
"url-loader": "^0.6.2",
|
38
|
+
"webpack": "^3.8.1",
|
39
|
+
"webpack-manifest-plugin": "^1.3.2"
|
39
40
|
},
|
40
41
|
"devDependencies": {
|
41
|
-
"eslint": "^
|
42
|
-
"eslint-config-airbnb": "^
|
43
|
-
"eslint-plugin-import": "^2.
|
44
|
-
"eslint-plugin-jsx-a11y": "^
|
45
|
-
"eslint-plugin-react": "^
|
42
|
+
"eslint": "^4.11.0",
|
43
|
+
"eslint-config-airbnb": "^16.1.0",
|
44
|
+
"eslint-plugin-import": "^2.8.0",
|
45
|
+
"eslint-plugin-jsx-a11y": "^6.0.2",
|
46
|
+
"eslint-plugin-react": "^7.5.1",
|
47
|
+
"jest": "^21.2.1"
|
48
|
+
},
|
49
|
+
"jest": {
|
50
|
+
"testRegex": "(/__tests__/.*|(\\.|/))\\.jsx?$",
|
51
|
+
"roots": [
|
52
|
+
"<rootDir>/package"
|
53
|
+
]
|
46
54
|
},
|
47
55
|
"peerDependencies": {
|
48
56
|
"coffeescript": ">= 1.12.7 || >= 2.x"
|
49
57
|
},
|
50
58
|
"scripts": {
|
51
|
-
"test": "
|
59
|
+
"test": "jest",
|
52
60
|
"lint": "eslint {package,lib}/"
|
53
61
|
},
|
54
62
|
"repository": {
|
data/package/asset_host.js
CHANGED
@@ -1,11 +1,10 @@
|
|
1
1
|
const config = require('./config')
|
2
2
|
const { resolve } = require('path')
|
3
3
|
|
4
|
-
|
5
|
-
|
6
|
-
}
|
4
|
+
const removeOuterSlashes = string =>
|
5
|
+
string.replace(/^\/*/, '').replace(/\/*$/, '')
|
7
6
|
|
8
|
-
|
7
|
+
const formatPublicPath = (host = '', path = '') => {
|
9
8
|
let formattedHost = removeOuterSlashes(host)
|
10
9
|
if (formattedHost && !/^http/i.test(formattedHost)) {
|
11
10
|
formattedHost = `//${formattedHost}`
|
@@ -17,5 +16,5 @@ function formatPublicPath(host = '', path = '') {
|
|
17
16
|
module.exports = {
|
18
17
|
path: resolve('public', config.public_output_path),
|
19
18
|
publicPath: `/${config.public_output_path}/`.replace(/([^:]\/)\/+/g, '$1'),
|
20
|
-
publicPathWithHost: formatPublicPath(process.env.
|
19
|
+
publicPathWithHost: formatPublicPath(process.env.WEBPACKER_ASSET_HOST, config.public_output_path)
|
21
20
|
}
|
data/package/config.js
CHANGED
@@ -1,9 +1,15 @@
|
|
1
1
|
const { resolve } = require('path')
|
2
2
|
const { safeLoad } = require('js-yaml')
|
3
3
|
const { readFileSync } = require('fs')
|
4
|
+
const deepMerge = require('./utils/deep_merge')
|
4
5
|
|
6
|
+
const defaultFilePath = require.resolve('../lib/install/config/webpacker.yml')
|
5
7
|
const filePath = resolve('config', 'webpacker.yml')
|
6
|
-
|
8
|
+
|
9
|
+
const environment = process.env.NODE_ENV || 'development'
|
10
|
+
const defaultConfig = safeLoad(readFileSync(defaultFilePath), 'utf8')[environment]
|
11
|
+
const appConfig = safeLoad(readFileSync(filePath), 'utf8')[environment]
|
12
|
+
const config = deepMerge(defaultConfig, appConfig)
|
7
13
|
|
8
14
|
const isBoolean = str => /^true/.test(str) || /^false/.test(str)
|
9
15
|
|
@@ -0,0 +1,123 @@
|
|
1
|
+
/* global test expect */
|
2
|
+
|
3
|
+
const ConfigList = require('../config_list')
|
4
|
+
|
5
|
+
test('new', () => {
|
6
|
+
const list = new ConfigList()
|
7
|
+
expect(list).toBeInstanceOf(ConfigList)
|
8
|
+
expect(list).toBeInstanceOf(Array)
|
9
|
+
})
|
10
|
+
|
11
|
+
test('set', () => {
|
12
|
+
const list = new ConfigList()
|
13
|
+
expect(list.set('key', 'value')).toEqual([{ key: 'key', value: 'value' }])
|
14
|
+
})
|
15
|
+
|
16
|
+
test('get', () => {
|
17
|
+
const list = new ConfigList()
|
18
|
+
list.append('key', 'value')
|
19
|
+
expect(list.get('key')).toEqual('value')
|
20
|
+
})
|
21
|
+
|
22
|
+
test('append', () => {
|
23
|
+
const list = new ConfigList()
|
24
|
+
list.append('key', 'value')
|
25
|
+
expect(list.append('key1', 'value1')).toEqual([
|
26
|
+
{ key: 'key', value: 'value' },
|
27
|
+
{ key: 'key1', value: 'value1' }
|
28
|
+
])
|
29
|
+
})
|
30
|
+
|
31
|
+
test('prepend', () => {
|
32
|
+
const list = new ConfigList()
|
33
|
+
list.append('key', 'value')
|
34
|
+
expect(list.prepend('key1', 'value1')).toEqual([
|
35
|
+
{ key: 'key1', value: 'value1' },
|
36
|
+
{ key: 'key', value: 'value' }
|
37
|
+
])
|
38
|
+
})
|
39
|
+
|
40
|
+
test('insert without position', () => {
|
41
|
+
const list = new ConfigList()
|
42
|
+
list.append('key', 'value')
|
43
|
+
|
44
|
+
expect(list.insert('key1', 'value1')).toEqual([
|
45
|
+
{ key: 'key', value: 'value' },
|
46
|
+
{ key: 'key1', value: 'value1' }
|
47
|
+
])
|
48
|
+
|
49
|
+
expect(list.insert('key2', 'value2')).toEqual([
|
50
|
+
{ key: 'key', value: 'value' },
|
51
|
+
{ key: 'key1', value: 'value1' },
|
52
|
+
{ key: 'key2', value: 'value2' }
|
53
|
+
])
|
54
|
+
})
|
55
|
+
|
56
|
+
test('insert before an item', () => {
|
57
|
+
const list = new ConfigList()
|
58
|
+
list.append('key', 'value')
|
59
|
+
list.append('key1', 'value1')
|
60
|
+
|
61
|
+
expect(list.insert('key2', 'value2', { before: 'key' })).toEqual([
|
62
|
+
{ key: 'key2', value: 'value2' },
|
63
|
+
{ key: 'key', value: 'value' },
|
64
|
+
{ key: 'key1', value: 'value1' }
|
65
|
+
])
|
66
|
+
|
67
|
+
expect(list.insert('key3', 'value3', { before: 'key2' })).toEqual([
|
68
|
+
{ key: 'key3', value: 'value3' },
|
69
|
+
{ key: 'key2', value: 'value2' },
|
70
|
+
{ key: 'key', value: 'value' },
|
71
|
+
{ key: 'key1', value: 'value1' }
|
72
|
+
])
|
73
|
+
})
|
74
|
+
|
75
|
+
test('insert after an item', () => {
|
76
|
+
const list = new ConfigList()
|
77
|
+
list.append('key', 'value')
|
78
|
+
list.append('key1', 'value1')
|
79
|
+
|
80
|
+
expect(list.insert('key2', 'value2', { after: 'key' })).toEqual([
|
81
|
+
{ key: 'key', value: 'value' },
|
82
|
+
{ key: 'key2', value: 'value2' },
|
83
|
+
{ key: 'key1', value: 'value1' }
|
84
|
+
])
|
85
|
+
|
86
|
+
expect(list.insert('key3', 'value3', { after: 'key2' })).toEqual([
|
87
|
+
{ key: 'key', value: 'value' },
|
88
|
+
{ key: 'key2', value: 'value2' },
|
89
|
+
{ key: 'key3', value: 'value3' },
|
90
|
+
{ key: 'key1', value: 'value1' }
|
91
|
+
])
|
92
|
+
})
|
93
|
+
|
94
|
+
test('delete', () => {
|
95
|
+
const list = new ConfigList()
|
96
|
+
list.append('key', 'value')
|
97
|
+
list.append('key1', 'value1')
|
98
|
+
expect(list.delete('key')).toEqual([{ key: 'key1', value: 'value1' }])
|
99
|
+
expect(list.delete('key1')).toEqual([])
|
100
|
+
})
|
101
|
+
|
102
|
+
test('getIndex', () => {
|
103
|
+
const list = new ConfigList()
|
104
|
+
list.append('key', 'value')
|
105
|
+
list.append('key1', 'value1')
|
106
|
+
expect(list.getIndex('key')).toEqual(0)
|
107
|
+
expect(list.getIndex('key2')).toEqual(-1)
|
108
|
+
expect(() => list.getIndex('key2', true)).toThrow('Item key2 not found')
|
109
|
+
})
|
110
|
+
|
111
|
+
test('values', () => {
|
112
|
+
const list = new ConfigList()
|
113
|
+
list.append('key', 'value')
|
114
|
+
list.append('key1', 'value1')
|
115
|
+
expect(list.values()).toEqual(['value', 'value1'])
|
116
|
+
})
|
117
|
+
|
118
|
+
test('keys', () => {
|
119
|
+
const list = new ConfigList()
|
120
|
+
list.append('key', 'value')
|
121
|
+
list.append('key1', 'value1')
|
122
|
+
expect(list.keys()).toEqual(['key', 'key1'])
|
123
|
+
})
|
@@ -0,0 +1,43 @@
|
|
1
|
+
/* global test expect */
|
2
|
+
|
3
|
+
const ConfigObject = require('../config_object')
|
4
|
+
|
5
|
+
test('new', () => {
|
6
|
+
const object = new ConfigObject()
|
7
|
+
expect(object).toBeInstanceOf(ConfigObject)
|
8
|
+
expect(object).toBeInstanceOf(Object)
|
9
|
+
})
|
10
|
+
|
11
|
+
test('set', () => {
|
12
|
+
const object = new ConfigObject()
|
13
|
+
expect(object.set('key', 'value')).toEqual({ key: 'value' })
|
14
|
+
})
|
15
|
+
|
16
|
+
test('get', () => {
|
17
|
+
const object = new ConfigObject()
|
18
|
+
object.set('key', 'value')
|
19
|
+
object.set('key1', 'value1')
|
20
|
+
expect(object.get('key')).toEqual('value')
|
21
|
+
})
|
22
|
+
|
23
|
+
test('delete', () => {
|
24
|
+
const object = new ConfigObject()
|
25
|
+
object.set('key', { key1: 'value' })
|
26
|
+
expect(object.delete('key.key1')).toEqual({ key: {} })
|
27
|
+
expect(object.delete('key')).toEqual({})
|
28
|
+
})
|
29
|
+
|
30
|
+
test('toObject', () => {
|
31
|
+
const object = new ConfigObject()
|
32
|
+
object.set('key', 'value')
|
33
|
+
object.set('key1', 'value1')
|
34
|
+
expect(object.toObject()).toEqual({ key: 'value', key1: 'value1' })
|
35
|
+
})
|
36
|
+
|
37
|
+
test('merge', () => {
|
38
|
+
const object = new ConfigObject()
|
39
|
+
object.set('foo', {})
|
40
|
+
expect(object.merge({ key: 'foo', value: 'bar' })).toEqual(
|
41
|
+
{ foo: {}, key: 'foo', value: 'bar' }
|
42
|
+
)
|
43
|
+
})
|
@@ -0,0 +1,83 @@
|
|
1
|
+
/**
|
2
|
+
* @class
|
3
|
+
* @extends { Array }
|
4
|
+
*/
|
5
|
+
class ConfigList extends Array {
|
6
|
+
get(key) {
|
7
|
+
const index = this.getIndex(key, true)
|
8
|
+
return this[index].value
|
9
|
+
}
|
10
|
+
|
11
|
+
/**
|
12
|
+
* @deprecated after the 3.0.2 release and will be removed in the next major release
|
13
|
+
*/
|
14
|
+
set(key, value) {
|
15
|
+
/* eslint no-console: 0 */
|
16
|
+
console.warn('set is deprecated! Use append instead')
|
17
|
+
return this.append(key, value)
|
18
|
+
}
|
19
|
+
|
20
|
+
append(key, value) {
|
21
|
+
return this.add({ key, value })
|
22
|
+
}
|
23
|
+
|
24
|
+
prepend(key, value) {
|
25
|
+
return this.add({ key, value }, 'prepend')
|
26
|
+
}
|
27
|
+
|
28
|
+
insert(key, value, pos = {}) {
|
29
|
+
if (!(pos.before || pos.after)) return this.append(key, value)
|
30
|
+
|
31
|
+
const currentIndex = this.getIndex(key)
|
32
|
+
if (currentIndex >= 0) this.splice(currentIndex, 1)
|
33
|
+
|
34
|
+
let newIndex = this.getIndex(pos.before || pos.after)
|
35
|
+
if (pos.after) newIndex += 1
|
36
|
+
|
37
|
+
this.splice(newIndex, 0, { key, value })
|
38
|
+
return this
|
39
|
+
}
|
40
|
+
|
41
|
+
delete(key) {
|
42
|
+
const index = this.getIndex(key, true)
|
43
|
+
this.splice(index, 1)
|
44
|
+
return this
|
45
|
+
}
|
46
|
+
|
47
|
+
getIndex(key, shouldThrow = false) {
|
48
|
+
const index = this.findIndex(entry =>
|
49
|
+
(
|
50
|
+
entry === key ||
|
51
|
+
entry.key === key ||
|
52
|
+
(entry.constructor && entry.constructor.name === key)
|
53
|
+
))
|
54
|
+
|
55
|
+
if (shouldThrow && index < 0) throw new Error(`Item ${key} not found`)
|
56
|
+
return index
|
57
|
+
}
|
58
|
+
|
59
|
+
add({ key, value }, strategy = 'append') {
|
60
|
+
const index = this.getIndex(key)
|
61
|
+
if (index >= 0) this.delete(key)
|
62
|
+
|
63
|
+
switch (strategy) {
|
64
|
+
case 'prepend':
|
65
|
+
this.unshift({ key, value })
|
66
|
+
break
|
67
|
+
default:
|
68
|
+
this.push({ key, value })
|
69
|
+
}
|
70
|
+
|
71
|
+
return this
|
72
|
+
}
|
73
|
+
|
74
|
+
values() {
|
75
|
+
return this.map(item => item.value)
|
76
|
+
}
|
77
|
+
|
78
|
+
keys() {
|
79
|
+
return this.map(item => item.key)
|
80
|
+
}
|
81
|
+
}
|
82
|
+
|
83
|
+
module.exports = ConfigList
|