mirror of
https://github.com/usebruno/bruno.git
synced 2024-11-24 00:43:46 +01:00
fix: lossless json serialization
This commit is contained in:
parent
72c3aaa5ba
commit
103e0a2444
4
package-lock.json
generated
4
package-lock.json
generated
@ -19668,7 +19668,7 @@
|
|||||||
},
|
},
|
||||||
"packages/bruno-electron": {
|
"packages/bruno-electron": {
|
||||||
"name": "bruno",
|
"name": "bruno",
|
||||||
"version": "v1.23.1",
|
"version": "v1.24.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@aws-sdk/credential-providers": "3.525.0",
|
"@aws-sdk/credential-providers": "3.525.0",
|
||||||
"@usebruno/common": "0.1.0",
|
"@usebruno/common": "0.1.0",
|
||||||
@ -19698,6 +19698,7 @@
|
|||||||
"js-yaml": "^4.1.0",
|
"js-yaml": "^4.1.0",
|
||||||
"json-bigint": "^1.0.0",
|
"json-bigint": "^1.0.0",
|
||||||
"lodash": "^4.17.21",
|
"lodash": "^4.17.21",
|
||||||
|
"lossless-json": "^4.0.1",
|
||||||
"mime-types": "^2.1.35",
|
"mime-types": "^2.1.35",
|
||||||
"mustache": "^4.2.0",
|
"mustache": "^4.2.0",
|
||||||
"nanoid": "3.3.4",
|
"nanoid": "3.3.4",
|
||||||
@ -26347,6 +26348,7 @@
|
|||||||
"js-yaml": "^4.1.0",
|
"js-yaml": "^4.1.0",
|
||||||
"json-bigint": "^1.0.0",
|
"json-bigint": "^1.0.0",
|
||||||
"lodash": "^4.17.21",
|
"lodash": "^4.17.21",
|
||||||
|
"lossless-json": "^4.0.1",
|
||||||
"mime-types": "^2.1.35",
|
"mime-types": "^2.1.35",
|
||||||
"mustache": "^4.2.0",
|
"mustache": "^4.2.0",
|
||||||
"nanoid": "3.3.4",
|
"nanoid": "3.3.4",
|
||||||
|
@ -19,7 +19,9 @@
|
|||||||
"test": "jest"
|
"test": "jest"
|
||||||
},
|
},
|
||||||
"jest": {
|
"jest": {
|
||||||
"modulePaths": ["node_modules"]
|
"modulePaths": [
|
||||||
|
"node_modules"
|
||||||
|
]
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@aws-sdk/credential-providers": "3.525.0",
|
"@aws-sdk/credential-providers": "3.525.0",
|
||||||
@ -50,6 +52,7 @@
|
|||||||
"js-yaml": "^4.1.0",
|
"js-yaml": "^4.1.0",
|
||||||
"json-bigint": "^1.0.0",
|
"json-bigint": "^1.0.0",
|
||||||
"lodash": "^4.17.21",
|
"lodash": "^4.17.21",
|
||||||
|
"lossless-json": "^4.0.1",
|
||||||
"mime-types": "^2.1.35",
|
"mime-types": "^2.1.35",
|
||||||
"mustache": "^4.2.0",
|
"mustache": "^4.2.0",
|
||||||
"nanoid": "3.3.4",
|
"nanoid": "3.3.4",
|
||||||
|
@ -16,13 +16,21 @@ const {
|
|||||||
sanitizeDirectoryName
|
sanitizeDirectoryName
|
||||||
} = require('../utils/filesystem');
|
} = require('../utils/filesystem');
|
||||||
const { openCollectionDialog } = require('../app/collections');
|
const { openCollectionDialog } = require('../app/collections');
|
||||||
const { generateUidBasedOnHash, stringifyJson, safeParseJSON, safeStringifyJSON } = require('../utils/common');
|
const { generateUidBasedOnHash, safeParseJSON, safeStringifyJSON } = require('../utils/common');
|
||||||
const { moveRequestUid, deleteRequestUid } = require('../cache/requestUids');
|
const { moveRequestUid, deleteRequestUid } = require('../cache/requestUids');
|
||||||
const { deleteCookiesForDomain, getDomainsWithCookies } = require('../utils/cookies');
|
const { deleteCookiesForDomain, getDomainsWithCookies } = require('../utils/cookies');
|
||||||
const EnvironmentSecretsStore = require('../store/env-secrets');
|
const EnvironmentSecretsStore = require('../store/env-secrets');
|
||||||
|
|
||||||
const environmentSecretsStore = new EnvironmentSecretsStore();
|
const environmentSecretsStore = new EnvironmentSecretsStore();
|
||||||
|
|
||||||
|
const stringifyJson = async (str) => {
|
||||||
|
try {
|
||||||
|
return JSON.stringify(str, null, 2);
|
||||||
|
} catch (err) {
|
||||||
|
return Promise.reject(err);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const envHasSecrets = (environment = {}) => {
|
const envHasSecrets = (environment = {}) => {
|
||||||
const secrets = _.filter(environment.variables, (v) => v.secret);
|
const secrets = _.filter(environment.variables, (v) => v.secret);
|
||||||
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
const URL = require('url');
|
const URL = require('url');
|
||||||
const Socket = require('net').Socket;
|
const Socket = require('net').Socket;
|
||||||
const axios = require('axios');
|
const axios = require('axios');
|
||||||
|
const { safeStringifyJSON } = require('../../utils/common');
|
||||||
const connectionCache = new Map(); // Cache to store checkConnection() results
|
const connectionCache = new Map(); // Cache to store checkConnection() results
|
||||||
|
|
||||||
const LOCAL_IPV6 = '::1';
|
const LOCAL_IPV6 = '::1';
|
||||||
@ -49,7 +50,22 @@ const checkConnection = (host, port) =>
|
|||||||
*/
|
*/
|
||||||
function makeAxiosInstance() {
|
function makeAxiosInstance() {
|
||||||
/** @type {axios.AxiosInstance} */
|
/** @type {axios.AxiosInstance} */
|
||||||
const instance = axios.create();
|
const instance = axios.create({
|
||||||
|
transformRequest: function transformRequest(data, headers) {
|
||||||
|
const isObject = (thing) => thing !== null && typeof thing === 'object';
|
||||||
|
const hasJSONContentType = () => {
|
||||||
|
const contentType = headers?.['Content-Type'] || headers?.['content-type'] || '';
|
||||||
|
return contentType.includes('application/json');
|
||||||
|
};
|
||||||
|
|
||||||
|
if (isObject(data) && hasJSONContentType()) {
|
||||||
|
headers.setContentType('application/json', false);
|
||||||
|
return safeStringifyJSON(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
axios.defaults.transformRequest.forEach((tr) => tr(data, headers));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
instance.interceptors.request.use(async (config) => {
|
instance.interceptors.request.use(async (config) => {
|
||||||
const url = URL.parse(config.url);
|
const url = URL.parse(config.url);
|
||||||
|
@ -16,7 +16,7 @@ const prepareRequest = require('./prepare-request');
|
|||||||
const prepareCollectionRequest = require('./prepare-collection-request');
|
const prepareCollectionRequest = require('./prepare-collection-request');
|
||||||
const prepareGqlIntrospectionRequest = require('./prepare-gql-introspection-request');
|
const prepareGqlIntrospectionRequest = require('./prepare-gql-introspection-request');
|
||||||
const { cancelTokens, saveCancelToken, deleteCancelToken } = require('../../utils/cancel-token');
|
const { cancelTokens, saveCancelToken, deleteCancelToken } = require('../../utils/cancel-token');
|
||||||
const { uuid } = require('../../utils/common');
|
const { uuid, parseJson } = require('../../utils/common');
|
||||||
const interpolateVars = require('./interpolate-vars');
|
const interpolateVars = require('./interpolate-vars');
|
||||||
const { interpolateString } = require('./interpolate-string');
|
const { interpolateString } = require('./interpolate-string');
|
||||||
const { sortFolder, getAllRequestsInFolderRecursively } = require('./helper');
|
const { sortFolder, getAllRequestsInFolderRecursively } = require('./helper');
|
||||||
@ -285,7 +285,7 @@ const parseDataFromResponse = (response) => {
|
|||||||
// Filter out ZWNBSP character
|
// Filter out ZWNBSP character
|
||||||
// https://gist.github.com/antic183/619f42b559b78028d1fe9e7ae8a1352d
|
// https://gist.github.com/antic183/619f42b559b78028d1fe9e7ae8a1352d
|
||||||
data = data.replace(/^\uFEFF/, '');
|
data = data.replace(/^\uFEFF/, '');
|
||||||
data = JSON.parse(data);
|
data = parseJson(data);
|
||||||
} catch {}
|
} catch {}
|
||||||
|
|
||||||
return { data, dataBuffer };
|
return { data, dataBuffer };
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
const { interpolate } = require('@usebruno/common');
|
const { interpolate } = require('@usebruno/common');
|
||||||
const { each, forOwn, cloneDeep, find } = require('lodash');
|
const { each, forOwn, cloneDeep } = require('lodash');
|
||||||
|
const { parseJson, stringifyJson } = require('../../utils/common');
|
||||||
|
|
||||||
const getContentType = (headers = {}) => {
|
const getContentType = (headers = {}) => {
|
||||||
let contentType = '';
|
let contentType = '';
|
||||||
@ -61,9 +62,9 @@ const interpolateVars = (request, envVars = {}, runtimeVariables = {}, processEn
|
|||||||
if (contentType.includes('json')) {
|
if (contentType.includes('json')) {
|
||||||
if (typeof request.data === 'object') {
|
if (typeof request.data === 'object') {
|
||||||
try {
|
try {
|
||||||
let parsed = JSON.stringify(request.data);
|
let parsed = stringifyJson(request.data);
|
||||||
parsed = _interpolate(parsed);
|
parsed = _interpolate(parsed);
|
||||||
request.data = JSON.parse(parsed);
|
request.data = parseJson(parsed);
|
||||||
} catch (err) {}
|
} catch (err) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -75,9 +76,9 @@ const interpolateVars = (request, envVars = {}, runtimeVariables = {}, processEn
|
|||||||
} else if (contentType === 'application/x-www-form-urlencoded') {
|
} else if (contentType === 'application/x-www-form-urlencoded') {
|
||||||
if (typeof request.data === 'object') {
|
if (typeof request.data === 'object') {
|
||||||
try {
|
try {
|
||||||
let parsed = JSON.stringify(request.data);
|
let parsed = stringifyJson(request.data);
|
||||||
parsed = _interpolate(parsed);
|
parsed = _interpolate(parsed);
|
||||||
request.data = JSON.parse(parsed);
|
request.data = parseJson(parsed);
|
||||||
} catch (err) {}
|
} catch (err) {}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
const os = require('os');
|
const os = require('os');
|
||||||
const { get, each, filter, extend, compact } = require('lodash');
|
const { get, each, filter, extend, compact } = require('lodash');
|
||||||
const decomment = require('decomment');
|
const decomment = require('decomment');
|
||||||
var JSONbig = require('json-bigint');
|
const { parseJson } = require('../../utils/common');
|
||||||
const FormData = require('form-data');
|
const FormData = require('form-data');
|
||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
@ -349,7 +349,7 @@ const prepareRequest = (item, collection) => {
|
|||||||
jsonBody = request?.body?.json;
|
jsonBody = request?.body?.json;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
axiosRequest.data = JSONbig.parse(jsonBody);
|
axiosRequest.data = parseJson(jsonBody);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
axiosRequest.data = jsonBody;
|
axiosRequest.data = jsonBody;
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
const { customAlphabet } = require('nanoid');
|
const { customAlphabet } = require('nanoid');
|
||||||
|
const { stringify, parse, LosslessNumber } = require('lossless-json');
|
||||||
|
|
||||||
// a customized version of nanoid without using _ and -
|
// a customized version of nanoid without using _ and -
|
||||||
const uuid = () => {
|
const uuid = () => {
|
||||||
@ -9,25 +10,21 @@ const uuid = () => {
|
|||||||
return customNanoId();
|
return customNanoId();
|
||||||
};
|
};
|
||||||
|
|
||||||
const stringifyJson = async (str) => {
|
const stringifyJson = (data) => {
|
||||||
try {
|
return stringify(data);
|
||||||
return JSON.stringify(str, null, 2);
|
|
||||||
} catch (err) {
|
|
||||||
return Promise.reject(err);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const parseJson = async (obj) => {
|
const parseJson = (data) => {
|
||||||
try {
|
return parse(data, null, (value) => {
|
||||||
return JSON.parse(obj);
|
// By default, this will return the LosslessNumber object for big ints
|
||||||
} catch (err) {
|
// need to convert it into a number
|
||||||
return Promise.reject(err);
|
return new LosslessNumber(value).valueOf();
|
||||||
}
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const safeStringifyJSON = (data) => {
|
const safeStringifyJSON = (data) => {
|
||||||
try {
|
try {
|
||||||
return JSON.stringify(data);
|
return stringify(data);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
@ -35,7 +32,11 @@ const safeStringifyJSON = (data) => {
|
|||||||
|
|
||||||
const safeParseJSON = (data) => {
|
const safeParseJSON = (data) => {
|
||||||
try {
|
try {
|
||||||
return JSON.parse(data);
|
return parse(data, null, (value) => {
|
||||||
|
// By default, this will return the LosslessNumber object for big ints
|
||||||
|
// need to convert it into a number
|
||||||
|
return new LosslessNumber(value).valueOf();
|
||||||
|
});
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
34
packages/bruno-tests/collection/echo/echo bigint.bru
Normal file
34
packages/bruno-tests/collection/echo/echo bigint.bru
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
meta {
|
||||||
|
name: echo bigint
|
||||||
|
type: http
|
||||||
|
seq: 6
|
||||||
|
}
|
||||||
|
|
||||||
|
post {
|
||||||
|
url: {{host}}/api/echo/json
|
||||||
|
body: json
|
||||||
|
auth: none
|
||||||
|
}
|
||||||
|
|
||||||
|
headers {
|
||||||
|
foo: bar
|
||||||
|
}
|
||||||
|
|
||||||
|
auth:basic {
|
||||||
|
username: asd
|
||||||
|
password: j
|
||||||
|
}
|
||||||
|
|
||||||
|
auth:bearer {
|
||||||
|
token:
|
||||||
|
}
|
||||||
|
|
||||||
|
body:json {
|
||||||
|
{
|
||||||
|
"hello": 990531470713421825
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
assert {
|
||||||
|
res.status: eq 200
|
||||||
|
}
|
@ -1,7 +1,7 @@
|
|||||||
meta {
|
meta {
|
||||||
name: echo json
|
name: echo json
|
||||||
type: http
|
type: http
|
||||||
seq: 1
|
seq: 2
|
||||||
}
|
}
|
||||||
|
|
||||||
post {
|
post {
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
meta {
|
meta {
|
||||||
name: echo plaintext
|
name: echo plaintext
|
||||||
type: http
|
type: http
|
||||||
seq: 2
|
seq: 3
|
||||||
}
|
}
|
||||||
|
|
||||||
post {
|
post {
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
meta {
|
meta {
|
||||||
name: echo xml parsed
|
name: echo xml parsed
|
||||||
type: http
|
type: http
|
||||||
seq: 3
|
seq: 4
|
||||||
}
|
}
|
||||||
|
|
||||||
post {
|
post {
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
meta {
|
meta {
|
||||||
name: echo xml raw
|
name: echo xml raw
|
||||||
type: http
|
type: http
|
||||||
seq: 4
|
seq: 5
|
||||||
}
|
}
|
||||||
|
|
||||||
post {
|
post {
|
||||||
|
Loading…
Reference in New Issue
Block a user