airtable
Version:
The official Airtable JavaScript library.
188 lines • 6.98 kB
JavaScript
;
var __assign = (this && this.__assign) || function () {
__assign = Object.assign || function(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
t[p] = s[p];
}
return t;
};
return __assign.apply(this, arguments);
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
var isFunction_1 = __importDefault(require("lodash/isFunction"));
var keys_1 = __importDefault(require("lodash/keys"));
var record_1 = __importDefault(require("./record"));
var callback_to_promise_1 = __importDefault(require("./callback_to_promise"));
var has_1 = __importDefault(require("./has"));
var query_params_1 = require("./query_params");
var object_to_query_param_string_1 = __importDefault(require("./object_to_query_param_string"));
/**
* Builds a query object. Won't fetch until `firstPage` or
* or `eachPage` is called.
*
* Params should be validated prior to being passed to Query
* with `Query.validateParams`.
*/
var Query = /** @class */ (function () {
function Query(table, params) {
this._table = table;
this._params = params;
this.firstPage = callback_to_promise_1.default(firstPage, this);
this.eachPage = callback_to_promise_1.default(eachPage, this, 1);
this.all = callback_to_promise_1.default(all, this);
}
/**
* Validates the parameters for passing to the Query constructor.
*
* @params {object} params parameters to validate
*
* @return an object with two keys:
* validParams: the object that should be passed to the constructor.
* ignoredKeys: a list of keys that will be ignored.
* errors: a list of error messages.
*/
Query.validateParams = function (params) {
var validParams = {};
var ignoredKeys = [];
var errors = [];
for (var _i = 0, _a = keys_1.default(params); _i < _a.length; _i++) {
var key = _a[_i];
var value = params[key];
if (has_1.default(Query.paramValidators, key)) {
var validator = Query.paramValidators[key];
var validationResult = validator(value);
if (validationResult.pass) {
validParams[key] = value;
}
else {
errors.push(validationResult.error);
}
}
else {
ignoredKeys.push(key);
}
}
return {
validParams: validParams,
ignoredKeys: ignoredKeys,
errors: errors,
};
};
Query.paramValidators = query_params_1.paramValidators;
return Query;
}());
/**
* Fetches the first page of results for the query asynchronously,
* then calls `done(error, records)`.
*/
function firstPage(done) {
if (!isFunction_1.default(done)) {
throw new Error('The first parameter to `firstPage` must be a function');
}
this.eachPage(function (records) {
done(null, records);
}, function (error) {
done(error, null);
});
}
/**
* Fetches each page of results for the query asynchronously.
*
* Calls `pageCallback(records, fetchNextPage)` for each
* page. You must call `fetchNextPage()` to fetch the next page of
* results.
*
* After fetching all pages, or if there's an error, calls
* `done(error)`.
*/
function eachPage(pageCallback, done) {
var _this = this;
if (!isFunction_1.default(pageCallback)) {
throw new Error('The first parameter to `eachPage` must be a function');
}
if (!isFunction_1.default(done) && done !== void 0) {
throw new Error('The second parameter to `eachPage` must be a function or undefined');
}
var params = __assign({}, this._params);
var pathAndParamsAsString = "/" + this._table._urlEncodedNameOrId() + "?" + object_to_query_param_string_1.default(params);
var queryParams = {};
var requestData = null;
var method;
var path;
if (params.method === 'post' || pathAndParamsAsString.length > query_params_1.URL_CHARACTER_LENGTH_LIMIT) {
// There is a 16kb limit on GET requests. Since the URL makes up nearly all of the request size, we check for any requests that
// that come close to this limit and send it as a POST instead. Additionally, we'll send the request as a post if it is specified
// with the request params
requestData = params;
method = 'post';
path = "/" + this._table._urlEncodedNameOrId() + "/listRecords";
var paramNames = Object.keys(params);
for (var _i = 0, paramNames_1 = paramNames; _i < paramNames_1.length; _i++) {
var paramName = paramNames_1[_i];
if (query_params_1.shouldListRecordsParamBePassedAsParameter(paramName)) {
// timeZone and userLocale is parsed from the GET request separately from the other params. This parsing
// does not occurring within the body parser we use for POST requests, so this will still need to be passed
// via query params
queryParams[paramName] = params[paramName];
}
else {
requestData[paramName] = params[paramName];
}
}
}
else {
method = 'get';
queryParams = params;
path = "/" + this._table._urlEncodedNameOrId();
}
var inner = function () {
_this._table._base.runAction(method, path, queryParams, requestData, function (err, response, result) {
if (err) {
done(err, null);
}
else {
var next = void 0;
if (result.offset) {
params.offset = result.offset;
next = inner;
}
else {
next = function () {
done(null);
};
}
var records = result.records.map(function (recordJson) {
return new record_1.default(_this._table, null, recordJson);
});
pageCallback(records, next);
}
});
};
inner();
}
/**
* Fetches all pages of results asynchronously. May take a long time.
*/
function all(done) {
if (!isFunction_1.default(done)) {
throw new Error('The first parameter to `all` must be a function');
}
var allRecords = [];
this.eachPage(function (pageRecords, fetchNextPage) {
allRecords.push.apply(allRecords, pageRecords);
fetchNextPage();
}, function (err) {
if (err) {
done(err, null);
}
else {
done(null, allRecords);
}
});
}
module.exports = Query;
//# sourceMappingURL=query.js.map