@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
JavaScript
;
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;