activestorage-validator 0.6.0 → 0.8.0
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/.github/workflows/rspec.yml +5 -11
- data/.gitignore +1 -0
- data/README.md +43 -3
- data/activestorage-validator.gemspec +4 -4
- data/gemfiles/rails72.gemfile +1 -1
- data/gemfiles/rails80.gemfile +1 -1
- data/gemfiles/rails81.gemfile +6 -0
- data/lib/activestorage/validator/blob.rb +37 -20
- data/lib/activestorage/validator/version.rb +1 -1
- data/skills/activestorage-validator/SKILL.md +138 -0
- metadata +10 -11
- data/gemfiles/rails61.gemfile +0 -7
- data/gemfiles/rails70.gemfile +0 -7
- data/gemfiles/rails71.gemfile +0 -6
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 7dd3596f7f7c5643a6bb22c897877b3d622acf3d525884108b047e02bfb36792
|
|
4
|
+
data.tar.gz: f705a000c6d22a36770bee09629c28c8fd3f5322c7e7ab48194aa8b5a976571d
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: bb4c1f92c407d40b7bc8658f59bb94e5126db2f6418b9667ad45538c8a1cd91251b896db728a422c403a5c04292bb93f8759f6c9db3e606e71c767940f91a6fb
|
|
7
|
+
data.tar.gz: 50763f805cf34602d88bd07b805dcf0321e5f64ab2b50078209d6a201cfa95095cf7009cef688ebf85706eb8105f2669dee43656ba046a7ec86b542c7304f0a6
|
data/.github/workflows/rspec.yml
CHANGED
|
@@ -23,21 +23,15 @@ jobs:
|
|
|
23
23
|
fail-fast: false
|
|
24
24
|
matrix:
|
|
25
25
|
include:
|
|
26
|
-
- { ruby: "3.0", gemfile: "rails61" }
|
|
27
|
-
- { ruby: "3.1", gemfile: "rails61" }
|
|
28
|
-
- { ruby: "3.2", gemfile: "rails61" }
|
|
29
|
-
- { ruby: "3.0", gemfile: "rails70" }
|
|
30
|
-
- { ruby: "3.1", gemfile: "rails70" }
|
|
31
|
-
- { ruby: "3.2", gemfile: "rails70" }
|
|
32
|
-
- { ruby: "3.0", gemfile: "rails71" }
|
|
33
|
-
- { ruby: "3.1", gemfile: "rails71" }
|
|
34
|
-
- { ruby: "3.2", gemfile: "rails71" }
|
|
35
|
-
- { ruby: "3.2", gemfile: "rails72" }
|
|
36
26
|
- { ruby: "3.3", gemfile: "rails72" }
|
|
37
27
|
- { ruby: "3.4", gemfile: "rails72" }
|
|
38
|
-
- { ruby: "
|
|
28
|
+
- { ruby: "4.0", gemfile: "rails72" }
|
|
39
29
|
- { ruby: "3.3", gemfile: "rails80" }
|
|
40
30
|
- { ruby: "3.4", gemfile: "rails80" }
|
|
31
|
+
- { ruby: "4.0", gemfile: "rails80" }
|
|
32
|
+
- { ruby: "3.3", gemfile: "rails81" }
|
|
33
|
+
- { ruby: "3.4", gemfile: "rails81" }
|
|
34
|
+
- { ruby: "4.0", gemfile: "rails81" }
|
|
41
35
|
steps:
|
|
42
36
|
- name: Install packages
|
|
43
37
|
run: |
|
data/.gitignore
CHANGED
data/README.md
CHANGED
|
@@ -55,9 +55,9 @@ end
|
|
|
55
55
|
|
|
56
56
|
| Option | Description |
|
|
57
57
|
|--------------|---------------------------------------------------------------------------------------------|
|
|
58
|
-
| content_type | Allowed MIME types. Accepts a symbol (`:web_image`, `:image`, `:audio`, `:video`, `:text`), an array of MIME types, a regular expression, or a string (single MIME type). |
|
|
59
|
-
| size_range | Allowed file size range (e.g. `1..5.megabytes`)
|
|
60
|
-
| extension | Allowed file extensions. Accepts a String or an Array of Strings. Case-insensitive, leading dot optional. Files without an extension are rejected. |
|
|
58
|
+
| content_type | Allowed MIME types. Accepts a symbol (`:web_image`, `:image`, `:audio`, `:video`, `:text`), an array of MIME types, a regular expression, or a string (single MIME type). Or a Proc/lambda returning one of the above. |
|
|
59
|
+
| size_range | Allowed file size range (e.g. `1..5.megabytes`). Or a Proc/lambda returning a Range. |
|
|
60
|
+
| extension | Allowed file extensions. Accepts a String or an Array of Strings. Case-insensitive, leading dot optional. Files without an extension are rejected. Or a Proc/lambda returning one of the above. |
|
|
61
61
|
|
|
62
62
|
### content_type Examples
|
|
63
63
|
|
|
@@ -82,6 +82,29 @@ end
|
|
|
82
82
|
|
|
83
83
|
The leading dot is optional (`"mp3"` and `".mp3"` behave the same), and matching is case-insensitive (`PHOTO.JPG` matches `extension: "jpg"`).
|
|
84
84
|
|
|
85
|
+
## Dynamic Options (Proc/lambda)
|
|
86
|
+
|
|
87
|
+
Every option (`content_type`, `size_range`, `extension`) also accepts a Proc/lambda,
|
|
88
|
+
so you can decide the allowed values per record at validation time:
|
|
89
|
+
|
|
90
|
+
```ruby
|
|
91
|
+
validates :avatar, blob: {
|
|
92
|
+
content_type: ->(record) { record.premium? ? %w[image/png image/jpeg] : :web_image },
|
|
93
|
+
size_range: ->(record) { 1..(record.premium? ? 20.megabytes : 5.megabytes) }
|
|
94
|
+
}
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
The Proc is resolved with the same arity convention as Rails' built-in validators
|
|
98
|
+
(the same rule used by `if:` / `unless:`):
|
|
99
|
+
|
|
100
|
+
- **No argument** (`-> { ... }`) — called as-is.
|
|
101
|
+
- **One argument** (`->(record) { ... }`) — the record is passed in.
|
|
102
|
+
|
|
103
|
+
The Proc must return a value of one of the types the option already accepts
|
|
104
|
+
(a Symbol/Array/Regexp/String for `content_type`, a Range for `size_range`, a
|
|
105
|
+
String/Array for `extension`). For `has_many_attached`, the Proc is evaluated
|
|
106
|
+
once per record (not per attached file).
|
|
107
|
+
|
|
85
108
|
## I18n Error Message Options
|
|
86
109
|
|
|
87
110
|
Validation error messages are I18n compatible. The following interpolation keys are available in your translation files, according to the validator's implementation:
|
|
@@ -117,6 +140,23 @@ en:
|
|
|
117
140
|
- Some features may not work depending on your ActiveStorage or Rails version.
|
|
118
141
|
- Validation error messages are I18n compatible and support interpolation keys as described above.
|
|
119
142
|
|
|
143
|
+
## Agent skill
|
|
144
|
+
|
|
145
|
+
This repo ships an [agent skill](skills/activestorage-validator/) (`SKILL.md`,
|
|
146
|
+
plus a Japanese `SKILL-ja.md`) that teaches coding agents when and how to apply
|
|
147
|
+
`activestorage-validator`. Install it into your project with the GitHub CLI:
|
|
148
|
+
|
|
149
|
+
```sh
|
|
150
|
+
gh skill install aki77/activestorage-validator
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
> `gh skill` is currently a GitHub CLI preview feature.
|
|
154
|
+
|
|
155
|
+
Alternatively, if your project already pulls `activestorage-validator` in via
|
|
156
|
+
Bundler, the [bundler-skills](https://github.com/aki77/bundler-skills) plugin
|
|
157
|
+
auto-syncs this skill on `bundle install` — keeping the skill version locked to
|
|
158
|
+
the gem version.
|
|
159
|
+
|
|
120
160
|
## Contributing
|
|
121
161
|
|
|
122
162
|
Bug reports and pull requests are welcome on GitHub via [issues](https://github.com/aki77/activestorage-validator/issues) or [pull requests](https://github.com/aki77/activestorage-validator/pulls).
|
|
@@ -17,16 +17,16 @@ Gem::Specification.new do |spec|
|
|
|
17
17
|
# Specify which files should be added to the gem when it is released.
|
|
18
18
|
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
|
19
19
|
spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
|
|
20
|
-
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
|
20
|
+
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) || f.match(%r{^skills/.*-ja\.md$}) }
|
|
21
21
|
end
|
|
22
22
|
spec.bindir = "exe"
|
|
23
23
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
|
24
24
|
spec.require_paths = ["lib"]
|
|
25
25
|
|
|
26
|
-
spec.required_ruby_version = '>= 3.
|
|
26
|
+
spec.required_ruby_version = '>= 3.3.0'
|
|
27
27
|
|
|
28
|
-
spec.add_dependency "rails", ">=
|
|
29
|
-
spec.add_development_dependency "bundler", "
|
|
28
|
+
spec.add_dependency "rails", ">= 7.2.0"
|
|
29
|
+
spec.add_development_dependency "bundler", ">= 2.0"
|
|
30
30
|
spec.add_development_dependency "rake", ">= 12.3.3"
|
|
31
31
|
spec.add_development_dependency "rspec", "~> 3.0"
|
|
32
32
|
spec.add_development_dependency "combustion"
|
data/gemfiles/rails72.gemfile
CHANGED
data/gemfiles/rails80.gemfile
CHANGED
|
@@ -4,25 +4,23 @@ module ActiveRecord
|
|
|
4
4
|
def validate_each(record, attribute, values) # rubocop:disable Metrics/AbcSize
|
|
5
5
|
return unless values.attached?
|
|
6
6
|
|
|
7
|
+
size_range = resolve_option(record, options[:size_range])
|
|
8
|
+
content_type = resolve_option(record, options[:content_type])
|
|
9
|
+
extension = resolve_option(record, options[:extension])
|
|
10
|
+
|
|
7
11
|
Array(values).each do |value|
|
|
8
|
-
if
|
|
9
|
-
if options[:size_range].min > value.blob.byte_size
|
|
10
|
-
record.errors.add(attribute, :min_size_error, min_size: ActiveSupport::NumberHelper.number_to_human_size(options[:size_range].min), filename: value.blob.filename.to_s)
|
|
11
|
-
elsif options[:size_range].max < value.blob.byte_size
|
|
12
|
-
record.errors.add(attribute, :max_size_error, max_size: ActiveSupport::NumberHelper.number_to_human_size(options[:size_range].max), filename: value.blob.filename.to_s)
|
|
13
|
-
end
|
|
14
|
-
end
|
|
12
|
+
validate_size(record, attribute, value, size_range) if size_range.present?
|
|
15
13
|
|
|
16
|
-
unless valid_content_type?(value.blob)
|
|
14
|
+
unless valid_content_type?(value.blob, content_type)
|
|
17
15
|
record.errors.add(attribute, :content_type, filename: value.blob.filename.to_s)
|
|
18
16
|
end
|
|
19
17
|
|
|
20
|
-
unless valid_extension?(value.blob)
|
|
18
|
+
unless valid_extension?(value.blob, extension)
|
|
21
19
|
record.errors.add(
|
|
22
20
|
attribute,
|
|
23
21
|
:extension,
|
|
24
22
|
filename: value.blob.filename.to_s,
|
|
25
|
-
extension: Array(
|
|
23
|
+
extension: Array(extension).map { |e| normalize_extension(e) }.join(', ')
|
|
26
24
|
)
|
|
27
25
|
end
|
|
28
26
|
end
|
|
@@ -30,27 +28,46 @@ module ActiveRecord
|
|
|
30
28
|
|
|
31
29
|
private
|
|
32
30
|
|
|
33
|
-
|
|
34
|
-
|
|
31
|
+
# Resolve only when the value is a Proc, using the same arity convention
|
|
32
|
+
# as Rails' built-in validators: arity 0 calls the proc as-is, otherwise
|
|
33
|
+
# the record is passed in. Anything else (Symbol/String/Array/Regexp/
|
|
34
|
+
# Range/nil) is returned untouched, preserving backward compatibility.
|
|
35
|
+
def resolve_option(record, value)
|
|
36
|
+
return value unless value.is_a?(Proc)
|
|
37
|
+
|
|
38
|
+
value.arity.zero? ? value.call : value.call(record)
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def validate_size(record, attribute, value, size_range)
|
|
42
|
+
byte_size = value.blob.byte_size
|
|
43
|
+
if size_range.min > byte_size
|
|
44
|
+
record.errors.add(attribute, :min_size_error, min_size: ActiveSupport::NumberHelper.number_to_human_size(size_range.min), filename: value.blob.filename.to_s)
|
|
45
|
+
elsif size_range.max < byte_size
|
|
46
|
+
record.errors.add(attribute, :max_size_error, max_size: ActiveSupport::NumberHelper.number_to_human_size(size_range.max), filename: value.blob.filename.to_s)
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def valid_content_type?(blob, content_type)
|
|
51
|
+
return true if content_type.nil?
|
|
35
52
|
|
|
36
|
-
case
|
|
53
|
+
case content_type
|
|
37
54
|
when Regexp
|
|
38
|
-
|
|
55
|
+
content_type.match?(blob.content_type)
|
|
39
56
|
when Array
|
|
40
|
-
|
|
57
|
+
content_type.include?(blob.content_type)
|
|
41
58
|
when :web_image
|
|
42
59
|
ActiveStorage.web_image_content_types.include?(blob.content_type)
|
|
43
60
|
when Symbol
|
|
44
|
-
blob.public_send("#{
|
|
61
|
+
blob.public_send("#{content_type}?")
|
|
45
62
|
else
|
|
46
|
-
|
|
63
|
+
content_type == blob.content_type
|
|
47
64
|
end
|
|
48
65
|
end
|
|
49
66
|
|
|
50
|
-
def valid_extension?(blob)
|
|
51
|
-
return true if
|
|
67
|
+
def valid_extension?(blob, extension)
|
|
68
|
+
return true if extension.nil?
|
|
52
69
|
|
|
53
|
-
allowed = Array(
|
|
70
|
+
allowed = Array(extension).map { |e| normalize_extension(e) }
|
|
54
71
|
actual = normalize_extension(blob.filename.extension)
|
|
55
72
|
return false if actual.empty?
|
|
56
73
|
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: activestorage-validator
|
|
3
|
+
description: "Validate ActiveStorage attachments (content type, file size, file extension) with the activestorage-validator gem's `blob` validator. Use when adding validations to has_one_attached / has_many_attached attributes."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# activestorage-validator
|
|
7
|
+
|
|
8
|
+
A Rails gem that adds a `blob` validator for ActiveStorage attachments. It
|
|
9
|
+
validates content type, file size, and file extension on both
|
|
10
|
+
`has_one_attached` and `has_many_attached` attributes.
|
|
11
|
+
|
|
12
|
+
## First: determine applicability
|
|
13
|
+
|
|
14
|
+
Use this gem **only** for validating ActiveStorage attachments. For ordinary
|
|
15
|
+
(non-attachment) attributes, use the standard Rails validators (`presence`,
|
|
16
|
+
`length`, `numericality`, etc.).
|
|
17
|
+
|
|
18
|
+
| What you validate | Tool |
|
|
19
|
+
| --- | --- |
|
|
20
|
+
| ActiveStorage attachment (content type / size / extension) | **`blob:` validator (this gem)** |
|
|
21
|
+
| Plain string/number/boolean columns | Standard Rails validators |
|
|
22
|
+
| Presence of the attachment itself | `presence: true` (works alongside `blob:`) |
|
|
23
|
+
|
|
24
|
+
There is no special read path — declare `validates ..., blob: { ... }` and the
|
|
25
|
+
attachment is validated like any other Rails validation on `save`/`valid?`.
|
|
26
|
+
|
|
27
|
+
## Usage
|
|
28
|
+
|
|
29
|
+
Declare validations on the model with the `blob:` validator.
|
|
30
|
+
|
|
31
|
+
```ruby
|
|
32
|
+
class User < ApplicationRecord
|
|
33
|
+
has_one_attached :avatar
|
|
34
|
+
has_many_attached :photos
|
|
35
|
+
|
|
36
|
+
# Allow only web image files (PNG, JPEG, GIF, WebP)
|
|
37
|
+
validates :avatar, presence: true, blob: { content_type: :web_image }
|
|
38
|
+
|
|
39
|
+
# Allow only JPEG/PNG, up to 5MB per file
|
|
40
|
+
validates :photos, presence: true, blob: {
|
|
41
|
+
content_type: ["image/png", "image/jpg", "image/jpeg"],
|
|
42
|
+
size_range: 1..(5.megabytes)
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
# Regexp content_type + required extension (AND condition)
|
|
46
|
+
validates :audio, blob: { content_type: "audio/mpeg", extension: %w[mp3] }
|
|
47
|
+
end
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
> For `has_many_attached`, every option (including `size_range`) is applied to
|
|
51
|
+
> **each file individually**.
|
|
52
|
+
|
|
53
|
+
## Options (all optional, combine freely)
|
|
54
|
+
|
|
55
|
+
| Option | Accepts | Notes |
|
|
56
|
+
| --- | --- | --- |
|
|
57
|
+
| `content_type` | Symbol / Array / Regexp / String / Proc | Allowed MIME type(s). See matching below. |
|
|
58
|
+
| `size_range` | Range / Proc | Allowed byte size, e.g. `1..(5.megabytes)`. |
|
|
59
|
+
| `extension` | String / Array / Proc | Allowed filename extension(s). |
|
|
60
|
+
|
|
61
|
+
Any option also accepts a **Proc/lambda** returning a value of the listed type,
|
|
62
|
+
resolved with the same arity convention as Rails' built-in validators (`if:` /
|
|
63
|
+
`unless:`): `-> { ... }` is called as-is, `->(record) { ... }` receives the
|
|
64
|
+
record. For `has_many_attached` the Proc is evaluated once per record. Example:
|
|
65
|
+
`content_type: ->(record) { record.premium? ? %w[image/png] : :web_image }`.
|
|
66
|
+
|
|
67
|
+
### `content_type` matching
|
|
68
|
+
|
|
69
|
+
- **`:web_image`** — special-cased to `ActiveStorage.web_image_content_types`
|
|
70
|
+
(PNG, JPEG, GIF, WebP). Use this instead of `:image` when you want only
|
|
71
|
+
browser-safe images.
|
|
72
|
+
- **Other Symbol** (`:image`, `:audio`, `:video`, `:text`) — calls the
|
|
73
|
+
ActiveStorage built-in predicate `blob.image?` / `blob.audio?` / etc.
|
|
74
|
+
- **Array** — `["image/png", "image/jpeg"]`: exact membership of the blob's
|
|
75
|
+
content type in the list.
|
|
76
|
+
- **Regexp** — `%r{^image/}`: matched against the blob's content type.
|
|
77
|
+
- **String** — `"application/pdf"`: exact equality.
|
|
78
|
+
|
|
79
|
+
### `extension` matching
|
|
80
|
+
|
|
81
|
+
- Accepts a String (`"mp3"`) or Array (`%w[mp3 m4a]`).
|
|
82
|
+
- Leading dot is optional (`"mp3"` == `".mp3"`).
|
|
83
|
+
- Case-insensitive (`PHOTO.JPG` matches `extension: "jpg"`).
|
|
84
|
+
- **A file with no extension is always rejected** when `extension` is set.
|
|
85
|
+
- When combined with `content_type`, both must pass (AND). E.g.
|
|
86
|
+
`{ content_type: "audio/mpeg", extension: %w[mp3] }` rejects a `.wav` file
|
|
87
|
+
even if its MIME type happens to be `audio/mpeg`.
|
|
88
|
+
|
|
89
|
+
## I18n error messages
|
|
90
|
+
|
|
91
|
+
Errors are I18n-compatible. Error types and their interpolation keys:
|
|
92
|
+
|
|
93
|
+
| Error type | Interpolation keys | When |
|
|
94
|
+
| --- | --- | --- |
|
|
95
|
+
| `content_type` | `filename` | content type not allowed |
|
|
96
|
+
| `min_size_error` | `filename`, `min_size` | smaller than `size_range.min` |
|
|
97
|
+
| `max_size_error` | `filename`, `max_size` | larger than `size_range.max` |
|
|
98
|
+
| `extension` | `filename`, `extension` | extension not allowed (or missing) |
|
|
99
|
+
|
|
100
|
+
`min_size` / `max_size` are humanized (`ActiveSupport::NumberHelper.number_to_human_size`).
|
|
101
|
+
`extension` is the allowed list joined by `, `.
|
|
102
|
+
|
|
103
|
+
```yaml
|
|
104
|
+
# config/locales/en.yml
|
|
105
|
+
en:
|
|
106
|
+
errors:
|
|
107
|
+
messages:
|
|
108
|
+
content_type: "%{filename} has an invalid content type"
|
|
109
|
+
min_size_error: "%{filename} is too small (minimum is %{min_size})"
|
|
110
|
+
max_size_error: "%{filename} is too large (maximum is %{max_size})"
|
|
111
|
+
extension: "%{filename} has an invalid file extension (allowed: %{extension})"
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
The gem ships default messages for 7 locales: `en`, `ja`, `de`, `es`, `fr`,
|
|
115
|
+
`pl`, `pt-br`. Override them in your app's locale files using the keys above.
|
|
116
|
+
|
|
117
|
+
## Behavior details
|
|
118
|
+
|
|
119
|
+
- **Unattached values are skipped.** Validation returns early unless the
|
|
120
|
+
attachment is attached, so `blob:` does not enforce presence — add
|
|
121
|
+
`presence: true` separately if the attachment is required.
|
|
122
|
+
- **Size boundaries are inclusive.** A blob is valid when
|
|
123
|
+
`size_range.min <= byte_size <= size_range.max`. Below min → `min_size_error`;
|
|
124
|
+
above max → `max_size_error`.
|
|
125
|
+
- **Extension normalization** is `downcase` + strip a single leading dot; an
|
|
126
|
+
empty resulting extension (no extension on the file) fails.
|
|
127
|
+
- Options are independent — omit any you don't need; only the present ones run.
|
|
128
|
+
|
|
129
|
+
## Pitfalls
|
|
130
|
+
|
|
131
|
+
- A file **without an extension** is rejected whenever `extension:` is set —
|
|
132
|
+
even if its content type is allowed. Don't set `extension:` if you accept
|
|
133
|
+
extension-less uploads.
|
|
134
|
+
- For `has_many_attached`, `size_range` applies **per file**, not to the total.
|
|
135
|
+
- `blob:` alone does **not** require an attachment; pair it with `presence: true`
|
|
136
|
+
when the upload is mandatory.
|
|
137
|
+
- No special read/preload path exists — this is a plain `EachValidator`; it runs
|
|
138
|
+
on standard `valid?` / `save`.
|
metadata
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: activestorage-validator
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.8.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- aki
|
|
8
8
|
bindir: exe
|
|
9
9
|
cert_chain: []
|
|
10
|
-
date:
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
11
11
|
dependencies:
|
|
12
12
|
- !ruby/object:Gem::Dependency
|
|
13
13
|
name: rails
|
|
@@ -15,26 +15,26 @@ dependencies:
|
|
|
15
15
|
requirements:
|
|
16
16
|
- - ">="
|
|
17
17
|
- !ruby/object:Gem::Version
|
|
18
|
-
version:
|
|
18
|
+
version: 7.2.0
|
|
19
19
|
type: :runtime
|
|
20
20
|
prerelease: false
|
|
21
21
|
version_requirements: !ruby/object:Gem::Requirement
|
|
22
22
|
requirements:
|
|
23
23
|
- - ">="
|
|
24
24
|
- !ruby/object:Gem::Version
|
|
25
|
-
version:
|
|
25
|
+
version: 7.2.0
|
|
26
26
|
- !ruby/object:Gem::Dependency
|
|
27
27
|
name: bundler
|
|
28
28
|
requirement: !ruby/object:Gem::Requirement
|
|
29
29
|
requirements:
|
|
30
|
-
- - "
|
|
30
|
+
- - ">="
|
|
31
31
|
- !ruby/object:Gem::Version
|
|
32
32
|
version: '2.0'
|
|
33
33
|
type: :development
|
|
34
34
|
prerelease: false
|
|
35
35
|
version_requirements: !ruby/object:Gem::Requirement
|
|
36
36
|
requirements:
|
|
37
|
-
- - "
|
|
37
|
+
- - ">="
|
|
38
38
|
- !ruby/object:Gem::Version
|
|
39
39
|
version: '2.0'
|
|
40
40
|
- !ruby/object:Gem::Dependency
|
|
@@ -107,14 +107,13 @@ files:
|
|
|
107
107
|
- config/locales/ja.yml
|
|
108
108
|
- config/locales/pl.yml
|
|
109
109
|
- config/locales/pt-br.yml
|
|
110
|
-
- gemfiles/rails61.gemfile
|
|
111
|
-
- gemfiles/rails70.gemfile
|
|
112
|
-
- gemfiles/rails71.gemfile
|
|
113
110
|
- gemfiles/rails72.gemfile
|
|
114
111
|
- gemfiles/rails80.gemfile
|
|
112
|
+
- gemfiles/rails81.gemfile
|
|
115
113
|
- lib/activestorage/validator.rb
|
|
116
114
|
- lib/activestorage/validator/blob.rb
|
|
117
115
|
- lib/activestorage/validator/version.rb
|
|
116
|
+
- skills/activestorage-validator/SKILL.md
|
|
118
117
|
homepage: https://github.com/aki77/activestorage-validator
|
|
119
118
|
licenses:
|
|
120
119
|
- MIT
|
|
@@ -126,14 +125,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
126
125
|
requirements:
|
|
127
126
|
- - ">="
|
|
128
127
|
- !ruby/object:Gem::Version
|
|
129
|
-
version: 3.
|
|
128
|
+
version: 3.3.0
|
|
130
129
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
131
130
|
requirements:
|
|
132
131
|
- - ">="
|
|
133
132
|
- !ruby/object:Gem::Version
|
|
134
133
|
version: '0'
|
|
135
134
|
requirements: []
|
|
136
|
-
rubygems_version:
|
|
135
|
+
rubygems_version: 4.0.10
|
|
137
136
|
specification_version: 4
|
|
138
137
|
summary: ActiveStorage blob validator.
|
|
139
138
|
test_files: []
|
data/gemfiles/rails61.gemfile
DELETED
data/gemfiles/rails70.gemfile
DELETED