Resolve blank line added at the end of embedded code block (#936)
This commit is contained in:
Родитель
057c124720
Коммит
8a0b35d915
|
@ -144,7 +144,6 @@ namespace Example {
|
|||
@route("/message")
|
||||
op getMessage(): string;
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
You can compile it to OpenAPI 3.0 by using the following command:
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
{
|
||||
"changes": [
|
||||
{
|
||||
"packageName": "@cadl-lang/compiler",
|
||||
"comment": "Formatter: Cadl doesn't include blank line at the end of embeded markdown codeblock",
|
||||
"type": "patch"
|
||||
}
|
||||
],
|
||||
"packageName": "@cadl-lang/compiler"
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
{
|
||||
"changes": [
|
||||
{
|
||||
"packageName": "@cadl-lang/openapi",
|
||||
"comment": "",
|
||||
"type": "none"
|
||||
}
|
||||
],
|
||||
"packageName": "@cadl-lang/openapi"
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
{
|
||||
"changes": [
|
||||
{
|
||||
"packageName": "@cadl-lang/openapi3",
|
||||
"comment": "",
|
||||
"type": "none"
|
||||
}
|
||||
],
|
||||
"packageName": "@cadl-lang/openapi3"
|
||||
}
|
|
@ -58,7 +58,6 @@ enum Color {
|
|||
Blue: "blue",
|
||||
Green: "green",
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
Another is to use the union operation to define the enum values inline, e.g.:
|
||||
|
@ -94,7 +93,6 @@ namespace Pets {
|
|||
op create(@body pet: Pet): Pet; // uses path "/pets"
|
||||
op read(@path petId: int32): Pet; // uses path "/pets/{petId}"
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
## Path Item Object
|
||||
|
@ -245,7 +243,6 @@ model Snake {
|
|||
name: string;
|
||||
// snakes have no legs
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
Cadl also supports single inheritance of models with the `extends` keyword. This construct can be used to produce an `allOf` with a single element (the parent schema) in OpenAPI. For example:
|
||||
|
@ -262,7 +259,6 @@ model Cat extends Pet {
|
|||
model Dog extends Pet {
|
||||
bark: string;
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
Cadl does not current provide a means to produce an `allOf` with more than one element -- these are generally treated as "composition" in code generators and thus better represented in Cadl with the spread operator.
|
||||
|
@ -285,7 +281,6 @@ model PetId {
|
|||
namespace Pets {
|
||||
op read(...PetId): Pet | Error;
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
results in a `$ref` to the named parameter `PetId` in either `parameters` or `components.parameters`.
|
||||
|
@ -330,5 +325,4 @@ For example:
|
|||
namespace Pets {
|
||||
@extension("x-streaming-operation", true) op read(...PetId): Pet | Error;
|
||||
}
|
||||
|
||||
```
|
||||
|
|
|
@ -16,14 +16,12 @@ For example, the following used to define a request body of type `string`, but n
|
|||
|
||||
```cadl
|
||||
op create(body: string): void;
|
||||
|
||||
```
|
||||
|
||||
To get the previous behavior, the parameter now needs to be explicitly marked with `@body`:
|
||||
|
||||
```cadl
|
||||
op create(@body body: string): void;
|
||||
|
||||
```
|
||||
|
||||
## OkResponse is no longer a template
|
||||
|
@ -34,35 +32,30 @@ Since 200 is the default status code for non-empty bodies, you can usually repla
|
|||
|
||||
```cadl
|
||||
op get(id: string): OkResponse<Pet>;
|
||||
|
||||
```
|
||||
|
||||
Can be:
|
||||
|
||||
```cadl
|
||||
op get(id: string): Pet;
|
||||
|
||||
```
|
||||
|
||||
In certain situations where the body type is not (necessarily) a model, you will need to use the new `Body<T>` type. For example.
|
||||
|
||||
```cadl
|
||||
op list(): OkResponse<Pet[]>;
|
||||
|
||||
```
|
||||
|
||||
Can become:
|
||||
|
||||
```cadl
|
||||
op list(): OkResponse & Body<Pet[]>;
|
||||
|
||||
```
|
||||
|
||||
Since 200 status code is used by default, this could also be:
|
||||
|
||||
```cadl
|
||||
op list(): Pet[];
|
||||
|
||||
```
|
||||
|
||||
Generic models based on `OkResponse<T>` may also require `Body<T>`. For example:
|
||||
|
@ -72,7 +65,6 @@ model MyResponse<T> {
|
|||
...OkResponse<T>;
|
||||
@header example: string;
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
Since T is not constrainted to be a model, it might be an intrinsic type, an array, or the like, the template should be changed to use `Body<T>`:
|
||||
|
@ -83,7 +75,6 @@ model MyResponse<T> {
|
|||
...Body<T>;
|
||||
@header example: string;
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
In general, the prior `OkResponse<T>` is equivalent to `OkResponse & Body<T>` now or, equivalently, `{ ...OkResponse, ...Body<T> }`. In practice there are many situations where you can leave out OkResponse altogether and use plain `T` rather than `Body<T>`.
|
||||
|
@ -110,7 +101,6 @@ Resolving operation routes now follows the following logic:
|
|||
|
||||
```cadl
|
||||
op test(): void;
|
||||
|
||||
```
|
||||
|
||||
✅ Stay the same
|
||||
|
@ -125,7 +115,6 @@ op test(): void;
|
|||
namespace DemoService;
|
||||
|
||||
op test(): void;
|
||||
|
||||
```
|
||||
|
||||
⚠️ Output stays the same but add warning that no routes are emitted
|
||||
|
@ -141,7 +130,6 @@ namespace DemoService;
|
|||
|
||||
@route("/")
|
||||
op test(): void;
|
||||
|
||||
```
|
||||
|
||||
⚠️ Now the same as previous case, no routes emitted and emit warning
|
||||
|
@ -160,7 +148,6 @@ namespace DemoService;
|
|||
|
||||
@route("/")
|
||||
op test(): void;
|
||||
|
||||
```
|
||||
|
||||
#### Operation in service namespace
|
||||
|
@ -170,7 +157,6 @@ op test(): void;
|
|||
namespace Foo;
|
||||
|
||||
op test(): void;
|
||||
|
||||
```
|
||||
|
||||
✅ Stay the same
|
||||
|
@ -196,7 +182,6 @@ namespace MyLib {
|
|||
@route("my-lib")
|
||||
op test(): void;
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
⚠️ Other namespace routes are not included anymore
|
||||
|
@ -224,7 +209,6 @@ namespace Foo.MyLib {
|
|||
@route("my-lib")
|
||||
op test(): void;
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
## Remove Map type
|
||||
|
@ -237,7 +221,6 @@ namespace Foo.MyLib {
|
|||
model Foo {
|
||||
options: Map<string, string>;
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
#### Replace with `Record<T>`
|
||||
|
@ -246,7 +229,6 @@ model Foo {
|
|||
model Foo {
|
||||
options: Record<string>;
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
### Map using non-string key type
|
||||
|
@ -255,7 +237,6 @@ model Foo {
|
|||
model Foo {
|
||||
options: Map<int32, string>;
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
#### Replace with `object`
|
||||
|
@ -264,7 +245,6 @@ model Foo {
|
|||
model Foo {
|
||||
options: object;
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
## `@path` may not decorate optional properties or parameters without a default
|
||||
|
@ -278,7 +258,6 @@ model Foo {
|
|||
@path
|
||||
name?: string;
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
Was a bad practice, but was allowed in previous versions. This will now throw an error diagnostic.
|
||||
|
@ -290,7 +269,6 @@ model Foo {
|
|||
@path
|
||||
name: string;
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
### Resolve by adding a default value
|
||||
|
@ -300,5 +278,4 @@ model Foo {
|
|||
@path
|
||||
name?: string = "singleton";
|
||||
}
|
||||
|
||||
```
|
||||
|
|
|
@ -39,7 +39,6 @@ model Dog {
|
|||
favoriteToy?: string;
|
||||
bestTreat?: string = "chicken";
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
#### Built-in Models
|
||||
|
@ -95,7 +94,6 @@ model Dog {
|
|||
species: string;
|
||||
name: string;
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
#### Extends
|
||||
|
@ -108,7 +106,6 @@ model Animal {
|
|||
}
|
||||
|
||||
model Dog extends Animal {}
|
||||
|
||||
```
|
||||
|
||||
#### Is
|
||||
|
@ -128,7 +125,6 @@ model StringThing is Thing<string>;
|
|||
model StringThing {
|
||||
property: string;
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
### Enums
|
||||
|
@ -141,7 +137,6 @@ enum Color {
|
|||
Blue,
|
||||
Green,
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
In this case, we haven't specified how the constants will be represented, allowing for different choices in different scenarios. For example, the OpenAPI emitter will choose string values "Red", "Green", "Blue". Another protocol might prefer to assign incrementing numeric values 0, 1, 2.
|
||||
|
@ -159,7 +154,6 @@ enum Priority {
|
|||
High: 100,
|
||||
Low: 0,
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
#### Templates
|
||||
|
@ -175,7 +169,6 @@ model Page<T> {
|
|||
model DogPage {
|
||||
...Page<Dog>;
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
A template parameter can be given a default value with `= <value>`.
|
||||
|
@ -185,7 +178,6 @@ model Page<T = string> {
|
|||
size: number;
|
||||
item: T[];
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
#### Type Aliases
|
||||
|
@ -194,7 +186,6 @@ Sometimes it's convenient to alias a model template instantiation or type produc
|
|||
|
||||
```cadl
|
||||
alias DogPage = Page<Dog>;
|
||||
|
||||
```
|
||||
|
||||
Unlike `model`, `alias` does not create a new entity, and as such will not change generated code in any way. An alias merely describes a source code shorthand to avoid repeating the right-hand side in multiple places.
|
||||
|
@ -211,7 +202,6 @@ model BestDog {
|
|||
age: 14;
|
||||
best: true;
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
String literal types can also be created using the triple-quote syntax which enables multi-line strings:
|
||||
|
@ -224,7 +214,6 @@ model Dog {
|
|||
And so on
|
||||
""";
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
### Type Operators
|
||||
|
@ -237,7 +226,6 @@ Unions describe a type that must be exactly one of the union's constituents. Cre
|
|||
|
||||
```cadl
|
||||
alias GoodBreed = Beagle | GermanShepherd | GoldenRetriever;
|
||||
|
||||
```
|
||||
|
||||
##### Named unions
|
||||
|
@ -250,7 +238,6 @@ union GoodBreed {
|
|||
shepherd: GermanShepherd,
|
||||
retriever: GoldenRetriever,
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
The above example is equivalent to the `GoodBreed` alias above, except that emitters can actually see `GoodBreed` as a named entity and also see the `beagle`, `shepherd`, and `retriever` names for the options. It also becomes possible to apply [decorators](#Decorators) to each of the options when using this form.
|
||||
|
@ -261,7 +248,6 @@ Intersections describe a type that must include all the intersection's constitue
|
|||
|
||||
```cadl
|
||||
alias Dog = Animal & Pet;
|
||||
|
||||
```
|
||||
|
||||
#### Arrays
|
||||
|
@ -270,7 +256,6 @@ Arrays describe lists of things. Create an Array type with the `[]` operator.
|
|||
|
||||
```cadl
|
||||
alias Pack = Dog[];
|
||||
|
||||
```
|
||||
|
||||
### Operations
|
||||
|
@ -279,14 +264,12 @@ Operations describe service endpoints and consist of an operation name, paramete
|
|||
|
||||
```cadl
|
||||
op getDog(name: string): Dog;
|
||||
|
||||
```
|
||||
|
||||
The operation's parameters describe a model, so anything you can do in a model you can do in a parameter list as well, including using the spread operator:
|
||||
|
||||
```cadl
|
||||
op getDog(...commonParams, name: string): Dog;
|
||||
|
||||
```
|
||||
|
||||
Often an endpoint returns one of any number of models. For example, there might be a return type for when an item is found, and a return type for when an item isn't found. Unions are used to describe this pattern:
|
||||
|
@ -297,7 +280,6 @@ model DogNotFound {
|
|||
}
|
||||
|
||||
op getDog(name: string): Dog | DogNotFound;
|
||||
|
||||
```
|
||||
|
||||
### Namespaces & Usings
|
||||
|
@ -310,7 +292,6 @@ namespace Models {
|
|||
}
|
||||
|
||||
op getDog(): Models.Dog;
|
||||
|
||||
```
|
||||
|
||||
You can also put an entire Cadl file into a namespace by using the blockless namespace syntax:
|
||||
|
@ -319,14 +300,12 @@ You can also put an entire Cadl file into a namespace by using the blockless nam
|
|||
// models.cadl
|
||||
namespace Models;
|
||||
model Dog {}
|
||||
|
||||
```
|
||||
|
||||
```cadl
|
||||
// main.cadl
|
||||
import "./models.cadl";
|
||||
op getDog(): Models.Dog;
|
||||
|
||||
```
|
||||
|
||||
Namespace declarations can declare multiple namespaces at once by using a dotted member expression. There's no need to declare nested namespace blocks if you don't want to.
|
||||
|
@ -341,7 +320,6 @@ namespace C.D.E {
|
|||
}
|
||||
|
||||
alias M = A.B.C.D.E.M;
|
||||
|
||||
```
|
||||
|
||||
It can be convenient to add references to a namespace's declarations to your local namespace, especially when namespaces can become deeply nested. The `using` statement lets us do this:
|
||||
|
@ -350,7 +328,6 @@ It can be convenient to add references to a namespace's declarations to your loc
|
|||
// models.cadl
|
||||
namespace Service.Models;
|
||||
model Dog {}
|
||||
|
||||
```
|
||||
|
||||
```cadl
|
||||
|
@ -358,7 +335,6 @@ model Dog {}
|
|||
import "./models.cadl";
|
||||
using ServiceModels;
|
||||
op getDog(): Dog; // here we can use Dog directly.
|
||||
|
||||
```
|
||||
|
||||
The bindings introduced by a `using` statement are local to the namespace they are declared in. They do not become part of the namespace themselves.
|
||||
|
@ -375,7 +351,6 @@ namespace Test2 {
|
|||
|
||||
alias C = Test2.A; // not ok
|
||||
alias C = Test2.B; // ok
|
||||
|
||||
```
|
||||
|
||||
### Interfaces
|
||||
|
@ -390,7 +365,6 @@ interface A {
|
|||
interface B {
|
||||
b(): string;
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
And the keyword `extends` can be used to compose operations from other interfaces into a new interface:
|
||||
|
@ -406,7 +380,6 @@ interface C {
|
|||
b(): string;
|
||||
c(): string;
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
### Imports
|
||||
|
@ -419,20 +392,17 @@ The path you import must either begin with "./" or "../" or otherwise be an abso
|
|||
// main.cadl
|
||||
import "./models";
|
||||
op getDog(): Dog;
|
||||
|
||||
```
|
||||
|
||||
```cadl
|
||||
// models/main.cadl
|
||||
import "./dog.cadl";
|
||||
|
||||
```
|
||||
|
||||
```cadl
|
||||
// models/dog.cadl
|
||||
namespace Models;
|
||||
model Dog {}
|
||||
|
||||
```
|
||||
|
||||
### Decorators
|
||||
|
@ -463,7 +433,6 @@ model Dog {
|
|||
@logType("Name type")
|
||||
name: string;
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
After running this Cadl program, the following will be printed to the console:
|
||||
|
@ -697,7 +666,6 @@ model ReadDog {
|
|||
model WriteDog {
|
||||
...Dog;
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
#### @withDefaultKeyVisibility
|
||||
|
@ -782,7 +750,6 @@ Lastly, you need to import the libraries into your Cadl program. By convention,
|
|||
// in main.cadl
|
||||
import "@cadl-lang/rest";
|
||||
import "@cadl-lang/openapi3";
|
||||
|
||||
```
|
||||
|
||||
#### Using emitter libraries
|
||||
|
@ -870,7 +837,6 @@ Here's an example that uses these to define a Pet Store service:
|
|||
@Cadl.Rest.produces("application/json", "image/png")
|
||||
@Cadl.Rest.consumes("application/json")
|
||||
namespace PetStore;
|
||||
|
||||
```
|
||||
|
||||
The `server` keyword can take a third parameter with parameters as necessary:
|
||||
|
@ -893,7 +859,6 @@ using Cadl.Http;
|
|||
namespace Pets {
|
||||
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
To define an operation on this resource, you need to provide the HTTP verb for the route using the `@get`, `@head` `@post`, `@put`, `@patch`, or `@delete` decorators. Alternatively, you can name your operation `list`, `create`, `read`, `update`, `delete`, or `deleteAll` and the appropriate verb will be used automatically. Lets add an operation to our `Pets` resource:
|
||||
|
@ -906,7 +871,6 @@ namespace Pets {
|
|||
// or you could also use
|
||||
@get op listPets(): Pet[];
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
##### Automatic route generation
|
||||
|
@ -959,7 +923,6 @@ namespace Pets {
|
|||
op list(@query skip: int32, @query top: int32): Pet[];
|
||||
op read(@path petId: int32): Pet;
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
Path parameters are appended to the URL unless a substitution with that parameter name exists on the resource path. For example, we might define a sub-resource using the following Cadl. Note how the path parameter for our sub-resource's list operation corresponds to the substitution in the URL.
|
||||
|
@ -969,7 +932,6 @@ Path parameters are appended to the URL unless a substitution with that paramete
|
|||
namespace PetToys {
|
||||
op list(@path petId: int32): Toy[];
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
#### Request & response bodies
|
||||
|
@ -988,7 +950,6 @@ namespace Pets {
|
|||
@post
|
||||
op create(@body pet: Pet): {};
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
Note that in the absence of explicit `@body`:
|
||||
|
@ -1006,7 +967,6 @@ namespace Pets {
|
|||
@post
|
||||
op create(...Pet): {};
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
#### Polymorphism with discriminators
|
||||
|
@ -1035,7 +995,6 @@ model Dog extends Pet {
|
|||
kind: "dog";
|
||||
bark: string;
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
#### Headers
|
||||
|
@ -1055,7 +1014,6 @@ namespace Pets {
|
|||
@post
|
||||
op create(@body pet: Pet): {};
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
#### Status codes
|
||||
|
@ -1080,7 +1038,6 @@ namespace Pets {
|
|||
@statusCode statusCode: 204;
|
||||
};
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
#### Built-in response shapes
|
||||
|
@ -1104,7 +1061,6 @@ namespace Pets {
|
|||
@post
|
||||
op create(...Pet): NoContentResponse;
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
Note that the default status code is 200 for non-empty bodies and 204 for empty bodies. Similarly, explicit `Body<T>` is not required when T is known to be a model. So the following terser form is equivalent:
|
||||
|
@ -1117,7 +1073,6 @@ namespace Pets {
|
|||
@post
|
||||
op create(...Pet): {};
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
Finally, another common style is to make helper response types that are
|
||||
|
@ -1151,7 +1106,6 @@ namespace Pets {
|
|||
@post
|
||||
op create(...Pet): CreateResponse;
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
### CADL Config
|
||||
|
|
|
@ -75,7 +75,6 @@ model S {
|
|||
foo: string;
|
||||
bar: int64; // int64 is NOT assignable to int32
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
## Record<T>
|
||||
|
@ -113,7 +112,6 @@ model S {
|
|||
foo: 123;
|
||||
bar: 456;
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
#### Why is the last case not assignable to `Record<int32>`?
|
||||
|
@ -126,7 +124,6 @@ model S {
|
|||
foo: 123;
|
||||
bar: 456;
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
The reason is `model S` here is not assignable but the model expression `{ foo: 123; bar: 456; }` is, is that model S could be extended with additional properties that could then not be compatible.
|
||||
|
@ -137,7 +134,6 @@ If you for example now add a new model
|
|||
model Foo is S {
|
||||
otherProp: string;
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
Now here `Foo` is assignable to `S` following the [model with property logic](#model-with-properties) and if `S` was assignable to `Record<int32>`, `Foo` would be able to be passed through as well but this is now invalid as `otherProp` is not an `int32` property.
|
||||
|
|
|
@ -85,7 +85,14 @@ export function printCadl(
|
|||
const directives = shouldPrintDirective(node) ? printDirectives(path, options, print) : "";
|
||||
const printedNode = printNode(path, options, print);
|
||||
const value = needsParens(path, options) ? ["(", printedNode, ")"] : printedNode;
|
||||
return [directives, value];
|
||||
const parts: Doc[] = [directives, value];
|
||||
if (node.kind === SyntaxKind.CadlScript) {
|
||||
// For CadlScript(root of cadl document) we had a new line at the end.
|
||||
// This must be done here so the hardline entry can be the last item of the doc array returned by the printer
|
||||
// so the markdown(and other embeded formatter) can omit that extra line.
|
||||
parts.push(hardline);
|
||||
}
|
||||
return parts;
|
||||
}
|
||||
|
||||
function shouldPrintDirective(node: Node) {
|
||||
|
@ -106,7 +113,6 @@ export function printNode(
|
|||
case SyntaxKind.CadlScript:
|
||||
return [
|
||||
printStatementSequence(path as AstPath<CadlScriptNode>, options, print, "statements"),
|
||||
line,
|
||||
];
|
||||
|
||||
// Statements
|
||||
|
|
|
@ -2,16 +2,25 @@ import { strictEqual, throws } from "assert";
|
|||
import prettier from "prettier";
|
||||
import * as plugin from "../../formatter/index.js";
|
||||
|
||||
function format(code: string): string {
|
||||
type TestParser = "cadl" | "markdown";
|
||||
function format(code: string, parser: TestParser = "cadl"): string {
|
||||
const output = prettier.format(code, {
|
||||
parser: "cadl",
|
||||
parser,
|
||||
plugins: [plugin],
|
||||
});
|
||||
return output;
|
||||
}
|
||||
|
||||
function assertFormat({ code, expected }: { code: string; expected: string }) {
|
||||
const result = format(code);
|
||||
function assertFormat({
|
||||
code,
|
||||
expected,
|
||||
parser,
|
||||
}: {
|
||||
code: string;
|
||||
expected: string;
|
||||
parser?: TestParser;
|
||||
}) {
|
||||
const result = format(code, parser ?? "cadl");
|
||||
strictEqual(result.trim(), expected.trim());
|
||||
}
|
||||
|
||||
|
@ -1575,4 +1584,28 @@ projection model#proj {
|
|||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("when embeded", () => {
|
||||
it("doesn't include blank line at the end (in markdown)", () => {
|
||||
assertFormat({
|
||||
parser: "markdown",
|
||||
code: `
|
||||
This is markdown
|
||||
\`\`\`cadl
|
||||
|
||||
op test(): string;
|
||||
|
||||
|
||||
\`\`\`
|
||||
`,
|
||||
expected: `
|
||||
This is markdown
|
||||
|
||||
\`\`\`cadl
|
||||
op test(): string;
|
||||
\`\`\`
|
||||
`,
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -16,7 +16,6 @@ npm install @cadl-lang/openapi
|
|||
import "@cadl-lang/openapi";
|
||||
|
||||
using OpenAPI;
|
||||
|
||||
```
|
||||
|
||||
## References
|
||||
|
@ -39,7 +38,6 @@ Decorator that can be used on a response model to specify the `default` status c
|
|||
model MyNonErrorResponse {}
|
||||
|
||||
op foo(): MyNonErrorResponse;
|
||||
|
||||
```
|
||||
|
||||
### `@extension`
|
||||
|
@ -66,7 +64,6 @@ model Foo {}
|
|||
}
|
||||
)
|
||||
model Foo {}
|
||||
|
||||
```
|
||||
|
||||
### `@externalDocs`
|
||||
|
@ -84,7 +81,6 @@ Arguments:
|
|||
```cadl
|
||||
@externalDocs("https://example.com", "More info there")
|
||||
model Foo {}
|
||||
|
||||
```
|
||||
|
||||
### `@operationId`
|
||||
|
@ -100,7 +96,6 @@ Arguments:
|
|||
```cadl
|
||||
@operationId("custom_Foo")
|
||||
op foo(): string;
|
||||
|
||||
```
|
||||
|
||||
## See also
|
||||
|
|
|
@ -46,7 +46,6 @@ union MyUnion {
|
|||
cat: Cat,
|
||||
dog: Dog,
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
## Decorators
|
||||
|
|
|
@ -14,14 +14,12 @@ The path you import must either begin with `"./"` or `"../"` or otherwise be an
|
|||
|
||||
```cadl
|
||||
import "./models/foo.cadl";
|
||||
|
||||
```
|
||||
|
||||
## Import Js file
|
||||
|
||||
```cadl
|
||||
import "./decorators.js";
|
||||
|
||||
```
|
||||
|
||||
## Import a library
|
||||
|
@ -30,7 +28,6 @@ The import value can be name one of the package dependencies. In that case cadl
|
|||
|
||||
```cadl
|
||||
import "@cadl-lang/rest";
|
||||
|
||||
```
|
||||
|
||||
```json
|
||||
|
@ -48,10 +45,8 @@ If the import value is a directory it will lookup if that directoy is a node pac
|
|||
|
||||
```cadl
|
||||
import "./models"; // same as `import "./models/main.cadl";
|
||||
|
||||
```
|
||||
|
||||
```cadl
|
||||
import "./path/to/local/module"; // Assuming this path is a cadl package, it will load it using the cadlMain file.
|
||||
|
||||
```
|
||||
|
|
Загрузка…
Ссылка в новой задаче