sprockets 4.0.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 +7 -0
- data/CHANGELOG.md +72 -0
- data/README.md +665 -0
- data/bin/sprockets +93 -0
- data/lib/rake/sprocketstask.rb +153 -0
- data/lib/sprockets.rb +229 -0
- data/lib/sprockets/add_source_map_comment_to_asset_processor.rb +60 -0
- data/lib/sprockets/asset.rb +202 -0
- data/lib/sprockets/autoload.rb +16 -0
- data/lib/sprockets/autoload/babel.rb +8 -0
- data/lib/sprockets/autoload/closure.rb +8 -0
- data/lib/sprockets/autoload/coffee_script.rb +8 -0
- data/lib/sprockets/autoload/eco.rb +8 -0
- data/lib/sprockets/autoload/ejs.rb +8 -0
- data/lib/sprockets/autoload/jsminc.rb +8 -0
- data/lib/sprockets/autoload/sass.rb +8 -0
- data/lib/sprockets/autoload/sassc.rb +8 -0
- data/lib/sprockets/autoload/uglifier.rb +8 -0
- data/lib/sprockets/autoload/yui.rb +8 -0
- data/lib/sprockets/autoload/zopfli.rb +7 -0
- data/lib/sprockets/babel_processor.rb +66 -0
- data/lib/sprockets/base.rb +147 -0
- data/lib/sprockets/bower.rb +61 -0
- data/lib/sprockets/bundle.rb +105 -0
- data/lib/sprockets/cache.rb +271 -0
- data/lib/sprockets/cache/file_store.rb +208 -0
- data/lib/sprockets/cache/memory_store.rb +75 -0
- data/lib/sprockets/cache/null_store.rb +54 -0
- data/lib/sprockets/cached_environment.rb +64 -0
- data/lib/sprockets/closure_compressor.rb +48 -0
- data/lib/sprockets/coffee_script_processor.rb +39 -0
- data/lib/sprockets/compressing.rb +134 -0
- data/lib/sprockets/configuration.rb +79 -0
- data/lib/sprockets/context.rb +304 -0
- data/lib/sprockets/dependencies.rb +74 -0
- data/lib/sprockets/digest_utils.rb +200 -0
- data/lib/sprockets/directive_processor.rb +414 -0
- data/lib/sprockets/eco_processor.rb +33 -0
- data/lib/sprockets/ejs_processor.rb +32 -0
- data/lib/sprockets/encoding_utils.rb +262 -0
- data/lib/sprockets/environment.rb +46 -0
- data/lib/sprockets/erb_processor.rb +37 -0
- data/lib/sprockets/errors.rb +12 -0
- data/lib/sprockets/exporters/base.rb +71 -0
- data/lib/sprockets/exporters/file_exporter.rb +24 -0
- data/lib/sprockets/exporters/zlib_exporter.rb +33 -0
- data/lib/sprockets/exporters/zopfli_exporter.rb +14 -0
- data/lib/sprockets/exporting.rb +73 -0
- data/lib/sprockets/file_reader.rb +16 -0
- data/lib/sprockets/http_utils.rb +135 -0
- data/lib/sprockets/jsminc_compressor.rb +32 -0
- data/lib/sprockets/jst_processor.rb +50 -0
- data/lib/sprockets/loader.rb +345 -0
- data/lib/sprockets/manifest.rb +338 -0
- data/lib/sprockets/manifest_utils.rb +48 -0
- data/lib/sprockets/mime.rb +96 -0
- data/lib/sprockets/npm.rb +52 -0
- data/lib/sprockets/path_dependency_utils.rb +77 -0
- data/lib/sprockets/path_digest_utils.rb +48 -0
- data/lib/sprockets/path_utils.rb +367 -0
- data/lib/sprockets/paths.rb +82 -0
- data/lib/sprockets/preprocessors/default_source_map.rb +49 -0
- data/lib/sprockets/processing.rb +228 -0
- data/lib/sprockets/processor_utils.rb +169 -0
- data/lib/sprockets/resolve.rb +295 -0
- data/lib/sprockets/sass_cache_store.rb +30 -0
- data/lib/sprockets/sass_compressor.rb +63 -0
- data/lib/sprockets/sass_functions.rb +3 -0
- data/lib/sprockets/sass_importer.rb +3 -0
- data/lib/sprockets/sass_processor.rb +313 -0
- data/lib/sprockets/sassc_compressor.rb +56 -0
- data/lib/sprockets/sassc_processor.rb +297 -0
- data/lib/sprockets/server.rb +295 -0
- data/lib/sprockets/source_map_processor.rb +66 -0
- data/lib/sprockets/source_map_utils.rb +483 -0
- data/lib/sprockets/transformers.rb +173 -0
- data/lib/sprockets/uglifier_compressor.rb +66 -0
- data/lib/sprockets/unloaded_asset.rb +139 -0
- data/lib/sprockets/uri_tar.rb +99 -0
- data/lib/sprockets/uri_utils.rb +191 -0
- data/lib/sprockets/utils.rb +202 -0
- data/lib/sprockets/utils/gzip.rb +99 -0
- data/lib/sprockets/version.rb +4 -0
- data/lib/sprockets/yui_compressor.rb +56 -0
- metadata +444 -0
@@ -0,0 +1,82 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require 'sprockets/path_utils'
|
3
|
+
require 'sprockets/utils'
|
4
|
+
|
5
|
+
module Sprockets
|
6
|
+
module Paths
|
7
|
+
include PathUtils, Utils
|
8
|
+
|
9
|
+
# Returns `Environment` root.
|
10
|
+
#
|
11
|
+
# All relative paths are expanded with root as its base. To be
|
12
|
+
# useful set this to your applications root directory. (`Rails.root`)
|
13
|
+
def root
|
14
|
+
config[:root]
|
15
|
+
end
|
16
|
+
|
17
|
+
# Internal: Change Environment root.
|
18
|
+
#
|
19
|
+
# Only the initializer should change the root.
|
20
|
+
def root=(path)
|
21
|
+
self.config = hash_reassoc(config, :root) do
|
22
|
+
File.expand_path(path)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
private :root=
|
26
|
+
|
27
|
+
# Returns an `Array` of path `String`s.
|
28
|
+
#
|
29
|
+
# These paths will be used for asset logical path lookups.
|
30
|
+
def paths
|
31
|
+
config[:paths]
|
32
|
+
end
|
33
|
+
|
34
|
+
# Prepend a `path` to the `paths` list.
|
35
|
+
#
|
36
|
+
# Paths at the end of the `Array` have the least priority.
|
37
|
+
def prepend_path(path)
|
38
|
+
self.config = hash_reassoc(config, :paths) do |paths|
|
39
|
+
path = File.expand_path(path, config[:root]).freeze
|
40
|
+
paths.unshift(path)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
# Append a `path` to the `paths` list.
|
45
|
+
#
|
46
|
+
# Paths at the beginning of the `Array` have a higher priority.
|
47
|
+
def append_path(path)
|
48
|
+
self.config = hash_reassoc(config, :paths) do |paths|
|
49
|
+
path = File.expand_path(path, config[:root]).freeze
|
50
|
+
paths.push(path)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
# Clear all paths and start fresh.
|
55
|
+
#
|
56
|
+
# There is no mechanism for reordering paths, so its best to
|
57
|
+
# completely wipe the paths list and reappend them in the order
|
58
|
+
# you want.
|
59
|
+
def clear_paths
|
60
|
+
self.config = hash_reassoc(config, :paths) do |paths|
|
61
|
+
paths.clear
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
# Public: Iterate over every file under all load paths.
|
66
|
+
#
|
67
|
+
# Returns Enumerator if no block is given.
|
68
|
+
def each_file
|
69
|
+
return to_enum(__method__) unless block_given?
|
70
|
+
|
71
|
+
paths.each do |root|
|
72
|
+
stat_tree(root).each do |filename, stat|
|
73
|
+
if stat.file?
|
74
|
+
yield filename
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
nil
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module Sprockets
|
3
|
+
module Preprocessors
|
4
|
+
# Private: Adds a default map to assets when one is not present
|
5
|
+
#
|
6
|
+
# If the input file already has a source map, it effectively returns the original
|
7
|
+
# result. Otherwise it maps 1 for 1 lines original to generated. This is needed
|
8
|
+
# Because other generators run after might depend on having a valid source map
|
9
|
+
# available.
|
10
|
+
class DefaultSourceMap
|
11
|
+
def call(input)
|
12
|
+
result = { data: input[:data] }
|
13
|
+
map = input[:metadata][:map]
|
14
|
+
filename = input[:filename]
|
15
|
+
load_path = input[:load_path]
|
16
|
+
lines = input[:data].lines.length
|
17
|
+
basename = File.basename(filename)
|
18
|
+
mime_exts = input[:environment].config[:mime_exts]
|
19
|
+
pipeline_exts = input[:environment].config[:pipeline_exts]
|
20
|
+
if map.nil? || map.empty?
|
21
|
+
result[:map] = {
|
22
|
+
"version" => 3,
|
23
|
+
"file" => PathUtils.split_subpath(load_path, filename),
|
24
|
+
"mappings" => default_mappings(lines),
|
25
|
+
"sources" => [PathUtils.set_pipeline(basename, mime_exts, pipeline_exts, :source)],
|
26
|
+
"names" => []
|
27
|
+
}
|
28
|
+
else
|
29
|
+
result[:map] = map
|
30
|
+
end
|
31
|
+
|
32
|
+
result[:map]["x_sprockets_linecount"] = lines
|
33
|
+
return result
|
34
|
+
end
|
35
|
+
|
36
|
+
private
|
37
|
+
|
38
|
+
def default_mappings(lines)
|
39
|
+
if (lines == 0)
|
40
|
+
""
|
41
|
+
elsif (lines == 1)
|
42
|
+
"AAAA"
|
43
|
+
else
|
44
|
+
"AAAA;" + "AACA;"*(lines - 2) + "AACA"
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,228 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require 'sprockets/file_reader'
|
3
|
+
require 'sprockets/mime'
|
4
|
+
require 'sprockets/processor_utils'
|
5
|
+
require 'sprockets/uri_utils'
|
6
|
+
require 'sprockets/utils'
|
7
|
+
|
8
|
+
module Sprockets
|
9
|
+
# `Processing` is an internal mixin whose public methods are exposed on
|
10
|
+
# the `Environment` and `CachedEnvironment` classes.
|
11
|
+
module Processing
|
12
|
+
include ProcessorUtils, URIUtils, Utils
|
13
|
+
|
14
|
+
def pipelines
|
15
|
+
config[:pipelines]
|
16
|
+
end
|
17
|
+
|
18
|
+
# Registers a pipeline that will be called by `call_processor` method.
|
19
|
+
def register_pipeline(name, proc = nil, &block)
|
20
|
+
proc ||= block
|
21
|
+
|
22
|
+
self.config = hash_reassoc(config, :pipeline_exts) do |pipeline_exts|
|
23
|
+
pipeline_exts.merge(".#{name}".freeze => name.to_sym)
|
24
|
+
end
|
25
|
+
|
26
|
+
self.config = hash_reassoc(config, :pipelines) do |pipelines|
|
27
|
+
pipelines.merge(name.to_sym => proc)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
# Preprocessors are ran before Postprocessors and Engine
|
32
|
+
# processors.
|
33
|
+
def preprocessors
|
34
|
+
config[:preprocessors]
|
35
|
+
end
|
36
|
+
alias_method :processors, :preprocessors
|
37
|
+
|
38
|
+
# Postprocessors are ran after Preprocessors and Engine processors.
|
39
|
+
def postprocessors
|
40
|
+
config[:postprocessors]
|
41
|
+
end
|
42
|
+
|
43
|
+
# Registers a new Preprocessor `klass` for `mime_type`.
|
44
|
+
#
|
45
|
+
# register_preprocessor 'text/css', Sprockets::DirectiveProcessor
|
46
|
+
#
|
47
|
+
# A block can be passed for to create a shorthand processor.
|
48
|
+
#
|
49
|
+
# register_preprocessor 'text/css' do |input|
|
50
|
+
# input[:data].gsub(...)
|
51
|
+
# end
|
52
|
+
#
|
53
|
+
def register_preprocessor(*args, &block)
|
54
|
+
register_config_processor(:preprocessors, *args, &block)
|
55
|
+
compute_transformers!(self.config[:registered_transformers])
|
56
|
+
end
|
57
|
+
alias_method :register_processor, :register_preprocessor
|
58
|
+
|
59
|
+
# Registers a new Postprocessor `klass` for `mime_type`.
|
60
|
+
#
|
61
|
+
# register_postprocessor 'application/javascript', Sprockets::DirectiveProcessor
|
62
|
+
#
|
63
|
+
# A block can be passed for to create a shorthand processor.
|
64
|
+
#
|
65
|
+
# register_postprocessor 'application/javascript' do |input|
|
66
|
+
# input[:data].gsub(...)
|
67
|
+
# end
|
68
|
+
#
|
69
|
+
def register_postprocessor(*args, &block)
|
70
|
+
register_config_processor(:postprocessors, *args, &block)
|
71
|
+
compute_transformers!(self.config[:registered_transformers])
|
72
|
+
end
|
73
|
+
|
74
|
+
# Remove Preprocessor `klass` for `mime_type`.
|
75
|
+
#
|
76
|
+
# unregister_preprocessor 'text/css', Sprockets::DirectiveProcessor
|
77
|
+
#
|
78
|
+
def unregister_preprocessor(*args)
|
79
|
+
unregister_config_processor(:preprocessors, *args)
|
80
|
+
compute_transformers!(self.config[:registered_transformers])
|
81
|
+
end
|
82
|
+
alias_method :unregister_processor, :unregister_preprocessor
|
83
|
+
|
84
|
+
# Remove Postprocessor `klass` for `mime_type`.
|
85
|
+
#
|
86
|
+
# unregister_postprocessor 'text/css', Sprockets::DirectiveProcessor
|
87
|
+
#
|
88
|
+
def unregister_postprocessor(*args)
|
89
|
+
unregister_config_processor(:postprocessors, *args)
|
90
|
+
compute_transformers!(self.config[:registered_transformers])
|
91
|
+
end
|
92
|
+
|
93
|
+
# Bundle Processors are ran on concatenated assets rather than
|
94
|
+
# individual files.
|
95
|
+
def bundle_processors
|
96
|
+
config[:bundle_processors]
|
97
|
+
end
|
98
|
+
|
99
|
+
# Registers a new Bundle Processor `klass` for `mime_type`.
|
100
|
+
#
|
101
|
+
# register_bundle_processor 'application/javascript', Sprockets::DirectiveProcessor
|
102
|
+
#
|
103
|
+
# A block can be passed for to create a shorthand processor.
|
104
|
+
#
|
105
|
+
# register_bundle_processor 'application/javascript' do |input|
|
106
|
+
# input[:data].gsub(...)
|
107
|
+
# end
|
108
|
+
#
|
109
|
+
def register_bundle_processor(*args, &block)
|
110
|
+
register_config_processor(:bundle_processors, *args, &block)
|
111
|
+
end
|
112
|
+
|
113
|
+
# Remove Bundle Processor `klass` for `mime_type`.
|
114
|
+
#
|
115
|
+
# unregister_bundle_processor 'application/javascript', Sprockets::DirectiveProcessor
|
116
|
+
#
|
117
|
+
def unregister_bundle_processor(*args)
|
118
|
+
unregister_config_processor(:bundle_processors, *args)
|
119
|
+
end
|
120
|
+
|
121
|
+
# Public: Register bundle metadata reducer function.
|
122
|
+
#
|
123
|
+
# Examples
|
124
|
+
#
|
125
|
+
# Sprockets.register_bundle_metadata_reducer 'application/javascript', :jshint_errors, [], :+
|
126
|
+
#
|
127
|
+
# Sprockets.register_bundle_metadata_reducer 'text/css', :selector_count, 0 { |total, count|
|
128
|
+
# total + count
|
129
|
+
# }
|
130
|
+
#
|
131
|
+
# mime_type - String MIME Type. Use '*/*' applies to all types.
|
132
|
+
# key - Symbol metadata key
|
133
|
+
# initial - Initial memo to pass to the reduce funciton (default: nil)
|
134
|
+
# block - Proc accepting the memo accumulator and current value
|
135
|
+
#
|
136
|
+
# Returns nothing.
|
137
|
+
def register_bundle_metadata_reducer(mime_type, key, *args, &block)
|
138
|
+
case args.size
|
139
|
+
when 0
|
140
|
+
reducer = block
|
141
|
+
when 1
|
142
|
+
if block_given?
|
143
|
+
initial = args[0]
|
144
|
+
reducer = block
|
145
|
+
else
|
146
|
+
initial = nil
|
147
|
+
reducer = args[0].to_proc
|
148
|
+
end
|
149
|
+
when 2
|
150
|
+
initial = args[0]
|
151
|
+
reducer = args[1].to_proc
|
152
|
+
else
|
153
|
+
raise ArgumentError, "wrong number of arguments (#{args.size} for 0..2)"
|
154
|
+
end
|
155
|
+
|
156
|
+
self.config = hash_reassoc(config, :bundle_reducers, mime_type) do |reducers|
|
157
|
+
reducers.merge(key => [initial, reducer])
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
protected
|
162
|
+
def resolve_processors_cache_key_uri(uri)
|
163
|
+
params = parse_uri_query_params(uri[11..-1])
|
164
|
+
processors = processors_for(params[:type], params[:file_type], params[:pipeline])
|
165
|
+
processors_cache_keys(processors)
|
166
|
+
end
|
167
|
+
|
168
|
+
def build_processors_uri(type, file_type, pipeline)
|
169
|
+
query = encode_uri_query_params(
|
170
|
+
type: type,
|
171
|
+
file_type: file_type,
|
172
|
+
pipeline: pipeline
|
173
|
+
)
|
174
|
+
"processors:#{query}"
|
175
|
+
end
|
176
|
+
|
177
|
+
def processors_for(type, file_type, pipeline)
|
178
|
+
pipeline ||= :default
|
179
|
+
if fn = config[:pipelines][pipeline.to_sym]
|
180
|
+
fn.call(self, type, file_type)
|
181
|
+
else
|
182
|
+
raise Error, "no pipeline: #{pipeline}"
|
183
|
+
end
|
184
|
+
end
|
185
|
+
|
186
|
+
def default_processors_for(type, file_type)
|
187
|
+
bundled_processors = config[:bundle_processors][type]
|
188
|
+
if bundled_processors.any?
|
189
|
+
bundled_processors
|
190
|
+
else
|
191
|
+
self_processors_for(type, file_type)
|
192
|
+
end
|
193
|
+
end
|
194
|
+
|
195
|
+
def self_processors_for(type, file_type)
|
196
|
+
processors = []
|
197
|
+
|
198
|
+
processors.concat config[:postprocessors][type]
|
199
|
+
if type != file_type && processor = config[:transformers][file_type][type]
|
200
|
+
processors << processor
|
201
|
+
end
|
202
|
+
processors.concat config[:preprocessors][file_type]
|
203
|
+
|
204
|
+
if processors.any? || mime_type_charset_detecter(type)
|
205
|
+
processors << FileReader
|
206
|
+
end
|
207
|
+
|
208
|
+
processors
|
209
|
+
end
|
210
|
+
|
211
|
+
private
|
212
|
+
def register_config_processor(type, mime_type, processor = nil, &block)
|
213
|
+
processor ||= block
|
214
|
+
|
215
|
+
self.config = hash_reassoc(config, type, mime_type) do |processors|
|
216
|
+
processors.unshift(processor)
|
217
|
+
processors
|
218
|
+
end
|
219
|
+
end
|
220
|
+
|
221
|
+
def unregister_config_processor(type, mime_type, processor)
|
222
|
+
self.config = hash_reassoc(config, type, mime_type) do |processors|
|
223
|
+
processors.delete_if { |p| p == processor || p.class == processor }
|
224
|
+
processors
|
225
|
+
end
|
226
|
+
end
|
227
|
+
end
|
228
|
+
end
|
@@ -0,0 +1,169 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require 'set'
|
3
|
+
|
4
|
+
module Sprockets
|
5
|
+
# Functional utilities for dealing with Processor functions.
|
6
|
+
#
|
7
|
+
# A Processor is a general function that may modify or transform an asset as
|
8
|
+
# part of the pipeline. CoffeeScript to JavaScript conversion, Minification
|
9
|
+
# or Concatenation are all implemented as seperate Processor steps.
|
10
|
+
#
|
11
|
+
# Processors maybe any object that responds to call. So procs or a class that
|
12
|
+
# defines a self.call method.
|
13
|
+
#
|
14
|
+
# For ergonomics, processors may return a number of shorthand values.
|
15
|
+
# Unfortunately, this means that processors can not compose via ordinary
|
16
|
+
# function composition. The composition helpers here can help.
|
17
|
+
module ProcessorUtils
|
18
|
+
extend self
|
19
|
+
|
20
|
+
class CompositeProcessor < Struct.new(:processor_strategy, :param, :processors) # :nodoc:
|
21
|
+
SINGULAR = lambda { |param, input| ProcessorUtils.call_processor param, input }
|
22
|
+
PLURAL = lambda { |param, input| ProcessorUtils.call_processors param, input }
|
23
|
+
|
24
|
+
def self.create(processors)
|
25
|
+
if processors.length == 1
|
26
|
+
new SINGULAR, processors.first, processors
|
27
|
+
else
|
28
|
+
new PLURAL, processors, processors
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def call(input)
|
33
|
+
processor_strategy.call param, input
|
34
|
+
end
|
35
|
+
|
36
|
+
def cache_key
|
37
|
+
ProcessorUtils.processors_cache_keys(processors)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
# Public: Compose processors in right to left order.
|
42
|
+
#
|
43
|
+
# processors - Array of processors callables
|
44
|
+
#
|
45
|
+
# Returns a composed Proc.
|
46
|
+
def compose_processors(*processors)
|
47
|
+
CompositeProcessor.create processors
|
48
|
+
end
|
49
|
+
|
50
|
+
# Public: Invoke list of processors in right to left order.
|
51
|
+
#
|
52
|
+
# The right to left order processing mirrors standard function composition.
|
53
|
+
# Think about:
|
54
|
+
#
|
55
|
+
# bundle.call(uglify.call(coffee.call(input)))
|
56
|
+
#
|
57
|
+
# processors - Array of processor callables
|
58
|
+
# input - Hash of input data to pass to each processor
|
59
|
+
#
|
60
|
+
# Returns a Hash with :data and other processor metadata key/values.
|
61
|
+
def call_processors(processors, input)
|
62
|
+
data = input[:data] || ""
|
63
|
+
metadata = (input[:metadata] || {}).dup
|
64
|
+
|
65
|
+
processors.reverse_each do |processor|
|
66
|
+
result = call_processor(processor, input.merge(data: data, metadata: metadata))
|
67
|
+
data = result.delete(:data)
|
68
|
+
metadata.merge!(result)
|
69
|
+
end
|
70
|
+
|
71
|
+
metadata.merge(data: data)
|
72
|
+
end
|
73
|
+
|
74
|
+
# Public: Invoke processor.
|
75
|
+
#
|
76
|
+
# processor - Processor callables
|
77
|
+
# input - Hash of input data to pass to processor
|
78
|
+
#
|
79
|
+
# Returns a Hash with :data and other processor metadata key/values.
|
80
|
+
def call_processor(processor, input)
|
81
|
+
metadata = (input[:metadata] || {}).dup
|
82
|
+
metadata[:data] = input[:data]
|
83
|
+
|
84
|
+
case result = processor.call({data: "", metadata: {}}.merge(input))
|
85
|
+
when NilClass
|
86
|
+
metadata
|
87
|
+
when Hash
|
88
|
+
metadata.merge(result)
|
89
|
+
when String
|
90
|
+
metadata.merge(data: result)
|
91
|
+
else
|
92
|
+
raise TypeError, "invalid processor return type: #{result.class}"
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
# Internal: Get processor defined cached key.
|
97
|
+
#
|
98
|
+
# processor - Processor function
|
99
|
+
#
|
100
|
+
# Returns JSON serializable key or nil.
|
101
|
+
def processor_cache_key(processor)
|
102
|
+
processor.cache_key if processor.respond_to?(:cache_key)
|
103
|
+
end
|
104
|
+
|
105
|
+
# Internal: Get combined cache keys for set of processors.
|
106
|
+
#
|
107
|
+
# processors - Array of processor functions
|
108
|
+
#
|
109
|
+
# Returns Array of JSON serializable keys.
|
110
|
+
def processors_cache_keys(processors)
|
111
|
+
processors.map { |processor| processor_cache_key(processor) }
|
112
|
+
end
|
113
|
+
|
114
|
+
# Internal: Set of all "simple" value types allowed to be returned in
|
115
|
+
# processor metadata.
|
116
|
+
VALID_METADATA_VALUE_TYPES = Set.new([
|
117
|
+
String,
|
118
|
+
Symbol,
|
119
|
+
TrueClass,
|
120
|
+
FalseClass,
|
121
|
+
NilClass
|
122
|
+
] + (0.class == Integer ? [Integer] : [Bignum, Fixnum])).freeze
|
123
|
+
|
124
|
+
# Internal: Set of all nested compound metadata types that can nest values.
|
125
|
+
VALID_METADATA_COMPOUND_TYPES = Set.new([
|
126
|
+
Array,
|
127
|
+
Hash,
|
128
|
+
Set
|
129
|
+
]).freeze
|
130
|
+
|
131
|
+
# Internal: Hash of all "simple" value types allowed to be returned in
|
132
|
+
# processor metadata.
|
133
|
+
VALID_METADATA_VALUE_TYPES_HASH = VALID_METADATA_VALUE_TYPES.each_with_object({}) do |type, hash|
|
134
|
+
hash[type] = true
|
135
|
+
end.freeze
|
136
|
+
|
137
|
+
# Internal: Hash of all nested compound metadata types that can nest values.
|
138
|
+
VALID_METADATA_COMPOUND_TYPES_HASH = VALID_METADATA_COMPOUND_TYPES.each_with_object({}) do |type, hash|
|
139
|
+
hash[type] = true
|
140
|
+
end.freeze
|
141
|
+
|
142
|
+
# Internal: Set of all allowed metadata types.
|
143
|
+
VALID_METADATA_TYPES = (VALID_METADATA_VALUE_TYPES + VALID_METADATA_COMPOUND_TYPES).freeze
|
144
|
+
|
145
|
+
# Internal: Validate returned result of calling a processor pipeline and
|
146
|
+
# raise a friendly user error message.
|
147
|
+
#
|
148
|
+
# result - Metadata Hash returned from call_processors
|
149
|
+
#
|
150
|
+
# Returns result or raises a TypeError.
|
151
|
+
def validate_processor_result!(result)
|
152
|
+
if !result.instance_of?(Hash)
|
153
|
+
raise TypeError, "processor metadata result was expected to be a Hash, but was #{result.class}"
|
154
|
+
end
|
155
|
+
|
156
|
+
if !result[:data].instance_of?(String)
|
157
|
+
raise TypeError, "processor :data was expected to be a String, but as #{result[:data].class}"
|
158
|
+
end
|
159
|
+
|
160
|
+
result.each do |key, value|
|
161
|
+
if !key.instance_of?(Symbol)
|
162
|
+
raise TypeError, "processor metadata[#{key.inspect}] expected to be a Symbol"
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
result
|
167
|
+
end
|
168
|
+
end
|
169
|
+
end
|