UNPKG

backendless

Version:

Backendless JavaScript SDK for Node.js and the browser

587 lines (450 loc) 12.8 kB
import Request from 'backendless-request' import APIRequest from './request' import Urls from './urls' import Utils from './utils' import Expression from './expression' const DEFAULT_PROPS = { appId : null, apiKey : null, serverURL : 'https://api.backendless.com', automationServerURL: null, domain : null, apiURI : '/api', debugMode : false, standalone : false, XMLHttpRequest : typeof XMLHttpRequest !== 'undefined' ? XMLHttpRequest : undefined, } const STATELESS_PROPS = ['appId', 'apiKey', 'domain'] const previousBackendless = Utils.globalScope && Utils.globalScope.Backendless const showLegacyDataWarning = () => { if (!showLegacyDataWarning.isShown) { // eslint-disable-next-line no-console console.warn('Backendless.Persistence is deprecated namespace, use Backendless.Data instead') showLegacyDataWarning.isShown = true } } // Backendless supports three signatures for the initApp method // two args - applicationId {String} and secretKey {String} // one argument - domain {String} // one argument - whole set of options {Object} const parseInitConfig = (...args) => { const [appId, apiKey] = args if (appId && typeof appId === 'object') { return appId } if (typeof appId === 'string' && !apiKey) { return { domain: appId } } return { appId, apiKey } } const validateConfig = config => { if (config.domain) { if (!config.domain.startsWith('https://') && !config.domain.startsWith('http://')) { throw new Error( 'When initialize the SDK with a custom domain it should start with http:// or https://, ' + 'for example: Backendless.initApp(\'https://foobar.com\')' ) } } } const SERVICES = { 'Logging' : () => require('./logging').default, 'Counters' : () => require('./counters').default, 'Cache' : () => require('./cache').default, 'Commerce' : () => require('./commerce').default, 'Users' : () => require('./users').default, 'BL' : () => require('./bl').default, 'Data' : () => require('./data').default, 'Hive' : () => require('./hive').default, 'Messaging' : () => require('./messaging').default, 'Files' : () => require('./files').default, 'RT' : () => require('./rt').default, 'SharedObject': () => require('./rso').default, 'LocalCache' : () => require('./local-cache').default, 'UnitOfWork' : () => require('./unit-of-work').default, 'Management' : () => require('./management').default, 'Automations' : () => require('./automations').default, } class Backendless { constructor(props) { this.initConfig(props) this.Request = Request this.request = new APIRequest(this) this.urls = new Urls(this) } /** * @param {Object} config */ initConfig(config) { config = { ...config } if (config.domain) { delete config.appId delete config.apiKey } for (const key in DEFAULT_PROPS) { if (DEFAULT_PROPS.hasOwnProperty(key)) { const privateKey = `__${key}` if (STATELESS_PROPS.includes(key)) { delete this[privateKey] } const defaultValue = this[privateKey] === undefined ? DEFAULT_PROPS[key] : this[privateKey] this[privateKey] = config[key] === undefined ? defaultValue : config[key] } } } /** * @param {string|Object} appId|domain|config * @param {string} [apiKey] * @returns {Backendless} */ initApp() { const config = parseInitConfig(...arguments) validateConfig(config) const app = config.standalone ? new Backendless(this) : this app.initConfig(config) app.resetRT() app.__removeService('LocalCache') app.appInfoPromise() const loggingConfig = Object.assign({ loadLevels: true, globalLevel: 'all', levels: {} }, config.logging) if (app.__hasService('Logging')) { app.Logging.reset() app.Logging.setConfig(loggingConfig) } if (app.__hasService('Users')) { app.Users.currentUser = null } delete this.__device app.loggingConfig = loggingConfig return app } appInfoPromise(reset) { if (reset || !this.__appInfoPromise) { this.__appInfoPromise = new Promise((resolve, reject) => { this.request.get({ url: this.urls.appInfo() }) .then(resolve) .catch(error => { if (error.code === 3064) { this.setCurrentUserToken(null) return this.request.get({ url: this.urls.appInfo() }) } throw error }) .catch(reject) }) } this.__appInfoPromise .catch(error => { // eslint-disable-next-line no-console console.error('could not load backendless app info', error) }) return this.__appInfoPromise } __hasService(name) { return !!this[`__${name}`] } __removeService(name) { delete this[`__${name}`] } __getService(name) { const privateName = `__${name}` if (!this[privateName]) { const Service = SERVICES[name]() this[privateName] = new Service(this) } return this[privateName] } ///--------SETTERS/GETTERS-------/// ///--------standalone-------/// get standalone() { return this.__standalone } set standalone(standalone) { throw new Error( 'Setting value to Backendless.standalone directly is not possible, ' + `instead you must use Backendless.initApp({ appId: [APP_ID], apiKey: [API_KEY], standalone: ${standalone} })` ) } get appId() { return this.__appId } set appId(appId) { throw new Error( `Setting '${appId}' value to Backendless.appId directly is not possible, ` + `instead you must use Backendless.initApp('${appId}', API_KEY)` ) } get apiKey() { return this.__apiKey } set apiKey(apiKey) { throw new Error( `Setting '${apiKey}' value to Backendless.apiKey directly is not possible, ` + `instead you must use Backendless.initApp(APP_ID, '${apiKey}')` ) } ///--------serverURL-------/// get serverURL() { return this.__serverURL } set serverURL(url) { this.__serverURL = url } ///--------automationServerURL-------/// get automationServerURL() { return this.__automationServerURL } set automationServerURL(url) { this.__automationServerURL = url } ///--------domain-------/// get domain() { return this.__domain } set domain(domain) { this.__domain = domain } ///--------apiURI-------/// get apiURI() { return this.__apiURI } set apiURI(apiURI) { this.__apiURI = apiURI } ///--------appPath-------/// get appPath() { if (this.domain) { return this.domain + this.apiURI } if (this.appId && this.apiKey) { return [this.serverURL, this.appId, this.apiKey].join('/') } return null } set appPath(appPath) { throw new Error( `Setting '${appPath}' value to Backendless.appPath directly is not possible, ` + 'instead you must use Backendless.initApp(APP_ID, API_KEY) for setup the value' ) } get automationPath() { if (!this.automationServerURL) { return this.appPath } return [this.automationServerURL, this.appId, this.apiKey].join('/') } set automationPath(automationPath) { throw new Error( `Setting '${automationPath}' value to Backendless.automationPath directly is not possible` ) } ///--------debugMode-------/// get debugMode() { return this.__debugMode } set debugMode(debugMode) { debugMode = !!debugMode if (this.__debugMode !== debugMode) { this.__debugMode = debugMode if (this.__RT) { this.RT.setDebugMode(debugMode) } } } ///--------XMLHttpRequestMode-------/// get XMLHttpRequest() { return this.__XMLHttpRequest } set XMLHttpRequest(XMLHttpRequest) { this.__XMLHttpRequest = XMLHttpRequest } ///--------device-------/// get device() { if (!this.__device) { throw new Error('Device is not defined. Please, run the Backendless.setupDevice') } return this.__device } set device(props) { throw new Error( 'Setting value to Backendless.device directly is not possible, ' + 'instead you must use Backendless.setupDevice(deviceProperties) for setup the device' ) } setupDevice(device) { const Device = require('./device').default this.__device = new Device(device) } ///----------UTIL METHODS--------/// get Utils() { return Utils } getCurrentUserToken() { return this.Users.getCurrentUserToken() } setCurrentUserToken(userToken) { this.Users.setCurrentUserToken(userToken) } get browser() { return require('./user-agent').getUserAgent() } noConflict() { if (Utils.globalScope) { Utils.globalScope.Backendless = previousBackendless } return this } ///-------------------------------------/// ///-------------- SERVICES -------------/// get Logging() { return this.__getService('Logging') } get Counters() { return this.__getService('Counters') } get Cache() { return this.__getService('Cache') } get Commerce() { return this.__getService('Commerce') } get Users() { return this.__getService('Users') } get User() { return require('./users/user').default } get UserService() { return this.Users } get BL() { return this.__getService('BL') } get CustomServices() { return this.BL.CustomServices } get APIServices() { return this.BL.CustomServices } get Events() { return this.BL.Events } get Data() { return this.__getService('Data') } get Hive() { return this.__getService('Hive') } get Messaging() { return this.__getService('Messaging') } get Files() { return this.__getService('Files') } get RT() { return this.__getService('RT') } resetRT() { if (this.__RT) { this.__RT.terminate() delete this.__RT } } get SharedObject() { return this.__getService('SharedObject') } get LocalCache() { return this.__getService('LocalCache') } get UnitOfWork() { return this.__getService('UnitOfWork') } get Management() { return this.__getService('Management') } get Automations() { return this.__getService('Automations') } ///-------------- SERVICES -------------/// ///-------------------------------------/// ///-------------------------------------/// ///--------BACKWARD COMPATIBILITY-------/// /** @deprecated */ get applicationId() { // eslint-disable-next-line no-console // temporary comment it because it breaks JS-CodeRunner version less than 6.3.0 // console.warn('getter/setter for Backendless.applicationId is deprecated, instead use Backendless.appId') return this.appId } /** @deprecated */ set applicationId(appId) { // eslint-disable-next-line no-console console.warn('getter/setter for Backendless.applicationId is deprecated, instead use Backendless.appId') this.appId = appId } /** @deprecated */ get secretKey() { // eslint-disable-next-line no-console console.warn('getter/setter for Backendless.secretKey is deprecated, instead use Backendless.apiKey') return this.apiKey } /** @deprecated */ set secretKey(apiKey) { // eslint-disable-next-line no-console console.warn('getter/setter for Backendless.secretKey is deprecated, instead use Backendless.apiKey') this.apiKey = apiKey } /** @deprecated */ get Persistence() { showLegacyDataWarning() return this.Data } get DataQueryBuilder() { return this.Data.QueryBuilder } get GroupQueryBuilder() { return this.Data.GroupQueryBuilder } get JSONUpdateBuilder() { return this.Data.JSONUpdateBuilder } get LoadRelationsQueryBuilder() { return this.Data.LoadRelationsQueryBuilder } get Bodyparts() { return this.Messaging.Bodyparts } get PublishOptions() { return this.Messaging.PublishOptions } get DeliveryOptions() { return this.Messaging.DeliveryOptions } get PublishOptionsHeaders() { return this.Messaging.PublishOptionsHeaders } get EmailEnvelope() { return this.Messaging.EmailEnvelope } get Expression() { return Expression } ///--------BACKWARD COMPATIBILITY-------/// ///-------------------------------------/// } const backendless = new Backendless(DEFAULT_PROPS) if (Utils.globalScope) { Utils.globalScope.Backendless = backendless } exports = module.exports = backendless export default backendless