import_js 0.4.0 → 0.4.1
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/lib/import_js/configuration.rb +5 -5
- data/lib/import_js/emacs_editor.rb +3 -3
- data/lib/import_js/import_statement.rb +3 -3
- data/lib/import_js/importer.rb +54 -16
- data/lib/import_js/js_module.rb +56 -11
- data/lib/import_js/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3808c953be3c8a47d0212d952f35b4329774cba8
|
4
|
+
data.tar.gz: f1929ccab0f99004521babc2dbbf8d35347c7313
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9380c3f44a4306a0e9d843496bf846c47200e696649a88348135e9c7f1d928e04ad5520d67a7c15beb3306e02af1ad7aa2fd2aaaef983c0eec2463e6ca9fd288
|
7
|
+
data.tar.gz: cc46051020022e9e7ba9db5b4c8750b104ad372bb72442f5fb7712867084f8bfff92f9dcba06826ca77d87a42d4897dfe72b5b96b7fb89f7dcb61d804e684f75
|
@@ -57,7 +57,7 @@ module ImportJS
|
|
57
57
|
path = path.sub(/\{filename\}/,
|
58
58
|
File.basename(path_to_current_file, '.*'))
|
59
59
|
end
|
60
|
-
|
60
|
+
JSModule.new(import_path: path)
|
61
61
|
end
|
62
62
|
|
63
63
|
# @param variable_name [String]
|
@@ -66,7 +66,7 @@ module ImportJS
|
|
66
66
|
get('named_exports').each do |import_path, named_exports|
|
67
67
|
next unless named_exports.include?(variable_name)
|
68
68
|
|
69
|
-
js_module =
|
69
|
+
js_module = JSModule.new(import_path: import_path)
|
70
70
|
js_module.has_named_exports = true
|
71
71
|
return js_module
|
72
72
|
end
|
@@ -108,11 +108,11 @@ module ImportJS
|
|
108
108
|
def check_current_version!
|
109
109
|
minimum_version = get('minimum_version')
|
110
110
|
return if Gem::Dependency.new('', ">= #{minimum_version}")
|
111
|
-
.match?('',
|
111
|
+
.match?('', VERSION)
|
112
112
|
|
113
|
-
fail
|
113
|
+
fail ClientTooOldError,
|
114
114
|
'The .importjs.json file you are using requires version ' \
|
115
|
-
"#{get('minimum_version')}. You are using #{
|
115
|
+
"#{get('minimum_version')}. You are using #{VERSION}."
|
116
116
|
end
|
117
117
|
end
|
118
118
|
end
|
@@ -16,13 +16,13 @@ module ImportJS
|
|
16
16
|
|
17
17
|
case command
|
18
18
|
when 'import'
|
19
|
-
|
19
|
+
Importer.new(self).import
|
20
20
|
write_file
|
21
21
|
puts 'import:success'
|
22
22
|
when 'goto'
|
23
|
-
|
23
|
+
Importer.new(self).goto
|
24
24
|
when 'fix'
|
25
|
-
|
25
|
+
Importer.new(self).fix_imports
|
26
26
|
write_file
|
27
27
|
puts 'import:success'
|
28
28
|
else
|
@@ -1,7 +1,7 @@
|
|
1
1
|
module ImportJS
|
2
2
|
# Class that represents an import statement, e.g.
|
3
3
|
# `const foo = require('foo');`
|
4
|
-
# `
|
4
|
+
# `var foo = myCustomRequire('foo');`
|
5
5
|
# `import foo from 'foo';`
|
6
6
|
class ImportStatement
|
7
7
|
REGEX_CONST_LET_VAR = /
|
@@ -50,7 +50,7 @@ module ImportJS
|
|
50
50
|
|
51
51
|
# @param string [String] a possible import statement, e.g.
|
52
52
|
# `const foo = require('foo');`
|
53
|
-
# `
|
53
|
+
# `var foo = myCustomRequire('foo');`
|
54
54
|
# `import foo from 'foo';`
|
55
55
|
# @return [ImportJS::ImportStatement?] a parsed statement, or nil if the
|
56
56
|
# string can't be parsed
|
@@ -138,7 +138,7 @@ module ImportJS
|
|
138
138
|
else
|
139
139
|
[default_import_string(max_line_length, tab)]
|
140
140
|
end
|
141
|
-
else # const/
|
141
|
+
else # const/var
|
142
142
|
strings = []
|
143
143
|
|
144
144
|
if default_import
|
data/lib/import_js/importer.rb
CHANGED
@@ -9,14 +9,14 @@ module ImportJS
|
|
9
9
|
REGEX_MULTI_LINE_COMMENT_END = %r{\*/}
|
10
10
|
REGEX_WHITESPACE_ONLY = /\A\s*\Z/
|
11
11
|
|
12
|
-
def initialize(editor =
|
12
|
+
def initialize(editor = VIMEditor.new)
|
13
13
|
@editor = editor
|
14
14
|
end
|
15
15
|
|
16
16
|
# Finds variable under the cursor to import. By default, this is bound to
|
17
17
|
# `<Leader>j`.
|
18
18
|
def import
|
19
|
-
|
19
|
+
reload_config
|
20
20
|
variable_name = @editor.current_word
|
21
21
|
if variable_name.empty?
|
22
22
|
message(<<-EOS.split.join(' '))
|
@@ -39,17 +39,29 @@ module ImportJS
|
|
39
39
|
end
|
40
40
|
|
41
41
|
def goto
|
42
|
-
|
42
|
+
reload_config
|
43
43
|
js_modules = []
|
44
44
|
variable_name = @editor.current_word
|
45
45
|
time do
|
46
46
|
js_modules = find_js_modules(variable_name)
|
47
47
|
end
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
48
|
+
|
49
|
+
if js_modules.empty?
|
50
|
+
# No JS modules are found for the variable, so there is nothing to go to
|
51
|
+
# and we return early.
|
52
|
+
return message("No modules were found for `#{variable_name}`")
|
53
|
+
end
|
54
|
+
|
55
|
+
js_module = resolve_goto_module(js_modules, variable_name)
|
56
|
+
|
57
|
+
unless js_module
|
58
|
+
# The current word is not mappable to one of the JS modules that we
|
59
|
+
# found. This can happen if the user does not select one from the list.
|
60
|
+
# We have nothing to go to, so we return early.
|
61
|
+
return message("Could not resolve a module for `#{variable_name}`")
|
52
62
|
end
|
63
|
+
|
64
|
+
@editor.open_file(js_module.open_file_path(@editor.path_to_current_file))
|
53
65
|
end
|
54
66
|
|
55
67
|
REGEX_ESLINT_RESULT = /
|
@@ -68,7 +80,7 @@ module ImportJS
|
|
68
80
|
|
69
81
|
# Removes unused imports and adds imports for undefined variables
|
70
82
|
def fix_imports
|
71
|
-
|
83
|
+
reload_config
|
72
84
|
eslint_result = run_eslint_command
|
73
85
|
|
74
86
|
unused_variables = []
|
@@ -107,6 +119,13 @@ module ImportJS
|
|
107
119
|
|
108
120
|
private
|
109
121
|
|
122
|
+
# The configuration is relative to the current file, so we need to make sure
|
123
|
+
# that we are operating with the appropriate configuration when we perform
|
124
|
+
# certain actions.
|
125
|
+
def reload_config
|
126
|
+
@config = Configuration.new(@editor.path_to_current_file)
|
127
|
+
end
|
128
|
+
|
110
129
|
def message(str)
|
111
130
|
@editor.message("ImportJS: #{str}")
|
112
131
|
end
|
@@ -139,11 +158,11 @@ module ImportJS
|
|
139
158
|
stdin_data: @editor.current_file_content)
|
140
159
|
|
141
160
|
if ESLINT_STDOUT_ERROR_REGEXES.any? { |regex| out =~ regex }
|
142
|
-
fail
|
161
|
+
fail ParseError.new, out
|
143
162
|
end
|
144
163
|
|
145
164
|
if ESLINT_STDERR_ERROR_REGEXES.any? { |regex| err =~ regex }
|
146
|
-
fail
|
165
|
+
fail ParseError.new, err
|
147
166
|
end
|
148
167
|
|
149
168
|
out.split("\n")
|
@@ -296,7 +315,7 @@ module ImportJS
|
|
296
315
|
# iterate through those and stop at anything that's not an import.
|
297
316
|
imports = {}
|
298
317
|
potential_imports_blob.scan(/^.*?;/m).each do |potential_import|
|
299
|
-
import_statement =
|
318
|
+
import_statement = ImportStatement.parse(potential_import)
|
300
319
|
break unless import_statement
|
301
320
|
|
302
321
|
if imports[import_statement.path]
|
@@ -333,7 +352,7 @@ module ImportJS
|
|
333
352
|
if lookup_path == ''
|
334
353
|
# If lookup_path is an empty string, the `find` command will not work
|
335
354
|
# as desired so we bail early.
|
336
|
-
fail
|
355
|
+
fail FindError.new,
|
337
356
|
"lookup path cannot be empty (#{lookup_path.inspect})"
|
338
357
|
end
|
339
358
|
|
@@ -345,14 +364,14 @@ module ImportJS
|
|
345
364
|
command = "#{find_command} | #{egrep_command}"
|
346
365
|
out, err = Open3.capture3(command)
|
347
366
|
|
348
|
-
fail
|
367
|
+
fail FindError.new, err unless err == ''
|
349
368
|
|
350
369
|
matched_modules.concat(
|
351
370
|
out.split("\n").map do |f|
|
352
371
|
next if @config.get('excludes').any? do |glob_pattern|
|
353
372
|
File.fnmatch(glob_pattern, f)
|
354
373
|
end
|
355
|
-
|
374
|
+
JSModule.construct(
|
356
375
|
lookup_path: lookup_path,
|
357
376
|
relative_file_path: f,
|
358
377
|
strip_file_extensions:
|
@@ -376,7 +395,7 @@ module ImportJS
|
|
376
395
|
@config.package_dependencies.each do |dep|
|
377
396
|
next unless dep =~ dep_regex
|
378
397
|
|
379
|
-
js_module =
|
398
|
+
js_module = JSModule.construct(
|
380
399
|
lookup_path: 'node_modules',
|
381
400
|
relative_file_path: "node_modules/#{dep}/package.json",
|
382
401
|
strip_file_extensions: [])
|
@@ -399,7 +418,7 @@ module ImportJS
|
|
399
418
|
|
400
419
|
# @param js_modules [Array]
|
401
420
|
# @param variable_name [String]
|
402
|
-
# @return [
|
421
|
+
# @return [ImportJS::JSModule]
|
403
422
|
def resolve_one_js_module(js_modules, variable_name)
|
404
423
|
if js_modules.length == 1
|
405
424
|
js_module = js_modules.first
|
@@ -421,6 +440,25 @@ module ImportJS
|
|
421
440
|
js_modules[selected_index]
|
422
441
|
end
|
423
442
|
|
443
|
+
# @param js_modules [Array]
|
444
|
+
# @param variable_name [String]
|
445
|
+
# @return [ImportJS::JSModule]
|
446
|
+
def resolve_goto_module(js_modules, variable_name)
|
447
|
+
return js_modules.first if js_modules.length == 1
|
448
|
+
|
449
|
+
# Look for a current import matching the goto
|
450
|
+
find_current_imports[:imports].each do |ist|
|
451
|
+
js_modules.each do |js_module|
|
452
|
+
next unless variable_name == ist.default_import ||
|
453
|
+
(ist.named_imports || []).include?(variable_name)
|
454
|
+
return js_module if ist.path == js_module.import_path
|
455
|
+
end
|
456
|
+
end
|
457
|
+
|
458
|
+
# Fall back to asking the user to resolve the ambiguity
|
459
|
+
resolve_one_js_module(js_modules, variable_name)
|
460
|
+
end
|
461
|
+
|
424
462
|
# Takes a string in any of the following four formats:
|
425
463
|
# dash-separated
|
426
464
|
# snake_case
|
data/lib/import_js/js_module.rb
CHANGED
@@ -52,10 +52,28 @@ module ImportJS
|
|
52
52
|
# @return [String, String]
|
53
53
|
def self.resolve_import_path_and_main(file_path, strip_file_extensions)
|
54
54
|
if file_path.end_with? '/package.json'
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
return
|
55
|
+
return [nil, nil] unless File.exist?(file_path)
|
56
|
+
|
57
|
+
file_contents = File.read(file_path)
|
58
|
+
return [nil, nil] if file_contents.strip.empty?
|
59
|
+
|
60
|
+
main_file = JSON.parse(file_contents)['main']
|
61
|
+
match = file_path.match(%r{(?<package>.*)/package\.json})
|
62
|
+
|
63
|
+
unless main_file
|
64
|
+
index_file = find_index(match[:package])
|
65
|
+
return [nil, nil] unless index_file
|
66
|
+
main_file = index_file
|
67
|
+
end
|
68
|
+
|
69
|
+
if File.directory?("#{match[:package]}/#{main_file}")
|
70
|
+
# The main in package.json refers to a directory, so we want to
|
71
|
+
# resolve it to an index file.
|
72
|
+
index_file = find_index("#{match[:package]}/#{main_file}")
|
73
|
+
main_file += "/#{index_file}" if index_file
|
74
|
+
end
|
75
|
+
|
76
|
+
return match[:package], main_file
|
59
77
|
end
|
60
78
|
|
61
79
|
match = file_path.match(%r{(.*)/(index\.js[^/]*)$})
|
@@ -66,6 +84,15 @@ module ImportJS
|
|
66
84
|
[import_path, nil]
|
67
85
|
end
|
68
86
|
|
87
|
+
# @param directory [String]
|
88
|
+
# @return [String, nil]
|
89
|
+
def self.find_index(directory)
|
90
|
+
%w[index.js index.jsx].each do |index_file|
|
91
|
+
return index_file if File.exist? "#{directory}/#{index_file}"
|
92
|
+
end
|
93
|
+
nil
|
94
|
+
end
|
95
|
+
|
69
96
|
# @param import_path [String]
|
70
97
|
def initialize(import_path: nil)
|
71
98
|
self.import_path = import_path
|
@@ -110,23 +137,41 @@ module ImportJS
|
|
110
137
|
# @param path_to_current_file [String]
|
111
138
|
# @return [String]
|
112
139
|
def open_file_path(path_to_current_file)
|
113
|
-
if file_path
|
114
|
-
|
140
|
+
if @file_path
|
141
|
+
# There is a file_path. This happens for JSModules that are not aliases.
|
142
|
+
return @file_path unless @file_path.end_with?('/package.json')
|
143
|
+
|
144
|
+
# The file_path points to a package.json file, so we want to look in
|
145
|
+
# that package.json file for a `main` configuration value and open that
|
146
|
+
# file instead.
|
147
|
+
return @file_path.sub(/package\.json$/, main_file)
|
115
148
|
end
|
116
|
-
return file_path if file_path
|
117
149
|
|
118
|
-
|
119
|
-
|
150
|
+
# There is no file_path. This likely means that we are working with an
|
151
|
+
# alias, so we want to expand it to a full path if we can.
|
152
|
+
|
153
|
+
if @import_path.start_with?('.')
|
154
|
+
# The import path in the alias starts with a ".", which means that it is
|
155
|
+
# relative to the current file. In order to open this file, we need to
|
156
|
+
# expand it to a full path.
|
157
|
+
return File.expand_path(
|
158
|
+
@import_path, File.dirname(path_to_current_file))
|
120
159
|
end
|
121
160
|
|
122
|
-
|
161
|
+
# This is likely an alias that points to a package, so let's try to find
|
162
|
+
# its main file from its package.json file.
|
163
|
+
file_path = "node_modules/#{@import_path}/package.json"
|
164
|
+
_, main = self.class.resolve_import_path_and_main(file_path, [])
|
165
|
+
return "node_modules/#{@import_path}/#{main}" if main
|
166
|
+
|
167
|
+
@import_path
|
123
168
|
end
|
124
169
|
|
125
170
|
# @param variable_name [String]
|
126
171
|
# @param config [ImportJS::Configuration]
|
127
172
|
# @return [ImportJS::ImportStatement]
|
128
173
|
def to_import_statement(variable_name, config)
|
129
|
-
|
174
|
+
ImportStatement.new.tap do |statement|
|
130
175
|
if has_named_exports
|
131
176
|
statement.inject_named_import(variable_name)
|
132
177
|
else
|
data/lib/import_js/version.rb
CHANGED