@scalar/api-client 0.2.0 → 0.2.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 (59) hide show
  1. package/dist/components/SimpleTable/SimpleCell.vue.d.ts.map +1 -1
  2. package/dist/components/SimpleTable/SimpleHeader.vue.d.ts.map +1 -1
  3. package/dist/components/SimpleTable/SimpleRow.vue.d.ts.map +1 -1
  4. package/dist/components/SimpleTable/SimpleTable.vue.d.ts.map +1 -1
  5. package/dist/fixtures/index.d.ts +1 -1
  6. package/dist/fixtures/index.d.ts.map +1 -1
  7. package/dist/index.js +37 -26
  8. package/package.json +6 -6
  9. package/src/components/ApiClient/AddressBar.vue +462 -0
  10. package/src/components/ApiClient/ApiClient.vue +266 -0
  11. package/src/components/ApiClient/Request/Request.vue +271 -0
  12. package/src/components/ApiClient/Request/RequestAuth.vue +221 -0
  13. package/src/components/ApiClient/Request/RequestBody.vue +39 -0
  14. package/src/components/ApiClient/Request/RequestHeaders.vue +24 -0
  15. package/src/components/ApiClient/Request/RequestQuery.vue +25 -0
  16. package/src/components/ApiClient/Request/RequestVariables.vue +25 -0
  17. package/src/components/ApiClient/Request/index.ts +1 -0
  18. package/src/components/ApiClient/RequestHistory.vue +114 -0
  19. package/src/components/ApiClient/RequestHistoryItem.vue +59 -0
  20. package/src/components/ApiClient/Response/Copilot.vue.bak +385 -0
  21. package/src/components/ApiClient/Response/Response.vue +120 -0
  22. package/src/components/ApiClient/Response/ResponseBody.vue +23 -0
  23. package/src/components/ApiClient/Response/ResponseHeaders.vue +52 -0
  24. package/src/components/ApiClient/Response/ResponseMetaInformation.vue +58 -0
  25. package/src/components/ApiClient/Response/index.ts +1 -0
  26. package/src/components/ApiClient/index.ts +1 -0
  27. package/src/components/CodeMirror/CodeMirror.vue +232 -0
  28. package/src/components/CodeMirror/extensions/variables.ts +41 -0
  29. package/src/components/CodeMirror/index.ts +1 -0
  30. package/src/components/CollapsibleSection/CollapsibleSection.vue +149 -0
  31. package/src/components/CollapsibleSection/index.ts +1 -0
  32. package/src/components/FlowModal.vue +133 -0
  33. package/src/components/Grid/Grid.vue +511 -0
  34. package/src/components/Grid/SimpleGrid.vue +33 -0
  35. package/src/components/Grid/index.ts +2 -0
  36. package/src/components/HelpfulLink.vue +19 -0
  37. package/src/components/SimpleTable/SimpleCell.vue +47 -0
  38. package/src/components/SimpleTable/SimpleHeader.vue +17 -0
  39. package/src/components/SimpleTable/SimpleRow.vue +14 -0
  40. package/src/components/SimpleTable/SimpleTable.vue +13 -0
  41. package/src/components/SimpleTable/index.ts +4 -0
  42. package/src/fixtures/httpHeaders.ts +530 -0
  43. package/src/fixtures/httpStatusCodes.ts +259 -0
  44. package/src/fixtures/index.ts +6 -0
  45. package/src/helpers/createPlaceholderRequest.ts +16 -0
  46. package/src/helpers/generateParameters.ts +19 -0
  47. package/src/helpers/generateRequest.ts +26 -0
  48. package/src/helpers/index.ts +5 -0
  49. package/src/helpers/mapFromArray.ts +16 -0
  50. package/src/helpers/sendRequest.ts +94 -0
  51. package/src/hooks/index.ts +2 -0
  52. package/src/hooks/useCopilot.ts +64 -0
  53. package/src/hooks/useOperation.test.ts +7 -0
  54. package/src/hooks/useOperation.ts +43 -0
  55. package/src/index.ts +9 -0
  56. package/src/stores/apiClientRequestStore.ts +103 -0
  57. package/src/stores/apiClientStore.ts +57 -0
  58. package/src/stores/index.ts +5 -0
  59. package/src/types.ts +181 -0
@@ -0,0 +1,259 @@
1
+ export type HttpStatusCode = {
2
+ name: string
3
+ url: string
4
+ }
5
+
6
+ export type HttpStatusCodes = Record<string, HttpStatusCode>
7
+
8
+ export const httpStatusCodes: HttpStatusCodes = {
9
+ 100: {
10
+ name: 'Continue',
11
+ url: 'https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/100',
12
+ },
13
+ 101: {
14
+ name: 'Switching Protocols',
15
+ url: 'https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/101',
16
+ },
17
+ 102: {
18
+ name: 'Processing',
19
+ url: 'https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/102',
20
+ },
21
+ 103: {
22
+ name: 'Early Hints',
23
+ url: 'https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/103',
24
+ },
25
+ 200: {
26
+ name: 'OK',
27
+ url: 'https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/200',
28
+ },
29
+ 201: {
30
+ name: 'Created',
31
+ url: 'https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/201',
32
+ },
33
+ 202: {
34
+ name: 'Accepted',
35
+ url: 'https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/202',
36
+ },
37
+ 203: {
38
+ name: 'Non-Authoritative Information',
39
+ url: 'https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/203',
40
+ },
41
+ 204: {
42
+ name: 'No Content',
43
+ url: 'https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/204',
44
+ },
45
+ 205: {
46
+ name: 'Reset Content',
47
+ url: 'https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/205',
48
+ },
49
+ 206: {
50
+ name: 'Partial Content',
51
+ url: 'https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/206',
52
+ },
53
+ 207: {
54
+ name: 'Multi-Status',
55
+ url: 'https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/207',
56
+ },
57
+ 208: {
58
+ name: 'Already Reported',
59
+ url: 'https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/208',
60
+ },
61
+ 226: {
62
+ name: 'IM Used',
63
+ url: 'https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/226',
64
+ },
65
+ 300: {
66
+ name: 'Multiple Choices',
67
+ url: 'https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/300',
68
+ },
69
+ 301: {
70
+ name: 'Moved Permanently',
71
+ url: 'https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/301',
72
+ },
73
+ 302: {
74
+ name: 'Found',
75
+ url: 'https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/302',
76
+ },
77
+ 303: {
78
+ name: 'See Other',
79
+ url: 'https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/303',
80
+ },
81
+ 304: {
82
+ name: 'Not Modified',
83
+ url: 'https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/304',
84
+ },
85
+ 305: {
86
+ name: 'Use Proxy',
87
+ url: 'https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/305',
88
+ },
89
+ 306: {
90
+ name: '(Unused)',
91
+ url: 'https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/306',
92
+ },
93
+ 307: {
94
+ name: 'Temporary Redirect',
95
+ url: 'https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/307',
96
+ },
97
+ 308: {
98
+ name: 'Permanent Redirect',
99
+ url: 'https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/308',
100
+ },
101
+ 400: {
102
+ name: 'Bad Request',
103
+ url: 'https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/400',
104
+ },
105
+ 401: {
106
+ name: 'Unauthorized',
107
+ url: 'https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/401',
108
+ },
109
+ 402: {
110
+ name: 'Payment Required',
111
+ url: 'https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/402',
112
+ },
113
+ 403: {
114
+ name: 'Forbidden',
115
+ url: 'https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/403',
116
+ },
117
+ 404: {
118
+ name: 'Not Found',
119
+ url: 'https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/404',
120
+ },
121
+ 405: {
122
+ name: 'Method Not Allowed',
123
+ url: 'https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/405',
124
+ },
125
+ 406: {
126
+ name: 'Not Acceptable',
127
+ url: 'https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/406',
128
+ },
129
+ 407: {
130
+ name: 'Proxy Authentication Required',
131
+ url: 'https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/407',
132
+ },
133
+ 408: {
134
+ name: 'Request Timeout',
135
+ url: 'https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/408',
136
+ },
137
+ 409: {
138
+ name: 'Conflict',
139
+ url: 'https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/409',
140
+ },
141
+ 410: {
142
+ name: 'Gone',
143
+ url: 'https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/410',
144
+ },
145
+ 411: {
146
+ name: 'Length Required',
147
+ url: 'https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/411',
148
+ },
149
+ 412: {
150
+ name: 'Precondition Failed',
151
+ url: 'https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/412',
152
+ },
153
+ 413: {
154
+ name: 'Content Too Large',
155
+ url: 'https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/413',
156
+ },
157
+ 414: {
158
+ name: 'URI Too Long',
159
+ url: 'https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/414',
160
+ },
161
+ 415: {
162
+ name: 'Unsupported Media Type',
163
+ url: 'https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/415',
164
+ },
165
+ 416: {
166
+ name: 'Range Not Satisfiable',
167
+ url: 'https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/416',
168
+ },
169
+ 417: {
170
+ name: 'Expectation Failed',
171
+ url: 'https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/417',
172
+ },
173
+ 421: {
174
+ name: 'Misdirected Request',
175
+ url: 'https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/421',
176
+ },
177
+ 422: {
178
+ name: 'Unprocessable Content',
179
+ url: 'https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/422',
180
+ },
181
+ 423: {
182
+ name: 'Locked',
183
+ url: 'https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/423',
184
+ },
185
+ 424: {
186
+ name: 'Failed Dependency',
187
+ url: 'https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/424',
188
+ },
189
+ 425: {
190
+ name: 'Too Early',
191
+ url: 'https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/425',
192
+ },
193
+ 426: {
194
+ name: 'Upgrade Required',
195
+ url: 'https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/426',
196
+ },
197
+ 428: {
198
+ name: 'Precondition Required',
199
+ url: 'https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/428',
200
+ },
201
+ 429: {
202
+ name: 'Too Many Requests',
203
+ url: 'https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/429',
204
+ },
205
+ 431: {
206
+ name: 'Request Header Fields Too Large',
207
+ url: 'https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/431',
208
+ },
209
+ 451: {
210
+ name: 'Unavailable For Legal Reasons',
211
+ url: 'https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/451',
212
+ },
213
+ 500: {
214
+ name: 'Internal Server Error',
215
+ url: 'https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/500',
216
+ },
217
+ 501: {
218
+ name: 'Not Implemented',
219
+ url: 'https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/501',
220
+ },
221
+ 502: {
222
+ name: 'Bad Gateway',
223
+ url: 'https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/502',
224
+ },
225
+ 503: {
226
+ name: 'Service Unavailable',
227
+ url: 'https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/503',
228
+ },
229
+ 504: {
230
+ name: 'Gateway Timeout',
231
+ url: 'https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/504',
232
+ },
233
+ 505: {
234
+ name: 'HTTP Version Not Supported',
235
+ url: 'https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/505',
236
+ },
237
+ 506: {
238
+ name: 'Variant Also Negotiates',
239
+ url: 'https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/506',
240
+ },
241
+ 507: {
242
+ name: 'Insufficient Storage',
243
+ url: 'https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/507',
244
+ },
245
+ 508: {
246
+ name: 'Loop Detected',
247
+ url: 'https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/508',
248
+ },
249
+ 510: {
250
+ name: 'Not Extended',
251
+ url: 'https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/510',
252
+ },
253
+ 511: {
254
+ name: 'Network Authentication Required',
255
+ url: 'https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/511',
256
+ },
257
+ }
258
+
259
+ export default httpStatusCodes
@@ -0,0 +1,6 @@
1
+ export { httpHeaders, type HttpHeader } from './httpHeaders'
2
+ export {
3
+ default as httpStatusCodes,
4
+ type HttpStatusCode,
5
+ type HttpStatusCodes,
6
+ } from './httpStatusCodes'
@@ -0,0 +1,16 @@
1
+ import type { ClientRequestConfig } from '../types'
2
+
3
+ /**
4
+ * Generate a new placeholder request
5
+ */
6
+ export const createPlaceholderRequest = (): ClientRequestConfig => ({
7
+ name: '',
8
+ url: '',
9
+ type: 'GET',
10
+ path: '',
11
+ parameters: [],
12
+ headers: [],
13
+ query: [],
14
+ body: '',
15
+ formData: [],
16
+ })
@@ -0,0 +1,19 @@
1
+ import type { BaseParameter, Parameters } from '../types'
2
+
3
+ /**
4
+ * Generate parameters for the request from the parameters in the swagger file
5
+ */
6
+ export function generateParameters(parameters: Parameters[]) {
7
+ const params: BaseParameter[] = []
8
+ parameters.forEach((parameter: Parameters) => {
9
+ const param: BaseParameter = {
10
+ name: parameter.name,
11
+ value: '',
12
+ customClass: parameter.required ? 'required-parameter' : '',
13
+ }
14
+ param.value = ''
15
+ params.push(param)
16
+ })
17
+
18
+ return params
19
+ }
@@ -0,0 +1,26 @@
1
+ import { type ParamMap } from '../hooks/useOperation'
2
+ import type { ClientRequestConfig, Operation, Server } from '../types'
3
+ import { generateParameters } from './generateParameters'
4
+
5
+ /**
6
+ * Generate parameters for the request
7
+ */
8
+ export function generateRequest(
9
+ operation: Operation,
10
+ parameterMap: ParamMap,
11
+ server: Server,
12
+ ): ClientRequestConfig {
13
+ const item = {
14
+ id: operation.operationId,
15
+ name: operation.name,
16
+ type: operation.httpVerb,
17
+ path: operation.path,
18
+ parameters: generateParameters(parameterMap.path),
19
+ query: generateParameters(parameterMap.query),
20
+ headers: generateParameters(parameterMap.header),
21
+ url: server.url,
22
+ body: '',
23
+ }
24
+
25
+ return item
26
+ }
@@ -0,0 +1,5 @@
1
+ export { createPlaceholderRequest } from './createPlaceholderRequest'
2
+ export { generateRequest } from './generateRequest'
3
+ export { generateParameters } from './generateParameters'
4
+ export { mapFromArray } from './mapFromArray'
5
+ export { sendRequest } from './sendRequest'
@@ -0,0 +1,16 @@
1
+ /**
2
+ * A utility function to convert an array of objects to an object of objects.
3
+ */
4
+ export function mapFromArray<
5
+ T extends Record<string, unknown>,
6
+ K extends keyof T & string,
7
+ V extends keyof T & string,
8
+ >(arr: T[], key: K, valueKey: V) {
9
+ const obj: Record<string, T[V]> = {}
10
+
11
+ arr.forEach((entry) => {
12
+ obj[entry[key] as string] = entry[valueKey]
13
+ })
14
+
15
+ return obj
16
+ }
@@ -0,0 +1,94 @@
1
+ import axios from 'axios'
2
+ import { nanoid } from 'nanoid'
3
+ import nunjucks from 'nunjucks'
4
+
5
+ import type {
6
+ ClientRequestConfig,
7
+ ClientResponse,
8
+ RequestResult,
9
+ } from '../types'
10
+ import { mapFromArray } from './mapFromArray'
11
+
12
+ const templateEngine = nunjucks.configure({
13
+ tags: {
14
+ variableStart: '{',
15
+ variableEnd: '}',
16
+ },
17
+ })
18
+
19
+ const defaultHeaders = {
20
+ 'User-Agent': 'Scalar API Client',
21
+ }
22
+
23
+ /**
24
+ * Send a request via the proxy
25
+ */
26
+ export async function sendRequest(
27
+ request: ClientRequestConfig,
28
+ proxyUrl: string,
29
+ ): Promise<RequestResult | null> {
30
+ // Format complete URL
31
+ const method = request.type.toUpperCase()
32
+ const fullUrl = `${request.url}${request.path}`
33
+ const headers: Record<string, string | number> = {
34
+ ...defaultHeaders,
35
+ ...mapFromArray(request.headers, 'name', 'value'),
36
+ }
37
+ /** TODO: Make dynamic */
38
+ const auth = {
39
+ type: 'none',
40
+ }
41
+ const variables = mapFromArray(request.parameters, 'name', 'value')
42
+ const renderedURL = templateEngine.renderString(fullUrl, variables)
43
+ /** TODO: Make dynamic */
44
+ const proxy = true
45
+
46
+ const startTime = Date.now()
47
+
48
+ const requestOptions = {
49
+ method,
50
+ url: renderedURL,
51
+ auth,
52
+ headers,
53
+ data: request.body,
54
+ }
55
+
56
+ const config = proxy
57
+ ? {
58
+ method: 'POST',
59
+ url: proxyUrl,
60
+ data: requestOptions,
61
+ }
62
+ : {
63
+ method: requestOptions.method,
64
+ url: requestOptions.url,
65
+ headers: requestOptions.headers,
66
+ data: requestOptions.data,
67
+ }
68
+
69
+ console.info(`${requestOptions.method} ${requestOptions.url}`)
70
+
71
+ const response: (ClientResponse & { error: false }) | { error: true } =
72
+ // @ts-ignore
73
+ await axios(config)
74
+ .then((res) => ({
75
+ ...res.data,
76
+ error: false,
77
+ }))
78
+ .catch((err) => ({
79
+ error: true,
80
+ ...err?.response,
81
+ }))
82
+
83
+ return !response.error
84
+ ? {
85
+ sentTime: Date.now(),
86
+ request,
87
+ response: {
88
+ ...response,
89
+ duration: Date.now() - startTime,
90
+ },
91
+ responseId: nanoid(),
92
+ }
93
+ : null
94
+ }
@@ -0,0 +1,2 @@
1
+ // export { useCopilot } from './useCopilot'
2
+ export { useOperation, type ParamMap } from './useOperation'
@@ -0,0 +1,64 @@
1
+ import { useWebSocket } from '@vueuse/core'
2
+ import { reactive, readonly } from 'vue'
3
+
4
+ export enum CopilotLoadingStates {
5
+ Inactive = 'Inactive',
6
+ Fix = 'Fix',
7
+ Loading = 'Loading',
8
+ Working = 'Working',
9
+ Success = 'Success',
10
+ }
11
+
12
+ export type RequestData = {
13
+ id: string
14
+ request: string
15
+ }
16
+ export type RecommendationHandler = (recommendation: string) => void
17
+
18
+ const recommendationHandler: Set<RecommendationHandler> = new Set([])
19
+
20
+ function onMessage(_ws: WebSocket, event: MessageEvent) {
21
+ const jsonData = JSON.parse(event.data)
22
+ const recommendation = jsonData['response']
23
+ recommendationHandler.forEach((handler) => handler(recommendation))
24
+ }
25
+
26
+ const { send } = useWebSocket(import.meta.env.VITE_COPILOT_WS_URL, {
27
+ onMessage,
28
+ autoReconnect: true,
29
+ })
30
+
31
+ function sendCopilot(requestData: RequestData) {
32
+ setLoadingState(CopilotLoadingStates.Loading)
33
+ const jsonString = JSON.stringify(requestData)
34
+ send(jsonString)
35
+ }
36
+
37
+ const serverHandler = () => ({
38
+ uuid: '',
39
+ curlRequest:
40
+ "curl -X 'GET' 'https://petstore.swagger.io/v2/pet/findByStatus?status=SOld' -H 'accept: application/json'",
41
+ })
42
+
43
+ const serverHandlerState = reactive(serverHandler())
44
+
45
+ const state = reactive({
46
+ loadingState: CopilotLoadingStates.Inactive,
47
+ })
48
+
49
+ function setLoadingState(loadingState: CopilotLoadingStates) {
50
+ state.loadingState = loadingState
51
+ }
52
+
53
+ /**
54
+ * This hook is used to send requests to the copilot server and receive recommendations.
55
+ */
56
+ export const useCopilot = () => ({
57
+ sendCopilot,
58
+ state: readonly(state),
59
+ onRecommendation: (handler: RecommendationHandler) => {
60
+ recommendationHandler.add(handler)
61
+ },
62
+ serverHandlerState,
63
+ setLoadingState,
64
+ })
@@ -0,0 +1,7 @@
1
+ import { describe, expect, it } from 'vitest'
2
+
3
+ describe('example', () => {
4
+ it('executes tests', () => {
5
+ expect(true).toBe(true)
6
+ })
7
+ })
@@ -0,0 +1,43 @@
1
+ import { computed } from 'vue'
2
+
3
+ import type { Operation, Parameters } from '../types'
4
+
5
+ export type ParamMap = {
6
+ path: Parameters[]
7
+ query: Parameters[]
8
+ header: Parameters[]
9
+ }
10
+
11
+ export type OperationProps = {
12
+ operation: Operation
13
+ }
14
+
15
+ /**
16
+ * This hook is used to generate the parameters for the request from the parameters in the swagger file
17
+ */
18
+ export function useOperation(props: OperationProps) {
19
+ const parameterMap = computed(() => {
20
+ const { parameters } = props.operation.information
21
+ const map: ParamMap = {
22
+ path: [],
23
+ query: [],
24
+ header: [],
25
+ }
26
+ if (parameters) {
27
+ parameters.forEach((parameter: Parameters) => {
28
+ if (parameter.in === 'path') {
29
+ map.path.push(parameter)
30
+ } else if (parameter.in === 'query') {
31
+ map.query.push(parameter)
32
+ } else if (parameter.in === 'header') {
33
+ map.header.push(parameter)
34
+ }
35
+ })
36
+ }
37
+ return map
38
+ })
39
+
40
+ return {
41
+ parameterMap,
42
+ }
43
+ }
package/src/index.ts ADDED
@@ -0,0 +1,9 @@
1
+ export { ApiClient } from './components/ApiClient'
2
+ export { CodeMirror } from './components/CodeMirror'
3
+
4
+ export * from './helpers'
5
+ export * from './hooks'
6
+ export * from './stores/apiClientStore'
7
+ export * from './stores/apiClientRequestStore'
8
+ export * from './types'
9
+ export * from './fixtures'
@@ -0,0 +1,103 @@
1
+ import { computed, reactive, ref } from 'vue'
2
+
3
+ import { createPlaceholderRequest } from '../helpers/createPlaceholderRequest'
4
+ import type { AuthState, ClientRequestConfig, RequestResult } from '../types'
5
+
6
+ // Auth state template
7
+ export const createEmptyAuthState = (): AuthState => ({
8
+ type: 'none',
9
+ basic: {
10
+ userName: '',
11
+ password: '',
12
+ active: true,
13
+ },
14
+ oauthTwo: {
15
+ generatedToken: '',
16
+ discoveryURL: '',
17
+ authURL: '',
18
+ accessTokenURL: '',
19
+ clientID: '',
20
+ clientSecret: '',
21
+ scope: '',
22
+ active: true,
23
+ },
24
+ bearer: {
25
+ token: '',
26
+ active: true,
27
+ },
28
+ digest: {
29
+ userName: '',
30
+ password: '',
31
+ active: true,
32
+ },
33
+ })
34
+
35
+ /**
36
+ * Request state
37
+ */
38
+ type RequestHistoryOrder = string[]
39
+ type RequestHistoryEntry = RequestResult
40
+
41
+ // Request Authorization State
42
+ const authState = reactive(createEmptyAuthState())
43
+
44
+ // Log of all requests made
45
+ const requestHistory: Record<string, RequestHistoryEntry> = reactive({})
46
+
47
+ // Request list order
48
+ const requestHistoryOrder = ref<RequestHistoryOrder>([])
49
+
50
+ // Id of the currently viewed request
51
+ const activeRequestId = ref('')
52
+
53
+ // Active request object
54
+ const activeRequest = reactive(createPlaceholderRequest())
55
+
56
+ /**
57
+ * Mutators
58
+ */
59
+
60
+ // Add a new request to the history log and make it active
61
+ const addRequestToHistory = (value: RequestHistoryEntry) => {
62
+ requestHistory[value.responseId] = value
63
+ activeRequestId.value = value.responseId
64
+ requestHistoryOrder.value.unshift(value.responseId)
65
+ }
66
+
67
+ // Set a response by key to currently active
68
+ const setActiveResponse = (historyID: string) => {
69
+ activeRequestId.value = historyID
70
+ const { request }: { request: ClientRequestConfig } =
71
+ requestHistory[historyID]
72
+ Object.assign(activeRequest, request)
73
+ }
74
+
75
+ // Get the currently active response
76
+ const activeResponse = computed(() =>
77
+ activeRequestId.value ? requestHistory[activeRequestId.value].response : null,
78
+ )
79
+
80
+ // Set the active request object
81
+ const setActiveRequest = (request: ClientRequestConfig) => {
82
+ Object.assign(activeRequest, request)
83
+ }
84
+
85
+ /**
86
+ * View state
87
+ */
88
+
89
+ // Whether the request is in read mode or edit mode
90
+ const readOnly = ref(true)
91
+
92
+ export const useApiClientRequestStore = () => ({
93
+ authState,
94
+ readOnly,
95
+ activeRequest,
96
+ activeResponse,
97
+ requestHistory,
98
+ requestHistoryOrder,
99
+ activeRequestId,
100
+ setActiveResponse,
101
+ addRequestToHistory,
102
+ setActiveRequest,
103
+ })