Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

convert long numbers to strings in response #131

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 13 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -220,18 +220,19 @@ connect('nedb://memory');

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:

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

: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.

Expand Down
30 changes: 30 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
"axios-cookiejar-support": "^1.0.0",
"form-data": "^3.0.0",
"into-stream": "^5.1.1",
"json-bigint": "^1.0.0",
"lodash": "^4.17.15",
"marpat": "^3.0.5",
"mime-types": "^2.1.26",
Expand Down
16 changes: 15 additions & 1 deletion src/models/agent.model.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ const { Connection } = require('./connection.model');
const axios = require('axios');
const axiosCookieJarSupport = require('axios-cookiejar-support').default;
const { omit } = require('../utilities');
const { parse } = require('../utilities/conversion.utilities');

const instance = axios.create();

Expand Down Expand Up @@ -111,6 +112,15 @@ class Agent extends EmbeddedDocument {
*/
proxy: {
type: Object
},
/**
* return long numbers as strings instead of truncated e notation.
* @member Agent#proxy
* @type Boolean
*/
convertLongNumbersToStrings: {
type: Boolean,
default: () => false
}
});
}
Expand All @@ -126,6 +136,8 @@ class Agent extends EmbeddedDocument {
preInit({ agent, protocol, timeout, concurrency, connection }) {
this.concurrency = concurrency > 0 ? concurrency : 1;

this.convertLongNumbersToStrings = !!this.convertLongNumbersToStrings;

this.connection = Connection.create(connection);
if (agent) this.globalize(protocol, agent);
}
Expand Down Expand Up @@ -213,6 +225,8 @@ class Agent extends EmbeddedDocument {
const id = uuidv4();
const interceptor = instance.interceptors.request.use(
({ httpAgent, httpsAgent, ...request }) => {
request.transformResponse = data =>
parse(data, this.convertLongNumbersToStrings);
instance.interceptors.request.eject(interceptor);
return new Promise((resolve, reject) =>
this.push({
Expand Down Expand Up @@ -384,7 +398,7 @@ class Agent extends EmbeddedDocument {
if (token) {
this.connection.deactivate(token, id);
}

this.connection.confirm();

if (error.code) {
Expand Down
41 changes: 32 additions & 9 deletions src/models/client.model.js
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ class Client extends Document {
threshold,
usage,
proxy,
convertLongNumbersToStrings,
...connection
} = data;
const protocol = data.server.startsWith('https') ? 'https' : 'http';
Expand All @@ -91,6 +92,7 @@ class Client extends Document {
threshold,
concurrency,
protocol,
convertLongNumbersToStrings,
connection
});
}
Expand Down Expand Up @@ -387,7 +389,9 @@ class Client extends Document {
.then(response => response.data)
.then(body => this.data.outgoing(body))
.then(body => this._save(body))
.then(body => parseScriptResult(body))
.then(body =>
parseScriptResult(body, this.agent.convertLongNumbersToStrings)
)
.then(result => resolve(result))
.catch(error => this._save(reject(error)))
);
Expand Down Expand Up @@ -450,7 +454,9 @@ class Client extends Document {
.then(response => response.data)
.then(body => this.data.outgoing(body))
.then(body => this._save(body))
.then(body => parseScriptResult(body))
.then(body =>
parseScriptResult(body, this.agent.convertLongNumbersToStrings)
)
.then(response =>
resolve(parameters.merge ? Object.assign(data, response) : response)
)
Expand Down Expand Up @@ -505,7 +511,9 @@ class Client extends Document {
.then(response => response.data)
.then(body => this.data.outgoing(body))
.then(body => this._save(body))
.then(body => parseScriptResult(body))
.then(body =>
parseScriptResult(body, this.agent.convertLongNumbersToStrings)
)
.then(body =>
resolve(
parameters.merge
Expand Down Expand Up @@ -555,7 +563,9 @@ class Client extends Document {
.then(response => response.data)
.then(body => this.data.outgoing(body))
.then(body => this._save(body))
.then(body => parseScriptResult(body))
.then(body =>
parseScriptResult(body, this.agent.convertLongNumbersToStrings)
)
.then(result => resolve(result))
.catch(error => this._save(reject(error)))
);
Expand Down Expand Up @@ -605,7 +615,9 @@ class Client extends Document {
.then(response => response.data)
.then(body => this.data.outgoing(body))
.then(body => this._save(body))
.then(body => parseScriptResult(body))
.then(body =>
parseScriptResult(body, this.agent.convertLongNumbersToStrings)
)
.then(result => resolve(result))
.catch(error => this._save(reject(error)))
);
Expand Down Expand Up @@ -659,7 +671,9 @@ class Client extends Document {
.then(response => response.data)
.then(body => this.data.outgoing(body))
.then(body => this._save(body))
.then(body => parseScriptResult(body))
.then(body =>
parseScriptResult(body, this.agent.convertLongNumbersToStrings)
)
.then(result => resolve(result))
.catch(error => this._save(reject(error)))
);
Expand Down Expand Up @@ -716,7 +730,9 @@ class Client extends Document {
.then(response => response.data)
.then(body => this.data.outgoing(body))
.then(body => this._save(body))
.then(body => parseScriptResult(body))
.then(body =>
parseScriptResult(body, this.agent.convertLongNumbersToStrings)
)
.then(result => resolve(result))
.catch(error => {
this._save();
Expand Down Expand Up @@ -829,7 +845,9 @@ class Client extends Document {
.then(response => response.data)
.then(body => this.data.outgoing(body))
.then(body => this._save(body))
.then(body => parseScriptResult(body))
.then(body =>
parseScriptResult(body, this.agent.convertLongNumbersToStrings)
)
.then(response => Object.assign(response, { recordId: resolvedId }))
)
.then(response => resolve(response))
Expand Down Expand Up @@ -895,7 +913,12 @@ class Client extends Document {
.then(response => response.data)
.then(body => this.data.outgoing(body))
.then(body => this._save(body))
.then(body => pick(parseScriptResult(body), 'scriptResult'))
.then(body =>
pick(
parseScriptResult(body, this.agent.convertLongNumbersToStrings),
'scriptResult'
)
)
.then(result => resolve(result))
.catch(error => this._save(reject(error)))
);
Expand Down
9 changes: 8 additions & 1 deletion src/utilities/conversion.utilities.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
'use strict';

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

/**
* @class Conversion Utilities
Expand Down Expand Up @@ -105,9 +106,15 @@ const omit = (data, properties) =>
* @description The parse 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.
* @see isJSON
* @param {Any} value The value to attempt to parse.
* @param {boolean} [convertLongNumbersToStrings] convert long numbers to strings.
* @return {Object|Any} A JSON object or array of objects without the properties passed to it
*/
const parse = value => (isJSON(value) ? JSON.parse(value) : value);
const parse = (value, convertLongNumbersToStrings) =>
isJSON(value)
? convertLongNumbersToStrings
? JSONbig.parse(value)
: JSON.parse(value)
: value;

/**
* @function pick
Expand Down
7 changes: 4 additions & 3 deletions src/utilities/filemaker.utilities.js
Original file line number Diff line number Diff line change
Expand Up @@ -111,19 +111,20 @@ const sanitizeParameters = (parameters, safeParameters) =>
);

/**
* @function parseScriptResults
* @function parseScriptResult
* @public
* @memberof Filemaker Utilities
* @description The parseScriptResults function filters the FileMaker DAPI response by testing if a script was triggered
* with the request, then either selecting the response, script error, and script result from the
* response or selecting just the response.
* @param {Object} data The response recieved from the FileMaker DAPI.
* @param {boolean} convertLongNumbersToStrings convert long numbers to strings
* @return {Object} A json object containing the selected data from the Data API Response.
*/
const parseScriptResult = data =>
const parseScriptResult = (data, convertLongNumbersToStrings) =>
_.mapValues(data.response, (value, property, object) =>
property.includes('scriptResult')
? (object[property] = parse(value))
? (object[property] = parse(value, convertLongNumbersToStrings))
: value
);

Expand Down
Loading