@typespec/http 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.
Files changed (58) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +106 -0
  3. package/dist/src/content-types.d.ts +15 -0
  4. package/dist/src/content-types.d.ts.map +1 -0
  5. package/dist/src/content-types.js +42 -0
  6. package/dist/src/content-types.js.map +1 -0
  7. package/dist/src/decorators.d.ts +82 -0
  8. package/dist/src/decorators.d.ts.map +1 -0
  9. package/dist/src/decorators.js +513 -0
  10. package/dist/src/decorators.js.map +1 -0
  11. package/dist/src/index.d.ts +11 -0
  12. package/dist/src/index.d.ts.map +1 -0
  13. package/dist/src/index.js +11 -0
  14. package/dist/src/index.js.map +1 -0
  15. package/dist/src/lib.d.ts +294 -0
  16. package/dist/src/lib.d.ts.map +1 -0
  17. package/dist/src/lib.js +121 -0
  18. package/dist/src/lib.js.map +1 -0
  19. package/dist/src/metadata.d.ts +129 -0
  20. package/dist/src/metadata.d.ts.map +1 -0
  21. package/dist/src/metadata.js +323 -0
  22. package/dist/src/metadata.js.map +1 -0
  23. package/dist/src/operations.d.ts +31 -0
  24. package/dist/src/operations.d.ts.map +1 -0
  25. package/dist/src/operations.js +162 -0
  26. package/dist/src/operations.js.map +1 -0
  27. package/dist/src/parameters.d.ts +4 -0
  28. package/dist/src/parameters.d.ts.map +1 -0
  29. package/dist/src/parameters.js +142 -0
  30. package/dist/src/parameters.js.map +1 -0
  31. package/dist/src/responses.d.ts +7 -0
  32. package/dist/src/responses.d.ts.map +1 -0
  33. package/dist/src/responses.js +186 -0
  34. package/dist/src/responses.js.map +1 -0
  35. package/dist/src/route.d.ts +23 -0
  36. package/dist/src/route.d.ts.map +1 -0
  37. package/dist/src/route.js +149 -0
  38. package/dist/src/route.js.map +1 -0
  39. package/dist/src/testing/index.d.ts +3 -0
  40. package/dist/src/testing/index.d.ts.map +1 -0
  41. package/dist/src/testing/index.js +8 -0
  42. package/dist/src/testing/index.js.map +1 -0
  43. package/dist/src/types.d.ts +254 -0
  44. package/dist/src/types.d.ts.map +1 -0
  45. package/dist/src/types.js +2 -0
  46. package/dist/src/types.js.map +1 -0
  47. package/dist/src/utils.d.ts +8 -0
  48. package/dist/src/utils.d.ts.map +1 -0
  49. package/dist/src/utils.js +11 -0
  50. package/dist/src/utils.js.map +1 -0
  51. package/dist/src/validate.d.ts +3 -0
  52. package/dist/src/validate.d.ts.map +1 -0
  53. package/dist/src/validate.js +9 -0
  54. package/dist/src/validate.js.map +1 -0
  55. package/lib/auth.tsp +185 -0
  56. package/lib/http-decorators.tsp +206 -0
  57. package/lib/http.tsp +57 -0
  58. package/package.json +72 -0
@@ -0,0 +1,142 @@
1
+ import { createDiagnosticCollector, filterModelProperties, } from "@typespec/compiler";
2
+ import { getContentTypes, isContentTypeHeader } from "./content-types.js";
3
+ import { getHeaderFieldOptions, getOperationVerb, getPathParamOptions, getQueryParamOptions, isBody, } from "./decorators.js";
4
+ import { createDiagnostic } from "./lib.js";
5
+ import { gatherMetadata, getRequestVisibility, isMetadata } from "./metadata.js";
6
+ export function getOperationParameters(program, operation, overloadBase, knownPathParamNames = [], options = {}) {
7
+ var _a, _b;
8
+ const verb = (_b = (_a = ((options === null || options === void 0 ? void 0 : options.verbSelector) && options.verbSelector(program, operation))) !== null && _a !== void 0 ? _a : getOperationVerb(program, operation)) !== null && _b !== void 0 ? _b : overloadBase === null || overloadBase === void 0 ? void 0 : overloadBase.verb;
9
+ if (verb) {
10
+ return getOperationParametersForVerb(program, operation, verb, knownPathParamNames);
11
+ }
12
+ // If no verb is explicitly specified, it is POST if there is a body and
13
+ // GET otherwise. Theoretically, it is possible to use @visibility
14
+ // strangely such that there is no body if the verb is POST and there is a
15
+ // body if the verb is GET. In that rare case, GET is chosen arbitrarily.
16
+ const post = getOperationParametersForVerb(program, operation, "post", knownPathParamNames);
17
+ return post[0].bodyType
18
+ ? post
19
+ : getOperationParametersForVerb(program, operation, "get", knownPathParamNames);
20
+ }
21
+ function getOperationParametersForVerb(program, operation, verb, knownPathParamNames) {
22
+ var _a;
23
+ const diagnostics = createDiagnosticCollector();
24
+ const visibility = getRequestVisibility(verb);
25
+ const metadata = gatherMetadata(program, diagnostics, operation.parameters, visibility, (_, param) => isMetadata(program, param) || isImplicitPathParam(param));
26
+ function isImplicitPathParam(param) {
27
+ const isTopLevel = param.model === operation.parameters;
28
+ return isTopLevel && knownPathParamNames.includes(param.name);
29
+ }
30
+ const parameters = [];
31
+ let bodyType;
32
+ let bodyParameter;
33
+ let contentTypes;
34
+ for (const param of metadata) {
35
+ const queryOptions = getQueryParamOptions(program, param);
36
+ const pathOptions = (_a = getPathParamOptions(program, param)) !== null && _a !== void 0 ? _a : (isImplicitPathParam(param) && { type: "path", name: param.name });
37
+ const headerOptions = getHeaderFieldOptions(program, param);
38
+ const bodyParam = isBody(program, param);
39
+ const defined = [
40
+ ["query", queryOptions],
41
+ ["path", pathOptions],
42
+ ["header", headerOptions],
43
+ ["body", bodyParam],
44
+ ].filter((x) => !!x[1]);
45
+ if (defined.length >= 2) {
46
+ diagnostics.add(createDiagnostic({
47
+ code: "operation-param-duplicate-type",
48
+ format: { paramName: param.name, types: defined.map((x) => x[0]).join(", ") },
49
+ target: param,
50
+ }));
51
+ }
52
+ if (queryOptions) {
53
+ parameters.push({
54
+ ...queryOptions,
55
+ param,
56
+ });
57
+ }
58
+ else if (pathOptions) {
59
+ if (param.optional) {
60
+ diagnostics.add(createDiagnostic({
61
+ code: "optional-path-param",
62
+ format: { paramName: param.name },
63
+ target: operation,
64
+ }));
65
+ }
66
+ parameters.push({
67
+ ...pathOptions,
68
+ param,
69
+ });
70
+ }
71
+ else if (headerOptions) {
72
+ if (isContentTypeHeader(program, param)) {
73
+ contentTypes = diagnostics.pipe(getContentTypes(param));
74
+ }
75
+ parameters.push({
76
+ ...headerOptions,
77
+ param,
78
+ });
79
+ }
80
+ else if (bodyParam) {
81
+ if (bodyType === undefined) {
82
+ bodyParameter = param;
83
+ bodyType = param.type;
84
+ }
85
+ else {
86
+ diagnostics.add(createDiagnostic({ code: "duplicate-body", target: param }));
87
+ }
88
+ }
89
+ }
90
+ const unannotatedProperties = filterModelProperties(program, operation.parameters, (p) => !metadata.has(p));
91
+ if (unannotatedProperties.properties.size > 0) {
92
+ if (bodyType === undefined) {
93
+ bodyType = unannotatedProperties;
94
+ }
95
+ else {
96
+ diagnostics.add(createDiagnostic({
97
+ code: "duplicate-body",
98
+ messageId: "bodyAndUnannotated",
99
+ target: operation,
100
+ }));
101
+ }
102
+ }
103
+ const body = diagnostics.pipe(computeHttpOperationBody(operation, bodyType, bodyParameter, contentTypes));
104
+ return diagnostics.wrap({
105
+ parameters,
106
+ verb,
107
+ body,
108
+ get bodyType() {
109
+ return body === null || body === void 0 ? void 0 : body.type;
110
+ },
111
+ get bodyParameter() {
112
+ return body === null || body === void 0 ? void 0 : body.parameter;
113
+ },
114
+ });
115
+ }
116
+ function computeHttpOperationBody(operation, bodyType, bodyProperty, contentTypes) {
117
+ contentTypes !== null && contentTypes !== void 0 ? contentTypes : (contentTypes = []);
118
+ const diagnostics = [];
119
+ if (bodyType === undefined) {
120
+ if (contentTypes.length > 0) {
121
+ diagnostics.push(createDiagnostic({
122
+ code: "content-type-ignored",
123
+ target: operation.parameters,
124
+ }));
125
+ }
126
+ return [undefined, diagnostics];
127
+ }
128
+ if (contentTypes.includes("multipart/form-data") && bodyType.kind !== "Model") {
129
+ diagnostics.push(createDiagnostic({
130
+ code: "multipart-model",
131
+ target: bodyProperty !== null && bodyProperty !== void 0 ? bodyProperty : operation.parameters,
132
+ }));
133
+ return [undefined, diagnostics];
134
+ }
135
+ const body = {
136
+ type: bodyType,
137
+ parameter: bodyProperty,
138
+ contentTypes,
139
+ };
140
+ return [body, diagnostics];
141
+ }
142
+ //# sourceMappingURL=parameters.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parameters.js","sourceRoot":"","sources":["../../src/parameters.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ import { Diagnostic, Operation, Program } from "@typespec/compiler";
2
+ import { HttpOperationResponse } from "./types.js";
3
+ /**
4
+ * Get the responses for a given operation.
5
+ */
6
+ export declare function getResponsesForOperation(program: Program, operation: Operation): [HttpOperationResponse[], readonly Diagnostic[]];
7
+ //# sourceMappingURL=responses.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"responses.d.ts","sourceRoot":"","sources":["../../src/responses.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,UAAU,EASV,SAAS,EACT,OAAO,EAGR,MAAM,oBAAoB,CAAC;AAY5B,OAAO,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AAEnD;;GAEG;AACH,wBAAgB,wBAAwB,CACtC,OAAO,EAAE,OAAO,EAChB,SAAS,EAAE,SAAS,GACnB,CAAC,qBAAqB,EAAE,EAAE,SAAS,UAAU,EAAE,CAAC,CAiBlD"}
@@ -0,0 +1,186 @@
1
+ import { createDiagnosticCollector, getDoc, isArrayModelType, isErrorModel, isNullType, isVoidType, walkPropertiesInherited, } from "@typespec/compiler";
2
+ import { getContentTypes, isContentTypeHeader } from "./content-types.js";
3
+ import { getHeaderFieldName, getStatusCodeDescription, getStatusCodes, isBody, isHeader, isStatusCode, } from "./decorators.js";
4
+ import { createDiagnostic } from "./lib.js";
5
+ import { gatherMetadata, isApplicableMetadata, Visibility } from "./metadata.js";
6
+ /**
7
+ * Get the responses for a given operation.
8
+ */
9
+ export function getResponsesForOperation(program, operation) {
10
+ const diagnostics = createDiagnosticCollector();
11
+ const responseType = operation.returnType;
12
+ const responses = {};
13
+ if (responseType.kind === "Union") {
14
+ for (const option of responseType.variants.values()) {
15
+ if (isNullType(option.type)) {
16
+ // TODO how should we treat this? https://github.com/microsoft/typespec/issues/356
17
+ continue;
18
+ }
19
+ processResponseType(program, diagnostics, responses, option.type);
20
+ }
21
+ }
22
+ else {
23
+ processResponseType(program, diagnostics, responses, responseType);
24
+ }
25
+ return diagnostics.wrap(Object.values(responses));
26
+ }
27
+ function processResponseType(program, diagnostics, responses, responseType) {
28
+ var _a;
29
+ const metadata = gatherMetadata(program, diagnostics, responseType, Visibility.Read);
30
+ // Get explicity defined status codes
31
+ const statusCodes = getResponseStatusCodes(program, responseType, metadata);
32
+ // Get explicitly defined content types
33
+ const contentTypes = getResponseContentTypes(program, diagnostics, metadata);
34
+ // Get response headers
35
+ const headers = getResponseHeaders(program, metadata);
36
+ // Get body
37
+ let bodyType = getResponseBody(program, diagnostics, responseType, metadata);
38
+ // If there is no explicit status code, check if it should be 204
39
+ if (statusCodes.length === 0) {
40
+ if (bodyType === undefined || isVoidType(bodyType)) {
41
+ bodyType = undefined;
42
+ statusCodes.push("204");
43
+ }
44
+ else if (isErrorModel(program, responseType)) {
45
+ statusCodes.push("*");
46
+ }
47
+ else {
48
+ statusCodes.push("200");
49
+ }
50
+ }
51
+ // If there is a body but no explicit content types, use application/json
52
+ if (bodyType && contentTypes.length === 0) {
53
+ contentTypes.push("application/json");
54
+ }
55
+ // Put them into currentEndpoint.responses
56
+ for (const statusCode of statusCodes) {
57
+ // the first model for this statusCode/content type pair carries the
58
+ // description for the endpoint. This could probably be improved.
59
+ const response = (_a = responses[statusCode]) !== null && _a !== void 0 ? _a : {
60
+ statusCode,
61
+ type: responseType,
62
+ description: getResponseDescription(program, responseType, statusCode, bodyType),
63
+ responses: [],
64
+ };
65
+ // check for duplicates
66
+ for (const contentType of contentTypes) {
67
+ if (response.responses.find((x) => { var _a; return (_a = x.body) === null || _a === void 0 ? void 0 : _a.contentTypes.includes(contentType); })) {
68
+ diagnostics.add(createDiagnostic({
69
+ code: "duplicate-response",
70
+ format: { statusCode: statusCode.toString(), contentType },
71
+ target: responseType,
72
+ }));
73
+ }
74
+ }
75
+ if (bodyType !== undefined) {
76
+ response.responses.push({ body: { contentTypes: contentTypes, type: bodyType }, headers });
77
+ }
78
+ else if (contentTypes.length > 0) {
79
+ diagnostics.add(createDiagnostic({
80
+ code: "content-type-ignored",
81
+ target: responseType,
82
+ }));
83
+ }
84
+ else {
85
+ response.responses.push({ headers });
86
+ }
87
+ responses[statusCode] = response;
88
+ }
89
+ }
90
+ /**
91
+ * Get explicity defined status codes from response type and metadata
92
+ * Return is an array of strings, possibly empty, which indicates no explicitly defined status codes.
93
+ * We do not check for duplicates here -- that will be done by the caller.
94
+ */
95
+ function getResponseStatusCodes(program, responseType, metadata) {
96
+ const codes = [];
97
+ for (const prop of metadata) {
98
+ if (isStatusCode(program, prop)) {
99
+ codes.push(...getStatusCodes(program, prop));
100
+ }
101
+ }
102
+ if (responseType.kind === "Model") {
103
+ for (let t = responseType; t; t = t.baseModel) {
104
+ codes.push(...getStatusCodes(program, t));
105
+ }
106
+ }
107
+ return codes;
108
+ }
109
+ /**
110
+ * Get explicity defined content-types from response metadata
111
+ * Return is an array of strings, possibly empty, which indicates no explicitly defined content-type.
112
+ * We do not check for duplicates here -- that will be done by the caller.
113
+ */
114
+ function getResponseContentTypes(program, diagnostics, metadata) {
115
+ const contentTypes = [];
116
+ for (const prop of metadata) {
117
+ if (isHeader(program, prop) && isContentTypeHeader(program, prop)) {
118
+ contentTypes.push(...diagnostics.pipe(getContentTypes(prop)));
119
+ }
120
+ }
121
+ return contentTypes;
122
+ }
123
+ /**
124
+ * Get response headers from response metadata
125
+ */
126
+ function getResponseHeaders(program, metadata) {
127
+ const responseHeaders = {};
128
+ for (const prop of metadata) {
129
+ const headerName = getHeaderFieldName(program, prop);
130
+ if (isHeader(program, prop) && headerName !== "content-type") {
131
+ responseHeaders[headerName] = prop;
132
+ }
133
+ }
134
+ return responseHeaders;
135
+ }
136
+ function getResponseBody(program, diagnostics, responseType, metadata) {
137
+ // non-model or intrinsic/array model -> response body is response type
138
+ if (responseType.kind !== "Model" || isArrayModelType(program, responseType)) {
139
+ return responseType;
140
+ }
141
+ // look for explicit body
142
+ let bodyProperty;
143
+ for (const property of metadata) {
144
+ if (isBody(program, property)) {
145
+ if (bodyProperty) {
146
+ diagnostics.add(createDiagnostic({ code: "duplicate-body", target: property }));
147
+ }
148
+ else {
149
+ bodyProperty = property;
150
+ }
151
+ }
152
+ }
153
+ if (bodyProperty) {
154
+ return bodyProperty.type;
155
+ }
156
+ // Without an explicit body, response type is response model itself if
157
+ // there it has at least one non-metadata property, if it is an empty object or if it has derived
158
+ // models
159
+ if (responseType.derivedModels.length > 0 || responseType.properties.size === 0) {
160
+ return responseType;
161
+ }
162
+ for (const property of walkPropertiesInherited(responseType)) {
163
+ if (!isApplicableMetadata(program, property, Visibility.Read)) {
164
+ return responseType;
165
+ }
166
+ }
167
+ // Otherwise, there is no body
168
+ return undefined;
169
+ }
170
+ function getResponseDescription(program, responseType, statusCode, bodyType) {
171
+ // NOTE: If the response type is an envelope and not the same as the body
172
+ // type, then use its @doc as the response description. However, if the
173
+ // response type is the same as the body type, then use the default status
174
+ // code description and don't duplicate the schema description of the body
175
+ // as the response description. This allows more freedom to change how
176
+ // TypeSpec is expressed in semantically equivalent ways without causing
177
+ // the output to change unnecessarily.
178
+ if (responseType !== bodyType) {
179
+ const desc = getDoc(program, responseType);
180
+ if (desc) {
181
+ return desc;
182
+ }
183
+ }
184
+ return getStatusCodeDescription(statusCode);
185
+ }
186
+ //# sourceMappingURL=responses.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"responses.js","sourceRoot":"","sources":["../../src/responses.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,23 @@
1
+ import { DecoratorContext, DiagnosticResult, Interface, Namespace, Operation, Program, Type } from "@typespec/compiler";
2
+ import { HttpOperation, HttpOperationParameters, RouteOptions, RoutePath, RouteProducer, RouteProducerResult, RouteResolutionOptions } from "./types.js";
3
+ export declare function resolvePathAndParameters(program: Program, operation: Operation, overloadBase: HttpOperation | undefined, options: RouteResolutionOptions): DiagnosticResult<{
4
+ path: string;
5
+ pathSegments: string[];
6
+ parameters: HttpOperationParameters;
7
+ }>;
8
+ /**
9
+ * @deprecated DO NOT USE. For internal use only as a workaround.
10
+ * @param program Program
11
+ * @param target Target namespace
12
+ * @param sourceInterface Interface that should be included in namespace.
13
+ */
14
+ export declare function includeInterfaceRoutesInNamespace(program: Program, target: Namespace, sourceInterface: string): void;
15
+ export declare function DefaultRouteProducer(program: Program, operation: Operation, parentSegments: string[], overloadBase: HttpOperation | undefined, options: RouteOptions): DiagnosticResult<RouteProducerResult>;
16
+ export declare function setRouteProducer(program: Program, operation: Operation, routeProducer: RouteProducer): void;
17
+ export declare function getRouteProducer(program: Program, operation: Operation): RouteProducer;
18
+ export declare function setRoute(context: DecoratorContext, entity: Type, details: RoutePath): void;
19
+ export declare function isSharedRoute(program: Program, operation: Operation): boolean;
20
+ export declare function getRoutePath(program: Program, entity: Namespace | Interface | Operation): RoutePath | undefined;
21
+ export declare function setRouteOptionsForNamespace(program: Program, namespace: Namespace, options: RouteOptions): void;
22
+ export declare function getRouteOptionsForNamespace(program: Program, namespace: Namespace): RouteOptions | undefined;
23
+ //# sourceMappingURL=route.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"route.d.ts","sourceRoot":"","sources":["../../src/route.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,gBAAgB,EAChB,gBAAgB,EAChB,SAAS,EACT,SAAS,EACT,SAAS,EACT,OAAO,EACP,IAAI,EAEL,MAAM,oBAAoB,CAAC;AAG5B,OAAO,EACL,aAAa,EACb,uBAAuB,EACvB,YAAY,EACZ,SAAS,EACT,aAAa,EACb,mBAAmB,EACnB,sBAAsB,EACvB,MAAM,YAAY,CAAC;AA8BpB,wBAAgB,wBAAwB,CACtC,OAAO,EAAE,OAAO,EAChB,SAAS,EAAE,SAAS,EACpB,YAAY,EAAE,aAAa,GAAG,SAAS,EACvC,OAAO,EAAE,sBAAsB,GAC9B,gBAAgB,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,UAAU,EAAE,uBAAuB,CAAC;CACrC,CAAC,CA+BD;AAyCD;;;;;GAKG;AACH,wBAAgB,iCAAiC,CAC/C,OAAO,EAAE,OAAO,EAChB,MAAM,EAAE,SAAS,EACjB,eAAe,EAAE,MAAM,QASxB;AAID,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,OAAO,EAChB,SAAS,EAAE,SAAS,EACpB,cAAc,EAAE,MAAM,EAAE,EACxB,YAAY,EAAE,aAAa,GAAG,SAAS,EACvC,OAAO,EAAE,YAAY,GACpB,gBAAgB,CAAC,mBAAmB,CAAC,CAgCvC;AAED,wBAAgB,gBAAgB,CAC9B,OAAO,EAAE,OAAO,EAChB,SAAS,EAAE,SAAS,EACpB,aAAa,EAAE,aAAa,GAC3B,IAAI,CAEN;AAED,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,GAAG,aAAa,CAEtF;AAID,wBAAgB,QAAQ,CAAC,OAAO,EAAE,gBAAgB,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,SAAS,QAqBnF;AAED,wBAAgB,aAAa,CAAC,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,GAAG,OAAO,CAE7E;AAED,wBAAgB,YAAY,CAC1B,OAAO,EAAE,OAAO,EAChB,MAAM,EAAE,SAAS,GAAG,SAAS,GAAG,SAAS,GACxC,SAAS,GAAG,SAAS,CAEvB;AAID,wBAAgB,2BAA2B,CACzC,OAAO,EAAE,OAAO,EAChB,SAAS,EAAE,SAAS,EACpB,OAAO,EAAE,YAAY,QAGtB;AAED,wBAAgB,2BAA2B,CACzC,OAAO,EAAE,OAAO,EAChB,SAAS,EAAE,SAAS,GACnB,YAAY,GAAG,SAAS,CAE1B"}
@@ -0,0 +1,149 @@
1
+ import { createDiagnosticCollector, validateDecoratorTarget, } from "@typespec/compiler";
2
+ import { createDiagnostic, createStateSymbol, reportDiagnostic } from "./lib.js";
3
+ import { getOperationParameters } from "./parameters.js";
4
+ import { extractParamsFromPath } from "./utils.js";
5
+ // The set of allowed segment separator characters
6
+ const AllowedSegmentSeparators = ["/", ":"];
7
+ function normalizeFragment(fragment) {
8
+ if (fragment.length > 0 && AllowedSegmentSeparators.indexOf(fragment[0]) < 0) {
9
+ // Insert the default separator
10
+ fragment = `/${fragment}`;
11
+ }
12
+ // Trim any trailing slash
13
+ return fragment.replace(/\/$/g, "");
14
+ }
15
+ function buildPath(pathFragments) {
16
+ // Join all fragments with leading and trailing slashes trimmed
17
+ const path = pathFragments.length === 0
18
+ ? "/"
19
+ : pathFragments
20
+ .map(normalizeFragment)
21
+ .filter((x) => x !== "")
22
+ .join("");
23
+ // The final path must start with a '/'
24
+ return path.length > 0 && path[0] === "/" ? path : `/${path}`;
25
+ }
26
+ export function resolvePathAndParameters(program, operation, overloadBase, options) {
27
+ const diagnostics = createDiagnosticCollector();
28
+ const { segments, parameters } = diagnostics.pipe(getRouteSegments(program, operation, overloadBase, options));
29
+ // Pull out path parameters to verify what's in the path string
30
+ const paramByName = new Set(parameters.parameters.filter(({ type }) => type === "path").map(({ param }) => param.name));
31
+ // Ensure that all of the parameters defined in the route are accounted for in
32
+ // the operation parameters
33
+ const routeParams = segments.flatMap(extractParamsFromPath);
34
+ for (const routeParam of routeParams) {
35
+ if (!paramByName.has(routeParam)) {
36
+ diagnostics.add(createDiagnostic({
37
+ code: "missing-path-param",
38
+ format: { param: routeParam },
39
+ target: operation,
40
+ }));
41
+ }
42
+ }
43
+ return diagnostics.wrap({
44
+ path: buildPath(segments),
45
+ pathSegments: segments,
46
+ parameters,
47
+ });
48
+ }
49
+ function collectSegmentsAndOptions(program, source) {
50
+ var _a, _b;
51
+ if (source === undefined)
52
+ return [[], {}];
53
+ const [parentSegments, parentOptions] = collectSegmentsAndOptions(program, source.namespace);
54
+ const route = (_a = getRoutePath(program, source)) === null || _a === void 0 ? void 0 : _a.path;
55
+ const options = source.kind === "Namespace" ? (_b = getRouteOptionsForNamespace(program, source)) !== null && _b !== void 0 ? _b : {} : {};
56
+ return [[...parentSegments, ...(route ? [route] : [])], { ...parentOptions, ...options }];
57
+ }
58
+ function getRouteSegments(program, operation, overloadBase, options) {
59
+ var _a, _b;
60
+ const diagnostics = createDiagnosticCollector();
61
+ const [parentSegments, parentOptions] = collectSegmentsAndOptions(program, (_a = operation.interface) !== null && _a !== void 0 ? _a : operation.namespace);
62
+ const routeProducer = (_b = getRouteProducer(program, operation)) !== null && _b !== void 0 ? _b : DefaultRouteProducer;
63
+ const result = diagnostics.pipe(routeProducer(program, operation, parentSegments, overloadBase, {
64
+ ...parentOptions,
65
+ ...options,
66
+ }));
67
+ return diagnostics.wrap(result);
68
+ }
69
+ const externalInterfaces = createStateSymbol("externalInterfaces");
70
+ /**
71
+ * @deprecated DO NOT USE. For internal use only as a workaround.
72
+ * @param program Program
73
+ * @param target Target namespace
74
+ * @param sourceInterface Interface that should be included in namespace.
75
+ */
76
+ export function includeInterfaceRoutesInNamespace(program, target, sourceInterface) {
77
+ let array = program.stateMap(externalInterfaces).get(target);
78
+ if (array === undefined) {
79
+ array = [];
80
+ program.stateMap(externalInterfaces).set(target, array);
81
+ }
82
+ array.push(sourceInterface);
83
+ }
84
+ const routeProducerKey = createStateSymbol("routeProducer");
85
+ export function DefaultRouteProducer(program, operation, parentSegments, overloadBase, options) {
86
+ var _a;
87
+ const diagnostics = createDiagnosticCollector();
88
+ const routePath = (_a = getRoutePath(program, operation)) === null || _a === void 0 ? void 0 : _a.path;
89
+ const segments = !routePath && overloadBase
90
+ ? overloadBase.pathSegments
91
+ : [...parentSegments, ...(routePath ? [routePath] : [])];
92
+ const routeParams = segments.flatMap(extractParamsFromPath);
93
+ const parameters = diagnostics.pipe(getOperationParameters(program, operation, overloadBase, routeParams, options.paramOptions));
94
+ // Pull out path parameters to verify what's in the path string
95
+ const unreferencedPathParamNames = new Set(parameters.parameters.filter(({ type }) => type === "path").map(({ param }) => param.name));
96
+ // Compile the list of all route params that aren't represented in the route
97
+ for (const routeParam of routeParams) {
98
+ unreferencedPathParamNames.delete(routeParam);
99
+ }
100
+ // Add any remaining declared path params
101
+ for (const paramName of unreferencedPathParamNames) {
102
+ segments.push(`{${paramName}}`);
103
+ }
104
+ return diagnostics.wrap({
105
+ segments,
106
+ parameters,
107
+ });
108
+ }
109
+ export function setRouteProducer(program, operation, routeProducer) {
110
+ program.stateMap(routeProducerKey).set(operation, routeProducer);
111
+ }
112
+ export function getRouteProducer(program, operation) {
113
+ return program.stateMap(routeProducerKey).get(operation);
114
+ }
115
+ const routesKey = createStateSymbol("routes");
116
+ export function setRoute(context, entity, details) {
117
+ if (!validateDecoratorTarget(context, entity, "@route", ["Namespace", "Interface", "Operation"])) {
118
+ return;
119
+ }
120
+ const state = context.program.stateMap(routesKey);
121
+ if (state.has(entity) && entity.kind === "Namespace") {
122
+ const existingValue = state.get(entity);
123
+ if (existingValue.path !== details.path) {
124
+ reportDiagnostic(context.program, {
125
+ code: "duplicate-route-decorator",
126
+ messageId: "namespace",
127
+ target: entity,
128
+ });
129
+ }
130
+ }
131
+ else {
132
+ state.set(entity, details);
133
+ }
134
+ }
135
+ export function isSharedRoute(program, operation) {
136
+ var _a;
137
+ return (_a = program.stateMap(routesKey).get(operation)) === null || _a === void 0 ? void 0 : _a.shared;
138
+ }
139
+ export function getRoutePath(program, entity) {
140
+ return program.stateMap(routesKey).get(entity);
141
+ }
142
+ const routeOptionsKey = createStateSymbol("routeOptions");
143
+ export function setRouteOptionsForNamespace(program, namespace, options) {
144
+ program.stateMap(routeOptionsKey).set(namespace, options);
145
+ }
146
+ export function getRouteOptionsForNamespace(program, namespace) {
147
+ return program.stateMap(routeOptionsKey).get(namespace);
148
+ }
149
+ //# sourceMappingURL=route.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"route.js","sourceRoot":"","sources":["../../src/route.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import { TypeSpecTestLibrary } from "@typespec/compiler/testing";
2
+ export declare const HttpTestLibrary: TypeSpecTestLibrary;
3
+ //# sourceMappingURL=index.d.ts.map
@@ -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 HttpTestLibrary = createTestLibrary({
5
+ name: "@typespec/http",
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"}