From 94c401660832956c9c2da0df2119ba89fe7fb08e Mon Sep 17 00:00:00 2001 From: Sam Date: Fri, 24 Jun 2022 12:32:44 +0200 Subject: [PATCH] feat: Move browser globals to lowdefy._internal.globals. --- packages/client/src/createLinkComponent.js | 1 + packages/client/src/initLowdefyContext.js | 7 +- packages/client/src/setupLink.js | 3 +- packages/engine/src/Actions.js | 3 +- packages/operators/src/nodeParser.test.js | 1 + packages/operators/src/webParser.js | 2 +- packages/operators/src/webParser.test.js | 77 ++++++++++--------- .../actions-core/src/actions/ScrollTo.js | 3 +- .../actions-core/src/actions/ScrollTo.test.js | 12 +-- .../src/operators/client/location.js | 3 +- .../src/operators/client/location.test.js | 10 ++- .../src/operators/client/media.js | 3 +- .../src/operators/client/media.test.js | 33 +++++--- 13 files changed, 95 insertions(+), 63 deletions(-) diff --git a/packages/client/src/createLinkComponent.js b/packages/client/src/createLinkComponent.js index e60627daa..c08afd4a3 100644 --- a/packages/client/src/createLinkComponent.js +++ b/packages/client/src/createLinkComponent.js @@ -3,6 +3,7 @@ import { createLink } from '@lowdefy/engine'; import { type } from '@lowdefy/helpers'; const createLinkComponent = (lowdefy, Link) => { + const { window } = lowdefy._internal.globals; const backLink = ({ ariaLabel, children, className, id, rel }) => ( diff --git a/packages/client/src/setupLink.js b/packages/client/src/setupLink.js index cec5e21de..5cf7c6723 100644 --- a/packages/client/src/setupLink.js +++ b/packages/client/src/setupLink.js @@ -17,7 +17,8 @@ import { createLink } from '@lowdefy/engine'; function setupLink(lowdefy) { - const { router, window } = lowdefy._internal; + const { router } = lowdefy._internal; + const { window } = lowdefy._internal.globals; const backLink = () => router.back(); const disabledLink = () => {}; const newOriginLink = ({ url, query, newTab }) => { diff --git a/packages/engine/src/Actions.js b/packages/engine/src/Actions.js index 5dc2ad864..814193732 100644 --- a/packages/engine/src/Actions.js +++ b/packages/engine/src/Actions.js @@ -165,6 +165,7 @@ class Actions { }); try { response = await this.actions[action.type]({ + globals: this.context._internal.lowdefy._internal.globals, methods: getActionMethods({ actions: responses, arrayIndices, @@ -172,9 +173,7 @@ class Actions { context: this.context, event, }), - document: this.context._internal.lowdefy._internal.document, params: parsedAction.params, - window: this.context._internal.lowdefy._internal.window, }); if (progress) { progress(); diff --git a/packages/operators/src/nodeParser.test.js b/packages/operators/src/nodeParser.test.js index 5d96053da..a2a5f295c 100644 --- a/packages/operators/src/nodeParser.test.js +++ b/packages/operators/src/nodeParser.test.js @@ -130,6 +130,7 @@ test('operator returns value', () => { "payload": Object { "payload": true, }, + "runtime": "node", "secrets": Object { "secrets": true, }, diff --git a/packages/operators/src/webParser.js b/packages/operators/src/webParser.js index 8be54f2b2..55082b232 100644 --- a/packages/operators/src/webParser.js +++ b/packages/operators/src/webParser.js @@ -56,6 +56,7 @@ class WebParser { basePath, event, eventLog: this.context.eventLog, + globals: _internal.globals, home, input: inputs ? inputs[this.context.id] : {}, location: applyArrayIndices(arrayIndices, location), @@ -72,7 +73,6 @@ class WebParser { state: this.context.state, urlQuery: urlQuery ?? {}, user: user ?? {}, - window: _internal.window, }); return res; } catch (e) { diff --git a/packages/operators/src/webParser.test.js b/packages/operators/src/webParser.test.js index 0e0433e2e..5af3d8ef4 100644 --- a/packages/operators/src/webParser.test.js +++ b/packages/operators/src/webParser.test.js @@ -39,17 +39,19 @@ const context = { configured: false, }, _internal: { - window: { - location: { - hash: 'window.location.hash', - host: 'window.location.host', - hostname: 'window.location.hostname', - href: 'window.location.href', - origin: 'window.location.origin', - pathname: 'window.location.pathname', - port: 'window.location.port', - protocol: 'window.location.protocol', - search: 'window.location.search', + globals: { + window: { + location: { + hash: 'window.location.hash', + host: 'window.location.host', + hostname: 'window.location.hostname', + href: 'window.location.href', + origin: 'window.location.origin', + pathname: 'window.location.pathname', + port: 'window.location.port', + protocol: 'window.location.protocol', + search: 'window.location.search', + }, }, }, }, @@ -137,6 +139,21 @@ test('operator returns value', () => { "eventLog": true, }, ], + "globals": Object { + "window": Object { + "location": Object { + "hash": "window.location.hash", + "host": "window.location.host", + "hostname": "window.location.hostname", + "href": "window.location.href", + "origin": "window.location.origin", + "pathname": "window.location.pathname", + "port": "window.location.port", + "protocol": "window.location.protocol", + "search": "window.location.search", + }, + }, + }, "home": Object { "configured": false, "pageId": "home.pageId", @@ -175,17 +192,19 @@ test('operator returns value', () => { "_internal": Object { "lowdefy": Object { "_internal": Object { - "window": Object { - "location": Object { - "hash": "window.location.hash", - "host": "window.location.host", - "hostname": "window.location.hostname", - "href": "window.location.href", - "origin": "window.location.origin", - "pathname": "window.location.pathname", - "port": "window.location.port", - "protocol": "window.location.protocol", - "search": "window.location.search", + "globals": Object { + "window": Object { + "location": Object { + "hash": "window.location.hash", + "host": "window.location.host", + "hostname": "window.location.hostname", + "href": "window.location.href", + "origin": "window.location.origin", + "pathname": "window.location.pathname", + "port": "window.location.port", + "protocol": "window.location.protocol", + "search": "window.location.search", + }, }, }, }, @@ -248,6 +267,7 @@ test('operator returns value', () => { "requests": true, }, ], + "runtime": "browser", "state": Object { "state": true, }, @@ -257,19 +277,6 @@ test('operator returns value', () => { "user": Object { "user": true, }, - "window": Object { - "location": Object { - "hash": "window.location.hash", - "host": "window.location.host", - "hostname": "window.location.hostname", - "href": "window.location.href", - "origin": "window.location.origin", - "pathname": "window.location.pathname", - "port": "window.location.port", - "protocol": "window.location.protocol", - "search": "window.location.search", - }, - }, }, ], ] diff --git a/packages/plugins/actions/actions-core/src/actions/ScrollTo.js b/packages/plugins/actions/actions-core/src/actions/ScrollTo.js index ae44e7330..df350b62e 100644 --- a/packages/plugins/actions/actions-core/src/actions/ScrollTo.js +++ b/packages/plugins/actions/actions-core/src/actions/ScrollTo.js @@ -16,7 +16,8 @@ import { type } from '@lowdefy/helpers'; -function ScrollTo({ document, params, window }) { +function ScrollTo({ globals, params }) { + const { document, window } = globals; if (!type.isObject(params)) { throw new Error(`Invalid ScrollTo, check action params. Received "${JSON.stringify(params)}".`); } diff --git a/packages/plugins/actions/actions-core/src/actions/ScrollTo.test.js b/packages/plugins/actions/actions-core/src/actions/ScrollTo.test.js index af2e56166..ce543881e 100644 --- a/packages/plugins/actions/actions-core/src/actions/ScrollTo.test.js +++ b/packages/plugins/actions/actions-core/src/actions/ScrollTo.test.js @@ -34,14 +34,16 @@ const window = { scrollTo: mockWindowScrollTo, }; +const globals = { document, window }; + test('ScrollTo with no params', async () => { - expect(() => ScrollTo({ document, window })).toThrow( + expect(() => ScrollTo({ globals })).toThrow( 'Invalid ScrollTo, check action params. Received "undefined".' ); }); test('ScrollTo with no blockId', async () => { - ScrollTo({ document, window, params: { behavior: 'smooth', top: 0 } }); + ScrollTo({ globals, params: { behavior: 'smooth', top: 0 } }); expect(mockWindowScrollTo.mock.calls).toEqual([ [ { @@ -56,7 +58,7 @@ test('ScrollTo with blockId', async () => { mockDocGetElementById.mockImplementation((id) => { if (id === 'blockId') return { id, scrollIntoView: mockElemScrollIntoView }; }); - ScrollTo({ document, window, params: { blockId: 'blockId' } }); + ScrollTo({ globals, params: { blockId: 'blockId' } }); expect(mockDocGetElementById.mock.calls).toEqual([['blockId']]); expect(mockElemScrollIntoView.mock.calls).toEqual([[undefined]]); }); @@ -65,7 +67,7 @@ test('ScrollTo with blockId and options', async () => { mockDocGetElementById.mockImplementation((id) => { if (id === 'blockId') return { id, scrollIntoView: mockElemScrollIntoView }; }); - ScrollTo({ document, window, params: { blockId: 'blockId', options: { behavior: 'smooth' } } }); + ScrollTo({ globals, params: { blockId: 'blockId', options: { behavior: 'smooth' } } }); expect(mockDocGetElementById.mock.calls).toEqual([['blockId']]); expect(mockElemScrollIntoView.mock.calls).toEqual([[{ behavior: 'smooth' }]]); }); @@ -74,7 +76,7 @@ test('ScrollTo with blockId, block not found', async () => { mockDocGetElementById.mockImplementation((id) => { if (id === 'blockId') return { id, scrollIntoView: mockElemScrollIntoView }; }); - ScrollTo({ document, window, params: { blockId: 'not_there' } }); + ScrollTo({ globals, params: { blockId: 'not_there' } }); expect(mockDocGetElementById.mock.calls).toEqual([['not_there']]); expect(mockElemScrollIntoView.mock.calls).toEqual([]); expect(mockWindowScrollTo.mock.calls).toEqual([]); diff --git a/packages/plugins/operators/operators-js/src/operators/client/location.js b/packages/plugins/operators/operators-js/src/operators/client/location.js index a513065b2..85e529942 100644 --- a/packages/plugins/operators/operators-js/src/operators/client/location.js +++ b/packages/plugins/operators/operators-js/src/operators/client/location.js @@ -31,7 +31,8 @@ const validProperties = [ 'search', ]; -function _location({ arrayIndices, basePath, home, location, pageId, params, window }) { +function _location({ arrayIndices, basePath, home, location, pageId, params, globals }) { + const { window } = globals; if (!window?.location) { throw new Error( `Operator Error: Browser window.location not available for _location. Received: ${JSON.stringify( diff --git a/packages/plugins/operators/operators-js/src/operators/client/location.test.js b/packages/plugins/operators/operators-js/src/operators/client/location.test.js index e2f48679e..2bd27be8f 100644 --- a/packages/plugins/operators/operators-js/src/operators/client/location.test.js +++ b/packages/plugins/operators/operators-js/src/operators/client/location.test.js @@ -34,6 +34,8 @@ const window = { }, }; +const globals = { window }; + const input = { arrayIndices: [0], basePath: 'base', @@ -48,7 +50,7 @@ const input = { test('location calls getFromObject', async () => { const lowdefyOperators = await import('@lowdefy/operators'); - location({ ...input, window }); + location({ ...input, globals }); expect(lowdefyOperators.getFromObject.mock.calls).toEqual([ [ { @@ -76,19 +78,19 @@ test('location calls getFromObject', async () => { }); test('_location throw on no window', () => { - expect(() => location(input)).toThrow( + expect(() => location({ ...input, globals: {} })).toThrow( 'Operator Error: Browser window.location not available for _location. Received: "origin" at location.' ); }); test('_location throw on no location', () => { - expect(() => location({ ...input, window: {} })).toThrow( + expect(() => location({ ...input, globals: { window: {} } })).toThrow( 'Operator Error: Browser window.location not available for _location. Received: "origin" at location.' ); }); test('_location throw invalid param', () => { - expect(() => location({ ...input, window, params: 'invalid' })).toThrow( + expect(() => location({ ...input, globals, params: 'invalid' })).toThrow( 'Operator Error: _location only returns values for basePath, hash, homePageId, host, hostname, href, origin, pageId, pathname, port, protocol, search. Received: "invalid" at location.' ); }); diff --git a/packages/plugins/operators/operators-js/src/operators/client/media.js b/packages/plugins/operators/operators-js/src/operators/client/media.js index 54e6a763f..e011a8876 100644 --- a/packages/plugins/operators/operators-js/src/operators/client/media.js +++ b/packages/plugins/operators/operators-js/src/operators/client/media.js @@ -24,7 +24,8 @@ const breakpoints = { xl: 1600, }; -function _media({ arrayIndices, location, params, window }) { +function _media({ arrayIndices, location, params, globals }) { + const { window } = globals; if (!window?.innerWidth) { throw new Error( `Operator Error: device window width not available for _media. Received: ${JSON.stringify( diff --git a/packages/plugins/operators/operators-js/src/operators/client/media.test.js b/packages/plugins/operators/operators-js/src/operators/client/media.test.js index 93bc308b9..10b10600a 100644 --- a/packages/plugins/operators/operators-js/src/operators/client/media.test.js +++ b/packages/plugins/operators/operators-js/src/operators/client/media.test.js @@ -20,9 +20,10 @@ import media from './media.js'; console.error = () => {}; const window = { innerHeight: 300, innerWidth: 500 }; +const globals = { window }; test('_media full media object', () => { - expect(media({ params: true, location: 'locationId', window })).toEqual({ + expect(media({ params: true, location: 'locationId', globals })).toEqual({ height: 300, size: 'xs', width: 500, @@ -31,47 +32,59 @@ test('_media full media object', () => { test('_media size', () => { expect( - media({ params: 'size', location: 'locationId', window: { innerHeight: 300, innerWidth: 500 } }) + media({ + params: 'size', + location: 'locationId', + globals: { window: { innerHeight: 300, innerWidth: 500 } }, + }) ).toEqual('xs'); expect( - media({ params: 'size', location: 'locationId', window: { innerHeight: 300, innerWidth: 700 } }) + media({ + params: 'size', + location: 'locationId', + globals: { window: { innerHeight: 300, innerWidth: 700 } }, + }) ).toEqual('sm'); expect( - media({ params: 'size', location: 'locationId', window: { innerHeight: 300, innerWidth: 900 } }) + media({ + params: 'size', + location: 'locationId', + globals: { window: { innerHeight: 300, innerWidth: 900 } }, + }) ).toEqual('md'); expect( media({ params: 'size', location: 'locationId', - window: { innerHeight: 300, innerWidth: 1100 }, + globals: { window: { innerHeight: 300, innerWidth: 1100 } }, }) ).toEqual('lg'); expect( media({ params: 'size', location: 'locationId', - window: { innerHeight: 300, innerWidth: 1400 }, + globals: { window: { innerHeight: 300, innerWidth: 1400 } }, }) ).toEqual('xl'); expect( media({ params: 'size', location: 'locationId', - window: { innerHeight: 300, innerWidth: 1900 }, + globals: { window: { innerHeight: 300, innerWidth: 1900 } }, }) ).toEqual('xxl'); }); test('_media width', () => { - expect(media({ params: 'width', location: 'locationId', window })).toEqual(500); + expect(media({ params: 'width', location: 'locationId', globals })).toEqual(500); }); test('_media height', () => { - expect(media({ params: 'height', location: 'locationId', window })).toEqual(300); + expect(media({ params: 'height', location: 'locationId', globals })).toEqual(300); }); test('_media throw on no innerWidth', () => { - expect(() => media({ params: true, location: 'locationId', window: {} })).toThrow( + expect(() => media({ params: true, location: 'locationId', globals: { window: {} } })).toThrow( 'Operator Error: device window width not available for _media. Received: true at locationId.' ); });