@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
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { DecoratorContext, Interface, Model, ModelProperty, Operation, Program, Scalar, Type } from "@typespec/compiler";
|
|
2
|
+
export interface FilteredRouteParam {
|
|
3
|
+
routeParamString?: string;
|
|
4
|
+
excludeFromOperationParams?: boolean;
|
|
5
|
+
}
|
|
6
|
+
export interface AutoRouteOptions {
|
|
7
|
+
routeParamFilter?: (op: Operation, param: ModelProperty) => FilteredRouteParam | undefined;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* `@autoRoute` enables automatic route generation for an operation or interface.
|
|
11
|
+
*
|
|
12
|
+
* When applied to an operation, it automatically generates the operation's route based on path parameter
|
|
13
|
+
* metadata. When applied to an interface, it causes all operations under that scope to have
|
|
14
|
+
* auto-generated routes.
|
|
15
|
+
*/
|
|
16
|
+
export declare function $autoRoute(context: DecoratorContext, entity: Interface | Operation): void;
|
|
17
|
+
export declare function isAutoRoute(program: Program, entity: Operation | Interface): boolean;
|
|
18
|
+
/**
|
|
19
|
+
* `@segment` defines the preceding path segment for a `@path` parameter in auto-generated routes
|
|
20
|
+
*
|
|
21
|
+
* The first argument should be a string that will be inserted into the operation route before the
|
|
22
|
+
* path parameter's name field.
|
|
23
|
+
*
|
|
24
|
+
* `@segment` can only be applied to model properties, operation parameters, or operations.
|
|
25
|
+
*/
|
|
26
|
+
export declare function $segment(context: DecoratorContext, entity: Model | ModelProperty | Operation, name: string): void;
|
|
27
|
+
export declare function $segmentOf(context: DecoratorContext, entity: Operation, resourceType: Model): void;
|
|
28
|
+
export declare function getSegment(program: Program, entity: Type): string | undefined;
|
|
29
|
+
/**
|
|
30
|
+
* `@actionSeparator` defines the separator string that is used to precede the action name
|
|
31
|
+
* in auto-generated actions.
|
|
32
|
+
*
|
|
33
|
+
* `@actionSeparator` can only be applied to model properties, operation parameters, or operations.
|
|
34
|
+
*/
|
|
35
|
+
export declare function $actionSeparator(context: DecoratorContext, entity: Model | ModelProperty | Operation, separator: "/" | ":" | "/:"): void;
|
|
36
|
+
/**
|
|
37
|
+
* @param program the TypeSpec program
|
|
38
|
+
* @param entity the target entity
|
|
39
|
+
* @returns the action separator string
|
|
40
|
+
*/
|
|
41
|
+
export declare function getActionSeparator(program: Program, entity: Type): string | undefined;
|
|
42
|
+
/**
|
|
43
|
+
* `@resource` marks a model as a resource type.
|
|
44
|
+
*
|
|
45
|
+
* The first argument should be the name of the collection that the resources
|
|
46
|
+
* belong to. For example, a resource type `Widget` might have a collection
|
|
47
|
+
* name of `widgets`.
|
|
48
|
+
*
|
|
49
|
+
* `@resource` can only be applied to models.
|
|
50
|
+
*/
|
|
51
|
+
export declare function $resource(context: DecoratorContext, entity: Model, collectionName: string): void;
|
|
52
|
+
export type ResourceOperations = "read" | "create" | "createOrReplace" | "createOrUpdate" | "update" | "delete" | "list";
|
|
53
|
+
export interface ResourceOperation {
|
|
54
|
+
operation: string;
|
|
55
|
+
resourceType: Model;
|
|
56
|
+
}
|
|
57
|
+
export declare function setResourceOperation(context: DecoratorContext, entity: Operation, resourceType: Model, operation: ResourceOperations): void;
|
|
58
|
+
export declare function getResourceOperation(program: Program, typespecOperation: Operation): ResourceOperation | undefined;
|
|
59
|
+
export declare function $readsResource(context: DecoratorContext, entity: Operation, resourceType: Model): void;
|
|
60
|
+
export declare function $createsResource(context: DecoratorContext, entity: Operation, resourceType: Model): void;
|
|
61
|
+
export declare function $createsOrReplacesResource(context: DecoratorContext, entity: Operation, resourceType: Model): void;
|
|
62
|
+
export declare function $createsOrUpdatesResource(context: DecoratorContext, entity: Operation, resourceType: Model): void;
|
|
63
|
+
export declare function $updatesResource(context: DecoratorContext, entity: Operation, resourceType: Model): void;
|
|
64
|
+
export declare function $deletesResource(context: DecoratorContext, entity: Operation, resourceType: Model): void;
|
|
65
|
+
export declare function $listsResource(context: DecoratorContext, entity: Operation, resourceType: Model): void;
|
|
66
|
+
export declare function $actionSegment(context: DecoratorContext, entity: Operation, name: string): void;
|
|
67
|
+
export declare function getActionSegment(program: Program, entity: Type): string | undefined;
|
|
68
|
+
export declare function $action(context: DecoratorContext, entity: Operation, name?: string): void;
|
|
69
|
+
export declare function getAction(program: Program, operation: Operation): string | null | undefined;
|
|
70
|
+
export declare function $collectionAction(context: DecoratorContext, entity: Operation, resourceType: Model, name?: string): void;
|
|
71
|
+
export declare function getCollectionAction(program: Program, operation: Operation): string | null | undefined;
|
|
72
|
+
export declare function $resourceLocation(context: DecoratorContext, entity: Model, resourceType: Model): void;
|
|
73
|
+
export declare function getResourceLocationType(program: Program, entity: Scalar): Model | undefined;
|
|
74
|
+
//# sourceMappingURL=rest.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rest.d.ts","sourceRoot":"","sources":["../../src/rest.ts"],"names":[],"mappings":"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"}
|
package/dist/src/rest.js
ADDED
|
@@ -0,0 +1,318 @@
|
|
|
1
|
+
import { $list, createDiagnosticCollector, setTypeSpecNamespace, } from "@typespec/compiler";
|
|
2
|
+
import { DefaultRouteProducer, getOperationParameters, getOperationVerb, getRoutePath, getRouteProducer, setRouteProducer, } from "@typespec/http";
|
|
3
|
+
import { createStateSymbol, reportDiagnostic } from "./lib.js";
|
|
4
|
+
import { getResourceTypeKey } from "./resource.js";
|
|
5
|
+
// ----------------- @autoRoute -----------------
|
|
6
|
+
function addActionFragment(program, target, pathFragments) {
|
|
7
|
+
var _a;
|
|
8
|
+
// add the action segment, if present
|
|
9
|
+
const defaultSeparator = "/";
|
|
10
|
+
const actionSegment = getActionSegment(program, target);
|
|
11
|
+
if (actionSegment && actionSegment !== "") {
|
|
12
|
+
const actionSeparator = (_a = getActionSeparator(program, target)) !== null && _a !== void 0 ? _a : defaultSeparator;
|
|
13
|
+
pathFragments.push(`${actionSeparator}${actionSegment}`);
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
function addSegmentFragment(program, target, pathFragments) {
|
|
17
|
+
// Don't add the segment prefix if it is meant to be excluded
|
|
18
|
+
// (empty string means exclude the segment)
|
|
19
|
+
const segment = getSegment(program, target);
|
|
20
|
+
if (segment && segment !== "") {
|
|
21
|
+
pathFragments.push(`/${segment}`);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
// TODO: Make this overridable by libraries
|
|
25
|
+
const resourceOperationToVerb = {
|
|
26
|
+
read: "get",
|
|
27
|
+
create: "post",
|
|
28
|
+
createOrUpdate: "patch",
|
|
29
|
+
createOrReplace: "put",
|
|
30
|
+
update: "patch",
|
|
31
|
+
delete: "delete",
|
|
32
|
+
list: "get",
|
|
33
|
+
};
|
|
34
|
+
function getResourceOperationHttpVerb(program, operation) {
|
|
35
|
+
var _a, _b;
|
|
36
|
+
const resourceOperation = getResourceOperation(program, operation);
|
|
37
|
+
return ((_b = (_a = getOperationVerb(program, operation)) !== null && _a !== void 0 ? _a : (resourceOperation && resourceOperationToVerb[resourceOperation.operation])) !== null && _b !== void 0 ? _b : (getAction(program, operation) || getCollectionAction(program, operation) ? "post" : undefined));
|
|
38
|
+
}
|
|
39
|
+
function autoRouteProducer(program, operation, parentSegments, overloadBase, options) {
|
|
40
|
+
var _a, _b, _c, _d;
|
|
41
|
+
const diagnostics = createDiagnosticCollector();
|
|
42
|
+
const routePath = (_a = getRoutePath(program, operation)) === null || _a === void 0 ? void 0 : _a.path;
|
|
43
|
+
const segments = [...parentSegments, ...(routePath ? [routePath] : [])];
|
|
44
|
+
const filteredParameters = [];
|
|
45
|
+
const paramOptions = {
|
|
46
|
+
...((_b = options === null || options === void 0 ? void 0 : options.paramOptions) !== null && _b !== void 0 ? _b : {}),
|
|
47
|
+
verbSelector: getResourceOperationHttpVerb,
|
|
48
|
+
};
|
|
49
|
+
const parameters = diagnostics.pipe(getOperationParameters(program, operation, undefined, [], paramOptions));
|
|
50
|
+
for (const httpParam of parameters.parameters) {
|
|
51
|
+
const { type, param } = httpParam;
|
|
52
|
+
if (type === "path") {
|
|
53
|
+
addSegmentFragment(program, param, segments);
|
|
54
|
+
const filteredParam = (_d = (_c = options.autoRouteOptions) === null || _c === void 0 ? void 0 : _c.routeParamFilter) === null || _d === void 0 ? void 0 : _d.call(_c, operation, param);
|
|
55
|
+
if (filteredParam === null || filteredParam === void 0 ? void 0 : filteredParam.routeParamString) {
|
|
56
|
+
segments.push(`/${filteredParam.routeParamString}`);
|
|
57
|
+
if ((filteredParam === null || filteredParam === void 0 ? void 0 : filteredParam.excludeFromOperationParams) === true) {
|
|
58
|
+
// Skip the rest of the loop so that we don't add the parameter to the final list
|
|
59
|
+
continue;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
else {
|
|
63
|
+
// Add the path variable for the parameter
|
|
64
|
+
if (param.type.kind === "String") {
|
|
65
|
+
segments.push(`/${param.type.value}`);
|
|
66
|
+
continue; // Skip adding to the parameter list
|
|
67
|
+
}
|
|
68
|
+
else {
|
|
69
|
+
segments.push(`/{${param.name}}`);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
// Push all usable parameters to the filtered list
|
|
74
|
+
filteredParameters.push(httpParam);
|
|
75
|
+
}
|
|
76
|
+
// Replace the original parameters with filtered set
|
|
77
|
+
parameters.parameters = filteredParameters;
|
|
78
|
+
// Add the operation's own segment if present
|
|
79
|
+
addSegmentFragment(program, operation, segments);
|
|
80
|
+
// Add the operation's action segment if present
|
|
81
|
+
addActionFragment(program, operation, segments);
|
|
82
|
+
return diagnostics.wrap({
|
|
83
|
+
segments,
|
|
84
|
+
parameters: {
|
|
85
|
+
...parameters,
|
|
86
|
+
parameters: filteredParameters,
|
|
87
|
+
},
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
const autoRouteKey = createStateSymbol("autoRoute");
|
|
91
|
+
/**
|
|
92
|
+
* `@autoRoute` enables automatic route generation for an operation or interface.
|
|
93
|
+
*
|
|
94
|
+
* When applied to an operation, it automatically generates the operation's route based on path parameter
|
|
95
|
+
* metadata. When applied to an interface, it causes all operations under that scope to have
|
|
96
|
+
* auto-generated routes.
|
|
97
|
+
*/
|
|
98
|
+
export function $autoRoute(context, entity) {
|
|
99
|
+
if (entity.kind === "Operation") {
|
|
100
|
+
setRouteProducer(context.program, entity, autoRouteProducer);
|
|
101
|
+
}
|
|
102
|
+
else {
|
|
103
|
+
for (const [_, op] of entity.operations) {
|
|
104
|
+
// Instantly apply the decorator to the operation
|
|
105
|
+
context.call($autoRoute, op);
|
|
106
|
+
// Manually push the decorator onto the property so that it gets applied
|
|
107
|
+
// to operations which reference the operation with `is`
|
|
108
|
+
op.decorators.push({
|
|
109
|
+
decorator: $autoRoute,
|
|
110
|
+
args: [],
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
context.program.stateSet(autoRouteKey).add(entity);
|
|
115
|
+
}
|
|
116
|
+
export function isAutoRoute(program, entity) {
|
|
117
|
+
return program.stateSet(autoRouteKey).has(entity);
|
|
118
|
+
}
|
|
119
|
+
// ------------------ @segment ------------------
|
|
120
|
+
const segmentsKey = createStateSymbol("segments");
|
|
121
|
+
/**
|
|
122
|
+
* `@segment` defines the preceding path segment for a `@path` parameter in auto-generated routes
|
|
123
|
+
*
|
|
124
|
+
* The first argument should be a string that will be inserted into the operation route before the
|
|
125
|
+
* path parameter's name field.
|
|
126
|
+
*
|
|
127
|
+
* `@segment` can only be applied to model properties, operation parameters, or operations.
|
|
128
|
+
*/
|
|
129
|
+
export function $segment(context, entity, name) {
|
|
130
|
+
context.program.stateMap(segmentsKey).set(entity, name);
|
|
131
|
+
}
|
|
132
|
+
function getResourceSegment(program, resourceType) {
|
|
133
|
+
// Add path segment for resource type key (if it has one)
|
|
134
|
+
const resourceKey = getResourceTypeKey(program, resourceType);
|
|
135
|
+
return resourceKey
|
|
136
|
+
? getSegment(program, resourceKey.keyProperty)
|
|
137
|
+
: getSegment(program, resourceType);
|
|
138
|
+
}
|
|
139
|
+
export function $segmentOf(context, entity, resourceType) {
|
|
140
|
+
if (resourceType.kind === "TemplateParameter") {
|
|
141
|
+
// Skip it, this operation is in a templated interface
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
144
|
+
// Add path segment for resource type key (if it has one)
|
|
145
|
+
const segment = getResourceSegment(context.program, resourceType);
|
|
146
|
+
if (segment) {
|
|
147
|
+
context.call($segment, entity, segment);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
export function getSegment(program, entity) {
|
|
151
|
+
return program.stateMap(segmentsKey).get(entity);
|
|
152
|
+
}
|
|
153
|
+
const actionSeparatorKey = createStateSymbol("actionSeparator");
|
|
154
|
+
/**
|
|
155
|
+
* `@actionSeparator` defines the separator string that is used to precede the action name
|
|
156
|
+
* in auto-generated actions.
|
|
157
|
+
*
|
|
158
|
+
* `@actionSeparator` can only be applied to model properties, operation parameters, or operations.
|
|
159
|
+
*/
|
|
160
|
+
export function $actionSeparator(context, entity, separator) {
|
|
161
|
+
context.program.stateMap(actionSeparatorKey).set(entity, separator);
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* @param program the TypeSpec program
|
|
165
|
+
* @param entity the target entity
|
|
166
|
+
* @returns the action separator string
|
|
167
|
+
*/
|
|
168
|
+
export function getActionSeparator(program, entity) {
|
|
169
|
+
return program.stateMap(actionSeparatorKey).get(entity);
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* `@resource` marks a model as a resource type.
|
|
173
|
+
*
|
|
174
|
+
* The first argument should be the name of the collection that the resources
|
|
175
|
+
* belong to. For example, a resource type `Widget` might have a collection
|
|
176
|
+
* name of `widgets`.
|
|
177
|
+
*
|
|
178
|
+
* `@resource` can only be applied to models.
|
|
179
|
+
*/
|
|
180
|
+
export function $resource(context, entity, collectionName) {
|
|
181
|
+
// Ensure type has a key property
|
|
182
|
+
const key = getResourceTypeKey(context.program, entity);
|
|
183
|
+
// A resource type must have a key property
|
|
184
|
+
if (!key) {
|
|
185
|
+
reportDiagnostic(context.program, {
|
|
186
|
+
code: "resource-missing-key",
|
|
187
|
+
format: {
|
|
188
|
+
modelName: entity.name,
|
|
189
|
+
},
|
|
190
|
+
target: entity,
|
|
191
|
+
});
|
|
192
|
+
return;
|
|
193
|
+
}
|
|
194
|
+
// Apply the @segment decorator with the collection name
|
|
195
|
+
context.call($segment, key.keyProperty, collectionName);
|
|
196
|
+
// Manually push the decorator onto the property so that it's copyable in KeysOf<T>
|
|
197
|
+
key.keyProperty.decorators.push({
|
|
198
|
+
decorator: $segment,
|
|
199
|
+
args: [{ value: context.program.checker.createLiteralType(collectionName) }],
|
|
200
|
+
});
|
|
201
|
+
}
|
|
202
|
+
const resourceOperationsKey = createStateSymbol("resourceOperations");
|
|
203
|
+
function resourceRouteProducer(program, operation, parentSegments, overloadBase, options) {
|
|
204
|
+
// NOTE: The purpose of this producer is to pass along the behavior of the
|
|
205
|
+
// DefaultRouteProducer while setting the appropriate HTTP verb based on any
|
|
206
|
+
// resource operation decorators that have been applied. This behavior will
|
|
207
|
+
// be overridden by the `autoRouteProducer` if `autoRoute` is also applied to
|
|
208
|
+
// the same operation.
|
|
209
|
+
var _a;
|
|
210
|
+
// Set the OperationVerbSelector to pick verbs based on resource operation type
|
|
211
|
+
const paramOptions = {
|
|
212
|
+
...((_a = options === null || options === void 0 ? void 0 : options.paramOptions) !== null && _a !== void 0 ? _a : {}),
|
|
213
|
+
verbSelector: getResourceOperationHttpVerb,
|
|
214
|
+
};
|
|
215
|
+
return DefaultRouteProducer(program, operation, parentSegments, overloadBase, {
|
|
216
|
+
...options,
|
|
217
|
+
paramOptions,
|
|
218
|
+
});
|
|
219
|
+
}
|
|
220
|
+
export function setResourceOperation(context, entity, resourceType, operation) {
|
|
221
|
+
if (resourceType.kind === "TemplateParameter") {
|
|
222
|
+
// Skip it, this operation is in a templated interface
|
|
223
|
+
return;
|
|
224
|
+
}
|
|
225
|
+
context.program.stateMap(resourceOperationsKey).set(entity, {
|
|
226
|
+
operation,
|
|
227
|
+
resourceType,
|
|
228
|
+
});
|
|
229
|
+
// Set a custom RouteProducer on the operation if one hasn't already been
|
|
230
|
+
// established yet. This is intended to translate lifecycle operations to
|
|
231
|
+
// HTTP verbs.
|
|
232
|
+
if (!getRouteProducer(context.program, entity)) {
|
|
233
|
+
setRouteProducer(context.program, entity, resourceRouteProducer);
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
export function getResourceOperation(program, typespecOperation) {
|
|
237
|
+
return program.stateMap(resourceOperationsKey).get(typespecOperation);
|
|
238
|
+
}
|
|
239
|
+
export function $readsResource(context, entity, resourceType) {
|
|
240
|
+
setResourceOperation(context, entity, resourceType, "read");
|
|
241
|
+
}
|
|
242
|
+
export function $createsResource(context, entity, resourceType) {
|
|
243
|
+
// Add path segment for resource type key
|
|
244
|
+
context.call($segmentOf, entity, resourceType);
|
|
245
|
+
setResourceOperation(context, entity, resourceType, "create");
|
|
246
|
+
}
|
|
247
|
+
export function $createsOrReplacesResource(context, entity, resourceType) {
|
|
248
|
+
setResourceOperation(context, entity, resourceType, "createOrReplace");
|
|
249
|
+
}
|
|
250
|
+
export function $createsOrUpdatesResource(context, entity, resourceType) {
|
|
251
|
+
setResourceOperation(context, entity, resourceType, "createOrUpdate");
|
|
252
|
+
}
|
|
253
|
+
export function $updatesResource(context, entity, resourceType) {
|
|
254
|
+
setResourceOperation(context, entity, resourceType, "update");
|
|
255
|
+
}
|
|
256
|
+
export function $deletesResource(context, entity, resourceType) {
|
|
257
|
+
setResourceOperation(context, entity, resourceType, "delete");
|
|
258
|
+
}
|
|
259
|
+
export function $listsResource(context, entity, resourceType) {
|
|
260
|
+
// Add the @list decorator too so that collection routes are generated correctly
|
|
261
|
+
context.call($list, entity, resourceType);
|
|
262
|
+
// Add path segment for resource type key
|
|
263
|
+
context.call($segmentOf, entity, resourceType);
|
|
264
|
+
setResourceOperation(context, entity, resourceType, "list");
|
|
265
|
+
}
|
|
266
|
+
function lowerCaseFirstChar(str) {
|
|
267
|
+
return str[0].toLocaleLowerCase() + str.substring(1);
|
|
268
|
+
}
|
|
269
|
+
function makeActionName(op, name) {
|
|
270
|
+
return lowerCaseFirstChar(name || op.name);
|
|
271
|
+
}
|
|
272
|
+
const actionsSegmentKey = createStateSymbol("actionSegment");
|
|
273
|
+
export function $actionSegment(context, entity, name) {
|
|
274
|
+
context.program.stateMap(actionsSegmentKey).set(entity, name);
|
|
275
|
+
}
|
|
276
|
+
export function getActionSegment(program, entity) {
|
|
277
|
+
return program.stateMap(actionsSegmentKey).get(entity);
|
|
278
|
+
}
|
|
279
|
+
const actionsKey = createStateSymbol("actions");
|
|
280
|
+
export function $action(context, entity, name) {
|
|
281
|
+
const action = makeActionName(entity, name);
|
|
282
|
+
context.call($actionSegment, entity, action);
|
|
283
|
+
context.program.stateMap(actionsKey).set(entity, action);
|
|
284
|
+
}
|
|
285
|
+
export function getAction(program, operation) {
|
|
286
|
+
return program.stateMap(actionsKey).get(operation);
|
|
287
|
+
}
|
|
288
|
+
const collectionActionsKey = createStateSymbol("collectionActions");
|
|
289
|
+
export function $collectionAction(context, entity, resourceType, name) {
|
|
290
|
+
if (resourceType.kind === "TemplateParameter") {
|
|
291
|
+
// Skip it, this operation is in a templated interface
|
|
292
|
+
return;
|
|
293
|
+
}
|
|
294
|
+
// only add the resource portion of the segment
|
|
295
|
+
const segment = getResourceSegment(context.program, resourceType);
|
|
296
|
+
if (segment) {
|
|
297
|
+
context.call($segment, entity, segment);
|
|
298
|
+
}
|
|
299
|
+
const action = makeActionName(entity, name);
|
|
300
|
+
context.call($actionSegment, entity, action);
|
|
301
|
+
context.program.stateMap(collectionActionsKey).set(entity, `${segment}/${action}`);
|
|
302
|
+
}
|
|
303
|
+
export function getCollectionAction(program, operation) {
|
|
304
|
+
return program.stateMap(collectionActionsKey).get(operation);
|
|
305
|
+
}
|
|
306
|
+
const resourceLocationsKey = createStateSymbol("resourceLocations");
|
|
307
|
+
export function $resourceLocation(context, entity, resourceType) {
|
|
308
|
+
if (resourceType.kind === "TemplateParameter") {
|
|
309
|
+
// Skip it, this operation is in a templated interface
|
|
310
|
+
return;
|
|
311
|
+
}
|
|
312
|
+
context.program.stateMap(resourceLocationsKey).set(entity, resourceType);
|
|
313
|
+
}
|
|
314
|
+
export function getResourceLocationType(program, entity) {
|
|
315
|
+
return program.stateMap(resourceLocationsKey).get(entity);
|
|
316
|
+
}
|
|
317
|
+
setTypeSpecNamespace("Private", $resourceLocation, $actionSegment, getActionSegment);
|
|
318
|
+
//# sourceMappingURL=rest.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rest.js","sourceRoot":"","sources":["../../src/rest.ts"],"names":[],"mappings":"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"}
|
|
@@ -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,eAAe,EAAE,mBAG5B,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 RestTestLibrary = createTestLibrary({
|
|
5
|
+
name: "@typespec/rest",
|
|
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,eAAe,GAAwB,iBAAiB,CAAC;IACpE,IAAI,EAAE,gBAAgB;IACtB,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":"validate.d.ts","sourceRoot":"","sources":["../../src/validate.ts"],"names":[],"mappings":"AAAA,OAAO,EAOL,OAAO,EACR,MAAM,oBAAoB,CAAC;AAsD5B,wBAAgB,WAAW,CAAC,OAAO,EAAE,OAAO,QAI3C"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { DuplicateTracker, getKeyName, getTypeName, listServices, navigateTypesInNamespace, } from "@typespec/compiler";
|
|
2
|
+
import { reportDiagnostic } from "./lib.js";
|
|
3
|
+
import { getParentResource, getResourceTypeKey } from "./resource.js";
|
|
4
|
+
function checkForDuplicateResourceKeyNames(program) {
|
|
5
|
+
const seenTypes = new Set();
|
|
6
|
+
function checkResourceModelKeys(model) {
|
|
7
|
+
if (model.name === "") {
|
|
8
|
+
return;
|
|
9
|
+
}
|
|
10
|
+
let currentType = model;
|
|
11
|
+
const keyProperties = new DuplicateTracker();
|
|
12
|
+
while (currentType) {
|
|
13
|
+
const resourceKey = getResourceTypeKey(program, currentType);
|
|
14
|
+
if (resourceKey) {
|
|
15
|
+
const keyName = getKeyName(program, resourceKey.keyProperty);
|
|
16
|
+
keyProperties.track(keyName, resourceKey);
|
|
17
|
+
}
|
|
18
|
+
currentType = getParentResource(program, currentType);
|
|
19
|
+
}
|
|
20
|
+
// Report a diagnostic for each duplicate key
|
|
21
|
+
for (const [keyName, dupes] of keyProperties.entries()) {
|
|
22
|
+
for (const key of dupes) {
|
|
23
|
+
// Make sure we don't report a duplicate for a particular
|
|
24
|
+
// resource type and key name more than once
|
|
25
|
+
const fullName = `${getTypeName(key.resourceType)}.${keyName}`;
|
|
26
|
+
if (!seenTypes.has(fullName)) {
|
|
27
|
+
seenTypes.add(fullName);
|
|
28
|
+
reportDiagnostic(program, {
|
|
29
|
+
code: "duplicate-parent-key",
|
|
30
|
+
format: {
|
|
31
|
+
resourceName: key.resourceType.name,
|
|
32
|
+
keyName,
|
|
33
|
+
},
|
|
34
|
+
target: key.keyProperty,
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
for (const service of listServices(program)) {
|
|
41
|
+
// If the model type is defined under the service namespace, check that the
|
|
42
|
+
// parent resource type(s) don't have the same key name as the
|
|
43
|
+
// current resource type.
|
|
44
|
+
navigateTypesInNamespace(service.type, {
|
|
45
|
+
model: (model) => checkResourceModelKeys(model),
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
export function $onValidate(program) {
|
|
50
|
+
// Make sure any defined resource types don't have any conflicts with parent
|
|
51
|
+
// resource type key names
|
|
52
|
+
checkForDuplicateResourceKeyNames(program);
|
|
53
|
+
}
|
|
54
|
+
//# sourceMappingURL=validate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validate.js","sourceRoot":"","sources":["../../src/validate.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,gBAAgB,EAChB,UAAU,EACV,WAAW,EACX,YAAY,EAEZ,wBAAwB,GAEzB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAC5C,OAAO,EAAE,iBAAiB,EAAE,kBAAkB,EAAe,MAAM,eAAe,CAAC;AAEnF,SAAS,iCAAiC,CAAC,OAAgB;IACzD,MAAM,SAAS,GAAG,IAAI,GAAG,EAAU,CAAC;IAEpC,SAAS,sBAAsB,CAAC,KAAY;QAC1C,IAAI,KAAK,CAAC,IAAI,KAAK,EAAE,EAAE;YACrB,OAAO;SACR;QACD,IAAI,WAAW,GAAsB,KAAK,CAAC;QAC3C,MAAM,aAAa,GAAG,IAAI,gBAAgB,EAAuB,CAAC;QAClE,OAAO,WAAW,EAAE;YAClB,MAAM,WAAW,GAAG,kBAAkB,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC;YAC7D,IAAI,WAAW,EAAE;gBACf,MAAM,OAAO,GAAG,UAAU,CAAC,OAAO,EAAE,WAAW,CAAC,WAAW,CAAC,CAAC;gBAC7D,aAAa,CAAC,KAAK,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC;aAC3C;YAED,WAAW,GAAG,iBAAiB,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC;SACvD;QAED,6CAA6C;QAC7C,KAAK,MAAM,CAAC,OAAO,EAAE,KAAK,CAAC,IAAI,aAAa,CAAC,OAAO,EAAE,EAAE;YACtD,KAAK,MAAM,GAAG,IAAI,KAAK,EAAE;gBACvB,yDAAyD;gBACzD,4CAA4C;gBAC5C,MAAM,QAAQ,GAAG,GAAG,WAAW,CAAC,GAAG,CAAC,YAAY,CAAC,IAAI,OAAO,EAAE,CAAC;gBAC/D,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE;oBAC5B,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;oBACxB,gBAAgB,CAAC,OAAO,EAAE;wBACxB,IAAI,EAAE,sBAAsB;wBAC5B,MAAM,EAAE;4BACN,YAAY,EAAE,GAAG,CAAC,YAAY,CAAC,IAAI;4BACnC,OAAO;yBACR;wBACD,MAAM,EAAE,GAAG,CAAC,WAAW;qBACxB,CAAC,CAAC;iBACJ;aACF;SACF;IACH,CAAC;IAED,KAAK,MAAM,OAAO,IAAI,YAAY,CAAC,OAAO,CAAC,EAAE;QAC3C,2EAA2E;QAC3E,8DAA8D;QAC9D,yBAAyB;QACzB,wBAAwB,CAAC,OAAO,CAAC,IAAI,EAAE;YACrC,KAAK,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,sBAAsB,CAAC,KAAK,CAAC;SAChD,CAAC,CAAC;KACJ;AACH,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,OAAgB;IAC1C,4EAA4E;IAC5E,0BAA0B;IAC1B,iCAAiC,CAAC,OAAO,CAAC,CAAC;AAC7C,CAAC"}
|