brick 1.0.149 → 1.0.151
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/brick/extensions.rb +111 -18
- data/lib/brick/frameworks/rails/engine.rb +9 -7
- data/lib/brick/version_number.rb +1 -1
- data/lib/brick.rb +22 -0
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 1d8abfeb02b561a0ac8214de3c4791992947cab9f288f9f57c816a883dc4592a
|
|
4
|
+
data.tar.gz: 1ec0f9d11eea9b1741e454ac04aa2c51380a0d9676f4e84a5de2419d3ef751bd
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 758e2ab6e10589689abdb77df64731e3df2fff341998e8f815bd5f180a73df89fb1282155a9520cc43102a49b1f7283114c02146329161e2324fc2fa79c6048e
|
|
7
|
+
data.tar.gz: 9a77d3d4318943225427c59e676c4a067c95a22351eaea88ed14bbc6da60ee834498117704bc0fe1dd493f6e10ab65a27db4bff3b060440f4e7dfaf3b31ad184
|
data/lib/brick/extensions.rb
CHANGED
|
@@ -1528,12 +1528,12 @@ class Object
|
|
|
1528
1528
|
# end
|
|
1529
1529
|
end
|
|
1530
1530
|
|
|
1531
|
-
# Enable Turbo Stream if possible -- equivalent of: broadcasts_to ->(comment) { :comments }
|
|
1532
|
-
if Object.const_defined?(:ApplicationCable) && Object.const_defined?(:Turbo) && Turbo.const_defined?(:Broadcastable) && respond_to?(:broadcasts_to)
|
|
1533
|
-
|
|
1534
|
-
|
|
1535
|
-
|
|
1536
|
-
end
|
|
1531
|
+
# # %%% Enable Turbo Stream if possible -- equivalent of: broadcasts_to ->(comment) { :comments }
|
|
1532
|
+
# if Object.const_defined?(:ApplicationCable) && Object.const_defined?(:Turbo) && Turbo.const_defined?(:Broadcastable) && respond_to?(:broadcasts_to)
|
|
1533
|
+
# relation[:broadcasts] = true
|
|
1534
|
+
# self.broadcasts_to ->(model) { (model&.class&.name || chosen_name).underscore.pluralize.to_sym }
|
|
1535
|
+
# code << " broadcasts_to ->(#{chosen_name}) { #{chosen_name}&.class&.name&.underscore&.pluralize&.to_sym }\n"
|
|
1536
|
+
# end
|
|
1537
1537
|
end # class definition
|
|
1538
1538
|
# Having this separate -- will this now work out better?
|
|
1539
1539
|
built_model.class_exec do
|
|
@@ -2155,13 +2155,16 @@ class Object
|
|
|
2155
2155
|
::Brick.set_db_schema(params)
|
|
2156
2156
|
if request.format == :csv # Importing CSV?
|
|
2157
2157
|
require 'csv'
|
|
2158
|
+
|
|
2158
2159
|
# See if internally it's likely a TSV file (tab-separated)
|
|
2159
|
-
|
|
2160
|
-
|
|
2160
|
+
likely_separator = Hash.new { |h, k| h[k] = 0 }
|
|
2161
|
+
request.body.readline # Expect first row to have column headers
|
|
2162
|
+
5.times { ::Brick._find_csv_separator(request.body, likely_separator) unless request.body.eof? }
|
|
2161
2163
|
request.body.rewind
|
|
2162
|
-
separator = "\t" if
|
|
2163
|
-
|
|
2164
|
-
|
|
2164
|
+
separator = "\t" if likely_separator["\t"] > likely_separator[',']
|
|
2165
|
+
|
|
2166
|
+
result = model.df_import(CSV.parse(request.body, **{ col_sep: separator || :auto }), model.brick_import_template)
|
|
2167
|
+
render inline: result.to_json, content_type: request.format
|
|
2165
2168
|
return
|
|
2166
2169
|
# elsif request.format == :js # Asking for JSON?
|
|
2167
2170
|
# render inline: model.df_export(true).to_json, content_type: request.format
|
|
@@ -2238,14 +2241,9 @@ class Object
|
|
|
2238
2241
|
|
|
2239
2242
|
if is_need_params
|
|
2240
2243
|
code << " def #{params_name}\n"
|
|
2241
|
-
permits = model.columns_hash.keys.map(&:to_sym)
|
|
2242
|
-
permits_txt = permits.map(&:inspect) +
|
|
2243
|
-
model.reflect_on_all_associations.select { |assoc| assoc.macro == :has_many && assoc.options[:through] }.map do |assoc|
|
|
2244
|
-
permits << { "#{assoc.name.to_s.singularize}_ids".to_sym => [] }
|
|
2245
|
-
"#{assoc.name.to_s.singularize}_ids: []"
|
|
2246
|
-
end
|
|
2244
|
+
permits_txt = self._brick_find_permits(model, (permits = model.columns_hash.keys.map(&:to_sym)))
|
|
2247
2245
|
code << " params.require(:#{require_name = model.name.underscore.tr('/', '_')
|
|
2248
|
-
}).permit(#{permits_txt.join(', ')})\n"
|
|
2246
|
+
}).permit(#{permits_txt.map(&:inspect).join(', ')})\n"
|
|
2249
2247
|
code << " end\n"
|
|
2250
2248
|
self.define_method(params_name) do
|
|
2251
2249
|
params.require(require_name.to_sym).permit(permits)
|
|
@@ -2259,6 +2257,101 @@ class Object
|
|
|
2259
2257
|
[built_controller, code]
|
|
2260
2258
|
end
|
|
2261
2259
|
|
|
2260
|
+
def _brick_find_permits(model, current_permits, done_permits = [])
|
|
2261
|
+
unless done_permits.include?(self)
|
|
2262
|
+
done_permits << self
|
|
2263
|
+
model.reflect_on_all_associations.select { |assoc| assoc.macro == :has_many }.each_with_object([]) do |assoc, s|
|
|
2264
|
+
if assoc.options[:through]
|
|
2265
|
+
current_permits << { "#{assoc.name.to_s.singularize}_ids".to_sym => [] }
|
|
2266
|
+
s << "#{assoc.name.to_s.singularize}_ids: []"
|
|
2267
|
+
elsif assoc.active_record.instance_methods.include?(:"#{assoc.name}_attributes=")
|
|
2268
|
+
# Support nested attributes which use the friendly_id gem
|
|
2269
|
+
self._brick_nested_friendly_id if Object.const_defined?('FriendlyId') &&
|
|
2270
|
+
assoc.klass.instance_variable_get(:@friendly_id_config)
|
|
2271
|
+
new_attrib_text = self._brick_find_permits(assoc.klass, (new_permits = assoc.klass.columns_hash.keys.map(&:to_sym)), done_permits)
|
|
2272
|
+
new_permits << :_destroy
|
|
2273
|
+
current_permits << { "#{assoc.name}_attributes".to_sym => new_permits }
|
|
2274
|
+
s << "#{assoc.name}_attributes: #{new_attrib_text}"
|
|
2275
|
+
end
|
|
2276
|
+
end
|
|
2277
|
+
end
|
|
2278
|
+
current_permits
|
|
2279
|
+
end
|
|
2280
|
+
|
|
2281
|
+
def _brick_nested_friendly_id
|
|
2282
|
+
unless @_brick_nested_friendly_id
|
|
2283
|
+
::ActiveRecord::Base.class_exec do
|
|
2284
|
+
if private_instance_methods.include?(:assign_nested_attributes_for_collection_association)
|
|
2285
|
+
alias _brick_anafca assign_nested_attributes_for_collection_association
|
|
2286
|
+
def assign_nested_attributes_for_collection_association(association_name, attributes_collection)
|
|
2287
|
+
association = association(association_name)
|
|
2288
|
+
slug_column = association.klass.instance_variable_get(:@friendly_id_config)&.slug_column
|
|
2289
|
+
return _brick_anafca unless slug_column
|
|
2290
|
+
|
|
2291
|
+
# Here is the FriendlyId version of #assign_nested_attributes_for_collection_association
|
|
2292
|
+
options = nested_attributes_options[association_name]
|
|
2293
|
+
attributes_collection = attributes_collection.to_h if attributes_collection.respond_to?(:permitted?)
|
|
2294
|
+
|
|
2295
|
+
unless attributes_collection.is_a?(Hash) || attributes_collection.is_a?(Array)
|
|
2296
|
+
raise ArgumentError, "Hash or Array expected for attribute `#{association_name}`, got #{attributes_collection.class.name} (#{attributes_collection.inspect})"
|
|
2297
|
+
end
|
|
2298
|
+
|
|
2299
|
+
check_record_limit!(options[:limit], attributes_collection)
|
|
2300
|
+
|
|
2301
|
+
if attributes_collection.is_a? Hash
|
|
2302
|
+
keys = attributes_collection.keys
|
|
2303
|
+
attributes_collection = if keys.include?("id") || keys.include?(:id)
|
|
2304
|
+
[attributes_collection]
|
|
2305
|
+
else
|
|
2306
|
+
attributes_collection.values
|
|
2307
|
+
end
|
|
2308
|
+
end
|
|
2309
|
+
existing_records = if association.loaded?
|
|
2310
|
+
association.target
|
|
2311
|
+
else
|
|
2312
|
+
attribute_ids = attributes_collection.filter_map { |a| a["id"] || a[:id] }
|
|
2313
|
+
if attribute_ids.empty?
|
|
2314
|
+
[]
|
|
2315
|
+
else # Implement the same logic as "friendly" scope
|
|
2316
|
+
association.scope.where(association.klass.primary_key => attribute_ids)
|
|
2317
|
+
.or(association.scope.where(slug_column => attribute_ids))
|
|
2318
|
+
end
|
|
2319
|
+
end
|
|
2320
|
+
attributes_collection.each do |attributes|
|
|
2321
|
+
attributes = attributes.to_h if attributes.respond_to?(:permitted?)
|
|
2322
|
+
attributes = attributes.with_indifferent_access
|
|
2323
|
+
if attributes["id"].blank? && attributes[slug_column].blank?
|
|
2324
|
+
unless reject_new_record?(association_name, attributes)
|
|
2325
|
+
association.reader.build(attributes.except(*::ActiveRecord::Base::UNASSIGNABLE_KEYS))
|
|
2326
|
+
end
|
|
2327
|
+
elsif (attr_id_str = attributes["id"].to_s) &&
|
|
2328
|
+
(existing_record = existing_records.detect { |record| record.id.to_s == attr_id_str ||
|
|
2329
|
+
record.send(slug_column).to_s == attr_id_str })
|
|
2330
|
+
unless call_reject_if(association_name, attributes)
|
|
2331
|
+
# Make sure we are operating on the actual object which is in the association's
|
|
2332
|
+
# proxy_target array (either by finding it, or adding it if not found)
|
|
2333
|
+
# Take into account that the proxy_target may have changed due to callbacks
|
|
2334
|
+
target_record = association.target.detect { |record| record.id.to_s == attr_id_str ||
|
|
2335
|
+
record.send(slug_column).to_s == attr_id_str }
|
|
2336
|
+
if target_record
|
|
2337
|
+
existing_record = target_record
|
|
2338
|
+
else
|
|
2339
|
+
association.add_to_target(existing_record, skip_callbacks: true)
|
|
2340
|
+
end
|
|
2341
|
+
|
|
2342
|
+
assign_to_or_mark_for_destruction(existing_record, attributes, options[:allow_destroy])
|
|
2343
|
+
end
|
|
2344
|
+
else
|
|
2345
|
+
raise_nested_attributes_record_not_found!(association_name, attributes["id"])
|
|
2346
|
+
end
|
|
2347
|
+
end
|
|
2348
|
+
end # anafca
|
|
2349
|
+
end
|
|
2350
|
+
end if ::ActiveRecord::QueryMethods.instance_methods.include?(:or)
|
|
2351
|
+
@_brick_nested_friendly_id = true
|
|
2352
|
+
end
|
|
2353
|
+
end
|
|
2354
|
+
|
|
2262
2355
|
def _brick_get_hm_assoc_name(relation, hm_assoc, source = nil)
|
|
2263
2356
|
assoc_name, needs_class = if (relation[:hm_counts][hm_assoc[:inverse_table]]&.> 1) &&
|
|
2264
2357
|
hm_assoc[:alternate_name] != (source || name.underscore)
|
|
@@ -263,11 +263,11 @@ function linkSchemas() {
|
|
|
263
263
|
|
|
264
264
|
# After we're initialized and before running the rest of stuff, put our configuration in place
|
|
265
265
|
ActiveSupport.on_load(:after_initialize) do |app|
|
|
266
|
-
assets_path = File.expand_path("#{__dir__}/../../../../vendor/assets")
|
|
267
|
-
if (app_config = app.config).respond_to?(:assets)
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
end
|
|
266
|
+
# assets_path = File.expand_path("#{__dir__}/../../../../vendor/assets")
|
|
267
|
+
# if (app_config = app.config).respond_to?(:assets)
|
|
268
|
+
# (app_config.assets.precompile ||= []) << "#{assets_path}/images/brick_erd.png"
|
|
269
|
+
# (app.config.assets.paths ||= []) << assets_path
|
|
270
|
+
# end
|
|
271
271
|
|
|
272
272
|
# Treat ActiveStorage::Blob metadata as JSON
|
|
273
273
|
if ::Brick.config.table_name_prefixes.fetch('active_storage_', nil) == 'ActiveStorage' &&
|
|
@@ -813,7 +813,7 @@ h1, h3 {
|
|
|
813
813
|
margin-bottom: 0;
|
|
814
814
|
}
|
|
815
815
|
#imgErd {
|
|
816
|
-
background-image:url(/
|
|
816
|
+
background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAE0AAABNCAMAAADU1xmCAAAABGdBTUEAALGPC/xhBQAAAAFzUkdCAK7OHOkAAARxaVRYdFhNTDpjb20uYWRvYmUueG1wAAAAAAA8eDp4bXBtZXRhIHhtbG5zOng9ImFkb2JlOm5zOm1ldGEvIiB4OnhtcHRrPSJYTVAgQ29yZSA2LjAuMCI+CiAgIDxyZGY6UkRGIHhtbG5zOnJkZj0iaHR0cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi1yZGYtc3ludGF4LW5zIyI+CiAgICAgIDxyZGY6RGVzY3JpcHRpb24gcmRmOmFib3V0PSIiCiAgICAgICAgICAgIHhtbG5zOnRpZmY9Imh0dHA6Ly9ucy5hZG9iZS5jb20vdGlmZi8xLjAvIgogICAgICAgICAgICB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIKICAgICAgICAgICAgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiCiAgICAgICAgICAgIHhtbG5zOnhtcD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLyI+CiAgICAgICAgIDx0aWZmOllSZXNvbHV0aW9uPjcyPC90aWZmOllSZXNvbHV0aW9uPgogICAgICAgICA8dGlmZjpYUmVzb2x1dGlvbj43MjwvdGlmZjpYUmVzb2x1dGlvbj4KICAgICAgICAgPHRpZmY6T3JpZW50YXRpb24+MTwvdGlmZjpPcmllbnRhdGlvbj4KICAgICAgICAgPHhtcE1NOkRlcml2ZWRGcm9tIHJkZjpwYXJzZVR5cGU9IlJlc291cmNlIj4KICAgICAgICAgICAgPHN0UmVmOmluc3RhbmNlSUQ+eG1wLmlpZDoxN0U3OEI3RjAzN0MxMUU3QTZDMDhBQjVCRDc2QkZCQjwvc3RSZWY6aW5zdGFuY2VJRD4KICAgICAgICAgICAgPHN0UmVmOmRvY3VtZW50SUQ+eG1wLmRpZDoxN0U3OEI4MDAzN0MxMUU3QTZDMDhBQjVCRDc2QkZCQjwvc3RSZWY6ZG9jdW1lbnRJRD4KICAgICAgICAgPC94bXBNTTpEZXJpdmVkRnJvbT4KICAgICAgICAgPHhtcE1NOkRvY3VtZW50SUQ+eG1wLmRpZDoxN0U3OEI4MjAzN0MxMUU3QTZDMDhBQjVCRDc2QkZCQjwveG1wTU06RG9jdW1lbnRJRD4KICAgICAgICAgPHhtcE1NOkluc3RhbmNlSUQ+eG1wLmlpZDoxN0U3OEI4MTAzN0MxMUU3QTZDMDhBQjVCRDc2QkZCQjwveG1wTU06SW5zdGFuY2VJRD4KICAgICAgICAgPHhtcDpDcmVhdG9yVG9vbD5BZG9iZSBQaG90b3Nob3AgQ1M1IFdpbmRvd3M8L3htcDpDcmVhdG9yVG9vbD4KICAgICAgPC9yZGY6RGVzY3JpcHRpb24+CiAgIDwvcmRmOlJERj4KPC94OnhtcG1ldGE+ChMBcXgAAAAJcEhZcwAACxMAAAsTAQCanBgAAAL9UExURUdwTDRRc1EVG6ioqFJSUmJiYn+AgURWa2uEkauorszGwmtrawonUKzY7DMRIlFTVWV9m4qKiwaN0G1raJSQiJjV7jWh2HmizPLs6CaV0QohSmdoaVdXWLWsomFdYmIgD4WCfQWa2WIoFUxylldpekeRuGtrajhztIuLizV3qc3DvThDVEyFs31+fiRViVRNViVWjwsvWxIzXxZEekeL1FZIVVRdeEZrk359fj52ppubm3l6e4qbqJOTlBlGfM3k3Nzc3K6lnk9RWaenp0FjikGDyJGRkWJiYk2L0Li4uJubnH5+flFbeNPT02tpac3NzVBGJkCCyMvLy9LS0oxETk2U3tLS0tXV1cPDw+Xl5amDftbX19na2uLj4+jo6dzd3OXl511dXd/g31paWlZXV9TU1HBwcOvr687OzdDQ0u/u7fTx79PSzcrJx6KiooWFhujn5NvW05WUk7S1t3R1d7y9vcLCv37J68vMzVJTVOLY1gMiSpmamnt7e7K6zHq+43LQ9Vyez+Pf3LGyscXGybzD1sXDw46v02vI8I+Pj7vEtNvIx7q4ubnZ54a3it3f5s+8vGS/6L6trK+6qICs1H+33cXc6KiuwAOr48fN20ee0Fao0lyz4W6s1qyrrKKlt3XdkoqnyyFoqzuTy6ixosuVeobA4YHNl8TOv3/Ck9bc4I3P7Uqq3tDIxz2FwzN/vF+VxdDe59mIfU+OxJmovxl+wX7S9WjbhovW9jihyKGalIq31uNyY36exJCatJONhTm36nKj0B2q4Mqxsae2zc/U3tvf1cqKa7zAyJS4npqyyTh2tUhMT1drj5ixtN98cEfC8U2Y5vf39355cSN0s4mDfKaomlrG8b2cmcFvaGx/m2CeZge68HG64YCNntSgoVHUdJzKnIHIh6c+BalVVaPM5qrG2CZZkyaHH3WRtYrdn5nH2rxoP22+gN1VQTyxW1aXl0iO2GaxtFuzaCCAQyXSWDOKlDZwkxIINVZPP52Io3uldtIoC1uGVxmzRP6PHn8AAADVdFJOUwAmEf6t/v4EAQVR/oT+Hl4U/v1bR/7+Kf7+a/76Q4Y2Wf1b4j71sXm0y2hF/bBwbtXN/fyGl8Sxiu382Preqfzia9iIkdP51/Povnineu+9n6H7ov5ksLfYy/7////////+/////////////////////v/////////////////////////////////////////////////////////////////////////////+/////////////////////////////////////////////////////r5xM8kAAA0qSURBVFjDpZh3WFNnG8YDMZOiLEFEsVhn1Vq1Vq1abWv3br+dc5IQsklCSEiIyAoJyAhb9h4ishVQcCAIOLC4UBFxr7bu0X6dX6/vec8JikIptecPVrh+576f5z3vez+HQmGyKBSK28eT4SsL/fiXLiaFwmD/E5NzPmU7wG8s5l/DOXy8+vhxLg8TcN5/yw0JZPwV2GoJH+fjPI7UHBWV/8HzwGIynlkgm+vv788RiURSs06bT6WuJAQynlEgO+JaUzoWhGAWE1X1mkqlmYUEMp5JIBs7ejYz3L4iyN+gy1epVMGvaYI1K5faIIF/nsfuPDr325LMo5XpvCCFThUMrHccY2L85j2TQHZna11kZFGd19lo+4oI/yiqJiYmxtGP7kdf/gwC2bLWuix1RWTX7uzMo+PTI4KkJo0fXPSQkBDxDOc/KZBtaK3P4uLqrPXri+rcz4YjgbpgegidHhIgDhC/6/mnBLLNVTWdclzdmbYTeAMClVS6OCAgQGxnZ0cbM4dBPDKjoh2oqo309ZV3ppWV7UTAur1nw+MrIhRaRzsPsdiDRqN5v+lpO0oc0OrrirLkiWGVZVYeIXBLRFBUsNiH5kHz9vHxeZMxOhxb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);
|
|
817
817
|
background-size: 100% 100%;
|
|
818
818
|
width: 2.2em;
|
|
819
819
|
height: 2.2em;
|
|
@@ -1241,7 +1241,9 @@ erDiagram
|
|
|
1241
1241
|
btnImport.style.display = droppedTSV.length > 0 ? \"block\" : \"none\";
|
|
1242
1242
|
});
|
|
1243
1243
|
btnImport.addEventListener(\"click\", function () {
|
|
1244
|
-
|
|
1244
|
+
var patchPath = <%= #{path_obj_name}_path(-1, format: :csv).inspect.html_safe %>;
|
|
1245
|
+
if (brickSchema) patchPath = changeout(patchPath, \"_brick_schema\", brickSchema);
|
|
1246
|
+
fetch(patchPath, {
|
|
1245
1247
|
method: \"PATCH\",
|
|
1246
1248
|
headers: { \"Content-Type\": \"text/tab-separated-values\" },
|
|
1247
1249
|
body: droppedTSV
|
data/lib/brick/version_number.rb
CHANGED
data/lib/brick.rb
CHANGED
|
@@ -742,6 +742,28 @@ In config/initializers/brick.rb appropriate entries would look something like:
|
|
|
742
742
|
@double_underscore_applied = true
|
|
743
743
|
end
|
|
744
744
|
end
|
|
745
|
+
|
|
746
|
+
def _find_csv_separator(stream, likely_separator)
|
|
747
|
+
line = nil
|
|
748
|
+
last_char = nil
|
|
749
|
+
in_quotes = false
|
|
750
|
+
ret = +''
|
|
751
|
+
while true
|
|
752
|
+
(line = stream.readline).each_char do |ch|
|
|
753
|
+
likely_separator[ch] += 2 if !in_quotes && last_char == '"' && ch != "\n"
|
|
754
|
+
if ch == '"'
|
|
755
|
+
in_quotes = !in_quotes
|
|
756
|
+
likely_separator[last_char] += 2 if in_quotes && last_char != "\n"
|
|
757
|
+
end
|
|
758
|
+
last_char = ch
|
|
759
|
+
end
|
|
760
|
+
ret << line
|
|
761
|
+
break if !in_quotes || stream.eof?
|
|
762
|
+
end
|
|
763
|
+
likely_separator[line[0]] += 1
|
|
764
|
+
likely_separator[line[-2]] += 1
|
|
765
|
+
ret
|
|
766
|
+
end
|
|
745
767
|
end
|
|
746
768
|
|
|
747
769
|
module RouteSet
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: brick
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.0.
|
|
4
|
+
version: 1.0.151
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Lorin Thwaits
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2023-06-
|
|
11
|
+
date: 2023-06-08 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: activerecord
|