@gitbook/react-openapi 0.7.1 → 1.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.
Files changed (118) hide show
  1. package/CHANGELOG.md +49 -0
  2. package/dist/InteractiveSection.d.ts +4 -8
  3. package/dist/InteractiveSection.jsx +60 -0
  4. package/dist/Markdown.d.ts +1 -2
  5. package/dist/Markdown.jsx +5 -0
  6. package/dist/OpenAPICodeSample.d.ts +2 -4
  7. package/dist/OpenAPICodeSample.jsx +141 -0
  8. package/dist/OpenAPIDisclosure.d.ts +12 -0
  9. package/dist/OpenAPIDisclosure.jsx +32 -0
  10. package/dist/OpenAPIDisclosureGroup.d.ts +19 -0
  11. package/dist/OpenAPIDisclosureGroup.jsx +81 -0
  12. package/dist/OpenAPIOperation.d.ts +2 -4
  13. package/dist/OpenAPIOperation.jsx +51 -0
  14. package/dist/OpenAPIOperationContext.d.ts +16 -0
  15. package/dist/OpenAPIOperationContext.jsx +26 -0
  16. package/dist/OpenAPIPath.d.ts +8 -0
  17. package/dist/OpenAPIPath.jsx +54 -0
  18. package/dist/OpenAPIRequestBody.d.ts +4 -5
  19. package/dist/OpenAPIRequestBody.jsx +22 -0
  20. package/dist/OpenAPIResponse.d.ts +4 -4
  21. package/dist/OpenAPIResponse.jsx +39 -0
  22. package/dist/OpenAPIResponseExample.d.ts +2 -4
  23. package/dist/OpenAPIResponseExample.jsx +108 -0
  24. package/dist/OpenAPIResponses.d.ts +3 -4
  25. package/dist/OpenAPIResponses.jsx +35 -0
  26. package/dist/OpenAPISchema.d.ts +11 -8
  27. package/dist/OpenAPISchema.jsx +285 -0
  28. package/dist/OpenAPISchemaName.d.ts +12 -0
  29. package/dist/OpenAPISchemaName.jsx +15 -0
  30. package/dist/OpenAPISecurities.d.ts +2 -4
  31. package/dist/OpenAPISecurities.jsx +55 -0
  32. package/dist/OpenAPIServerURL.d.ts +2 -3
  33. package/dist/OpenAPIServerURL.jsx +67 -0
  34. package/dist/OpenAPIServerURLVariable.d.ts +2 -3
  35. package/dist/OpenAPIServerURLVariable.jsx +8 -0
  36. package/dist/OpenAPISpec.d.ts +3 -4
  37. package/dist/OpenAPISpec.jsx +91 -0
  38. package/dist/OpenAPITabs.d.ts +26 -0
  39. package/dist/OpenAPITabs.jsx +103 -0
  40. package/dist/ScalarApiButton.d.ts +3 -3
  41. package/dist/ScalarApiButton.jsx +51 -0
  42. package/dist/code-samples.d.ts +4 -0
  43. package/dist/code-samples.js +103 -38
  44. package/dist/generateSchemaExample.d.ts +2 -2
  45. package/dist/generateSchemaExample.js +29 -102
  46. package/dist/index.d.ts +3 -2
  47. package/dist/index.js +2 -1
  48. package/dist/resolveOpenAPIOperation.d.ts +11 -0
  49. package/dist/resolveOpenAPIOperation.js +194 -0
  50. package/dist/stringifyOpenAPI.d.ts +4 -0
  51. package/dist/stringifyOpenAPI.js +6 -0
  52. package/dist/tsconfig.build.tsbuildinfo +1 -0
  53. package/dist/types.d.ts +11 -12
  54. package/dist/useSyncedTabsGlobalState.d.ts +1 -0
  55. package/dist/useSyncedTabsGlobalState.js +16 -0
  56. package/dist/utils.d.ts +6 -2
  57. package/dist/utils.js +13 -6
  58. package/package.json +12 -10
  59. package/src/InteractiveSection.tsx +90 -86
  60. package/src/Markdown.tsx +2 -3
  61. package/src/OpenAPICodeSample.tsx +43 -31
  62. package/src/OpenAPIDisclosure.tsx +50 -0
  63. package/src/OpenAPIDisclosureGroup.tsx +136 -0
  64. package/src/OpenAPIOperation.tsx +36 -42
  65. package/src/OpenAPIOperationContext.tsx +45 -0
  66. package/src/OpenAPIPath.tsx +65 -0
  67. package/src/OpenAPIRequestBody.tsx +10 -17
  68. package/src/OpenAPIResponse.tsx +27 -45
  69. package/src/OpenAPIResponseExample.tsx +89 -31
  70. package/src/OpenAPIResponses.tsx +48 -17
  71. package/src/OpenAPISchema.test.ts +1 -1
  72. package/src/OpenAPISchema.tsx +129 -108
  73. package/src/OpenAPISchemaName.tsx +27 -0
  74. package/src/OpenAPISecurities.tsx +45 -24
  75. package/src/OpenAPIServerURL.tsx +17 -10
  76. package/src/OpenAPIServerURLVariable.tsx +2 -4
  77. package/src/OpenAPISpec.tsx +58 -58
  78. package/src/OpenAPITabs.tsx +153 -0
  79. package/src/ScalarApiButton.tsx +84 -7
  80. package/src/code-samples.test.ts +51 -0
  81. package/src/code-samples.ts +95 -31
  82. package/src/generateSchemaExample.ts +26 -153
  83. package/src/index.ts +3 -2
  84. package/src/resolveOpenAPIOperation.test.ts +177 -0
  85. package/src/resolveOpenAPIOperation.ts +164 -0
  86. package/src/stringifyOpenAPI.ts +6 -0
  87. package/src/types.ts +17 -10
  88. package/src/useSyncedTabsGlobalState.ts +23 -0
  89. package/src/utils.ts +14 -7
  90. package/dist/InteractiveSection.js +0 -47
  91. package/dist/Markdown.js +0 -6
  92. package/dist/OpenAPICodeSample.js +0 -110
  93. package/dist/OpenAPIOperation.js +0 -38
  94. package/dist/OpenAPIRequestBody.js +0 -18
  95. package/dist/OpenAPIResponse.js +0 -32
  96. package/dist/OpenAPIResponseExample.js +0 -54
  97. package/dist/OpenAPIResponses.js +0 -18
  98. package/dist/OpenAPISchema.js +0 -235
  99. package/dist/OpenAPISchema.test.d.ts +0 -1
  100. package/dist/OpenAPISchema.test.js +0 -91
  101. package/dist/OpenAPISecurities.js +0 -42
  102. package/dist/OpenAPIServerURL.js +0 -51
  103. package/dist/OpenAPIServerURLVariable.js +0 -10
  104. package/dist/OpenAPISpec.js +0 -70
  105. package/dist/ScalarApiButton.js +0 -14
  106. package/dist/fetchOpenAPIOperation.d.ts +0 -72
  107. package/dist/fetchOpenAPIOperation.js +0 -124
  108. package/dist/fetchOpenAPIOperation.test.d.ts +0 -1
  109. package/dist/fetchOpenAPIOperation.test.js +0 -152
  110. package/dist/resolveOpenAPIPath.d.ts +0 -7
  111. package/dist/resolveOpenAPIPath.js +0 -112
  112. package/dist/resolveOpenAPIPath.test.d.ts +0 -1
  113. package/dist/resolveOpenAPIPath.test.js +0 -39
  114. package/dist/tsconfig.tsbuildinfo +0 -1
  115. package/src/fetchOpenAPIOperation.test.ts +0 -185
  116. package/src/fetchOpenAPIOperation.ts +0 -230
  117. package/src/resolveOpenAPIPath.test.ts +0 -60
  118. package/src/resolveOpenAPIPath.ts +0 -145
@@ -1,119 +1,46 @@
1
- import { noReference } from './utils';
1
+ import { getExampleFromSchema } from '@scalar/oas-utils/spec-getters';
2
2
  /**
3
3
  * Generate a JSON example from a schema
4
4
  */
5
- export function generateSchemaExample(schema, options = {}, ancestors = new Set()) {
6
- const { onlyRequired = false } = options;
7
- if (ancestors.has(schema)) {
8
- return undefined;
9
- }
10
- if (typeof schema.example !== 'undefined') {
11
- return schema.example;
12
- }
13
- if (schema.enum && schema.enum.length > 0) {
14
- return schema.enum[0];
15
- }
16
- if (schema.type === 'string') {
17
- if (schema.default) {
18
- return schema.default;
19
- }
20
- if (schema.format === 'date-time') {
21
- return new Date().toISOString();
22
- }
23
- if (schema.format === 'date') {
24
- return new Date().toISOString().split('T')[0];
25
- }
26
- if (schema.format === 'email') {
27
- return 'name@gmail.com';
28
- }
29
- if (schema.format === 'hostname') {
30
- return 'example.com';
31
- }
32
- if (schema.format === 'ipv4') {
33
- return '0.0.0.0';
34
- }
35
- if (schema.format === 'ipv6') {
36
- return '2001:0db8:85a3:0000:0000:8a2e:0370:7334';
37
- }
38
- if (schema.format === 'uri') {
39
- return 'https://example.com';
40
- }
41
- if (schema.format === 'uuid') {
42
- return '123e4567-e89b-12d3-a456-426614174000';
43
- }
44
- if (schema.format === 'binary') {
45
- return 'binary';
46
- }
47
- if (schema.format === 'byte') {
48
- return 'Ynl0ZXM=';
49
- }
50
- if (schema.format === 'password') {
51
- return 'password';
52
- }
53
- return 'text';
54
- }
55
- if (schema.type === 'number' || schema.type === 'integer') {
56
- return schema.default || 0;
57
- }
58
- if (schema.type === 'boolean') {
59
- return schema.default || false;
60
- }
61
- if (schema.type === 'array') {
62
- if (schema.items) {
63
- const exampleValue = generateSchemaExample(noReference(schema.items), options, new Set(ancestors).add(schema));
64
- if (exampleValue !== undefined) {
65
- return [exampleValue];
66
- }
67
- return [];
68
- }
69
- return [];
70
- }
71
- if (schema.properties) {
72
- const example = {};
73
- const props = onlyRequired ? (schema.required ?? []) : Object.keys(schema.properties);
74
- for (const key of props) {
75
- const property = noReference(schema.properties[key]);
76
- if (property && (onlyRequired || !property.deprecated)) {
77
- const exampleValue = generateSchemaExample(noReference(property), options, new Set(ancestors).add(schema));
78
- if (exampleValue !== undefined) {
79
- example[key] = exampleValue;
80
- }
81
- }
82
- }
83
- return example;
84
- }
85
- if (schema.oneOf && schema.oneOf.length > 0) {
86
- return generateSchemaExample(noReference(schema.oneOf[0]), options, new Set(ancestors).add(schema));
87
- }
88
- if (schema.anyOf && schema.anyOf.length > 0) {
89
- return generateSchemaExample(noReference(schema.anyOf[0]), options, new Set(ancestors).add(schema));
90
- }
91
- if (schema.allOf && schema.allOf.length > 0) {
92
- return schema.allOf.reduce((acc, curr) => {
93
- const example = generateSchemaExample(noReference(curr), options, new Set(ancestors).add(schema));
94
- if (typeof example === 'object' && !Array.isArray(example) && example !== null) {
95
- return { ...acc, ...example };
96
- }
97
- return acc;
98
- }, {});
99
- }
100
- return undefined;
5
+ export function generateSchemaExample(schema, options) {
6
+ if (options === void 0) { options = {}; }
7
+ return getExampleFromSchema(schema, {
8
+ emptyString: 'text',
9
+ omitEmptyAndOptionalProperties: options.onlyRequired,
10
+ variables: {
11
+ 'date-time': new Date().toISOString(),
12
+ date: new Date().toISOString().split('T')[0],
13
+ email: 'name@gmail.com',
14
+ hostname: 'example.com',
15
+ ipv4: '0.0.0.0',
16
+ ipv6: '2001:0db8:85a3:0000:0000:8a2e:0370:7334',
17
+ uri: 'https://example.com',
18
+ uuid: '123e4567-e89b-12d3-a456-426614174000',
19
+ binary: 'binary',
20
+ byte: 'Ynl0ZXM=',
21
+ password: 'password',
22
+ },
23
+ });
101
24
  }
102
25
  /**
103
26
  * Generate an example for a media type.
104
27
  */
105
- export function generateMediaTypeExample(mediaType, options = {}) {
28
+ export function generateMediaTypeExample(mediaType, options) {
29
+ if (options === void 0) { options = {}; }
106
30
  if (mediaType.example) {
107
31
  return mediaType.example;
108
32
  }
109
33
  if (mediaType.examples) {
110
- const example = mediaType.examples[Object.keys(mediaType.examples)[0]];
111
- if (example) {
112
- return noReference(example).value;
34
+ var key = Object.keys(mediaType.examples)[0];
35
+ if (key) {
36
+ var example = mediaType.examples[key];
37
+ if (example) {
38
+ return example.value;
39
+ }
113
40
  }
114
41
  }
115
42
  if (mediaType.schema) {
116
- return generateSchemaExample(noReference(mediaType.schema), options);
43
+ return generateSchemaExample(mediaType.schema, options);
117
44
  }
118
45
  return undefined;
119
46
  }
package/dist/index.d.ts CHANGED
@@ -1,3 +1,4 @@
1
- export * from './fetchOpenAPIOperation';
1
+ export * from './resolveOpenAPIOperation';
2
2
  export * from './OpenAPIOperation';
3
- export type { OpenAPIFetcher } from './types';
3
+ export * from './OpenAPIOperationContext';
4
+ export type { OpenAPIOperationData } from './types';
package/dist/index.js CHANGED
@@ -1,2 +1,3 @@
1
- export * from './fetchOpenAPIOperation';
1
+ export * from './resolveOpenAPIOperation';
2
2
  export * from './OpenAPIOperation';
3
+ export * from './OpenAPIOperationContext';
@@ -0,0 +1,11 @@
1
+ import { toJSON, fromJSON } from 'flatted';
2
+ import { type OpenAPIV3xDocument, type Filesystem } from '@gitbook/openapi-parser';
3
+ import { OpenAPIOperationData } from './types';
4
+ export { toJSON, fromJSON };
5
+ /**
6
+ * Resolve an OpenAPI operation in a file and compile it to a more usable format.
7
+ */
8
+ export declare function resolveOpenAPIOperation(filesystem: Filesystem<OpenAPIV3xDocument>, operationDescriptor: {
9
+ path: string;
10
+ method: string;
11
+ }): Promise<OpenAPIOperationData | null>;
@@ -0,0 +1,194 @@
1
+ var __assign = (this && this.__assign) || function () {
2
+ __assign = Object.assign || function(t) {
3
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
4
+ s = arguments[i];
5
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
6
+ t[p] = s[p];
7
+ }
8
+ return t;
9
+ };
10
+ return __assign.apply(this, arguments);
11
+ };
12
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
13
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
14
+ return new (P || (P = Promise))(function (resolve, reject) {
15
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
16
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
17
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
18
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
19
+ });
20
+ };
21
+ var __generator = (this && this.__generator) || function (thisArg, body) {
22
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
23
+ return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
24
+ function verb(n) { return function (v) { return step([n, v]); }; }
25
+ function step(op) {
26
+ if (f) throw new TypeError("Generator is already executing.");
27
+ while (g && (g = 0, op[0] && (_ = 0)), _) try {
28
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
29
+ if (y = 0, t) op = [op[0] & 2, t.value];
30
+ switch (op[0]) {
31
+ case 0: case 1: t = op; break;
32
+ case 4: _.label++; return { value: op[1], done: false };
33
+ case 5: _.label++; y = op[1]; op = [0]; continue;
34
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
35
+ default:
36
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
37
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
38
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
39
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
40
+ if (t[2]) _.ops.pop();
41
+ _.trys.pop(); continue;
42
+ }
43
+ op = body.call(thisArg, _);
44
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
45
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
46
+ }
47
+ };
48
+ var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
49
+ if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
50
+ if (ar || !(i in from)) {
51
+ if (!ar) ar = Array.prototype.slice.call(from, 0, i);
52
+ ar[i] = from[i];
53
+ }
54
+ }
55
+ return to.concat(ar || Array.prototype.slice.call(from));
56
+ };
57
+ import { toJSON, fromJSON } from 'flatted';
58
+ import { dereference, } from '@gitbook/openapi-parser';
59
+ import { checkIsReference } from './utils';
60
+ export { toJSON, fromJSON };
61
+ /**
62
+ * Resolve an OpenAPI operation in a file and compile it to a more usable format.
63
+ */
64
+ export function resolveOpenAPIOperation(filesystem, operationDescriptor) {
65
+ return __awaiter(this, void 0, void 0, function () {
66
+ var path, method, schema, operation, commonParameters, servers, security, securities, _i, security_1, entry, securityKey, securityScheme;
67
+ var _a, _b, _c, _d, _e, _f;
68
+ return __generator(this, function (_g) {
69
+ switch (_g.label) {
70
+ case 0:
71
+ path = operationDescriptor.path, method = operationDescriptor.method;
72
+ return [4 /*yield*/, memoDereferenceFilesystem(filesystem)];
73
+ case 1:
74
+ schema = _g.sent();
75
+ operation = getOperationByPathAndMethod(schema, path, method);
76
+ if (!operation) {
77
+ return [2 /*return*/, null];
78
+ }
79
+ commonParameters = getPathObjectParameter(schema, path);
80
+ if (commonParameters) {
81
+ operation = __assign(__assign({}, operation), { parameters: __spreadArray(__spreadArray([], commonParameters, true), ((_a = operation.parameters) !== null && _a !== void 0 ? _a : []), true) });
82
+ }
83
+ servers = 'servers' in schema ? ((_b = schema.servers) !== null && _b !== void 0 ? _b : []) : [];
84
+ security = flattenSecurities((_d = (_c = operation.security) !== null && _c !== void 0 ? _c : schema.security) !== null && _d !== void 0 ? _d : []);
85
+ securities = [];
86
+ for (_i = 0, security_1 = security; _i < security_1.length; _i++) {
87
+ entry = security_1[_i];
88
+ securityKey = Object.keys(entry)[0];
89
+ if (securityKey) {
90
+ securityScheme = (_f = (_e = schema.components) === null || _e === void 0 ? void 0 : _e.securitySchemes) === null || _f === void 0 ? void 0 : _f[securityKey];
91
+ if (securityScheme && !checkIsReference(securityScheme)) {
92
+ securities.push([securityKey, securityScheme]);
93
+ }
94
+ }
95
+ }
96
+ return [2 /*return*/, {
97
+ servers: servers,
98
+ operation: operation,
99
+ method: method,
100
+ path: path,
101
+ securities: securities,
102
+ 'x-codeSamples': typeof schema['x-codeSamples'] === 'boolean' ? schema['x-codeSamples'] : undefined,
103
+ 'x-hideTryItPanel': typeof schema['x-hideTryItPanel'] === 'boolean'
104
+ ? schema['x-hideTryItPanel']
105
+ : undefined,
106
+ }];
107
+ }
108
+ });
109
+ });
110
+ }
111
+ var dereferenceCache = new WeakMap();
112
+ /**
113
+ * Memoized version of `dereferenceSchema`.
114
+ */
115
+ function memoDereferenceFilesystem(filesystem) {
116
+ if (dereferenceCache.has(filesystem)) {
117
+ return dereferenceCache.get(filesystem);
118
+ }
119
+ var promise = dereferenceFilesystem(filesystem);
120
+ dereferenceCache.set(filesystem, promise);
121
+ return promise;
122
+ }
123
+ /**
124
+ * Dereference an OpenAPI schema.
125
+ */
126
+ function dereferenceFilesystem(filesystem) {
127
+ return __awaiter(this, void 0, void 0, function () {
128
+ var result;
129
+ return __generator(this, function (_a) {
130
+ switch (_a.label) {
131
+ case 0: return [4 /*yield*/, dereference(filesystem)];
132
+ case 1:
133
+ result = _a.sent();
134
+ if (!result.schema) {
135
+ throw new Error('Failed to dereference OpenAPI document');
136
+ }
137
+ return [2 /*return*/, result.schema];
138
+ }
139
+ });
140
+ });
141
+ }
142
+ /**
143
+ * Get a path object from its path.
144
+ */
145
+ function getPathObject(schema, path) {
146
+ var _a;
147
+ if ((_a = schema.paths) === null || _a === void 0 ? void 0 : _a[path]) {
148
+ return schema.paths[path];
149
+ }
150
+ return null;
151
+ }
152
+ /**
153
+ * Resolve parameters from a path in an OpenAPI schema.
154
+ */
155
+ function getPathObjectParameter(schema, path) {
156
+ var pathObject = getPathObject(schema, path);
157
+ if (pathObject === null || pathObject === void 0 ? void 0 : pathObject.parameters) {
158
+ return pathObject.parameters;
159
+ }
160
+ return null;
161
+ }
162
+ /**
163
+ * Get an operation by its path and method.
164
+ */
165
+ function getOperationByPathAndMethod(schema, path, method) {
166
+ // Types are buffy for OpenAPIV3_1.OperationObject, so we use v3
167
+ var pathObject = getPathObject(schema, path);
168
+ if (!pathObject) {
169
+ return null;
170
+ }
171
+ var normalizedMethod = method.toLowerCase();
172
+ if (!pathObject[normalizedMethod]) {
173
+ return null;
174
+ }
175
+ return pathObject[normalizedMethod];
176
+ }
177
+ /**
178
+ * Flatten security objects in case they are nested.
179
+ * @example [{bearerAuth:[], basicAuth:[]}] => [{ bearerAuth: [] }, { basicAuth: [] }]
180
+ */
181
+ function flattenSecurities(security) {
182
+ if (!Array.isArray(security) || security.length === 0) {
183
+ return [];
184
+ }
185
+ return security.flatMap(function (securityObject) {
186
+ return Object.entries(securityObject).map(function (_a) {
187
+ var _b;
188
+ var authType = _a[0], config = _a[1];
189
+ return (_b = {},
190
+ _b[authType] = config,
191
+ _b);
192
+ });
193
+ });
194
+ }
@@ -0,0 +1,4 @@
1
+ /**
2
+ * Stringify an OpenAPI object. Same API as JSON.stringify.
3
+ */
4
+ export declare function stringifyOpenAPI(body: unknown, transformer?: null, indent?: number): string;
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Stringify an OpenAPI object. Same API as JSON.stringify.
3
+ */
4
+ export function stringifyOpenAPI(body, transformer, indent) {
5
+ return JSON.stringify(body, transformer, indent);
6
+ }