@typespec/rest 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/LICENSE +21 -0
- package/README.md +134 -0
- package/dist/src/index.d.ts +5 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +5 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/internal-decorators.d.ts +5 -0
- package/dist/src/internal-decorators.d.ts.map +1 -0
- package/dist/src/internal-decorators.js +43 -0
- package/dist/src/internal-decorators.js.map +1 -0
- package/dist/src/lib.d.ts +84 -0
- package/dist/src/lib.d.ts.map +1 -0
- package/dist/src/lib.js +40 -0
- package/dist/src/lib.js.map +1 -0
- package/dist/src/resource.d.ts +22 -0
- package/dist/src/resource.d.ts.map +1 -0
- package/dist/src/resource.js +140 -0
- package/dist/src/resource.js.map +1 -0
- package/dist/src/rest.d.ts +74 -0
- package/dist/src/rest.d.ts.map +1 -0
- package/dist/src/rest.js +318 -0
- package/dist/src/rest.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/validate.d.ts +3 -0
- package/dist/src/validate.d.ts.map +1 -0
- package/dist/src/validate.js +54 -0
- package/dist/src/validate.js.map +1 -0
- package/lib/resource.tsp +280 -0
- package/lib/rest-decorators.tsp +112 -0
- package/lib/rest.tsp +9 -0
- package/package.json +73 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) Microsoft Corporation. All rights reserved.
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE
|
package/README.md
ADDED
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
# TypeSpec REST Library
|
|
2
|
+
|
|
3
|
+
This package provides [TypeSpec](https://github.com/microsoft/TypeSpec) decorators, models, and interfaces to describe APIs using the [REST style](https://en.wikipedia.org/wiki/Representational_state_transfer). These building blocks make defining REST resources and operations based on standard patterns extremely simple.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
In your TypeSpec project root
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npm install @typespec/rest
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Usage
|
|
14
|
+
|
|
15
|
+
```TypeSpec
|
|
16
|
+
import "@typespec/rest";
|
|
17
|
+
|
|
18
|
+
using TypeSpec.Rest;
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
See [Http and rest](https://microsoft.github.io/typespec/docs/standard-library/rest/).
|
|
22
|
+
|
|
23
|
+
## Library Tour
|
|
24
|
+
|
|
25
|
+
`@typespec/rest` library defines of the following artifacts:
|
|
26
|
+
|
|
27
|
+
- [TypeSpec HTTP/Rest Library](#typespec-httprest-library)
|
|
28
|
+
- [Install](#install)
|
|
29
|
+
- [Usage](#usage)
|
|
30
|
+
- [Library Tour](#library-tour)
|
|
31
|
+
- [Models](#models)
|
|
32
|
+
- [Decorators](#decorators)
|
|
33
|
+
- [Interfaces](#interfaces)
|
|
34
|
+
- [See also](#see-also)
|
|
35
|
+
|
|
36
|
+
## Models
|
|
37
|
+
|
|
38
|
+
| Model | Notes |
|
|
39
|
+
| ------------------------------------------ | ----------------------------------------------------------------------------------------------------------- |
|
|
40
|
+
| KeysOf<T> | Dynamically gathers keys of the model type T. |
|
|
41
|
+
| Page<T> | A model defines page of T which includes an array of T and optional next link. |
|
|
42
|
+
| ParentKeysOf<T> | Dynamically gathers parent keys of the model type T, which are referenced with `@parentResource` decorator. |
|
|
43
|
+
| ResourceError | The default error response for resource operations that includes <br> `code: int32` and `message string`. |
|
|
44
|
+
| ResourceParameters<TResource> | Represents operation parameters for resource TResource. Default to KeysOf<T>. |
|
|
45
|
+
| ResourceCollectionParameters<TResource> | Represents collection operation parameters for resource TResource. Default to ParentKeysOf<T> |
|
|
46
|
+
| ResourceCreatedResponse<T> | Resource create operation completed successfully. |
|
|
47
|
+
| ResourceDeletedResponse | Resource deleted successfully. |
|
|
48
|
+
|
|
49
|
+
## Decorators
|
|
50
|
+
|
|
51
|
+
The `@typespec/rest` library defines the following decorators in `TypeSpec.Rest` namespace:
|
|
52
|
+
|
|
53
|
+
| Declarator | Scope | Syntax |
|
|
54
|
+
| ------------------------- | ----------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
55
|
+
| @discriminator | models | Syntax:<br> `@discriminator(kindString)` <br><br>Note:<br> `@discriminator` allows defining polymorphic models to be used by API as parameters and return types. In many strongly typed languages, they are expressed as inheritance. |
|
|
56
|
+
| @resource | Model | Syntax:<br> `@resource(collectionName)` <br><br>Note:<br> This decorator is to used to mark a model as a resource type with a name for the type's collection. |
|
|
57
|
+
| @readsResource | operations | Syntax:<br> `@readsResource(modelType)` <br><br>Note:<br> This decorator is to used to signal the operation that is the Read operation for a particular resource. |
|
|
58
|
+
| @createsResource | operations | Syntax:<br> `@createsResource(modelType)` <br><br>Note:<br> This decorator is to used to signal the operation that is the Create operation for a particular resource. |
|
|
59
|
+
| @createsOrUpdatesResource | operations | Syntax:<br> `@createsOrUpdatesResource(modelType)` <br><br>Note:<br> This decorator is to used to signal the operation that is the CreatesOrUpdate operation for a particular resource. |
|
|
60
|
+
| @updatesResource | operations | Syntax:<br> `@updatesResource(modelType)` <br><br>Note:<br> This decorator is to used to signal the operation that is the Update operation for a particular resource. |
|
|
61
|
+
| @deletesResource | operations | Syntax:<br> `@deletesResource(modelType)` <br><br>Note:<br> This decorator is to used to signal the operation that is the Delete operation for a particular resource. |
|
|
62
|
+
| @listsResource | operations | Syntax:<br> `@listsResource(modelType)` <br><br>Note:<br> This decorator is to used to signal the operation that is the List operation for a particular resource. |
|
|
63
|
+
| @parentResource | models | Syntax:<br> `@parentResource(parentModelTypeReference)` <br><br>Note:<br> `@parentResource` marks a model property with a reference to its parent resource type. The first argument should be a reference to a model type which will be treated as the parent type of the target model type. This will cause the `@key` properties of all parent types of the target type to show up in operations of the `Resource*<T>` interfaces defined in this library. |
|
|
64
|
+
| @segment | model properties, operation parameters | Syntax:<br> `@segment(segmentString)` <br><br>Note:<br>`@segment` defines the preceding path segment for a `@path` parameter in auto-generated routes. The first argument should be a string that will be inserted into the operation route before the path parameter's name field. For example: <br> `op getUser(@path @segment("users") userId: string): User` <br> will produce the route `/users/{userId}`. |
|
|
65
|
+
| @segmentOf | models | Syntax:<br> `@segment(segmentString)` <br><br>Note:<br>`@segmentOf` returns the URL segment of a given model if it has `@segment` and `@key` decorator. |
|
|
66
|
+
| @segmentSeparator | model properties, operation parameters, or operations | Syntax:<br> `@segmentSeparator(separatorString)` <br><br>Note:<br> `@segmentSeparator` defines the separator string that is inserted between the target's `@segment` and the preceding route path in auto-generated routes. <br> The first argument should be a string that will be inserted into the operation route before the target's `@segment` value. Can be a string of any length. Defaults to `/`. |
|
|
67
|
+
| @actionSeparator | model properties, operation parameters, or operations | Syntax:<br> `@actionSeparator(separatorString)` <br><br>Note:<br> `@actionSeparator` defines the separator string that is inserted before the action name in auto-generated routes for actions. |
|
|
68
|
+
| @autoRoute | operations | Syntax:<br> `@autoRoute()` <br><br>Note:<br>`@autoRoute` enables automatic route generation for an operation, namespace, or interface. <br> When applied to an operation, it automatically generates the operation's route based on path parameter metadata. When applied to a namespace or interface, it causes all operations under that scope to have auto-generated routes. |
|
|
69
|
+
|
|
70
|
+
## Interfaces
|
|
71
|
+
|
|
72
|
+
These standard interfaces defines resource operations in basic building blocks that you can expose on the resources. You can use `extends` to compose the operations to meet the exact needs of your resource APIs.
|
|
73
|
+
|
|
74
|
+
For example, for below `Widget` model
|
|
75
|
+
|
|
76
|
+
```
|
|
77
|
+
@resource("widgets")
|
|
78
|
+
model Widget {
|
|
79
|
+
@key id: string;
|
|
80
|
+
name: string;
|
|
81
|
+
}
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
- `Widget` resource supports full CRUDL operations.
|
|
85
|
+
|
|
86
|
+
```TypeSpec
|
|
87
|
+
interface WidgetService extends Resource.ResourceOperations<Widget, Error>;
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
- `Widget` resource supports only CRD operations.
|
|
91
|
+
|
|
92
|
+
```TypeSpec
|
|
93
|
+
interface WidgetService
|
|
94
|
+
extends Resource.ResourceRead<Widget, Error>,
|
|
95
|
+
Resource.ResourceCreate<Widget, Error>,
|
|
96
|
+
Resource.ResourceDelete<Widget, Error> {
|
|
97
|
+
}
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
-
|
|
101
|
+
|
|
102
|
+
| Interfaces | Notes |
|
|
103
|
+
| ----------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------- |
|
|
104
|
+
| ResourceRead<TResource, TError> | Resource GET operation |
|
|
105
|
+
| ResourceCreateOrUpdate<TResource, TError> | Resource PUT operation |
|
|
106
|
+
| ResourceCreate<TResource, TError> | Resource POST operation |
|
|
107
|
+
| ResourceUpdate<TResource, TError> | Resource PATCH operation |
|
|
108
|
+
| ResourceDelete<TResource, TError> | Resource DEL operation |
|
|
109
|
+
| ResourceList<TResource, TError> | Resource LIST operation which is a GET operation from a parent resource. |
|
|
110
|
+
| ResourceInstanceOperations<TResource, TError> | Combines resource GET + PATCH + DEL operations |
|
|
111
|
+
| ResourceCollectionOperations<TResource, TError> | Combines resource POST + LIST operations |
|
|
112
|
+
| ResourceOperations<TResource, TError> | Combines resource instance and collection operations. Includes GET + PATCH + DEL + POST + LIST |
|
|
113
|
+
| SingletonResourceRead<TSingleton, TResource, TError> | Singleton resource GET operation. |
|
|
114
|
+
| SingletonResourceUpdate<TSingleton, TResource, TError> | Singleton resource PATCH operation. |
|
|
115
|
+
| SingletonResourceOperations<TSingleton, TResource, TError> | Combines resource GET + PATCH operations |
|
|
116
|
+
| ExtensionResourceRead<TExtension, TResource, TError> | Extension resource GET operation. |
|
|
117
|
+
| ExtensionResourceCreateOrUpdate<TExtension, TResource, TError> | Extension resource PUT operation |
|
|
118
|
+
| ExtensionResourceCreate<TExtension, TResource, TError> | Extension resource POST operation |
|
|
119
|
+
| ExtensionResourceUpdate<TExtension, TResource, TError> | Extension resource PATCH operation |
|
|
120
|
+
| ExtensionResourceDelete<TExtension, TResource, TError> | Extension resource GET operation |
|
|
121
|
+
| ExtensionResourceList<TExtension, TResource, TError> | Extension resource LIST operation which is a GET operation from a parent resource. |
|
|
122
|
+
| ExtensionResourceInstanceOperations<TExtension, TResource, TError> | Combines extension resource GET + PATCH + DEL operations. |
|
|
123
|
+
| ExtensionResourceCollectionOperations<TExtension, TResource, TError> | Combines extension resource POST + LIST operations. |
|
|
124
|
+
| ExtensionResourceOperations<TExtension, TResource, TError> | Combines extension resource instance and collection operations. Includes GET + PATCH + DEL + POST + LIST operations. |
|
|
125
|
+
|
|
126
|
+
## See also
|
|
127
|
+
|
|
128
|
+
- [REST example](https://cadlplayground.z22.web.core.windows.net/?c=aW1wb3J0ICJAY2FkbC1sYW5nL3Jlc3QiOwoKQHNlcnZpY2VUaXRsZSgiV2lkZ2V0IFPGFSIpCm5hbWVzcGFjZSBEZW1vxxg7Cgp1c2luZyBDYWRsLkh0dHA7zBFSZXN0OwoKbW9kZWwgx1J7CiAgQGtleSBpZDogc3RyaW5nOwogIHdlaWdodDogaW50MzLEEWNvbG9yOiAicmVkIiB8ICJibHVlIjsKfQoKQGVycm9yx1ZFxAzFVWNvZGXLQG1lc3NhZ2XKZH0KCmludGVyZuQAxOYAjecAxiBleHRlbmRzIFJlc291cmNl5AC5xQlPcGVyYXRpb25zPMYyLMZxPsVyQOQA0EByb3V0ZSgiY3VzdG9tR2V0IikgyQwoKTrHa%2BQAgA%3D%3D):
|
|
129
|
+
- [TypeSpec Getting Started](https://github.com/microsoft/typespec#getting-started)
|
|
130
|
+
- [TypeSpec Website](https://microsoft.github.io/typespec)
|
|
131
|
+
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
```
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,SAAS,kBAAkB,CAAC;AACzC,cAAc,eAAe,CAAC;AAC9B,cAAc,WAAW,CAAC;AAC1B,cAAc,eAAe,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,SAAS,GAAG,eAAe,CAAC;AACzC,cAAc,eAAe,CAAC;AAC9B,cAAc,WAAW,CAAC;AAC1B,cAAc,eAAe,CAAC"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { DecoratorContext, Type } from "@typespec/compiler";
|
|
2
|
+
export declare const namespace = "TypeSpec.Rest.Private";
|
|
3
|
+
export declare function $validateHasKey(context: DecoratorContext, target: Type, value: Type): void;
|
|
4
|
+
export declare function $validateIsError(context: DecoratorContext, target: Type, value: Type): void;
|
|
5
|
+
//# sourceMappingURL=internal-decorators.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"internal-decorators.d.ts","sourceRoot":"","sources":["../../src/internal-decorators.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,gBAAgB,EAEhB,IAAI,EAEL,MAAM,oBAAoB,CAAC;AAI5B,eAAO,MAAM,SAAS,0BAA0B,CAAC;AAIjD,wBAAgB,eAAe,CAAC,OAAO,EAAE,gBAAgB,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,QAgBnF;AAID,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,gBAAgB,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,QAgBpF"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { isErrorModel, validateDecoratorParamType, } from "@typespec/compiler";
|
|
2
|
+
import { createStateSymbol, reportDiagnostic } from "./lib.js";
|
|
3
|
+
import { getResourceTypeKey } from "./resource.js";
|
|
4
|
+
export const namespace = "TypeSpec.Rest.Private";
|
|
5
|
+
const validatedMissingKey = createStateSymbol("validatedMissing");
|
|
6
|
+
// Workaround for the lack of template constraints https://github.com/microsoft/typespec/issues/377
|
|
7
|
+
export function $validateHasKey(context, target, value) {
|
|
8
|
+
if (!validateDecoratorParamType(context.program, target, value, "Model")) {
|
|
9
|
+
return;
|
|
10
|
+
}
|
|
11
|
+
if (context.program.stateSet(validatedMissingKey).has(value)) {
|
|
12
|
+
return;
|
|
13
|
+
}
|
|
14
|
+
const resourceKey = getResourceTypeKey(context.program, value);
|
|
15
|
+
if (resourceKey === undefined) {
|
|
16
|
+
reportDiagnostic(context.program, {
|
|
17
|
+
code: "resource-missing-key",
|
|
18
|
+
format: { modelName: value.name },
|
|
19
|
+
target: value,
|
|
20
|
+
});
|
|
21
|
+
context.program.stateSet(validatedMissingKey).add(value);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
const validatedErrorKey = createStateSymbol("validatedError");
|
|
25
|
+
// Workaround for the lack of template constraints https://github.com/microsoft/typespec/issues/377
|
|
26
|
+
export function $validateIsError(context, target, value) {
|
|
27
|
+
if (!validateDecoratorParamType(context.program, target, value, "Model")) {
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
if (context.program.stateSet(validatedErrorKey).has(value)) {
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
const isError = isErrorModel(context.program, value);
|
|
34
|
+
if (!isError) {
|
|
35
|
+
reportDiagnostic(context.program, {
|
|
36
|
+
code: "resource-missing-error",
|
|
37
|
+
format: { modelName: value.name },
|
|
38
|
+
target: value,
|
|
39
|
+
});
|
|
40
|
+
context.program.stateSet(validatedErrorKey).add(value);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=internal-decorators.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"internal-decorators.js","sourceRoot":"","sources":["../../src/internal-decorators.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,YAAY,EAEZ,0BAA0B,GAC3B,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAC/D,OAAO,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AAEnD,MAAM,CAAC,MAAM,SAAS,GAAG,uBAAuB,CAAC;AAEjD,MAAM,mBAAmB,GAAG,iBAAiB,CAAC,kBAAkB,CAAC,CAAC;AAClE,mGAAmG;AACnG,MAAM,UAAU,eAAe,CAAC,OAAyB,EAAE,MAAY,EAAE,KAAW;IAClF,IAAI,CAAC,0BAA0B,CAAC,OAAO,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,CAAC,EAAE;QACxE,OAAO;KACR;IACD,IAAI,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE;QAC5D,OAAO;KACR;IACD,MAAM,WAAW,GAAG,kBAAkB,CAAC,OAAO,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;IAC/D,IAAI,WAAW,KAAK,SAAS,EAAE;QAC7B,gBAAgB,CAAC,OAAO,CAAC,OAAO,EAAE;YAChC,IAAI,EAAE,sBAAsB;YAC5B,MAAM,EAAE,EAAE,SAAS,EAAE,KAAK,CAAC,IAAI,EAAE;YACjC,MAAM,EAAE,KAAK;SACd,CAAC,CAAC;QACH,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;KAC1D;AACH,CAAC;AAED,MAAM,iBAAiB,GAAG,iBAAiB,CAAC,gBAAgB,CAAC,CAAC;AAC9D,mGAAmG;AACnG,MAAM,UAAU,gBAAgB,CAAC,OAAyB,EAAE,MAAY,EAAE,KAAW;IACnF,IAAI,CAAC,0BAA0B,CAAC,OAAO,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,CAAC,EAAE;QACxE,OAAO;KACR;IACD,IAAI,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE;QAC1D,OAAO;KACR;IACD,MAAM,OAAO,GAAG,YAAY,CAAC,OAAO,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;IACrD,IAAI,CAAC,OAAO,EAAE;QACZ,gBAAgB,CAAC,OAAO,CAAC,OAAO,EAAE;YAChC,IAAI,EAAE,wBAAwB;YAC9B,MAAM,EAAE,EAAE,SAAS,EAAE,KAAK,CAAC,IAAI,EAAE;YACjC,MAAM,EAAE,KAAK;SACd,CAAC,CAAC;QACH,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;KACxD;AACH,CAAC"}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
declare const restLib: import("@typespec/compiler").TypeSpecLibrary<{
|
|
2
|
+
"not-key-type": {
|
|
3
|
+
readonly default: "Cannot copy keys from a non-key type (KeysOf<T> or ParentKeysOf<T>)";
|
|
4
|
+
};
|
|
5
|
+
"resource-missing-key": {
|
|
6
|
+
readonly default: import("@typespec/compiler").CallableMessage<["modelName"]>;
|
|
7
|
+
};
|
|
8
|
+
"resource-missing-error": {
|
|
9
|
+
readonly default: import("@typespec/compiler").CallableMessage<["modelName"]>;
|
|
10
|
+
};
|
|
11
|
+
"duplicate-key": {
|
|
12
|
+
readonly default: import("@typespec/compiler").CallableMessage<["resourceName"]>;
|
|
13
|
+
};
|
|
14
|
+
"duplicate-parent-key": {
|
|
15
|
+
readonly default: import("@typespec/compiler").CallableMessage<["resourceName", "keyName"]>;
|
|
16
|
+
};
|
|
17
|
+
}, Record<string, any>>;
|
|
18
|
+
declare const reportDiagnostic: <C extends "not-key-type" | "resource-missing-key" | "resource-missing-error" | "duplicate-key" | "duplicate-parent-key", M extends keyof {
|
|
19
|
+
"not-key-type": {
|
|
20
|
+
readonly default: "Cannot copy keys from a non-key type (KeysOf<T> or ParentKeysOf<T>)";
|
|
21
|
+
};
|
|
22
|
+
"resource-missing-key": {
|
|
23
|
+
readonly default: import("@typespec/compiler").CallableMessage<["modelName"]>;
|
|
24
|
+
};
|
|
25
|
+
"resource-missing-error": {
|
|
26
|
+
readonly default: import("@typespec/compiler").CallableMessage<["modelName"]>;
|
|
27
|
+
};
|
|
28
|
+
"duplicate-key": {
|
|
29
|
+
readonly default: import("@typespec/compiler").CallableMessage<["resourceName"]>;
|
|
30
|
+
};
|
|
31
|
+
"duplicate-parent-key": {
|
|
32
|
+
readonly default: import("@typespec/compiler").CallableMessage<["resourceName", "keyName"]>;
|
|
33
|
+
};
|
|
34
|
+
}[C]>(program: import("@typespec/compiler").Program, diag: import("@typespec/compiler").DiagnosticReport<{
|
|
35
|
+
"not-key-type": {
|
|
36
|
+
readonly default: "Cannot copy keys from a non-key type (KeysOf<T> or ParentKeysOf<T>)";
|
|
37
|
+
};
|
|
38
|
+
"resource-missing-key": {
|
|
39
|
+
readonly default: import("@typespec/compiler").CallableMessage<["modelName"]>;
|
|
40
|
+
};
|
|
41
|
+
"resource-missing-error": {
|
|
42
|
+
readonly default: import("@typespec/compiler").CallableMessage<["modelName"]>;
|
|
43
|
+
};
|
|
44
|
+
"duplicate-key": {
|
|
45
|
+
readonly default: import("@typespec/compiler").CallableMessage<["resourceName"]>;
|
|
46
|
+
};
|
|
47
|
+
"duplicate-parent-key": {
|
|
48
|
+
readonly default: import("@typespec/compiler").CallableMessage<["resourceName", "keyName"]>;
|
|
49
|
+
};
|
|
50
|
+
}, C, M>) => void, createDiagnostic: <C extends "not-key-type" | "resource-missing-key" | "resource-missing-error" | "duplicate-key" | "duplicate-parent-key", M extends keyof {
|
|
51
|
+
"not-key-type": {
|
|
52
|
+
readonly default: "Cannot copy keys from a non-key type (KeysOf<T> or ParentKeysOf<T>)";
|
|
53
|
+
};
|
|
54
|
+
"resource-missing-key": {
|
|
55
|
+
readonly default: import("@typespec/compiler").CallableMessage<["modelName"]>;
|
|
56
|
+
};
|
|
57
|
+
"resource-missing-error": {
|
|
58
|
+
readonly default: import("@typespec/compiler").CallableMessage<["modelName"]>;
|
|
59
|
+
};
|
|
60
|
+
"duplicate-key": {
|
|
61
|
+
readonly default: import("@typespec/compiler").CallableMessage<["resourceName"]>;
|
|
62
|
+
};
|
|
63
|
+
"duplicate-parent-key": {
|
|
64
|
+
readonly default: import("@typespec/compiler").CallableMessage<["resourceName", "keyName"]>;
|
|
65
|
+
};
|
|
66
|
+
}[C]>(diag: import("@typespec/compiler").DiagnosticReport<{
|
|
67
|
+
"not-key-type": {
|
|
68
|
+
readonly default: "Cannot copy keys from a non-key type (KeysOf<T> or ParentKeysOf<T>)";
|
|
69
|
+
};
|
|
70
|
+
"resource-missing-key": {
|
|
71
|
+
readonly default: import("@typespec/compiler").CallableMessage<["modelName"]>;
|
|
72
|
+
};
|
|
73
|
+
"resource-missing-error": {
|
|
74
|
+
readonly default: import("@typespec/compiler").CallableMessage<["modelName"]>;
|
|
75
|
+
};
|
|
76
|
+
"duplicate-key": {
|
|
77
|
+
readonly default: import("@typespec/compiler").CallableMessage<["resourceName"]>;
|
|
78
|
+
};
|
|
79
|
+
"duplicate-parent-key": {
|
|
80
|
+
readonly default: import("@typespec/compiler").CallableMessage<["resourceName", "keyName"]>;
|
|
81
|
+
};
|
|
82
|
+
}, C, M>) => import("@typespec/compiler").Diagnostic, createStateSymbol: (name: string) => symbol;
|
|
83
|
+
export { restLib, reportDiagnostic, createDiagnostic, createStateSymbol };
|
|
84
|
+
//# sourceMappingURL=lib.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lib.d.ts","sourceRoot":"","sources":["../../src/lib.ts"],"names":[],"mappings":"AAsCA,QAAA,MAAM,OAAO;;;;;;;;;;;;;;;;uBAAuC,CAAC;AACrD,QAAA,MAAQ,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;mBAAE,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;sDAAE,iBAAiB,0BAAY,CAAC;AAE1E,OAAO,EAAE,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,CAAC"}
|
package/dist/src/lib.js
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { createTypeSpecLibrary, paramMessage } from "@typespec/compiler";
|
|
2
|
+
const libDefinition = {
|
|
3
|
+
name: "@typespec/rest",
|
|
4
|
+
diagnostics: {
|
|
5
|
+
"not-key-type": {
|
|
6
|
+
severity: "error",
|
|
7
|
+
messages: {
|
|
8
|
+
default: "Cannot copy keys from a non-key type (KeysOf<T> or ParentKeysOf<T>)",
|
|
9
|
+
},
|
|
10
|
+
},
|
|
11
|
+
"resource-missing-key": {
|
|
12
|
+
severity: "error",
|
|
13
|
+
messages: {
|
|
14
|
+
default: paramMessage `Type '${"modelName"}' is used as a resource and therefore must have a key. Use @key to designate a property as the key.`,
|
|
15
|
+
},
|
|
16
|
+
},
|
|
17
|
+
"resource-missing-error": {
|
|
18
|
+
severity: "error",
|
|
19
|
+
messages: {
|
|
20
|
+
default: paramMessage `Type '${"modelName"}' is used as an error and therefore must have the @error decorator applied.`,
|
|
21
|
+
},
|
|
22
|
+
},
|
|
23
|
+
"duplicate-key": {
|
|
24
|
+
severity: "error",
|
|
25
|
+
messages: {
|
|
26
|
+
default: paramMessage `More than one key found on model type ${"resourceName"}`,
|
|
27
|
+
},
|
|
28
|
+
},
|
|
29
|
+
"duplicate-parent-key": {
|
|
30
|
+
severity: "error",
|
|
31
|
+
messages: {
|
|
32
|
+
default: paramMessage `Resource type '${"resourceName"}' has a key property named '${"keyName"}' which conflicts with the key name of a parent or child resource.`,
|
|
33
|
+
},
|
|
34
|
+
},
|
|
35
|
+
},
|
|
36
|
+
};
|
|
37
|
+
const restLib = createTypeSpecLibrary(libDefinition);
|
|
38
|
+
const { reportDiagnostic, createDiagnostic, createStateSymbol } = restLib;
|
|
39
|
+
export { restLib, reportDiagnostic, createDiagnostic, createStateSymbol };
|
|
40
|
+
//# 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,aAAa,GAAG;IACpB,IAAI,EAAE,gBAAgB;IACtB,WAAW,EAAE;QACX,cAAc,EAAE;YACd,QAAQ,EAAE,OAAO;YACjB,QAAQ,EAAE;gBACR,OAAO,EAAE,qEAAqE;aAC/E;SACF;QACD,sBAAsB,EAAE;YACtB,QAAQ,EAAE,OAAO;YACjB,QAAQ,EAAE;gBACR,OAAO,EAAE,YAAY,CAAA,SAAS,WAAW,qGAAqG;aAC/I;SACF;QACD,wBAAwB,EAAE;YACxB,QAAQ,EAAE,OAAO;YACjB,QAAQ,EAAE;gBACR,OAAO,EAAE,YAAY,CAAA,SAAS,WAAW,6EAA6E;aACvH;SACF;QACD,eAAe,EAAE;YACf,QAAQ,EAAE,OAAO;YACjB,QAAQ,EAAE;gBACR,OAAO,EAAE,YAAY,CAAA,yCAAyC,cAAc,EAAE;aAC/E;SACF;QACD,sBAAsB,EAAE;YACtB,QAAQ,EAAE,OAAO;YACjB,QAAQ,EAAE;gBACR,OAAO,EAAE,YAAY,CAAA,kBAAkB,cAAc,+BAA+B,SAAS,oEAAoE;aAClK;SACF;KACF;CACO,CAAC;AAEX,MAAM,OAAO,GAAG,qBAAqB,CAAC,aAAa,CAAC,CAAC;AACrD,MAAM,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,GAAG,OAAO,CAAC;AAE1E,OAAO,EAAE,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,CAAC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { DecoratorContext, Model, ModelProperty, Program, Type } from "@typespec/compiler";
|
|
2
|
+
export interface ResourceKey {
|
|
3
|
+
resourceType: Model;
|
|
4
|
+
keyProperty: ModelProperty;
|
|
5
|
+
}
|
|
6
|
+
export declare function setResourceTypeKey(program: Program, resourceType: Model, keyProperty: ModelProperty): void;
|
|
7
|
+
export declare function getResourceTypeKey(program: Program, resourceType: Model): ResourceKey | undefined;
|
|
8
|
+
export declare function $resourceTypeForKeyParam(context: DecoratorContext, entity: Type, resourceType: Type): void;
|
|
9
|
+
export declare function getResourceTypeForKeyParam(program: Program, param: ModelProperty): Model | undefined;
|
|
10
|
+
export declare function $copyResourceKeyParameters(context: DecoratorContext, entity: Type, filter?: string): void;
|
|
11
|
+
export declare function getParentResource(program: Program, resourceType: Model): Model | undefined;
|
|
12
|
+
/**
|
|
13
|
+
* `@parentResource` marks a model with a reference to its parent resource type
|
|
14
|
+
*
|
|
15
|
+
* The first argument should be a reference to a model type which will be treated as the parent
|
|
16
|
+
* type of the target model type. This will cause the `@key` properties of all parent types of
|
|
17
|
+
* the target type to show up in operations of the `Resource*<T>` interfaces defined in this library.
|
|
18
|
+
*
|
|
19
|
+
* `@parentResource` can only be applied to models.
|
|
20
|
+
*/
|
|
21
|
+
export declare function $parentResource(context: DecoratorContext, entity: Type, parentType: Type): void;
|
|
22
|
+
//# sourceMappingURL=resource.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resource.d.ts","sourceRoot":"","sources":["../../src/resource.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,gBAAgB,EAIhB,KAAK,EACL,aAAa,EACb,OAAO,EACP,IAAI,EAEL,MAAM,oBAAoB,CAAC;AAI5B,MAAM,WAAW,WAAW;IAC1B,YAAY,EAAE,KAAK,CAAC;IACpB,WAAW,EAAE,aAAa,CAAC;CAC5B;AAKD,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,OAAO,EAChB,YAAY,EAAE,KAAK,EACnB,WAAW,EAAE,aAAa,GACzB,IAAI,CAKN;AAED,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,OAAO,EAAE,YAAY,EAAE,KAAK,GAAG,WAAW,GAAG,SAAS,CA+BjG;AAED,wBAAgB,wBAAwB,CACtC,OAAO,EAAE,gBAAgB,EACzB,MAAM,EAAE,IAAI,EACZ,YAAY,EAAE,IAAI,QAOnB;AAED,wBAAgB,0BAA0B,CACxC,OAAO,EAAE,OAAO,EAChB,KAAK,EAAE,aAAa,GACnB,KAAK,GAAG,SAAS,CAEnB;AA6CD,wBAAgB,0BAA0B,CACxC,OAAO,EAAE,gBAAgB,EACzB,MAAM,EAAE,IAAI,EACZ,MAAM,CAAC,EAAE,MAAM,QAmChB;AAGD,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,OAAO,EAAE,YAAY,EAAE,KAAK,GAAG,KAAK,GAAG,SAAS,CAE1F;AAED;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,gBAAgB,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,QAOxF"}
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
import { $visibility, getKeyName, isErrorType, isKey, validateDecoratorTarget, } from "@typespec/compiler";
|
|
2
|
+
import { $path } from "@typespec/http";
|
|
3
|
+
import { createStateSymbol, reportDiagnostic } from "./lib.js";
|
|
4
|
+
const resourceKeysKey = createStateSymbol("resourceKeys");
|
|
5
|
+
const resourceTypeForKeyParamKey = createStateSymbol("resourceTypeForKeyParam");
|
|
6
|
+
export function setResourceTypeKey(program, resourceType, keyProperty) {
|
|
7
|
+
program.stateMap(resourceKeysKey).set(resourceType, {
|
|
8
|
+
resourceType,
|
|
9
|
+
keyProperty,
|
|
10
|
+
});
|
|
11
|
+
}
|
|
12
|
+
export function getResourceTypeKey(program, resourceType) {
|
|
13
|
+
// Look up the key first
|
|
14
|
+
let resourceKey = program.stateMap(resourceKeysKey).get(resourceType);
|
|
15
|
+
if (resourceKey) {
|
|
16
|
+
return resourceKey;
|
|
17
|
+
}
|
|
18
|
+
// Try to find it in the resource type
|
|
19
|
+
resourceType.properties.forEach((p) => {
|
|
20
|
+
if (isKey(program, p)) {
|
|
21
|
+
if (resourceKey) {
|
|
22
|
+
reportDiagnostic(program, {
|
|
23
|
+
code: "duplicate-key",
|
|
24
|
+
format: {
|
|
25
|
+
resourceName: resourceType.name,
|
|
26
|
+
},
|
|
27
|
+
target: p,
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
else {
|
|
31
|
+
resourceKey = {
|
|
32
|
+
resourceType,
|
|
33
|
+
keyProperty: p,
|
|
34
|
+
};
|
|
35
|
+
// Cache the key for future queries
|
|
36
|
+
setResourceTypeKey(program, resourceType, resourceKey.keyProperty);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
return resourceKey;
|
|
41
|
+
}
|
|
42
|
+
export function $resourceTypeForKeyParam(context, entity, resourceType) {
|
|
43
|
+
if (!validateDecoratorTarget(context, entity, "@resourceTypeForKeyParam", "ModelProperty")) {
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
context.program.stateMap(resourceTypeForKeyParamKey).set(entity, resourceType);
|
|
47
|
+
}
|
|
48
|
+
export function getResourceTypeForKeyParam(program, param) {
|
|
49
|
+
return program.stateMap(resourceTypeForKeyParamKey).get(param);
|
|
50
|
+
}
|
|
51
|
+
function cloneKeyProperties(context, target, resourceType) {
|
|
52
|
+
const { program } = context;
|
|
53
|
+
// Add parent keys first
|
|
54
|
+
const parentType = getParentResource(program, resourceType);
|
|
55
|
+
if (parentType) {
|
|
56
|
+
cloneKeyProperties(context, target, parentType);
|
|
57
|
+
}
|
|
58
|
+
const resourceKey = getResourceTypeKey(program, resourceType);
|
|
59
|
+
if (resourceKey) {
|
|
60
|
+
const { keyProperty } = resourceKey;
|
|
61
|
+
const keyName = getKeyName(program, keyProperty);
|
|
62
|
+
const decorators = [
|
|
63
|
+
// Filter out the @visibility decorator because it might affect metadata
|
|
64
|
+
// filtering. NOTE: Check for name equality instead of function equality
|
|
65
|
+
// to deal with multiple copies of core being used.
|
|
66
|
+
...keyProperty.decorators.filter((d) => d.decorator.name !== $visibility.name),
|
|
67
|
+
{
|
|
68
|
+
decorator: $path,
|
|
69
|
+
args: [],
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
decorator: $resourceTypeForKeyParam,
|
|
73
|
+
args: [{ node: target.node, value: resourceType }],
|
|
74
|
+
},
|
|
75
|
+
];
|
|
76
|
+
// Clone the key property and ensure that an optional key property doesn't
|
|
77
|
+
// become an optional path parameter
|
|
78
|
+
const newProp = program.checker.cloneType(keyProperty, {
|
|
79
|
+
name: keyName,
|
|
80
|
+
decorators,
|
|
81
|
+
optional: false,
|
|
82
|
+
model: target,
|
|
83
|
+
sourceProperty: undefined,
|
|
84
|
+
});
|
|
85
|
+
// Add the key property to the target type
|
|
86
|
+
target.properties.set(keyName, newProp);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
export function $copyResourceKeyParameters(context, entity, filter) {
|
|
90
|
+
if (!validateDecoratorTarget(context, entity, "@copyResourceKeyParameters", "Model")) {
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
const reportNoKeyError = () => reportDiagnostic(context.program, {
|
|
94
|
+
code: "not-key-type",
|
|
95
|
+
target: entity,
|
|
96
|
+
});
|
|
97
|
+
const templateArguments = entity.templateArguments;
|
|
98
|
+
if (!templateArguments || templateArguments.length !== 1) {
|
|
99
|
+
return reportNoKeyError();
|
|
100
|
+
}
|
|
101
|
+
if (templateArguments[0].kind !== "Model") {
|
|
102
|
+
if (isErrorType(templateArguments[0])) {
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
return reportNoKeyError();
|
|
106
|
+
}
|
|
107
|
+
const resourceType = templateArguments[0];
|
|
108
|
+
if (filter === "parent") {
|
|
109
|
+
// Only copy keys of the parent type if there is one
|
|
110
|
+
const parentType = getParentResource(context.program, resourceType);
|
|
111
|
+
if (parentType) {
|
|
112
|
+
cloneKeyProperties(context, entity, parentType);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
else {
|
|
116
|
+
// Copy keys of the resource type and all parents
|
|
117
|
+
cloneKeyProperties(context, entity, resourceType);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
const parentResourceTypesKey = createStateSymbol("parentResourceTypes");
|
|
121
|
+
export function getParentResource(program, resourceType) {
|
|
122
|
+
return program.stateMap(parentResourceTypesKey).get(resourceType);
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* `@parentResource` marks a model with a reference to its parent resource type
|
|
126
|
+
*
|
|
127
|
+
* The first argument should be a reference to a model type which will be treated as the parent
|
|
128
|
+
* type of the target model type. This will cause the `@key` properties of all parent types of
|
|
129
|
+
* the target type to show up in operations of the `Resource*<T>` interfaces defined in this library.
|
|
130
|
+
*
|
|
131
|
+
* `@parentResource` can only be applied to models.
|
|
132
|
+
*/
|
|
133
|
+
export function $parentResource(context, entity, parentType) {
|
|
134
|
+
if (!validateDecoratorTarget(context, parentType, "@parentResource", "Model")) {
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
137
|
+
const { program } = context;
|
|
138
|
+
program.stateMap(parentResourceTypesKey).set(entity, parentType);
|
|
139
|
+
}
|
|
140
|
+
//# sourceMappingURL=resource.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resource.js","sourceRoot":"","sources":["../../src/resource.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,WAAW,EAEX,UAAU,EACV,WAAW,EACX,KAAK,EAKL,uBAAuB,GACxB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAC;AACvC,OAAO,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAO/D,MAAM,eAAe,GAAG,iBAAiB,CAAC,cAAc,CAAC,CAAC;AAC1D,MAAM,0BAA0B,GAAG,iBAAiB,CAAC,yBAAyB,CAAC,CAAC;AAEhF,MAAM,UAAU,kBAAkB,CAChC,OAAgB,EAChB,YAAmB,EACnB,WAA0B;IAE1B,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAC,CAAC,GAAG,CAAC,YAAY,EAAE;QAClD,YAAY;QACZ,WAAW;KACZ,CAAC,CAAC;AACL,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,OAAgB,EAAE,YAAmB;IACtE,wBAAwB;IACxB,IAAI,WAAW,GAAG,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAC,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;IACtE,IAAI,WAAW,EAAE;QACf,OAAO,WAAW,CAAC;KACpB;IAED,sCAAsC;IACtC,YAAY,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,CAAgB,EAAE,EAAE;QACnD,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC,EAAE;YACrB,IAAI,WAAW,EAAE;gBACf,gBAAgB,CAAC,OAAO,EAAE;oBACxB,IAAI,EAAE,eAAe;oBACrB,MAAM,EAAE;wBACN,YAAY,EAAE,YAAY,CAAC,IAAI;qBAChC;oBACD,MAAM,EAAE,CAAC;iBACV,CAAC,CAAC;aACJ;iBAAM;gBACL,WAAW,GAAG;oBACZ,YAAY;oBACZ,WAAW,EAAE,CAAC;iBACf,CAAC;gBAEF,mCAAmC;gBACnC,kBAAkB,CAAC,OAAO,EAAE,YAAY,EAAE,WAAW,CAAC,WAAW,CAAC,CAAC;aACpE;SACF;IACH,CAAC,CAAC,CAAC;IAEH,OAAO,WAAW,CAAC;AACrB,CAAC;AAED,MAAM,UAAU,wBAAwB,CACtC,OAAyB,EACzB,MAAY,EACZ,YAAkB;IAElB,IAAI,CAAC,uBAAuB,CAAC,OAAO,EAAE,MAAM,EAAE,0BAA0B,EAAE,eAAe,CAAC,EAAE;QAC1F,OAAO;KACR;IAED,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,0BAA0B,CAAC,CAAC,GAAG,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;AACjF,CAAC;AAED,MAAM,UAAU,0BAA0B,CACxC,OAAgB,EAChB,KAAoB;IAEpB,OAAO,OAAO,CAAC,QAAQ,CAAC,0BAA0B,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;AACjE,CAAC;AAED,SAAS,kBAAkB,CAAC,OAAyB,EAAE,MAAa,EAAE,YAAmB;IACvF,MAAM,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC;IAC5B,wBAAwB;IACxB,MAAM,UAAU,GAAG,iBAAiB,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC;IAC5D,IAAI,UAAU,EAAE;QACd,kBAAkB,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,CAAC,CAAC;KACjD;IAED,MAAM,WAAW,GAAG,kBAAkB,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC;IAC9D,IAAI,WAAW,EAAE;QACf,MAAM,EAAE,WAAW,EAAE,GAAG,WAAW,CAAC;QACpC,MAAM,OAAO,GAAG,UAAU,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC;QAEjD,MAAM,UAAU,GAAG;YACjB,wEAAwE;YACxE,wEAAwE;YACxE,mDAAmD;YACnD,GAAG,WAAW,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,IAAI,KAAK,WAAW,CAAC,IAAI,CAAC;YAC9E;gBACE,SAAS,EAAE,KAAK;gBAChB,IAAI,EAAE,EAAE;aACT;YACD;gBACE,SAAS,EAAE,wBAAwB;gBACnC,IAAI,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,KAAK,EAAE,YAAY,EAAE,CAAC;aACnD;SACF,CAAC;QAEF,0EAA0E;QAC1E,oCAAoC;QACpC,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,SAAS,CAAC,WAAW,EAAE;YACrD,IAAI,EAAE,OAAO;YACb,UAAU;YACV,QAAQ,EAAE,KAAK;YACf,KAAK,EAAE,MAAM;YACb,cAAc,EAAE,SAAS;SAC1B,CAAC,CAAC;QAEH,0CAA0C;QAC1C,MAAM,CAAC,UAAU,CAAC,GAAG,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;KACzC;AACH,CAAC;AAED,MAAM,UAAU,0BAA0B,CACxC,OAAyB,EACzB,MAAY,EACZ,MAAe;IAEf,IAAI,CAAC,uBAAuB,CAAC,OAAO,EAAE,MAAM,EAAE,4BAA4B,EAAE,OAAO,CAAC,EAAE;QACpF,OAAO;KACR;IAED,MAAM,gBAAgB,GAAG,GAAG,EAAE,CAC5B,gBAAgB,CAAC,OAAO,CAAC,OAAO,EAAE;QAChC,IAAI,EAAE,cAAc;QACpB,MAAM,EAAE,MAAM;KACf,CAAC,CAAC;IACL,MAAM,iBAAiB,GAAG,MAAM,CAAC,iBAAiB,CAAC;IACnD,IAAI,CAAC,iBAAiB,IAAI,iBAAiB,CAAC,MAAM,KAAK,CAAC,EAAE;QACxD,OAAO,gBAAgB,EAAE,CAAC;KAC3B;IAED,IAAI,iBAAiB,CAAC,CAAC,CAAC,CAAC,IAAI,KAAK,OAAO,EAAE;QACzC,IAAI,WAAW,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,EAAE;YACrC,OAAO;SACR;QACD,OAAO,gBAAgB,EAAE,CAAC;KAC3B;IAED,MAAM,YAAY,GAAG,iBAAiB,CAAC,CAAC,CAAU,CAAC;IAEnD,IAAI,MAAM,KAAK,QAAQ,EAAE;QACvB,oDAAoD;QACpD,MAAM,UAAU,GAAG,iBAAiB,CAAC,OAAO,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC;QACpE,IAAI,UAAU,EAAE;YACd,kBAAkB,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,CAAC,CAAC;SACjD;KACF;SAAM;QACL,iDAAiD;QACjD,kBAAkB,CAAC,OAAO,EAAE,MAAM,EAAE,YAAY,CAAC,CAAC;KACnD;AACH,CAAC;AAED,MAAM,sBAAsB,GAAG,iBAAiB,CAAC,qBAAqB,CAAC,CAAC;AACxE,MAAM,UAAU,iBAAiB,CAAC,OAAgB,EAAE,YAAmB;IACrE,OAAO,OAAO,CAAC,QAAQ,CAAC,sBAAsB,CAAC,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;AACpE,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,eAAe,CAAC,OAAyB,EAAE,MAAY,EAAE,UAAgB;IACvF,IAAI,CAAC,uBAAuB,CAAC,OAAO,EAAE,UAAU,EAAE,iBAAiB,EAAE,OAAO,CAAC,EAAE;QAC7E,OAAO;KACR;IACD,MAAM,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC;IAE5B,OAAO,CAAC,QAAQ,CAAC,sBAAsB,CAAC,CAAC,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;AACnE,CAAC"}
|