@scalar/mock-server 0.9.8 → 0.9.10
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 +17 -0
- package/dist/create-mock-server.js +79 -68
- package/dist/index.js +1 -5
- package/dist/libs/store.js +66 -65
- package/dist/routes/mock-any-response.js +70 -63
- package/dist/routes/mock-handler-response.js +140 -100
- package/dist/routes/respond-with-authorize-page.js +89 -80
- package/dist/routes/respond-with-openapi-document.js +32 -35
- package/dist/routes/respond-with-token.js +40 -45
- package/dist/types.js +2 -5
- package/dist/utils/build-handler-context.js +83 -70
- package/dist/utils/build-seed-context.js +59 -52
- package/dist/utils/create-openapi-definition.js +7 -10
- package/dist/utils/execute-handler.js +16 -18
- package/dist/utils/execute-seed.js +22 -21
- package/dist/utils/find-preferred-response-key.js +9 -9
- package/dist/utils/get-open-auth-token-urls.js +45 -35
- package/dist/utils/get-operation.js +12 -12
- package/dist/utils/handle-authentication.js +106 -101
- package/dist/utils/hono-route-from-path.js +6 -6
- package/dist/utils/is-authentication-required.js +17 -15
- package/dist/utils/log-authentication-instructions.js +105 -110
- package/dist/utils/process-openapi-document.js +71 -58
- package/dist/utils/set-up-authentication-routes.js +80 -77
- package/dist/utils/store-wrapper.js +40 -39
- package/package.json +10 -14
- package/dist/create-mock-server.js.map +0 -7
- package/dist/index.js.map +0 -7
- package/dist/libs/store.js.map +0 -7
- package/dist/routes/mock-any-response.js.map +0 -7
- package/dist/routes/mock-handler-response.js.map +0 -7
- package/dist/routes/respond-with-authorize-page.js.map +0 -7
- package/dist/routes/respond-with-openapi-document.js.map +0 -7
- package/dist/routes/respond-with-token.js.map +0 -7
- package/dist/types.js.map +0 -7
- package/dist/utils/build-handler-context.js.map +0 -7
- package/dist/utils/build-seed-context.js.map +0 -7
- package/dist/utils/create-openapi-definition.js.map +0 -7
- package/dist/utils/execute-handler.js.map +0 -7
- package/dist/utils/execute-seed.js.map +0 -7
- package/dist/utils/find-preferred-response-key.js.map +0 -7
- package/dist/utils/get-open-auth-token-urls.js.map +0 -7
- package/dist/utils/get-operation.js.map +0 -7
- package/dist/utils/handle-authentication.js.map +0 -7
- package/dist/utils/hono-route-from-path.js.map +0 -7
- package/dist/utils/is-authentication-required.js.map +0 -7
- package/dist/utils/log-authentication-instructions.js.map +0 -7
- package/dist/utils/process-openapi-document.js.map +0 -7
- package/dist/utils/set-up-authentication-routes.js.map +0 -7
- package/dist/utils/store-wrapper.js.map +0 -7
|
@@ -1,75 +1,88 @@
|
|
|
1
|
-
import { faker } from
|
|
2
|
-
import { getExampleFromSchema } from
|
|
3
|
-
import { accepts } from
|
|
4
|
-
import { store } from
|
|
5
|
-
import { createStoreWrapper } from
|
|
1
|
+
import { faker } from '@faker-js/faker';
|
|
2
|
+
import { getExampleFromSchema } from '@scalar/oas-utils/spec-getters';
|
|
3
|
+
import { accepts } from 'hono/accepts';
|
|
4
|
+
import { store } from '../libs/store.js';
|
|
5
|
+
import { createStoreWrapper } from './store-wrapper.js';
|
|
6
|
+
/**
|
|
7
|
+
* Get example response from OpenAPI spec for a given status code.
|
|
8
|
+
* Returns the example value if found, or null if not available.
|
|
9
|
+
*/
|
|
6
10
|
function getExampleFromResponse(c, statusCode, responses) {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
11
|
+
if (!responses) {
|
|
12
|
+
return null;
|
|
13
|
+
}
|
|
14
|
+
const response = responses[statusCode] || responses.default;
|
|
15
|
+
if (!response) {
|
|
16
|
+
return null;
|
|
17
|
+
}
|
|
18
|
+
const supportedContentTypes = Object.keys(response.content ?? {});
|
|
19
|
+
// If no content types are defined, return null
|
|
20
|
+
if (supportedContentTypes.length === 0) {
|
|
21
|
+
return null;
|
|
22
|
+
}
|
|
23
|
+
// Content-Type negotiation - prefer application/json
|
|
24
|
+
const acceptedContentType = accepts(c, {
|
|
25
|
+
header: 'Accept',
|
|
26
|
+
supports: supportedContentTypes,
|
|
27
|
+
default: supportedContentTypes.includes('application/json')
|
|
28
|
+
? 'application/json'
|
|
29
|
+
: (supportedContentTypes[0] ?? 'text/plain;charset=UTF-8'),
|
|
30
|
+
});
|
|
31
|
+
const acceptedResponse = response.content?.[acceptedContentType];
|
|
32
|
+
if (!acceptedResponse) {
|
|
33
|
+
return null;
|
|
34
|
+
}
|
|
35
|
+
// Extract example from example property or generate from schema
|
|
36
|
+
return acceptedResponse.example !== undefined
|
|
37
|
+
? acceptedResponse.example
|
|
38
|
+
: acceptedResponse.schema
|
|
39
|
+
? getExampleFromSchema(acceptedResponse.schema, {
|
|
40
|
+
emptyString: 'string',
|
|
41
|
+
variables: c.req.param(),
|
|
42
|
+
mode: 'read',
|
|
43
|
+
})
|
|
44
|
+
: null;
|
|
32
45
|
}
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
46
|
+
/**
|
|
47
|
+
* Build the handler context from a Hono context.
|
|
48
|
+
*/
|
|
49
|
+
export async function buildHandlerContext(c, operation) {
|
|
50
|
+
let body = undefined;
|
|
51
|
+
try {
|
|
52
|
+
const contentType = c.req.header('content-type') ?? '';
|
|
53
|
+
if (contentType.includes('application/json')) {
|
|
54
|
+
body = await c.req.json().catch(() => undefined);
|
|
55
|
+
}
|
|
56
|
+
else if (contentType.includes('application/x-www-form-urlencoded')) {
|
|
57
|
+
body = await c.req.parseBody().catch(() => undefined);
|
|
58
|
+
}
|
|
59
|
+
else if (contentType.includes('text/')) {
|
|
60
|
+
body = await c.req.text().catch(() => undefined);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
catch {
|
|
64
|
+
// Ignore parsing errors, body remains undefined
|
|
43
65
|
}
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
c,
|
|
52
|
-
statusCode,
|
|
53
|
-
operation.responses
|
|
54
|
-
);
|
|
66
|
+
const { wrappedStore, tracking } = createStoreWrapper(store);
|
|
67
|
+
// Build res object with examples for all response status codes
|
|
68
|
+
const res = {};
|
|
69
|
+
if (operation?.responses) {
|
|
70
|
+
for (const statusCode of Object.keys(operation.responses)) {
|
|
71
|
+
res[statusCode] = getExampleFromResponse(c, statusCode, operation.responses);
|
|
72
|
+
}
|
|
55
73
|
}
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
};
|
|
74
|
+
return {
|
|
75
|
+
context: {
|
|
76
|
+
store: wrappedStore,
|
|
77
|
+
faker,
|
|
78
|
+
req: {
|
|
79
|
+
body,
|
|
80
|
+
params: c.req.param(),
|
|
81
|
+
query: Object.fromEntries(new URL(c.req.url).searchParams.entries()),
|
|
82
|
+
headers: Object.fromEntries(Object.entries(c.req.header()).map(([key, value]) => [key, value ?? ''])),
|
|
83
|
+
},
|
|
84
|
+
res,
|
|
85
|
+
},
|
|
86
|
+
tracking,
|
|
87
|
+
};
|
|
71
88
|
}
|
|
72
|
-
export {
|
|
73
|
-
buildHandlerContext
|
|
74
|
-
};
|
|
75
|
-
//# sourceMappingURL=build-handler-context.js.map
|
|
@@ -1,53 +1,60 @@
|
|
|
1
|
-
import { faker } from
|
|
2
|
-
import { store } from
|
|
3
|
-
import { createStoreWrapper } from
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
1
|
+
import { faker } from '@faker-js/faker';
|
|
2
|
+
import { store } from '../libs/store.js';
|
|
3
|
+
import { createStoreWrapper } from './store-wrapper.js';
|
|
4
|
+
/**
|
|
5
|
+
* Build the seed context with a seed helper function.
|
|
6
|
+
* The seed helper automatically uses the schema key as the collection name.
|
|
7
|
+
*/
|
|
8
|
+
export function buildSeedContext(schemaKey) {
|
|
9
|
+
const { wrappedStore } = createStoreWrapper(store);
|
|
10
|
+
/**
|
|
11
|
+
* Seed helper function that provides a Laravel-inspired API.
|
|
12
|
+
*/
|
|
13
|
+
const seedHelper = ((arg1, arg2) => {
|
|
14
|
+
// Case 1: seed.count(n, factory)
|
|
15
|
+
if (typeof arg1 === 'number' && typeof arg2 === 'function') {
|
|
16
|
+
const count = arg1;
|
|
17
|
+
const factory = arg2;
|
|
18
|
+
const items = [];
|
|
19
|
+
for (let i = 0; i < count; i++) {
|
|
20
|
+
const item = factory();
|
|
21
|
+
const created = wrappedStore.create(schemaKey, item);
|
|
22
|
+
items.push(created);
|
|
23
|
+
}
|
|
24
|
+
return items;
|
|
25
|
+
}
|
|
26
|
+
// Case 2: seed(array)
|
|
27
|
+
if (Array.isArray(arg1)) {
|
|
28
|
+
const items = [];
|
|
29
|
+
for (const item of arg1) {
|
|
30
|
+
const created = wrappedStore.create(schemaKey, item);
|
|
31
|
+
items.push(created);
|
|
32
|
+
}
|
|
33
|
+
return items;
|
|
34
|
+
}
|
|
35
|
+
// Case 3: seed(factory) - single item
|
|
36
|
+
if (typeof arg1 === 'function') {
|
|
37
|
+
const factory = arg1;
|
|
38
|
+
const item = factory();
|
|
39
|
+
const created = wrappedStore.create(schemaKey, item);
|
|
40
|
+
return created;
|
|
41
|
+
}
|
|
42
|
+
throw new Error('Invalid seed() usage. Use seed.count(n, factory), seed(array), or seed(factory)');
|
|
43
|
+
});
|
|
44
|
+
// Add count method to the function
|
|
45
|
+
seedHelper.count = (n, factory) => {
|
|
46
|
+
const items = [];
|
|
47
|
+
for (let i = 0; i < n; i++) {
|
|
48
|
+
const item = factory();
|
|
49
|
+
const created = wrappedStore.create(schemaKey, item);
|
|
50
|
+
items.push(created);
|
|
51
|
+
}
|
|
52
|
+
return items;
|
|
53
|
+
};
|
|
54
|
+
return {
|
|
55
|
+
store: wrappedStore,
|
|
56
|
+
faker,
|
|
57
|
+
seed: seedHelper,
|
|
58
|
+
schema: schemaKey,
|
|
59
|
+
};
|
|
49
60
|
}
|
|
50
|
-
export {
|
|
51
|
-
buildSeedContext
|
|
52
|
-
};
|
|
53
|
-
//# sourceMappingURL=build-seed-context.js.map
|
|
@@ -1,11 +1,8 @@
|
|
|
1
|
-
function
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
1
|
+
/** Helper function create an OpenAPI document with security schemss */
|
|
2
|
+
export function createOpenApiDefinition(securitySchemes) {
|
|
3
|
+
return {
|
|
4
|
+
openapi: '3.1.1',
|
|
5
|
+
info: { title: 'Test API', version: '1.0.0' },
|
|
6
|
+
components: { securitySchemes },
|
|
7
|
+
};
|
|
7
8
|
}
|
|
8
|
-
export {
|
|
9
|
-
createOpenApiDefinition
|
|
10
|
-
};
|
|
11
|
-
//# sourceMappingURL=create-openapi-definition.js.map
|
|
@@ -1,20 +1,18 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Execute handler code in a sandboxed environment.
|
|
3
|
+
* The code has access only to the provided context (store, faker, req, res).
|
|
4
|
+
*/
|
|
5
|
+
export async function executeHandler(code, context) {
|
|
6
|
+
// Create a function that executes the handler code with the context
|
|
7
|
+
// Using Function constructor to create a sandboxed environment
|
|
8
|
+
// The code is wrapped in a function body that returns the result
|
|
9
|
+
const handlerFunction = new Function('store', 'faker', 'req', 'res', `
|
|
8
10
|
${code}
|
|
9
|
-
`
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
11
|
+
`);
|
|
12
|
+
const result = handlerFunction(context.store, context.faker, context.req, context.res);
|
|
13
|
+
// If the result is a Promise, await it
|
|
14
|
+
if (result instanceof Promise) {
|
|
15
|
+
return { result: await result };
|
|
16
|
+
}
|
|
17
|
+
return { result };
|
|
16
18
|
}
|
|
17
|
-
export {
|
|
18
|
-
executeHandler
|
|
19
|
-
};
|
|
20
|
-
//# sourceMappingURL=execute-handler.js.map
|
|
@@ -1,24 +1,25 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Execute seed code in a sandboxed environment.
|
|
3
|
+
* The code has access only to the provided context (store, faker, seed, schema).
|
|
4
|
+
*/
|
|
5
|
+
export async function executeSeed(code, context) {
|
|
6
|
+
// Create a function that executes the seed code with the context
|
|
7
|
+
// Using Function constructor to create a sandboxed environment
|
|
8
|
+
// The code is wrapped in a function body that returns the result
|
|
9
|
+
const seedFunction = new Function('store', 'faker', 'seed', 'schema', `
|
|
8
10
|
${code}
|
|
9
|
-
`
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
11
|
+
`);
|
|
12
|
+
// Execute the seed function with the context
|
|
13
|
+
try {
|
|
14
|
+
const result = seedFunction(context.store, context.faker, context.seed, context.schema);
|
|
15
|
+
// If the result is a Promise, await it
|
|
16
|
+
if (result instanceof Promise) {
|
|
17
|
+
return { result: await result };
|
|
18
|
+
}
|
|
19
|
+
return { result };
|
|
20
|
+
}
|
|
21
|
+
catch (error) {
|
|
22
|
+
// Re-throw to be caught by the caller
|
|
23
|
+
throw error;
|
|
15
24
|
}
|
|
16
|
-
return { result };
|
|
17
|
-
} catch (error) {
|
|
18
|
-
throw error;
|
|
19
|
-
}
|
|
20
25
|
}
|
|
21
|
-
export {
|
|
22
|
-
executeSeed
|
|
23
|
-
};
|
|
24
|
-
//# sourceMappingURL=execute-seed.js.map
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Find the preferred response key: default, 200, 201 …
|
|
3
|
+
*/
|
|
4
|
+
export function findPreferredResponseKey(responses) {
|
|
5
|
+
return (
|
|
3
6
|
// Regular status codes
|
|
4
|
-
[
|
|
5
|
-
|
|
6
|
-
|
|
7
|
+
['default', '200', '201', '204', '404', '500'].find((key) => responses?.includes(key) ?? false) ??
|
|
8
|
+
// Lowest status code
|
|
9
|
+
responses?.sort()[0] ??
|
|
10
|
+
undefined);
|
|
7
11
|
}
|
|
8
|
-
export {
|
|
9
|
-
findPreferredResponseKey
|
|
10
|
-
};
|
|
11
|
-
//# sourceMappingURL=find-preferred-response-key.js.map
|
|
@@ -1,42 +1,52 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Extract path from URL
|
|
3
|
+
*/
|
|
4
|
+
export function getPathFromUrl(url) {
|
|
5
|
+
try {
|
|
6
|
+
// Handle relative URLs by prepending a base
|
|
7
|
+
const urlObject = url.startsWith('http') ? new URL(url) : new URL(url, 'http://example.com');
|
|
8
|
+
// Normalize: remove trailing slash except for root path
|
|
9
|
+
const path = urlObject.pathname;
|
|
10
|
+
return path === '/' ? path : path.replace(/\/$/, '');
|
|
11
|
+
}
|
|
12
|
+
catch {
|
|
13
|
+
// If URL is invalid, return the original string
|
|
14
|
+
return url;
|
|
15
|
+
}
|
|
9
16
|
}
|
|
17
|
+
/**
|
|
18
|
+
* Returns all token URLs mentioned in the securitySchemes, without the domain
|
|
19
|
+
*/
|
|
20
|
+
// Type guard for OAuth2 security scheme
|
|
10
21
|
function isOAuth2Scheme(scheme) {
|
|
11
|
-
|
|
22
|
+
return scheme.type === 'oauth2';
|
|
12
23
|
}
|
|
24
|
+
// Validate token URL
|
|
13
25
|
function isValidTokenUrl(url) {
|
|
14
|
-
|
|
26
|
+
return url.trim().length > 0;
|
|
15
27
|
}
|
|
16
|
-
function getOpenAuthTokenUrls(schema) {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
28
|
+
export function getOpenAuthTokenUrls(schema) {
|
|
29
|
+
if (!schema?.components?.securitySchemes) {
|
|
30
|
+
return [];
|
|
31
|
+
}
|
|
32
|
+
const securitySchemes = schema.components.securitySchemes;
|
|
33
|
+
// Use Set from the start for better memory efficiency
|
|
34
|
+
const tokenUrls = new Set();
|
|
35
|
+
// Iterate through all security schemes
|
|
36
|
+
for (const scheme of Object.values(securitySchemes)) {
|
|
37
|
+
if (!isOAuth2Scheme(scheme)) {
|
|
38
|
+
continue;
|
|
39
|
+
}
|
|
40
|
+
const flows = scheme.flows; // Type assertion no longer needed
|
|
41
|
+
// Helper to safely add valid token URLs
|
|
42
|
+
const addTokenUrl = (url) => {
|
|
43
|
+
if (url && isValidTokenUrl(url)) {
|
|
44
|
+
tokenUrls.add(getPathFromUrl(url));
|
|
45
|
+
}
|
|
46
|
+
};
|
|
47
|
+
addTokenUrl(flows?.password?.tokenUrl);
|
|
48
|
+
addTokenUrl(flows?.clientCredentials?.tokenUrl);
|
|
49
|
+
addTokenUrl(flows?.authorizationCode?.tokenUrl);
|
|
25
50
|
}
|
|
26
|
-
|
|
27
|
-
const addTokenUrl = (url) => {
|
|
28
|
-
if (url && isValidTokenUrl(url)) {
|
|
29
|
-
tokenUrls.add(getPathFromUrl(url));
|
|
30
|
-
}
|
|
31
|
-
};
|
|
32
|
-
addTokenUrl(flows?.password?.tokenUrl);
|
|
33
|
-
addTokenUrl(flows?.clientCredentials?.tokenUrl);
|
|
34
|
-
addTokenUrl(flows?.authorizationCode?.tokenUrl);
|
|
35
|
-
}
|
|
36
|
-
return Array.from(tokenUrls);
|
|
51
|
+
return Array.from(tokenUrls);
|
|
37
52
|
}
|
|
38
|
-
export {
|
|
39
|
-
getOpenAuthTokenUrls,
|
|
40
|
-
getPathFromUrl
|
|
41
|
-
};
|
|
42
|
-
//# sourceMappingURL=get-open-auth-token-urls.js.map
|
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
import { httpMethods } from
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
1
|
+
import { httpMethods } from '../types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Takes a dereferenced OpenAPI document and returns all operations.
|
|
4
|
+
* Ignores other attributes, like summary, parameters, etc.
|
|
5
|
+
*/
|
|
6
|
+
export function getOperations(path) {
|
|
7
|
+
const operations = {};
|
|
8
|
+
for (const method of httpMethods) {
|
|
9
|
+
if (path?.[method]) {
|
|
10
|
+
operations[method] = path?.[method];
|
|
11
|
+
}
|
|
7
12
|
}
|
|
8
|
-
|
|
9
|
-
return operations;
|
|
13
|
+
return operations;
|
|
10
14
|
}
|
|
11
|
-
export {
|
|
12
|
-
getOperations
|
|
13
|
-
};
|
|
14
|
-
//# sourceMappingURL=get-operation.js.map
|