Skip to content

Commit

Permalink
Show file tree
Hide file tree
Showing 18 changed files with 1,285 additions and 79 deletions.
8 changes: 8 additions & 0 deletions .chronus/changes/examples-2024-5-12-22-55-41.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
# Change versionKind to one of: internal, fix, dependencies, feature, deprecation, breaking
changeKind: feature
packages:
- "@typespec/openapi3"
---

Add support for new `@example` and `@opExample` decorator
43 changes: 43 additions & 0 deletions .chronus/changes/examples-2024-5-14-18-46-26.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
---
# Change versionKind to one of: internal, fix, dependencies, feature, deprecation, breaking
changeKind: feature
packages:
- "@typespec/compiler"
---

Add new `@example` and `@opExample` decorator to provide examples on types and operations.

```tsp
@example(#{
id: "some",
date: utcDateTime.fromISO("2020-01-01T00:00:00Z"),
timeout: duration.fromISO("PT1M"),
})
model Foo {
id: string;
date: utcDateTime;
@encode("seconds", int32) timeout: duration;
}
```

```tsp
@opExample(
#{
parameters: #{
pet: #{
id: "some",
name: "Fluffy",
dob: plainDate.fromISO("2020-01-01"),
},
},
returnType: #{
id: "some",
name: "Fluffy",
dob: plainDate.fromISO("2020-01-01"),
},
},
#{ title: "First", description: "Show creating a pet" }
)
op createPet(pet: Pet): Pet;
```
28 changes: 28 additions & 0 deletions docs/standard-library/built-in-data-types.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,20 @@ model DefaultKeyVisibility<Source, Visibility>
#### Properties
None

### `ExampleOptions` {#ExampleOptions}

Options for example decorators
```typespec
model ExampleOptions
```


#### Properties
| Name | Type | Description |
|------|------|-------------|
| title? | [`string`](#string) | The title of the example |
| description? | [`string`](#string) | Description of the example |

### `object` {#object}

Represent a model
Expand Down Expand Up @@ -83,6 +97,20 @@ model OmitProperties<Source, Keys>
#### Properties
None

### `OperationExample` {#OperationExample}

Operation example configuration.
```typespec
model OperationExample
```


#### Properties
| Name | Type | Description |
|------|------|-------------|
| parameters? | `unknown` | Example request body. |
| returnType? | `unknown` | Example response body. |

### `OptionalProperties` {#OptionalProperties}

Represents a collection of optional properties.
Expand Down
53 changes: 53 additions & 0 deletions docs/standard-library/built-in-decorators.md
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,34 @@ op get(): Pet | NotFound;
```


### `@example` {#@example}

Provide an example value for a data type.
```typespec
@example(example: valueof unknown, options?: valueof ExampleOptions)
```

#### Target

`Model | Enum | Scalar | Union | ModelProperty | UnionVariant`

#### Parameters
| Name | Type | Description |
|------|------|-------------|
| example | `valueof unknown` | Example value. |
| options | [valueof `ExampleOptions`](./built-in-data-types.md#ExampleOptions) | Optional metadata for the example. |

#### Examples

```tsp
@example(#{name: "Fluffy", age: 2})
model Pet {
name: string;
age: int32;
}
```


### `@format` {#@format}

Specify a known data format hint for this string type. For example `uuid`, `uri`, etc.
Expand Down Expand Up @@ -570,6 +598,31 @@ scalar distance is float64;
```


### `@opExample` {#@opExample}

Provide example values for an operation's parameters and corresponding return type.
```typespec
@opExample(example: valueof OperationExample, options?: valueof ExampleOptions)
```

#### Target

`Operation`

#### Parameters
| Name | Type | Description |
|------|------|-------------|
| example | [valueof `OperationExample`](./built-in-data-types.md#OperationExample) | Example value. |
| options | [valueof `ExampleOptions`](./built-in-data-types.md#ExampleOptions) | Optional metadata for the example. |

#### Examples

```tsp
@example(#{parameters: #{name: "Fluffy", age: 2}, returnType: #{name: "Fluffy", age: 2, id: "abc"})
op createPet(pet: Pet): Pet;
```


### `@overload` {#@overload}

Specify this operation is an overload of the given operation.
Expand Down
40 changes: 40 additions & 0 deletions packages/compiler/generated-defs/TypeSpec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import type {
Scalar,
Type,
Union,
UnionVariant,
} from "../src/index.js";

/**
Expand Down Expand Up @@ -571,6 +572,45 @@ export type DiscriminatorDecorator = (
propertyName: string
) => void;

/**
* Provide an example value for a data type.
*
* @param example Example value.
* @param options Optional metadata for the example.
* @example
* ```tsp
* @example(#{name: "Fluffy", age: 2})
* model Pet {
* name: string;
* age: int32;
* }
* ```
*/
export type ExampleDecorator = (
context: DecoratorContext,
target: Model | Enum | Scalar | Union | ModelProperty | UnionVariant,
example: unknown,
options?: unknown
) => void;

/**
* Provide example values for an operation's parameters and corresponding return type.
*
* @param example Example value.
* @param options Optional metadata for the example.
* @example
* ```tsp
* @example(#{parameters: #{name: "Fluffy", age: 2}, returnType: #{name: "Fluffy", age: 2, id: "abc"})
* op createPet(pet: Pet): Pet;
* ```
*/
export type OpExampleDecorator = (
context: DecoratorContext,
target: Operation,
example: unknown,
options?: unknown
) => void;

/**
* Indicates that a property is only considered to be present or applicable ("visible") with
* the in the given named contexts ("visibilities"). When a property has no visibilities applied
Expand Down
8 changes: 8 additions & 0 deletions packages/compiler/generated-defs/TypeSpec.ts-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
$encodedName,
$error,
$errorsDoc,
$example,
$format,
$friendlyName,
$inspectType,
Expand All @@ -22,6 +23,7 @@ import {
$minLength,
$minValue,
$minValueExclusive,
$opExample,
$overload,
$parameterVisibility,
$pattern,
Expand Down Expand Up @@ -49,6 +51,7 @@ import type {
EncodedNameDecorator,
ErrorDecorator,
ErrorsDocDecorator,
ExampleDecorator,
FormatDecorator,
FriendlyNameDecorator,
InspectTypeDecorator,
Expand All @@ -64,6 +67,7 @@ import type {
MinLengthDecorator,
MinValueDecorator,
MinValueExclusiveDecorator,
OpExampleDecorator,
OverloadDecorator,
ParameterVisibilityDecorator,
PatternDecorator,
Expand Down Expand Up @@ -119,6 +123,8 @@ type Decorators = {
$projectedName: ProjectedNameDecorator;
$encodedName: EncodedNameDecorator;
$discriminator: DiscriminatorDecorator;
$example: ExampleDecorator;
$opExample: OpExampleDecorator;
$visibility: VisibilityDecorator;
$withVisibility: WithVisibilityDecorator;
$inspectType: InspectTypeDecorator;
Expand Down Expand Up @@ -163,6 +169,8 @@ const _: Decorators = {
$projectedName,
$encodedName,
$discriminator,
$example,
$opExample,
$visibility,
$withVisibility,
$inspectType,
Expand Down
60 changes: 60 additions & 0 deletions packages/compiler/lib/std/decorators.tsp
Original file line number Diff line number Diff line change
Expand Up @@ -500,6 +500,66 @@ extern dec encode(
encodedAs?: Scalar
);

/** Options for example decorators */
model ExampleOptions {
/** The title of the example */
title?: string;

/** Description of the example */
description?: string;
}

/**
* Provide an example value for a data type.
*
* @param example Example value.
* @param options Optional metadata for the example.
*
* @example
*
* ```tsp
* @example(#{name: "Fluffy", age: 2})
* model Pet {
* name: string;
* age: int32;
* }
* ```
*/
extern dec example(
target: Model | Enum | Scalar | Union | ModelProperty | UnionVariant,
example: valueof unknown,
options?: valueof ExampleOptions
);

/**
* Operation example configuration.
*/
model OperationExample {
/** Example request body. */
parameters?: unknown;

/** Example response body. */
returnType?: unknown;
}

/**
* Provide example values for an operation's parameters and corresponding return type.
*
* @param example Example value.
* @param options Optional metadata for the example.
*
* @example
*
* ```tsp
* @example(#{parameters: #{name: "Fluffy", age: 2}, returnType: #{name: "Fluffy", age: 2, id: "abc"})
* op createPet(pet: Pet): Pet;
* ```
*/
extern dec opExample(
target: Operation,
example: valueof OperationExample,
options?: valueof ExampleOptions
);
/**
* Indicates that a property is only considered to be present or applicable ("visible") with
* the in the given named contexts ("visibilities"). When a property has no visibilities applied
Expand Down
1 change: 1 addition & 0 deletions packages/compiler/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@
"prettier": "~3.3.2",
"prompts": "~2.4.2",
"semver": "^7.6.2",
"temporal-polyfill": "^0.2.5",
"vscode-languageserver": "~9.0.1",
"vscode-languageserver-textdocument": "~1.0.11",
"yaml": "~2.4.5",
Expand Down
Loading

0 comments on commit fef3f01

Please sign in to comment.