import_js 0.2.2 → 0.2.3

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 7281a4ddb53f991a2649b7fe3be8a49299cc5e4a
4
- data.tar.gz: 44a9e946d556775eda9572bdd1fd411fff8434ff
3
+ metadata.gz: 0c2841cf4974c8a53e788a4ec74e78091948e470
4
+ data.tar.gz: 97e8905dc410a022a31522585054fda588a622c9
5
5
  SHA512:
6
- metadata.gz: 768713a538e2e4c13eeb3fcb8d73df611a679add1f0a2bc65476c3c859f68aa260d61837e94b38aebdad234e776249347adccba2574c78817171ade902fc199c
7
- data.tar.gz: 198423cbd91368c37904ff26f9e2ceaf2bbcb83b4d9db37be3e26ee094b9341ebd7f75360021a67fc99bd61700fe07dff3fd3bfc56c36f29926dcf533964d6e1
6
+ metadata.gz: a0c6a2f736161c17bf7ad89b0921c36295618930f1b598c565e748e25ea74837662b78d835c9801464ced440bb8c2e52461942e75c598c3a80294229b5858603
7
+ data.tar.gz: 9695778534d541cf215728512635f7d78b01e4f2c72ab315021e2d5b2900170e5db7379a4205e06b9ec7c1393b2ca31527519235a7a167670f31267e7856411d
@@ -26,10 +26,22 @@ module ImportJS
26
26
  ;?\s*
27
27
  }xm
28
28
 
29
+ REGEX_DESTRUCTURE = %r{
30
+ (?: # non-capturing group
31
+ (?<default>.*?) # <default> variable
32
+ ,\s*
33
+ )?
34
+ \{
35
+ \s*
36
+ (?<destructured>.*) # <destructured> variables
37
+ \s*
38
+ \}
39
+ }x
40
+
29
41
  attr_accessor :assignment
30
42
  attr_accessor :original_import_string # a cache of the parsed import string
31
- attr_accessor :variables
32
- attr_accessor :is_destructured # can't use `destructured?` because of 1.9.3
43
+ attr_accessor :default_variable
44
+ attr_accessor :destructured_variables
33
45
  attr_accessor :path
34
46
 
35
47
  # @param string [String] a possible import statement, e.g.
@@ -45,66 +57,123 @@ module ImportJS
45
57
  statement.original_import_string = match.string
46
58
  statement.path = match[:path]
47
59
  statement.assignment = match[:assignment]
48
- if dest_match = statement.assignment.match(/\{\s*(.*)\s*\}/)
49
- statement.variables = dest_match[1].split(/,\s*/).map(&:strip)
50
- statement.is_destructured = true
60
+ if dest_match = statement.assignment.match(REGEX_DESTRUCTURE)
61
+ statement.default_variable = dest_match[:default]
62
+ statement.destructured_variables =
63
+ dest_match[:destructured].split(/,\s*/).map(&:strip)
51
64
  else
52
- statement.variables = [statement.assignment]
65
+ statement.default_variable = statement.assignment
53
66
  end
54
67
  statement
55
68
  end
56
69
 
70
+ # Sets the default_variable and clears the original import string cache.
71
+ # @param value [String]
72
+ def set_default_variable(value)
73
+ @default_variable = value
74
+ @original_import_string = nil # clear import string cache if there was one
75
+ end
76
+
57
77
  # Injects a new variable into an already existing set of destructured
58
78
  # variables.
59
79
  # @param variable_name [String]
60
- def inject_variable(variable_name)
61
- variables << variable_name
62
- variables.sort!.uniq!
80
+ def inject_destructured_variable(variable_name)
81
+ @destructured_variables ||= []
82
+ destructured_variables << variable_name
83
+ destructured_variables.sort!.uniq!
63
84
 
64
85
  @original_import_string = nil # clear import string cache if there was one
65
86
  end
66
87
 
67
- # Deletes a variable from an already existing set of destructured
68
- # variables.
88
+ # Deletes a variable from an already existing default variable or set of
89
+ # destructured variables.
69
90
  # @param variable_name [String]
70
91
  def delete_variable(variable_name)
71
- variables.delete(variable_name)
92
+ @default_variable = nil if default_variable == variable_name
93
+ @destructured_variables.delete(variable_name) unless destructured_variables.nil?
72
94
 
73
95
  @original_import_string = nil # clear import string cache if there was one
74
96
  end
75
97
 
98
+ # @return [Boolean] true if there are destructured variables
99
+ def destructured?
100
+ !destructured_variables.nil? && !destructured_variables.empty?
101
+ end
102
+
103
+ # @return [Boolean] true if there is no default variable and there are no
104
+ # destructured variables
105
+ def empty?
106
+ default_variable.nil? && !destructured?
107
+ end
108
+
76
109
  # @return [Array] an array that can be used in `uniq!` to dedupe equal
77
110
  # statements, e.g.
78
111
  # `const foo = require('foo');`
79
112
  # `import foo from 'foo';`
80
- def normalize
81
- [variables, path]
113
+ def to_normalized
114
+ [default_variable, destructured_variables, path]
82
115
  end
83
116
 
84
117
  # @param declaration_keyword [String] const, let, var, or import
85
118
  # @param max_line_length [Number] where to cap lines at
86
119
  # @param tab [String] e.g. ' ' (two spaces)
87
- # @return a generated import statement string
88
- def to_import_string(declaration_keyword, max_line_length, tab)
89
- return original_import_string if original_import_string
90
-
91
- declaration = if is_destructured
92
- "#{declaration_keyword} { #{variables.join(', ')} }"
93
- else
94
- "#{declaration_keyword} #{variables.first}"
95
- end
96
-
97
- equals, value = if declaration_keyword == 'import'
98
- ['from', "'#{path}';"]
99
- else
100
- ['=', "require('#{path}');"]
101
- end
120
+ # @return [Array] generated import statement strings
121
+ def to_import_strings(declaration_keyword, max_line_length, tab)
122
+ return [original_import_string] if original_import_string
123
+
124
+ if declaration_keyword == 'import'
125
+ # ES2015 Modules (ESM) syntax can support default values and
126
+ # destructuring on the same line.
127
+ declaration = declaration_keyword
128
+ if destructured?
129
+ declaration += " #{default_variable}," if default_variable
130
+ declaration += " #{destructured_string}"
131
+ else
132
+ declaration += " #{default_variable}"
133
+ end
134
+ declaration += ' from'
135
+
136
+ [wrap_import(declaration, "'#{path}';", max_line_length, tab)]
137
+ else # const/let/var
138
+ value = "require('#{path}');"
102
139
 
140
+ if destructured? && !default_variable.nil?
141
+ # We have both a default variable and a destructuring to do, so we
142
+ # need to generate 2 lines for CommonJS style syntax.
143
+ default_declaration = "#{declaration_keyword} #{default_variable} ="
144
+ destructured_declaration = "#{declaration_keyword} #{destructured_string} ="
145
+
146
+ return [
147
+ wrap_import(default_declaration, value, max_line_length, tab),
148
+ wrap_import(destructured_declaration, value, max_line_length, tab)
149
+ ]
150
+ end
151
+
152
+ declaration_assignment =
153
+ destructured? ? destructured_string : default_variable
154
+ declaration = "#{declaration_keyword} #{declaration_assignment} ="
155
+ [wrap_import(declaration, value, max_line_length, tab)]
156
+ end
157
+ end
158
+
159
+ private
160
+
161
+ # @return [String]
162
+ def destructured_string
163
+ "{ #{destructured_variables.join(', ')} }"
164
+ end
165
+
166
+ # @param declaration [String]
167
+ # @param value [String]
168
+ # @param max_line_length [Number] where to cap lines at
169
+ # @param tab [String] e.g. ' ' (two spaces)
170
+ # @return [String] import statement, wrapped at max line length if necessary
171
+ def wrap_import(declaration, value, max_line_length, tab)
103
172
  if max_line_length &&
104
- "#{declaration} #{equals} #{value}".length > max_line_length
105
- "#{declaration} #{equals}\n#{tab}#{value}"
173
+ "#{declaration} #{value}".length > max_line_length
174
+ "#{declaration}\n#{tab}#{value}"
106
175
  else
107
- "#{declaration} #{equals} #{value}"
176
+ "#{declaration} #{value}"
108
177
  end
109
178
  end
110
179
  end
@@ -68,7 +68,7 @@ module ImportJS
68
68
  unused_variables.each do |unused_variable|
69
69
  import_statement.delete_variable(unused_variable)
70
70
  end
71
- import_statement.variables.empty?
71
+ import_statement.empty?
72
72
  end
73
73
 
74
74
  undefined_variables.each do |variable|
@@ -128,18 +128,25 @@ module ImportJS
128
128
  resolve_one_js_module(js_modules, variable_name)
129
129
  end
130
130
 
131
+ # Add new import to the block of imports, wrapping at the max line length
131
132
  # @param variable_name [String]
132
133
  # @param js_module [ImportJS::JSModule]
133
134
  # @param imports [Array<ImportJS::ImportStatement>]
134
135
  def inject_js_module(variable_name, js_module, imports)
135
- # Add new import to the block of imports, wrapping at the max line length
136
- unless js_module.is_destructured && inject_destructured_variable(
137
- variable_name, js_module, imports)
136
+ import = imports.find { |import| import.path == js_module.import_path }
137
+
138
+ if import
139
+ if js_module.is_destructured
140
+ import.inject_destructured_variable(variable_name)
141
+ else
142
+ import.set_default_variable(variable_name)
143
+ end
144
+ else
138
145
  imports.unshift(js_module.to_import_statement(variable_name))
139
146
  end
140
147
 
141
148
  # Remove duplicate import statements
142
- imports.uniq!(&:normalize)
149
+ imports.uniq!(&:to_normalized)
143
150
  end
144
151
 
145
152
  # @param old_imports_lines [Number]
@@ -154,11 +161,11 @@ module ImportJS
154
161
 
155
162
  # Generate import strings
156
163
  import_strings = new_imports.map do |import|
157
- import.to_import_string(
164
+ import.to_import_strings(
158
165
  @config.get('declaration_keyword'),
159
166
  @editor.max_line_length,
160
167
  @editor.tab)
161
- end.sort
168
+ end.flatten.sort
162
169
 
163
170
  # Delete old imports, then add the modified list back in.
164
171
  old_imports_lines.times { @editor.delete_line(1 + imports_start_at) }
@@ -171,17 +178,6 @@ module ImportJS
171
178
  end
172
179
  end
173
180
 
174
- def inject_destructured_variable(variable_name, js_module, imports)
175
- imports.each do |import|
176
- next unless import.path == js_module.import_path
177
- next unless import.is_destructured
178
-
179
- import.inject_variable(variable_name)
180
- return true
181
- end
182
- false
183
- end
184
-
185
181
  # @return [Hash]
186
182
  def find_current_imports
187
183
  potential_import_lines = []
@@ -208,13 +204,32 @@ module ImportJS
208
204
 
209
205
  # Scan potential imports for everything ending in a semicolon, then
210
206
  # iterate through those and stop at anything that's not an import.
207
+ imports = {}
211
208
  potential_imports_blob.scan(/^.*?;/m).each do |potential_import|
212
209
  import_statement = ImportJS::ImportStatement.parse(potential_import)
213
210
  break unless import_statement
214
211
 
215
- result[:imports] << import_statement
212
+ if imports[import_statement.path]
213
+ # Import already exists, so this line is likely one of a destructuring
214
+ # pair. Combine it into the same ImportStatement.
215
+ unless import_statement.default_variable.nil?
216
+ imports[import_statement.path].default_variable =
217
+ import_statement.default_variable
218
+ end
219
+
220
+ if import_statement.destructured?
221
+ imports[import_statement.path].destructured_variables ||= []
222
+ imports[import_statement.path].destructured_variables
223
+ .concat(import_statement.destructured_variables)
224
+ end
225
+ else
226
+ # This is a new import, so we just add it to the hash.
227
+ imports[import_statement.path] = import_statement
228
+ end
229
+
216
230
  result[:newline_count] += potential_import.scan(/\n/).length + 1
217
231
  end
232
+ result[:imports] = imports.values
218
233
  result
219
234
  end
220
235
 
@@ -51,8 +51,11 @@ module ImportJS
51
51
  # @return [ImportJS::ImportStatement]
52
52
  def to_import_statement(variable_name)
53
53
  ImportJS::ImportStatement.new.tap do |statement|
54
- statement.is_destructured = is_destructured
55
- statement.variables = [variable_name]
54
+ if is_destructured
55
+ statement.inject_destructured_variable(variable_name)
56
+ else
57
+ statement.default_variable = variable_name
58
+ end
56
59
  statement.path = import_path
57
60
  end
58
61
  end
@@ -1,4 +1,4 @@
1
1
  # Defines the gem version.
2
2
  module ImportJS
3
- VERSION = '0.2.2'
3
+ VERSION = '0.2.3'
4
4
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: import_js
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.2
4
+ version: 0.2.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Henric Trotzig