UNPKG

@shopify/app-bridge-host

Version:

App Bridge Host contains components and middleware to be consumed by the app's host, as well as the host itself. The middleware and `Frame` component are responsible for facilitating communication between the client and host, and used to act on actions se

292 lines (284 loc) 12.7 kB
'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); var tslib = require('tslib'); var client = require('@shopify/app-bridge-core/client'); var Actions = require('@shopify/app-bridge-core/actions'); var mergeProps = require('@shopify/app-bridge-core/actions/merge'); var validator = require('@shopify/app-bridge-core/actions/validator'); var appBridgeCore = require('@shopify/app-bridge-core'); var types = require('@shopify/app-bridge-core/actions/types'); var utilities = require('../utilities.js'); function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; } function _interopNamespace(e) { if (e && e.__esModule) return e; var n = Object.create(null); if (e) { Object.keys(e).forEach(function (k) { if (k !== 'default') { var d = Object.getOwnPropertyDescriptor(e, k); Object.defineProperty(n, k, d.get ? d : { enumerable: true, get: function () { return e[k]; } }); } }); } n.default = e; return Object.freeze(n); } var Actions__namespace = /*#__PURE__*/_interopNamespace(Actions); var mergeProps__default = /*#__PURE__*/_interopDefault(mergeProps); var _a, _b, _c; var APP_REDIRECT_KEY = validator.getPermissionKey(Actions__namespace.Redirect.Action.APP); var FEATURES_UPDATE_KEY = validator.getPermissionKey(Actions__namespace.Features.Action.UPDATE); var FEATURES_REQUEST_KEY = validator.getPermissionKey(Actions__namespace.Features.Action.REQUEST); var FEATURES_REQUEST_UPDATE_KEY = validator.getPermissionKey(Actions__namespace.Features.Action.REQUEST_UPDATE); var DEFAULT_FEATURES_STATE = (_a = {}, _a[FEATURES_UPDATE_KEY] = { Dispatch: false, Subscribe: true, }, _a[FEATURES_REQUEST_KEY] = { Dispatch: true, Subscribe: false, }, _a[FEATURES_REQUEST_UPDATE_KEY] = { Dispatch: false, Subscribe: true, }, _a); var AUTH_CODE_REQUEST_KEY = validator.getPermissionKey(Actions__namespace.AuthCode.Action.REQUEST); var AUTH_CODE_RESPOND_KEY = validator.getPermissionKey(Actions__namespace.AuthCode.Action.RESPOND); var AUTH_CODE_FEATURES_STATE = (_b = {}, _b[AUTH_CODE_REQUEST_KEY] = { Dispatch: true, Subscribe: true, }, _b[AUTH_CODE_RESPOND_KEY] = { Dispatch: false, Subscribe: true, }, _b); var SESSION_TOKEN_REQUEST_KEY = validator.getPermissionKey(Actions__namespace.SessionToken.Action.REQUEST); var SESSION_TOKEN_RESPOND_KEY = validator.getPermissionKey(Actions__namespace.SessionToken.Action.RESPOND); var SESSION_TOKEN_FEATURES_STATE = (_c = {}, _c[SESSION_TOKEN_REQUEST_KEY] = { Dispatch: true, Subscribe: true, }, _c[SESSION_TOKEN_RESPOND_KEY] = { Dispatch: false, Subscribe: true, }, _c); var DEFAULT_ENABLED_GROUPS = [types.Group.Button, types.Group.ButtonGroup, types.Group.Error]; var defaultFeaturesStore = getDefaultFeatures(); function getFeaturesPermissions() { var _a, _b, _c, _d; var navigationFeature = setFeatureByActionGroup(types.Group.Navigation, true); var modalNavigationFeature = tslib.__assign(tslib.__assign({}, navigationFeature), (_a = {}, _a[APP_REDIRECT_KEY] = { Dispatch: true, Subscribe: false, }, _a)); var mainPermissions = (_b = {}, _b[types.Group.AuthCode] = AUTH_CODE_FEATURES_STATE, _b[types.Group.Button] = setFeatureByActionGroup(types.Group.Button, true), _b[types.Group.ButtonGroup] = setFeatureByActionGroup(types.Group.ButtonGroup, true), _b[types.Group.Cart] = setFeatureByActionGroup(types.Group.Cart, true), _b[types.Group.Client] = setFeatureByActionGroup(types.Group.Client, true), _b[types.Group.ContextualSaveBar] = setFeatureByActionGroup(types.Group.ContextualSaveBar, true), _b[types.Group.Error] = setFeatureByActionGroup(types.Group.Error, true), _b[types.Group.Features] = setFeatureByActionGroup(types.Group.Features, true), _b[types.Group.FeedbackModal] = setFeatureByActionGroup(types.Group.FeedbackModal, true), _b[types.Group.Fullscreen] = setFeatureByActionGroup(types.Group.Fullscreen, true), _b[types.Group.LeaveConfirmation] = setFeatureByActionGroup(types.Group.LeaveConfirmation, true), _b[types.Group.Link] = setFeatureByActionGroup(types.Group.Link, true), _b[types.Group.Loading] = setFeatureByActionGroup(types.Group.Loading, true), _b[types.Group.MarketingExternalActivityTopBar] = setFeatureByActionGroup(types.Group.MarketingExternalActivityTopBar, true), _b[types.Group.Menu] = setFeatureByActionGroup(types.Group.Menu, true), _b[types.Group.Modal] = setFeatureByActionGroup(types.Group.Modal, true), _b[types.Group.Navigation] = navigationFeature, _b[types.Group.Performance] = setFeatureByActionGroup(types.Group.Performance, true), _b[types.Group.Pos] = setFeatureByActionGroup(types.Group.Pos, true), _b[types.Group.Print] = setFeatureByActionGroup(types.Group.Print, true), _b[types.Group.ResourcePicker] = setFeatureByActionGroup(types.Group.ResourcePicker, true), _b[types.Group.Scanner] = setFeatureByActionGroup(types.Group.Scanner, true), _b[types.Group.SessionToken] = SESSION_TOKEN_FEATURES_STATE, _b[types.Group.Share] = setFeatureByActionGroup(types.Group.Share, true), _b[types.Group.TitleBar] = setFeatureByActionGroup(types.Group.TitleBar, true), _b[types.Group.Toast] = setFeatureByActionGroup(types.Group.Toast, true), _b[types.Group.unstable_Picker] = setFeatureByActionGroup(types.Group.unstable_Picker, true), _b[types.Group.WebVitals] = setFeatureByActionGroup(types.Group.WebVitals, true), _b); var modalPermissions = mergeProps__default.default(mainPermissions, (_c = {}, // Should we enable fullscreen here? _c[types.Group.Fullscreen] = setFeatureByActionGroup(types.Group.Fullscreen, false), _c[types.Group.Navigation] = modalNavigationFeature, _c[types.Group.Print] = setFeatureByActionGroup(types.Group.Print, false), _c)); return _d = {}, _d[appBridgeCore.Context.Main] = mainPermissions, _d[appBridgeCore.Context.Modal] = modalPermissions, _d; } function setFeatureByActionGroup(group, value) { if (value === void 0) { value = false; } return setFeature(utilities.getGroupActionType(group), value); } /** * Map an action enum to the given permission * @public * @param actions - the actions enum * @param value - the permission to set * @returns an object with keys mapped to the actions and value set to the given permission */ function setFeature(actions, value) { if (value === void 0) { value = false; } var features = {}; var permission = value; if (typeof value === 'boolean') { permission = { Dispatch: value, Subscribe: value }; } var actionsAsArray = Array.isArray(actions) ? actions : [actions]; actionsAsArray.forEach(function (action) { Object.values(action).forEach(function (value) { features[validator.getPermissionKey(value)] = permission; }); }); return features; } /** * Returns the updated feature state * @param state - the current state * @param action - the update action with partial features in the payload * @internal * */ function featuresReducer(state, action) { if (state === void 0) { state = defaultFeaturesStore; } switch (action.type) { case Actions__namespace.Features.Action.UPDATE: { var payload = action.payload; return mergeProps__default.default(state, getUpdatePayload(payload)); } default: return state; } } function normalizePermissions(features) { if (features === void 0) { features = {}; } return Object.keys(features).reduce(function (acc, group) { var _a; var featureGroup = features[group]; if (!featureGroup) { return acc; } var actionPermissions = Object.keys(featureGroup).reduce(function (actionAcc, action) { var _a, _b; var permission = featureGroup[action]; return tslib.__assign(tslib.__assign({}, actionAcc), (_a = {}, _a[action] = hasNewPermission(permission) ? permission : (_b = {}, _b[client.PermissionType.Dispatch] = permission, _b[client.PermissionType.Subscribe] = permission, _b), _a)); }, {}); return tslib.__assign(tslib.__assign({}, acc), (_a = {}, _a[group] = actionPermissions, _a)); }, {}); } function hasNewPermission(permission) { return (Object.prototype.hasOwnProperty.call(permission, client.PermissionType.Dispatch) && Object.prototype.hasOwnProperty.call(permission, client.PermissionType.Subscribe)); } function getUpdatePayload(payload) { var _a, _b; if (Object.prototype.hasOwnProperty.call(payload, appBridgeCore.Context.Main) || Object.prototype.hasOwnProperty.call(payload, appBridgeCore.Context.Modal)) { return _a = {}, _a[appBridgeCore.Context.Main] = normalizePermissions(payload[appBridgeCore.Context.Main]), _a[appBridgeCore.Context.Modal] = normalizePermissions(payload[appBridgeCore.Context.Modal]), _a; } return _b = {}, _b[appBridgeCore.Context.Main] = normalizePermissions(payload), _b; } function getDefaultFeatures() { var _a; var features = enumValues(types.Group).reduce(function (acc, group) { var _a; var castedGroup = group; var permissions = group === types.Group.Features ? DEFAULT_FEATURES_STATE : setFeature(utilities.getGroupActionType(castedGroup), DEFAULT_ENABLED_GROUPS.includes(castedGroup)); return tslib.__assign(tslib.__assign({}, acc), (_a = {}, _a[castedGroup] = permissions, _a)); }, {}); return _a = {}, _a[appBridgeCore.Context.Main] = features, _a[appBridgeCore.Context.Modal] = features, _a; } function getDefaultAsyncFeatures() { var _a; var features = enumValues(types.Group).reduce(function (acc, group) { var _a; var castedGroup = group; var permissions = group === types.Group.Features ? DEFAULT_FEATURES_STATE : setFeature(utilities.getGroupActionType(castedGroup), DEFAULT_ENABLED_GROUPS.includes(castedGroup)); return tslib.__assign(tslib.__assign({}, acc), (_a = {}, _a[castedGroup] = permissions, _a)); }, {}); return _a = {}, _a[appBridgeCore.Context.Main] = features, _a[appBridgeCore.Context.Modal] = features, _a; } var defaultAsyncFeaturesStore = getDefaultAsyncFeatures(); /** * Returns the updated feature state * @param state - the current state * @param action - the update action with partial features in the payload * @internal * */ function asyncFeaturesReducer(state, action) { if (state === void 0) { state = defaultAsyncFeaturesStore; } return featuresReducer(state, action); } /** * Returns the features state with the provided group(s) enabled * The permission is set for both Main and Modal context * according to the default feature permission rules * @argument keys - the group(s) to enable the feature permission * @public * */ function setFeaturesAvailable() { var _a; var features = []; for (var _i = 0; _i < arguments.length; _i++) { features[_i] = arguments[_i]; } var _b = getFeaturesPermissions(), Modal = _b.Modal, Main = _b.Main; var modalPermission = features.reduce(function (acc, curr) { var _a; return tslib.__assign(tslib.__assign({}, acc), (_a = {}, _a[curr] = Modal && Modal[curr], _a)); }, {}); var mainPermission = features.reduce(function (acc, curr) { var _a; return tslib.__assign(tslib.__assign({}, acc), (_a = {}, _a[curr] = Main && Main[curr], _a)); }, {}); return mergeProps__default.default(defaultFeaturesStore, (_a = {}, _a[appBridgeCore.Context.Main] = mainPermission, _a[appBridgeCore.Context.Modal] = modalPermission, _a)); } /** * Returns typed enum values as an array * @internal */ function enumValues(enumObject) { return Object.keys(enumObject).map(function (key) { return enumObject[key]; }); } exports.asyncFeaturesReducer = asyncFeaturesReducer; exports.default = featuresReducer; exports.defaultFeaturesStore = defaultFeaturesStore; exports.setFeature = setFeature; exports.setFeaturesAvailable = setFeaturesAvailable;