@schmock/cli 2.1.6 → 2.2.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 +46 -29
- package/dist/index.js +46 -29
- package/package.json +3 -3
package/dist/bin.js
CHANGED
|
@@ -23855,7 +23855,7 @@ function extractHeaders(input, init) {
|
|
|
23855
23855
|
return headers;
|
|
23856
23856
|
if (raw instanceof Headers) {
|
|
23857
23857
|
raw.forEach((value, key) => {
|
|
23858
|
-
headers[key] = value;
|
|
23858
|
+
headers[key.toLowerCase()] = value;
|
|
23859
23859
|
});
|
|
23860
23860
|
} else if (Array.isArray(raw)) {
|
|
23861
23861
|
for (const [key, value] of raw) {
|
|
@@ -24058,7 +24058,7 @@ async function runPluginPipeline(plugins, context, initialResponse, logger) {
|
|
|
24058
24058
|
if (errorResult instanceof Error) {
|
|
24059
24059
|
throw new PluginError(plugin.name, errorResult);
|
|
24060
24060
|
}
|
|
24061
|
-
if (typeof errorResult === "object" && errorResult !== null && "status" in errorResult) {
|
|
24061
|
+
if (isStatusTuple(errorResult) || typeof errorResult === "object" && errorResult !== null && "status" in errorResult) {
|
|
24062
24062
|
response = errorResult;
|
|
24063
24063
|
break;
|
|
24064
24064
|
}
|
|
@@ -24079,7 +24079,7 @@ async function runPluginPipeline(plugins, context, initialResponse, logger) {
|
|
|
24079
24079
|
|
|
24080
24080
|
// ../core/src/response-parser.ts
|
|
24081
24081
|
function isResponseObject(value) {
|
|
24082
|
-
return typeof value === "object" && value !== null && "status" in value && "body" in value;
|
|
24082
|
+
return typeof value === "object" && value !== null && "status" in value && typeof value.status === "number" && "body" in value;
|
|
24083
24083
|
}
|
|
24084
24084
|
function parseResponse(result, routeConfig) {
|
|
24085
24085
|
let status = 200;
|
|
@@ -24201,18 +24201,19 @@ class CallableMockInstance {
|
|
|
24201
24201
|
});
|
|
24202
24202
|
}
|
|
24203
24203
|
defineRoute(route, generator, config) {
|
|
24204
|
-
|
|
24204
|
+
const routeConfig = { ...config };
|
|
24205
|
+
if (!routeConfig.contentType) {
|
|
24205
24206
|
if (typeof generator === "function") {
|
|
24206
|
-
|
|
24207
|
+
routeConfig.contentType = "application/json";
|
|
24207
24208
|
} else if (typeof generator === "string" || typeof generator === "number" || typeof generator === "boolean") {
|
|
24208
|
-
|
|
24209
|
+
routeConfig.contentType = "text/plain";
|
|
24209
24210
|
} else if (Buffer.isBuffer(generator)) {
|
|
24210
|
-
|
|
24211
|
+
routeConfig.contentType = "application/octet-stream";
|
|
24211
24212
|
} else {
|
|
24212
|
-
|
|
24213
|
+
routeConfig.contentType = "application/json";
|
|
24213
24214
|
}
|
|
24214
24215
|
}
|
|
24215
|
-
if (typeof generator !== "function" &&
|
|
24216
|
+
if (typeof generator !== "function" && routeConfig.contentType === "application/json") {
|
|
24216
24217
|
try {
|
|
24217
24218
|
JSON.stringify(generator);
|
|
24218
24219
|
} catch (_error) {
|
|
@@ -24220,7 +24221,8 @@ class CallableMockInstance {
|
|
|
24220
24221
|
}
|
|
24221
24222
|
}
|
|
24222
24223
|
const parsed = parseRouteKey(route);
|
|
24223
|
-
const
|
|
24224
|
+
const normalizedParsedPath = normalizePath(parsed.path);
|
|
24225
|
+
const existing = this.routes.find((r) => r.method === parsed.method && normalizePath(r.path) === normalizedParsedPath);
|
|
24224
24226
|
if (existing) {
|
|
24225
24227
|
this.logger.log("warning", `Duplicate route: ${route} — first registration wins`);
|
|
24226
24228
|
return this;
|
|
@@ -24231,7 +24233,7 @@ class CallableMockInstance {
|
|
|
24231
24233
|
method: parsed.method,
|
|
24232
24234
|
path: parsed.path,
|
|
24233
24235
|
generator,
|
|
24234
|
-
config
|
|
24236
|
+
config: routeConfig
|
|
24235
24237
|
};
|
|
24236
24238
|
this.routes.push(compiledRoute);
|
|
24237
24239
|
if (parsed.params.length === 0) {
|
|
@@ -24239,7 +24241,7 @@ class CallableMockInstance {
|
|
|
24239
24241
|
this.staticRoutes.set(key, compiledRoute);
|
|
24240
24242
|
}
|
|
24241
24243
|
this.logger.log("route", `Route defined: ${route}`, {
|
|
24242
|
-
contentType:
|
|
24244
|
+
contentType: routeConfig.contentType,
|
|
24243
24245
|
generatorType: typeof generator,
|
|
24244
24246
|
hasParams: parsed.params.length > 0
|
|
24245
24247
|
});
|
|
@@ -24261,11 +24263,21 @@ class CallableMockInstance {
|
|
|
24261
24263
|
}
|
|
24262
24264
|
return this;
|
|
24263
24265
|
}
|
|
24266
|
+
cloneRecord(r) {
|
|
24267
|
+
try {
|
|
24268
|
+
return structuredClone(r);
|
|
24269
|
+
} catch {
|
|
24270
|
+
return {
|
|
24271
|
+
...r,
|
|
24272
|
+
response: { ...r.response }
|
|
24273
|
+
};
|
|
24274
|
+
}
|
|
24275
|
+
}
|
|
24264
24276
|
history(method, path) {
|
|
24265
24277
|
if (method || path) {
|
|
24266
|
-
return this.requestHistory.filter((r) => (!method || r.method === method) && (!path || r.path === path));
|
|
24278
|
+
return this.requestHistory.filter((r) => (!method || r.method === method) && (!path || r.path === path)).map((r) => this.cloneRecord(r));
|
|
24267
24279
|
}
|
|
24268
|
-
return
|
|
24280
|
+
return this.requestHistory.map((r) => this.cloneRecord(r));
|
|
24269
24281
|
}
|
|
24270
24282
|
called(method, path) {
|
|
24271
24283
|
if (method || path) {
|
|
@@ -24282,9 +24294,11 @@ class CallableMockInstance {
|
|
|
24282
24294
|
lastRequest(method, path) {
|
|
24283
24295
|
if (method || path) {
|
|
24284
24296
|
const filtered = this.requestHistory.filter((r) => (!method || r.method === method) && (!path || r.path === path));
|
|
24285
|
-
|
|
24297
|
+
const last2 = filtered[filtered.length - 1];
|
|
24298
|
+
return last2 ? this.cloneRecord(last2) : undefined;
|
|
24286
24299
|
}
|
|
24287
|
-
|
|
24300
|
+
const last = this.requestHistory[this.requestHistory.length - 1];
|
|
24301
|
+
return last ? this.cloneRecord(last) : undefined;
|
|
24288
24302
|
}
|
|
24289
24303
|
getRoutes() {
|
|
24290
24304
|
return this.routes.map((r) => ({
|
|
@@ -24327,9 +24341,7 @@ class CallableMockInstance {
|
|
|
24327
24341
|
this.requestHistory = [];
|
|
24328
24342
|
this.listeners.clear();
|
|
24329
24343
|
if (this.globalConfig.state) {
|
|
24330
|
-
|
|
24331
|
-
delete this.globalConfig.state[key];
|
|
24332
|
-
}
|
|
24344
|
+
this.globalConfig.state = {};
|
|
24333
24345
|
}
|
|
24334
24346
|
this.logger.log("lifecycle", "Mock fully reset");
|
|
24335
24347
|
}
|
|
@@ -24339,9 +24351,7 @@ class CallableMockInstance {
|
|
|
24339
24351
|
}
|
|
24340
24352
|
resetState() {
|
|
24341
24353
|
if (this.globalConfig.state) {
|
|
24342
|
-
|
|
24343
|
-
delete this.globalConfig.state[key];
|
|
24344
|
-
}
|
|
24354
|
+
this.globalConfig.state = {};
|
|
24345
24355
|
}
|
|
24346
24356
|
this.logger.log("lifecycle", "State cleared");
|
|
24347
24357
|
}
|
|
@@ -24607,7 +24617,7 @@ function schmock(config) {
|
|
|
24607
24617
|
return callableInstance;
|
|
24608
24618
|
}
|
|
24609
24619
|
// ../openapi/package.json
|
|
24610
|
-
var version = "2.1
|
|
24620
|
+
var version = "2.2.1";
|
|
24611
24621
|
|
|
24612
24622
|
// ../openapi/src/utils.ts
|
|
24613
24623
|
function isRecord(value) {
|
|
@@ -30221,7 +30231,9 @@ function enhanceSchemaWithSmartMapping(schema) {
|
|
|
30221
30231
|
function enhanceFieldSchema(fieldName, fieldSchema) {
|
|
30222
30232
|
const enhanced = { ...fieldSchema };
|
|
30223
30233
|
if (enhanced.faker) {
|
|
30224
|
-
|
|
30234
|
+
if (typeof enhanced.faker === "string") {
|
|
30235
|
+
validateFakerMethod(enhanced.faker);
|
|
30236
|
+
}
|
|
30225
30237
|
return enhanced;
|
|
30226
30238
|
}
|
|
30227
30239
|
const hasComposition = enhanced.allOf || enhanced.anyOf || enhanced.oneOf;
|
|
@@ -30237,12 +30249,17 @@ function enhanceFieldSchema(fieldName, fieldSchema) {
|
|
|
30237
30249
|
}
|
|
30238
30250
|
const match = findBestMapping(fieldName, enhanced);
|
|
30239
30251
|
if (match) {
|
|
30240
|
-
|
|
30241
|
-
if (
|
|
30242
|
-
enhanced.
|
|
30252
|
+
const { fakerMethod, format, trueProbability, fakerArgs } = match.mapping;
|
|
30253
|
+
if (fakerArgs) {
|
|
30254
|
+
enhanced.faker = { [fakerMethod]: [fakerArgs] };
|
|
30255
|
+
} else {
|
|
30256
|
+
enhanced.faker = fakerMethod;
|
|
30257
|
+
}
|
|
30258
|
+
if (format) {
|
|
30259
|
+
enhanced.format = format;
|
|
30243
30260
|
}
|
|
30244
|
-
if (
|
|
30245
|
-
enhanced.schmockTrueProbability =
|
|
30261
|
+
if (trueProbability !== undefined) {
|
|
30262
|
+
enhanced.schmockTrueProbability = trueProbability;
|
|
30246
30263
|
}
|
|
30247
30264
|
}
|
|
30248
30265
|
return enhanced;
|
package/dist/index.js
CHANGED
|
@@ -23854,7 +23854,7 @@ function extractHeaders(input, init) {
|
|
|
23854
23854
|
return headers;
|
|
23855
23855
|
if (raw instanceof Headers) {
|
|
23856
23856
|
raw.forEach((value, key) => {
|
|
23857
|
-
headers[key] = value;
|
|
23857
|
+
headers[key.toLowerCase()] = value;
|
|
23858
23858
|
});
|
|
23859
23859
|
} else if (Array.isArray(raw)) {
|
|
23860
23860
|
for (const [key, value] of raw) {
|
|
@@ -24057,7 +24057,7 @@ async function runPluginPipeline(plugins, context, initialResponse, logger) {
|
|
|
24057
24057
|
if (errorResult instanceof Error) {
|
|
24058
24058
|
throw new PluginError(plugin.name, errorResult);
|
|
24059
24059
|
}
|
|
24060
|
-
if (typeof errorResult === "object" && errorResult !== null && "status" in errorResult) {
|
|
24060
|
+
if (isStatusTuple(errorResult) || typeof errorResult === "object" && errorResult !== null && "status" in errorResult) {
|
|
24061
24061
|
response = errorResult;
|
|
24062
24062
|
break;
|
|
24063
24063
|
}
|
|
@@ -24078,7 +24078,7 @@ async function runPluginPipeline(plugins, context, initialResponse, logger) {
|
|
|
24078
24078
|
|
|
24079
24079
|
// ../core/src/response-parser.ts
|
|
24080
24080
|
function isResponseObject(value) {
|
|
24081
|
-
return typeof value === "object" && value !== null && "status" in value && "body" in value;
|
|
24081
|
+
return typeof value === "object" && value !== null && "status" in value && typeof value.status === "number" && "body" in value;
|
|
24082
24082
|
}
|
|
24083
24083
|
function parseResponse(result, routeConfig) {
|
|
24084
24084
|
let status = 200;
|
|
@@ -24200,18 +24200,19 @@ class CallableMockInstance {
|
|
|
24200
24200
|
});
|
|
24201
24201
|
}
|
|
24202
24202
|
defineRoute(route, generator, config) {
|
|
24203
|
-
|
|
24203
|
+
const routeConfig = { ...config };
|
|
24204
|
+
if (!routeConfig.contentType) {
|
|
24204
24205
|
if (typeof generator === "function") {
|
|
24205
|
-
|
|
24206
|
+
routeConfig.contentType = "application/json";
|
|
24206
24207
|
} else if (typeof generator === "string" || typeof generator === "number" || typeof generator === "boolean") {
|
|
24207
|
-
|
|
24208
|
+
routeConfig.contentType = "text/plain";
|
|
24208
24209
|
} else if (Buffer.isBuffer(generator)) {
|
|
24209
|
-
|
|
24210
|
+
routeConfig.contentType = "application/octet-stream";
|
|
24210
24211
|
} else {
|
|
24211
|
-
|
|
24212
|
+
routeConfig.contentType = "application/json";
|
|
24212
24213
|
}
|
|
24213
24214
|
}
|
|
24214
|
-
if (typeof generator !== "function" &&
|
|
24215
|
+
if (typeof generator !== "function" && routeConfig.contentType === "application/json") {
|
|
24215
24216
|
try {
|
|
24216
24217
|
JSON.stringify(generator);
|
|
24217
24218
|
} catch (_error) {
|
|
@@ -24219,7 +24220,8 @@ class CallableMockInstance {
|
|
|
24219
24220
|
}
|
|
24220
24221
|
}
|
|
24221
24222
|
const parsed = parseRouteKey(route);
|
|
24222
|
-
const
|
|
24223
|
+
const normalizedParsedPath = normalizePath(parsed.path);
|
|
24224
|
+
const existing = this.routes.find((r) => r.method === parsed.method && normalizePath(r.path) === normalizedParsedPath);
|
|
24223
24225
|
if (existing) {
|
|
24224
24226
|
this.logger.log("warning", `Duplicate route: ${route} — first registration wins`);
|
|
24225
24227
|
return this;
|
|
@@ -24230,7 +24232,7 @@ class CallableMockInstance {
|
|
|
24230
24232
|
method: parsed.method,
|
|
24231
24233
|
path: parsed.path,
|
|
24232
24234
|
generator,
|
|
24233
|
-
config
|
|
24235
|
+
config: routeConfig
|
|
24234
24236
|
};
|
|
24235
24237
|
this.routes.push(compiledRoute);
|
|
24236
24238
|
if (parsed.params.length === 0) {
|
|
@@ -24238,7 +24240,7 @@ class CallableMockInstance {
|
|
|
24238
24240
|
this.staticRoutes.set(key, compiledRoute);
|
|
24239
24241
|
}
|
|
24240
24242
|
this.logger.log("route", `Route defined: ${route}`, {
|
|
24241
|
-
contentType:
|
|
24243
|
+
contentType: routeConfig.contentType,
|
|
24242
24244
|
generatorType: typeof generator,
|
|
24243
24245
|
hasParams: parsed.params.length > 0
|
|
24244
24246
|
});
|
|
@@ -24260,11 +24262,21 @@ class CallableMockInstance {
|
|
|
24260
24262
|
}
|
|
24261
24263
|
return this;
|
|
24262
24264
|
}
|
|
24265
|
+
cloneRecord(r) {
|
|
24266
|
+
try {
|
|
24267
|
+
return structuredClone(r);
|
|
24268
|
+
} catch {
|
|
24269
|
+
return {
|
|
24270
|
+
...r,
|
|
24271
|
+
response: { ...r.response }
|
|
24272
|
+
};
|
|
24273
|
+
}
|
|
24274
|
+
}
|
|
24263
24275
|
history(method, path) {
|
|
24264
24276
|
if (method || path) {
|
|
24265
|
-
return this.requestHistory.filter((r) => (!method || r.method === method) && (!path || r.path === path));
|
|
24277
|
+
return this.requestHistory.filter((r) => (!method || r.method === method) && (!path || r.path === path)).map((r) => this.cloneRecord(r));
|
|
24266
24278
|
}
|
|
24267
|
-
return
|
|
24279
|
+
return this.requestHistory.map((r) => this.cloneRecord(r));
|
|
24268
24280
|
}
|
|
24269
24281
|
called(method, path) {
|
|
24270
24282
|
if (method || path) {
|
|
@@ -24281,9 +24293,11 @@ class CallableMockInstance {
|
|
|
24281
24293
|
lastRequest(method, path) {
|
|
24282
24294
|
if (method || path) {
|
|
24283
24295
|
const filtered = this.requestHistory.filter((r) => (!method || r.method === method) && (!path || r.path === path));
|
|
24284
|
-
|
|
24296
|
+
const last2 = filtered[filtered.length - 1];
|
|
24297
|
+
return last2 ? this.cloneRecord(last2) : undefined;
|
|
24285
24298
|
}
|
|
24286
|
-
|
|
24299
|
+
const last = this.requestHistory[this.requestHistory.length - 1];
|
|
24300
|
+
return last ? this.cloneRecord(last) : undefined;
|
|
24287
24301
|
}
|
|
24288
24302
|
getRoutes() {
|
|
24289
24303
|
return this.routes.map((r) => ({
|
|
@@ -24326,9 +24340,7 @@ class CallableMockInstance {
|
|
|
24326
24340
|
this.requestHistory = [];
|
|
24327
24341
|
this.listeners.clear();
|
|
24328
24342
|
if (this.globalConfig.state) {
|
|
24329
|
-
|
|
24330
|
-
delete this.globalConfig.state[key];
|
|
24331
|
-
}
|
|
24343
|
+
this.globalConfig.state = {};
|
|
24332
24344
|
}
|
|
24333
24345
|
this.logger.log("lifecycle", "Mock fully reset");
|
|
24334
24346
|
}
|
|
@@ -24338,9 +24350,7 @@ class CallableMockInstance {
|
|
|
24338
24350
|
}
|
|
24339
24351
|
resetState() {
|
|
24340
24352
|
if (this.globalConfig.state) {
|
|
24341
|
-
|
|
24342
|
-
delete this.globalConfig.state[key];
|
|
24343
|
-
}
|
|
24353
|
+
this.globalConfig.state = {};
|
|
24344
24354
|
}
|
|
24345
24355
|
this.logger.log("lifecycle", "State cleared");
|
|
24346
24356
|
}
|
|
@@ -24606,7 +24616,7 @@ function schmock(config) {
|
|
|
24606
24616
|
return callableInstance;
|
|
24607
24617
|
}
|
|
24608
24618
|
// ../openapi/package.json
|
|
24609
|
-
var version = "2.1
|
|
24619
|
+
var version = "2.2.1";
|
|
24610
24620
|
|
|
24611
24621
|
// ../openapi/src/utils.ts
|
|
24612
24622
|
function isRecord(value) {
|
|
@@ -30220,7 +30230,9 @@ function enhanceSchemaWithSmartMapping(schema) {
|
|
|
30220
30230
|
function enhanceFieldSchema(fieldName, fieldSchema) {
|
|
30221
30231
|
const enhanced = { ...fieldSchema };
|
|
30222
30232
|
if (enhanced.faker) {
|
|
30223
|
-
|
|
30233
|
+
if (typeof enhanced.faker === "string") {
|
|
30234
|
+
validateFakerMethod(enhanced.faker);
|
|
30235
|
+
}
|
|
30224
30236
|
return enhanced;
|
|
30225
30237
|
}
|
|
30226
30238
|
const hasComposition = enhanced.allOf || enhanced.anyOf || enhanced.oneOf;
|
|
@@ -30236,12 +30248,17 @@ function enhanceFieldSchema(fieldName, fieldSchema) {
|
|
|
30236
30248
|
}
|
|
30237
30249
|
const match = findBestMapping(fieldName, enhanced);
|
|
30238
30250
|
if (match) {
|
|
30239
|
-
|
|
30240
|
-
if (
|
|
30241
|
-
enhanced.
|
|
30251
|
+
const { fakerMethod, format, trueProbability, fakerArgs } = match.mapping;
|
|
30252
|
+
if (fakerArgs) {
|
|
30253
|
+
enhanced.faker = { [fakerMethod]: [fakerArgs] };
|
|
30254
|
+
} else {
|
|
30255
|
+
enhanced.faker = fakerMethod;
|
|
30256
|
+
}
|
|
30257
|
+
if (format) {
|
|
30258
|
+
enhanced.format = format;
|
|
30242
30259
|
}
|
|
30243
|
-
if (
|
|
30244
|
-
enhanced.schmockTrueProbability =
|
|
30260
|
+
if (trueProbability !== undefined) {
|
|
30261
|
+
enhanced.schmockTrueProbability = trueProbability;
|
|
30245
30262
|
}
|
|
30246
30263
|
}
|
|
30247
30264
|
return enhanced;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@schmock/cli",
|
|
3
3
|
"description": "CLI for running Schmock mock servers from OpenAPI specs",
|
|
4
|
-
"version": "2.1
|
|
4
|
+
"version": "2.2.1",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
7
7
|
"types": "./dist/index.d.ts",
|
|
@@ -32,8 +32,8 @@
|
|
|
32
32
|
},
|
|
33
33
|
"license": "MIT",
|
|
34
34
|
"dependencies": {
|
|
35
|
-
"@schmock/core": "^2.1
|
|
36
|
-
"@schmock/openapi": "^2.1
|
|
35
|
+
"@schmock/core": "^2.2.1",
|
|
36
|
+
"@schmock/openapi": "^2.2.1"
|
|
37
37
|
},
|
|
38
38
|
"devDependencies": {
|
|
39
39
|
"@amiceli/vitest-cucumber": "^6.5.0",
|