@scalar/workspace-store 0.3.1 → 0.3.2
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 +8 -0
- package/dist/client.js +1 -1
- package/dist/client.js.map +1 -1
- package/package.json +6 -2
- package/.turbo/turbo-build.log +0 -13
- package/esbuild.ts +0 -8
- package/src/client.test.ts +0 -409
- package/src/client.ts +0 -254
- package/src/helpers/general.ts +0 -30
- package/src/helpers/json-path-utils.test.ts +0 -13
- package/src/helpers/json-path-utils.ts +0 -38
- package/src/helpers/proxy.test.ts +0 -61
- package/src/helpers/proxy.ts +0 -213
- package/src/schemas/callback.ts +0 -13
- package/src/schemas/components.ts +0 -36
- package/src/schemas/contact.ts +0 -11
- package/src/schemas/discriminator.ts +0 -13
- package/src/schemas/encoding.ts +0 -17
- package/src/schemas/example.ts +0 -17
- package/src/schemas/external-documentation.ts +0 -9
- package/src/schemas/header.ts +0 -19
- package/src/schemas/info.ts +0 -23
- package/src/schemas/license.ts +0 -11
- package/src/schemas/link.ts +0 -24
- package/src/schemas/media-type.ts +0 -21
- package/src/schemas/oauth-flow.ts +0 -13
- package/src/schemas/oauthflows.ts +0 -16
- package/src/schemas/openapi-document.ts +0 -34
- package/src/schemas/operation-without-callback.ts +0 -37
- package/src/schemas/parameter.ts +0 -26
- package/src/schemas/path-item.ts +0 -35
- package/src/schemas/paths.ts +0 -11
- package/src/schemas/reference.ts +0 -20
- package/src/schemas/request-body.ts +0 -12
- package/src/schemas/response.ts +0 -16
- package/src/schemas/responses.ts +0 -14
- package/src/schemas/schema.ts +0 -26
- package/src/schemas/security-requirement.ts +0 -16
- package/src/schemas/security-scheme.ts +0 -58
- package/src/schemas/server-variable.ts +0 -11
- package/src/schemas/server-workspace.ts +0 -36
- package/src/schemas/server.ts +0 -12
- package/src/schemas/tag.ts +0 -12
- package/src/schemas/xml.ts +0 -19
- package/src/schemas.ts +0 -6
- package/src/server.test.ts +0 -470
- package/src/server.ts +0 -341
- package/test/helpers.ts +0 -16
- package/tsconfig.build.json +0 -12
- package/tsconfig.json +0 -8
- package/vite.config.ts +0 -9
package/src/schemas.ts
DELETED
package/src/server.test.ts
DELETED
|
@@ -1,470 +0,0 @@
|
|
|
1
|
-
import { describe, expect, test } from 'vitest'
|
|
2
|
-
import {
|
|
3
|
-
createServerWorkspaceStore,
|
|
4
|
-
escapePaths,
|
|
5
|
-
externalizeComponentReferences,
|
|
6
|
-
externalizePathReferences,
|
|
7
|
-
filterHttpMethodsOnly,
|
|
8
|
-
} from './server'
|
|
9
|
-
import fs from 'node:fs/promises'
|
|
10
|
-
import { cwd } from 'node:process'
|
|
11
|
-
import { allFilesMatch } from '../test/helpers'
|
|
12
|
-
|
|
13
|
-
describe('create-server-store', () => {
|
|
14
|
-
const exampleDocument = () => ({
|
|
15
|
-
'openapi': '3.1.1',
|
|
16
|
-
'info': {
|
|
17
|
-
'title': 'Scalar Galaxy',
|
|
18
|
-
'version': '0.3.2',
|
|
19
|
-
},
|
|
20
|
-
'paths': {
|
|
21
|
-
'/planets': {
|
|
22
|
-
get: { summary: 'List planets' },
|
|
23
|
-
},
|
|
24
|
-
},
|
|
25
|
-
'components': {
|
|
26
|
-
'parameters': {
|
|
27
|
-
'planetId': {
|
|
28
|
-
'name': 'planetId',
|
|
29
|
-
'description': 'The ID of the planet to get',
|
|
30
|
-
'in': 'path',
|
|
31
|
-
'required': true,
|
|
32
|
-
'schema': {
|
|
33
|
-
'type': 'integer',
|
|
34
|
-
'format': 'int64',
|
|
35
|
-
'examples': [1],
|
|
36
|
-
},
|
|
37
|
-
},
|
|
38
|
-
},
|
|
39
|
-
},
|
|
40
|
-
})
|
|
41
|
-
|
|
42
|
-
describe('ssr', () => {
|
|
43
|
-
test('should be able to pass a list of documents and get the workspace', async () => {
|
|
44
|
-
const store = createServerWorkspaceStore({
|
|
45
|
-
mode: 'ssr',
|
|
46
|
-
baseUrl: 'https://example.com',
|
|
47
|
-
documents: [
|
|
48
|
-
{
|
|
49
|
-
name: 'api-1',
|
|
50
|
-
document: exampleDocument(),
|
|
51
|
-
},
|
|
52
|
-
{
|
|
53
|
-
name: 'api-2',
|
|
54
|
-
document: exampleDocument(),
|
|
55
|
-
},
|
|
56
|
-
],
|
|
57
|
-
meta: {
|
|
58
|
-
'x-scalar-active-document': 'api-1',
|
|
59
|
-
'x-scalar-dark-mode': true,
|
|
60
|
-
},
|
|
61
|
-
})
|
|
62
|
-
|
|
63
|
-
const workspaceDocument = (name: string) => ({
|
|
64
|
-
'openapi': '3.1.1',
|
|
65
|
-
'info': {
|
|
66
|
-
'title': 'Scalar Galaxy',
|
|
67
|
-
'version': '0.3.2',
|
|
68
|
-
},
|
|
69
|
-
'paths': {
|
|
70
|
-
'/planets': {
|
|
71
|
-
get: {
|
|
72
|
-
'$ref': `https://example.com/${name}/operations/~1planets/get#`,
|
|
73
|
-
$global: true,
|
|
74
|
-
},
|
|
75
|
-
},
|
|
76
|
-
},
|
|
77
|
-
'components': {
|
|
78
|
-
parameters: {
|
|
79
|
-
planetId: {
|
|
80
|
-
'$ref': `https://example.com/${name}/components/parameters/planetId#`,
|
|
81
|
-
$global: true,
|
|
82
|
-
},
|
|
83
|
-
},
|
|
84
|
-
},
|
|
85
|
-
})
|
|
86
|
-
|
|
87
|
-
expect(store.getWorkspace()).toEqual({
|
|
88
|
-
'x-scalar-active-document': 'api-1',
|
|
89
|
-
'x-scalar-dark-mode': true,
|
|
90
|
-
documents: {
|
|
91
|
-
'api-1': workspaceDocument('api-1'),
|
|
92
|
-
'api-2': workspaceDocument('api-2'),
|
|
93
|
-
},
|
|
94
|
-
})
|
|
95
|
-
})
|
|
96
|
-
|
|
97
|
-
test('should be able to get the document chunks', async () => {
|
|
98
|
-
const store = createServerWorkspaceStore({
|
|
99
|
-
mode: 'ssr',
|
|
100
|
-
baseUrl: 'https://example.com',
|
|
101
|
-
documents: [
|
|
102
|
-
{
|
|
103
|
-
name: 'doc-1',
|
|
104
|
-
document: exampleDocument(),
|
|
105
|
-
},
|
|
106
|
-
],
|
|
107
|
-
})
|
|
108
|
-
|
|
109
|
-
expect(store.get('#/doc-1/operations/~1planets/get')).toEqual({ summary: 'List planets' })
|
|
110
|
-
expect(store.get('#/doc-1/components/parameters/planetId')).toEqual({
|
|
111
|
-
'name': 'planetId',
|
|
112
|
-
'description': 'The ID of the planet to get',
|
|
113
|
-
'in': 'path',
|
|
114
|
-
'required': true,
|
|
115
|
-
'schema': {
|
|
116
|
-
'type': 'integer',
|
|
117
|
-
'format': 'int64',
|
|
118
|
-
'examples': [1],
|
|
119
|
-
},
|
|
120
|
-
})
|
|
121
|
-
})
|
|
122
|
-
|
|
123
|
-
test('should be able to add more documents on the workspace', async () => {
|
|
124
|
-
const store = createServerWorkspaceStore({
|
|
125
|
-
mode: 'ssr',
|
|
126
|
-
baseUrl: 'https://example.com',
|
|
127
|
-
documents: [
|
|
128
|
-
{
|
|
129
|
-
name: 'doc-1',
|
|
130
|
-
document: exampleDocument(),
|
|
131
|
-
meta: {
|
|
132
|
-
'x-scalar-active-auth': 'test',
|
|
133
|
-
},
|
|
134
|
-
},
|
|
135
|
-
{
|
|
136
|
-
name: 'doc-2',
|
|
137
|
-
document: exampleDocument(),
|
|
138
|
-
},
|
|
139
|
-
],
|
|
140
|
-
})
|
|
141
|
-
|
|
142
|
-
store.addDocument(exampleDocument(), { name: 'doc-3', 'x-scalar-active-auth': 'test' })
|
|
143
|
-
const workspace = store.getWorkspace()
|
|
144
|
-
|
|
145
|
-
expect(workspace.documents['doc-1']).toEqual({
|
|
146
|
-
'openapi': '3.1.1',
|
|
147
|
-
'info': {
|
|
148
|
-
'title': 'Scalar Galaxy',
|
|
149
|
-
'version': '0.3.2',
|
|
150
|
-
},
|
|
151
|
-
'paths': {
|
|
152
|
-
'/planets': {
|
|
153
|
-
get: { '$ref': 'https://example.com/doc-1/operations/~1planets/get#', $global: true },
|
|
154
|
-
},
|
|
155
|
-
},
|
|
156
|
-
'components': {
|
|
157
|
-
'parameters': {
|
|
158
|
-
planetId: {
|
|
159
|
-
'$ref': 'https://example.com/doc-1/components/parameters/planetId#',
|
|
160
|
-
$global: true,
|
|
161
|
-
},
|
|
162
|
-
},
|
|
163
|
-
},
|
|
164
|
-
'x-scalar-active-auth': 'test',
|
|
165
|
-
})
|
|
166
|
-
|
|
167
|
-
expect(workspace.documents['doc-3']).toEqual({
|
|
168
|
-
'openapi': '3.1.1',
|
|
169
|
-
'info': {
|
|
170
|
-
'title': 'Scalar Galaxy',
|
|
171
|
-
'version': '0.3.2',
|
|
172
|
-
},
|
|
173
|
-
'paths': {
|
|
174
|
-
'/planets': {
|
|
175
|
-
get: { '$ref': 'https://example.com/doc-3/operations/~1planets/get#', $global: true },
|
|
176
|
-
},
|
|
177
|
-
},
|
|
178
|
-
'components': {
|
|
179
|
-
'parameters': {
|
|
180
|
-
planetId: {
|
|
181
|
-
'$ref': 'https://example.com/doc-3/components/parameters/planetId#',
|
|
182
|
-
$global: true,
|
|
183
|
-
},
|
|
184
|
-
},
|
|
185
|
-
},
|
|
186
|
-
'x-scalar-active-auth': 'test',
|
|
187
|
-
})
|
|
188
|
-
})
|
|
189
|
-
})
|
|
190
|
-
|
|
191
|
-
describe('ssg', () => {
|
|
192
|
-
test('should generate the workspace file and also all the related chunks', async () => {
|
|
193
|
-
const dir = 'temp'
|
|
194
|
-
|
|
195
|
-
const store = createServerWorkspaceStore({
|
|
196
|
-
mode: 'static',
|
|
197
|
-
directory: dir,
|
|
198
|
-
documents: [
|
|
199
|
-
{
|
|
200
|
-
document: exampleDocument(),
|
|
201
|
-
name: 'doc-1',
|
|
202
|
-
meta: {
|
|
203
|
-
'x-scalar-active-auth': 'test',
|
|
204
|
-
'x-scalar-active-server': 'test',
|
|
205
|
-
},
|
|
206
|
-
},
|
|
207
|
-
],
|
|
208
|
-
meta: {
|
|
209
|
-
'x-scalar-active-document': 'test',
|
|
210
|
-
'x-scalar-dark-mode': true,
|
|
211
|
-
'x-scalar-default-client': 'node',
|
|
212
|
-
'x-scalar-theme': 'default',
|
|
213
|
-
},
|
|
214
|
-
})
|
|
215
|
-
|
|
216
|
-
store.addDocument(exampleDocument(), {
|
|
217
|
-
name: 'doc-2',
|
|
218
|
-
'x-scalar-active-auth': 'test',
|
|
219
|
-
'x-scalar-active-server': 'test',
|
|
220
|
-
})
|
|
221
|
-
await store.generateWorkspaceChunks()
|
|
222
|
-
|
|
223
|
-
const basePath = `${cwd()}/${dir}`
|
|
224
|
-
|
|
225
|
-
// check the workspace is the correct format
|
|
226
|
-
expect(JSON.parse(await fs.readFile(`${basePath}/scalar-workspace.json`, { encoding: 'utf-8' }))).toEqual({
|
|
227
|
-
documents: {
|
|
228
|
-
'doc-1': {
|
|
229
|
-
'x-scalar-active-auth': 'test',
|
|
230
|
-
'x-scalar-active-server': 'test',
|
|
231
|
-
'openapi': '3.1.1',
|
|
232
|
-
'info': {
|
|
233
|
-
'title': 'Scalar Galaxy',
|
|
234
|
-
'version': '0.3.2',
|
|
235
|
-
},
|
|
236
|
-
'paths': {
|
|
237
|
-
'/planets': {
|
|
238
|
-
get: { '$ref': 'temp/chunks/doc-1/operations/~1planets/get.json#', $global: true },
|
|
239
|
-
},
|
|
240
|
-
},
|
|
241
|
-
'components': {
|
|
242
|
-
'parameters': {
|
|
243
|
-
planetId: { '$ref': 'temp/chunks/doc-1/components/parameters/planetId.json#', $global: true },
|
|
244
|
-
},
|
|
245
|
-
},
|
|
246
|
-
},
|
|
247
|
-
'doc-2': {
|
|
248
|
-
'x-scalar-active-auth': 'test',
|
|
249
|
-
'x-scalar-active-server': 'test',
|
|
250
|
-
'openapi': '3.1.1',
|
|
251
|
-
'info': {
|
|
252
|
-
'title': 'Scalar Galaxy',
|
|
253
|
-
'version': '0.3.2',
|
|
254
|
-
},
|
|
255
|
-
'paths': {
|
|
256
|
-
'/planets': {
|
|
257
|
-
get: { '$ref': 'temp/chunks/doc-2/operations/~1planets/get.json#', $global: true },
|
|
258
|
-
},
|
|
259
|
-
},
|
|
260
|
-
'components': {
|
|
261
|
-
'parameters': {
|
|
262
|
-
planetId: { '$ref': 'temp/chunks/doc-2/components/parameters/planetId.json#', $global: true },
|
|
263
|
-
},
|
|
264
|
-
},
|
|
265
|
-
},
|
|
266
|
-
},
|
|
267
|
-
'x-scalar-active-document': 'test',
|
|
268
|
-
'x-scalar-dark-mode': true,
|
|
269
|
-
'x-scalar-default-client': 'node',
|
|
270
|
-
'x-scalar-theme': 'default',
|
|
271
|
-
})
|
|
272
|
-
|
|
273
|
-
// check the generated chucks
|
|
274
|
-
expect(
|
|
275
|
-
await allFilesMatch([
|
|
276
|
-
{
|
|
277
|
-
content: JSON.stringify({
|
|
278
|
-
...exampleDocument().components.parameters.planetId,
|
|
279
|
-
}),
|
|
280
|
-
path: `${basePath}/chunks/doc-1/components/parameters/planetId.json`,
|
|
281
|
-
},
|
|
282
|
-
{
|
|
283
|
-
content: JSON.stringify({
|
|
284
|
-
...exampleDocument().paths['/planets'].get,
|
|
285
|
-
}),
|
|
286
|
-
path: `${basePath}/chunks/doc-1/operations/~1planets/get.json`,
|
|
287
|
-
},
|
|
288
|
-
]),
|
|
289
|
-
).toBe(true)
|
|
290
|
-
|
|
291
|
-
// clean up generated files
|
|
292
|
-
await fs.rmdir(basePath, { recursive: true })
|
|
293
|
-
})
|
|
294
|
-
})
|
|
295
|
-
})
|
|
296
|
-
|
|
297
|
-
describe('filter-http-methods-only', () => {
|
|
298
|
-
test('should only keep the http methods', () => {
|
|
299
|
-
const result = filterHttpMethodsOnly({
|
|
300
|
-
'/path': {
|
|
301
|
-
get: { description: 'some description' },
|
|
302
|
-
'x-scalar-test': 'test',
|
|
303
|
-
servers: [],
|
|
304
|
-
parameters: [{ name: 'name', in: 'path' }],
|
|
305
|
-
},
|
|
306
|
-
})
|
|
307
|
-
|
|
308
|
-
// check that all the other keys are filtered
|
|
309
|
-
expect(Object.keys(result['/path'] ?? {})).toEqual(['get'])
|
|
310
|
-
|
|
311
|
-
// check the contents of the operation
|
|
312
|
-
expect(result['/path']?.get).toEqual({ description: 'some description' })
|
|
313
|
-
})
|
|
314
|
-
})
|
|
315
|
-
|
|
316
|
-
describe('escape-paths', () => {
|
|
317
|
-
test('should correctly escape / paths', () => {
|
|
318
|
-
const result = escapePaths({ '/hello/users': { get: { description: 'some description' } } })
|
|
319
|
-
expect(Object.keys(result)).toEqual(['~1hello~1users'])
|
|
320
|
-
expect(result['~1hello~1users']).toEqual({ get: { description: 'some description' } })
|
|
321
|
-
})
|
|
322
|
-
|
|
323
|
-
test('should correctly escape ~ paths', () => {
|
|
324
|
-
const result = escapePaths({ '/hello~world/users': { get: { description: 'some description' } } })
|
|
325
|
-
expect(Object.keys(result)).toEqual(['~1hello~0world~1users'])
|
|
326
|
-
|
|
327
|
-
expect(result['~1hello~0world~1users']).toEqual({ get: { description: 'some description' } })
|
|
328
|
-
})
|
|
329
|
-
})
|
|
330
|
-
|
|
331
|
-
describe('externalize-component-references', () => {
|
|
332
|
-
test('should convert the components with refs correctly for ssr mode', () => {
|
|
333
|
-
const result = externalizeComponentReferences(
|
|
334
|
-
{
|
|
335
|
-
components: {
|
|
336
|
-
schemas: {
|
|
337
|
-
'User': {
|
|
338
|
-
'type': 'object',
|
|
339
|
-
'required': ['id', 'name', 'email'],
|
|
340
|
-
'properties': {
|
|
341
|
-
'id': {
|
|
342
|
-
'type': 'string',
|
|
343
|
-
'format': 'uuid',
|
|
344
|
-
'example': '123e4567-e89b-12d3-a456-426614174000',
|
|
345
|
-
},
|
|
346
|
-
},
|
|
347
|
-
},
|
|
348
|
-
},
|
|
349
|
-
},
|
|
350
|
-
},
|
|
351
|
-
{
|
|
352
|
-
mode: 'ssr',
|
|
353
|
-
name: 'name',
|
|
354
|
-
baseUrl: 'https://example.com',
|
|
355
|
-
},
|
|
356
|
-
)
|
|
357
|
-
|
|
358
|
-
expect(result).toEqual({
|
|
359
|
-
schemas: { User: { '$ref': 'https://example.com/name/components/schemas/User#', $global: true } },
|
|
360
|
-
})
|
|
361
|
-
})
|
|
362
|
-
|
|
363
|
-
test('should convert the components with refs correctly for ssg mode', () => {
|
|
364
|
-
const result = externalizeComponentReferences(
|
|
365
|
-
{
|
|
366
|
-
components: {
|
|
367
|
-
schemas: {
|
|
368
|
-
'User': {
|
|
369
|
-
'type': 'object',
|
|
370
|
-
'required': ['id', 'name', 'email'],
|
|
371
|
-
'properties': {
|
|
372
|
-
'id': {
|
|
373
|
-
'type': 'string',
|
|
374
|
-
'format': 'uuid',
|
|
375
|
-
'example': '123e4567-e89b-12d3-a456-426614174000',
|
|
376
|
-
},
|
|
377
|
-
},
|
|
378
|
-
},
|
|
379
|
-
},
|
|
380
|
-
},
|
|
381
|
-
},
|
|
382
|
-
{
|
|
383
|
-
mode: 'static',
|
|
384
|
-
name: 'name',
|
|
385
|
-
directory: 'assets',
|
|
386
|
-
},
|
|
387
|
-
)
|
|
388
|
-
|
|
389
|
-
expect(result).toEqual({
|
|
390
|
-
schemas: { User: { '$ref': 'assets/chunks/name/components/schemas/User.json#', $global: true } },
|
|
391
|
-
})
|
|
392
|
-
})
|
|
393
|
-
})
|
|
394
|
-
|
|
395
|
-
describe('externalize-path-references', () => {
|
|
396
|
-
test('should correctly replace the contents with a ref for ssr mode', () => {
|
|
397
|
-
const result = externalizePathReferences(
|
|
398
|
-
{
|
|
399
|
-
paths: {
|
|
400
|
-
'/test': {
|
|
401
|
-
get: {
|
|
402
|
-
description: 'string',
|
|
403
|
-
},
|
|
404
|
-
},
|
|
405
|
-
},
|
|
406
|
-
},
|
|
407
|
-
{
|
|
408
|
-
mode: 'ssr',
|
|
409
|
-
baseUrl: 'https://example.com',
|
|
410
|
-
name: 'name',
|
|
411
|
-
},
|
|
412
|
-
)
|
|
413
|
-
|
|
414
|
-
expect(result).toEqual({
|
|
415
|
-
'/test': { get: { '$ref': 'https://example.com/name/operations/~1test/get#', $global: true } },
|
|
416
|
-
})
|
|
417
|
-
})
|
|
418
|
-
|
|
419
|
-
test('should replace the http methods with the reference while preserving other properties', () => {
|
|
420
|
-
const result = externalizePathReferences(
|
|
421
|
-
{
|
|
422
|
-
paths: {
|
|
423
|
-
'/test': {
|
|
424
|
-
get: {
|
|
425
|
-
description: 'string',
|
|
426
|
-
},
|
|
427
|
-
otherProperty: {
|
|
428
|
-
description: 'I should still be in the output',
|
|
429
|
-
},
|
|
430
|
-
},
|
|
431
|
-
},
|
|
432
|
-
},
|
|
433
|
-
{
|
|
434
|
-
mode: 'ssr',
|
|
435
|
-
baseUrl: 'https://example.com',
|
|
436
|
-
name: 'name',
|
|
437
|
-
},
|
|
438
|
-
)
|
|
439
|
-
|
|
440
|
-
expect(result).toEqual({
|
|
441
|
-
'/test': {
|
|
442
|
-
get: { '$ref': 'https://example.com/name/operations/~1test/get#', $global: true },
|
|
443
|
-
otherProperty: { description: 'I should still be in the output' },
|
|
444
|
-
},
|
|
445
|
-
})
|
|
446
|
-
})
|
|
447
|
-
|
|
448
|
-
test('should correctly replace the contents with a ref for ssg mode', () => {
|
|
449
|
-
const result = externalizePathReferences(
|
|
450
|
-
{
|
|
451
|
-
paths: {
|
|
452
|
-
'/test': {
|
|
453
|
-
get: {
|
|
454
|
-
description: 'string',
|
|
455
|
-
},
|
|
456
|
-
},
|
|
457
|
-
},
|
|
458
|
-
},
|
|
459
|
-
{
|
|
460
|
-
mode: 'static',
|
|
461
|
-
directory: 'assets',
|
|
462
|
-
name: 'name',
|
|
463
|
-
},
|
|
464
|
-
)
|
|
465
|
-
|
|
466
|
-
expect(result).toEqual({
|
|
467
|
-
'/test': { get: { '$ref': 'assets/chunks/name/operations/~1test/get.json#', $global: true } },
|
|
468
|
-
})
|
|
469
|
-
})
|
|
470
|
-
})
|