Skip to content

Commit d57cbd8

Browse files
authored
Update examples (#68)
1 parent 5b68a49 commit d57cbd8

File tree

7 files changed

+340
-283
lines changed

7 files changed

+340
-283
lines changed

packages/example/README.md

Lines changed: 24 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,10 @@
1-
# protovalidate example
1+
# Protovalidate examples
22

3-
This directory contains an example that uses protovalidate to validate a money
4-
transfer.
3+
This package contains examples for using `@bufbuild/protovalidate`.
54

6-
The transfer is defined as a Protobuf message in [money_transfer.proto](./proto/banking/v1/money_transfer.proto). It uses annotations to set up protovalidate rules on the message.
5+
### Requirements
76

8-
After generating code for the Protobuf message, it can be validated with
9-
`createValidator()` from `@bufbuild/protovalidate`. [src/index.ts](./src/index.ts)
10-
creates a money transfer, validates it, and prints the results on the terminal.
11-
12-
13-
### Run the example
14-
15-
You need [Node](https://nodejs.org/en/download/) version 20 or later installed. Download the example project
7+
You need [Node.js](https://nodejs.org/en/download/) version 20 or later installed. Download the example project
168
and install its dependencies:
179

1810
```shell
@@ -23,6 +15,10 @@ cd protovalidate-es-main/packages/example
2315
npm install
2416
```
2517

18+
### Basic example
19+
20+
This example shows basic usage. We're validating a money transfer, defined as a Protobuf message in [money_transfer.proto](./proto/banking/v1/money_transfer.proto).
21+
2622
Run the example:
2723

2824
```shell
@@ -33,20 +29,27 @@ This prints the following result:
3329

3430
> Transfer is valid!
3531
36-
Modify the transfer in [src/index.ts](./src/index.ts) and re-run the example to see different results.
37-
38-
39-
### Generate code
40-
41-
If you want to use the [Buf CLI](https://github.com/bufbuild/buf) to generate the code,
42-
simply run `npx buf generate` in this directory. [`buf.gen.yaml`](./buf.gen.yaml)
43-
contains the plugin configuration.
32+
Modify the transfer in [src/basic.ts](./src/index.ts) and re-run the example to see different results.
4433

4534

4635
### Valid types
4736

4837
Protovalidate rules can modify TypeScript types. A message field annotated with protovalidate's [`required` rule](https://buf.build/docs/reference/protovalidate/rules/field_rules/#required) becomes a required property.
4938

5039
See [order.proto](./proto/store/v1/order.proto) and [src/valid-types.ts](./src/valid-types.ts) for an example,
51-
and take a look at the [Valid types](https://github.com/bufbuild/protobuf-es/blob/v2.5.0/MANUAL.md#valid-types)
40+
and take a look at the [Valid types](https://github.com/bufbuild/protobuf-es/blob/v2.6.1/MANUAL.md#valid-types)
5241
section in the Protobuf-ES manual.
42+
43+
44+
### Standard Schema v1
45+
46+
Protovalidate-ES supports [Standard Schema v1](https://github.com/standard-schema/standard-schema). See [src/standard-schema](./src/standard-schema.ts) for an example.
47+
48+
49+
### Generate code
50+
51+
If you modify the rules of one of the Protobuf messages, make sure to re-generate the code.
52+
53+
With the [Buf CLI](https://github.com/bufbuild/buf), simply run `npx buf generate` in this directory. [`buf.gen.yaml`](./buf.gen.yaml)
54+
contains the plugin configuration.
55+

packages/example/buf.lock

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,5 @@
22
version: v2
33
deps:
44
- name: buf.build/bufbuild/protovalidate
5-
commit: 8976f5be98c146529b1cc15cd2012b60
6-
digest: b5:5d513af91a439d9e78cacac0c9455c7cb885a8737d30405d0b91974fe05276d19c07a876a51a107213a3d01b83ecc912996cdad4cddf7231f91379079cf7488d
5+
commit: 6c6e0d3c608e4549802254a2eee81bc8
6+
digest: b5:a7ca081f38656fc0f5aaa685cc111d3342876723851b47ca6b80cbb810cbb2380f8c444115c495ada58fa1f85eff44e68dc54a445761c195acdb5e8d9af675b6

packages/example/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
"private": true,
55
"license": "Apache-2.0",
66
"scripts": {
7-
"start": "tsx src/index.ts",
7+
"start": "tsx src/basic.ts",
88
"generate": "buf generate",
99
"postgenerate": "license-header src/gen",
1010
"build": "tsc --project tsconfig.json --outDir ./dist/esm",
File renamed without changes.

packages/example/src/gen/buf/validate/validate_pb.ts

Lines changed: 283 additions & 205 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/example/src/standard-schema.ts

Lines changed: 23 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -14,53 +14,41 @@
1414

1515
import { create } from "@bufbuild/protobuf";
1616
import { createStandardSchema } from "@bufbuild/protovalidate";
17-
import {
18-
OrderSchema,
19-
type OrderValid,
20-
type User,
21-
} from "./gen/store/v1/order_pb.js";
17+
import { OrderSchema, type OrderValid } from "./gen/store/v1/order_pb.js";
2218
import type { StandardSchemaV1 } from "@standard-schema/spec";
2319

24-
async function standardValidate<T extends StandardSchemaV1>(
25-
schema: T,
26-
input: StandardSchemaV1.InferInput<T>,
27-
): Promise<StandardSchemaV1.Result<StandardSchemaV1.InferOutput<T>>> {
28-
const result = schema["~standard"].validate(input);
29-
// Handle both sync and async results
30-
return Promise.resolve(result);
31-
}
32-
33-
const order = create(OrderSchema, {
34-
id: "ed1cb800-75cb-4e4c-95ab-e093a7f23e55",
35-
user: {
36-
// This field is required. Once validation passes, it will always be defined.
37-
name: "John Doe",
38-
},
39-
});
40-
4120
async function main() {
21+
const order = create(OrderSchema, {
22+
id: "ed1cb800-75cb-4e4c-95ab-e093a7f23e55",
23+
// The field `user` is required. Once validation passes, it will always be defined.
24+
// user: {
25+
// name: "John Doe",
26+
// },
27+
});
28+
4229
const schema = createStandardSchema(OrderSchema);
4330
const result = await standardValidate(schema, order);
4431

4532
if (result.issues !== undefined) {
46-
console.log(`invalid order ${result.issues}`);
47-
return;
33+
console.error(`invalid order: ${result.issues[0].message}`);
34+
process.exit(1);
4835
}
4936

5037
// If there are no issues, the result is valid.
51-
processOrder(result.value);
52-
}
53-
54-
main();
55-
56-
function processOrder(order: OrderValid) {
57-
console.log(`processing order ${order.id}`);
38+
const validOrder: OrderValid = result.value;
5839
// On the Valid type, the `user` property isn't optional, because
5940
// the field is annotated with the protovalidate required rule.
60-
setUserActive(order.user);
61-
return true;
41+
console.log(`user ${validOrder.user.name} has ordered something`);
6242
}
6343

64-
function setUserActive(user: User) {
65-
console.log(`user ${user.name} has ordered something`);
44+
void main();
45+
46+
// Placeholder for any framework that support the standard schema.
47+
async function standardValidate<T extends StandardSchemaV1>(
48+
schema: T,
49+
input: StandardSchemaV1.InferInput<T>,
50+
): Promise<StandardSchemaV1.Result<StandardSchemaV1.InferOutput<T>>> {
51+
const result = schema["~standard"].validate(input);
52+
// Handle both sync and async results
53+
return Promise.resolve(result);
6654
}

packages/example/src/valid-types.ts

Lines changed: 7 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -14,19 +14,16 @@
1414

1515
import { create } from "@bufbuild/protobuf";
1616
import { createValidator } from "@bufbuild/protovalidate";
17-
import {
18-
OrderSchema,
19-
type OrderValid,
20-
type User,
21-
} from "./gen/store/v1/order_pb";
17+
import { OrderSchema, type OrderValid } from "./gen/store/v1/order_pb";
2218

2319
const validator = createValidator({
24-
// This option enabled validation of the proto2 `required` label.
20+
// This option enables validation of the proto2 `required` label.
2521
legacyRequired: true,
2622
});
2723

2824
const order = create(OrderSchema, {
2925
id: "ed1cb800-75cb-4e4c-95ab-e093a7f23e55",
26+
// The field `user` is required. Once validation passes, it will always be defined.
3027
user: {
3128
name: "John Doe",
3229
},
@@ -36,20 +33,11 @@ const result = validator.validate(OrderSchema, order);
3633

3734
switch (result.kind) {
3835
case "valid":
39-
processOrder(result.message);
36+
const validOrder: OrderValid = result.message;
37+
// On the Valid type, the `user` property isn't optional, because
38+
// the field is annotated with the protovalidate required rule.
39+
console.log(`user ${validOrder.user.name} has ordered something`);
4040
break;
4141
default:
4242
throw result.error;
4343
}
44-
45-
function processOrder(order: OrderValid) {
46-
console.log(`processing order ${order.id}`);
47-
// On the Valid type, the `user` property isn't optional, because
48-
// the field is annotated with the protovalidate required rule.
49-
setUserActive(order.user);
50-
return true;
51-
}
52-
53-
function setUserActive(user: User) {
54-
console.log(`user ${user.name} has ordered something`);
55-
}

0 commit comments

Comments
 (0)