UNPKG

@1hive/connect-core

Version:

Access and interact with Aragon Organizations and their apps.

113 lines 4.68 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.createAppConnector = void 0; const types_1 = require("../types"); const errors_1 = require("../errors"); function normalizeConnectorConfig(connector) { var _a; if (Array.isArray(connector)) { // Returning `{} as Config` shouldn’t be an issue, because the config type // of an app connector should have all its properties declared as optional. return [connector[0], (_a = connector[1]) !== null && _a !== void 0 ? _a : {}]; } if (typeof connector === 'string') { return [connector, {}]; } throw new errors_1.ErrorInvalidConnector('The connector should be passed as a string or an array.'); } // Check if an app is valid. We are not using instanceof here, because the // passed app might come from the final app dependency, while @connect-core // might come from the app connector they are using, with two different // versions. It also makes it easier to work with linked dependencies, as it // creates the same kind of issues. function isApp(app) { return (typeof app === 'object' && 'name' in app && 'address' in app && 'appId' in app && 'version' in app); } async function getProxiedApp(app, connector, callback) { app = (await app); if (!isApp(app)) { throw new errors_1.ErrorInvalidApp(`App connector: the passed value doesn’t appear to be an App.`); } const { connection } = app.organization; const { orgConnector } = connection; // App connector config. const [connectorName, connectorConfig] = normalizeConnectorConfig( // Contrary to the main connect() function, app connectors don’t require // the connector to be passed. In this case, the name of the org // connector (e.g. `name`) is used instead. connector || orgConnector.name); const connectedApp = await callback({ app, config: connectorConfig, connector: connectorName, ipfs: connection.ipfs, network: orgConnector.network, orgConnector, verbose: connection.verbose, }); const boundMethods = new WeakMap(); const proxiedApp = new Proxy(connectedApp, { get: (target, key) => { const isAppProperty = connectedApp[key] === undefined; // Pick properties from ConnectedApp first, then App const instance = (isAppProperty ? app : connectedApp); // Bind methods as they get accessed (so `this` works as expected). // This is done once for reference comparisons to work as expected. if (typeof instance[key] === 'function' && !boundMethods.has(instance[key])) { instance[key] = instance[key].bind(instance); boundMethods.set(instance[key], true); } return instance[key]; }, }); // Useful for inspection proxiedApp._app = app; proxiedApp._connectedApp = connectedApp; return proxiedApp; } function createAppConnector(callback) { return function connect(appOrSubscribe, connector) { // If app is a SubscriptionStart, assume it is onApp(): // start listening, and return the handler. if (types_1.isSubscriptionStart(appOrSubscribe)) { return (subscriptionCb) => { let cancelled = false; const subscriptionHandler = appOrSubscribe((error, app) => { if (error !== null) { subscriptionCb(error); return; } getProxiedApp(app, connector, callback) .then((app) => { if (cancelled) { return; } subscriptionCb(null, app); }) .catch((err) => { if (!cancelled) { subscriptionCb(err); } }); }); return { unsubscribe() { cancelled = true; subscriptionHandler.unsubscribe(); }, }; }; } if (types_1.isSubscriptionHandler(appOrSubscribe)) { throw new errors_1.ErrorInvalidApp(`App connector: the value doesn’t appear to be an App or an app subscription.`); } return getProxiedApp(appOrSubscribe, connector, callback); }; } exports.createAppConnector = createAppConnector; //# sourceMappingURL=app-connectors.js.map