@typespec/openapi 0.41.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.
- package/README.md +105 -0
- package/dist/src/decorators.d.ts +37 -0
- package/dist/src/decorators.d.ts.map +1 -0
- package/dist/src/decorators.js +85 -0
- package/dist/src/decorators.js.map +1 -0
- package/dist/src/helpers.d.ts +50 -0
- package/dist/src/helpers.d.ts.map +1 -0
- package/dist/src/helpers.js +119 -0
- package/dist/src/helpers.js.map +1 -0
- package/dist/src/index.d.ts +4 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +4 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/lib.d.ts +36 -0
- package/dist/src/lib.d.ts.map +1 -0
- package/dist/src/lib.js +21 -0
- package/dist/src/lib.js.map +1 -0
- package/dist/src/testing/index.d.ts +3 -0
- package/dist/src/testing/index.d.ts.map +1 -0
- package/dist/src/testing/index.js +8 -0
- package/dist/src/testing/index.js.map +1 -0
- package/dist/src/types.d.ts +2 -0
- package/dist/src/types.d.ts.map +1 -0
- package/dist/src/types.js +2 -0
- package/dist/src/types.js.map +1 -0
- package/lib/decorators.tsp +62 -0
- package/lib/main.tsp +2 -0
- package/package.json +76 -0
package/README.md
ADDED
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
# TypeSpec OpenAPI Library
|
|
2
|
+
|
|
3
|
+
This package provide [TypeSpec](https://github.com/microsoft/typespec) decorators to specify some OpenAPI specific concepts.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
In your typespec project root
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npm install @typespec/openapi
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Usage
|
|
14
|
+
|
|
15
|
+
```typespec
|
|
16
|
+
import "@typespec/openapi";
|
|
17
|
+
|
|
18
|
+
using OpenAPI;
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## References
|
|
22
|
+
|
|
23
|
+
Decorators:
|
|
24
|
+
|
|
25
|
+
- [`@defaultResponse`](#defaultResponse)
|
|
26
|
+
- [`@extension`](#extension)
|
|
27
|
+
- [`@externalDocs`](#externalDocs)
|
|
28
|
+
- [`@operationId`](#operationId)
|
|
29
|
+
|
|
30
|
+
### `@defaultResponse`
|
|
31
|
+
|
|
32
|
+
**IMPORTANT This is to be used on `NON-ERROR` responses that cover all the other status codes. If you are looking to represent an error use [`@error`](https://microsoft.github.io/typespec/docs/standard-library/built-in-decorators/#error)**
|
|
33
|
+
|
|
34
|
+
Decorator that can be used on a response model to specify the `default` status code that OpenAPI allow.
|
|
35
|
+
|
|
36
|
+
```typespec
|
|
37
|
+
@defaultResponse
|
|
38
|
+
model MyNonErrorResponse {}
|
|
39
|
+
|
|
40
|
+
op foo(): MyNonErrorResponse;
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
### `@extension`
|
|
44
|
+
|
|
45
|
+
This decorator lets you specify custom key(starting with `x-`) value pair that will be added to the OpenAPI document.
|
|
46
|
+
[OpenAPI reference on extensions](https://github.com/OAI/OpenAPI-Specification/blob/3.0.3/versions/3.0.3.md#specificationExtensions)
|
|
47
|
+
|
|
48
|
+
Arguments:
|
|
49
|
+
|
|
50
|
+
| Name | foo | Description |
|
|
51
|
+
| ------- | ------------ | ---------------------------------------------------------------- |
|
|
52
|
+
| `key` | **Required** | Extension key. **MUST** start with `x-` |
|
|
53
|
+
| `value` | **Required** | Value of the extension. Can be an primitive, a tuple or a model. |
|
|
54
|
+
|
|
55
|
+
```typespec
|
|
56
|
+
@extension("x-custom", "MyCustomValue")
|
|
57
|
+
model Foo {}
|
|
58
|
+
|
|
59
|
+
// Value can be an model.
|
|
60
|
+
@extension(
|
|
61
|
+
"x-custom",
|
|
62
|
+
{
|
|
63
|
+
some: "value",
|
|
64
|
+
}
|
|
65
|
+
)
|
|
66
|
+
model Foo {}
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
### `@externalDocs`
|
|
70
|
+
|
|
71
|
+
Decorator that can be used to provide the `externalDocs` property on OpenAPI elements.
|
|
72
|
+
[OpenAPI spec for externalDocs](https://github.com/OAI/OpenAPI-Specification/blob/3.0.3/versions/3.0.3.md#externalDocumentationObject)
|
|
73
|
+
|
|
74
|
+
Arguments:
|
|
75
|
+
|
|
76
|
+
| Name | foo | Description |
|
|
77
|
+
| ------------- | ------------ | -------------------------------- |
|
|
78
|
+
| `url` | **Required** | Url for the external docs |
|
|
79
|
+
| `description` | **Optional** | Description of the documentation |
|
|
80
|
+
|
|
81
|
+
```typespec
|
|
82
|
+
@externalDocs("https://example.com", "More info there")
|
|
83
|
+
model Foo {}
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
### `@operationId`
|
|
87
|
+
|
|
88
|
+
Decorator that can be used on an operation to specify the `operationId` field in OpenAPI. If this is not provided the `operationId` will be the typespec operation name.
|
|
89
|
+
|
|
90
|
+
Arguments:
|
|
91
|
+
|
|
92
|
+
| Name | foo | Description |
|
|
93
|
+
| ------ | ------------ | ------------------- |
|
|
94
|
+
| `opId` | **Required** | Id of the operation |
|
|
95
|
+
|
|
96
|
+
```typespec
|
|
97
|
+
@operationId("custom_Foo")
|
|
98
|
+
op foo(): string;
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
## See also
|
|
102
|
+
|
|
103
|
+
- [TypeSpec Getting Started](https://github.com/microsoft/typespec#getting-started)
|
|
104
|
+
- [TypeSpec Website](https://microsoft.github.io/typespec)
|
|
105
|
+
- [TypeSpec for the OpenAPI Developer](https://github.com/microsoft/typespec/blob/main/docs/typespec-for-openapi-dev.md)
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { DecoratorContext, Model, Operation, Program, Type, TypeSpecValue } from "@typespec/compiler";
|
|
2
|
+
import { ExtensionKey } from "./types.js";
|
|
3
|
+
export declare const namespace = "OpenAPI";
|
|
4
|
+
/**
|
|
5
|
+
* Set a specific operation ID.
|
|
6
|
+
* @param context Decorator Context
|
|
7
|
+
* @param entity Decorator target
|
|
8
|
+
* @param opId Operation ID.
|
|
9
|
+
*/
|
|
10
|
+
export declare function $operationId(context: DecoratorContext, entity: Operation, opId: string): void;
|
|
11
|
+
/**
|
|
12
|
+
* @returns operationId set via the @operationId decorator or `undefined`
|
|
13
|
+
*/
|
|
14
|
+
export declare function getOperationId(program: Program, entity: Operation): string | undefined;
|
|
15
|
+
export declare function $extension(context: DecoratorContext, entity: Type, extensionName: string, value: TypeSpecValue): void;
|
|
16
|
+
export declare function setExtension(program: Program, entity: Type, extensionName: ExtensionKey, data: unknown): void;
|
|
17
|
+
export declare function getExtensions(program: Program, entity: Type): ReadonlyMap<ExtensionKey, any>;
|
|
18
|
+
export declare function $defaultResponse(context: DecoratorContext, entity: Model): void;
|
|
19
|
+
/**
|
|
20
|
+
* Check if the given model has been mark as a default response.
|
|
21
|
+
* @param program TypeSpec Program
|
|
22
|
+
* @param entity Model to check.
|
|
23
|
+
* @returns boolean.
|
|
24
|
+
*/
|
|
25
|
+
export declare function isDefaultResponse(program: Program, entity: Type): boolean;
|
|
26
|
+
export interface ExternalDocs {
|
|
27
|
+
url: string;
|
|
28
|
+
description?: string;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Allows referencing an external resource for extended documentation.
|
|
32
|
+
* @param url The URL for the target documentation. Value MUST be in the format of a URL.
|
|
33
|
+
* @param @optional description A short description of the target documentation.
|
|
34
|
+
*/
|
|
35
|
+
export declare function $externalDocs(context: DecoratorContext, target: Type, url: string, description?: string): void;
|
|
36
|
+
export declare function getExternalDocs(program: Program, entity: Type): ExternalDocs | undefined;
|
|
37
|
+
//# sourceMappingURL=decorators.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"decorators.d.ts","sourceRoot":"","sources":["../../src/decorators.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,gBAAgB,EAChB,KAAK,EACL,SAAS,EACT,OAAO,EACP,IAAI,EAEJ,aAAa,EACd,MAAM,oBAAoB,CAAC;AAG5B,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE1C,eAAO,MAAM,SAAS,YAAY,CAAC;AAGnC;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,gBAAgB,EAAE,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,QAEtF;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,GAAG,MAAM,GAAG,SAAS,CAEtF;AAID,wBAAgB,UAAU,CACxB,OAAO,EAAE,gBAAgB,EACzB,MAAM,EAAE,IAAI,EACZ,aAAa,EAAE,MAAM,EACrB,KAAK,EAAE,aAAa,QAerB;AAED,wBAAgB,YAAY,CAC1B,OAAO,EAAE,OAAO,EAChB,MAAM,EAAE,IAAI,EACZ,aAAa,EAAE,YAAY,EAC3B,IAAI,EAAE,OAAO,QAOd;AAED,wBAAgB,aAAa,CAAC,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,GAAG,WAAW,CAAC,YAAY,EAAE,GAAG,CAAC,CAE5F;AAYD,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,gBAAgB,EAAE,MAAM,EAAE,KAAK,QAGxE;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,GAAG,OAAO,CAEzE;AAED,MAAM,WAAW,YAAY;IAC3B,GAAG,EAAE,MAAM,CAAC;IACZ,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAGD;;;;GAIG;AACH,wBAAgB,aAAa,CAC3B,OAAO,EAAE,gBAAgB,EACzB,MAAM,EAAE,IAAI,EACZ,GAAG,EAAE,MAAM,EACX,WAAW,CAAC,EAAE,MAAM,QAOrB;AAED,wBAAgB,eAAe,CAAC,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,GAAG,YAAY,GAAG,SAAS,CAExF"}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { typespecTypeToJson, } from "@typespec/compiler";
|
|
2
|
+
import { setStatusCode } from "@typespec/http";
|
|
3
|
+
import { createStateSymbol, reportDiagnostic } from "./lib.js";
|
|
4
|
+
export const namespace = "OpenAPI";
|
|
5
|
+
const operationIdsKey = createStateSymbol("operationIds");
|
|
6
|
+
/**
|
|
7
|
+
* Set a specific operation ID.
|
|
8
|
+
* @param context Decorator Context
|
|
9
|
+
* @param entity Decorator target
|
|
10
|
+
* @param opId Operation ID.
|
|
11
|
+
*/
|
|
12
|
+
export function $operationId(context, entity, opId) {
|
|
13
|
+
context.program.stateMap(operationIdsKey).set(entity, opId);
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* @returns operationId set via the @operationId decorator or `undefined`
|
|
17
|
+
*/
|
|
18
|
+
export function getOperationId(program, entity) {
|
|
19
|
+
return program.stateMap(operationIdsKey).get(entity);
|
|
20
|
+
}
|
|
21
|
+
const openApiExtensionKey = createStateSymbol("openApiExtension");
|
|
22
|
+
export function $extension(context, entity, extensionName, value) {
|
|
23
|
+
if (!isOpenAPIExtensionKey(extensionName)) {
|
|
24
|
+
reportDiagnostic(context.program, {
|
|
25
|
+
code: "invalid-extension-key",
|
|
26
|
+
format: { value: extensionName },
|
|
27
|
+
target: entity,
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
const [data, diagnostics] = typespecTypeToJson(value, entity);
|
|
31
|
+
if (diagnostics.length > 0) {
|
|
32
|
+
context.program.reportDiagnostics(diagnostics);
|
|
33
|
+
}
|
|
34
|
+
setExtension(context.program, entity, extensionName, data);
|
|
35
|
+
}
|
|
36
|
+
export function setExtension(program, entity, extensionName, data) {
|
|
37
|
+
var _a;
|
|
38
|
+
const openApiExtensions = program.stateMap(openApiExtensionKey);
|
|
39
|
+
const typeExtensions = (_a = openApiExtensions.get(entity)) !== null && _a !== void 0 ? _a : new Map();
|
|
40
|
+
typeExtensions.set(extensionName, data);
|
|
41
|
+
openApiExtensions.set(entity, typeExtensions);
|
|
42
|
+
}
|
|
43
|
+
export function getExtensions(program, entity) {
|
|
44
|
+
var _a;
|
|
45
|
+
return (_a = program.stateMap(openApiExtensionKey).get(entity)) !== null && _a !== void 0 ? _a : new Map();
|
|
46
|
+
}
|
|
47
|
+
function isOpenAPIExtensionKey(key) {
|
|
48
|
+
return key.startsWith("x-");
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* The @defaultResponse decorator can be applied to a model. When that model is used
|
|
52
|
+
* as the return type of an operation, this return type will be the default response.
|
|
53
|
+
*
|
|
54
|
+
*/
|
|
55
|
+
const defaultResponseKey = createStateSymbol("defaultResponse");
|
|
56
|
+
export function $defaultResponse(context, entity) {
|
|
57
|
+
setStatusCode(context.program, entity, ["*"]);
|
|
58
|
+
context.program.stateSet(defaultResponseKey).add(entity);
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Check if the given model has been mark as a default response.
|
|
62
|
+
* @param program TypeSpec Program
|
|
63
|
+
* @param entity Model to check.
|
|
64
|
+
* @returns boolean.
|
|
65
|
+
*/
|
|
66
|
+
export function isDefaultResponse(program, entity) {
|
|
67
|
+
return program.stateSet(defaultResponseKey).has(entity);
|
|
68
|
+
}
|
|
69
|
+
const externalDocsKey = createStateSymbol("externalDocs");
|
|
70
|
+
/**
|
|
71
|
+
* Allows referencing an external resource for extended documentation.
|
|
72
|
+
* @param url The URL for the target documentation. Value MUST be in the format of a URL.
|
|
73
|
+
* @param @optional description A short description of the target documentation.
|
|
74
|
+
*/
|
|
75
|
+
export function $externalDocs(context, target, url, description) {
|
|
76
|
+
const doc = { url };
|
|
77
|
+
if (description) {
|
|
78
|
+
doc.description = description;
|
|
79
|
+
}
|
|
80
|
+
context.program.stateMap(externalDocsKey).set(target, doc);
|
|
81
|
+
}
|
|
82
|
+
export function getExternalDocs(program, entity) {
|
|
83
|
+
return program.stateMap(externalDocsKey).get(entity);
|
|
84
|
+
}
|
|
85
|
+
//# sourceMappingURL=decorators.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"decorators.js","sourceRoot":"","sources":["../../src/decorators.ts"],"names":[],"mappings":"AAAA,OAAO,EAML,kBAAkB,GAEnB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAC/C,OAAO,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAG/D,MAAM,CAAC,MAAM,SAAS,GAAG,SAAS,CAAC;AAEnC,MAAM,eAAe,GAAG,iBAAiB,CAAC,cAAc,CAAC,CAAC;AAC1D;;;;;GAKG;AACH,MAAM,UAAU,YAAY,CAAC,OAAyB,EAAE,MAAiB,EAAE,IAAY;IACrF,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAC,CAAC,GAAG,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;AAC9D,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,cAAc,CAAC,OAAgB,EAAE,MAAiB;IAChE,OAAO,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;AACvD,CAAC;AAED,MAAM,mBAAmB,GAAG,iBAAiB,CAAC,kBAAkB,CAAC,CAAC;AAElE,MAAM,UAAU,UAAU,CACxB,OAAyB,EACzB,MAAY,EACZ,aAAqB,EACrB,KAAoB;IAEpB,IAAI,CAAC,qBAAqB,CAAC,aAAa,CAAC,EAAE;QACzC,gBAAgB,CAAC,OAAO,CAAC,OAAO,EAAE;YAChC,IAAI,EAAE,uBAAuB;YAC7B,MAAM,EAAE,EAAE,KAAK,EAAE,aAAa,EAAE;YAChC,MAAM,EAAE,MAAM;SACf,CAAC,CAAC;KACJ;IAED,MAAM,CAAC,IAAI,EAAE,WAAW,CAAC,GAAG,kBAAkB,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;IAC9D,IAAI,WAAW,CAAC,MAAM,GAAG,CAAC,EAAE;QAC1B,OAAO,CAAC,OAAO,CAAC,iBAAiB,CAAC,WAAW,CAAC,CAAC;KAChD;IACD,YAAY,CAAC,OAAO,CAAC,OAAO,EAAE,MAAM,EAAE,aAA6B,EAAE,IAAI,CAAC,CAAC;AAC7E,CAAC;AAED,MAAM,UAAU,YAAY,CAC1B,OAAgB,EAChB,MAAY,EACZ,aAA2B,EAC3B,IAAa;;IAEb,MAAM,iBAAiB,GAAG,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAC,CAAC;IAChE,MAAM,cAAc,GAAG,MAAA,iBAAiB,CAAC,GAAG,CAAC,MAAM,CAAC,mCAAI,IAAI,GAAG,EAAe,CAAC;IAC/E,cAAc,CAAC,GAAG,CAAC,aAAa,EAAE,IAAI,CAAC,CAAC;IAExC,iBAAiB,CAAC,GAAG,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;AAChD,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,OAAgB,EAAE,MAAY;;IAC1D,OAAO,MAAA,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,mCAAI,IAAI,GAAG,EAAqB,CAAC;AAC3F,CAAC;AAED,SAAS,qBAAqB,CAAC,GAAW;IACxC,OAAO,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;AAC9B,CAAC;AAED;;;;GAIG;AACH,MAAM,kBAAkB,GAAG,iBAAiB,CAAC,iBAAiB,CAAC,CAAC;AAChE,MAAM,UAAU,gBAAgB,CAAC,OAAyB,EAAE,MAAa;IACvE,aAAa,CAAC,OAAO,CAAC,OAAO,EAAE,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IAC9C,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;AAC3D,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,iBAAiB,CAAC,OAAgB,EAAE,MAAY;IAC9D,OAAO,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;AAC1D,CAAC;AAMD,MAAM,eAAe,GAAG,iBAAiB,CAAC,cAAc,CAAC,CAAC;AAE1D;;;;GAIG;AACH,MAAM,UAAU,aAAa,CAC3B,OAAyB,EACzB,MAAY,EACZ,GAAW,EACX,WAAoB;IAEpB,MAAM,GAAG,GAAiB,EAAE,GAAG,EAAE,CAAC;IAClC,IAAI,WAAW,EAAE;QACf,GAAG,CAAC,WAAW,GAAG,WAAW,CAAC;KAC/B;IACD,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAC,CAAC,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;AAC7D,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,OAAgB,EAAE,MAAY;IAC5D,OAAO,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;AACvD,CAAC"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { ModelProperty, Operation, Program, Type, TypeNameOptions } from "@typespec/compiler";
|
|
2
|
+
/**
|
|
3
|
+
* Determines whether a type will be inlined in OpenAPI rather than defined
|
|
4
|
+
* as a schema and referenced.
|
|
5
|
+
*
|
|
6
|
+
* All anonymous types (anonymous models, arrays, tuples, etc.) are inlined.
|
|
7
|
+
*
|
|
8
|
+
* Template instantiations are inlined unless they have a friendly name.
|
|
9
|
+
*
|
|
10
|
+
* A friendly name can be provided by the user using `@friendlyName`
|
|
11
|
+
* decorator, or chosen by default in simple cases.
|
|
12
|
+
*/
|
|
13
|
+
export declare function shouldInline(program: Program, type: Type): boolean;
|
|
14
|
+
/**
|
|
15
|
+
* Gets the name of a type to be used in OpenAPI.
|
|
16
|
+
*
|
|
17
|
+
* For inlined types: this is the TypeSpec-native name written to `x-typespec-name`.
|
|
18
|
+
*
|
|
19
|
+
* For non-inlined types: this is either the friendly name or the TypeSpec-native name.
|
|
20
|
+
*
|
|
21
|
+
* TypeSpec-native names are shortened to exclude root `TypeSpec` namespace and service
|
|
22
|
+
* namespace using the provided `TypeNameOptions`.
|
|
23
|
+
*/
|
|
24
|
+
export declare function getOpenAPITypeName(program: Program, type: Type, options: TypeNameOptions, existing?: Record<string, any>): string;
|
|
25
|
+
export declare function checkDuplicateTypeName(program: Program, type: Type, name: string, existing: Record<string, unknown> | undefined): void;
|
|
26
|
+
/**
|
|
27
|
+
* Gets the key that is used to define a parameter in OpenAPI.
|
|
28
|
+
*/
|
|
29
|
+
export declare function getParameterKey(program: Program, property: ModelProperty, newParam: unknown, existingParams: Record<string, unknown>, options: TypeNameOptions): string;
|
|
30
|
+
/**
|
|
31
|
+
* Resolve the OpenAPI operation ID for the given operation using the following logic:
|
|
32
|
+
* - If @operationId was specified use that value
|
|
33
|
+
* - If operation is defined at the root or under the service namespace return `<operation.name>`
|
|
34
|
+
* - Otherwise(operation is under another namespace or interface) return `<namespace/interface.name>_<operation.name>`
|
|
35
|
+
*
|
|
36
|
+
* @param program TypeSpec Program
|
|
37
|
+
* @param operation Operation
|
|
38
|
+
* @returns Operation ID in this format `<name>` or `<group>_<name>`
|
|
39
|
+
*/
|
|
40
|
+
export declare function resolveOperationId(program: Program, operation: Operation): string;
|
|
41
|
+
/**
|
|
42
|
+
* Determines if a property is read-only, which is defined as being
|
|
43
|
+
* decorated `@visibility("read")`.
|
|
44
|
+
*
|
|
45
|
+
* If there is more than 1 `@visibility` argument, then the property is not
|
|
46
|
+
* read-only. For example, `@visibility("read", "update")` does not
|
|
47
|
+
* designate a read-only property.
|
|
48
|
+
*/
|
|
49
|
+
export declare function isReadonlyProperty(program: Program, property: ModelProperty): boolean;
|
|
50
|
+
//# sourceMappingURL=helpers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../../src/helpers.ts"],"names":[],"mappings":"AAAA,OAAO,EAOL,aAAa,EACb,SAAS,EACT,OAAO,EACP,IAAI,EACJ,eAAe,EAChB,MAAM,oBAAoB,CAAC;AAI5B;;;;;;;;;;GAUG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,GAAG,OAAO,CAelE;AAED;;;;;;;;;GASG;AACH,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,OAAO,EAChB,IAAI,EAAE,IAAI,EACV,OAAO,EAAE,eAAe,EACxB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAC7B,MAAM,CAKR;AAED,wBAAgB,sBAAsB,CACpC,OAAO,EAAE,OAAO,EAChB,IAAI,EAAE,IAAI,EACV,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,QAW9C;AAED;;GAEG;AACH,wBAAgB,eAAe,CAC7B,OAAO,EAAE,OAAO,EAChB,QAAQ,EAAE,aAAa,EACvB,QAAQ,EAAE,OAAO,EACjB,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACvC,OAAO,EAAE,eAAe,GACvB,MAAM,CAoBR;AAED;;;;;;;;;GASG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,UAmBxE;AAED;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,aAAa,WAK3E"}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import { getFriendlyName, getTypeName, getVisibility, isGlobalNamespace, isService, isTemplateInstance, } from "@typespec/compiler";
|
|
2
|
+
import { getOperationId } from "./decorators.js";
|
|
3
|
+
import { reportDiagnostic } from "./lib.js";
|
|
4
|
+
/**
|
|
5
|
+
* Determines whether a type will be inlined in OpenAPI rather than defined
|
|
6
|
+
* as a schema and referenced.
|
|
7
|
+
*
|
|
8
|
+
* All anonymous types (anonymous models, arrays, tuples, etc.) are inlined.
|
|
9
|
+
*
|
|
10
|
+
* Template instantiations are inlined unless they have a friendly name.
|
|
11
|
+
*
|
|
12
|
+
* A friendly name can be provided by the user using `@friendlyName`
|
|
13
|
+
* decorator, or chosen by default in simple cases.
|
|
14
|
+
*/
|
|
15
|
+
export function shouldInline(program, type) {
|
|
16
|
+
if (getFriendlyName(program, type)) {
|
|
17
|
+
return false;
|
|
18
|
+
}
|
|
19
|
+
switch (type.kind) {
|
|
20
|
+
case "Model":
|
|
21
|
+
return !type.name || isTemplateInstance(type);
|
|
22
|
+
case "Scalar":
|
|
23
|
+
return program.checker.isStdType(type) || isTemplateInstance(type);
|
|
24
|
+
case "Enum":
|
|
25
|
+
case "Union":
|
|
26
|
+
return !type.name;
|
|
27
|
+
default:
|
|
28
|
+
return true;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Gets the name of a type to be used in OpenAPI.
|
|
33
|
+
*
|
|
34
|
+
* For inlined types: this is the TypeSpec-native name written to `x-typespec-name`.
|
|
35
|
+
*
|
|
36
|
+
* For non-inlined types: this is either the friendly name or the TypeSpec-native name.
|
|
37
|
+
*
|
|
38
|
+
* TypeSpec-native names are shortened to exclude root `TypeSpec` namespace and service
|
|
39
|
+
* namespace using the provided `TypeNameOptions`.
|
|
40
|
+
*/
|
|
41
|
+
export function getOpenAPITypeName(program, type, options, existing) {
|
|
42
|
+
var _a;
|
|
43
|
+
const name = (_a = getFriendlyName(program, type)) !== null && _a !== void 0 ? _a : getTypeName(type, options);
|
|
44
|
+
checkDuplicateTypeName(program, type, name, existing);
|
|
45
|
+
return name;
|
|
46
|
+
}
|
|
47
|
+
export function checkDuplicateTypeName(program, type, name, existing) {
|
|
48
|
+
if (existing && existing[name]) {
|
|
49
|
+
reportDiagnostic(program, {
|
|
50
|
+
code: "duplicate-type-name",
|
|
51
|
+
format: {
|
|
52
|
+
value: name,
|
|
53
|
+
},
|
|
54
|
+
target: type,
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Gets the key that is used to define a parameter in OpenAPI.
|
|
60
|
+
*/
|
|
61
|
+
export function getParameterKey(program, property, newParam, existingParams, options) {
|
|
62
|
+
const parent = property.model;
|
|
63
|
+
let key = getOpenAPITypeName(program, parent, options);
|
|
64
|
+
if (parent.properties.size > 1) {
|
|
65
|
+
key += `.${property.name}`;
|
|
66
|
+
}
|
|
67
|
+
if (existingParams[key]) {
|
|
68
|
+
reportDiagnostic(program, {
|
|
69
|
+
code: "duplicate-type-name",
|
|
70
|
+
messageId: "parameter",
|
|
71
|
+
format: {
|
|
72
|
+
value: key,
|
|
73
|
+
},
|
|
74
|
+
target: property,
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
return key;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Resolve the OpenAPI operation ID for the given operation using the following logic:
|
|
81
|
+
* - If @operationId was specified use that value
|
|
82
|
+
* - If operation is defined at the root or under the service namespace return `<operation.name>`
|
|
83
|
+
* - Otherwise(operation is under another namespace or interface) return `<namespace/interface.name>_<operation.name>`
|
|
84
|
+
*
|
|
85
|
+
* @param program TypeSpec Program
|
|
86
|
+
* @param operation Operation
|
|
87
|
+
* @returns Operation ID in this format `<name>` or `<group>_<name>`
|
|
88
|
+
*/
|
|
89
|
+
export function resolveOperationId(program, operation) {
|
|
90
|
+
const explicitOperationId = getOperationId(program, operation);
|
|
91
|
+
if (explicitOperationId) {
|
|
92
|
+
return explicitOperationId;
|
|
93
|
+
}
|
|
94
|
+
if (operation.interface) {
|
|
95
|
+
return `${operation.interface.name}_${operation.name}`;
|
|
96
|
+
}
|
|
97
|
+
const namespace = operation.namespace;
|
|
98
|
+
if (namespace === undefined ||
|
|
99
|
+
isGlobalNamespace(program, namespace) ||
|
|
100
|
+
isService(program, namespace)) {
|
|
101
|
+
return operation.name;
|
|
102
|
+
}
|
|
103
|
+
return `${namespace.name}_${operation.name}`;
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Determines if a property is read-only, which is defined as being
|
|
107
|
+
* decorated `@visibility("read")`.
|
|
108
|
+
*
|
|
109
|
+
* If there is more than 1 `@visibility` argument, then the property is not
|
|
110
|
+
* read-only. For example, `@visibility("read", "update")` does not
|
|
111
|
+
* designate a read-only property.
|
|
112
|
+
*/
|
|
113
|
+
export function isReadonlyProperty(program, property) {
|
|
114
|
+
const visibility = getVisibility(program, property);
|
|
115
|
+
// note: multiple visibilities that include read are not handled using
|
|
116
|
+
// readonly: true, but using separate schemas.
|
|
117
|
+
return (visibility === null || visibility === void 0 ? void 0 : visibility.length) === 1 && visibility[0] === "read";
|
|
118
|
+
}
|
|
119
|
+
//# sourceMappingURL=helpers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"helpers.js","sourceRoot":"","sources":["../../src/helpers.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,iBAAiB,CAAC;AAChC,cAAc,cAAc,CAAC;AAC7B,cAAc,YAAY,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,iBAAiB,CAAC;AAChC,cAAc,cAAc,CAAC;AAC7B,cAAc,YAAY,CAAC"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
export declare const libDef: {
|
|
2
|
+
readonly name: "@typespec/openapi";
|
|
3
|
+
readonly diagnostics: {
|
|
4
|
+
readonly "invalid-extension-key": {
|
|
5
|
+
readonly severity: "error";
|
|
6
|
+
readonly messages: {
|
|
7
|
+
readonly default: import("@typespec/compiler").CallableMessage<["value"]>;
|
|
8
|
+
};
|
|
9
|
+
};
|
|
10
|
+
readonly "duplicate-type-name": {
|
|
11
|
+
readonly severity: "error";
|
|
12
|
+
readonly messages: {
|
|
13
|
+
readonly default: import("@typespec/compiler").CallableMessage<["value"]>;
|
|
14
|
+
readonly parameter: import("@typespec/compiler").CallableMessage<["value"]>;
|
|
15
|
+
};
|
|
16
|
+
};
|
|
17
|
+
};
|
|
18
|
+
};
|
|
19
|
+
export declare const reportDiagnostic: <C extends "invalid-extension-key" | "duplicate-type-name", M extends keyof {
|
|
20
|
+
"invalid-extension-key": {
|
|
21
|
+
readonly default: import("@typespec/compiler").CallableMessage<["value"]>;
|
|
22
|
+
};
|
|
23
|
+
"duplicate-type-name": {
|
|
24
|
+
readonly default: import("@typespec/compiler").CallableMessage<["value"]>;
|
|
25
|
+
readonly parameter: import("@typespec/compiler").CallableMessage<["value"]>;
|
|
26
|
+
};
|
|
27
|
+
}[C]>(program: import("@typespec/compiler").Program, diag: import("@typespec/compiler").DiagnosticReport<{
|
|
28
|
+
"invalid-extension-key": {
|
|
29
|
+
readonly default: import("@typespec/compiler").CallableMessage<["value"]>;
|
|
30
|
+
};
|
|
31
|
+
"duplicate-type-name": {
|
|
32
|
+
readonly default: import("@typespec/compiler").CallableMessage<["value"]>;
|
|
33
|
+
readonly parameter: import("@typespec/compiler").CallableMessage<["value"]>;
|
|
34
|
+
};
|
|
35
|
+
}, C, M>) => void, createStateSymbol: (name: string) => symbol;
|
|
36
|
+
//# sourceMappingURL=lib.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lib.d.ts","sourceRoot":"","sources":["../../src/lib.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,MAAM;;;;;;;;;;;;;;;;;CAiBT,CAAC;AACX,eAAO,MAAQ,gBAAgB;;;;;;;;;;;;;;;;mBAAE,iBAAiB,0BAAkC,CAAC"}
|
package/dist/src/lib.js
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { createTypeSpecLibrary, paramMessage } from "@typespec/compiler";
|
|
2
|
+
export const libDef = {
|
|
3
|
+
name: "@typespec/openapi",
|
|
4
|
+
diagnostics: {
|
|
5
|
+
"invalid-extension-key": {
|
|
6
|
+
severity: "error",
|
|
7
|
+
messages: {
|
|
8
|
+
default: paramMessage `OpenAPI extension must start with 'x-' but was '${"value"}'`,
|
|
9
|
+
},
|
|
10
|
+
},
|
|
11
|
+
"duplicate-type-name": {
|
|
12
|
+
severity: "error",
|
|
13
|
+
messages: {
|
|
14
|
+
default: paramMessage `Duplicate type name: '${"value"}'. Check @friendlyName decorators and overlap with types in TypeSpec or service namespace.`,
|
|
15
|
+
parameter: paramMessage `Duplicate parameter key: '${"value"}'. Check @friendlyName decorators and overlap with types in TypeSpec or service namespace.`,
|
|
16
|
+
},
|
|
17
|
+
},
|
|
18
|
+
},
|
|
19
|
+
};
|
|
20
|
+
export const { reportDiagnostic, createStateSymbol } = createTypeSpecLibrary(libDef);
|
|
21
|
+
//# sourceMappingURL=lib.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lib.js","sourceRoot":"","sources":["../../src/lib.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAEzE,MAAM,CAAC,MAAM,MAAM,GAAG;IACpB,IAAI,EAAE,mBAAmB;IACzB,WAAW,EAAE;QACX,uBAAuB,EAAE;YACvB,QAAQ,EAAE,OAAO;YACjB,QAAQ,EAAE;gBACR,OAAO,EAAE,YAAY,CAAA,mDAAmD,OAAO,GAAG;aACnF;SACF;QACD,qBAAqB,EAAE;YACrB,QAAQ,EAAE,OAAO;YACjB,QAAQ,EAAE;gBACR,OAAO,EAAE,YAAY,CAAA,yBAAyB,OAAO,4FAA4F;gBACjJ,SAAS,EAAE,YAAY,CAAA,6BAA6B,OAAO,4FAA4F;aACxJ;SACF;KACF;CACO,CAAC;AACX,MAAM,CAAC,MAAM,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,GAAG,qBAAqB,CAAC,MAAM,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/testing/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAqB,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AAGpF,eAAO,MAAM,kBAAkB,EAAE,mBAG/B,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { resolvePath } from "@typespec/compiler";
|
|
2
|
+
import { createTestLibrary } from "@typespec/compiler/testing";
|
|
3
|
+
import { fileURLToPath } from "url";
|
|
4
|
+
export const OpenAPITestLibrary = createTestLibrary({
|
|
5
|
+
name: "@typespec/openapi",
|
|
6
|
+
packageRoot: resolvePath(fileURLToPath(import.meta.url), "../../../../"),
|
|
7
|
+
});
|
|
8
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/testing/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,iBAAiB,EAAuB,MAAM,4BAA4B,CAAC;AACpF,OAAO,EAAE,aAAa,EAAE,MAAM,KAAK,CAAC;AAEpC,MAAM,CAAC,MAAM,kBAAkB,GAAwB,iBAAiB,CAAC;IACvE,IAAI,EAAE,mBAAmB;IACzB,WAAW,EAAE,WAAW,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,cAAc,CAAC;CACzE,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,YAAY,GAAG,KAAK,MAAM,EAAE,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
using TypeSpec.Reflection;
|
|
2
|
+
|
|
3
|
+
namespace OpenAPI;
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Specify the OpenAPI `operationId` property for this operation.
|
|
7
|
+
*
|
|
8
|
+
* @param operationId Operation id value.
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
*
|
|
12
|
+
* ```typespec
|
|
13
|
+
* @operationId("download")
|
|
14
|
+
* op read(): string;
|
|
15
|
+
* ```
|
|
16
|
+
*/
|
|
17
|
+
extern dec operationId(target: Operation, operationId: string);
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Attach some custom data to the OpenAPI element generated from this type.
|
|
21
|
+
*
|
|
22
|
+
* @param key Extension key. Must start with `x-`
|
|
23
|
+
* @param value Extension value.
|
|
24
|
+
*
|
|
25
|
+
* @example
|
|
26
|
+
*
|
|
27
|
+
* ```typespec
|
|
28
|
+
* @extension("x-custom", "My value")
|
|
29
|
+
* @extension("x-pageable", {nextLink: "x-next-link"})
|
|
30
|
+
* op read(): string;
|
|
31
|
+
* ```
|
|
32
|
+
*/
|
|
33
|
+
extern dec extension(target: unknown, key: string, value: unknown);
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Specify that this model is to be treated as the OpenAPI `default` response.
|
|
37
|
+
* This differs from the compiler built-in `@error` decorator as this does not necessarily represent an error.
|
|
38
|
+
*
|
|
39
|
+
* @example
|
|
40
|
+
*
|
|
41
|
+
* ```typespec
|
|
42
|
+
* @defaultResponse
|
|
43
|
+
* model PetStoreResponse is object;
|
|
44
|
+
*
|
|
45
|
+
* op listPets(): Pet[] | PetStoreResponse;
|
|
46
|
+
* ```
|
|
47
|
+
*/
|
|
48
|
+
extern dec defaultResponse(target: object);
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Specify the OpenAPI `externalDocs` property for this type.
|
|
52
|
+
*
|
|
53
|
+
* @param url Url to the docs
|
|
54
|
+
* @param description Description of the docs
|
|
55
|
+
*
|
|
56
|
+
* @example
|
|
57
|
+
* ```typespec
|
|
58
|
+
* @externalDocs("https://example.com/detailed.md", "Detailed information on how to use this operation")
|
|
59
|
+
* op listPets(): Pet[];
|
|
60
|
+
* ```
|
|
61
|
+
*/
|
|
62
|
+
extern dec externalDocs(target: unknown, url: string, description?: string);
|
package/lib/main.tsp
ADDED
package/package.json
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@typespec/openapi",
|
|
3
|
+
"version": "0.41.0",
|
|
4
|
+
"author": "Microsoft Corporation",
|
|
5
|
+
"description": "TypeSpec library providing OpenAPI concepts",
|
|
6
|
+
"homepage": "https://microsoft.github.io/typespec",
|
|
7
|
+
"readme": "https://github.com/Azure/typespec/blob/master/README.md",
|
|
8
|
+
"license": "MIT",
|
|
9
|
+
"repository": {
|
|
10
|
+
"type": "git",
|
|
11
|
+
"url": "git+https://github.com/Azure/typespec.git"
|
|
12
|
+
},
|
|
13
|
+
"bugs": {
|
|
14
|
+
"url": "https://github.com/Azure/typespec/issues"
|
|
15
|
+
},
|
|
16
|
+
"keywords": [
|
|
17
|
+
"typespec"
|
|
18
|
+
],
|
|
19
|
+
"type": "module",
|
|
20
|
+
"main": "dist/src/index.js",
|
|
21
|
+
"tspMain": "lib/main.tsp",
|
|
22
|
+
"exports": {
|
|
23
|
+
".": "./dist/src/index.js",
|
|
24
|
+
"./testing": "./dist/src/testing/index.js"
|
|
25
|
+
},
|
|
26
|
+
"typesVersions": {
|
|
27
|
+
"*": {
|
|
28
|
+
"*": [
|
|
29
|
+
"./dist/src/index.d.ts"
|
|
30
|
+
],
|
|
31
|
+
"testing": [
|
|
32
|
+
"./dist/src/testing/index.d.ts"
|
|
33
|
+
]
|
|
34
|
+
}
|
|
35
|
+
},
|
|
36
|
+
"engines": {
|
|
37
|
+
"node": ">=16.0.0"
|
|
38
|
+
},
|
|
39
|
+
"files": [
|
|
40
|
+
"lib/*.tsp",
|
|
41
|
+
"dist/**",
|
|
42
|
+
"!dist/test/**"
|
|
43
|
+
],
|
|
44
|
+
"peerDependencies": {
|
|
45
|
+
"@typespec/compiler": "~0.41.0",
|
|
46
|
+
"@typespec/http": "~0.41.0",
|
|
47
|
+
"@typespec/rest": "~0.41.0"
|
|
48
|
+
},
|
|
49
|
+
"devDependencies": {
|
|
50
|
+
"@types/mocha": "~10.0.0",
|
|
51
|
+
"@types/node": "~18.11.9",
|
|
52
|
+
"@typespec/compiler": "~0.41.0",
|
|
53
|
+
"@typespec/http": "~0.41.0",
|
|
54
|
+
"@typespec/rest": "~0.41.0",
|
|
55
|
+
"@typespec/eslint-config-typespec": "~0.6.0",
|
|
56
|
+
"@typespec/library-linter": "~0.41.0",
|
|
57
|
+
"@typespec/eslint-plugin": "~0.41.0",
|
|
58
|
+
"eslint": "^8.12.0",
|
|
59
|
+
"mocha": "~10.1.0",
|
|
60
|
+
"mocha-junit-reporter": "~2.2.0",
|
|
61
|
+
"mocha-multi-reporters": "~1.5.1",
|
|
62
|
+
"c8": "~7.12.0",
|
|
63
|
+
"rimraf": "~3.0.2",
|
|
64
|
+
"typescript": "~4.9.3"
|
|
65
|
+
},
|
|
66
|
+
"scripts": {
|
|
67
|
+
"clean": "rimraf ./dist ./temp",
|
|
68
|
+
"build": "tsc -p . && npm run lint-typespec-library",
|
|
69
|
+
"watch": "tsc -p . --watch",
|
|
70
|
+
"lint-typespec-library": "tsp compile . --warn-as-error --import @typespec/library-linter --no-emit",
|
|
71
|
+
"test": "mocha",
|
|
72
|
+
"test-official": "c8 mocha --forbid-only --reporter mocha-multi-reporters",
|
|
73
|
+
"lint": "eslint . --ext .ts --max-warnings=0",
|
|
74
|
+
"lint:fix": "eslint . --fix --ext .ts"
|
|
75
|
+
}
|
|
76
|
+
}
|