@shopware-ag/admin-extension-sdk
Advanced tools
Comparing version 0.0.10 to 0.0.11
import { ShopwareMessageTypes } from './messages.types'; | ||
/** | ||
* ---------------- | ||
* GENERAL TYPES | ||
* ---------------- | ||
*/ | ||
/** | ||
* This type contains the data of the type without the responseType | ||
@@ -22,6 +27,11 @@ * @internal | ||
_type: MESSAGE_TYPE; | ||
_response: ShopwareMessageTypes[MESSAGE_TYPE]['responseType']; | ||
_response: ShopwareMessageTypes[MESSAGE_TYPE]['responseType'] | null; | ||
_callbackId: string; | ||
}; | ||
/** | ||
* ---------------- | ||
* MAIN FUNCTIONS FOR EXPORT | ||
* ---------------- | ||
*/ | ||
/** | ||
* With this method you can send actions or you can request data: | ||
@@ -33,3 +43,3 @@ * | ||
*/ | ||
export declare function send<MESSAGE_TYPE extends keyof ShopwareMessageTypes>(type: MESSAGE_TYPE, data: MessageDataType<MESSAGE_TYPE>): Promise<ShopwareMessageTypes[MESSAGE_TYPE]['responseType']>; | ||
export declare function send<MESSAGE_TYPE extends keyof ShopwareMessageTypes>(type: MESSAGE_TYPE, data: MessageDataType<MESSAGE_TYPE>, targetWindow?: Window): Promise<ShopwareMessageTypes[MESSAGE_TYPE]['responseType'] | null>; | ||
/** | ||
@@ -41,3 +51,3 @@ * | ||
*/ | ||
export declare function handle<MESSAGE_TYPE extends keyof ShopwareMessageTypes>(type: MESSAGE_TYPE, method: (data: MessageDataType<MESSAGE_TYPE>) => ShopwareMessageTypes[MESSAGE_TYPE]['responseType']): () => void; | ||
export declare function handle<MESSAGE_TYPE extends keyof ShopwareMessageTypes>(type: MESSAGE_TYPE, method: (data: MessageDataType<MESSAGE_TYPE>) => Promise<ShopwareMessageTypes[MESSAGE_TYPE]['responseType']> | ShopwareMessageTypes[MESSAGE_TYPE]['responseType']): () => void; | ||
/** | ||
@@ -52,2 +62,2 @@ * Function overloading for these two cases: | ||
export declare function createSender<MESSAGE_TYPE extends keyof ShopwareMessageTypes>(messageType: MESSAGE_TYPE): (messageOptions: MessageDataType<MESSAGE_TYPE>) => Promise<ShopwareMessageTypes[MESSAGE_TYPE]["responseType"]>; | ||
export declare function createHandler<MESSAGE_TYPE extends keyof ShopwareMessageTypes>(messageType: MESSAGE_TYPE): (method: (data: MessageDataType<MESSAGE_TYPE>) => ShopwareMessageTypes[MESSAGE_TYPE]['responseType']) => () => void; | ||
export declare function createHandler<MESSAGE_TYPE extends keyof ShopwareMessageTypes>(messageType: MESSAGE_TYPE): (method: (data: MessageDataType<MESSAGE_TYPE>) => Promise<ShopwareMessageTypes[MESSAGE_TYPE]['responseType']> | ShopwareMessageTypes[MESSAGE_TYPE]['responseType']) => () => void; |
@@ -0,2 +1,18 @@ | ||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } | ||
return new (P || (P = Promise))(function (resolve, reject) { | ||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } | ||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } | ||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } | ||
step((generator = generator.apply(thisArg, _arguments || [])).next()); | ||
}); | ||
}; | ||
import { serializeMessageData, deserializeMessageData } from './_internals/function-serializer'; | ||
import { generateUniqueId } from './_internals/utils'; | ||
/** | ||
* ---------------- | ||
* MAIN FUNCTIONS FOR EXPORT | ||
* ---------------- | ||
*/ | ||
/** | ||
* With this method you can send actions or you can request data: | ||
@@ -8,5 +24,5 @@ * | ||
*/ | ||
export function send(type, data) { | ||
export function send(type, data, targetWindow) { | ||
// generate a unique callback ID. This here is only for simple demonstration purposes | ||
const callbackId = String(Math.floor(Math.random() * Date.now())); | ||
const callbackId = generateUniqueId(); | ||
// set fallback data when no data is defined | ||
@@ -20,2 +36,5 @@ const sendData = data !== null && data !== void 0 ? data : {}; | ||
}; | ||
// replace methods etc. so that they are working in JSON format | ||
serializeMessageData(messageData); | ||
// convert message data to string for message sending | ||
const message = JSON.stringify(messageData); | ||
@@ -55,3 +74,5 @@ return new Promise((resolve) => { | ||
window.addEventListener('message', callbackHandler); | ||
window.parent.postMessage(message, window.parent.origin); | ||
targetWindow | ||
? targetWindow.postMessage(message, window.parent.origin) | ||
: window.parent.postMessage(message, window.parent.origin); | ||
}); | ||
@@ -67,40 +88,46 @@ } | ||
const handleListener = function (event) { | ||
var _a, _b; | ||
if (typeof event.data !== 'string') { | ||
return; | ||
} | ||
let shopwareMessageData; | ||
// try to parse the json file | ||
try { | ||
shopwareMessageData = JSON.parse(event.data); | ||
} | ||
catch (_c) { | ||
// fail silently when message is not a valid json file | ||
return; | ||
} | ||
// check if messageData is valid | ||
if (!isMessageData(shopwareMessageData)) { | ||
return; | ||
} | ||
// check if messageData type matches the type argument | ||
if (shopwareMessageData._type !== type) { | ||
return; | ||
} | ||
const responseMessage = { | ||
_callbackId: shopwareMessageData._callbackId, | ||
_type: shopwareMessageData._type, | ||
_response: (_a = method(shopwareMessageData._data)) !== null && _a !== void 0 ? _a : null | ||
}; | ||
const stringifiedResponseMessage = JSON.stringify(responseMessage); | ||
if (event.source) { | ||
// if event source exists then send it back to original source | ||
event.source.postMessage(stringifiedResponseMessage, { | ||
// @ts-expect-error - event.source.origin is not correctly defined in TS | ||
targetOrigin: (_b = event.source.origin) !== null && _b !== void 0 ? _b : '*' | ||
}); | ||
} | ||
else { | ||
// if no event source exists then it should send to same window | ||
window.postMessage(stringifiedResponseMessage, window.origin); | ||
} | ||
var _a; | ||
return __awaiter(this, void 0, void 0, function* () { | ||
if (typeof event.data !== 'string') { | ||
return; | ||
} | ||
let shopwareMessageData; | ||
// try to parse the json file | ||
try { | ||
shopwareMessageData = JSON.parse(event.data); | ||
} | ||
catch (_b) { | ||
// fail silently when message is not a valid json file | ||
return; | ||
} | ||
// check if messageData is valid | ||
if (!isMessageData(shopwareMessageData)) { | ||
return; | ||
} | ||
// check if messageData type matches the type argument | ||
if (shopwareMessageData._type !== type) { | ||
return; | ||
} | ||
// deserialize methods etc. so that they are callable in JS | ||
deserializeMessageData(shopwareMessageData); | ||
const responseValue = yield Promise.resolve(method(shopwareMessageData._data)); | ||
const responseMessage = { | ||
_callbackId: shopwareMessageData._callbackId, | ||
_type: shopwareMessageData._type, | ||
_response: responseValue !== null && responseValue !== void 0 ? responseValue : null | ||
}; | ||
const stringifiedResponseMessage = JSON.stringify(responseMessage); | ||
if (event.source) { | ||
// if event source exists then send it back to original source | ||
event.source.postMessage(stringifiedResponseMessage, { | ||
// @ts-expect-error - event.source.origin is not correctly defined in TS | ||
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment | ||
targetOrigin: (_a = event.source.origin) !== null && _a !== void 0 ? _a : '*' | ||
}); | ||
} | ||
else { | ||
// if no event source exists then it should send to same window | ||
window.postMessage(stringifiedResponseMessage, window.origin); | ||
} | ||
}); | ||
}; | ||
@@ -112,20 +139,29 @@ // start listening directly | ||
} | ||
export function createSender(messageType, baseMessageOptions) { | ||
return (messageOptions) => send(messageType, Object.assign(Object.assign({}, baseMessageOptions), messageOptions)); | ||
} | ||
export function createHandler(messageType) { | ||
return (method) => handle(messageType, method); | ||
} | ||
/** | ||
* ---------------- | ||
* INTERNAL HELPER FUNCTIONS | ||
* ---------------- | ||
*/ | ||
/** | ||
* check if the data is valid message data | ||
*/ | ||
function isMessageData(eventData) { | ||
const shopwareMessageData = eventData; | ||
return shopwareMessageData._type | ||
&& shopwareMessageData._data | ||
&& shopwareMessageData._callbackId; | ||
return !!shopwareMessageData._type | ||
&& !!shopwareMessageData._data | ||
&& !!shopwareMessageData._callbackId; | ||
} | ||
// ShopwareMessageTypes[MESSAGE_TYPE]['responseType'] | ||
function isMessageResponseData(eventData) { | ||
const shopwareMessageData = eventData; | ||
return shopwareMessageData._type | ||
&& shopwareMessageData.hasOwnProperty('_response') | ||
&& shopwareMessageData._callbackId; | ||
return !!shopwareMessageData._type | ||
&& !!shopwareMessageData.hasOwnProperty('_response') | ||
&& !!shopwareMessageData._callbackId; | ||
} | ||
export function createSender(messageType, baseMessageOptions) { | ||
return (messageOptions) => send(messageType, Object.assign(Object.assign({}, baseMessageOptions), messageOptions)); | ||
} | ||
export function createHandler(messageType) { | ||
return (method) => handle(messageType, method); | ||
} | ||
//# sourceMappingURL=channel.js.map |
@@ -0,1 +1,10 @@ | ||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } | ||
return new (P || (P = Promise))(function (resolve, reject) { | ||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } | ||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } | ||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } | ||
step((generator = generator.apply(thisArg, _arguments || [])).next()); | ||
}); | ||
}; | ||
import { send, handle, createSender, createHandler } from './channel'; | ||
@@ -54,3 +63,51 @@ describe('Test the channel bridge from iFrame to admin', () => { | ||
}); | ||
it('should convert functions in options and call them on the handler side', (done) => { | ||
const buttonMethodMock = jest.fn(() => { }); | ||
const dispatchNotification = createSender('dispatchNotification'); | ||
const handleNotification = createHandler('dispatchNotification'); | ||
const removeListener = handleNotification(({ actions }) => __awaiter(void 0, void 0, void 0, function* () { | ||
if (!actions || (actions === null || actions === void 0 ? void 0 : actions.length) <= 0) { | ||
fail('The notification handler does not get any actions from the sender'); | ||
return; | ||
} | ||
const firstAction = actions[0]; | ||
if (!firstAction.method) { | ||
fail('"method" in the firstAction is undefined'); | ||
} | ||
expect(typeof firstAction.method).toBe('function'); | ||
expect(buttonMethodMock).toHaveBeenCalledTimes(0); | ||
yield firstAction.method(); | ||
expect(buttonMethodMock).toHaveBeenCalledTimes(1); | ||
})); | ||
dispatchNotification({ | ||
title: 'Notification with action', | ||
message: 'The action should contain a callable method', | ||
actions: [ | ||
{ | ||
label: 'Button with method', | ||
method: () => buttonMethodMock() | ||
} | ||
] | ||
}).then(() => { | ||
removeListener(); | ||
done(); | ||
}); | ||
}); | ||
it('should convert functions in options and call them on the handler side with arguments and return value', (done) => { | ||
const methodMock = jest.fn((firstNumber, secondNumber) => { | ||
return firstNumber * secondNumber; | ||
}); | ||
const sendMultiply = createSender('_multiply'); | ||
const handleMultiply = createHandler('_multiply'); | ||
const removeListener = handleMultiply(({ firstNumber, secondNumber }) => { | ||
return Promise.resolve(methodMock(firstNumber, secondNumber)); | ||
}); | ||
sendMultiply({ firstNumber: 7, secondNumber: 8 }) | ||
.then((result) => { | ||
expect(result).toEqual(56); | ||
removeListener(); | ||
done(); | ||
}); | ||
}); | ||
}); | ||
//# sourceMappingURL=channel.spec.js.map |
import { dispatchNotification } from './notification/index'; | ||
import { redirectWindow } from './window/index'; | ||
/** | ||
* Contains all shopware send types. | ||
* Contains all shopware send types. | ||
* @internal | ||
@@ -12,2 +12,5 @@ */ | ||
reload: reload; | ||
__function__: __function__; | ||
_multiply: _multiply; | ||
_subtract: _subtract; | ||
}; | ||
@@ -29,1 +32,20 @@ /** | ||
}; | ||
/** | ||
* @private | ||
* JUST FOR TEST CASES | ||
*/ | ||
export declare type _multiply = { | ||
responseType: number; | ||
firstNumber: number; | ||
secondNumber: number; | ||
}; | ||
export declare type _subtract = { | ||
responseType: number; | ||
firstNumber: number; | ||
secondNumber: number; | ||
}; | ||
export declare type __function__ = { | ||
responseType: any; | ||
args: unknown[]; | ||
id: string; | ||
}; |
export declare const dispatch: (messageOptions: import("../channel").MessageDataType<"dispatchNotification">) => Promise<void>; | ||
/** | ||
* Dispatch a notification. | ||
*/ | ||
* Dispatch a notification. | ||
*/ | ||
export declare type dispatchNotification = { | ||
@@ -37,5 +37,6 @@ responseType: void; | ||
label: string; | ||
route: string; | ||
method?: () => void; | ||
route?: string; | ||
disabled?: boolean; | ||
}>; | ||
}; |
export declare const redirect: (messageOptions: import("../channel").MessageDataType<"redirectWindow">) => Promise<void>; | ||
/** | ||
* Redirect to another URL | ||
*/ | ||
* Redirect to another URL | ||
*/ | ||
export declare type redirectWindow = { | ||
@@ -6,0 +6,0 @@ responseType: void; |
{ | ||
"name": "@shopware-ag/admin-extension-sdk", | ||
"version": "0.0.10", | ||
"version": "0.0.11", | ||
"repository": "git://github.com/shopware/admin-extension-sdk.git", | ||
@@ -36,3 +36,5 @@ "description": "The SDK for App iframes to communicate with the Shopware Adminstration", | ||
"doc:dev": "cd docs && npm run start", | ||
"lint": "tsc --noEmit", | ||
"lint": "npm run lint:types && npm run lint:eslint", | ||
"lint:types": "tsc --noEmit", | ||
"lint:eslint": "eslint ./src --ext .ts", | ||
"e2e:open": "concurrently --handle-input --kill-others --success first \"cypress open\" \"npm run dev:build-watch\" \"npm run dev:serve -- --no-browser\"", | ||
@@ -45,4 +47,7 @@ "e2e:run": "concurrently --handle-input --kill-others --success first \"cypress run\" \"npm run dev:build-watch\" \"npm run dev:serve -- --no-browser\"", | ||
"@types/jest": "^27.0.3", | ||
"@typescript-eslint/eslint-plugin": "^5.4.0", | ||
"@typescript-eslint/parser": "^5.4.0", | ||
"concurrently": "^6.3.0", | ||
"cypress": "^8.5.0", | ||
"eslint": "^8.3.0", | ||
"jest": "^27.3.1", | ||
@@ -49,0 +54,0 @@ "live-server": "^1.2.1", |
@@ -7,2 +7,3 @@ # Warning: | ||
[![Tests](https://github.com/shopware/admin-extension-sdk/actions/workflows/base.yml/badge.svg?branch=main)](https://github.com/shopware/admin-extension-sdk/actions/workflows/base.yml) | ||
[![NPM Package](https://img.shields.io/npm/v/@shopware-ag/admin-extension-sdk)](https://www.npmjs.com/package/@shopware-ag/admin-extension-sdk) | ||
@@ -9,0 +10,0 @@ # Admin app actions |
import { ShopwareMessageTypes } from './messages.types'; | ||
/** | ||
* ---------------- | ||
* GENERAL TYPES | ||
* ---------------- | ||
*/ | ||
/** | ||
* This type contains the data of the type without the responseType | ||
@@ -22,6 +27,11 @@ * @internal | ||
_type: MESSAGE_TYPE; | ||
_response: ShopwareMessageTypes[MESSAGE_TYPE]['responseType']; | ||
_response: ShopwareMessageTypes[MESSAGE_TYPE]['responseType'] | null; | ||
_callbackId: string; | ||
}; | ||
/** | ||
* ---------------- | ||
* MAIN FUNCTIONS FOR EXPORT | ||
* ---------------- | ||
*/ | ||
/** | ||
* With this method you can send actions or you can request data: | ||
@@ -33,3 +43,3 @@ * | ||
*/ | ||
export declare function send<MESSAGE_TYPE extends keyof ShopwareMessageTypes>(type: MESSAGE_TYPE, data: MessageDataType<MESSAGE_TYPE>): Promise<ShopwareMessageTypes[MESSAGE_TYPE]['responseType']>; | ||
export declare function send<MESSAGE_TYPE extends keyof ShopwareMessageTypes>(type: MESSAGE_TYPE, data: MessageDataType<MESSAGE_TYPE>, targetWindow?: Window): Promise<ShopwareMessageTypes[MESSAGE_TYPE]['responseType'] | null>; | ||
/** | ||
@@ -41,3 +51,3 @@ * | ||
*/ | ||
export declare function handle<MESSAGE_TYPE extends keyof ShopwareMessageTypes>(type: MESSAGE_TYPE, method: (data: MessageDataType<MESSAGE_TYPE>) => ShopwareMessageTypes[MESSAGE_TYPE]['responseType']): () => void; | ||
export declare function handle<MESSAGE_TYPE extends keyof ShopwareMessageTypes>(type: MESSAGE_TYPE, method: (data: MessageDataType<MESSAGE_TYPE>) => Promise<ShopwareMessageTypes[MESSAGE_TYPE]['responseType']> | ShopwareMessageTypes[MESSAGE_TYPE]['responseType']): () => void; | ||
/** | ||
@@ -52,2 +62,2 @@ * Function overloading for these two cases: | ||
export declare function createSender<MESSAGE_TYPE extends keyof ShopwareMessageTypes>(messageType: MESSAGE_TYPE): (messageOptions: MessageDataType<MESSAGE_TYPE>) => Promise<ShopwareMessageTypes[MESSAGE_TYPE]["responseType"]>; | ||
export declare function createHandler<MESSAGE_TYPE extends keyof ShopwareMessageTypes>(messageType: MESSAGE_TYPE): (method: (data: MessageDataType<MESSAGE_TYPE>) => ShopwareMessageTypes[MESSAGE_TYPE]['responseType']) => () => void; | ||
export declare function createHandler<MESSAGE_TYPE extends keyof ShopwareMessageTypes>(messageType: MESSAGE_TYPE): (method: (data: MessageDataType<MESSAGE_TYPE>) => Promise<ShopwareMessageTypes[MESSAGE_TYPE]['responseType']> | ShopwareMessageTypes[MESSAGE_TYPE]['responseType']) => () => void; |
@@ -0,1 +1,10 @@ | ||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } | ||
return new (P || (P = Promise))(function (resolve, reject) { | ||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } | ||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } | ||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } | ||
step((generator = generator.apply(thisArg, _arguments || [])).next()); | ||
}); | ||
}; | ||
(function (factory) { | ||
@@ -7,3 +16,3 @@ if (typeof module === "object" && typeof module.exports === "object") { | ||
else if (typeof define === "function" && define.amd) { | ||
define(["require", "exports"], factory); | ||
define(["require", "exports", "./_internals/function-serializer", "./_internals/utils"], factory); | ||
} | ||
@@ -14,3 +23,10 @@ })(function (require, exports) { | ||
exports.createHandler = exports.createSender = exports.handle = exports.send = void 0; | ||
const function_serializer_1 = require("./_internals/function-serializer"); | ||
const utils_1 = require("./_internals/utils"); | ||
/** | ||
* ---------------- | ||
* MAIN FUNCTIONS FOR EXPORT | ||
* ---------------- | ||
*/ | ||
/** | ||
* With this method you can send actions or you can request data: | ||
@@ -22,5 +38,5 @@ * | ||
*/ | ||
function send(type, data) { | ||
function send(type, data, targetWindow) { | ||
// generate a unique callback ID. This here is only for simple demonstration purposes | ||
const callbackId = String(Math.floor(Math.random() * Date.now())); | ||
const callbackId = (0, utils_1.generateUniqueId)(); | ||
// set fallback data when no data is defined | ||
@@ -34,2 +50,5 @@ const sendData = data !== null && data !== void 0 ? data : {}; | ||
}; | ||
// replace methods etc. so that they are working in JSON format | ||
(0, function_serializer_1.serializeMessageData)(messageData); | ||
// convert message data to string for message sending | ||
const message = JSON.stringify(messageData); | ||
@@ -69,3 +88,5 @@ return new Promise((resolve) => { | ||
window.addEventListener('message', callbackHandler); | ||
window.parent.postMessage(message, window.parent.origin); | ||
targetWindow | ||
? targetWindow.postMessage(message, window.parent.origin) | ||
: window.parent.postMessage(message, window.parent.origin); | ||
}); | ||
@@ -82,40 +103,46 @@ } | ||
const handleListener = function (event) { | ||
var _a, _b; | ||
if (typeof event.data !== 'string') { | ||
return; | ||
} | ||
let shopwareMessageData; | ||
// try to parse the json file | ||
try { | ||
shopwareMessageData = JSON.parse(event.data); | ||
} | ||
catch (_c) { | ||
// fail silently when message is not a valid json file | ||
return; | ||
} | ||
// check if messageData is valid | ||
if (!isMessageData(shopwareMessageData)) { | ||
return; | ||
} | ||
// check if messageData type matches the type argument | ||
if (shopwareMessageData._type !== type) { | ||
return; | ||
} | ||
const responseMessage = { | ||
_callbackId: shopwareMessageData._callbackId, | ||
_type: shopwareMessageData._type, | ||
_response: (_a = method(shopwareMessageData._data)) !== null && _a !== void 0 ? _a : null | ||
}; | ||
const stringifiedResponseMessage = JSON.stringify(responseMessage); | ||
if (event.source) { | ||
// if event source exists then send it back to original source | ||
event.source.postMessage(stringifiedResponseMessage, { | ||
// @ts-expect-error - event.source.origin is not correctly defined in TS | ||
targetOrigin: (_b = event.source.origin) !== null && _b !== void 0 ? _b : '*' | ||
}); | ||
} | ||
else { | ||
// if no event source exists then it should send to same window | ||
window.postMessage(stringifiedResponseMessage, window.origin); | ||
} | ||
var _a; | ||
return __awaiter(this, void 0, void 0, function* () { | ||
if (typeof event.data !== 'string') { | ||
return; | ||
} | ||
let shopwareMessageData; | ||
// try to parse the json file | ||
try { | ||
shopwareMessageData = JSON.parse(event.data); | ||
} | ||
catch (_b) { | ||
// fail silently when message is not a valid json file | ||
return; | ||
} | ||
// check if messageData is valid | ||
if (!isMessageData(shopwareMessageData)) { | ||
return; | ||
} | ||
// check if messageData type matches the type argument | ||
if (shopwareMessageData._type !== type) { | ||
return; | ||
} | ||
// deserialize methods etc. so that they are callable in JS | ||
(0, function_serializer_1.deserializeMessageData)(shopwareMessageData); | ||
const responseValue = yield Promise.resolve(method(shopwareMessageData._data)); | ||
const responseMessage = { | ||
_callbackId: shopwareMessageData._callbackId, | ||
_type: shopwareMessageData._type, | ||
_response: responseValue !== null && responseValue !== void 0 ? responseValue : null | ||
}; | ||
const stringifiedResponseMessage = JSON.stringify(responseMessage); | ||
if (event.source) { | ||
// if event source exists then send it back to original source | ||
event.source.postMessage(stringifiedResponseMessage, { | ||
// @ts-expect-error - event.source.origin is not correctly defined in TS | ||
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment | ||
targetOrigin: (_a = event.source.origin) !== null && _a !== void 0 ? _a : '*' | ||
}); | ||
} | ||
else { | ||
// if no event source exists then it should send to same window | ||
window.postMessage(stringifiedResponseMessage, window.origin); | ||
} | ||
}); | ||
}; | ||
@@ -128,14 +155,2 @@ // start listening directly | ||
exports.handle = handle; | ||
function isMessageData(eventData) { | ||
const shopwareMessageData = eventData; | ||
return shopwareMessageData._type | ||
&& shopwareMessageData._data | ||
&& shopwareMessageData._callbackId; | ||
} | ||
function isMessageResponseData(eventData) { | ||
const shopwareMessageData = eventData; | ||
return shopwareMessageData._type | ||
&& shopwareMessageData.hasOwnProperty('_response') | ||
&& shopwareMessageData._callbackId; | ||
} | ||
function createSender(messageType, baseMessageOptions) { | ||
@@ -149,3 +164,24 @@ return (messageOptions) => send(messageType, Object.assign(Object.assign({}, baseMessageOptions), messageOptions)); | ||
exports.createHandler = createHandler; | ||
/** | ||
* ---------------- | ||
* INTERNAL HELPER FUNCTIONS | ||
* ---------------- | ||
*/ | ||
/** | ||
* check if the data is valid message data | ||
*/ | ||
function isMessageData(eventData) { | ||
const shopwareMessageData = eventData; | ||
return !!shopwareMessageData._type | ||
&& !!shopwareMessageData._data | ||
&& !!shopwareMessageData._callbackId; | ||
} | ||
// ShopwareMessageTypes[MESSAGE_TYPE]['responseType'] | ||
function isMessageResponseData(eventData) { | ||
const shopwareMessageData = eventData; | ||
return !!shopwareMessageData._type | ||
&& !!shopwareMessageData.hasOwnProperty('_response') | ||
&& !!shopwareMessageData._callbackId; | ||
} | ||
}); | ||
//# sourceMappingURL=channel.js.map |
@@ -0,1 +1,10 @@ | ||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } | ||
return new (P || (P = Promise))(function (resolve, reject) { | ||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } | ||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } | ||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } | ||
step((generator = generator.apply(thisArg, _arguments || [])).next()); | ||
}); | ||
}; | ||
(function (factory) { | ||
@@ -65,4 +74,52 @@ if (typeof module === "object" && typeof module.exports === "object") { | ||
}); | ||
it('should convert functions in options and call them on the handler side', (done) => { | ||
const buttonMethodMock = jest.fn(() => { }); | ||
const dispatchNotification = (0, channel_1.createSender)('dispatchNotification'); | ||
const handleNotification = (0, channel_1.createHandler)('dispatchNotification'); | ||
const removeListener = handleNotification(({ actions }) => __awaiter(void 0, void 0, void 0, function* () { | ||
if (!actions || (actions === null || actions === void 0 ? void 0 : actions.length) <= 0) { | ||
fail('The notification handler does not get any actions from the sender'); | ||
return; | ||
} | ||
const firstAction = actions[0]; | ||
if (!firstAction.method) { | ||
fail('"method" in the firstAction is undefined'); | ||
} | ||
expect(typeof firstAction.method).toBe('function'); | ||
expect(buttonMethodMock).toHaveBeenCalledTimes(0); | ||
yield firstAction.method(); | ||
expect(buttonMethodMock).toHaveBeenCalledTimes(1); | ||
})); | ||
dispatchNotification({ | ||
title: 'Notification with action', | ||
message: 'The action should contain a callable method', | ||
actions: [ | ||
{ | ||
label: 'Button with method', | ||
method: () => buttonMethodMock() | ||
} | ||
] | ||
}).then(() => { | ||
removeListener(); | ||
done(); | ||
}); | ||
}); | ||
it('should convert functions in options and call them on the handler side with arguments and return value', (done) => { | ||
const methodMock = jest.fn((firstNumber, secondNumber) => { | ||
return firstNumber * secondNumber; | ||
}); | ||
const sendMultiply = (0, channel_1.createSender)('_multiply'); | ||
const handleMultiply = (0, channel_1.createHandler)('_multiply'); | ||
const removeListener = handleMultiply(({ firstNumber, secondNumber }) => { | ||
return Promise.resolve(methodMock(firstNumber, secondNumber)); | ||
}); | ||
sendMultiply({ firstNumber: 7, secondNumber: 8 }) | ||
.then((result) => { | ||
expect(result).toEqual(56); | ||
removeListener(); | ||
done(); | ||
}); | ||
}); | ||
}); | ||
}); | ||
//# sourceMappingURL=channel.spec.js.map |
import { dispatchNotification } from './notification/index'; | ||
import { redirectWindow } from './window/index'; | ||
/** | ||
* Contains all shopware send types. | ||
* Contains all shopware send types. | ||
* @internal | ||
@@ -12,2 +12,5 @@ */ | ||
reload: reload; | ||
__function__: __function__; | ||
_multiply: _multiply; | ||
_subtract: _subtract; | ||
}; | ||
@@ -29,1 +32,20 @@ /** | ||
}; | ||
/** | ||
* @private | ||
* JUST FOR TEST CASES | ||
*/ | ||
export declare type _multiply = { | ||
responseType: number; | ||
firstNumber: number; | ||
secondNumber: number; | ||
}; | ||
export declare type _subtract = { | ||
responseType: number; | ||
firstNumber: number; | ||
secondNumber: number; | ||
}; | ||
export declare type __function__ = { | ||
responseType: any; | ||
args: unknown[]; | ||
id: string; | ||
}; |
export declare const dispatch: (messageOptions: import("../channel").MessageDataType<"dispatchNotification">) => Promise<void>; | ||
/** | ||
* Dispatch a notification. | ||
*/ | ||
* Dispatch a notification. | ||
*/ | ||
export declare type dispatchNotification = { | ||
@@ -37,5 +37,6 @@ responseType: void; | ||
label: string; | ||
route: string; | ||
method?: () => void; | ||
route?: string; | ||
disabled?: boolean; | ||
}>; | ||
}; |
export declare const redirect: (messageOptions: import("../channel").MessageDataType<"redirectWindow">) => Promise<void>; | ||
/** | ||
* Redirect to another URL | ||
*/ | ||
* Redirect to another URL | ||
*/ | ||
export declare type redirectWindow = { | ||
@@ -6,0 +6,0 @@ responseType: void; |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
77655
50
1206
111
0
13