@scalar/oas-utils 0.2.77 → 0.2.79
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +19 -0
- package/dist/entities/spec/collection.d.ts +0 -278
- package/dist/entities/spec/collection.d.ts.map +1 -1
- package/dist/entities/spec/collection.js +1 -8
- package/dist/entities/spec/index.js +1 -1
- package/dist/entities/spec/requests.d.ts +2 -2
- package/dist/entities/spec/security.d.ts +1123 -783
- package/dist/entities/spec/security.d.ts.map +1 -1
- package/dist/entities/spec/security.js +73 -133
- package/dist/entities/workspace/workspace.d.ts +3 -7
- package/dist/entities/workspace/workspace.d.ts.map +1 -1
- package/dist/entities/workspace/workspace.js +0 -2
- package/dist/migrations/data-version.d.ts +3 -2
- package/dist/migrations/data-version.d.ts.map +1 -1
- package/dist/migrations/data-version.js +3 -2
- package/dist/migrations/local-storage.d.ts.map +1 -1
- package/dist/migrations/local-storage.js +3 -5
- package/dist/migrations/migrator.d.ts +2 -2
- package/dist/migrations/migrator.d.ts.map +1 -1
- package/dist/migrations/migrator.js +16 -13
- package/dist/migrations/v-0.0.0/types.generated.d.ts +139 -90
- package/dist/migrations/v-0.0.0/types.generated.d.ts.map +1 -1
- package/dist/migrations/v-2.1.0/migration.d.ts +11 -340
- package/dist/migrations/v-2.1.0/migration.d.ts.map +1 -1
- package/dist/migrations/v-2.1.0/migration.js +67 -46
- package/dist/migrations/v-2.1.0/types.generated.d.ts +353 -28
- package/dist/migrations/v-2.1.0/types.generated.d.ts.map +1 -1
- package/dist/migrations/v-2.2.0/index.d.ts +3 -0
- package/dist/migrations/v-2.2.0/index.d.ts.map +1 -0
- package/dist/migrations/v-2.2.0/index.js +1 -0
- package/dist/migrations/v-2.2.0/migration.d.ts +5 -0
- package/dist/migrations/v-2.2.0/migration.d.ts.map +1 -0
- package/dist/migrations/v-2.2.0/migration.js +110 -0
- package/dist/migrations/v-2.2.0/types.generated.d.ts +41 -0
- package/dist/migrations/v-2.2.0/types.generated.d.ts.map +1 -0
- package/dist/transforms/import-spec.d.ts +9 -4
- package/dist/transforms/import-spec.d.ts.map +1 -1
- package/dist/transforms/import-spec.js +74 -99
- package/dist/transforms/index.js +1 -1
- package/package.json +10 -5
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { securitySchemeSchema
|
|
1
|
+
import { securitySchemeSchema } from '../entities/spec/security.js';
|
|
2
2
|
import { schemaModel } from '../helpers/schema-model.js';
|
|
3
3
|
import { keysOf } from '@scalar/object-utils/arrays';
|
|
4
4
|
import { load, upgrade, dereference } from '@scalar/openapi-parser';
|
|
@@ -8,90 +8,31 @@ import { tagSchema } from '../entities/spec/spec-objects.js';
|
|
|
8
8
|
import { createExampleFromRequest } from '../entities/spec/request-examples.js';
|
|
9
9
|
import { collectionSchema } from '../entities/spec/collection.js';
|
|
10
10
|
|
|
11
|
-
/**
|
|
12
|
-
* We need to convert from openapi spec flows to our singular flow object here
|
|
13
|
-
* If we ever go spec compliant (flows), we will no longer need this conversion
|
|
14
|
-
*/
|
|
15
|
-
const convertOauth2Flows = (security, nameKey, auth) => {
|
|
16
|
-
if (security.type === 'oauth2') {
|
|
17
|
-
const entries = Object.entries(security.flows ?? {});
|
|
18
|
-
if (entries.length) {
|
|
19
|
-
const [[type, flow]] = entries;
|
|
20
|
-
const payload = {
|
|
21
|
-
...security,
|
|
22
|
-
nameKey,
|
|
23
|
-
flow: {
|
|
24
|
-
...flow,
|
|
25
|
-
scopes:
|
|
26
|
-
// Ensure we convert array scope to an object
|
|
27
|
-
Array.isArray(flow.scopes) && typeof flow.scopes[0] === 'string'
|
|
28
|
-
? flow.scopes.reduce((prev, s) => ({ ...prev, [s]: '' }), {})
|
|
29
|
-
: flow.scopes,
|
|
30
|
-
type,
|
|
31
|
-
},
|
|
32
|
-
};
|
|
33
|
-
if (auth?.oAuth2 && payload.flow) {
|
|
34
|
-
// Set client id
|
|
35
|
-
if (auth.oAuth2.clientId)
|
|
36
|
-
payload['x-scalar-client-id'] = auth.oAuth2.clientId;
|
|
37
|
-
// Set selected scopes
|
|
38
|
-
if (auth.oAuth2.scopes)
|
|
39
|
-
payload.flow.selectedScopes = auth.oAuth2.scopes;
|
|
40
|
-
}
|
|
41
|
-
// Handle x-defaultClientId
|
|
42
|
-
if ('x-defaultClientId' in flow &&
|
|
43
|
-
typeof flow['x-defaultClientId'] === 'string')
|
|
44
|
-
payload['x-scalar-client-id'] = flow['x-defaultClientId'];
|
|
45
|
-
return payload;
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
return {
|
|
49
|
-
...security,
|
|
50
|
-
nameKey,
|
|
51
|
-
};
|
|
52
|
-
};
|
|
53
|
-
/** Pre-fill baseValues if we have authentication config */
|
|
54
|
-
const getBaseAuthValues = (scheme, auth) => {
|
|
55
|
-
if (!auth)
|
|
56
|
-
return {};
|
|
57
|
-
// ApiKey
|
|
58
|
-
if (scheme.type === 'apiKey')
|
|
59
|
-
return { value: auth.apiKey?.token ?? '' };
|
|
60
|
-
// HTTP
|
|
61
|
-
else if (scheme.type === 'http') {
|
|
62
|
-
if (scheme.scheme === 'basic')
|
|
63
|
-
return {
|
|
64
|
-
username: auth.http?.basic?.username ?? '',
|
|
65
|
-
password: auth.http?.basic?.password ?? '',
|
|
66
|
-
};
|
|
67
|
-
else if (scheme.scheme === 'bearer')
|
|
68
|
-
return { token: auth.http?.bearer?.token ?? '' };
|
|
69
|
-
}
|
|
70
|
-
// oauth2 implicit only for now, when we support multi flow can expand this
|
|
71
|
-
else if (scheme.type === 'oauth2') {
|
|
72
|
-
if (scheme.flow?.type === 'implicit')
|
|
73
|
-
return {
|
|
74
|
-
type: 'oauth-implicit',
|
|
75
|
-
token: auth.oAuth2?.accessToken ?? '',
|
|
76
|
-
};
|
|
77
|
-
else if (scheme.flow?.type === 'password')
|
|
78
|
-
return {
|
|
79
|
-
type: 'oauth-password',
|
|
80
|
-
token: auth.oAuth2?.accessToken ?? '',
|
|
81
|
-
username: auth.oAuth2?.username ?? '',
|
|
82
|
-
password: auth.oAuth2?.password ?? '',
|
|
83
|
-
};
|
|
84
|
-
}
|
|
85
|
-
return {};
|
|
86
|
-
};
|
|
87
11
|
/** Takes a string or object and parses it into an openapi spec compliant schema */
|
|
88
12
|
const parseSchema = async (spec) => {
|
|
89
13
|
// TODO: Plugins for URLs and files with the proxy is missing here.
|
|
90
14
|
// @see packages/api-reference/src/helpers/parse.ts
|
|
91
|
-
const { filesystem } = await load(spec)
|
|
15
|
+
const { filesystem, errors: loadErrors = [] } = await load(spec).catch((e) => ({
|
|
16
|
+
errors: [
|
|
17
|
+
{
|
|
18
|
+
code: e.code,
|
|
19
|
+
message: e.message,
|
|
20
|
+
},
|
|
21
|
+
],
|
|
22
|
+
filesystem: [],
|
|
23
|
+
}));
|
|
92
24
|
const { specification } = upgrade(filesystem);
|
|
93
|
-
const { schema, errors = [] } = await dereference(specification);
|
|
94
|
-
|
|
25
|
+
const { schema, errors: derefErrors = [] } = await dereference(specification);
|
|
26
|
+
if (!schema)
|
|
27
|
+
console.warn('[@scalar/oas-utils] OpenAPI Parser Warning: Schema is undefined');
|
|
28
|
+
return {
|
|
29
|
+
/**
|
|
30
|
+
* Temporary fix for the parser returning an empty array
|
|
31
|
+
* TODO: remove this once the parser is fixed
|
|
32
|
+
*/
|
|
33
|
+
schema: (Array.isArray(schema) ? {} : schema),
|
|
34
|
+
errors: [...loadErrors, ...derefErrors],
|
|
35
|
+
};
|
|
95
36
|
};
|
|
96
37
|
/**
|
|
97
38
|
* Imports an OpenAPI document and converts it to workspace entities (Collection, Request, Server, etc.)
|
|
@@ -149,15 +90,58 @@ async function importSpecToWorkspace(spec, { authentication, baseServerURL, docu
|
|
|
149
90
|
// SECURITY HANDLING
|
|
150
91
|
const security = schema.components?.securitySchemes ?? schema?.securityDefinitions ?? {};
|
|
151
92
|
const securitySchemes = Object.entries(security)
|
|
152
|
-
.map?.(([nameKey,
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
93
|
+
.map?.(([nameKey, _scheme]) => {
|
|
94
|
+
// Apply any transforms we need before parsing
|
|
95
|
+
const payload = {
|
|
96
|
+
..._scheme,
|
|
97
|
+
nameKey,
|
|
98
|
+
};
|
|
99
|
+
// For oauth2 we need to add the type to the flows + prefill from authentication
|
|
100
|
+
if (payload.type === 'oauth2' && payload.flows) {
|
|
101
|
+
const flowKeys = Object.keys(payload.flows);
|
|
102
|
+
flowKeys.forEach((key) => {
|
|
103
|
+
if (!payload.flows?.[key])
|
|
104
|
+
return;
|
|
105
|
+
const flow = payload.flows[key];
|
|
106
|
+
// Set the type
|
|
107
|
+
flow.type = key;
|
|
108
|
+
// Prefill values from authorization config
|
|
109
|
+
if (authentication?.oAuth2) {
|
|
110
|
+
if (authentication.oAuth2.accessToken)
|
|
111
|
+
flow.token = authentication.oAuth2.accessToken;
|
|
112
|
+
if (flow.type === 'password') {
|
|
113
|
+
flow.username = authentication.oAuth2.username;
|
|
114
|
+
flow.password = authentication.oAuth2.password;
|
|
115
|
+
}
|
|
116
|
+
if (authentication.oAuth2.scopes) {
|
|
117
|
+
flow.selectedScopes = authentication.oAuth2.scopes;
|
|
118
|
+
flow['x-scalar-client-id'] = authentication.oAuth2.clientId;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
// Convert scopes to an object
|
|
122
|
+
if (Array.isArray(flow.scopes))
|
|
123
|
+
flow.scopes = flow.scopes.reduce((prev, s) => ({ ...prev, [s]: '' }), {});
|
|
124
|
+
// Handle x-defaultClientId
|
|
125
|
+
if (flow['x-defaultClientId'])
|
|
126
|
+
flow['x-scalar-client-id'] = flow['x-defaultClientId'];
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
// Otherwise we just prefill
|
|
130
|
+
else if (authentication) {
|
|
131
|
+
// ApiKey
|
|
132
|
+
if (payload.type === 'apiKey' && authentication.apiKey?.token)
|
|
133
|
+
payload.value = authentication.apiKey.token;
|
|
134
|
+
// HTTP
|
|
135
|
+
else if (payload.type === 'http') {
|
|
136
|
+
if (payload.scheme === 'basic' && authentication.http?.basic) {
|
|
137
|
+
payload.username = authentication.http.basic.username ?? '';
|
|
138
|
+
payload.password = authentication.http.basic.password ?? '';
|
|
139
|
+
}
|
|
140
|
+
else if (payload.scheme === 'bearer' && authentication.http?.bearer)
|
|
141
|
+
payload.token = authentication.http.bearer.token ?? '';
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
const scheme = schemaModel(payload, securitySchemeSchema, false);
|
|
161
145
|
if (!scheme)
|
|
162
146
|
importWarnings.push(`Security scheme ${nameKey} is invalid.`);
|
|
163
147
|
return scheme;
|
|
@@ -299,14 +283,6 @@ async function importSpecToWorkspace(spec, { authentication, baseServerURL, docu
|
|
|
299
283
|
});
|
|
300
284
|
// ---------------------------------------------------------------------------
|
|
301
285
|
// Generate Collection
|
|
302
|
-
// Create the auth examples
|
|
303
|
-
const auth = securitySchemes?.reduce((prev, s) => {
|
|
304
|
-
const baseValues = getBaseAuthValues(s, authentication);
|
|
305
|
-
const example = authExampleFromSchema(s, baseValues);
|
|
306
|
-
if (example)
|
|
307
|
-
prev[s.uid] = example;
|
|
308
|
-
return prev;
|
|
309
|
-
}, {});
|
|
310
286
|
const securityKeys = Object.keys(security);
|
|
311
287
|
let selectedSecuritySchemeUids = [];
|
|
312
288
|
/** Selected security scheme UIDs for the collection, defaults to the first key */
|
|
@@ -319,7 +295,6 @@ async function importSpecToWorkspace(spec, { authentication, baseServerURL, docu
|
|
|
319
295
|
...schema,
|
|
320
296
|
watchMode,
|
|
321
297
|
documentUrl,
|
|
322
|
-
auth,
|
|
323
298
|
requests: requests.map((r) => r.uid),
|
|
324
299
|
servers: servers.map((s) => s.uid),
|
|
325
300
|
tags: tags.map((t) => t.uid),
|
|
@@ -350,4 +325,4 @@ async function importSpecToWorkspace(spec, { authentication, baseServerURL, docu
|
|
|
350
325
|
};
|
|
351
326
|
}
|
|
352
327
|
|
|
353
|
-
export {
|
|
328
|
+
export { importSpecToWorkspace, parseSchema };
|
package/dist/transforms/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export {
|
|
1
|
+
export { importSpecToWorkspace, parseSchema } from './import-spec.js';
|
|
2
2
|
export { exportSpecFromWorkspace } from './export-spec.js';
|
package/package.json
CHANGED
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
"specification",
|
|
17
17
|
"yaml"
|
|
18
18
|
],
|
|
19
|
-
"version": "0.2.
|
|
19
|
+
"version": "0.2.79",
|
|
20
20
|
"engines": {
|
|
21
21
|
"node": ">=18"
|
|
22
22
|
},
|
|
@@ -38,6 +38,11 @@
|
|
|
38
38
|
"types": "./dist/migrations/index.d.ts",
|
|
39
39
|
"default": "./dist/migrations/index.js"
|
|
40
40
|
},
|
|
41
|
+
"./migrations/v-2.2.0": {
|
|
42
|
+
"import": "./dist/migrations/v-2.2.0/index.js",
|
|
43
|
+
"types": "./dist/migrations/v-2.2.0/index.d.ts",
|
|
44
|
+
"default": "./dist/migrations/v-2.2.0/index.js"
|
|
45
|
+
},
|
|
41
46
|
"./migrations/v-2.1.0": {
|
|
42
47
|
"import": "./dist/migrations/v-2.1.0/index.js",
|
|
43
48
|
"types": "./dist/migrations/v-2.1.0/index.d.ts",
|
|
@@ -106,16 +111,16 @@
|
|
|
106
111
|
"nanoid": "^5.0.7",
|
|
107
112
|
"yaml": "^2.4.5",
|
|
108
113
|
"zod": "^3.23.8",
|
|
109
|
-
"@scalar/openapi-types": "0.1.5",
|
|
110
114
|
"@scalar/object-utils": "1.1.12",
|
|
111
|
-
"@scalar/
|
|
112
|
-
"@scalar/
|
|
115
|
+
"@scalar/openapi-types": "0.1.5",
|
|
116
|
+
"@scalar/themes": "0.9.50",
|
|
117
|
+
"@scalar/types": "0.0.20"
|
|
113
118
|
},
|
|
114
119
|
"devDependencies": {
|
|
115
120
|
"type-fest": "^4.20.0",
|
|
116
121
|
"vite": "^5.4.10",
|
|
117
122
|
"vitest": "^1.6.0",
|
|
118
|
-
"zod-to-ts": "
|
|
123
|
+
"zod-to-ts": "github:amritk/zod-to-ts#build",
|
|
119
124
|
"@scalar/build-tooling": "0.1.12",
|
|
120
125
|
"@scalar/openapi-parser": "0.8.10",
|
|
121
126
|
"@scalar/openapi-types": "0.1.5"
|