versponse 0.1.0 → 0.2.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/.rubocop.yml +15 -6
- data/CHANGELOG.md +59 -1
- data/CODE_OF_CONDUCT.md +1 -1
- data/LICENSE.txt +1 -1
- data/README.md +674 -20
- data/Rakefile +26 -3
- data/lib/versponse/base/class_methods.rb +180 -0
- data/lib/versponse/base/dsl.rb +231 -0
- data/lib/versponse/base.rb +35 -0
- data/lib/versponse/builder.rb +423 -0
- data/lib/versponse/cache.rb +47 -0
- data/lib/versponse/callable.rb +74 -0
- data/lib/versponse/class_policies.rb +15 -0
- data/lib/versponse/collapse_if_plan.rb +26 -0
- data/lib/versponse/collections.rb +49 -0
- data/lib/versponse/components.rb +37 -0
- data/lib/versponse/condition.rb +33 -0
- data/lib/versponse/configuration.rb +261 -0
- data/lib/versponse/const_as_enum.rb +39 -0
- data/lib/versponse/context_override/call.rb +27 -0
- data/lib/versponse/context_override/merge.rb +23 -0
- data/lib/versponse/context_override.rb +25 -0
- data/lib/versponse/context_plan.rb +24 -0
- data/lib/versponse/deep_copy.rb +27 -0
- data/lib/versponse/deep_freeze.rb +20 -0
- data/lib/versponse/discriminated_plan.rb +26 -0
- data/lib/versponse/error_policy/recovery.rb +68 -0
- data/lib/versponse/error_policy.rb +97 -0
- data/lib/versponse/expansion.rb +46 -0
- data/lib/versponse/extractors/block.rb +24 -0
- data/lib/versponse/extractors/fallback.rb +27 -0
- data/lib/versponse/extractors/itself.rb +21 -0
- data/lib/versponse/extractors/key.rb +28 -0
- data/lib/versponse/extractors/path.rb +28 -0
- data/lib/versponse/extractors.rb +23 -0
- data/lib/versponse/field_order.rb +23 -0
- data/lib/versponse/field_type.rb +88 -0
- data/lib/versponse/formatters.rb +38 -0
- data/lib/versponse/gem_version.rb +6 -0
- data/lib/versponse/inline_validation/builder.rb +129 -0
- data/lib/versponse/inline_validation/state.rb +16 -0
- data/lib/versponse/inline_validation.rb +86 -0
- data/lib/versponse/internals.rb +553 -0
- data/lib/versponse/json_value.rb +22 -0
- data/lib/versponse/lazy_plan.rb +30 -0
- data/lib/versponse/naming.rb +68 -0
- data/lib/versponse/object_schema.rb +25 -0
- data/lib/versponse/open_api/builder.rb +159 -0
- data/lib/versponse/open_api/component_set.rb +33 -0
- data/lib/versponse/open_api/declarations.rb +90 -0
- data/lib/versponse/open_api/document.rb +187 -0
- data/lib/versponse/open_api/ref_check.rb +89 -0
- data/lib/versponse/open_api/rswag_specs.rb +98 -0
- data/lib/versponse/open_api/sources.rb +72 -0
- data/lib/versponse/open_api/values.rb +29 -0
- data/lib/versponse/open_api.rb +12 -0
- data/lib/versponse/output_validator.rb +82 -0
- data/lib/versponse/pattern.rb +38 -0
- data/lib/versponse/plan.rb +104 -0
- data/lib/versponse/properties/array.rb +56 -0
- data/lib/versponse/properties/base.rb +325 -0
- data/lib/versponse/properties/collection.rb +135 -0
- data/lib/versponse/properties/const.rb +46 -0
- data/lib/versponse/properties/container.rb +51 -0
- data/lib/versponse/properties/enum.rb +93 -0
- data/lib/versponse/properties/field.rb +43 -0
- data/lib/versponse/properties/item_one_of.rb +19 -0
- data/lib/versponse/properties/object.rb +32 -0
- data/lib/versponse/properties/one_of.rb +176 -0
- data/lib/versponse/properties/reference.rb +133 -0
- data/lib/versponse/references.rb +162 -0
- data/lib/versponse/registry.rb +124 -0
- data/lib/versponse/schema_context.rb +69 -0
- data/lib/versponse/schema_merge.rb +24 -0
- data/lib/versponse/selection/scope.rb +36 -0
- data/lib/versponse/selection.rb +92 -0
- data/lib/versponse/selection_schema.rb +101 -0
- data/lib/versponse/steps/checked.rb +43 -0
- data/lib/versponse/steps/checked_read.rb +46 -0
- data/lib/versponse/steps/checked_read_formatted.rb +32 -0
- data/lib/versponse/steps/checked_value.rb +48 -0
- data/lib/versponse/steps/const.rb +44 -0
- data/lib/versponse/steps/nested.rb +98 -0
- data/lib/versponse/steps/one_of.rb +62 -0
- data/lib/versponse/steps/read.rb +48 -0
- data/lib/versponse/steps/read_formatted.rb +28 -0
- data/lib/versponse/steps/value.rb +52 -0
- data/lib/versponse/supported_versions.rb +61 -0
- data/lib/versponse/validator/all.rb +32 -0
- data/lib/versponse/validator/array_check.rb +48 -0
- data/lib/versponse/validator/boolean_check.rb +16 -0
- data/lib/versponse/validator/both.rb +24 -0
- data/lib/versponse/validator/class_check.rb +25 -0
- data/lib/versponse/validator/closed_object_check.rb +78 -0
- data/lib/versponse/validator/combinator.rb +40 -0
- data/lib/versponse/validator/compiler.rb +146 -0
- data/lib/versponse/validator/constant.rb +33 -0
- data/lib/versponse/validator/date_time_check.rb +21 -0
- data/lib/versponse/validator/format_check.rb +49 -0
- data/lib/versponse/validator/integer_check.rb +16 -0
- data/lib/versponse/validator/nullable_check.rb +22 -0
- data/lib/versponse/validator/number_check.rb +58 -0
- data/lib/versponse/validator/object_check.rb +90 -0
- data/lib/versponse/validator/ref.rb +38 -0
- data/lib/versponse/validator/root.rb +31 -0
- data/lib/versponse/validator/string_check.rb +48 -0
- data/lib/versponse/validator/string_keys.rb +21 -0
- data/lib/versponse/validator/type_check.rb +84 -0
- data/lib/versponse/validator/value_check.rb +36 -0
- data/lib/versponse/validator.rb +10 -0
- data/lib/versponse/variant_dispatcher.rb +35 -0
- data/lib/versponse/version.rb +179 -1
- data/lib/versponse/version_resolver.rb +27 -0
- data/lib/versponse/versions.rb +116 -0
- data/lib/versponse/view.rb +126 -0
- data/lib/versponse/wrapper.rb +53 -0
- data/lib/versponse.rb +165 -3
- metadata +151 -12
- data/sig/versponse.rbs +0 -4
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 9650c5e4fb0479ed7f1d64f3299fd7e217872e1a6de0366f608239f299214120
|
|
4
|
+
data.tar.gz: 32fc80226f3dabacbb598e9dadb921025117c058b041598a9e99b0e90691b5fd
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 138417fd2ad1873a118538e14ac6cef8b58ea89f8609d6c37b1542c32e35b68771a9f15a407a09a1f9c297bf3079592888b94bc9f37790cb10deb6d6c027753e
|
|
7
|
+
data.tar.gz: 7b86b87148d78b6f2efeb3a16d9430d6200369d34730ee64efbc8d72a6f5a3692114e4e83764c36e513accac09db32ec2ea7006b4d272319ba0127f6859bb908
|
data/.rubocop.yml
CHANGED
|
@@ -1,8 +1,17 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
inherit_gem:
|
|
2
|
+
standard: config/base.yml
|
|
3
|
+
standard-performance: config/base.yml
|
|
4
|
+
standard-custom: config/base.yml
|
|
5
|
+
|
|
6
|
+
plugins:
|
|
7
|
+
- standard-custom
|
|
8
|
+
- standard-performance
|
|
9
|
+
- rubocop-minitest
|
|
10
|
+
- rubocop-rake
|
|
3
11
|
|
|
4
|
-
|
|
5
|
-
|
|
12
|
+
AllCops:
|
|
13
|
+
TargetRubyVersion: 3.2
|
|
14
|
+
NewCops: enable
|
|
6
15
|
|
|
7
|
-
|
|
8
|
-
|
|
16
|
+
Minitest/MultipleAssertions:
|
|
17
|
+
Max: 6
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,63 @@
|
|
|
1
1
|
## [Unreleased]
|
|
2
2
|
|
|
3
|
+
## [0.2.0] - 2026-11-09
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
|
|
7
|
+
- Response DSL shared with verquest: `field`, `enum`, `const`, `array`, `object`, `collection`, `reference`, `one_of`, and `with_options`. As in verquest, a nested `with_options` replaces the outer options and ignores `map:`. `view:` and `discriminator:` apply.
|
|
8
|
+
- Class-level `description` and `schema_options` reach subclasses and are looked up when schemas are built. A subclass's `schema_options` merge with its ancestors', and the subclass wins per key.
|
|
9
|
+
- `field type: :object` for free-form maps, and `one_of` with `source` and `match:` arrays.
|
|
10
|
+
- Versions with inheritance and closest-earlier resolution.
|
|
11
|
+
- Blueprinter-style views (`view`, `include_view`, `exclude_properties`) that later versions inherit.
|
|
12
|
+
- `serialize` and `serialize_json` with root keys and meta.
|
|
13
|
+
- OpenAPI schemas per version and view, validation schemas, component names and `$ref`s.
|
|
14
|
+
- `Versponse.components` and `Versponse.eager_load!`.
|
|
15
|
+
- Opt-in output validation. `validate_output` takes `true`, or a callable that receives the response class on each render, for example to read Rails' `Current`. `validate_output_sample_rate` validates a share of renders. Setting a callable that can't take the response class raises `ArgumentError`.
|
|
16
|
+
- Output validation checks most fields while rendering, which adds about half the cost of a plain render. A value that a later block could change in place and so break its schema is checked after the render finishes. Such values are a Hash or Array not frozen all the way down, a String whose schema constrains more than its type, and an integer. The built-in `date` and `date-time` formatters return frozen Strings, so their values are checked while rendering.
|
|
17
|
+
- References to verquest request schemas.
|
|
18
|
+
- Polymorphic collections: an unnamed `one_of` inside a `collection` block types each item.
|
|
19
|
+
- `reference property:` reuses a property of another response class.
|
|
20
|
+
- `source { }` in inline `object` and `collection`.
|
|
21
|
+
- `one_of` with `discriminator:` emits an OpenAPI discriminator `mapping` built from each variant's `const`.
|
|
22
|
+
- Errors inside collection properties name the item index (`activity.3`).
|
|
23
|
+
- Expansion:
|
|
24
|
+
- `expandable: true` on `reference`, `collection item:`, and `one_of`.
|
|
25
|
+
- `identifier` for the collapsed shape.
|
|
26
|
+
- `serialize(expand: [...])` with dotted paths, `"path.*"`, and `"*"`. `"*"` expands every path `expandable_paths` lists, so recursive associations expand once.
|
|
27
|
+
- Schemas that describe both shapes with `anyOf`, and `<Name>Collapsed` components.
|
|
28
|
+
- `expandable_paths` and `config.unknown_expand`.
|
|
29
|
+
- OpenAPI documents:
|
|
30
|
+
- A `Versponse::OpenAPI::Document` class DSL with base sections, `finalize` hooks, and an `openapi` version that follows `config.json_schema_version`. `versions` and `document_name` without arguments return the declared values. A `finalize` block or lambda may take only the document.
|
|
31
|
+
- `responses` and `requests` take one or more classes, or `namespace:` with a Module or a String, eager-loaded through Zeitwerk at build. An undefined namespace, one with no response classes or body requests, a listed class of the wrong kind, and a listed query request raise `Versponse::DefinitionError`.
|
|
32
|
+
- Named `wrapper` components. A Symbol name becomes PascalCase (`:contact_list` declares `ContactList`). `meta:` takes a response class, checked when declared (`Versponse::DefinitionError` otherwise), and a meta class that doesn't serve the version raises `Versponse::VersionNotFoundError`, as in `to_schema`.
|
|
33
|
+
- `server` and `tag` write `x_` keywords as extensions (`x_display_name:` becomes `"x-display-name"`).
|
|
34
|
+
- Subclasses inherit declarations. `info` merges over the parent's, `schema`, `wrapper` and `security_scheme` with a parent's name replace the parent's entry, and one class declaring a name twice raises `Versponse::DefinitionError`.
|
|
35
|
+
- `build`, which returns a copy the caller can change, and `validate`, which checks the OpenAPI meta-schema and reports local `$ref`s that don't resolve.
|
|
36
|
+
- `Versponse::OpenAPI.rswag_specs` for rswag's `openapi_specs`. Every document needs `document_name` and `versions`.
|
|
37
|
+
- `config.custom_field_types` in verquest's shape (`type` and `schema_options`), used by `field` and `array`.
|
|
38
|
+
- `config.json_schema_version` takes the same versions as verquest (`:draft4`, `:draft6`, `:draft7`, `:draft2019_09`, `:draft2020_12`, `:openapi30`, and `:openapi31`, the default). Output validation uses that version's meta-schema, and `const` is a one-value `enum` under `:draft4` and `:openapi30`. Recursive classes are named with `$anchor`, a plain-name `$id` in drafts 6 and 7, or `id` in draft 4 and OpenAPI 3.0. Under `:openapi30`, nullable references, `one_of` and expandable properties get a `{"nullable": true, "enum": [null]}` branch, and object schemas leave out an empty `required`.
|
|
39
|
+
- Output validation compiles each validation schema into Ruby checks and calls json_schemer only for errors and unsupported keywords. With validation on, versponse renders faster than alba and blueprinter do without it. Like json_schemer, validation reads the Symbol keys of rendered Hashes as Strings. `InvalidOutputError`'s message names the first two errors, and errors of collection items point into the collection.
|
|
40
|
+
- `config.field_order = :alphabetical` orders output and schemas like blueprinter's `sort_fields_by :name_asc`.
|
|
41
|
+
- OpenAPI documents: `schema` for hand-written components, camelized like every other schema, and a `webhooks` section.
|
|
42
|
+
- Schema options are camelized (`max_length:` becomes `maxLength`), except `x-` extensions with their values, keys of name maps such as `properties` and `definitions`, and a discriminator's `mapping` keys. A Regexp `pattern:` is written as ECMA-262 (`\A` and `\z` become `^` and `$`), and options or `\Z` raise `Versponse::DefinitionError`, also from `config.custom_field_types`. Output validation reads patterns as ECMA-262, as documents do.
|
|
43
|
+
- `supported_versions min:, max:` limits the versions a class serves. Both bounds are inclusive and optional, and `min` defaults to the first declared version. Resolving a version outside the range raises `Versponse::VersionNotFoundError`. `Versponse.components` and OpenAPI documents leave the class and its wrappers out of that version, and `eager_load!` compiles only the versions the range serves. Only the requested version is checked, so `min: "preview"` can be served by an earlier block. `min` after `max`, or a `max` before the first declared version, raises `Versponse::DefinitionError`. Versions are compared with `config.version_resolver`, and subclasses inherit the range.
|
|
44
|
+
- `identifier collapse_if:` renders an expandable association in full instead of collapsed when the condition is false for its value. A `collection item:` renders in full when the condition is false for any item. An expandable `one_of` decides per value. Schemas don't change, and associations without it cost nothing extra.
|
|
45
|
+
- Type unions: `field` and `array` take `type: [:integer, :string]`, written as a JSON Schema `type` array with `"null"` added for `nullable: true`, or as an `anyOf` of single types under OpenAPI 3.0. Unions take only built-in types. `format:` and its formatter still apply, and the compiled validator checks them. A union combines with `any_of:`, as an `allOf` of both under OpenAPI 3.0. `nullable:` doesn't add a null branch to `any_of:`.
|
|
46
|
+
- `enum` writes a `type` next to its values, from `type:` (built-in, union or the base type of a custom type, falling back to `with_options type:`) or inferred from the values (`string`, `integer`, `number`, `boolean`, `object`, or a union for mixed values). A value that isn't of the type, or has no JSON type such as a Symbol, raises `Versponse::DefinitionError`. `nullable: true` adds `"null"` to `type` and `nil` to the values, or writes `nullable: true` under OpenAPI 3.0.
|
|
47
|
+
- `const` values need a JSON type, like `enum` values, so a Symbol raises `Versponse::DefinitionError`.
|
|
48
|
+
- `identifier` also declares its field in the full shape, so it needs no matching `field :id`. A property with an identifier's key raises `Versponse::DefinitionError`. With `collapse_if:`, the full shape leaves the identifier out when the condition is false.
|
|
49
|
+
- `Versponse::OpenAPI.rswag_specs` writes security scheme `type` and `in` as symbols, so rswag sends API key headers.
|
|
50
|
+
- The class registry replaces a class when one with the same name is defined again, so code reloading in development doesn't grow it.
|
|
51
|
+
- `time_precision digits, from:` sets the fraction digits of `date-time` values per class, from a version on, so an API can keep whole seconds in released versions and change precision in a new one. A subclass without `time_precision` inherits its closest ancestor's settings. A subclass that declares any uses only its own. Each `from:` is registered like a `supported_versions` bound.
|
|
52
|
+
- `context:` on `reference`, `collection`, `object`, `one_of` and `one_of` variants renders the subtree with its own context: a Hash merged over the parent context, or a callable returning it.
|
|
53
|
+
- `default:` on `field`, `enum` and `array`, and class-level `on_nil`, replace nil values. A static `default:` must match the property's schema, `default: nil` means no default, and `default:` on `reference`, `collection`, `object`, `one_of` or `const` raises `DefinitionError`.
|
|
54
|
+
- `on_error` on properties, classes and `config` recovers failed properties (`:nullify`, `:omit` or a handler), with `config.recoverable_errors` and the `config.on_recovered_error` hook. `reference property:` reuses the property's policy only where it fits the copy. An `:omit` carries over only when the copy has `if:` or `unless:`. Lambdas, Methods and objects with `#call` given to `on_nil` or `on_error` are checked for their arity when they are set. An error raised by `config.on_recovered_error` propagates past every policy.
|
|
55
|
+
- `fields:` on `serialize` renders a selection of fields, `selectable_paths` lists the paths, and `config.unknown_fields` sets what happens to invalid ones. Under `:ignore`, a list with no valid path renders only identifiers and consts.
|
|
56
|
+
- `expandable_targets` maps each expandable path to the response classes it renders.
|
|
57
|
+
- Rendered arrays are new Arrays, and Hash or Array defaults and consts render as copies, so output can be changed without touching the source or later renders.
|
|
58
|
+
- `serialize(context: nil)` renders with an empty context. `view: nil`, and `view: :collapsed` on a class without an identifier, raise `Versponse::ViewNotFoundError`.
|
|
59
|
+
- `Versponse::OpenAPI::Document.ref` and `.component_name` return the `$ref` and component name of a declared wrapper or `schema`, and raise `Versponse::DefinitionError` for a name the document doesn't declare.
|
|
60
|
+
|
|
3
61
|
## [0.1.0] - 2025-06-17
|
|
4
62
|
|
|
5
|
-
-
|
|
63
|
+
- Name reservation.
|
data/CODE_OF_CONDUCT.md
CHANGED
|
@@ -60,7 +60,7 @@ representative at an online or offline event.
|
|
|
60
60
|
|
|
61
61
|
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
|
62
62
|
reported to the community leaders responsible for enforcement at
|
|
63
|
-
|
|
63
|
+
yes@petr.codes.
|
|
64
64
|
All complaints will be reviewed and investigated promptly and fairly.
|
|
65
65
|
|
|
66
66
|
All community leaders are obligated to respect the privacy and security of the
|
data/LICENSE.txt
CHANGED