From 2d1db6b24d08e4f2ea6a21d95ef293d56faafd83 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 27 Feb 2026 18:36:23 +0000 Subject: [PATCH 01/15] Bump minimatch from 10.1.1 to 10.2.4 in /docs/_preview Bumps [minimatch](https://github.com/isaacs/minimatch) from 10.1.1 to 10.2.4. - [Changelog](https://github.com/isaacs/minimatch/blob/main/changelog.md) - [Commits](https://github.com/isaacs/minimatch/compare/v10.1.1...v10.2.4) --- updated-dependencies: - dependency-name: minimatch dependency-version: 10.2.4 dependency-type: indirect ... Signed-off-by: dependabot[bot] --- docs/_preview/package-lock.json | 55 +++++++++++++++++---------------- 1 file changed, 29 insertions(+), 26 deletions(-) diff --git a/docs/_preview/package-lock.json b/docs/_preview/package-lock.json index c514573791..f2a2bed615 100644 --- a/docs/_preview/package-lock.json +++ b/docs/_preview/package-lock.json @@ -28,27 +28,6 @@ "postcss": "^8.0.0" } }, - "node_modules/@isaacs/balanced-match": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@isaacs/balanced-match/-/balanced-match-4.0.1.tgz", - "integrity": "sha512-yzMTt9lEb8Gv7zRioUilSglI0c0smZ9k5D65677DLWLtWJaXIS3CqcGyUFByYKlnUj6TkjLVs54fBl6+TiGQDQ==", - "dev": true, - "engines": { - "node": "20 || >=22" - } - }, - "node_modules/@isaacs/brace-expansion": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/@isaacs/brace-expansion/-/brace-expansion-5.0.0.tgz", - "integrity": "sha512-ZT55BDLV0yv0RBm2czMiZ+SqCGO7AvmOM3G/w2xhVPH+te0aKgFjmBvGlL1dH+ql2tgGO3MVrbb3jCKyvpgnxA==", - "dev": true, - "dependencies": { - "@isaacs/balanced-match": "^4.0.1" - }, - "engines": { - "node": "20 || >=22" - } - }, "node_modules/@isaacs/cliui": { "version": "8.0.2", "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", @@ -219,6 +198,16 @@ "postcss": "^8.1.0" } }, + "node_modules/balanced-match": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", + "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "18 || 20 || >=22" + } + }, "node_modules/baseline-browser-mapping": { "version": "2.8.31", "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.8.31.tgz", @@ -240,6 +229,19 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/brace-expansion": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.4.tgz", + "integrity": "sha512-h+DEnpVvxmfVefa4jFbCf5HdH5YMDXRsmKflpf1pILZWRFlTbJpxeU55nJl4Smt5HQaGzg1o6RHFPJaOqnmBDg==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^4.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" + } + }, "node_modules/braces": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", @@ -657,15 +659,16 @@ } }, "node_modules/minimatch": { - "version": "10.1.1", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.1.1.tgz", - "integrity": "sha512-enIvLvRAFZYXJzkCYG5RKmPfrFArdLv+R+lbQ53BmIMLIry74bjKzX6iHAm8WYamJkhSSEabrWN5D97XnKObjQ==", + "version": "10.2.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.4.tgz", + "integrity": "sha512-oRjTw/97aTBN0RHbYCdtF1MQfvusSIBQM0IZEgzl6426+8jSC0nF1a/GmnVLpfB9yyr6g6FTqWqiZVbxrtaCIg==", "dev": true, + "license": "BlueOak-1.0.0", "dependencies": { - "@isaacs/brace-expansion": "^5.0.0" + "brace-expansion": "^5.0.2" }, "engines": { - "node": "20 || >=22" + "node": "18 || 20 || >=22" }, "funding": { "url": "https://github.com/sponsors/isaacs" From aec24f3b7062fde31df565746d792aadab7f7bec Mon Sep 17 00:00:00 2001 From: alexander-yevsyukov Date: Fri, 27 Feb 2026 18:43:43 +0000 Subject: [PATCH 02/15] Bump version -> `2.0.0-SNAPSHOT.400` --- version.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.gradle.kts b/version.gradle.kts index 8b272b178d..197951b0e1 100644 --- a/version.gradle.kts +++ b/version.gradle.kts @@ -29,4 +29,4 @@ * * For Spine-based dependencies please see [io.spine.dependency.local.Spine]. */ -val validationVersion by extra("2.0.0-SNAPSHOT.399") +val validationVersion by extra("2.0.0-SNAPSHOT.400") From ea821e8f06bdef0f3e55a5846bea661c3478ba26 Mon Sep 17 00:00:00 2001 From: alexander-yevsyukov Date: Fri, 27 Feb 2026 19:32:54 +0000 Subject: [PATCH 03/15] Add details for the `build-in-options-plan.md` --- .agents/tasks/built-in-options-plan.md | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/.agents/tasks/built-in-options-plan.md b/.agents/tasks/built-in-options-plan.md index 90df03f04d..2e9eab8c84 100644 --- a/.agents/tasks/built-in-options-plan.md +++ b/.agents/tasks/built-in-options-plan.md @@ -1,7 +1,18 @@ -# Task: Publish a minimal reference set on built-in validation options +# Task: Publish a reference set on built-in validation options - Placement: a separate section coming after the "Concepts" section. - From `docs/_options/options.proto`, enumerate the built-in options and group them (fields, strings, numbers, collections, message-level). -- For each documented option: purpose, supported field types, common pitfalls, and a short `.proto` example. -- Start with the options already used in docs/examples: `(required)`, `(pattern)`, `(min)/(max)`, - `(distinct)`, `(validate)`. +- We don't need to repeat the documentation of the options available from + the source code of `spine/options.proto`. +- The option catalog should help navigate to the relevant options for a particular use case, + but it should not be a copy of the documentation of an option. +- If needed, we can have several pages under the "Built-in options" section, + but we should avoid having a separate page for each option. +- Pages that we can have: + - Field-level options (required, pattern, min/max, etc.) + - Options for `oneof` fields. + - Message-level options + - Options for `repeated` and `map` fields. +- Give the link to the `spine/options.proto` source code at GitHub where appropriate. + - https://github.com/SpineEventEngine/base-libraries/blob/master/base/src/main/proto/spine/options.proto + From 60f7ecea3e6a4c5068cc2f3f221c56ca81050ffe Mon Sep 17 00:00:00 2001 From: alexander-yevsyukov Date: Fri, 27 Feb 2026 19:46:12 +0000 Subject: [PATCH 04/15] Update the plan for "Built-in options" --- .agents/tasks/built-in-options-plan.md | 89 +++++++++++++++++++++----- 1 file changed, 73 insertions(+), 16 deletions(-) diff --git a/.agents/tasks/built-in-options-plan.md b/.agents/tasks/built-in-options-plan.md index 2e9eab8c84..c45e25385e 100644 --- a/.agents/tasks/built-in-options-plan.md +++ b/.agents/tasks/built-in-options-plan.md @@ -1,18 +1,75 @@ # Task: Publish a reference set on built-in validation options -- Placement: a separate section coming after the "Concepts" section. -- From `docs/_options/options.proto`, - enumerate the built-in options and group them (fields, strings, numbers, collections, message-level). -- We don't need to repeat the documentation of the options available from - the source code of `spine/options.proto`. -- The option catalog should help navigate to the relevant options for a particular use case, - but it should not be a copy of the documentation of an option. -- If needed, we can have several pages under the "Built-in options" section, - but we should avoid having a separate page for each option. -- Pages that we can have: - - Field-level options (required, pattern, min/max, etc.) - - Options for `oneof` fields. - - Message-level options - - Options for `repeated` and `map` fields. -- Give the link to the `spine/options.proto` source code at GitHub where appropriate. - - https://github.com/SpineEventEngine/base-libraries/blob/master/base/src/main/proto/spine/options.proto +## Goal + +Publish an actionable catalog of built-in *validation-related* options, organized by where +the option can be declared (field, `oneof`, message), and optimized for selecting the right +option for a use case. + +## Placement and structure + +- Placement: the "Built-in options" section comes after the "Concepts" section. +- Structure: implement "Built-in options" as a folder with a landing page and 4 child pages + (not a single long page). +- Avoid having a separate page per option. + +Proposed doc files under `docs/content/docs/validation/03-built-in-options/`: + +- `docs/content/docs/validation/03-built-in-options/_index.md` (landing page) +- `docs/content/docs/validation/03-built-in-options/field-level-options.md` + - Title: "Field-level options" +- `docs/content/docs/validation/03-built-in-options/oneof-fields.md` + - Title: "Options for `oneof` fields" +- `docs/content/docs/validation/03-built-in-options/message-level-options.md` + - Title: "Message-level options" +- `docs/content/docs/validation/03-built-in-options/repeated-and-map-fields.md` + - Title: "Options for `repeated` and `map` fields" + +Order of pages: exactly as listed above. + +## Scope and source of truth + +- Source of truth for what exists: `docs/_options/options.proto`. +- Scope: validation-related options only. + - Exclude non-validation options (API annotations, entity metadata, etc.). + - Exclude deprecated options (do not document them; do not add “deprecated catalogs”). +- Do not duplicate the full option documentation from `spine/options.proto`. + - Prefer short, “how to choose” descriptions, and link out for authoritative details. + +## Content principles (what each page should contain) + +Each page should: + +- Start with “When to use this page” and a small “Choose an option” list (use case → option). +- Group options by intent (presence, range, pattern, uniqueness, recursion, dependencies), + not by field number order. +- Include 1–2 minimal examples per group (copy-pasteable `.proto` snippets). +- Include “Applies to” and “Common combinations / gotchas” where the behavior is easy to + misunderstand (e.g., `(validate)` + default instances, uniqueness for collections, etc.). +- Link to `spine/options.proto` on GitHub when referencing the canonical definition. + +## What options to cover (high-level checklist) + +The catalog should cover (non-deprecated) validation-related options defined in +`docs/_options/options.proto`, including: + +- Field-level: + - Presence: `(required)`, `(if_missing)` + - Numeric constraints: `(min)`, `(max)`, `(range)` + - String/bytes constraints: `(pattern)` + - Nested validation: `(validate)` + - Cross-field dependency: `(goes)` + - Immutability: `(set_once)`, `(if_set_again)` + - Uniqueness for collections: `(distinct)`, `(if_has_duplicates)` +- `oneof`: + - Required selection: `(choice)` +- Message-level: + - Field-group requirements: `(require)` + +Note: keep this list aligned with `docs/_options/options.proto` and update it if the proto +changes. + +## External links + +- Link to canonical `spine/options.proto` where appropriate: + - https://github.com/SpineEventEngine/base-libraries/blob/master/base/src/main/proto/spine/options.proto From fecedfa704a23d96caee020787037bc289b317c1 Mon Sep 17 00:00:00 2001 From: alexander-yevsyukov Date: Fri, 27 Feb 2026 19:52:28 +0000 Subject: [PATCH 05/15] Update `_examples` ref. --- docs/_examples | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/_examples b/docs/_examples index 4d3727541f..57934013cb 160000 --- a/docs/_examples +++ b/docs/_examples @@ -1 +1 @@ -Subproject commit 4d3727541f0c4f771a6c1a215eef065cd3e74032 +Subproject commit 57934013cb7910c95f7926114d6c97c7be7329cd From c8204fe89f1bc816d52b62072a5782ceea1fe1ef Mon Sep 17 00:00:00 2001 From: alexander-yevsyukov Date: Fri, 27 Feb 2026 20:31:57 +0000 Subject: [PATCH 06/15] Add text for "Built-in options" section --- .../validation/03-built-in-options/_index.md | 40 +++- .../field-level-options.md | 189 ++++++++++++++++++ .../message-level-options.md | 54 +++++ .../03-built-in-options/oneof-fields.md | 53 +++++ .../repeated-and-map-fields.md | 115 +++++++++++ .../validation/2-0-0-snapshot/sidenav.yml | 13 +- 6 files changed, 462 insertions(+), 2 deletions(-) create mode 100644 docs/content/docs/validation/03-built-in-options/field-level-options.md create mode 100644 docs/content/docs/validation/03-built-in-options/message-level-options.md create mode 100644 docs/content/docs/validation/03-built-in-options/oneof-fields.md create mode 100644 docs/content/docs/validation/03-built-in-options/repeated-and-map-fields.md diff --git a/docs/content/docs/validation/03-built-in-options/_index.md b/docs/content/docs/validation/03-built-in-options/_index.md index 6e186d9a85..4ebd2a8b2b 100644 --- a/docs/content/docs/validation/03-built-in-options/_index.md +++ b/docs/content/docs/validation/03-built-in-options/_index.md @@ -6,7 +6,45 @@ headline: Documentation # Built-in options -## What’s next +{{% note-block class="lead" %}} +This section is a “how to choose” catalog of the **built-in validation options** +from `spine/options.proto`. + +It focuses on the options that affect **Spine Validation** and skips deprecated and +non-validation options. +{{% /note-block %}} + +## When to use this section + +Use this section when you want to: + +- pick the right option for a specific validation need, like presence, bounds, uniqueness, etc.; +- understand where an option can be declared (field, `oneof`, message); +- see minimal `.proto` snippets you can copy into a model. + +## Choose a page +- **Most field constraints** (presence, bounds, patterns, nested validation, dependencies): + [Field-level options](field-level-options.md) +- **Enforce “one of these fields must be set” in a `oneof`:** + [Options for `oneof` fields](oneof-fields.md) +- **Cross-field rules on a message (“at least one group is set”):** + [Message-level options](message-level-options.md) +- **Collections (`repeated` / `map`) — non-empty, uniqueness, per-element validation:** + [Options for `repeated` and `map` fields](repeated-and-map-fields.md) + +## Source of truth + +This catalog is based on the non-deprecated, validation-related options defined in +[spine/options.proto](https://github.com/SpineEventEngine/base-libraries/blob/master/base/src/main/proto/spine/options.proto). + +For the canonical option definitions, see `spine/options.proto` in the Spine base libraries +on GitHub: [spine/options.proto](https://github.com/SpineEventEngine/base-libraries/blob/master/base/src/main/proto/spine/options.proto). + +## What’s next +- [Field-level options](field-level-options.md) +- [Options for `oneof` fields](oneof-fields.md) +- [Message-level options](message-level-options.md) +- [Options for `repeated` and `map` fields](repeated-and-map-fields.md) - [Validating third-party messages](../04-third-party-messages/) - [Custom validation](../08-custom-validation/) diff --git a/docs/content/docs/validation/03-built-in-options/field-level-options.md b/docs/content/docs/validation/03-built-in-options/field-level-options.md new file mode 100644 index 0000000000..c67d3b112f --- /dev/null +++ b/docs/content/docs/validation/03-built-in-options/field-level-options.md @@ -0,0 +1,189 @@ +--- +title: Field-level options +description: How to choose built-in validation options applied to fields. +headline: Documentation +weight: 10 +--- + +# Field-level options + +{{% note-block class="lead" %}} +Use this page when you want to validate a **single field** by declaring options next to it in a +`.proto` file. +{{% /note-block %}} + +## Choose an option + +- Require a value to be present: `(required)`, customize with `(if_missing).error_msg` +- Enforce a numeric boundary: `(min)`, `(max)`, or `(range)` +- Enforce a string format: `(pattern).regex` +- Validate a nested message: `(validate) = true` +- Require another field when this one is set: `(goes).with = "other_field"` +- Prevent reassignment: `(set_once) = true`, customize with `(if_set_again).error_msg` + +For canonical definitions, see +[spine/options.proto](https://github.com/SpineEventEngine/base-libraries/blob/master/base/src/main/proto/spine/options.proto). + +## Presence: `(required)` and `(if_missing)` + +Use `(required)` when a field must not be “unset” for its type. + +**Applies to** + +- Message and enum fields (must be non-default). +- `string` / `bytes` fields (must be non-empty). +- Collections (`repeated` / `map`) (must be non-empty; see also + [Options for `repeated` and `map` fields](repeated-and-map-fields.md)). + +**Minimal example** + +```protobuf +import "spine/options.proto"; + +message UserEmail { + string value = 1 [(required) = true]; +} +``` + +**Custom message** + +```protobuf +import "spine/options.proto"; + +message Student { + string id = 1 [ + (required) = true, + (if_missing).error_msg = "Student ID must be set." + ]; +} +``` + +## Numeric constraints + +Use `(min)`, `(max)`, and `(range)` when a numeric value must fall within a bound. + +**Applies to** + +- Singular numeric fields. +- `repeated` numeric fields — each element is checked. + +### Choose between `(min)` / `(max)` and `(range)` + +- Use `(min)` / `(max)` for **unbounded** ranges (for example, “`>= 0`”). +- Use `(range)` for a **bounded** interval in one option. + +**Minimal example** + +```protobuf +import "spine/options.proto"; + +message Temperature { + int32 kelvin = 1 [(min).value = "0"]; +} +``` + +**Bounded range** + +```protobuf +import "spine/options.proto"; + +message Percent { + int32 value = 1 [(range).value = "[0..100]"]; +} +``` + +## Patterns: `(pattern)` + +Use `(pattern).regex` when a `string` must match a regular expression. + +**Applies to** + +- Singular `string` fields. +- `repeated string` fields — each element is checked. + +**Minimal example** + +```protobuf +import "spine/options.proto"; + +message OrderId { + string value = 1 [(pattern).regex = "^[A-Z]{3}-\\d{6}$"]; +} +``` + +## Nested validation: `(validate)` + +Use `(validate) = true` when a field refers to another **message type** and you want to enforce +the nested message’s own constraints. + +**Applies to** + +- Singular message fields. +- Repeated fields of message type. +- Map fields with message values. + +**Common gotcha: default instances** + +For **singular** message fields, default instances are treated like “no value set”, even when +`(validate) = true`. If you want to reject default instances, make the field required. + +```protobuf +import "spine/options.proto"; + +message Address { + string value = 1 [(required) = true]; +} + +message Student { + Address address = 1 [(validate) = true, (required) = true]; +} +``` + +## Cross-field dependency: `(goes)` + +Use `(goes).with = "companion"` when this field is only valid if another field is also set. + +**Applies to** + +- Message and enum fields. +- `string` / `bytes` fields. +- Collections (`repeated` / `map`). + +**Minimal example** + +```protobuf +import "spine/options.proto"; + +message ScheduledItem { + string date = 1; + string time = 2 [(goes).with = "date"]; +} +``` + +## Single assignment: `(set_once)` and `(if_set_again)` + +Use `(set_once) = true` when a field must be assigned at most once, for example, a permanent ID. + +**Applies to** + +- Singular fields of supported scalar, enum, and message types. + +**Does not apply to** + +- `repeated` / `map` fields. +- Fields with explicit `optional` cardinality. + +**Minimal example** + +```protobuf +import "spine/options.proto"; + +message UserId { + string value = 1 [(required) = true]; +} + +message User { + UserId id = 1 [(set_once) = true]; +} +``` + diff --git a/docs/content/docs/validation/03-built-in-options/message-level-options.md b/docs/content/docs/validation/03-built-in-options/message-level-options.md new file mode 100644 index 0000000000..5a01343e4d --- /dev/null +++ b/docs/content/docs/validation/03-built-in-options/message-level-options.md @@ -0,0 +1,54 @@ +--- +title: Message-level options +description: How to express validation rules that depend on multiple fields. +headline: Documentation +weight: 30 +--- + +# Message-level options + +{{% note-block class="lead" %}} +Use this page when message validity depends on **multiple fields together**, such as: + +- “At least one of these fields must be set.” +- “Either this group of fields is set, or that group is set.” +{{% /note-block %}} + + +For canonical definitions, see +[spine/options.proto](https://github.com/SpineEventEngine/base-libraries/blob/master/base/src/main/proto/spine/options.proto). + +## Field group requirements: `(require)` + +Use `option (require).fields` on a message to declare **alternative groups** of required fields. + +**How to write the expression** + +- Use `|` to separate alternative groups. +- Use `&` inside a group to require multiple fields together. +- You can use `oneof` group names as operands (useful together with `(choice)`). + +**Applies to** + +- Message types (declared as a message option). + +**Minimal example** + +```protobuf +import "spine/options.proto"; + +message PersonName { + option (require).fields = "given_name | honorific_prefix & family_name"; + + string honorific_prefix = 1; + string given_name = 2; + string family_name = 3; +} +``` + +## Common gotchas + +- This option works only with field types where “set” is well-defined: messages/enums + (non-default), `string`/`bytes` (non-empty), and collections (non-empty). If you need a similar + rule for scalars, wrap the scalar into a message or use a `oneof`. + diff --git a/docs/content/docs/validation/03-built-in-options/oneof-fields.md b/docs/content/docs/validation/03-built-in-options/oneof-fields.md new file mode 100644 index 0000000000..119db8b017 --- /dev/null +++ b/docs/content/docs/validation/03-built-in-options/oneof-fields.md @@ -0,0 +1,53 @@ +--- +title: Options for `oneof` fields +description: How to enforce selection rules for `oneof` groups. +headline: Documentation +weight: 20 +--- + +# Options for `oneof` fields + +{{% note-block class="lead" %}} +Use this page when you have a `oneof` group and want to enforce that **one of its cases is set**. +{{% /note-block %}} + +## Choose an option + +- Require a `oneof` group to have a value: `(choice).required = true` + +For canonical definitions, see +[spine/options.proto](https://github.com/SpineEventEngine/base-libraries/blob/master/base/src/main/proto/spine/options.proto). + +## Required selection + +### `(choice)` + +Use `(choice).required = true` on a `oneof` group to require selecting one of its fields. + +**Applies to** + +- `oneof` groups (declared on the `oneof` itself, not on a field inside it). + +**Minimal example** + +```protobuf +import "spine/options.proto"; + +message Contact { + oneof channel { + option (choice).required = true; + + string email = 1; + string phone = 2; + } +} +``` + +## Common combinations / gotchas + +- Use `(choice)` for the group, and apply field-level constraints (like `(pattern)` or + `(required)`) to individual cases when needed. +- If the requirement is “at least one of these fields OR one of these other fields”, use + [Message-level options](message-level-options.md) with `(require).fields` and include `oneof` + group names. + diff --git a/docs/content/docs/validation/03-built-in-options/repeated-and-map-fields.md b/docs/content/docs/validation/03-built-in-options/repeated-and-map-fields.md new file mode 100644 index 0000000000..ec6ad72141 --- /dev/null +++ b/docs/content/docs/validation/03-built-in-options/repeated-and-map-fields.md @@ -0,0 +1,115 @@ +--- +title: Options for `repeated` and `map` fields +description: How to choose built-in validation options for collections. +headline: Documentation +weight: 40 +--- + +# Options for `repeated` and `map` fields + +{{% note-block class="lead" %}} +Use this page when you want to validate **collections** declared as `repeated` fields +or `map` fields. +{{% /note-block %}} + +## Choose an option + +- Require a collection to be non-empty: `(required) = true` +- Enforce uniqueness: `(distinct) = true`, customize with `(if_has_duplicates).error_msg` +- Validate nested message elements/values: `(validate) = true` +- Enforce numeric constraints per element: `(min)`, `(max)`, `(range)` +- Enforce a pattern per element: `(pattern).regex` +- Require a companion field when the collection is present: `(goes).with = "other_field"` + +For canonical definitions, see +[spine/options.proto](https://github.com/SpineEventEngine/base-libraries/blob/master/base/src/main/proto/spine/options.proto). + +## Presence: `(required)` + +Use `(required) = true` when a `repeated` field or a `map` must contain **at least one element**. + +```protobuf +import "spine/options.proto"; + +message Team { + repeated string members = 1 [(required) = true]; +} +``` + +## Uniqueness: `(distinct)` and `(if_has_duplicates)` + +Use `(distinct) = true` when all elements in a collection must be unique. + +**Applies to** + +- `repeated` fields — elements must be unique. +- `map` fields — values must be unique; keys are already unique by Protobuf rules. + +**Minimal example** + +```protobuf +import "spine/options.proto"; + +message Labels { + repeated string value = 1 [(distinct) = true]; +} +``` + +**Map values** + +```protobuf +import "spine/options.proto"; + +message Emails { + map by_type = 1 [(distinct) = true]; +} +``` + +**Common gotcha** + +Uniqueness is checked by full element equality, for example, `equals()` in Java. +If you need “unique by ID”, model the ID as the element itself, or use a `map` keyed by the ID. + +## Nested validation: `(validate)` for elements and map values + +Use `(validate) = true` when collection elements (or map values) are messages and must satisfy +their own constraints. + +```protobuf +import "spine/options.proto"; + +message PhoneNumber { + string value = 1 [(required) = true, (pattern).regex = "^\\+?[0-9\\s\\-()]{1,30}$"]; +} + +message ContactBook { + repeated PhoneNumber number = 1 [(validate) = true]; +} +``` + +## Per-element value constraints + +### Numeric options: `(min)`, `(max)`, `(range)` + +Use numeric constraints on `repeated` numeric fields to validate each element. + +```protobuf +import "spine/options.proto"; + +message Measurements { + repeated int32 sample = 1 [(min).value = "0", (max).value = "100"]; +} +``` + +### String patterns: `(pattern)` + +Use `(pattern)` on `repeated string` fields to validate each element. + +```protobuf +import "spine/options.proto"; + +message Tags { + repeated string value = 1 [(pattern).regex = "^[a-z0-9-]{1,32}$"]; +} +``` + diff --git a/docs/data/docs/validation/2-0-0-snapshot/sidenav.yml b/docs/data/docs/validation/2-0-0-snapshot/sidenav.yml index 907ffec735..6c910b386a 100644 --- a/docs/data/docs/validation/2-0-0-snapshot/sidenav.yml +++ b/docs/data/docs/validation/2-0-0-snapshot/sidenav.yml @@ -36,7 +36,18 @@ - page: Working with error messages file_path: 02-concepts/error-messages - page: Built-in options - file_path: 03-built-in-options + key: 03-built-in-options + children: + - page: Built-in options + file_path: 03-built-in-options + - page: Field-level options + file_path: 03-built-in-options/field-level-options + - page: "Options for `oneof` fields" + file_path: 03-built-in-options/oneof-fields + - page: Message-level options + file_path: 03-built-in-options/message-level-options + - page: "Options for `repeated` and `map` fields" + file_path: 03-built-in-options/repeated-and-map-fields - page: Validating third-party messages file_path: 04-third-party-messages - page: Custom validation From b3e5ff6d63e21151a83c5583d6bc6d5468f0e7a6 Mon Sep 17 00:00:00 2001 From: alexander-yevsyukov Date: Fri, 27 Feb 2026 20:32:57 +0000 Subject: [PATCH 07/15] Makr "Built-in options" section done --- .agents/tasks/{ => archive}/built-in-options-plan.md | 0 .agents/tasks/validation-documentation-plan.md | 1 + 2 files changed, 1 insertion(+) rename .agents/tasks/{ => archive}/built-in-options-plan.md (100%) diff --git a/.agents/tasks/built-in-options-plan.md b/.agents/tasks/archive/built-in-options-plan.md similarity index 100% rename from .agents/tasks/built-in-options-plan.md rename to .agents/tasks/archive/built-in-options-plan.md diff --git a/.agents/tasks/validation-documentation-plan.md b/.agents/tasks/validation-documentation-plan.md index 8152490abd..b84615806f 100644 --- a/.agents/tasks/validation-documentation-plan.md +++ b/.agents/tasks/validation-documentation-plan.md @@ -50,6 +50,7 @@ buildable documentation set, without expanding scope unnecessarily. - Status: DONE (2026-02-27). 5) [Built-in options](built-in-options-plan.md): publish a minimal reference set +- Status: DONE (2026-02-27). 6) [Validating third-party messages](third-party-messages-plan.md) From e5e2b6586ed14f0089092c3a7599954b360b7b0b Mon Sep 17 00:00:00 2001 From: alexander-yevsyukov Date: Fri, 27 Feb 2026 20:35:54 +0000 Subject: [PATCH 08/15] Update dependency reports --- dependencies.md | 60 ++++++++++++++++++++++++------------------------- pom.xml | 2 +- 2 files changed, 31 insertions(+), 31 deletions(-) diff --git a/dependencies.md b/dependencies.md index 7ce35d6304..93172c0ca6 100644 --- a/dependencies.md +++ b/dependencies.md @@ -1,6 +1,6 @@ -# Dependencies of `io.spine.tools:validation-context:2.0.0-SNAPSHOT.399` +# Dependencies of `io.spine.tools:validation-context:2.0.0-SNAPSHOT.400` ## Runtime 1. **Group** : com.fasterxml.jackson. **Name** : jackson-bom. **Version** : 2.20.0. @@ -1139,14 +1139,14 @@ The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Thu Feb 26 22:11:03 WET 2026** using +This report was generated on **Fri Feb 27 20:33:13 WET 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). -# Dependencies of `io.spine.tools:validation-context-tests:2.0.0-SNAPSHOT.399` +# Dependencies of `io.spine.tools:validation-context-tests:2.0.0-SNAPSHOT.400` ## Runtime 1. **Group** : com.fasterxml.jackson. **Name** : jackson-bom. **Version** : 2.20.0. @@ -1731,7 +1731,7 @@ This report was generated on **Thu Feb 26 22:11:03 WET 2026** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Thu Feb 26 22:11:02 WET 2026** using +This report was generated on **Fri Feb 27 20:33:12 WET 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). @@ -1752,7 +1752,7 @@ This report was generated on **Mon Feb 23 18:35:33 WET 2026** using -# Dependencies of `io.spine.tools:validation-gradle-plugin:2.0.0-SNAPSHOT.399` +# Dependencies of `io.spine.tools:validation-gradle-plugin:2.0.0-SNAPSHOT.400` ## Runtime 1. **Group** : com.fasterxml.jackson. **Name** : jackson-bom. **Version** : 2.20.0. @@ -2841,14 +2841,14 @@ This report was generated on **Mon Feb 23 18:35:33 WET 2026** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Thu Feb 26 22:11:03 WET 2026** using +This report was generated on **Fri Feb 27 20:33:13 WET 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). -# Dependencies of `io.spine.tools:validation-java:2.0.0-SNAPSHOT.399` +# Dependencies of `io.spine.tools:validation-java:2.0.0-SNAPSHOT.400` ## Runtime 1. **Group** : com.fasterxml.jackson. **Name** : jackson-bom. **Version** : 2.20.0. @@ -3935,14 +3935,14 @@ This report was generated on **Thu Feb 26 22:11:03 WET 2026** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Thu Feb 26 22:11:03 WET 2026** using +This report was generated on **Fri Feb 27 20:33:13 WET 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). -# Dependencies of `io.spine.tools:validation-java-bundle:2.0.0-SNAPSHOT.399` +# Dependencies of `io.spine.tools:validation-java-bundle:2.0.0-SNAPSHOT.400` ## Runtime 1. **Group** : com.google.auto.service. **Name** : auto-service-annotations. **Version** : 1.1.1. @@ -4005,14 +4005,14 @@ This report was generated on **Thu Feb 26 22:11:03 WET 2026** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Thu Feb 26 22:11:01 WET 2026** using +This report was generated on **Fri Feb 27 20:33:11 WET 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). -# Dependencies of `io.spine:validation-jvm-runtime:2.0.0-SNAPSHOT.399` +# Dependencies of `io.spine:validation-jvm-runtime:2.0.0-SNAPSHOT.400` ## Runtime 1. **Group** : com.google.code.findbugs. **Name** : jsr305. **Version** : 3.0.2. @@ -4845,14 +4845,14 @@ This report was generated on **Thu Feb 26 22:11:01 WET 2026** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Thu Feb 26 22:11:03 WET 2026** using +This report was generated on **Fri Feb 27 20:33:13 WET 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). -# Dependencies of `io.spine.tools:validation-ksp:2.0.0-SNAPSHOT.399` +# Dependencies of `io.spine.tools:validation-ksp:2.0.0-SNAPSHOT.400` ## Runtime 1. **Group** : com.google.auto.service. **Name** : auto-service-annotations. **Version** : 1.1.1. @@ -5781,14 +5781,14 @@ This report was generated on **Thu Feb 26 22:11:03 WET 2026** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Thu Feb 26 22:11:03 WET 2026** using +This report was generated on **Fri Feb 27 20:33:13 WET 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). -# Dependencies of `io.spine.tools:validation-consumer:2.0.0-SNAPSHOT.399` +# Dependencies of `io.spine.tools:validation-consumer:2.0.0-SNAPSHOT.400` ## Runtime 1. **Group** : com.fasterxml.jackson. **Name** : jackson-bom. **Version** : 2.20.0. @@ -6379,14 +6379,14 @@ This report was generated on **Thu Feb 26 22:11:03 WET 2026** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Thu Feb 26 22:11:01 WET 2026** using +This report was generated on **Fri Feb 27 20:33:12 WET 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). -# Dependencies of `io.spine.tools:validation-consumer-dependency:2.0.0-SNAPSHOT.399` +# Dependencies of `io.spine.tools:validation-consumer-dependency:2.0.0-SNAPSHOT.400` ## Runtime 1. **Group** : com.google.code.findbugs. **Name** : jsr305. **Version** : 3.0.2. @@ -6897,14 +6897,14 @@ This report was generated on **Thu Feb 26 22:11:01 WET 2026** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Thu Feb 26 22:11:03 WET 2026** using +This report was generated on **Fri Feb 27 20:33:13 WET 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). -# Dependencies of `io.spine.tools:validation-extensions:2.0.0-SNAPSHOT.399` +# Dependencies of `io.spine.tools:validation-extensions:2.0.0-SNAPSHOT.400` ## Runtime 1. **Group** : com.fasterxml.jackson. **Name** : jackson-bom. **Version** : 2.20.0. @@ -7588,14 +7588,14 @@ This report was generated on **Thu Feb 26 22:11:03 WET 2026** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Thu Feb 26 22:11:03 WET 2026** using +This report was generated on **Fri Feb 27 20:33:12 WET 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). -# Dependencies of `io.spine.tools:validation-runtime:2.0.0-SNAPSHOT.399` +# Dependencies of `io.spine.tools:validation-runtime:2.0.0-SNAPSHOT.400` ## Runtime 1. **Group** : com.google.code.findbugs. **Name** : jsr305. **Version** : 3.0.2. @@ -8217,14 +8217,14 @@ This report was generated on **Thu Feb 26 22:11:03 WET 2026** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Thu Feb 26 22:11:03 WET 2026** using +This report was generated on **Fri Feb 27 20:33:13 WET 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). -# Dependencies of `io.spine.tools:validation-validating:2.0.0-SNAPSHOT.399` +# Dependencies of `io.spine.tools:validation-validating:2.0.0-SNAPSHOT.400` ## Runtime 1. **Group** : com.google.code.findbugs. **Name** : jsr305. **Version** : 3.0.2. @@ -8889,14 +8889,14 @@ This report was generated on **Thu Feb 26 22:11:03 WET 2026** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Thu Feb 26 22:11:03 WET 2026** using +This report was generated on **Fri Feb 27 20:33:13 WET 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). -# Dependencies of `io.spine.tools:validation-validator:2.0.0-SNAPSHOT.399` +# Dependencies of `io.spine.tools:validation-validator:2.0.0-SNAPSHOT.400` ## Runtime 1. **Group** : com.fasterxml.jackson. **Name** : jackson-bom. **Version** : 2.20.0. @@ -9647,14 +9647,14 @@ This report was generated on **Thu Feb 26 22:11:03 WET 2026** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Thu Feb 26 22:11:02 WET 2026** using +This report was generated on **Fri Feb 27 20:33:12 WET 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). -# Dependencies of `io.spine.tools:validation-validator-dependency:2.0.0-SNAPSHOT.399` +# Dependencies of `io.spine.tools:validation-validator-dependency:2.0.0-SNAPSHOT.400` ## Runtime 1. **Group** : com.google.code.findbugs. **Name** : jsr305. **Version** : 3.0.2. @@ -9924,14 +9924,14 @@ This report was generated on **Thu Feb 26 22:11:02 WET 2026** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Thu Feb 26 22:11:02 WET 2026** using +This report was generated on **Fri Feb 27 20:33:12 WET 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). -# Dependencies of `io.spine.tools:validation-vanilla:2.0.0-SNAPSHOT.399` +# Dependencies of `io.spine.tools:validation-vanilla:2.0.0-SNAPSHOT.400` ## Runtime 1. **Group** : com.google.code.findbugs. **Name** : jsr305. **Version** : 3.0.2. @@ -10282,6 +10282,6 @@ This report was generated on **Thu Feb 26 22:11:02 WET 2026** using The dependencies distributed under several licenses, are used according their commercial-use-friendly license. -This report was generated on **Thu Feb 26 22:11:01 WET 2026** using +This report was generated on **Fri Feb 27 20:33:12 WET 2026** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE). \ No newline at end of file diff --git a/pom.xml b/pom.xml index ed86aa7649..84c66423bc 100644 --- a/pom.xml +++ b/pom.xml @@ -10,7 +10,7 @@ all modules and does not describe the project structure per-subproject. --> io.spine.tools validation -2.0.0-SNAPSHOT.399 +2.0.0-SNAPSHOT.400 2015 From da8ae13a493f93ad11ebc1d510d3fa92e57377d1 Mon Sep 17 00:00:00 2001 From: alexander-yevsyukov Date: Fri, 27 Feb 2026 20:54:20 +0000 Subject: [PATCH 09/15] Update Validation version --- .../docs/validation/01-getting-started/adding-to-build.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/content/docs/validation/01-getting-started/adding-to-build.md b/docs/content/docs/validation/01-getting-started/adding-to-build.md index 8a3026ca63..06205c6dea 100644 --- a/docs/content/docs/validation/01-getting-started/adding-to-build.md +++ b/docs/content/docs/validation/01-getting-started/adding-to-build.md @@ -82,7 +82,7 @@ Add the Validation plugin to the build. ```kotlin plugins { module - id("io.spine.validation") version "2.0.0-SNAPSHOT.399" + id("io.spine.validation") version "2.0.0-SNAPSHOT.400" } ``` From 5f875f2a7b784fe8d765d067819a17a223ab4dd1 Mon Sep 17 00:00:00 2001 From: alexander-yevsyukov Date: Fri, 27 Feb 2026 20:56:30 +0000 Subject: [PATCH 10/15] Avoid braces in the text --- docs/content/docs/validation/03-built-in-options/_index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/content/docs/validation/03-built-in-options/_index.md b/docs/content/docs/validation/03-built-in-options/_index.md index 4ebd2a8b2b..0559f82d32 100644 --- a/docs/content/docs/validation/03-built-in-options/_index.md +++ b/docs/content/docs/validation/03-built-in-options/_index.md @@ -24,7 +24,7 @@ Use this section when you want to: ## Choose a page -- **Most field constraints** (presence, bounds, patterns, nested validation, dependencies): +- **Most field constraints** — presence, bounds, patterns, nested validation, dependencies: [Field-level options](field-level-options.md) - **Enforce “one of these fields must be set” in a `oneof`:** [Options for `oneof` fields](oneof-fields.md) From 70bdd1e4e44097dcb167b0943aea4fad2cd6d1cb Mon Sep 17 00:00:00 2001 From: alexander-yevsyukov Date: Mon, 2 Mar 2026 15:18:54 +0000 Subject: [PATCH 11/15] Remove extra empty lines --- .../docs/validation/03-built-in-options/field-level-options.md | 1 - .../docs/validation/03-built-in-options/message-level-options.md | 1 - docs/content/docs/validation/03-built-in-options/oneof-fields.md | 1 - .../validation/03-built-in-options/repeated-and-map-fields.md | 1 - 4 files changed, 4 deletions(-) diff --git a/docs/content/docs/validation/03-built-in-options/field-level-options.md b/docs/content/docs/validation/03-built-in-options/field-level-options.md index c67d3b112f..8e10e20fd4 100644 --- a/docs/content/docs/validation/03-built-in-options/field-level-options.md +++ b/docs/content/docs/validation/03-built-in-options/field-level-options.md @@ -186,4 +186,3 @@ message User { UserId id = 1 [(set_once) = true]; } ``` - diff --git a/docs/content/docs/validation/03-built-in-options/message-level-options.md b/docs/content/docs/validation/03-built-in-options/message-level-options.md index 5a01343e4d..4af6b76512 100644 --- a/docs/content/docs/validation/03-built-in-options/message-level-options.md +++ b/docs/content/docs/validation/03-built-in-options/message-level-options.md @@ -51,4 +51,3 @@ message PersonName { - This option works only with field types where “set” is well-defined: messages/enums (non-default), `string`/`bytes` (non-empty), and collections (non-empty). If you need a similar rule for scalars, wrap the scalar into a message or use a `oneof`. - diff --git a/docs/content/docs/validation/03-built-in-options/oneof-fields.md b/docs/content/docs/validation/03-built-in-options/oneof-fields.md index 119db8b017..be6f3711d6 100644 --- a/docs/content/docs/validation/03-built-in-options/oneof-fields.md +++ b/docs/content/docs/validation/03-built-in-options/oneof-fields.md @@ -50,4 +50,3 @@ message Contact { - If the requirement is “at least one of these fields OR one of these other fields”, use [Message-level options](message-level-options.md) with `(require).fields` and include `oneof` group names. - diff --git a/docs/content/docs/validation/03-built-in-options/repeated-and-map-fields.md b/docs/content/docs/validation/03-built-in-options/repeated-and-map-fields.md index ec6ad72141..9ac6442b4b 100644 --- a/docs/content/docs/validation/03-built-in-options/repeated-and-map-fields.md +++ b/docs/content/docs/validation/03-built-in-options/repeated-and-map-fields.md @@ -112,4 +112,3 @@ message Tags { repeated string value = 1 [(pattern).regex = "^[a-z0-9-]{1,32}$"]; } ``` - From f9ec80271d6cb8233a3e8b3a09c800332b54abd9 Mon Sep 17 00:00:00 2001 From: alexander-yevsyukov Date: Mon, 2 Mar 2026 15:21:22 +0000 Subject: [PATCH 12/15] Condense wording in `oneof-fields.md` --- .../docs/validation/03-built-in-options/oneof-fields.md | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/docs/content/docs/validation/03-built-in-options/oneof-fields.md b/docs/content/docs/validation/03-built-in-options/oneof-fields.md index be6f3711d6..57d7993e8c 100644 --- a/docs/content/docs/validation/03-built-in-options/oneof-fields.md +++ b/docs/content/docs/validation/03-built-in-options/oneof-fields.md @@ -11,16 +11,10 @@ weight: 20 Use this page when you have a `oneof` group and want to enforce that **one of its cases is set**. {{% /note-block %}} -## Choose an option - -- Require a `oneof` group to have a value: `(choice).required = true` - For canonical definitions, see [spine/options.proto](https://github.com/SpineEventEngine/base-libraries/blob/master/base/src/main/proto/spine/options.proto). -## Required selection - -### `(choice)` +## Required selection: `(choice)` Use `(choice).required = true` on a `oneof` group to require selecting one of its fields. From 6bfa7c1a595b48a3f352151c7eaae66434990923 Mon Sep 17 00:00:00 2001 From: alexander-yevsyukov Date: Mon, 2 Mar 2026 15:25:11 +0000 Subject: [PATCH 13/15] Link back to `oneof-fields.md` --- .../validation/03-built-in-options/message-level-options.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/content/docs/validation/03-built-in-options/message-level-options.md b/docs/content/docs/validation/03-built-in-options/message-level-options.md index 4af6b76512..142371ebe6 100644 --- a/docs/content/docs/validation/03-built-in-options/message-level-options.md +++ b/docs/content/docs/validation/03-built-in-options/message-level-options.md @@ -26,7 +26,8 @@ Use `option (require).fields` on a message to declare **alternative groups** of - Use `|` to separate alternative groups. - Use `&` inside a group to require multiple fields together. -- You can use `oneof` group names as operands (useful together with `(choice)`). +- You can use `oneof` group names as operands in combination with + the [`(choice)`](oneof-fields.md) option. **Applies to** From 85e9c86c0c50d552bf8491793d0356c010945d64 Mon Sep 17 00:00:00 2001 From: alexander-yevsyukov Date: Mon, 2 Mar 2026 15:27:06 +0000 Subject: [PATCH 14/15] Improve wording in `field-level-options.md` --- .../docs/validation/03-built-in-options/field-level-options.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/docs/content/docs/validation/03-built-in-options/field-level-options.md b/docs/content/docs/validation/03-built-in-options/field-level-options.md index 8e10e20fd4..bbeb8f4e37 100644 --- a/docs/content/docs/validation/03-built-in-options/field-level-options.md +++ b/docs/content/docs/validation/03-built-in-options/field-level-options.md @@ -8,8 +8,7 @@ weight: 10 # Field-level options {{% note-block class="lead" %}} -Use this page when you want to validate a **single field** by declaring options next to it in a -`.proto` file. +Use this page when you want to validate a field by declaring options next to it in a`.proto` file. {{% /note-block %}} ## Choose an option From 738b7bc293e5d78f052bc9cf202020a3e05dfb39 Mon Sep 17 00:00:00 2001 From: alexander-yevsyukov Date: Mon, 2 Mar 2026 15:28:05 +0000 Subject: [PATCH 15/15] Add missing space --- .../docs/validation/03-built-in-options/field-level-options.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/content/docs/validation/03-built-in-options/field-level-options.md b/docs/content/docs/validation/03-built-in-options/field-level-options.md index bbeb8f4e37..8fe8703497 100644 --- a/docs/content/docs/validation/03-built-in-options/field-level-options.md +++ b/docs/content/docs/validation/03-built-in-options/field-level-options.md @@ -8,7 +8,7 @@ weight: 10 # Field-level options {{% note-block class="lead" %}} -Use this page when you want to validate a field by declaring options next to it in a`.proto` file. +Use this page when you want to validate a field by declaring options next to it in a `.proto` file. {{% /note-block %}} ## Choose an option