@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.
Files changed (40) hide show
  1. package/CHANGELOG.md +19 -0
  2. package/dist/entities/spec/collection.d.ts +0 -278
  3. package/dist/entities/spec/collection.d.ts.map +1 -1
  4. package/dist/entities/spec/collection.js +1 -8
  5. package/dist/entities/spec/index.js +1 -1
  6. package/dist/entities/spec/requests.d.ts +2 -2
  7. package/dist/entities/spec/security.d.ts +1123 -783
  8. package/dist/entities/spec/security.d.ts.map +1 -1
  9. package/dist/entities/spec/security.js +73 -133
  10. package/dist/entities/workspace/workspace.d.ts +3 -7
  11. package/dist/entities/workspace/workspace.d.ts.map +1 -1
  12. package/dist/entities/workspace/workspace.js +0 -2
  13. package/dist/migrations/data-version.d.ts +3 -2
  14. package/dist/migrations/data-version.d.ts.map +1 -1
  15. package/dist/migrations/data-version.js +3 -2
  16. package/dist/migrations/local-storage.d.ts.map +1 -1
  17. package/dist/migrations/local-storage.js +3 -5
  18. package/dist/migrations/migrator.d.ts +2 -2
  19. package/dist/migrations/migrator.d.ts.map +1 -1
  20. package/dist/migrations/migrator.js +16 -13
  21. package/dist/migrations/v-0.0.0/types.generated.d.ts +139 -90
  22. package/dist/migrations/v-0.0.0/types.generated.d.ts.map +1 -1
  23. package/dist/migrations/v-2.1.0/migration.d.ts +11 -340
  24. package/dist/migrations/v-2.1.0/migration.d.ts.map +1 -1
  25. package/dist/migrations/v-2.1.0/migration.js +67 -46
  26. package/dist/migrations/v-2.1.0/types.generated.d.ts +353 -28
  27. package/dist/migrations/v-2.1.0/types.generated.d.ts.map +1 -1
  28. package/dist/migrations/v-2.2.0/index.d.ts +3 -0
  29. package/dist/migrations/v-2.2.0/index.d.ts.map +1 -0
  30. package/dist/migrations/v-2.2.0/index.js +1 -0
  31. package/dist/migrations/v-2.2.0/migration.d.ts +5 -0
  32. package/dist/migrations/v-2.2.0/migration.d.ts.map +1 -0
  33. package/dist/migrations/v-2.2.0/migration.js +110 -0
  34. package/dist/migrations/v-2.2.0/types.generated.d.ts +41 -0
  35. package/dist/migrations/v-2.2.0/types.generated.d.ts.map +1 -0
  36. package/dist/transforms/import-spec.d.ts +9 -4
  37. package/dist/transforms/import-spec.d.ts.map +1 -1
  38. package/dist/transforms/import-spec.js +74 -99
  39. package/dist/transforms/index.js +1 -1
  40. package/package.json +10 -5
@@ -1,4 +1,4 @@
1
- import { securitySchemeSchema, authExampleFromSchema } from '../entities/spec/security.js';
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
- return { schema: schema, errors };
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, s]) => {
153
- const scheme = schemaModel(
154
- // We must convert flows to a singular object, technically not spec compliant so we grab the first
155
- s.type === 'oauth2'
156
- ? convertOauth2Flows(s, nameKey, authentication)
157
- : {
158
- ...s,
159
- nameKey,
160
- }, securitySchemeSchema, false);
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 { getBaseAuthValues, importSpecToWorkspace, parseSchema };
328
+ export { importSpecToWorkspace, parseSchema };
@@ -1,2 +1,2 @@
1
- export { getBaseAuthValues, importSpecToWorkspace, parseSchema } from './import-spec.js';
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.77",
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/themes": "0.9.48",
112
- "@scalar/types": "0.0.19"
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": "^1.2.0",
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"