@orval/mock 8.23.0 → 8.25.0

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/index.d.mts CHANGED
@@ -1,5 +1,4 @@
1
1
  import { ClientMockGeneratorBuilder, ContextSpec, FakerMockOptions, FinalizeMockImplementationOptions, GenerateMockImports, GeneratorImport, GeneratorOptions, GeneratorSchema, GeneratorVerbOptions, GlobalMockOptions, MswMockOptions, StrictMockSchemaKind, StrictMockSchemaKind as StrictMockSchemaKind$1 } from "@orval/core";
2
-
3
2
  //#region src/faker/index.d.ts
4
3
  /**
5
4
  * Emits the import header for a faker-only mock file. Faker output never
package/dist/index.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { EnumGeneration, OutputMockType, OutputMode, PropertySortOrder, camelPathParamName, compareVersions, escapeRegExp, generalJSTypesWithArray, generateDependencyImports, getKey, getOperationTagKey, getRefInfo, isBoolean, isFunction, isMswMock, isNumber, isObject, isReference, isSchema, isString, jsStringLiteralEscape, mergeDeep, pascal, resolveRef, stringify, toColonRoutePath } from "@orval/core";
1
+ import { EnumGeneration, OutputMockType, OutputMode, PropertySortOrder, camelPathParamName, compareNatural, compareVersions, escapeRegExp, generalJSTypesWithArray, generateDependencyImports, getKey, getOperationTagKey, getRefInfo, getRequiredKeys, isBoolean, isFunction, isMswMock, isNumber, isObject, isReference, isString, jsStringLiteralEscape, mergeDeep, pascal, resolveRef, stringify, toColonRoutePath } from "@orval/core";
2
2
  import { prop } from "remeda";
3
3
  //#region src/mock-types.ts
4
4
  function isStrictMock(mockOptions) {
@@ -265,6 +265,43 @@ const getDelay = (override, options) => {
265
265
  return false;
266
266
  };
267
267
  //#endregion
268
+ //#region src/faker/getters/all-of-required.ts
269
+ function derefAllOfMember(member, context, seen) {
270
+ let current = member;
271
+ while (current && typeof current === "object" && isReference(current)) {
272
+ const ref = current.$ref;
273
+ if (typeof ref !== "string" || seen.has(ref)) return;
274
+ seen.add(ref);
275
+ const { refPaths } = getRefInfo(ref, context);
276
+ current = Array.isArray(refPaths) ? prop(context.spec, ...refPaths) : void 0;
277
+ }
278
+ return current && typeof current === "object" ? current : void 0;
279
+ }
280
+ function collectAllOfRequiredWithDeclared(schemas, context, seen) {
281
+ const required = [];
282
+ const declared = /* @__PURE__ */ new Set();
283
+ for (const val of schemas) {
284
+ const memberSeen = new Set(seen);
285
+ const schema = derefAllOfMember(val, context, memberSeen);
286
+ if (!schema) continue;
287
+ const properties = schema.properties;
288
+ if (properties && typeof properties === "object") for (const key of Object.keys(properties)) declared.add(key);
289
+ if (Array.isArray(schema.required)) required.push(...schema.required);
290
+ if (Array.isArray(schema.allOf)) {
291
+ const inner = collectAllOfRequiredWithDeclared(schema.allOf, context, memberSeen);
292
+ required.push(...inner.required.filter((name) => inner.declared.has(name) || properties && name in properties));
293
+ for (const key of inner.declared) declared.add(key);
294
+ }
295
+ }
296
+ return {
297
+ required,
298
+ declared
299
+ };
300
+ }
301
+ function collectAllOfRequired(schemas, context) {
302
+ return collectAllOfRequiredWithDeclared(schemas, context, /* @__PURE__ */ new Set()).required;
303
+ }
304
+ //#endregion
268
305
  //#region src/faker/compatible-v9.ts
269
306
  const getFakerPackageVersion = (packageJson) => {
270
307
  return packageJson.resolvedVersions?.["@faker-js/faker"] ?? packageJson.dependencies?.["@faker-js/faker"] ?? packageJson.devDependencies?.["@faker-js/faker"] ?? packageJson.peerDependencies?.["@faker-js/faker"];
@@ -316,6 +353,20 @@ function getReferenceName$1(ref, context) {
316
353
  if (!ref) return "";
317
354
  return getRefInfo(ref, context).name;
318
355
  }
356
+ function isNullableRefTarget(ref, context) {
357
+ return isNullableSchema(resolveRefTarget(ref, context));
358
+ }
359
+ function reExpansionWouldCollapse(ref, context, existingReferencedProperties, nonNullable) {
360
+ const target = resolveRefTarget(ref, context);
361
+ const targetProperties = target?.properties;
362
+ const targetRequired = target?.required;
363
+ if (!targetProperties || !Array.isArray(targetRequired)) return false;
364
+ return Object.entries(targetProperties).some(([key, property]) => {
365
+ if (!targetRequired.includes(key) || !isReference(property)) return false;
366
+ if (!existingReferencedProperties.includes(getReferenceName$1(property.$ref, context))) return false;
367
+ return nonNullable || !isNullableRefTarget(property.$ref, context);
368
+ });
369
+ }
319
370
  function getMockObject({ item, mockOptions, operationId, tags, combine, context, imports, existingReferencedProperties, existingReferencedAllOfRefs = [], splitMockImplementations, allowOverride = false }) {
320
371
  if (isReference(item)) return resolveMockValue({
321
372
  schema: {
@@ -415,15 +466,22 @@ function getMockObject({ item, mockOptions, operationId, tags, combine, context,
415
466
  const includedProperties = [];
416
467
  const entries = Object.entries(itemProperties);
417
468
  if (context.output.propertySortOrder === PropertySortOrder.ALPHABETICAL) entries.sort((a, b) => {
418
- return a[0].localeCompare(b[0], "en", { numeric: true });
469
+ return compareNatural(a[0], b[0]);
419
470
  });
420
471
  const propertyScalars = entries.map(([key, prop]) => {
421
472
  if (combine?.includedProperties.includes(key)) return;
422
473
  const isRequired = mockOptions?.required ?? (Array.isArray(itemRequired) ? itemRequired : []).includes(key);
423
474
  const hasNullable = "nullable" in prop && prop.nullable === true;
424
- if (isReference(prop) && existingReferencedProperties.includes(getReferenceName$1(prop.$ref, context))) {
425
- if (isRequired) return `${getKey(key)}: null`;
426
- return;
475
+ const refName = isReference(prop) ? getReferenceName$1(prop.$ref, context) : "";
476
+ const isRecursiveRef = !!refName && existingReferencedProperties.includes(refName);
477
+ if (isRecursiveRef) {
478
+ if (!isRequired) return;
479
+ const keyDefinition = getKey(key);
480
+ if (!mockOptions?.nonNullable && (hasNullable || isReference(prop) && isNullableRefTarget(prop.$ref, context))) return `${keyDefinition}: null`;
481
+ if (new Set(existingReferencedProperties).size !== existingReferencedProperties.length || isReference(prop) && reExpansionWouldCollapse(prop.$ref, context, existingReferencedProperties, mockOptions?.nonNullable)) {
482
+ imports.push({ name: refName });
483
+ return `${keyDefinition}: {} as unknown as ${refName}`;
484
+ }
427
485
  }
428
486
  const importsBefore = imports.length;
429
487
  const resolvedValue = resolveMockValue({
@@ -445,6 +503,14 @@ function getMockObject({ item, mockOptions, operationId, tags, combine, context,
445
503
  mergeReturnedMockImports(imports, importsBefore, resolvedValue.imports);
446
504
  includedProperties.push(key);
447
505
  const keyDefinition = getKey(key);
506
+ if (isRequired && refName && resolvedValue.value === "undefined") {
507
+ imports.push({ name: refName });
508
+ return `${keyDefinition}: undefined as unknown as ${refName}`;
509
+ }
510
+ if (isRequired && isRecursiveRef && resolvedValue.value.includes(" as unknown as ")) {
511
+ imports.push({ name: refName });
512
+ return `${keyDefinition}: {} as unknown as ${refName}`;
513
+ }
448
514
  const hasDefault = "default" in prop && prop.default !== void 0;
449
515
  if (!isRequired && !resolvedValue.overrided && !hasDefault) {
450
516
  const omitValue = mockOptions?.nonNullable || !hasNullable ? "undefined" : "null";
@@ -675,7 +741,7 @@ function extractArrayItemMock({ items, propertyName, parentName, operationId, ta
675
741
  }
676
742
  //#endregion
677
743
  //#region src/faker/format-example-value.ts
678
- const DATE_FORMATS = new Set(["date", "date-time"]);
744
+ const DATE_FORMATS = /* @__PURE__ */ new Set(["date", "date-time"]);
679
745
  function isDateFormat(format) {
680
746
  return format !== void 0 && DATE_FORMATS.has(format);
681
747
  }
@@ -791,7 +857,7 @@ function getMockScalar({ item, imports, mockOptions, operationId, tags, combine,
791
857
  const operationProperty = resolveMockOverride(safeMockOptions.operations?.[operationId]?.properties, item, nonNullableOption);
792
858
  if (operationProperty) return operationProperty;
793
859
  let overrideTag = { properties: {} };
794
- const sortedTags = Object.entries(safeMockOptions.tags ?? {}).toSorted((a, b) => a[0].localeCompare(b[0], "en", { numeric: true }));
860
+ const sortedTags = Object.entries(safeMockOptions.tags ?? {}).toSorted((a, b) => compareNatural(a[0], b[0]));
795
861
  for (const [tag, options] of sortedTags) {
796
862
  if (!tags.includes(tag)) continue;
797
863
  overrideTag = mergeDeep(overrideTag, options);
@@ -1073,17 +1139,19 @@ function getItemType(item) {
1073
1139
  function getEnum(item, imports, context, existingReferencedProperties, type) {
1074
1140
  if (!item.enum) return "";
1075
1141
  let enumValue = `[${item.enum.filter((e) => e !== null).map((e) => type === "string" || type === void 0 && isString(e) ? `'${jsStringLiteralEscape(e)}'` : e).join(",")}]`;
1076
- if (context.output.override.enumGenerationType === EnumGeneration.ENUM) if (item.isRef || existingReferencedProperties.length === 0) {
1077
- enumValue += ` as ${item.name}${item.name.endsWith("[]") ? "" : "[]"}`;
1078
- imports.push({ name: item.name });
1079
- } else {
1080
- const parentReference = existingReferencedProperties.at(-1);
1081
- if (!parentReference) return "";
1082
- enumValue += ` as ${parentReference}['${item.name}']`;
1083
- if (!item.path?.endsWith("[]")) enumValue += "[]";
1084
- imports.push({ name: parentReference });
1085
- }
1086
- else enumValue += " as const";
1142
+ if (context.output.override.enumGenerationType === EnumGeneration.ENUM) {
1143
+ const isRootSchema = !item.parentName && existingReferencedProperties.at(-1) === item.name;
1144
+ if (item.isRef || existingReferencedProperties.length === 0 || isRootSchema) {
1145
+ enumValue += ` as ${item.name}${item.name.endsWith("[]") ? "" : "[]"}`;
1146
+ imports.push({ name: item.name });
1147
+ } else {
1148
+ const parentReference = existingReferencedProperties.at(-1);
1149
+ if (!parentReference) return "";
1150
+ enumValue += ` as ${parentReference}['${item.name}']`;
1151
+ if (!item.path?.endsWith("[]")) enumValue += "[]";
1152
+ imports.push({ name: parentReference });
1153
+ }
1154
+ } else enumValue += " as const";
1087
1155
  if (item.isRef && type === "string" && context.output.override.enumGenerationType !== EnumGeneration.UNION) {
1088
1156
  enumValue = `Object.values(${item.name})`;
1089
1157
  imports.push({
@@ -1122,6 +1190,15 @@ function resolveMockOverride(properties = {}, item, nonNullableOption) {
1122
1190
  overrided: true
1123
1191
  };
1124
1192
  }
1193
+ /** Resolves a `$ref` string to its schema in the loaded spec, if any. */
1194
+ function resolveRefTarget(ref, context) {
1195
+ if (typeof ref !== "string") return void 0;
1196
+ const [, fragment] = ref.split("#");
1197
+ if (!fragment) return void 0;
1198
+ const { refPaths } = getRefInfo(ref, context);
1199
+ if (!Array.isArray(refPaths)) return void 0;
1200
+ return prop(context.spec, ...refPaths);
1201
+ }
1125
1202
  /** OpenAPI 3.0 `nullable: true` or 3.1 `type` unions that include `null`. */
1126
1203
  function isNullableSchema(schema) {
1127
1204
  if (!schema || typeof schema !== "object") return false;
@@ -1188,14 +1265,15 @@ function hasOverrideTouchingSchema(schemaProperties, mockOptions, operationId, t
1188
1265
  function resolveMockValue({ schema, mockOptions, operationId, tags, combine, context, imports, existingReferencedProperties, existingReferencedAllOfRefs = [], splitMockImplementations, allowOverride }) {
1189
1266
  if (isReference(schema)) {
1190
1267
  const schemaReference = schema;
1191
- const { name, refPaths } = getRefInfo(typeof schema.$ref === "string" ? schema.$ref : "", context);
1192
- const schemaRef = Array.isArray(refPaths) ? prop(context.spec, ...refPaths) : void 0;
1268
+ const schemaRefPath = typeof schema.$ref === "string" ? schema.$ref : "";
1269
+ const { name, refPaths } = getRefInfo(schemaRefPath, context);
1270
+ const schemaRef = resolveRefTarget(schemaRefPath, context);
1193
1271
  const newSchema = {
1194
1272
  ...schemaRef,
1195
1273
  name,
1196
1274
  path: schemaReference.path,
1197
1275
  isRef: true,
1198
- required: [...schemaRef?.required ?? [], ...schemaReference.required ?? []],
1276
+ required: [...schemaRef?.required ?? [], ...getRequiredKeys(schemaReference, name)],
1199
1277
  ...schemaReference.nullable === void 0 ? {} : { nullable: schemaReference.nullable }
1200
1278
  };
1201
1279
  if (combine?.separator === "allOf" && newSchema.discriminator && newSchema.oneOf) {
@@ -1219,7 +1297,9 @@ function resolveMockValue({ schema, mockOptions, operationId, tags, combine, con
1219
1297
  }
1220
1298
  }
1221
1299
  const newSeparator = newSchema.allOf ? "allOf" : newSchema.oneOf ? "oneOf" : "anyOf";
1222
- if (shouldDelegateToSchemaFactories(context) && isComponentsSchemaRef(refPaths) && !hasOverrideTouchingSchema(schemaRef?.properties, mockOptions, operationId, tags, schemaReference.path)) {
1300
+ const targetEffective = schemaRef ? collectAllOfRequiredWithDeclared([schemaRef], context, /* @__PURE__ */ new Set()) : void 0;
1301
+ const delegationDropsRequired = (schemaReference.required ?? []).some((requiredName) => targetEffective?.declared.has(requiredName) && !targetEffective.required.includes(requiredName));
1302
+ if (shouldDelegateToSchemaFactories(context) && isComponentsSchemaRef(refPaths) && !existingReferencedProperties.includes(name) && !delegationDropsRequired && !hasOverrideTouchingSchema(schemaRef?.properties, mockOptions, operationId, tags, schemaReference.path)) {
1223
1303
  const factoryName = `get${pascal(name)}Mock`;
1224
1304
  const factoryImport = {
1225
1305
  name: factoryName,
@@ -1315,8 +1395,7 @@ function resolvesToObjectLike(schema, context, seen = /* @__PURE__ */ new Set())
1315
1395
  if (isReference(schema)) {
1316
1396
  if (typeof schema.$ref !== "string" || seen.has(schema.$ref)) return false;
1317
1397
  seen = new Set(seen).add(schema.$ref);
1318
- const { refPaths } = getRefInfo(schema.$ref, context);
1319
- resolved = Array.isArray(refPaths) ? prop(context.spec, ...refPaths) : void 0;
1398
+ resolved = resolveRefTarget(schema.$ref, context);
1320
1399
  } else resolved = schema;
1321
1400
  if (!resolved) return false;
1322
1401
  if (resolved.type === "object" || resolved.properties || resolved.additionalProperties || resolved.allOf) return true;
@@ -1355,8 +1434,18 @@ function combineSchemasMock({ item, separator, mockOptions, operationId, tags, c
1355
1434
  }
1356
1435
  }
1357
1436
  const hasResolvableProperties = itemEntriesForResolve.some(([key]) => key === "properties");
1437
+ const allRequiredFields = [];
1438
+ if (separator === "allOf") {
1439
+ if (itemRequired) allRequiredFields.push(...itemRequired);
1440
+ allRequiredFields.push(...collectAllOfRequired(separatorItems, context));
1441
+ }
1442
+ const itemSchemaForResolve = Object.fromEntries(itemEntriesForResolve);
1443
+ if (separator === "allOf" && allRequiredFields.length > 0) {
1444
+ const itemResolveRequired = itemSchemaForResolve.required;
1445
+ itemSchemaForResolve.required = [.../* @__PURE__ */ new Set([...allRequiredFields, ...itemResolveRequired ?? []])];
1446
+ }
1358
1447
  const itemResolvedValue = isRefAndNotExisting || hasResolvableProperties ? resolveMockValue({
1359
- schema: Object.fromEntries(itemEntriesForResolve),
1448
+ schema: itemSchemaForResolve,
1360
1449
  combine: {
1361
1450
  separator: "allOf",
1362
1451
  includedProperties: []
@@ -1373,11 +1462,6 @@ function combineSchemasMock({ item, separator, mockOptions, operationId, tags, c
1373
1462
  includedProperties.push(...itemResolvedValue?.includedProperties ?? []);
1374
1463
  combineImports.push(...itemResolvedValue?.imports ?? []);
1375
1464
  let containsOnlyPrimitiveValues = true;
1376
- const allRequiredFields = [];
1377
- if (separator === "allOf") {
1378
- if (itemRequired) allRequiredFields.push(...itemRequired);
1379
- for (const val of separatorItems) if (isSchema(val) && val.required) allRequiredFields.push(...val.required);
1380
- }
1381
1465
  let value = separator === "allOf" ? "" : "faker.helpers.arrayElement([";
1382
1466
  for (const val of separatorItems) {
1383
1467
  const refName = isReference(val) ? getReferenceName(val.$ref, context) : "";
@@ -1701,19 +1785,20 @@ function generateDefinition(name, route, getResponseMockFunctionNameBase, handle
1701
1785
  let mockFactoryParam = "";
1702
1786
  let mockFactoryReturnType = nonVoidMockReturnType;
1703
1787
  let mockFactoryReturnCast = "";
1704
- if (isResponseOverridable) if (strictMock && simpleSchemaReturnType) {
1705
- const signature = getMockFactorySignatureParts(simpleSchemaReturnType, mockOptionsFromOverride, {
1706
- isOverridable: true,
1707
- overrideType: overrideResponseType
1708
- });
1709
- mockFactoryParam = signature.param;
1710
- mockFactoryReturnType = signature.returnType;
1711
- mockFactoryReturnCast = signature.returnCast;
1712
- } else {
1713
- mockFactoryParam = `overrideResponse: ${overrideResponseType} = {}`;
1714
- mockFactoryReturnType = strictMock ? strictMockReturnType : nonVoidMockReturnType;
1715
- }
1716
- else if (strictMock) mockFactoryReturnType = strictMockReturnType;
1788
+ if (isResponseOverridable) {
1789
+ if (strictMock && simpleSchemaReturnType) {
1790
+ const signature = getMockFactorySignatureParts(simpleSchemaReturnType, mockOptionsFromOverride, {
1791
+ isOverridable: true,
1792
+ overrideType: overrideResponseType
1793
+ });
1794
+ mockFactoryParam = signature.param;
1795
+ mockFactoryReturnType = signature.returnType;
1796
+ mockFactoryReturnCast = signature.returnCast;
1797
+ } else {
1798
+ mockFactoryParam = `overrideResponse: ${overrideResponseType} = {}`;
1799
+ mockFactoryReturnType = strictMock ? strictMockReturnType : nonVoidMockReturnType;
1800
+ }
1801
+ } else if (strictMock) mockFactoryReturnType = strictMockReturnType;
1717
1802
  const mockImplementation = isReturnHttpResponse ? `${mockImplementations}${formatMockFactoryDeclaration(getResponseMockFunctionName, mockFactoryParam, mockFactoryReturnType, value, mockFactoryReturnCast, { omitReturnType: Boolean(mockData) })}\n\n` : mockImplementations;
1718
1803
  const delay = getDelay(override, isFunction(mock) ? void 0 : mock);
1719
1804
  const infoParam = "info";
@@ -1724,6 +1809,10 @@ function generateDefinition(name, route, getResponseMockFunctionNameBase, handle
1724
1809
  const binaryContentType = (preferredContentTypeMatch && isBinaryLikeContentType(preferredContentTypeMatch) ? preferredContentTypeMatch : contentTypes.find((ct) => isBinaryLikeContentType(ct))) ?? "application/octet-stream";
1725
1810
  const firstTextCt = isExactlyStringReturnType && !!preferredContentTypeMatch && !isTextLikeContentType(preferredContentTypeMatch) && hasTextLikeContentType ? contentTypes.find((ct) => isTextLikeContentType(ct)) : contentTypesByPreference.find((ct) => isTextLikeContentType(ct));
1726
1811
  const textHelper = firstTextCt === "application/xml" || firstTextCt?.endsWith("+xml") ? "xml" : firstTextCt === "text/html" ? "html" : "text";
1812
+ const firstJsonCt = contentTypesByPreference.find((ct) => ct.includes("json"));
1813
+ const textHelperDefaultContentType = textHelper === "xml" ? "text/xml" : textHelper === "html" ? "text/html" : "text/plain";
1814
+ const jsonCtHeaderSuffix = firstJsonCt && firstJsonCt !== "application/json" ? `, headers: { 'Content-Type': '${firstJsonCt}' }` : "";
1815
+ const textCtHeaderSuffix = firstTextCt && firstTextCt !== textHelperDefaultContentType ? `, headers: { 'Content-Type': '${firstTextCt}' }` : "";
1727
1816
  let responseBody;
1728
1817
  let responsePrelude = "";
1729
1818
  if (isReturnHttpResponse) {
@@ -1745,23 +1834,23 @@ function generateDefinition(name, route, getResponseMockFunctionNameBase, handle
1745
1834
  else if (isVoidUnionType) {
1746
1835
  let nonVoidBody;
1747
1836
  if (needsRuntimeContentTypeSwitch) nonVoidBody = `typeof resolvedBody === 'string'
1748
- ? HttpResponse.${textHelper}(resolvedBody, { status: ${statusCode} })
1749
- : HttpResponse.json(resolvedBody, { status: ${statusCode} })`;
1837
+ ? HttpResponse.${textHelper}(resolvedBody, { status: ${statusCode}${textCtHeaderSuffix} })
1838
+ : HttpResponse.json(resolvedBody, { status: ${statusCode}${jsonCtHeaderSuffix} })`;
1750
1839
  else if (isTextResponse && !shouldPreferJsonResponse) nonVoidBody = `HttpResponse.${textHelper}(
1751
1840
  typeof resolvedBody === 'string' ? resolvedBody : JSON.stringify(resolvedBody ?? null),
1752
- { status: ${statusCode} })`;
1753
- else nonVoidBody = `HttpResponse.json(resolvedBody, { status: ${statusCode} })`;
1841
+ { status: ${statusCode}${textCtHeaderSuffix} })`;
1842
+ else nonVoidBody = `HttpResponse.json(resolvedBody, { status: ${statusCode}${jsonCtHeaderSuffix} })`;
1754
1843
  responseBody = `resolvedBody === undefined
1755
1844
  ? new HttpResponse(null, { status: ${noContentStatusCode} })
1756
1845
  : ${nonVoidBody}`;
1757
1846
  } else if (needsRuntimeContentTypeSwitch) responseBody = `typeof resolvedBody === 'string'
1758
- ? HttpResponse.${textHelper}(resolvedBody, { status: ${statusCode} })
1759
- : HttpResponse.json(resolvedBody, { status: ${statusCode} })`;
1847
+ ? HttpResponse.${textHelper}(resolvedBody, { status: ${statusCode}${textCtHeaderSuffix} })
1848
+ : HttpResponse.json(resolvedBody, { status: ${statusCode}${jsonCtHeaderSuffix} })`;
1760
1849
  else if (isTextResponse && !shouldPreferJsonResponse) responseBody = `HttpResponse.${textHelper}(textBody,
1761
- { status: ${statusCode}
1850
+ { status: ${statusCode}${textCtHeaderSuffix}
1762
1851
  })`;
1763
1852
  else responseBody = `HttpResponse.json(${resolvedResponseExpr},
1764
- { status: ${statusCode}
1853
+ { status: ${statusCode}${jsonCtHeaderSuffix}
1765
1854
  })`;
1766
1855
  const infoType = `Parameters<Parameters<typeof http.${verb}>[1]>[0]`;
1767
1856
  const handlerImplementation = `