globalstorage
Version:
Global Storage is a Global Distributed Data Warehouse
833 lines (718 loc) • 29 kB
JavaScript
;
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; var ownKeys = Object.keys(source); if (typeof Object.getOwnPropertySymbols === 'function') { ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function (sym) { return Object.getOwnPropertyDescriptor(source, sym).enumerable; })); } ownKeys.forEach(function (key) { _defineProperty(target, key, source[key]); }); } return target; }
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _nonIterableSpread(); }
function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance"); }
function _iterableToArray(iter) { if (Symbol.iterator in Object(iter) || Object.prototype.toString.call(iter) === "[object Arguments]") return Array.from(iter); }
function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } }
function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _nonIterableRest(); }
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance"); }
function _iterableToArrayLimit(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }
function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
var _require = require('@metarhia/common'),
Uint64 = _require.Uint64,
iter = _require.iter;
var _require2 = require('./errors'),
GSError = _require2.GSError,
errorCodes = _require2.codes;
var _require3 = require('./remote.provider.jstp.api.js'),
createRemoteProviderJstpApi = _require3.createRemoteProviderJstpApi;
var _require4 = require('./utils'),
runIfFn = _require4.runIfFn;
var _require5 = require('./log'),
prepareForLogging = _require5.prepareForLogging,
LogStatus = _require5.LogStatus;
var requireLogging = new Set(['get', 'getDetails', 'set', 'create', 'update', 'delete', 'linkDetails', 'unlinkDetails', 'select', 'execute']);
var opToUserAccess = {
get: 'Read',
getDetails: 'Read',
set: 'Update',
create: 'Insert',
update: 'Update',
delete: 'Delete',
linkDetails: 'Update',
unlinkDetails: 'Update',
select: 'Read',
execute: null
};
var fillLogData = {
get: function get(args, dest) {
dest.Identifier = args[0];
},
getDetails: function getDetails(args, dest) {
dest.Category = args[0];
dest.Identifier = args[1];
dest.Query = {
getDetails: args[2]
};
},
set: function set(args, dest) {
dest.Identifier = args[0].Id;
dest.Patch = args[0];
},
create: function create(args, dest) {
dest.Category = args[0];
dest.Query = args[1];
},
update: function update(args, dest) {
dest.Category = args[0];
dest.Query = args[1];
dest.Patch = args[2];
},
delete: function _delete(args, dest) {
dest.Category = args[0];
dest.Query = args[1];
},
linkDetails: function linkDetails(args, dest) {
dest.Category = args[0];
dest.Query = {
linkDetails: args[1],
from: args[2],
to: args[3]
};
},
unlinkDetails: function unlinkDetails(args, dest) {
dest.Category = args[0];
dest.Query = {
unlinkDetails: args[1],
from: args[2],
to: args[3]
};
},
select: function select(args, dest) {
dest.Category = args[0];
dest.Query = args[1];
},
execute: function execute(args, dest) {
dest.Category = args[0];
dest.Action = args[1];
dest.Query = args[2][1];
}
};
var originalProvider = Symbol('originalProvider'); // Abstract Storage Provider
var StorageProvider =
/*#__PURE__*/
function () {
// Create StorageProvider
// options <Object>
// serverSuffix <Uint64> optional
// serverBitmask <Uint64> optional
// systemSuffix <Uint64> optional
// systemBitmas <Uint64> optional
function StorageProvider(_ref) {
var _ref$serverSuffix = _ref.serverSuffix,
serverSuffix = _ref$serverSuffix === void 0 ? new Uint64(0) : _ref$serverSuffix,
_ref$serverBitmask = _ref.serverBitmask,
serverBitmask = _ref$serverBitmask === void 0 ? new Uint64(0xffffff) : _ref$serverBitmask,
_ref$systemSuffix = _ref.systemSuffix,
systemSuffix = _ref$systemSuffix === void 0 ? null : _ref$systemSuffix,
_ref$systemBitmask = _ref.systemBitmask,
systemBitmask = _ref$systemBitmask === void 0 ? null : _ref$systemBitmask,
_ref$systemLogger = _ref.systemLogger,
systemLogger = _ref$systemLogger === void 0 ? function () {
var _console;
return (_console = console).error.apply(_console, arguments);
} : _ref$systemLogger;
_classCallCheck(this, StorageProvider);
this.active = false;
this.cursorFactory = null;
this.schema = null;
this.systemLogger = systemLogger || function () {};
this.serverSuffix = serverSuffix;
this.serverBitmask = serverBitmask;
this.systemSuffix = systemSuffix;
this.systemBitmask = systemBitmask;
this.serverBitmaskSize = this.serverBitmask.toString(2).length;
} // Open StorageProvider
// options - <Object>
// schema - <Metaschema>
// callback - <Function>
// err - <Error> | <null>
// provider - <StorageProvider>
_createClass(StorageProvider, [{
key: "open",
value: function open(_ref2, callback) {
var schema = _ref2.schema;
this.schema = schema;
callback();
} // Close StorageProvider
// callback - <Function>
// err - <Error> | <null>
// eslint-disable-next-line no-unused-vars
}, {
key: "close",
value: function close(callback) {
throw new GSError(errorCodes.NOT_IMPLEMENTED);
} // Setup StorageProvider
// callback - <Function>
// options - <Object>
// err - <Error> | <null>
// eslint-disable-next-line no-unused-vars
}, {
key: "setup",
value: function setup(options, callback) {
throw new GSError(errorCodes.NOT_IMPLEMENTED);
}
}, {
key: "enableLogging",
value: function enableLogging(ctx) {
return new Proxy(this, {
get: function get(provider, prop, proxy) {
if (prop === originalProvider) return provider;
if (prop === 'loggingEnabled') return true;
if (typeof provider[prop] !== 'function' || !requireLogging.has(prop)) {
return provider[prop];
}
if (prop === 'select') {
return function () {
var _provider$select;
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
args[_key] = arguments[_key];
}
provider.log('select', args, ctx);
return (_provider$select = provider.select).call.apply(_provider$select, [proxy].concat(args)).enableLogging(proxy, ctx, args);
};
}
return function () {
var _provider$prop;
for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
args[_key2] = arguments[_key2];
}
var callback, permissionChecker;
if (args.length === provider[prop].length) {
permissionChecker = args.pop();
callback = args.pop();
} else {
callback = args.pop();
}
provider.log(prop, args, ctx);
(_provider$prop = provider[prop]).call.apply(_provider$prop, [proxy].concat(args, [function (err, result) {
provider.log(prop, args, ctx, err || result);
callback(LogStatus.strip(err), LogStatus.strip(result));
}, permissionChecker]));
};
}
});
} // Generate globally unique id
// callback - <Function>
// err - <Error> | <null>
// id - <string>
// eslint-disable-next-line no-unused-vars
}, {
key: "takeId",
value: function takeId(callback) {
throw new GSError(errorCodes.NOT_IMPLEMENTED);
} // Get object from GlobalStorage
// id - <string>, globally unique object id
// callback - <Function>
// err - <Error> | <null>
// obj - <Object>
// permissionChecker - <Function>, optional
// category - <string>
// options - <Object>
// callback - <Function>
// err - <Error> | <null>
// eslint-disable-next-line no-unused-vars
}, {
key: "get",
value: function get(id, callback, permissionChecker) {
throw new GSError(errorCodes.NOT_IMPLEMENTED);
} // Get details for many-to-many link from GlobalStorage
// category - <string>, category to get details in
// id - <string>, object id
// fieldName - <string>, field with the Many decorator
// callback - <Function>
// err - <Error> | <null>
// details - <Object[]>
// permissionChecker - <Function>, optional
// category - <string>
// options - <Object>
// callback - <Function>
// err - <Error> | <null>
// eslint-disable-next-line no-unused-vars
}, {
key: "getDetails",
value: function getDetails(category, id, fieldName, callback, permissionChecker) {
throw new GSError(errorCodes.NOT_IMPLEMENTED);
} // Set object in GlobalStorage
// obj - <Object>, to be stored
// callback - <Function>
// err - <Error> | <null>
// permissionChecker - <Function>, optional
// category - <string>
// options - <Object>
// callback - <Function>
// err - <Error> | <null>
// eslint-disable-next-line no-unused-vars
}, {
key: "set",
value: function set(obj, callback, permissionChecker) {
throw new GSError(errorCodes.NOT_IMPLEMENTED);
} // Create object in GlobalStorage
// category - <string>, category to store the object in
// obj - <Object>, to be stored
// callback - <Function>
// err - <Error> | <null>
// id - <string>
// permissionChecker - <Function>, optional
// category - <string>
// options - <Object>
// callback - <Function>
// err - <Error> | <null>
// eslint-disable-next-line no-unused-vars
}, {
key: "create",
value: function create(category, obj, callback, permissionChecker) {
throw new GSError(errorCodes.NOT_IMPLEMENTED);
} // Update object in GlobalStorage
// category - <string>, category to update the records in
// query - <Object>, example: { Id }
// patch - <Object>, fields to update
// callback - <Function>
// err - <Error> | <null>
// count - <number>
// permissionChecker - <Function>, optional
// category - <string>
// options - <Object>
// callback - <Function>
// err - <Error> | <null>
// eslint-disable-next-line no-unused-vars
}, {
key: "update",
value: function update(category, query, patch, callback, permissionChecker) {
throw new GSError(errorCodes.NOT_IMPLEMENTED);
} // Delete object in GlobalStorage
// category - <string>, category to delete the records from
// query - <Object>, example: { Id }
// callback - <Function>
// err - <Error> | <null>
// count - <number>
// permissionChecker - <Function>, optional
// category - <string>
// options - <Object>
// callback - <Function>
// err - <Error> | <null>
// eslint-disable-next-line no-unused-vars
}, {
key: "delete",
value: function _delete(category, query, callback, permissionChecker) {
throw new GSError(errorCodes.NOT_IMPLEMENTED);
} // Link records with Many relation between them
// category - <string>, category with field having the Many decorator
// field - <string>, field with the Many decorator
// fromId - <Uint64>, Id of the record in category specified in the first
// argument
// toIds - <Uint64> | <Uint64[]>, Id(s) of the record(s) in category
// specified in the Many decorator of the specified field
// callback - <Function>
// err - <Error> | <null>
// permissionChecker - <Function>, optional
// category - <string>
// options - <Object>
// callback - <Function>
// err - <Error> | <null>
// eslint-disable-next-line no-unused-vars
}, {
key: "linkDetails",
value: function linkDetails(category, field, fromId, toIds, callback, permissionChecker) {
throw new GSError(errorCodes.NOT_IMPLEMENTED);
} // Unlink records with Many relation between them
// category - <string>, category with field having the Many decorator
// field - <string>, field with the Many decorator
// fromId - <Uint64>, Id of the record in category specified in the first
// argument
// toIds - <Uint64> | <Uint64[]>, Id(s) of the record(s) in category
// specified in the Many decorator of the specified field
// callback - <Function>
// err - <Error> | <null>
// permissionChecker - <Function>, optional
// category - <string>
// options - <Object>
// callback - <Function>
// err - <Error> | <null>
// eslint-disable-next-line no-unused-vars
}, {
key: "unlinkDetails",
value: function unlinkDetails(category, field, fromId, toIds, callback, permissionChecker) {
throw new GSError(errorCodes.NOT_IMPLEMENTED);
} // Select objects from GlobalStorage
// category - <string>, category to select the records from
// query - <Object>, fields conditions
// permissionChecker - <Function>, optional
// category - <string>
// options - <Object>
// callback - <Function>
// err - <Error> | <null>
//
// Returns: <Cursor>
// eslint-disable-next-line no-unused-vars
}, {
key: "select",
value: function select(category, query, permissionChecker) {
throw new GSError(errorCodes.NOT_IMPLEMENTED);
} // Execute an action
// category <string> | <null> category name or null to execute public action
// action <string> action name
// actionArgs <Array>
// session <jstp.Session>
// args <Object>
// callback <Function>
// error <Error> | <null>
// result <any>
// permissionChecker - <Function>, optional
// category - <string>
// action - <string>
// callback - <Function>
// err - <Error> | <null>
}, {
key: "execute",
value: function execute(category, action, actionArgs, callback, permissionChecker) {
var _this = this;
runIfFn(permissionChecker, category, action, function (err) {
if (err) {
callback(err);
return;
}
var foundAction;
if (category === null) {
foundAction = _this.schema.actions.get(action);
} else {
var categorySchema = _this.schema.categories.get(category);
if (!categorySchema) {
callback(new GSError(errorCodes.NOT_FOUND));
return;
}
foundAction = categorySchema.actions.get(action);
}
if (!foundAction) {
callback(new GSError(errorCodes.NOT_FOUND));
return;
}
var error;
var _this$schema$createAn = _this.schema.createAndValidate('action', foundAction, actionArgs[1]);
var _this$schema$createAn2 = _slicedToArray(_this$schema$createAn, 2);
error = _this$schema$createAn2[0];
actionArgs[1] = _this$schema$createAn2[1];
if (error) {
process.nextTick(callback, new GSError(errorCodes.INVALID_SCHEMA, "Invalid arguments provided: ".concat(error)));
return;
}
var execute = foundAction.definition.Execute;
execute.apply(void 0, [_this].concat(_toConsumableArray(actionArgs), [_this.loggingEnabled ? callback : function () {
for (var _len3 = arguments.length, args = new Array(_len3), _key3 = 0; _key3 < _len3; _key3++) {
args[_key3] = arguments[_key3];
}
callback.apply(void 0, _toConsumableArray(args.map(LogStatus.strip)));
}]));
});
}
}, {
key: "log",
value: function log(op, args, ctx, response) {
var _this2 = this;
var hasStatus = response instanceof LogStatus;
var record = _objectSpread({}, ctx, {
DateTime: new Date(),
Operation: opToUserAccess[op],
Response: !hasStatus ? response : response.value,
Status: !hasStatus ? 'info' : response.status,
ServerId: this.serverSuffix
});
fillLogData[op](args, record);
var provider = this[originalProvider] || this;
prepareForLogging(provider, record);
provider.create('Log', record, function (err) {
if (err) {
_this2.systemLogger(err);
}
});
} // Get system suffix for given id
// id - <common.Uint64>
//
// Returns: <common.Uint64>
}, {
key: "getSystemSuffix",
value: function getSystemSuffix(id) {
return Uint64.and(id, this.systemBitmask);
} // Check whether data with given id is stored on this system
// id - <common.Uint64>
//
// Returns: <boolean>
}, {
key: "curSystem",
value: function curSystem(id) {
return Uint64.cmp(this.getSystemSuffix(id), this.systemSuffix) === 0;
} // Get server suffix for given id
// id - <common.Uint64>
//
// Returns: <common.Uint64>
}, {
key: "getServerSuffix",
value: function getServerSuffix(id) {
return Uint64.and(id, this.serverBitmask);
} // Check whether data with given id is stored on this server
// id - <common.Uint64>
//
// Returns: <boolean>
}, {
key: "curServer",
value: function curServer(id) {
return Uint64.cmp(this.getServerSuffix(id), this.serverSuffix) === 0;
} // Get id without system and server suffix
// id - <common.Uint64>
//
// Returns: <common.Uint64>
}, {
key: "getLocalId",
value: function getLocalId(id) {
return Uint64.and(Uint64.not(this.serverBitmask), id);
} // Parse id
// id - <common.Uint64>
//
// Returns: <Object>
// systemSuffix - <common.Uint64>, system suffix for given id
// serverSuffix - <common.Uint64>, server suffix for given id
// localId - <common.Uint64>, id without system and server suffix
}, {
key: "parseId",
value: function parseId(id) {
return {
systemSuffix: this.getSystemSuffix(id),
serverSuffix: this.getServerSuffix(id),
localId: this.getLocalId(id)
};
} // List all available applications
// callback - <Function>
// err - <Error> | <null>
// applications - <string[]>
// filtererByRoles - <Function> optional
// applications - <string[]>
// callback - <Function>
// err - <Error> | <null>
// applications - <string[]>
}, {
key: "listApplications",
value: function listApplications(callback, filtererByRoles) {
var result = _toConsumableArray(this.schema.applications.keys());
if (filtererByRoles) {
filtererByRoles(result, callback);
} else {
process.nextTick(callback, null, result);
}
} // List all available categories
// callback - <Function>
// err - <Error> | <null>
// categories - <string[]>
// filtererByPermission - <Function> optional
// categories - <string[]>
// callback - <Function>
// err - <Error> | <null>
// categories - <string[]>
}, {
key: "listCategories",
value: function listCategories(callback, filtererByPermission) {
var result = _toConsumableArray(this.schema.categories.keys());
if (filtererByPermission) {
filtererByPermission(result, callback);
} else {
process.nextTick(callback, null, result);
}
} // List all available actions
// callback - <Function>
// err - <Error> | <null>
// actions - <Object>
// public - <string[]>
// private - <Object>
// [categoryName] - <string[]>
// filtererByPermission - <Function> optional
// actions - <Object>
// callback - <Function>
// err - <Error> | <null>
// actions - <Object>
}, {
key: "listActions",
value: function listActions(callback, filtererByPermission) {
var result = {
public: _toConsumableArray(this.schema.actions.keys()),
private: {}
};
var _iteratorNormalCompletion = true;
var _didIteratorError = false;
var _iteratorError = undefined;
try {
for (var _iterator = this.schema.categories[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
var _step$value = _slicedToArray(_step.value, 2),
key = _step$value[0],
value = _step$value[1];
if (value.actions.size !== 0) {
result.private[key] = _toConsumableArray(value.actions.keys());
}
}
} catch (err) {
_didIteratorError = true;
_iteratorError = err;
} finally {
try {
if (!_iteratorNormalCompletion && _iterator.return != null) {
_iterator.return();
}
} finally {
if (_didIteratorError) {
throw _iteratorError;
}
}
}
if (filtererByPermission) {
filtererByPermission(result, callback);
} else {
process.nextTick(callback, null, result);
}
}
}, {
key: "createJstpApi",
value: function createJstpApi() {
return createRemoteProviderJstpApi(this, this.cursorFactory);
}
}, {
key: "getSchemaSources",
value: function getSchemaSources(callback) {
var _this3 = this;
var _ref3 = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {},
categoryList = _ref3.categoryList,
actionLists = _ref3.actionLists,
appList = _ref3.appList;
process.nextTick(callback, null, iter(this.schema.schemas).filter(function (schema) {
if (!schema.source) return false;
if (categoryList && schema.type === 'category') {
return categoryList.includes(schema.name);
}
if (appList && schema.type === 'application') {
return appList.includes(schema.name);
}
if (actionLists) {
if (schema.type === 'action') {
if (!schema.category) {
return actionLists.public.includes(schema.name);
} else {
var categoryActions = actionLists.private[schema.category];
return categoryActions && categoryActions.includes(schema.name);
}
} else if (schema.type === 'form') {
var _categoryActions = actionLists.private[schema.category];
if (!_categoryActions) return false;
var _this3$schema$categor = _this3.schema.categories.get(schema.category).forms.get(schema.name),
usedIn = _this3$schema$categor.usedIn;
return usedIn.some(function (action) {
return _categoryActions.includes(action);
});
}
}
return true;
}).map(function (schema) {
return {
type: schema.type,
module: schema.module,
name: schema.name,
source: schema.source,
category: schema.category
};
}).toArray());
}
}, {
key: "getCategoryL10n",
value: function getCategoryL10n(langTag, category, callback) {
var categorySchema = this.schema.categories.get(category);
if (!categorySchema) {
process.nextTick(callback, new GSError(errorCodes.NOT_FOUND, "No category ".concat(category, " found")));
return;
}
var l10n = categorySchema.resources.get(langTag);
if (!l10n) {
process.nextTick(callback, new GSError(errorCodes.NOT_FOUND, "No ".concat(langTag, " localization data for ").concat(category, " category")));
return;
}
process.nextTick(callback, null, l10n);
}
}, {
key: "getDomainsL10n",
value: function getDomainsL10n(langTag, callback) {
var l10n = this.schema.resources.domains.get(langTag);
if (!l10n) {
process.nextTick(callback, new GSError(errorCodes.NOT_FOUND, "No ".concat(langTag, " localization data for domains")));
return;
}
process.nextTick(callback, null, l10n);
}
}, {
key: "getCommonL10n",
value: function getCommonL10n(langTag, callback) {
var l10n = this.schema.resources.common.get(langTag);
if (!l10n) {
process.nextTick(callback, new GSError(errorCodes.NOT_FOUND, "No ".concat(langTag, " localization data for common")));
return;
}
process.nextTick(callback, null, l10n);
}
}, {
key: "getFormL10n",
value: function getFormL10n(langTag, category, form, callback) {
var categorySchema = this.schema.categories.get(category);
if (!categorySchema) {
process.nextTick(callback, new GSError(errorCodes.NOT_FOUND, "No category ".concat(category, " found")));
return;
}
var formSchema = categorySchema.forms.get(form);
if (!formSchema) {
process.nextTick(callback, new GSError(errorCodes.NOT_FOUND, "No form ".concat(category, ".").concat(form, " found")));
return;
}
var l10n = formSchema.resources.get(langTag);
if (!l10n) {
process.nextTick(callback, new GSError(errorCodes.NOT_FOUND, "No ".concat(langTag, " localization data for ").concat(category, ".").concat(form, " form")));
return;
}
process.nextTick(callback, null, l10n);
}
}, {
key: "getActionL10n",
value: function getActionL10n(langTag, category, action, callback) {
if (category === null) {
var _actionSchema = this.schema.actions.get(action);
if (!_actionSchema) {
process.nextTick(callback, new GSError(errorCodes.NOT_FOUND, "No public action ".concat(action, " found")));
return;
}
var _l10n = _actionSchema.resources.get(langTag);
if (!_l10n) {
process.nextTick(callback, new GSError(errorCodes.NOT_FOUND, "No ".concat(langTag, " localization data for public action ").concat(action)));
return;
}
process.nextTick(callback, null, _l10n);
return;
}
var categorySchema = this.schema.categories.get(category);
if (!categorySchema) {
process.nextTick(callback, new GSError(errorCodes.NOT_FOUND, "No category ".concat(category, " found")));
return;
}
var actionSchema = categorySchema.actions.get(action);
if (!actionSchema) {
process.nextTick(callback, new GSError(errorCodes.NOT_FOUND, "No action ".concat(category, ".").concat(action, " found")));
return;
}
var l10n = actionSchema.resources.get(langTag);
if (!l10n) {
process.nextTick(callback, new GSError(errorCodes.NOT_FOUND, "No ".concat(langTag, " localization data for ").concat(category, ".").concat(action, " action")));
return;
}
process.nextTick(callback, null, l10n);
}
}]);
return StorageProvider;
}();
module.exports = {
StorageProvider: StorageProvider
};