activestorage-validator 0.6.0 → 0.7.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/README.md +17 -0
- data/activestorage-validator.gemspec +1 -1
- data/lib/activestorage/validator/version.rb +1 -1
- data/skills/activestorage-validator/SKILL.md +132 -0
- metadata +4 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: acc9fae7338e419736df276e25e94e198cdc8a0ca9a2b80210c3175d684f5f22
|
|
4
|
+
data.tar.gz: 6b9be22b0d25c70bcf08cc51a05f9443982963d7e42e3817b90c60a596e5e071
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 57e1e9cd4353cfcb2aaeee8a2eef4bbedfe49b3382a3cacc7281fa1e5ec5ca1aa10158465a42e6eff8c2dbfd375b16f9ddb26c3027d1b337ca8fd0b41824c94b
|
|
7
|
+
data.tar.gz: 597d5cd7f32091fcf00a196fa4bd9d7404e5f129db45d0235c70768a01167d47ae9ec361b635b2732add9ba8be45c2bb2fef6db5a4b67e676130dfe7cf9fd13a
|
data/README.md
CHANGED
|
@@ -117,6 +117,23 @@ en:
|
|
|
117
117
|
- Some features may not work depending on your ActiveStorage or Rails version.
|
|
118
118
|
- Validation error messages are I18n compatible and support interpolation keys as described above.
|
|
119
119
|
|
|
120
|
+
## Agent skill
|
|
121
|
+
|
|
122
|
+
This repo ships an [agent skill](skills/activestorage-validator/) (`SKILL.md`,
|
|
123
|
+
plus a Japanese `SKILL-ja.md`) that teaches coding agents when and how to apply
|
|
124
|
+
`activestorage-validator`. Install it into your project with the GitHub CLI:
|
|
125
|
+
|
|
126
|
+
```sh
|
|
127
|
+
gh skill install aki77/activestorage-validator
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
> `gh skill` is currently a GitHub CLI preview feature.
|
|
131
|
+
|
|
132
|
+
Alternatively, if your project already pulls `activestorage-validator` in via
|
|
133
|
+
Bundler, the [bundler-skills](https://github.com/aki77/bundler-skills) plugin
|
|
134
|
+
auto-syncs this skill on `bundle install` — keeping the skill version locked to
|
|
135
|
+
the gem version.
|
|
136
|
+
|
|
120
137
|
## Contributing
|
|
121
138
|
|
|
122
139
|
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,7 +17,7 @@ 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) }
|
|
@@ -0,0 +1,132 @@
|
|
|
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 | Allowed MIME type(s). See matching below. |
|
|
58
|
+
| `size_range` | Range | Allowed byte size, e.g. `1..(5.megabytes)`. |
|
|
59
|
+
| `extension` | String / Array | Allowed filename extension(s). |
|
|
60
|
+
|
|
61
|
+
### `content_type` matching
|
|
62
|
+
|
|
63
|
+
- **`:web_image`** — special-cased to `ActiveStorage.web_image_content_types`
|
|
64
|
+
(PNG, JPEG, GIF, WebP). Use this instead of `:image` when you want only
|
|
65
|
+
browser-safe images.
|
|
66
|
+
- **Other Symbol** (`:image`, `:audio`, `:video`, `:text`) — calls the
|
|
67
|
+
ActiveStorage built-in predicate `blob.image?` / `blob.audio?` / etc.
|
|
68
|
+
- **Array** — `["image/png", "image/jpeg"]`: exact membership of the blob's
|
|
69
|
+
content type in the list.
|
|
70
|
+
- **Regexp** — `%r{^image/}`: matched against the blob's content type.
|
|
71
|
+
- **String** — `"application/pdf"`: exact equality.
|
|
72
|
+
|
|
73
|
+
### `extension` matching
|
|
74
|
+
|
|
75
|
+
- Accepts a String (`"mp3"`) or Array (`%w[mp3 m4a]`).
|
|
76
|
+
- Leading dot is optional (`"mp3"` == `".mp3"`).
|
|
77
|
+
- Case-insensitive (`PHOTO.JPG` matches `extension: "jpg"`).
|
|
78
|
+
- **A file with no extension is always rejected** when `extension` is set.
|
|
79
|
+
- When combined with `content_type`, both must pass (AND). E.g.
|
|
80
|
+
`{ content_type: "audio/mpeg", extension: %w[mp3] }` rejects a `.wav` file
|
|
81
|
+
even if its MIME type happens to be `audio/mpeg`.
|
|
82
|
+
|
|
83
|
+
## I18n error messages
|
|
84
|
+
|
|
85
|
+
Errors are I18n-compatible. Error types and their interpolation keys:
|
|
86
|
+
|
|
87
|
+
| Error type | Interpolation keys | When |
|
|
88
|
+
| --- | --- | --- |
|
|
89
|
+
| `content_type` | `filename` | content type not allowed |
|
|
90
|
+
| `min_size_error` | `filename`, `min_size` | smaller than `size_range.min` |
|
|
91
|
+
| `max_size_error` | `filename`, `max_size` | larger than `size_range.max` |
|
|
92
|
+
| `extension` | `filename`, `extension` | extension not allowed (or missing) |
|
|
93
|
+
|
|
94
|
+
`min_size` / `max_size` are humanized (`ActiveSupport::NumberHelper.number_to_human_size`).
|
|
95
|
+
`extension` is the allowed list joined by `, `.
|
|
96
|
+
|
|
97
|
+
```yaml
|
|
98
|
+
# config/locales/en.yml
|
|
99
|
+
en:
|
|
100
|
+
errors:
|
|
101
|
+
messages:
|
|
102
|
+
content_type: "%{filename} has an invalid content type"
|
|
103
|
+
min_size_error: "%{filename} is too small (minimum is %{min_size})"
|
|
104
|
+
max_size_error: "%{filename} is too large (maximum is %{max_size})"
|
|
105
|
+
extension: "%{filename} has an invalid file extension (allowed: %{extension})"
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
The gem ships default messages for 7 locales: `en`, `ja`, `de`, `es`, `fr`,
|
|
109
|
+
`pl`, `pt-br`. Override them in your app's locale files using the keys above.
|
|
110
|
+
|
|
111
|
+
## Behavior details
|
|
112
|
+
|
|
113
|
+
- **Unattached values are skipped.** Validation returns early unless the
|
|
114
|
+
attachment is attached, so `blob:` does not enforce presence — add
|
|
115
|
+
`presence: true` separately if the attachment is required.
|
|
116
|
+
- **Size boundaries are inclusive.** A blob is valid when
|
|
117
|
+
`size_range.min <= byte_size <= size_range.max`. Below min → `min_size_error`;
|
|
118
|
+
above max → `max_size_error`.
|
|
119
|
+
- **Extension normalization** is `downcase` + strip a single leading dot; an
|
|
120
|
+
empty resulting extension (no extension on the file) fails.
|
|
121
|
+
- Options are independent — omit any you don't need; only the present ones run.
|
|
122
|
+
|
|
123
|
+
## Pitfalls
|
|
124
|
+
|
|
125
|
+
- A file **without an extension** is rejected whenever `extension:` is set —
|
|
126
|
+
even if its content type is allowed. Don't set `extension:` if you accept
|
|
127
|
+
extension-less uploads.
|
|
128
|
+
- For `has_many_attached`, `size_range` applies **per file**, not to the total.
|
|
129
|
+
- `blob:` alone does **not** require an attachment; pair it with `presence: true`
|
|
130
|
+
when the upload is mandatory.
|
|
131
|
+
- No special read/preload path exists — this is a plain `EachValidator`; it runs
|
|
132
|
+
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.7.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
|
|
@@ -115,6 +115,7 @@ files:
|
|
|
115
115
|
- lib/activestorage/validator.rb
|
|
116
116
|
- lib/activestorage/validator/blob.rb
|
|
117
117
|
- lib/activestorage/validator/version.rb
|
|
118
|
+
- skills/activestorage-validator/SKILL.md
|
|
118
119
|
homepage: https://github.com/aki77/activestorage-validator
|
|
119
120
|
licenses:
|
|
120
121
|
- MIT
|
|
@@ -133,7 +134,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
133
134
|
- !ruby/object:Gem::Version
|
|
134
135
|
version: '0'
|
|
135
136
|
requirements: []
|
|
136
|
-
rubygems_version:
|
|
137
|
+
rubygems_version: 4.0.10
|
|
137
138
|
specification_version: 4
|
|
138
139
|
summary: ActiveStorage blob validator.
|
|
139
140
|
test_files: []
|