@schmock/cli 2.0.0 → 2.0.1
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/dist/bin.js +92 -58
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +20 -3
- package/dist/index.js +92 -58
- package/package.json +1 -1
package/dist/bin.js
CHANGED
|
@@ -17926,7 +17926,7 @@ function extractQuery(url) {
|
|
|
17926
17926
|
}
|
|
17927
17927
|
function extractHeaders(input, init) {
|
|
17928
17928
|
const headers = {};
|
|
17929
|
-
const raw = input instanceof Request ? input.headers :
|
|
17929
|
+
const raw = init?.headers ?? (input instanceof Request ? input.headers : undefined);
|
|
17930
17930
|
if (!raw)
|
|
17931
17931
|
return headers;
|
|
17932
17932
|
if (raw instanceof Headers) {
|
|
@@ -17935,18 +17935,19 @@ function extractHeaders(input, init) {
|
|
|
17935
17935
|
});
|
|
17936
17936
|
} else if (Array.isArray(raw)) {
|
|
17937
17937
|
for (const [key, value] of raw) {
|
|
17938
|
-
headers[key] = value;
|
|
17938
|
+
headers[key.toLowerCase()] = value;
|
|
17939
17939
|
}
|
|
17940
17940
|
} else {
|
|
17941
|
-
Object.
|
|
17941
|
+
for (const key of Object.keys(raw)) {
|
|
17942
|
+
headers[key.toLowerCase()] = raw[key];
|
|
17943
|
+
}
|
|
17942
17944
|
}
|
|
17943
17945
|
return headers;
|
|
17944
17946
|
}
|
|
17945
17947
|
async function extractBody(input, init) {
|
|
17946
|
-
const
|
|
17947
|
-
if (
|
|
17948
|
+
const bodyInit = init?.body ?? (input instanceof Request ? input.body : null);
|
|
17949
|
+
if (bodyInit === null || bodyInit === undefined)
|
|
17948
17950
|
return;
|
|
17949
|
-
const bodyInit = init?.body;
|
|
17950
17951
|
if (typeof bodyInit === "string") {
|
|
17951
17952
|
try {
|
|
17952
17953
|
return JSON.parse(bodyInit);
|
|
@@ -17954,7 +17955,14 @@ async function extractBody(input, init) {
|
|
|
17954
17955
|
return bodyInit;
|
|
17955
17956
|
}
|
|
17956
17957
|
}
|
|
17957
|
-
if (
|
|
17958
|
+
if (bodyInit instanceof URLSearchParams) {
|
|
17959
|
+
const result = {};
|
|
17960
|
+
bodyInit.forEach((value, key) => {
|
|
17961
|
+
result[key] = value;
|
|
17962
|
+
});
|
|
17963
|
+
return result;
|
|
17964
|
+
}
|
|
17965
|
+
if (input instanceof Request && !init?.body && input.body) {
|
|
17958
17966
|
try {
|
|
17959
17967
|
return await input.clone().json();
|
|
17960
17968
|
} catch {
|
|
@@ -17980,8 +17988,12 @@ function createFetchInterceptor(handle, options = {}) {
|
|
|
17980
17988
|
globalThis.fetch = async (input, init) => {
|
|
17981
17989
|
const urlString = input instanceof Request ? input.url : input instanceof URL ? input.href : input;
|
|
17982
17990
|
const path = extractPathname(urlString);
|
|
17983
|
-
if (baseUrl
|
|
17984
|
-
|
|
17991
|
+
if (baseUrl) {
|
|
17992
|
+
const normalizedBase = baseUrl.endsWith("/") ? baseUrl.slice(0, -1) : baseUrl;
|
|
17993
|
+
const isMatch = path === normalizedBase || path.startsWith(`${normalizedBase}/`);
|
|
17994
|
+
if (!isMatch) {
|
|
17995
|
+
return originalFetch(input, init);
|
|
17996
|
+
}
|
|
17985
17997
|
}
|
|
17986
17998
|
const method = input instanceof Request ? input.method : init?.method ?? "GET";
|
|
17987
17999
|
const headers = extractHeaders(input, init);
|
|
@@ -18375,6 +18387,8 @@ class CallableMockInstance {
|
|
|
18375
18387
|
}
|
|
18376
18388
|
}
|
|
18377
18389
|
reset() {
|
|
18390
|
+
this.interceptHandle?.restore();
|
|
18391
|
+
this.interceptHandle = null;
|
|
18378
18392
|
this.close();
|
|
18379
18393
|
this.routes = [];
|
|
18380
18394
|
this.staticRoutes.clear();
|
|
@@ -18445,6 +18459,7 @@ class CallableMockInstance {
|
|
|
18445
18459
|
if (!this.server) {
|
|
18446
18460
|
return;
|
|
18447
18461
|
}
|
|
18462
|
+
this.server.closeAllConnections();
|
|
18448
18463
|
this.server.close();
|
|
18449
18464
|
this.server = undefined;
|
|
18450
18465
|
this.serverInfo = undefined;
|
|
@@ -18654,7 +18669,7 @@ function schmock(config) {
|
|
|
18654
18669
|
return callableInstance;
|
|
18655
18670
|
}
|
|
18656
18671
|
// ../openapi/package.json
|
|
18657
|
-
var version = "2.0.
|
|
18672
|
+
var version = "2.0.1";
|
|
18658
18673
|
|
|
18659
18674
|
// ../openapi/src/utils.ts
|
|
18660
18675
|
function isRecord(value) {
|
|
@@ -18679,7 +18694,9 @@ function fireCallbacks(callbacks, context, response) {
|
|
|
18679
18694
|
method: callback.method,
|
|
18680
18695
|
headers: { "content-type": "application/json" },
|
|
18681
18696
|
body: body !== undefined ? JSON.stringify(body) : undefined
|
|
18682
|
-
}).catch(() => {
|
|
18697
|
+
}).catch((error) => {
|
|
18698
|
+
console.warn(`[@schmock/openapi] Callback ${callback.method} ${url} failed:`, error instanceof Error ? error.message : error);
|
|
18699
|
+
});
|
|
18683
18700
|
}
|
|
18684
18701
|
}
|
|
18685
18702
|
function resolveCallbackUrl(expression, context, response) {
|
|
@@ -18725,7 +18742,6 @@ function resolveJsonPointer(obj, pointer) {
|
|
|
18725
18742
|
|
|
18726
18743
|
// ../openapi/src/generators.ts
|
|
18727
18744
|
import { randomUUID } from "node:crypto";
|
|
18728
|
-
|
|
18729
18745
|
// ../faker/src/constants.ts
|
|
18730
18746
|
var MAX_ARRAY_SIZE = 1e4;
|
|
18731
18747
|
var MAX_NESTING_DEPTH = 10;
|
|
@@ -22610,7 +22626,9 @@ function determineArrayCount(schema, explicitCount, random = Math.random) {
|
|
|
22610
22626
|
return explicitCount;
|
|
22611
22627
|
}
|
|
22612
22628
|
if (schema.minItems !== undefined && schema.maxItems !== undefined) {
|
|
22613
|
-
|
|
22629
|
+
const min = schema.minItems;
|
|
22630
|
+
const max = Math.max(min, schema.maxItems);
|
|
22631
|
+
return Math.floor(random() * (max - min + 1)) + min;
|
|
22614
22632
|
}
|
|
22615
22633
|
if (schema.minItems !== undefined) {
|
|
22616
22634
|
return Math.max(schema.minItems, DEFAULT_ARRAY_COUNT);
|
|
@@ -22623,6 +22641,8 @@ function determineArrayCount(schema, explicitCount, random = Math.random) {
|
|
|
22623
22641
|
function applyOverrides(data, overrides, params, state, query) {
|
|
22624
22642
|
if (!overrides)
|
|
22625
22643
|
return data;
|
|
22644
|
+
if (typeof data !== "object" || data === null)
|
|
22645
|
+
return data;
|
|
22626
22646
|
const result = structuredClone(data);
|
|
22627
22647
|
for (const [key, value] of Object.entries(overrides)) {
|
|
22628
22648
|
if (DANGEROUS_KEYS.has(key))
|
|
@@ -22631,10 +22651,11 @@ function applyOverrides(data, overrides, params, state, query) {
|
|
|
22631
22651
|
setNestedProperty(result, key, value, { params, state, query });
|
|
22632
22652
|
} else {
|
|
22633
22653
|
if (typeof value === "object" && value !== null && !Array.isArray(value)) {
|
|
22654
|
+
const nested = value;
|
|
22634
22655
|
if (result[key] && typeof result[key] === "object") {
|
|
22635
|
-
result[key] = applyOverrides(result[key],
|
|
22656
|
+
result[key] = applyOverrides(result[key], nested, params, state, query);
|
|
22636
22657
|
} else {
|
|
22637
|
-
result[key] = applyOverrides({},
|
|
22658
|
+
result[key] = applyOverrides({}, nested, params, state, query);
|
|
22638
22659
|
}
|
|
22639
22660
|
} else if (typeof value === "string" && value.includes("{{")) {
|
|
22640
22661
|
result[key] = processTemplate(value, { params, state, query });
|
|
@@ -22666,34 +22687,28 @@ function setNestedProperty(obj, path, value, context) {
|
|
|
22666
22687
|
current[finalKey] = value;
|
|
22667
22688
|
}
|
|
22668
22689
|
}
|
|
22690
|
+
function resolveTemplatePath(context, expression) {
|
|
22691
|
+
const parts = expression.trim().split(".");
|
|
22692
|
+
let result = context;
|
|
22693
|
+
for (const part of parts) {
|
|
22694
|
+
if (result && typeof result === "object") {
|
|
22695
|
+
result = result[part];
|
|
22696
|
+
} else {
|
|
22697
|
+
return;
|
|
22698
|
+
}
|
|
22699
|
+
}
|
|
22700
|
+
return result;
|
|
22701
|
+
}
|
|
22669
22702
|
function processTemplate(template, context) {
|
|
22670
22703
|
const singleTemplateMatch = template.match(/^\{\{\s*([^}]+)\s*\}\}$/);
|
|
22671
22704
|
if (singleTemplateMatch) {
|
|
22672
|
-
const
|
|
22673
|
-
const parts = expression.trim().split(".");
|
|
22674
|
-
let result = context;
|
|
22675
|
-
for (const part of parts) {
|
|
22676
|
-
if (result && typeof result === "object") {
|
|
22677
|
-
result = result[part];
|
|
22678
|
-
} else {
|
|
22679
|
-
return template;
|
|
22680
|
-
}
|
|
22681
|
-
}
|
|
22705
|
+
const result = resolveTemplatePath(context, singleTemplateMatch[1]);
|
|
22682
22706
|
return result !== undefined ? result : template;
|
|
22683
22707
|
}
|
|
22684
|
-
|
|
22685
|
-
const
|
|
22686
|
-
let result = context;
|
|
22687
|
-
for (const part of parts) {
|
|
22688
|
-
if (result && typeof result === "object") {
|
|
22689
|
-
result = result[part];
|
|
22690
|
-
} else {
|
|
22691
|
-
return match;
|
|
22692
|
-
}
|
|
22693
|
-
}
|
|
22708
|
+
return template.replace(/\{\{\s*([^}]+)\s*\}\}/g, (match, expression) => {
|
|
22709
|
+
const result = resolveTemplatePath(context, expression);
|
|
22694
22710
|
return result !== undefined ? String(result) : match;
|
|
22695
22711
|
});
|
|
22696
|
-
return processed;
|
|
22697
22712
|
}
|
|
22698
22713
|
|
|
22699
22714
|
// ../faker/src/field-mappings.ts
|
|
@@ -24165,7 +24180,6 @@ function enhanceFieldSchema(fieldName, fieldSchema) {
|
|
|
24165
24180
|
async function generateFromSchema(options) {
|
|
24166
24181
|
const { schema, count, overrides, params, state, query, seed } = options;
|
|
24167
24182
|
validateSchema(schema);
|
|
24168
|
-
let generated;
|
|
24169
24183
|
if (schema.type === "array" && schema.items) {
|
|
24170
24184
|
const itemCount = determineArrayCount(schema, count);
|
|
24171
24185
|
if (itemCount > MAX_ARRAY_SIZE) {
|
|
@@ -24177,38 +24191,39 @@ async function generateFromSchema(options) {
|
|
|
24177
24191
|
}
|
|
24178
24192
|
const itemSchema = rawItemSchema;
|
|
24179
24193
|
const enhancedItemSchema = enhanceSchemaWithSmartMapping(itemSchema);
|
|
24180
|
-
|
|
24194
|
+
const items = [];
|
|
24181
24195
|
for (let i3 = 0;i3 < itemCount; i3++) {
|
|
24182
24196
|
let item = await generateWithJsf(enhancedItemSchema, seed);
|
|
24183
24197
|
item = postProcessGenerated(item, enhancedItemSchema);
|
|
24184
24198
|
item = applyOverrides(item, overrides, params, state, query);
|
|
24185
|
-
|
|
24199
|
+
items.push(item);
|
|
24186
24200
|
}
|
|
24187
|
-
|
|
24188
|
-
const enhancedSchema = enhanceSchemaWithSmartMapping(schema);
|
|
24189
|
-
generated = await generateWithJsf(enhancedSchema, seed);
|
|
24190
|
-
generated = postProcessGenerated(generated, enhancedSchema);
|
|
24191
|
-
generated = applyOverrides(generated, overrides, params, state, query);
|
|
24201
|
+
return items;
|
|
24192
24202
|
}
|
|
24203
|
+
const enhancedSchema = enhanceSchemaWithSmartMapping(schema);
|
|
24204
|
+
let generated = await generateWithJsf(enhancedSchema, seed);
|
|
24205
|
+
generated = postProcessGenerated(generated, enhancedSchema);
|
|
24206
|
+
generated = applyOverrides(generated, overrides, params, state, query);
|
|
24193
24207
|
return generated;
|
|
24194
24208
|
}
|
|
24195
24209
|
function postProcessGenerated(data, schema) {
|
|
24196
24210
|
if (data === null || data === undefined || !schema || typeof schema !== "object") {
|
|
24197
24211
|
return data;
|
|
24198
24212
|
}
|
|
24199
|
-
const
|
|
24200
|
-
if (
|
|
24213
|
+
const schemaExt = schema;
|
|
24214
|
+
if (schemaExt.schmockNullable === true) {
|
|
24201
24215
|
if (Math.random() < NULLABLE_NULL_PROBABILITY) {
|
|
24202
24216
|
return null;
|
|
24203
24217
|
}
|
|
24204
24218
|
}
|
|
24205
|
-
if (schema.type === "boolean" && typeof
|
|
24206
|
-
return Math.random() <
|
|
24219
|
+
if (schema.type === "boolean" && typeof schemaExt.schmockTrueProbability === "number") {
|
|
24220
|
+
return Math.random() < schemaExt.schmockTrueProbability;
|
|
24207
24221
|
}
|
|
24208
24222
|
if (typeof data === "object" && !Array.isArray(data) && schema.properties) {
|
|
24223
|
+
const record = data;
|
|
24209
24224
|
for (const [key, propSchema] of Object.entries(schema.properties)) {
|
|
24210
|
-
if (key in
|
|
24211
|
-
|
|
24225
|
+
if (key in record && isJSONSchema7(propSchema)) {
|
|
24226
|
+
record[key] = postProcessGenerated(record[key], propSchema);
|
|
24212
24227
|
}
|
|
24213
24228
|
}
|
|
24214
24229
|
}
|
|
@@ -24469,7 +24484,9 @@ async function generateErrorResponse(status, meta) {
|
|
|
24469
24484
|
try {
|
|
24470
24485
|
const body = await generateFromSchema({ schema: errorSchema });
|
|
24471
24486
|
return toTuple(status, body);
|
|
24472
|
-
} catch {
|
|
24487
|
+
} catch (error) {
|
|
24488
|
+
console.warn(`[@schmock/openapi] Error schema generation failed for status ${status}:`, error instanceof Error ? error.message : error);
|
|
24489
|
+
}
|
|
24473
24490
|
}
|
|
24474
24491
|
const defaults = {
|
|
24475
24492
|
404: { error: "Not found", code: "NOT_FOUND" },
|
|
@@ -24481,7 +24498,8 @@ async function generateErrorResponse(status, meta) {
|
|
|
24481
24498
|
async function generateWrapperSkeleton(schema) {
|
|
24482
24499
|
try {
|
|
24483
24500
|
return await generateFromSchema({ schema });
|
|
24484
|
-
} catch {
|
|
24501
|
+
} catch (error) {
|
|
24502
|
+
console.warn("[@schmock/openapi] Wrapper skeleton generation failed:", error instanceof Error ? error.message : error);
|
|
24485
24503
|
return {};
|
|
24486
24504
|
}
|
|
24487
24505
|
}
|
|
@@ -25060,7 +25078,7 @@ async function parseSpec(source) {
|
|
|
25060
25078
|
}
|
|
25061
25079
|
const isSwagger2 = "swagger" in api && typeof api.swagger === "string";
|
|
25062
25080
|
const title = api.info?.title ?? "Untitled";
|
|
25063
|
-
const
|
|
25081
|
+
const version3 = api.info?.version ?? "0.0.0";
|
|
25064
25082
|
let basePath = "";
|
|
25065
25083
|
if (isSwagger2 && "basePath" in api) {
|
|
25066
25084
|
const bp = api.basePath;
|
|
@@ -25085,7 +25103,7 @@ async function parseSpec(source) {
|
|
|
25085
25103
|
const paths = [];
|
|
25086
25104
|
const rawPaths = "paths" in api && isRecord(api.paths) ? api.paths : undefined;
|
|
25087
25105
|
if (!rawPaths) {
|
|
25088
|
-
return { title, version:
|
|
25106
|
+
return { title, version: version3, basePath, paths, securitySchemes, globalSecurity };
|
|
25089
25107
|
}
|
|
25090
25108
|
for (const [pathTemplate, pathItemRaw] of Object.entries(rawPaths)) {
|
|
25091
25109
|
if (!isRecord(pathItemRaw))
|
|
@@ -25126,7 +25144,7 @@ async function parseSpec(source) {
|
|
|
25126
25144
|
});
|
|
25127
25145
|
}
|
|
25128
25146
|
}
|
|
25129
|
-
return { title, version:
|
|
25147
|
+
return { title, version: version3, basePath, paths, securitySchemes, globalSecurity };
|
|
25130
25148
|
}
|
|
25131
25149
|
function isValidParamLocation(location2, isSwagger2) {
|
|
25132
25150
|
const validLocations = isSwagger2 ? ["path", "query", "header", "body"] : ["path", "query", "header"];
|
|
@@ -25657,7 +25675,8 @@ async function generateResponseBody(schema, seed, onSchema, context) {
|
|
|
25657
25675
|
}
|
|
25658
25676
|
try {
|
|
25659
25677
|
return await generateFromSchema({ schema: finalSchema, seed });
|
|
25660
|
-
} catch {
|
|
25678
|
+
} catch (error) {
|
|
25679
|
+
console.warn("[@schmock/openapi] Response body generation failed:", error instanceof Error ? error.message : error);
|
|
25661
25680
|
return {};
|
|
25662
25681
|
}
|
|
25663
25682
|
}
|
|
@@ -25871,7 +25890,15 @@ async function createCliServer(options) {
|
|
|
25871
25890
|
collectBody(req, headers).then((body) => mock.handle(method, path, { headers, body, query }).then((schmockResponse) => {
|
|
25872
25891
|
const extra = cors ? CORS_HEADERS : undefined;
|
|
25873
25892
|
writeSchmockResponse(res, schmockResponse, extra);
|
|
25874
|
-
}))
|
|
25893
|
+
})).catch((error) => {
|
|
25894
|
+
if (!res.headersSent) {
|
|
25895
|
+
res.writeHead(500, { "content-type": "application/json" });
|
|
25896
|
+
}
|
|
25897
|
+
res.end(JSON.stringify({
|
|
25898
|
+
error: error instanceof Error ? error.message : "Internal Server Error",
|
|
25899
|
+
code: "SERVER_ERROR"
|
|
25900
|
+
}));
|
|
25901
|
+
});
|
|
25875
25902
|
});
|
|
25876
25903
|
return new Promise((resolve, reject) => {
|
|
25877
25904
|
httpServer.on("error", reject);
|
|
@@ -25889,6 +25916,13 @@ async function createCliServer(options) {
|
|
|
25889
25916
|
});
|
|
25890
25917
|
});
|
|
25891
25918
|
}
|
|
25919
|
+
function validatePort(value) {
|
|
25920
|
+
const port = Number(value);
|
|
25921
|
+
if (!Number.isInteger(port) || port < 0 || port > 65535) {
|
|
25922
|
+
throw new Error(`Invalid port "${value}". Port must be an integer between 0 and 65535.`);
|
|
25923
|
+
}
|
|
25924
|
+
return port;
|
|
25925
|
+
}
|
|
25892
25926
|
function parseCliArgs(args) {
|
|
25893
25927
|
const { values, positionals } = parseArgs({
|
|
25894
25928
|
args,
|
|
@@ -25911,7 +25945,7 @@ function parseCliArgs(args) {
|
|
|
25911
25945
|
const spec = values.spec ?? positionals[0] ?? "";
|
|
25912
25946
|
return {
|
|
25913
25947
|
spec,
|
|
25914
|
-
port: values.port ?
|
|
25948
|
+
port: values.port ? validatePort(values.port) : undefined,
|
|
25915
25949
|
hostname: values.hostname,
|
|
25916
25950
|
seed: values.seed,
|
|
25917
25951
|
cors: values.cors,
|
package/dist/cli.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AAaxC,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED,MAAM,WAAW,SAAS;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,IAAI,IAAI,CAAC;CACf;AA0ED,wBAAsB,eAAe,CAAC,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC,SAAS,CAAC,
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AAaxC,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED,MAAM,WAAW,SAAS;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,IAAI,IAAI,CAAC;CACf;AA0ED,wBAAsB,eAAe,CAAC,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC,SAAS,CAAC,CAuF7E;AAYD,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,UAAU,GAAG;IAAE,IAAI,EAAE,OAAO,CAAA;CAAE,CAqC3E;AAqBD,MAAM,WAAW,WAAW;IAC1B,KAAK,IAAI,IAAI,CAAC;CACf;AAED;;GAEG;AACH,wBAAsB,YAAY,CAChC,OAAO,EAAE,SAAS,EAClB,OAAO,EAAE,UAAU,GAClB,OAAO,CAAC,SAAS,CAAC,CAQpB;AAED;;GAEG;AACH,wBAAgB,UAAU,CACxB,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,UAAU,EACnB,gBAAgB,EAAE,MAAM,SAAS,EACjC,QAAQ,EAAE,CAAC,MAAM,EAAE,SAAS,KAAK,IAAI,GACpC,WAAW,CA2Bb;AAED,wBAAsB,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAiDvD"}
|
package/dist/cli.js
CHANGED
|
@@ -92,12 +92,22 @@ export async function createCliServer(options) {
|
|
|
92
92
|
const method = toHttpMethod(req.method ?? "GET");
|
|
93
93
|
const headers = parseNodeHeaders(req);
|
|
94
94
|
const query = parseNodeQuery(url);
|
|
95
|
-
void collectBody(req, headers)
|
|
95
|
+
void collectBody(req, headers)
|
|
96
|
+
.then((body) => mock
|
|
96
97
|
.handle(method, path, { headers, body, query })
|
|
97
98
|
.then((schmockResponse) => {
|
|
98
99
|
const extra = cors ? CORS_HEADERS : undefined;
|
|
99
100
|
writeSchmockResponse(res, schmockResponse, extra);
|
|
100
|
-
}))
|
|
101
|
+
}))
|
|
102
|
+
.catch((error) => {
|
|
103
|
+
if (!res.headersSent) {
|
|
104
|
+
res.writeHead(500, { "content-type": "application/json" });
|
|
105
|
+
}
|
|
106
|
+
res.end(JSON.stringify({
|
|
107
|
+
error: error instanceof Error ? error.message : "Internal Server Error",
|
|
108
|
+
code: "SERVER_ERROR",
|
|
109
|
+
}));
|
|
110
|
+
});
|
|
101
111
|
});
|
|
102
112
|
return new Promise((resolve, reject) => {
|
|
103
113
|
httpServer.on("error", reject);
|
|
@@ -115,6 +125,13 @@ export async function createCliServer(options) {
|
|
|
115
125
|
});
|
|
116
126
|
});
|
|
117
127
|
}
|
|
128
|
+
function validatePort(value) {
|
|
129
|
+
const port = Number(value);
|
|
130
|
+
if (!Number.isInteger(port) || port < 0 || port > 65535) {
|
|
131
|
+
throw new Error(`Invalid port "${value}". Port must be an integer between 0 and 65535.`);
|
|
132
|
+
}
|
|
133
|
+
return port;
|
|
134
|
+
}
|
|
118
135
|
export function parseCliArgs(args) {
|
|
119
136
|
const { values, positionals } = parseArgs({
|
|
120
137
|
args,
|
|
@@ -137,7 +154,7 @@ export function parseCliArgs(args) {
|
|
|
137
154
|
const spec = values.spec ?? positionals[0] ?? "";
|
|
138
155
|
return {
|
|
139
156
|
spec,
|
|
140
|
-
port: values.port ?
|
|
157
|
+
port: values.port ? validatePort(values.port) : undefined,
|
|
141
158
|
hostname: values.hostname,
|
|
142
159
|
seed: values.seed,
|
|
143
160
|
cors: values.cors,
|
package/dist/index.js
CHANGED
|
@@ -17925,7 +17925,7 @@ function extractQuery(url) {
|
|
|
17925
17925
|
}
|
|
17926
17926
|
function extractHeaders(input, init) {
|
|
17927
17927
|
const headers = {};
|
|
17928
|
-
const raw = input instanceof Request ? input.headers :
|
|
17928
|
+
const raw = init?.headers ?? (input instanceof Request ? input.headers : undefined);
|
|
17929
17929
|
if (!raw)
|
|
17930
17930
|
return headers;
|
|
17931
17931
|
if (raw instanceof Headers) {
|
|
@@ -17934,18 +17934,19 @@ function extractHeaders(input, init) {
|
|
|
17934
17934
|
});
|
|
17935
17935
|
} else if (Array.isArray(raw)) {
|
|
17936
17936
|
for (const [key, value] of raw) {
|
|
17937
|
-
headers[key] = value;
|
|
17937
|
+
headers[key.toLowerCase()] = value;
|
|
17938
17938
|
}
|
|
17939
17939
|
} else {
|
|
17940
|
-
Object.
|
|
17940
|
+
for (const key of Object.keys(raw)) {
|
|
17941
|
+
headers[key.toLowerCase()] = raw[key];
|
|
17942
|
+
}
|
|
17941
17943
|
}
|
|
17942
17944
|
return headers;
|
|
17943
17945
|
}
|
|
17944
17946
|
async function extractBody(input, init) {
|
|
17945
|
-
const
|
|
17946
|
-
if (
|
|
17947
|
+
const bodyInit = init?.body ?? (input instanceof Request ? input.body : null);
|
|
17948
|
+
if (bodyInit === null || bodyInit === undefined)
|
|
17947
17949
|
return;
|
|
17948
|
-
const bodyInit = init?.body;
|
|
17949
17950
|
if (typeof bodyInit === "string") {
|
|
17950
17951
|
try {
|
|
17951
17952
|
return JSON.parse(bodyInit);
|
|
@@ -17953,7 +17954,14 @@ async function extractBody(input, init) {
|
|
|
17953
17954
|
return bodyInit;
|
|
17954
17955
|
}
|
|
17955
17956
|
}
|
|
17956
|
-
if (
|
|
17957
|
+
if (bodyInit instanceof URLSearchParams) {
|
|
17958
|
+
const result = {};
|
|
17959
|
+
bodyInit.forEach((value, key) => {
|
|
17960
|
+
result[key] = value;
|
|
17961
|
+
});
|
|
17962
|
+
return result;
|
|
17963
|
+
}
|
|
17964
|
+
if (input instanceof Request && !init?.body && input.body) {
|
|
17957
17965
|
try {
|
|
17958
17966
|
return await input.clone().json();
|
|
17959
17967
|
} catch {
|
|
@@ -17979,8 +17987,12 @@ function createFetchInterceptor(handle, options = {}) {
|
|
|
17979
17987
|
globalThis.fetch = async (input, init) => {
|
|
17980
17988
|
const urlString = input instanceof Request ? input.url : input instanceof URL ? input.href : input;
|
|
17981
17989
|
const path = extractPathname(urlString);
|
|
17982
|
-
if (baseUrl
|
|
17983
|
-
|
|
17990
|
+
if (baseUrl) {
|
|
17991
|
+
const normalizedBase = baseUrl.endsWith("/") ? baseUrl.slice(0, -1) : baseUrl;
|
|
17992
|
+
const isMatch = path === normalizedBase || path.startsWith(`${normalizedBase}/`);
|
|
17993
|
+
if (!isMatch) {
|
|
17994
|
+
return originalFetch(input, init);
|
|
17995
|
+
}
|
|
17984
17996
|
}
|
|
17985
17997
|
const method = input instanceof Request ? input.method : init?.method ?? "GET";
|
|
17986
17998
|
const headers = extractHeaders(input, init);
|
|
@@ -18374,6 +18386,8 @@ class CallableMockInstance {
|
|
|
18374
18386
|
}
|
|
18375
18387
|
}
|
|
18376
18388
|
reset() {
|
|
18389
|
+
this.interceptHandle?.restore();
|
|
18390
|
+
this.interceptHandle = null;
|
|
18377
18391
|
this.close();
|
|
18378
18392
|
this.routes = [];
|
|
18379
18393
|
this.staticRoutes.clear();
|
|
@@ -18444,6 +18458,7 @@ class CallableMockInstance {
|
|
|
18444
18458
|
if (!this.server) {
|
|
18445
18459
|
return;
|
|
18446
18460
|
}
|
|
18461
|
+
this.server.closeAllConnections();
|
|
18447
18462
|
this.server.close();
|
|
18448
18463
|
this.server = undefined;
|
|
18449
18464
|
this.serverInfo = undefined;
|
|
@@ -18653,7 +18668,7 @@ function schmock(config) {
|
|
|
18653
18668
|
return callableInstance;
|
|
18654
18669
|
}
|
|
18655
18670
|
// ../openapi/package.json
|
|
18656
|
-
var version = "2.0.
|
|
18671
|
+
var version = "2.0.1";
|
|
18657
18672
|
|
|
18658
18673
|
// ../openapi/src/utils.ts
|
|
18659
18674
|
function isRecord(value) {
|
|
@@ -18678,7 +18693,9 @@ function fireCallbacks(callbacks, context, response) {
|
|
|
18678
18693
|
method: callback.method,
|
|
18679
18694
|
headers: { "content-type": "application/json" },
|
|
18680
18695
|
body: body !== undefined ? JSON.stringify(body) : undefined
|
|
18681
|
-
}).catch(() => {
|
|
18696
|
+
}).catch((error) => {
|
|
18697
|
+
console.warn(`[@schmock/openapi] Callback ${callback.method} ${url} failed:`, error instanceof Error ? error.message : error);
|
|
18698
|
+
});
|
|
18682
18699
|
}
|
|
18683
18700
|
}
|
|
18684
18701
|
function resolveCallbackUrl(expression, context, response) {
|
|
@@ -18724,7 +18741,6 @@ function resolveJsonPointer(obj, pointer) {
|
|
|
18724
18741
|
|
|
18725
18742
|
// ../openapi/src/generators.ts
|
|
18726
18743
|
import { randomUUID } from "node:crypto";
|
|
18727
|
-
|
|
18728
18744
|
// ../faker/src/constants.ts
|
|
18729
18745
|
var MAX_ARRAY_SIZE = 1e4;
|
|
18730
18746
|
var MAX_NESTING_DEPTH = 10;
|
|
@@ -22609,7 +22625,9 @@ function determineArrayCount(schema, explicitCount, random = Math.random) {
|
|
|
22609
22625
|
return explicitCount;
|
|
22610
22626
|
}
|
|
22611
22627
|
if (schema.minItems !== undefined && schema.maxItems !== undefined) {
|
|
22612
|
-
|
|
22628
|
+
const min = schema.minItems;
|
|
22629
|
+
const max = Math.max(min, schema.maxItems);
|
|
22630
|
+
return Math.floor(random() * (max - min + 1)) + min;
|
|
22613
22631
|
}
|
|
22614
22632
|
if (schema.minItems !== undefined) {
|
|
22615
22633
|
return Math.max(schema.minItems, DEFAULT_ARRAY_COUNT);
|
|
@@ -22622,6 +22640,8 @@ function determineArrayCount(schema, explicitCount, random = Math.random) {
|
|
|
22622
22640
|
function applyOverrides(data, overrides, params, state, query) {
|
|
22623
22641
|
if (!overrides)
|
|
22624
22642
|
return data;
|
|
22643
|
+
if (typeof data !== "object" || data === null)
|
|
22644
|
+
return data;
|
|
22625
22645
|
const result = structuredClone(data);
|
|
22626
22646
|
for (const [key, value] of Object.entries(overrides)) {
|
|
22627
22647
|
if (DANGEROUS_KEYS.has(key))
|
|
@@ -22630,10 +22650,11 @@ function applyOverrides(data, overrides, params, state, query) {
|
|
|
22630
22650
|
setNestedProperty(result, key, value, { params, state, query });
|
|
22631
22651
|
} else {
|
|
22632
22652
|
if (typeof value === "object" && value !== null && !Array.isArray(value)) {
|
|
22653
|
+
const nested = value;
|
|
22633
22654
|
if (result[key] && typeof result[key] === "object") {
|
|
22634
|
-
result[key] = applyOverrides(result[key],
|
|
22655
|
+
result[key] = applyOverrides(result[key], nested, params, state, query);
|
|
22635
22656
|
} else {
|
|
22636
|
-
result[key] = applyOverrides({},
|
|
22657
|
+
result[key] = applyOverrides({}, nested, params, state, query);
|
|
22637
22658
|
}
|
|
22638
22659
|
} else if (typeof value === "string" && value.includes("{{")) {
|
|
22639
22660
|
result[key] = processTemplate(value, { params, state, query });
|
|
@@ -22665,34 +22686,28 @@ function setNestedProperty(obj, path, value, context) {
|
|
|
22665
22686
|
current[finalKey] = value;
|
|
22666
22687
|
}
|
|
22667
22688
|
}
|
|
22689
|
+
function resolveTemplatePath(context, expression) {
|
|
22690
|
+
const parts = expression.trim().split(".");
|
|
22691
|
+
let result = context;
|
|
22692
|
+
for (const part of parts) {
|
|
22693
|
+
if (result && typeof result === "object") {
|
|
22694
|
+
result = result[part];
|
|
22695
|
+
} else {
|
|
22696
|
+
return;
|
|
22697
|
+
}
|
|
22698
|
+
}
|
|
22699
|
+
return result;
|
|
22700
|
+
}
|
|
22668
22701
|
function processTemplate(template, context) {
|
|
22669
22702
|
const singleTemplateMatch = template.match(/^\{\{\s*([^}]+)\s*\}\}$/);
|
|
22670
22703
|
if (singleTemplateMatch) {
|
|
22671
|
-
const
|
|
22672
|
-
const parts = expression.trim().split(".");
|
|
22673
|
-
let result = context;
|
|
22674
|
-
for (const part of parts) {
|
|
22675
|
-
if (result && typeof result === "object") {
|
|
22676
|
-
result = result[part];
|
|
22677
|
-
} else {
|
|
22678
|
-
return template;
|
|
22679
|
-
}
|
|
22680
|
-
}
|
|
22704
|
+
const result = resolveTemplatePath(context, singleTemplateMatch[1]);
|
|
22681
22705
|
return result !== undefined ? result : template;
|
|
22682
22706
|
}
|
|
22683
|
-
|
|
22684
|
-
const
|
|
22685
|
-
let result = context;
|
|
22686
|
-
for (const part of parts) {
|
|
22687
|
-
if (result && typeof result === "object") {
|
|
22688
|
-
result = result[part];
|
|
22689
|
-
} else {
|
|
22690
|
-
return match;
|
|
22691
|
-
}
|
|
22692
|
-
}
|
|
22707
|
+
return template.replace(/\{\{\s*([^}]+)\s*\}\}/g, (match, expression) => {
|
|
22708
|
+
const result = resolveTemplatePath(context, expression);
|
|
22693
22709
|
return result !== undefined ? String(result) : match;
|
|
22694
22710
|
});
|
|
22695
|
-
return processed;
|
|
22696
22711
|
}
|
|
22697
22712
|
|
|
22698
22713
|
// ../faker/src/field-mappings.ts
|
|
@@ -24164,7 +24179,6 @@ function enhanceFieldSchema(fieldName, fieldSchema) {
|
|
|
24164
24179
|
async function generateFromSchema(options) {
|
|
24165
24180
|
const { schema, count, overrides, params, state, query, seed } = options;
|
|
24166
24181
|
validateSchema(schema);
|
|
24167
|
-
let generated;
|
|
24168
24182
|
if (schema.type === "array" && schema.items) {
|
|
24169
24183
|
const itemCount = determineArrayCount(schema, count);
|
|
24170
24184
|
if (itemCount > MAX_ARRAY_SIZE) {
|
|
@@ -24176,38 +24190,39 @@ async function generateFromSchema(options) {
|
|
|
24176
24190
|
}
|
|
24177
24191
|
const itemSchema = rawItemSchema;
|
|
24178
24192
|
const enhancedItemSchema = enhanceSchemaWithSmartMapping(itemSchema);
|
|
24179
|
-
|
|
24193
|
+
const items = [];
|
|
24180
24194
|
for (let i3 = 0;i3 < itemCount; i3++) {
|
|
24181
24195
|
let item = await generateWithJsf(enhancedItemSchema, seed);
|
|
24182
24196
|
item = postProcessGenerated(item, enhancedItemSchema);
|
|
24183
24197
|
item = applyOverrides(item, overrides, params, state, query);
|
|
24184
|
-
|
|
24198
|
+
items.push(item);
|
|
24185
24199
|
}
|
|
24186
|
-
|
|
24187
|
-
const enhancedSchema = enhanceSchemaWithSmartMapping(schema);
|
|
24188
|
-
generated = await generateWithJsf(enhancedSchema, seed);
|
|
24189
|
-
generated = postProcessGenerated(generated, enhancedSchema);
|
|
24190
|
-
generated = applyOverrides(generated, overrides, params, state, query);
|
|
24200
|
+
return items;
|
|
24191
24201
|
}
|
|
24202
|
+
const enhancedSchema = enhanceSchemaWithSmartMapping(schema);
|
|
24203
|
+
let generated = await generateWithJsf(enhancedSchema, seed);
|
|
24204
|
+
generated = postProcessGenerated(generated, enhancedSchema);
|
|
24205
|
+
generated = applyOverrides(generated, overrides, params, state, query);
|
|
24192
24206
|
return generated;
|
|
24193
24207
|
}
|
|
24194
24208
|
function postProcessGenerated(data, schema) {
|
|
24195
24209
|
if (data === null || data === undefined || !schema || typeof schema !== "object") {
|
|
24196
24210
|
return data;
|
|
24197
24211
|
}
|
|
24198
|
-
const
|
|
24199
|
-
if (
|
|
24212
|
+
const schemaExt = schema;
|
|
24213
|
+
if (schemaExt.schmockNullable === true) {
|
|
24200
24214
|
if (Math.random() < NULLABLE_NULL_PROBABILITY) {
|
|
24201
24215
|
return null;
|
|
24202
24216
|
}
|
|
24203
24217
|
}
|
|
24204
|
-
if (schema.type === "boolean" && typeof
|
|
24205
|
-
return Math.random() <
|
|
24218
|
+
if (schema.type === "boolean" && typeof schemaExt.schmockTrueProbability === "number") {
|
|
24219
|
+
return Math.random() < schemaExt.schmockTrueProbability;
|
|
24206
24220
|
}
|
|
24207
24221
|
if (typeof data === "object" && !Array.isArray(data) && schema.properties) {
|
|
24222
|
+
const record = data;
|
|
24208
24223
|
for (const [key, propSchema] of Object.entries(schema.properties)) {
|
|
24209
|
-
if (key in
|
|
24210
|
-
|
|
24224
|
+
if (key in record && isJSONSchema7(propSchema)) {
|
|
24225
|
+
record[key] = postProcessGenerated(record[key], propSchema);
|
|
24211
24226
|
}
|
|
24212
24227
|
}
|
|
24213
24228
|
}
|
|
@@ -24468,7 +24483,9 @@ async function generateErrorResponse(status, meta) {
|
|
|
24468
24483
|
try {
|
|
24469
24484
|
const body = await generateFromSchema({ schema: errorSchema });
|
|
24470
24485
|
return toTuple(status, body);
|
|
24471
|
-
} catch {
|
|
24486
|
+
} catch (error) {
|
|
24487
|
+
console.warn(`[@schmock/openapi] Error schema generation failed for status ${status}:`, error instanceof Error ? error.message : error);
|
|
24488
|
+
}
|
|
24472
24489
|
}
|
|
24473
24490
|
const defaults = {
|
|
24474
24491
|
404: { error: "Not found", code: "NOT_FOUND" },
|
|
@@ -24480,7 +24497,8 @@ async function generateErrorResponse(status, meta) {
|
|
|
24480
24497
|
async function generateWrapperSkeleton(schema) {
|
|
24481
24498
|
try {
|
|
24482
24499
|
return await generateFromSchema({ schema });
|
|
24483
|
-
} catch {
|
|
24500
|
+
} catch (error) {
|
|
24501
|
+
console.warn("[@schmock/openapi] Wrapper skeleton generation failed:", error instanceof Error ? error.message : error);
|
|
24484
24502
|
return {};
|
|
24485
24503
|
}
|
|
24486
24504
|
}
|
|
@@ -25059,7 +25077,7 @@ async function parseSpec(source) {
|
|
|
25059
25077
|
}
|
|
25060
25078
|
const isSwagger2 = "swagger" in api && typeof api.swagger === "string";
|
|
25061
25079
|
const title = api.info?.title ?? "Untitled";
|
|
25062
|
-
const
|
|
25080
|
+
const version3 = api.info?.version ?? "0.0.0";
|
|
25063
25081
|
let basePath = "";
|
|
25064
25082
|
if (isSwagger2 && "basePath" in api) {
|
|
25065
25083
|
const bp = api.basePath;
|
|
@@ -25084,7 +25102,7 @@ async function parseSpec(source) {
|
|
|
25084
25102
|
const paths = [];
|
|
25085
25103
|
const rawPaths = "paths" in api && isRecord(api.paths) ? api.paths : undefined;
|
|
25086
25104
|
if (!rawPaths) {
|
|
25087
|
-
return { title, version:
|
|
25105
|
+
return { title, version: version3, basePath, paths, securitySchemes, globalSecurity };
|
|
25088
25106
|
}
|
|
25089
25107
|
for (const [pathTemplate, pathItemRaw] of Object.entries(rawPaths)) {
|
|
25090
25108
|
if (!isRecord(pathItemRaw))
|
|
@@ -25125,7 +25143,7 @@ async function parseSpec(source) {
|
|
|
25125
25143
|
});
|
|
25126
25144
|
}
|
|
25127
25145
|
}
|
|
25128
|
-
return { title, version:
|
|
25146
|
+
return { title, version: version3, basePath, paths, securitySchemes, globalSecurity };
|
|
25129
25147
|
}
|
|
25130
25148
|
function isValidParamLocation(location2, isSwagger2) {
|
|
25131
25149
|
const validLocations = isSwagger2 ? ["path", "query", "header", "body"] : ["path", "query", "header"];
|
|
@@ -25656,7 +25674,8 @@ async function generateResponseBody(schema, seed, onSchema, context) {
|
|
|
25656
25674
|
}
|
|
25657
25675
|
try {
|
|
25658
25676
|
return await generateFromSchema({ schema: finalSchema, seed });
|
|
25659
|
-
} catch {
|
|
25677
|
+
} catch (error) {
|
|
25678
|
+
console.warn("[@schmock/openapi] Response body generation failed:", error instanceof Error ? error.message : error);
|
|
25660
25679
|
return {};
|
|
25661
25680
|
}
|
|
25662
25681
|
}
|
|
@@ -25870,7 +25889,15 @@ async function createCliServer(options) {
|
|
|
25870
25889
|
collectBody(req, headers).then((body) => mock.handle(method, path, { headers, body, query }).then((schmockResponse) => {
|
|
25871
25890
|
const extra = cors ? CORS_HEADERS : undefined;
|
|
25872
25891
|
writeSchmockResponse(res, schmockResponse, extra);
|
|
25873
|
-
}))
|
|
25892
|
+
})).catch((error) => {
|
|
25893
|
+
if (!res.headersSent) {
|
|
25894
|
+
res.writeHead(500, { "content-type": "application/json" });
|
|
25895
|
+
}
|
|
25896
|
+
res.end(JSON.stringify({
|
|
25897
|
+
error: error instanceof Error ? error.message : "Internal Server Error",
|
|
25898
|
+
code: "SERVER_ERROR"
|
|
25899
|
+
}));
|
|
25900
|
+
});
|
|
25874
25901
|
});
|
|
25875
25902
|
return new Promise((resolve, reject) => {
|
|
25876
25903
|
httpServer.on("error", reject);
|
|
@@ -25888,6 +25915,13 @@ async function createCliServer(options) {
|
|
|
25888
25915
|
});
|
|
25889
25916
|
});
|
|
25890
25917
|
}
|
|
25918
|
+
function validatePort(value) {
|
|
25919
|
+
const port = Number(value);
|
|
25920
|
+
if (!Number.isInteger(port) || port < 0 || port > 65535) {
|
|
25921
|
+
throw new Error(`Invalid port "${value}". Port must be an integer between 0 and 65535.`);
|
|
25922
|
+
}
|
|
25923
|
+
return port;
|
|
25924
|
+
}
|
|
25891
25925
|
function parseCliArgs(args) {
|
|
25892
25926
|
const { values, positionals } = parseArgs({
|
|
25893
25927
|
args,
|
|
@@ -25910,7 +25944,7 @@ function parseCliArgs(args) {
|
|
|
25910
25944
|
const spec = values.spec ?? positionals[0] ?? "";
|
|
25911
25945
|
return {
|
|
25912
25946
|
spec,
|
|
25913
|
-
port: values.port ?
|
|
25947
|
+
port: values.port ? validatePort(values.port) : undefined,
|
|
25914
25948
|
hostname: values.hostname,
|
|
25915
25949
|
seed: values.seed,
|
|
25916
25950
|
cors: values.cors,
|