Skip to content

Commit a1453bf

Browse files
convert long numbers to strings in response
1 parent 753bbda commit a1453bf

9 files changed

+222
-28
lines changed

README.md

+13-12
Original file line numberDiff line numberDiff line change
@@ -220,18 +220,19 @@ connect('nedb://memory');
220220

221221
After connecting to a datastore you can import and create clients. A client is created using the create method on the Filemaker class. The FileMaker class accepts an object with the following properties:
222222

223-
| Property | Type | Description |
224-
| ------------- | :------------------: | :---------------------------------------------------------------------------------: |
225-
| database | <code>String</code> | The FileMaker database to connect to |
226-
| server | <code>String</code> | The FileMaker server to use as the host. **Note:** Must be an http or https Domain. |
227-
| user | <code>String</code> | The FileMaker user account to be used when authenticating into the Data API |
228-
| password | <code>String</code> | The FileMaker user account's password. |
229-
| [name] | <code>String</code> | A name for the client. |
230-
| [usage] | <code>Boolean</code> | Track Data API usage for this client. **Note:** Default is `true` |
231-
| [timeout] | <code>Number</code> | The default timeout time for requests **Note:** Default is 0, (no timeout) |
232-
| [concurrency] | <code>Number</code> | The number of concurrent requests that will be made to FileMaker |
233-
| [proxy] | <code>Object</code> | settings for a proxy server |
234-
| [agent] | <code>Object</code> | settings for a custom request agent |
223+
| Property | Type | Description |
224+
| ----------------------------- | :------------------: | :---------------------------------------------------------------------------------: |
225+
| database | <code>String</code> | The FileMaker database to connect to |
226+
| server | <code>String</code> | The FileMaker server to use as the host. **Note:** Must be an http or https Domain. |
227+
| user | <code>String</code> | The FileMaker user account to be used when authenticating into the Data API |
228+
| password | <code>String</code> | The FileMaker user account's password. |
229+
| [name] | <code>String</code> | A name for the client. |
230+
| [usage] | <code>Boolean</code> | Track Data API usage for this client. **Note:** Default is `true` |
231+
| [timeout] | <code>Number</code> | The default timeout time for requests **Note:** Default is 0, (no timeout) |
232+
| [concurrency] | <code>Number</code> | The number of concurrent requests that will be made to FileMaker |
233+
| [proxy] | <code>Object</code> | settings for a proxy server |
234+
| [agent] | <code>Object</code> | settings for a custom request agent |
235+
| [convertLongNumbersToStrings] | <code>Boolean</code> | Converts long numbers like Get(UUIDNumber) and Random() to strings in responses |
235236

236237
:warning: You should only use the agent parameter when absolutely necessary. The Data API was designed to be used on https. Deviating from the intended use should be done with caution.
237238

package-lock.json

+30
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

+1
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
"axios-cookiejar-support": "^1.0.0",
4444
"form-data": "^3.0.0",
4545
"into-stream": "^5.1.1",
46+
"json-bigint": "^1.0.0",
4647
"lodash": "^4.17.15",
4748
"marpat": "^3.0.5",
4849
"mime-types": "^2.1.26",

src/models/agent.model.js

+15-1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ const { Connection } = require('./connection.model');
1111
const axios = require('axios');
1212
const axiosCookieJarSupport = require('axios-cookiejar-support').default;
1313
const { omit } = require('../utilities');
14+
const JSONbig = require('json-bigint')({ storeAsString: true });
1415

1516
const instance = axios.create();
1617

@@ -111,6 +112,15 @@ class Agent extends EmbeddedDocument {
111112
*/
112113
proxy: {
113114
type: Object
115+
},
116+
/**
117+
* return long numbers as strings instead of truncated e notation.
118+
* @member Agent#proxy
119+
* @type Boolean
120+
*/
121+
convertLongNumbersToStrings: {
122+
type: Boolean,
123+
default: () => false
114124
}
115125
});
116126
}
@@ -126,6 +136,8 @@ class Agent extends EmbeddedDocument {
126136
preInit({ agent, protocol, timeout, concurrency, connection }) {
127137
this.concurrency = concurrency > 0 ? concurrency : 1;
128138

139+
this.convertLongNumbersToStrings = !!this.convertLongNumbersToStrings;
140+
129141
this.connection = Connection.create(connection);
130142
if (agent) this.globalize(protocol, agent);
131143
}
@@ -213,6 +225,8 @@ class Agent extends EmbeddedDocument {
213225
const id = uuidv4();
214226
const interceptor = instance.interceptors.request.use(
215227
({ httpAgent, httpsAgent, ...request }) => {
228+
if (this.convertLongNumbersToStrings)
229+
request.transformResponse = data => JSONbig.parse(data);
216230
instance.interceptors.request.eject(interceptor);
217231
return new Promise((resolve, reject) =>
218232
this.push({
@@ -384,7 +398,7 @@ class Agent extends EmbeddedDocument {
384398
if (token) {
385399
this.connection.deactivate(token, id);
386400
}
387-
401+
388402
this.connection.confirm();
389403

390404
if (error.code) {

src/models/client.model.js

+32-9
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ class Client extends Document {
8080
threshold,
8181
usage,
8282
proxy,
83+
convertLongNumbersToStrings,
8384
...connection
8485
} = data;
8586
const protocol = data.server.startsWith('https') ? 'https' : 'http';
@@ -91,6 +92,7 @@ class Client extends Document {
9192
threshold,
9293
concurrency,
9394
protocol,
95+
convertLongNumbersToStrings,
9496
connection
9597
});
9698
}
@@ -387,7 +389,9 @@ class Client extends Document {
387389
.then(response => response.data)
388390
.then(body => this.data.outgoing(body))
389391
.then(body => this._save(body))
390-
.then(body => parseScriptResult(body))
392+
.then(body =>
393+
parseScriptResult(body, this.agent.convertLongNumbersToStrings)
394+
)
391395
.then(result => resolve(result))
392396
.catch(error => this._save(reject(error)))
393397
);
@@ -450,7 +454,9 @@ class Client extends Document {
450454
.then(response => response.data)
451455
.then(body => this.data.outgoing(body))
452456
.then(body => this._save(body))
453-
.then(body => parseScriptResult(body))
457+
.then(body =>
458+
parseScriptResult(body, this.agent.convertLongNumbersToStrings)
459+
)
454460
.then(response =>
455461
resolve(parameters.merge ? Object.assign(data, response) : response)
456462
)
@@ -505,7 +511,9 @@ class Client extends Document {
505511
.then(response => response.data)
506512
.then(body => this.data.outgoing(body))
507513
.then(body => this._save(body))
508-
.then(body => parseScriptResult(body))
514+
.then(body =>
515+
parseScriptResult(body, this.agent.convertLongNumbersToStrings)
516+
)
509517
.then(body =>
510518
resolve(
511519
parameters.merge
@@ -555,7 +563,9 @@ class Client extends Document {
555563
.then(response => response.data)
556564
.then(body => this.data.outgoing(body))
557565
.then(body => this._save(body))
558-
.then(body => parseScriptResult(body))
566+
.then(body =>
567+
parseScriptResult(body, this.agent.convertLongNumbersToStrings)
568+
)
559569
.then(result => resolve(result))
560570
.catch(error => this._save(reject(error)))
561571
);
@@ -605,7 +615,9 @@ class Client extends Document {
605615
.then(response => response.data)
606616
.then(body => this.data.outgoing(body))
607617
.then(body => this._save(body))
608-
.then(body => parseScriptResult(body))
618+
.then(body =>
619+
parseScriptResult(body, this.agent.convertLongNumbersToStrings)
620+
)
609621
.then(result => resolve(result))
610622
.catch(error => this._save(reject(error)))
611623
);
@@ -659,7 +671,9 @@ class Client extends Document {
659671
.then(response => response.data)
660672
.then(body => this.data.outgoing(body))
661673
.then(body => this._save(body))
662-
.then(body => parseScriptResult(body))
674+
.then(body =>
675+
parseScriptResult(body, this.agent.convertLongNumbersToStrings)
676+
)
663677
.then(result => resolve(result))
664678
.catch(error => this._save(reject(error)))
665679
);
@@ -716,7 +730,9 @@ class Client extends Document {
716730
.then(response => response.data)
717731
.then(body => this.data.outgoing(body))
718732
.then(body => this._save(body))
719-
.then(body => parseScriptResult(body))
733+
.then(body =>
734+
parseScriptResult(body, this.agent.convertLongNumbersToStrings)
735+
)
720736
.then(result => resolve(result))
721737
.catch(error => {
722738
this._save();
@@ -829,7 +845,9 @@ class Client extends Document {
829845
.then(response => response.data)
830846
.then(body => this.data.outgoing(body))
831847
.then(body => this._save(body))
832-
.then(body => parseScriptResult(body))
848+
.then(body =>
849+
parseScriptResult(body, this.agent.convertLongNumbersToStrings)
850+
)
833851
.then(response => Object.assign(response, { recordId: resolvedId }))
834852
)
835853
.then(response => resolve(response))
@@ -895,7 +913,12 @@ class Client extends Document {
895913
.then(response => response.data)
896914
.then(body => this.data.outgoing(body))
897915
.then(body => this._save(body))
898-
.then(body => pick(parseScriptResult(body), 'scriptResult'))
916+
.then(body =>
917+
pick(
918+
parseScriptResult(body, this.agent.convertLongNumbersToStrings),
919+
'scriptResult'
920+
)
921+
)
899922
.then(result => resolve(result))
900923
.catch(error => this._save(reject(error)))
901924
);

src/utilities/conversion.utilities.js

+13
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
'use strict';
22

33
const _ = require('lodash');
4+
const JSONbig = require('json-bigint')({ storeAsString: true });
45

56
/**
67
* @class Conversion Utilities
@@ -109,6 +110,17 @@ const omit = (data, properties) =>
109110
*/
110111
const parse = value => (isJSON(value) ? JSON.parse(value) : value);
111112

113+
/**
114+
* @function parseBigInt
115+
* @public
116+
* @memberof Conversion Utilities
117+
* @description The parseBigInt function performs a try catch before attempting to parse the value as JSON. If the value is not valid JSON it wil return the value. Long numbers are returned as strings.
118+
* @see isJSON
119+
* @param {Any} value The value to attempt to parse.
120+
* @return {Object|Any} A JSON object or array of objects without the properties passed to it
121+
*/
122+
const parseBigInt = value => (isJSON(value) ? JSONbig.parse(value) : value);
123+
112124
/**
113125
* @function pick
114126
* @public
@@ -158,5 +170,6 @@ module.exports = {
158170
omit,
159171
pick,
160172
parse,
173+
parseBigInt,
161174
deepMapKeys
162175
};

src/utilities/filemaker.utilities.js

+7-4
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
'use strict';
22

33
const _ = require('lodash');
4-
const { stringify, parse } = require('./conversion.utilities');
4+
const { stringify, parse, parseBigInt } = require('./conversion.utilities');
55

66
/** @class Filemaker Utilities */
77

@@ -111,19 +111,22 @@ const sanitizeParameters = (parameters, safeParameters) =>
111111
);
112112

113113
/**
114-
* @function parseScriptResults
114+
* @function parseScriptResult
115115
* @public
116116
* @memberof Filemaker Utilities
117117
* @description The parseScriptResults function filters the FileMaker DAPI response by testing if a script was triggered
118118
* with the request, then either selecting the response, script error, and script result from the
119119
* response or selecting just the response.
120120
* @param {Object} data The response recieved from the FileMaker DAPI.
121+
* @param {boolean} convertLongNumbersToStrings convert long numbers to strings
121122
* @return {Object} A json object containing the selected data from the Data API Response.
122123
*/
123-
const parseScriptResult = data =>
124+
const parseScriptResult = (data, convertLongNumbersToStrings) =>
124125
_.mapValues(data.response, (value, property, object) =>
125126
property.includes('scriptResult')
126-
? (object[property] = parse(value))
127+
? (object[property] = convertLongNumbersToStrings
128+
? parseBigInt(value)
129+
: parse(value))
127130
: value
128131
);
129132

0 commit comments

Comments
 (0)