@scalar/api-client 0.5.0 → 0.5.1

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 (44) hide show
  1. package/dist/components/ApiClient/Request/RequestHeaders.vue.d.ts +0 -2
  2. package/dist/components/ApiClient/Request/RequestHeaders.vue.d.ts.map +1 -1
  3. package/dist/components/ApiClient/Request/RequestQuery.vue.d.ts +0 -2
  4. package/dist/components/ApiClient/Request/RequestQuery.vue.d.ts.map +1 -1
  5. package/dist/components/ApiClient/Request/RequestVariables.vue.d.ts +2 -4
  6. package/dist/components/ApiClient/Request/RequestVariables.vue.d.ts.map +1 -1
  7. package/dist/helpers/concatenateUrlAndPath.d.ts +5 -0
  8. package/dist/helpers/concatenateUrlAndPath.d.ts.map +1 -0
  9. package/dist/helpers/index.d.ts +6 -1
  10. package/dist/helpers/index.d.ts.map +1 -1
  11. package/dist/helpers/normalizePath.d.ts +5 -0
  12. package/dist/helpers/normalizePath.d.ts.map +1 -0
  13. package/dist/helpers/normalizeRequestMethod.d.ts +5 -0
  14. package/dist/helpers/normalizeRequestMethod.d.ts.map +1 -0
  15. package/dist/helpers/normalizeUrl.d.ts +5 -0
  16. package/dist/helpers/normalizeUrl.d.ts.map +1 -0
  17. package/dist/helpers/replaceVariables.d.ts +5 -0
  18. package/dist/helpers/replaceVariables.d.ts.map +1 -0
  19. package/dist/helpers/sendRequest.d.ts +2 -2
  20. package/dist/helpers/sendRequest.d.ts.map +1 -1
  21. package/dist/index.js +140 -56
  22. package/dist/stores/apiClientRequestStore.d.ts +8 -8
  23. package/dist/types.d.ts +7 -5
  24. package/dist/types.d.ts.map +1 -1
  25. package/package.json +6 -7
  26. package/src/components/ApiClient/Request/Request.vue +1 -1
  27. package/src/components/ApiClient/Request/RequestHeaders.vue +2 -2
  28. package/src/components/ApiClient/Request/RequestQuery.vue +2 -2
  29. package/src/components/ApiClient/Request/RequestVariables.vue +3 -3
  30. package/src/helpers/concatenateUrlAndPath.test.ts +27 -0
  31. package/src/helpers/concatenateUrlAndPath.ts +13 -0
  32. package/src/helpers/index.ts +6 -1
  33. package/src/helpers/normalizePath.test.ts +17 -0
  34. package/src/helpers/normalizePath.ts +16 -0
  35. package/src/helpers/normalizeRequestMethod.test.ts +29 -0
  36. package/src/helpers/normalizeRequestMethod.ts +43 -0
  37. package/src/helpers/normalizeUrl.test.ts +25 -0
  38. package/src/helpers/normalizeUrl.ts +24 -0
  39. package/src/helpers/replaceVariables.test.ts +13 -0
  40. package/src/helpers/replaceVariables.ts +11 -0
  41. package/src/helpers/sendRequest.test.ts +50 -0
  42. package/src/helpers/sendRequest.ts +43 -32
  43. package/src/types.ts +9 -5
  44. package/src/hooks/useOperation.test.ts +0 -7
@@ -1,12 +1,10 @@
1
1
  declare const _default: import("vue").DefineComponent<{
2
2
  headers: {
3
3
  type: import("vue").PropType<any[]>;
4
- required: true;
5
4
  };
6
5
  }, {}, unknown, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps, Readonly<import("vue").ExtractPropTypes<{
7
6
  headers: {
8
7
  type: import("vue").PropType<any[]>;
9
- required: true;
10
8
  };
11
9
  }>>, {}, {}>;
12
10
  export default _default;
@@ -1 +1 @@
1
- {"version":3,"file":"RequestHeaders.vue.d.ts","sourceRoot":"","sources":["../../../../src/components/ApiClient/Request/RequestHeaders.vue.ts"],"names":[],"mappings":";;;;;;;;;;;AAyFA,wBAAkD"}
1
+ {"version":3,"file":"RequestHeaders.vue.d.ts","sourceRoot":"","sources":["../../../../src/components/ApiClient/Request/RequestHeaders.vue.ts"],"names":[],"mappings":";;;;;;;;;AAyFA,wBAAkD"}
@@ -1,12 +1,10 @@
1
1
  declare const _default: import("vue").DefineComponent<{
2
2
  queries: {
3
3
  type: import("vue").PropType<import("../../../types").BaseParameter[]>;
4
- required: true;
5
4
  };
6
5
  }, {}, unknown, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps, Readonly<import("vue").ExtractPropTypes<{
7
6
  queries: {
8
7
  type: import("vue").PropType<import("../../../types").BaseParameter[]>;
9
- required: true;
10
8
  };
11
9
  }>>, {}, {}>;
12
10
  export default _default;
@@ -1 +1 @@
1
- {"version":3,"file":"RequestQuery.vue.d.ts","sourceRoot":"","sources":["../../../../src/components/ApiClient/Request/RequestQuery.vue.ts"],"names":[],"mappings":";;;;;;;;;;;AA0FA,wBAAkD"}
1
+ {"version":3,"file":"RequestQuery.vue.d.ts","sourceRoot":"","sources":["../../../../src/components/ApiClient/Request/RequestQuery.vue.ts"],"names":[],"mappings":";;;;;;;;;AA0FA,wBAAkD"}
@@ -1,13 +1,11 @@
1
1
  import type { BaseParameter } from '../../../types';
2
2
  declare const _default: import("vue").DefineComponent<{
3
- paths: {
3
+ variables: {
4
4
  type: import("vue").PropType<BaseParameter[]>;
5
- required: true;
6
5
  };
7
6
  }, {}, unknown, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps, Readonly<import("vue").ExtractPropTypes<{
8
- paths: {
7
+ variables: {
9
8
  type: import("vue").PropType<BaseParameter[]>;
10
- required: true;
11
9
  };
12
10
  }>>, {}, {}>;
13
11
  export default _default;
@@ -1 +1 @@
1
- {"version":3,"file":"RequestVariables.vue.d.ts","sourceRoot":"","sources":["../../../../src/components/ApiClient/Request/RequestVariables.vue.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAA;;;;;;;;;;;;AAwFnD,wBAAkD"}
1
+ {"version":3,"file":"RequestVariables.vue.d.ts","sourceRoot":"","sources":["../../../../src/components/ApiClient/Request/RequestVariables.vue.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAA;;;;;;;;;;AAwFnD,wBAAkD"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Make sure the URL and path are concatenated correctly.
3
+ */
4
+ export declare const concatenateUrlAndPath: (url: string, path?: string) => string;
5
+ //# sourceMappingURL=concatenateUrlAndPath.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"concatenateUrlAndPath.d.ts","sourceRoot":"","sources":["../../src/helpers/concatenateUrlAndPath.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,eAAO,MAAM,qBAAqB,QAAS,MAAM,SAAS,MAAM,WAS/D,CAAA"}
@@ -1,6 +1,11 @@
1
+ export { concatenateUrlAndPath } from './concatenateUrlAndPath';
1
2
  export { createPlaceholderRequest } from './createPlaceholderRequest';
2
- export { generateRequest } from './generateRequest';
3
3
  export { generateParameters } from './generateParameters';
4
+ export { generateRequest } from './generateRequest';
4
5
  export { mapFromArray } from './mapFromArray';
6
+ export { normalizePath } from './normalizePath';
7
+ export { normalizeRequestMethod } from './normalizeRequestMethod';
8
+ export { normalizeUrl } from './normalizeUrl';
9
+ export { replaceVariables } from './replaceVariables';
5
10
  export { sendRequest } from './sendRequest';
6
11
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/helpers/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,wBAAwB,EAAE,MAAM,4BAA4B,CAAA;AACrE,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAA;AACnD,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAA;AACzD,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAA;AAC7C,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/helpers/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAA;AAC/D,OAAO,EAAE,wBAAwB,EAAE,MAAM,4BAA4B,CAAA;AACrE,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAA;AACzD,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAA;AACnD,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAA;AAC7C,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAA;AAC/C,OAAO,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAA;AACjE,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAA;AAC7C,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAA;AACrD,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAA"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Normalizes a path by removing leading slashes.
3
+ */
4
+ export declare const normalizePath: (path?: string) => string;
5
+ //# sourceMappingURL=normalizePath.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"normalizePath.d.ts","sourceRoot":"","sources":["../../src/helpers/normalizePath.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,eAAO,MAAM,aAAa,UAAW,MAAM,WAY1C,CAAA"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Get a normalized request method (e.g. GET, POST, etc.)
3
+ */
4
+ export declare const normalizeRequestMethod: (method?: string) => string;
5
+ //# sourceMappingURL=normalizeRequestMethod.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"normalizeRequestMethod.d.ts","sourceRoot":"","sources":["../../src/helpers/normalizeRequestMethod.ts"],"names":[],"mappings":"AAcA;;GAEG;AACH,eAAO,MAAM,sBAAsB,YAAa,MAAM,WAyBrD,CAAA"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Normalizes a URL by trimming it and adding http:// as the default prefix.
3
+ */
4
+ export declare const normalizeUrl: (url?: string) => string;
5
+ //# sourceMappingURL=normalizeUrl.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"normalizeUrl.d.ts","sourceRoot":"","sources":["../../src/helpers/normalizeUrl.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,eAAO,MAAM,YAAY,SAAU,MAAM,WAoBxC,CAAA"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Replaces variables in a url with the values provided.
3
+ */
4
+ export declare const replaceVariables: (url: string, variables: Record<string, string | number>) => string;
5
+ //# sourceMappingURL=replaceVariables.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"replaceVariables.d.ts","sourceRoot":"","sources":["../../src/helpers/replaceVariables.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,eAAO,MAAM,gBAAgB,QACtB,MAAM,aACA,OAAO,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,WAK3C,CAAA"}
@@ -1,6 +1,6 @@
1
- import type { ClientRequestConfig, RequestResult } from '../types';
1
+ import type { RequestResult, SendRequestConfig } from '../types';
2
2
  /**
3
3
  * Send a request via the proxy
4
4
  */
5
- export declare function sendRequest(request: ClientRequestConfig, proxyUrl: string): Promise<RequestResult | null>;
5
+ export declare function sendRequest(request: SendRequestConfig, proxyUrl?: string): Promise<RequestResult | null>;
6
6
  //# sourceMappingURL=sendRequest.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"sendRequest.d.ts","sourceRoot":"","sources":["../../src/helpers/sendRequest.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EACV,mBAAmB,EAEnB,aAAa,EACd,MAAM,UAAU,CAAA;AAcjB;;GAEG;AACH,wBAAsB,WAAW,CAC/B,OAAO,EAAE,mBAAmB,EAC5B,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC,CAiE/B"}
1
+ {"version":3,"file":"sendRequest.d.ts","sourceRoot":"","sources":["../../src/helpers/sendRequest.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAGV,aAAa,EACb,iBAAiB,EAClB,MAAM,UAAU,CAAA;AAcjB;;GAEG;AACH,wBAAsB,WAAW,CAC/B,OAAO,EAAE,iBAAiB,EAC1B,QAAQ,CAAC,EAAE,MAAM,GAChB,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC,CA4E/B"}
package/dist/index.js CHANGED
@@ -12,7 +12,6 @@
12
12
  })();
13
13
  import { cloneVNode, h as h$2, Fragment, inject, provide, ref, onMounted, watchEffect, computed, defineComponent, onUnmounted, watch, Teleport, reactive, unref, shallowRef, nextTick, getCurrentScope, onScopeDispose, toRef as toRef$1, readonly, customRef, getCurrentInstance, openBlock, createBlock, withCtx, createElementVNode, createVNode, normalizeClass, normalizeStyle, createTextVNode, toDisplayString, createCommentVNode, renderSlot, createElementBlock, renderList, createStaticVNode, withDirectives, withModifiers, vShow, vModelSelect, vModelText, vModelCheckbox, withKeys } from "vue";
14
14
  import { CodeMirror } from "@scalar/use-codemirror";
15
- import nunjucks from "nunjucks";
16
15
  function u$3(r2, n2, ...a2) {
17
16
  if (r2 in n2) {
18
17
  let e2 = n2[r2];
@@ -5890,6 +5889,41 @@ let nanoid = (size = 21) => crypto.getRandomValues(new Uint8Array(size)).reduce(
5890
5889
  }
5891
5890
  return id;
5892
5891
  }, "");
5892
+ const concatenateUrlAndPath = (url, path) => {
5893
+ if (typeof path !== "string" || !path.length) {
5894
+ return url;
5895
+ }
5896
+ const urlWithSlash = url.endsWith("/") ? url : `${url}/`;
5897
+ const pathWithoutSlash = path.startsWith("/") ? path.slice(1) : path;
5898
+ return [urlWithSlash, pathWithoutSlash].join("");
5899
+ };
5900
+ function generateParameters(parameters) {
5901
+ const params = [];
5902
+ parameters.forEach((parameter) => {
5903
+ const param = {
5904
+ name: parameter.name,
5905
+ value: "",
5906
+ customClass: parameter.required ? "required-parameter" : ""
5907
+ };
5908
+ param.value = "";
5909
+ params.push(param);
5910
+ });
5911
+ return params;
5912
+ }
5913
+ function generateRequest(operation, parameterMap, server) {
5914
+ const item = {
5915
+ id: operation.operationId,
5916
+ name: operation.name,
5917
+ type: operation.httpVerb,
5918
+ path: operation.path,
5919
+ parameters: generateParameters(parameterMap.path),
5920
+ query: generateParameters(parameterMap.query),
5921
+ headers: generateParameters(parameterMap.header),
5922
+ url: server.url,
5923
+ body: ""
5924
+ };
5925
+ return item;
5926
+ }
5893
5927
  function mapFromArray(arr, key, valueKey) {
5894
5928
  const obj = {};
5895
5929
  arr.forEach((entry) => {
@@ -5897,27 +5931,85 @@ function mapFromArray(arr, key, valueKey) {
5897
5931
  });
5898
5932
  return obj;
5899
5933
  }
5900
- const templateEngine = nunjucks.configure({
5901
- tags: {
5902
- variableStart: "{",
5903
- variableEnd: "}"
5934
+ const normalizePath = (path) => {
5935
+ if (typeof path !== "string") {
5936
+ return "";
5904
5937
  }
5905
- });
5938
+ let normalizedPath = path.trim();
5939
+ if (normalizedPath.startsWith("/")) {
5940
+ normalizedPath = normalizedPath.slice(1);
5941
+ }
5942
+ return normalizedPath;
5943
+ };
5944
+ const defaultRequestMethod = "GET";
5945
+ const validRequestMethods = [
5946
+ "GET",
5947
+ "POST",
5948
+ "PUT",
5949
+ "HEAD",
5950
+ "DELETE",
5951
+ "PATCH",
5952
+ "OPTIONS",
5953
+ "CONNECT",
5954
+ "TRACE"
5955
+ ];
5956
+ const normalizeRequestMethod = (method) => {
5957
+ if (typeof method !== "string") {
5958
+ console.warn(
5959
+ `[sendRequest] Request method is not a string. Using ${defaultRequestMethod} as the default.`
5960
+ );
5961
+ return defaultRequestMethod;
5962
+ }
5963
+ const normalizedMethod = method.trim().toUpperCase();
5964
+ const isValidRequestMethod = validRequestMethods.includes(normalizedMethod);
5965
+ if (!isValidRequestMethod) {
5966
+ console.warn(
5967
+ `[sendRequest] ${method} is not a valid request method. Using ${defaultRequestMethod} as the default.`
5968
+ );
5969
+ return defaultRequestMethod;
5970
+ }
5971
+ return normalizedMethod;
5972
+ };
5973
+ const normalizeUrl = (url) => {
5974
+ if (typeof url !== "string") {
5975
+ console.warn(
5976
+ `[sendRequest] URL is not a string. Using an empty string as the default.`
5977
+ );
5978
+ return "";
5979
+ }
5980
+ let normalizedUrl = url.trim().toLowerCase();
5981
+ if (!normalizedUrl.startsWith("http")) {
5982
+ console.warn(
5983
+ `[sendRequest] URL does not start with http. Adding http:// as the default prefix.`
5984
+ );
5985
+ normalizedUrl = `http://${normalizedUrl}`;
5986
+ }
5987
+ return normalizedUrl;
5988
+ };
5989
+ const replaceVariables = (url, variables) => {
5990
+ return Object.entries(variables).reduce((acc, [key, value]) => {
5991
+ return acc.replace(`{${key}}`, value.toString());
5992
+ }, url);
5993
+ };
5906
5994
  const defaultHeaders = {
5907
5995
  "User-Agent": "Scalar API Client"
5908
5996
  };
5909
5997
  async function sendRequest(request, proxyUrl) {
5910
- const method = request.type.toUpperCase();
5911
- const fullUrl = `${request.url}${request.path}`;
5998
+ const method = normalizeRequestMethod(request.type);
5912
5999
  const headers = {
5913
6000
  ...defaultHeaders,
5914
- ...mapFromArray(request.headers, "name", "value")
6001
+ ...mapFromArray(request.headers ?? [], "name", "value")
5915
6002
  };
6003
+ const url = normalizeUrl(request.url);
6004
+ const path = normalizePath(request.path);
6005
+ const urlWithPath = concatenateUrlAndPath(url, path);
6006
+ const renderedURL = replaceVariables(
6007
+ urlWithPath,
6008
+ mapFromArray(request.parameters ?? [], "name", "value")
6009
+ );
5916
6010
  const auth = {
5917
6011
  type: "none"
5918
6012
  };
5919
- const variables = mapFromArray(request.parameters, "name", "value");
5920
- const renderedURL = templateEngine.renderString(fullUrl, variables);
5921
6013
  const startTime = Date.now();
5922
6014
  const requestOptions = {
5923
6015
  method,
@@ -5926,31 +6018,45 @@ async function sendRequest(request, proxyUrl) {
5926
6018
  headers,
5927
6019
  data: request.body
5928
6020
  };
5929
- const config = {
6021
+ const config = proxyUrl ? {
5930
6022
  method: "POST",
5931
6023
  url: proxyUrl,
5932
6024
  data: requestOptions
6025
+ } : {
6026
+ method: requestOptions.method,
6027
+ url: requestOptions.url,
6028
+ headers: requestOptions.headers,
6029
+ data: requestOptions.data
5933
6030
  };
5934
6031
  console.info(`${requestOptions.method} ${requestOptions.url}`);
5935
6032
  const response = (
5936
6033
  // @ts-ignore
5937
- await axios$1(config).then((res) => ({
5938
- ...res.data,
5939
- error: false
5940
- })).catch((err) => ({
5941
- error: true,
5942
- ...err == null ? void 0 : err.response
5943
- }))
6034
+ await axios$1(config).then((res) => {
6035
+ return {
6036
+ ...res.data,
6037
+ error: false
6038
+ };
6039
+ }).catch((err) => {
6040
+ return {
6041
+ error: true,
6042
+ ...err == null ? void 0 : err.response
6043
+ };
6044
+ })
5944
6045
  );
5945
- return !response.error ? {
6046
+ return response.error ? null : {
5946
6047
  sentTime: Date.now(),
5947
- request,
6048
+ request: {
6049
+ ...request,
6050
+ type: method,
6051
+ url,
6052
+ path
6053
+ },
5948
6054
  response: {
5949
6055
  ...response,
5950
6056
  duration: Date.now() - startTime
5951
6057
  },
5952
6058
  responseId: nanoid()
5953
- } : null;
6059
+ };
5954
6060
  }
5955
6061
  const _hoisted_1$k = { class: "modal-layout" };
5956
6062
  const useModalState = () => reactive({
@@ -7021,7 +7127,7 @@ const _sfc_main$d = /* @__PURE__ */ defineComponent({
7021
7127
  return (_ctx, _cache) => {
7022
7128
  return openBlock(), createBlock(unref(_sfc_main$i), { title: "Headers" }, {
7023
7129
  default: withCtx(() => [
7024
- _ctx.headers.length === 0 ? (openBlock(), createElementBlock("div", _hoisted_1$b, "No Headers")) : (openBlock(), createBlock(unref(_sfc_main$g), {
7130
+ !_ctx.headers || _ctx.headers.length === 0 ? (openBlock(), createElementBlock("div", _hoisted_1$b, "No Headers")) : (openBlock(), createBlock(unref(_sfc_main$g), {
7025
7131
  key: 1,
7026
7132
  items: _ctx.headers
7027
7133
  }, null, 8, ["items"]))
@@ -7044,7 +7150,7 @@ const _sfc_main$c = /* @__PURE__ */ defineComponent({
7044
7150
  return (_ctx, _cache) => {
7045
7151
  return openBlock(), createBlock(unref(_sfc_main$i), { title: "Query Parameters" }, {
7046
7152
  default: withCtx(() => [
7047
- _ctx.queries.length === 0 ? (openBlock(), createElementBlock("div", _hoisted_1$a, "No Query Parameters")) : (openBlock(), createBlock(unref(_sfc_main$g), {
7153
+ !_ctx.queries || _ctx.queries.length === 0 ? (openBlock(), createElementBlock("div", _hoisted_1$a, "No Query Parameters")) : (openBlock(), createBlock(unref(_sfc_main$g), {
7048
7154
  key: 1,
7049
7155
  items: _ctx.queries
7050
7156
  }, null, 8, ["items"]))
@@ -7061,15 +7167,15 @@ const _hoisted_1$9 = {
7061
7167
  const _sfc_main$b = /* @__PURE__ */ defineComponent({
7062
7168
  __name: "RequestVariables",
7063
7169
  props: {
7064
- paths: {}
7170
+ variables: {}
7065
7171
  },
7066
7172
  setup(__props) {
7067
7173
  return (_ctx, _cache) => {
7068
7174
  return openBlock(), createBlock(unref(_sfc_main$i), { title: "Variables" }, {
7069
7175
  default: withCtx(() => [
7070
- _ctx.paths.length === 0 ? (openBlock(), createElementBlock("div", _hoisted_1$9, "No variables")) : (openBlock(), createBlock(unref(_sfc_main$g), {
7176
+ !_ctx.variables || _ctx.variables.length === 0 ? (openBlock(), createElementBlock("div", _hoisted_1$9, "No variables")) : (openBlock(), createBlock(unref(_sfc_main$g), {
7071
7177
  key: 1,
7072
- items: _ctx.paths
7178
+ items: _ctx.variables
7073
7179
  }, null, 8, ["items"]))
7074
7180
  ]),
7075
7181
  _: 1
@@ -7109,8 +7215,8 @@ const _sfc_main$a = /* @__PURE__ */ defineComponent({
7109
7215
  createElementVNode("div", null, [
7110
7216
  createVNode(_sfc_main$h),
7111
7217
  createVNode(_sfc_main$b, {
7112
- paths: unref(activeRequest2).parameters
7113
- }, null, 8, ["paths"]),
7218
+ variables: unref(activeRequest2).parameters
7219
+ }, null, 8, ["variables"]),
7114
7220
  createVNode(_sfc_main$c, {
7115
7221
  queries: unref(activeRequest2).query
7116
7222
  }, null, 8, ["queries"]),
@@ -8331,33 +8437,6 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
8331
8437
  }
8332
8438
  });
8333
8439
  const ApiClient_vue_vue_type_style_index_0_lang = "";
8334
- function generateParameters(parameters) {
8335
- const params = [];
8336
- parameters.forEach((parameter) => {
8337
- const param = {
8338
- name: parameter.name,
8339
- value: "",
8340
- customClass: parameter.required ? "required-parameter" : ""
8341
- };
8342
- param.value = "";
8343
- params.push(param);
8344
- });
8345
- return params;
8346
- }
8347
- function generateRequest(operation, parameterMap, server) {
8348
- const item = {
8349
- id: operation.operationId,
8350
- name: operation.name,
8351
- type: operation.httpVerb,
8352
- path: operation.path,
8353
- parameters: generateParameters(parameterMap.path),
8354
- query: generateParameters(parameterMap.query),
8355
- headers: generateParameters(parameterMap.header),
8356
- url: server.url,
8357
- body: ""
8358
- };
8359
- return item;
8360
- }
8361
8440
  function useOperation(props) {
8362
8441
  const parameterMap = computed(() => {
8363
8442
  const { parameters } = props.operation.information;
@@ -8385,6 +8464,7 @@ function useOperation(props) {
8385
8464
  }
8386
8465
  export {
8387
8466
  _sfc_main as ApiClient,
8467
+ concatenateUrlAndPath,
8388
8468
  createEmptyAuthState,
8389
8469
  createPlaceholderRequest,
8390
8470
  generateParameters,
@@ -8392,6 +8472,10 @@ export {
8392
8472
  httpHeaders,
8393
8473
  httpStatusCodes,
8394
8474
  mapFromArray,
8475
+ normalizePath,
8476
+ normalizeRequestMethod,
8477
+ normalizeUrl,
8478
+ replaceVariables,
8395
8479
  sendRequest,
8396
8480
  useApiClientRequestStore,
8397
8481
  useApiClientStore,
@@ -32,26 +32,26 @@ export declare const useApiClientRequestStore: () => {
32
32
  readOnly: import("vue").Ref<boolean>;
33
33
  activeRequest: {
34
34
  id?: string | undefined;
35
- name: string;
35
+ name?: string | undefined;
36
36
  url: string;
37
37
  type: string;
38
38
  path: string;
39
- parameters: {
39
+ parameters?: {
40
40
  name: string;
41
41
  value: string | number;
42
42
  customClass?: string | undefined;
43
- }[];
44
- query: {
43
+ }[] | undefined;
44
+ query?: {
45
45
  name: string;
46
46
  value: string | number;
47
47
  customClass?: string | undefined;
48
- }[];
49
- headers: {
48
+ }[] | undefined;
49
+ headers?: {
50
50
  name: string;
51
51
  value: string | number;
52
52
  customClass?: string | undefined;
53
- }[];
54
- body: string;
53
+ }[] | undefined;
54
+ body?: string | undefined;
55
55
  formData?: {
56
56
  name: string;
57
57
  value: string | number;
package/dist/types.d.ts CHANGED
@@ -41,20 +41,21 @@ export type FormDataItem = BaseParameter;
41
41
  /** Complete request state for a client request */
42
42
  export type ClientRequestConfig = {
43
43
  id?: string;
44
- name: string;
44
+ name?: string;
45
45
  url: string;
46
46
  /** HTTP Request Method */
47
47
  type: string;
48
48
  /** Request path */
49
49
  path: string;
50
+ /** TODO: Rename to variables? */
50
51
  /** Path parameters */
51
- parameters: BaseParameter[];
52
+ parameters?: BaseParameter[];
52
53
  /** Query parameters */
53
- query: Query[];
54
+ query?: Query[];
54
55
  /** Request headers */
55
- headers: Header[];
56
+ headers?: Header[];
56
57
  /** Content type matched body */
57
- body: string;
58
+ body?: string;
58
59
  /** Optional form data body */
59
60
  formData?: FormDataItem[];
60
61
  };
@@ -76,6 +77,7 @@ export type ClientResponse = {
76
77
  data: string;
77
78
  duration: number;
78
79
  };
80
+ export type SendRequestConfig = Partial<ClientRequestConfig> & Required<Pick<ClientRequestConfig, 'url'>>;
79
81
  export type RequestResult = {
80
82
  request: ClientRequestConfig;
81
83
  response: ClientResponse;
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -9,7 +9,7 @@
9
9
  "graphql",
10
10
  "postman alternative"
11
11
  ],
12
- "version": "0.5.0",
12
+ "version": "0.5.1",
13
13
  "author": "Scalar (https://github.com/scalar)",
14
14
  "homepage": "https://github.com/scalar/scalar",
15
15
  "repository": {
@@ -42,13 +42,12 @@
42
42
  "axios": "1.4.0",
43
43
  "javascript-time-ago": "2.5.9",
44
44
  "nanoid": "4.0.2",
45
- "nunjucks": "3.2.3",
46
45
  "pretty-bytes": "6.1.0",
47
46
  "pretty-ms": "8.0.0",
48
47
  "tippy.js": "6.3.7",
49
48
  "@scalar/default-theme": "0.2.1",
50
- "@scalar/use-codemirror": "0.5.0",
51
- "@scalar/use-keyboard-event": "0.4.1"
49
+ "@scalar/use-keyboard-event": "0.4.1",
50
+ "@scalar/use-codemirror": "0.5.0"
52
51
  },
53
52
  "devDependencies": {
54
53
  "@vitejs/plugin-vue": "4.2.3",
@@ -56,11 +55,11 @@
56
55
  "vite": "4.4.8",
57
56
  "vite-plugin-css-injected-by-js": "^3.3.0",
58
57
  "vitest": "0.34.1",
59
- "vue-tsc": "1.8.8"
58
+ "vue-tsc": "1.8.8",
59
+ "@scalar/echo-server": "0.4.1"
60
60
  },
61
61
  "peerDependencies": {
62
- "vue": "3.3.4",
63
- "@types/nunjucks": "3.2.2"
62
+ "vue": "3.3.4"
64
63
  },
65
64
  "scripts": {
66
65
  "build": "vite build && pnpm types:build && tsc-alias -p tsconfig.build.json",
@@ -25,7 +25,7 @@ const { activeRequest, readOnly } = useApiClientRequestStore()
25
25
  </div>
26
26
  <div>
27
27
  <RequestAuth />
28
- <RequestVariables :paths="activeRequest.parameters" />
28
+ <RequestVariables :variables="activeRequest.parameters" />
29
29
  <RequestQuery :queries="activeRequest.query" />
30
30
  <RequestHeaders :headers="activeRequest.headers" />
31
31
  <RequestBody
@@ -2,11 +2,11 @@
2
2
  import { CollapsibleSection } from '../../CollapsibleSection'
3
3
  import { Grid } from '../../Grid'
4
4
 
5
- defineProps<{ headers: any[] }>()
5
+ defineProps<{ headers?: any[] }>()
6
6
  </script>
7
7
  <template>
8
8
  <CollapsibleSection title="Headers">
9
- <template v-if="headers.length === 0">
9
+ <template v-if="!headers || headers.length === 0">
10
10
  <div class="scalar-api-client__empty-state">No Headers</div>
11
11
  </template>
12
12
  <template v-else>
@@ -3,11 +3,11 @@ import type { Query } from '../../../types'
3
3
  import { CollapsibleSection } from '../../CollapsibleSection'
4
4
  import { Grid } from '../../Grid'
5
5
 
6
- defineProps<{ queries: Query[] }>()
6
+ defineProps<{ queries?: Query[] }>()
7
7
  </script>
8
8
  <template>
9
9
  <CollapsibleSection title="Query Parameters">
10
- <template v-if="queries.length === 0">
10
+ <template v-if="!queries || queries.length === 0">
11
11
  <div class="scalar-api-client__empty-state">No Query Parameters</div>
12
12
  </template>
13
13
  <template v-else>
@@ -3,15 +3,15 @@ import type { BaseParameter } from '../../../types'
3
3
  import { CollapsibleSection } from '../../CollapsibleSection'
4
4
  import { Grid } from '../../Grid'
5
5
 
6
- defineProps<{ paths: BaseParameter[] }>()
6
+ defineProps<{ variables?: BaseParameter[] }>()
7
7
  </script>
8
8
  <template>
9
9
  <CollapsibleSection title="Variables">
10
- <template v-if="paths.length === 0">
10
+ <template v-if="!variables || variables.length === 0">
11
11
  <div class="scalar-api-client__empty-state">No variables</div>
12
12
  </template>
13
13
  <template v-else>
14
- <Grid :items="paths" />
14
+ <Grid :items="variables" />
15
15
  <!-- @addAnother="addQuery"
16
16
  @deleteItem="deleteQuery"
17
17
  @toggleDescription="toggleDescription"
@@ -0,0 +1,27 @@
1
+ import { describe, expect, it } from 'vitest'
2
+
3
+ import { concatenateUrlAndPath } from './'
4
+
5
+ describe('concatenateUrlAndPath', () => {
6
+ it('trims a slash from the URL', async () => {
7
+ expect(concatenateUrlAndPath('http://127.0.0.1/', 'foobar')).toBe(
8
+ 'http://127.0.0.1/foobar',
9
+ )
10
+ })
11
+
12
+ it('adds a slash between url and path', async () => {
13
+ expect(concatenateUrlAndPath('http://127.0.0.1', 'foobar')).toBe(
14
+ 'http://127.0.0.1/foobar',
15
+ )
16
+ })
17
+
18
+ it('trims a slash from the path', async () => {
19
+ expect(concatenateUrlAndPath('http://127.0.0.1', '/foobar')).toBe(
20
+ 'http://127.0.0.1/foobar',
21
+ )
22
+ })
23
+
24
+ it('works without a path', async () => {
25
+ expect(concatenateUrlAndPath('http://127.0.0.1')).toBe('http://127.0.0.1')
26
+ })
27
+ })
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Make sure the URL and path are concatenated correctly.
3
+ */
4
+ export const concatenateUrlAndPath = (url: string, path?: string) => {
5
+ if (typeof path !== 'string' || !path.length) {
6
+ return url
7
+ }
8
+
9
+ const urlWithSlash = url.endsWith('/') ? url : `${url}/`
10
+ const pathWithoutSlash = path.startsWith('/') ? path.slice(1) : path
11
+
12
+ return [urlWithSlash, pathWithoutSlash].join('')
13
+ }
@@ -1,5 +1,10 @@
1
+ export { concatenateUrlAndPath } from './concatenateUrlAndPath'
1
2
  export { createPlaceholderRequest } from './createPlaceholderRequest'
2
- export { generateRequest } from './generateRequest'
3
3
  export { generateParameters } from './generateParameters'
4
+ export { generateRequest } from './generateRequest'
4
5
  export { mapFromArray } from './mapFromArray'
6
+ export { normalizePath } from './normalizePath'
7
+ export { normalizeRequestMethod } from './normalizeRequestMethod'
8
+ export { normalizeUrl } from './normalizeUrl'
9
+ export { replaceVariables } from './replaceVariables'
5
10
  export { sendRequest } from './sendRequest'
@@ -0,0 +1,17 @@
1
+ import { describe, expect, it } from 'vitest'
2
+
3
+ import { normalizePath } from './'
4
+
5
+ describe('normalizePath', () => {
6
+ it('keeps a path as is', async () => {
7
+ expect(normalizePath('foobar')).toBe('foobar')
8
+ })
9
+
10
+ it('removes slash', async () => {
11
+ expect(normalizePath('/foobar')).toBe('foobar')
12
+ })
13
+
14
+ it('trims whitespace', async () => {
15
+ expect(normalizePath('foobar ')).toBe('foobar')
16
+ })
17
+ })
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Normalizes a path by removing leading slashes.
3
+ */
4
+ export const normalizePath = (path?: string) => {
5
+ if (typeof path !== 'string') {
6
+ return ''
7
+ }
8
+
9
+ let normalizedPath = path.trim()
10
+
11
+ if (normalizedPath.startsWith('/')) {
12
+ normalizedPath = normalizedPath.slice(1)
13
+ }
14
+
15
+ return normalizedPath
16
+ }
@@ -0,0 +1,29 @@
1
+ import { describe, expect, it } from 'vitest'
2
+
3
+ import { normalizeRequestMethod } from './'
4
+
5
+ describe('normalizeRequestMethod', () => {
6
+ it('returns a valid request method', async () => {
7
+ expect(normalizeRequestMethod('GET')).toBe('GET')
8
+ })
9
+
10
+ it('makes method uppercase', async () => {
11
+ expect(normalizeRequestMethod('get')).toBe('GET')
12
+ })
13
+
14
+ it('return uppercase POST', async () => {
15
+ expect(normalizeRequestMethod('post')).toBe('POST')
16
+ })
17
+
18
+ it('trims whitespace', async () => {
19
+ expect(normalizeRequestMethod('post ')).toBe('POST')
20
+ })
21
+
22
+ it('uses GET as the default', async () => {
23
+ expect(normalizeRequestMethod()).toBe('GET')
24
+ })
25
+
26
+ it('ignores invalid request methods', async () => {
27
+ expect(normalizeRequestMethod('fantasy')).toBe('GET')
28
+ })
29
+ })
@@ -0,0 +1,43 @@
1
+ const defaultRequestMethod = 'GET'
2
+
3
+ const validRequestMethods = [
4
+ 'GET',
5
+ 'POST',
6
+ 'PUT',
7
+ 'HEAD',
8
+ 'DELETE',
9
+ 'PATCH',
10
+ 'OPTIONS',
11
+ 'CONNECT',
12
+ 'TRACE',
13
+ ]
14
+
15
+ /**
16
+ * Get a normalized request method (e.g. GET, POST, etc.)
17
+ */
18
+ export const normalizeRequestMethod = (method?: string) => {
19
+ // Make sure it’s a string
20
+ if (typeof method !== 'string') {
21
+ console.warn(
22
+ `[sendRequest] Request method is not a string. Using ${defaultRequestMethod} as the default.`,
23
+ )
24
+
25
+ return defaultRequestMethod
26
+ }
27
+
28
+ // Normalize the string
29
+ const normalizedMethod = method.trim().toUpperCase()
30
+
31
+ // Make sure it’s a valid request method
32
+ const isValidRequestMethod = validRequestMethods.includes(normalizedMethod)
33
+
34
+ if (!isValidRequestMethod) {
35
+ console.warn(
36
+ `[sendRequest] ${method} is not a valid request method. Using ${defaultRequestMethod} as the default.`,
37
+ )
38
+
39
+ return defaultRequestMethod
40
+ }
41
+
42
+ return normalizedMethod
43
+ }
@@ -0,0 +1,25 @@
1
+ import { describe, expect, it } from 'vitest'
2
+
3
+ import { normalizeUrl } from './'
4
+
5
+ describe('normalizeUrl', () => {
6
+ it('keeps URLs as is', async () => {
7
+ expect(normalizeUrl('http://127.0.0.1')).toBe('http://127.0.0.1')
8
+ })
9
+
10
+ it('keeps slashes', async () => {
11
+ expect(normalizeUrl('http://127.0.0.1/')).toBe('http://127.0.0.1/')
12
+ })
13
+
14
+ it('makes URLs lowercase', async () => {
15
+ expect(normalizeUrl('http://EXAMPLE.COM')).toBe('http://example.com')
16
+ })
17
+
18
+ it('adds http://', async () => {
19
+ expect(normalizeUrl('example.com')).toBe('http://example.com')
20
+ })
21
+
22
+ it('trims whitespace', async () => {
23
+ expect(normalizeUrl('http://example.com ')).toBe('http://example.com')
24
+ })
25
+ })
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Normalizes a URL by trimming it and adding http:// as the default prefix.
3
+ */
4
+ export const normalizeUrl = (url?: string) => {
5
+ if (typeof url !== 'string') {
6
+ console.warn(
7
+ `[sendRequest] URL is not a string. Using an empty string as the default.`,
8
+ )
9
+
10
+ return ''
11
+ }
12
+
13
+ let normalizedUrl = url.trim().toLowerCase()
14
+
15
+ if (!normalizedUrl.startsWith('http')) {
16
+ console.warn(
17
+ `[sendRequest] URL does not start with http. Adding http:// as the default prefix.`,
18
+ )
19
+
20
+ normalizedUrl = `http://${normalizedUrl}`
21
+ }
22
+
23
+ return normalizedUrl
24
+ }
@@ -0,0 +1,13 @@
1
+ import { describe, expect, it } from 'vitest'
2
+
3
+ import { replaceVariables } from './'
4
+
5
+ describe('replaceVariables', () => {
6
+ it('replaces variables', async () => {
7
+ expect(
8
+ replaceVariables('http://{baseUrl}/foobar', {
9
+ baseUrl: 'example.com',
10
+ }),
11
+ ).toBe('http://example.com/foobar')
12
+ })
13
+ })
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Replaces variables in a url with the values provided.
3
+ */
4
+ export const replaceVariables = (
5
+ url: string,
6
+ variables: Record<string, string | number>,
7
+ ) => {
8
+ return Object.entries(variables).reduce((acc, [key, value]) => {
9
+ return acc.replace(`{${key}}`, value.toString())
10
+ }, url)
11
+ }
@@ -0,0 +1,50 @@
1
+ import { createEchoServer } from '@scalar/echo-server'
2
+ import { describe, expect, it } from 'vitest'
3
+
4
+ import { sendRequest } from './sendRequest'
5
+
6
+ const createEchoServerOnAnyPort = (): { address: string; port: number } => {
7
+ const { listen } = createEchoServer()
8
+ const instance = listen(0)
9
+
10
+ return instance.address()
11
+ }
12
+
13
+ describe('sendRequest', () => {
14
+ it('sends requests', async () => {
15
+ const { port } = createEchoServerOnAnyPort()
16
+
17
+ const request = {
18
+ url: `http://127.0.0.1:${port}`,
19
+ }
20
+
21
+ const result = await sendRequest(request)
22
+
23
+ expect(result?.response).toContain({
24
+ method: 'GET',
25
+ path: '/',
26
+ })
27
+ })
28
+
29
+ it('replaces variables', async () => {
30
+ const { port } = createEchoServerOnAnyPort()
31
+
32
+ const request = {
33
+ url: `http://127.0.0.1:${port}`,
34
+ path: '{path}',
35
+ parameters: [
36
+ {
37
+ name: 'path',
38
+ value: 'example',
39
+ },
40
+ ],
41
+ }
42
+
43
+ const result = await sendRequest(request)
44
+
45
+ expect(result?.response).toContain({
46
+ method: 'GET',
47
+ path: '/example',
48
+ })
49
+ })
50
+ })
@@ -1,20 +1,20 @@
1
1
  import axios from 'axios'
2
2
  import { nanoid } from 'nanoid'
3
- import nunjucks from 'nunjucks'
4
3
 
5
4
  import type {
6
5
  ClientRequestConfig,
7
6
  ClientResponse,
8
7
  RequestResult,
8
+ SendRequestConfig,
9
9
  } from '../types'
10
- import { mapFromArray } from './mapFromArray'
11
-
12
- const templateEngine = nunjucks.configure({
13
- tags: {
14
- variableStart: '{',
15
- variableEnd: '}',
16
- },
17
- })
10
+ import {
11
+ concatenateUrlAndPath,
12
+ mapFromArray,
13
+ normalizePath,
14
+ normalizeRequestMethod,
15
+ normalizeUrl,
16
+ replaceVariables,
17
+ } from './'
18
18
 
19
19
  const defaultHeaders = {
20
20
  'User-Agent': 'Scalar API Client',
@@ -24,24 +24,26 @@ const defaultHeaders = {
24
24
  * Send a request via the proxy
25
25
  */
26
26
  export async function sendRequest(
27
- request: ClientRequestConfig,
28
- proxyUrl: string,
27
+ request: SendRequestConfig,
28
+ proxyUrl?: string,
29
29
  ): Promise<RequestResult | null> {
30
- // Format complete URL
31
- const method = request.type.toUpperCase()
32
- const fullUrl = `${request.url}${request.path}`
30
+ const method = normalizeRequestMethod(request.type)
33
31
  const headers: Record<string, string | number> = {
34
32
  ...defaultHeaders,
35
- ...mapFromArray(request.headers, 'name', 'value'),
33
+ ...mapFromArray(request.headers ?? [], 'name', 'value'),
36
34
  }
35
+ const url = normalizeUrl(request.url)
36
+ const path = normalizePath(request.path)
37
+ const urlWithPath = concatenateUrlAndPath(url, path)
38
+ const renderedURL = replaceVariables(
39
+ urlWithPath,
40
+ mapFromArray(request.parameters ?? [], 'name', 'value'),
41
+ )
42
+
37
43
  /** TODO: Make dynamic */
38
44
  const auth = {
39
45
  type: 'none',
40
46
  }
41
- const variables = mapFromArray(request.parameters, 'name', 'value')
42
- const renderedURL = templateEngine.renderString(fullUrl, variables)
43
- /** TODO: Make dynamic */
44
- const proxy = true
45
47
 
46
48
  const startTime = Date.now()
47
49
 
@@ -53,7 +55,7 @@ export async function sendRequest(
53
55
  data: request.body,
54
56
  }
55
57
 
56
- const config = proxy
58
+ const config = proxyUrl
57
59
  ? {
58
60
  method: 'POST',
59
61
  url: proxyUrl,
@@ -71,24 +73,33 @@ export async function sendRequest(
71
73
  const response: (ClientResponse & { error: false }) | { error: true } =
72
74
  // @ts-ignore
73
75
  await axios(config)
74
- .then((res) => ({
75
- ...res.data,
76
- error: false,
77
- }))
78
- .catch((err) => ({
79
- error: true,
80
- ...err?.response,
81
- }))
76
+ .then((res) => {
77
+ return {
78
+ ...res.data,
79
+ error: false,
80
+ }
81
+ })
82
+ .catch((err) => {
83
+ return {
84
+ error: true,
85
+ ...err?.response,
86
+ }
87
+ })
82
88
 
83
- return !response.error
84
- ? {
89
+ return response.error
90
+ ? null
91
+ : {
85
92
  sentTime: Date.now(),
86
- request,
93
+ request: {
94
+ ...request,
95
+ type: method,
96
+ url,
97
+ path,
98
+ },
87
99
  response: {
88
100
  ...response,
89
101
  duration: Date.now() - startTime,
90
102
  },
91
103
  responseId: nanoid(),
92
104
  }
93
- : null
94
105
  }
package/src/types.ts CHANGED
@@ -51,20 +51,21 @@ export type FormDataItem = BaseParameter
51
51
  /** Complete request state for a client request */
52
52
  export type ClientRequestConfig = {
53
53
  id?: string
54
- name: string
54
+ name?: string
55
55
  url: string
56
56
  /** HTTP Request Method */
57
57
  type: string
58
58
  /** Request path */
59
59
  path: string
60
+ /** TODO: Rename to variables? */
60
61
  /** Path parameters */
61
- parameters: BaseParameter[]
62
+ parameters?: BaseParameter[]
62
63
  /** Query parameters */
63
- query: Query[]
64
+ query?: Query[]
64
65
  /** Request headers */
65
- headers: Header[]
66
+ headers?: Header[]
66
67
  /** Content type matched body */
67
- body: string
68
+ body?: string
68
69
  /** Optional form data body */
69
70
  formData?: FormDataItem[]
70
71
  }
@@ -89,6 +90,9 @@ export type ClientResponse = {
89
90
  duration: number
90
91
  }
91
92
 
93
+ export type SendRequestConfig = Partial<ClientRequestConfig> &
94
+ Required<Pick<ClientRequestConfig, 'url'>>
95
+
92
96
  export type RequestResult = {
93
97
  request: ClientRequestConfig
94
98
  response: ClientResponse
@@ -1,7 +0,0 @@
1
- import { describe, expect, it } from 'vitest'
2
-
3
- describe('example', () => {
4
- it('executes tests', () => {
5
- expect(true).toBe(true)
6
- })
7
- })