@readme/oas-to-har 30.0.2 → 31.0.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.js CHANGED
@@ -4,6 +4,7 @@ import {
4
4
 
5
5
  // src/index.ts
6
6
  import { parse as parseDataUrl } from "@readme/data-urls";
7
+ import Oas from "oas";
7
8
  import { HEADERS, PROXY_ENABLED } from "oas/extensions";
8
9
  import { Operation } from "oas/operation";
9
10
  import { isRef as isRef2 } from "oas/types";
@@ -35,7 +36,7 @@ import qs from "qs";
35
36
 
36
37
  // src/lib/utils.ts
37
38
  import { isRef } from "oas/types";
38
- import { getParameterContentType as getParameterContentTypeUtil } from "oas/utils";
39
+ import { dereferenceRef, getParameterContentType as getParameterContentTypeUtil } from "oas/utils";
39
40
  function hasSchemaType(schema, discriminator) {
40
41
  if (Array.isArray(schema.type)) {
41
42
  return schema.type.includes(discriminator);
@@ -50,7 +51,7 @@ function getSafeRequestBody(obj) {
50
51
  }
51
52
  return obj;
52
53
  }
53
- function getSubschemas(schema, opts) {
54
+ function getSubschemas(schema, api, opts) {
54
55
  let subSchemaDataSize = 0;
55
56
  if (opts.parentIsArray) {
56
57
  const parentData = get(opts.payload, opts.parentKey || "");
@@ -62,22 +63,67 @@ function getSubschemas(schema, opts) {
62
63
  let subschemas = [];
63
64
  if (subSchemaDataSize > 0) {
64
65
  for (let idx = 0; idx < subSchemaDataSize; idx += 1) {
65
- subschemas = subschemas.concat(
66
- Object.entries(schema).map(([key, subschema]) => ({
67
- key: opts.parentKey ? [opts.parentKey, idx, key].join(".") : key,
68
- schema: getSafeRequestBody(subschema)
69
- }))
70
- );
66
+ const foundSubschemas = getSubschemas(schema, api, {
67
+ ...opts,
68
+ parentIsArray: false,
69
+ parentKey: opts.parentKey ? [opts.parentKey, idx].join(".") : String(idx)
70
+ });
71
+ if (foundSubschemas) {
72
+ subschemas = subschemas.concat(foundSubschemas);
73
+ }
71
74
  }
72
75
  } else {
73
- subschemas = Object.entries(schema).map(([key, subschema]) => ({
74
- key: opts.parentKey ? [opts.parentKey, key].join(".") : key,
75
- schema: getSafeRequestBody(subschema)
76
- }));
76
+ let resolvedSchema = schema;
77
+ if (schema && isRef(schema)) {
78
+ resolvedSchema = dereferenceRef(schema, api);
79
+ if (!resolvedSchema || isRef(resolvedSchema)) {
80
+ return subschemas;
81
+ }
82
+ }
83
+ const baseKey = opts.parentKey ?? "";
84
+ if (resolvedSchema.properties && typeof resolvedSchema.properties === "object") {
85
+ for (const [propName, propSchema] of Object.entries(resolvedSchema.properties)) {
86
+ if (propSchema && typeof propSchema === "object") {
87
+ const resolved = isRef(propSchema) ? dereferenceRef(propSchema, api) : propSchema;
88
+ if (resolved && !isRef(resolved)) {
89
+ subschemas.push({
90
+ key: baseKey ? [baseKey, propName].join(".") : propName,
91
+ schema: resolved
92
+ });
93
+ }
94
+ }
95
+ }
96
+ }
97
+ if (!("properties" in resolvedSchema) && typeof resolvedSchema === "object" && !("type" in resolvedSchema && resolvedSchema.type !== "object")) {
98
+ for (const [propName, propSchema] of Object.entries(resolvedSchema)) {
99
+ if (propSchema && (Array.isArray(propSchema) || typeof propSchema === "object" && propSchema !== null)) {
100
+ const raw = getSafeRequestBody(propSchema);
101
+ const resolved = isRef(raw) ? dereferenceRef(raw, api) : raw;
102
+ const toPush = resolved && !isRef(resolved) ? resolved : raw;
103
+ if (toPush && typeof toPush === "object") {
104
+ subschemas.push({
105
+ key: baseKey ? [baseKey, propName].join(".") : propName,
106
+ schema: toPush
107
+ });
108
+ }
109
+ }
110
+ }
111
+ }
112
+ if ("items" in resolvedSchema && resolvedSchema.items !== void 0 && resolvedSchema.items !== true) {
113
+ const itemsSchema = resolvedSchema.items;
114
+ const resolved = isRef(itemsSchema) ? dereferenceRef(itemsSchema, api) : itemsSchema;
115
+ if (resolved && !isRef(resolved)) {
116
+ subschemas.push({
117
+ key: baseKey,
118
+ schema: resolved,
119
+ parentIsArray: true
120
+ });
121
+ }
122
+ }
77
123
  }
78
124
  return subschemas;
79
125
  }
80
- function getTypedFormatsInSchema(format, schema, opts) {
126
+ function getTypedFormatsInSchema(format, schema, api, opts) {
81
127
  try {
82
128
  if (schema?.format === format) {
83
129
  if (opts.parentIsArray) {
@@ -93,33 +139,28 @@ function getTypedFormatsInSchema(format, schema, opts) {
93
139
  }
94
140
  } else if (opts.parentKey && get(opts.payload, opts.parentKey) !== void 0) {
95
141
  return opts.parentKey;
96
- } else if (opts.payload !== void 0) {
142
+ } else if (!opts.parentKey && opts.payload !== void 0) {
97
143
  return true;
98
144
  }
99
145
  return false;
100
146
  }
101
- const subschemas = getSubschemas(schema, opts);
147
+ const subschemas = getSubschemas(schema, api, opts);
102
148
  if (!subschemas) {
103
149
  return false;
104
150
  }
105
- return subschemas.flatMap(({ key, schema: subschema }) => {
106
- if ("properties" in subschema) {
107
- return getTypedFormatsInSchema(format, subschema.properties, { payload: opts.payload, parentKey: key });
108
- } else if ("items" in subschema) {
109
- if (subschema.items?.properties) {
110
- return getTypedFormatsInSchema(format, subschema.items.properties, {
111
- payload: opts.payload,
112
- parentKey: key,
113
- parentIsArray: true
114
- });
151
+ return subschemas.flatMap(({ key, schema: subschema, parentIsArray: entryIsArray }) => {
152
+ if (isRef(subschema)) {
153
+ const resolved = dereferenceRef(subschema, api);
154
+ if (resolved && !isRef(resolved)) {
155
+ return resolved;
115
156
  }
116
- return getTypedFormatsInSchema(format, subschema.items, {
117
- payload: opts.payload,
118
- parentKey: key,
119
- parentIsArray: true
120
- });
157
+ return false;
121
158
  }
122
- return getTypedFormatsInSchema(format, subschema, { payload: opts.payload, parentKey: key });
159
+ return getTypedFormatsInSchema(format, subschema, api, {
160
+ payload: opts.payload,
161
+ parentKey: key,
162
+ parentIsArray: entryIsArray
163
+ });
123
164
  }).filter(Boolean);
124
165
  } catch {
125
166
  return [];
@@ -145,6 +186,27 @@ function getParameterContentSchema(param, contentType) {
145
186
  }
146
187
  return null;
147
188
  }
189
+ function parseJsonStringsInBody(obj) {
190
+ if (typeof obj === "string") {
191
+ try {
192
+ const p = JSON.parse(obj);
193
+ return typeof p === "object" && p !== null ? parseJsonStringsInBody(p) : p;
194
+ } catch {
195
+ return obj;
196
+ }
197
+ }
198
+ if (Array.isArray(obj)) {
199
+ return obj.map(parseJsonStringsInBody);
200
+ }
201
+ if (obj !== null && typeof obj === "object") {
202
+ const out = {};
203
+ for (const [k, v] of Object.entries(obj)) {
204
+ out[k] = parseJsonStringsInBody(v);
205
+ }
206
+ return out;
207
+ }
208
+ return obj;
209
+ }
148
210
 
149
211
  // src/lib/style-formatting/style-serializer.ts
150
212
  var isRfc3986Reserved = (char) => ":/?#[]@!$&'()*+,;=".indexOf(char) > -1;
@@ -689,8 +751,9 @@ function encodeBodyForHAR(body) {
689
751
  function oasToHar(oas, operationSchema, values = {}, auth = {}, opts = { proxyUrl: "" }) {
690
752
  let operation;
691
753
  if (!operationSchema || typeof operationSchema.getParameters !== "function") {
754
+ const currentOas = Oas.init(oas);
692
755
  operation = new Operation(
693
- oas,
756
+ currentOas,
694
757
  operationSchema?.path || "",
695
758
  operationSchema?.method || "",
696
759
  operationSchema || { path: "", method: "" }
@@ -757,9 +820,10 @@ function oasToHar(oas, operationSchema, values = {}, auth = {}, opts = { proxyUr
757
820
  });
758
821
  }
759
822
  if (operation.schema.responses) {
760
- Object.keys(operation.schema.responses).some((response) => {
761
- if (isRef2(operation.schema.responses?.[response])) return false;
762
- const content = (operation.schema.responses?.[response]).content;
823
+ Object.keys(operation.schema.responses).some((statusCode) => {
824
+ const response = operation.getResponseByStatusCode(statusCode);
825
+ if (!response) return false;
826
+ const content = response.content;
763
827
  if (!content) return false;
764
828
  if (Object.keys(formData.header || {}).find((h) => h.toLowerCase() === "accept")) return true;
765
829
  har.headers.push({
@@ -853,11 +917,15 @@ function oasToHar(oas, operationSchema, values = {}, auth = {}, opts = { proxyUr
853
917
  return false;
854
918
  });
855
919
  if (cleanBody !== void 0) {
856
- const multipartParams = multipartBodyToFormatterParams(
857
- formData.body,
858
- operation.schema.requestBody.content["multipart/form-data"],
859
- safeBodySchema
860
- );
920
+ let multipartParams = [];
921
+ const multipartContent = operation.getRequestBody("multipart/form-data");
922
+ if (typeof multipartContent === "object" && multipartContent !== null && // `getRequestBody()` will return an array if there are multiple content types that
923
+ // match the one we're looking for but because we're looking for an exact
924
+ // `multipart/form-data` match `getRequestBody()` will only ever return a single
925
+ // object back for us.
926
+ !Array.isArray(multipartContent)) {
927
+ multipartParams = multipartBodyToFormatterParams(formData.body, multipartContent, safeBodySchema);
928
+ }
861
929
  if (multipartParams.length) {
862
930
  Object.keys(cleanBody).forEach((name) => {
863
931
  const param = multipartParams.find((multipartParam) => multipartParam.name === name);
@@ -888,7 +956,9 @@ function oasToHar(oas, operationSchema, values = {}, auth = {}, opts = { proxyUr
888
956
  if (hasSchemaType(requestBody.schema, "string") || hasSchemaType(requestBody.schema, "integer") || hasSchemaType(requestBody.schema, "number") || hasSchemaType(requestBody.schema, "boolean")) {
889
957
  har.postData.text = JSON.stringify(JSON.parse(cleanBody));
890
958
  } else {
891
- const jsonTypes = getTypedFormatsInSchema("json", requestBodySchema.properties, { payload: cleanBody });
959
+ const jsonTypes = getTypedFormatsInSchema("json", requestBodySchema, operation.api, {
960
+ payload: cleanBody
961
+ });
892
962
  if (Array.isArray(jsonTypes) && jsonTypes.length) {
893
963
  try {
894
964
  jsonTypes.forEach((prop) => {
@@ -905,7 +975,16 @@ function oasToHar(oas, operationSchema, values = {}, auth = {}, opts = { proxyUr
905
975
  har.postData.text = stringify(formData.body);
906
976
  }
907
977
  } else {
908
- har.postData.text = encodeBodyForHAR(formData.body);
978
+ try {
979
+ const parsed = parseJsonStringsInBody(cleanBody);
980
+ if (typeof parsed?.RAW_BODY !== "undefined") {
981
+ har.postData.text = isPrimitive(parsed.RAW_BODY) ? String(parsed.RAW_BODY) : stringify(parsed.RAW_BODY);
982
+ } else {
983
+ har.postData.text = JSON.stringify(parsed);
984
+ }
985
+ } catch {
986
+ har.postData.text = encodeBodyForHAR(formData.body);
987
+ }
909
988
  }
910
989
  }
911
990
  }