@typespec/ts-http-runtime 1.0.0-alpha.20240930.1 → 1.0.0-alpha.20241007.3

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 (30) hide show
  1. package/dist/browser/client/common.d.ts +15 -1
  2. package/dist/browser/client/common.d.ts.map +1 -1
  3. package/dist/browser/client/common.js.map +1 -1
  4. package/dist/browser/client/urlHelpers.d.ts +2 -2
  5. package/dist/browser/client/urlHelpers.d.ts.map +1 -1
  6. package/dist/browser/client/urlHelpers.js +75 -23
  7. package/dist/browser/client/urlHelpers.js.map +1 -1
  8. package/dist/commonjs/client/common.d.ts +15 -1
  9. package/dist/commonjs/client/common.d.ts.map +1 -1
  10. package/dist/commonjs/client/common.js.map +1 -1
  11. package/dist/commonjs/client/urlHelpers.d.ts +2 -2
  12. package/dist/commonjs/client/urlHelpers.d.ts.map +1 -1
  13. package/dist/commonjs/client/urlHelpers.js +75 -23
  14. package/dist/commonjs/client/urlHelpers.js.map +1 -1
  15. package/dist/esm/client/common.d.ts +15 -1
  16. package/dist/esm/client/common.d.ts.map +1 -1
  17. package/dist/esm/client/common.js.map +1 -1
  18. package/dist/esm/client/urlHelpers.d.ts +2 -2
  19. package/dist/esm/client/urlHelpers.d.ts.map +1 -1
  20. package/dist/esm/client/urlHelpers.js +75 -23
  21. package/dist/esm/client/urlHelpers.js.map +1 -1
  22. package/dist/react-native/client/common.d.ts +15 -1
  23. package/dist/react-native/client/common.d.ts.map +1 -1
  24. package/dist/react-native/client/common.js.map +1 -1
  25. package/dist/react-native/client/urlHelpers.d.ts +2 -2
  26. package/dist/react-native/client/urlHelpers.d.ts.map +1 -1
  27. package/dist/react-native/client/urlHelpers.js +75 -23
  28. package/dist/react-native/client/urlHelpers.js.map +1 -1
  29. package/dist/ts-http-runtime.d.ts +16 -1
  30. package/package.json +1 -1
@@ -1,5 +1,9 @@
1
1
  // Copyright (c) Microsoft Corporation.
2
2
  // Licensed under the MIT License.
3
+ function isQueryParameterWithOptions(x) {
4
+ const value = x.value;
5
+ return (value !== undefined && value.toString !== undefined && typeof value.toString === "function");
6
+ }
3
7
  /**
4
8
  * Builds the request url, filling in query and path parameters
5
9
  * @param endpoint - base url which can be a template url
@@ -21,41 +25,87 @@ export function buildRequestUrl(endpoint, routePath, pathParameters, options = {
21
25
  // Remove double forward slashes
22
26
  .replace(/([^:]\/)\/+/g, "$1"));
23
27
  }
28
+ function getQueryParamValue(key, allowReserved, style, param) {
29
+ let separator;
30
+ if (style === "pipeDelimited") {
31
+ separator = "|";
32
+ }
33
+ else if (style === "spaceDelimited") {
34
+ separator = "%20";
35
+ }
36
+ else {
37
+ separator = ",";
38
+ }
39
+ let paramValues;
40
+ if (Array.isArray(param)) {
41
+ paramValues = param;
42
+ }
43
+ else if (typeof param === "object" && param.toString === Object.prototype.toString) {
44
+ // If the parameter is an object without a custom toString implementation (e.g. a Date),
45
+ // then we should deconstruct the object into an array [key1, value1, key2, value2, ...].
46
+ paramValues = Object.entries(param).flat();
47
+ }
48
+ else {
49
+ paramValues = [param];
50
+ }
51
+ const value = paramValues
52
+ .map((p) => {
53
+ if (p === null || p === undefined) {
54
+ return "";
55
+ }
56
+ if (!p.toString || typeof p.toString !== "function") {
57
+ throw new Error(`Query parameters must be able to be represented as string, ${key} can't`);
58
+ }
59
+ const rawValue = p.toISOString !== undefined ? p.toISOString() : p.toString();
60
+ return allowReserved ? rawValue : encodeURIComponent(rawValue);
61
+ })
62
+ .join(separator);
63
+ return `${allowReserved ? key : encodeURIComponent(key)}=${value}`;
64
+ }
24
65
  function appendQueryParams(url, options = {}) {
66
+ var _a, _b, _c, _d;
25
67
  if (!options.queryParameters) {
26
68
  return url;
27
69
  }
28
- let parsedUrl = new URL(url);
70
+ const parsedUrl = new URL(url);
29
71
  const queryParams = options.queryParameters;
72
+ const paramStrings = [];
30
73
  for (const key of Object.keys(queryParams)) {
31
74
  const param = queryParams[key];
32
75
  if (param === undefined || param === null) {
33
76
  continue;
34
77
  }
35
- if (!param.toString || typeof param.toString !== "function") {
36
- throw new Error(`Query parameters must be able to be represented as string, ${key} can't`);
78
+ const hasMetadata = isQueryParameterWithOptions(param);
79
+ const rawValue = hasMetadata ? param.value : param;
80
+ const explode = hasMetadata ? ((_a = param.explode) !== null && _a !== void 0 ? _a : false) : false;
81
+ const style = hasMetadata && param.style ? param.style : "form";
82
+ if (explode) {
83
+ if (Array.isArray(rawValue)) {
84
+ for (const item of rawValue) {
85
+ paramStrings.push(getQueryParamValue(key, (_b = options.skipUrlEncoding) !== null && _b !== void 0 ? _b : false, style, item));
86
+ }
87
+ }
88
+ else if (typeof rawValue === "object") {
89
+ // For object explode, the name of the query parameter is ignored and we use the object key instead
90
+ for (const [actualKey, value] of Object.entries(rawValue)) {
91
+ paramStrings.push(getQueryParamValue(actualKey, (_c = options.skipUrlEncoding) !== null && _c !== void 0 ? _c : false, style, value));
92
+ }
93
+ }
94
+ else {
95
+ // Explode doesn't really make sense for primitives
96
+ throw new Error("explode can only be set to true for objects and arrays");
97
+ }
98
+ }
99
+ else {
100
+ paramStrings.push(getQueryParamValue(key, (_d = options.skipUrlEncoding) !== null && _d !== void 0 ? _d : false, style, rawValue));
37
101
  }
38
- const value = param.toISOString !== undefined ? param.toISOString() : param.toString();
39
- parsedUrl.searchParams.append(key, value);
40
102
  }
41
- if (options.skipUrlEncoding) {
42
- parsedUrl = skipQueryParameterEncoding(parsedUrl);
103
+ if (parsedUrl.search !== "") {
104
+ parsedUrl.search += "&";
43
105
  }
106
+ parsedUrl.search += paramStrings.join("&");
44
107
  return parsedUrl.toString();
45
108
  }
46
- function skipQueryParameterEncoding(url) {
47
- if (!url) {
48
- return url;
49
- }
50
- const searchPieces = [];
51
- for (const [name, value] of url.searchParams) {
52
- // QUIRK: searchParams.get retrieves the values decoded
53
- searchPieces.push(`${name}=${value}`);
54
- }
55
- // QUIRK: we have to set search manually as searchParams will encode comma when it shouldn't.
56
- url.search = searchPieces.length ? `?${searchPieces.join("&")}` : "";
57
- return url;
58
- }
59
109
  export function buildBaseUrl(endpoint, options) {
60
110
  var _a;
61
111
  if (!options.pathParameters) {
@@ -78,10 +128,12 @@ export function buildBaseUrl(endpoint, options) {
78
128
  return endpoint;
79
129
  }
80
130
  function buildRoutePath(routePath, pathParameters, options = {}) {
131
+ var _a;
81
132
  for (const pathParam of pathParameters) {
82
- let value = pathParam;
83
- if (!options.skipUrlEncoding) {
84
- value = encodeURIComponent(pathParam);
133
+ const allowReserved = typeof pathParam === "string" ? false : ((_a = pathParam === null || pathParam === void 0 ? void 0 : pathParam.allowReserved) !== null && _a !== void 0 ? _a : false);
134
+ let value = typeof pathParam === "string" ? pathParam : pathParam === null || pathParam === void 0 ? void 0 : pathParam.value;
135
+ if (!options.skipUrlEncoding && !allowReserved) {
136
+ value = encodeURIComponent(value);
85
137
  }
86
138
  routePath = routePath.replace(/\{\w+\}/, value);
87
139
  }
@@ -1 +1 @@
1
- {"version":3,"file":"urlHelpers.js","sourceRoot":"","sources":["../../../src/client/urlHelpers.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\nimport { RequestParameters } from \"./common.js\";\n\n/**\n * Builds the request url, filling in query and path parameters\n * @param endpoint - base url which can be a template url\n * @param routePath - path to append to the endpoint\n * @param pathParameters - values of the path parameters\n * @param options - request parameters including query parameters\n * @returns a full url with path and query parameters\n */\nexport function buildRequestUrl(\n endpoint: string,\n routePath: string,\n pathParameters: string[],\n options: RequestParameters = {},\n): string {\n if (routePath.startsWith(\"https://\") || routePath.startsWith(\"http://\")) {\n return routePath;\n }\n endpoint = buildBaseUrl(endpoint, options);\n routePath = buildRoutePath(routePath, pathParameters, options);\n const requestUrl = appendQueryParams(`${endpoint}/${routePath}`, options);\n const url = new URL(requestUrl);\n\n return (\n url\n .toString()\n // Remove double forward slashes\n .replace(/([^:]\\/)\\/+/g, \"$1\")\n );\n}\n\nfunction appendQueryParams(url: string, options: RequestParameters = {}): string {\n if (!options.queryParameters) {\n return url;\n }\n let parsedUrl = new URL(url);\n const queryParams = options.queryParameters;\n for (const key of Object.keys(queryParams)) {\n const param = queryParams[key] as any;\n if (param === undefined || param === null) {\n continue;\n }\n if (!param.toString || typeof param.toString !== \"function\") {\n throw new Error(`Query parameters must be able to be represented as string, ${key} can't`);\n }\n const value = param.toISOString !== undefined ? param.toISOString() : param.toString();\n parsedUrl.searchParams.append(key, value);\n }\n\n if (options.skipUrlEncoding) {\n parsedUrl = skipQueryParameterEncoding(parsedUrl);\n }\n return parsedUrl.toString();\n}\n\nfunction skipQueryParameterEncoding(url: URL): URL {\n if (!url) {\n return url;\n }\n const searchPieces: string[] = [];\n for (const [name, value] of url.searchParams) {\n // QUIRK: searchParams.get retrieves the values decoded\n searchPieces.push(`${name}=${value}`);\n }\n // QUIRK: we have to set search manually as searchParams will encode comma when it shouldn't.\n url.search = searchPieces.length ? `?${searchPieces.join(\"&\")}` : \"\";\n return url;\n}\n\nexport function buildBaseUrl(endpoint: string, options: RequestParameters): string {\n if (!options.pathParameters) {\n return endpoint;\n }\n const pathParams = options.pathParameters;\n for (const [key, param] of Object.entries(pathParams)) {\n if (param === undefined || param === null) {\n throw new Error(`Path parameters ${key} must not be undefined or null`);\n }\n if (!param.toString || typeof param.toString !== \"function\") {\n throw new Error(`Path parameters must be able to be represented as string, ${key} can't`);\n }\n let value = param.toISOString !== undefined ? param.toISOString() : String(param);\n if (!options.skipUrlEncoding) {\n value = encodeURIComponent(param);\n }\n endpoint = replaceAll(endpoint, `{${key}}`, value) ?? \"\";\n }\n return endpoint;\n}\n\nfunction buildRoutePath(\n routePath: string,\n pathParameters: string[],\n options: RequestParameters = {},\n): string {\n for (const pathParam of pathParameters) {\n let value = pathParam;\n if (!options.skipUrlEncoding) {\n value = encodeURIComponent(pathParam);\n }\n\n routePath = routePath.replace(/\\{\\w+\\}/, value);\n }\n return routePath;\n}\n\n/**\n * Replace all of the instances of searchValue in value with the provided replaceValue.\n * @param value - The value to search and replace in.\n * @param searchValue - The value to search for in the value argument.\n * @param replaceValue - The value to replace searchValue with in the value argument.\n * @returns The value where each instance of searchValue was replaced with replacedValue.\n */\nexport function replaceAll(\n value: string | undefined,\n searchValue: string,\n replaceValue: string,\n): string | undefined {\n return !value || !searchValue ? value : value.split(searchValue).join(replaceValue || \"\");\n}\n"]}
1
+ {"version":3,"file":"urlHelpers.js","sourceRoot":"","sources":["../../../src/client/urlHelpers.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC;AAqClC,SAAS,2BAA2B,CAAC,CAAU;IAC7C,MAAM,KAAK,GAAI,CAA+B,CAAC,KAAY,CAAC;IAC5D,OAAO,CACL,KAAK,KAAK,SAAS,IAAI,KAAK,CAAC,QAAQ,KAAK,SAAS,IAAI,OAAO,KAAK,CAAC,QAAQ,KAAK,UAAU,CAC5F,CAAC;AACJ,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,eAAe,CAC7B,QAAgB,EAChB,SAAiB,EACjB,cAAqD,EACrD,UAA6B,EAAE;IAE/B,IAAI,SAAS,CAAC,UAAU,CAAC,UAAU,CAAC,IAAI,SAAS,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;QACxE,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,QAAQ,GAAG,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IAC3C,SAAS,GAAG,cAAc,CAAC,SAAS,EAAE,cAAc,EAAE,OAAO,CAAC,CAAC;IAC/D,MAAM,UAAU,GAAG,iBAAiB,CAAC,GAAG,QAAQ,IAAI,SAAS,EAAE,EAAE,OAAO,CAAC,CAAC;IAC1E,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,UAAU,CAAC,CAAC;IAEhC,OAAO,CACL,GAAG;SACA,QAAQ,EAAE;QACX,gCAAgC;SAC/B,OAAO,CAAC,cAAc,EAAE,IAAI,CAAC,CACjC,CAAC;AACJ,CAAC;AAED,SAAS,kBAAkB,CACzB,GAAW,EACX,aAAsB,EACtB,KAA0B,EAC1B,KAAU;IAEV,IAAI,SAAiB,CAAC;IACtB,IAAI,KAAK,KAAK,eAAe,EAAE,CAAC;QAC9B,SAAS,GAAG,GAAG,CAAC;IAClB,CAAC;SAAM,IAAI,KAAK,KAAK,gBAAgB,EAAE,CAAC;QACtC,SAAS,GAAG,KAAK,CAAC;IACpB,CAAC;SAAM,CAAC;QACN,SAAS,GAAG,GAAG,CAAC;IAClB,CAAC;IAED,IAAI,WAAkB,CAAC;IACvB,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACzB,WAAW,GAAG,KAAK,CAAC;IACtB,CAAC;SAAM,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,QAAQ,KAAK,MAAM,CAAC,SAAS,CAAC,QAAQ,EAAE,CAAC;QACrF,wFAAwF;QACxF,yFAAyF;QACzF,WAAW,GAAG,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,CAAC;IAC7C,CAAC;SAAM,CAAC;QACN,WAAW,GAAG,CAAC,KAAK,CAAC,CAAC;IACxB,CAAC;IAED,MAAM,KAAK,GAAG,WAAW;SACtB,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;QACT,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,SAAS,EAAE,CAAC;YAClC,OAAO,EAAE,CAAC;QACZ,CAAC;QAED,IAAI,CAAC,CAAC,CAAC,QAAQ,IAAI,OAAO,CAAC,CAAC,QAAQ,KAAK,UAAU,EAAE,CAAC;YACpD,MAAM,IAAI,KAAK,CAAC,8DAA8D,GAAG,QAAQ,CAAC,CAAC;QAC7F,CAAC;QAED,MAAM,QAAQ,GAAG,CAAC,CAAC,WAAW,KAAK,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC;QAC9E,OAAO,aAAa,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,kBAAkB,CAAC,QAAQ,CAAC,CAAC;IACjE,CAAC,CAAC;SACD,IAAI,CAAC,SAAS,CAAC,CAAC;IAEnB,OAAO,GAAG,aAAa,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,kBAAkB,CAAC,GAAG,CAAC,IAAI,KAAK,EAAE,CAAC;AACrE,CAAC;AAED,SAAS,iBAAiB,CAAC,GAAW,EAAE,UAA6B,EAAE;;IACrE,IAAI,CAAC,OAAO,CAAC,eAAe,EAAE,CAAC;QAC7B,OAAO,GAAG,CAAC;IACb,CAAC;IACD,MAAM,SAAS,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC;IAC/B,MAAM,WAAW,GAAG,OAAO,CAAC,eAAe,CAAC;IAE5C,MAAM,YAAY,GAAa,EAAE,CAAC;IAClC,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,CAAC;QAC3C,MAAM,KAAK,GAAG,WAAW,CAAC,GAAG,CAAQ,CAAC;QACtC,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;YAC1C,SAAS;QACX,CAAC;QAED,MAAM,WAAW,GAAG,2BAA2B,CAAC,KAAK,CAAC,CAAC;QACvD,MAAM,QAAQ,GAAG,WAAW,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC;QACnD,MAAM,OAAO,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC,MAAA,KAAK,CAAC,OAAO,mCAAI,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;QAC/D,MAAM,KAAK,GAAG,WAAW,IAAI,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC;QAEhE,IAAI,OAAO,EAAE,CAAC;YACZ,IAAI,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC;gBAC5B,KAAK,MAAM,IAAI,IAAI,QAAQ,EAAE,CAAC;oBAC5B,YAAY,CAAC,IAAI,CAAC,kBAAkB,CAAC,GAAG,EAAE,MAAA,OAAO,CAAC,eAAe,mCAAI,KAAK,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC,CAAC;gBAC5F,CAAC;YACH,CAAC;iBAAM,IAAI,OAAO,QAAQ,KAAK,QAAQ,EAAE,CAAC;gBACxC,mGAAmG;gBACnG,KAAK,MAAM,CAAC,SAAS,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC;oBAC1D,YAAY,CAAC,IAAI,CACf,kBAAkB,CAAC,SAAS,EAAE,MAAA,OAAO,CAAC,eAAe,mCAAI,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC,CAC9E,CAAC;gBACJ,CAAC;YACH,CAAC;iBAAM,CAAC;gBACN,mDAAmD;gBACnD,MAAM,IAAI,KAAK,CAAC,wDAAwD,CAAC,CAAC;YAC5E,CAAC;QACH,CAAC;aAAM,CAAC;YACN,YAAY,CAAC,IAAI,CAAC,kBAAkB,CAAC,GAAG,EAAE,MAAA,OAAO,CAAC,eAAe,mCAAI,KAAK,EAAE,KAAK,EAAE,QAAQ,CAAC,CAAC,CAAC;QAChG,CAAC;IACH,CAAC;IAED,IAAI,SAAS,CAAC,MAAM,KAAK,EAAE,EAAE,CAAC;QAC5B,SAAS,CAAC,MAAM,IAAI,GAAG,CAAC;IAC1B,CAAC;IACD,SAAS,CAAC,MAAM,IAAI,YAAY,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC3C,OAAO,SAAS,CAAC,QAAQ,EAAE,CAAC;AAC9B,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,QAAgB,EAAE,OAA0B;;IACvE,IAAI,CAAC,OAAO,CAAC,cAAc,EAAE,CAAC;QAC5B,OAAO,QAAQ,CAAC;IAClB,CAAC;IACD,MAAM,UAAU,GAAG,OAAO,CAAC,cAAc,CAAC;IAC1C,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,CAAC;QACtD,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;YAC1C,MAAM,IAAI,KAAK,CAAC,mBAAmB,GAAG,gCAAgC,CAAC,CAAC;QAC1E,CAAC;QACD,IAAI,CAAC,KAAK,CAAC,QAAQ,IAAI,OAAO,KAAK,CAAC,QAAQ,KAAK,UAAU,EAAE,CAAC;YAC5D,MAAM,IAAI,KAAK,CAAC,6DAA6D,GAAG,QAAQ,CAAC,CAAC;QAC5F,CAAC;QACD,IAAI,KAAK,GAAG,KAAK,CAAC,WAAW,KAAK,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAClF,IAAI,CAAC,OAAO,CAAC,eAAe,EAAE,CAAC;YAC7B,KAAK,GAAG,kBAAkB,CAAC,KAAK,CAAC,CAAC;QACpC,CAAC;QACD,QAAQ,GAAG,MAAA,UAAU,CAAC,QAAQ,EAAE,IAAI,GAAG,GAAG,EAAE,KAAK,CAAC,mCAAI,EAAE,CAAC;IAC3D,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,SAAS,cAAc,CACrB,SAAiB,EACjB,cAAqD,EACrD,UAA6B,EAAE;;IAE/B,KAAK,MAAM,SAAS,IAAI,cAAc,EAAE,CAAC;QACvC,MAAM,aAAa,GACjB,OAAO,SAAS,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAA,SAAS,aAAT,SAAS,uBAAT,SAAS,CAAE,aAAa,mCAAI,KAAK,CAAC,CAAC;QAC9E,IAAI,KAAK,GAAG,OAAO,SAAS,KAAK,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,aAAT,SAAS,uBAAT,SAAS,CAAE,KAAK,CAAC;QAEzE,IAAI,CAAC,OAAO,CAAC,eAAe,IAAI,CAAC,aAAa,EAAE,CAAC;YAC/C,KAAK,GAAG,kBAAkB,CAAC,KAAK,CAAC,CAAC;QACpC,CAAC;QAED,SAAS,GAAG,SAAS,CAAC,OAAO,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;IAClD,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,UAAU,CACxB,KAAyB,EACzB,WAAmB,EACnB,YAAoB;IAEpB,OAAO,CAAC,KAAK,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,YAAY,IAAI,EAAE,CAAC,CAAC;AAC5F,CAAC","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\nimport { PathParameterWithOptions, RequestParameters } from \"./common.js\";\n\ntype QueryParameterStyle = \"form\" | \"spaceDelimited\" | \"pipeDelimited\";\n\n/**\n * An object that can be passed as a query parameter, allowing for additional options to be set relating to how the parameter is encoded.\n */\ninterface QueryParameterWithOptions {\n /**\n * The value of the query parameter.\n */\n value: unknown;\n\n /**\n * If set to true, value must be an array. Setting this option to true will cause the array to be encoded as multiple query parameters.\n * Setting it to false will cause the array values to be encoded as a single query parameter, with each value separated by a comma ','.\n *\n * For example, with `explode` set to true, a query parameter named \"foo\" with value [\"a\", \"b\", \"c\"] will be encoded as foo=a&foo=b&foo=c.\n * If `explode` was set to false, the same example would instead be encouded as foo=a,b,c.\n *\n * Defaults to false.\n */\n explode?: boolean;\n\n /**\n * Style for encoding arrays. Three possible values:\n * - \"form\": array values will be separated by a comma \",\" in the query parameter value.\n * - \"spaceDelimited\": array values will be separated by a space (\" \", url-encoded to \"%20\").\n * - \"pipeDelimited\": array values will be separated by a pipe (\"|\").\n *\n * Defaults to \"form\".\n */\n style?: QueryParameterStyle;\n}\n\nfunction isQueryParameterWithOptions(x: unknown): x is QueryParameterWithOptions {\n const value = (x as QueryParameterWithOptions).value as any;\n return (\n value !== undefined && value.toString !== undefined && typeof value.toString === \"function\"\n );\n}\n\n/**\n * Builds the request url, filling in query and path parameters\n * @param endpoint - base url which can be a template url\n * @param routePath - path to append to the endpoint\n * @param pathParameters - values of the path parameters\n * @param options - request parameters including query parameters\n * @returns a full url with path and query parameters\n */\nexport function buildRequestUrl(\n endpoint: string,\n routePath: string,\n pathParameters: (string | PathParameterWithOptions)[],\n options: RequestParameters = {},\n): string {\n if (routePath.startsWith(\"https://\") || routePath.startsWith(\"http://\")) {\n return routePath;\n }\n endpoint = buildBaseUrl(endpoint, options);\n routePath = buildRoutePath(routePath, pathParameters, options);\n const requestUrl = appendQueryParams(`${endpoint}/${routePath}`, options);\n const url = new URL(requestUrl);\n\n return (\n url\n .toString()\n // Remove double forward slashes\n .replace(/([^:]\\/)\\/+/g, \"$1\")\n );\n}\n\nfunction getQueryParamValue(\n key: string,\n allowReserved: boolean,\n style: QueryParameterStyle,\n param: any,\n): string {\n let separator: string;\n if (style === \"pipeDelimited\") {\n separator = \"|\";\n } else if (style === \"spaceDelimited\") {\n separator = \"%20\";\n } else {\n separator = \",\";\n }\n\n let paramValues: any[];\n if (Array.isArray(param)) {\n paramValues = param;\n } else if (typeof param === \"object\" && param.toString === Object.prototype.toString) {\n // If the parameter is an object without a custom toString implementation (e.g. a Date),\n // then we should deconstruct the object into an array [key1, value1, key2, value2, ...].\n paramValues = Object.entries(param).flat();\n } else {\n paramValues = [param];\n }\n\n const value = paramValues\n .map((p) => {\n if (p === null || p === undefined) {\n return \"\";\n }\n\n if (!p.toString || typeof p.toString !== \"function\") {\n throw new Error(`Query parameters must be able to be represented as string, ${key} can't`);\n }\n\n const rawValue = p.toISOString !== undefined ? p.toISOString() : p.toString();\n return allowReserved ? rawValue : encodeURIComponent(rawValue);\n })\n .join(separator);\n\n return `${allowReserved ? key : encodeURIComponent(key)}=${value}`;\n}\n\nfunction appendQueryParams(url: string, options: RequestParameters = {}): string {\n if (!options.queryParameters) {\n return url;\n }\n const parsedUrl = new URL(url);\n const queryParams = options.queryParameters;\n\n const paramStrings: string[] = [];\n for (const key of Object.keys(queryParams)) {\n const param = queryParams[key] as any;\n if (param === undefined || param === null) {\n continue;\n }\n\n const hasMetadata = isQueryParameterWithOptions(param);\n const rawValue = hasMetadata ? param.value : param;\n const explode = hasMetadata ? (param.explode ?? false) : false;\n const style = hasMetadata && param.style ? param.style : \"form\";\n\n if (explode) {\n if (Array.isArray(rawValue)) {\n for (const item of rawValue) {\n paramStrings.push(getQueryParamValue(key, options.skipUrlEncoding ?? false, style, item));\n }\n } else if (typeof rawValue === \"object\") {\n // For object explode, the name of the query parameter is ignored and we use the object key instead\n for (const [actualKey, value] of Object.entries(rawValue)) {\n paramStrings.push(\n getQueryParamValue(actualKey, options.skipUrlEncoding ?? false, style, value),\n );\n }\n } else {\n // Explode doesn't really make sense for primitives\n throw new Error(\"explode can only be set to true for objects and arrays\");\n }\n } else {\n paramStrings.push(getQueryParamValue(key, options.skipUrlEncoding ?? false, style, rawValue));\n }\n }\n\n if (parsedUrl.search !== \"\") {\n parsedUrl.search += \"&\";\n }\n parsedUrl.search += paramStrings.join(\"&\");\n return parsedUrl.toString();\n}\n\nexport function buildBaseUrl(endpoint: string, options: RequestParameters): string {\n if (!options.pathParameters) {\n return endpoint;\n }\n const pathParams = options.pathParameters;\n for (const [key, param] of Object.entries(pathParams)) {\n if (param === undefined || param === null) {\n throw new Error(`Path parameters ${key} must not be undefined or null`);\n }\n if (!param.toString || typeof param.toString !== \"function\") {\n throw new Error(`Path parameters must be able to be represented as string, ${key} can't`);\n }\n let value = param.toISOString !== undefined ? param.toISOString() : String(param);\n if (!options.skipUrlEncoding) {\n value = encodeURIComponent(param);\n }\n endpoint = replaceAll(endpoint, `{${key}}`, value) ?? \"\";\n }\n return endpoint;\n}\n\nfunction buildRoutePath(\n routePath: string,\n pathParameters: (string | PathParameterWithOptions)[],\n options: RequestParameters = {},\n): string {\n for (const pathParam of pathParameters) {\n const allowReserved =\n typeof pathParam === \"string\" ? false : (pathParam?.allowReserved ?? false);\n let value = typeof pathParam === \"string\" ? pathParam : pathParam?.value;\n\n if (!options.skipUrlEncoding && !allowReserved) {\n value = encodeURIComponent(value);\n }\n\n routePath = routePath.replace(/\\{\\w+\\}/, value);\n }\n return routePath;\n}\n\n/**\n * Replace all of the instances of searchValue in value with the provided replaceValue.\n * @param value - The value to search and replace in.\n * @param searchValue - The value to search for in the value argument.\n * @param replaceValue - The value to replace searchValue with in the value argument.\n * @returns The value where each instance of searchValue was replaced with replacedValue.\n */\nexport function replaceAll(\n value: string | undefined,\n searchValue: string,\n replaceValue: string,\n): string | undefined {\n return !value || !searchValue ? value : value.split(searchValue).join(replaceValue || \"\");\n}\n"]}
@@ -1174,11 +1174,26 @@ export declare type OptionsWithTracingContext<Options extends {
1174
1174
  * text surrounded by \{\} will be considered a path parameter
1175
1175
  */
1176
1176
  export declare type PathParameters<TRoute extends string> = TRoute extends `${infer _Head}/{${infer _Param}}${infer Tail}` ? [
1177
- pathParameter: string,
1177
+ pathParameter: string | PathParameterWithOptions,
1178
1178
  ...pathParameters: PathParameters<Tail>
1179
1179
  ] : [
1180
1180
  ];
1181
1181
 
1182
+ /**
1183
+ * An object that can be passed as a path parameter, allowing for additional options to be set relating to how the parameter is encoded.
1184
+ */
1185
+ export declare interface PathParameterWithOptions {
1186
+ /**
1187
+ * The value of the parameter.
1188
+ */
1189
+ value: string;
1190
+ /**
1191
+ * Whether to allow for reserved characters in the value. If set to true, special characters such as '/' in the parameter's value will not be URL encoded.
1192
+ * Defaults to false.
1193
+ */
1194
+ allowReserved?: boolean;
1195
+ }
1196
+
1182
1197
  /**
1183
1198
  * Defines the signature for pathUnchecked.
1184
1199
  */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@typespec/ts-http-runtime",
3
- "version": "1.0.0-alpha.20240930.1",
3
+ "version": "1.0.0-alpha.20241007.3",
4
4
  "description": "Isomorphic client library for making HTTP requests in node.js and browser.",
5
5
  "sdk-type": "client",
6
6
  "type": "module",