| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115 |
- import {
- BaseExtensionMessage,
- ExtensionMesssage,
- MessageResponse,
- NotificationMessage,
- WatchQueryFetchPolicy,
- } from '@vendure/common/lib/extension-host-types';
- import { Observable } from 'rxjs';
- import { take } from 'rxjs/operators';
- let targetOrigin = 'http://localhost:3000';
- /**
- * @description
- * Set the [window.postMessage API](https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage)
- * `targetOrigin`. The Vendure ui-devkit uses the postMessage API to
- * enable cross-frame and cross-origin communication between the ui extension code and the Admin UI
- * app. The `targetOrigin` is a security feature intended to provide control over where messages are sent.
- */
- export function setTargetOrigin(value: string) {
- targetOrigin = value;
- }
- /**
- * @description
- * Perform a GraphQL query and returns either an Observable or a Promise of the result.
- */
- export function graphQlQuery<T, V extends { [key: string]: any }>(
- document: string,
- variables?: { [key: string]: any },
- fetchPolicy?: WatchQueryFetchPolicy,
- ): {
- then: Promise<T>['then'];
- stream: Observable<T>;
- } {
- const result$ = sendMessage('graphql-query', { document, variables, fetchPolicy });
- return {
- then: (...args: any[]) =>
- result$
- .pipe(take(1))
- .toPromise()
- .then(...args),
- stream: result$,
- };
- }
- /**
- * @description
- * Perform a GraphQL mutation and returns either an Observable or a Promise of the result.
- */
- export function graphQlMutation<T, V extends { [key: string]: any }>(
- document: string,
- variables?: { [key: string]: any },
- ): {
- then: Promise<T>['then'];
- stream: Observable<T>;
- } {
- const result$ = sendMessage('graphql-mutation', { document, variables });
- return {
- then: (...args: any[]) =>
- result$
- .pipe(take(1))
- .toPromise()
- .then(...args),
- stream: result$,
- };
- }
- /**
- * @description
- * Display a toast notification.
- */
- export function notify(options: NotificationMessage['data']) {
- sendMessage('notification', options).toPromise();
- }
- function sendMessage<T extends ExtensionMesssage>(type: T['type'], data: T['data']): Observable<any> {
- const requestId =
- type +
- '__' +
- Math.random()
- .toString(36)
- .substr(3);
- const message: BaseExtensionMessage = {
- requestId,
- type,
- data,
- };
- return new Observable<any>(subscriber => {
- const handleReply = (event: MessageEvent) => {
- const response: MessageResponse = event.data;
- if (response && response.requestId === requestId) {
- if (response.complete) {
- subscriber.complete();
- tearDown();
- return;
- }
- if (response.error) {
- subscriber.error(response.data);
- tearDown();
- return;
- }
- subscriber.next(response.data);
- }
- };
- const tearDown = () => {
- window.parent.postMessage({ requestId, type: 'cancellation', data: null }, targetOrigin);
- };
- window.addEventListener('message', handleReply);
- window.parent.postMessage(message, targetOrigin);
- return tearDown;
- });
- }
|