@scalar/oas-utils 0.2.43 → 0.2.45

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 (188) hide show
  1. package/CHANGELOG.md +22 -0
  2. package/dist/diff/diff.d.ts +13 -0
  3. package/dist/diff/diff.d.ts.map +1 -0
  4. package/dist/diff/index.d.ts +1 -0
  5. package/dist/diff/index.d.ts.map +1 -0
  6. package/dist/diff/index.js +1 -0
  7. package/dist/entities/{workspace/cookie → cookie}/cookie.d.ts +1 -17
  8. package/dist/entities/cookie/cookie.d.ts.map +1 -0
  9. package/dist/entities/{workspace/cookie → cookie}/cookie.js +1 -4
  10. package/dist/entities/cookie/index.d.ts.map +1 -0
  11. package/dist/entities/cookie/index.js +1 -0
  12. package/dist/entities/environment/environment.d.ts +24 -0
  13. package/dist/entities/environment/environment.d.ts.map +1 -0
  14. package/dist/entities/environment/environment.js +12 -0
  15. package/dist/entities/environment/index.d.ts.map +1 -0
  16. package/dist/entities/environment/index.js +1 -0
  17. package/dist/entities/{workspace/consts/hot-keys.d.ts → hotkeys/hotkeys.d.ts} +2 -2
  18. package/dist/entities/hotkeys/hotkeys.d.ts.map +1 -0
  19. package/dist/entities/{workspace/consts/hot-keys.js → hotkeys/hotkeys.js} +1 -0
  20. package/dist/entities/hotkeys/index.d.ts +2 -0
  21. package/dist/entities/hotkeys/index.d.ts.map +1 -0
  22. package/dist/entities/hotkeys/index.js +1 -0
  23. package/dist/entities/index.d.ts +1 -1
  24. package/dist/entities/index.d.ts.map +1 -1
  25. package/dist/entities/index.js +1 -1
  26. package/dist/entities/shared/index.d.ts.map +1 -0
  27. package/dist/entities/shared/utility.d.ts.map +1 -0
  28. package/dist/entities/spec/collection.d.ts +489 -0
  29. package/dist/entities/spec/collection.d.ts.map +1 -0
  30. package/dist/entities/spec/collection.js +63 -0
  31. package/dist/entities/spec/index.d.ts +10 -0
  32. package/dist/entities/spec/index.d.ts.map +1 -0
  33. package/dist/entities/spec/index.js +7 -0
  34. package/dist/entities/spec/parameters.d.ts +42 -0
  35. package/dist/entities/spec/parameters.d.ts.map +1 -0
  36. package/dist/entities/spec/parameters.js +30 -0
  37. package/dist/entities/spec/request-examples.d.ts +916 -0
  38. package/dist/entities/spec/request-examples.d.ts.map +1 -0
  39. package/dist/entities/spec/request-examples.js +168 -0
  40. package/dist/entities/spec/requests.d.ts +317 -0
  41. package/dist/entities/spec/requests.d.ts.map +1 -0
  42. package/dist/entities/{workspace/spec → spec}/requests.js +56 -32
  43. package/dist/entities/spec/security.d.ts +964 -0
  44. package/dist/entities/spec/security.d.ts.map +1 -0
  45. package/dist/entities/spec/security.js +222 -0
  46. package/dist/entities/spec/server.d.ts +82 -0
  47. package/dist/entities/spec/server.d.ts.map +1 -0
  48. package/dist/entities/{workspace/server → spec}/server.js +11 -13
  49. package/dist/entities/spec/spec-objects.d.ts +279 -0
  50. package/dist/entities/spec/spec-objects.d.ts.map +1 -0
  51. package/dist/entities/{workspace/collection/collection.js → spec/spec-objects.js} +21 -45
  52. package/dist/entities/workspace/index.js +1 -1
  53. package/dist/entities/workspace/workspace.d.ts +24 -43
  54. package/dist/entities/workspace/workspace.d.ts.map +1 -1
  55. package/dist/entities/workspace/workspace.js +6 -7
  56. package/dist/helpers/httpMethods.d.ts +16 -82
  57. package/dist/helpers/httpMethods.d.ts.map +1 -1
  58. package/dist/helpers/httpMethods.js +45 -41
  59. package/dist/helpers/index.d.ts +2 -0
  60. package/dist/helpers/index.d.ts.map +1 -1
  61. package/dist/helpers/index.js +4 -2
  62. package/dist/helpers/local-storage.d.ts +16 -0
  63. package/dist/helpers/local-storage.d.ts.map +1 -0
  64. package/dist/helpers/local-storage.js +17 -0
  65. package/dist/helpers/redirectToProxy.d.ts +2 -0
  66. package/dist/helpers/redirectToProxy.d.ts.map +1 -1
  67. package/dist/helpers/redirectToProxy.js +6 -7
  68. package/dist/helpers/regexHelpers.d.ts +3 -0
  69. package/dist/helpers/regexHelpers.d.ts.map +1 -0
  70. package/dist/helpers/regexHelpers.js +4 -0
  71. package/dist/helpers/schema-model.d.ts +2 -2
  72. package/dist/helpers/schema-model.d.ts.map +1 -1
  73. package/dist/helpers/schema-model.js +11 -17
  74. package/dist/migrations/data-version.d.ts +12 -0
  75. package/dist/migrations/data-version.d.ts.map +1 -0
  76. package/dist/migrations/data-version.js +13 -0
  77. package/dist/migrations/generate-types.d.ts +2 -0
  78. package/dist/migrations/generate-types.d.ts.map +1 -0
  79. package/dist/migrations/index.d.ts +4 -0
  80. package/dist/migrations/index.d.ts.map +1 -0
  81. package/dist/migrations/index.js +3 -0
  82. package/dist/migrations/local-storage.d.ts +8 -0
  83. package/dist/migrations/local-storage.d.ts.map +1 -0
  84. package/dist/migrations/local-storage.js +36 -0
  85. package/dist/migrations/migrator.d.ts +4 -0
  86. package/dist/migrations/migrator.d.ts.map +1 -0
  87. package/dist/migrations/migrator.js +40 -0
  88. package/dist/migrations/semver.d.ts +5 -0
  89. package/dist/migrations/semver.d.ts.map +1 -0
  90. package/dist/migrations/semver.js +25 -0
  91. package/dist/migrations/v-0.0.0/index.d.ts +2 -0
  92. package/dist/migrations/v-0.0.0/index.d.ts.map +1 -0
  93. package/dist/migrations/v-0.0.0/index.js +1 -0
  94. package/dist/migrations/v-0.0.0/types.generated.d.ts +347 -0
  95. package/dist/migrations/v-0.0.0/types.generated.d.ts.map +1 -0
  96. package/dist/migrations/v-2.1.0/index.d.ts +3 -0
  97. package/dist/migrations/v-2.1.0/index.d.ts.map +1 -0
  98. package/dist/migrations/v-2.1.0/index.js +1 -0
  99. package/dist/migrations/v-2.1.0/migration.d.ts +334 -0
  100. package/dist/migrations/v-2.1.0/migration.d.ts.map +1 -0
  101. package/dist/migrations/v-2.1.0/migration.js +249 -0
  102. package/dist/migrations/v-2.1.0/types.generated.d.ts +42 -0
  103. package/dist/migrations/v-2.1.0/types.generated.d.ts.map +1 -0
  104. package/dist/spec-getters/getExampleFromSchema.d.ts.map +1 -1
  105. package/dist/spec-getters/getExampleFromSchema.js +21 -8
  106. package/dist/spec-getters/getParametersFromOperation.d.ts +1 -1
  107. package/dist/spec-getters/getParametersFromOperation.d.ts.map +1 -1
  108. package/dist/spec-getters/getParametersFromOperation.js +8 -7
  109. package/dist/spec-getters/getRequestBodyFromOperation.d.ts +12 -40
  110. package/dist/spec-getters/getRequestBodyFromOperation.d.ts.map +1 -1
  111. package/dist/spec-getters/getRequestBodyFromOperation.js +34 -23
  112. package/dist/spec-getters/getRequestFromOperation.d.ts.map +1 -1
  113. package/dist/spec-getters/getRequestFromOperation.js +1 -2
  114. package/dist/spec-getters/getServerVariableExamples.d.ts +4 -0
  115. package/dist/spec-getters/getServerVariableExamples.d.ts.map +1 -0
  116. package/dist/spec-getters/getServerVariableExamples.js +12 -0
  117. package/dist/spec-getters/index.d.ts +1 -0
  118. package/dist/spec-getters/index.d.ts.map +1 -1
  119. package/dist/spec-getters/index.js +1 -0
  120. package/dist/transforms/export-spec.d.ts +68 -0
  121. package/dist/transforms/export-spec.d.ts.map +1 -0
  122. package/dist/transforms/import-spec.d.ts +20 -68
  123. package/dist/transforms/import-spec.d.ts.map +1 -1
  124. package/dist/transforms/import-spec.js +209 -126
  125. package/package.json +43 -37
  126. package/dist/entities/workspace/collection/collection.d.ts +0 -330
  127. package/dist/entities/workspace/collection/collection.d.ts.map +0 -1
  128. package/dist/entities/workspace/collection/index.d.ts +0 -2
  129. package/dist/entities/workspace/collection/index.d.ts.map +0 -1
  130. package/dist/entities/workspace/collection/index.js +0 -1
  131. package/dist/entities/workspace/consts/hot-keys.d.ts.map +0 -1
  132. package/dist/entities/workspace/consts/index.d.ts +0 -2
  133. package/dist/entities/workspace/consts/index.d.ts.map +0 -1
  134. package/dist/entities/workspace/consts/index.js +0 -1
  135. package/dist/entities/workspace/cookie/cookie.d.ts.map +0 -1
  136. package/dist/entities/workspace/cookie/index.d.ts.map +0 -1
  137. package/dist/entities/workspace/cookie/index.js +0 -1
  138. package/dist/entities/workspace/environment/environment.d.ts +0 -55
  139. package/dist/entities/workspace/environment/environment.d.ts.map +0 -1
  140. package/dist/entities/workspace/environment/environment.js +0 -23
  141. package/dist/entities/workspace/environment/index.d.ts.map +0 -1
  142. package/dist/entities/workspace/environment/index.js +0 -1
  143. package/dist/entities/workspace/folder/folder.d.ts +0 -36
  144. package/dist/entities/workspace/folder/folder.d.ts.map +0 -1
  145. package/dist/entities/workspace/folder/folder.js +0 -21
  146. package/dist/entities/workspace/folder/index.d.ts +0 -2
  147. package/dist/entities/workspace/folder/index.d.ts.map +0 -1
  148. package/dist/entities/workspace/folder/index.js +0 -1
  149. package/dist/entities/workspace/security/index.d.ts +0 -3
  150. package/dist/entities/workspace/security/index.d.ts.map +0 -1
  151. package/dist/entities/workspace/security/index.js +0 -2
  152. package/dist/entities/workspace/security/security-requirement.d.ts +0 -13
  153. package/dist/entities/workspace/security/security-requirement.d.ts.map +0 -1
  154. package/dist/entities/workspace/security/security-requirement.js +0 -15
  155. package/dist/entities/workspace/security/security-schemes.d.ts +0 -696
  156. package/dist/entities/workspace/security/security-schemes.d.ts.map +0 -1
  157. package/dist/entities/workspace/security/security-schemes.js +0 -139
  158. package/dist/entities/workspace/server/index.d.ts +0 -2
  159. package/dist/entities/workspace/server/index.d.ts.map +0 -1
  160. package/dist/entities/workspace/server/index.js +0 -1
  161. package/dist/entities/workspace/server/server.d.ts +0 -91
  162. package/dist/entities/workspace/server/server.d.ts.map +0 -1
  163. package/dist/entities/workspace/shared/index.d.ts.map +0 -1
  164. package/dist/entities/workspace/shared/utility.d.ts.map +0 -1
  165. package/dist/entities/workspace/spec/components.d.ts +0 -3
  166. package/dist/entities/workspace/spec/components.d.ts.map +0 -1
  167. package/dist/entities/workspace/spec/index.d.ts +0 -5
  168. package/dist/entities/workspace/spec/index.d.ts.map +0 -1
  169. package/dist/entities/workspace/spec/index.js +0 -2
  170. package/dist/entities/workspace/spec/parameters.d.ts +0 -16
  171. package/dist/entities/workspace/spec/parameters.d.ts.map +0 -1
  172. package/dist/entities/workspace/spec/refs.d.ts +0 -30
  173. package/dist/entities/workspace/spec/refs.d.ts.map +0 -1
  174. package/dist/entities/workspace/spec/refs.js +0 -9
  175. package/dist/entities/workspace/spec/request-examples.d.ts +0 -1573
  176. package/dist/entities/workspace/spec/request-examples.d.ts.map +0 -1
  177. package/dist/entities/workspace/spec/request-examples.js +0 -96
  178. package/dist/entities/workspace/spec/requests.d.ts +0 -181
  179. package/dist/entities/workspace/spec/requests.d.ts.map +0 -1
  180. package/dist/entities/workspace/spec/spec.d.ts +0 -18
  181. package/dist/entities/workspace/spec/spec.d.ts.map +0 -1
  182. package/dist/entities/workspace/spec/spec.js +0 -8
  183. /package/dist/entities/{workspace/cookie → cookie}/index.d.ts +0 -0
  184. /package/dist/entities/{workspace/environment → environment}/index.d.ts +0 -0
  185. /package/dist/entities/{workspace/shared → shared}/index.d.ts +0 -0
  186. /package/dist/entities/{workspace/shared → shared}/index.js +0 -0
  187. /package/dist/entities/{workspace/shared → shared}/utility.d.ts +0 -0
  188. /package/dist/entities/{workspace/shared → shared}/utility.js +0 -0
@@ -1,149 +1,232 @@
1
- import { tagObjectSchema } from '../entities/workspace/spec/spec.js';
1
+ import { securitySchemeSchema, authExampleFromSchema } from '../entities/spec/security.js';
2
2
  import { schemaModel } from '../helpers/schema-model.js';
3
- import { load, dereference } from '@scalar/openapi-parser';
4
- import { createRequest } from '../entities/workspace/spec/requests.js';
5
- import { createFolder } from '../entities/workspace/folder/folder.js';
6
- import { createServer } from '../entities/workspace/server/server.js';
7
- import { createCollection } from '../entities/workspace/collection/collection.js';
3
+ import { keysOf } from '@scalar/object-utils/arrays';
4
+ import { load, upgrade, dereference } from '@scalar/openapi-parser';
5
+ import { serverSchema } from '../entities/spec/server.js';
6
+ import { requestMethods, requestSchema } from '../entities/spec/requests.js';
7
+ import { tagSchema } from '../entities/spec/spec-objects.js';
8
+ import { createExampleFromRequest } from '../entities/spec/request-examples.js';
9
+ import { collectionSchema } from '../entities/spec/collection.js';
8
10
 
9
- const PARAM_DICTIONARY = {
10
- cookie: 'cookies',
11
- header: 'headers',
12
- path: 'path',
13
- query: 'query',
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) => {
16
+ if (security.type === 'oauth2') {
17
+ const entries = Object.entries(security.flows ?? {});
18
+ if (entries.length) {
19
+ const [[type, flow]] = entries;
20
+ return {
21
+ ...security,
22
+ nameKey,
23
+ flow: {
24
+ ...flow,
25
+ type,
26
+ },
27
+ };
28
+ }
29
+ }
30
+ return {
31
+ ...security,
32
+ nameKey,
33
+ };
14
34
  };
15
- /** Import an OpenAPI spec file and convert it to workspace entities */
16
- const importSpecToWorkspace = async (spec, overloadServers) => {
17
- const importWarnings = [];
18
- const requests = [];
19
- // TODO: `parsedSpec` can have circular reference and will break.
20
- // We always have to use the original document.
35
+ /**
36
+ * Import an OpenAPI spec file and convert it to workspace entities
37
+ *
38
+ * We will aim to keep the entities as close to the specification as possible
39
+ * to leverage bi-directional translation. Where entities are able to be
40
+ * created and used at various levels we will index via the uids to create
41
+ * the relationships
42
+ */
43
+ async function importSpecToWorkspace(spec) {
21
44
  const { filesystem } = await load(spec);
22
- const { schema, errors } = await dereference(filesystem);
23
- if (errors?.length || !schema) {
24
- console.warn('Please open an issue on https://github.com/scalar/scalar\n', 'Scalar OpenAPI Parser Warning:\n', errors);
25
- }
26
- // Keep a list of all tags used in requests so we can reference them later
27
- const requestTags = new Set();
28
- Object.entries(schema?.paths || {}).forEach(([pathString, path]) => {
45
+ const { specification } = upgrade(filesystem);
46
+ const { schema: _schema, errors = [] } = await dereference(specification);
47
+ const schema = _schema;
48
+ const importWarnings = [...errors.map((e) => e.message)];
49
+ if (!schema)
50
+ return { importWarnings, error: true };
51
+ // ---------------------------------------------------------------------------
52
+ // Some entities will be broken out as individual lists for modification in the workspace
53
+ const requests = [];
54
+ const servers = serverSchema.array().parse(schema.servers?.map((s) => s ?? [
55
+ {
56
+ url: typeof window !== 'undefined'
57
+ ? window.location.origin
58
+ : 'http://localhost',
59
+ description: 'Replace with your API server',
60
+ },
61
+ ]) ?? []);
62
+ /**
63
+ * List of all tag strings. For non compliant specs we may need to
64
+ * add top level tag objects for missing tag objects
65
+ */
66
+ const tagNames = new Set();
67
+ // ---------------------------------------------------------------------------
68
+ // SECURITY HANDLING
69
+ const security = schema.components?.securitySchemes ?? {};
70
+ const securitySchemes = Object.entries(security)
71
+ .map?.(([nameKey, s]) => {
72
+ const scheme = schemaModel(
73
+ // We must convert flows to a singular object, technically not spec compliant so we grab the first
74
+ s.type === 'oauth2'
75
+ ? convertOauth2Flows(s, nameKey)
76
+ : {
77
+ ...s,
78
+ nameKey,
79
+ }, securitySchemeSchema, false);
80
+ if (!scheme)
81
+ importWarnings.push(`Security scheme ${nameKey} is invalid.`);
82
+ return scheme;
83
+ })
84
+ .filter((v) => !!v);
85
+ // Map of security scheme names to UIDs
86
+ const securitySchemeMap = {};
87
+ securitySchemes.forEach((s) => {
88
+ securitySchemeMap[s.nameKey] = s.uid;
89
+ });
90
+ // ---------------------------------------------------------------------------
91
+ // REQUEST HANDLING
92
+ keysOf(schema.paths ?? {}).forEach((pathString) => {
93
+ const path = schema?.paths?.[pathString];
29
94
  if (!path)
30
95
  return;
31
- const methods = [
32
- 'get',
33
- 'put',
34
- 'post',
35
- 'delete',
36
- 'options',
37
- 'head',
38
- 'patch',
39
- 'trace',
40
- ];
41
- methods.forEach((method) => {
96
+ // Path level servers must be saved
97
+ const pathServers = serverSchema.array().parse(path.servers ?? []);
98
+ servers.push(...pathServers);
99
+ requestMethods.forEach((method) => {
42
100
  const operation = path[method];
43
- if (!operation)
44
- return;
45
- if ('$ref' in operation) {
46
- importWarnings.push(`${method.toUpperCase}:${pathString} - Importing of $ref paths is not yet supported`);
47
- return;
101
+ if (operation && typeof operation === 'object') {
102
+ const operationServers = serverSchema
103
+ .array()
104
+ .parse(operation.servers ?? []);
105
+ servers.push(...operationServers);
106
+ // We will save a list of all tags to ensure they exists at the top level
107
+ // TODO: make sure we add any loose requests with no tags to the collection children
108
+ operation.tags?.forEach((t) => tagNames.add(t));
109
+ // Remove security here and add it correctly below
110
+ const { security: removed, ...operationWithoutSecurity } = operation;
111
+ const requestPayload = {
112
+ ...operationWithoutSecurity,
113
+ method,
114
+ path: pathString,
115
+ selectedSecuritySchemeUids: [],
116
+ // Merge path and operation level parameters
117
+ parameters: [
118
+ ...(path?.parameters ?? []),
119
+ ...(operation.parameters ?? []),
120
+ ],
121
+ servers: [...pathServers, ...operationServers].map((s) => s.uid),
122
+ };
123
+ // Add list of UIDs to associate security schemes
124
+ // As per the spec if there is operation level security we ignore the top level requirements
125
+ if (operation.security?.length)
126
+ requestPayload.security = operation.security?.map((s) => {
127
+ const keys = Object.keys(s);
128
+ // Handle the case of {} for optional
129
+ if (keys.length) {
130
+ const [key] = Object.keys(s);
131
+ return {
132
+ [key]: s[key],
133
+ };
134
+ }
135
+ else
136
+ return s;
137
+ });
138
+ // Save parse the request
139
+ const request = schemaModel(requestPayload, requestSchema, false);
140
+ if (!request)
141
+ importWarnings.push(`${method} Request at ${path} is invalid.`);
142
+ else
143
+ requests.push(request);
48
144
  }
49
- const parameters = {
50
- path: {},
51
- query: {},
52
- headers: {},
53
- cookies: {},
54
- };
55
- // An operation can have component level parameters as well :)
56
- const pathAndOperationParameters = [
57
- ...(path.parameters || []),
58
- ...(operation.parameters || []),
59
- ].filter((p) => p);
60
- // Loop over params to set request params
61
- pathAndOperationParameters.forEach((_param) => {
62
- const param = _param;
63
- if ('name' in param &&
64
- PARAM_DICTIONARY[param.in]) {
65
- parameters[
66
- // Map cookie -> and header -> headers
67
- PARAM_DICTIONARY[param.in]][param.name] = param;
68
- }
69
- });
70
- const request = createRequest({
71
- method: method.toUpperCase(),
72
- path: pathString,
73
- tags: operation.tags || ['default'],
74
- description: operation.description,
75
- operationId: operation.operationId,
76
- security: operation.security,
77
- summary: operation.summary || pathString,
78
- externalDocs: operation.externalDocs,
79
- requestBody: operation.requestBody,
80
- parameters,
81
- });
82
- request.tags?.forEach((t) => requestTags.add(t));
83
- requests.push(request);
84
145
  });
85
146
  });
86
- // todo workaround till we rethink how we do createTags
87
- const tags = schemaModel(schema?.tags, tagObjectSchema.array(), false) ?? [
88
- { name: 'default' },
89
- ];
90
- // If there are request tags that are only defined in
91
- requestTags.forEach((requestTag) => {
92
- if (!tags.some((tag) => tag.name === requestTag)) {
93
- // Warn the user about implicit tags
94
- importWarnings.push(`The tag *${requestTags}* is does not have an explicit tag object in the specification file. `);
95
- tags.push({ name: requestTag });
96
- }
147
+ // ---------------------------------------------------------------------------
148
+ // TAG HANDLING
149
+ // TODO: We may need to handle de-duping tags
150
+ const tags = schemaModel(schema?.tags ?? [], tagSchema.array(), false) ?? [];
151
+ // Delete any tag names that already have a definition
152
+ tags.forEach((t) => tagNames.delete(t.name));
153
+ // Add an entry for any tags that are used but do not have a definition
154
+ tagNames.forEach((name) => tags.push(tagSchema.parse({ name })));
155
+ // Tag name to UID map
156
+ const tagMap = {};
157
+ tags.forEach((t) => {
158
+ tagMap[t.name] = t;
97
159
  });
98
- // TODO: Consider if we want this for production or just for data mocking
99
- // Create a basic folder structure from tags
100
- const folders = [];
160
+ // Add all tags by default. We will remove nested ones
161
+ const collectionChildren = new Set(tags.map((t) => t.uid));
162
+ // Nested folders go before any requests
101
163
  tags.forEach((t) => {
102
- const folder = createFolder({
103
- ...t,
104
- childUids: requests
105
- .filter((r) => r.tags?.includes(t.name))
106
- .map((r) => r.uid),
164
+ t['x-scalar-children']?.forEach((c) => {
165
+ // Add the uid to the appropriate parent.children
166
+ const nestedUid = tagMap[c.tagName].uid;
167
+ t.children.push(nestedUid);
168
+ // Remove the nested uid from the root folder
169
+ collectionChildren.delete(nestedUid);
107
170
  });
108
- folders.push(folder);
109
171
  });
110
- // Toss in a default server if there aren't any
111
- const unparsedServers = overloadServers ??
112
- (schema?.servers?.length
113
- ? schema.servers
114
- : [
115
- {
116
- url: typeof window !== 'undefined'
117
- ? window.location.origin
118
- : 'http://localhost',
119
- description: 'Replace with your API server',
120
- },
121
- ]);
122
- const servers = unparsedServers.map((server) => createServer(server));
123
- const collection = createCollection({
124
- spec: {
125
- openapi: schema?.openapi,
126
- info: schema?.info,
127
- security: schema?.security || schema?.securityDefinitions,
128
- externalDocs: schema?.externalDocs,
129
- serverUids: servers.map(({ uid }) => uid),
130
- tags,
172
+ // Add the request UIDs to the tag children (or collection root)
173
+ requests.forEach((r) => {
174
+ if (r.tags) {
175
+ r.tags.forEach((t) => {
176
+ tagMap[t].children.push(r.uid);
177
+ });
178
+ }
179
+ else {
180
+ collectionChildren.add(r.uid);
181
+ }
182
+ });
183
+ // ---------------------------------------------------------------------------
184
+ const examples = [];
185
+ // Ensure each request has at least 1 example
186
+ requests.forEach((request) => {
187
+ // TODO: Need to handle parsing examples
188
+ // if (request['x-scalar-examples']) return
189
+ // Create the initial example
190
+ const example = createExampleFromRequest(request, 'Default Example');
191
+ examples.push(example);
192
+ request.examples.push(example.uid);
193
+ });
194
+ // ---------------------------------------------------------------------------
195
+ // Generate Collection
196
+ // Create the auth examples
197
+ const auth = securitySchemes?.reduce((prev, s) => {
198
+ const example = authExampleFromSchema(s);
199
+ if (example)
200
+ prev[s.uid] = example;
201
+ return prev;
202
+ }, {});
203
+ const collection = collectionSchema.parse({
204
+ ...schema,
205
+ auth,
206
+ requests: requests.map((r) => r.uid),
207
+ servers: servers.map((s) => s.uid),
208
+ tags: tags.map((t) => t.uid),
209
+ children: [...collectionChildren],
210
+ security: schema.security ?? [{}],
211
+ selectedServerUid: servers?.[0]?.uid,
212
+ components: {
213
+ ...schema.components,
131
214
  },
132
- selectedServerUid: servers[0].uid,
133
- // We default to having all the requests in the root folder
134
- childUids: folders.map(({ uid }) => uid),
215
+ securitySchemes: securitySchemes.map((s) => s.uid),
135
216
  });
136
- const components = schema?.components;
137
- const securityDefinitions = schema?.securityDefinitions;
217
+ /**
218
+ * Servers and requests will be saved in top level maps and indexed via UID to
219
+ * maintain specification relationships
220
+ */
138
221
  return {
139
- tags,
140
- folders,
222
+ error: false,
141
223
  servers,
142
224
  requests,
225
+ examples,
143
226
  collection,
144
- components,
145
- securityDefinitions,
227
+ tags,
228
+ securitySchemes,
146
229
  };
147
- };
230
+ }
148
231
 
149
232
  export { importSpecToWorkspace };
package/package.json CHANGED
@@ -16,7 +16,7 @@
16
16
  "specification",
17
17
  "yaml"
18
18
  ],
19
- "version": "0.2.43",
19
+ "version": "0.2.45",
20
20
  "engines": {
21
21
  "node": ">=18"
22
22
  },
@@ -31,6 +31,18 @@
31
31
  "import": "./dist/spec-getters/index.js",
32
32
  "types": "./dist/spec-getters/index.d.ts"
33
33
  },
34
+ "./migrations": {
35
+ "import": "./dist/migrations/index.js",
36
+ "types": "./dist/migrations/index.d.ts"
37
+ },
38
+ "./migrations/v-2.1.0": {
39
+ "import": "./dist/migrations/v-2.1.0/index.js",
40
+ "types": "./dist/migrations/v-2.1.0/index.d.ts"
41
+ },
42
+ "./migrations/v-0.0.0": {
43
+ "import": "./dist/migrations/v-0.0.0/index.js",
44
+ "types": "./dist/migrations/v-0.0.0/index.d.ts"
45
+ },
34
46
  "./helpers": {
35
47
  "import": "./dist/helpers/index.js",
36
48
  "types": "./dist/helpers/index.d.ts"
@@ -43,41 +55,29 @@
43
55
  "import": "./dist/entities/workspace/index.js",
44
56
  "types": "./dist/entities/workspace/index.d.ts"
45
57
  },
46
- "./entities/workspace/spec": {
47
- "import": "./dist/entities/workspace/spec/index.js",
48
- "types": "./dist/entities/workspace/spec/index.d.ts"
49
- },
50
- "./entities/workspace/shared": {
51
- "import": "./dist/entities/workspace/shared/index.js",
52
- "types": "./dist/entities/workspace/shared/index.d.ts"
53
- },
54
- "./entities/workspace/server": {
55
- "import": "./dist/entities/workspace/server/index.js",
56
- "types": "./dist/entities/workspace/server/index.d.ts"
57
- },
58
- "./entities/workspace/security": {
59
- "import": "./dist/entities/workspace/security/index.js",
60
- "types": "./dist/entities/workspace/security/index.d.ts"
58
+ "./entities/spec": {
59
+ "import": "./dist/entities/spec/index.js",
60
+ "types": "./dist/entities/spec/index.d.ts"
61
61
  },
62
- "./entities/workspace/folder": {
63
- "import": "./dist/entities/workspace/folder/index.js",
64
- "types": "./dist/entities/workspace/folder/index.d.ts"
62
+ "./entities/shared": {
63
+ "import": "./dist/entities/shared/index.js",
64
+ "types": "./dist/entities/shared/index.d.ts"
65
65
  },
66
- "./entities/workspace/environment": {
67
- "import": "./dist/entities/workspace/environment/index.js",
68
- "types": "./dist/entities/workspace/environment/index.d.ts"
66
+ "./entities/hotkeys": {
67
+ "import": "./dist/entities/hotkeys/index.js",
68
+ "types": "./dist/entities/hotkeys/index.d.ts"
69
69
  },
70
- "./entities/workspace/cookie": {
71
- "import": "./dist/entities/workspace/cookie/index.js",
72
- "types": "./dist/entities/workspace/cookie/index.d.ts"
70
+ "./entities/environment": {
71
+ "import": "./dist/entities/environment/index.js",
72
+ "types": "./dist/entities/environment/index.d.ts"
73
73
  },
74
- "./entities/workspace/consts": {
75
- "import": "./dist/entities/workspace/consts/index.js",
76
- "types": "./dist/entities/workspace/consts/index.d.ts"
74
+ "./entities/cookie": {
75
+ "import": "./dist/entities/cookie/index.js",
76
+ "types": "./dist/entities/cookie/index.d.ts"
77
77
  },
78
- "./entities/workspace/collection": {
79
- "import": "./dist/entities/workspace/collection/index.js",
80
- "types": "./dist/entities/workspace/collection/index.d.ts"
78
+ "./diff": {
79
+ "import": "./dist/diff/index.js",
80
+ "types": "./dist/diff/index.d.ts"
81
81
  }
82
82
  },
83
83
  "files": [
@@ -86,21 +86,26 @@
86
86
  ],
87
87
  "module": "dist/index.js",
88
88
  "dependencies": {
89
+ "@hyperjump/json-schema": "^1.9.6",
90
+ "flatted": "^3.3.1",
91
+ "microdiff": "^1.4.0",
89
92
  "nanoid": "^5.0.7",
90
93
  "yaml": "^2.4.5",
91
- "zod": "^3.22.4",
92
- "@scalar/themes": "0.9.29",
93
- "@scalar/types": "0.0.8",
94
- "@scalar/object-utils": "1.1.7"
94
+ "zod": "^3.23.8",
95
+ "@scalar/object-utils": "1.1.8",
96
+ "@scalar/openapi-types": "0.1.1",
97
+ "@scalar/themes": "0.9.30",
98
+ "@scalar/types": "0.0.9"
95
99
  },
96
100
  "devDependencies": {
97
101
  "rollup": "^4.16.4",
98
102
  "type-fest": "^4.20.0",
99
103
  "vite": "^5.2.10",
100
104
  "vitest": "^1.6.0",
105
+ "zod-to-ts": "^1.2.0",
101
106
  "@scalar/build-tooling": "0.1.10",
102
- "@scalar/openapi-parser": "0.8.2",
103
- "@scalar/openapi-types": "0.1.1"
107
+ "@scalar/openapi-types": "0.1.1",
108
+ "@scalar/openapi-parser": "0.8.3"
104
109
  },
105
110
  "scripts": {
106
111
  "build": "scalar-build-rollup",
@@ -110,6 +115,7 @@
110
115
  "preview": "vite preview",
111
116
  "test": "vitest",
112
117
  "test:unit": "vitest .",
118
+ "typegen:migration": "vite-node ./src/migrations/generate-types.ts",
113
119
  "types:build": "scalar-types-build",
114
120
  "types:check": "scalar-types-check"
115
121
  }