sprockets 3.7.3 → 4.0.0.beta1

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 (66) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +2 -299
  3. data/README.md +21 -35
  4. data/bin/sprockets +11 -8
  5. data/lib/rake/sprocketstask.rb +2 -2
  6. data/lib/sprockets/asset.rb +8 -21
  7. data/lib/sprockets/autoload/babel.rb +7 -0
  8. data/lib/sprockets/autoload/jsminc.rb +7 -0
  9. data/lib/sprockets/autoload/sassc.rb +7 -0
  10. data/lib/sprockets/autoload.rb +3 -0
  11. data/lib/sprockets/babel_processor.rb +58 -0
  12. data/lib/sprockets/base.rb +8 -8
  13. data/lib/sprockets/bower.rb +4 -2
  14. data/lib/sprockets/bundle.rb +1 -1
  15. data/lib/sprockets/cache.rb +2 -4
  16. data/lib/sprockets/closure_compressor.rb +1 -2
  17. data/lib/sprockets/coffee_script_processor.rb +9 -3
  18. data/lib/sprockets/compressing.rb +2 -2
  19. data/lib/sprockets/configuration.rb +1 -7
  20. data/lib/sprockets/context.rb +10 -18
  21. data/lib/sprockets/digest_utils.rb +40 -52
  22. data/lib/sprockets/directive_processor.rb +10 -15
  23. data/lib/sprockets/erb_processor.rb +1 -13
  24. data/lib/sprockets/http_utils.rb +19 -4
  25. data/lib/sprockets/jsminc_compressor.rb +31 -0
  26. data/lib/sprockets/jst_processor.rb +10 -10
  27. data/lib/sprockets/loader.rb +34 -28
  28. data/lib/sprockets/manifest.rb +3 -35
  29. data/lib/sprockets/manifest_utils.rb +0 -2
  30. data/lib/sprockets/mime.rb +7 -62
  31. data/lib/sprockets/path_dependency_utils.rb +2 -11
  32. data/lib/sprockets/path_digest_utils.rb +1 -1
  33. data/lib/sprockets/path_utils.rb +43 -18
  34. data/lib/sprockets/preprocessors/default_source_map.rb +24 -0
  35. data/lib/sprockets/processing.rb +30 -61
  36. data/lib/sprockets/processor_utils.rb +27 -28
  37. data/lib/sprockets/resolve.rb +172 -92
  38. data/lib/sprockets/sass_cache_store.rb +1 -6
  39. data/lib/sprockets/sass_compressor.rb +14 -1
  40. data/lib/sprockets/sass_processor.rb +18 -8
  41. data/lib/sprockets/sassc_compressor.rb +30 -0
  42. data/lib/sprockets/sassc_processor.rb +68 -0
  43. data/lib/sprockets/server.rb +11 -22
  44. data/lib/sprockets/source_map_comment_processor.rb +29 -0
  45. data/lib/sprockets/source_map_processor.rb +40 -0
  46. data/lib/sprockets/source_map_utils.rb +345 -0
  47. data/lib/sprockets/transformers.rb +62 -35
  48. data/lib/sprockets/uglifier_compressor.rb +12 -5
  49. data/lib/sprockets/unloaded_asset.rb +12 -11
  50. data/lib/sprockets/uri_tar.rb +4 -2
  51. data/lib/sprockets/uri_utils.rb +5 -8
  52. data/lib/sprockets/utils.rb +30 -79
  53. data/lib/sprockets/version.rb +1 -1
  54. data/lib/sprockets.rb +80 -35
  55. metadata +70 -41
  56. data/LICENSE +0 -21
  57. data/lib/sprockets/coffee_script_template.rb +0 -17
  58. data/lib/sprockets/deprecation.rb +0 -90
  59. data/lib/sprockets/eco_template.rb +0 -17
  60. data/lib/sprockets/ejs_template.rb +0 -17
  61. data/lib/sprockets/engines.rb +0 -92
  62. data/lib/sprockets/erb_template.rb +0 -11
  63. data/lib/sprockets/legacy.rb +0 -330
  64. data/lib/sprockets/legacy_proc_processor.rb +0 -35
  65. data/lib/sprockets/legacy_tilt_processor.rb +0 -29
  66. data/lib/sprockets/sass_template.rb +0 -19
@@ -1,6 +1,5 @@
1
1
  require 'sprockets/asset'
2
2
  require 'sprockets/digest_utils'
3
- require 'sprockets/engines'
4
3
  require 'sprockets/errors'
5
4
  require 'sprockets/file_reader'
6
5
  require 'sprockets/mime'
@@ -18,7 +17,7 @@ module Sprockets
18
17
  # object.
19
18
  module Loader
20
19
  include DigestUtils, PathUtils, ProcessorUtils, URIUtils
21
- include Engines, Mime, Processing, Resolve, Transformers
20
+ include Mime, Processing, Resolve, Transformers
22
21
 
23
22
 
24
23
  # Public: Load Asset by Asset URI.
@@ -27,7 +26,6 @@ module Sprockets
27
26
  # and full path such as:
28
27
  # "file:///Path/app/assets/js/app.js?type=application/javascript"
29
28
  #
30
- #
31
29
  # Returns Asset.
32
30
  def load(uri)
33
31
  unloaded = UnloadedAsset.new(uri, self)
@@ -46,7 +44,7 @@ module Sprockets
46
44
  # The presence of `paths` indicates dependencies were stored.
47
45
  # We can check to see if the dependencies have not changed by "resolving" them and
48
46
  # generating a digest key from the resolved entries. If this digest key has not
49
- # changed the asset will be pulled from cache.
47
+ # changed, the asset will be pulled from cache.
50
48
  #
51
49
  # If this `paths` is present but the cache returns nothing then `fetch_asset_from_dependency_cache`
52
50
  # will confusingly be called again with `paths` set to nil where the asset will be
@@ -61,7 +59,7 @@ module Sprockets
61
59
  end
62
60
  end
63
61
  end
64
- Asset.new(self, asset)
62
+ Asset.new(asset)
65
63
  end
66
64
 
67
65
  private
@@ -103,13 +101,23 @@ module Sprockets
103
101
  raise FileNotFound, "could not find file: #{unloaded.filename}"
104
102
  end
105
103
 
106
- load_path, logical_path = paths_split(config[:paths], unloaded.filename)
104
+ path_to_split =
105
+ if index_alias = unloaded.params[:index_alias]
106
+ expand_from_root index_alias
107
+ else
108
+ unloaded.filename
109
+ end
110
+
111
+ load_path, logical_path = paths_split(config[:paths], path_to_split)
107
112
 
108
113
  unless load_path
109
- raise FileOutsidePaths, "#{unloaded.filename} is no longer under a load path: #{self.paths.join(', ')}"
114
+ target = path_to_split
115
+ target += " (index alias of #{unloaded.filename})" if unloaded.params[:index_alias]
116
+ raise FileOutsidePaths, "#{target} is no longer under a load path: #{self.paths.join(', ')}"
110
117
  end
111
118
 
112
- logical_path, file_type, engine_extnames, _ = parse_path_extnames(logical_path)
119
+ extname, file_type = match_path_extname(logical_path, mime_exts)
120
+ logical_path = logical_path.chomp(extname)
113
121
  name = logical_path
114
122
 
115
123
  if pipeline = unloaded.params[:pipeline]
@@ -124,22 +132,31 @@ module Sprockets
124
132
  raise ConversionError, "could not convert #{file_type.inspect} to #{type.inspect}"
125
133
  end
126
134
 
127
- processors = processors_for(type, file_type, engine_extnames, pipeline)
135
+ processors = processors_for(type, file_type, pipeline)
128
136
 
129
- processors_dep_uri = build_processors_uri(type, file_type, engine_extnames, pipeline)
137
+ processors_dep_uri = build_processors_uri(type, file_type, pipeline)
130
138
  dependencies = config[:dependencies] + [processors_dep_uri]
131
139
 
132
140
  # Read into memory and process if theres a processor pipeline
133
141
  if processors.any?
142
+ source_uri, _ = resolve!(unloaded.filename, pipeline: :source)
143
+ source_asset = load(source_uri)
144
+
145
+ source_path = source_asset.digest_path
146
+
134
147
  result = call_processors(processors, {
135
148
  environment: self,
136
149
  cache: self.cache,
137
150
  uri: unloaded.uri,
138
151
  filename: unloaded.filename,
139
152
  load_path: load_path,
153
+ source_path: source_path,
140
154
  name: name,
141
155
  content_type: type,
142
- metadata: { dependencies: dependencies }
156
+ metadata: {
157
+ dependencies: dependencies,
158
+ map: []
159
+ }
143
160
  })
144
161
  validate_processor_result!(result)
145
162
  source = result.delete(:data)
@@ -171,17 +188,6 @@ module Sprockets
171
188
  asset[:id] = pack_hexdigest(digest(asset))
172
189
  asset[:uri] = build_asset_uri(unloaded.filename, unloaded.params.merge(id: asset[:id]))
173
190
 
174
- # Deprecated: Avoid tracking Asset mtime
175
- asset[:mtime] = metadata[:dependencies].map { |u|
176
- if u.start_with?("file-digest:")
177
- s = self.stat(parse_file_digest_uri(u))
178
- s ? s.mtime.to_i : nil
179
- else
180
- nil
181
- end
182
- }.compact.max
183
- asset[:mtime] ||= self.stat(unloaded.filename).mtime.to_i
184
-
185
191
  store_asset(asset, unloaded)
186
192
  asset
187
193
  end
@@ -255,11 +261,11 @@ module Sprockets
255
261
  # "processors:type=text/css&file_type=text/css&pipeline=self",
256
262
  # "file-digest:///Full/path/app/assets/stylesheets"]
257
263
  #
258
- # Returns back array of things that the given uri dpends on
264
+ # Returns back array of things that the given uri depends on
259
265
  # For example the environment version, if you're using a different version of sprockets
260
266
  # then the dependencies should be different, this is used only for generating cache key
261
267
  # for example the "environment-version" may be resolved to "environment-1.0-3.2.0" for
262
- # version "3.2.0" of sprockets.
268
+ # version "3.2.0" of sprockets.
263
269
  #
264
270
  # Any paths that are returned are converted to relative paths
265
271
  #
@@ -276,9 +282,9 @@ module Sprockets
276
282
  #
277
283
  # This method attempts to retrieve the last `limit` number of histories of an asset
278
284
  # from the cache a "history" which is an array of unresolved "dependencies" that the asset needs
279
- # to compile. In this case A dependency can refer to either an asset i.e. index.js
280
- # may rely on jquery.js (so jquery.js is a depndency), or other factors that may affect
281
- # compilation, such as the VERSION of sprockets (i.e. the environment) and what "processors"
285
+ # to compile. In this case a dependency can refer to either an asset e.g. index.js
286
+ # may rely on jquery.js (so jquery.js is a dependency), or other factors that may affect
287
+ # compilation, such as the VERSION of Sprockets (i.e. the environment) and what "processors"
282
288
  # are used.
283
289
  #
284
290
  # For example a history array may look something like this
@@ -289,7 +295,7 @@ module Sprockets
289
295
  # "file-digest:///Full/path/app/assets/stylesheets"]]
290
296
  #
291
297
  # Where the first entry is a Set of dependencies for last generated version of that asset.
292
- # Multiple versions are stored since sprockets keeps the last `limit` number of assets
298
+ # Multiple versions are stored since Sprockets keeps the last `limit` number of assets
293
299
  # generated present in the system.
294
300
  #
295
301
  # If a "history" of dependencies is present in the cache, each version of "history" will be
@@ -52,14 +52,8 @@ module Sprockets
52
52
  @directory ||= File.dirname(@filename) if @filename
53
53
 
54
54
  # If directory is given w/o filename, pick a random manifest location
55
- @rename_filename = nil
56
55
  if @directory && @filename.nil?
57
56
  @filename = find_directory_manifest(@directory)
58
-
59
- # If legacy manifest name autodetected, mark to rename on save
60
- if File.basename(@filename).start_with?("manifest")
61
- @rename_filename = File.join(@directory, generate_manifest_path)
62
- end
63
57
  end
64
58
 
65
59
  unless @directory && @filename
@@ -125,27 +119,13 @@ module Sprockets
125
119
 
126
120
  return to_enum(__method__, *args) unless block_given?
127
121
 
128
- paths, filters = args.flatten.partition { |arg| self.class.simple_logical_path?(arg) }
129
- filters = filters.map { |arg| self.class.compile_match_filter(arg) }
130
-
131
122
  environment = self.environment.cached
132
-
133
- paths.each do |path|
123
+ args.flatten.each do |path|
134
124
  environment.find_all_linked_assets(path) do |asset|
135
125
  yield asset
136
126
  end
137
127
  end
138
128
 
139
- if filters.any?
140
- environment.logical_paths do |logical_path, filename|
141
- if filters.any? { |f| f.call(logical_path, filename) }
142
- environment.find_all_linked_assets(filename) do |asset|
143
- yield asset
144
- end
145
- end
146
- end
147
- end
148
-
149
129
  nil
150
130
  end
151
131
 
@@ -161,8 +141,7 @@ module Sprockets
161
141
  end
162
142
  else
163
143
  args.each do |path|
164
- asset = assets[path]
165
- yield File.binread(File.join(dir, asset)) if asset
144
+ yield File.binread(File.join(dir, assets[path]))
166
145
  end
167
146
  end
168
147
  end
@@ -186,7 +165,7 @@ module Sprockets
186
165
  find(*args) do |asset|
187
166
  files[asset.digest_path] = {
188
167
  'logical_path' => asset.logical_path,
189
- 'mtime' => asset.mtime.iso8601,
168
+ 'mtime' => Time.now.iso8601,
190
169
  'size' => asset.bytesize,
191
170
  'digest' => asset.hexdigest,
192
171
 
@@ -197,10 +176,6 @@ module Sprockets
197
176
  }
198
177
  assets[asset.logical_path] = asset.digest_path
199
178
 
200
- if alias_logical_path = self.class.compute_alias_logical_path(asset.logical_path)
201
- assets[alias_logical_path] = asset.digest_path
202
- end
203
-
204
179
  target = File.join(dir, asset.digest_path)
205
180
 
206
181
  if File.exist?(target)
@@ -300,13 +275,6 @@ module Sprockets
300
275
 
301
276
  # Persist manfiest back to FS
302
277
  def save
303
- if @rename_filename
304
- logger.info "Renaming #{@filename} to #{@rename_filename}"
305
- FileUtils.mv(@filename, @rename_filename)
306
- @filename = @rename_filename
307
- @rename_filename = nil
308
- end
309
-
310
278
  data = json_encode(@data)
311
279
  FileUtils.mkdir_p File.dirname(@filename)
312
280
  PathUtils.atomic_write(@filename) do |f|
@@ -36,8 +36,6 @@ module Sprockets
36
36
  def find_directory_manifest(dirname)
37
37
  entries = File.directory?(dirname) ? Dir.entries(dirname) : []
38
38
  entry = entries.find { |e| e =~ MANIFEST_RE } ||
39
- # Deprecated: Will be removed in 4.x
40
- entries.find { |e| e =~ LEGACY_MANIFEST_RE } ||
41
39
  generate_manifest_path
42
40
  File.join(dirname, entry)
43
41
  end
@@ -36,29 +36,18 @@ module Sprockets
36
36
 
37
37
  # Public: Register a new mime type.
38
38
  #
39
- # mime_type - String MIME Type
40
- # options - Hash
41
- # extensions: Array of String extnames
42
- # charset: Proc/Method that detects the charset of a file.
43
- # See EncodingUtils.
39
+ # mime_type - String MIME Type
40
+ # extensions - Array of String extnames
41
+ # charset - Proc/Method that detects the charset of a file.
42
+ # See EncodingUtils.
44
43
  #
45
44
  # Returns nothing.
46
- def register_mime_type(mime_type, options = {})
47
- # Legacy extension argument, will be removed from 4.x
48
- if options.is_a?(String)
49
- options = { extensions: [options] }
50
- end
51
-
52
- extnames = Array(options[:extensions]).map { |extname|
53
- Sprockets::Utils.normalize_extension(extname)
54
- }
45
+ def register_mime_type(mime_type, extensions: [], charset: nil)
46
+ extnames = Array(extensions)
55
47
 
56
- charset = options[:charset]
57
48
  charset ||= :default if mime_type.start_with?('text/')
58
49
  charset = EncodingUtils::CHARSET_DETECT[charset] if charset.is_a?(Symbol)
59
50
 
60
- self.computed_config = {}
61
-
62
51
  self.config = hash_reassoc(config, :mime_exts) do |mime_exts|
63
52
  extnames.each do |extname|
64
53
  mime_exts[extname] = mime_type
@@ -97,54 +86,10 @@ module Sprockets
97
86
  data = File.binread(filename)
98
87
 
99
88
  if detect = mime_type_charset_detecter(content_type)
100
- detect.call(data).encode(Encoding::UTF_8, :universal_newline => true)
89
+ detect.call(data).encode(Encoding::UTF_8, universal_newline: true)
101
90
  else
102
91
  data
103
92
  end
104
93
  end
105
-
106
- private
107
- def extname_map
108
- self.computed_config[:_extnames] ||= compute_extname_map
109
- end
110
-
111
- def compute_extname_map
112
- graph = {}
113
-
114
- engine_extname_permutation = []
115
-
116
- 4.times do |n|
117
- config[:engines].keys.permutation(n).each do |engine_extnames|
118
- engine_extname_permutation << engine_extnames
119
- end
120
- end
121
-
122
- mime_exts_grouped_by_mime_type = {}
123
- config[:mime_exts].each do |format_extname,format_type|
124
- mime_exts_grouped_by_mime_type[format_type] ||= []
125
- mime_exts_grouped_by_mime_type[format_type] << format_extname
126
- end
127
-
128
- ([nil] + pipelines.keys.map(&:to_s)).each do |pipeline|
129
- pipeline_extname = pipeline ? ".#{pipeline}" : ''.freeze
130
- engine_extname_permutation.each do |engine_extnames|
131
- mime_exts_grouped_by_mime_type.each do |format_type, format_extnames|
132
- type = format_type
133
- value = [type, engine_extnames, pipeline]
134
- format_extnames.each do |format_extname|
135
- key = "#{pipeline_extname}#{format_extname}#{engine_extnames.join}"
136
- graph[key] = value
137
- end
138
- if format_type == config[:engine_mime_types][engine_extnames.first]
139
- key = "#{pipeline_extname}#{engine_extnames.join}"
140
- graph[key] = value
141
- end
142
- end
143
- end
144
- graph[pipeline_extname] = [nil, [], pipeline]
145
- end
146
-
147
- graph
148
- end
149
94
  end
150
95
  end
@@ -41,7 +41,7 @@ module Sprockets
41
41
  #
42
42
  # Returns an Array of entry names and a Set of dependency URIs.
43
43
  def entries_with_dependencies(path)
44
- return entries(path), file_digest_dependency_set(path)
44
+ return entries(path), Set.new([build_file_digest_uri(path)])
45
45
  end
46
46
 
47
47
  # Internal: List directory filenames and associated Stats under a
@@ -53,16 +53,7 @@ module Sprockets
53
53
  #
54
54
  # Returns an Array of filenames and a Set of dependency URIs.
55
55
  def stat_directory_with_dependencies(dir)
56
- return stat_directory(dir).to_a, file_digest_dependency_set(dir)
57
- end
58
-
59
- # Internal: Returns a set of dependencies for a particular path.
60
- #
61
- # path - String directory path
62
- #
63
- # Returns a Set of dependency URIs.
64
- def file_digest_dependency_set(path)
65
- Set.new([build_file_digest_uri(path)])
56
+ return stat_directory(dir).to_a, Set.new([build_file_digest_uri(dir)])
66
57
  end
67
58
 
68
59
  # Internal: List directory filenames and associated Stats under an entire
@@ -15,7 +15,7 @@ module Sprockets
15
15
  def stat_digest(path, stat)
16
16
  if stat.directory?
17
17
  # If its a directive, digest the list of filenames
18
- digest_class.digest(self.entries(path).join(','))
18
+ digest_class.digest(self.entries(path).join(','.freeze))
19
19
  elsif stat.file?
20
20
  # If its a file, digest the contents
21
21
  digest_class.file(path.to_s).digest
@@ -1,3 +1,5 @@
1
+ require 'fileutils'
2
+
1
3
  module Sprockets
2
4
  # Internal: File and path related utilities. Mixed into Environment.
3
5
  #
@@ -53,13 +55,12 @@ module Sprockets
53
55
  # Returns an empty `Array` if the directory does not exist.
54
56
  def entries(path)
55
57
  if File.directory?(path)
56
- entries = Dir.entries(path, :encoding => Encoding.default_internal)
58
+ entries = Dir.entries(path, encoding: Encoding.default_internal)
57
59
  entries.reject! { |entry|
58
- entry.start_with?(".".freeze) ||
59
- (entry.start_with?("#".freeze) && entry.end_with?("#".freeze)) ||
60
- entry.end_with?("~".freeze)
60
+ entry =~ /^\.|~$|^\#.*\#$/
61
61
  }
62
62
  entries.sort!
63
+ entries
63
64
  else
64
65
  []
65
66
  end
@@ -109,7 +110,7 @@ module Sprockets
109
110
  # subpath is outside of path.
110
111
  def split_subpath(path, subpath)
111
112
  return "" if path == subpath
112
- path = File.join(path, '')
113
+ path = File.join(path, ''.freeze)
113
114
  if subpath.start_with?(path)
114
115
  subpath[path.length..-1]
115
116
  else
@@ -148,19 +149,43 @@ module Sprockets
148
149
  #
149
150
  # Returns [String extname, Object value] or nil nothing matched.
150
151
  def match_path_extname(path, extensions)
151
- basename = File.basename(path)
152
-
153
- i = basename.index('.'.freeze)
154
- while i && i < basename.length - 1
155
- extname = basename[i..-1]
156
- if value = extensions[extname]
157
- return extname, value
152
+ match, key = nil, ""
153
+ path_extnames(path).reverse_each do |extname|
154
+ key.prepend(extname)
155
+ if value = extensions[key]
156
+ match = [key.dup, value]
157
+ elsif match
158
+ break
158
159
  end
159
-
160
- i = basename.index('.'.freeze, i+1)
161
160
  end
161
+ match
162
+ end
162
163
 
163
- nil
164
+ # Internal: Match paths in a directory against available extensions.
165
+ #
166
+ # path - String directory
167
+ # basename - String basename of target file
168
+ # extensions - Hash of String extnames to values
169
+ #
170
+ # Examples
171
+ #
172
+ # exts = { ".js" => "application/javascript" }
173
+ # find_matching_path_for_extensions("app/assets", "application", exts)
174
+ # # => ["app/assets/application.js", "application/javascript"]
175
+ #
176
+ # Returns an Array of [String path, Object value] matches.
177
+ def find_matching_path_for_extensions(path, basename, extensions)
178
+ matches = []
179
+ entries(path).each do |entry|
180
+ extname, value = match_path_extname(entry, extensions)
181
+ if basename == entry.chomp(extname)
182
+ filename = File.join(path, entry)
183
+ if file?(filename)
184
+ matches << [filename, value]
185
+ end
186
+ end
187
+ end
188
+ matches
164
189
  end
165
190
 
166
191
  # Internal: Returns all parents for path
@@ -272,16 +297,16 @@ module Sprockets
272
297
  Thread.current.object_id,
273
298
  Process.pid,
274
299
  rand(1000000)
275
- ].join('.')
300
+ ].join('.'.freeze)
276
301
  tmpname = File.join(dirname, basename)
277
302
 
278
303
  File.open(tmpname, 'wb+') do |f|
279
304
  yield f
280
305
  end
281
306
 
282
- File.rename(tmpname, filename)
307
+ FileUtils.mv(tmpname, filename)
283
308
  ensure
284
- File.delete(tmpname) if File.exist?(tmpname)
309
+ FileUtils.rm(tmpname) if File.exist?(tmpname)
285
310
  end
286
311
  end
287
312
  end
@@ -0,0 +1,24 @@
1
+ module Sprockets
2
+ module Preprocessors
3
+ # Private: Adds a default map to assets when one is not present
4
+ #
5
+ # If the input file already has a source map, it effectively returns the original
6
+ # result. Otherwise it maps 1 for 1 lines original to generated. This is needed
7
+ # Because other generators run after might depend on having a valid source map
8
+ # available.
9
+ class DefaultSourceMap
10
+ def call(input)
11
+ result = { data: input[:data] }
12
+ map = input[:metadata][:map]
13
+ if map.nil? || map.empty?
14
+ result[:map] ||= []
15
+ input[:data].each_line.with_index do |_, index|
16
+ line = index + 1
17
+ result[:map] << { source: input[:source_path], generated: [line , 0], original: [line, 0] }
18
+ end
19
+ end
20
+ return result
21
+ end
22
+ end
23
+ end
24
+ end